Floppy-amee 0.0.2
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 +22 -0
- data/examples/view_data_category.rb +40 -0
- data/lib/amee.rb +17 -0
- data/lib/amee/connection.rb +66 -0
- data/lib/amee/data_category.rb +61 -0
- data/lib/amee/data_item.rb +46 -0
- data/lib/amee/data_item_value.rb +14 -0
- data/lib/amee/object.rb +25 -0
- metadata +60 -0
data/README
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
== AMEE-Ruby
|
2
|
+
|
3
|
+
A gem to provide a Ruby interface to the AMEE carbon calculator (http://amee.cc)
|
4
|
+
|
5
|
+
Licensed under the MIT license (See COPYING file for details)
|
6
|
+
|
7
|
+
Author: James Smith (james@floppy.org.uk / http://www.floppy.org.uk)
|
8
|
+
|
9
|
+
Homepage: http://github.com/Floppy/amee-ruby
|
10
|
+
|
11
|
+
== INSTALLATION
|
12
|
+
|
13
|
+
1) Enable gems from github, if you haven't already done so:
|
14
|
+
> sudo gem sources -a http://gems.github.com
|
15
|
+
|
16
|
+
2) Install gem
|
17
|
+
> sudo gem install Floppy-amee
|
18
|
+
|
19
|
+
== USAGE
|
20
|
+
|
21
|
+
Currently, in this first version, only reading data categories is supported. See
|
22
|
+
examples/view_data_category.rb for a simple usage example.
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'amee'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
# Command-line options - get username, password, and server
|
6
|
+
options = {}
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.on("-u", "--username USERNAME", "AMEE username") do |u|
|
9
|
+
options[:username] = u
|
10
|
+
end
|
11
|
+
opts.on("-p", "--password PASSWORD", "AMEE password") do |p|
|
12
|
+
options[:password] = p
|
13
|
+
end
|
14
|
+
opts.on("-s", "--server SERVER", "AMEE server") do |s|
|
15
|
+
options[:server] = s
|
16
|
+
end
|
17
|
+
end.parse!
|
18
|
+
|
19
|
+
# Connect
|
20
|
+
connection = AMEE::Connection.new(options[:server], options[:username], options[:password])
|
21
|
+
|
22
|
+
# For each path in arg list, show details
|
23
|
+
ARGV.each do |path|
|
24
|
+
cat = AMEE::Data::Category.get(connection, path)
|
25
|
+
puts "---------------------"
|
26
|
+
puts "Category: #{cat.name}"
|
27
|
+
puts "Path: #{cat.full_path}"
|
28
|
+
puts "UID: #{cat.uid}"
|
29
|
+
puts "Subcategories:"
|
30
|
+
cat.children.each do |c|
|
31
|
+
puts " - #{c[:path]} (#{c[:name]})"
|
32
|
+
end
|
33
|
+
puts "Items:"
|
34
|
+
cat.items.each do |i|
|
35
|
+
puts " - #{i[:path]} (#{i[:label]})"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
data/lib/amee.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'amee/connection'
|
3
|
+
require 'amee/object'
|
4
|
+
require 'amee/data_category'
|
5
|
+
require 'amee/data_item'
|
6
|
+
require 'amee/data_item_value'
|
7
|
+
|
8
|
+
module AMEE
|
9
|
+
|
10
|
+
module VERSION #:nodoc:
|
11
|
+
MAJOR = 0
|
12
|
+
MINOR = 0
|
13
|
+
TINY = 2
|
14
|
+
STRING = [MAJOR, MINOR, TINY].join('.')
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module AMEE
|
4
|
+
class Connection
|
5
|
+
|
6
|
+
def initialize(server, username = nil, password = nil)
|
7
|
+
@server = server
|
8
|
+
@username = username
|
9
|
+
@password = password
|
10
|
+
@auth_token = nil
|
11
|
+
raise "Must specify both username and password for authenticated access" if (@username || @password) && !valid?
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
!((@username || @password) ? (@username.nil? || @password.nil? || @server.nil?) : @server.nil?)
|
16
|
+
end
|
17
|
+
|
18
|
+
def can_authenticate?
|
19
|
+
!(@username.nil? || @password.nil?)
|
20
|
+
end
|
21
|
+
|
22
|
+
def authenticated?
|
23
|
+
!@auth_token.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(path)
|
27
|
+
response = nil
|
28
|
+
http = Net::HTTP.new(@server)
|
29
|
+
#http.set_debug_output($stdout)
|
30
|
+
http.start do
|
31
|
+
get = Net::HTTP::Get.new(path)
|
32
|
+
get['authToken'] = @auth_token
|
33
|
+
get['Accept'] = 'application/xml'
|
34
|
+
response = http.request(get)
|
35
|
+
# If request fails, authenticate and try again
|
36
|
+
if authentication_failed?(response)
|
37
|
+
authenticate
|
38
|
+
get['authToken'] = @auth_token
|
39
|
+
response = http.request(get)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
yield response.body if block_given?
|
43
|
+
response.body
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def authentication_failed?(response)
|
49
|
+
response.code == '401'
|
50
|
+
end
|
51
|
+
|
52
|
+
def authenticate
|
53
|
+
unless can_authenticate?
|
54
|
+
raise "AMEE authentication required. Please provide your username and password."
|
55
|
+
end
|
56
|
+
response = nil
|
57
|
+
http = Net::HTTP.new(@server)
|
58
|
+
http.start do
|
59
|
+
response = http.post("/auth", "username=#{@username}&password=#{@password}")
|
60
|
+
@auth_token = response['authToken']
|
61
|
+
raise "AMEE authentication failed. Please check your username and password." unless authenticated?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module AMEE
|
4
|
+
module Data
|
5
|
+
class Category < AMEE::Object
|
6
|
+
|
7
|
+
def initialize(data = {})
|
8
|
+
@children = data ? data[:children] : []
|
9
|
+
@items = data ? data[:items] : []
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :children
|
14
|
+
attr_reader :items
|
15
|
+
|
16
|
+
def self.get(connection, path)
|
17
|
+
# Load data from path
|
18
|
+
response = connection.get(path)
|
19
|
+
# Parse data from response into hash
|
20
|
+
doc = REXML::Document.new(response)
|
21
|
+
data = {}
|
22
|
+
data[:uid] = REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@uid").to_s
|
23
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@created").to_s)
|
24
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@modified").to_s)
|
25
|
+
data[:name] = REXML::XPath.first(doc, '/Resources/DataCategoryResource/DataCategory/Name').text
|
26
|
+
data[:path] = REXML::XPath.first(doc, '/Resources/DataCategoryResource/Path').text || ""
|
27
|
+
data[:children] = []
|
28
|
+
REXML::XPath.each(doc, '/Resources/DataCategoryResource/Children/DataCategories/DataCategory') do |child|
|
29
|
+
category_data = {}
|
30
|
+
category_data[:name] = child.elements['Name'].text
|
31
|
+
category_data[:path] = child.elements['Path'].text
|
32
|
+
category_data[:uid] = child.attributes['uid'].to_s
|
33
|
+
data[:children] << category_data
|
34
|
+
end
|
35
|
+
data[:items] = []
|
36
|
+
REXML::XPath.each(doc, '/Resources/DataCategoryResource/Children/DataItems/DataItem') do |item|
|
37
|
+
item_data = {}
|
38
|
+
item_data[:label] = item.elements['label'].text
|
39
|
+
item_data[:path] = item.elements['path'].text
|
40
|
+
item_data[:uid] = item.attributes['uid'].to_s
|
41
|
+
data[:items] << item_data
|
42
|
+
end
|
43
|
+
# Create category object
|
44
|
+
cat = Category.new(data)
|
45
|
+
# Store connection in object for future use
|
46
|
+
cat.connection = connection
|
47
|
+
# Done
|
48
|
+
return cat
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.root(connection)
|
52
|
+
self.get(connection, '/data')
|
53
|
+
end
|
54
|
+
|
55
|
+
def child(child_path)
|
56
|
+
AMEE::Data::Category.get(connection, "#{full_path}/#{child_path}")
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module AMEE
|
2
|
+
module Data
|
3
|
+
class Item < AMEE::Object
|
4
|
+
|
5
|
+
def initialize(data = {})
|
6
|
+
@values = data ? data[:values] : []
|
7
|
+
@label = data ? data[:label] : []
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :values
|
12
|
+
attr_reader :label
|
13
|
+
|
14
|
+
def self.get(connection, path)
|
15
|
+
# Load data from path
|
16
|
+
response = connection.get(path)
|
17
|
+
# Parse data from response into hash
|
18
|
+
doc = REXML::Document.new(response)
|
19
|
+
data = {}
|
20
|
+
data[:uid] = REXML::XPath.first(doc, "/Resources/DataItemResource/DataItem/@uid").to_s
|
21
|
+
data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemResource/DataItem/@created").to_s)
|
22
|
+
data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemResource/DataItem/@modified").to_s)
|
23
|
+
data[:name] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Name').text
|
24
|
+
data[:path] = REXML::XPath.first(doc, '/Resources/DataItemResource/Path').text
|
25
|
+
data[:label] = REXML::XPath.first(doc, '/Resources/DataItemResource/DataItem/Label').text
|
26
|
+
# Get values
|
27
|
+
data[:values] = []
|
28
|
+
REXML::XPath.each(doc, '/Resources/DataItemResource/DataItem/ItemValues/ItemValue') do |value|
|
29
|
+
value_data = {}
|
30
|
+
value_data[:name] = value.elements['Name'].text
|
31
|
+
value_data[:path] = value.elements['Path'].text
|
32
|
+
value_data[:value] = value.elements['Value'].text
|
33
|
+
value_data[:uid] = value.attributes['uid'].to_s
|
34
|
+
data[:values] << value_data
|
35
|
+
end
|
36
|
+
# Create item object
|
37
|
+
item = Item.new(data)
|
38
|
+
# Store connection in object for future use
|
39
|
+
item.connection = connection
|
40
|
+
# Done
|
41
|
+
return item
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/amee/object.rb
ADDED
@@ -0,0 +1,25 @@
|
|
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
|
+
def full_path
|
21
|
+
"/data#{@path}"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Floppy-amee
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Smith
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-07-10 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: james@floppy.org.uk
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- lib/amee.rb
|
27
|
+
- lib/amee/connection.rb
|
28
|
+
- lib/amee/data_category.rb
|
29
|
+
- lib/amee/data_item.rb
|
30
|
+
- lib/amee/data_item_value.rb
|
31
|
+
- lib/amee/object.rb
|
32
|
+
- examples/view_data_category.rb
|
33
|
+
has_rdoc: false
|
34
|
+
homepage: http://github.com/Floppy/amee-ruby
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 1.2.0
|
56
|
+
signing_key:
|
57
|
+
specification_version: 2
|
58
|
+
summary: Ruby interface to the AMEE carbon calculator
|
59
|
+
test_files: []
|
60
|
+
|