Floppy-amee 2.0.16 → 2.0.17
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/README +2 -0
- data/lib/amee/data_category.rb +52 -0
- data/lib/amee/data_item.rb +84 -2
- data/lib/amee/item_definition.rb +96 -14
- metadata +1 -1
data/README
CHANGED
@@ -8,6 +8,8 @@ Author: James Smith (james@floppy.org.uk / http://www.floppy.org.uk)
|
|
8
8
|
|
9
9
|
Homepage: http://github.com/Floppy/amee-ruby
|
10
10
|
|
11
|
+
Documentation: http://docs.github.com/Floppy/amee-ruby
|
12
|
+
|
11
13
|
== INSTALLATION
|
12
14
|
|
13
15
|
1) Enable gems from github, if you haven't already done so (rubygems >= 1.2):
|
data/lib/amee/data_category.rb
CHANGED
@@ -110,6 +110,58 @@ module AMEE
|
|
110
110
|
AMEE::Data::DrillDown.get(connection, "#{full_path}/drill")
|
111
111
|
end
|
112
112
|
|
113
|
+
def item(options)
|
114
|
+
# Search fields - from most specific to least specific
|
115
|
+
item = items.find{ |x| (x[:uid] && x[:uid] == options[:uid]) ||
|
116
|
+
(x[:name] && x[:name] == options[:name]) ||
|
117
|
+
(x[:path] && x[:path] == options[:path]) ||
|
118
|
+
(x[:label] && x[:label] == options[:label]) }
|
119
|
+
# Pass through some options
|
120
|
+
new_opts = {}
|
121
|
+
new_opts[:format] = options[:format] if options[:format]
|
122
|
+
item ? AMEE::Data::Item.get(connection, "#{full_path}/#{item[:path]}", new_opts) : nil
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.create(category, options = {})
|
126
|
+
|
127
|
+
connection = category.connection
|
128
|
+
path = category.full_path
|
129
|
+
|
130
|
+
# Do we want to automatically fetch the item afterwards?
|
131
|
+
get_item = options.delete(:get_item)
|
132
|
+
|
133
|
+
get_item = true if get_item.nil?
|
134
|
+
# Store format if set
|
135
|
+
format = options[:format]
|
136
|
+
unless options.is_a?(Hash)
|
137
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
138
|
+
end
|
139
|
+
# Send data to path
|
140
|
+
options[:newObjectType] = "DC"
|
141
|
+
response = connection.post(path, options)
|
142
|
+
if response['Location']
|
143
|
+
location = response['Location'].match("http://.*?(/.*)")[1]
|
144
|
+
else
|
145
|
+
category = Category.parse(connection, response.body)
|
146
|
+
location = category.full_path
|
147
|
+
end
|
148
|
+
if get_item == true
|
149
|
+
get_options = {}
|
150
|
+
get_options[:format] = format if format
|
151
|
+
return AMEE::Data::Category.get(connection, location, get_options)
|
152
|
+
else
|
153
|
+
return location
|
154
|
+
end
|
155
|
+
rescue
|
156
|
+
raise AMEE::BadData.new("Couldn't create DataCategory. Check that your information is correct.")
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.delete(connection, path)
|
160
|
+
connection.delete(path)
|
161
|
+
rescue
|
162
|
+
raise AMEE::BadData.new("Couldn't delete DataCategory. Check that your information is correct.")
|
163
|
+
end
|
164
|
+
|
113
165
|
end
|
114
166
|
end
|
115
167
|
end
|
data/lib/amee/data_item.rb
CHANGED
@@ -8,6 +8,7 @@ module AMEE
|
|
8
8
|
@label = data[:label]
|
9
9
|
@item_definition = data[:item_definition]
|
10
10
|
@total_amount = data[:total_amount]
|
11
|
+
@total_amount_unit = data[:total_amount_unit]
|
11
12
|
super
|
12
13
|
end
|
13
14
|
|
@@ -16,6 +17,7 @@ module AMEE
|
|
16
17
|
attr_reader :label
|
17
18
|
attr_reader :item_definition
|
18
19
|
attr_reader :total_amount
|
20
|
+
attr_reader :total_amount_unit
|
19
21
|
|
20
22
|
def self.from_json(json)
|
21
23
|
# Read JSON
|
@@ -28,7 +30,14 @@ module AMEE
|
|
28
30
|
data[:path] = doc['path']
|
29
31
|
data[:label] = doc['dataItem']['label']
|
30
32
|
data[:item_definition] = doc['dataItem']['itemDefinition']['uid']
|
31
|
-
|
33
|
+
# Read v2 total
|
34
|
+
data[:total_amount] = doc['amount']['value'] rescue nil
|
35
|
+
data[:total_amount_unit] = doc['amount']['unit'] rescue nil
|
36
|
+
# Read v1 total
|
37
|
+
if data[:total_amount].nil?
|
38
|
+
data[:total_amount] = doc['amountPerMonth'] rescue nil
|
39
|
+
data[:total_amount_unit] = "kg/month"
|
40
|
+
end
|
32
41
|
# Get values
|
33
42
|
data[:values] = []
|
34
43
|
doc['dataItem']['itemValues'].each do |value|
|
@@ -64,7 +73,14 @@ module AMEE
|
|
64
73
|
data[:path] = (REXML::XPath.first(doc, '/Resources/DataItemResource/Path') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/path')).text
|
65
74
|
data[:label] = (REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Label') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/label')).text
|
66
75
|
data[:item_definition] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/ItemDefinition/@uid').to_s
|
67
|
-
|
76
|
+
# Read v2 total
|
77
|
+
data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount').text.to_f rescue nil
|
78
|
+
data[:total_amount_unit] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount/@unit').to_s rescue nil
|
79
|
+
# Read v1 total
|
80
|
+
if data[:total_amount].nil?
|
81
|
+
data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/AmountPerMonth').text.to_f rescue nil
|
82
|
+
data[:total_amount_unit] = "kg/month"
|
83
|
+
end
|
68
84
|
# Get values
|
69
85
|
data[:values] = []
|
70
86
|
REXML::XPath.each(doc, '/Resources/DataItemResource/DataItem/ItemValues/ItemValue') do |value|
|
@@ -107,6 +123,72 @@ module AMEE
|
|
107
123
|
raise AMEE::BadData.new("Couldn't load DataItem. Check that your URL is correct.")
|
108
124
|
end
|
109
125
|
|
126
|
+
def self.create_batch_without_category(connection, category_path, items, options = {})
|
127
|
+
if connection.format == :json
|
128
|
+
options.merge! :profileItems => items
|
129
|
+
post_data = options.to_json
|
130
|
+
else
|
131
|
+
options.merge!({:DataItems => items})
|
132
|
+
post_data = options.to_xml(:root => "DataCategory", :skip_types => true, :skip_nil => true)
|
133
|
+
end
|
134
|
+
# Post to category
|
135
|
+
response = connection.raw_post(category_path, post_data).body
|
136
|
+
# Send back a category object containing all the created items
|
137
|
+
unless response.empty?
|
138
|
+
return AMEE::Data::Category.parse(connection, response)
|
139
|
+
else
|
140
|
+
return true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.create(category, options = {})
|
145
|
+
create_without_category(category.connection, category.full_path, options)
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.create_without_category(connection, path, options = {})
|
149
|
+
# Do we want to automatically fetch the item afterwards?
|
150
|
+
get_item = options.delete(:get_item)
|
151
|
+
get_item = true if get_item.nil?
|
152
|
+
# Store format if set
|
153
|
+
format = options[:format]
|
154
|
+
unless options.is_a?(Hash)
|
155
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
156
|
+
end
|
157
|
+
# Set dates
|
158
|
+
if options[:start_date] && connection.version < 2
|
159
|
+
options[:validFrom] = options[:start_date].amee1_date
|
160
|
+
elsif options[:start_date] && connection.version >= 2
|
161
|
+
options[:startDate] = options[:start_date].xmlschema
|
162
|
+
end
|
163
|
+
options.delete(:start_date)
|
164
|
+
if options[:end_date] && connection.version >= 2
|
165
|
+
options[:endDate] = options[:end_date].xmlschema
|
166
|
+
end
|
167
|
+
options.delete(:end_date)
|
168
|
+
if options[:duration] && connection.version >= 2
|
169
|
+
options[:duration] = "PT#{options[:duration] * 86400}S"
|
170
|
+
end
|
171
|
+
# Create a data item!
|
172
|
+
options[:newObjectType] = "DI"
|
173
|
+
# Send data to path
|
174
|
+
response = connection.post(path, options)
|
175
|
+
# if response['Location']
|
176
|
+
# location = response['Location'].match("http://.*?(/.*)")[1]
|
177
|
+
# else
|
178
|
+
# category = Category.parse(connection, response.body)
|
179
|
+
# location = category.full_path + "/" + category.items[0][:path]
|
180
|
+
# end
|
181
|
+
# if get_item == true
|
182
|
+
# get_options = {}
|
183
|
+
# get_options[:format] = format if format
|
184
|
+
# return AMEE::Data::Item.get(connection, location, get_options)
|
185
|
+
# else
|
186
|
+
# return location
|
187
|
+
# end
|
188
|
+
rescue
|
189
|
+
raise AMEE::BadData.new("Couldn't create DataItem. Check that your information is correct.")
|
190
|
+
end
|
191
|
+
|
110
192
|
def update(options = {})
|
111
193
|
response = connection.put(full_path, options).body
|
112
194
|
rescue
|
data/lib/amee/item_definition.rb
CHANGED
@@ -1,5 +1,49 @@
|
|
1
1
|
module AMEE
|
2
2
|
module Admin
|
3
|
+
|
4
|
+
class ItemDefinitionList < Array
|
5
|
+
|
6
|
+
def initialize(connection, options = {})
|
7
|
+
# Load data from path
|
8
|
+
response = connection.get('/definitions/itemDefinitions', options).body
|
9
|
+
# Parse data from response
|
10
|
+
if response.is_json?
|
11
|
+
# Read JSON
|
12
|
+
doc = JSON.parse(response)
|
13
|
+
@pager = AMEE::Pager.from_json(doc['pager'])
|
14
|
+
doc['itemDefinitions'].each do |p|
|
15
|
+
data = {}
|
16
|
+
data[:uid] = p['uid']
|
17
|
+
data[:name] = p['name']
|
18
|
+
# Create ItemDefinition
|
19
|
+
item_definition = ItemDefinition.new(data)
|
20
|
+
# Store in array
|
21
|
+
self << item_definition
|
22
|
+
end
|
23
|
+
else
|
24
|
+
# Read XML
|
25
|
+
doc = REXML::Document.new(response)
|
26
|
+
@pager = AMEE::Pager.from_xml(REXML::XPath.first(doc, '/Resources/ItemDefinitionsResource/Pager'))
|
27
|
+
REXML::XPath.each(doc, '/Resources/ItemDefinitionsResource/ItemDefinitions/ItemDefinition') do |p|
|
28
|
+
data = {}
|
29
|
+
data[:uid] = p.attributes['uid'].to_s
|
30
|
+
data[:name] = p.elements['Name'].text || data[:uid]
|
31
|
+
# Create ItemDefinition
|
32
|
+
item_definition = ItemDefinition.new(data)
|
33
|
+
# Store connection in ItemDefinition object
|
34
|
+
item_definition.connection = connection
|
35
|
+
# Store in array
|
36
|
+
self << item_definition
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue
|
40
|
+
raise AMEE::BadData.new("Couldn't load ItemDefinition list.")
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :pager
|
44
|
+
|
45
|
+
end
|
46
|
+
|
3
47
|
class ItemDefinition < AMEE::Object
|
4
48
|
|
5
49
|
def initialize(data = {})
|
@@ -9,6 +53,23 @@ module AMEE
|
|
9
53
|
|
10
54
|
attr_reader :name
|
11
55
|
|
56
|
+
def self.list(connection)
|
57
|
+
ItemDefinitionList.new(connection)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.parse(connection, response, is_list = true)
|
61
|
+
# Parse data from response
|
62
|
+
if response.is_json?
|
63
|
+
item_definition = ItemDefinition.from_json(response)
|
64
|
+
else
|
65
|
+
item_definition = ItemDefinition.from_xml(response, is_list)
|
66
|
+
end
|
67
|
+
# Store connection in object for future use
|
68
|
+
item_definition.connection = connection
|
69
|
+
# Done
|
70
|
+
return item_definition
|
71
|
+
end
|
72
|
+
|
12
73
|
def self.from_json(json)
|
13
74
|
# Read JSON
|
14
75
|
doc = JSON.parse(json)
|
@@ -22,15 +83,16 @@ module AMEE
|
|
22
83
|
rescue
|
23
84
|
raise AMEE::BadData.new("Couldn't load ItemDefinition from JSON. Check that your URL is correct.")
|
24
85
|
end
|
25
|
-
|
26
|
-
def self.from_xml(xml)
|
86
|
+
|
87
|
+
def self.from_xml(xml, is_list = true)
|
88
|
+
prefix = is_list ? "/Resources/ItemDefinitionsResource/" : "/Resources/ItemDefinitionResource/"
|
27
89
|
# Parse data from response into hash
|
28
90
|
doc = REXML::Document.new(xml)
|
29
91
|
data = {}
|
30
|
-
data[:uid] = REXML::XPath.first(doc, "
|
31
|
-
data[:created] = DateTime.parse(REXML::XPath.first(doc, "
|
32
|
-
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "
|
33
|
-
data[:name] = REXML::XPath.first(doc,
|
92
|
+
data[:uid] = REXML::XPath.first(doc, prefix + "ItemDefinition/@uid").to_s
|
93
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemDefinition/@created").to_s)
|
94
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemDefinition/@modified").to_s)
|
95
|
+
data[:name] = REXML::XPath.first(doc, prefix + "ItemDefinition/Name").text
|
34
96
|
# Create object
|
35
97
|
ItemDefinition.new(data)
|
36
98
|
rescue
|
@@ -40,14 +102,8 @@ module AMEE
|
|
40
102
|
def self.get(connection, path, options = {})
|
41
103
|
# Load data from path
|
42
104
|
response = connection.get(path, options).body
|
43
|
-
# Parse
|
44
|
-
|
45
|
-
item_definition = ItemDefinition.from_json(response)
|
46
|
-
else
|
47
|
-
item_definition = ItemDefinition.from_xml(response)
|
48
|
-
end
|
49
|
-
# Store connection in object for future use
|
50
|
-
item_definition.connection = connection
|
105
|
+
# Parse response
|
106
|
+
item_definition = ItemDefinition.parse(connection, response, false)
|
51
107
|
# Done
|
52
108
|
return item_definition
|
53
109
|
rescue
|
@@ -60,6 +116,32 @@ module AMEE
|
|
60
116
|
raise AMEE::BadData.new("Couldn't update ItemDefinition. Check that your information is correct.")
|
61
117
|
end
|
62
118
|
|
119
|
+
def self.create(connection, options = {})
|
120
|
+
unless options.is_a?(Hash)
|
121
|
+
raise AMEE::ArgumentError.new("Second argument must be a hash of options!")
|
122
|
+
end
|
123
|
+
# Send data
|
124
|
+
response = connection.post("/definitions/itemDefinitions", options).body
|
125
|
+
# Parse response
|
126
|
+
item_definition = ItemDefinition.parse(connection, response)
|
127
|
+
# Get the ItemDefinition again
|
128
|
+
return ItemDefinition.get(connection, "/definitions/itemDefinitions/" + item_definition.uid)
|
129
|
+
rescue
|
130
|
+
raise AMEE::BadData.new("Couldn't create ItemDefinition. Check that your information is correct.")
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.delete(connection, item_definition)
|
134
|
+
# Deleting takes a while... up the timeout to 120 seconds temporarily
|
135
|
+
t = connection.timeout
|
136
|
+
connection.timeout = 120
|
137
|
+
connection.delete("/definitions/itemDefinitions/" + item_definition.uid)
|
138
|
+
connection.timeout = t
|
139
|
+
rescue
|
140
|
+
raise AMEE::BadData.new("Couldn't delete ProfileItem. Check that your information is correct.")
|
141
|
+
end
|
142
|
+
|
63
143
|
end
|
144
|
+
|
64
145
|
end
|
146
|
+
|
65
147
|
end
|