cosm-rb 0.0.1
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 +12 -0
- data/.rbenv-version +1 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +91 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +195 -0
- data/Rakefile +35 -0
- data/ci/build_hudson.sh +24 -0
- data/cosm-rb.gemspec +40 -0
- data/init.rb +2 -0
- data/lib/cosm-rb/array_extensions.rb +6 -0
- data/lib/cosm-rb/base/instance_methods.rb +28 -0
- data/lib/cosm-rb/base.rb +52 -0
- data/lib/cosm-rb/client.rb +7 -0
- data/lib/cosm-rb/datapoint.rb +71 -0
- data/lib/cosm-rb/datastream.rb +136 -0
- data/lib/cosm-rb/feed.rb +108 -0
- data/lib/cosm-rb/hash_extensions.rb +16 -0
- data/lib/cosm-rb/helpers.rb +42 -0
- data/lib/cosm-rb/key.rb +98 -0
- data/lib/cosm-rb/nil_content.rb +15 -0
- data/lib/cosm-rb/object_extensions.rb +6 -0
- data/lib/cosm-rb/parsers/csv/datastream_defaults.rb +12 -0
- data/lib/cosm-rb/parsers/csv/feed_defaults.rb +38 -0
- data/lib/cosm-rb/parsers/defaults.rb +13 -0
- data/lib/cosm-rb/parsers/json/datapoint_defaults.rb +12 -0
- data/lib/cosm-rb/parsers/json/datastream_defaults.rb +53 -0
- data/lib/cosm-rb/parsers/json/feed_defaults.rb +103 -0
- data/lib/cosm-rb/parsers/json/key_defaults.rb +15 -0
- data/lib/cosm-rb/parsers/json/search_result_defaults.rb +18 -0
- data/lib/cosm-rb/parsers/json/trigger_defaults.rb +12 -0
- data/lib/cosm-rb/parsers/xml/datapoint_defaults.rb +20 -0
- data/lib/cosm-rb/parsers/xml/datastream_defaults.rb +77 -0
- data/lib/cosm-rb/parsers/xml/feed_defaults.rb +127 -0
- data/lib/cosm-rb/parsers/xml/key_defaults.rb +40 -0
- data/lib/cosm-rb/parsers/xml/trigger_defaults.rb +22 -0
- data/lib/cosm-rb/permission.rb +67 -0
- data/lib/cosm-rb/resource.rb +43 -0
- data/lib/cosm-rb/search_result.rb +63 -0
- data/lib/cosm-rb/string_extensions.rb +6 -0
- data/lib/cosm-rb/template.rb +32 -0
- data/lib/cosm-rb/templates/csv/datapoint_defaults.rb +22 -0
- data/lib/cosm-rb/templates/csv/datastream_defaults.rb +43 -0
- data/lib/cosm-rb/templates/csv/feed_defaults.rb +47 -0
- data/lib/cosm-rb/templates/defaults.rb +14 -0
- data/lib/cosm-rb/templates/json/datapoint_defaults.rb +15 -0
- data/lib/cosm-rb/templates/json/datastream_defaults.rb +66 -0
- data/lib/cosm-rb/templates/json/feed_defaults.rb +134 -0
- data/lib/cosm-rb/templates/json/key_defaults.rb +41 -0
- data/lib/cosm-rb/templates/json/search_result_defaults.rb +47 -0
- data/lib/cosm-rb/templates/json/trigger_defaults.rb +21 -0
- data/lib/cosm-rb/templates/xml/datapoint_defaults.rb +25 -0
- data/lib/cosm-rb/templates/xml/datastream_defaults.rb +66 -0
- data/lib/cosm-rb/templates/xml/feed_defaults.rb +110 -0
- data/lib/cosm-rb/templates/xml/search_result_defaults.rb +116 -0
- data/lib/cosm-rb/templates/xml_headers.rb +17 -0
- data/lib/cosm-rb/trigger.rb +65 -0
- data/lib/cosm-rb/validations.rb +9 -0
- data/lib/cosm-rb/version.rb +3 -0
- data/lib/cosm-rb.rb +29 -0
- data/spec/cosm-rb/array_extensions_spec.rb +9 -0
- data/spec/cosm-rb/base/instance_methods_spec.rb +109 -0
- data/spec/cosm-rb/base_spec.rb +56 -0
- data/spec/cosm-rb/client_spec.rb +7 -0
- data/spec/cosm-rb/datapoint_spec.rb +169 -0
- data/spec/cosm-rb/datastream_spec.rb +301 -0
- data/spec/cosm-rb/feed_spec.rb +298 -0
- data/spec/cosm-rb/hash_extensions_spec.rb +20 -0
- data/spec/cosm-rb/helpers_spec.rb +56 -0
- data/spec/cosm-rb/key_spec.rb +178 -0
- data/spec/cosm-rb/parsers/csv/datastream_defaults_spec.rb +12 -0
- data/spec/cosm-rb/parsers/csv/feed_defaults_spec.rb +35 -0
- data/spec/cosm-rb/parsers/json/datapoint_defaults_spec.rb +15 -0
- data/spec/cosm-rb/parsers/json/datastream_defaults_spec.rb +82 -0
- data/spec/cosm-rb/parsers/json/feed_defaults_spec.rb +18 -0
- data/spec/cosm-rb/parsers/json/key_defaults_spec.rb +8 -0
- data/spec/cosm-rb/parsers/json/search_result_defaults_spec.rb +12 -0
- data/spec/cosm-rb/parsers/json/trigger_defaults_spec.rb +16 -0
- data/spec/cosm-rb/parsers/xml/datapoint_defaults_spec.rb +19 -0
- data/spec/cosm-rb/parsers/xml/datastream_defaults_spec.rb +63 -0
- data/spec/cosm-rb/parsers/xml/feed_defaults_spec.rb +65 -0
- data/spec/cosm-rb/parsers/xml/key_defaults_spec.rb +16 -0
- data/spec/cosm-rb/parsers/xml/trigger_defaults_spec.rb +16 -0
- data/spec/cosm-rb/search_result_spec.rb +258 -0
- data/spec/cosm-rb/string_extensions_spec.rb +12 -0
- data/spec/cosm-rb/template_spec.rb +74 -0
- data/spec/cosm-rb/templates/csv/datapoint_defaults_spec.rb +41 -0
- data/spec/cosm-rb/templates/csv/datastream_defaults_spec.rb +131 -0
- data/spec/cosm-rb/templates/csv/feed_defaults_spec.rb +78 -0
- data/spec/cosm-rb/templates/json/datapoint_defaults_spec.rb +14 -0
- data/spec/cosm-rb/templates/json/datastream_defaults_spec.rb +170 -0
- data/spec/cosm-rb/templates/json/feed_defaults_spec.rb +397 -0
- data/spec/cosm-rb/templates/json/key_defaults_spec.rb +29 -0
- data/spec/cosm-rb/templates/json/search_result_defaults_spec.rb +37 -0
- data/spec/cosm-rb/templates/json/trigger_defaults_spec.rb +19 -0
- data/spec/cosm-rb/templates/xml/datapoint_defaults_spec.rb +14 -0
- data/spec/cosm-rb/templates/xml/datastream_defaults_spec.rb +113 -0
- data/spec/cosm-rb/templates/xml/feed_defaults_spec.rb +131 -0
- data/spec/cosm-rb/templates/xml/search_result_defaults_spec.rb +44 -0
- data/spec/cosm-rb/trigger_spec.rb +117 -0
- data/spec/fixtures/models.rb +81 -0
- data/spec/spec_helper.rb +17 -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 +96 -0
- data/spec/support/datapoint_helper.rb +53 -0
- data/spec/support/datastream_helper.rb +300 -0
- data/spec/support/describe_eeml_matcher.rb +23 -0
- data/spec/support/feed_helper.rb +771 -0
- data/spec/support/fully_represent_datapoint_matcher.rb +30 -0
- data/spec/support/fully_represent_datastream_matcher.rb +92 -0
- data/spec/support/fully_represent_feed_matcher.rb +226 -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
- metadata +363 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
class Datastream
|
|
3
|
+
ALLOWED_KEYS = %w(feed_id id feed_creator current_value datapoints max_value min_value tags unit_label unit_symbol unit_type updated datapoints_function)
|
|
4
|
+
ALLOWED_KEYS.each { |key| attr_accessor(key.to_sym) }
|
|
5
|
+
VALID_UNIT_TYPES = %w(basicSI derivedSI conversionBasedUnits derivedUnits contextDependentUnits)
|
|
6
|
+
|
|
7
|
+
include Cosm::Helpers
|
|
8
|
+
include Cosm::Templates::JSON::DatastreamDefaults
|
|
9
|
+
include Cosm::Templates::XML::DatastreamDefaults
|
|
10
|
+
include Cosm::Templates::CSV::DatastreamDefaults
|
|
11
|
+
include Cosm::Parsers::JSON::DatastreamDefaults
|
|
12
|
+
include Cosm::Parsers::XML::DatastreamDefaults
|
|
13
|
+
include Cosm::Parsers::CSV::DatastreamDefaults
|
|
14
|
+
|
|
15
|
+
include Validations
|
|
16
|
+
# validate :before, :join_tags
|
|
17
|
+
|
|
18
|
+
# validates_presence_of :id
|
|
19
|
+
# validates_length_of :current_value, :maximum => 255
|
|
20
|
+
# validates_length_of :tags, :maximum => 255
|
|
21
|
+
# validates_inclusion_of :unit_type, :in => VALID_UNIT_TYPES,
|
|
22
|
+
# :allow_nil => true,
|
|
23
|
+
# :message => "is not a valid unit_type (pick one from #{VALID_UNIT_TYPES} or leave blank)"
|
|
24
|
+
# validates_format_of :id, :with => /\A[\w\-\+\.]+\Z/
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
def valid?
|
|
28
|
+
pass = true
|
|
29
|
+
[:id].each do |attr|
|
|
30
|
+
if self.send(attr).blank?
|
|
31
|
+
errors[attr] = ["can't be blank"]
|
|
32
|
+
pass = false
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
if !unit_type.blank?
|
|
36
|
+
if !VALID_UNIT_TYPES.include?(unit_type)
|
|
37
|
+
errors[:unit_type] = ["is not a valid unit_type (pick one from #{VALID_UNIT_TYPES.join(', ')} or leave blank)"]
|
|
38
|
+
pass = false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
if current_value && current_value.length > 255
|
|
42
|
+
errors[:current_value] = ["is too long (maximum is 255 characters)"]
|
|
43
|
+
pass = false
|
|
44
|
+
end
|
|
45
|
+
if tags
|
|
46
|
+
self.tags = join_tags(self.tags)
|
|
47
|
+
if tags && tags.length > 255
|
|
48
|
+
errors[:tags] = ["is too long (maximum is 255 characters)"]
|
|
49
|
+
pass = false
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
stream_id_regexp = RUBY_VERSION.to_f >= 1.9 ? /\A[\p{L}\w\-\+\.]+\Z/u : /\A[\w\-\+\.]+\Z/u
|
|
54
|
+
|
|
55
|
+
unless self.id =~ stream_id_regexp
|
|
56
|
+
errors[:id] = ["is invalid"]
|
|
57
|
+
pass = false
|
|
58
|
+
end
|
|
59
|
+
if self.id.blank?
|
|
60
|
+
errors[:id] = ["can't be blank"]
|
|
61
|
+
pass = false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
unless self.feed_id.to_s =~ /\A\d*\Z/
|
|
65
|
+
errors[:feed_id] = ["is invalid"]
|
|
66
|
+
pass = false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
return pass
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def initialize(input = {})
|
|
73
|
+
if input.is_a? Hash
|
|
74
|
+
self.attributes = input
|
|
75
|
+
elsif input.strip[0...1].to_s == "{"
|
|
76
|
+
self.attributes = from_json(input)
|
|
77
|
+
elsif input.strip[0...1].to_s == "<"
|
|
78
|
+
self.attributes = from_xml(input)
|
|
79
|
+
else
|
|
80
|
+
self.attributes = from_csv(input)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def attributes
|
|
85
|
+
h = {}
|
|
86
|
+
ALLOWED_KEYS.each do |key|
|
|
87
|
+
value = self.send(key)
|
|
88
|
+
h[key] = value unless value.nil?
|
|
89
|
+
end
|
|
90
|
+
return h
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def attributes=(input)
|
|
94
|
+
return if input.nil?
|
|
95
|
+
input.deep_stringify_keys!
|
|
96
|
+
ALLOWED_KEYS.each { |key| self.send("#{key}=", input[key]) }
|
|
97
|
+
return attributes
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def datapoints
|
|
101
|
+
@datapoints.nil? ? [] : @datapoints
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def datapoints=(array)
|
|
105
|
+
return unless array.is_a?(Array)
|
|
106
|
+
@datapoints = []
|
|
107
|
+
array.each do |datapoint|
|
|
108
|
+
if datapoint.is_a?(Datapoint)
|
|
109
|
+
@datapoints << datapoint
|
|
110
|
+
elsif datapoint.is_a?(Hash)
|
|
111
|
+
@datapoints << Datapoint.new(datapoint)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def as_json(options = {})
|
|
117
|
+
options[:version] ||= "1.0.0"
|
|
118
|
+
generate_json(options.delete(:version), options)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def to_json(options = {})
|
|
122
|
+
::JSON.generate as_json(options)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def to_xml(options = {})
|
|
126
|
+
options[:version] ||= "0.5.1"
|
|
127
|
+
generate_xml(options.delete(:version), options)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def to_csv(options = {})
|
|
131
|
+
options[:version] ||= "2"
|
|
132
|
+
generate_csv(options.delete(:version), options)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
data/lib/cosm-rb/feed.rb
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
class Feed
|
|
3
|
+
# The order of these keys is the order attributes are assigned in. (i.e. id should come before datastreams)
|
|
4
|
+
ALLOWED_KEYS = %w(id creator owner_login datastreams description email feed icon location_disposition location_domain location_ele location_exposure location_lat location_lon location_name location_waypoints private status tags title updated created website auto_feed_url csv_version)
|
|
5
|
+
ALLOWED_KEYS.each { |key| attr_accessor(key.to_sym) }
|
|
6
|
+
|
|
7
|
+
include Cosm::Templates::JSON::FeedDefaults
|
|
8
|
+
include Cosm::Templates::XML::FeedDefaults
|
|
9
|
+
include Cosm::Templates::CSV::FeedDefaults
|
|
10
|
+
include Cosm::Parsers::JSON::FeedDefaults
|
|
11
|
+
include Cosm::Parsers::XML::FeedDefaults
|
|
12
|
+
include Cosm::Parsers::CSV::FeedDefaults
|
|
13
|
+
|
|
14
|
+
include Validations
|
|
15
|
+
|
|
16
|
+
def valid?
|
|
17
|
+
pass = true
|
|
18
|
+
if title.blank?
|
|
19
|
+
errors[:title] = ["can't be blank"]
|
|
20
|
+
pass = false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
duplicate_datastream_ids = datastreams.inject({}) {|h,v| h[v.id]=h[v.id].to_i+1; h}.reject{|k,v| v==1}.keys
|
|
24
|
+
if duplicate_datastream_ids.any?
|
|
25
|
+
errors[:datastreams] = ["can't have duplicate IDs: #{duplicate_datastream_ids.join(',')}"]
|
|
26
|
+
pass = false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
datastreams.each do |ds|
|
|
30
|
+
unless ds.valid?
|
|
31
|
+
ds.errors.each { |attr, ds_errors|
|
|
32
|
+
errors["datastreams_#{attr}".to_sym] = ([*errors["datastreams_#{attr}".to_sym]] | [*ds_errors]).compact
|
|
33
|
+
}
|
|
34
|
+
pass = false
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
return pass
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize(input = {}, csv_version = nil)
|
|
42
|
+
if input.is_a?(Hash)
|
|
43
|
+
self.attributes = input
|
|
44
|
+
elsif input.strip[0...1].to_s == "{"
|
|
45
|
+
self.attributes = from_json(input)
|
|
46
|
+
elsif input.strip[0...5].to_s == "<?xml" || input.strip[0...5].to_s == "<eeml"
|
|
47
|
+
self.attributes = from_xml(input)
|
|
48
|
+
else
|
|
49
|
+
self.attributes = from_csv(input, csv_version)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def attributes
|
|
54
|
+
h = {}
|
|
55
|
+
ALLOWED_KEYS.each do |key|
|
|
56
|
+
value = self.send(key)
|
|
57
|
+
h[key] = value unless value.nil?
|
|
58
|
+
end
|
|
59
|
+
return h
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def datastreams
|
|
63
|
+
return [] if @datastreams.nil?
|
|
64
|
+
@datastreams
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def attributes=(input)
|
|
68
|
+
return if input.nil?
|
|
69
|
+
input.deep_stringify_keys!
|
|
70
|
+
ALLOWED_KEYS.each { |key| self.send("#{key}=", input[key]) }
|
|
71
|
+
return attributes
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def datastreams=(array)
|
|
75
|
+
return unless array.is_a?(Array)
|
|
76
|
+
@datastreams = []
|
|
77
|
+
array.each do |datastream|
|
|
78
|
+
if datastream.is_a?(Datastream)
|
|
79
|
+
@datastreams << datastream
|
|
80
|
+
elsif datastream.is_a?(Hash)
|
|
81
|
+
@datastreams << Datastream.new(datastream)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def as_json(options = {})
|
|
87
|
+
options[:version] ||= "1.0.0"
|
|
88
|
+
generate_json(options.delete(:version), options)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def to_json(options = {})
|
|
92
|
+
::JSON.generate as_json(options)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def to_xml(options = {})
|
|
96
|
+
options[:version] ||= "0.5.1"
|
|
97
|
+
generate_xml(options.delete(:version), options)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def to_csv(options = {})
|
|
101
|
+
options[:version] ||= "2"
|
|
102
|
+
generate_csv(options.delete(:version), options)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class Hash
|
|
2
|
+
def delete_if_nil_value
|
|
3
|
+
delete_if{|k,v| v.nil? || v.blank?}
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def deep_stringify_keys
|
|
7
|
+
inject({}) do |options, (key, value)|
|
|
8
|
+
options[key.to_s] = (value.is_a?(Hash) ? value.deep_stringify_keys : value)
|
|
9
|
+
options
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def deep_stringify_keys!
|
|
14
|
+
self.replace(self.deep_stringify_keys)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
module Helpers
|
|
3
|
+
def parse_tag_string(string)
|
|
4
|
+
return [] if string.blank?
|
|
5
|
+
string = string.join(',') if string.is_a?(Array)
|
|
6
|
+
tags = []
|
|
7
|
+
quoted_mode = false
|
|
8
|
+
tags << string.chars.reduce("") do |buffer, char|
|
|
9
|
+
case char
|
|
10
|
+
when ','
|
|
11
|
+
if !quoted_mode
|
|
12
|
+
tags << buffer
|
|
13
|
+
buffer = ""
|
|
14
|
+
else
|
|
15
|
+
buffer << char
|
|
16
|
+
end
|
|
17
|
+
when '"'
|
|
18
|
+
if buffer.length > 0 && buffer[-1,1] == '\\'
|
|
19
|
+
buffer[-1] = char
|
|
20
|
+
else
|
|
21
|
+
quoted_mode = !quoted_mode
|
|
22
|
+
buffer << char
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
buffer << char
|
|
26
|
+
end
|
|
27
|
+
buffer
|
|
28
|
+
end
|
|
29
|
+
# strip the tags
|
|
30
|
+
tags.map { |t|
|
|
31
|
+
/\A\s*("(.*)"|(.*))\s*\Z/.match(t)
|
|
32
|
+
$2 || $3.strip
|
|
33
|
+
}.sort{|a,b| a.downcase <=> b.downcase}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def join_tags(tags)
|
|
37
|
+
return tags unless tags.is_a?(Array)
|
|
38
|
+
tags.sort{|a,b| a.downcase <=> b.downcase}.join(',')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
data/lib/cosm-rb/key.rb
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
class Key
|
|
3
|
+
ALLOWED_KEYS = %w(id key label user expires_at permissions private_access)
|
|
4
|
+
ALLOWED_KEYS.each { |key| attr_accessor(key.to_sym) }
|
|
5
|
+
NESTED_KEYS = %w(permissions)
|
|
6
|
+
|
|
7
|
+
include Cosm::Templates::JSON::KeyDefaults
|
|
8
|
+
#include Cosm::Templates::XML::KeyDefaults
|
|
9
|
+
include Cosm::Parsers::JSON::KeyDefaults
|
|
10
|
+
include Cosm::Parsers::XML::KeyDefaults
|
|
11
|
+
|
|
12
|
+
include Validations
|
|
13
|
+
|
|
14
|
+
def valid?
|
|
15
|
+
pass = true
|
|
16
|
+
[:label, :permissions, :user].each do |attr|
|
|
17
|
+
if self.send(attr).blank?
|
|
18
|
+
errors[attr] = ["can't be blank"]
|
|
19
|
+
pass = false
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
permissions.each do |permission|
|
|
24
|
+
unless permission.valid?
|
|
25
|
+
permission.errors.each do |attr, permission_errors|
|
|
26
|
+
errors["permissions_#{attr}".to_sym] = ([*errors["permissions_#{attr}".to_sym]] | [*permission_errors]).compact
|
|
27
|
+
end
|
|
28
|
+
pass = false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return pass
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Build an instance from either a Hash, a JSON string, or an XML document
|
|
36
|
+
def initialize(input = {})
|
|
37
|
+
if input.is_a?(Hash)
|
|
38
|
+
self.attributes = input
|
|
39
|
+
elsif input.strip[0...1].to_s == "{"
|
|
40
|
+
self.attributes = from_json(input)
|
|
41
|
+
else
|
|
42
|
+
self.attributes = from_xml(input)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def attributes
|
|
47
|
+
h = {}
|
|
48
|
+
ALLOWED_KEYS.each do |key|
|
|
49
|
+
value = self.send(key)
|
|
50
|
+
h[key] = value unless value.nil?
|
|
51
|
+
end
|
|
52
|
+
return h
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def attributes=(input)
|
|
56
|
+
return if input.nil?
|
|
57
|
+
input.deep_stringify_keys!
|
|
58
|
+
ALLOWED_KEYS.each { |key| self.send("#{key}=", input[key]) }
|
|
59
|
+
NESTED_KEYS.each { |key|
|
|
60
|
+
self.send("#{key}=".to_sym, input["#{key}_attributes"]) unless input["#{key}_attributes"].nil?
|
|
61
|
+
}
|
|
62
|
+
return attributes
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def as_json(options = nil)
|
|
66
|
+
generate_json(options || {})
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def to_json(options = nil)
|
|
70
|
+
::JSON.generate as_json(options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def permissions
|
|
74
|
+
return [] if @permissions.nil?
|
|
75
|
+
@permissions
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def permissions=(array)
|
|
79
|
+
return unless array.is_a?(Array)
|
|
80
|
+
@permissions = []
|
|
81
|
+
array.each do |permission|
|
|
82
|
+
if permission.is_a?(Permission)
|
|
83
|
+
@permissions << permission
|
|
84
|
+
elsif permission.is_a?(Hash)
|
|
85
|
+
@permissions << Permission.new(permission)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def private_access?
|
|
91
|
+
@private_access || false
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def id
|
|
95
|
+
@id.nil? ? @key : @id
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
module Parsers
|
|
3
|
+
module CSV
|
|
4
|
+
class UnknownVersionError < StandardError ; end
|
|
5
|
+
module FeedDefaults
|
|
6
|
+
def from_csv(csv, csv_version = nil)
|
|
7
|
+
array = ::CSV.parse(csv.strip)
|
|
8
|
+
version = detect_version(array, csv_version)
|
|
9
|
+
hash = Hash.new
|
|
10
|
+
if version == :v2
|
|
11
|
+
hash["datastreams"] = array.collect {|row|
|
|
12
|
+
{ "id" => row.first.to_s,
|
|
13
|
+
"current_value" => row.last.to_s
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
elsif version == :v1
|
|
17
|
+
hash["datastreams"] = []
|
|
18
|
+
array.first.each_with_index do |current_value, stream_id|
|
|
19
|
+
hash["datastreams"] << { "id" => stream_id.to_s, "current_value" => current_value }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
hash["csv_version"] = version
|
|
23
|
+
hash
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def detect_version(array, version = nil)
|
|
29
|
+
return version if version
|
|
30
|
+
return :v2 if array.size >= 2
|
|
31
|
+
return :v1 if array.size == 1 && array.first.size != 2
|
|
32
|
+
raise UnknownVersionError, "CSV Version could not be detected"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'cosm-rb/parsers/json/feed_defaults'
|
|
2
|
+
require 'cosm-rb/parsers/json/search_result_defaults'
|
|
3
|
+
require 'cosm-rb/parsers/json/datastream_defaults'
|
|
4
|
+
require 'cosm-rb/parsers/json/datapoint_defaults'
|
|
5
|
+
require 'cosm-rb/parsers/json/trigger_defaults'
|
|
6
|
+
require 'cosm-rb/parsers/json/key_defaults'
|
|
7
|
+
require 'cosm-rb/parsers/xml/feed_defaults'
|
|
8
|
+
require 'cosm-rb/parsers/xml/datastream_defaults'
|
|
9
|
+
require 'cosm-rb/parsers/xml/datapoint_defaults'
|
|
10
|
+
require 'cosm-rb/parsers/xml/trigger_defaults'
|
|
11
|
+
require 'cosm-rb/parsers/xml/key_defaults'
|
|
12
|
+
require 'cosm-rb/parsers/csv/feed_defaults'
|
|
13
|
+
require 'cosm-rb/parsers/csv/datastream_defaults'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
module Parsers
|
|
3
|
+
module JSON
|
|
4
|
+
module DatastreamDefaults
|
|
5
|
+
def from_json(json)
|
|
6
|
+
hash = ::JSON.parse(json)
|
|
7
|
+
case hash['version']
|
|
8
|
+
when '1.0.0'
|
|
9
|
+
transform_1_0_0(hash)
|
|
10
|
+
when '0.6-alpha', nil
|
|
11
|
+
transform_0_6_alpha(hash)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# As produced by http://cosm.com/api/v2/FEED_ID/datastreams/DATASTREAM_ID.json
|
|
18
|
+
def transform_1_0_0(hash)
|
|
19
|
+
hash["id"] = hash.delete("id")
|
|
20
|
+
hash["updated"] = hash.delete("at")
|
|
21
|
+
hash["current_value"] = hash.delete("current_value")
|
|
22
|
+
hash["tags"] = hash["tags"].join(',') if hash["tags"]
|
|
23
|
+
if unit = hash.delete('unit')
|
|
24
|
+
hash['unit_type'] = unit['type']
|
|
25
|
+
hash['unit_symbol'] = unit['symbol']
|
|
26
|
+
hash['unit_label'] = unit['label']
|
|
27
|
+
end
|
|
28
|
+
hash
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# As produced by http://cosm.com/api/v1/FEED_ID/datastreams/DATASTREAM_ID.json
|
|
32
|
+
def transform_0_6_alpha(hash)
|
|
33
|
+
hash["id"] = hash.delete("id")
|
|
34
|
+
if values = [*hash["values"]].first
|
|
35
|
+
hash["updated"] = hash["values"].first.delete("recorded_at")
|
|
36
|
+
hash["current_value"] = hash["values"].first.delete("value")
|
|
37
|
+
hash["max_value"] = hash["values"].first.delete("max_value")
|
|
38
|
+
hash["min_value"] = hash["values"].first.delete("min_value")
|
|
39
|
+
end
|
|
40
|
+
hash["tags"] = hash["tags"].join(',') if hash["tags"]
|
|
41
|
+
if unit = hash.delete('unit')
|
|
42
|
+
hash['unit_type'] = unit['type']
|
|
43
|
+
hash['unit_symbol'] = unit['symbol']
|
|
44
|
+
hash['unit_label'] = unit['label']
|
|
45
|
+
end
|
|
46
|
+
hash
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module Cosm
|
|
2
|
+
module Parsers
|
|
3
|
+
module JSON
|
|
4
|
+
module FeedDefaults
|
|
5
|
+
|
|
6
|
+
include Cosm::Helpers
|
|
7
|
+
|
|
8
|
+
def from_json(json)
|
|
9
|
+
hash = ::JSON.parse(json)
|
|
10
|
+
case hash['version']
|
|
11
|
+
when '1.0.0'
|
|
12
|
+
transform_1_0_0(hash)
|
|
13
|
+
when '0.6-alpha'
|
|
14
|
+
transform_0_6_alpha(hash)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# As produced by http://cosm.com/api/v2/FEED_ID.json
|
|
21
|
+
def transform_1_0_0(hash)
|
|
22
|
+
hash["updated"] = hash["updated"]
|
|
23
|
+
hash["created"] = hash["created"]
|
|
24
|
+
hash["status"] = hash["status"]
|
|
25
|
+
hash["tags"] = join_tags(hash["tags"])
|
|
26
|
+
hash["datastreams"] = hash["datastreams"].collect do |datastream|
|
|
27
|
+
unit_hash = {}
|
|
28
|
+
if unit = datastream.delete('unit')
|
|
29
|
+
unit_hash['unit_type'] = unit['type']
|
|
30
|
+
unit_hash['unit_symbol'] = unit['symbol']
|
|
31
|
+
unit_hash['unit_label'] = unit['label']
|
|
32
|
+
end
|
|
33
|
+
{
|
|
34
|
+
"id" => datastream["id"],
|
|
35
|
+
"current_value" => datastream["current_value"],
|
|
36
|
+
"min_value" => datastream["min_value"],
|
|
37
|
+
"max_value" => datastream["max_value"],
|
|
38
|
+
"updated" => datastream["at"],
|
|
39
|
+
"tags" => join_tags(datastream["tags"]),
|
|
40
|
+
"datapoints" => setup_datapoints(datastream["datapoints"])
|
|
41
|
+
}.merge(unit_hash)
|
|
42
|
+
end if hash["datastreams"]
|
|
43
|
+
if location = hash.delete("location")
|
|
44
|
+
hash["location_disposition"] = location["disposition"]
|
|
45
|
+
hash["location_domain"] = location["domain"]
|
|
46
|
+
hash["location_ele"] = location["ele"]
|
|
47
|
+
hash["location_exposure"] = location["exposure"]
|
|
48
|
+
hash["location_lat"] = location["lat"]
|
|
49
|
+
hash["location_lon"] = location["lon"]
|
|
50
|
+
hash["location_name"] = location["name"]
|
|
51
|
+
end
|
|
52
|
+
if owner = hash.delete("user")
|
|
53
|
+
hash["owner_login"] = owner["login"]
|
|
54
|
+
end
|
|
55
|
+
hash
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# As produced by http://cosm.com/api/v1/FEED_ID.json
|
|
59
|
+
def transform_0_6_alpha(hash)
|
|
60
|
+
hash["retrieved_at"] = hash["updated"]
|
|
61
|
+
hash["state"] = hash["status"]
|
|
62
|
+
hash["datastreams"] = hash["datastreams"].collect do |datastream|
|
|
63
|
+
unit_hash = {}
|
|
64
|
+
if unit = datastream.delete('unit')
|
|
65
|
+
unit_hash['unit_type'] = unit['type']
|
|
66
|
+
unit_hash['unit_symbol'] = unit['symbol']
|
|
67
|
+
unit_hash['unit_label'] = unit['label']
|
|
68
|
+
end
|
|
69
|
+
{
|
|
70
|
+
"id" => datastream["id"],
|
|
71
|
+
"current_value" => datastream["values"].first["value"],
|
|
72
|
+
"min_value" => datastream["values"].first["min_value"],
|
|
73
|
+
"max_value" => datastream["values"].first["max_value"],
|
|
74
|
+
"updated" => datastream["values"].first["recorded_at"],
|
|
75
|
+
"tags" => join_tags(datastream["tags"]),
|
|
76
|
+
}.merge(unit_hash)
|
|
77
|
+
end
|
|
78
|
+
if location = hash.delete("location")
|
|
79
|
+
hash["location_disposition"] = location["disposition"]
|
|
80
|
+
hash["location_domain"] = location["domain"]
|
|
81
|
+
hash["location_ele"] = location["ele"]
|
|
82
|
+
hash["location_exposure"] = location["exposure"]
|
|
83
|
+
hash["location_lat"] = location["lat"]
|
|
84
|
+
hash["location_lon"] = location["lon"]
|
|
85
|
+
hash["location_name"] = location["name"]
|
|
86
|
+
end
|
|
87
|
+
hash
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def setup_datapoints(datapoints)
|
|
91
|
+
return [] unless datapoints
|
|
92
|
+
datapoints.collect do |datapoint|
|
|
93
|
+
{
|
|
94
|
+
"at" => datapoint["at"],
|
|
95
|
+
"value" => datapoint["value"]
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|