Floppy-amee 2.0.16 → 2.0.17

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/README CHANGED
@@ -8,6 +8,8 @@ Author: James Smith (james@floppy.org.uk / http://www.floppy.org.uk)
8
8
 
9
9
  Homepage: http://github.com/Floppy/amee-ruby
10
10
 
11
+ Documentation: http://docs.github.com/Floppy/amee-ruby
12
+
11
13
  == INSTALLATION
12
14
 
13
15
  1) Enable gems from github, if you haven't already done so (rubygems >= 1.2):
@@ -110,6 +110,58 @@ module AMEE
110
110
  AMEE::Data::DrillDown.get(connection, "#{full_path}/drill")
111
111
  end
112
112
 
113
+ def item(options)
114
+ # Search fields - from most specific to least specific
115
+ item = items.find{ |x| (x[:uid] && x[:uid] == options[:uid]) ||
116
+ (x[:name] && x[:name] == options[:name]) ||
117
+ (x[:path] && x[:path] == options[:path]) ||
118
+ (x[:label] && x[:label] == options[:label]) }
119
+ # Pass through some options
120
+ new_opts = {}
121
+ new_opts[:format] = options[:format] if options[:format]
122
+ item ? AMEE::Data::Item.get(connection, "#{full_path}/#{item[:path]}", new_opts) : nil
123
+ end
124
+
125
+ def self.create(category, options = {})
126
+
127
+ connection = category.connection
128
+ path = category.full_path
129
+
130
+ # Do we want to automatically fetch the item afterwards?
131
+ get_item = options.delete(:get_item)
132
+
133
+ get_item = true if get_item.nil?
134
+ # Store format if set
135
+ format = options[:format]
136
+ unless options.is_a?(Hash)
137
+ raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
138
+ end
139
+ # Send data to path
140
+ options[:newObjectType] = "DC"
141
+ response = connection.post(path, options)
142
+ if response['Location']
143
+ location = response['Location'].match("http://.*?(/.*)")[1]
144
+ else
145
+ category = Category.parse(connection, response.body)
146
+ location = category.full_path
147
+ end
148
+ if get_item == true
149
+ get_options = {}
150
+ get_options[:format] = format if format
151
+ return AMEE::Data::Category.get(connection, location, get_options)
152
+ else
153
+ return location
154
+ end
155
+ rescue
156
+ raise AMEE::BadData.new("Couldn't create DataCategory. Check that your information is correct.")
157
+ end
158
+
159
+ def self.delete(connection, path)
160
+ connection.delete(path)
161
+ rescue
162
+ raise AMEE::BadData.new("Couldn't delete DataCategory. Check that your information is correct.")
163
+ end
164
+
113
165
  end
114
166
  end
115
167
  end
@@ -8,6 +8,7 @@ module AMEE
8
8
  @label = data[:label]
9
9
  @item_definition = data[:item_definition]
10
10
  @total_amount = data[:total_amount]
11
+ @total_amount_unit = data[:total_amount_unit]
11
12
  super
12
13
  end
13
14
 
@@ -16,6 +17,7 @@ module AMEE
16
17
  attr_reader :label
17
18
  attr_reader :item_definition
18
19
  attr_reader :total_amount
20
+ attr_reader :total_amount_unit
19
21
 
20
22
  def self.from_json(json)
21
23
  # Read JSON
@@ -28,7 +30,14 @@ module AMEE
28
30
  data[:path] = doc['path']
29
31
  data[:label] = doc['dataItem']['label']
30
32
  data[:item_definition] = doc['dataItem']['itemDefinition']['uid']
31
- data[:total_amount] = doc['amountPerMonth'] rescue nil
33
+ # Read v2 total
34
+ data[:total_amount] = doc['amount']['value'] rescue nil
35
+ data[:total_amount_unit] = doc['amount']['unit'] rescue nil
36
+ # Read v1 total
37
+ if data[:total_amount].nil?
38
+ data[:total_amount] = doc['amountPerMonth'] rescue nil
39
+ data[:total_amount_unit] = "kg/month"
40
+ end
32
41
  # Get values
33
42
  data[:values] = []
34
43
  doc['dataItem']['itemValues'].each do |value|
@@ -64,7 +73,14 @@ module AMEE
64
73
  data[:path] = (REXML::XPath.first(doc, '/Resources/DataItemResource/Path') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/path')).text
65
74
  data[:label] = (REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Label') || REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/label')).text
66
75
  data[:item_definition] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/ItemDefinition/@uid').to_s
67
- data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/AmountPerMonth').text.to_f rescue nil
76
+ # Read v2 total
77
+ data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount').text.to_f rescue nil
78
+ data[:total_amount_unit] = REXML::XPath.first(doc, '/Resources/DataItemResource/Amount/@unit').to_s rescue nil
79
+ # Read v1 total
80
+ if data[:total_amount].nil?
81
+ data[:total_amount] = REXML::XPath.first(doc, '/Resources/DataItemResource/AmountPerMonth').text.to_f rescue nil
82
+ data[:total_amount_unit] = "kg/month"
83
+ end
68
84
  # Get values
69
85
  data[:values] = []
70
86
  REXML::XPath.each(doc, '/Resources/DataItemResource/DataItem/ItemValues/ItemValue') do |value|
@@ -107,6 +123,72 @@ module AMEE
107
123
  raise AMEE::BadData.new("Couldn't load DataItem. Check that your URL is correct.")
108
124
  end
109
125
 
126
+ def self.create_batch_without_category(connection, category_path, items, options = {})
127
+ if connection.format == :json
128
+ options.merge! :profileItems => items
129
+ post_data = options.to_json
130
+ else
131
+ options.merge!({:DataItems => items})
132
+ post_data = options.to_xml(:root => "DataCategory", :skip_types => true, :skip_nil => true)
133
+ end
134
+ # Post to category
135
+ response = connection.raw_post(category_path, post_data).body
136
+ # Send back a category object containing all the created items
137
+ unless response.empty?
138
+ return AMEE::Data::Category.parse(connection, response)
139
+ else
140
+ return true
141
+ end
142
+ end
143
+
144
+ def self.create(category, options = {})
145
+ create_without_category(category.connection, category.full_path, options)
146
+ end
147
+
148
+ def self.create_without_category(connection, path, options = {})
149
+ # Do we want to automatically fetch the item afterwards?
150
+ get_item = options.delete(:get_item)
151
+ get_item = true if get_item.nil?
152
+ # Store format if set
153
+ format = options[:format]
154
+ unless options.is_a?(Hash)
155
+ raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
156
+ end
157
+ # Set dates
158
+ if options[:start_date] && connection.version < 2
159
+ options[:validFrom] = options[:start_date].amee1_date
160
+ elsif options[:start_date] && connection.version >= 2
161
+ options[:startDate] = options[:start_date].xmlschema
162
+ end
163
+ options.delete(:start_date)
164
+ if options[:end_date] && connection.version >= 2
165
+ options[:endDate] = options[:end_date].xmlschema
166
+ end
167
+ options.delete(:end_date)
168
+ if options[:duration] && connection.version >= 2
169
+ options[:duration] = "PT#{options[:duration] * 86400}S"
170
+ end
171
+ # Create a data item!
172
+ options[:newObjectType] = "DI"
173
+ # Send data to path
174
+ response = connection.post(path, options)
175
+ # if response['Location']
176
+ # location = response['Location'].match("http://.*?(/.*)")[1]
177
+ # else
178
+ # category = Category.parse(connection, response.body)
179
+ # location = category.full_path + "/" + category.items[0][:path]
180
+ # end
181
+ # if get_item == true
182
+ # get_options = {}
183
+ # get_options[:format] = format if format
184
+ # return AMEE::Data::Item.get(connection, location, get_options)
185
+ # else
186
+ # return location
187
+ # end
188
+ rescue
189
+ raise AMEE::BadData.new("Couldn't create DataItem. Check that your information is correct.")
190
+ end
191
+
110
192
  def update(options = {})
111
193
  response = connection.put(full_path, options).body
112
194
  rescue
@@ -1,5 +1,49 @@
1
1
  module AMEE
2
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.")
41
+ end
42
+
43
+ attr_reader :pager
44
+
45
+ end
46
+
3
47
  class ItemDefinition < AMEE::Object
4
48
 
5
49
  def initialize(data = {})
@@ -9,6 +53,23 @@ module AMEE
9
53
 
10
54
  attr_reader :name
11
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
+
12
73
  def self.from_json(json)
13
74
  # Read JSON
14
75
  doc = JSON.parse(json)
@@ -22,15 +83,16 @@ module AMEE
22
83
  rescue
23
84
  raise AMEE::BadData.new("Couldn't load ItemDefinition from JSON. Check that your URL is correct.")
24
85
  end
25
-
26
- def self.from_xml(xml)
86
+
87
+ def self.from_xml(xml, is_list = true)
88
+ prefix = is_list ? "/Resources/ItemDefinitionsResource/" : "/Resources/ItemDefinitionResource/"
27
89
  # Parse data from response into hash
28
90
  doc = REXML::Document.new(xml)
29
91
  data = {}
30
- data[:uid] = REXML::XPath.first(doc, "/Resources/ItemDefinitionResource/ItemDefinition/@uid").to_s
31
- data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/ItemDefinitionResource/ItemDefinition/@created").to_s)
32
- data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/ItemDefinitionResource/ItemDefinition/@modified").to_s)
33
- data[:name] = REXML::XPath.first(doc, '/Resources/ItemDefinitionResource/ItemDefinition/Name').text
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
34
96
  # Create object
35
97
  ItemDefinition.new(data)
36
98
  rescue
@@ -40,14 +102,8 @@ module AMEE
40
102
  def self.get(connection, path, options = {})
41
103
  # Load data from path
42
104
  response = connection.get(path, options).body
43
- # Parse data from response
44
- if response.is_json?
45
- item_definition = ItemDefinition.from_json(response)
46
- else
47
- item_definition = ItemDefinition.from_xml(response)
48
- end
49
- # Store connection in object for future use
50
- item_definition.connection = connection
105
+ # Parse response
106
+ item_definition = ItemDefinition.parse(connection, response, false)
51
107
  # Done
52
108
  return item_definition
53
109
  rescue
@@ -60,6 +116,32 @@ module AMEE
60
116
  raise AMEE::BadData.new("Couldn't update ItemDefinition. Check that your information is correct.")
61
117
  end
62
118
 
119
+ def self.create(connection, options = {})
120
+ unless options.is_a?(Hash)
121
+ raise AMEE::ArgumentError.new("Second argument must be a hash of options!")
122
+ end
123
+ # Send data
124
+ response = connection.post("/definitions/itemDefinitions", options).body
125
+ # Parse response
126
+ item_definition = ItemDefinition.parse(connection, response)
127
+ # Get the ItemDefinition again
128
+ return ItemDefinition.get(connection, "/definitions/itemDefinitions/" + item_definition.uid)
129
+ rescue
130
+ raise AMEE::BadData.new("Couldn't create ItemDefinition. Check that your information is correct.")
131
+ end
132
+
133
+ def self.delete(connection, item_definition)
134
+ # Deleting takes a while... up the timeout to 120 seconds temporarily
135
+ t = connection.timeout
136
+ connection.timeout = 120
137
+ connection.delete("/definitions/itemDefinitions/" + item_definition.uid)
138
+ connection.timeout = t
139
+ rescue
140
+ raise AMEE::BadData.new("Couldn't delete ProfileItem. Check that your information is correct.")
141
+ end
142
+
63
143
  end
144
+
64
145
  end
146
+
65
147
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Floppy-amee
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.16
4
+ version: 2.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith