lib/hubspot/utils.rb in hubspot-ruby-0.1.8 vs lib/hubspot/utils.rb in hubspot-ruby-0.2.0
- old
+ new
@@ -1,18 +1,121 @@
module Hubspot
class Utils
class << self
# Parses the hubspot properties format into a key-value hash
def properties_to_hash(props)
- newprops = {}
- props.each{ |k,v| newprops[k] = v["value"] }
+ newprops = HashWithIndifferentAccess.new
+ props.each { |k, v| newprops[k] = v["value"] }
newprops
end
# Turns a hash into the hubspot properties format
def hash_to_properties(hash, opts = {})
key_name = opts[:key_name] || "property"
- hash.map{ |k,v| { key_name => k.to_s, "value" => v}}
+ hash.map { |k, v| { key_name => k.to_s, "value" => v } }
+ end
+
+ def dump_properties(klass, hapikey=ENV['HUBSPOT_API_KEY'], filter={})
+ with_hapikey(hapikey) do
+ { 'groups' => klass.groups({}, filter),
+ 'properties' => klass.all({}, filter).select { |p| !p['hubspotDefined'] }
+ }
+ end
+ end
+
+ def restore_properties(klass, hapikey=ENV['HUPSPOT_API_KEY'], properties={}, dry_run=false)
+ existing_properties = dump_properties(klass, hapikey)
+ skip, new_groups, new_props, update_props = compare_property_lists(klass, properties, existing_properties)
+ puts '', 'Dry Run - Changes will not be applied' if dry_run
+ puts '','Skipping'
+ skip.each { |h| puts "#{h[:reason]} - #{h[:prop]['groupName']}:#{h[:prop]['name']}" }
+ with_hapikey(hapikey) do
+ create_groups(klass, new_groups, dry_run)
+ create_properties(klass, new_props, dry_run)
+ update_properties(klass, update_props, dry_run)
+ end
+ end
+
+ def create_groups(klass, groups, dry_run=false)
+ puts '','Creating new groups'
+ groups.each do |g|
+ if dry_run || klass.create_group!(g)
+ puts "Created: #{g['name']}"
+ else
+ puts "Failed: #{g['name']}"
+ end
+ end
+ end
+
+ def create_properties(klass, props, dry_run=false)
+ puts '','Creating new properties'
+ props.each do |p|
+ if dry_run || klass.create!(p)
+ puts "Created: #{p['groupName']}:#{p['name']}"
+ else
+ puts "Failed: #{p['groupName']}:#{p['name']}"
+ end
+ end
+ end
+
+ def update_properties(klass, props, dry_run=false)
+ puts '','Updating existing properties'
+ props.each do |p|
+ if dry_run || klass.update!(p['name'], p)
+ puts "Updated: #{p['groupName']}:#{p['name']}"
+ else
+ puts "Failed: #{p['groupName']}:#{p['name']}"
+ end
+ end
+ end
+
+ def compare_property_lists(klass, source, target)
+ skip = [] # Array of skipped properties and the reason
+ new_groups = Set.new # Array of groups to create
+ new_props = [] # Array of properties to add
+ update_props = [] # Array of properties to update
+ src_groups = source['groups']
+ dst_groups = target['groups']
+ src_props = source['properties']
+ dst_props = target['properties']
+
+ src_props.each do |src|
+ group = find_by_name(src['groupName'], src_groups)
+ if src['createdUserId'].blank? && src['updatedUserId'].blank? then
+ skip << { prop: src, reason: 'Not user created' }
+ else
+ dst = find_by_name(src['name'], dst_props)
+ if dst
+ if dst['readOnlyDefinition']
+ skip << { prop: src, reason: 'Definition is read-only' }
+ elsif klass.same?(src, dst)
+ skip << { prop: src, reason: 'No change' }
+ else
+ new_groups << group unless group.blank? || find_by_name(group['name'], dst_groups)
+ update_props << src
+ end
+ else
+ new_groups << group unless group.blank? || find_by_name(group['name'], dst_groups)
+ new_props << src
+ end
+ end
+ end
+ [skip, new_groups.to_a, new_props, update_props]
+ end
+
+ def with_hapikey(hapikey)
+ begin
+ Hubspot.configure(hapikey: hapikey) unless hapikey.blank?
+ yield if block_given?
+ ensure
+ Hubspot.configure(hapikey: ENV['HUBSPOT_API_KEY']) unless hapikey.blank?
+ end
+ end
+
+ private
+
+ def find_by_name(name, set)
+ set.detect { |item| item['name'] == name }
end
end
end
end