зеркало из https://github.com/github/ruby.git
* lib/rss/{rss,parser,0.9,1.0,2.0}.rb: supported RSS 0.9x/2.0
validation and validation which disregard order of elements. * test/rss/test_parser.rb: added tests for RSS 0.9x/2.0 validation. * test/rss/{test_trackback,rss-testcase}.rb: fixed no good method name. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6590 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
9800838ff0
Коммит
e289fcf81a
|
@ -1,3 +1,12 @@
|
||||||
|
Wed Jul 7 02:31:41 2004 Kouhei Sutou <kou@cozmixng.org>
|
||||||
|
|
||||||
|
* lib/rss/{rss,parser,0.9,1.0,2.0}.rb: supported RSS 0.9x/2.0
|
||||||
|
validation and validation which disregard order of elements.
|
||||||
|
* test/rss/test_parser.rb: added tests for RSS 0.9x/2.0
|
||||||
|
validation.
|
||||||
|
* test/rss/{test_trackback,rss-testcase}.rb: fixed no good method
|
||||||
|
name.
|
||||||
|
|
||||||
Wed Jul 7 00:48:34 2004 WATANABE Hirofumi <eban@ruby-lang.org>
|
Wed Jul 7 00:48:34 2004 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* ext/tk/lib/tkextlib/tktrans.rb,
|
* ext/tk/lib/tkextlib/tktrans.rb,
|
||||||
|
|
164
lib/rss/0.9.rb
164
lib/rss/0.9.rb
|
@ -5,6 +5,12 @@ module RSS
|
||||||
module RSS09
|
module RSS09
|
||||||
NSPOOL = {}
|
NSPOOL = {}
|
||||||
ELEMENTS = []
|
ELEMENTS = []
|
||||||
|
|
||||||
|
def self.append_features(klass)
|
||||||
|
super
|
||||||
|
|
||||||
|
klass.install_must_call_validator('', nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Rss < Element
|
class Rss < Element
|
||||||
|
@ -62,22 +68,34 @@ EOR
|
||||||
[@channel]
|
[@channel]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def _tags
|
||||||
|
[
|
||||||
|
[nil, 'channel'],
|
||||||
|
].delete_if {|x| send(x[1]).nil?}
|
||||||
|
end
|
||||||
|
|
||||||
|
def _attrs
|
||||||
|
[
|
||||||
|
["version", true],
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
class Channel < Element
|
class Channel < Element
|
||||||
|
|
||||||
include RSS09
|
include RSS09
|
||||||
|
|
||||||
[
|
[
|
||||||
["title", nil],
|
["title", nil],
|
||||||
["link", nil],
|
["link", nil],
|
||||||
["description", nil],
|
["description", nil],
|
||||||
["language", nil],
|
["language", nil],
|
||||||
["copyright", "?"],
|
["copyright", "?"],
|
||||||
["managingEditor", "?"],
|
["managingEditor", "?"],
|
||||||
["webMaster", "?"],
|
["webMaster", "?"],
|
||||||
["rating", "?"],
|
["rating", "?"],
|
||||||
["docs", "?"],
|
["docs", "?"],
|
||||||
["skipDays", "?"],
|
["skipDays", "?"],
|
||||||
["skipHours", "?"],
|
["skipHours", "?"],
|
||||||
].each do |x, occurs|
|
].each do |x, occurs|
|
||||||
install_text_element(x)
|
install_text_element(x)
|
||||||
install_model(x, occurs)
|
install_model(x, occurs)
|
||||||
|
@ -85,7 +103,7 @@ EOR
|
||||||
|
|
||||||
[
|
[
|
||||||
["pubDate", "?"],
|
["pubDate", "?"],
|
||||||
["lastBuildDate", "?"],
|
["lastBuildDate", "?"],
|
||||||
].each do |x, occurs|
|
].each do |x, occurs|
|
||||||
install_date_element(x, 'rfc822')
|
install_date_element(x, 'rfc822')
|
||||||
install_model(x, occurs)
|
install_model(x, occurs)
|
||||||
|
@ -93,13 +111,19 @@ EOR
|
||||||
|
|
||||||
[
|
[
|
||||||
["image", nil],
|
["image", nil],
|
||||||
["textInput", "?"],
|
["textInput", "?"],
|
||||||
["cloud", "?"]
|
|
||||||
].each do |x, occurs|
|
].each do |x, occurs|
|
||||||
install_have_child_element(x)
|
install_have_child_element(x)
|
||||||
install_model(x, occurs)
|
install_model(x, occurs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[
|
||||||
|
["cloud", "?"]
|
||||||
|
].each do |x, occurs|
|
||||||
|
install_have_attribute_element(x)
|
||||||
|
install_model(x, occurs)
|
||||||
|
end
|
||||||
|
|
||||||
[
|
[
|
||||||
["item", "*"]
|
["item", "*"]
|
||||||
].each do |x, occurs|
|
].each do |x, occurs|
|
||||||
|
@ -142,12 +166,46 @@ EOT
|
||||||
[@image, @textInput, @cloud, *@item]
|
[@image, @textInput, @cloud, *@item]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def _tags
|
||||||
|
rv = [
|
||||||
|
"title",
|
||||||
|
"link",
|
||||||
|
"description",
|
||||||
|
"language",
|
||||||
|
"copyright",
|
||||||
|
"managingEditor",
|
||||||
|
"webMaster",
|
||||||
|
"rating",
|
||||||
|
"docs",
|
||||||
|
"skipDays",
|
||||||
|
"skipHours",
|
||||||
|
"image",
|
||||||
|
"textInput",
|
||||||
|
"cloud",
|
||||||
|
].delete_if do |x|
|
||||||
|
send(x).nil?
|
||||||
|
end.collect do |elem|
|
||||||
|
[nil, elem]
|
||||||
|
end
|
||||||
|
|
||||||
|
@item.each do
|
||||||
|
rv << [nil, "item"]
|
||||||
|
end
|
||||||
|
|
||||||
|
rv
|
||||||
|
end
|
||||||
|
|
||||||
class Image < Element
|
class Image < Element
|
||||||
|
|
||||||
include RSS09
|
include RSS09
|
||||||
|
|
||||||
%w(url title link width height description).each do |x|
|
%w(url title link).each do |x|
|
||||||
install_text_element(x)
|
install_text_element(x)
|
||||||
|
install_model(x, nil)
|
||||||
|
end
|
||||||
|
%w(width height description).each do |x|
|
||||||
|
install_text_element(x)
|
||||||
|
install_model(x, "?")
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s(convert=true)
|
def to_s(convert=true)
|
||||||
|
@ -166,6 +224,14 @@ EOT
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def _tags
|
||||||
|
%w(url title link width height description).delete_if do |x|
|
||||||
|
send(x).nil?
|
||||||
|
end.collect do |elem|
|
||||||
|
[nil, elem]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Cloud < Element
|
class Cloud < Element
|
||||||
|
@ -173,15 +239,24 @@ EOT
|
||||||
include RSS09
|
include RSS09
|
||||||
|
|
||||||
[
|
[
|
||||||
["domain", nil, false],
|
["domain", nil, true],
|
||||||
["port", nil, false],
|
["port", nil, true],
|
||||||
["path", nil, false],
|
["path", nil, true],
|
||||||
["registerProcedure", nil, false],
|
["registerProcedure", nil, true],
|
||||||
["protocol", nil ,false],
|
["protocol", nil ,true],
|
||||||
].each do |name, uri, required|
|
].each do |name, uri, required|
|
||||||
install_get_attribute(name, uri, required)
|
install_get_attribute(name, uri, required)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def initialize(domain, port, path, rp, protocol)
|
||||||
|
super()
|
||||||
|
@domain = domain
|
||||||
|
@port = port
|
||||||
|
@path = path
|
||||||
|
@registerProcedure = rp
|
||||||
|
@protocol = protocol
|
||||||
|
end
|
||||||
|
|
||||||
def to_s(convert=true)
|
def to_s(convert=true)
|
||||||
rv = <<-EOT
|
rv = <<-EOT
|
||||||
<cloud
|
<cloud
|
||||||
|
@ -195,13 +270,20 @@ EOT
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def _attrs
|
||||||
|
%w(domain port path registerProcedure protocol).collect do |attr|
|
||||||
|
[attr, true]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Item < Element
|
class Item < Element
|
||||||
|
|
||||||
include RSS09
|
include RSS09
|
||||||
|
|
||||||
%w(title link description author comments).each do |x|
|
%w(title link description).each do |x|
|
||||||
install_text_element(x)
|
install_text_element(x)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -213,8 +295,6 @@ EOT
|
||||||
["title", '?'],
|
["title", '?'],
|
||||||
["link", '?'],
|
["link", '?'],
|
||||||
["description", '?'],
|
["description", '?'],
|
||||||
["author", '?'],
|
|
||||||
["comments", '?'],
|
|
||||||
["category", '?'],
|
["category", '?'],
|
||||||
["source", '?'],
|
["source", '?'],
|
||||||
["enclosure", '?'],
|
["enclosure", '?'],
|
||||||
|
@ -228,11 +308,9 @@ EOT
|
||||||
#{title_element(false)}
|
#{title_element(false)}
|
||||||
#{link_element(false)}
|
#{link_element(false)}
|
||||||
#{description_element(false)}
|
#{description_element(false)}
|
||||||
#{author_element(false)}
|
|
||||||
#{category_element(false)}
|
#{category_element(false)}
|
||||||
#{comments_element(false)}
|
|
||||||
#{enclosure_element(false)}
|
|
||||||
#{source_element(false)}
|
#{source_element(false)}
|
||||||
|
#{enclosure_element(false)}
|
||||||
#{other_element(false, "\t\t\t\t")}
|
#{other_element(false, "\t\t\t\t")}
|
||||||
</item>
|
</item>
|
||||||
EOT
|
EOT
|
||||||
|
@ -240,6 +318,20 @@ EOT
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def children
|
||||||
|
[@category, @source, @enclosure,].compact
|
||||||
|
end
|
||||||
|
|
||||||
|
def _tags
|
||||||
|
%w(title link description author comments category
|
||||||
|
source enclosure).delete_if do |x|
|
||||||
|
send(x).nil?
|
||||||
|
end.collect do |x|
|
||||||
|
[nil, x]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Source < Element
|
class Source < Element
|
||||||
|
|
||||||
include RSS09
|
include RSS09
|
||||||
|
@ -270,6 +362,10 @@ EOT
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def _tags
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
def _attrs
|
def _attrs
|
||||||
[
|
[
|
||||||
["url", true]
|
["url", true]
|
||||||
|
@ -284,8 +380,8 @@ EOT
|
||||||
|
|
||||||
[
|
[
|
||||||
["url", nil, true],
|
["url", nil, true],
|
||||||
["length", nil, true],
|
["length", nil, true],
|
||||||
["type", nil, true],
|
["type", nil, true],
|
||||||
].each do |name, uri, required|
|
].each do |name, uri, required|
|
||||||
install_get_attribute(name, uri, required)
|
install_get_attribute(name, uri, required)
|
||||||
end
|
end
|
||||||
|
@ -312,8 +408,8 @@ EOT
|
||||||
def _attrs
|
def _attrs
|
||||||
[
|
[
|
||||||
["url", true],
|
["url", true],
|
||||||
["length", true],
|
["length", true],
|
||||||
["type", true],
|
["type", true],
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -365,6 +461,7 @@ EOT
|
||||||
|
|
||||||
%w(title description name link).each do |x|
|
%w(title description name link).each do |x|
|
||||||
install_text_element(x)
|
install_text_element(x)
|
||||||
|
install_model(x, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s(convert=true)
|
def to_s(convert=true)
|
||||||
|
@ -381,6 +478,14 @@ EOT
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def _tags
|
||||||
|
%w(title description name link).each do |x|
|
||||||
|
send(x).nil?
|
||||||
|
end.collect do |elem|
|
||||||
|
[nil, elem]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -397,6 +502,7 @@ EOT
|
||||||
check_ns(tag_name, prefix, ns, nil)
|
check_ns(tag_name, prefix, ns, nil)
|
||||||
|
|
||||||
@rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
|
@rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
|
||||||
|
@rss.do_validate = @do_validate
|
||||||
@rss.xml_stylesheets = @xml_stylesheets
|
@rss.xml_stylesheets = @xml_stylesheets
|
||||||
@last_element = @rss
|
@last_element = @rss
|
||||||
@proc_stack.push Proc.new { |text, tags|
|
@proc_stack.push Proc.new { |text, tags|
|
||||||
|
|
|
@ -5,6 +5,13 @@ module RSS
|
||||||
module RSS10
|
module RSS10
|
||||||
NSPOOL = {}
|
NSPOOL = {}
|
||||||
ELEMENTS = []
|
ELEMENTS = []
|
||||||
|
|
||||||
|
def self.append_features(klass)
|
||||||
|
super
|
||||||
|
|
||||||
|
klass.install_must_call_validator('', ::RSS::URI)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class RDF < Element
|
class RDF < Element
|
||||||
|
|
|
@ -4,30 +4,21 @@ module RSS
|
||||||
|
|
||||||
class Rss
|
class Rss
|
||||||
|
|
||||||
# URI = "http://backend.userland.com/rss2"
|
|
||||||
|
|
||||||
# install_ns('', URI)
|
|
||||||
|
|
||||||
# def self.required_uri
|
|
||||||
# URI
|
|
||||||
# end
|
|
||||||
|
|
||||||
class Channel
|
class Channel
|
||||||
|
|
||||||
# def self.required_uri
|
|
||||||
# URI
|
|
||||||
# end
|
|
||||||
|
|
||||||
%w(generator ttl).each do |x|
|
%w(generator ttl).each do |x|
|
||||||
install_text_element(x)
|
install_text_element(x)
|
||||||
|
install_model(x, '?')
|
||||||
end
|
end
|
||||||
|
|
||||||
%w(category).each do |x|
|
%w(category).each do |x|
|
||||||
install_have_child_element(x)
|
install_have_child_element(x)
|
||||||
|
install_model(x, '?')
|
||||||
end
|
end
|
||||||
|
|
||||||
[
|
[
|
||||||
["image", "?"],
|
["image", "?"],
|
||||||
|
["language", "?"],
|
||||||
].each do |x, occurs|
|
].each do |x, occurs|
|
||||||
install_model(x, occurs)
|
install_model(x, occurs)
|
||||||
end
|
end
|
||||||
|
@ -41,16 +32,32 @@ EOT
|
||||||
rv << super
|
rv << super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
alias children09 children
|
||||||
|
def children
|
||||||
|
children09 + [@category].compact
|
||||||
|
end
|
||||||
|
|
||||||
|
alias _tags09 _tags
|
||||||
|
def _tags
|
||||||
|
%w(generator ttl category).delete_if do |x|
|
||||||
|
send(x).nil?
|
||||||
|
end.collect do |elem|
|
||||||
|
[nil, elem]
|
||||||
|
end + _tags09
|
||||||
|
end
|
||||||
|
|
||||||
Category = Item::Category
|
Category = Item::Category
|
||||||
# def Category.required_uri
|
|
||||||
# URI
|
|
||||||
# end
|
|
||||||
|
|
||||||
class Item
|
class Item
|
||||||
|
|
||||||
# def self.required_uri
|
[
|
||||||
# URI
|
["comments", "?"],
|
||||||
# end
|
["author", "?"],
|
||||||
|
].each do |x, occurs|
|
||||||
|
install_text_element(x)
|
||||||
|
install_model(x, occurs)
|
||||||
|
end
|
||||||
|
|
||||||
[
|
[
|
||||||
["pubDate", '?'],
|
["pubDate", '?'],
|
||||||
|
@ -68,20 +75,33 @@ EOT
|
||||||
|
|
||||||
def other_element(convert, indent='')
|
def other_element(convert, indent='')
|
||||||
rv = <<-EOT
|
rv = <<-EOT
|
||||||
|
#{indent}#{author_element(false)}
|
||||||
|
#{indent}#{comments_element(false)}
|
||||||
#{indent}#{pubDate_element(false)}
|
#{indent}#{pubDate_element(false)}
|
||||||
#{indent}#{guid_element(false)}
|
#{indent}#{guid_element(false)}
|
||||||
EOT
|
EOT
|
||||||
rv << super
|
rv << super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
alias children09 children
|
||||||
|
def children
|
||||||
|
children09 + [@guid].compact
|
||||||
|
end
|
||||||
|
|
||||||
|
alias _tags09 _tags
|
||||||
|
def _tags
|
||||||
|
%w(comments author pubDate guid).delete_if do |x|
|
||||||
|
send(x).nil?
|
||||||
|
end.collect do |elem|
|
||||||
|
[nil, elem]
|
||||||
|
end + _tags09
|
||||||
|
end
|
||||||
|
|
||||||
class Guid < Element
|
class Guid < Element
|
||||||
|
|
||||||
include RSS09
|
include RSS09
|
||||||
|
|
||||||
# def self.required_uri
|
|
||||||
# URI
|
|
||||||
# end
|
|
||||||
|
|
||||||
[
|
[
|
||||||
["isPermaLink", nil, false]
|
["isPermaLink", nil, false]
|
||||||
].each do |name, uri, required|
|
].each do |name, uri, required|
|
||||||
|
@ -124,24 +144,7 @@ EOT
|
||||||
end
|
end
|
||||||
|
|
||||||
RSS09::ELEMENTS.each do |x|
|
RSS09::ELEMENTS.each do |x|
|
||||||
# BaseListener.install_get_text_element(x, Rss::URI, "#{x}=")
|
|
||||||
BaseListener.install_get_text_element(x, nil, "#{x}=")
|
BaseListener.install_get_text_element(x, nil, "#{x}=")
|
||||||
end
|
end
|
||||||
|
|
||||||
module ListenerMixin
|
|
||||||
private
|
|
||||||
alias start_rss09 start_rss
|
|
||||||
def start_rss(tag_name, prefix, attrs, ns)
|
|
||||||
# check_ns(tag_name, prefix, ns, Rss::URI)
|
|
||||||
|
|
||||||
@rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
|
|
||||||
@rss.xml_stylesheets = @xml_stylesheets
|
|
||||||
@last_element = @rss
|
|
||||||
@proc_stack.push Proc.new { |text, tags|
|
|
||||||
@rss.validate_for_stream(tags) if @do_validate
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -124,11 +124,22 @@ module RSS
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
@@setter = {}
|
@@setter = {}
|
||||||
|
@@registered_uris = {}
|
||||||
|
|
||||||
def install_setter(uri, tag_name, setter)
|
def install_setter(uri, tag_name, setter)
|
||||||
@@setter[uri] = {} unless @@setter.has_key?(uri)
|
@@setter[uri] = {} unless @@setter.has_key?(uri)
|
||||||
@@setter[uri][tag_name] = setter
|
@@setter[uri][tag_name] = setter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def register_uri(name, uri)
|
||||||
|
@@registered_uris[name] = {} unless @@registered_uris.has_key?(name)
|
||||||
|
@@registered_uris[name][uri] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def uri_registered?(name, uri)
|
||||||
|
@@registered_uris[name].has_key?(uri)
|
||||||
|
end
|
||||||
|
|
||||||
def setter(uri, tag_name)
|
def setter(uri, tag_name)
|
||||||
begin
|
begin
|
||||||
@@setter[uri][tag_name]
|
@@setter[uri][tag_name]
|
||||||
|
@ -147,27 +158,32 @@ module RSS
|
||||||
|
|
||||||
def install_get_text_element(name, uri, setter)
|
def install_get_text_element(name, uri, setter)
|
||||||
install_setter(uri, name, setter)
|
install_setter(uri, name, setter)
|
||||||
def_get_text_element(name, *get_file_and_line_from_caller(1))
|
def_get_text_element(uri, name, *get_file_and_line_from_caller(1))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def def_get_text_element(name, file, line)
|
def def_get_text_element(uri, name, file, line)
|
||||||
|
register_uri(name, uri)
|
||||||
unless private_instance_methods(false).include?("start_#{name}")
|
unless private_instance_methods(false).include?("start_#{name}")
|
||||||
module_eval(<<-EOT, file, line)
|
module_eval(<<-EOT, file, line)
|
||||||
def start_#{name}(name, prefix, attrs, ns)
|
def start_#{name}(name, prefix, attrs, ns)
|
||||||
uri = ns[prefix]
|
uri = ns[prefix]
|
||||||
if @do_validate
|
if self.class.uri_registered?(#{name.inspect}, uri)
|
||||||
tags = self.class.available_tags(uri)
|
if @do_validate
|
||||||
unless tags.include?(name)
|
tags = self.class.available_tags(uri)
|
||||||
raise UnknownTagError.new(name, uri)
|
unless tags.include?(name)
|
||||||
|
raise UnknownTagError.new(name, uri)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
start_get_text_element(name, prefix, ns, uri)
|
||||||
|
else
|
||||||
|
start_else_element(name, prefix, attrs, ns)
|
||||||
end
|
end
|
||||||
start_get_text_element(name, prefix, ns, uri)
|
|
||||||
end
|
end
|
||||||
EOT
|
EOT
|
||||||
|
send("private", "start_#{name}")
|
||||||
end
|
end
|
||||||
send("private", "start_#{name}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,6 +35,20 @@ class Time
|
||||||
end
|
end
|
||||||
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
|
||||||
|
|
||||||
require "English"
|
require "English"
|
||||||
require "rss/utils"
|
require "rss/utils"
|
||||||
require "rss/converter"
|
require "rss/converter"
|
||||||
|
@ -42,7 +56,9 @@ require "rss/xml-stylesheet"
|
||||||
|
|
||||||
module RSS
|
module RSS
|
||||||
|
|
||||||
VERSION = "0.0.8"
|
VERSION = "0.0.9"
|
||||||
|
|
||||||
|
URI = "http://purl.org/rss/1.0/"
|
||||||
|
|
||||||
DEBUG = false
|
DEBUG = false
|
||||||
|
|
||||||
|
@ -298,8 +314,6 @@ EOC
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
URI = "http://purl.org/rss/1.0/"
|
|
||||||
|
|
||||||
class Element
|
class Element
|
||||||
|
|
||||||
extend BaseModel
|
extend BaseModel
|
||||||
|
@ -314,7 +328,7 @@ EOC
|
||||||
TAG_NAME = name.split('::').last.downcase
|
TAG_NAME = name.split('::').last.downcase
|
||||||
|
|
||||||
|
|
||||||
@@must_call_validators = {::RSS::URI => ''}
|
@@must_call_validators = {}
|
||||||
|
|
||||||
def self.must_call_validators
|
def self.must_call_validators
|
||||||
@@must_call_validators
|
@@must_call_validators
|
||||||
|
@ -427,6 +441,7 @@ EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_for_stream(tags)
|
def validate_for_stream(tags)
|
||||||
|
validate_attribute
|
||||||
__validate(tags, false)
|
__validate(tags, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -504,6 +519,11 @@ EOC
|
||||||
do_redo = false
|
do_redo = false
|
||||||
not_shift = false
|
not_shift = false
|
||||||
tag = nil
|
tag = nil
|
||||||
|
element_names = model.collect {|elem| elem[0]}
|
||||||
|
if tags
|
||||||
|
tags_size = tags.size
|
||||||
|
tags = tags.sort_by {|x| element_names.index(x) || tags_size}
|
||||||
|
end
|
||||||
|
|
||||||
model.each_with_index do |elem, i|
|
model.each_with_index do |elem, i|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ module RSS
|
||||||
LINK_VALUE = "http://xml.com/pub"
|
LINK_VALUE = "http://xml.com/pub"
|
||||||
URL_VALUE = "http://xml.com/universal/images/xml_tiny.gif"
|
URL_VALUE = "http://xml.com/universal/images/xml_tiny.gif"
|
||||||
NAME_VALUE = "hogehoge"
|
NAME_VALUE = "hogehoge"
|
||||||
|
LANGUAGE_VALUE = "ja"
|
||||||
DESCRIPTION_VALUE = "
|
DESCRIPTION_VALUE = "
|
||||||
XML.com features a rich mix of information and services
|
XML.com features a rich mix of information and services
|
||||||
for the XML community.
|
for the XML community.
|
||||||
|
@ -28,6 +29,18 @@ module RSS
|
||||||
"http://xml.com/pub/2000/08/09/rdfdb/index.html",
|
"http://xml.com/pub/2000/08/09/rdfdb/index.html",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CLOUD_DOMAIN = "data.ourfavoritesongs.com"
|
||||||
|
CLOUD_PORT = "80"
|
||||||
|
CLOUD_PATH = "/RPC2"
|
||||||
|
CLOUD_REGISTER_PROCEDURE = "ourFavoriteSongs.rssPleaseNotify"
|
||||||
|
CLOUD_PROTOCOL = "xml-rpc"
|
||||||
|
|
||||||
|
ENCLOSURE_URL = "http://www.scripting.com/mp3s/weatherReportSuite.mp3"
|
||||||
|
ENCLOSURE_LENGTH = "12216320"
|
||||||
|
ENCLOSURE_TYPE = "audio/mpeg"
|
||||||
|
|
||||||
|
CATEGORY_DOMAIN = "http://www.superopendirectory.com/"
|
||||||
|
|
||||||
def default_test
|
def default_test
|
||||||
# This class isn't tested
|
# This class isn't tested
|
||||||
end
|
end
|
||||||
|
@ -116,7 +129,7 @@ EOT
|
||||||
EOR
|
EOR
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_Rss2(content=nil, xmlns=[])
|
def make_rss20(content=nil, xmlns=[])
|
||||||
<<-EORSS
|
<<-EORSS
|
||||||
#{make_xmldecl}
|
#{make_xmldecl}
|
||||||
<rss version="2.0"
|
<rss version="2.0"
|
||||||
|
@ -126,12 +139,13 @@ EOR
|
||||||
EORSS
|
EORSS
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_channel2(content=nil)
|
def make_channel20(content=nil)
|
||||||
<<-EOC
|
<<-EOC
|
||||||
<channel>
|
<channel>
|
||||||
<title>#{TITLE_VALUE}</title>
|
<title>#{TITLE_VALUE}</title>
|
||||||
<link>#{LINK_VALUE}</link>
|
<link>#{LINK_VALUE}</link>
|
||||||
<description>#{DESCRIPTION_VALUE}</description>
|
<description>#{DESCRIPTION_VALUE}</description>
|
||||||
|
<language>#{LANGUAGE_VALUE}</language>
|
||||||
|
|
||||||
<image>
|
<image>
|
||||||
<url>#{RDF_RESOURCE}</url>
|
<url>#{RDF_RESOURCE}</url>
|
||||||
|
@ -142,6 +156,9 @@ EORSS
|
||||||
#{RESOURCES.collect do |res| '<item><link>' + res + '</link></item>' end.join("\n")}
|
#{RESOURCES.collect do |res| '<item><link>' + res + '</link></item>' end.join("\n")}
|
||||||
|
|
||||||
<textInput>
|
<textInput>
|
||||||
|
<title>#{TITLE_VALUE}</title>
|
||||||
|
<description>#{DESCRIPTION_VALUE}</description>
|
||||||
|
<name>#{NAME_VALUE}</name>
|
||||||
<link>#{RDF_RESOURCE}</link>
|
<link>#{RDF_RESOURCE}</link>
|
||||||
</textInput>
|
</textInput>
|
||||||
|
|
||||||
|
@ -150,7 +167,7 @@ EORSS
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_item2(content=nil)
|
def make_item20(content=nil)
|
||||||
<<-EOI
|
<<-EOI
|
||||||
<item>
|
<item>
|
||||||
<title>#{TITLE_VALUE}</title>
|
<title>#{TITLE_VALUE}</title>
|
||||||
|
@ -160,5 +177,17 @@ EOC
|
||||||
</item>
|
</item>
|
||||||
EOI
|
EOI
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def make_cloud20
|
||||||
|
<<-EOC
|
||||||
|
<cloud
|
||||||
|
domain="#{CLOUD_DOMAIN}"
|
||||||
|
port="#{CLOUD_PORT}"
|
||||||
|
path="#{CLOUD_PATH}"
|
||||||
|
registerProcedure="#{CLOUD_REGISTER_PROCEDURE}"
|
||||||
|
protocol="#{CLOUD_PROTOCOL}" />
|
||||||
|
EOC
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
require "rss-testcase"
|
require "rss-testcase"
|
||||||
|
|
||||||
require "rss/1.0"
|
require "rss/1.0"
|
||||||
|
require "rss/2.0"
|
||||||
|
require "rss/dublincore"
|
||||||
|
|
||||||
module RSS
|
module RSS
|
||||||
class TestParser < TestCase
|
class TestParser < TestCase
|
||||||
|
@ -76,14 +78,19 @@ EOR
|
||||||
EOR
|
EOR
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_not_excepted_tag("image", "RDF") do
|
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||||
Parser.parse(make_RDF(<<-EOR))
|
|
||||||
#{make_channel}
|
#{make_channel}
|
||||||
#{make_item}
|
#{make_item}
|
||||||
#{make_image}
|
#{make_image}
|
||||||
#{make_textinput}
|
#{make_textinput}
|
||||||
EOR
|
EOR
|
||||||
end
|
|
||||||
|
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||||
|
#{make_channel}
|
||||||
|
#{make_item}
|
||||||
|
#{make_textinput}
|
||||||
|
#{make_image}
|
||||||
|
EOR
|
||||||
|
|
||||||
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||||
#{make_channel}
|
#{make_channel}
|
||||||
|
@ -279,23 +286,6 @@ EOR
|
||||||
</image>
|
</image>
|
||||||
EOR
|
EOR
|
||||||
|
|
||||||
rss = make_RDF(<<-EOR)
|
|
||||||
#{make_channel}
|
|
||||||
<image rdf:about="http://example.com/hoge.png">
|
|
||||||
<title>hoge</title>
|
|
||||||
<link>http://example.com/</link>
|
|
||||||
<url>http://example.com/hoge.png</url>
|
|
||||||
</image>
|
|
||||||
EOR
|
|
||||||
|
|
||||||
assert_missing_tag("url", "image") do
|
|
||||||
Parser.parse(rss)
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_missing_tag("item", "RDF") do
|
|
||||||
Parser.parse(rss, false).validate
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||||
#{make_channel}
|
#{make_channel}
|
||||||
<image rdf:about="http://example.com/hoge.png">
|
<image rdf:about="http://example.com/hoge.png">
|
||||||
|
@ -305,6 +295,23 @@ EOR
|
||||||
</image>
|
</image>
|
||||||
EOR
|
EOR
|
||||||
|
|
||||||
|
rss = make_RDF(<<-EOR)
|
||||||
|
#{make_channel}
|
||||||
|
<image rdf:about="http://example.com/hoge.png">
|
||||||
|
<link>http://example.com/</link>
|
||||||
|
<url>http://example.com/hoge.png</url>
|
||||||
|
<title>hoge</title>
|
||||||
|
</image>
|
||||||
|
EOR
|
||||||
|
|
||||||
|
assert_missing_tag("item", "RDF") do
|
||||||
|
Parser.parse(rss)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_missing_tag("item", "RDF") do
|
||||||
|
Parser.parse(rss, false).validate
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_item
|
def test_item
|
||||||
|
@ -439,6 +446,142 @@ EOR
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_rss20
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), :missing_tag, "channel", "rss")
|
||||||
|
EOR
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), :nothing_raised)
|
||||||
|
#{make_channel20("")}
|
||||||
|
EOR
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cloud20
|
||||||
|
|
||||||
|
attrs = [
|
||||||
|
["domain", CLOUD_DOMAIN],
|
||||||
|
["port", CLOUD_PORT],
|
||||||
|
["path", CLOUD_PATH],
|
||||||
|
["registerProcedure", CLOUD_REGISTER_PROCEDURE],
|
||||||
|
["protocol", CLOUD_PROTOCOL],
|
||||||
|
]
|
||||||
|
|
||||||
|
(attrs.size + 1).times do |i|
|
||||||
|
missing_attr = attrs[i]
|
||||||
|
if missing_attr
|
||||||
|
meth = :missing_attribute
|
||||||
|
args = ["cloud", missing_attr[0]]
|
||||||
|
else
|
||||||
|
meth = :nothing_raised
|
||||||
|
args = []
|
||||||
|
end
|
||||||
|
|
||||||
|
cloud_attrs = []
|
||||||
|
attrs.each_with_index do |attr, j|
|
||||||
|
unless i == j
|
||||||
|
cloud_attrs << %Q[#{attr[0]}="#{attr[1]}"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), meth, *args)
|
||||||
|
#{make_channel20(%Q[<cloud #{cloud_attrs.join("\n")}/>])}
|
||||||
|
EOR
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_source20
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), :missing_attribute, "source", "url")
|
||||||
|
#{make_channel20(make_item20(%Q[<source>Example</source>]))}
|
||||||
|
EOR
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), :nothing_raised)
|
||||||
|
#{make_channel20(make_item20(%Q[<source url="http://example.com/" />]))}
|
||||||
|
EOR
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), :nothing_raised)
|
||||||
|
#{make_channel20(make_item20(%Q[<source url="http://example.com/">Example</source>]))}
|
||||||
|
EOR
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_enclosure20
|
||||||
|
|
||||||
|
attrs = [
|
||||||
|
["url", ENCLOSURE_URL],
|
||||||
|
["length", ENCLOSURE_LENGTH],
|
||||||
|
["type", ENCLOSURE_TYPE],
|
||||||
|
]
|
||||||
|
|
||||||
|
(attrs.size + 1).times do |i|
|
||||||
|
missing_attr = attrs[i]
|
||||||
|
if missing_attr
|
||||||
|
meth = :missing_attribute
|
||||||
|
args = ["enclosure", missing_attr[0]]
|
||||||
|
else
|
||||||
|
meth = :nothing_raised
|
||||||
|
args = []
|
||||||
|
end
|
||||||
|
|
||||||
|
enclosure_attrs = []
|
||||||
|
attrs.each_with_index do |attr, j|
|
||||||
|
unless i == j
|
||||||
|
enclosure_attrs << %Q[#{attr[0]}="#{attr[1]}"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_parse(make_rss20(<<-EOR), meth, *args)
|
||||||
|
#{make_channel20(%Q[
|
||||||
|
#{make_item20(%Q[
|
||||||
|
<enclosure
|
||||||
|
#{enclosure_attrs.join("\n")} />
|
||||||
|
])}
|
||||||
|
])}
|
||||||
|
EOR
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_category20
|
||||||
|
|
||||||
|
attrs = [
|
||||||
|
["domain", CATEGORY_DOMAIN],
|
||||||
|
]
|
||||||
|
|
||||||
|
(attrs.size + 1).times do |i|
|
||||||
|
missing_attr = attrs[i]
|
||||||
|
if missing_attr
|
||||||
|
meth = :missing_attribute
|
||||||
|
args = ["category", missing_attr[0]]
|
||||||
|
else
|
||||||
|
meth = :nothing_raised
|
||||||
|
args = []
|
||||||
|
end
|
||||||
|
|
||||||
|
category_attrs = []
|
||||||
|
attrs.each_with_index do |attr, j|
|
||||||
|
unless i == j
|
||||||
|
category_attrs << %Q[#{attr[0]}="#{attr[1]}"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
["", "Example Text"].each do |text|
|
||||||
|
assert_parse(make_rss20(<<-EOR), meth, *args)
|
||||||
|
#{make_channel20(%Q[
|
||||||
|
#{make_item20(%Q[
|
||||||
|
<category
|
||||||
|
#{category_attrs.join("\n")}>#{text}</category>
|
||||||
|
])}
|
||||||
|
])}
|
||||||
|
EOR
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def test_ignore
|
def test_ignore
|
||||||
|
|
||||||
rss = make_RDF(<<-EOR)
|
rss = make_RDF(<<-EOR)
|
||||||
|
|
|
@ -40,13 +40,13 @@ EOR
|
||||||
|
|
||||||
@rss = Parser.parse(@rss_source)
|
@rss = Parser.parse(@rss_source)
|
||||||
|
|
||||||
@rss2_source = make_Rss2(nil, {@prefix => @uri}) do
|
@rss20_source = make_rss20(nil, {@prefix => @uri}) do
|
||||||
make_channel2(nil) do
|
make_channel20(nil) do
|
||||||
make_item2(@content_nodes2)
|
make_item20(@content_nodes2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@rss2 = Parser.parse(@rss2_source, false)
|
@rss20 = Parser.parse(@rss20_source, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_parser
|
def test_parser
|
||||||
|
@ -92,18 +92,18 @@ EOR
|
||||||
accessor = "#{RSS::TRACKBACK_PREFIX}_#{name}"
|
accessor = "#{RSS::TRACKBACK_PREFIX}_#{name}"
|
||||||
target_accessor = "resource"
|
target_accessor = "resource"
|
||||||
target = @rss.send(parent).send(accessor)
|
target = @rss.send(parent).send(accessor)
|
||||||
target2 = @rss2.channel.send(parent, -1)
|
target20 = @rss20.channel.send(parent, -1)
|
||||||
assert_equal(value, target.send(target_accessor))
|
assert_equal(value, target.send(target_accessor))
|
||||||
assert_equal(value, target2.send(accessor))
|
assert_equal(value, target20.send(accessor))
|
||||||
target.send("#{target_accessor}=", new_value[name].to_s)
|
target.send("#{target_accessor}=", new_value[name].to_s)
|
||||||
if name == :about
|
if name == :about
|
||||||
# abount is zero or more
|
# abount is zero or more
|
||||||
target2.send("#{accessor}=", 0, new_value[name].to_s)
|
target20.send("#{accessor}=", 0, new_value[name].to_s)
|
||||||
else
|
else
|
||||||
target2.send("#{accessor}=", new_value[name].to_s)
|
target20.send("#{accessor}=", new_value[name].to_s)
|
||||||
end
|
end
|
||||||
assert_equal(new_value[name], target.send(target_accessor))
|
assert_equal(new_value[name], target.send(target_accessor))
|
||||||
assert_equal(new_value[name], target2.send(accessor))
|
assert_equal(new_value[name], target20.send(accessor))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче