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.
- data/.gitignore +13 -0
- data/.rbenv-version +1 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +91 -0
- data/CONTRIBUTING.md +95 -0
- data/Gemfile +15 -0
- data/LICENSE.md +13 -0
- data/README.md +10 -0
- data/Rakefile +25 -0
- data/ci/build_hudson.sh +24 -0
- data/init.rb +2 -0
- data/lib/xively-rb.rb +44 -0
- data/lib/xively-rb/array_extensions.rb +6 -0
- data/lib/xively-rb/base.rb +52 -0
- data/lib/xively-rb/base/instance_methods.rb +28 -0
- data/lib/xively-rb/client.rb +43 -0
- data/lib/xively-rb/datapoint.rb +72 -0
- data/lib/xively-rb/datastream.rb +127 -0
- data/lib/xively-rb/exceptions.rb +5 -0
- data/lib/xively-rb/feed.rb +109 -0
- data/lib/xively-rb/hash_extensions.rb +16 -0
- data/lib/xively-rb/helpers.rb +41 -0
- data/lib/xively-rb/key.rb +99 -0
- data/lib/xively-rb/nil_content.rb +15 -0
- data/lib/xively-rb/object_extensions.rb +6 -0
- data/lib/xively-rb/parsers/csv/datastream_defaults.rb +50 -0
- data/lib/xively-rb/parsers/csv/feed_defaults.rb +97 -0
- data/lib/xively-rb/parsers/defaults.rb +15 -0
- data/lib/xively-rb/parsers/json/datapoint_defaults.rb +16 -0
- data/lib/xively-rb/parsers/json/datastream_defaults.rb +58 -0
- data/lib/xively-rb/parsers/json/feed_defaults.rb +114 -0
- data/lib/xively-rb/parsers/json/key_defaults.rb +20 -0
- data/lib/xively-rb/parsers/json/search_result_defaults.rb +24 -0
- data/lib/xively-rb/parsers/json/trigger_defaults.rb +16 -0
- data/lib/xively-rb/parsers/xml/datapoint_defaults.rb +27 -0
- data/lib/xively-rb/parsers/xml/datastream_defaults.rb +53 -0
- data/lib/xively-rb/parsers/xml/errors.rb +7 -0
- data/lib/xively-rb/parsers/xml/feed_defaults.rb +83 -0
- data/lib/xively-rb/parsers/xml/helpers.rb +116 -0
- data/lib/xively-rb/parsers/xml/key_defaults.rb +46 -0
- data/lib/xively-rb/parsers/xml/trigger_defaults.rb +28 -0
- data/lib/xively-rb/permission.rb +67 -0
- data/lib/xively-rb/resource.rb +43 -0
- data/lib/xively-rb/search_result.rb +68 -0
- data/lib/xively-rb/string_extensions.rb +6 -0
- data/lib/xively-rb/templates/csv/datapoint_defaults.rb +22 -0
- data/lib/xively-rb/templates/csv/datastream_defaults.rb +43 -0
- data/lib/xively-rb/templates/csv/feed_defaults.rb +47 -0
- data/lib/xively-rb/templates/defaults.rb +14 -0
- data/lib/xively-rb/templates/json/datapoint_defaults.rb +15 -0
- data/lib/xively-rb/templates/json/datastream_defaults.rb +61 -0
- data/lib/xively-rb/templates/json/feed_defaults.rb +90 -0
- data/lib/xively-rb/templates/json/key_defaults.rb +39 -0
- data/lib/xively-rb/templates/json/search_result_defaults.rb +42 -0
- data/lib/xively-rb/templates/json/trigger_defaults.rb +21 -0
- data/lib/xively-rb/templates/xml/datapoint_defaults.rb +25 -0
- data/lib/xively-rb/templates/xml/datastream_defaults.rb +66 -0
- data/lib/xively-rb/templates/xml/feed_defaults.rb +112 -0
- data/lib/xively-rb/templates/xml/search_result_defaults.rb +118 -0
- data/lib/xively-rb/templates/xml_headers.rb +17 -0
- data/lib/xively-rb/trigger.rb +66 -0
- data/lib/xively-rb/validations.rb +9 -0
- data/lib/xively-rb/version.rb +3 -0
- data/spec/fixtures/models.rb +81 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/contain_datapoint_eeml_matcher.rb +16 -0
- data/spec/support/contain_datastream_eeml_matcher.rb +60 -0
- data/spec/support/contain_feed_eeml_matcher.rb +98 -0
- data/spec/support/datapoint_helper.rb +53 -0
- data/spec/support/datastream_helper.rb +324 -0
- data/spec/support/describe_eeml_matcher.rb +23 -0
- data/spec/support/feed_helper.rb +783 -0
- data/spec/support/fully_represent_datapoint_matcher.rb +30 -0
- data/spec/support/fully_represent_datastream_matcher.rb +96 -0
- data/spec/support/fully_represent_feed_matcher.rb +234 -0
- data/spec/support/fully_represent_key_matcher.rb +74 -0
- data/spec/support/fully_represent_search_result_matcher.rb +67 -0
- data/spec/support/fully_represent_trigger_matcher.rb +29 -0
- data/spec/support/key_helper.rb +74 -0
- data/spec/support/search_result_helper.rb +252 -0
- data/spec/support/trigger_helper.rb +51 -0
- data/spec/xively-rb/array_extensions_spec.rb +9 -0
- data/spec/xively-rb/base/instance_methods_spec.rb +109 -0
- data/spec/xively-rb/base_spec.rb +56 -0
- data/spec/xively-rb/client_spec.rb +51 -0
- data/spec/xively-rb/datapoint_spec.rb +187 -0
- data/spec/xively-rb/datastream_spec.rb +344 -0
- data/spec/xively-rb/feed_spec.rb +341 -0
- data/spec/xively-rb/hash_extensions_spec.rb +20 -0
- data/spec/xively-rb/helpers_spec.rb +56 -0
- data/spec/xively-rb/key_spec.rb +198 -0
- data/spec/xively-rb/parsers/csv/datastream_defaults_spec.rb +110 -0
- data/spec/xively-rb/parsers/csv/feed_defaults_spec.rb +234 -0
- data/spec/xively-rb/parsers/json/datapoint_defaults_spec.rb +21 -0
- data/spec/xively-rb/parsers/json/datastream_defaults_spec.rb +105 -0
- data/spec/xively-rb/parsers/json/feed_defaults_spec.rb +45 -0
- data/spec/xively-rb/parsers/json/key_defaults_spec.rb +14 -0
- data/spec/xively-rb/parsers/json/search_result_defaults_spec.rb +18 -0
- data/spec/xively-rb/parsers/json/trigger_defaults_spec.rb +22 -0
- data/spec/xively-rb/parsers/xml/datapoint_defaults_spec.rb +19 -0
- data/spec/xively-rb/parsers/xml/datastream_defaults_spec.rb +148 -0
- data/spec/xively-rb/parsers/xml/feed_defaults_spec.rb +254 -0
- data/spec/xively-rb/parsers/xml/key_defaults_spec.rb +22 -0
- data/spec/xively-rb/parsers/xml/trigger_defaults_spec.rb +22 -0
- data/spec/xively-rb/search_result_spec.rb +257 -0
- data/spec/xively-rb/string_extensions_spec.rb +12 -0
- data/spec/xively-rb/templates/csv/datapoint_defaults_spec.rb +41 -0
- data/spec/xively-rb/templates/csv/datastream_defaults_spec.rb +131 -0
- data/spec/xively-rb/templates/csv/feed_defaults_spec.rb +78 -0
- data/spec/xively-rb/templates/json/datapoint_defaults_spec.rb +14 -0
- data/spec/xively-rb/templates/json/datastream_defaults_spec.rb +170 -0
- data/spec/xively-rb/templates/json/feed_defaults_spec.rb +399 -0
- data/spec/xively-rb/templates/json/key_defaults_spec.rb +29 -0
- data/spec/xively-rb/templates/json/search_result_defaults_spec.rb +37 -0
- data/spec/xively-rb/templates/json/trigger_defaults_spec.rb +19 -0
- data/spec/xively-rb/templates/xml/datapoint_defaults_spec.rb +14 -0
- data/spec/xively-rb/templates/xml/datastream_defaults_spec.rb +113 -0
- data/spec/xively-rb/templates/xml/feed_defaults_spec.rb +131 -0
- data/spec/xively-rb/templates/xml/search_result_defaults_spec.rb +44 -0
- data/spec/xively-rb/trigger_spec.rb +157 -0
- data/xively-rb.gemspec +41 -0
- 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,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
|