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.
@@ -0,0 +1,11 @@
1
+ module AMEE
2
+ module Data
3
+ class Object < AMEE::Object
4
+
5
+ def full_path
6
+ "/data#{@path}"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,102 @@
1
+ require 'cgi'
2
+
3
+ module AMEE
4
+ module Data
5
+ class DrillDown < AMEE::Data::Object
6
+
7
+ def initialize(data = {})
8
+ @choices = data ? data[:choices] : []
9
+ @choice_name = data[:choice_name]
10
+ @selections = data ? data[:selections] : []
11
+ super
12
+ end
13
+
14
+ attr_reader :choices
15
+ attr_reader :choice_name
16
+ attr_reader :selections
17
+
18
+ def path=(path)
19
+ @path = path
20
+ end
21
+
22
+ def data_item_uid
23
+ return nil if @choice_name != 'uid' || @choices.size != 1
24
+ @choices[0]
25
+ end
26
+
27
+ def choose(choice)
28
+ options = []
29
+ @selections.each_pair do |key, value|
30
+ options << "#{CGI::escape(key)}=#{CGI::escape(value)}"
31
+ end
32
+ options << "#{CGI::escape(@choice_name)}=#{CGI::escape(choice)}"
33
+ query_string = options.join "&"
34
+ DrillDown.get(connection, "#{full_path}?#{query_string}")
35
+ end
36
+
37
+ def self.from_json(json)
38
+ # Parse json
39
+ doc = JSON.parse(json)
40
+ data = {}
41
+ data[:choice_name] = doc['choices']['name']
42
+ choices = []
43
+ doc['choices']['choices'].each do |c|
44
+ choices << c['value']
45
+ end
46
+ data[:choices] = choices
47
+ selections = {}
48
+ doc['selections'].each do |c|
49
+ selections[c['name']] = c['value']
50
+ end
51
+ data[:selections] = selections
52
+ # Create object
53
+ DrillDown.new(data)
54
+ rescue
55
+ raise AMEE::BadData.new("Couldn't load DrillDown resource from JSON data. Check that your URL is correct.\n#{json}")
56
+ end
57
+
58
+ def self.from_xml(xml)
59
+ # Parse XML
60
+ doc = REXML::Document.new(xml)
61
+ data = {}
62
+ data[:choice_name] = REXML::XPath.first(doc, "/Resources/DrillDownResource/Choices/?ame").text
63
+ choices = []
64
+ REXML::XPath.each(doc, "/Resources/DrillDownResource/Choices//Choice") do |c|
65
+ choices << (c.elements['Value'] || c.elements['value']).text
66
+ end
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
75
+ # Create object
76
+ DrillDown.new(data)
77
+ rescue
78
+ raise AMEE::BadData.new("Couldn't load DrillDown resource from XML data. Check that your URL is correct.\n#{xml}")
79
+ end
80
+
81
+ def self.get(connection, path)
82
+ # Load data from path
83
+ response = connection.get(path).body
84
+ # Parse data from response
85
+ if response.is_json?
86
+ drill = DrillDown.from_json(response)
87
+ else
88
+ drill = DrillDown.from_xml(response)
89
+ end
90
+ # Store path in drill object - response does not include it
91
+ drill.path = path.split('?')[0].gsub(/^\/data/, '')
92
+ # Store connection in object for future use
93
+ drill.connection = connection
94
+ # Done
95
+ return drill
96
+ rescue
97
+ raise AMEE::BadData.new("Couldn't load DrillDown resource. Check that your URL is correct (#{path}).\n#{response}")
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,27 @@
1
+ module AMEE
2
+
3
+ class ArgumentError < Exception
4
+ end
5
+
6
+ class BadData < Exception
7
+ end
8
+
9
+ class AuthFailed < Exception
10
+ end
11
+
12
+ class PermissionDenied < Exception
13
+ end
14
+
15
+ class ConnectionFailed < Exception
16
+ end
17
+
18
+ class NotFound < Exception
19
+ end
20
+
21
+ class DuplicateResource < Exception
22
+ end
23
+
24
+ class UnknownError < Exception
25
+ end
26
+
27
+ end
@@ -0,0 +1,158 @@
1
+ module AMEE
2
+ module Admin
3
+
4
+ class ItemDefinitionList < Array
5
+
6
+ def initialize(connection, options = {})
7
+ # Load data from path
8
+ response = connection.get('/definitions/itemDefinitions', options).body
9
+ # Parse data from response
10
+ if response.is_json?
11
+ # Read JSON
12
+ doc = JSON.parse(response)
13
+ @pager = AMEE::Pager.from_json(doc['pager'])
14
+ doc['itemDefinitions'].each do |p|
15
+ data = {}
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}")
41
+ end
42
+
43
+ attr_reader :pager
44
+
45
+ end
46
+
47
+ class ItemDefinition < AMEE::Object
48
+
49
+ def initialize(data = {})
50
+ @name = data[:name]
51
+ super
52
+ end
53
+
54
+ attr_reader :name
55
+
56
+ def self.list(connection)
57
+ ItemDefinitionList.new(connection)
58
+ end
59
+
60
+ def self.parse(connection, response, is_list = true)
61
+ # Parse data from response
62
+ if response.is_json?
63
+ item_definition = ItemDefinition.from_json(response)
64
+ else
65
+ item_definition = ItemDefinition.from_xml(response, is_list)
66
+ end
67
+ # Store connection in object for future use
68
+ item_definition.connection = connection
69
+ # Done
70
+ return item_definition
71
+ end
72
+
73
+ def self.from_json(json)
74
+ # Read JSON
75
+ doc = JSON.parse(json)
76
+ data = {}
77
+ data[:uid] = doc['itemDefinition']['uid']
78
+ data[:created] = DateTime.parse(doc['itemDefinition']['created'])
79
+ data[:modified] = DateTime.parse(doc['itemDefinition']['modified'])
80
+ data[:name] = doc['itemDefinition']['name']
81
+ # Create object
82
+ ItemDefinition.new(data)
83
+ rescue
84
+ raise AMEE::BadData.new("Couldn't load ItemDefinition from JSON. Check that your URL is correct.\n#{json}")
85
+ end
86
+
87
+ def self.from_xml(xml, is_list = true)
88
+ prefix = is_list ? "/Resources/ItemDefinitionsResource/" : "/Resources/ItemDefinitionResource/"
89
+ # Parse data from response into hash
90
+ doc = REXML::Document.new(xml)
91
+ data = {}
92
+ data[:uid] = REXML::XPath.first(doc, prefix + "ItemDefinition/@uid").to_s
93
+ data[:created] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemDefinition/@created").to_s)
94
+ data[:modified] = DateTime.parse(REXML::XPath.first(doc, prefix + "ItemDefinition/@modified").to_s)
95
+ data[:name] = REXML::XPath.first(doc, prefix + "ItemDefinition/Name").text
96
+ # Create object
97
+ ItemDefinition.new(data)
98
+ rescue
99
+ raise AMEE::BadData.new("Couldn't load ItemDefinition from XML. Check that your URL is correct.\n#{xml}")
100
+ end
101
+
102
+ def self.get(connection, path, options = {})
103
+ # Load data from path
104
+ response = connection.get(path, options).body
105
+ # Parse response
106
+ item_definition = ItemDefinition.parse(connection, response, false)
107
+ # Done
108
+ return item_definition
109
+ rescue
110
+ raise AMEE::BadData.new("Couldn't load ItemDefinition. Check that your URL is correct.\n#{response}")
111
+ end
112
+
113
+ def self.update(connection, path, options = {})
114
+ # Do we want to automatically fetch the item afterwards?
115
+ get_item = options.delete(:get_item)
116
+ get_item = true if get_item.nil?
117
+ # Go
118
+ response = connection.put(path, options)
119
+ if get_item
120
+ if response.body.empty?
121
+ return ItemDefinition.get(connection, path)
122
+ else
123
+ return ItemDefinition.parse(connection, response.body)
124
+ end
125
+ end
126
+ rescue
127
+ raise AMEE::BadData.new("Couldn't update ItemDefinition. Check that your information is correct.\n#{response}")
128
+ end
129
+
130
+ def self.create(connection, options = {})
131
+ unless options.is_a?(Hash)
132
+ raise AMEE::ArgumentError.new("Second argument must be a hash of options!")
133
+ end
134
+ # Send data
135
+ response = connection.post("/definitions/itemDefinitions", options).body
136
+ # Parse response
137
+ item_definition = ItemDefinition.parse(connection, response)
138
+ # Get the ItemDefinition again
139
+ return ItemDefinition.get(connection, "/definitions/itemDefinitions/" + item_definition.uid)
140
+ rescue
141
+ raise AMEE::BadData.new("Couldn't create ItemDefinition. Check that your information is correct.\n#{response}")
142
+ end
143
+
144
+ def self.delete(connection, item_definition)
145
+ # Deleting takes a while... up the timeout to 120 seconds temporarily
146
+ t = connection.timeout
147
+ connection.timeout = 120
148
+ connection.delete("/definitions/itemDefinitions/" + item_definition.uid)
149
+ connection.timeout = t
150
+ rescue
151
+ raise AMEE::BadData.new("Couldn't delete ProfileItem. Check that your information is correct.")
152
+ end
153
+
154
+ end
155
+
156
+ end
157
+
158
+ end
@@ -0,0 +1,21 @@
1
+ module AMEE
2
+ class Object
3
+
4
+ def initialize(data = nil)
5
+ @uid = data ? data[:uid] : nil
6
+ @created = data ? data[:created] : Time.now
7
+ @modified = data ? data[:modified] : @created
8
+ @path = data ? data[:path] : nil
9
+ @name = data ? data[:name] : nil
10
+ @connection = nil
11
+ end
12
+
13
+ attr_accessor :connection
14
+ attr_reader :uid
15
+ attr_reader :created
16
+ attr_reader :modified
17
+ attr_reader :path
18
+ attr_reader :name
19
+
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ module AMEE
2
+ class Pager
3
+
4
+ def initialize(data)
5
+ @start = data[:start]
6
+ @from = data[:from]
7
+ @to = data[:to]
8
+ @items = data[:items]
9
+ @current_page = data[:current_page]
10
+ @requested_page = data[:requested_page]
11
+ @next_page = data[:next_page]
12
+ @previous_page = data[:previous_page]
13
+ @last_page = data[:last_page]
14
+ @items_per_page = data[:items_per_page]
15
+ @items_found = data[:items_found]
16
+ end
17
+
18
+ attr_reader :start
19
+ attr_reader :from
20
+ attr_reader :to
21
+ attr_reader :items
22
+ attr_reader :current_page
23
+ attr_reader :requested_page
24
+ attr_reader :next_page
25
+ attr_reader :previous_page
26
+ attr_reader :last_page
27
+ attr_reader :items_per_page
28
+ attr_reader :items_found
29
+
30
+ def self.from_xml(node)
31
+ return Pager.new({:start => node.elements["Start"].text.to_i,
32
+ :from => node.elements["From"].text.to_i,
33
+ :to => node.elements["To"].text.to_i,
34
+ :items => node.elements["Items"].text.to_i,
35
+ :current_page => node.elements["CurrentPage"].text.to_i,
36
+ :requested_page => node.elements["RequestedPage"].text.to_i,
37
+ :next_page => node.elements["NextPage"].text.to_i,
38
+ :previous_page => node.elements["PreviousPage"].text.to_i,
39
+ :last_page => node.elements["LastPage"].text.to_i,
40
+ :items_per_page => node.elements["ItemsPerPage"].text.to_i,
41
+ :items_found => node.elements["ItemsFound"].text.to_i})
42
+ end
43
+
44
+ def self.from_json(node)
45
+ return Pager.new({:start => node["start"],
46
+ :from => node["from"],
47
+ :to => node["to"],
48
+ :items => node["items"],
49
+ :current_page => node["currentPage"],
50
+ :requested_page => node["requestedPage"],
51
+ :next_page => node["nextPage"],
52
+ :previous_page => node["previousPage"],
53
+ :last_page => node["lastPage"],
54
+ :items_per_page => node["itemsPerPage"],
55
+ :items_found => node["itemsFound"]})
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,108 @@
1
+ module AMEE
2
+ module Profile
3
+ class ProfileList < Array
4
+
5
+ def initialize(connection, options = {})
6
+ # Load data from path
7
+ response = connection.get('/profiles', options).body
8
+ # Parse data from response
9
+ if response.is_json?
10
+ # Read JSON
11
+ doc = JSON.parse(response)
12
+ @pager = AMEE::Pager.from_json(doc['pager'])
13
+ doc['profiles'].each do |p|
14
+ data = {}
15
+ data[:uid] = p['uid']
16
+ data[:created] = DateTime.parse(p['created'])
17
+ data[:modified] = DateTime.parse(p['modified'])
18
+ data[:name] = p['name']
19
+ data[:path] = "/#{p['path']}"
20
+ # Create profile
21
+ profile = Profile.new(data)
22
+ # Store in array
23
+ self << profile
24
+ end
25
+ else
26
+ # Read XML
27
+ doc = REXML::Document.new(response)
28
+ @pager = AMEE::Pager.from_xml(REXML::XPath.first(doc, '/Resources/ProfilesResource/Pager'))
29
+ REXML::XPath.each(doc, '/Resources/ProfilesResource/Profiles/Profile') do |p|
30
+ data = {}
31
+ data[:uid] = p.attributes['uid'].to_s
32
+ data[:created] = DateTime.parse(p.attributes['created'].to_s)
33
+ data[:modified] = DateTime.parse(p.attributes['modified'].to_s)
34
+ data[:name] = p.elements['Name'].text || data[:uid]
35
+ data[:path] = "/#{p.elements['Path'].text || data[:uid]}"
36
+ # Create profile
37
+ profile = Profile.new(data)
38
+ # Store connection in profile object
39
+ profile.connection = connection
40
+ # Store in array
41
+ self << profile
42
+ end
43
+ end
44
+ rescue
45
+ raise AMEE::BadData.new("Couldn't load Profile list.\n#{response}")
46
+ end
47
+
48
+ attr_reader :pager
49
+
50
+ end
51
+
52
+ class Profile < AMEE::Profile::Object
53
+
54
+ # backwards compatibility
55
+ def self.list(connection)
56
+ ProfileList.new(connection)
57
+ end
58
+
59
+ def self.create(connection)
60
+ # Create new profile
61
+ response = connection.post('/profiles', :profile => true).body
62
+ # Parse data from response
63
+ if response.is_json?
64
+ # Read JSON
65
+ doc = JSON.parse(response)
66
+ p = doc['profile']
67
+ data = {}
68
+ data[:uid] = p['uid']
69
+ data[:created] = DateTime.parse(p['created'])
70
+ data[:modified] = DateTime.parse(p['modified'])
71
+ data[:name] = p['name']
72
+ data[:path] = p['path']
73
+ # Create profile
74
+ profile = Profile.new(data)
75
+ # Done
76
+ return profile
77
+ else
78
+ # Read XML
79
+ doc = REXML::Document.new(response)
80
+ p = REXML::XPath.first(doc, '/Resources/ProfilesResource/Profile')
81
+ data = {}
82
+ data[:uid] = p.attributes['uid'].to_s
83
+ data[:created] = DateTime.parse(p.attributes['created'].to_s)
84
+ data[:modified] = DateTime.parse(p.attributes['modified'].to_s)
85
+ data[:name] = p.elements['Name'].text || data[:uid]
86
+ data[:path] = p.elements['Path'].text || data[:uid]
87
+ # Create profile
88
+ profile = Profile.new(data)
89
+ # Store connection in profile object
90
+ profile.connection = connection
91
+ # Done
92
+ return profile
93
+ end
94
+ rescue
95
+ raise AMEE::BadData.new("Couldn't create Profile.\n#{response}")
96
+ end
97
+
98
+ def self.delete(connection, uid)
99
+ # Deleting profiles takes a while... up the timeout to 60 seconds temporarily
100
+ t = connection.timeout
101
+ connection.timeout = 60
102
+ connection.delete("/profiles/#{uid}")
103
+ connection.timeout = t
104
+ end
105
+
106
+ end
107
+ end
108
+ end