summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--lib/rss/0.9.rb7
-rw-r--r--lib/rss/rss.rb35
-rwxr-xr-xsample/rss/convert.rb69
-rw-r--r--test/rss/rss-testcase.rb17
-rw-r--r--test/rss/test_1.0.rb13
-rw-r--r--test/rss/test_2.0.rb15
7 files changed, 150 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index cc0e247fbf..4a27df54f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+Sat Jun 17 10:30:41 2006 Kouhei Sutou <kou@cozmixng.org>
+
+ * lib/rss/rss.rb (Hash#merge, Enumerable#sort_by): removed.
+
+ * lib/rss/rss.rb (RSS::RootElementMixin#to_xml): added.
+ [ruby-talk:197284]
+
+ We can convert RSS version easily like the following:
+ rss10 = RSS::Parser.parse(File.read("1.0.rdf"))
+ File.open("2.0.rss", "w") {|f| f.print(rss10.to_xml("2.0"))}
+
+ * test/rss/test_1.0.rb: added #to_xml test.
+ * test/rss/test_2.0.rb: ditto.
+
+ * test/rss/rss-testcase.rb: added some helper methods that
+ generates sample RSS 2.0.
+
+ * sample/rss/convert.rb: added a sample script to convert RSS format.
+
Sat Jun 17 10:23:22 2006 Kouhei Sutou <kou@cozmixng.org>
* lib/rss/rss.rb (Kernel#funcall): removed.
diff --git a/lib/rss/0.9.rb b/lib/rss/0.9.rb
index f0060cbad5..cfd2596bcc 100644
--- a/lib/rss/0.9.rb
+++ b/lib/rss/0.9.rb
@@ -70,6 +70,13 @@ module RSS
rv
end
+ def setup_maker_elements(maker)
+ super
+ items.each do |item|
+ item.setup_maker(maker.items)
+ end
+ end
+
private
def children
[@channel]
diff --git a/lib/rss/rss.rb b/lib/rss/rss.rb
index 589478665c..c36cee050a 100644
--- a/lib/rss/rss.rb
+++ b/lib/rss/rss.rb
@@ -30,28 +30,6 @@ class Time
end
end
-module Enumerable
- unless instance_methods.include?("sort_by")
- def sort_by
- collect do |x|
- [yield(x), x]
- end.sort do |x, y|
- x[0] <=> y[0]
- end.collect! do |x|
- x[1]
- end
- end
- end
-end
-
-class Hash
- unless instance_methods.include?("merge")
- def merge(other)
- dup.update(other)
- end
- end
-end
-
require "English"
require "rss/utils"
require "rss/converter"
@@ -946,7 +924,18 @@ EOC
setup_maker_elements(maker)
end
-
+
+ def to_xml(version=nil, &block)
+ if version.nil? or version == @rss_version
+ to_s
+ else
+ RSS::Maker.make(version) do |maker|
+ setup_maker(maker)
+ block.call(maker) if block
+ end.to_s
+ end
+ end
+
private
def tag(indent, attrs, &block)
rv = xmldecl + xml_stylesheet_pi
diff --git a/sample/rss/convert.rb b/sample/rss/convert.rb
new file mode 100755
index 0000000000..394b13e8eb
--- /dev/null
+++ b/sample/rss/convert.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+
+require "rss"
+
+feeds = []
+verbose = false
+encoding = "UTF-8"
+to_version = "1.0"
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ STDERR.puts mark
+ STDERR.puts exception.class
+ STDERR.puts exception.message
+ STDERR.puts exception.backtrace
+ STDERR.puts mark
+end
+
+before_time = Time.now
+ARGV.each do |fname|
+ case fname
+ when '-v'
+ verbose = true
+ next
+ when /^-t(0\.91|1\.0|2\.0)$/
+ to_version = $1
+ next
+ end
+ rss = nil
+ f = File.read(fname)
+ begin
+ ## do validate parse
+ rss = RSS::Parser.parse(f)
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(f, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+ if rss.nil?
+ STDERR.puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
+ else
+ begin
+ rss.output_encoding = encoding
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+ feeds << [fname, rss]
+ end
+end
+processing_time = Time.now - before_time
+
+feeds.each do |fname, rss|
+ converted_rss = rss.to_xml(to_version)
+ output_name = fname.sub(/(\.[^\.]+)$/, "-#{to_version}\\1")
+ File.open(output_name, "w") do |output|
+ output.print(converted_rss)
+ end
+end
+
+STDERR.puts "Used XML parser: #{RSS::Parser.default_parser}"
+STDERR.puts "Processing time: #{processing_time}s"
diff --git a/test/rss/rss-testcase.rb b/test/rss/rss-testcase.rb
index 0612abcccd..21670bc05c 100644
--- a/test/rss/rss-testcase.rb
+++ b/test/rss/rss-testcase.rb
@@ -140,6 +140,15 @@ EOR
EORSS
end
+ def make_sample_items20
+ RESOURCES.collect do |res|
+ elems = ["<link>#{res}</link>"]
+ elems << "<title>title of #{res}</title>"
+ elems = elems.join("\n")
+ item = "<item>\n#{elems}\n</item>"
+ end.join("\n")
+ end
+
def make_channel20(content=nil)
<<-EOC
<channel>
@@ -154,7 +163,7 @@ EORSS
<link>#{LINK_VALUE}</link>
</image>
-#{RESOURCES.collect do |res| '<item><link>' + res + '</link></item>' end.join("\n")}
+#{make_sample_items20}
<textInput>
<title>#{TITLE_VALUE}</title>
@@ -190,6 +199,12 @@ EOI
EOC
end
+ def make_sample_rss20
+ make_rss20(<<-EOR)
+#{make_channel20}
+EOR
+ end
+
def make_element(elem_name, attrs, contents)
attrs_str = attrs.collect do |name, value|
"#{h name}='#{h value}'"
diff --git a/test/rss/test_1.0.rb b/test/rss/test_1.0.rb
index b905ba6e94..3266e00393 100644
--- a/test/rss/test_1.0.rb
+++ b/test/rss/test_1.0.rb
@@ -233,6 +233,19 @@ module RSS
end
end
+ def test_to_xml
+ rss = RSS::Parser.parse(make_sample_RDF)
+ assert_equal(rss.to_s, rss.to_xml)
+ assert_equal(rss.to_s, rss.to_xml("1.0"))
+ rss09 = rss.to_xml("0.91") do |maker|
+ maker.channel.language = "en-us"
+ end
+ rss09 = RSS::Parser.parse(rss09)
+ assert_equal("0.91", rss09.rss_version)
+ rss20 = RSS::Parser.parse(rss.to_xml("2.0"))
+ assert_equal("2.0", rss20.rss_version)
+ end
+
def test_indent_size
assert_equal(0, RDF.indent_size)
assert_equal(1, RDF::Channel.indent_size)
diff --git a/test/rss/test_2.0.rb b/test/rss/test_2.0.rb
index 2027e5344a..b0e6b17165 100644
--- a/test/rss/test_2.0.rb
+++ b/test/rss/test_2.0.rb
@@ -373,7 +373,20 @@ module RSS
end
assert_equal(source_params, actual)
end
-
+
+ def test_to_xml
+ rss = RSS::Parser.parse(make_sample_rss20)
+ assert_equal(rss.to_s, rss.to_xml)
+ assert_equal(rss.to_s, rss.to_xml("2.0"))
+ rss09 = RSS::Parser.parse(rss.to_xml("0.91"))
+ assert_equal("0.91", rss09.rss_version)
+ rss10 = rss.to_xml("1.0") do |maker|
+ maker.channel.about = "http://www.example.com/index.rdf"
+ end
+ rss10 = RSS::Parser.parse(rss10)
+ assert_equal("1.0", rss10.rss_version)
+ end
+
def test_indent_size
assert_equal(0, Rss.indent_size)
assert_equal(1, Rss::Channel.indent_size)