Floppy-amee 2.0.16 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- 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
|