feedtools 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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: