feedtools 0.2.8 → 0.2.9

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/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ == FeedTools 0.2.9
2
+ * changed ordering of elements checked for the item content
3
+ * added dependancy on uuidtools, uuids used in feed generation
4
+ * database feed cache implementation factored out into its own file
5
+ * http_fetch changed to use lambda
6
+ * fixed invalid rss 1.0/2.0 generation (missing some namespaces)
1
7
  == FeedTools 0.2.8
2
8
  * fixed bug with http headers being loaded from invalid YAML
3
9
  * fixed uninitialized constant bug (you shouldn't have RUBYOPT set)
@@ -0,0 +1,145 @@
1
+ #= database_feed_cache.rb
2
+ #
3
+ # The <tt>DatabaseFeedCache</tt> is the default caching mechanism for
4
+ # FeedTools. This mechanism can be replaced easily by creating another
5
+ # class with the required set of methods and setting
6
+ # <tt>FeedTools#feed_cache</tt> to the new class.
7
+ module FeedTools
8
+ # The default caching mechanism for the FeedTools module
9
+ class DatabaseFeedCache < ActiveRecord::Base
10
+ # Overrides the default table name to use the "feeds" table.
11
+ def self.table_name() "feeds" end
12
+
13
+ # If ActiveRecord is not already connected, attempts to find a configuration file and use
14
+ # it to open a connection for ActiveRecord.
15
+ # This method is probably unnecessary for anything but testing and debugging purposes.
16
+ # In a Rails environment, the connection will already have been established
17
+ # and this method will simply do nothing.
18
+ #
19
+ # This method should not raise any exceptions because it's designed to be run only when
20
+ # the module is first loaded. If it fails, the user should get an exception when they
21
+ # try to perform some action that makes use of the caching functionality, and not until.
22
+ def DatabaseFeedCache.initialize_cache
23
+ # Establish a connection if we don't already have one
24
+ begin
25
+ ActiveRecord::Base.connection
26
+ rescue
27
+ begin
28
+ possible_config_files = [
29
+ "./config/database.yml",
30
+ "../config/database.yml",
31
+ "./database.yml",
32
+ "../database.yml"
33
+ ]
34
+ database_config_file = nil
35
+ for file in possible_config_files
36
+ if File.exists? file
37
+ database_config_file = file
38
+ break
39
+ end
40
+ end
41
+ database_config_hash = File.open(database_config_file) do |file|
42
+ config_hash = YAML::load(file)
43
+ unless config_hash[FEED_TOOLS_ENV].nil?
44
+ config_hash = config_hash[FEED_TOOLS_ENV]
45
+ end
46
+ config_hash
47
+ end
48
+ ActiveRecord::Base.configurations = database_config_hash
49
+ ActiveRecord::Base.establish_connection(database_config_hash)
50
+ ActiveRecord::Base.connection
51
+ rescue
52
+ end
53
+ end
54
+ # Verify that the necessary database tables are in place
55
+ # and if they're missing, create them
56
+ unless DatabaseFeedCache.table_exists?
57
+ DatabaseFeedCache.create_table
58
+ end
59
+ return nil
60
+ end
61
+
62
+ # Returns true if a connection to the database has been established and the
63
+ # required table structure is in place.
64
+ def DatabaseFeedCache.connected?
65
+ begin
66
+ ActiveRecord::Base.connection
67
+ return false if ActiveRecord::Base.configurations.nil?
68
+ return false unless DatabaseFeedCache.table_exists?
69
+ rescue => error
70
+ return false
71
+ end
72
+ return true
73
+ end
74
+
75
+ # True if the appropriate database table already exists
76
+ def DatabaseFeedCache.table_exists?
77
+ begin
78
+ ActiveRecord::Base.connection.execute "select id, url, title, " +
79
+ "link, xml_data, http_headers, last_retrieved " +
80
+ "from #{self.table_name()} limit 1"
81
+ rescue ActiveRecord::StatementInvalid
82
+ return false
83
+ rescue
84
+ return false
85
+ end
86
+ return true
87
+ end
88
+
89
+ # Creates the appropriate database table
90
+ # Deprecated.
91
+ def DatabaseFeedCache.create_table
92
+ warn("The table creation methods will be removed in a future version " +
93
+ "and any reliance on this method should be removed.")
94
+ unless DatabaseFeedCache.table_exists?
95
+ feeds_mysql = <<-SQL_END
96
+ CREATE TABLE `#{self.table_name()}` (
97
+ `id` int(10) unsigned NOT NULL auto_increment,
98
+ `url` varchar(255) default NULL,
99
+ `title` varchar(255) default NULL,
100
+ `link` varchar(255) default NULL,
101
+ `xml_data` longtext default NULL,
102
+ `http_headers` text default NULL,
103
+ `last_retrieved` datetime default NULL,
104
+ PRIMARY KEY (`id`)
105
+ )
106
+ SQL_END
107
+ feeds_sqlite = <<-SQL_END
108
+ CREATE TABLE '#{self.table_name()}' (
109
+ 'id' INTEGER PRIMARY KEY NOT NULL,
110
+ 'url' VARCHAR(255) DEFAULT NULL,
111
+ 'title' VARCHAR(255) DEFAULT NULL,
112
+ 'link' VARCHAR(255) DEFAULT NULL,
113
+ 'xml_data' TEXT DEFAULT NULL,
114
+ 'http_headers' TEXT DEFAULT NULL,
115
+ 'last_retrieved' DATETIME DEFAULT NULL
116
+ );
117
+ SQL_END
118
+ feeds_psql = <<-SQL_END
119
+ CREATE TABLE #{self.table_name()} (
120
+ id SERIAL PRIMARY KEY NOT NULL,
121
+ url varchar(255) default NULL,
122
+ title varchar(255) default NULL,
123
+ link varchar(255) default NULL,
124
+ xml_data text default NULL,
125
+ http_headers text default NULL,
126
+ last_retrieved timestamp default NULL
127
+ );
128
+ SQL_END
129
+ table_creation_sql = nil
130
+ if configurations["adapter"] == "mysql"
131
+ table_creation_sql = feeds_mysql
132
+ elsif configurations["adapter"] == "sqlite"
133
+ table_creation_sql = feeds_sqlite
134
+ elsif configurations["adapter"] == "postgresql"
135
+ table_creation_sql = feeds_psql
136
+ end
137
+ if table_creation_sql.nil?
138
+ raise "Could not build #{self.table_name()} table."
139
+ else
140
+ connection.execute table_creation_sql
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
data/lib/feed_tools.rb CHANGED
@@ -22,19 +22,30 @@
22
22
  #++
23
23
 
24
24
  if Object.const_defined?(:FEED_TOOLS_ENV)
25
- raise "Double-require attempted, aborting. This may be caused " +
26
- "by the presence of the RUBYOPT environment variable."
25
+ warn("FeedTools may have been loaded improperly. This may be caused " +
26
+ "by the presence of the RUBYOPT environment variable or by using " +
27
+ "load instead of require. This can also be caused by missing " +
28
+ "the Iconv library, which is common on Windows.")
27
29
  end
28
30
 
29
31
  FEED_TOOLS_ENV = ENV['FEED_TOOLS_ENV'] ||
30
32
  ENV['RAILS_ENV'] ||
31
33
  'production' # :nodoc:
32
34
 
33
- FEED_TOOLS_VERSION = "0.2.8"
35
+ FEED_TOOLS_VERSION = "0.2.9"
34
36
 
35
37
  $:.unshift(File.dirname(__FILE__))
36
38
  $:.unshift(File.dirname(__FILE__) + "/feed_tools/vendor")
37
- $:.unshift(File.dirname(__FILE__) + "/../../activerecord/lib")
39
+
40
+ begin
41
+ require 'iconv'
42
+ rescue LoadError
43
+ warn("The Iconv library does not appear to be installed properly. " +
44
+ "FeedTools cannot function properly without it.")
45
+ raise
46
+ end
47
+
48
+ require 'rubygems'
38
49
 
39
50
  begin
40
51
  require 'builder'
@@ -57,15 +68,16 @@ require 'net/ftp'
57
68
 
58
69
  require 'rexml/document'
59
70
 
60
- require 'iconv'
61
71
  require 'uri'
62
72
  require 'time'
63
73
  require 'cgi'
64
74
  require 'pp'
65
75
  require 'yaml'
66
76
 
67
- require 'rubygems'
68
77
  require_gem('activerecord', '>= 1.10.1')
78
+ require_gem('uuidtools', '>= 0.1.1')
79
+
80
+ require 'database_feed_cache'
69
81
 
70
82
  #= feed_tools.rb
71
83
  #
@@ -84,141 +96,6 @@ require_gem('activerecord', '>= 1.10.1')
84
96
  # => "43,37,28,23,11,3,1"
85
97
  module FeedTools
86
98
 
87
- # The default caching mechanism for the FeedTools module
88
- class DatabaseFeedCache < ActiveRecord::Base
89
- # Overrides the default table name to use the "feeds" table.
90
- def self.table_name() "feeds" end
91
-
92
- # If ActiveRecord is not already connected, attempts to find a configuration file and use
93
- # it to open a connection for ActiveRecord.
94
- # This method is probably unnecessary for anything but testing and debugging purposes.
95
- # In a Rails environment, the connection will already have been established
96
- # and this method will simply do nothing.
97
- #
98
- # This method should not raise any exceptions because it's designed to be run only when
99
- # the module is first loaded. If it fails, the user should get an exception when they
100
- # try to perform some action that makes use of the caching functionality, and not until.
101
- def DatabaseFeedCache.initialize_cache
102
- # Establish a connection if we don't already have one
103
- begin
104
- ActiveRecord::Base.connection
105
- rescue
106
- begin
107
- possible_config_files = [
108
- "./config/database.yml",
109
- "../config/database.yml",
110
- "./database.yml",
111
- "../database.yml"
112
- ]
113
- database_config_file = nil
114
- for file in possible_config_files
115
- if File.exists? file
116
- database_config_file = file
117
- break
118
- end
119
- end
120
- database_config_hash = File.open(database_config_file) do |file|
121
- config_hash = YAML::load(file)
122
- unless config_hash[FEED_TOOLS_ENV].nil?
123
- config_hash = config_hash[FEED_TOOLS_ENV]
124
- end
125
- config_hash
126
- end
127
- ActiveRecord::Base.configurations = database_config_hash
128
- ActiveRecord::Base.establish_connection(database_config_hash)
129
- ActiveRecord::Base.connection
130
- rescue
131
- end
132
- end
133
- # Verify that the necessary database tables are in place
134
- # and if they're missing, create them
135
- unless DatabaseFeedCache.table_exists?
136
- DatabaseFeedCache.create_table
137
- end
138
- return nil
139
- end
140
-
141
- # Returns true if a connection to the database has been established and the
142
- # required table structure is in place.
143
- def DatabaseFeedCache.connected?
144
- begin
145
- ActiveRecord::Base.connection
146
- return false if ActiveRecord::Base.configurations.nil?
147
- return false unless DatabaseFeedCache.table_exists?
148
- rescue => error
149
- return false
150
- end
151
- return true
152
- end
153
-
154
- # True if the appropriate database table already exists
155
- def DatabaseFeedCache.table_exists?
156
- begin
157
- ActiveRecord::Base.connection.execute "select id, url, title, " +
158
- "link, xml_data, http_headers, last_retrieved " +
159
- "from #{self.table_name()} limit 1"
160
- rescue ActiveRecord::StatementInvalid
161
- return false
162
- rescue
163
- return false
164
- end
165
- return true
166
- end
167
-
168
- # Creates the appropriate database table
169
- def DatabaseFeedCache.create_table
170
- unless DatabaseFeedCache.table_exists?
171
- feeds_mysql = <<-SQL_END
172
- CREATE TABLE `#{self.table_name()}` (
173
- `id` int(10) unsigned NOT NULL auto_increment,
174
- `url` varchar(255) default NULL,
175
- `title` varchar(255) default NULL,
176
- `link` varchar(255) default NULL,
177
- `xml_data` longtext default NULL,
178
- `http_headers` text default NULL,
179
- `last_retrieved` datetime default NULL,
180
- PRIMARY KEY (`id`)
181
- ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
182
- SQL_END
183
- feeds_sqlite = <<-SQL_END
184
- CREATE TABLE '#{self.table_name()}' (
185
- 'id' INTEGER PRIMARY KEY NOT NULL,
186
- 'url' VARCHAR(255) DEFAULT NULL,
187
- 'title' VARCHAR(255) DEFAULT NULL,
188
- 'link' VARCHAR(255) DEFAULT NULL,
189
- 'xml_data' TEXT DEFAULT NULL,
190
- 'http_headers' TEXT DEFAULT NULL,
191
- 'last_retrieved' DATETIME DEFAULT NULL
192
- );
193
- SQL_END
194
- feeds_psql = <<-SQL_END
195
- CREATE TABLE #{self.table_name()} (
196
- id SERIAL PRIMARY KEY NOT NULL,
197
- url varchar(255) default NULL,
198
- title varchar(255) default NULL,
199
- link varchar(255) default NULL,
200
- xml_data text default NULL,
201
- http_headers text default NULL,
202
- last_retrieved timestamp default NULL
203
- );
204
- SQL_END
205
- table_creation_sql = nil
206
- if configurations["adapter"] == "mysql"
207
- table_creation_sql = feeds_mysql
208
- elsif configurations["adapter"] == "sqlite"
209
- table_creation_sql = feeds_sqlite
210
- elsif configurations["adapter"] == "postgresql"
211
- table_creation_sql = feeds_psql
212
- end
213
- if table_creation_sql.nil?
214
- raise "Could not build #{self.table_name()} table."
215
- else
216
- connection.execute table_creation_sql
217
- end
218
- end
219
- end
220
- end
221
-
222
99
  # Error raised when a feed cannot be retrieved
223
100
  class FeedAccessError < StandardError
224
101
  end
@@ -446,6 +323,8 @@ module FeedTools
446
323
  '/usr/lib/tidy.so',
447
324
  'C:\Program Files\Tidy\tidy.dll',
448
325
  'C:\Tidy\tidy.dll',
326
+ 'C:\Ruby\bin\tidy.dll',
327
+ 'C:\Ruby\tidy.dll',
449
328
  '/usr/local/lib',
450
329
  '/opt/local/lib',
451
330
  '/usr/lib'
@@ -558,6 +437,7 @@ module FeedTools
558
437
  if (feed_uri.path =~ /^[\/]+/) == 0
559
438
  feed_uri.path.gsub!(/^[\/]+/, "/")
560
439
  end
440
+ feed_uri.host.downcase!
561
441
  return feed_uri.to_s
562
442
  rescue URI::InvalidURIError
563
443
  return normalized_url
@@ -586,18 +466,14 @@ module FeedTools
586
466
  end
587
467
 
588
468
  # Converts a url into a urn:uuid: uri
589
- # def FeedTools.build_urn_uri(url)
590
- # unless url.kind_of? String
591
- # raise ArgumentError, "Expected String, got #{url.class.name}"
592
- # end
593
- # normalized_url = normalize_url(url)
594
- # unless FeedTools.is_uri?(normalized_url)
595
- # raise ArgumentError, "Must supply a valid URL."
596
- # end
597
- # require 'uuidtools'
598
- # tag_uri = UUID.sha1_create(normalized_url).to_uri_string
599
- # return tag_uri
600
- # end
469
+ def FeedTools.build_urn_uri(url)
470
+ unless url.kind_of? String
471
+ raise ArgumentError, "Expected String, got #{url.class.name}"
472
+ end
473
+ normalized_url = normalize_url(url)
474
+ require 'uuidtools'
475
+ return UUID.sha1_create(normalized_url).to_uri_string
476
+ end
601
477
 
602
478
  # Returns true if the parameter appears to be a valid uri
603
479
  def FeedTools.is_uri?(url)
@@ -896,10 +772,10 @@ module FeedTools
896
772
  @http_headers = YAML.load(self.cache_object.http_headers)
897
773
  @http_headers = {} unless @http_headers.kind_of? Hash
898
774
  end
899
- if expired? && !FeedTools.cache_only?
900
- load_remote_feed!
901
- else
775
+ if FeedTools.cache_only? || self.expired? == false
902
776
  @live = false
777
+ else
778
+ load_remote_feed!
903
779
  end
904
780
  end
905
781
 
@@ -955,8 +831,8 @@ module FeedTools
955
831
  FeedTools.user_agent unless FeedTools.user_agent.nil?
956
832
 
957
833
  # The http feed access method
958
- def http_fetch(feed_url, http_headers, redirect_limit = 10,
959
- response_chain = []) # :nodoc:
834
+ http_fetch = lambda do |feed_url, http_headers, redirect_limit,
835
+ response_chain|
960
836
  raise FeedAccessError, 'Redirect too deep' if redirect_limit == 0
961
837
  feed_uri = nil
962
838
  begin
@@ -995,7 +871,7 @@ module FeedTools
995
871
  break
996
872
  end
997
873
  end
998
- return response
874
+ response
999
875
  when Net::HTTPRedirection
1000
876
  if response.code.to_i == 304
1001
877
  response.error!
@@ -1012,7 +888,7 @@ module FeedTools
1012
888
  # TODO: deal with stupid people using relative urls
1013
889
  # in Location header
1014
890
  # =================================================
1015
- http_fetch(new_location, http_headers,
891
+ http_fetch.call(new_location, http_headers,
1016
892
  redirect_limit - 1, response_chain)
1017
893
  end
1018
894
  else
@@ -1022,7 +898,7 @@ module FeedTools
1022
898
  end
1023
899
 
1024
900
  begin
1025
- @http_response = http_fetch(self.url, headers)
901
+ @http_response = http_fetch.call(self.url, headers, 10, [])
1026
902
  @http_headers = {}
1027
903
  self.http_response.each_header do |header|
1028
904
  self.http_headers[header.first.downcase] = header.last
@@ -1142,6 +1018,9 @@ module FeedTools
1142
1018
  def xml
1143
1019
  if @xml_doc.nil?
1144
1020
  begin
1021
+ # TODO: :ignore_whitespace_nodes => :all
1022
+ # Add that?
1023
+ # ======================================
1145
1024
  @xml_doc = Document.new(xml_data)
1146
1025
  rescue
1147
1026
  # Something failed, attempt to repair the xml with htree.
@@ -2446,9 +2325,17 @@ module FeedTools
2446
2325
  elsif feed_type == "atom" && (version == nil || version == 0.0)
2447
2326
  version = 0.3
2448
2327
  end
2449
- if feed_type == "rss" && (version == 0.9 || version == 1.0 || version == 1.1)
2328
+ if feed_type == "rss" && (version == 0.9 || version == 1.0 ||
2329
+ version == 1.1)
2450
2330
  # RDF-based rss format
2451
- return xml_builder.tag!("rdf:RDF") do
2331
+ return xml_builder.tag!("rdf:RDF",
2332
+ "xmlns" => "http://purl.org/rss/1.0/",
2333
+ "xmlns:rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
2334
+ "xmlns:dc" => "http://purl.org/dc/elements/1.1/",
2335
+ "xmlns:syn" => "http://purl.org/rss/1.0/modules/syndication/",
2336
+ "xmlns:taxo" => "http://purl.org/rss/1.0/modules/taxonomy/",
2337
+ "xmlns:itunes" => "http://www.itunes.com/DTDs/Podcast-1.0.dtd",
2338
+ "xmlns:media" => "http://search.yahoo.com/mrss") do
2452
2339
  channel_attributes = {}
2453
2340
  unless self.link.nil?
2454
2341
  channel_attributes["rdf:about"] = CGI.escapeHTML(self.link)
@@ -2530,22 +2417,32 @@ module FeedTools
2530
2417
  end
2531
2418
  elsif feed_type == "rss"
2532
2419
  # normal rss format
2533
- return xml_builder.rss("version" => version) do
2534
- unless title.nil? || title == ""
2535
- xml_builder.title(title)
2536
- end
2537
- unless link.nil? || link == ""
2538
- xml_builder.link(link)
2539
- end
2540
- unless description.nil? || description == ""
2541
- xml_builder.description(description)
2542
- end
2543
- xml_builder.ttl((time_to_live / 1.minute).to_s)
2544
- xml_builder.generator("http://www.sporkmonger.com/projects/feedtools")
2545
- build_xml_hook(feed_type, version, xml_builder)
2546
- unless items.nil?
2547
- for item in items
2548
- item.build_xml(feed_type, version, xml_builder)
2420
+ return xml_builder.rss("version" => "2.0",
2421
+ "xmlns:rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
2422
+ "xmlns:dc" => "http://purl.org/dc/elements/1.1/",
2423
+ "xmlns:taxo" => "http://purl.org/rss/1.0/modules/taxonomy/",
2424
+ "xmlns:trackback" =>
2425
+ "http://madskills.com/public/xml/rss/module/trackback/",
2426
+ "xmlns:itunes" => "http://www.itunes.com/DTDs/Podcast-1.0.dtd",
2427
+ "xmlns:media" => "http://search.yahoo.com/mrss") do
2428
+ xml_builder.channel do
2429
+ unless title.nil? || title == ""
2430
+ xml_builder.title(title)
2431
+ end
2432
+ unless link.nil? || link == ""
2433
+ xml_builder.link(link)
2434
+ end
2435
+ unless description.nil? || description == ""
2436
+ xml_builder.description(description)
2437
+ end
2438
+ xml_builder.ttl((time_to_live / 1.minute).to_s)
2439
+ xml_builder.generator(
2440
+ "http://www.sporkmonger.com/projects/feedtools")
2441
+ build_xml_hook(feed_type, version, xml_builder)
2442
+ unless items.nil?
2443
+ for item in items
2444
+ item.build_xml(feed_type, version, xml_builder)
2445
+ end
2549
2446
  end
2550
2447
  end
2551
2448
  end
@@ -2647,16 +2544,16 @@ module FeedTools
2647
2544
  "http://www.sporkmonger.com/projects/feedtools")
2648
2545
  if self.id != nil
2649
2546
  unless FeedTools.is_uri? self.id
2650
- # if self.link != nil
2651
- # xml_builder.id(FeedTools.build_urn_uri(self.link))
2652
- # else
2547
+ if self.link != nil
2548
+ xml_builder.id(FeedTools.build_urn_uri(self.link))
2549
+ else
2653
2550
  raise "The unique id must be a valid URI."
2654
- # end
2551
+ end
2655
2552
  else
2656
2553
  xml_builder.id(self.id)
2657
2554
  end
2658
- # elsif self.link != nil
2659
- # xml_builder.id(FeedTools.build_urn_uri(self.link))
2555
+ elsif self.link != nil
2556
+ xml_builder.id(FeedTools.build_urn_uri(self.link))
2660
2557
  else
2661
2558
  raise "Cannot build feed, missing feed unique id."
2662
2559
  end
@@ -2880,6 +2777,9 @@ module FeedTools
2880
2777
  # Returns a REXML Document of the xml_data
2881
2778
  def xml
2882
2779
  if @xml_doc.nil?
2780
+ # TODO: :ignore_whitespace_nodes => :all
2781
+ # Add that?
2782
+ # ======================================
2883
2783
  @xml_doc = Document.new(xml_data)
2884
2784
  end
2885
2785
  return @xml_doc
@@ -2984,10 +2884,7 @@ module FeedTools
2984
2884
  if @description.nil?
2985
2885
  unless root_node.nil?
2986
2886
  repair_entities = false
2987
- description_node = XPath.first(root_node, "description")
2988
- if description_node.nil?
2989
- description_node = XPath.first(root_node, "content:encoded")
2990
- end
2887
+ description_node = XPath.first(root_node, "content:encoded")
2991
2888
  if description_node.nil?
2992
2889
  description_node = XPath.first(root_node, "content")
2993
2890
  end
@@ -3000,6 +2897,9 @@ module FeedTools
3000
2897
  if description_node.nil?
3001
2898
  description_node = XPath.first(root_node, "body")
3002
2899
  end
2900
+ if description_node.nil?
2901
+ description_node = XPath.first(root_node, "description")
2902
+ end
3003
2903
  if description_node.nil?
3004
2904
  description_node = XPath.first(root_node, "tagline")
3005
2905
  end
@@ -4178,7 +4078,7 @@ module FeedTools
4178
4078
  xml_builder.tag!("dc:date", time.iso8601)
4179
4079
  end
4180
4080
  unless tags.nil? || tags.size == 0
4181
- xml_builder.tag!("dc:subject") do
4081
+ xml_builder.tag!("taxo:topics") do
4182
4082
  xml_builder.tag!("rdf:Bag") do
4183
4083
  for tag in tags
4184
4084
  xml_builder.tag!("rdf:li", tag)
@@ -4205,7 +4105,7 @@ module FeedTools
4205
4105
  xml_builder.pubDate(time.rfc822)
4206
4106
  end
4207
4107
  unless tags.nil? || tags.size == 0
4208
- xml_builder.tag!("dc:subject") do
4108
+ xml_builder.tag!("taxo:topics") do
4209
4109
  xml_builder.tag!("rdf:Bag") do
4210
4110
  for tag in tags
4211
4111
  xml_builder.tag!("rdf:li", tag)
data/rakefile CHANGED
@@ -7,7 +7,7 @@ require 'rake/gempackagetask'
7
7
  require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  PKG_NAME = 'feedtools'
10
- PKG_VERSION = '0.2.8'
10
+ PKG_VERSION = '0.2.9'
11
11
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
12
12
 
13
13
  RELEASE_NAME = "REL #{PKG_VERSION}"
@@ -59,6 +59,7 @@ spec = Gem::Specification.new do |s|
59
59
  end
60
60
 
61
61
  s.add_dependency('activerecord', '>= 1.10.1')
62
+ s.add_dependency('uuidtools', '>= 0.1.1')
62
63
 
63
64
  s.require_path = 'lib'
64
65
  s.autorequire = 'feed_tools'
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: feedtools
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.8
7
- date: 2005-09-13 00:00:00 -04:00
6
+ version: 0.2.9
7
+ date: 2005-09-25 00:00:00 -04:00
8
8
  summary: "Parsing, generation, and caching system for xml news feeds."
9
9
  require_paths:
10
10
  - lib
@@ -33,6 +33,7 @@ files:
33
33
  - install.rb
34
34
  - README
35
35
  - CHANGELOG
36
+ - lib/database_feed_cache.rb
36
37
  - lib/feed_tools
37
38
  - lib/feed_tools.rb
38
39
  - lib/feed_tools/vendor
@@ -96,4 +97,14 @@ dependencies:
96
97
  - ">="
97
98
  - !ruby/object:Gem::Version
98
99
  version: 1.10.1
100
+ version:
101
+ - !ruby/object:Gem::Dependency
102
+ name: uuidtools
103
+ version_requirement:
104
+ version_requirements: !ruby/object:Gem::Version::Requirement
105
+ requirements:
106
+ -
107
+ - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 0.1.1
99
110
  version: