Floppy-amee 2.0.22 → 2.0.24

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -55,16 +55,16 @@ example:
55
55
 
56
56
  config.gem "Floppy-amee", :lib => "amee", :source => "http://gems.github.com", :version => '>= 0.3.0'
57
57
 
58
- The first time you run your app after installing the gem, a config/amee.yml file
59
- will be created. You should edit this file and add your AMEE username and
60
- password to it, as well as the server you want to connect to.
61
-
62
- Once that is all set up, you can use AMEE objects within Rails anywhere you like.
63
- There is a persistent AMEE connection available called $amee, which you can pass
64
- into the other objects to fetch data. For instance:
58
+ If you copy amee.example.yml from the gem source directory to amee.yml in your
59
+ app's config directory, a persistent AMEE connection available called $amee,
60
+ will be automatically set up for you, which you can pass into the other objects
61
+ to fetch data. For instance:
65
62
 
66
63
  data = AMEE::Data::Category.root($amee)
67
64
 
65
+ If you do not use this facility, you will have to create your own connection
66
+ objects and manage them yourself.
67
+
68
68
  There is a helper for ActiveRecord models which should be linked to an AMEE profile.
69
69
  By adding:
70
70
 
data/amee.example.yml ADDED
@@ -0,0 +1,12 @@
1
+ development:
2
+ server: stage.amee.com
3
+ username: your_amee_username
4
+ password: your_amee_password
5
+ test:
6
+ server: stage.amee.com
7
+ username: your_amee_username
8
+ password: your_amee_password
9
+ production:
10
+ server: live.amee.com
11
+ username: your_amee_username
12
+ password: your_amee_password
data/lib/amee.rb CHANGED
@@ -42,6 +42,7 @@ require 'amee/profile_item_value'
42
42
  require 'amee/drill_down'
43
43
  require 'amee/pager'
44
44
  require 'amee/item_definition'
45
+ require 'amee/user'
45
46
 
46
47
  class Date
47
48
  def amee1_date
@@ -178,6 +178,12 @@ module AMEE
178
178
  when '401'
179
179
  authenticate
180
180
  return false
181
+ when '400'
182
+ if response.body.include? "would have resulted in a duplicate resource being created"
183
+ raise AMEE::DuplicateResource.new("The specified resource already exists. This is most often caused by creating an item that overlaps another in time. AMEE Response: #{response.body}")
184
+ else
185
+ raise AMEE::UnknownError.new("An error occurred while talking to AMEE: HTTP response code #{response.code}. AMEE Response: #{response.body}")
186
+ end
181
187
  else
182
188
  raise AMEE::UnknownError.new("An error occurred while talking to AMEE: HTTP response code #{response.code}. AMEE Response: #{response.body}")
183
189
  end
@@ -81,9 +81,21 @@ module AMEE
81
81
  raise AMEE::BadData.new("Couldn't load DataCategory from XML data. Check that your URL is correct.\n#{xml}")
82
82
  end
83
83
 
84
- def self.get(connection, path, items_per_page = 10)
84
+ def self.get(connection, path, orig_options = {})
85
+ unless orig_options.is_a?(Hash)
86
+ raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
87
+ end
88
+ # Convert to AMEE options
89
+ options = orig_options.clone
90
+ if orig_options[:items_per_page]
91
+ options[:itemsPerPage] = orig_options[:items_per_page]
92
+ else
93
+ options[:itemsPerPage] = 10
94
+ end
95
+
85
96
  # Load data from path
86
- response = connection.get(path, :itemsPerPage => items_per_page).body
97
+ response = connection.get(path, options).body
98
+
87
99
  # Parse data from response
88
100
  if response.is_json?
89
101
  cat = Category.from_json(response)
@@ -161,6 +173,23 @@ module AMEE
161
173
  rescue
162
174
  raise AMEE::BadData.new("Couldn't delete DataCategory. Check that your information is correct.")
163
175
  end
176
+
177
+ def self.update(connection, path, options = {})
178
+ # Do we want to automatically fetch the item afterwards?
179
+ get_item = options.delete(:get_item)
180
+ get_item = true if get_item.nil?
181
+ # Go
182
+ response = connection.put(path, options)
183
+ if get_item
184
+ if response.body.empty?
185
+ return Category.get(connection, path)
186
+ else
187
+ return Category.parse(connection, response.body)
188
+ end
189
+ end
190
+ rescue
191
+ raise AMEE::BadData.new("Couldn't update Data Category. Check that your information is correct.")
192
+ end
164
193
 
165
194
  end
166
195
  end
@@ -18,7 +18,7 @@ module AMEE
18
18
  attr_reader :item_definition
19
19
  attr_reader :total_amount
20
20
  attr_reader :total_amount_unit
21
-
21
+
22
22
  def self.from_json(json)
23
23
  # Read JSON
24
24
  doc = JSON.parse(json)
@@ -111,6 +111,12 @@ module AMEE
111
111
  def self.get(connection, path, options = {})
112
112
  # Load data from path
113
113
  response = connection.get(path, options).body
114
+ AMEE::Data::Item.parse(connection, response)
115
+ rescue
116
+ raise AMEE::BadData.new("Couldn't load DataItem. Check that your URL is correct.\n#{response}")
117
+ end
118
+
119
+ def self.parse(connection, response)
114
120
  # Parse data from response
115
121
  if response.is_json?
116
122
  item = Item.from_json(response)
@@ -121,8 +127,6 @@ module AMEE
121
127
  item.connection = connection
122
128
  # Done
123
129
  return item
124
- rescue
125
- raise AMEE::BadData.new("Couldn't load DataItem. Check that your URL is correct.\n#{response}")
126
130
  end
127
131
 
128
132
  def self.create_batch_without_category(connection, category_path, items, options = {})
@@ -156,47 +160,54 @@ module AMEE
156
160
  unless options.is_a?(Hash)
157
161
  raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
158
162
  end
159
- # Set dates
160
- if options[:start_date] && connection.version < 2
161
- options[:validFrom] = options[:start_date].amee1_date
162
- elsif options[:start_date] && connection.version >= 2
163
- options[:startDate] = options[:start_date].xmlschema
164
- end
165
- options.delete(:start_date)
166
- if options[:end_date] && connection.version >= 2
167
- options[:endDate] = options[:end_date].xmlschema
168
- end
169
- options.delete(:end_date)
170
- if options[:duration] && connection.version >= 2
171
- options[:duration] = "PT#{options[:duration] * 86400}S"
172
- end
173
163
  # Create a data item!
174
164
  options[:newObjectType] = "DI"
175
165
  # Send data to path
176
166
  response = connection.post(path, options)
177
- # if response['Location']
178
- # location = response['Location'].match("http://.*?(/.*)")[1]
179
- # else
180
- # category = Category.parse(connection, response.body)
181
- # location = category.full_path + "/" + category.items[0][:path]
182
- # end
183
- # if get_item == true
184
- # get_options = {}
185
- # get_options[:format] = format if format
186
- # return AMEE::Data::Item.get(connection, location, get_options)
187
- # else
188
- # return location
189
- # end
167
+ if response['Location']
168
+ location = response['Location'].match("http://.*?(/.*)")[1]
169
+ else
170
+ category = Category.parse(connection, response.body)
171
+ location = category.full_path + "/" + category.items[0][:path]
172
+ end
173
+ if get_item == true
174
+ get_options = {}
175
+ get_options[:format] = format if format
176
+ return AMEE::Data::Item.get(connection, location, get_options)
177
+ else
178
+ return location
179
+ end
190
180
  rescue
191
181
  raise AMEE::BadData.new("Couldn't create DataItem. Check that your information is correct.\n#{response}")
192
182
  end
193
183
 
194
- def update(options = {})
195
- response = connection.put(full_path, options).body
184
+ def self.update(connection, path, options = {})
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 Item.get(connection, path)
193
+ else
194
+ return Item.parse(connection, response.body)
195
+ end
196
+ end
196
197
  rescue
197
198
  raise AMEE::BadData.new("Couldn't update DataItem. Check that your information is correct.\n#{response}")
198
199
  end
200
+
201
+ def update(options = {})
202
+ AMEE::Data::Item.update(connection, full_path, options)
203
+ end
199
204
 
205
+ def self.delete(connection, path)
206
+ connection.delete(path)
207
+ rescue
208
+ raise AMEE::BadData.new("Couldn't delete DataItem. Check that your information is correct.")
209
+ end
210
+
200
211
  def value(name_or_path_or_uid)
201
212
  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}
202
213
  val ? val[:value] : nil
@@ -7,6 +7,7 @@ module AMEE
7
7
  @type = data ? data[:type] : nil
8
8
  @from_profile = data ? data[:from_profile] : nil
9
9
  @from_data = data ? data[:from_data] : nil
10
+ @start_date = data ? data[:start_date] : nil
10
11
  super
11
12
  end
12
13
 
@@ -33,6 +34,10 @@ module AMEE
33
34
  @from_data
34
35
  end
35
36
 
37
+ def start_date
38
+ @start_date
39
+ end
40
+
36
41
  def self.from_json(json, path)
37
42
  # Read JSON
38
43
  doc = JSON.parse(json)['itemValue']
@@ -44,6 +49,7 @@ module AMEE
44
49
  data[:path] = path.gsub(/^\/data/, '')
45
50
  data[:value] = doc['value']
46
51
  data[:type] = doc['itemValueDefinition']['valueDefinition']['valueType']
52
+ data[:start_date] = DateTime.parse(doc['startDate']) rescue nil
47
53
  # Create object
48
54
  ItemValue.new(data)
49
55
  rescue
@@ -63,6 +69,7 @@ module AMEE
63
69
  data[:type] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/ValueDefinition/ValueType').text
64
70
  data[:from_profile] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/FromProfile').text == "true" ? true : false
65
71
  data[:from_data] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/FromData').text == "true" ? true : false
72
+ data[:start_date] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/StartDate").text) rescue nil
66
73
  # Create object
67
74
  ItemValue.new(data)
68
75
  rescue
@@ -74,6 +81,18 @@ module AMEE
74
81
  response = connection.get(path).body
75
82
  # Parse data from response
76
83
  data = {}
84
+ value = ItemValue.parse(connection, response, path)
85
+ # Done
86
+ return value
87
+ rescue
88
+ raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.")
89
+ end
90
+
91
+ def save!
92
+ response = @connection.put(full_path, :value => value).body
93
+ end
94
+
95
+ def self.parse(connection, response, path)
77
96
  if response.is_json?
78
97
  value = ItemValue.from_json(response, path)
79
98
  else
@@ -86,11 +105,63 @@ module AMEE
86
105
  rescue
87
106
  raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.\n#{response}")
88
107
  end
108
+
109
+ def self.create(data_item, options = {})
110
+ # Do we want to automatically fetch the item afterwards?
111
+ get_item = options.delete(:get_item)
112
+ get_item = true if get_item.nil?
113
+ # Store format if set
114
+ format = options[:format]
115
+ unless options.is_a?(Hash)
116
+ raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
117
+ end
118
+ # Set startDate
119
+ if (options[:start_date])
120
+ options[:startDate] = options[:start_date].xmlschema
121
+ options.delete(:start_date)
122
+ end
123
+
124
+ response = data_item.connection.post(data_item.full_path, options)
125
+ location = response['Location'].match("http://.*?(/.*)")[1]
89
126
 
90
- def save!
91
- response = @connection.put(full_path, :value => value).body
127
+ if get_item == true
128
+ get_options = {}
129
+ get_options[:format] = format if format
130
+ return AMEE::Data::ItemValue.get(data_item.connection, location)
131
+ else
132
+ return location
133
+ end
134
+ rescue
135
+ raise AMEE::BadData.new("Couldn't create DataItemValue. Check that your information is correct.")
92
136
  end
93
137
 
138
+ def self.update(connection, path, options = {})
139
+ # Do we want to automatically fetch the item afterwards?
140
+ get_item = options.delete(:get_item)
141
+ get_item = true if get_item.nil?
142
+ # Go
143
+ response = connection.put(path, options)
144
+ if get_item
145
+ if response.body.empty?
146
+ return AMEE::Data::ItemValue.get(connection, path)
147
+ else
148
+ return AMEE::Data::ItemValue.parse(connection, response.body)
149
+ end
150
+ end
151
+ rescue
152
+ raise AMEE::BadData.new("Couldn't update DataItemValue. Check that your information is correct.\n#{response}")
153
+ end
154
+
155
+ def update(options = {})
156
+ AMEE::Data::ItemValue.update(connection, full_path, options)
157
+ end
158
+
159
+ def self.delete(connection, path)
160
+ connection.delete(path)
161
+ rescue
162
+ raise AMEE::BadData.new("Couldn't delete DataItemValue. Check that your information is correct.")
163
+ end
164
+
94
165
  end
95
166
  end
96
- end
167
+ end
@@ -18,6 +18,9 @@ module AMEE
18
18
  class NotFound < Exception
19
19
  end
20
20
 
21
+ class DuplicateResource < Exception
22
+ end
23
+
21
24
  class UnknownError < Exception
22
25
  end
23
26
 
@@ -110,8 +110,19 @@ module AMEE
110
110
  raise AMEE::BadData.new("Couldn't load ItemDefinition. Check that your URL is correct.\n#{response}")
111
111
  end
112
112
 
113
- def update(options = {})
114
- response = connection.put(full_path, options).body
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
115
126
  rescue
116
127
  raise AMEE::BadData.new("Couldn't update ItemDefinition. Check that your information is correct.\n#{response}")
117
128
  end
@@ -316,7 +316,7 @@ module AMEE
316
316
  options.delete(:start_date)
317
317
  if options[:end_date] && connection.version >= 2
318
318
  options[:endDate] = options[:end_date].xmlschema
319
- end
319
+ end
320
320
  options.delete(:end_date)
321
321
  if options[:duration] && connection.version >= 2
322
322
  options[:duration] = "PT#{options[:duration] * 86400}S"
data/lib/amee/user.rb ADDED
@@ -0,0 +1,111 @@
1
+ module AMEE
2
+ module Admin
3
+
4
+ class User < AMEE::Object
5
+
6
+ attr_reader :username
7
+ attr_reader :name
8
+ attr_reader :email
9
+ attr_reader :api_version
10
+ attr_reader :status
11
+
12
+ def initialize(data = {})
13
+ @username = data[:username]
14
+ @name = data[:name]
15
+ @email = data[:email]
16
+ @status = data[:status]
17
+ @api_version = data[:api_version].to_f rescue nil
18
+ @environment_uid = data[:environment_uid]
19
+ super
20
+ end
21
+
22
+ def self.parse(connection, response)
23
+ # Parse data from response
24
+ if response.is_json?
25
+ user = User.from_json(response)
26
+ else
27
+ user = User.from_xml(response)
28
+ end
29
+ # Store connection in object for future use
30
+ user.connection = connection
31
+ # Done
32
+ return user
33
+ end
34
+
35
+ def self.from_json(json)
36
+ # Read JSON
37
+ doc = JSON.parse(json)
38
+ data = {}
39
+ data[:environment_uid] = doc['user']['environment']['uid']
40
+ data[:uid] = doc['user']['uid']
41
+ data[:created] = DateTime.parse(doc['user']['created'])
42
+ data[:modified] = DateTime.parse(doc['user']['modified'])
43
+ data[:username] = doc['user']['username']
44
+ data[:name] = doc['user']['name']
45
+ data[:email] = doc['user']['email']
46
+ data[:api_version] = doc['user']['apiVersion']
47
+ data[:status] = doc['user']['status']
48
+ # Create object
49
+ User.new(data)
50
+ rescue
51
+ raise AMEE::BadData.new("Couldn't load User from JSON. Check that your URL is correct.\n#{json}")
52
+ end
53
+
54
+ def self.from_xml(xml)
55
+ # Parse data from response into hash
56
+ doc = REXML::Document.new(xml)
57
+ data = {}
58
+ data[:environment_uid] = REXML::XPath.first(doc, "//Environment/@uid").to_s
59
+ data[:uid] = REXML::XPath.first(doc, "//User/@uid").to_s
60
+ data[:created] = DateTime.parse(REXML::XPath.first(doc, "//User/@created").to_s)
61
+ data[:modified] = DateTime.parse(REXML::XPath.first(doc, "//User/@modified").to_s)
62
+ data[:username] = REXML::XPath.first(doc, "//User/Username").text
63
+ data[:name] = REXML::XPath.first(doc, "//User/Name").text
64
+ data[:email] = REXML::XPath.first(doc, "//User/Email").text
65
+ data[:api_version] = REXML::XPath.first(doc, "//User/ApiVersion").text
66
+ data[:status] = REXML::XPath.first(doc, "//User/Status").text
67
+ # Create object
68
+ User.new(data)
69
+ rescue
70
+ raise AMEE::BadData.new("Couldn't load User from XML. Check that your URL is correct.\n#{xml}")
71
+ end
72
+
73
+ def self.get(connection, path, options = {})
74
+ # Load data from path
75
+ response = connection.get(path, options).body
76
+ # Parse response
77
+ User.parse(connection, response)
78
+ rescue
79
+ raise AMEE::BadData.new("Couldn't load User. Check that your URL is correct.\n#{response}")
80
+ end
81
+
82
+ def update(options = {})
83
+ connection.put(full_path, options).body
84
+ AMEE::Admin::User.get(connection, full_path)
85
+ end
86
+
87
+ def self.create(connection, environment_uid, options = {})
88
+ unless options.is_a?(Hash)
89
+ raise AMEE::ArgumentError.new("Second argument must be a hash of options!")
90
+ end
91
+ # Send data
92
+ response = connection.post("/environments/#{environment_uid}/users", options).body
93
+ # Parse response
94
+ User.parse(connection, response)
95
+ rescue
96
+ raise AMEE::BadData.new("Couldn't create User. Check that your information is correct.\n#{response}")
97
+ end
98
+
99
+ def delete
100
+ connection.delete(full_path)
101
+ rescue
102
+ raise AMEE::BadData.new("Couldn't delete User. Check that your information is correct.")
103
+ end
104
+
105
+ def full_path
106
+ "/environments/#{@environment_uid}/users/#{uid}"
107
+ end
108
+
109
+ end
110
+ end
111
+ end
data/rails/init.rb CHANGED
@@ -8,17 +8,6 @@ if File.exist?(amee_config)
8
8
  $AMEE_CONFIG = YAML.load_file(amee_config)[RAILS_ENV]
9
9
  # Create a global AMEE connection that we can use from anywhere in this app
10
10
  AMEE::Rails.establish_connection($AMEE_CONFIG['server'], $AMEE_CONFIG['username'], $AMEE_CONFIG['password'])
11
- else
12
- # Create an example AMEE config file and save it to config/amee.yml
13
- example_config = {}
14
- example_config['development'] = {'server' => "stage.co2.dgen.net", 'username' => "your_amee_username", 'password' => "your_amee_password"}
15
- example_config['production'] = {'server' => "stage.co2.dgen.net", 'username' => "your_amee_username", 'password' => "your_amee_password"}
16
- example_config['test'] = {'server' => "stage.co2.dgen.net", 'username' => "your_amee_username", 'password' => "your_amee_password"}
17
- File.open(amee_config, 'w') do |out|
18
- YAML.dump(example_config, out)
19
- end
20
- # Inform the user that we've written a file for them
21
- raise AMEE::ConnectionFailed.new("config/amee.yml doesn't exist. I've created one for you - please add your API keys to it.")
22
11
  end
23
12
 
24
13
  # Add AMEE extensions into ActiveRecord::Base
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.22
4
+ version: 2.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-06 00:00:00 -07:00
12
+ date: 2009-09-15 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -62,6 +62,7 @@ files:
62
62
  - lib/amee/rails.rb
63
63
  - lib/amee/pager.rb
64
64
  - lib/amee/item_definition.rb
65
+ - lib/amee/user.rb
65
66
  - bin/ameesh
66
67
  - examples/list_profiles.rb
67
68
  - examples/create_profile.rb
@@ -70,6 +71,7 @@ files:
70
71
  - examples/view_data_item.rb
71
72
  - init.rb
72
73
  - rails/init.rb
74
+ - amee.example.yml
73
75
  has_rdoc: true
74
76
  homepage: http://github.com/Floppy/amee-ruby
75
77
  licenses: