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/CHANGELOG
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
= Changelog
|
2
|
+
|
3
|
+
== 2.2.0
|
4
|
+
|
5
|
+
* Add SSL support. SSL connections are now used by default.
|
6
|
+
* Log4r support
|
7
|
+
* Support for reading ItemValueDefinitions
|
8
|
+
* Include accessors from other objects
|
9
|
+
* Internal improvements including
|
10
|
+
* Improved paging support
|
11
|
+
* Tidier code for collections
|
data/README
CHANGED
@@ -12,13 +12,15 @@ Documentation: http://docs.github.com/Floppy/amee-ruby
|
|
12
12
|
|
13
13
|
== INSTALLATION
|
14
14
|
|
15
|
-
1)
|
16
|
-
> sudo gem install gemcutter
|
17
|
-
> sudo gem tumble
|
18
|
-
|
19
|
-
2) Install gem
|
15
|
+
1) Install gem
|
20
16
|
> sudo gem install amee
|
21
17
|
|
18
|
+
== IMPORTANT CHANGES when upgrading to 2.2.0 and above
|
19
|
+
|
20
|
+
SSL connections are now supported, and are used BY DEFAULT.If you do not want to
|
21
|
+
use SSL, you can disable it using the ":ssl => false" option to Connection.new, or
|
22
|
+
by adding "ssl: false" to your amee.yml if you are using Rails.
|
23
|
+
|
22
24
|
== IMPORTANT CHANGES when upgrading beyond 2.0.25
|
23
25
|
|
24
26
|
If you are using the $amee connection in your Rails apps, this is now deprecated
|
@@ -60,7 +62,7 @@ This gem can also be used as a Rails plugin. You can either extract it into
|
|
60
62
|
vendor/plugins, or use the new-style config.gem command in environment.rb. For
|
61
63
|
example:
|
62
64
|
|
63
|
-
config.gem "amee", :version => '
|
65
|
+
config.gem "amee", :version => '~> 2.2.0'
|
64
66
|
|
65
67
|
If you copy amee.example.yml from the gem source directory to amee.yml in your
|
66
68
|
app's config directory, a persistent AMEE connection will be available from
|
data/amee.example.yml
CHANGED
@@ -2,11 +2,14 @@ development:
|
|
2
2
|
server: stage.amee.com
|
3
3
|
username: your_amee_username
|
4
4
|
password: your_amee_password
|
5
|
+
#ssl: false # Uncomment if you don't want to use SSL
|
5
6
|
test:
|
6
7
|
server: stage.amee.com
|
7
8
|
username: your_amee_username
|
8
9
|
password: your_amee_password
|
10
|
+
#ssl: false # Uncomment if you don't want to use SSL
|
9
11
|
production:
|
10
12
|
server: live.amee.com
|
11
13
|
username: your_amee_username
|
12
14
|
password: your_amee_password
|
15
|
+
#ssl: false # Uncomment if you don't want to use SSL
|
data/cacert.pem
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUF
|
3
|
+
ADCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
|
4
|
+
IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw
|
5
|
+
HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVU
|
6
|
+
Ti1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5
|
7
|
+
MTgxOTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQH
|
8
|
+
Ew5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3
|
9
|
+
b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNV
|
10
|
+
BAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3DQEBAQUA
|
11
|
+
A4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZ
|
12
|
+
FvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6N
|
13
|
+
q9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEH
|
14
|
+
OG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNdoI6yqqr2jmmI
|
15
|
+
BsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjfPe58
|
16
|
+
BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhb
|
17
|
+
AgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
|
18
|
+
VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWG
|
19
|
+
M2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3
|
20
|
+
YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
|
21
|
+
BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0o
|
22
|
+
XnWO6y1n7k57K9cM//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjA
|
23
|
+
bPLPSbtNk28GpgoiskliCE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59
|
24
|
+
Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4f
|
25
|
+
Fm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchq
|
26
|
+
J/kniCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0q
|
27
|
+
UZ6B+dQ7XnASfxAynB67nfhmqA==
|
28
|
+
-----END CERTIFICATE-----
|
29
|
+
-----BEGIN CERTIFICATE-----
|
30
|
+
MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJV
|
31
|
+
UzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1
|
32
|
+
aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0
|
33
|
+
MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoT
|
34
|
+
E0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJl
|
35
|
+
IEdsb2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
|
36
|
+
gYkCgYEAuucXkAJlsTRVPEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQy
|
37
|
+
td4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORR
|
38
|
+
OhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxnhcXIw2EC
|
39
|
+
AwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8w
|
40
|
+
HwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6o
|
41
|
+
oHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf
|
42
|
+
2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkAZ70Br83gcfxa
|
43
|
+
z2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIYNMR1
|
44
|
+
pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
|
45
|
+
-----END CERTIFICATE-----
|
data/lib/amee.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rexml/document'
|
2
2
|
require 'active_support'
|
3
|
+
require 'log4r'
|
3
4
|
|
4
5
|
# We don't NEED the JSON gem, but if it's available, use it.
|
5
6
|
begin
|
@@ -26,9 +27,12 @@ class String
|
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
30
|
+
require 'amee/logger'
|
29
31
|
require 'amee/version'
|
30
32
|
require 'amee/exceptions'
|
31
33
|
require 'amee/connection'
|
34
|
+
require 'amee/parse_helper'
|
35
|
+
require 'amee/collection'
|
32
36
|
require 'amee/object'
|
33
37
|
require 'amee/data_object'
|
34
38
|
require 'amee/profile_object'
|
@@ -43,6 +47,7 @@ require 'amee/profile_item_value'
|
|
43
47
|
require 'amee/drill_down'
|
44
48
|
require 'amee/pager'
|
45
49
|
require 'amee/item_definition'
|
50
|
+
require 'amee/item_value_definition'
|
46
51
|
require 'amee/user'
|
47
52
|
|
48
53
|
class Date
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module AMEE
|
2
|
+
class Collection < Array
|
3
|
+
include ParseHelper
|
4
|
+
attr_reader :pager,:connection,:doc,:json,:response
|
5
|
+
def initialize(connection, options = {})
|
6
|
+
# Load data from path
|
7
|
+
@options=options
|
8
|
+
@max=options.delete :resultMax
|
9
|
+
@connection=connection
|
10
|
+
# Parse data from response
|
11
|
+
each_page do
|
12
|
+
parse_page
|
13
|
+
end
|
14
|
+
rescue => err
|
15
|
+
#raise AMEE::BadData.new("Couldn't load #{self.class.name}.\n#{response} due to #{err}")
|
16
|
+
raise AMEE::BadData.new("Couldn't load #{self.class.name}.\n#{response}")
|
17
|
+
end
|
18
|
+
def parse_page
|
19
|
+
if json
|
20
|
+
jsoncollector.each do |p|
|
21
|
+
obj = klass.new(parse_json(p))
|
22
|
+
obj.connection = connection
|
23
|
+
self << obj
|
24
|
+
break if @max&&length>=@max
|
25
|
+
end
|
26
|
+
else
|
27
|
+
REXML::XPath.first(doc,xmlcollectorpath.split('/')[1...-1].join('/')) or
|
28
|
+
raise AMEE::BadData.new("Couldn't load #{self.class.name}.\n#{response}")
|
29
|
+
REXML::XPath.each(doc, xmlcollectorpath) do |p|
|
30
|
+
obj=klass.new(parse_xml(p))
|
31
|
+
obj.connection = connection
|
32
|
+
self << obj
|
33
|
+
break if @max&&length>=@max
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch
|
39
|
+
@options.merge! @pager.options if @pager
|
40
|
+
@response= @connection.get(collectionpath, @options).body
|
41
|
+
if @response.is_json?
|
42
|
+
@json = true
|
43
|
+
@doc = JSON.parse(@response)
|
44
|
+
else
|
45
|
+
@doc = REXML::Document.new(@response)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_page
|
50
|
+
begin
|
51
|
+
fetch
|
52
|
+
yield
|
53
|
+
if json
|
54
|
+
@pager = AMEE::Pager.from_json(doc['pager'])
|
55
|
+
else
|
56
|
+
@pager = AMEE::Pager.from_xml(REXML::XPath.first(doc, '/Resources//Pager'))
|
57
|
+
end
|
58
|
+
break if @max && length>=@max
|
59
|
+
end while @pager && @pager.next! #pager is nil if no pager in response,
|
60
|
+
# pager.next! is false if @pager said current=last.
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
data/lib/amee/connection.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'net/http'
|
2
|
+
require 'net/https'
|
2
3
|
|
3
4
|
module AMEE
|
4
5
|
class Connection
|
5
6
|
|
7
|
+
RootCA = File.dirname(__FILE__) + '/../../cacert.pem'
|
8
|
+
|
6
9
|
def initialize(server, username, password, options = {})
|
7
10
|
unless options.is_a?(Hash)
|
8
11
|
raise AMEE::ArgumentError.new("Fourth argument must be a hash of options!")
|
@@ -10,8 +13,11 @@ module AMEE
|
|
10
13
|
@server = server
|
11
14
|
@username = username
|
12
15
|
@password = password
|
16
|
+
@ssl = (options[:ssl] == false) ? false : true
|
17
|
+
@port = @ssl ? 443 : 80
|
13
18
|
@auth_token = nil
|
14
19
|
@format = options[:format] || (defined?(JSON) ? :json : :xml)
|
20
|
+
@amee_source = options[:amee_source]
|
15
21
|
if !valid?
|
16
22
|
raise "You must supply connection details - server, username and password are all required!"
|
17
23
|
end
|
@@ -20,20 +26,29 @@ module AMEE
|
|
20
26
|
$cache ||= {}
|
21
27
|
end
|
22
28
|
# Make connection to server
|
23
|
-
@http = Net::HTTP.new(@server)
|
29
|
+
@http = Net::HTTP.new(@server, @port)
|
30
|
+
if @ssl == true
|
31
|
+
@http.use_ssl = true
|
32
|
+
if File.exists? RootCA
|
33
|
+
@http.ca_file = RootCA
|
34
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
35
|
+
@http.verify_depth = 5
|
36
|
+
end
|
37
|
+
end
|
24
38
|
@http.read_timeout = 60
|
25
39
|
@http.set_debug_output($stdout) if options[:enable_debug]
|
40
|
+
@debug = options[:enable_debug]
|
26
41
|
end
|
27
42
|
|
28
43
|
attr_reader :format
|
29
44
|
attr_reader :server
|
30
45
|
attr_reader :username
|
31
46
|
attr_reader :password
|
32
|
-
|
47
|
+
|
33
48
|
def timeout
|
34
49
|
@http.read_timeout
|
35
50
|
end
|
36
|
-
|
51
|
+
|
37
52
|
def timeout=(t)
|
38
53
|
@http.read_timeout = t
|
39
54
|
end
|
@@ -46,7 +61,7 @@ module AMEE
|
|
46
61
|
def valid?
|
47
62
|
@username && @password && @server
|
48
63
|
end
|
49
|
-
|
64
|
+
|
50
65
|
def authenticated?
|
51
66
|
!@auth_token.nil?
|
52
67
|
end
|
@@ -68,7 +83,7 @@ module AMEE
|
|
68
83
|
$cache[path] = response if @enable_caching
|
69
84
|
return response
|
70
85
|
end
|
71
|
-
|
86
|
+
|
72
87
|
def post(path, data = {})
|
73
88
|
# Allow format override
|
74
89
|
format = data.delete(:format) || @format
|
@@ -140,6 +155,7 @@ module AMEE
|
|
140
155
|
post = Net::HTTP::Post.new("/auth/signIn")
|
141
156
|
post.body = "username=#{@username}&password=#{@password}"
|
142
157
|
post['Accept'] = content_type(:xml)
|
158
|
+
post['X-AMEE-Source'] = @amee_source if @amee_source
|
143
159
|
response = @http.request(post)
|
144
160
|
@auth_token = response['authToken']
|
145
161
|
unless authenticated?
|
@@ -167,7 +183,7 @@ module AMEE
|
|
167
183
|
return 'application/atom+xml'
|
168
184
|
end
|
169
185
|
end
|
170
|
-
|
186
|
+
|
171
187
|
def redirect?(response)
|
172
188
|
response.code == '301' || response.code == '302'
|
173
189
|
end
|
@@ -176,6 +192,8 @@ module AMEE
|
|
176
192
|
case response.code
|
177
193
|
when '200', '201'
|
178
194
|
return true
|
195
|
+
when '404'
|
196
|
+
raise AMEE::NotFound.new("The URL was not found on the server.\nRequest: #{request.method} #{request.path}")
|
179
197
|
when '403'
|
180
198
|
raise AMEE::PermissionDenied.new("You do not have permission to perform the requested operation.\nRequest: #{request.method} #{request.path}\n#{request.body}\Response: #{response.body}")
|
181
199
|
when '401'
|
@@ -197,6 +215,7 @@ module AMEE
|
|
197
215
|
@http.start
|
198
216
|
# Do request
|
199
217
|
begin
|
218
|
+
Logger.log.debug("Requesting #{request.class} at #{request.path} with #{request.body} in format #{format}")
|
200
219
|
response = send_request(request, format)
|
201
220
|
end while !response_ok?(response, request)
|
202
221
|
# Return response
|
@@ -207,19 +226,17 @@ module AMEE
|
|
207
226
|
# Close HTTP connection
|
208
227
|
@http.finish if @http.started?
|
209
228
|
end
|
210
|
-
|
229
|
+
|
211
230
|
def send_request(request, format = @format)
|
212
231
|
# Set auth token in cookie (and header just in case someone's stripping cookies)
|
213
232
|
request['Cookie'] = "authToken=#{@auth_token}"
|
214
233
|
request['authToken'] = @auth_token
|
215
234
|
# Set accept header
|
216
235
|
request['Accept'] = content_type(format)
|
236
|
+
# Set AMEE source header if set
|
237
|
+
request['X-AMEE-Source'] = @amee_source if @amee_source
|
217
238
|
# Do the business
|
218
239
|
response = @http.request(request)
|
219
|
-
# Handle 404s
|
220
|
-
if response.code == '404'
|
221
|
-
raise AMEE::NotFound.new("URL doesn't exist on server.")
|
222
|
-
end
|
223
240
|
# Done
|
224
241
|
response
|
225
242
|
end
|
data/lib/amee/data_category.rb
CHANGED
@@ -17,6 +17,11 @@ module AMEE
|
|
17
17
|
attr_reader :pager
|
18
18
|
attr_reader :itemdef
|
19
19
|
|
20
|
+
def item_definition
|
21
|
+
return nil unless itemdef
|
22
|
+
@item_definition ||= AMEE::Admin::ItemDefinition.load(connection,itemdef)
|
23
|
+
end
|
24
|
+
|
20
25
|
def self.from_json(json)
|
21
26
|
# Parse json
|
22
27
|
doc = JSON.parse(json)
|
@@ -52,12 +57,15 @@ module AMEE
|
|
52
57
|
rescue
|
53
58
|
raise AMEE::BadData.new("Couldn't load DataCategory from JSON data. Check that your URL is correct.\n#{json}")
|
54
59
|
end
|
55
|
-
|
60
|
+
|
61
|
+
def self.xmlpathpreamble
|
62
|
+
"/Resources/DataCategoryResource/DataCategory/"
|
63
|
+
end
|
56
64
|
def self.from_xml(xml)
|
57
65
|
# Parse XML
|
58
|
-
doc = REXML::Document.new(xml)
|
66
|
+
@doc = doc= REXML::Document.new(xml)
|
59
67
|
data = {}
|
60
|
-
data[:uid] =
|
68
|
+
data[:uid] = x '@uid'
|
61
69
|
data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@created").to_s)
|
62
70
|
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@modified").to_s)
|
63
71
|
data[:name] = REXML::XPath.first(doc, '/Resources/DataCategoryResource/DataCategory/?ame').text
|
@@ -90,7 +98,7 @@ module AMEE
|
|
90
98
|
rescue
|
91
99
|
raise AMEE::BadData.new("Couldn't load DataCategory from XML data. Check that your URL is correct.\n#{xml}")
|
92
100
|
end
|
93
|
-
|
101
|
+
|
94
102
|
def self.get(connection, path, orig_options = {})
|
95
103
|
unless orig_options.is_a?(Hash)
|
96
104
|
raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
|
@@ -119,11 +127,11 @@ module AMEE
|
|
119
127
|
rescue
|
120
128
|
raise AMEE::BadData.new("Couldn't load DataCategory. Check that your URL is correct.\n#{response}")
|
121
129
|
end
|
122
|
-
|
130
|
+
|
123
131
|
def self.root(connection)
|
124
132
|
self.get(connection, '/data')
|
125
133
|
end
|
126
|
-
|
134
|
+
|
127
135
|
def child(child_path)
|
128
136
|
AMEE::Data::Category.get(connection, "#{full_path}/#{child_path}")
|
129
137
|
end
|
@@ -148,7 +156,7 @@ module AMEE
|
|
148
156
|
|
149
157
|
connection = category.connection
|
150
158
|
path = category.full_path
|
151
|
-
|
159
|
+
|
152
160
|
# Do we want to automatically fetch the item afterwards?
|
153
161
|
get_item = options.delete(:get_item)
|
154
162
|
|
@@ -162,7 +170,7 @@ module AMEE
|
|
162
170
|
options[:newObjectType] = "DC"
|
163
171
|
response = connection.post(path, options)
|
164
172
|
if response['Location']
|
165
|
-
location = response['Location'].match("
|
173
|
+
location = response['Location'].match("https??://.*?(/.*)")[1]
|
166
174
|
else
|
167
175
|
category = Category.parse(connection, response.body)
|
168
176
|
location = category.full_path
|
@@ -200,7 +208,7 @@ module AMEE
|
|
200
208
|
rescue
|
201
209
|
raise AMEE::BadData.new("Couldn't update Data Category. Check that your information is correct.")
|
202
210
|
end
|
203
|
-
|
211
|
+
|
204
212
|
end
|
205
213
|
end
|
206
214
|
end
|
data/lib/amee/data_item.rb
CHANGED
@@ -8,21 +8,29 @@ module AMEE
|
|
8
8
|
@values = data[:values]
|
9
9
|
@choices = data[:choices]
|
10
10
|
@label = data[:label]
|
11
|
-
@
|
11
|
+
@item_definition_uid = data[:item_definition]
|
12
12
|
@total_amount = data[:total_amount]
|
13
13
|
@total_amount_unit = data[:total_amount_unit]
|
14
14
|
@start_date = data[:start_date]
|
15
|
+
@category_uid = data[:category_uid]
|
15
16
|
super
|
16
17
|
end
|
17
18
|
|
18
19
|
attr_reader :values
|
19
20
|
attr_reader :choices
|
20
21
|
attr_reader :label
|
21
|
-
attr_reader :item_definition
|
22
22
|
attr_reader :total_amount
|
23
23
|
attr_reader :total_amount_unit
|
24
24
|
attr_reader :start_date
|
25
|
-
|
25
|
+
attr_reader :category_uid
|
26
|
+
attr_reader :item_definition_uid
|
27
|
+
|
28
|
+
def item_definition
|
29
|
+
return nil unless item_definition_uid
|
30
|
+
@item_definition ||= AMEE::Admin::ItemDefinition.load(connection,item_definition_uid)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
26
34
|
def self.from_json(json)
|
27
35
|
# Read JSON
|
28
36
|
doc = JSON.parse(json)
|
@@ -34,6 +42,7 @@ module AMEE
|
|
34
42
|
data[:path] = doc['path']
|
35
43
|
data[:label] = doc['dataItem']['label']
|
36
44
|
data[:item_definition] = doc['dataItem']['itemDefinition']['uid']
|
45
|
+
data[:category_uid] = doc['dataItem']['dataCategory']['uid']
|
37
46
|
# Read v2 total
|
38
47
|
data[:total_amount] = doc['amount']['value'] rescue nil
|
39
48
|
data[:total_amount_unit] = doc['amount']['unit'] rescue nil
|
@@ -67,7 +76,7 @@ module AMEE
|
|
67
76
|
rescue
|
68
77
|
raise AMEE::BadData.new("Couldn't load DataItem from JSON. Check that your URL is correct.\n#{json}")
|
69
78
|
end
|
70
|
-
|
79
|
+
|
71
80
|
def self.from_xml(xml)
|
72
81
|
# Parse data from response into hash
|
73
82
|
doc = REXML::Document.new(xml)
|
@@ -79,6 +88,7 @@ module AMEE
|
|
79
88
|
data[:path] = (REXML::XPath.first(doc, '/Resources/DataItemResource/Path') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/path')).text
|
80
89
|
data[:label] = (REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Label') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/label')).text
|
81
90
|
data[:item_definition] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/ItemDefinition/@uid').to_s
|
91
|
+
data[:category_uid] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/DataCategory/@uid').to_s
|
82
92
|
# Read v2 total
|
83
93
|
data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount').text.to_f rescue nil
|
84
94
|
data[:total_amount_unit] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount/@unit').to_s rescue nil
|
@@ -113,7 +123,7 @@ module AMEE
|
|
113
123
|
raise AMEE::BadData.new("Couldn't load DataItem from XML. Check that your URL is correct.\n#{xml}")
|
114
124
|
end
|
115
125
|
|
116
|
-
|
126
|
+
|
117
127
|
def self.get(connection, path, options = {})
|
118
128
|
# Load data from path
|
119
129
|
response = connection.get(path, options).body
|
@@ -171,7 +181,7 @@ module AMEE
|
|
171
181
|
# Send data to path
|
172
182
|
response = connection.post(path, options)
|
173
183
|
if response['Location']
|
174
|
-
location = response['Location'].match("
|
184
|
+
location = response['Location'].match("https??://.*?(/.*)")[1]
|
175
185
|
else
|
176
186
|
category = Category.parse(connection, response.body)
|
177
187
|
location = category.full_path + "/" + category.items[0][:path]
|
@@ -203,7 +213,7 @@ module AMEE
|
|
203
213
|
rescue
|
204
214
|
raise AMEE::BadData.new("Couldn't update DataItem. Check that your information is correct.\n#{response}")
|
205
215
|
end
|
206
|
-
|
216
|
+
|
207
217
|
def update(options = {})
|
208
218
|
AMEE::Data::Item.update(connection, full_path, options)
|
209
219
|
end
|
@@ -213,7 +223,7 @@ module AMEE
|
|
213
223
|
rescue
|
214
224
|
raise AMEE::BadData.new("Couldn't delete DataItem. Check that your information is correct.")
|
215
225
|
end
|
216
|
-
|
226
|
+
|
217
227
|
def value(name_or_path_or_uid)
|
218
228
|
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}
|
219
229
|
val ? val[:value] : nil
|