feedtools 0.2.23 → 0.2.24

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,16 @@
1
+ == FeedTools 0.2.24
2
+ * fixed autodiscovery bugs
3
+ * updated autodiscovery to handle relative uris
4
+ * added per feed configuration
5
+ * rewrote http retrieval code
6
+ * supports authenticated http proxies
7
+ * supports basic http auth
8
+ * fixed relative url resolution issues
9
+ * corrected db schema files to match migration file
10
+ * fixed bug in the save method
11
+ * fixed some major http bugs
12
+ * updated dependancies
13
+ * no longer causes problems with frozen rails
1
14
  == FeedTools 0.2.23
2
15
  * autodiscovery implemented
3
16
  * now knows a title from a hole in the ground
@@ -1,5 +1,5 @@
1
1
  -- Example MySQL schema
2
- CREATE TABLE `feeds` (
2
+ CREATE TABLE `cached_feeds` (
3
3
  `id` int(10) unsigned NOT NULL auto_increment,
4
4
  `href` varchar(255) default NULL,
5
5
  `title` varchar(255) default NULL,
@@ -1,5 +1,5 @@
1
1
  -- Example PostgreSQL schema
2
- CREATE TABLE feeds (
2
+ CREATE TABLE cached_feeds (
3
3
  id SERIAL PRIMARY KEY NOT NULL,
4
4
  href varchar(255) default NULL,
5
5
  title varchar(255) default NULL,
@@ -1,5 +1,5 @@
1
1
  -- Example Sqlite schema
2
- CREATE TABLE feeds (
2
+ CREATE TABLE cached_feeds (
3
3
  id INTEGER PRIMARY KEY NOT NULL,
4
4
  href VARCHAR(255) DEFAULT NULL,
5
5
  title VARCHAR(255) DEFAULT NULL,
@@ -21,7 +21,7 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- if Object.const_defined?(:FEED_TOOLS_ENV)
24
+ if Object.const_defined?(:FEED_TOOLS_NAMESPACES)
25
25
  warn("FeedTools may have been loaded improperly. This may be caused " +
26
26
  "by the presence of the RUBYOPT environment variable or by using " +
27
27
  "load instead of require. This can also be caused by missing " +
@@ -32,8 +32,6 @@ FEED_TOOLS_ENV = ENV['FEED_TOOLS_ENV'] ||
32
32
  ENV['RAILS_ENV'] ||
33
33
  'development' # :nodoc:
34
34
 
35
- FEED_TOOLS_VERSION = "0.2.23"
36
-
37
35
  FEED_TOOLS_NAMESPACES = {
38
36
  "admin" => "http://webns.net/mvcb/",
39
37
  "ag" => "http://purl.org/rss/1.0/modules/aggregation/",
@@ -58,6 +56,7 @@ FEED_TOOLS_NAMESPACES = {
58
56
  "image" => "http://purl.org/rss/1.0/modules/image/",
59
57
  "feedburner" => "http://rssnamespace.org/feedburner/ext/1.0",
60
58
  "foaf" => "http://xmlns.com/foaf/0.1/",
59
+ "foo" => "http://hsivonen.iki.fi/FooML",
61
60
  "fm" => "http://freshmeat.net/rss/fm/",
62
61
  "itunes" => "http://www.itunes.com/dtds/podcast-1.0.dtd",
63
62
  "l" => "http://purl.org/rss/1.0/modules/link/",
@@ -94,6 +93,8 @@ $:.unshift(File.dirname(__FILE__))
94
93
  $:.unshift(File.dirname(__FILE__) + "/feed_tools/vendor")
95
94
 
96
95
  begin
96
+ require 'feed_tools/version'
97
+
97
98
  begin
98
99
  require 'iconv'
99
100
  rescue Object
@@ -133,8 +134,12 @@ begin
133
134
  require 'yaml'
134
135
  require 'base64'
135
136
 
136
- require_gem('activesupport', '>= 1.1.1')
137
- require_gem('activerecord', '>= 1.11.1')
137
+ if !defined?(ActiveSupport)
138
+ require_gem('activesupport', '>= 1.1.1')
139
+ end
140
+ if !defined?(ActiveRecord)
141
+ require_gem('activerecord', '>= 1.11.1')
142
+ end
138
143
 
139
144
  begin
140
145
  require_gem('uuidtools', '>= 0.1.2')
@@ -186,13 +191,19 @@ module FeedTools
186
191
  config_hash = {}
187
192
  @configurations = {
188
193
  :feed_cache => nil,
194
+ :disable_update_from_remote => false,
189
195
  :proxy_address => nil,
190
196
  :proxy_port => nil,
191
- :user_agent => "FeedTools/#{FEED_TOOLS_VERSION} " +
197
+ :proxy_user => nil,
198
+ :proxy_password => nil,
199
+ :user_agent =>
200
+ "FeedTools/#{FeedTools::FEED_TOOLS_VERSION::STRING} " +
192
201
  "+http://www.sporkmonger.com/projects/feedtools/",
193
- :generator_name => "FeedTools/#{FEED_TOOLS_VERSION}",
194
- :generator_href => "http://www.sporkmonger.com/projects/feedtools/",
195
- :tidy_enabled => true,
202
+ :generator_name =>
203
+ "FeedTools/#{FeedTools::FEED_TOOLS_VERSION::STRING}",
204
+ :generator_href =>
205
+ "http://www.sporkmonger.com/projects/feedtools/",
206
+ :tidy_enabled => false,
196
207
  :tidy_options => {},
197
208
  :idn_enabled => true,
198
209
  :sanitization_enabled => true,
@@ -357,7 +368,7 @@ module REXML # :nodoc:
357
368
  ns = node.namespace( prefix )
358
369
  end
359
370
  !(node.node_type == :element and
360
- node.name.downcase == name and node.namespace == ns )
371
+ node.name.downcase == name.downcase and node.namespace == ns )
361
372
  end
362
373
  return n
363
374
 
@@ -420,7 +431,7 @@ module REXML # :nodoc:
420
431
  for element in nodeset
421
432
  if element.node_type == :element
422
433
  for attribute_name in element.attributes.keys
423
- if attribute_name.downcase == name
434
+ if attribute_name.downcase == name.downcase
424
435
  attrib = element.attribute( attribute_name,
425
436
  @namespaces[prefix] )
426
437
  new_nodeset << attrib if attrib
@@ -438,7 +449,8 @@ module REXML # :nodoc:
438
449
  return new_nodeset
439
450
 
440
451
  when :parent
441
- return internal_parse( path_stack, nodeset.collect{|n| n.parent}.compact )
452
+ return internal_parse( path_stack,
453
+ nodeset.collect{|n| n.parent}.compact )
442
454
 
443
455
  when :ancestor
444
456
  new_nodeset = []
@@ -51,14 +51,17 @@ module FeedTools
51
51
  begin
52
52
  possible_config_files = [
53
53
  "./config/database.yml",
54
- "../config/database.yml",
55
54
  "./database.yml",
55
+ "../config/database.yml",
56
56
  "../database.yml",
57
- "../../database.yml"
57
+ "../../config/database.yml",
58
+ "../../database.yml",
59
+ "../../../config/database.yml",
60
+ "../../../database.yml"
58
61
  ]
59
62
  database_config_file = nil
60
63
  for file in possible_config_files
61
- if File.exists? file
64
+ if File.exists?(File.expand_path(file))
62
65
  database_config_file = file
63
66
  break
64
67
  end
@@ -109,9 +112,9 @@ module FeedTools
109
112
  # True if the appropriate database table already exists
110
113
  def DatabaseFeedCache.table_exists?
111
114
  begin
112
- ActiveRecord::Base.connection.execute "select id, href, title, " +
115
+ ActiveRecord::Base.connection.execute("select id, href, title, " +
113
116
  "link, feed_data, feed_data_type, http_headers, last_retrieved " +
114
- "from #{self.table_name()} limit 1"
117
+ "from #{self.table_name()} limit 1")
115
118
  rescue ActiveRecord::StatementInvalid
116
119
  return false
117
120
  rescue
@@ -24,6 +24,7 @@
24
24
  require 'rexml/document'
25
25
  require 'feed_tools/feed_item'
26
26
  require 'feed_tools/feed_structures'
27
+ require 'feed_tools/helpers/retrieval_helper'
27
28
  require 'feed_tools/helpers/generic_helper'
28
29
  require 'feed_tools/helpers/xml_helper'
29
30
  require 'feed_tools/helpers/html_helper'
@@ -51,19 +52,22 @@ module FeedTools
51
52
  @entries = nil
52
53
  @live = false
53
54
  @encoding = nil
55
+ @options = nil
54
56
  end
55
57
 
56
58
  # Loads the feed specified by the url, pulling the data from the
57
- # cache if it hasn't expired.
58
- # Options are:
59
- # * <tt>:cache_only</tt> - If set to true, the feed will only be
60
- # pulled from the cache.
59
+ # cache if it hasn't expired. Options supplied will override the
60
+ # default options.
61
61
  def Feed.open(url, options={})
62
- FeedTools::GenericHelper.validate_options([ :cache_only ],
63
- options.keys)
64
- options = { :cache_only => false }.merge(options)
62
+ FeedTools::GenericHelper.validate_options(
63
+ FeedTools.configurations.keys, options.keys)
64
+
65
+ # create the new feed
66
+ feed = FeedTools::Feed.new
67
+
68
+ feed.configurations = FeedTools.configurations.merge(options)
65
69
 
66
- if options[:cache_only] && FeedTools.feed_cache.nil?
70
+ if feed.configurations[:feed_cache] != nil && FeedTools.feed_cache.nil?
67
71
  raise(ArgumentError, "There is currently no caching mechanism set. " +
68
72
  "Cannot retrieve cached feeds.")
69
73
  end
@@ -71,16 +75,32 @@ module FeedTools
71
75
  # clean up the url
72
76
  url = FeedTools::UriHelper.normalize_url(url)
73
77
 
74
- # create and load the new feed
75
- feed = FeedTools::Feed.new
78
+ # load the new feed
76
79
  feed.href = url
77
- feed.update! unless options[:cache_only]
80
+ feed.update! unless feed.configurations[:disable_update_from_remote]
78
81
  return feed
79
82
  end
83
+
84
+ # Returns the load options for this feed.
85
+ def configurations
86
+ if @configurations.blank?
87
+ @configurations = FeedTools.configurations.dup
88
+ end
89
+ return @configurations
90
+ end
91
+
92
+ # Sets the load options for this feed.
93
+ def configurations=(new_configurations)
94
+ @configurations = new_configurations
95
+ end
80
96
 
81
97
  # Loads the feed from the remote url if the feed has expired from the
82
98
  # cache or cannot be retrieved from the cache for some reason.
83
99
  def update!
100
+ if self.configurations[:disable_update_from_remote]
101
+ # Don't do anything if this option is set
102
+ return
103
+ end
84
104
  if !FeedTools.feed_cache.nil? &&
85
105
  !FeedTools.feed_cache.set_up_correctly?
86
106
  raise "Your feed cache system is incorrectly set up. " +
@@ -101,7 +121,7 @@ module FeedTools
101
121
  # Handle autodiscovery
102
122
  if self.http_headers['content-type'] =~ /text\/html/ ||
103
123
  self.http_headers['content-type'] =~ /application\/xhtml\+xml/
104
-
124
+
105
125
  autodiscovered_url = nil
106
126
  autodiscovered_url =
107
127
  FeedTools::HtmlHelper.extract_link_by_mime_type(self.feed_data,
@@ -117,9 +137,19 @@ module FeedTools
117
137
  "application/rdf+xml")
118
138
  end
119
139
  unless autodiscovered_url.nil?
140
+ begin
141
+ autodiscovered_url = FeedTools::UriHelper.resolve_relative_uri(
142
+ autodiscovered_url, [self.href])
143
+ rescue Exception
144
+ end
120
145
  self.feed_data = nil
121
146
  self.href = autodiscovered_url
122
- self.expire! unless self.cache_object.nil?
147
+ if FeedTools.feed_cache.nil?
148
+ self.cache_object = nil
149
+ else
150
+ self.cache_object =
151
+ FeedTools.feed_cache.find_by_href(autodiscovered_url)
152
+ end
123
153
  self.update!
124
154
  end
125
155
  end
@@ -170,226 +200,67 @@ module FeedTools
170
200
 
171
201
  # No need for http headers unless we're actually doing http
172
202
  if retrieval_method == "http"
173
- # Set up the appropriate http headers
174
- headers = {}
175
- unless self.http_headers.nil?
176
- headers["If-None-Match"] =
177
- self.http_headers['etag'] unless self.http_headers['etag'].nil?
178
- headers["If-Modified-Since"] =
179
- self.http_headers['last-modified'] unless
180
- self.http_headers['last-modified'].nil?
181
- end
182
- unless FeedTools.configurations[:user_agent].nil?
183
- headers["User-Agent"] = FeedTools.configurations[:user_agent]
184
- end
185
-
186
- # The http feed access method
187
- http_fetch = lambda do |feed_url, request_headers, redirect_limit,
188
- response_chain, no_headers|
189
- raise FeedAccessError, 'Redirect too deep' if redirect_limit == 0
190
- feed_uri = nil
191
- begin
192
- feed_uri = URI.parse(feed_url)
193
- rescue URI::InvalidURIError
194
- # Uh, maybe try to fix it?
195
- feed_uri = URI.parse(FeedTools::UriHelper.normalize_url(feed_url))
196
- end
197
-
198
- begin
199
- proxy_address = (FeedTools.configurations[:proxy_address] || nil)
200
- proxy_port = (FeedTools.configurations[:proxy_port].to_i || nil)
201
-
202
- http = Net::HTTP::Proxy(proxy_address, proxy_port).new(
203
- feed_uri.host, (feed_uri.port or 80))
204
- http.start do
205
- final_uri = feed_uri.path
206
- final_uri += ('?' + feed_uri.query) if feed_uri.query
207
- request_headers = {} if no_headers
208
- response = http.request_get(final_uri, request_headers)
209
-
210
- case response
211
- when Net::HTTPSuccess
212
- # We've reached the final destination, process all previous
213
- # redirections, and see if we need to update the url.
214
- for redirected_response in response_chain
215
- if redirected_response.last.code.to_i == 301
216
- # Reset the cache object or we may get duplicate entries
217
- self.cache_object = nil
218
- self.href = redirected_response.last['location']
219
- else
220
- # Jump out as soon as we hit anything that isn't a
221
- # permanently moved redirection.
222
- break
223
- end
224
- end
225
- response
226
- when Net::HTTPRedirection
227
- if response.code.to_i == 304
228
- response.error!
229
- else
230
- if response['location'].nil?
231
- raise FeedAccessError,
232
- "No location to redirect to supplied: " + response.code
233
- end
234
- response_chain << [feed_url, response]
235
- new_location = response['location']
236
- if response_chain.assoc(new_location) != nil
237
- raise FeedAccessError,
238
- "Redirection loop detected: #{new_location}"
239
- end
240
-
241
- # Find out if we've already seen the url we've been
242
- # redirected to.
243
- found_redirect = false
244
- begin
245
- cached_feed = FeedTools::Feed.open(new_location,
246
- :cache_only => true)
247
- if cached_feed.cache_object != nil &&
248
- cached_feed.cache_object.new_record? != true
249
- if !cached_feed.expired? &&
250
- !cached_feed.http_headers.blank?
251
- # Copy the cached state
252
- self.href = cached_feed.href
253
-
254
- @feed_data = cached_feed.feed_data
255
- @feed_data_type = cached_feed.feed_data_type
256
-
257
- if @feed_data.blank?
258
- raise "Invalid cache data."
259
- end
203
+ begin
204
+ @http_response = (FeedTools::RetrievalHelper.http_get(
205
+ self.href, :feed_object => self) do |url, response|
206
+ # Find out if we've already seen the url we've been
207
+ # redirected to.
208
+ follow_redirect = true
260
209
 
261
- @title = nil; self.title
262
- @link = nil; self.link
263
-
264
- self.last_retrieved = cached_feed.last_retrieved
265
- self.http_headers = cached_feed.http_headers
266
- self.cache_object = cached_feed.cache_object
267
- @live = false
268
- found_redirect = true
269
- end
210
+ begin
211
+ cached_feed = FeedTools::Feed.open(url,
212
+ :disable_update_from_remote => true)
213
+ if cached_feed.cache_object != nil &&
214
+ cached_feed.cache_object.new_record? != true
215
+ if !cached_feed.expired? &&
216
+ !cached_feed.http_headers.blank?
217
+ # Copy the cached state
218
+ self.href = cached_feed.href
219
+
220
+ @feed_data = cached_feed.feed_data
221
+ @feed_data_type = cached_feed.feed_data_type
222
+
223
+ if @feed_data.blank?
224
+ raise "Invalid cache data."
270
225
  end
271
- rescue
272
- # If anything goes wrong, ignore it.
273
- end
274
- unless found_redirect
275
- # TODO: deal with stupid people using relative urls
276
- # in Location header
277
- # =================================================
278
- http_fetch.call(new_location, http_headers,
279
- redirect_limit - 1, response_chain, no_headers)
280
- else
281
- response
282
- end
283
- end
284
- else
285
- class << response
286
- def response_chain
287
- return @response_chain
226
+
227
+ @title = nil; self.title
228
+ @link = nil; self.link
229
+
230
+ self.last_retrieved = cached_feed.last_retrieved
231
+ self.http_headers = cached_feed.http_headers
232
+ self.cache_object = cached_feed.cache_object
233
+ @live = false
234
+ follow_redirect = false
288
235
  end
289
236
  end
290
- response.instance_variable_set("@response_chain",
291
- response_chain)
292
- response.error!
293
- end
294
- end
295
- rescue SocketError
296
- raise FeedAccessError, 'Socket error prevented feed retrieval'
297
- rescue Timeout::Error
298
- raise FeedAccessError, 'Timeout while attempting to retrieve feed'
299
- rescue Errno::ENETUNREACH
300
- raise FeedAccessError, 'Network was unreachable'
301
- rescue Errno::ECONNRESET
302
- raise FeedAccessError, 'Connection was reset by peer'
303
- end
304
- end
305
-
306
- begin
307
- begin
308
- @http_response = http_fetch.call(self.href, headers, 10, [], false)
309
- rescue => error
310
- if error.respond_to?(:response)
311
- # You might not believe this, but...
312
- #
313
- # Under certain circumstances, web servers will try to block
314
- # based on the User-Agent header. This is *retarded*. But
315
- # we won't let their stupid error stop us!
316
- #
317
- # This is, of course, a quick-n-dirty hack. But at least
318
- # we get to blame other people's bad software and/or bad
319
- # configuration files.
320
- if error.response.code.to_i == 404 &&
321
- FeedTools.configurations[:user_agent] != nil
322
- @http_response = http_fetch.call(self.href, {}, 10, [], true)
323
- if @http_response != nil && @http_response.code.to_i == 200
324
- warn("The server appears to be blocking based on the " +
325
- "User-Agent header. This is stupid, and you should " +
326
- "inform the webmaster of this.")
327
- end
328
- else
329
- raise error
237
+ rescue
238
+ # If anything goes wrong, ignore it.
330
239
  end
331
- else
332
- raise error
333
- end
334
- end
335
- unless @http_response.kind_of? Net::HTTPRedirection
240
+ follow_redirect
241
+ end)
242
+ case @http_response
243
+ when Net::HTTPSuccess
336
244
  @feed_data = self.http_response.body
337
245
  @http_headers = {}
338
246
  self.http_response.each_header do |key, value|
339
247
  self.http_headers[key.downcase] = value
340
248
  end
341
249
  self.last_retrieved = Time.now.gmtime
342
- end
343
- rescue FeedAccessError
344
- @live = false
345
- if self.feed_data.nil?
346
- raise
347
- end
348
- rescue Timeout::Error
349
- # if we time out, do nothing, it should fall back to the feed_data
350
- # stored in the cache.
351
- @live = false
352
- if self.feed_data.nil?
353
- raise
354
- end
355
- rescue Errno::ECONNRESET
356
- # if the connection gets reset by peer, oh well, fall back to the
357
- # feed_data stored in the cache
358
- @live = false
359
- if self.feed_data.nil?
360
- raise
361
- end
362
- rescue => error
363
- # heck, if anything at all bad happens, fall back to the feed_data
364
- # stored in the cache.
365
-
366
- # If we can, get the HTTPResponse...
367
- @http_response = nil
368
- if error.respond_to?(:each_header)
369
- @http_response = error
370
- end
371
- if error.respond_to?(:response) &&
372
- error.response.respond_to?(:each_header)
373
- @http_response = error.response
374
- end
375
- if @http_response != nil
250
+ @live = true
251
+ when Net::HTTPNotModified
376
252
  @http_headers = {}
377
253
  self.http_response.each_header do |key, value|
378
254
  self.http_headers[key.downcase] = value
379
255
  end
380
- if self.http_response.code.to_i == 304
381
- self.last_retrieved = Time.now.gmtime
382
- end
256
+ self.last_retrieved = Time.now.gmtime
257
+ @live = true
258
+ else
259
+ @live = false
383
260
  end
261
+ rescue Exception => error
384
262
  @live = false
385
263
  if self.feed_data.nil?
386
- if error.respond_to?(:response) &&
387
- error.response.respond_to?(:response_chain)
388
- redirects = error.response.response_chain.map do |pair|
389
- pair.first
390
- end
391
- error.message << (" - Redirects: " + redirects.inspect)
392
- end
393
264
  raise error
394
265
  end
395
266
  end
@@ -407,7 +278,7 @@ module FeedTools
407
278
  # with 'file://', strip the 'file://' off the front of the url.
408
279
  file_name = self.href.gsub(/^file:\/\//, "")
409
280
  if RUBY_PLATFORM =~ /mswin/
410
- file_name = file_name[1..-1] if file_name[1..1] == "/"
281
+ file_name = file_name[1..-1] if file_name[0..0] == "/"
411
282
  end
412
283
  begin
413
284
  open(file_name) do |file|
@@ -885,7 +756,7 @@ module FeedTools
885
756
  end
886
757
  rescue
887
758
  end
888
- if FeedTools.configurations[:url_normalization_enabled]
759
+ if self.configurations[:url_normalization_enabled]
889
760
  @href = FeedTools::UriHelper.normalize_url(@href)
890
761
  end
891
762
  @href.strip! unless @href.nil?
@@ -925,7 +796,7 @@ module FeedTools
925
796
  @title = FeedTools::HtmlHelper.process_text_construct(title_node,
926
797
  self.feed_type, self.feed_version)
927
798
  if self.feed_type == "atom" ||
928
- FeedTools.configurations[:always_strip_wrapper_elements]
799
+ self.configurations[:always_strip_wrapper_elements]
929
800
  @title = FeedTools::HtmlHelper.strip_wrapper_element(@title)
930
801
  end
931
802
  @title = nil if @title.blank?
@@ -943,7 +814,6 @@ module FeedTools
943
814
  # Returns the feed subtitle
944
815
  def subtitle
945
816
  if @subtitle.nil?
946
- repair_entities = false
947
817
  subtitle_node = FeedTools::XmlHelper.try_xpaths(self.channel_node, [
948
818
  "atom10:subtitle",
949
819
  "subtitle",
@@ -968,7 +838,7 @@ module FeedTools
968
838
  @subtitle = FeedTools::HtmlHelper.process_text_construct(
969
839
  subtitle_node, self.feed_type, self.feed_version)
970
840
  if self.feed_type == "atom" ||
971
- FeedTools.configurations[:always_strip_wrapper_elements]
841
+ self.configurations[:always_strip_wrapper_elements]
972
842
  @subtitle = FeedTools::HtmlHelper.strip_wrapper_element(@subtitle)
973
843
  end
974
844
  if @subtitle.blank?
@@ -1125,7 +995,7 @@ module FeedTools
1125
995
  end
1126
996
  rescue
1127
997
  end
1128
- if FeedTools.configurations[:url_normalization_enabled]
998
+ if self.configurations[:url_normalization_enabled]
1129
999
  @link = FeedTools::UriHelper.normalize_url(@link)
1130
1000
  end
1131
1001
  unless self.cache_object.nil?
@@ -1179,7 +1049,7 @@ module FeedTools
1179
1049
  end
1180
1050
  rescue
1181
1051
  end
1182
- if FeedTools.configurations[:url_normalization_enabled]
1052
+ if self.configurations[:url_normalization_enabled]
1183
1053
  link_object.href =
1184
1054
  FeedTools::UriHelper.normalize_url(link_object.href)
1185
1055
  end
@@ -1609,12 +1479,12 @@ module FeedTools
1609
1479
  unless time_string.blank?
1610
1480
  @time = Time.parse(time_string).gmtime
1611
1481
  else
1612
- if FeedTools.configurations[:timestamp_estimation_enabled]
1482
+ if self.configurations[:timestamp_estimation_enabled]
1613
1483
  @time = Time.now.gmtime
1614
1484
  end
1615
1485
  end
1616
1486
  rescue
1617
- if FeedTools.configurations[:timestamp_estimation_enabled]
1487
+ if self.configurations[:timestamp_estimation_enabled]
1618
1488
  @time = Time.now.gmtime
1619
1489
  end
1620
1490
  end
@@ -1750,7 +1620,7 @@ module FeedTools
1750
1620
  end
1751
1621
  rescue
1752
1622
  end
1753
- if FeedTools.configurations[:url_normalization_enabled]
1623
+ if self.configurations[:url_normalization_enabled]
1754
1624
  image.href = FeedTools::UriHelper.normalize_url(image.href)
1755
1625
  end
1756
1626
  image.href.strip! unless image.href.nil?
@@ -1835,7 +1705,7 @@ module FeedTools
1835
1705
  @rights = FeedTools::HtmlHelper.process_text_construct(rights_node,
1836
1706
  self.feed_type, self.feed_version)
1837
1707
  if self.feed_type == "atom" ||
1838
- FeedTools.configurations[:always_strip_wrapper_elements]
1708
+ self.configurations[:always_strip_wrapper_elements]
1839
1709
  @rights = FeedTools::HtmlHelper.strip_wrapper_element(@rights)
1840
1710
  end
1841
1711
  end
@@ -1944,10 +1814,10 @@ module FeedTools
1944
1814
  if @time_to_live.nil? || @time_to_live == 0
1945
1815
  # Default to one hour
1946
1816
  @time_to_live = 1.hour
1947
- elsif FeedTools.configurations[:max_ttl] != nil &&
1948
- FeedTools.configurations[:max_ttl] != 0 &&
1949
- @time_to_live >= FeedTools.configurations[:max_ttl].to_i
1950
- @time_to_live = FeedTools.configurations[:max_ttl].to_i
1817
+ elsif self.configurations[:max_ttl] != nil &&
1818
+ self.configurations[:max_ttl] != 0 &&
1819
+ @time_to_live >= self.configurations[:max_ttl].to_i
1820
+ @time_to_live = self.configurations[:max_ttl].to_i
1951
1821
  end
1952
1822
  @time_to_live = @time_to_live.round
1953
1823
  return @time_to_live
@@ -2034,7 +1904,7 @@ module FeedTools
2034
1904
  end
2035
1905
  rescue
2036
1906
  end
2037
- if FeedTools.configurations[:url_normalization_enabled]
1907
+ if self.configurations[:url_normalization_enabled]
2038
1908
  @docs = FeedTools::UriHelper.normalize_url(@docs)
2039
1909
  end
2040
1910
  end
@@ -2145,17 +2015,17 @@ module FeedTools
2145
2015
  end
2146
2016
 
2147
2017
  # Sort the items
2148
- if FeedTools.configurations[:entry_sorting_property] == "time"
2018
+ if self.configurations[:entry_sorting_property] == "time"
2149
2019
  @entries = @entries.sort do |a, b|
2150
2020
  (b.time or Time.utc(1970)) <=> (a.time or Time.utc(1970))
2151
2021
  end
2152
- elsif FeedTools.configurations[:entry_sorting_property] != nil
2153
- sorting_property = FeedTools.configurations[:entry_sorting_property]
2022
+ elsif self.configurations[:entry_sorting_property] != nil
2023
+ sorting_property = self.configurations[:entry_sorting_property]
2154
2024
  @entries = @entries.sort do |a, b|
2155
2025
  eval("a.#{sorting_property}") <=> eval("b.#{sorting_property}")
2156
2026
  end
2157
2027
  else
2158
- @entries = @entries.reverse
2028
+ return @entries.reverse
2159
2029
  end
2160
2030
  return @entries
2161
2031
  end
@@ -2255,7 +2125,7 @@ module FeedTools
2255
2125
  xml_builder=Builder::XmlMarkup.new(
2256
2126
  :indent => 2, :escape_attrs => false))
2257
2127
  xml_builder.instruct! :xml, :version => "1.0",
2258
- :encoding => (FeedTools.configurations[:output_encoding] or "utf-8")
2128
+ :encoding => (self.configurations[:output_encoding] or "utf-8")
2259
2129
  if feed_type.nil?
2260
2130
  feed_type = self.feed_type
2261
2131
  end
@@ -2335,7 +2205,7 @@ module FeedTools
2335
2205
  end
2336
2206
  xml_builder.tag!(
2337
2207
  "admin:generatorAgent",
2338
- "rdf:resource" => FeedTools.configurations[:generator_href])
2208
+ "rdf:resource" => self.configurations[:generator_href])
2339
2209
  build_xml_hook(feed_type, feed_version, xml_builder)
2340
2210
  end
2341
2211
  unless self.images.blank?
@@ -2408,7 +2278,7 @@ module FeedTools
2408
2278
  end
2409
2279
  xml_builder.ttl((time_to_live / 1.minute).to_s)
2410
2280
  xml_builder.generator(
2411
- FeedTools.configurations[:generator_href])
2281
+ self.configurations[:generator_href])
2412
2282
  build_xml_hook(feed_type, feed_version, xml_builder)
2413
2283
  unless items.nil?
2414
2284
  for item in items
@@ -2467,8 +2337,8 @@ module FeedTools
2467
2337
  unless self.rights.blank?
2468
2338
  xml_builder.rights(self.rights)
2469
2339
  end
2470
- xml_builder.generator(FeedTools.configurations[:generator_name] +
2471
- " - " + FeedTools.configurations[:generator_href])
2340
+ xml_builder.generator(self.configurations[:generator_name] +
2341
+ " - " + self.configurations[:generator_href])
2472
2342
  if self.id != nil
2473
2343
  unless FeedTools::UriHelper.is_uri? self.id
2474
2344
  if self.link != nil
@@ -2498,6 +2368,18 @@ module FeedTools
2498
2368
 
2499
2369
  # Persists the current feed state to the cache.
2500
2370
  def save
2371
+ if self.configurations[:feed_cache].nil?
2372
+ # The cache is disabled for this feed, do nothing.
2373
+ return
2374
+ end
2375
+ if self.http_headers['content-type'] =~ /text\/html/ ||
2376
+ self.http_headers['content-type'] =~ /application\/xhtml\+xml/
2377
+ if self.title.nil? && self.link.nil? && self.entries.blank?
2378
+ # Don't save html pages to the cache, it messes with
2379
+ # autodiscovery.
2380
+ return
2381
+ end
2382
+ end
2501
2383
  unless self.href =~ /^file:\/\//
2502
2384
  if FeedTools.feed_cache.nil?
2503
2385
  raise "Caching is currently disabled. Cannot save to cache."