amee 2.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +19 -0
- data/README +106 -0
- data/amee.example.yml +12 -0
- data/bin/ameesh +30 -0
- data/examples/create_profile.rb +27 -0
- data/examples/create_profile_item.rb +33 -0
- data/examples/list_profiles.rb +29 -0
- data/examples/view_data_category.rb +40 -0
- data/examples/view_data_item.rb +37 -0
- data/init.rb +1 -0
- data/lib/amee.rb +63 -0
- data/lib/amee/connection.rb +236 -0
- data/lib/amee/data_category.rb +196 -0
- data/lib/amee/data_item.rb +218 -0
- data/lib/amee/data_item_value.rb +167 -0
- data/lib/amee/data_object.rb +11 -0
- data/lib/amee/drill_down.rb +102 -0
- data/lib/amee/exceptions.rb +27 -0
- data/lib/amee/item_definition.rb +158 -0
- data/lib/amee/object.rb +21 -0
- data/lib/amee/pager.rb +59 -0
- data/lib/amee/profile.rb +108 -0
- data/lib/amee/profile_category.rb +514 -0
- data/lib/amee/profile_item.rb +374 -0
- data/lib/amee/profile_item_value.rb +106 -0
- data/lib/amee/profile_object.rb +20 -0
- data/lib/amee/rails.rb +82 -0
- data/lib/amee/shell.rb +90 -0
- data/lib/amee/user.rb +111 -0
- data/lib/amee/version.rb +10 -0
- data/rails/init.rb +12 -0
- metadata +104 -0
@@ -0,0 +1,514 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module AMEE
|
4
|
+
module Profile
|
5
|
+
class Category < AMEE::Profile::Object
|
6
|
+
|
7
|
+
def initialize(data = {})
|
8
|
+
@children = data ? data[:children] : []
|
9
|
+
@items = data ? data[:items] : []
|
10
|
+
@total_amount = data[:total_amount]
|
11
|
+
@total_amount_unit = data[:total_amount_unit]
|
12
|
+
@start_date = data[:start_date]
|
13
|
+
@end_date = data[:end_date]
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :children
|
18
|
+
attr_reader :items
|
19
|
+
attr_reader :total_amount
|
20
|
+
attr_reader :total_amount_unit
|
21
|
+
|
22
|
+
def start_date
|
23
|
+
@start_date || profile_date
|
24
|
+
end
|
25
|
+
|
26
|
+
def end_date
|
27
|
+
@end_date
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.parse_json_profile_item(item)
|
31
|
+
item_data = {}
|
32
|
+
item_data[:values] = {}
|
33
|
+
item.each_pair do |key, value|
|
34
|
+
case key
|
35
|
+
when 'dataItemLabel', 'dataItemUid', 'name', 'path', 'uid'
|
36
|
+
item_data[key.to_sym] = value
|
37
|
+
when 'dataItem'
|
38
|
+
item_data[:dataItemLabel] = value['Label']
|
39
|
+
item_data[:dataItemUid] = value['uid']
|
40
|
+
when 'label' # ignore these
|
41
|
+
nil
|
42
|
+
when 'created'
|
43
|
+
item_data[:created] = DateTime.parse(value)
|
44
|
+
when 'modified'
|
45
|
+
item_data[:modified] = DateTime.parse(value)
|
46
|
+
when 'validFrom'
|
47
|
+
item_data[:validFrom] = DateTime.strptime(value, "%Y%m%d")
|
48
|
+
when 'startDate'
|
49
|
+
item_data[:startDate] = DateTime.parse(value)
|
50
|
+
when 'endDate'
|
51
|
+
item_data[:endDate] = DateTime.parse(value) rescue nil
|
52
|
+
when 'end'
|
53
|
+
item_data[:end] = (value == "true")
|
54
|
+
when 'amountPerMonth'
|
55
|
+
item_data[:amountPerMonth] = value.to_f
|
56
|
+
when 'amount'
|
57
|
+
item_data[:amount] = value['value'].to_f
|
58
|
+
item_data[:amount_unit] = value['unit']
|
59
|
+
when 'itemValues'
|
60
|
+
value.each do |itemval|
|
61
|
+
path = itemval['path'].to_sym
|
62
|
+
item_data[:values][path.to_sym] = {}
|
63
|
+
item_data[:values][path.to_sym][:name] = itemval['name']
|
64
|
+
item_data[:values][path.to_sym][:value] = itemval['value']
|
65
|
+
item_data[:values][path.to_sym][:unit] = itemval['unit']
|
66
|
+
item_data[:values][path.to_sym][:per_unit] = itemval['perUnit']
|
67
|
+
end
|
68
|
+
else
|
69
|
+
item_data[:values][key.to_sym] = value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
item_data[:path] ||= item_data[:uid] # Fill in path if not retrieved from response
|
73
|
+
return item_data
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.parse_json_profile_category(category)
|
77
|
+
datacat = category['dataCategory'] ? category['dataCategory'] : category
|
78
|
+
category_data = {}
|
79
|
+
category_data[:name] = datacat['name']
|
80
|
+
category_data[:path] = datacat['path']
|
81
|
+
category_data[:uid] = datacat['uid']
|
82
|
+
category_data[:totalAmountPerMonth] = category['totalAmountPerMonth'].to_f
|
83
|
+
category_data[:children] = []
|
84
|
+
category_data[:items] = []
|
85
|
+
if category['children']
|
86
|
+
category['children'].each do |child|
|
87
|
+
if child[0] == 'dataCategories'
|
88
|
+
child[1].each do |child_cat|
|
89
|
+
category_data[:children] << parse_json_profile_category(child_cat)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
if child[0] == 'profileItems' && child[1]['rows']
|
93
|
+
child[1]['rows'].each do |child_item|
|
94
|
+
category_data[:items] << parse_json_profile_item(child_item)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
return category_data
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.from_json(json, options)
|
103
|
+
# Parse json
|
104
|
+
doc = JSON.parse(json)
|
105
|
+
data = {}
|
106
|
+
data[:profile_uid] = doc['profile']['uid']
|
107
|
+
data[:profile_date] = DateTime.strptime(doc['profileDate'], "%Y%m") rescue nil
|
108
|
+
data[:name] = doc['dataCategory']['name']
|
109
|
+
data[:path] = doc['path']
|
110
|
+
data[:total_amount] = doc['totalAmountPerMonth']
|
111
|
+
data[:total_amount_unit] = "kg/month"
|
112
|
+
data[:children] = []
|
113
|
+
if doc['children'] && doc['children']['dataCategories']
|
114
|
+
doc['children']['dataCategories'].each do |child|
|
115
|
+
data[:children] << parse_json_profile_category(child)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
data[:items] = []
|
119
|
+
profile_items = []
|
120
|
+
profile_items.concat doc['children']['profileItems']['rows'] rescue nil
|
121
|
+
profile_items << doc['profileItem'] unless doc['profileItem'].nil?
|
122
|
+
profile_items.each do |item|
|
123
|
+
data[:items] << parse_json_profile_item(item)
|
124
|
+
end
|
125
|
+
# Create object
|
126
|
+
Category.new(data)
|
127
|
+
rescue
|
128
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory from JSON data. Check that your URL is correct.\n#{json}")
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.from_v2_json(json, options)
|
132
|
+
# Parse json
|
133
|
+
doc = JSON.parse(json)
|
134
|
+
data = {}
|
135
|
+
data[:profile_uid] = doc['profile']['uid']
|
136
|
+
data[:start_date] = options[:start_date]
|
137
|
+
data[:end_date] = options[:end_date]
|
138
|
+
data[:name] = doc['dataCategory']['name']
|
139
|
+
data[:path] = doc['path']
|
140
|
+
data[:total_amount] = doc['totalAmount']['value'].to_f rescue nil
|
141
|
+
data[:total_amount_unit] = doc['totalAmount']['unit'] rescue nil
|
142
|
+
data[:children] = []
|
143
|
+
if doc['profileCategories']
|
144
|
+
doc['profileCategories'].each do |child|
|
145
|
+
data[:children] << parse_json_profile_category(child)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
data[:items] = []
|
149
|
+
profile_items = []
|
150
|
+
profile_items.concat doc['profileItems'] rescue nil
|
151
|
+
profile_items << doc['profileItem'] unless doc['profileItem'].nil?
|
152
|
+
profile_items.each do |item|
|
153
|
+
data[:items] << parse_json_profile_item(item)
|
154
|
+
end
|
155
|
+
# Create object
|
156
|
+
Category.new(data)
|
157
|
+
rescue
|
158
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory from V2 JSON data. Check that your URL is correct.\n#{json}")
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.parse_xml_profile_item(item)
|
162
|
+
item_data = {}
|
163
|
+
item_data[:values] = {}
|
164
|
+
item.elements.each do |element|
|
165
|
+
key = element.name
|
166
|
+
value = element.text
|
167
|
+
case key.downcase
|
168
|
+
when 'dataitemlabel', 'dataitemuid', 'name', 'path'
|
169
|
+
item_data[key.to_sym] = value
|
170
|
+
when 'dataitem'
|
171
|
+
item_data[:dataItemUid] = element.attributes['uid']
|
172
|
+
when 'validfrom'
|
173
|
+
item_data[:validFrom] = DateTime.strptime(value, "%Y%m%d")
|
174
|
+
when 'end'
|
175
|
+
item_data[:end] = (value == "true")
|
176
|
+
when 'amountpermonth'
|
177
|
+
item_data[:amountPerMonth] = value.to_f
|
178
|
+
else
|
179
|
+
item_data[:values][key.to_sym] = value
|
180
|
+
end
|
181
|
+
end
|
182
|
+
item_data[:uid] = item.attributes['uid'].to_s
|
183
|
+
item_data[:created] = DateTime.parse(item.attributes['created'].to_s) rescue nil
|
184
|
+
item_data[:modified] = DateTime.parse(item.attributes['modified'].to_s) rescue nil
|
185
|
+
item_data[:path] ||= item_data[:uid] # Fill in path if not retrieved from response
|
186
|
+
return item_data
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.from_v2_batch_json(json)
|
190
|
+
# Parse JSON
|
191
|
+
doc = JSON.parse(json)
|
192
|
+
data = {}
|
193
|
+
data[:profileItems] = []
|
194
|
+
doc['profileItems'].each do |child|
|
195
|
+
profile_item = {}
|
196
|
+
profile_item[:uri] = child['uri'].to_s
|
197
|
+
profile_item[:uid] = child['uid'].to_s
|
198
|
+
data[:profileItems] << profile_item
|
199
|
+
end
|
200
|
+
return data
|
201
|
+
rescue
|
202
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory batch response from V2 JSON data. Check that your URL is correct.\n#{json}")
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.parse_xml_profile_category(category)
|
206
|
+
category_data = {}
|
207
|
+
category_data[:name] = category.elements['DataCategory'].elements['Name'].text
|
208
|
+
category_data[:path] = category.elements['DataCategory'].elements['Path'].text
|
209
|
+
category_data[:uid] = category.elements['DataCategory'].attributes['uid'].to_s
|
210
|
+
category_data[:totalAmountPerMonth] = category.elements['TotalAmountPerMonth'].text.to_f rescue nil
|
211
|
+
category_data[:children] = []
|
212
|
+
category_data[:items] = []
|
213
|
+
if category.elements['Children']
|
214
|
+
category.elements['Children'].each do |child|
|
215
|
+
if child.name == 'ProfileCategories'
|
216
|
+
child.each do |child_cat|
|
217
|
+
category_data[:children] << parse_xml_profile_category(child_cat)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
if child.name == 'ProfileItems'
|
221
|
+
child.each do |child_item|
|
222
|
+
category_data[:items] << parse_xml_profile_item(child_item)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
return category_data
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.from_xml(xml, options)
|
231
|
+
# Parse XML
|
232
|
+
doc = REXML::Document.new(xml)
|
233
|
+
data = {}
|
234
|
+
data[:profile_uid] = REXML::XPath.first(doc, "/Resources/ProfileCategoryResource/Profile/@uid").to_s
|
235
|
+
data[:profile_date] = DateTime.strptime(REXML::XPath.first(doc, "/Resources/ProfileCategoryResource/ProfileDate").text, "%Y%m")
|
236
|
+
data[:name] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/DataCategory/?ame').text
|
237
|
+
data[:path] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/Path | /Resources/ProfileCategoryResource/DataCategory/path').text || ""
|
238
|
+
data[:path] = "/#{data[:path]}" if data[:path].slice(0,1) != '/'
|
239
|
+
data[:total_amount] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/TotalAmountPerMonth').text.to_f rescue nil
|
240
|
+
data[:total_amount_unit] = "kg/month"
|
241
|
+
data[:children] = []
|
242
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/Children/ProfileCategories/DataCategory | /Resources/ProfileCategoryResource/Children/DataCategories/DataCategory') do |child|
|
243
|
+
category_data = {}
|
244
|
+
category_data[:name] = (child.elements['Name'] || child.elements['name']).text
|
245
|
+
category_data[:path] = (child.elements['Path'] || child.elements['path']).text
|
246
|
+
category_data[:uid] = child.attributes['uid'].to_s
|
247
|
+
data[:children] << category_data
|
248
|
+
end
|
249
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/Children/ProfileCategories/ProfileCategory') do |child|
|
250
|
+
data[:children] << parse_xml_profile_category(child)
|
251
|
+
end
|
252
|
+
data[:items] = []
|
253
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/Children/ProfileItems/ProfileItem') do |item|
|
254
|
+
data[:items] << parse_xml_profile_item(item)
|
255
|
+
end
|
256
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/ProfileItem') do |item|
|
257
|
+
data[:items] << parse_xml_profile_item(item)
|
258
|
+
end
|
259
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/ProfileItems/ProfileItem') do |item|
|
260
|
+
data[:items] << parse_xml_profile_item(item)
|
261
|
+
end
|
262
|
+
# Create object
|
263
|
+
Category.new(data)
|
264
|
+
rescue
|
265
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory from XML data. Check that your URL is correct.\n#{xml}")
|
266
|
+
end
|
267
|
+
|
268
|
+
def self.parse_v2_xml_profile_item(item)
|
269
|
+
item_data = {}
|
270
|
+
item_data[:values] = {}
|
271
|
+
item.elements.each do |element|
|
272
|
+
key = element.name
|
273
|
+
case key.downcase
|
274
|
+
when 'name', 'path'
|
275
|
+
item_data[key.downcase.to_sym] = element.text
|
276
|
+
when 'dataitem'
|
277
|
+
item_data[:dataItemLabel] = element.elements['Label'].text
|
278
|
+
item_data[:dataItemUid] = element.attributes['uid'].to_s
|
279
|
+
when 'validfrom'
|
280
|
+
item_data[:validFrom] = DateTime.strptime(element.text, "%Y%m%d")
|
281
|
+
when 'startdate'
|
282
|
+
item_data[:startDate] = DateTime.parse(element.text)
|
283
|
+
when 'enddate'
|
284
|
+
item_data[:endDate] = DateTime.parse(element.text) if element.text
|
285
|
+
when 'end'
|
286
|
+
item_data[:end] = (element.text == "true")
|
287
|
+
when 'amount'
|
288
|
+
item_data[:amount] = element.text.to_f
|
289
|
+
item_data[:amount_unit] = element.attributes['unit'].to_s
|
290
|
+
when 'itemvalues'
|
291
|
+
element.elements.each do |itemvalue|
|
292
|
+
path = itemvalue.elements['Path'].text
|
293
|
+
item_data[:values][path.to_sym] = {}
|
294
|
+
item_data[:values][path.to_sym][:name] = itemvalue.elements['Name'].text
|
295
|
+
item_data[:values][path.to_sym][:value] = itemvalue.elements['Value'].text || "0"
|
296
|
+
item_data[:values][path.to_sym][:unit] = itemvalue.elements['Unit'].text
|
297
|
+
item_data[:values][path.to_sym][:per_unit] = itemvalue.elements['PerUnit'].text
|
298
|
+
end
|
299
|
+
else
|
300
|
+
item_data[:values][key.to_sym] = element.text
|
301
|
+
end
|
302
|
+
end
|
303
|
+
item_data[:uid] = item.attributes['uid'].to_s
|
304
|
+
item_data[:created] = DateTime.parse(item.attributes['created'].to_s) rescue nil
|
305
|
+
item_data[:modified] = DateTime.parse(item.attributes['modified'].to_s) rescue nil
|
306
|
+
item_data[:path] ||= item_data[:uid] # Fill in path if not retrieved from response
|
307
|
+
return item_data
|
308
|
+
end
|
309
|
+
|
310
|
+
def self.from_v2_xml(xml, options)
|
311
|
+
# Parse XML
|
312
|
+
doc = REXML::Document.new(xml)
|
313
|
+
data = {}
|
314
|
+
data[:profile_uid] = REXML::XPath.first(doc, "/Resources/ProfileCategoryResource/Profile/@uid").to_s
|
315
|
+
data[:start_date] = options[:start_date]
|
316
|
+
data[:end_date] = options[:end_date]
|
317
|
+
data[:name] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/DataCategory/Name').text
|
318
|
+
data[:path] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/Path').text || ""
|
319
|
+
data[:total_amount] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/TotalAmount').text.to_f rescue nil
|
320
|
+
data[:total_amount_unit] = REXML::XPath.first(doc, '/Resources/ProfileCategoryResource/TotalAmount/@unit').to_s rescue nil
|
321
|
+
data[:children] = []
|
322
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/ProfileCategories/DataCategory') do |child|
|
323
|
+
category_data = {}
|
324
|
+
category_data[:name] = child.elements['Name'].text
|
325
|
+
category_data[:path] = child.elements['Path'].text
|
326
|
+
category_data[:uid] = child.attributes['uid'].to_s
|
327
|
+
data[:children] << category_data
|
328
|
+
end
|
329
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/Children/ProfileCategories/ProfileCategory') do |child|
|
330
|
+
data[:children] << parse_xml_profile_category(child)
|
331
|
+
end
|
332
|
+
data[:items] = []
|
333
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/ProfileItems/ProfileItem') do |item|
|
334
|
+
data[:items] << parse_v2_xml_profile_item(item)
|
335
|
+
end
|
336
|
+
REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/ProfileItem') do |item|
|
337
|
+
data[:items] << parse_v2_xml_profile_item(item)
|
338
|
+
end
|
339
|
+
# Create object
|
340
|
+
Category.new(data)
|
341
|
+
rescue
|
342
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory from V2 XML data. Check that your URL is correct.\n#{xml}")
|
343
|
+
end
|
344
|
+
|
345
|
+
def self.from_v2_batch_xml(xml)
|
346
|
+
# Parse XML
|
347
|
+
doc = REXML::Document.new(xml)
|
348
|
+
data = {}
|
349
|
+
data[:profileItems] = []
|
350
|
+
REXML::XPath.each(doc, '/Resources/ProfileItems/ProfileItem') do |child|
|
351
|
+
profile_item = {}
|
352
|
+
profile_item[:uri] = child.attributes['uri'].to_s
|
353
|
+
profile_item[:uid] = child.attributes['uid'].to_s
|
354
|
+
data[:profileItems] << profile_item
|
355
|
+
end
|
356
|
+
return data
|
357
|
+
rescue
|
358
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory batch response from V2 XML data. Check that your URL is correct.\n#{xml}")
|
359
|
+
end
|
360
|
+
|
361
|
+
def self.from_v2_atom(response, options)
|
362
|
+
# Parse XML
|
363
|
+
doc = REXML::Document.new(response)
|
364
|
+
data = {}
|
365
|
+
data[:profile_uid] = REXML::XPath.first(doc, "/feed/@xml:base").to_s.match("/profiles/(.*?)/")[1]
|
366
|
+
data[:start_date] = options[:start_date]
|
367
|
+
data[:end_date] = options[:end_date]
|
368
|
+
data[:name] = REXML::XPath.first(doc, '/feed/amee:name').text
|
369
|
+
data[:path] = REXML::XPath.first(doc, "/feed/@xml:base").to_s.match("/profiles/.*?(/.*)")[1]
|
370
|
+
data[:total_amount] = REXML::XPath.first(doc, '/feed/amee:totalAmount').text.to_f rescue nil
|
371
|
+
data[:total_amount_unit] = REXML::XPath.first(doc, '/feed/amee:totalAmount/@unit').to_s rescue nil
|
372
|
+
data[:children] = []
|
373
|
+
REXML::XPath.each(doc, '/feed/amee:categories/amee:category') do |child|
|
374
|
+
category_data = {}
|
375
|
+
# category_data[:path] = child.text
|
376
|
+
category_data[:path] = child.text
|
377
|
+
# category_data[:uid] = child.attributes['uid'].to_s
|
378
|
+
data[:children] << category_data
|
379
|
+
end
|
380
|
+
# REXML::XPath.each(doc, '/Resources/ProfileCategoryResource/Children/ProfileCategories/ProfileCategory') do |child|
|
381
|
+
# data[:children] << parse_xml_profile_category(child)
|
382
|
+
# end
|
383
|
+
data[:items] = []
|
384
|
+
REXML::XPath.each(doc, '/feed/entry') do |entry|
|
385
|
+
item = {}
|
386
|
+
item[:uid] = entry.elements['id'].text.match("urn:item:(.*)")[1]
|
387
|
+
item[:name] = entry.elements['title'].text
|
388
|
+
item[:path] = item[:uid]
|
389
|
+
# data[:dataItemLabel].should == "gas"
|
390
|
+
# data[:dataItemUid].should == "66056991EE23"
|
391
|
+
item[:amount] = entry.elements['amee:amount'].text.to_f rescue nil
|
392
|
+
item[:amount_unit] = entry.elements['amee:amount'].attributes['unit'].to_s rescue nil
|
393
|
+
item[:startDate] = DateTime.parse(entry.elements['amee:startDate'].text)
|
394
|
+
item[:endDate] = DateTime.parse(entry.elements['amee:endDate'].text) rescue nil
|
395
|
+
item[:values] = {}
|
396
|
+
entry.elements.each do |itemvalue|
|
397
|
+
if itemvalue.name == 'itemValue'
|
398
|
+
path = itemvalue.elements['link'].attributes['href'].to_s.match(".*/(.*)")[1]
|
399
|
+
x = {}
|
400
|
+
x[:path] = path
|
401
|
+
x[:name] = itemvalue.elements['amee:name'].text
|
402
|
+
x[:value] = itemvalue.elements['amee:value'].text unless itemvalue.elements['amee:value'].text == "N/A"
|
403
|
+
x[:value] ||= "0"
|
404
|
+
x[:unit] = itemvalue.elements['amee:unit'].text rescue nil
|
405
|
+
x[:per_unit] = itemvalue.elements['amee:perUnit'].text rescue nil
|
406
|
+
item[:values][path.to_sym] = x
|
407
|
+
end
|
408
|
+
end
|
409
|
+
data[:items] << item
|
410
|
+
end
|
411
|
+
# Create object
|
412
|
+
Category.new(data)
|
413
|
+
rescue
|
414
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory from V2 Atom data. Check that your URL is correct.\n#{response}")
|
415
|
+
end
|
416
|
+
|
417
|
+
def self.get_history(connection, path, num_months, end_date = Date.today, items_per_page = 10)
|
418
|
+
month = end_date.month
|
419
|
+
year = end_date.year
|
420
|
+
history = []
|
421
|
+
num_months.times do
|
422
|
+
date = Date.new(year, month)
|
423
|
+
data = self.get(connection, path, :start_date => date, :itemsPerPage => items_per_page)
|
424
|
+
# If we get no data items back, there is no data at all before this date, so don't bother fetching it
|
425
|
+
if data.items.empty?
|
426
|
+
(num_months - history.size).times do
|
427
|
+
history << Category.new(:children => [], :items => [])
|
428
|
+
end
|
429
|
+
break
|
430
|
+
else
|
431
|
+
history << data
|
432
|
+
end
|
433
|
+
month -= 1
|
434
|
+
if (month == 0)
|
435
|
+
year -= 1
|
436
|
+
month = 12
|
437
|
+
end
|
438
|
+
end
|
439
|
+
return history.reverse
|
440
|
+
end
|
441
|
+
|
442
|
+
def self.parse(connection, response, options)
|
443
|
+
# Parse data from response
|
444
|
+
if response.is_v2_json?
|
445
|
+
cat = Category.from_v2_json(response, options)
|
446
|
+
elsif response.is_json?
|
447
|
+
cat = Category.from_json(response, options)
|
448
|
+
elsif response.is_v2_atom?
|
449
|
+
cat = Category.from_v2_atom(response, options)
|
450
|
+
elsif response.is_v2_xml?
|
451
|
+
cat = Category.from_v2_xml(response, options)
|
452
|
+
elsif response.is_xml?
|
453
|
+
cat = Category.from_xml(response, options)
|
454
|
+
end
|
455
|
+
# Store connection in object for future use
|
456
|
+
cat.connection = connection
|
457
|
+
# Done
|
458
|
+
return cat
|
459
|
+
end
|
460
|
+
|
461
|
+
def self.parse_batch(connection, response)
|
462
|
+
if response.is_v2_json?
|
463
|
+
return Category.from_v2_batch_json(response)
|
464
|
+
elsif response.is_v2_xml?
|
465
|
+
return Category.from_v2_batch_xml(response)
|
466
|
+
else
|
467
|
+
return self.parse(connection, response, nil)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
def self.get(connection, path, orig_options = {})
|
472
|
+
unless orig_options.is_a?(Hash)
|
473
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
474
|
+
end
|
475
|
+
# Convert to AMEE options
|
476
|
+
options = orig_options.clone
|
477
|
+
if options[:start_date] && connection.version < 2
|
478
|
+
options[:profileDate] = options[:start_date].amee1_month
|
479
|
+
elsif options[:start_date] && connection.version >= 2
|
480
|
+
options[:startDate] = options[:start_date].xmlschema
|
481
|
+
end
|
482
|
+
options.delete(:start_date)
|
483
|
+
if options[:end_date] && connection.version >= 2
|
484
|
+
options[:endDate] = options[:end_date].xmlschema
|
485
|
+
end
|
486
|
+
options.delete(:end_date)
|
487
|
+
if options[:duration] && connection.version >= 2
|
488
|
+
options[:duration] = "PT#{options[:duration] * 86400}S"
|
489
|
+
end
|
490
|
+
# Load data from path
|
491
|
+
response = connection.get(path, options).body
|
492
|
+
return Category.parse(connection, response, orig_options)
|
493
|
+
rescue
|
494
|
+
raise AMEE::BadData.new("Couldn't load ProfileCategory. Check that your URL is correct.\n#{response}")
|
495
|
+
end
|
496
|
+
|
497
|
+
def child(child_path)
|
498
|
+
AMEE::Profile::Category.get(connection, "#{full_path}/#{child_path}")
|
499
|
+
end
|
500
|
+
|
501
|
+
def item(options)
|
502
|
+
# Search fields - from most specific to least specific
|
503
|
+
item = items.find{ |x| x[:uid] == options[:uid] || x[:name] == options[:name] || x[:dataItemUid] == options[:dataItemUid] || x[:dataItemLabel] == options[:dataItemLabel] }
|
504
|
+
# Pass through some options
|
505
|
+
new_opts = {}
|
506
|
+
new_opts[:returnUnit] = options[:returnUnit] if options[:returnUnit]
|
507
|
+
new_opts[:returnPerUnit] = options[:returnPerUnit] if options[:returnPerUnit]
|
508
|
+
new_opts[:format] = options[:format] if options[:format]
|
509
|
+
item ? AMEE::Profile::Item.get(connection, "#{full_path}/#{item[:path]}", new_opts) : nil
|
510
|
+
end
|
511
|
+
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|