eeml 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <eeml>
3
+ <environment>
4
+ <title>Minimal</title>
5
+ <data id="0">
6
+ <value>36.2</value>
7
+ </data>
8
+ </environment>
9
+ </eeml>
@@ -163,6 +163,30 @@ class TestEnvironment < Test::Unit::TestCase
163
163
  assert_equal "36.2", datastream.value
164
164
  end
165
165
 
166
+ test "fails if no default namespace provided" do
167
+ assert_raise(MissingNamespace) {env = create_env_from_xml_file('no_namespace.xml')}
168
+ end
169
+
170
+ test "creates multiple environments from list xml" do
171
+ xml = File.read('test/data/list.xml')
172
+ list = Environment.new_list_from_eeml(xml)
173
+ assert 3, list.size
174
+ list.each do |obj|
175
+ assert obj.is_a? Environment
176
+ end
177
+ titles = list.map {|e| e.title}.sort
178
+ expected_titles = ["Badgerpower", "CurrentCost for house", "Power and Temperature"]
179
+ assert_equal expected_titles, titles
180
+ #TODO: check the environments fully (that no aliasing or other confusion has occurred in their parsing)
181
+ end
182
+
183
+ test "creates zero environments from list xml when has none" do
184
+ original_xml = File.read('test/data/list.xml')
185
+ xml = remove_nodes_called('environment', original_xml)
186
+ list = Environment.new_list_from_eeml(xml)
187
+ assert list.empty?, "should be empty list"
188
+ end
189
+
166
190
  def read_xml_file_one
167
191
  return File.read('test/data/doc_1.xml')
168
192
  end
@@ -246,20 +270,75 @@ class TestEnvironment < Test::Unit::TestCase
246
270
  assert_equal 'http://www.example.com/ourstudio/feeds/house.xml', env.feed_url
247
271
  end
248
272
 
249
- # --- ------------------------------------------------------------
250
- # --- json stuff ------------------------------------------------------------
251
- # --- ------------------------------------------------------------
273
+ # --- ------------------------------------------------------
274
+ # --- json input stuff ------------------------------------------------------
275
+ # --- ------------------------------------------------------
252
276
 
253
277
  test "creating Env obj from a JSON string" do
254
278
  env = create_env_from_json_file_one
255
279
  assert_not_nil env
256
280
  assert_instance_of Environment, env
281
+ assert_equal('title here', env.title)
282
+ assert_equal('description here', env.description)
283
+ assert_equal('http://example.com/api/1247.xml', env.feed_url)
284
+ assert_equal('http://example.com/studio/', env.website)
285
+ assert_equal('frozen', env.status)
286
+ assert_equal('someone@example.com', env.email)
287
+ assert_equal('http://example.com/some/icon.gif', env.icon)
288
+
289
+ #env attrs
290
+ assert_equal('1247', env.identifier)
291
+ assert_equal('2009-02-11T10:56:56Z', env.updated.strftime("%Y-%m-%dT%H:%M:%SZ"))
257
292
  end
258
293
 
294
+ test "location parses ok from json" do
295
+ env = create_env_from_json_file_one
296
+ assert_not_nil env.location
297
+ location = env.location
298
+ assert_equal "Up on the roof (somewhere)", location.name
299
+ assert_equal "50.1", location.latitude
300
+ assert_equal "48.7", location.longitude
301
+ assert_equal "1.34", location.elevation
302
+ assert_equal "physical", location.domain
303
+ assert_equal "outdoor", location.exposure
304
+ assert_equal "mobile", location.disposition
305
+ end
259
306
 
260
- # --- -------------------------------------------------------------
261
- # --- csv stuff -------------------------------------------------------------
262
- # --- -------------------------------------------------------------
307
+ test "datastreams parse ok from json" do
308
+ env = create_env_from_json_file_one
309
+ assert_equal 3, env.datastreams.size
310
+
311
+ #the expected values for the datastreams in the test doc
312
+ expectations_list = [
313
+ #id, tag array, min, max, value, unit_symbol, unit_type, unit_value
314
+ ['0', ['tagD0'], '-9999.0', '1022.0', '0', 'C', 'basicSI', 'Celsius'],
315
+ ['1', [], '0.0', '1023.0', '33', nil, nil, nil],
316
+ ['2', ['tagD2a', 'tagD2b', 'tagD2c'], '23.4', '1021.0', '42.1', nil, nil, nil]
317
+ ]
318
+ env.datastreams.each_with_index do |ds, i|
319
+
320
+ e_identifier, e_tags, e_min_value, e_max_value, e_value, e_unit_symbol, e_unit_type, e_unit_value = expectations_list[i]
321
+
322
+ assert_equal e_identifier, ds.identifier
323
+
324
+ assert_equal e_tags.size, ds.tags.size, "should have right num of tags"
325
+
326
+ e_tags.each do |expected_tag|
327
+ ds.tags.member? expected_tag
328
+ end
329
+
330
+ assert_equal e_min_value, ds.min_value
331
+ assert_equal e_max_value, ds.max_value
332
+ assert_equal e_value, ds.value
333
+ assert_equal e_unit_symbol, ds.unit_symbol
334
+ assert_equal e_unit_type, ds.unit_type
335
+ assert_equal e_unit_value, ds.unit_value
336
+ end
337
+ end
338
+
339
+ # --- -------------------------------------------------------
340
+ # --- csv input stuff -------------------------------------------------------
341
+ # --- -------------------------------------------------------
263
342
 
264
343
  def create_env_with_datastream_values(values)
265
344
  e = Environment.new
@@ -305,9 +384,10 @@ class TestEnvironment < Test::Unit::TestCase
305
384
  env.update_datastreams_from_csv_values!(values)
306
385
  assert_equal values, env.values_quick
307
386
  end
308
- # --- ----------------------------------------------------------
309
- # --- output stuff ----------------------------------------------------------
310
- # --- ----------------------------------------------------------
387
+
388
+ # --- -----------------------------------------------------
389
+ # --- eeml output stuff -----------------------------------------------------
390
+ # --- -----------------------------------------------------
311
391
 
312
392
  test "should output to xml ok" do
313
393
  env = create_env_from_xml_file_one
@@ -331,7 +411,58 @@ class TestEnvironment < Test::Unit::TestCase
331
411
  assert_equal expected_xml, output_xml
332
412
  end
333
413
 
414
+ # --- -----------------------------------------------------
415
+ # --- json output stuff -----------------------------------------------------
416
+ # --- -----------------------------------------------------
417
+ #DEV NOTE: use jsondiff tool to visual-diff expected and actual json http://tlrobinson.net/projects/js/jsondiff/
418
+
419
+ #TODO: decide what trailing whitespace should be output after json, and eeml, and correct tests
420
+ test "basic output in public json format" do
421
+ input_xml = File.read('test/data/doc_2.xml')
422
+ env = create_env_from_xml_string(input_xml)
423
+ output_json = env.to_json
424
+ expected_json = File.read('test/data/doc_2_expected.json').rstrip
425
+ expected_hash = JSON.parse(expected_json)
426
+ output_hash = JSON.parse(output_json)
427
+ assert_equal(expected_hash, output_hash)
428
+ end
334
429
 
430
+ test "basic output in public json format - no location" do
431
+ input_xml = File.read('test/data/doc_2.xml')
432
+ input_xml = remove_first_node_called('location', input_xml)
433
+ env = create_env_from_xml_string(input_xml)
434
+ output_json = env.to_json
435
+ output_hash = JSON.parse(output_json)
436
+
437
+ expected_json = File.read('test/data/doc_2_expected.json')
438
+ expected_hash = JSON.parse(expected_json)
439
+ assert_not_nil expected_hash.delete("location")
440
+ assert_json_hashes_equal(expected_hash, output_hash)
441
+ end
442
+
443
+ test "basic output in public json format - location but no latitude" do
444
+ input_xml = File.read('test/data/doc_2.xml')
445
+ input_xml = remove_first_node_called('lat', input_xml)
446
+ env = create_env_from_xml_string(input_xml)
447
+ actual_json = env.to_json
448
+ actual_hash = JSON.parse(actual_json)
449
+
450
+ assert_nil env.location.latitude
451
+ expected_json = File.read('test/data/doc_2_expected.json')
452
+ expected_hash = JSON.parse(expected_json)
453
+ expected_hash["location"].delete("lat")
454
+ #File.open('tmp_expected.json', 'w') {|f| f.write expected_hash.to_json }
455
+ #File.open('tmp_actual.json', 'w') {|f| f.write actual_hash.to_json }
456
+
457
+ assert_json_hashes_equal(expected_hash, actual_hash)
458
+ end
459
+
460
+ test "basic output in public json format - minimal env" do
461
+ env = Environment.new
462
+ assert_nil env.identifier
463
+ output_json = env.to_json
464
+ assert_not_nil output_json
465
+ end
335
466
 
336
467
  # --- convenience stuff - don't put tests under here ------------------------------
337
468
 
@@ -366,5 +497,12 @@ class TestEnvironment < Test::Unit::TestCase
366
497
  return Environment.new_from_json(json)
367
498
  end
368
499
 
500
+ def prep_json_for_reading(json)
501
+ return nil if json.nil?
502
+ json.gsub(/","/, '"' + "\n" + '"').sort
503
+ end
504
+
505
+
506
+
369
507
 
370
508
  end
data/test/test_helper.rb CHANGED
@@ -5,13 +5,12 @@ require 'test/libxml_test_helper'
5
5
  # Thought a mock library will be useful for testing out any stuff that
6
6
  # does any http-ing, but have no strong feelings about which one to use.
7
7
  # Looking at the syntax of each of the libraries, I liked the look of the
8
- # mocha syntax more, so was thinking to use that when required.
8
+ # mocha syntax more, so was thinking to use that when/if required.
9
9
  #
10
10
  # require 'flexmock'
11
11
  require 'mocha'
12
12
 
13
13
 
14
-
15
14
  #consider adding custom assertions to clean code up
16
15
  #http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit/Assertions.html
17
16
 
@@ -47,10 +46,71 @@ class Test::Unit::TestCase
47
46
  out
48
47
  end
49
48
 
49
+ #compare not the given json strings directly but their hash structures after parsing.
50
+ #also try to give a more concise diff, if they are different, using Hash.diff from activesupport
51
+ def assert_json_strings_equal(expected_string, actual_string, message=nil)
52
+ expected_structure = JSON.parse(expected_string)
53
+ actual_structure = JSON.parse(actual_string)
54
+
55
+ diff = expected_structure.diff(actual_structure)
56
+ diff_string = diff.inspect.gsub(/"/, "'")
57
+ full_message = build_message(message, "Parsed JSON structure doesn't match expected. Hash Diff (quotes changed): <?>\n" +
58
+ "Full text: Expected: \n<?>\nbut was: <?>.\n",
59
+ diff_string, expected_string, actual_string)
60
+ assert_block(full_message) do
61
+ expected_structure == actual_structure
62
+ end
63
+ #File.open('tmp.json', 'w') {|f| f.write output_json }
64
+ #File.open('tmp_split.json', 'w') {|f| f.write prep_json_for_reading(output_json) }
65
+ #File.open('tmp_expected_split.json', 'w') {|f| f.write prep_json_for_reading(expected_json)}
66
+
67
+ #TODO: consider allowing submission of both to a json visual diff app, too. (only if switched on by an environment variable).
68
+ end
69
+
70
+ def assert_json_hashes_equal(expected_structure, actual_structure, message=nil)
71
+ diff = expected_structure.diff(actual_structure)
72
+ diff_string = diff.inspect.gsub(/"/, "'")
73
+ full_message = build_message(message, "JSON structure doesn't match expected. Hash Diff (quotes changed): <?>\n" +
74
+ "Full values: Expected: \n<?>\nbut was: <?>.\n", diff_string, expected_structure.inspect, actual_structure.inspect)
75
+ assert_block(full_message) do
76
+ expected_structure == actual_structure
77
+ end
78
+ end
79
+
50
80
  end
51
81
 
82
+
83
+
84
+ #TODO: don't add this Hash.diff(h2) for all hashes, only for ones we want to diff (e.g. on the fly during assert_json_strings_equal)
85
+ #TODO: check rails license
86
+ module ASCoreExtensions #was ActiveSupport
87
+ module Hash #:nodoc:
88
+ module Diff
89
+ # Returns a hash that represents the difference between two hashes.
90
+ #
91
+ # Examples:
92
+ #
93
+ # {1 => 2}.diff(1 => 2) # => {}
94
+ # {1 => 2}.diff(1 => 3) # => {1 => 2}
95
+ # {}.diff(1 => 2) # => {1 => 2}
96
+ # {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
97
+ def diff(h2)
98
+ self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ class Hash #:nodoc:
105
+ include ASCoreExtensions::Hash::Diff
106
+ end
107
+
108
+
109
+
52
110
  $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
53
111
 
54
112
  require 'eeml'
55
113
 
56
114
  include Eeml
115
+
116
+
@@ -6,4 +6,7 @@ class TestLibXMLEemlParserV005 < Test::Unit::TestCase
6
6
  #p.make_environment_from_xml('bad')
7
7
  end
8
8
 
9
+ implement "re-populates env if env given" do
10
+ end
11
+
9
12
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eeml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neill Bogie, Sam Mulube
@@ -30,7 +30,7 @@ cert_chain:
30
30
  yyRwZdVyDdsafg==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2009-04-17 00:00:00 +01:00
33
+ date: 2009-05-05 00:00:00 +01:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -57,7 +57,7 @@ dependencies:
57
57
  version: "0"
58
58
  - - "="
59
59
  - !ruby/object:Gem::Version
60
- version: 1.1.3
60
+ version: 1.1.4
61
61
  version:
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rake
@@ -97,15 +97,14 @@ extra_rdoc_files:
97
97
  - README
98
98
  - lib/eeml.rb
99
99
  - lib/eeml/constants.rb
100
- - lib/eeml/feed_retriever.rb
101
- - lib/eeml/json_environment_parser.rb
100
+ - lib/eeml/json_environment_parser_v005.rb
102
101
  - lib/eeml/output_registry.rb
103
102
  - lib/eeml/parser_registry.rb
104
103
  - lib/eeml/libxml_eeml_output_v005.rb
105
- - lib/eeml/feed_output.rb
106
104
  - lib/eeml/libxml_eeml_parser_v005.rb
107
105
  - lib/eeml/exceptions.rb
108
106
  - lib/eeml/csv_parser.rb
107
+ - lib/eeml/json_output.rb
109
108
  - lib/eeml/environment.rb
110
109
  - lib/blank.rb
111
110
  files:
@@ -120,20 +119,23 @@ files:
120
119
  - test/test_libxml_eeml_parser_v005.rb
121
120
  - test/test_helper.rb
122
121
  - test/data/minimal.xml
122
+ - test/data/doc_2_expected.json
123
+ - test/data/list.xml
123
124
  - test/data/out_empty.xml
125
+ - test/data/no_namespace.xml
124
126
  - test/data/doc_1.xml
125
127
  - test/data/doc_1.json
128
+ - test/data/doc_2.xml
126
129
  - lib/eeml.rb
127
130
  - lib/eeml/constants.rb
128
- - lib/eeml/feed_retriever.rb
129
- - lib/eeml/json_environment_parser.rb
131
+ - lib/eeml/json_environment_parser_v005.rb
130
132
  - lib/eeml/output_registry.rb
131
133
  - lib/eeml/parser_registry.rb
132
134
  - lib/eeml/libxml_eeml_output_v005.rb
133
- - lib/eeml/feed_output.rb
134
135
  - lib/eeml/libxml_eeml_parser_v005.rb
135
136
  - lib/eeml/exceptions.rb
136
137
  - lib/eeml/csv_parser.rb
138
+ - lib/eeml/json_output.rb
137
139
  - lib/eeml/environment.rb
138
140
  - lib/blank.rb
139
141
  - schemas/eeml/005.xsd
metadata.gz.sig CHANGED
@@ -1,3 +1 @@
1
- (ѭ�س�
2
- A���5jj�Bh�k_�G�F�ȴ'*KLY�|4��Q��
3
- ��<R���5 7z>ӱ�|�|]m��E:��a�.{�ҹ�J��h:�C�C�Է��DT���д���w�^d^
1
+ >�t�{��� ��)g�Bcg�T8�Z"B��.���C釴�d��3����M |�����I����uJ��Z�����Z%t4y��jM�����9 �=4<�+W���Y��l��M��et^>puEz�J4���?@�Mn\�kR�1���)�/�ʶTM y{��mb��J71_&v��5&�g�ˡ�l���JJ�v���c�؏oY�w���d� wN�9�[��Z����8S1�<wC�p�@�'�.�I�X�"X���B}�
@@ -1,169 +0,0 @@
1
- module FeedOutput # :nodoc:
2
- #TODO: move away from mixins for this functionality.
3
- #TODO: This is v005-specific.
4
- module EnvironmentNode # :nodoc:
5
- include LibXML
6
- #assumes a logger()
7
- #assumes retrieved_at()
8
-
9
- #TODO: Move these (now unused) methods to the publisher (e.g. a rails controller?) which will decide where it's going to host the env,
10
- # and which will set the feed property accordingly before serialising the env.
11
- # def public_feed_url
12
- # return "http://#{DEFAULT_HOST}/api/#{self.id}.xml"
13
- # end
14
-
15
- # def public_csv_url
16
- # return "http://#{DEFAULT_HOST}/api/#{self.id}.csv"
17
- # end
18
-
19
- # def public_json_url
20
- # return "http://#{DEFAULT_HOST}/api/#{self.id}.json"
21
- # end
22
-
23
-
24
- def create_eeml_document
25
- doc = XML::Document.new
26
- eeml = doc.root = XML::Node.new('eeml')
27
- XML::Namespace.new(eeml, nil, Eeml::EEML_HREF)
28
- XML::Namespace.new(eeml, 'xsi', Eeml::XSI_NAMESPACE)
29
- eeml['version'] = Eeml::EEML_VERSION
30
- eeml['xsi:schemaLocation'] = Eeml::EEML_SCHEMA_LOCATION
31
- return doc
32
- end
33
-
34
- # Create a csv representation of this environment by iterating through all datastreams and returning
35
- # their values.
36
- def to_csv
37
- return self.datastreams.map { |d| d.value }.join(",")
38
- end
39
-
40
- # Create an xml representation of this environment. The document returned should be valid EEML.
41
- # def to_eeml(options = { :full => true })
42
- # # Returns the public feed URL for this environment.
43
-
44
-
45
- # logger.debug("*** Returning eeml representation of environment: #{self.identifier}")
46
-
47
- # doc = create_eeml_document
48
-
49
- # doc.root << to_xml_node(options)
50
-
51
- # return doc.to_s(:encoding => XML::Encoding::UTF_8)
52
- # end
53
-
54
- def to_xml_node_old(options = { :full => true })
55
- logger.debug("*** Creating xml node for environment: #{self.identifier}")
56
-
57
- environment_node = XML::Node.new('environment')
58
- #TODO: this was retrieved_at in the db, but it's 'updated' in the xml. Clarify w sam...
59
- # ... env.retrieved_at doesn't make much sense to clients generating eeml using the gem.
60
- environment_node['updated'] = self.updated.strftime(XML_TIME_FORMAT_STRING) unless self.updated.nil?
61
- environment_node['id'] = self.identifier.to_s unless self.identifier.blank?
62
- #TODO: write all these strings out safely for xml
63
- environment_node['creator'] = self.creator.to_s unless self.creator.blank?
64
-
65
- #TODO: these all should really appear, even when absent? likely make conditional.
66
- unless self.title.blank?
67
- environment_node << title_node = XML::Node.new('title')
68
- title_node << self.title
69
- end
70
-
71
- unless self.feed_url.blank?
72
- environment_node << feed_node = XML::Node.new('feed')
73
- feed_node << self.feed_url
74
- end
75
-
76
- unless self.status.blank?
77
- environment_node << status_node = XML::Node.new('status')
78
- status_node << self.status
79
- end
80
-
81
- unless self.description.blank?
82
- environment_node << description_node = XML::Node.new('description')
83
- description_node << self.description
84
- end
85
-
86
- unless self.icon.blank?
87
- environment_node << icon_node = XML::Node.new('icon')
88
- icon_node << self.icon
89
- end
90
-
91
- unless self.website.blank?
92
- environment_node << website_node = XML::Node.new('website')
93
- website_node << self.website
94
- end
95
-
96
- unless self.email.blank?
97
- environment_node << email_node = XML::Node.new('email')
98
- email_node << self.email
99
- end
100
-
101
- unless self.location.nil?
102
- environment_node << location_node = XML::Node.new('location')
103
- location_node['domain'] = self.location.domain
104
- location_node['exposure'] = self.location.exposure unless self.location.exposure.blank?
105
- location_node['disposition'] = self.location.disposition unless self.location.disposition.blank?
106
-
107
- unless self.location.name.blank?
108
- location_node << location_name_node = XML::Node.new('name')
109
- location_name_node << self.location.name
110
- end
111
-
112
- location_node << lat_node = XML::Node.new('lat')
113
- lat_node << self.location.latitude
114
-
115
- location_node << lng_node = XML::Node.new('lon')
116
- lng_node << self.location.longitude
117
-
118
- unless self.location.elevation.blank?
119
- location_node << elevation_node = XML::Node.new('ele')
120
- elevation_node << self.location.elevation
121
- end
122
- end
123
-
124
- if options[:full] == true
125
- self.datastreams.each do |datastream|
126
- environment_node << datastream.to_xml_node unless datastream.nil?
127
- end
128
- end
129
-
130
- return environment_node
131
- end
132
- end
133
-
134
-
135
-
136
- module DataStreamNode # :nodoc:
137
- include LibXML
138
- # Create and return an XML::Node object representing this datastream. This method creates all
139
- # required child nodes of the datastream object, including the list of tag elements, any units element
140
- # and the value.
141
- def to_xml_node
142
- datastream_node = XML::Node.new('data')
143
- datastream_node['id'] = self.identifier.to_s
144
-
145
- self.tags.each do |tag|
146
- tag_node = XML::Node.new('tag')
147
- tag_node << tag
148
- datastream_node << tag_node
149
- end
150
-
151
- datastream_node << value_node = XML::Node.new('value')
152
-
153
- value_node['minValue'] = self.min_value.to_s unless self.min_value.to_s.empty?
154
- value_node['maxValue'] = self.max_value.to_s unless self.max_value.to_s.empty?
155
-
156
- value_node << self.value.to_s
157
-
158
- unless self.unit_value.to_s.empty? && self.unit_type.to_s.empty? && self.unit_symbol.to_s.empty?
159
- datastream_node << unit_node = XML::Node.new('unit')
160
- unit_node['type'] = self.unit_type.to_s unless self.unit_type.to_s.empty?
161
- unit_node['symbol'] = self.unit_symbol.to_s unless self.unit_symbol.to_s.empty?
162
- unit_node << self.unit_value.to_s unless self.unit_value.to_s.empty?
163
- end
164
-
165
- return datastream_node
166
- end
167
- end
168
-
169
- end
@@ -1,103 +0,0 @@
1
- require 'uri'
2
- require 'net/http'
3
- module Eeml
4
-
5
- class FeedRetriever
6
-
7
- DEFAULT_TIMEOUT = 5
8
- PREMIUM_ENVIRONMENT_AGE = raise 3
9
-
10
- attr_accessor :retrieval_errors #will hold an array of string error messages populated during feed retrieval. currently populated only in fetch_remote_data
11
- attr_accessor :logger
12
- attr_accessor :feed_url, :retrieved_at
13
- attr_accessor :feed_changed, :feed_retrieved
14
- attr_accessor :feed_content, :mime_type
15
-
16
- def initialize
17
- end
18
-
19
- # only attempt to retrieve data if request is after our minimum time delta
20
- #currently makes use of get_response() and fetch() to do actual retrieval.
21
- def fetch_remote_data
22
- @retrieval_errors = []
23
- logger.debug("*** Attempting to fetch remote data")
24
-
25
- # only attempt to retrieve data if this environment has a feed_url
26
- if !self.feed_url.blank? && (self.retrieved_at.nil? || (Time.now.utc - self.retrieved_at.utc) > PREMIUM_ENVIRONMENT_AGE)
27
- logger.debug("*** Our refresh delta has passed so retrieve remote data")
28
-
29
- self.feed_changed = false
30
- self.feed_retrieved = false
31
-
32
- response = get_response
33
-
34
- case response
35
- when Net::HTTPSuccess
36
- logger.debug("*** 200 ok... checking mime type #{response.content_type}.")
37
- if MIME_TYPES.include?(response.content_type)
38
- logger.debug("*** We have a valid mime type")
39
-
40
- self.feed_content = response.body.to_s.strip
41
- self.mime_type = response.content_type
42
-
43
- self.retrieved_at = Time.now.utc.to_s(:db)
44
- else
45
- logger.debug("*** wrong mime-type.")
46
- white_list = ['text/html', 'text/javascript', 'application/javascript'] # acceptably WRONG header values.
47
- filtered_advice = ( white_list.member?(response.content_type) ? " Got '#{response.content_type}'." : "" )
48
- @retrieval_errors << "Wrong mime-type. Need application/xml, text/csv, or variants." + filtered_advice
49
- end
50
- else
51
- self.feed_retrieved = false
52
- self.feed_changed = false
53
- logger.debug("*** Unable to fetch remote data")
54
- end
55
- else
56
- logger.debug("*** No feed url present or refresh delta not yet expired - don't do nothin")
57
- # TODO remove after development
58
- end
59
- rescue URI::InvalidURIError, Timeout::Error, SystemCallError => e
60
- self.feed_retrieved = false
61
- self.feed_changed = false
62
- @retrieval_errors << "Url bad or unavailable."
63
- logger.error("*** Error retrieving feed from remote source: #{e}")
64
- end
65
-
66
- # private
67
-
68
- # separating this method out makes mocking our response fairly simple
69
- # basically we just create a dummy response object, and override this
70
- # method with a stubbed version that returns our dummy response
71
- def get_response
72
- return fetch(feed_url)
73
- end
74
-
75
- # TODO: update test specs so this passes properly
76
- # this fetch method recursively follows redirections up to a maximum depth of 10 redirections
77
- def fetch(uri_str, limit = 10)
78
- uri = create_uri(uri_str)
79
-
80
- logger.debug("*** Fetching content from :#{uri}")
81
- http_client = Net::HTTP.new(uri.host, uri.port)
82
-
83
- # the default timeout appears to be 60 seconds. this is very long
84
- # override it to be 5 seconds
85
- http_client.open_timeout = DEFAULT_TIMEOUT
86
- http_client.read_timeout = DEFAULT_TIMEOUT
87
- response = http_client.request_get(uri.request_uri)
88
- logger.debug("*** Got response: #{response}")
89
- case response
90
- when Net::HTTPSuccess then response
91
- when Net::HTTPRedirection then fetch(response['location'], limit - 1)
92
- else response
93
- end
94
- end
95
-
96
- def create_uri(uri_str)
97
- logger.debug("*** Creating uri from: #{uri_str}")
98
- uri = URI.parse(uri_str)
99
- raise URI::InvalidURIError unless uri.is_a?(URI::HTTP) or uri.is_a?(URI::HTTPS)
100
- return uri
101
- end
102
- end
103
- end
@@ -1,11 +0,0 @@
1
- module Eeml
2
- #a parser for json environments
3
- class JsonEnvironmentParser
4
- def make_environment_from_json(json_str)
5
- env = Environment.new
6
- return env
7
- end
8
- end
9
- end
10
-
11
-