amee 2.0.35 → 2.2.0
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/CHANGELOG +11 -0
- data/README +8 -6
- data/amee.example.yml +3 -0
- data/cacert.pem +45 -0
- data/lib/amee.rb +5 -0
- data/lib/amee/collection.rb +64 -0
- data/lib/amee/connection.rb +28 -11
- data/lib/amee/data_category.rb +17 -9
- data/lib/amee/data_item.rb +18 -8
- data/lib/amee/data_item_value.rb +11 -11
- data/lib/amee/item_definition.rb +36 -42
- data/lib/amee/item_value_definition.rb +231 -0
- data/lib/amee/logger.rb +18 -0
- data/lib/amee/object.rb +4 -3
- data/lib/amee/pager.rb +43 -0
- data/lib/amee/parse_helper.rb +29 -0
- data/lib/amee/profile_category.rb +44 -2
- data/lib/amee/profile_item.rb +45 -4
- data/lib/amee/rails.rb +5 -1
- metadata +24 -4
data/lib/amee/data_item_value.rb
CHANGED
@@ -30,11 +30,11 @@ module AMEE
|
|
30
30
|
def from_profile?
|
31
31
|
@from_profile
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def from_data?
|
35
35
|
@from_data
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
attr_accessor :start_date
|
39
39
|
attr_accessor :uid
|
40
40
|
|
@@ -65,10 +65,10 @@ module AMEE
|
|
65
65
|
data[:start_date] = DateTime.parse(doc['startDate']) rescue nil
|
66
66
|
# Create object
|
67
67
|
ItemValue.new(data)
|
68
|
-
rescue
|
68
|
+
rescue
|
69
69
|
raise AMEE::BadData.new("Couldn't load DataItemValue from JSON. Check that your URL is correct.\n#{json}")
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def self.from_xml(xml, path)
|
73
73
|
# Read XML
|
74
74
|
doc = xml.is_a?(String) ? REXML::Document.new(xml) : xml
|
@@ -135,7 +135,7 @@ module AMEE
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
-
def self.parse(connection, response, path)
|
138
|
+
def self.parse(connection, response, path)
|
139
139
|
if response.is_json?
|
140
140
|
value = ItemValue.from_json(response, path)
|
141
141
|
else
|
@@ -148,7 +148,7 @@ module AMEE
|
|
148
148
|
rescue
|
149
149
|
raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.\n#{response}")
|
150
150
|
end
|
151
|
-
|
151
|
+
|
152
152
|
def self.create(data_item, options = {})
|
153
153
|
|
154
154
|
# Do we want to automatically fetch the item afterwards?
|
@@ -159,7 +159,7 @@ module AMEE
|
|
159
159
|
unless options.is_a?(Hash)
|
160
160
|
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
163
|
# Set startDate
|
164
164
|
if (options[:start_date])
|
165
165
|
options[:startDate] = options[:start_date].xmlschema
|
@@ -167,7 +167,7 @@ module AMEE
|
|
167
167
|
end
|
168
168
|
|
169
169
|
response = data_item.connection.post(data_item.full_path, options)
|
170
|
-
location = response['Location'].match("
|
170
|
+
location = response['Location'].match("https??://.*?(/.*)")[1]
|
171
171
|
if get_item == true
|
172
172
|
get_options = {}
|
173
173
|
get_options[:format] = format if format
|
@@ -200,7 +200,7 @@ module AMEE
|
|
200
200
|
rescue
|
201
201
|
raise AMEE::BadData.new("Couldn't update DataItemValue. Check that your information is correct.\n#{response}")
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
def update(options = {})
|
205
205
|
AMEE::Data::ItemValue.update(connection, full_path, options)
|
206
206
|
end
|
@@ -210,8 +210,8 @@ module AMEE
|
|
210
210
|
connection.delete(path)
|
211
211
|
rescue
|
212
212
|
raise AMEE::BadData.new("Couldn't delete DataItemValue. Check that your information is correct.")
|
213
|
-
end
|
214
|
-
|
213
|
+
end
|
214
|
+
|
215
215
|
end
|
216
216
|
end
|
217
217
|
end
|
data/lib/amee/item_definition.rb
CHANGED
@@ -1,57 +1,43 @@
|
|
1
1
|
module AMEE
|
2
2
|
module Admin
|
3
3
|
|
4
|
-
class ItemDefinitionList <
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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.\n#{response}")
|
4
|
+
class ItemDefinitionList < AMEE::Collection
|
5
|
+
def collectionpath
|
6
|
+
'/definitions/itemDefinitions'
|
7
|
+
end
|
8
|
+
def klass
|
9
|
+
ItemDefinition
|
10
|
+
end
|
11
|
+
def jsoncollector
|
12
|
+
@doc['itemDefinitions']
|
13
|
+
end
|
14
|
+
def xmlcollectorpath
|
15
|
+
'/Resources/ItemDefinitionsResource/ItemDefinitions/ItemDefinition'
|
41
16
|
end
|
42
17
|
|
43
|
-
|
44
|
-
|
18
|
+
def parse_json(p)
|
19
|
+
data = {}
|
20
|
+
data[:uid] = p['uid']
|
21
|
+
data[:name] = p['name']
|
22
|
+
data
|
23
|
+
end
|
24
|
+
def parse_xml(p)
|
25
|
+
data = {}
|
26
|
+
data[:uid] = x '@uid',:doc=>p
|
27
|
+
data[:name] = x('Name',:doc=>p) || data[:uid]
|
28
|
+
data
|
29
|
+
end
|
45
30
|
end
|
46
31
|
|
47
32
|
class ItemDefinition < AMEE::Object
|
48
33
|
|
49
34
|
def initialize(data = {})
|
50
35
|
@name = data[:name]
|
36
|
+
@drill_downs = data[:drillDown]
|
51
37
|
super
|
52
38
|
end
|
53
39
|
|
54
|
-
attr_reader :name
|
40
|
+
attr_reader :name, :drill_downs
|
55
41
|
|
56
42
|
def self.list(connection)
|
57
43
|
ItemDefinitionList.new(connection)
|
@@ -78,6 +64,7 @@ module AMEE
|
|
78
64
|
data[:created] = DateTime.parse(doc['itemDefinition']['created'])
|
79
65
|
data[:modified] = DateTime.parse(doc['itemDefinition']['modified'])
|
80
66
|
data[:name] = doc['itemDefinition']['name']
|
67
|
+
data[:drillDown] = doc['itemDefinition']['drillDown'].split(",") rescue nil
|
81
68
|
# Create object
|
82
69
|
ItemDefinition.new(data)
|
83
70
|
rescue
|
@@ -93,6 +80,7 @@ module AMEE
|
|
93
80
|
data[:created] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemDefinition/@created").to_s)
|
94
81
|
data[:modified] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemDefinition/@modified").to_s)
|
95
82
|
data[:name] = REXML::XPath.first(doc, prefix + "ItemDefinition/Name").text
|
83
|
+
data[:drillDown] = REXML::XPath.first(doc, prefix + "ItemDefinition/DrillDown").text.split(",") rescue nil
|
96
84
|
# Create object
|
97
85
|
ItemDefinition.new(data)
|
98
86
|
rescue
|
@@ -127,6 +115,14 @@ module AMEE
|
|
127
115
|
raise AMEE::BadData.new("Couldn't update ItemDefinition. Check that your information is correct.\n#{response}")
|
128
116
|
end
|
129
117
|
|
118
|
+
def self.load(connection,uid,options={})
|
119
|
+
ItemDefinition.get(connection,"/definitions/itemDefinitions/#{uid}",options)
|
120
|
+
end
|
121
|
+
|
122
|
+
def item_value_definition_list
|
123
|
+
@item_value_definitions ||= AMEE::Admin::ItemValueDefinitionList.new(connection,uid)
|
124
|
+
end
|
125
|
+
|
130
126
|
def self.create(connection, options = {})
|
131
127
|
unless options.is_a?(Hash)
|
132
128
|
raise AMEE::ArgumentError.new("Second argument must be a hash of options!")
|
@@ -152,7 +148,5 @@ module AMEE
|
|
152
148
|
end
|
153
149
|
|
154
150
|
end
|
155
|
-
|
156
151
|
end
|
157
|
-
|
158
152
|
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
module AMEE
|
2
|
+
module Admin
|
3
|
+
|
4
|
+
class ItemValueDefinitionList < AMEE::Collection
|
5
|
+
# TODO this class does not yet page through multiple pages
|
6
|
+
def initialize(connection,uid,options={})
|
7
|
+
@uid=uid
|
8
|
+
super(connection,options)
|
9
|
+
end
|
10
|
+
def klass
|
11
|
+
ItemValueDefinition
|
12
|
+
end
|
13
|
+
def collectionpath
|
14
|
+
"/definitions/itemDefinitions/#{@uid}/itemValueDefinitions"
|
15
|
+
end
|
16
|
+
|
17
|
+
def jsoncollector
|
18
|
+
@doc['itemValueDefinitions']
|
19
|
+
end
|
20
|
+
def xmlcollectorpath
|
21
|
+
'/Resources/ItemValueDefinitionsResource/ItemValueDefinitions/ItemValueDefinition'
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_json(p)
|
25
|
+
data = {}
|
26
|
+
data[:itemdefuid] = @uid
|
27
|
+
data[:uid] = p['uid']
|
28
|
+
data[:name] = p['name']
|
29
|
+
data[:path] = p['path']
|
30
|
+
data[:unit] = p['unit']
|
31
|
+
data[:perunit] = p['perunit']
|
32
|
+
data[:valuetype] = p['valueDefinition']['valueType']
|
33
|
+
data=ItemValueDefinition.parsetype(data,p['drillDown'],p['fromProfile'],p['fromData'])
|
34
|
+
|
35
|
+
end
|
36
|
+
def parse_xml(p)
|
37
|
+
data = {}
|
38
|
+
data[:itemdefuid] = @uid
|
39
|
+
data[:uid] = x '@uid',:doc => p
|
40
|
+
data[:name] = x 'Name',:doc => p || data[:uid]
|
41
|
+
data[:path] = x 'Path',:doc => p
|
42
|
+
data[:unit] = x 'Unit',:doc => p
|
43
|
+
data[:perunit] = x 'PerUnit',:doc => p
|
44
|
+
data[:valuetype] =x 'ValueDefinition/ValueType',:doc => p
|
45
|
+
drill=(x('DrillDown',:doc => p)=='true')
|
46
|
+
profile=(x('FromProfile',:doc => p)=='true')
|
47
|
+
ldata=(x('FromData',:doc => p)=='true')
|
48
|
+
data=ItemValueDefinition.parsetype(data,drill,profile,ldata)
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class ItemValueDefinition < AMEE::Object
|
54
|
+
|
55
|
+
def initialize(data = {})
|
56
|
+
@itemdefuid=data[:itemdefuid]
|
57
|
+
@name = data[:name]
|
58
|
+
@uid = data[:uid]
|
59
|
+
@path = data[:path]
|
60
|
+
@type = data[:type]
|
61
|
+
@unit = data[:unit]
|
62
|
+
@perunit = data[:perunit]
|
63
|
+
@valuetype = data[:valuetype]
|
64
|
+
@default = data[:default] == "" ? nil : data[:default]
|
65
|
+
@choices = data[:choices] || []
|
66
|
+
@versions = data[:versions] || []
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
attr_reader :name,:uid,:path,:itemdefuid, :type, :valuetype, :unit, :perunit, :type, :default, :choices, :versions
|
71
|
+
|
72
|
+
def profile?
|
73
|
+
type=='profile'
|
74
|
+
end
|
75
|
+
|
76
|
+
def data?
|
77
|
+
type=='data'
|
78
|
+
end
|
79
|
+
|
80
|
+
def drill?
|
81
|
+
type=='drill'
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.list(connection)
|
85
|
+
ItemValueDefinitionList.new(connection)
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.parse(connection, response, is_list = true)
|
89
|
+
# Parse data from response
|
90
|
+
if response.is_json?
|
91
|
+
item_definition = ItemValueDefinition.from_json(response)
|
92
|
+
else
|
93
|
+
item_definition = ItemValueDefinition.from_xml(response, is_list)
|
94
|
+
end
|
95
|
+
# Store connection in object for future use
|
96
|
+
item_definition.connection = connection
|
97
|
+
# Done
|
98
|
+
return item_definition
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.from_json(json)
|
102
|
+
# Read JSON
|
103
|
+
doc = JSON.parse(json)
|
104
|
+
data = {}
|
105
|
+
p=doc['itemValueDefinition']
|
106
|
+
data[:uid] = p['uid']
|
107
|
+
data[:itemdefuid] = p['itemDefinition']['uid']
|
108
|
+
data[:created] = DateTime.parse(p['created'])
|
109
|
+
data[:modified] = DateTime.parse(p['modified'])
|
110
|
+
data[:name] = p['name']
|
111
|
+
data[:path] = p['path']
|
112
|
+
data[:unit] = p['unit']
|
113
|
+
data[:perunit] = p['perUnit']
|
114
|
+
data[:valuetype] = p['valueDefinition']['valueType']
|
115
|
+
data[:default] = p['value']
|
116
|
+
data[:choices] = p['choices'].split(',')
|
117
|
+
data[:versions] = p['apiVersions'].map{|v| v['apiVersion']}
|
118
|
+
data=ItemValueDefinition.parsetype(data,p['drillDown'],p['fromProfile'],p['fromData'])
|
119
|
+
# Create object
|
120
|
+
ItemValueDefinition.new(data)
|
121
|
+
rescue
|
122
|
+
raise AMEE::BadData.new("Couldn't load ItemValueDefinition from JSON. Check that your URL is correct.\n#{json}")
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.parsetype(data,drill,profile,ldata)
|
126
|
+
( (profile && !(drill||ldata) ) || ldata) or raise 'inconsistent type'
|
127
|
+
data[:type]='profile' if profile
|
128
|
+
data[:type]='data' if ldata
|
129
|
+
data[:type]='drill' if drill
|
130
|
+
data
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.from_xml(xml, is_list = true)
|
134
|
+
prefix = is_list ? "/Resources/ItemValueDefinitionsResource/" : "/Resources/ItemValueDefinitionResource/"
|
135
|
+
# Parse data from response into hash
|
136
|
+
doc = REXML::Document.new(xml)
|
137
|
+
data = {}
|
138
|
+
data[:uid] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/@uid").to_s
|
139
|
+
data[:itemdefuid] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/ItemDefinition/@uid").to_s
|
140
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemValueDefinition/@created").to_s)
|
141
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemValueDefinition/@modified").to_s)
|
142
|
+
data[:name] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/Name").text
|
143
|
+
data[:path] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/Path").text
|
144
|
+
uxml=REXML::XPath.first(doc, prefix + "ItemValueDefinition/Unit")
|
145
|
+
data[:unit] = uxml ? uxml.text : nil
|
146
|
+
puxml=data[:perunit] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/PerUnit")
|
147
|
+
data[:perunit] = puxml ? puxml.text : nil
|
148
|
+
data[:valuetype] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/ValueDefinition/ValueType").text
|
149
|
+
data[:default] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/Value").text
|
150
|
+
data[:choices] = REXML::XPath.first(doc, prefix + "ItemValueDefinition/Choices").text.split(',') rescue nil
|
151
|
+
data[:versions] = REXML::XPath.each(doc, prefix + "ItemValueDefinition/APIVersions/APIVersion").map{|v| v.text}
|
152
|
+
drill=(REXML::XPath.first(doc, prefix + "ItemValueDefinition/DrillDown").text=='true')
|
153
|
+
profile=(REXML::XPath.first(doc, prefix + "ItemValueDefinition/FromProfile").text=='true')
|
154
|
+
ldata=(REXML::XPath.first(doc, prefix + "ItemValueDefinition/FromData").text=='true')
|
155
|
+
data=parsetype(data,drill,profile,ldata)
|
156
|
+
# Create object
|
157
|
+
ItemValueDefinition.new(data)
|
158
|
+
rescue
|
159
|
+
raise AMEE::BadData.new("Couldn't load ItemValueDefinition from XML. Check that your URL is correct.\n#{xml}")
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.get(connection, path, options = {})
|
163
|
+
# Load data from path
|
164
|
+
response = connection.get(path, options).body
|
165
|
+
# Parse response
|
166
|
+
item_definition = ItemValueDefinition.parse(connection, response, false)
|
167
|
+
# Done
|
168
|
+
return item_definition
|
169
|
+
rescue
|
170
|
+
raise AMEE::BadData.new("Couldn't load ItemValueDefinition. Check that your URL is correct.\n#{response}")
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
def self.load(connection,itemdefuid,ivduid,options={})
|
176
|
+
ItemValueDefinition.get(connection,"/definitions/itemDefinitions/#{itemdefuid}/itemValueDefinitions/#{ivduid}",options)
|
177
|
+
end
|
178
|
+
|
179
|
+
def reload(connection)
|
180
|
+
ItemValueDefinition.load(connection,itemdefuid,uid)
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.update(connection, path, options = {})
|
184
|
+
raise AMEE::NotSupported
|
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 ItemValueDefinition.get(connection, path)
|
193
|
+
# else
|
194
|
+
# return ItemValueDefinition.parse(connection, response.body)
|
195
|
+
# end
|
196
|
+
# end
|
197
|
+
# rescue
|
198
|
+
# raise AMEE::BadData.new("Couldn't update ItemValueDefinition. Check that your information is correct.\n#{response}")
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.create(connection,itemdefuid, options = {})
|
202
|
+
raise AMEE::NotSupported
|
203
|
+
# unless options.is_a?(Hash)
|
204
|
+
# raise AMEE::ArgumentError.new("Second argument must be a hash of options!")
|
205
|
+
# end
|
206
|
+
# # Send data
|
207
|
+
# response = connection.post("/definitions/itemDefinitions/#{itemdefuid}/itemValueDefintions", options).body
|
208
|
+
# # Parse response
|
209
|
+
# item_value_definition = ItemValueDefinition.parse(connection, response)
|
210
|
+
# # Get the ItemValueDefinition again
|
211
|
+
# return ItemValueDefinition.load(connection,itemdefuid , item_value_definition.uid)
|
212
|
+
# rescue
|
213
|
+
# raise AMEE::BadData.new("Couldn't create ItemValueDefinition. Check that your information is correct.\n#{response}")
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.delete(connection, itemdefuid,item_value_definition)
|
217
|
+
raise AMEE::NotSupported
|
218
|
+
# # Deleting takes a while... up the timeout to 120 seconds temporarily
|
219
|
+
# t = connection.timeout
|
220
|
+
# connection.timeout = 120
|
221
|
+
# connection.delete("/definitions/itemDefinitions/#{itemdefuid}/itemValueDefinitions/" + item_value_definition.uid)
|
222
|
+
# connection.timeout = t
|
223
|
+
# rescue
|
224
|
+
# raise AMEE::BadData.new("Couldn't delete ItemValueDefinition. Check that your information is correct.")
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
data/lib/amee/logger.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Log4r logger for AMEE rubgem
|
2
|
+
# by default, just log to stderr
|
3
|
+
# clients can change this thus
|
4
|
+
# AMEE::Log.to logtothis
|
5
|
+
|
6
|
+
module AMEE
|
7
|
+
module Logger
|
8
|
+
@@log=Log4r::Logger.new('AMEERuby')
|
9
|
+
@@log.outputters=[Log4r::StderrOutputter.new('AMEERubyStdout')]
|
10
|
+
@@log.level=Log4r::WARN
|
11
|
+
def self.log
|
12
|
+
@@log
|
13
|
+
end
|
14
|
+
def self.to(log)
|
15
|
+
@@log=log
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|