xively-rb 0.2.09

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.
Files changed (124) hide show
  1. data/.gitignore +13 -0
  2. data/.rbenv-version +1 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +7 -0
  6. data/CHANGELOG.md +91 -0
  7. data/CONTRIBUTING.md +95 -0
  8. data/Gemfile +15 -0
  9. data/LICENSE.md +13 -0
  10. data/README.md +10 -0
  11. data/Rakefile +25 -0
  12. data/ci/build_hudson.sh +24 -0
  13. data/init.rb +2 -0
  14. data/lib/xively-rb.rb +44 -0
  15. data/lib/xively-rb/array_extensions.rb +6 -0
  16. data/lib/xively-rb/base.rb +52 -0
  17. data/lib/xively-rb/base/instance_methods.rb +28 -0
  18. data/lib/xively-rb/client.rb +43 -0
  19. data/lib/xively-rb/datapoint.rb +72 -0
  20. data/lib/xively-rb/datastream.rb +127 -0
  21. data/lib/xively-rb/exceptions.rb +5 -0
  22. data/lib/xively-rb/feed.rb +109 -0
  23. data/lib/xively-rb/hash_extensions.rb +16 -0
  24. data/lib/xively-rb/helpers.rb +41 -0
  25. data/lib/xively-rb/key.rb +99 -0
  26. data/lib/xively-rb/nil_content.rb +15 -0
  27. data/lib/xively-rb/object_extensions.rb +6 -0
  28. data/lib/xively-rb/parsers/csv/datastream_defaults.rb +50 -0
  29. data/lib/xively-rb/parsers/csv/feed_defaults.rb +97 -0
  30. data/lib/xively-rb/parsers/defaults.rb +15 -0
  31. data/lib/xively-rb/parsers/json/datapoint_defaults.rb +16 -0
  32. data/lib/xively-rb/parsers/json/datastream_defaults.rb +58 -0
  33. data/lib/xively-rb/parsers/json/feed_defaults.rb +114 -0
  34. data/lib/xively-rb/parsers/json/key_defaults.rb +20 -0
  35. data/lib/xively-rb/parsers/json/search_result_defaults.rb +24 -0
  36. data/lib/xively-rb/parsers/json/trigger_defaults.rb +16 -0
  37. data/lib/xively-rb/parsers/xml/datapoint_defaults.rb +27 -0
  38. data/lib/xively-rb/parsers/xml/datastream_defaults.rb +53 -0
  39. data/lib/xively-rb/parsers/xml/errors.rb +7 -0
  40. data/lib/xively-rb/parsers/xml/feed_defaults.rb +83 -0
  41. data/lib/xively-rb/parsers/xml/helpers.rb +116 -0
  42. data/lib/xively-rb/parsers/xml/key_defaults.rb +46 -0
  43. data/lib/xively-rb/parsers/xml/trigger_defaults.rb +28 -0
  44. data/lib/xively-rb/permission.rb +67 -0
  45. data/lib/xively-rb/resource.rb +43 -0
  46. data/lib/xively-rb/search_result.rb +68 -0
  47. data/lib/xively-rb/string_extensions.rb +6 -0
  48. data/lib/xively-rb/templates/csv/datapoint_defaults.rb +22 -0
  49. data/lib/xively-rb/templates/csv/datastream_defaults.rb +43 -0
  50. data/lib/xively-rb/templates/csv/feed_defaults.rb +47 -0
  51. data/lib/xively-rb/templates/defaults.rb +14 -0
  52. data/lib/xively-rb/templates/json/datapoint_defaults.rb +15 -0
  53. data/lib/xively-rb/templates/json/datastream_defaults.rb +61 -0
  54. data/lib/xively-rb/templates/json/feed_defaults.rb +90 -0
  55. data/lib/xively-rb/templates/json/key_defaults.rb +39 -0
  56. data/lib/xively-rb/templates/json/search_result_defaults.rb +42 -0
  57. data/lib/xively-rb/templates/json/trigger_defaults.rb +21 -0
  58. data/lib/xively-rb/templates/xml/datapoint_defaults.rb +25 -0
  59. data/lib/xively-rb/templates/xml/datastream_defaults.rb +66 -0
  60. data/lib/xively-rb/templates/xml/feed_defaults.rb +112 -0
  61. data/lib/xively-rb/templates/xml/search_result_defaults.rb +118 -0
  62. data/lib/xively-rb/templates/xml_headers.rb +17 -0
  63. data/lib/xively-rb/trigger.rb +66 -0
  64. data/lib/xively-rb/validations.rb +9 -0
  65. data/lib/xively-rb/version.rb +3 -0
  66. data/spec/fixtures/models.rb +81 -0
  67. data/spec/spec_helper.rb +29 -0
  68. data/spec/support/contain_datapoint_eeml_matcher.rb +16 -0
  69. data/spec/support/contain_datastream_eeml_matcher.rb +60 -0
  70. data/spec/support/contain_feed_eeml_matcher.rb +98 -0
  71. data/spec/support/datapoint_helper.rb +53 -0
  72. data/spec/support/datastream_helper.rb +324 -0
  73. data/spec/support/describe_eeml_matcher.rb +23 -0
  74. data/spec/support/feed_helper.rb +783 -0
  75. data/spec/support/fully_represent_datapoint_matcher.rb +30 -0
  76. data/spec/support/fully_represent_datastream_matcher.rb +96 -0
  77. data/spec/support/fully_represent_feed_matcher.rb +234 -0
  78. data/spec/support/fully_represent_key_matcher.rb +74 -0
  79. data/spec/support/fully_represent_search_result_matcher.rb +67 -0
  80. data/spec/support/fully_represent_trigger_matcher.rb +29 -0
  81. data/spec/support/key_helper.rb +74 -0
  82. data/spec/support/search_result_helper.rb +252 -0
  83. data/spec/support/trigger_helper.rb +51 -0
  84. data/spec/xively-rb/array_extensions_spec.rb +9 -0
  85. data/spec/xively-rb/base/instance_methods_spec.rb +109 -0
  86. data/spec/xively-rb/base_spec.rb +56 -0
  87. data/spec/xively-rb/client_spec.rb +51 -0
  88. data/spec/xively-rb/datapoint_spec.rb +187 -0
  89. data/spec/xively-rb/datastream_spec.rb +344 -0
  90. data/spec/xively-rb/feed_spec.rb +341 -0
  91. data/spec/xively-rb/hash_extensions_spec.rb +20 -0
  92. data/spec/xively-rb/helpers_spec.rb +56 -0
  93. data/spec/xively-rb/key_spec.rb +198 -0
  94. data/spec/xively-rb/parsers/csv/datastream_defaults_spec.rb +110 -0
  95. data/spec/xively-rb/parsers/csv/feed_defaults_spec.rb +234 -0
  96. data/spec/xively-rb/parsers/json/datapoint_defaults_spec.rb +21 -0
  97. data/spec/xively-rb/parsers/json/datastream_defaults_spec.rb +105 -0
  98. data/spec/xively-rb/parsers/json/feed_defaults_spec.rb +45 -0
  99. data/spec/xively-rb/parsers/json/key_defaults_spec.rb +14 -0
  100. data/spec/xively-rb/parsers/json/search_result_defaults_spec.rb +18 -0
  101. data/spec/xively-rb/parsers/json/trigger_defaults_spec.rb +22 -0
  102. data/spec/xively-rb/parsers/xml/datapoint_defaults_spec.rb +19 -0
  103. data/spec/xively-rb/parsers/xml/datastream_defaults_spec.rb +148 -0
  104. data/spec/xively-rb/parsers/xml/feed_defaults_spec.rb +254 -0
  105. data/spec/xively-rb/parsers/xml/key_defaults_spec.rb +22 -0
  106. data/spec/xively-rb/parsers/xml/trigger_defaults_spec.rb +22 -0
  107. data/spec/xively-rb/search_result_spec.rb +257 -0
  108. data/spec/xively-rb/string_extensions_spec.rb +12 -0
  109. data/spec/xively-rb/templates/csv/datapoint_defaults_spec.rb +41 -0
  110. data/spec/xively-rb/templates/csv/datastream_defaults_spec.rb +131 -0
  111. data/spec/xively-rb/templates/csv/feed_defaults_spec.rb +78 -0
  112. data/spec/xively-rb/templates/json/datapoint_defaults_spec.rb +14 -0
  113. data/spec/xively-rb/templates/json/datastream_defaults_spec.rb +170 -0
  114. data/spec/xively-rb/templates/json/feed_defaults_spec.rb +399 -0
  115. data/spec/xively-rb/templates/json/key_defaults_spec.rb +29 -0
  116. data/spec/xively-rb/templates/json/search_result_defaults_spec.rb +37 -0
  117. data/spec/xively-rb/templates/json/trigger_defaults_spec.rb +19 -0
  118. data/spec/xively-rb/templates/xml/datapoint_defaults_spec.rb +14 -0
  119. data/spec/xively-rb/templates/xml/datastream_defaults_spec.rb +113 -0
  120. data/spec/xively-rb/templates/xml/feed_defaults_spec.rb +131 -0
  121. data/spec/xively-rb/templates/xml/search_result_defaults_spec.rb +44 -0
  122. data/spec/xively-rb/trigger_spec.rb +157 -0
  123. data/xively-rb.gemspec +41 -0
  124. metadata +333 -0
@@ -0,0 +1,15 @@
1
+ class NilClass
2
+ def content
3
+ end
4
+
5
+ def value
6
+ end
7
+
8
+ def iso8601(precision = nil)
9
+ end
10
+
11
+ def empty?
12
+ true
13
+ end
14
+ end
15
+
@@ -0,0 +1,6 @@
1
+ class Object
2
+ def blank?
3
+ respond_to?(:empty?) ? empty? : !self
4
+ end
5
+ end
6
+
@@ -0,0 +1,50 @@
1
+ module Xively
2
+ module Parsers
3
+ module CSV
4
+ module DatastreamDefaults
5
+ def from_csv(csv, csv_version = nil)
6
+ begin
7
+ rows = Xively::CSV.parse(csv.strip)
8
+ rescue Exception => e
9
+ # this might be a FasterCSV or CSV exception depending on whether
10
+ # we are running under 1.8.x or 1.9.x
11
+ raise InvalidCSVError, e.message
12
+ end
13
+
14
+ version = FeedDefaults.detect_version(rows, csv_version)
15
+
16
+ raise InvalidCSVError, "CSV is invalid. Submitted data appears to be empty" if rows.nil?
17
+
18
+ if version == :v1
19
+ raise InvalidCSVError, "CSV is invalid. Can only construct a Xively::Datastream object from a single row of data" if rows.size > 1
20
+ row = rows.first
21
+ raise InvalidCSVError, "CSV is invalid. Too many fields; must only be a single value" if row.size > 1
22
+ return { "current_value" => row[0].to_s.strip }
23
+ else
24
+ row_sizes = rows.collect { |row| row.size }.uniq
25
+ raise InvalidCSVError, "CSV is invalid. Too many fields; must only be a single value, or a timestamp and a value" if row_sizes.max > 2
26
+
27
+ if rows.size == 1
28
+ # capture single lines (normal case)
29
+ row = rows.first
30
+
31
+ if row.size == 2
32
+ return { "updated" => row[0].to_s.strip, "current_value" => row[1].to_s.strip }
33
+ else
34
+ return { "current_value" => row[0].to_s.strip }
35
+ end
36
+ else
37
+ # capture multiple lines
38
+ raise InvalidCSVError, "CSV is invalid. If multiple values are included, then a timestamp and value must be submitted for every row" if row_sizes.min < 2
39
+
40
+ return { "datapoints" => rows.collect { |row| { "at" => row[0].to_s.strip, "value" => row[1].to_s.strip } } }
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,97 @@
1
+ module Xively
2
+ module Parsers
3
+ module CSV
4
+ class UnknownVersionError < Xively::ParserError ; end
5
+ class InvalidCSVError < Xively::ParserError ; end
6
+
7
+ module FeedDefaults
8
+
9
+ class << self
10
+ def detect_version(rows, version = nil)
11
+ return version if version
12
+ return :v2 if rows.size >= 2
13
+ return :v1 if rows.size == 1 && rows.first.size != 2
14
+ raise UnknownVersionError, "CSV Version could not be detected"
15
+ end
16
+ end
17
+
18
+ def from_csv(csv, csv_version = nil)
19
+ begin
20
+ rows = Xively::CSV.parse(csv.strip)
21
+ rescue Exception => e
22
+ # this might be a FasterCSV or CSV exception depending on whether
23
+ # we are running under 1.8.x or 1.9.x
24
+ raise InvalidCSVError, e.message
25
+ end
26
+
27
+ version = FeedDefaults.detect_version(rows, csv_version)
28
+
29
+ hash = Hash.new
30
+
31
+ raise InvalidCSVError, "Submitted CSV is empty." if rows.empty?
32
+
33
+ if version == :v2
34
+ hash["datastreams"] = extract_datastreams(rows)
35
+ elsif version == :v1
36
+ raise InvalidCSVError, "CSV is invalid. Currently we can only accept CSV for your most recent set of values. You have submitted #{rows.size} rows of data." if rows.size > 1
37
+ hash["datastreams"] = []
38
+ rows.first.each_with_index do |current_value, stream_id|
39
+ hash["datastreams"] << { "id" => stream_id.to_s.strip, "current_value" => current_value.to_s.strip }
40
+ end
41
+ end
42
+ hash["csv_version"] = version
43
+ hash
44
+ end
45
+
46
+ private
47
+
48
+ # This is used by v2 only
49
+ def extract_datastreams(rows)
50
+ row_sizes = rows.collect { |row| row.size }.uniq
51
+ row_ids = rows.collect { |row| row.first.to_s.strip }.uniq
52
+
53
+ raise InvalidCSVError, "CSV is invalid. Incorrect number of fields" if row_sizes.max > 3 || row_sizes.min <= 1
54
+
55
+ datastream_buckets = {}
56
+
57
+ # iterate through each row bucketing by datastream id
58
+ rows.each do |row|
59
+ # this splits each row into the id first element, and an array containing the rest of the row
60
+ id, *rest = *row
61
+
62
+ # make empty array if it doesn't exist
63
+ datastream_buckets[id.to_s.strip] ||= []
64
+ # add this row to the correct bucketed array
65
+ datastream_buckets[id.to_s.strip] << rest
66
+ end
67
+
68
+ datastreams = []
69
+
70
+ row_ids.each do |datastream_id|
71
+ datastream_data = datastream_buckets[datastream_id]
72
+
73
+ if datastream_data.size == 1
74
+ # single value for this datastream - current normal
75
+ data = datastream_data[0]
76
+ if data.size == 2
77
+ datastreams << { "id" => datastream_id, "updated" => data[0].to_s.strip, "current_value" => data[1].to_s.strip }
78
+ else
79
+ datastreams << { "id" => datastream_id, "current_value" => data[0].to_s.strip }
80
+ end
81
+ else
82
+ # multiple values for this datastream
83
+ raise InvalidCSVError, "CSV is invalid. If multiple values given they must include a timestamp for all values" if datastream_data.collect { |d| d.size }.min < 2
84
+
85
+ datapoints = datastream_data.collect { |datapoint_data| { "at" => datapoint_data[0].to_s.strip, "value" => datapoint_data[1].to_s.strip } }
86
+
87
+ datastreams << { "id" => datastream_id, "datapoints" => datapoints }
88
+ end
89
+ end
90
+
91
+ return datastreams
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+
@@ -0,0 +1,15 @@
1
+ require 'xively-rb/parsers/json/feed_defaults'
2
+ require 'xively-rb/parsers/json/search_result_defaults'
3
+ require 'xively-rb/parsers/json/datastream_defaults'
4
+ require 'xively-rb/parsers/json/datapoint_defaults'
5
+ require 'xively-rb/parsers/json/trigger_defaults'
6
+ require 'xively-rb/parsers/json/key_defaults'
7
+ require 'xively-rb/parsers/xml/errors'
8
+ require 'xively-rb/parsers/xml/helpers'
9
+ require 'xively-rb/parsers/xml/feed_defaults'
10
+ require 'xively-rb/parsers/xml/datastream_defaults'
11
+ require 'xively-rb/parsers/xml/datapoint_defaults'
12
+ require 'xively-rb/parsers/xml/trigger_defaults'
13
+ require 'xively-rb/parsers/xml/key_defaults'
14
+ require 'xively-rb/parsers/csv/feed_defaults'
15
+ require 'xively-rb/parsers/csv/datastream_defaults'
@@ -0,0 +1,16 @@
1
+ module Xively
2
+ module Parsers
3
+ module JSON
4
+ module DatapointDefaults
5
+ def from_json(json)
6
+ begin
7
+ MultiJson.load(json)
8
+ rescue MultiJson::DecodeError => e
9
+ raise InvalidJSONError, e.message
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,58 @@
1
+ module Xively
2
+ module Parsers
3
+ module JSON
4
+ module DatastreamDefaults
5
+ def from_json(json)
6
+ begin
7
+ hash = MultiJson.load(json)
8
+ rescue MultiJson::DecodeError => e
9
+ raise InvalidJSONError, e.message
10
+ end
11
+ raise InvalidJSONError, "JSON doesn't appear to be a hash" unless hash.is_a?(Hash)
12
+ case hash['version']
13
+ when '0.6-alpha'
14
+ transform_0_6_alpha(hash)
15
+ when '1.0.0', nil
16
+ transform_1_0_0(hash)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ # As produced by http://xively.com/api/v2/FEED_ID/datastreams/DATASTREAM_ID.json
23
+ def transform_1_0_0(hash)
24
+ hash["id"] = hash.delete("id")
25
+ hash["updated"] = hash.delete("at")
26
+ hash["current_value"] = hash.delete("current_value")
27
+ hash["tags"] = join_tags(hash["tags"])
28
+ if unit = hash.delete('unit')
29
+ hash['unit_type'] = unit['type']
30
+ hash['unit_symbol'] = unit['symbol']
31
+ hash['unit_label'] = unit['label']
32
+ end
33
+ hash
34
+ end
35
+
36
+ # As produced by http://xively.com/api/v1/FEED_ID/datastreams/DATASTREAM_ID.json
37
+ def transform_0_6_alpha(hash)
38
+ hash["id"] = hash.delete("id")
39
+ if values = [*hash["values"]].first
40
+ hash["updated"] = hash["values"].first.delete("recorded_at")
41
+ hash["current_value"] = hash["values"].first.delete("value")
42
+ hash["max_value"] = hash["values"].first.delete("max_value")
43
+ hash["min_value"] = hash["values"].first.delete("min_value")
44
+ end
45
+ hash["tags"] = join_tags(hash["tags"])
46
+ if unit = hash.delete('unit')
47
+ hash['unit_type'] = unit['type']
48
+ hash['unit_symbol'] = unit['symbol']
49
+ hash['unit_label'] = unit['label']
50
+ end
51
+ hash
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,114 @@
1
+ module Xively
2
+ module Parsers
3
+ module JSON
4
+ class InvalidJSONError < Xively::ParserError; end
5
+ module FeedDefaults
6
+
7
+ include Xively::Helpers
8
+
9
+ def from_json(json)
10
+ begin
11
+ hash = MultiJson.load(json)
12
+ rescue MultiJson::DecodeError => e
13
+ raise InvalidJSONError, e.message
14
+ end
15
+ raise InvalidJSONError, "JSON doesn't appear to be a hash" unless hash.is_a?(Hash)
16
+ case hash['version']
17
+ when '0.6-alpha', '0.6'
18
+ transform_0_6_alpha(hash)
19
+ else
20
+ transform_1_0_0(hash)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ # As produced by http://xively.com/api/v2/FEED_ID.json
27
+ def transform_1_0_0(hash)
28
+ hash["updated"] = hash["updated"]
29
+ hash["created"] = hash["created"]
30
+ hash["status"] = hash["status"]
31
+ hash["tags"] = join_tags(hash["tags"])
32
+ hash["datastreams"] = hash["datastreams"].collect do |datastream|
33
+ unit_hash = {}
34
+ if unit = datastream.delete('unit')
35
+ unit_hash['unit_type'] = unit['type']
36
+ unit_hash['unit_symbol'] = unit['symbol']
37
+ unit_hash['unit_label'] = unit['label']
38
+ end
39
+ {
40
+ "id" => datastream["id"],
41
+ "current_value" => datastream["current_value"],
42
+ "min_value" => datastream["min_value"],
43
+ "max_value" => datastream["max_value"],
44
+ "updated" => datastream["at"],
45
+ "tags" => join_tags(datastream["tags"]),
46
+ "datapoints" => setup_datapoints(datastream["datapoints"])
47
+ }.merge(unit_hash)
48
+ end if hash["datastreams"]
49
+ if location = hash.delete("location")
50
+ hash["location_disposition"] = location["disposition"]
51
+ hash["location_domain"] = location["domain"]
52
+ hash["location_ele"] = location["ele"]
53
+ hash["location_exposure"] = location["exposure"]
54
+ hash["location_lat"] = location["lat"]
55
+ hash["location_lon"] = location["lon"]
56
+ hash["location_name"] = location["name"]
57
+ end
58
+ if owner = hash.delete("user")
59
+ hash["owner_login"] = owner["login"]
60
+ end
61
+ hash
62
+ end
63
+
64
+ # As produced by http://xively.com/api/v1/FEED_ID.json
65
+ def transform_0_6_alpha(hash)
66
+ hash["retrieved_at"] = hash["updated"]
67
+ hash["state"] = hash["status"]
68
+ if hash["datastreams"]
69
+ hash["datastreams"] = hash["datastreams"].collect do |datastream|
70
+ unit_hash = {}
71
+ if unit = datastream.delete('unit')
72
+ unit_hash['unit_type'] = unit['type']
73
+ unit_hash['unit_symbol'] = unit['symbol']
74
+ unit_hash['unit_label'] = unit['label']
75
+ end
76
+ value_hash = {}
77
+ if datastream["values"].size >= 1
78
+ value_hash["current_value"] = datastream["values"].first["value"]
79
+ value_hash["min_value"] = datastream["values"].first["min_value"]
80
+ value_hash["max_value"] = datastream["values"].first["max_value"]
81
+ value_hash["updated"] = datastream["values"].first["recorded_at"]
82
+ end
83
+ {
84
+ "id" => datastream["id"],
85
+ "tags" => join_tags(datastream["tags"]),
86
+ }.merge(value_hash).merge(unit_hash)
87
+ end
88
+ if location = hash.delete("location")
89
+ hash["location_disposition"] = location["disposition"]
90
+ hash["location_domain"] = location["domain"]
91
+ hash["location_ele"] = location["ele"]
92
+ hash["location_exposure"] = location["exposure"]
93
+ hash["location_lat"] = location["lat"]
94
+ hash["location_lon"] = location["lon"]
95
+ hash["location_name"] = location["name"]
96
+ end
97
+ end
98
+ hash
99
+ end
100
+
101
+ def setup_datapoints(datapoints)
102
+ return [] unless datapoints
103
+ datapoints.collect do |datapoint|
104
+ {
105
+ "at" => datapoint["at"],
106
+ "value" => datapoint["value"]
107
+ }
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
@@ -0,0 +1,20 @@
1
+ module Xively
2
+ module Parsers
3
+ module JSON
4
+ module KeyDefaults
5
+ def from_json(json)
6
+ begin
7
+ hash = MultiJson.load(json)["key"]
8
+ rescue MultiJson::DecodeError => e
9
+ raise InvalidJSONError, e.message
10
+ end
11
+ raise InvalidJSONError, "JSON doesn't appear to be a hash" unless hash.is_a?(Hash)
12
+ hash["id"] = hash.delete("id")
13
+ hash["key"] = hash.delete("api_key")
14
+ hash
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,24 @@
1
+ module Xively
2
+ module Parsers
3
+ module JSON
4
+ module SearchResultDefaults
5
+ include FeedDefaults
6
+
7
+ def from_json(json)
8
+ begin
9
+ hash = MultiJson.load(json)
10
+ rescue MultiJson::DecodeError => e
11
+ raise InvalidJSONError, e.message
12
+ end
13
+ raise InvalidJSONError, "JSON doesn't appear to be a hash" unless hash.is_a?(Hash)
14
+
15
+ hash['results'] = hash['results'].collect do |feed|
16
+ transform_1_0_0(feed)
17
+ end
18
+ hash
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ module Xively
2
+ module Parsers
3
+ module JSON
4
+ module TriggerDefaults
5
+ def from_json(json)
6
+ begin
7
+ MultiJson.load(json)
8
+ rescue MultiJson::DecodeError => e
9
+ raise InvalidJSONError, e.message
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,27 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ module DatapointDefaults
5
+
6
+ include Xively::Parsers::XML::Helpers
7
+
8
+ def from_xml(xml)
9
+ begin
10
+ parsed = MultiXml.parse(xml)
11
+ raise InvalidXMLError, "Missing 'environment' node from base node" if parsed['eeml'].nil? || !parsed['eeml'].key?('environment')
12
+ return {} if parsed['eeml']['environment'].nil?
13
+ datastream = parsed['eeml']['environment']['data']
14
+ raise InvalidXMLError, "Multiple 'data' nodes are not permitted for Datapoint level XML" if datastream.is_a?(Array)
15
+ datapoint = datastream['datapoints']
16
+ raise InvalidXMLError, "Multiple 'value' nodes are not permitted for Datapoint level XML" if datapoint.is_a?(Array)
17
+ _extract_datapoints(datapoint).first
18
+ rescue MultiXml::ParseError => e
19
+ raise InvalidXMLError, e.message
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
27
+