lib/amee/profile_item.rb in Floppy-amee-0.4.33 vs lib/amee/profile_item.rb in Floppy-amee-2.0.0
- old
+ new
@@ -2,33 +2,48 @@
module Profile
class Item < AMEE::Profile::Object
def initialize(data = {})
@values = data ? data[:values] : []
- @total_amount_per_month = data[:total_amount_per_month]
- @valid_from = data[:valid_from]
+ @total_amount = data[:total_amount]
+ @total_amount_unit = data[:total_amount_unit]
+ @start_date = data[:start_date] || data[:valid_from]
+ @end_date = data[:end_date] || (data[:end] == true ? @start_date : nil )
@data_item_uid = data[:data_item_uid]
- @end = data[:end]
super
end
attr_reader :values
- attr_reader :total_amount_per_month
- attr_reader :valid_from
- attr_reader :end
+ attr_reader :total_amount
+ attr_reader :total_amount_unit
+ attr_reader :start_date
+ attr_reader :end_date
attr_reader :data_item_uid
+ # V1 compatibility
+ def valid_from
+ start_date
+ end
+ def end
+ end_date.nil? ? false : start_date == end_date
+ end
+
+ def duration
+ end_date.nil? ? nil : (end_date - start_date).to_f
+ end
+
def self.from_json(json)
# Parse json
doc = JSON.parse(json)
data = {}
data[:profile_uid] = doc['profile']['uid']
data[:data_item_uid] = doc['profileItem']['dataItem']['uid']
data[:uid] = doc['profileItem']['uid']
data[:name] = doc['profileItem']['name']
data[:path] = doc['path']
- data[:total_amount_per_month] = doc['profileItem']['amountPerMonth']
+ data[:total_amount] = doc['profileItem']['amountPerMonth']
+ data[:total_amount_unit] = "kg/month"
data[:valid_from] = DateTime.strptime(doc['profileItem']['validFrom'], "%Y%m%d")
data[:end] = doc['profileItem']['end'] == "false" ? false : true
data[:values] = []
doc['profileItem']['itemValues'].each do |item|
value_data = {}
@@ -44,20 +59,53 @@
Item.new(data)
rescue
raise AMEE::BadData.new("Couldn't load ProfileItem from JSON data. Check that your URL is correct.")
end
+ def self.from_v2_json(json)
+ # Parse json
+ doc = JSON.parse(json)
+ data = {}
+ data[:profile_uid] = doc['profile']['uid']
+ data[:data_item_uid] = doc['profileItem']['dataItem']['uid']
+ data[:uid] = doc['profileItem']['uid']
+ data[:name] = doc['profileItem']['name']
+ data[:path] = doc['path']
+ data[:total_amount] = doc['profileItem']['amount']['value'].to_f
+ data[:total_amount_unit] = doc['profileItem']['amount']['unit']
+ data[:start_date] = DateTime.parse(doc['profileItem']['startDate'])
+ data[:end_date] = DateTime.parse(doc['profileItem']['endDate']) rescue nil
+ data[:values] = []
+ doc['profileItem']['itemValues'].each do |item|
+ value_data = {}
+ item.each_pair do |key,value|
+ case key
+ when 'name', 'path', 'uid', 'value', 'unit'
+ value_data[key.downcase.to_sym] = value
+ when 'perUnit'
+ value_data[:per_unit] = value
+ end
+ end
+ data[:values] << value_data
+ end
+ # Create object
+ Item.new(data)
+ rescue
+ raise AMEE::BadData.new("Couldn't load ProfileItem from V2 JSON data. Check that your URL is correct.")
+ end
+
def self.from_xml(xml)
# Parse XML
doc = REXML::Document.new(xml)
data = {}
data[:profile_uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/Profile/@uid").to_s
data[:data_item_uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/DataItem/@uid").to_s
data[:uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/ProfileItem/@uid").to_s
data[:name] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/Name').text
data[:path] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/Path').text || ""
- data[:total_amount_per_month] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/AmountPerMonth').text.to_f rescue nil
+ data[:total_amount] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/AmountPerMonth').text.to_f rescue nil
+ data[:total_amount_unit] = "kg/month"
data[:valid_from] = DateTime.strptime(REXML::XPath.first(doc, "/Resources/ProfileItemResource/ProfileItem/ValidFrom").text, "%Y%m%d")
data[:end] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/End').text == "false" ? false : true
data[:values] = []
REXML::XPath.each(doc, '/Resources/ProfileItemResource/ProfileItem/ItemValues/ItemValue') do |item|
value_data = {}
@@ -76,45 +124,152 @@
Item.new(data)
rescue
raise AMEE::BadData.new("Couldn't load ProfileItem from XML data. Check that your URL is correct.")
end
+ def self.from_v2_xml(xml)
+ # Parse XML
+ doc = REXML::Document.new(xml)
+ data = {}
+ data[:profile_uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/Profile/@uid").to_s
+ data[:data_item_uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/DataItem/@uid").to_s
+ data[:uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/ProfileItem/@uid").to_s
+ data[:name] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/Name').text
+ data[:path] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/Path').text || ""
+ data[:total_amount] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/Amount').text.to_f rescue nil
+ data[:total_amount_unit] = REXML::XPath.first(doc, '/Resources/ProfileItemResource/ProfileItem/Amount/@unit').to_s rescue nil
+ data[:start_date] = DateTime.parse(REXML::XPath.first(doc, "/Resources/ProfileItemResource/ProfileItem/StartDate").text)
+ data[:end_date] = DateTime.parse(REXML::XPath.first(doc, "/Resources/ProfileItemResource/ProfileItem/EndDate").text) rescue nil
+ data[:values] = []
+ REXML::XPath.each(doc, '/Resources/ProfileItemResource/ProfileItem/ItemValues/ItemValue') do |item|
+ value_data = {}
+ item.elements.each do |element|
+ key = element.name
+ value = element.text
+ case key
+ when 'Name', 'Path', 'Value', 'Unit'
+ value_data[key.downcase.to_sym] = value
+ when 'PerUnit'
+ value_data[:per_unit] = value
+ end
+ end
+ value_data[:uid] = item.attributes['uid'].to_s
+ data[:values] << value_data
+ end
+ # Create object
+ Item.new(data)
+ rescue
+ raise AMEE::BadData.new("Couldn't load ProfileItem from V2 XML data. Check that your URL is correct.")
+ end
+
+ def self.from_v2_atom(response)
+ # Parse XML
+ doc = REXML::Document.new(response)
+ data = {}
+ data[:profile_uid] = REXML::XPath.first(doc, "/entry/@xml:base").to_s.match("/profiles/(.*?)/")[1]
+ #data[:data_item_uid] = REXML::XPath.first(doc, "/Resources/ProfileItemResource/DataItem/@uid").to_s
+ data[:uid] = REXML::XPath.first(doc, "/entry/id").text.match("urn:item:(.*)")[1]
+ data[:name] = REXML::XPath.first(doc, '/entry/title').text
+ data[:path] = REXML::XPath.first(doc, "/entry/@xml:base").to_s.match("/profiles/.*?(/.*)")[1]
+ data[:total_amount] = REXML::XPath.first(doc, '/entry/amee:amount').text.to_f rescue nil
+ data[:total_amount_unit] = REXML::XPath.first(doc, '/entry/amee:amount/@unit').to_s rescue nil
+ data[:start_date] = DateTime.parse(REXML::XPath.first(doc, "/entry/amee:startDate").text)
+ data[:end_date] = DateTime.parse(REXML::XPath.first(doc, "/entry/amee:endDate").text) rescue nil
+ data[:values] = []
+ REXML::XPath.each(doc, '/entry/amee:itemValue') do |item|
+ value_data = {}
+ value_data[:name] = item.elements['amee:name'].text
+ value_data[:value] = item.elements['amee:value'].text unless item.elements['amee:value'].text == "N/A"
+ value_data[:path] = item.elements['link'].attributes['href'].to_s
+ value_data[:unit] = item.elements['amee:unit'].text rescue nil
+ value_data[:per_unit] = item.elements['amee:perUnit'].text rescue nil
+ data[:values] << value_data
+ end
+ # Create object
+ Item.new(data)
+ rescue
+ raise AMEE::BadData.new("Couldn't load ProfileItem from V2 ATOM data. Check that your URL is correct.")
+ end
+
def self.parse(connection, response)
# Parse data from response
- if response.is_json?
- cat = Item.from_json(response)
+ if response.is_v2_json?
+ item = Item.from_v2_json(response)
+ elsif response.is_json?
+ item = Item.from_json(response)
+ elsif response.is_v2_atom?
+ item = Item.from_v2_atom(response)
+ elsif response.is_v2_xml?
+ item = Item.from_v2_xml(response)
else
- cat = Item.from_xml(response)
+ item = Item.from_xml(response)
end
# Store connection in object for future use
- cat.connection = connection
+ item.connection = connection
# Done
- return cat
+ return item
end
- def self.get(connection, path, for_date = Date.today)
+ def self.get(connection, path, options = {})
+ unless options.is_a?(Hash)
+ raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
+ end
+ # Convert to AMEE options
+ if options[:start_date] && category.connection.version < 2
+ options[:profileDate] = options[:start_date].amee1_month
+ elsif options[:start_date] && category.connection.version >= 2
+ options[:startDate] = options[:start_date].amee2schema
+ end
+ options.delete(:start_date)
+ if options[:end_date] && category.connection.version >= 2
+ options[:endDate] = options[:end_date].amee2schema
+ end
+ options.delete(:end_date)
+ if options[:duration] && category.connection.version >= 2
+ options[:duration] = "PT#{options[:duration] * 86400}S"
+ end
# Load data from path
- response = connection.get(path, :profileDate => for_date.strftime("%Y%m"))
+ response = connection.get(path, options)
return Item.parse(connection, response)
rescue
raise AMEE::BadData.new("Couldn't load ProfileItem. Check that your URL is correct.")
end
- def self.create(profile, data_item_uid, options = {})
+ def self.create(category, data_item_uid, options = {})
+ # Store format if set
+ format = options[:format]
+ unless options.is_a?(Hash)
+ raise AMEE::ArgumentError.new("Third argument must be a hash of options!")
+ end
+ # Set dates
+ if options[:start_date] && category.connection.version < 2
+ options[:profileDate] = options[:start_date].amee1_month
+ elsif options[:start_date] && category.connection.version >= 2
+ options[:startDate] = options[:start_date].amee2schema
+ end
+ options.delete(:start_date)
+ if options[:end_date] && category.connection.version >= 2
+ options[:endDate] = options[:end_date].amee2schema
+ end
+ options.delete(:end_date)
+ if options[:duration] && category.connection.version >= 2
+ options[:duration] = "PT#{options[:duration] * 86400}S"
+ end
# Send data to path
options.merge! :dataItemUid => data_item_uid
- response = profile.connection.post(profile.full_path, options)
- category = Category.parse(profile.connection, response)
+ response = category.connection.post(category.full_path, options)
+ category = Category.parse(category.connection, response)
+ options.merge!(:format => format) if format
return category.item(options)
rescue
raise AMEE::BadData.new("Couldn't create ProfileItem. Check that your information is correct.")
end
def self.update(connection, path, options = {})
response = connection.put(path, options)
return Item.parse(connection, response)
- #rescue
- # raise AMEE::BadData.new("Couldn't update ProfileItem. Check that your information is correct.")
+ rescue
+ raise AMEE::BadData.new("Couldn't update ProfileItem. Check that your information is correct.")
end
def update(options = {})
AMEE::Profile::Item.update(connection, full_path, options)
end