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