amee 2.4.0 → 2.5.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 +20 -5
- data/lib/amee.rb +1 -0
- data/lib/amee/collection.rb +5 -5
- data/lib/amee/connection.rb +64 -17
- data/lib/amee/data_item_value.rb +14 -9
- data/lib/amee/data_item_value_history.rb +3 -2
- data/lib/amee/drill_down.rb +15 -18
- data/lib/amee/item_definition.rb +4 -0
- data/lib/amee/item_value_definition.rb +4 -0
- data/lib/amee/object.rb +4 -0
- data/lib/amee/pager.rb +12 -11
- data/lib/amee/parse_helper.rb +10 -1
- data/lib/amee/profile.rb +24 -16
- data/lib/amee/profile_item.rb +18 -14
- data/lib/amee/rails.rb +7 -0
- data/lib/amee/user.rb +1 -5
- data/lib/amee/version.rb +1 -1
- metadata +21 -4
data/CHANGELOG
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 2.5.0
|
4
|
+
* Use ActiveSupport::Cache for caching
|
5
|
+
* Add ability to specify cache and debug options in amee.yml for Rails projects.
|
6
|
+
* Uses Nokogiri for some XML parsing for big speed improvements. More to come.
|
7
|
+
|
8
|
+
== 2.4.0
|
9
|
+
* Collection objects support filter blocks.
|
10
|
+
|
11
|
+
== 2.3.1
|
12
|
+
* Remove required environment UID in AMEE::Admin classes.
|
13
|
+
|
3
14
|
== 2.3.0
|
4
15
|
* Remove misleading ItemValueDefinition#type function. Use profile?, data? and
|
5
16
|
drill? separately instead.
|
data/README
CHANGED
@@ -15,6 +15,12 @@ Documentation: http://docs.github.com/Floppy/amee-ruby
|
|
15
15
|
1) Install gem
|
16
16
|
> sudo gem install amee
|
17
17
|
|
18
|
+
== REQUIREMENTS
|
19
|
+
|
20
|
+
'Nokogiri' is used for XML parsing, and requires libxml2. See
|
21
|
+
http://nokogiri.org/tutorials/installing_nokogiri.html for instructions if you
|
22
|
+
have problems installing.
|
23
|
+
|
18
24
|
== IMPORTANT CHANGES when upgrading to 2.2.0 and above
|
19
25
|
|
20
26
|
SSL connections are now supported, and are used BY DEFAULT.If you do not want to
|
@@ -86,11 +92,20 @@ AMEE when your model is saved.
|
|
86
92
|
|
87
93
|
== CACHING
|
88
94
|
|
89
|
-
The AMEE::Connection object implements an optional cache for GET requests.
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
95
|
+
The AMEE::Connection object implements an optional cache for GET requests.
|
96
|
+
|
97
|
+
This uses ActiveSupport::Cache, and supports any ActiveSupport::Cache::Store
|
98
|
+
caching method except for MemCacheStore (which doesn't provide required features).
|
99
|
+
|
100
|
+
All GET requests are cached. POST, PUT, or DELETEs will clear the cache for any
|
101
|
+
path that matches the affected URL. #expire, #expire_matching, and #expire_all
|
102
|
+
functions are available for manual cache management. Also, all AMEE objects have
|
103
|
+
and #expire-cache function to clear them and their descendants from the cache.
|
104
|
+
|
105
|
+
To enable caching, pass ':cache => :memory_store' to AMEE::Connection.new, or add
|
106
|
+
'cache: memory_store' to your amee.yml if using Rails. If you want to use the
|
107
|
+
same caching configuration as your Rails app, you can add 'cache: rails' to
|
108
|
+
amee.yml instead. Caching is disabled by default.
|
94
109
|
|
95
110
|
== UPGRADING TO VERSION > 2
|
96
111
|
|
data/lib/amee.rb
CHANGED
data/lib/amee/collection.rb
CHANGED
@@ -25,9 +25,9 @@ module AMEE
|
|
25
25
|
break if @max&&length>=@max
|
26
26
|
end
|
27
27
|
else
|
28
|
-
|
29
|
-
raise AMEE::BadData.new("Couldn't load #{self.class.name}
|
30
|
-
|
28
|
+
doc.xpath(xmlcollectorpath.split('/')[1...-1].join('/')).first or
|
29
|
+
raise AMEE::BadData.new("Couldn't load #{self.class.name}. parp\n#{response}")
|
30
|
+
doc.xpath(xmlcollectorpath).each do |p|
|
31
31
|
obj=klass.new(parse_xml(p))
|
32
32
|
obj.connection = connection
|
33
33
|
x= @filter ? @filter.call(obj) : obj
|
@@ -44,7 +44,7 @@ module AMEE
|
|
44
44
|
@json = true
|
45
45
|
@doc = JSON.parse(@response)
|
46
46
|
else
|
47
|
-
@doc =
|
47
|
+
@doc = load_xml_doc(@response)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -55,7 +55,7 @@ module AMEE
|
|
55
55
|
if json
|
56
56
|
@pager = AMEE::Pager.from_json(doc['pager'])
|
57
57
|
else
|
58
|
-
@pager = AMEE::Pager.from_xml(
|
58
|
+
@pager = AMEE::Pager.from_xml(doc.xpath('/Resources//Pager').first)
|
59
59
|
end
|
60
60
|
break if @max && length>=@max
|
61
61
|
end while @pager && @pager.next! #pager is nil if no pager in response,
|
data/lib/amee/connection.rb
CHANGED
@@ -21,9 +21,26 @@ module AMEE
|
|
21
21
|
if !valid?
|
22
22
|
raise "You must supply connection details - server, username and password are all required!"
|
23
23
|
end
|
24
|
-
|
25
|
-
if
|
26
|
-
|
24
|
+
# Handle old option
|
25
|
+
if options[:enable_caching]
|
26
|
+
Kernel.warn '[DEPRECATED] :enable_caching => true is deprecated. Use :cache => :memory_store instead'
|
27
|
+
options[:cache] ||= :memory_store
|
28
|
+
end
|
29
|
+
# Create cache store
|
30
|
+
if options[:cache] &&
|
31
|
+
(options[:cache_store].is_a?(ActiveSupport::Cache::MemCacheStore) ||
|
32
|
+
options[:cache].to_sym == :mem_cache_store)
|
33
|
+
raise 'ActiveSupport::Cache::MemCacheStore is not supported, as it doesn\'t allow regexp expiry'
|
34
|
+
end
|
35
|
+
if options[:cache_store].is_a?(ActiveSupport::Cache::Store)
|
36
|
+
# Allows assignment of the entire cache store in Rails apps
|
37
|
+
@cache = options[:cache_store]
|
38
|
+
elsif options[:cache]
|
39
|
+
if options[:cache_options]
|
40
|
+
@cache = ActiveSupport::Cache.lookup_store(options[:cache].to_sym, options[:cache_options])
|
41
|
+
else
|
42
|
+
@cache = ActiveSupport::Cache.lookup_store(options[:cache].to_sym)
|
43
|
+
end
|
27
44
|
end
|
28
45
|
# Make connection to server
|
29
46
|
@http = Net::HTTP.new(@server, @port)
|
@@ -77,18 +94,15 @@ module AMEE
|
|
77
94
|
if params.size > 0
|
78
95
|
path += "?#{params.join('&')}"
|
79
96
|
end
|
80
|
-
# Send request
|
81
|
-
|
82
|
-
response = do_request(Net::HTTP::Get.new(path), format)
|
83
|
-
$cache[path] = response if @enable_caching
|
84
|
-
return response
|
97
|
+
# Send request
|
98
|
+
cache(path) { do_request(Net::HTTP::Get.new(path), format) }
|
85
99
|
end
|
86
100
|
|
87
101
|
def post(path, data = {})
|
88
102
|
# Allow format override
|
89
103
|
format = data.delete(:format) || @format
|
90
104
|
# Clear cache
|
91
|
-
|
105
|
+
expire_matching "#{raw_path(path)}.*"
|
92
106
|
# Create POST request
|
93
107
|
post = Net::HTTP::Post.new(path)
|
94
108
|
body = []
|
@@ -104,7 +118,7 @@ module AMEE
|
|
104
118
|
# Allow format override
|
105
119
|
format = options.delete(:format) || @format
|
106
120
|
# Clear cache
|
107
|
-
|
121
|
+
expire_matching "#{raw_path(path)}.*"
|
108
122
|
# Create POST request
|
109
123
|
post = Net::HTTP::Post.new(path)
|
110
124
|
post['Content-type'] = options[:content_type] || content_type(format)
|
@@ -117,7 +131,7 @@ module AMEE
|
|
117
131
|
# Allow format override
|
118
132
|
format = data.delete(:format) || @format
|
119
133
|
# Clear cache
|
120
|
-
|
134
|
+
expire_matching "#{parent_path(path)}.*"
|
121
135
|
# Create PUT request
|
122
136
|
put = Net::HTTP::Put.new(path)
|
123
137
|
body = []
|
@@ -133,7 +147,7 @@ module AMEE
|
|
133
147
|
# Allow format override
|
134
148
|
format = options.delete(:format) || @format
|
135
149
|
# Clear cache
|
136
|
-
|
150
|
+
expire_matching "#{parent_path(path)}.*"
|
137
151
|
# Create PUT request
|
138
152
|
put = Net::HTTP::Put.new(path)
|
139
153
|
put['Content-type'] = options[:content_type] || content_type(format)
|
@@ -143,7 +157,7 @@ module AMEE
|
|
143
157
|
end
|
144
158
|
|
145
159
|
def delete(path)
|
146
|
-
|
160
|
+
expire_matching "#{parent_path(path)}.*"
|
147
161
|
# Create DELETE request
|
148
162
|
delete = Net::HTTP::Delete.new(path)
|
149
163
|
# Send request
|
@@ -242,12 +256,45 @@ module AMEE
|
|
242
256
|
response
|
243
257
|
end
|
244
258
|
|
259
|
+
def cache(path, &block)
|
260
|
+
key = cache_key(path)
|
261
|
+
if @cache && @cache.exist?(key)
|
262
|
+
puts "CACHE HIT on #{key}" if @debug
|
263
|
+
return @cache.read(key)
|
264
|
+
end
|
265
|
+
puts "CACHE MISS on #{key}" if @debug
|
266
|
+
data = block.call
|
267
|
+
@cache.write(key, data) if @cache
|
268
|
+
return data
|
269
|
+
end
|
270
|
+
|
271
|
+
def parent_path(path)
|
272
|
+
path.split('/')[0..-2].join('/')
|
273
|
+
end
|
274
|
+
|
275
|
+
def raw_path(path)
|
276
|
+
path.split(/[;?]/)[0]
|
277
|
+
end
|
278
|
+
|
279
|
+
def cache_key(path)
|
280
|
+
# We have to make sure cache keys don't get too long for the filesystem,
|
281
|
+
# so we cut them off if they're too long and add a digest for uniqueness.
|
282
|
+
newpath = (path.length < 255) ? path : path.first(192)+Digest::MD5.hexdigest(path)
|
283
|
+
(@server+newpath)
|
284
|
+
end
|
285
|
+
|
245
286
|
public
|
246
287
|
|
247
|
-
def
|
248
|
-
if @
|
249
|
-
|
250
|
-
|
288
|
+
def expire(path, options = nil)
|
289
|
+
@cache.delete(cache_key(path), options) if @cache
|
290
|
+
end
|
291
|
+
|
292
|
+
def expire_matching(matcher, options = nil)
|
293
|
+
@cache.delete_matched(Regexp.new(cache_key(matcher)), options) if @cache
|
294
|
+
end
|
295
|
+
|
296
|
+
def expire_all
|
297
|
+
@cache.clear if @cache
|
251
298
|
end
|
252
299
|
|
253
300
|
end
|
data/lib/amee/data_item_value.rb
CHANGED
@@ -69,24 +69,29 @@ module AMEE
|
|
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
|
+
def self.xmlpathpreamble
|
73
|
+
"descendant-or-self::ItemValue/"
|
74
|
+
end
|
75
|
+
|
72
76
|
def self.from_xml(xml, path)
|
73
77
|
# Read XML
|
74
|
-
doc = xml.is_a?(String) ?
|
78
|
+
@doc = xml.is_a?(String) ? load_xml_doc(xml) : xml
|
75
79
|
data = {}
|
76
|
-
if
|
80
|
+
if @doc.xpath("descendant-or-self::ItemValue").length>1
|
77
81
|
raise AMEE::BadData.new("Couldn't load DataItemValue from XML. This is an item value history.\n#{xml}")
|
78
82
|
end
|
83
|
+
raise if @doc.xpath("descendant-or-self::ItemValue").length==0
|
79
84
|
begin
|
80
|
-
data[:uid] =
|
81
|
-
data[:created] = DateTime.parse(
|
82
|
-
data[:modified] = DateTime.parse(
|
83
|
-
data[:name] =
|
85
|
+
data[:uid] = x "@uid"
|
86
|
+
data[:created] = DateTime.parse(x "@Created") rescue nil
|
87
|
+
data[:modified] = DateTime.parse(x "@Modified") rescue nil
|
88
|
+
data[:name] = x 'Name'
|
84
89
|
data[:path] = path.gsub(/^\/data/, '')
|
85
|
-
data[:value] =
|
86
|
-
data[:type] =
|
90
|
+
data[:value] = x 'Value'
|
91
|
+
data[:type] = x 'ItemValueDefinition/ValueDefinition/ValueType'
|
87
92
|
data[:from_profile] = false
|
88
93
|
data[:from_data] = true
|
89
|
-
data[:start_date] = DateTime.parse(
|
94
|
+
data[:start_date] = DateTime.parse(x "StartDate") rescue nil
|
90
95
|
# Create object
|
91
96
|
ItemValue.new(data)
|
92
97
|
rescue
|
@@ -3,6 +3,7 @@ require 'set'
|
|
3
3
|
module AMEE
|
4
4
|
module Data
|
5
5
|
class ItemValueHistory
|
6
|
+
extend ParseHelper
|
6
7
|
|
7
8
|
def initialize(data = {})
|
8
9
|
@type = data ? data[:type] : nil
|
@@ -84,8 +85,8 @@ module AMEE
|
|
84
85
|
# Read XML
|
85
86
|
data = {}
|
86
87
|
data[:path] = path.gsub(/^\/data/, '')
|
87
|
-
doc =
|
88
|
-
valuedocs=
|
88
|
+
doc = load_xml_doc(xml)
|
89
|
+
valuedocs=doc.xpath('//ItemValue')
|
89
90
|
raise if valuedocs.length==0
|
90
91
|
data[:values] = valuedocs.map do |xml_item_value|
|
91
92
|
ItemValue.from_xml(xml_item_value,path)
|
data/lib/amee/drill_down.rb
CHANGED
@@ -8,6 +8,7 @@ module AMEE
|
|
8
8
|
@choices = data ? data[:choices] : []
|
9
9
|
@choice_name = data[:choice_name]
|
10
10
|
@selections = data ? data[:selections] : []
|
11
|
+
raise AMEE::ArgumentError.new('No choice_name specified') if @choice_name.nil?
|
11
12
|
super
|
12
13
|
end
|
13
14
|
|
@@ -51,30 +52,26 @@ module AMEE
|
|
51
52
|
data[:selections] = selections
|
52
53
|
# Create object
|
53
54
|
DrillDown.new(data)
|
54
|
-
rescue
|
55
|
+
rescue Exception
|
55
56
|
raise AMEE::BadData.new("Couldn't load DrillDown resource from JSON data. Check that your URL is correct.\n#{json}")
|
56
57
|
end
|
57
|
-
|
58
|
+
|
59
|
+
def self.xmlpathpreamble
|
60
|
+
'/Resources/DrillDownResource/'
|
61
|
+
end
|
62
|
+
|
58
63
|
def self.from_xml(xml)
|
59
64
|
# Parse XML
|
60
|
-
doc =
|
65
|
+
@doc = load_xml_doc(xml)
|
61
66
|
data = {}
|
62
|
-
data[:choice_name] =
|
63
|
-
choices = []
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
data[:choices] = choices
|
68
|
-
selections = {}
|
69
|
-
REXML::XPath.each(doc, "/Resources/DrillDownResource/Selections/Choice") do |c|
|
70
|
-
name = (c.elements['Name'] || c.elements['name']).text
|
71
|
-
value = (c.elements['Value'] || c.elements['value']).text
|
72
|
-
selections[name] = value
|
73
|
-
end
|
74
|
-
data[:selections] = selections
|
67
|
+
data[:choice_name] = x('Choices/Name') || x('Choices/name')
|
68
|
+
data[:choices] = [x('Choices/Choices/Choice/Value') || x('Choices/Choice/value')].flatten
|
69
|
+
names = x('Selections/Choice/Name') || x('Selections/Choice/name')
|
70
|
+
values = x('Selections/Choice/Value') || x('Selections/Choice/value')
|
71
|
+
data[:selections] = names && values ? Hash[*(names.zip(values)).flatten] : {}
|
75
72
|
# Create object
|
76
73
|
DrillDown.new(data)
|
77
|
-
rescue
|
74
|
+
rescue Exception
|
78
75
|
raise AMEE::BadData.new("Couldn't load DrillDown resource from XML data. Check that your URL is correct.\n#{xml}")
|
79
76
|
end
|
80
77
|
|
@@ -93,7 +90,7 @@ module AMEE
|
|
93
90
|
drill.connection = connection
|
94
91
|
# Done
|
95
92
|
return drill
|
96
|
-
rescue
|
93
|
+
rescue Exception
|
97
94
|
raise AMEE::BadData.new("Couldn't load DrillDown resource. Check that your URL is correct (#{path}).\n#{response}")
|
98
95
|
end
|
99
96
|
|
data/lib/amee/item_definition.rb
CHANGED
@@ -229,6 +229,10 @@ module AMEE
|
|
229
229
|
# raise AMEE::BadData.new("Couldn't delete ItemValueDefinition. Check that your information is correct.")
|
230
230
|
end
|
231
231
|
|
232
|
+
def full_path
|
233
|
+
"/definitions/itemDefinitions/#{itemdefuid}/itemValueDefinitions/#{uid}"
|
234
|
+
end
|
235
|
+
|
232
236
|
end
|
233
237
|
|
234
238
|
end
|
data/lib/amee/object.rb
CHANGED
data/lib/amee/pager.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module AMEE
|
2
2
|
class Pager
|
3
|
+
extend ParseHelper
|
3
4
|
|
4
5
|
def initialize(data)
|
5
6
|
@start = data[:start]
|
@@ -29,17 +30,17 @@ module AMEE
|
|
29
30
|
|
30
31
|
def self.from_xml(node)
|
31
32
|
return nil if node.nil? || node.elements.empty?
|
32
|
-
return Pager.new({:start =>
|
33
|
-
:from =>
|
34
|
-
:to =>
|
35
|
-
:items =>
|
36
|
-
:current_page =>
|
37
|
-
:requested_page =>
|
38
|
-
:next_page =>
|
39
|
-
:previous_page =>
|
40
|
-
:last_page =>
|
41
|
-
:items_per_page =>
|
42
|
-
:items_found =>
|
33
|
+
return Pager.new({:start => x("Start", :doc => node).to_i,
|
34
|
+
:from => x("From", :doc => node).to_i,
|
35
|
+
:to => x("To", :doc => node).to_i,
|
36
|
+
:items => x("Items", :doc => node).to_i,
|
37
|
+
:current_page => x("CurrentPage", :doc => node).to_i,
|
38
|
+
:requested_page => x("RequestedPage", :doc => node).to_i,
|
39
|
+
:next_page => x("NextPage", :doc => node).to_i,
|
40
|
+
:previous_page => x("PreviousPage", :doc => node).to_i,
|
41
|
+
:last_page => x("LastPage", :doc => node).to_i,
|
42
|
+
:items_per_page => x("ItemsPerPage", :doc => node).to_i,
|
43
|
+
:items_found => x("ItemsFound", :doc => node).to_i})
|
43
44
|
end
|
44
45
|
|
45
46
|
def self.from_json(node)
|
data/lib/amee/parse_helper.rb
CHANGED
@@ -2,7 +2,11 @@ module ParseHelper
|
|
2
2
|
def x(xpath,options = {})
|
3
3
|
doc = options[:doc] || @doc
|
4
4
|
preamble = options[:meta] == true ? metaxmlpathpreamble : xmlpathpreamble
|
5
|
-
|
5
|
+
if doc.is_a?(Nokogiri::XML::Node)
|
6
|
+
nodes = doc.xpath("#{preamble}#{xpath}")
|
7
|
+
else
|
8
|
+
nodes=REXML::XPath.match(doc,"#{preamble}#{xpath}")
|
9
|
+
end
|
6
10
|
if nodes.length==1
|
7
11
|
if nodes.first.respond_to?(:text)
|
8
12
|
return nodes.first.text
|
@@ -24,6 +28,11 @@ module ParseHelper
|
|
24
28
|
def xmlpathpreamble
|
25
29
|
''
|
26
30
|
end
|
31
|
+
def load_xml_doc(xml)
|
32
|
+
doc = Nokogiri.XML(xml)
|
33
|
+
doc.remove_namespaces!
|
34
|
+
doc
|
35
|
+
end
|
27
36
|
private :x
|
28
37
|
|
29
38
|
end
|
data/lib/amee/profile.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module AMEE
|
2
2
|
module Profile
|
3
3
|
class ProfileList < Array
|
4
|
+
include ParseHelper
|
4
5
|
|
5
6
|
def initialize(connection, options = {})
|
6
7
|
# Load data from path
|
@@ -24,15 +25,17 @@ module AMEE
|
|
24
25
|
end
|
25
26
|
else
|
26
27
|
# Read XML
|
27
|
-
doc =
|
28
|
-
@pager = AMEE::Pager.from_xml(
|
29
|
-
|
28
|
+
@doc = load_xml_doc(response)
|
29
|
+
@pager = AMEE::Pager.from_xml(@doc.xpath('/Resources/ProfilesResource/Pager').first)
|
30
|
+
@doc.xpath('/Resources/ProfilesResource/Profiles/Profile').each do |p|
|
30
31
|
data = {}
|
31
|
-
data[:uid] =
|
32
|
-
data[:created] = DateTime.parse(p
|
33
|
-
data[:modified] = DateTime.parse(p
|
34
|
-
data[:name] =
|
35
|
-
data[:
|
32
|
+
data[:uid] = x '@uid', :doc => p
|
33
|
+
data[:created] = DateTime.parse(x "@created", :doc => p)
|
34
|
+
data[:modified] = DateTime.parse(x "@modified", :doc => p)
|
35
|
+
data[:name] = x('Name', :doc => p)
|
36
|
+
data[:name] = data[:uid] if data[:name].blank?
|
37
|
+
data[:path] = x('Path', :doc => p)
|
38
|
+
data[:path] = "/#{data[:uid]}" if data[:path].blank?
|
36
39
|
# Create profile
|
37
40
|
profile = Profile.new(data)
|
38
41
|
# Store connection in profile object
|
@@ -56,6 +59,10 @@ module AMEE
|
|
56
59
|
ProfileList.new(connection)
|
57
60
|
end
|
58
61
|
|
62
|
+
def self.xmlpathpreamble
|
63
|
+
'/Resources/ProfilesResource/Profile/'
|
64
|
+
end
|
65
|
+
|
59
66
|
def self.create(connection)
|
60
67
|
# Create new profile
|
61
68
|
response = connection.post('/profiles', :profile => true).body
|
@@ -69,21 +76,22 @@ module AMEE
|
|
69
76
|
data[:created] = DateTime.parse(p['created'])
|
70
77
|
data[:modified] = DateTime.parse(p['modified'])
|
71
78
|
data[:name] = p['name']
|
72
|
-
data[:path] = p['path']
|
79
|
+
data[:path] = "/#{p['path']}"
|
73
80
|
# Create profile
|
74
81
|
profile = Profile.new(data)
|
75
82
|
# Done
|
76
83
|
return profile
|
77
84
|
else
|
78
85
|
# Read XML
|
79
|
-
doc =
|
80
|
-
p = REXML::XPath.first(doc, '/Resources/ProfilesResource/Profile')
|
86
|
+
@doc = load_xml_doc(response)
|
81
87
|
data = {}
|
82
|
-
data[:uid] =
|
83
|
-
data[:created] = DateTime.parse(
|
84
|
-
data[:modified] = DateTime.parse(
|
85
|
-
data[:name] =
|
86
|
-
data[:
|
88
|
+
data[:uid] = x '@uid'
|
89
|
+
data[:created] = DateTime.parse(x '@created')
|
90
|
+
data[:modified] = DateTime.parse(x '@modified')
|
91
|
+
data[:name] = x 'Name'
|
92
|
+
data[:name] = data[:uid] if data[:name].blank?
|
93
|
+
data[:path] = x 'Path'
|
94
|
+
data[:path] = "/#{data[:uid]}" if data[:path].blank?
|
87
95
|
# Create profile
|
88
96
|
profile = Profile.new(data)
|
89
97
|
# Store connection in profile object
|
data/lib/amee/profile_item.rb
CHANGED
@@ -151,28 +151,32 @@ module AMEE
|
|
151
151
|
raise AMEE::BadData.new("Couldn't load ProfileItem from XML data. Check that your URL is correct.\n#{xml}")
|
152
152
|
end
|
153
153
|
|
154
|
+
def self.xmlpathpreamble
|
155
|
+
"/Resources/ProfileItemResource/"
|
156
|
+
end
|
157
|
+
|
154
158
|
def self.from_v2_xml(xml)
|
155
159
|
# Parse XML
|
156
|
-
doc =
|
160
|
+
@doc = load_xml_doc(xml)
|
157
161
|
data = {}
|
158
|
-
data[:profile_uid] =
|
159
|
-
data[:data_item_uid] =
|
160
|
-
data[:uid] =
|
161
|
-
data[:name] =
|
162
|
-
data[:path] =
|
163
|
-
data[:total_amount] =
|
164
|
-
data[:total_amount_unit] =
|
165
|
-
data[:start_date] = DateTime.parse(
|
166
|
-
data[:end_date] = DateTime.parse(
|
162
|
+
data[:profile_uid] = x 'Profile/@uid'
|
163
|
+
data[:data_item_uid] = x 'DataItem/@uid'
|
164
|
+
data[:uid] = x 'ProfileItem/@uid'
|
165
|
+
data[:name] = x 'ProfileItem/Name'
|
166
|
+
data[:path] = x('Path') || ""
|
167
|
+
data[:total_amount] = x('ProfileItem/Amount').to_f rescue nil
|
168
|
+
data[:total_amount_unit] = x 'ProfileItem/Amount/@unit' rescue nil
|
169
|
+
data[:start_date] = DateTime.parse(x 'ProfileItem/StartDate')
|
170
|
+
data[:end_date] = DateTime.parse(x 'ProfileItem/EndDate') rescue nil
|
167
171
|
data[:values] = []
|
168
|
-
|
172
|
+
@doc.xpath("#{xmlpathpreamble}ProfileItem/ItemValues/ItemValue").each do |item|
|
169
173
|
value_data = {}
|
170
174
|
item.elements.each do |element|
|
171
175
|
key = element.name
|
172
176
|
value = element.text
|
173
177
|
case key
|
174
178
|
when 'Name', 'Path', 'Value', 'Unit'
|
175
|
-
value_data[key.downcase.to_sym] = value
|
179
|
+
value_data[key.downcase.to_sym] = value.blank? ? nil : value
|
176
180
|
when 'PerUnit'
|
177
181
|
value_data[:per_unit] = value
|
178
182
|
end
|
@@ -180,7 +184,7 @@ module AMEE
|
|
180
184
|
value_data[:uid] = item.attributes['uid'].to_s
|
181
185
|
data[:values] << value_data
|
182
186
|
end
|
183
|
-
data[:amounts] =
|
187
|
+
data[:amounts] = @doc.xpath('/Resources/ProfileItemResource/ProfileItem/Amounts/Amount').map do |item|
|
184
188
|
x = {
|
185
189
|
:type => item.attribute('type').value,
|
186
190
|
:value => item.text.to_f,
|
@@ -190,7 +194,7 @@ module AMEE
|
|
190
194
|
x[:default] = (item.attribute('default').value == 'true') if item.attribute('default')
|
191
195
|
x
|
192
196
|
end
|
193
|
-
data[:notes] =
|
197
|
+
data[:notes] = @doc.xpath('/Resources/ProfileItemResource/ProfileItem/Amounts/Note').map do |item|
|
194
198
|
{
|
195
199
|
:type => item.attribute('type').value,
|
196
200
|
:value => item.text,
|
data/lib/amee/rails.rb
CHANGED
@@ -12,6 +12,13 @@ module AMEE
|
|
12
12
|
if $AMEE_CONFIG['ssl'] == false
|
13
13
|
options.merge! :ssl => false
|
14
14
|
end
|
15
|
+
if $AMEE_CONFIG['cache'] == 'rails'
|
16
|
+
# Pass in the rails cache store
|
17
|
+
options[:cache_store] = ActionController::Base.cache_store
|
18
|
+
else
|
19
|
+
options[:cache] ||= $AMEE_CONFIG['cache'] if $AMEE_CONFIG['cache'].present?
|
20
|
+
end
|
21
|
+
options[:enable_debug] ||= $AMEE_CONFIG['debug'] if $AMEE_CONFIG['debug'].present?
|
15
22
|
@connection = self.connect($AMEE_CONFIG['server'], $AMEE_CONFIG['username'], $AMEE_CONFIG['password'], options)
|
16
23
|
# Also store as $amee for backwards compatibility, though this is now deprecated
|
17
24
|
$amee = @connection
|
data/lib/amee/user.rb
CHANGED
@@ -15,7 +15,6 @@ module AMEE
|
|
15
15
|
@email = data[:email]
|
16
16
|
@status = data[:status]
|
17
17
|
@api_version = data[:api_version].to_f rescue nil
|
18
|
-
@environment_uid = data[:environment_uid]
|
19
18
|
super
|
20
19
|
end
|
21
20
|
|
@@ -36,7 +35,6 @@ module AMEE
|
|
36
35
|
# Read JSON
|
37
36
|
doc = JSON.parse(json)
|
38
37
|
data = {}
|
39
|
-
data[:environment_uid] = doc['user']['environment']['uid']
|
40
38
|
data[:uid] = doc['user']['uid']
|
41
39
|
data[:created] = DateTime.parse(doc['user']['created'])
|
42
40
|
data[:modified] = DateTime.parse(doc['user']['modified'])
|
@@ -55,7 +53,6 @@ module AMEE
|
|
55
53
|
# Parse data from response into hash
|
56
54
|
doc = REXML::Document.new(xml)
|
57
55
|
data = {}
|
58
|
-
data[:environment_uid] = REXML::XPath.first(doc, "//Environment/@uid").to_s
|
59
56
|
data[:uid] = REXML::XPath.first(doc, "//User/@uid").to_s
|
60
57
|
data[:created] = DateTime.parse(REXML::XPath.first(doc, "//User/@created").to_s)
|
61
58
|
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "//User/@modified").to_s)
|
@@ -104,8 +101,7 @@ module AMEE
|
|
104
101
|
end
|
105
102
|
|
106
103
|
def full_path
|
107
|
-
|
108
|
-
"#{prefix}/users/#{uid}"
|
104
|
+
"/admin/users/#{uid}"
|
109
105
|
end
|
110
106
|
|
111
107
|
end
|
data/lib/amee/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 0
|
10
|
-
version: 2.
|
10
|
+
version: 2.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- James Smith
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-03 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -76,6 +76,23 @@ dependencies:
|
|
76
76
|
version: "0"
|
77
77
|
type: :runtime
|
78
78
|
version_requirements: *id004
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: nokogiri
|
81
|
+
prerelease: false
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 113
|
88
|
+
segments:
|
89
|
+
- 1
|
90
|
+
- 4
|
91
|
+
- 3
|
92
|
+
- 1
|
93
|
+
version: 1.4.3.1
|
94
|
+
type: :runtime
|
95
|
+
version_requirements: *id005
|
79
96
|
description:
|
80
97
|
email: james@floppy.org.uk
|
81
98
|
executables:
|