eeml 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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
-