eeml 0.0.7 → 0.0.8

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/Manifest CHANGED
@@ -9,18 +9,20 @@ lib/eeml.rb
9
9
  lib/eeml/constants.rb
10
10
  lib/eeml/csv_parser.rb
11
11
  lib/eeml/environment.rb
12
+ lib/eeml/environment_builder.rb
12
13
  lib/eeml/exceptions.rb
13
14
  lib/eeml/json_environment_parser_v005.rb
15
+ lib/eeml/json_environment_parser_v006.rb
14
16
  lib/eeml/json_output.rb
15
17
  lib/eeml/libxml_eeml_output_v005.rb
16
18
  lib/eeml/libxml_eeml_parser_v005.rb
17
19
  lib/eeml/output_registry.rb
18
- lib/eeml/parser_registry.rb
19
20
  schemas/eeml/005.xsd
20
21
  test/data/complete_namespaced.xml
21
22
  test/data/difficult_tag.xml
22
23
  test/data/doc_1.json
23
24
  test/data/doc_1.xml
25
+ test/data/doc_1_v6.json
24
26
  test/data/doc_2.xml
25
27
  test/data/doc_2_expected.json
26
28
  test/data/list.xml
data/eeml.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{eeml}
5
- s.version = "0.0.7"
5
+ s.version = "0.0.8"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Neill Bogie, Sam Mulube"]
9
9
  s.cert_chain = ["/home/sam/.gem/gem-public_cert.pem"]
10
- s.date = %q{2009-09-29}
10
+ s.date = %q{2009-11-21}
11
11
  s.description = %q{Simple little library for programmatically manipulating EEML documents, in particular this library is designed to work with the Pachube web service.}
12
12
  s.email = %q{sam.mulube@gmail.com}
13
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/blank.rb", "lib/eeml.rb", "lib/eeml/constants.rb", "lib/eeml/csv_parser.rb", "lib/eeml/environment.rb", "lib/eeml/exceptions.rb", "lib/eeml/json_environment_parser_v005.rb", "lib/eeml/json_output.rb", "lib/eeml/libxml_eeml_output_v005.rb", "lib/eeml/libxml_eeml_parser_v005.rb", "lib/eeml/output_registry.rb", "lib/eeml/parser_registry.rb"]
14
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "example.rb", "lib/blank.rb", "lib/eeml.rb", "lib/eeml/constants.rb", "lib/eeml/csv_parser.rb", "lib/eeml/environment.rb", "lib/eeml/exceptions.rb", "lib/eeml/json_environment_parser_v005.rb", "lib/eeml/json_output.rb", "lib/eeml/libxml_eeml_output_v005.rb", "lib/eeml/libxml_eeml_parser_v005.rb", "lib/eeml/output_registry.rb", "lib/eeml/parser_registry.rb", "schemas/eeml/005.xsd", "test/data/complete_namespaced.xml", "test/data/difficult_tag.xml", "test/data/doc_1.json", "test/data/doc_1.xml", "test/data/doc_2.xml", "test/data/doc_2_expected.json", "test/data/list.xml", "test/data/minimal.xml", "test/data/no_namespace.xml", "test/data/out_empty.xml", "test/libxml_test_helper.rb", "test/test_environment.rb", "test/test_helper.rb", "test/test_libxml_eeml_parser_v005.rb", "test/test_libxml_test_helper.rb", "eeml.gemspec"]
13
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/blank.rb", "lib/eeml.rb", "lib/eeml/constants.rb", "lib/eeml/csv_parser.rb", "lib/eeml/environment.rb", "lib/eeml/environment_builder.rb", "lib/eeml/exceptions.rb", "lib/eeml/json_environment_parser_v005.rb", "lib/eeml/json_environment_parser_v006.rb", "lib/eeml/json_output.rb", "lib/eeml/libxml_eeml_output_v005.rb", "lib/eeml/libxml_eeml_parser_v005.rb", "lib/eeml/output_registry.rb"]
14
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "example.rb", "lib/blank.rb", "lib/eeml.rb", "lib/eeml/constants.rb", "lib/eeml/csv_parser.rb", "lib/eeml/environment.rb", "lib/eeml/environment_builder.rb", "lib/eeml/exceptions.rb", "lib/eeml/json_environment_parser_v005.rb", "lib/eeml/json_environment_parser_v006.rb", "lib/eeml/json_output.rb", "lib/eeml/libxml_eeml_output_v005.rb", "lib/eeml/libxml_eeml_parser_v005.rb", "lib/eeml/output_registry.rb", "schemas/eeml/005.xsd", "test/data/complete_namespaced.xml", "test/data/difficult_tag.xml", "test/data/doc_1.json", "test/data/doc_1.xml", "test/data/doc_1_v6.json", "test/data/doc_2.xml", "test/data/doc_2_expected.json", "test/data/list.xml", "test/data/minimal.xml", "test/data/no_namespace.xml", "test/data/out_empty.xml", "test/libxml_test_helper.rb", "test/test_environment.rb", "test/test_helper.rb", "test/test_libxml_eeml_parser_v005.rb", "test/test_libxml_test_helper.rb", "eeml.gemspec"]
15
15
  s.homepage = %q{}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Eeml", "--main", "README"]
17
17
  s.require_paths = ["lib"]
@@ -1,18 +1,14 @@
1
1
  module Eeml
2
2
  module Constants
3
- LOCAL_EEML_SCHEMA_LOCATION = "schemas/eeml/005.xsd" # :nodoc:
4
- EEML_HREF = "http://www.eeml.org/xsd/005"
5
- EEML_VERSION = "5"
6
- EEML_SCHEMA_LOCATION = "http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"
3
+ LOCAL_EEML5_SCHEMA_LOCATION = "schemas/eeml/005.xsd" # :nodoc:
4
+ EEML5_HREF = "http://www.eeml.org/xsd/005"
5
+ EEML5_VERSION = "5"
6
+ EEML5_SCHEMA_LOCATION = "http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"
7
7
 
8
- EEML_NAMESPACE = ":#{EEML_HREF}"
8
+ EEML5_NAMESPACE = ":#{EEML5_HREF}"
9
9
  XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance"
10
10
 
11
- #--
12
- # TODO: better encapsulated as a set of methods.
13
- #++
14
- XML_TIME_FORMAT_STRING = "%Y-%m-%dT%H:%M:%SZ"
15
-
11
+ EEML6_VERSION = "0.6"
16
12
  end
17
13
  end
18
14
 
@@ -20,23 +20,76 @@ module Eeml
20
20
  # One of the component classes of Environment. Represents an individual datastream, and provides access to it's value
21
21
  # and other attributes. Environments can have zero or more datastreams.
22
22
  class DataStream
23
- attr_accessor :identifier, :value, :tags, :min_value, :max_value, :unit_symbol, :unit_type, :unit_value
23
+ attr_accessor :identifier, :tags, :unit_symbol, :unit_type, :unit_value
24
+ attr_accessor :values
24
25
 
25
26
  def initialize(options = {})
26
27
  @identifier = options[:identifier]
27
- @value = options[:value]
28
- @max_value = options[:max_value]
29
- @min_value = options[:min_value]
30
28
  @tags = []
31
29
  @unit_symbol = options[:unit_symbol]
32
30
  @unit_type = options[:unit_type]
33
31
  @unit_value = options[:unit_value]
32
+ @values = []
33
+ @values << Value.new(:value => options[:value],
34
+ :max_value => options[:max_value],
35
+ :min_value => options[:min_value],
36
+ :recorded_at => options[:recorded_at])
37
+ end
38
+
39
+ def add_value(value)
40
+ @values << value
41
+ end
42
+
43
+ def remove_last_value
44
+ @values.pop
45
+ end
46
+
47
+ def min_value
48
+ unless @values.last.nil?
49
+ return @values.last.min_value
50
+ else
51
+ return nil
52
+ end
53
+ end
54
+
55
+ def max_value
56
+ unless @values.last.nil?
57
+ return @values.last.max_value
58
+ else
59
+ return nil
60
+ end
61
+ end
62
+
63
+ def value
64
+ unless @values.last.nil?
65
+ return @values.last.value
66
+ else
67
+ return nil
68
+ end
69
+ end
70
+
71
+ def recorded_at
72
+ unless @values.last.nil?
73
+ return @values.last.recorded_at
74
+ else
75
+ return nil
76
+ end
34
77
  end
35
78
 
36
79
  def to_s
37
80
  "identifier: '#{@identifier}', value: '#{@value}', min_value: '#{@min_value}', max_value: '#{@max_value}', tags: '#{@tags.join(", ")}'"
38
81
  end
82
+ end
39
83
 
84
+ class Value
85
+ attr_accessor :min_value, :max_value, :value, :recorded_at
86
+
87
+ def initialize(options = {})
88
+ @min_value = options[:min_value]
89
+ @max_value = options[:max_value]
90
+ @value = options[:value]
91
+ @recorded_at = options[:recorded_at]
92
+ end
40
93
  end
41
94
 
42
95
  # This class represents the main point of entry to this library. In general we will be creating instances of this class, either
@@ -73,20 +126,17 @@ module Eeml
73
126
 
74
127
  # Create multiple Environment objects from an EEML string containing multiple `environment` stanzas.
75
128
  def self.new_list_from_eeml(xml_str)
76
- parser = ParserRegistry.get_xml_parser_for(xml_str)
77
- return parser.make_environments_from_xml(xml_str)
129
+ return EnvironmentBuilder.build_list_from_xml(xml_str)
78
130
  end
79
131
 
80
132
  # Create a new Environment object from an EEML string.
81
133
  def self.new_from_eeml(xml_str)
82
- parser = ParserRegistry.get_xml_parser_for(xml_str)
83
- return parser.make_environment_from_xml(xml_str)
134
+ return EnvironmentBuilder.build_from_xml(xml_str)
84
135
  end
85
136
 
86
137
  # Create a new Environment object from a JSON string.
87
138
  def self.new_from_json(json_str)
88
- parser = ParserRegistry.get_json_parser_for(json_str)
89
- return parser.make_environment_from_json(json_str)
139
+ return EnvironmentBuilder.build_from_json(json_str)
90
140
  end
91
141
 
92
142
  def update_datastreams_from_csv_values!(csv_values)
@@ -95,10 +145,12 @@ module Eeml
95
145
  datastream = datastreams[index]
96
146
  #if we don't have an existing datastream at same index, create new one
97
147
  if datastream.nil?
98
- self.datastreams << DataStream.new(:identifier => index, :value => new_val, :ordering => index)
148
+ datastream = DataStream.new(:identifier => index, :ordering => index)
149
+ datastream.add_value(Value.new(:value => new_val))
150
+ self.datastreams << datastream
99
151
  else
100
152
  #we had a match, so update the existing datastream
101
- datastream.value = new_val
153
+ datastream.values.last.value = new_val
102
154
  end
103
155
  end
104
156
 
@@ -110,7 +162,7 @@ module Eeml
110
162
  end
111
163
  end
112
164
 
113
- def to_eeml(version = Constants::EEML_VERSION)
165
+ def to_eeml(version = Constants::EEML5_VERSION)
114
166
  outputter = OutputRegistry.get_xml_output_for(version)
115
167
  outputter.to_eeml(self)
116
168
  end
@@ -0,0 +1,30 @@
1
+ require 'eeml/libxml_eeml_parser_v005'
2
+ require 'eeml/json_environment_parser_v005'
3
+ require 'eeml/json_environment_parser_v006'
4
+
5
+ module Eeml
6
+ class EnvironmentBuilder # :nodoc:
7
+ def self.build_from_xml(xml_str)
8
+ parser = LibXMLEemlParserV005.new
9
+ return parser.make_environment_from_xml(xml_str)
10
+ end
11
+
12
+ def self.build_list_from_xml(xml_str)
13
+ parser = LibXMLEemlParserV005.new
14
+ return parser.make_environments_from_xml(xml_str)
15
+ end
16
+
17
+ def self.build_from_json(json_str)
18
+ json = JSON.parse(json_str)
19
+ if json["version"] == EEML5_VERSION
20
+ parser = JsonEnvironmentParserV005.new
21
+ elsif json["version"] == EEML6_VERSION
22
+ parser = JsonEnvironmentParserV006.new
23
+ else
24
+ raise "Invalid version specification. Permitted versions are #{EEML5_VERSION} and #{EEML6_VERSION}"
25
+ end
26
+ return parser.make_environment_from_hash(json)
27
+ end
28
+ end
29
+ end
30
+
@@ -3,8 +3,7 @@ module Eeml
3
3
  class JsonEnvironmentParserV005 # :nodoc:
4
4
  include Exceptions
5
5
 
6
- def make_environment_from_json(json_str)
7
- env_hash = JSON.parse(json_str)
6
+ def make_environment_from_hash(env_hash)
8
7
  env = Environment.new(:title => env_hash["title"],
9
8
  :description => env_hash["description"],
10
9
  :feed_url => env_hash["feed"],
@@ -14,7 +13,7 @@ module Eeml
14
13
  :status => env_hash["status"],
15
14
  :identifier => env_hash["id"])
16
15
 
17
- env.updated = Time.mktime(*ParseDate.parsedate(env_hash['updated'])) unless env_hash['updated'].nil?
16
+ env.updated = Time.gm(*ParseDate.parsedate(env_hash['updated'])) unless env_hash['updated'].nil?
18
17
 
19
18
  env.location = buildLocation(env_hash)
20
19
 
@@ -23,6 +22,11 @@ module Eeml
23
22
  return env
24
23
  end
25
24
 
25
+ def make_environment_from_json(json_str)
26
+ env_hash = JSON.parse(json_str)
27
+ return make_environment_from_hash(env_hash)
28
+ end
29
+
26
30
  private
27
31
 
28
32
  def buildLocation(env_hash)
@@ -49,10 +53,13 @@ module Eeml
49
53
 
50
54
  value_hash = datastream_hash["value"]
51
55
  raise DataMissingValue if value_hash.nil?
52
- # raise DataHasMultipleValues if value_hash.size > 1
53
- datastream.value = value_hash["current_value"]
54
- datastream.min_value = value_hash["min_value"]
55
- datastream.max_value = value_hash["max_value"]
56
+ #raise DataHasMultipleValues if value_hash.size > 1
57
+
58
+ value = Value.new(:value => value_hash["current_value"],
59
+ :min_value => value_hash["min_value"],
60
+ :max_value => value_hash["max_value"])
61
+
62
+ datastream.add_value(value)
56
63
 
57
64
  unit_hash = datastream_hash["unit"]
58
65
  unless unit_hash.nil?
@@ -0,0 +1,81 @@
1
+ module Eeml
2
+ # A parser for json environments based on the EEML 5 specification.
3
+ class JsonEnvironmentParserV006 # :nodoc:
4
+ include Exceptions
5
+
6
+ def make_environment_from_hash(env_hash)
7
+ env = Environment.new(:title => env_hash["title"],
8
+ :description => env_hash["description"],
9
+ :feed_url => env_hash["feed"],
10
+ :website => env_hash["website"],
11
+ :email => env_hash["email"],
12
+ :icon => env_hash["icon"],
13
+ :status => env_hash["status"],
14
+ :identifier => env_hash["id"])
15
+
16
+ env.updated = Time.gm(*ParseDate.parsedate(env_hash['updated'])) unless env_hash['updated'].nil?
17
+
18
+ env.location = buildLocation(env_hash)
19
+
20
+ env.datastreams = buildDatastreams(env_hash)
21
+
22
+ return env
23
+ end
24
+
25
+ def make_environment_from_json(json_str)
26
+ env_hash = JSON.parse(json_str)
27
+ return make_environment_from_hash(env_hash)
28
+ end
29
+
30
+ private
31
+
32
+ def buildLocation(env_hash)
33
+ location_hash = env_hash["location"]
34
+ return if location_hash.nil?
35
+ Location.new(:name => location_hash["name"],
36
+ :latitude => location_hash["lat"],
37
+ :longitude => location_hash["lon"],
38
+ :elevation => location_hash["ele"],
39
+ :domain => location_hash["domain"],
40
+ :disposition => location_hash["disposition"],
41
+ :exposure => location_hash["exposure"])
42
+ end
43
+
44
+ def buildDatastreams(env_hash)
45
+ datastreams_hash = env_hash["datastreams"]
46
+ return if datastreams_hash.nil?
47
+ datastreams = []
48
+ datastreams_hash.each do |datastream_hash|
49
+ datastream = DataStream.new
50
+ raise MissingAttribute.new('id', "data") if datastream_hash['id'].nil?
51
+ datastream.identifier = datastream_hash['id']
52
+ datastream.tags = datastream_hash['tags'] unless datastream_hash['tags'].nil?
53
+
54
+ values_arr = datastream_hash["values"]
55
+
56
+ raise DataMissingValue if values_arr.nil?
57
+
58
+ values_arr.each do |v|
59
+ value = Value.new(:value => v["value"],
60
+ :min_value => v["min_value"],
61
+ :max_value => v["max_value"],
62
+ :recorded_at => v["recorded_at"])
63
+
64
+ datastream.add_value(value)
65
+ end
66
+
67
+ unit_hash = datastream_hash["unit"]
68
+ unless unit_hash.nil?
69
+ datastream.unit_symbol = unit_hash["symbol"]
70
+ datastream.unit_type = unit_hash["type"]
71
+ datastream.unit_value = unit_hash["label"]
72
+ end
73
+
74
+ datastreams << datastream
75
+ end
76
+ return datastreams
77
+ end
78
+ end
79
+ end
80
+
81
+
@@ -16,9 +16,9 @@ module Eeml
16
16
  :website => environment.website,
17
17
  :email => environment.email,
18
18
  :icon => environment.icon,
19
- :version => EEML_VERSION}
19
+ :version => EEML5_VERSION}
20
20
 
21
- environment_hash[:updated] = environment.updated.strftime("%Y-%m-%dT%H:%M:%SZ") unless environment.updated.nil? #TODO: was retrieved_at
21
+ environment_hash[:updated] = environment.updated.utc.iso8601 unless environment.updated.nil? #TODO: was retrieved_at
22
22
 
23
23
  environment_hash.delete_if { |key, value| value.blank? }
24
24
 
@@ -7,10 +7,10 @@ module Eeml
7
7
  def to_eeml(environment)
8
8
  doc = XML::Document.new
9
9
  eeml = doc.root = XML::Node.new('eeml')
10
- XML::Namespace.new(eeml, nil, EEML_HREF)
10
+ XML::Namespace.new(eeml, nil, EEML5_HREF)
11
11
  XML::Namespace.new(eeml, 'xsi', XSI_NAMESPACE)
12
- eeml['version'] = EEML_VERSION
13
- eeml['xsi:schemaLocation'] = EEML_SCHEMA_LOCATION
12
+ eeml['version'] = EEML5_VERSION
13
+ eeml['xsi:schemaLocation'] = EEML5_SCHEMA_LOCATION
14
14
  eeml << xml_node_for_environment(environment)
15
15
 
16
16
  return doc.to_s(:encoding => XML::Encoding::UTF_8)
@@ -21,7 +21,7 @@ module Eeml
21
21
 
22
22
  #TODO: write all these strings out safely for xml
23
23
 
24
- environment_node['updated'] = environment.updated.strftime(XML_TIME_FORMAT_STRING) unless environment.updated.nil?
24
+ environment_node['updated'] = environment.updated.utc.iso8601 unless environment.updated.nil?
25
25
  environment_node['id'] = environment.identifier.to_s unless environment.identifier.blank?
26
26
  environment_node['creator'] = environment.creator.to_s unless environment.creator.blank?
27
27
 
@@ -46,20 +46,20 @@ module Eeml
46
46
  #validation?
47
47
  # seems we have to recreate our XML::Schema object on each invocation
48
48
  # else libxml segfaults very quickly
49
- #doc.validate_schema(XML::Schema.from_string(IO.read(LOCAL_EEML_SCHEMA_LOCATION)))
49
+ #doc.validate_schema(XML::Schema.from_string(IO.read(LOCAL_EEML5_SCHEMA_LOCATION)))
50
50
  return doc
51
51
  end
52
52
 
53
53
 
54
54
  #multiple (zero or more)
55
55
  def extract_environments_from_doc(doc)
56
- env_nodes = doc.find('x:environment', "x:#{EEML_HREF}")
56
+ env_nodes = doc.find('x:environment', "x:#{EEML5_HREF}")
57
57
  return env_nodes.map{|env_node| new_env = Environment.new; extract_environment_from_node(env_node, new_env)}
58
58
  end
59
59
 
60
60
  #single, mandatory
61
61
  def extract_environment_from_doc(doc, env_to_populate)
62
- env_node = find_first_node_or_fail(doc, 'x:environment', 'environment', "x:#{EEML_HREF}")
62
+ env_node = find_first_node_or_fail(doc, 'x:environment', 'environment', "x:#{EEML5_HREF}")
63
63
  return extract_environment_from_node(env_node, env_to_populate)
64
64
  end
65
65
 
@@ -67,24 +67,23 @@ module Eeml
67
67
  def extract_environment_from_node(env_node, env_to_populate)
68
68
  env = env_to_populate
69
69
  env.identifier = env_node['id']
70
- env.updated = Time.mktime(*ParseDate.parsedate(env_node['updated'])) if !env_node['updated'].nil?
71
-
70
+ env.updated = Time.gm(*ParseDate.parsedate(env_node['updated'])).utc if !env_node['updated'].nil?
72
71
 
73
72
  env.creator = env_node['creator']
74
73
 
75
- env.title = optional_content(env_node, 'x:title', 'title', "x:#{EEML_HREF}")
76
- env.feed_url = optional_content(env_node, 'x:feed', 'feed', "x:#{EEML_HREF}")
77
- env.description = optional_content(env_node, 'x:description', 'description', "x:#{EEML_HREF}")
78
- env.website = optional_content(env_node, 'x:website', 'website', "x:#{EEML_HREF}")
79
- env.status = optional_content(env_node, 'x:status', 'status', "x:#{EEML_HREF}")
80
- env.email = optional_content(env_node, 'x:email', 'email', "x:#{EEML_HREF}")
81
- env.icon = optional_content(env_node, 'x:icon', 'icon', "x:#{EEML_HREF}")
74
+ env.title = optional_content(env_node, 'x:title', 'title', "x:#{EEML5_HREF}")
75
+ env.feed_url = optional_content(env_node, 'x:feed', 'feed', "x:#{EEML5_HREF}")
76
+ env.description = optional_content(env_node, 'x:description', 'description', "x:#{EEML5_HREF}")
77
+ env.website = optional_content(env_node, 'x:website', 'website', "x:#{EEML5_HREF}")
78
+ env.status = optional_content(env_node, 'x:status', 'status', "x:#{EEML5_HREF}")
79
+ env.email = optional_content(env_node, 'x:email', 'email', "x:#{EEML5_HREF}")
80
+ env.icon = optional_content(env_node, 'x:icon', 'icon', "x:#{EEML5_HREF}")
82
81
 
83
82
  #find_first_node_or_fail(env_node, 'x:location', 'location')
84
- loc_node = env_node.find_first('x:location', "x:#{EEML_HREF}")
83
+ loc_node = env_node.find_first('x:location', "x:#{EEML5_HREF}")
85
84
  env.location = extractLocation(loc_node) if loc_node
86
85
 
87
- datastream_nodes = env_node.find('x:data', "x:#{EEML_HREF}")
86
+ datastream_nodes = env_node.find('x:data', "x:#{EEML5_HREF}")
88
87
  # raise NoDataStreams.new, "no datastreams found" if datastream_nodes.empty?
89
88
  env.datastreams = extractDataStreams(datastream_nodes) unless datastream_nodes.empty?
90
89
 
@@ -102,10 +101,10 @@ module Eeml
102
101
  loc.domain = node['domain']
103
102
  loc.disposition = node['disposition']
104
103
  loc.exposure = node['exposure']
105
- loc.name = optional_content(node, 'x:name', 'name', "x:#{EEML_HREF}")
106
- loc.latitude = optional_content(node, 'x:lat', 'lat', "x:#{EEML_HREF}")
107
- loc.longitude = optional_content(node, 'x:lon', 'lon', "x:#{EEML_HREF}")
108
- loc.elevation = optional_content(node, 'x:ele', 'ele', "x:#{EEML_HREF}")
104
+ loc.name = optional_content(node, 'x:name', 'name', "x:#{EEML5_HREF}")
105
+ loc.latitude = optional_content(node, 'x:lat', 'lat', "x:#{EEML5_HREF}")
106
+ loc.longitude = optional_content(node, 'x:lon', 'lon', "x:#{EEML5_HREF}")
107
+ loc.elevation = optional_content(node, 'x:ele', 'ele', "x:#{EEML5_HREF}")
109
108
  return loc
110
109
  end
111
110
 
@@ -139,20 +138,24 @@ module Eeml
139
138
  data = DataStream.new
140
139
  raise MissingAttribute.new(node.name, 'id') if node['id'].nil?
141
140
  data.identifier = node['id']
142
- node.find('x:tag', "x:#{EEML_HREF}").each do |tag_node|
141
+ node.find('x:tag', "x:#{EEML5_HREF}").each do |tag_node|
143
142
  data.tags << tag_node.content.strip
144
143
  end
145
144
 
146
- value_nodes = node.find('x:value', "x:#{EEML_HREF}")
145
+ value_nodes = node.find('x:value', "x:#{EEML5_HREF}")
147
146
  raise exception_for_node(node, DataMissingValue, "Data node is missing value node.") if value_nodes.empty?
148
147
  raise exception_for_node(node, DataHasMultipleValues, "Data node has multiple 'value' nodes.") if value_nodes.size > 1
149
148
 
150
149
  value_node = value_nodes.first
151
- data.min_value = value_node['minValue']
152
- data.max_value = value_node['maxValue']
153
- data.value = value_node.content.strip
154
150
 
155
- unit_nodes = node.find('x:unit', "x:#{EEML_HREF}")
151
+ value = Value.new
152
+ value.min_value = value_node['minValue']
153
+ value.max_value = value_node['maxValue']
154
+ value.value = value_node.content.strip
155
+
156
+ data.add_value(value)
157
+
158
+ unit_nodes = node.find('x:unit', "x:#{EEML5_HREF}")
156
159
  raise exception_for_node(node, DataHasMultipleUnits, "Data node has multiple 'unit' nodes.") if unit_nodes.size > 1
157
160
 
158
161
  unit_node = unit_nodes.first
@@ -4,11 +4,11 @@ require 'eeml/json_output'
4
4
  module Eeml
5
5
  class OutputRegistry # :nodoc:
6
6
  #look at the given xml, build and return a new v005 or 006 parser, accordingly
7
- def self.get_xml_output_for(version = EEML_VERSION)
7
+ def self.get_xml_output_for(version = EEML5_VERSION)
8
8
  LibXMLEemlOutputV005.new
9
9
  end
10
10
 
11
- def self.get_json_output_for(version = EEML_VERSION)
11
+ def self.get_json_output_for(version = EEML5_VERSION)
12
12
  JsonOutput.new
13
13
  end
14
14
 
data/lib/eeml.rb CHANGED
@@ -8,13 +8,14 @@ require 'json'
8
8
  require 'eeml/constants'
9
9
  require 'eeml/exceptions'
10
10
  require 'eeml/environment'
11
- require 'eeml/parser_registry'
11
+ require 'eeml/environment_builder'
12
12
  require 'eeml/output_registry'
13
+ require 'time'
13
14
 
14
15
  module Eeml
15
16
 
16
17
  # library version number
17
- VERSION = '0.0.7'
18
+ VERSION = '0.0.8'
18
19
 
19
20
  # TODO: put in some configuration file, not here
20
21
  LOCAL_EEML_SCHEMA_LOCATION = 'schemas/eeml/005.xsd'
@@ -0,0 +1,30 @@
1
+ {"datastreams":[
2
+ {"tags":["tagD0"],
3
+ "values":[{"value":"0","min_value":"-9999.0","max_value":"1022.0","recorded_at":"2009-02-11T10:56:56Z"}],
4
+ "unit":{"type":"basicSI","label":"Celsius","symbol":"C"},
5
+ "id":"0"},
6
+ {"values":[{"value":"33","min_value":"0.0","max_value":"1023.0","recorded_at":"2009-02-11T10:56:55Z"}],
7
+ "id":"1"},
8
+ {"tags":["tagD2a","tagD2b","tagD2c"],
9
+ "values":[{"value":"42.1","min_value":"23.4","max_value":"1021.0","recorded_at":"2009-02-11T10:55:10Z"}],
10
+ "id":"2"}
11
+ ],
12
+ "description":"description here",
13
+ "updated":"2009-02-11T10:56:56Z",
14
+ "status":"frozen",
15
+ "website":"http:\/\/example.com\/studio\/",
16
+ "email":"someone@example.com",
17
+ "feed":"http:\/\/example.com\/api\/1247.xml",
18
+ "location":{
19
+ "lat":"50.1",
20
+ "lon":"48.7",
21
+ "ele":"1.34",
22
+ "name":"Up on the roof (somewhere)",
23
+ "domain":"physical",
24
+ "exposure":"outdoor",
25
+ "disposition":"mobile"
26
+ },
27
+ "icon":"http:\/\/example.com\/some\/icon.gif",
28
+ "id":"1247",
29
+ "title":"title here",
30
+ "version":"0.6"}
@@ -149,7 +149,7 @@ class TestEnvironment < Test::Unit::TestCase
149
149
  assert_equal('http://example.com/some/icon.gif', env.icon)
150
150
  #env attrs
151
151
  assert_equal('1247', env.identifier)
152
- assert_equal('2009-02-11T10:56:56Z', env.updated.strftime(XML_TIME_FORMAT_STRING))
152
+ assert_equal('2009-02-11T10:56:56Z', env.updated.utc.iso8601)
153
153
  assert_equal('http://example.com/creator/', env.creator)
154
154
  end
155
155
 
@@ -312,7 +312,7 @@ class TestEnvironment < Test::Unit::TestCase
312
312
 
313
313
  #env attrs
314
314
  assert_equal('1247', env.identifier)
315
- assert_equal('2009-02-11T10:56:56Z', env.updated.strftime("%Y-%m-%dT%H:%M:%SZ"))
315
+ assert_equal('2009-02-11T10:56:56Z', env.updated.utc.iso8601)
316
316
  end
317
317
 
318
318
  test "location parses ok from json" do
@@ -360,6 +360,68 @@ class TestEnvironment < Test::Unit::TestCase
360
360
  end
361
361
  end
362
362
 
363
+ test "parses a v6 input file ok" do
364
+ env = create_env_from_json_v6_file_one
365
+ assert_not_nil env
366
+ assert_instance_of Environment, env
367
+ assert_equal('title here', env.title)
368
+ assert_equal('description here', env.description)
369
+ assert_equal('http://example.com/api/1247.xml', env.feed_url)
370
+ assert_equal('http://example.com/studio/', env.website)
371
+ assert_equal('frozen', env.status)
372
+ assert_equal('someone@example.com', env.email)
373
+ assert_equal('http://example.com/some/icon.gif', env.icon)
374
+
375
+ #env attrs
376
+ assert_equal('1247', env.identifier)
377
+ assert_equal('2009-02-11T10:56:56Z', env.updated.utc.iso8601)
378
+ end
379
+
380
+ test "location parses ok from json when parsing a v6 file" do
381
+ env = create_env_from_json_v6_file_one
382
+ assert_not_nil env.location
383
+ location = env.location
384
+ assert_equal "Up on the roof (somewhere)", location.name
385
+ assert_equal "50.1", location.latitude
386
+ assert_equal "48.7", location.longitude
387
+ assert_equal "1.34", location.elevation
388
+ assert_equal "physical", location.domain
389
+ assert_equal "outdoor", location.exposure
390
+ assert_equal "mobile", location.disposition
391
+ end
392
+
393
+ test "datastreams parse ok from v6 json" do
394
+ env = create_env_from_json_v6_file_one
395
+ assert_equal 3, env.datastreams.size
396
+
397
+ #the expected values for the datastreams in the test doc
398
+ expectations_list = [
399
+ #id, tag array, min, max, value, unit_symbol, unit_type, unit_value
400
+ ['0', ['tagD0'], '-9999.0', '1022.0', '0', 'C', 'basicSI', 'Celsius'],
401
+ ['1', [], '0.0', '1023.0', '33', nil, nil, nil],
402
+ ['2', ['tagD2a', 'tagD2b', 'tagD2c'], '23.4', '1021.0', '42.1', nil, nil, nil]
403
+ ]
404
+ env.datastreams.each_with_index do |ds, i|
405
+
406
+ e_identifier, e_tags, e_min_value, e_max_value, e_value, e_unit_symbol, e_unit_type, e_unit_value = expectations_list[i]
407
+
408
+ assert_equal e_identifier, ds.identifier
409
+
410
+ assert_equal e_tags.size, ds.tags.size, "should have right num of tags"
411
+
412
+ e_tags.each do |expected_tag|
413
+ ds.tags.member? expected_tag
414
+ end
415
+
416
+ assert_equal e_min_value, ds.min_value
417
+ assert_equal e_max_value, ds.max_value
418
+ assert_equal e_value, ds.value
419
+ assert_equal e_unit_symbol, ds.unit_symbol
420
+ assert_equal e_unit_type, ds.unit_type
421
+ assert_equal e_unit_value, ds.unit_value
422
+ end
423
+ end
424
+
363
425
  # --- -------------------------------------------------------
364
426
  # --- csv input stuff -------------------------------------------------------
365
427
  # --- -------------------------------------------------------
@@ -379,7 +441,7 @@ class TestEnvironment < Test::Unit::TestCase
379
441
  #TODO: note, can't unload the class before other tests, so be careful with this approach to conveniences.
380
442
  class Eeml::Environment
381
443
  def values_quick
382
- datastreams.map {|ds| ds.value}
444
+ datastreams.map {|ds| ds.values.last.value}
383
445
  end
384
446
  end
385
447
 
@@ -448,7 +510,7 @@ class TestEnvironment < Test::Unit::TestCase
448
510
  expected_json = File.read('test/data/doc_2_expected.json').rstrip
449
511
  expected_hash = JSON.parse(expected_json)
450
512
  output_hash = JSON.parse(output_json)
451
- assert_equal(expected_hash, output_hash)
513
+ assert_json_hashes_equal(expected_hash, output_hash)
452
514
  end
453
515
 
454
516
  test "basic output in public json format - no location" do
@@ -516,6 +578,10 @@ class TestEnvironment < Test::Unit::TestCase
516
578
  return create_env_from_json_file('test/data/doc_1.json')
517
579
  end
518
580
 
581
+ def create_env_from_json_v6_file_one
582
+ return create_env_from_json_file('test/data/doc_1_v6.json')
583
+ end
584
+
519
585
  def create_env_from_json_file(filename)
520
586
  json = File.read(filename)
521
587
  return Environment.new_from_json(json)
@@ -525,8 +591,4 @@ class TestEnvironment < Test::Unit::TestCase
525
591
  return nil if json.nil?
526
592
  json.gsub(/","/, '"' + "\n" + '"').sort
527
593
  end
528
-
529
-
530
-
531
-
532
594
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eeml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neill Bogie, Sam Mulube
@@ -30,7 +30,7 @@ cert_chain:
30
30
  yyRwZdVyDdsafg==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2009-09-29 00:00:00 +01:00
33
+ date: 2009-11-21 00:00:00 +00:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -100,13 +100,14 @@ extra_rdoc_files:
100
100
  - lib/eeml/constants.rb
101
101
  - lib/eeml/csv_parser.rb
102
102
  - lib/eeml/environment.rb
103
+ - lib/eeml/environment_builder.rb
103
104
  - lib/eeml/exceptions.rb
104
105
  - lib/eeml/json_environment_parser_v005.rb
106
+ - lib/eeml/json_environment_parser_v006.rb
105
107
  - lib/eeml/json_output.rb
106
108
  - lib/eeml/libxml_eeml_output_v005.rb
107
109
  - lib/eeml/libxml_eeml_parser_v005.rb
108
110
  - lib/eeml/output_registry.rb
109
- - lib/eeml/parser_registry.rb
110
111
  files:
111
112
  - CHANGELOG
112
113
  - LICENSE
@@ -119,18 +120,20 @@ files:
119
120
  - lib/eeml/constants.rb
120
121
  - lib/eeml/csv_parser.rb
121
122
  - lib/eeml/environment.rb
123
+ - lib/eeml/environment_builder.rb
122
124
  - lib/eeml/exceptions.rb
123
125
  - lib/eeml/json_environment_parser_v005.rb
126
+ - lib/eeml/json_environment_parser_v006.rb
124
127
  - lib/eeml/json_output.rb
125
128
  - lib/eeml/libxml_eeml_output_v005.rb
126
129
  - lib/eeml/libxml_eeml_parser_v005.rb
127
130
  - lib/eeml/output_registry.rb
128
- - lib/eeml/parser_registry.rb
129
131
  - schemas/eeml/005.xsd
130
132
  - test/data/complete_namespaced.xml
131
133
  - test/data/difficult_tag.xml
132
134
  - test/data/doc_1.json
133
135
  - test/data/doc_1.xml
136
+ - test/data/doc_1_v6.json
134
137
  - test/data/doc_2.xml
135
138
  - test/data/doc_2_expected.json
136
139
  - test/data/list.xml
metadata.gz.sig CHANGED
Binary file
@@ -1,18 +0,0 @@
1
- require 'eeml/libxml_eeml_parser_v005'
2
- require 'eeml/json_environment_parser_v005'
3
-
4
- module Eeml
5
- class ParserRegistry # :nodoc:
6
- #look at the given xml, build and return a new v005 or 006 parser, accordingly
7
- #this should work whether the xml given is for a single environment, or for a results list
8
- def self.get_xml_parser_for(xml_str)
9
- LibXMLEemlParserV005.new
10
- end
11
-
12
- def self.get_json_parser_for(json_str)
13
- JsonEnvironmentParserV005.new
14
- end
15
-
16
- end
17
- end
18
-