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,196 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module AMEE
|
4
|
+
module Data
|
5
|
+
class Category < AMEE::Data::Object
|
6
|
+
|
7
|
+
def initialize(data = {})
|
8
|
+
@children = data ? data[:children] : []
|
9
|
+
@items = data ? data[:items] : []
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :children
|
14
|
+
attr_reader :items
|
15
|
+
|
16
|
+
def self.from_json(json)
|
17
|
+
# Parse json
|
18
|
+
doc = JSON.parse(json)
|
19
|
+
data = {}
|
20
|
+
data[:uid] = doc['dataCategory']['uid']
|
21
|
+
data[:created] = DateTime.parse(doc['dataCategory']['created'])
|
22
|
+
data[:modified] = DateTime.parse(doc['dataCategory']['modified'])
|
23
|
+
data[:name] = doc['dataCategory']['name']
|
24
|
+
data[:path] = doc['path']
|
25
|
+
data[:children] = []
|
26
|
+
doc['children']['dataCategories'].each do |child|
|
27
|
+
category_data = {}
|
28
|
+
category_data[:name] = child['name']
|
29
|
+
category_data[:path] = child['path']
|
30
|
+
category_data[:uid] = child['uid']
|
31
|
+
data[:children] << category_data
|
32
|
+
end
|
33
|
+
data[:items] = []
|
34
|
+
if doc['children']['dataItems']['rows']
|
35
|
+
doc['children']['dataItems']['rows'].each do |item|
|
36
|
+
item_data = {}
|
37
|
+
item.each_pair do |key, value|
|
38
|
+
item_data[key.to_sym] = value
|
39
|
+
end
|
40
|
+
data[:items] << item_data
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# Create object
|
44
|
+
Category.new(data)
|
45
|
+
rescue
|
46
|
+
raise AMEE::BadData.new("Couldn't load DataCategory from JSON data. Check that your URL is correct.\n#{json}")
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.from_xml(xml)
|
50
|
+
# Parse XML
|
51
|
+
doc = REXML::Document.new(xml)
|
52
|
+
data = {}
|
53
|
+
data[:uid] = REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@uid").to_s
|
54
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@created").to_s)
|
55
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@modified").to_s)
|
56
|
+
data[:name] = REXML::XPath.first(doc, '/Resources/DataCategoryResource/DataCategory/?ame').text
|
57
|
+
data[:path] = REXML::XPath.first(doc, '/Resources/DataCategoryResource//?ath').text || ""
|
58
|
+
data[:children] = []
|
59
|
+
REXML::XPath.each(doc, '/Resources/DataCategoryResource//Children/DataCategories/DataCategory') do |child|
|
60
|
+
category_data = {}
|
61
|
+
category_data[:name] = (child.elements['Name'] || child.elements['name']).text
|
62
|
+
category_data[:path] = (child.elements['Path'] || child.elements['path']).text
|
63
|
+
category_data[:uid] = child.attributes['uid'].to_s
|
64
|
+
data[:children] << category_data
|
65
|
+
end
|
66
|
+
data[:items] = []
|
67
|
+
REXML::XPath.each(doc, '/Resources/DataCategoryResource//Children/DataItems/DataItem') do |item|
|
68
|
+
item_data = {}
|
69
|
+
item_data[:uid] = item.attributes['uid'].to_s
|
70
|
+
item.elements.each do |element|
|
71
|
+
item_data[element.name.to_sym] = element.text
|
72
|
+
end
|
73
|
+
if item_data[:path].nil?
|
74
|
+
item_data[:path] = item_data[:uid]
|
75
|
+
end
|
76
|
+
data[:items] << item_data
|
77
|
+
end
|
78
|
+
# Create object
|
79
|
+
Category.new(data)
|
80
|
+
rescue
|
81
|
+
raise AMEE::BadData.new("Couldn't load DataCategory from XML data. Check that your URL is correct.\n#{xml}")
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.get(connection, path, orig_options = {})
|
85
|
+
unless orig_options.is_a?(Hash)
|
86
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
87
|
+
end
|
88
|
+
# Convert to AMEE options
|
89
|
+
options = orig_options.clone
|
90
|
+
if orig_options[:items_per_page]
|
91
|
+
options[:itemsPerPage] = orig_options[:items_per_page]
|
92
|
+
else
|
93
|
+
options[:itemsPerPage] = 10
|
94
|
+
end
|
95
|
+
|
96
|
+
# Load data from path
|
97
|
+
response = connection.get(path, options).body
|
98
|
+
|
99
|
+
# Parse data from response
|
100
|
+
if response.is_json?
|
101
|
+
cat = Category.from_json(response)
|
102
|
+
else
|
103
|
+
cat = Category.from_xml(response)
|
104
|
+
end
|
105
|
+
# Store connection in object for future use
|
106
|
+
cat.connection = connection
|
107
|
+
# Done
|
108
|
+
return cat
|
109
|
+
rescue
|
110
|
+
raise AMEE::BadData.new("Couldn't load DataCategory. Check that your URL is correct.\n#{response}")
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.root(connection)
|
114
|
+
self.get(connection, '/data')
|
115
|
+
end
|
116
|
+
|
117
|
+
def child(child_path)
|
118
|
+
AMEE::Data::Category.get(connection, "#{full_path}/#{child_path}")
|
119
|
+
end
|
120
|
+
|
121
|
+
def drill
|
122
|
+
AMEE::Data::DrillDown.get(connection, "#{full_path}/drill")
|
123
|
+
end
|
124
|
+
|
125
|
+
def item(options)
|
126
|
+
# Search fields - from most specific to least specific
|
127
|
+
item = items.find{ |x| (x[:uid] && x[:uid] == options[:uid]) ||
|
128
|
+
(x[:name] && x[:name] == options[:name]) ||
|
129
|
+
(x[:path] && x[:path] == options[:path]) ||
|
130
|
+
(x[:label] && x[:label] == options[:label]) }
|
131
|
+
# Pass through some options
|
132
|
+
new_opts = {}
|
133
|
+
new_opts[:format] = options[:format] if options[:format]
|
134
|
+
item ? AMEE::Data::Item.get(connection, "#{full_path}/#{item[:path]}", new_opts) : nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.create(category, options = {})
|
138
|
+
|
139
|
+
connection = category.connection
|
140
|
+
path = category.full_path
|
141
|
+
|
142
|
+
# Do we want to automatically fetch the item afterwards?
|
143
|
+
get_item = options.delete(:get_item)
|
144
|
+
|
145
|
+
get_item = true if get_item.nil?
|
146
|
+
# Store format if set
|
147
|
+
format = options[:format]
|
148
|
+
unless options.is_a?(Hash)
|
149
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
150
|
+
end
|
151
|
+
# Send data to path
|
152
|
+
options[:newObjectType] = "DC"
|
153
|
+
response = connection.post(path, options)
|
154
|
+
if response['Location']
|
155
|
+
location = response['Location'].match("http://.*?(/.*)")[1]
|
156
|
+
else
|
157
|
+
category = Category.parse(connection, response.body)
|
158
|
+
location = category.full_path
|
159
|
+
end
|
160
|
+
if get_item == true
|
161
|
+
get_options = {}
|
162
|
+
get_options[:format] = format if format
|
163
|
+
return AMEE::Data::Category.get(connection, location, get_options)
|
164
|
+
else
|
165
|
+
return location
|
166
|
+
end
|
167
|
+
rescue
|
168
|
+
raise AMEE::BadData.new("Couldn't create DataCategory. Check that your information is correct.\n#{response}")
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.delete(connection, path)
|
172
|
+
connection.delete(path)
|
173
|
+
rescue
|
174
|
+
raise AMEE::BadData.new("Couldn't delete DataCategory. Check that your information is correct.")
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.update(connection, path, options = {})
|
178
|
+
# Do we want to automatically fetch the item afterwards?
|
179
|
+
get_item = options.delete(:get_item)
|
180
|
+
get_item = true if get_item.nil?
|
181
|
+
# Go
|
182
|
+
response = connection.put(path, options)
|
183
|
+
if get_item
|
184
|
+
if response.body.empty?
|
185
|
+
return Category.get(connection, path)
|
186
|
+
else
|
187
|
+
return Category.parse(connection, response.body)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
rescue
|
191
|
+
raise AMEE::BadData.new("Couldn't update Data Category. Check that your information is correct.")
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
module AMEE
|
2
|
+
module Data
|
3
|
+
class Item < AMEE::Data::Object
|
4
|
+
|
5
|
+
def initialize(data = {})
|
6
|
+
@values = data[:values]
|
7
|
+
@choices = data[:choices]
|
8
|
+
@label = data[:label]
|
9
|
+
@item_definition = data[:item_definition]
|
10
|
+
@total_amount = data[:total_amount]
|
11
|
+
@total_amount_unit = data[:total_amount_unit]
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :values
|
16
|
+
attr_reader :choices
|
17
|
+
attr_reader :label
|
18
|
+
attr_reader :item_definition
|
19
|
+
attr_reader :total_amount
|
20
|
+
attr_reader :total_amount_unit
|
21
|
+
|
22
|
+
def self.from_json(json)
|
23
|
+
# Read JSON
|
24
|
+
doc = JSON.parse(json)
|
25
|
+
data = {}
|
26
|
+
data[:uid] = doc['dataItem']['uid']
|
27
|
+
data[:created] = DateTime.parse(doc['dataItem']['created'])
|
28
|
+
data[:modified] = DateTime.parse(doc['dataItem']['modified'])
|
29
|
+
data[:name] = doc['dataItem']['name']
|
30
|
+
data[:path] = doc['path']
|
31
|
+
data[:label] = doc['dataItem']['label']
|
32
|
+
data[:item_definition] = doc['dataItem']['itemDefinition']['uid']
|
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
|
41
|
+
# Get values
|
42
|
+
data[:values] = []
|
43
|
+
doc['dataItem']['itemValues'].each do |value|
|
44
|
+
value_data = {}
|
45
|
+
value_data[:name] = value['name']
|
46
|
+
value_data[:path] = value['path']
|
47
|
+
value_data[:value] = value['value']
|
48
|
+
value_data[:drill] = value['itemValueDefinition']['drillDown'] rescue nil
|
49
|
+
value_data[:uid] = value['uid']
|
50
|
+
data[:values] << value_data
|
51
|
+
end
|
52
|
+
# Get choices
|
53
|
+
data[:choices] = []
|
54
|
+
doc['userValueChoices']['choices'].each do |choice|
|
55
|
+
choice_data = {}
|
56
|
+
choice_data[:name] = choice['name']
|
57
|
+
choice_data[:value] = choice['value']
|
58
|
+
data[:choices] << choice_data
|
59
|
+
end
|
60
|
+
# Create object
|
61
|
+
Item.new(data)
|
62
|
+
rescue
|
63
|
+
raise AMEE::BadData.new("Couldn't load DataItem from JSON. Check that your URL is correct.\n#{json}")
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.from_xml(xml)
|
67
|
+
# Parse data from response into hash
|
68
|
+
doc = REXML::Document.new(xml)
|
69
|
+
data = {}
|
70
|
+
data[:uid] = REXML::XPath.first(doc, "/Resources/DataItemResource/DataItem/@uid").to_s
|
71
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemResource/DataItem/@created").to_s)
|
72
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemResource/DataItem/@modified").to_s)
|
73
|
+
data[:name] = (REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Name') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/name')).text
|
74
|
+
data[:path] = (REXML::XPath.first(doc, '/Resources/DataItemResource/Path') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/path')).text
|
75
|
+
data[:label] = (REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Label') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/label')).text
|
76
|
+
data[:item_definition] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/ItemDefinition/@uid').to_s
|
77
|
+
# Read v2 total
|
78
|
+
data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount').text.to_f rescue nil
|
79
|
+
data[:total_amount_unit] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount/@unit').to_s rescue nil
|
80
|
+
# Read v1 total
|
81
|
+
if data[:total_amount].nil?
|
82
|
+
data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/AmountPerMonth').text.to_f rescue nil
|
83
|
+
data[:total_amount_unit] = "kg/month"
|
84
|
+
end
|
85
|
+
# Get values
|
86
|
+
data[:values] = []
|
87
|
+
REXML::XPath.each(doc, '/Resources/DataItemResource/DataItem/ItemValues/ItemValue') do |value|
|
88
|
+
value_data = {}
|
89
|
+
value_data[:name] = (value.elements['Name'] || value.elements['name']).text
|
90
|
+
value_data[:path] = (value.elements['Path'] || value.elements['path']).text
|
91
|
+
value_data[:value] = (value.elements['Value'] || value.elements['value']).text
|
92
|
+
value_data[:drill] = value.elements['ItemValueDefinition'].elements['DrillDown'].text == "false" ? false : true rescue nil
|
93
|
+
value_data[:uid] = value.attributes['uid'].to_s
|
94
|
+
data[:values] << value_data
|
95
|
+
end
|
96
|
+
# Get choices
|
97
|
+
data[:choices] = []
|
98
|
+
REXML::XPath.each(doc, '/Resources/DataItemResource/Choices/Choices/Choice') do |choice|
|
99
|
+
choice_data = {}
|
100
|
+
choice_data[:name] = (choice.elements['Name']).text
|
101
|
+
choice_data[:value] = (choice.elements['Value']).text || ""
|
102
|
+
data[:choices] << choice_data
|
103
|
+
end
|
104
|
+
# Create object
|
105
|
+
Item.new(data)
|
106
|
+
rescue
|
107
|
+
raise AMEE::BadData.new("Couldn't load DataItem from XML. Check that your URL is correct.\n#{xml}")
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
def self.get(connection, path, options = {})
|
112
|
+
# Load data from path
|
113
|
+
response = connection.get(path, options).body
|
114
|
+
AMEE::Data::Item.parse(connection, response)
|
115
|
+
rescue
|
116
|
+
raise AMEE::BadData.new("Couldn't load DataItem. Check that your URL is correct.\n#{response}")
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.parse(connection, response)
|
120
|
+
# Parse data from response
|
121
|
+
if response.is_json?
|
122
|
+
item = Item.from_json(response)
|
123
|
+
else
|
124
|
+
item = Item.from_xml(response)
|
125
|
+
end
|
126
|
+
# Store connection in object for future use
|
127
|
+
item.connection = connection
|
128
|
+
# Done
|
129
|
+
return item
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.create_batch_without_category(connection, category_path, items, options = {})
|
133
|
+
if connection.format == :json
|
134
|
+
options.merge! :profileItems => items
|
135
|
+
post_data = options.to_json
|
136
|
+
else
|
137
|
+
options.merge!({:DataItems => items})
|
138
|
+
post_data = options.to_xml(:root => "DataCategory", :skip_types => true, :skip_nil => true)
|
139
|
+
end
|
140
|
+
# Post to category
|
141
|
+
response = connection.raw_post(category_path, post_data).body
|
142
|
+
# Send back a category object containing all the created items
|
143
|
+
unless response.empty?
|
144
|
+
return AMEE::Data::Category.parse(connection, response)
|
145
|
+
else
|
146
|
+
return true
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.create(category, options = {})
|
151
|
+
create_without_category(category.connection, category.full_path, options)
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.create_without_category(connection, path, options = {})
|
155
|
+
# Do we want to automatically fetch the item afterwards?
|
156
|
+
get_item = options.delete(:get_item)
|
157
|
+
get_item = true if get_item.nil?
|
158
|
+
# Store format if set
|
159
|
+
format = options[:format]
|
160
|
+
unless options.is_a?(Hash)
|
161
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
162
|
+
end
|
163
|
+
# Create a data item!
|
164
|
+
options[:newObjectType] = "DI"
|
165
|
+
# Send data to path
|
166
|
+
response = connection.post(path, options)
|
167
|
+
if response['Location']
|
168
|
+
location = response['Location'].match("http://.*?(/.*)")[1]
|
169
|
+
else
|
170
|
+
category = Category.parse(connection, response.body)
|
171
|
+
location = category.full_path + "/" + category.items[0][:path]
|
172
|
+
end
|
173
|
+
if get_item == true
|
174
|
+
get_options = {}
|
175
|
+
get_options[:format] = format if format
|
176
|
+
return AMEE::Data::Item.get(connection, location, get_options)
|
177
|
+
else
|
178
|
+
return location
|
179
|
+
end
|
180
|
+
rescue
|
181
|
+
raise AMEE::BadData.new("Couldn't create DataItem. Check that your information is correct.\n#{response}")
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.update(connection, path, options = {})
|
185
|
+
# Do we want to automatically fetch the item afterwards?
|
186
|
+
get_item = options.delete(:get_item)
|
187
|
+
get_item = true if get_item.nil?
|
188
|
+
# Go
|
189
|
+
response = connection.put(path, options)
|
190
|
+
if get_item
|
191
|
+
if response.body.empty?
|
192
|
+
return Item.get(connection, path)
|
193
|
+
else
|
194
|
+
return Item.parse(connection, response.body)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
rescue
|
198
|
+
raise AMEE::BadData.new("Couldn't update DataItem. Check that your information is correct.\n#{response}")
|
199
|
+
end
|
200
|
+
|
201
|
+
def update(options = {})
|
202
|
+
AMEE::Data::Item.update(connection, full_path, options)
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.delete(connection, path)
|
206
|
+
connection.delete(path)
|
207
|
+
rescue
|
208
|
+
raise AMEE::BadData.new("Couldn't delete DataItem. Check that your information is correct.")
|
209
|
+
end
|
210
|
+
|
211
|
+
def value(name_or_path_or_uid)
|
212
|
+
val = values.find{ |x| x[:name] == name_or_path_or_uid || x[:path] == name_or_path_or_uid || x[:uid] == name_or_path_or_uid}
|
213
|
+
val ? val[:value] : nil
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module AMEE
|
2
|
+
module Data
|
3
|
+
class ItemValue < AMEE::Data::Object
|
4
|
+
|
5
|
+
def initialize(data = {})
|
6
|
+
@value = data ? data[:value] : nil
|
7
|
+
@type = data ? data[:type] : nil
|
8
|
+
@from_profile = data ? data[:from_profile] : nil
|
9
|
+
@from_data = data ? data[:from_data] : nil
|
10
|
+
@start_date = data ? data[:start_date] : nil
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :type
|
15
|
+
|
16
|
+
def value
|
17
|
+
case type
|
18
|
+
when "DECIMAL"
|
19
|
+
@value.to_f
|
20
|
+
else
|
21
|
+
@value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def value=(val)
|
26
|
+
@value = val
|
27
|
+
end
|
28
|
+
|
29
|
+
def from_profile?
|
30
|
+
@from_profile
|
31
|
+
end
|
32
|
+
|
33
|
+
def from_data?
|
34
|
+
@from_data
|
35
|
+
end
|
36
|
+
|
37
|
+
def start_date
|
38
|
+
@start_date
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.from_json(json, path)
|
42
|
+
# Read JSON
|
43
|
+
doc = JSON.parse(json)['itemValue']
|
44
|
+
data = {}
|
45
|
+
data[:uid] = doc['uid']
|
46
|
+
data[:created] = DateTime.parse(doc['created'])
|
47
|
+
data[:modified] = DateTime.parse(doc['modified'])
|
48
|
+
data[:name] = doc['name']
|
49
|
+
data[:path] = path.gsub(/^\/data/, '')
|
50
|
+
data[:value] = doc['value']
|
51
|
+
data[:type] = doc['itemValueDefinition']['valueDefinition']['valueType']
|
52
|
+
data[:start_date] = DateTime.parse(doc['startDate']) rescue nil
|
53
|
+
# Create object
|
54
|
+
ItemValue.new(data)
|
55
|
+
rescue
|
56
|
+
raise AMEE::BadData.new("Couldn't load DataItemValue from JSON. Check that your URL is correct.\n#{json}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.from_xml(xml, path)
|
60
|
+
# Read XML
|
61
|
+
doc = REXML::Document.new(xml)
|
62
|
+
data = {}
|
63
|
+
data[:uid] = REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/@uid").to_s
|
64
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/@Created").to_s)
|
65
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/@Modified").to_s)
|
66
|
+
data[:name] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/Name').text
|
67
|
+
data[:path] = path.gsub(/^\/data/, '')
|
68
|
+
data[:value] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/Value').text
|
69
|
+
data[:type] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/ValueDefinition/ValueType').text
|
70
|
+
data[:from_profile] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/FromProfile').text == "true" ? true : false
|
71
|
+
data[:from_data] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/FromData').text == "true" ? true : false
|
72
|
+
data[:start_date] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/StartDate").text) rescue nil
|
73
|
+
# Create object
|
74
|
+
ItemValue.new(data)
|
75
|
+
rescue
|
76
|
+
raise AMEE::BadData.new("Couldn't load DataItemValue from XML. Check that your URL is correct.\n#{xml}")
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.get(connection, path)
|
80
|
+
# Load data from path
|
81
|
+
response = connection.get(path).body
|
82
|
+
# Parse data from response
|
83
|
+
data = {}
|
84
|
+
value = ItemValue.parse(connection, response, path)
|
85
|
+
# Done
|
86
|
+
return value
|
87
|
+
rescue
|
88
|
+
raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.")
|
89
|
+
end
|
90
|
+
|
91
|
+
def save!
|
92
|
+
response = @connection.put(full_path, :value => value).body
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.parse(connection, response, path)
|
96
|
+
if response.is_json?
|
97
|
+
value = ItemValue.from_json(response, path)
|
98
|
+
else
|
99
|
+
value = ItemValue.from_xml(response, path)
|
100
|
+
end
|
101
|
+
# Store connection in object for future use
|
102
|
+
value.connection = connection
|
103
|
+
# Done
|
104
|
+
return value
|
105
|
+
rescue
|
106
|
+
raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.\n#{response}")
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.create(data_item, options = {})
|
110
|
+
# Do we want to automatically fetch the item afterwards?
|
111
|
+
get_item = options.delete(:get_item)
|
112
|
+
get_item = true if get_item.nil?
|
113
|
+
# Store format if set
|
114
|
+
format = options[:format]
|
115
|
+
unless options.is_a?(Hash)
|
116
|
+
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
117
|
+
end
|
118
|
+
# Set startDate
|
119
|
+
if (options[:start_date])
|
120
|
+
options[:startDate] = options[:start_date].xmlschema
|
121
|
+
options.delete(:start_date)
|
122
|
+
end
|
123
|
+
|
124
|
+
response = data_item.connection.post(data_item.full_path, options)
|
125
|
+
location = response['Location'].match("http://.*?(/.*)")[1]
|
126
|
+
|
127
|
+
if get_item == true
|
128
|
+
get_options = {}
|
129
|
+
get_options[:format] = format if format
|
130
|
+
return AMEE::Data::ItemValue.get(data_item.connection, location)
|
131
|
+
else
|
132
|
+
return location
|
133
|
+
end
|
134
|
+
rescue
|
135
|
+
raise AMEE::BadData.new("Couldn't create DataItemValue. Check that your information is correct.")
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.update(connection, path, options = {})
|
139
|
+
# Do we want to automatically fetch the item afterwards?
|
140
|
+
get_item = options.delete(:get_item)
|
141
|
+
get_item = true if get_item.nil?
|
142
|
+
# Go
|
143
|
+
response = connection.put(path, options)
|
144
|
+
if get_item
|
145
|
+
if response.body.empty?
|
146
|
+
return AMEE::Data::ItemValue.get(connection, path)
|
147
|
+
else
|
148
|
+
return AMEE::Data::ItemValue.parse(connection, response.body)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
rescue
|
152
|
+
raise AMEE::BadData.new("Couldn't update DataItemValue. Check that your information is correct.\n#{response}")
|
153
|
+
end
|
154
|
+
|
155
|
+
def update(options = {})
|
156
|
+
AMEE::Data::ItemValue.update(connection, full_path, options)
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.delete(connection, path)
|
160
|
+
connection.delete(path)
|
161
|
+
rescue
|
162
|
+
raise AMEE::BadData.new("Couldn't delete DataItemValue. Check that your information is correct.")
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|