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,53 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ module DatastreamDefaults
5
+ include Xively::Parsers::XML::Helpers
6
+
7
+ def from_xml(xml)
8
+ begin
9
+ parsed = MultiXml.parse(xml)
10
+ raise InvalidXMLError, "Missing 'environment' node from base node" if parsed['eeml'].nil? || !parsed['eeml'].key?('environment')
11
+ return {} if parsed['eeml']['environment'].nil?
12
+ if parsed['eeml']['version'] == '5' || parsed['eeml']['xmlns'] == 'http://www.eeml.org/xsd/005'
13
+ transform_v1(parsed['eeml']['environment'])
14
+ else
15
+ transform_v2(parsed['eeml']['environment'])
16
+ end
17
+ rescue MultiXml::ParseError => e
18
+ raise InvalidXMLError, e.message
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # As produced by http://xively.com/api/v2/FEED_ID/datastreams/DATASTREAM_ID.xml
25
+ def transform_v2(xml)
26
+ validate_xml(xml)
27
+ datastream = convert_to_hash(xml['data'])
28
+ _extract_datastream(datastream).merge({
29
+ :feed_id => strip(xml,'id'),
30
+ :feed_creator => strip(xml,'creator')
31
+ })
32
+ end
33
+
34
+ # As produced by http://xively.com/api/v1/FEED_ID/datastreams/DATASTREAM_ID.xml
35
+ def transform_v1(xml)
36
+ validate_xml(xml)
37
+ datastream = convert_to_hash(xml['data'])
38
+ _extract_datastream_v1(datastream).merge({
39
+ :feed_id => strip(xml,'id'),
40
+ :updated => strip(xml,'updated'),
41
+ :feed_creator => 'http://www.haque.co.uk'
42
+ })
43
+ end
44
+
45
+ def validate_xml(xml)
46
+ raise InvalidXMLError, "Multiple 'data' nodes are not permitted for Datastream level XML" if xml['data'].is_a?(Array)
47
+ raise InvalidXMLError, "Missing 'data' node from source document" if xml['data'].nil?
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,7 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ class InvalidXMLError < Xively::ParserError; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,83 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ module FeedDefaults
5
+ include Xively::Parsers::XML::Helpers
6
+
7
+ def from_xml(xml)
8
+ begin
9
+ parsed = MultiXml.parse(xml)
10
+ raise InvalidXMLError, "Missing 'environment' node from base node" if parsed['eeml'].nil? || !parsed['eeml'].key?('environment')
11
+ return {} if parsed['eeml']['environment'].nil?
12
+ if parsed['eeml']['version'] == '5' || parsed['eeml']['xmlns'] == 'http://www.eeml.org/xsd/005'
13
+ transform_v1(parsed['eeml']['environment'])
14
+ else
15
+ transform_v2(parsed['eeml']['environment'])
16
+ end
17
+ rescue MultiXml::ParseError => e
18
+ raise InvalidXMLError, e.message
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # As produced by http://xively.com/api/v2/FEED_ID.xml
25
+ def transform_v2(xml)
26
+ location = xml['location'] || {}
27
+ user = xml['user'] || {}
28
+ {
29
+ :title => strip(xml,'title'),
30
+ :updated => strip(xml,'updated'),
31
+ :creator => strip(xml,'creator'),
32
+ :created => strip(xml,'created'),
33
+ :feed => strip(xml,'feed'),
34
+ :auto_feed_url => strip(xml,'auto_feed_url'),
35
+ :status => strip(xml,'status'),
36
+ :description => strip(xml,'description'),
37
+ :icon => strip(xml,'icon'),
38
+ :website => strip(xml,'website'),
39
+ :email => strip(xml,'email'),
40
+ :private => strip(xml,'private'),
41
+ :location_lon => strip(location,'lon'),
42
+ :location_lat => strip(location,'lat'),
43
+ :location_ele => strip(location,'ele'),
44
+ :location_name => strip(location,'name'),
45
+ :location_domain => strip(location,'domain'),
46
+ :location_exposure => strip(location,'exposure'),
47
+ :location_disposition => strip(location,'disposition'),
48
+ :owner_login => strip(user,'login'),
49
+ :datastreams => _extract_datastreams(xml['data'])
50
+ }.merge(sanitised_tags(xml))
51
+ end
52
+
53
+ # As produced by http://xively.com/api/v1/FEED_ID.xml
54
+ def transform_v1(xml)
55
+ location = xml['location'] || {}
56
+ user = xml['user'] || {}
57
+ {
58
+ :title => strip(xml,'title'),
59
+ :updated => strip(xml,'updated'),
60
+ :creator => 'http://www.haque.co.uk',
61
+ :created => strip(xml,'created'),
62
+ :feed => strip(xml,'feed'),
63
+ :status => strip(xml,'status'),
64
+ :description => strip(xml,'description'),
65
+ :icon => strip(xml,'icon'),
66
+ :website => strip(xml,'website'),
67
+ :email => strip(xml,'email'),
68
+ :location_lon => strip(location,'lon'),
69
+ :location_lat => strip(location,'lat'),
70
+ :location_ele => strip(location,'ele'),
71
+ :location_name => strip(location,'name'),
72
+ :location_domain => strip(location,'domain'),
73
+ :location_exposure => strip(location,'exposure'),
74
+ :location_disposition => strip(location,'disposition'),
75
+ :datastreams => _extract_datastreams_v1(xml['data'])
76
+ }
77
+ end
78
+
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,116 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ module Helpers
5
+
6
+ private
7
+
8
+ def strip(xml, value)
9
+ if xml.key?(value)
10
+ xml[value].nil? ? '' : xml[value].strip
11
+ else
12
+ nil
13
+ end
14
+ end
15
+
16
+ def convert_to_hash(val)
17
+ if val.class == String
18
+ {'__content__' => val}
19
+ else
20
+ val ? val.merge({'__content__' => val['__content__']}) : {}
21
+ end
22
+ end
23
+
24
+ def convert_to_array(val)
25
+ if val.is_a?(Hash)
26
+ val = [val]
27
+ else
28
+ [*val]
29
+ end
30
+ end
31
+
32
+ def _extract_datastreams(xml)
33
+ return unless xml
34
+ xml = convert_to_array(xml)
35
+ xml.collect do |ds|
36
+ _extract_datastream(ds)
37
+ end
38
+ end
39
+
40
+
41
+ def _extract_datastream(xml)
42
+ current_value = convert_to_hash(xml['current_value'])
43
+ unit = convert_to_hash(xml['unit'])
44
+ {
45
+ :current_value => strip(current_value,'__content__'),
46
+ :updated => strip(current_value,'at'),
47
+ :id => strip(xml,'id'),
48
+ :unit_symbol => strip(unit,'symbol'),
49
+ :unit_type => strip(unit,'type'),
50
+ :unit_label => strip(unit,'__content__'),
51
+ :min_value => strip(xml,'min_value'),
52
+ :max_value => strip(xml,'max_value'),
53
+ :datapoints => _extract_datapoints(xml['datapoints'])
54
+ }.merge(sanitised_tags(xml))
55
+ end
56
+
57
+ def _extract_datastreams_v1(xml)
58
+ return unless xml
59
+ xml = convert_to_array(xml)
60
+ xml.collect do |ds|
61
+ _extract_datastream_v1(ds)
62
+ end
63
+ end
64
+
65
+ def _extract_datastream_v1(xml)
66
+ unit = convert_to_hash(xml['unit'])
67
+ value = convert_to_hash(xml['value'])
68
+ {
69
+ :current_value => strip(value,'__content__'),
70
+ :id => strip(xml,'id'),
71
+ :unit_symbol => strip(unit,'symbol'),
72
+ :unit_type => strip(unit,'type'),
73
+ :unit_label => strip(unit,'__content__'),
74
+ :min_value => strip(value,'minValue'),
75
+ :max_value => strip(value,'maxValue')
76
+ }.merge(sanitised_tags(xml))
77
+ end
78
+
79
+ def _extract_datapoints(xml)
80
+ return unless xml
81
+ value = xml['value']
82
+ value = convert_to_array(value)
83
+ value.collect do |dp|
84
+ _extract_datapoint(dp)
85
+ end
86
+ end
87
+
88
+ def _extract_datapoint(xml)
89
+ value = convert_to_hash(xml)
90
+ {
91
+ :at => strip(value,'at'),
92
+ :value => strip(value,'__content__')
93
+ }
94
+ end
95
+
96
+ def _extract_tags(xml)
97
+ if xml.class != Array
98
+ xml = [xml]
99
+ end
100
+ if (tags = xml.collect { |t| "#{t}".strip }).any?
101
+ Xively::CSV.generate_line(tags.delete_if { |v| v.to_s.strip == "" }.sort{ |a,b| a.downcase <=> b.downcase}).strip
102
+ end
103
+ end
104
+
105
+ # Keep blank tags but delete if value is nil
106
+ def sanitised_tags(xml)
107
+ if xml.key?('tag')
108
+ {:tags => _extract_tags(xml['tag'])}
109
+ else
110
+ {}
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,46 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ module KeyDefaults
5
+ def from_xml(xml)
6
+ begin
7
+ xml = Nokogiri::XML(xml) do |config|
8
+ config.strict.nonet
9
+ end
10
+ hash = {}
11
+ hash["id"] = xml.at_xpath("//id").content if xml.at_xpath("//id")
12
+ hash["expires_at"] = xml.at_xpath("//expires-at").content if xml.at_xpath("//expires-at")
13
+ hash["key"] = xml.at_xpath("//api-key").content if xml.at_xpath("//api-key")
14
+ hash["label"] = xml.at_xpath("//label").content if xml.at_xpath("//label")
15
+ hash["user"] = xml.at_xpath("//user").content if xml.at_xpath("//user")
16
+ hash["private_access"] = xml.at_xpath("//private-access").content if xml.at_xpath("//private-access")
17
+
18
+ hash["permissions"] = xml.xpath("//key/permissions/permission").collect { |permission|
19
+ access_methods = permission.xpath("access-methods/access-method").collect { |method|
20
+ method.content.to_s.downcase
21
+ }
22
+ resources = permission.xpath("resources/resource").collect { |resource|
23
+ { "feed_id" => resource.at_xpath("feed-id").content,
24
+ "datastream_id" => resource.at_xpath("datastream-id").content,
25
+ "datastream_trigger_id" => resource.at_xpath("datastream-trigger-id").content
26
+ }.delete_if_nil_value
27
+ }
28
+ {
29
+ "referer" => permission.at_xpath("referer").content,
30
+ "source_ip" => permission.at_xpath("source-ip").content,
31
+ "private_access" => permission.at_xpath("private-access").content,
32
+ "access_methods" => access_methods,
33
+ "resources" => resources
34
+ }.delete_if_nil_value
35
+ }
36
+
37
+ hash
38
+ rescue Nokogiri::SyntaxError => e
39
+ raise InvalidXMLError, e.message
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,28 @@
1
+ module Xively
2
+ module Parsers
3
+ module XML
4
+ module TriggerDefaults
5
+ def from_xml(xml)
6
+ begin
7
+ xml = Nokogiri::XML(xml) do |config|
8
+ config.strict.nonet
9
+ end
10
+ hash = {}
11
+ hash["id"] = xml.at_xpath("//id").content if xml.at_xpath("//id")
12
+ hash["url"] = xml.at_xpath("//url").content if xml.at_xpath("//url")
13
+ hash["trigger_type"] = xml.at_xpath("//trigger-type").content if xml.at_xpath("//trigger-type")
14
+ hash["threshold_value"] = xml.at_xpath("//threshold-value").content if xml.at_xpath("//threshold-value")
15
+ hash["notified_at"] = xml.at_xpath("//notified-at").content if xml.at_xpath("//notified-at")
16
+ hash["user"] = xml.at_xpath("//user").content if xml.at_xpath("//user")
17
+ hash["environment_id"] = xml.at_xpath("//environment-id").content if xml.at_xpath("//environment-id")
18
+ hash["stream_id"] = xml.at_xpath("//stream-id").content if xml.at_xpath("//stream-id")
19
+ hash
20
+ rescue Nokogiri::SyntaxError => e
21
+ raise InvalidXMLError, e.message
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,67 @@
1
+ module Xively
2
+ class Permission
3
+ ALLOWED_KEYS = %w(label access_methods referer source_ip minimum_interval resources)
4
+ ALLOWED_KEYS.each { |key| attr_accessor(key.to_sym) }
5
+ NESTED_KEYS = %w(resources)
6
+
7
+ include Validations
8
+
9
+ def valid?
10
+ pass = true
11
+ if access_methods.nil? || access_methods.empty?
12
+ errors[:access_methods] = ["can't be blank"]
13
+ pass = false
14
+ end
15
+
16
+ resources.each do |resource|
17
+ unless resource.valid?
18
+ resource.errors.each do |attr, resource_errors|
19
+ errors["resources_#{attr}".to_sym] = ([*errors["resources_#{attr}".to_sym]] | [*resource_errors]).compact
20
+ end
21
+ pass = false
22
+ end
23
+ end
24
+
25
+ return pass
26
+ end
27
+
28
+ # Build an instance from a Hash only
29
+ def initialize(input = {})
30
+ self.attributes = input
31
+ end
32
+
33
+ def resources
34
+ return [] if @resources.nil?
35
+ @resources
36
+ end
37
+
38
+ def resources=(array)
39
+ return unless array.is_a?(Array)
40
+ @resources = []
41
+ array.each do |resource|
42
+ if resource.is_a?(Resource)
43
+ @resources << resource
44
+ elsif resource.is_a?(Hash)
45
+ @resources << Resource.new(resource)
46
+ end
47
+ end
48
+ end
49
+
50
+ def attributes
51
+ h = {}
52
+ ALLOWED_KEYS.each do |key|
53
+ value = self.send(key)
54
+ h[key] = value unless value.nil?
55
+ end
56
+ return h
57
+ end
58
+
59
+ def attributes=(input)
60
+ return if input.nil?
61
+ input.deep_stringify_keys!
62
+ ALLOWED_KEYS.each { |key| self.send("#{key}=", input[key]) }
63
+ NESTED_KEYS.each { |key| self.send("#{key}=", input["#{key}_attributes"]) unless input["#{key}_attributes"].nil? }
64
+ return attributes
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,43 @@
1
+ module Xively
2
+ class Resource
3
+ ALLOWED_KEYS = %w(feed_id datastream_id datastream_trigger_id)
4
+ ALLOWED_KEYS.each { |key| attr_accessor(key.to_sym) }
5
+
6
+ include Validations
7
+
8
+ def valid?
9
+ pass = true
10
+ if feed_id.blank? && datastream_id.blank? && datastream_trigger_id.blank?
11
+ errors[:feed_id] = "Must supply at least one of feed_id (optionally with a datastream_id) or datastream_trigger_id"
12
+ pass = false
13
+ end
14
+
15
+ if feed_id.blank? && !datastream_id.blank?
16
+ errors[:feed_id] = ["can't be blank if we have supplied a datastream_id"]
17
+ pass = false
18
+ end
19
+
20
+ return pass
21
+ end
22
+
23
+ def initialize(input = {})
24
+ self.attributes = input
25
+ end
26
+
27
+ def attributes
28
+ h = {}
29
+ ALLOWED_KEYS.each do |key|
30
+ value = self.send(key)
31
+ h[key] = value unless value.nil?
32
+ end
33
+ return h
34
+ end
35
+
36
+ def attributes=(input)
37
+ return if input.nil?
38
+ input.deep_stringify_keys!
39
+ ALLOWED_KEYS.each { |key| self.send("#{key}=", input[key]) }
40
+ return attributes
41
+ end
42
+ end
43
+ end