15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/api_object.rb', line 15
def initialize_from_api options = {}
class_attribute :url, :action, :key, :mode, :url_options, :data_tags, :object_name
self.url, self.action, self.key, self.mode, self.url_options, self.data_tags, self.object_name = [options[:url], options[:action], options[:key], options[:mode], (options[:url_options] || {}), ([*options[:data_tags]] || []), (options[:object_name] || self.to_s.downcase.gsub(/^(.+::)(.+)$/, '\2'))]
instance_eval do
def get_results_by_ip ip, arguments = {}
self.api_key = arguments.delete(:key) if arguments.include?(:key)
if self.api_key
location = GeoIp.geolocation(ip)
raise unless location[:status_code] == "OK"
return get_results [*arguments.keys].inject({}) { |opts, a| opts.merge(a.to_sym => location[arguments[a.to_sym]]) }
else
location = FreeGeoIP.locate(ip)
get_results [*arguments.keys].inject({}) { |opts, a| opts.merge(a.to_sym => location[arguments[a.to_sym].to_s]) }
end
rescue
puts "ERROR: Cannot get results or location by ip. Verify that you have a valid key for the location service"
return ApiObjectError.new(:class => self, :errors => invalid_loc_msg)
end
def get_results options = {}
self.url_options.merge!(:key => self.key) unless self.key.nil?
[:url, :action, :mode].each {|opt| eval("self.#{opt.to_s} = options.delete(opt)") if options[opt]}
result = query_api(self.url, self.action, self.mode, self.url_options.merge(options))
process_result result
rescue
puts "ERROR: The request returned no valid data. #{error_invalid_url result[:url]}"
return ApiObjectError.new(:class => self, :errors => invalid_url_msg)
end
def api_key=(key)
GeoIp.api_key = key
end
def api_key
GeoIp.api_key
end
def error_invalid_url url
"The request url is #{url}, please, check if it's invalid of there is no connectivity." unless url.nil?
end
def invalid_url_msg
"Cannot get results from the url"
end
def invalid_loc_msg
"Cannot obtain results by ip, check the location"
end
def invalid_data_msg
"Cannot initialize the object"
end
private
def process_result result
raise unless result[:success]
obj = result[:result]
url = result[:url]
other_keys = {}
until obj.keys.include?(self.object_name.to_s)
obj = obj[obj.keys[0]]
other_keys.merge!(obj.keys.inject({}) { |h, k| (self.method_defined?(k) ? h.merge(k => obj[k]) : h)})
end
res = obj[self.object_name.to_s]
res.instance_of?(Array) ? res.map{|r| attach_url other_keys.merge(r), url} : (attach_url other_keys.merge(res), url)
end
def attach_url result, url
result.merge(:url => url)
end
end
end
|