forked from chrisabruce/GeoAPI
-
Notifications
You must be signed in to change notification settings - Fork 2
/
entity.rb
252 lines (189 loc) · 7.43 KB
/
entity.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
module GeoAPI
class Entity < GeoAPI::GeoObject
attr_accessor :guid, :id, :name, :entity_type, :geom, :url, :latitude, :longitude, :views, :userviews, :raw_json, :errors, :shorturl, :raw_json
alias_method :lat, :latitude
alias_method :lon, :longitude
alias_method :geometry, :geom
# Class methods
def self.create(params)
puts "GEOAPI::Entity.create #{params.to_json}"
#required: name, geom
#optional: pass id and it will create a new guid for you as user-<apikey>-<id>
raise ArgumentError, "A name is required (pass :name in parameters)" unless params.has_key?(:name)
raise ArgumentError, "A geometry is required (pass :geom in parameters)" unless params.has_key?(:geom)
post_url = "/e"
post_url = "/e/user-#{GeoAPI::API_KEY}-#{params[:id]}" unless params[:id].blank?
post_url = "/e/#{params[:guid]}" unless params[:guid].blank?
pp post_url
begin
results = Entity.post(post_url, {:body=> params.to_json})
rescue
raise BadRequest, "There was a problem communicating with the API"
end
raise BadRequest, results['error'] unless results['error'].blank?
#todo the result does not contain the guid, so merge it back in. Possible point of failure here?
Entity.new(results['result'].merge({'guid'=>results['query']['params']['guid']}))
end
def self.destroy(params)
puts "GEOAPI::Entity.destroy #{params.to_json}"
raise ArgumentError, "An id or guid is required (pass :id or :guid in parameters)" unless params.has_key?(:id) || params.has_key?(:guid)
begin
unless params[:guid].blank?
delete("/e/#{params[:guid]}")
else
delete("/e/user-#{GeoAPI::API_KEY}-#{params[:guid]}") unless params[:id].blank?
end
rescue
raise BadRequest, "There was a problem communicating with the API"
end
end
def self.create_at_lat_lng(params, lat, lng)
puts "GEOAPI::Entity.create_at_lat_lng #{lat},#{lng}"
p = GeoAPI::Point.new(lat,lng)
self.create(params.merge({:geom=>p}))
end
def self.find(*args)
puts "GEOAPI::Entity.find #{args.to_s}"
raise ArgumentError, "First argument must be symbol (:all or :get)" unless args.first.kind_of?(Symbol)
params = args.extract_options!
params = params == {} ? nil : params
case args.first
when :all
results = []
else
results = nil
raise ArgumentError, "Arguments should include a :guid or :id" if params[:guid].blank? && params[:id].blank?
params[:guid] = "user-#{GeoAPI::API_KEY}-#{the_id}" unless params[:id].blank?
begin
response = get("/e/#{params[:guid]}")
rescue
raise BadRequest, "There was a problem communicating with the API"
end
results = Entity.new(response['result'].merge({'guid'=>params[:guid]})) unless response['result'].blank? #the api doesn't return a guid in json?!
end
results
end
def self.find_by_id(the_id)
puts "GEOAPI::Entity.find_by_id #{the_id}"
self.find(:get, :guid=>"user-#{GeoAPI::API_KEY}-#{the_id}")
end
def self.find_by_guid(the_guid)
puts "GEOAPI::Entity.find_by_guid #{the_guid}"
self.find(:get, :guid=>the_guid)
end
def self.search(lat, lng, conditions)
puts "GEOAPI::Entity.search #{lat},#{lng} | #{conditions.to_s}"
# Accepts all conditions from the API and passes them through - http://docs.geoapi.com/Simple-Search
begin
response = get("/search", :query=>conditions.merge({:lat=>lat,:lon=>lng}))
rescue
raise BadRequest, "There was a problem communicating with the API"
end
results = []
unless response['result'].blank?
response['result'].each do |result|
results << Entity.new(result)
end
results.reverse!
end
end
# Instance methods
def initialize(attrs)
setup(attrs)
end
def setup(attrs)
self.guid = attrs['guid'] unless attrs['guid'].blank?
self.guid = "user-#{GeoAPI::API_KEY}-#{attrs['id']}" unless attrs['id'].blank?
puts "GEOAPI::Entity.setup #{self.guid}"
self.errors = attrs['error']
self.name = attrs['name']
self.entity_type = attrs['type']
self.shorturl = attrs['shorturl']
self.geom = GeoAPI::Geometry.from_hash(attrs['geom'])
self.views = []
unless attrs['views'].blank?
if attrs['views'].size > 0
attrs['views'].each do |view|
self.views << GeoAPI::View.new({'name'=>view, 'guid'=>self.guid})
# Dynamically create methods like twitter_view
(class <<self; self; end).send :define_method, :"#{view}_view" do
find_view("#{view}")
end
(class <<self; self; end).send :define_method, :"#{view}_view_entries" do
find_view_entries("#{view}")
end
end
end
end
self.userviews = []
unless attrs['userviews'].blank?
if attrs['userviews'].size > 0
attrs['userviews'].each do |view|
self.userviews << GeoAPI::UserView.new({'name'=>view, 'guid'=>self.guid})
# Dynamically create methods like myapp_userview
class << self
define_method "#{view}_userview" do
find_view("#{view}")
end
define_method :"#{view}_entries" do
#todo needs caching here
find_view("#{view}").entries
end
end
end
end
end
self
end
def type #type is a reserved word
self.entity_type
end
def update
puts "GEOAPI::Entity.update #{self.guid}"
self.setup(post("/e/#{guid}", :body=>{self.to_json}))
end
def load
puts "GEOAPI::Entity.load #{self.guid}"
raise ArgumentError, "Properties should include a .guid or .id" if self.guid.blank? && self.id.blank?
the_guid = self.guid
the_guid ||= "user-#{GeoAPI::API_KEY}-#{self.id}"
begin
response = self.class.get("/e/#{the_guid}")
rescue
raise BadRequest, "There was a problem communicating with the API"
end
self.setup(response['result'].merge({'guid'=>self.guid }))
self
end
def delete
puts "GEOAPI::Entity.delete #{self.guid}"
raise ArgumentError, "Object has no :guid" if self.guid.blank?
begin
Entity.destroy(:guid=>self.guid)
rescue
raise BadRequest, "There was a problem communicating with the API"
end
end
def destroy
self.delete
end
def save
update
end
def to_s
self.name
end
def to_json options=nil
{:name=>name, :guid=>guid, :type=>entity_type, :geom=>geom, :views=>views, :userviews=>userviews, :shorturl=>shorturl}.to_json
end
# Common facility methods
def find_view view_name
views.each do |view|
return view if view.name == view_name
end
end
def find_view_entries view_name
find_view(view_name).load.entries
end
end
end