From 83240f315a10b42b53c3b62c1fbc428f97912665 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 11 Jan 2020 21:48:06 +0900 Subject: Make rss library to the bundle gems [Feature #16485][ruby-core:96683] --- lib/rss/0.9.rb | 462 --------------- lib/rss/1.0.rb | 485 --------------- lib/rss/2.0.rb | 143 ----- lib/rss/atom.rb | 1025 -------------------------------- lib/rss/content.rb | 34 -- lib/rss/content/1.0.rb | 10 - lib/rss/content/2.0.rb | 12 - lib/rss/converter.rb | 171 ------ lib/rss/dublincore.rb | 164 ------ lib/rss/dublincore/1.0.rb | 13 - lib/rss/dublincore/2.0.rb | 13 - lib/rss/dublincore/atom.rb | 17 - lib/rss/image.rb | 198 ------- lib/rss/itunes.rb | 425 ------------- lib/rss/maker.rb | 79 --- lib/rss/maker/0.9.rb | 509 ---------------- lib/rss/maker/1.0.rb | 436 -------------- lib/rss/maker/2.0.rb | 224 ------- lib/rss/maker/atom.rb | 173 ------ lib/rss/maker/base.rb | 945 ----------------------------- lib/rss/maker/content.rb | 22 - lib/rss/maker/dublincore.rb | 122 ---- lib/rss/maker/entry.rb | 164 ------ lib/rss/maker/feed.rb | 427 -------------- lib/rss/maker/image.rb | 112 ---- lib/rss/maker/itunes.rb | 243 -------- lib/rss/maker/slash.rb | 34 -- lib/rss/maker/syndication.rb | 19 - lib/rss/maker/taxonomy.rb | 119 ---- lib/rss/maker/trackback.rb | 62 -- lib/rss/parser.rb | 589 ------------------ lib/rss/rexmlparser.rb | 50 -- lib/rss/rss.gemspec | 80 --- lib/rss/rss.rb | 1342 ------------------------------------------ lib/rss/slash.rb | 52 -- lib/rss/syndication.rb | 69 --- lib/rss/taxonomy.rb | 148 ----- lib/rss/trackback.rb | 291 --------- lib/rss/utils.rb | 200 ------- lib/rss/version.rb | 4 - lib/rss/xml-stylesheet.rb | 106 ---- lib/rss/xml.rb | 72 --- lib/rss/xmlparser.rb | 95 --- lib/rss/xmlscanner.rb | 122 ---- 44 files changed, 10082 deletions(-) delete mode 100644 lib/rss/0.9.rb delete mode 100644 lib/rss/1.0.rb delete mode 100644 lib/rss/2.0.rb delete mode 100644 lib/rss/atom.rb delete mode 100644 lib/rss/content.rb delete mode 100644 lib/rss/content/1.0.rb delete mode 100644 lib/rss/content/2.0.rb delete mode 100644 lib/rss/converter.rb delete mode 100644 lib/rss/dublincore.rb delete mode 100644 lib/rss/dublincore/1.0.rb delete mode 100644 lib/rss/dublincore/2.0.rb delete mode 100644 lib/rss/dublincore/atom.rb delete mode 100644 lib/rss/image.rb delete mode 100644 lib/rss/itunes.rb delete mode 100644 lib/rss/maker.rb delete mode 100644 lib/rss/maker/0.9.rb delete mode 100644 lib/rss/maker/1.0.rb delete mode 100644 lib/rss/maker/2.0.rb delete mode 100644 lib/rss/maker/atom.rb delete mode 100644 lib/rss/maker/base.rb delete mode 100644 lib/rss/maker/content.rb delete mode 100644 lib/rss/maker/dublincore.rb delete mode 100644 lib/rss/maker/entry.rb delete mode 100644 lib/rss/maker/feed.rb delete mode 100644 lib/rss/maker/image.rb delete mode 100644 lib/rss/maker/itunes.rb delete mode 100644 lib/rss/maker/slash.rb delete mode 100644 lib/rss/maker/syndication.rb delete mode 100644 lib/rss/maker/taxonomy.rb delete mode 100644 lib/rss/maker/trackback.rb delete mode 100644 lib/rss/parser.rb delete mode 100644 lib/rss/rexmlparser.rb delete mode 100644 lib/rss/rss.gemspec delete mode 100644 lib/rss/rss.rb delete mode 100644 lib/rss/slash.rb delete mode 100644 lib/rss/syndication.rb delete mode 100644 lib/rss/taxonomy.rb delete mode 100644 lib/rss/trackback.rb delete mode 100644 lib/rss/utils.rb delete mode 100644 lib/rss/version.rb delete mode 100644 lib/rss/xml-stylesheet.rb delete mode 100644 lib/rss/xml.rb delete mode 100644 lib/rss/xmlparser.rb delete mode 100644 lib/rss/xmlscanner.rb (limited to 'lib') diff --git a/lib/rss/0.9.rb b/lib/rss/0.9.rb deleted file mode 100644 index 219ccefcdb..0000000000 --- a/lib/rss/0.9.rb +++ /dev/null @@ -1,462 +0,0 @@ -# frozen_string_literal: false -require_relative "parser" - -module RSS - - ## - # = RSS 0.9 support - # - # RSS has three different versions. This module contains support for version - # 0.9.1[http://www.rssboard.org/rss-0-9-1-netscape]. - # - # == Producing RSS 0.9 - # - # Producing our own RSS feeds is easy as well. Let's make a very basic feed: - # - # require "rss" - # - # rss = RSS::Maker.make("0.91") do |maker| - # maker.channel.language = "en" - # maker.channel.author = "matz" - # maker.channel.updated = Time.now.to_s - # maker.channel.link = "http://www.ruby-lang.org/en/feeds/news.rss" - # maker.channel.title = "Example Feed" - # maker.channel.description = "A longer description of my feed." - # maker.image.url = "http://www.ruby-lang.org/images/logo.gif" - # maker.image.title = "An image" - # maker.items.new_item do |item| - # item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/" - # item.title = "Ruby 1.9.2-p136 is released" - # item.updated = Time.now.to_s - # end - # end - # - # puts rss - # - # As you can see, this is a very Builder-like DSL. This code will spit out an - # RSS 0.9 feed with one item. If we needed a second item, we'd make another - # block with maker.items.new_item and build a second one. - module RSS09 - NSPOOL = {} - ELEMENTS = [] - - def self.append_features(klass) - super - - klass.install_must_call_validator('', "") - end - end - - class Rss < Element - - include RSS09 - include RootElementMixin - - %w(channel).each do |name| - install_have_child_element(name, "", nil) - end - - attr_writer :feed_version - alias_method(:rss_version, :feed_version) - alias_method(:rss_version=, :feed_version=) - - def initialize(feed_version, version=nil, encoding=nil, standalone=nil) - super - @feed_type = "rss" - end - - def items - if @channel - @channel.items - else - [] - end - end - - def image - if @channel - @channel.image - else - nil - end - end - - def textinput - if @channel - @channel.textInput - else - nil - end - end - - def setup_maker_elements(maker) - super - items.each do |item| - item.setup_maker(maker.items) - end - image.setup_maker(maker) if image - textinput.setup_maker(maker) if textinput - end - - private - def _attrs - [ - ["version", true, "feed_version"], - ] - end - - class Channel < Element - - include RSS09 - - [ - ["title", nil, :text], - ["link", nil, :text], - ["description", nil, :text], - ["language", nil, :text], - ["copyright", "?", :text], - ["managingEditor", "?", :text], - ["webMaster", "?", :text], - ["rating", "?", :text], - ["pubDate", "?", :date, :rfc822], - ["lastBuildDate", "?", :date, :rfc822], - ["docs", "?", :text], - ["cloud", "?", :have_attribute], - ["skipDays", "?", :have_child], - ["skipHours", "?", :have_child], - ["image", nil, :have_child], - ["item", "*", :have_children], - ["textInput", "?", :have_child], - ].each do |name, occurs, type, *args| - __send__("install_#{type}_element", name, "", occurs, name, *args) - end - alias date pubDate - alias date= pubDate= - - private - def maker_target(maker) - maker.channel - end - - def setup_maker_elements(channel) - super - [ - [skipDays, "day"], - [skipHours, "hour"], - ].each do |skip, key| - if skip - skip.__send__("#{key}s").each do |val| - target_skips = channel.__send__("skip#{key.capitalize}s") - new_target = target_skips.__send__("new_#{key}") - new_target.content = val.content - end - end - end - end - - def not_need_to_call_setup_maker_variables - %w(image textInput) - end - - class SkipDays < Element - include RSS09 - - [ - ["day", "*"] - ].each do |name, occurs| - install_have_children_element(name, "", occurs) - end - - class Day < Element - include RSS09 - - content_setup - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.content = args[0] - end - end - - end - - end - - class SkipHours < Element - include RSS09 - - [ - ["hour", "*"] - ].each do |name, occurs| - install_have_children_element(name, "", occurs) - end - - class Hour < Element - include RSS09 - - content_setup(:integer) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.content = args[0] - end - end - end - - end - - class Image < Element - - include RSS09 - - %w(url title link).each do |name| - install_text_element(name, "", nil) - end - [ - ["width", :integer], - ["height", :integer], - ["description"], - ].each do |name, type| - install_text_element(name, "", "?", name, type) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.url = args[0] - self.title = args[1] - self.link = args[2] - self.width = args[3] - self.height = args[4] - self.description = args[5] - end - end - - private - def maker_target(maker) - maker.image - end - end - - class Cloud < Element - - include RSS09 - - [ - ["domain", "", true], - ["port", "", true, :integer], - ["path", "", true], - ["registerProcedure", "", true], - ["protocol", "", true], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.domain = args[0] - self.port = args[1] - self.path = args[2] - self.registerProcedure = args[3] - self.protocol = args[4] - end - end - end - - class Item < Element - - include RSS09 - - [ - ["title", '?', :text], - ["link", '?', :text], - ["description", '?', :text], - ["category", '*', :have_children, "categories"], - ["source", '?', :have_child], - ["enclosure", '?', :have_child], - ].each do |tag, occurs, type, *args| - __send__("install_#{type}_element", tag, "", occurs, tag, *args) - end - - private - def maker_target(items) - if items.respond_to?("items") - # For backward compatibility - items = items.items - end - items.new_item - end - - def setup_maker_element(item) - super - @enclosure.setup_maker(item) if @enclosure - @source.setup_maker(item) if @source - end - - class Source < Element - - include RSS09 - - [ - ["url", "", true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required) - end - - content_setup - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.url = args[0] - self.content = args[1] - end - end - - private - def maker_target(item) - item.source - end - - def setup_maker_attributes(source) - source.url = url - source.content = content - end - end - - class Enclosure < Element - - include RSS09 - - [ - ["url", "", true], - ["length", "", true, :integer], - ["type", "", true], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.url = args[0] - self.length = args[1] - self.type = args[2] - end - end - - private - def maker_target(item) - item.enclosure - end - - def setup_maker_attributes(enclosure) - enclosure.url = url - enclosure.length = length - enclosure.type = type - end - end - - class Category < Element - - include RSS09 - - [ - ["domain", "", false] - ].each do |name, uri, required| - install_get_attribute(name, uri, required) - end - - content_setup - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.domain = args[0] - self.content = args[1] - end - end - - private - def maker_target(item) - item.new_category - end - - def setup_maker_attributes(category) - category.domain = domain - category.content = content - end - - end - - end - - class TextInput < Element - - include RSS09 - - %w(title description name link).each do |name| - install_text_element(name, "", nil) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.title = args[0] - self.description = args[1] - self.name = args[2] - self.link = args[3] - end - end - - private - def maker_target(maker) - maker.textinput - end - end - - end - - end - - RSS09::ELEMENTS.each do |name| - BaseListener.install_get_text_element("", name, name) - end - - module ListenerMixin - private - def initial_start_rss(tag_name, prefix, attrs, ns) - check_ns(tag_name, prefix, ns, "", false) - - @rss = Rss.new(attrs['version'], @version, @encoding, @standalone) - @rss.do_validate = @do_validate - @rss.xml_stylesheets = @xml_stylesheets - @last_element = @rss - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate - end - @proc_stack.push(pr) - end - - end - -end diff --git a/lib/rss/1.0.rb b/lib/rss/1.0.rb deleted file mode 100644 index c8f92fb54e..0000000000 --- a/lib/rss/1.0.rb +++ /dev/null @@ -1,485 +0,0 @@ -# frozen_string_literal: false -require_relative "parser" - -module RSS - - ## - # = RSS 1.0 support - # - # RSS has three different versions. This module contains support for version - # 1.0[http://web.resource.org/rss/1.0/] - # - # == Producing RSS 1.0 - # - # Producing our own RSS feeds is easy as well. Let's make a very basic feed: - # - # require "rss" - # - # rss = RSS::Maker.make("1.0") do |maker| - # maker.channel.language = "en" - # maker.channel.author = "matz" - # maker.channel.about = "About my feed." - # maker.channel.updated = Time.now.to_s - # maker.channel.link = "http://www.ruby-lang.org/en/feeds/news.rss" - # maker.channel.title = "Example Feed" - # maker.channel.description = "A longer description of my feed." - # maker.items.new_item do |item| - # item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/" - # item.title = "Ruby 1.9.2-p136 is released" - # item.updated = Time.now.to_s - # end - # end - # - # puts rss - # - # As you can see, this is a very Builder-like DSL. This code will spit out an - # RSS 1.0 feed with one item. If we needed a second item, we'd make another - # block with maker.items.new_item and build a second one. - module RSS10 - NSPOOL = {} - ELEMENTS = [] - - def self.append_features(klass) - super - - klass.install_must_call_validator('', ::RSS::URI) - end - - end - - class RDF < Element - - include RSS10 - include RootElementMixin - - class << self - - def required_uri - URI - end - - end - - @tag_name = 'RDF' - - PREFIX = 'rdf' - URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" - - install_ns('', ::RSS::URI) - install_ns(PREFIX, URI) - - [ - ["channel", nil], - ["image", "?"], - ["item", "+", :children], - ["textinput", "?"], - ].each do |tag, occurs, type| - type ||= :child - __send__("install_have_#{type}_element", tag, ::RSS::URI, occurs) - end - - alias_method(:rss_version, :feed_version) - def initialize(version=nil, encoding=nil, standalone=nil) - super('1.0', version, encoding, standalone) - @feed_type = "rss" - end - - def full_name - tag_name_with_prefix(PREFIX) - end - - class Li < Element - - include RSS10 - - class << self - def required_uri - URI - end - end - - [ - ["resource", [URI, ""], true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.resource = args[0] - end - end - - def full_name - tag_name_with_prefix(PREFIX) - end - end - - class Seq < Element - - include RSS10 - - Li = ::RSS::RDF::Li - - class << self - def required_uri - URI - end - end - - @tag_name = 'Seq' - - install_have_children_element("li", URI, "*") - install_must_call_validator('rdf', ::RSS::RDF::URI) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - @li = args[0] if args[0] - end - end - - def full_name - tag_name_with_prefix(PREFIX) - end - - def setup_maker(target) - lis.each do |li| - target << li.resource - end - end - end - - class Bag < Element - - include RSS10 - - Li = ::RSS::RDF::Li - - class << self - def required_uri - URI - end - end - - @tag_name = 'Bag' - - install_have_children_element("li", URI, "*") - install_must_call_validator('rdf', URI) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - @li = args[0] if args[0] - end - end - - def full_name - tag_name_with_prefix(PREFIX) - end - - def setup_maker(target) - lis.each do |li| - target << li.resource - end - end - end - - class Channel < Element - - include RSS10 - - class << self - - def required_uri - ::RSS::URI - end - - end - - [ - ["about", URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{PREFIX}:#{name}") - end - - [ - ['title', nil, :text], - ['link', nil, :text], - ['description', nil, :text], - ['image', '?', :have_child], - ['items', nil, :have_child], - ['textinput', '?', :have_child], - ].each do |tag, occurs, type| - __send__("install_#{type}_element", tag, ::RSS::URI, occurs) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - end - end - - private - def maker_target(maker) - maker.channel - end - - def setup_maker_attributes(channel) - channel.about = about - end - - class Image < Element - - include RSS10 - - class << self - - def required_uri - ::RSS::URI - end - - end - - [ - ["resource", URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{PREFIX}:#{name}") - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.resource = args[0] - end - end - end - - class Textinput < Element - - include RSS10 - - class << self - - def required_uri - ::RSS::URI - end - - end - - [ - ["resource", URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{PREFIX}:#{name}") - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.resource = args[0] - end - end - end - - class Items < Element - - include RSS10 - - Seq = ::RSS::RDF::Seq - - class << self - - def required_uri - ::RSS::URI - end - - end - - install_have_child_element("Seq", URI, nil) - install_must_call_validator('rdf', URI) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.Seq = args[0] - end - self.Seq ||= Seq.new - end - - def resources - if @Seq - @Seq.lis.collect do |li| - li.resource - end - else - [] - end - end - end - end - - class Image < Element - - include RSS10 - - class << self - - def required_uri - ::RSS::URI - end - - end - - [ - ["about", URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{PREFIX}:#{name}") - end - - %w(title url link).each do |name| - install_text_element(name, ::RSS::URI, nil) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - end - end - - private - def maker_target(maker) - maker.image - end - end - - class Item < Element - - include RSS10 - - class << self - - def required_uri - ::RSS::URI - end - - end - - - [ - ["about", URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{PREFIX}:#{name}") - end - - [ - ["title", nil], - ["link", nil], - ["description", "?"], - ].each do |tag, occurs| - install_text_element(tag, ::RSS::URI, occurs) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - end - end - - private - def maker_target(items) - if items.respond_to?("items") - # For backward compatibility - items = items.items - end - items.new_item - end - end - - class Textinput < Element - - include RSS10 - - class << self - - def required_uri - ::RSS::URI - end - - end - - [ - ["about", URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{PREFIX}:#{name}") - end - - %w(title description name link).each do |name| - install_text_element(name, ::RSS::URI, nil) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - end - end - - private - def maker_target(maker) - maker.textinput - end - end - - end - - RSS10::ELEMENTS.each do |name| - BaseListener.install_get_text_element(URI, name, name) - end - - module ListenerMixin - private - def initial_start_RDF(tag_name, prefix, attrs, ns) - check_ns(tag_name, prefix, ns, RDF::URI, false) - - @rss = RDF.new(@version, @encoding, @standalone) - @rss.do_validate = @do_validate - @rss.xml_stylesheets = @xml_stylesheets - @last_element = @rss - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate - end - @proc_stack.push(pr) - end - end - -end diff --git a/lib/rss/2.0.rb b/lib/rss/2.0.rb deleted file mode 100644 index 13f9ade918..0000000000 --- a/lib/rss/2.0.rb +++ /dev/null @@ -1,143 +0,0 @@ -# frozen_string_literal: false -require "rss/0.9" - -module RSS - - ## - # = RSS 2.0 support - # - # RSS has three different versions. This module contains support for version - # 2.0[http://www.rssboard.org/rss-specification] - # - # == Producing RSS 2.0 - # - # Producing our own RSS feeds is easy as well. Let's make a very basic feed: - # - # require "rss" - # - # rss = RSS::Maker.make("2.0") do |maker| - # maker.channel.language = "en" - # maker.channel.author = "matz" - # maker.channel.updated = Time.now.to_s - # maker.channel.link = "http://www.ruby-lang.org/en/feeds/news.rss" - # maker.channel.title = "Example Feed" - # maker.channel.description = "A longer description of my feed." - # maker.items.new_item do |item| - # item.link = "http://www.ruby-lang.org/en/news/2010/12/25/ruby-1-9-2-p136-is-released/" - # item.title = "Ruby 1.9.2-p136 is released" - # item.updated = Time.now.to_s - # end - # end - # - # puts rss - # - # As you can see, this is a very Builder-like DSL. This code will spit out an - # RSS 2.0 feed with one item. If we needed a second item, we'd make another - # block with maker.items.new_item and build a second one. - class Rss - - class Channel - - [ - ["generator"], - ["ttl", :integer], - ].each do |name, type| - install_text_element(name, "", "?", name, type) - end - - [ - %w(category categories), - ].each do |name, plural_name| - install_have_children_element(name, "", "*", name, plural_name) - end - - [ - ["image", "?"], - ["language", "?"], - ].each do |name, occurs| - install_model(name, "", occurs) - end - - Category = Item::Category - - class Item - - [ - ["comments", "?"], - ["author", "?"], - ].each do |name, occurs| - install_text_element(name, "", occurs) - end - - [ - ["pubDate", '?'], - ].each do |name, occurs| - install_date_element(name, "", occurs, name, 'rfc822') - end - alias date pubDate - alias date= pubDate= - - [ - ["guid", '?'], - ].each do |name, occurs| - install_have_child_element(name, "", occurs) - end - - private - alias _setup_maker_element setup_maker_element - def setup_maker_element(item) - _setup_maker_element(item) - @guid.setup_maker(item) if @guid - end - - class Guid < Element - - include RSS09 - - [ - ["isPermaLink", "", false, :boolean] - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - content_setup - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.isPermaLink = args[0] - self.content = args[1] - end - end - - alias_method :_PermaLink?, :PermaLink? - private :_PermaLink? - def PermaLink? - perma = _PermaLink? - perma or perma.nil? - end - - private - def maker_target(item) - item.guid - end - - def setup_maker_attributes(guid) - guid.isPermaLink = isPermaLink - guid.content = content - end - end - - end - - end - - end - - RSS09::ELEMENTS.each do |name| - BaseListener.install_get_text_element("", name, name) - end - -end diff --git a/lib/rss/atom.rb b/lib/rss/atom.rb deleted file mode 100644 index 48c27330d0..0000000000 --- a/lib/rss/atom.rb +++ /dev/null @@ -1,1025 +0,0 @@ -# frozen_string_literal: false -require_relative 'parser' - -module RSS - ## - # Atom is an XML-based document format that is used to describe 'feeds' of related information. - # A typical use is in a news feed where the information is periodically updated and which users - # can subscribe to. The Atom format is described in http://tools.ietf.org/html/rfc4287 - # - # The Atom module provides support in reading and creating feeds. - # - # See the RSS module for examples consuming and creating feeds. - module Atom - - ## - # The Atom URI W3C Namespace - - URI = "http://www.w3.org/2005/Atom" - - ## - # The XHTML URI W3C Namespace - - XHTML_URI = "http://www.w3.org/1999/xhtml" - - module CommonModel - NSPOOL = {} - ELEMENTS = [] - - def self.append_features(klass) - super - klass.install_must_call_validator("atom", URI) - [ - ["lang", :xml], - ["base", :xml], - ].each do |name, uri, required| - klass.install_get_attribute(name, uri, required, [nil, :inherit]) - end - klass.class_eval do - class << self - # Returns the Atom URI W3C Namespace - def required_uri - URI - end - - # Returns true - def need_parent? - true - end - end - end - end - end - - module ContentModel - module ClassMethods - def content_type - @content_type ||= nil - end - end - - class << self - def append_features(klass) - super - klass.extend(ClassMethods) - klass.content_setup(klass.content_type, klass.tag_name) - end - end - - def maker_target(target) - target - end - - private - def setup_maker_element_writer - "#{self.class.name.split(/::/).last.downcase}=" - end - - def setup_maker_element(target) - target.__send__(setup_maker_element_writer, content) - super - end - end - - module URIContentModel - class << self - def append_features(klass) - super - klass.class_eval do - @content_type = [nil, :uri] - include(ContentModel) - end - end - end - end - - # The TextConstruct module is used to define a Text construct Atom element, - # which is used to store small quantities of human-readable text. - # - # The TextConstruct has a type attribute, e.g. text, html, xhtml - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#text.constructs - module TextConstruct - def self.append_features(klass) - super - klass.class_eval do - [ - ["type", ""], - ].each do |name, uri, required| - install_get_attribute(name, uri, required, :text_type) - end - - content_setup - add_need_initialize_variable("xhtml") - - class << self - def xml_getter - "xhtml" - end - - def xml_setter - "xhtml=" - end - end - end - end - - attr_writer :xhtml - - # Returns or builds the XHTML content. - def xhtml - return @xhtml if @xhtml.nil? - if @xhtml.is_a?(XML::Element) and - [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI] - return @xhtml - end - - children = @xhtml - children = [children] unless children.is_a?(Array) - XML::Element.new("div", nil, XHTML_URI, - {"xmlns" => XHTML_URI}, children) - end - - # Returns true if type is "xhtml". - def have_xml_content? - @type == "xhtml" - end - - # Raises a MissingTagError or NotExpectedTagError - # if the element is not properly formatted. - def atom_validate(ignore_unknown_element, tags, uri) - if have_xml_content? - if @xhtml.nil? - raise MissingTagError.new("div", tag_name) - end - unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI] - raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name) - end - end - end - - private - def maker_target(target) - target.__send__(self.class.name.split(/::/).last.downcase) {|x| x} - end - - def setup_maker_attributes(target) - target.type = type - target.content = content - target.xml_content = @xhtml - end - end - - # The PersonConstruct module is used to define a person Atom element that can be - # used to describe a person, corporation or similar entity. - # - # The PersonConstruct has a Name, Uri and Email child elements. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#atomPersonConstruct - module PersonConstruct - - # Adds attributes for name, uri, and email to the +klass+ - def self.append_features(klass) - super - klass.class_eval do - [ - ["name", nil], - ["uri", "?"], - ["email", "?"], - ].each do |tag, occurs| - install_have_attribute_element(tag, URI, occurs, nil, :content) - end - end - end - - def maker_target(target) - target.__send__("new_#{self.class.name.split(/::/).last.downcase}") - end - - # The name of the person or entity. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.name - class Name < RSS::Element - include CommonModel - include ContentModel - end - - # The URI of the person or entity. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.uri - class Uri < RSS::Element - include CommonModel - include URIContentModel - end - - # The email of the person or entity. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.email - class Email < RSS::Element - include CommonModel - include ContentModel - end - end - - # Element used to describe an Atom date and time in the ISO 8601 format - # - # Examples: - # * 2013-03-04T15:30:02Z - # * 2013-03-04T10:30:02-05:00 - module DateConstruct - def self.append_features(klass) - super - klass.class_eval do - @content_type = :w3cdtf - include(ContentModel) - end - end - - # Raises NotAvailableValueError if element content is nil - def atom_validate(ignore_unknown_element, tags, uri) - raise NotAvailableValueError.new(tag_name, "") if content.nil? - end - end - - module DuplicateLinkChecker - # Checks if there are duplicate links with the same type and hreflang attributes - # that have an alternate (or empty) rel attribute - # - # Raises a TooMuchTagError if there are duplicates found - def validate_duplicate_links(links) - link_infos = {} - links.each do |link| - rel = link.rel || "alternate" - next unless rel == "alternate" - key = [link.hreflang, link.type] - if link_infos.has_key?(key) - raise TooMuchTagError.new("link", tag_name) - end - link_infos[key] = true - end - end - end - - # Defines the top-level element of an Atom Feed Document. - # It consists of a number of children Entry elements, - # and has the following attributes: - # - # * author - # * categories - # * category - # * content - # * contributor - # * entries (aliased as items) - # * entry - # * generator - # * icon - # * id - # * link - # * logo - # * rights - # * subtitle - # * title - # * updated - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.feed - class Feed < RSS::Element - include RootElementMixin - include CommonModel - include DuplicateLinkChecker - - install_ns('', URI) - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["contributor", "*", :children], - ["generator", "?"], - ["icon", "?", nil, :content], - ["id", nil, nil, :content], - ["link", "*", :children], - ["logo", "?"], - ["rights", "?"], - ["subtitle", "?", nil, :content], - ["title", nil, nil, :content], - ["updated", nil, nil, :content], - ["entry", "*", :children, "entries"], - ].each do |tag, occurs, type, *args| - type ||= :child - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - # Creates a new Atom feed - def initialize(version=nil, encoding=nil, standalone=nil) - super("1.0", version, encoding, standalone) - @feed_type = "atom" - @feed_subtype = "feed" - end - - alias_method :items, :entries - - # Returns true if there are any authors for the feed or any of the Entry - # child elements have an author - def have_author? - authors.any? {|author| !author.to_s.empty?} or - entries.any? {|entry| entry.have_author?(false)} - end - - private - def atom_validate(ignore_unknown_element, tags, uri) - unless have_author? - raise MissingTagError.new("author", tag_name) - end - validate_duplicate_links(links) - end - - def have_required_elements? - super and have_author? - end - - def maker_target(maker) - maker.channel - end - - def setup_maker_element(channel) - prev_dc_dates = channel.dc_dates.to_a.dup - super - channel.about = id.content if id - channel.dc_dates.replace(prev_dc_dates) - end - - def setup_maker_elements(channel) - super - items = channel.maker.items - entries.each do |entry| - entry.setup_maker(items) - end - end - - # PersonConstruct that contains information regarding the author - # of a Feed or Entry. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.author - class Author < RSS::Element - include CommonModel - include PersonConstruct - end - - # Contains information about a category associated with a Feed or Entry. - # It has the following attributes: - # - # * term - # * scheme - # * label - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.category - class Category < RSS::Element - include CommonModel - - [ - ["term", "", true], - ["scheme", "", false, [nil, :uri]], - ["label", ""], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - private - def maker_target(target) - target.new_category - end - end - - # PersonConstruct that contains information regarding the - # contributors of a Feed or Entry. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.contributor - class Contributor < RSS::Element - include CommonModel - include PersonConstruct - end - - # Contains information on the agent used to generate the feed. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.generator - class Generator < RSS::Element - include CommonModel - include ContentModel - - [ - ["uri", "", false, [nil, :uri]], - ["version", ""], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - private - def setup_maker_attributes(target) - target.generator do |generator| - generator.uri = uri if uri - generator.version = version if version - end - end - end - - # Defines an image that provides a visual identification for a eed. - # The image should have an aspect ratio of 1:1. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.icon - class Icon < RSS::Element - include CommonModel - include URIContentModel - end - - # Defines the Universally Unique Identifier (UUID) for a Feed or Entry. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.id - class Id < RSS::Element - include CommonModel - include URIContentModel - end - - # Defines a reference to a Web resource. It has the following - # attributes: - # - # * href - # * rel - # * type - # * hreflang - # * title - # * length - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.link - class Link < RSS::Element - include CommonModel - - [ - ["href", "", true, [nil, :uri]], - ["rel", ""], - ["type", ""], - ["hreflang", ""], - ["title", ""], - ["length", ""], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - private - def maker_target(target) - target.new_link - end - end - - # Defines an image that provides a visual identification for the Feed. - # The image should have an aspect ratio of 2:1 (horizontal:vertical). - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.logo - class Logo < RSS::Element - include CommonModel - include URIContentModel - - def maker_target(target) - target.maker.image - end - - private - def setup_maker_element_writer - "url=" - end - end - - # TextConstruct that contains copyright information regarding - # the content in an Entry or Feed. It should not be used to - # convey machine readable licensing information. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.rights - class Rights < RSS::Element - include CommonModel - include TextConstruct - end - - # TextConstruct that conveys a description or subtitle for a Feed. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.subtitle - class Subtitle < RSS::Element - include CommonModel - include TextConstruct - end - - # TextConstruct that conveys a description or title for a Feed or Entry. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.title - class Title < RSS::Element - include CommonModel - include TextConstruct - end - - # DateConstruct indicating the most recent time when a Feed or - # Entry was modified in a way the publisher considers - # significant. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.updated - class Updated < RSS::Element - include CommonModel - include DateConstruct - end - - # Defines a child Atom Entry element of an Atom Feed element. - # It has the following attributes: - # - # * author - # * category - # * categories - # * content - # * contributor - # * id - # * link - # * published - # * rights - # * source - # * summary - # * title - # * updated - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.entry - class Entry < RSS::Element - include CommonModel - include DuplicateLinkChecker - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["content", "?", :child], - ["contributor", "*", :children], - ["id", nil, nil, :content], - ["link", "*", :children], - ["published", "?", :child, :content], - ["rights", "?", :child], - ["source", "?"], - ["summary", "?", :child], - ["title", nil], - ["updated", nil, :child, :content], - ].each do |tag, occurs, type, *args| - type ||= :attribute - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - # Returns whether any of the following are true: - # - # * There are any authors in the feed - # * If the parent element has an author and the +check_parent+ - # parameter was given. - # * There is a source element that has an author - def have_author?(check_parent=true) - authors.any? {|author| !author.to_s.empty?} or - (check_parent and @parent and @parent.have_author?) or - (source and source.have_author?) - end - - private - def atom_validate(ignore_unknown_element, tags, uri) - unless have_author? - raise MissingTagError.new("author", tag_name) - end - validate_duplicate_links(links) - end - - def have_required_elements? - super and have_author? - end - - def maker_target(items) - if items.respond_to?("items") - # For backward compatibility - items = items.items - end - items.new_item - end - - # Feed::Author - Author = Feed::Author - # Feed::Category - Category = Feed::Category - - # Contains or links to the content of the Entry. - # It has the following attributes: - # - # * type - # * src - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.content - class Content < RSS::Element - include CommonModel - - class << self - def xml_setter - "xml=" - end - - def xml_getter - "xml" - end - end - - [ - ["type", ""], - ["src", "", false, [nil, :uri]], - ].each do |name, uri, required, type| - install_get_attribute(name, uri, required, type) - end - - content_setup - add_need_initialize_variable("xml") - - # Returns the element content in XML. - attr_writer :xml - - # Returns true if the element has inline XML content. - def have_xml_content? - inline_xhtml? or inline_other_xml? - end - - # Returns or builds the element content in XML. - def xml - return @xml unless inline_xhtml? - return @xml if @xml.nil? - if @xml.is_a?(XML::Element) and - [@xml.name, @xml.uri] == ["div", XHTML_URI] - return @xml - end - - children = @xml - children = [children] unless children.is_a?(Array) - XML::Element.new("div", nil, XHTML_URI, - {"xmlns" => XHTML_URI}, children) - end - - # Returns the element content in XHTML. - def xhtml - if inline_xhtml? - xml - else - nil - end - end - - # Raises a MissingAttributeError, NotAvailableValueError, - # MissingTagError or NotExpectedTagError if the element is - # not properly formatted. - def atom_validate(ignore_unknown_element, tags, uri) - if out_of_line? - raise MissingAttributeError.new(tag_name, "type") if @type.nil? - unless (content.nil? or content.empty?) - raise NotAvailableValueError.new(tag_name, content) - end - elsif inline_xhtml? - if @xml.nil? - raise MissingTagError.new("div", tag_name) - end - unless @xml.name == "div" and @xml.uri == XHTML_URI - raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name) - end - end - end - - # Returns true if the element contains inline content - # that has a text or HTML media type, or no media type at all. - def inline_text? - !out_of_line? and [nil, "text", "html"].include?(@type) - end - - # Returns true if the element contains inline content that - # has a HTML media type. - def inline_html? - return false if out_of_line? - @type == "html" or mime_split == ["text", "html"] - end - - # Returns true if the element contains inline content that - # has a XHTML media type. - def inline_xhtml? - !out_of_line? and @type == "xhtml" - end - - # Returns true if the element contains inline content that - # has a MIME media type. - def inline_other? - return false if out_of_line? - media_type, subtype = mime_split - return false if media_type.nil? or subtype.nil? - true - end - - # Returns true if the element contains inline content that - # has a text media type. - def inline_other_text? - return false unless inline_other? - return false if inline_other_xml? - - media_type, = mime_split - return true if "text" == media_type.downcase - false - end - - # Returns true if the element contains inline content that - # has a XML media type. - def inline_other_xml? - return false unless inline_other? - - media_type, subtype = mime_split - normalized_mime_type = "#{media_type}/#{subtype}".downcase - if /(?:\+xml|^xml)$/ =~ subtype or - %w(text/xml-external-parsed-entity - application/xml-external-parsed-entity - application/xml-dtd).find {|x| x == normalized_mime_type} - return true - end - false - end - - # Returns true if the element contains inline content - # encoded in base64. - def inline_other_base64? - inline_other? and !inline_other_text? and !inline_other_xml? - end - - # Returns true if the element contains linked content. - def out_of_line? - not @src.nil? - end - - # Splits the type attribute into an array, e.g. ["text", "xml"] - def mime_split - media_type = subtype = nil - if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/i =~ @type.to_s - media_type = $1.downcase - subtype = $2.downcase - end - [media_type, subtype] - end - - # Returns true if the content needs to be encoded in base64. - def need_base64_encode? - inline_other_base64? - end - - private - def empty_content? - out_of_line? or super - end - end - - # Feed::Contributor - Contributor = Feed::Contributor - # Feed::Id - Id = Feed::Id - # Feed::Link - Link = Feed::Link - - # DateConstruct that usually indicates the time of the initial - # creation of an Entry. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.published - class Published < RSS::Element - include CommonModel - include DateConstruct - end - - # Feed::Rights - Rights = Feed::Rights - - # Defines a Atom Source element. It has the following attributes: - # - # * author - # * category - # * categories - # * content - # * contributor - # * generator - # * icon - # * id - # * link - # * logo - # * rights - # * subtitle - # * title - # * updated - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.source - class Source < RSS::Element - include CommonModel - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["contributor", "*", :children], - ["generator", "?"], - ["icon", "?"], - ["id", "?", nil, :content], - ["link", "*", :children], - ["logo", "?"], - ["rights", "?"], - ["subtitle", "?"], - ["title", "?"], - ["updated", "?", nil, :content], - ].each do |tag, occurs, type, *args| - type ||= :attribute - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - # Returns true if the Source element has an author. - def have_author? - !author.to_s.empty? - end - - # Feed::Author - Author = Feed::Author - # Feed::Category - Category = Feed::Category - # Feed::Contributor - Contributor = Feed::Contributor - # Feed::Generator - Generator = Feed::Generator - # Feed::Icon - Icon = Feed::Icon - # Feed::Id - Id = Feed::Id - # Feed::Link - Link = Feed::Link - # Feed::Logo - Logo = Feed::Logo - # Feed::Rights - Rights = Feed::Rights - # Feed::Subtitle - Subtitle = Feed::Subtitle - # Feed::Title - Title = Feed::Title - # Feed::Updated - Updated = Feed::Updated - end - - # TextConstruct that describes a summary of the Entry. - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.summary - class Summary < RSS::Element - include CommonModel - include TextConstruct - end - - # Feed::Title - Title = Feed::Title - # Feed::Updated - Updated = Feed::Updated - end - end - - # Defines a top-level Atom Entry element, - # used as the document element of a stand-alone Atom Entry Document. - # It has the following attributes: - # - # * author - # * category - # * categories - # * content - # * contributor - # * id - # * link - # * published - # * rights - # * source - # * summary - # * title - # * updated - # - # Reference: https://validator.w3.org/feed/docs/rfc4287.html#element.entry] - class Entry < RSS::Element - include RootElementMixin - include CommonModel - include DuplicateLinkChecker - - [ - ["author", "*", :children], - ["category", "*", :children, "categories"], - ["content", "?"], - ["contributor", "*", :children], - ["id", nil, nil, :content], - ["link", "*", :children], - ["published", "?", :child, :content], - ["rights", "?"], - ["source", "?"], - ["summary", "?"], - ["title", nil], - ["updated", nil, nil, :content], - ].each do |tag, occurs, type, *args| - type ||= :attribute - __send__("install_have_#{type}_element", - tag, URI, occurs, tag, *args) - end - - # Creates a new Atom Entry element. - def initialize(version=nil, encoding=nil, standalone=nil) - super("1.0", version, encoding, standalone) - @feed_type = "atom" - @feed_subtype = "entry" - end - - # Returns the Entry in an array. - def items - [self] - end - - # Sets up the +maker+ for constructing Entry elements. - def setup_maker(maker) - maker = maker.maker if maker.respond_to?("maker") - super(maker) - end - - # Returns where there are any authors present or there is a - # source with an author. - def have_author? - authors.any? {|author| !author.to_s.empty?} or - (source and source.have_author?) - end - - private - def atom_validate(ignore_unknown_element, tags, uri) - unless have_author? - raise MissingTagError.new("author", tag_name) - end - validate_duplicate_links(links) - end - - def have_required_elements? - super and have_author? - end - - def maker_target(maker) - maker.items.new_item - end - - # Feed::Entry::Author - Author = Feed::Entry::Author - # Feed::Entry::Category - Category = Feed::Entry::Category - # Feed::Entry::Content - Content = Feed::Entry::Content - # Feed::Entry::Contributor - Contributor = Feed::Entry::Contributor - # Feed::Entry::Id - Id = Feed::Entry::Id - # Feed::Entry::Link - Link = Feed::Entry::Link - # Feed::Entry::Published - Published = Feed::Entry::Published - # Feed::Entry::Rights - Rights = Feed::Entry::Rights - # Feed::Entry::Source - Source = Feed::Entry::Source - # Feed::Entry::Summary - Summary = Feed::Entry::Summary - # Feed::Entry::Title - Title = Feed::Entry::Title - # Feed::Entry::Updated - Updated = Feed::Entry::Updated - end - end - - Atom::CommonModel::ELEMENTS.each do |name| - BaseListener.install_get_text_element(Atom::URI, name, "#{name}=") - end - - module ListenerMixin - private - def initial_start_feed(tag_name, prefix, attrs, ns) - check_ns(tag_name, prefix, ns, Atom::URI, false) - - @rss = Atom::Feed.new(@version, @encoding, @standalone) - @rss.do_validate = @do_validate - @rss.xml_stylesheets = @xml_stylesheets - @rss.lang = attrs["xml:lang"] - @rss.base = attrs["xml:base"] - @last_element = @rss - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags) if @do_validate - end - @proc_stack.push(pr) - end - - def initial_start_entry(tag_name, prefix, attrs, ns) - check_ns(tag_name, prefix, ns, Atom::URI, false) - - @rss = Atom::Entry.new(@version, @encoding, @standalone) - @rss.do_validate = @do_validate - @rss.xml_stylesheets = @xml_stylesheets - @rss.lang = attrs["xml:lang"] - @rss.base = attrs["xml:base"] - @last_element = @rss - pr = Proc.new do |text, tags| - @rss.validate_for_stream(tags) if @do_validate - end - @proc_stack.push(pr) - end - end -end diff --git a/lib/rss/content.rb b/lib/rss/content.rb deleted file mode 100644 index 78c18d103c..0000000000 --- a/lib/rss/content.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: false -require_relative "rss" - -module RSS - # The prefix for the Content XML namespace. - CONTENT_PREFIX = 'content' - # The URI of the Content specification. - CONTENT_URI = "http://purl.org/rss/1.0/modules/content/" - - module ContentModel - extend BaseModel - - ELEMENTS = ["#{CONTENT_PREFIX}_encoded"] - - def self.append_features(klass) - super - - klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI) - ELEMENTS.each do |full_name| - name = full_name[(CONTENT_PREFIX.size + 1)..-1] - klass.install_text_element(name, CONTENT_URI, "?", full_name) - end - end - end - - prefix_size = CONTENT_PREFIX.size + 1 - ContentModel::ELEMENTS.each do |full_name| - name = full_name[prefix_size..-1] - BaseListener.install_get_text_element(CONTENT_URI, name, full_name) - end -end - -require 'rss/content/1.0' -require 'rss/content/2.0' diff --git a/lib/rss/content/1.0.rb b/lib/rss/content/1.0.rb deleted file mode 100644 index 1367dfe092..0000000000 --- a/lib/rss/content/1.0.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: false -require 'rss/1.0' - -module RSS - RDF.install_ns(CONTENT_PREFIX, CONTENT_URI) - - class RDF - class Item; include ContentModel; end - end -end diff --git a/lib/rss/content/2.0.rb b/lib/rss/content/2.0.rb deleted file mode 100644 index 3b468248ac..0000000000 --- a/lib/rss/content/2.0.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: false -require "rss/2.0" - -module RSS - Rss.install_ns(CONTENT_PREFIX, CONTENT_URI) - - class Rss - class Channel - class Item; include ContentModel; end - end - end -end diff --git a/lib/rss/converter.rb b/lib/rss/converter.rb deleted file mode 100644 index d372e06725..0000000000 --- a/lib/rss/converter.rb +++ /dev/null @@ -1,171 +0,0 @@ -# frozen_string_literal: false -require_relative "utils" - -module RSS - - class Converter - - include Utils - - def initialize(to_enc, from_enc=nil) - if "".respond_to?(:encode) - @to_encoding = to_enc - return - end - normalized_to_enc = to_enc.downcase.gsub(/-/, '_') - from_enc ||= 'utf-8' - normalized_from_enc = from_enc.downcase.gsub(/-/, '_') - if normalized_to_enc == normalized_from_enc - def_same_enc() - else - def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}" - if respond_to?(def_diff_enc) - __send__(def_diff_enc) - else - def_else_enc(to_enc, from_enc) - end - end - end - - def convert(value) - if value.is_a?(String) and value.respond_to?(:encode) - value.encode(@to_encoding) - else - value - end - end - - def def_convert(depth=0) - instance_eval(<<-EOC, *get_file_and_line_from_caller(depth)) - def convert(value) - if value.kind_of?(String) - #{yield('value')} - else - value - end - end - EOC - end - - def def_iconv_convert(to_enc, from_enc, depth=0) - begin - require "iconv" - @iconv = Iconv.new(to_enc, from_enc) - def_convert(depth+1) do |value| - <<-EOC - begin - @iconv.iconv(#{value}) - rescue Iconv::Failure - raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}") - end - EOC - end - rescue LoadError, ArgumentError, SystemCallError - raise UnknownConversionMethodError.new(to_enc, from_enc) - end - end - - def def_else_enc(to_enc, from_enc) - def_iconv_convert(to_enc, from_enc, 0) - end - - def def_same_enc() - def_convert do |value| - value - end - end - - def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg) - begin - require "uconv" - def_convert(1) do |value| - <<-EOC - begin - Uconv.#{meth}(#{value}) - rescue Uconv::Error - raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}") - end - EOC - end - rescue LoadError - require 'nkf' - if NKF.const_defined?(:UTF8) - def_convert(1) do |value| - "NKF.nkf(#{nkf_arg.dump}, #{value})" - end - else - def_iconv_convert(to_enc, from_enc, 1) - end - end - end - - def def_to_euc_jp_from_utf_8 - def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We') - end - - def def_to_utf_8_from_euc_jp - def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew') - end - - def def_to_shift_jis_from_utf_8 - def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws') - end - - def def_to_utf_8_from_shift_jis - def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw') - end - - def def_to_euc_jp_from_shift_jis - require "nkf" - def_convert do |value| - "NKF.nkf('-Se', #{value})" - end - end - - def def_to_shift_jis_from_euc_jp - require "nkf" - def_convert do |value| - "NKF.nkf('-Es', #{value})" - end - end - - def def_to_euc_jp_from_iso_2022_jp - require "nkf" - def_convert do |value| - "NKF.nkf('-Je', #{value})" - end - end - - def def_to_iso_2022_jp_from_euc_jp - require "nkf" - def_convert do |value| - "NKF.nkf('-Ej', #{value})" - end - end - - def def_to_utf_8_from_iso_8859_1 - def_convert do |value| - "#{value}.unpack('C*').pack('U*')" - end - end - - def def_to_iso_8859_1_from_utf_8 - def_convert do |value| - <<-EOC - array_utf8 = #{value}.unpack('U*') - array_enc = [] - array_utf8.each do |num| - if num <= 0xFF - array_enc << num - else - array_enc.concat "&\#\#{num};".unpack('C*') - end - end - array_enc.pack('C*') - EOC - end - end - - end - -end diff --git a/lib/rss/dublincore.rb b/lib/rss/dublincore.rb deleted file mode 100644 index 85b836d3bf..0000000000 --- a/lib/rss/dublincore.rb +++ /dev/null @@ -1,164 +0,0 @@ -# frozen_string_literal: false -require_relative "rss" - -module RSS - # The prefix for the Dublin Core XML namespace. - DC_PREFIX = 'dc' - # The URI of the Dublin Core specification. - DC_URI = "http://purl.org/dc/elements/1.1/" - - module BaseDublinCoreModel - def append_features(klass) - super - - return if klass.instance_of?(Module) - DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| - plural = plural_name || "#{name}s" - full_name = "#{DC_PREFIX}_#{name}" - full_plural_name = "#{DC_PREFIX}_#{plural}" - klass_name = "DublinCore#{Utils.to_class_name(name)}" - klass.install_must_call_validator(DC_PREFIX, DC_URI) - klass.install_have_children_element(name, DC_URI, "*", - full_name, full_plural_name) - klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0)) - remove_method :#{full_name} - remove_method :#{full_name}= - remove_method :set_#{full_name} - - def #{full_name} - @#{full_name}.first and @#{full_name}.first.value - end - - def #{full_name}=(new_value) - @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value) - end - alias set_#{full_name} #{full_name}= - EOC - end - klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0)) - if method_defined?(:date) - alias date_without_#{DC_PREFIX}_date= date= - - def date=(value) - self.date_without_#{DC_PREFIX}_date = value - self.#{DC_PREFIX}_date = value - end - else - alias date #{DC_PREFIX}_date - alias date= #{DC_PREFIX}_date= - end - - # For backward compatibility - alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list - EOC - end - end - - module DublinCoreModel - - extend BaseModel - extend BaseDublinCoreModel - - TEXT_ELEMENTS = { - "title" => nil, - "description" => nil, - "creator" => nil, - "subject" => nil, - "publisher" => nil, - "contributor" => nil, - "type" => nil, - "format" => nil, - "identifier" => nil, - "source" => nil, - "language" => nil, - "relation" => nil, - "coverage" => nil, - "rights" => "rights_list" - } - - DATE_ELEMENTS = { - "date" => "w3cdtf", - } - - ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a - DublinCoreModel::DATE_ELEMENTS.each do |name, | - ELEMENT_NAME_INFOS << [name, nil] - end - - ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys - - ELEMENTS.each do |name, plural_name| - module_eval(<<-EOC, *get_file_and_line_from_caller(0)) - class DublinCore#{Utils.to_class_name(name)} < Element - include RSS10 - - content_setup - - class << self - def required_prefix - DC_PREFIX - end - - def required_uri - DC_URI - end - end - - @tag_name = #{name.dump} - - alias_method(:value, :content) - alias_method(:value=, :content=) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.content = args[0] - end - end - - def full_name - tag_name_with_prefix(DC_PREFIX) - end - - def maker_target(target) - target.new_#{name} - end - - def setup_maker_attributes(#{name}) - #{name}.content = content - end - end - EOC - end - - DATE_ELEMENTS.each do |name, type| - tag_name = "#{DC_PREFIX}:#{name}" - module_eval(<<-EOC, *get_file_and_line_from_caller(0)) - class DublinCore#{Utils.to_class_name(name)} < Element - remove_method(:content=) - remove_method(:value=) - - date_writer("content", #{type.dump}, #{tag_name.dump}) - - alias_method(:value=, :content=) - end - EOC - end - end - - # For backward compatibility - DublincoreModel = DublinCoreModel - - DublinCoreModel::ELEMENTS.each do |name| - class_name = Utils.to_class_name(name) - BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}") - end - - DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"} -end - -require 'rss/dublincore/1.0' -require 'rss/dublincore/2.0' -require_relative 'dublincore/atom' diff --git a/lib/rss/dublincore/1.0.rb b/lib/rss/dublincore/1.0.rb deleted file mode 100644 index 1d96fab9b9..0000000000 --- a/lib/rss/dublincore/1.0.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: false -require "rss/1.0" - -module RSS - RDF.install_ns(DC_PREFIX, DC_URI) - - class RDF - class Channel; include DublinCoreModel; end - class Image; include DublinCoreModel; end - class Item; include DublinCoreModel; end - class Textinput; include DublinCoreModel; end - end -end diff --git a/lib/rss/dublincore/2.0.rb b/lib/rss/dublincore/2.0.rb deleted file mode 100644 index e3011fef6a..0000000000 --- a/lib/rss/dublincore/2.0.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: false -require "rss/2.0" - -module RSS - Rss.install_ns(DC_PREFIX, DC_URI) - - class Rss - class Channel - include DublinCoreModel - class Item; include DublinCoreModel; end - end - end -end diff --git a/lib/rss/dublincore/atom.rb b/lib/rss/dublincore/atom.rb deleted file mode 100644 index 1cfcdec677..0000000000 --- a/lib/rss/dublincore/atom.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: false -require_relative "../atom" - -module RSS - module Atom - Feed.install_ns(DC_PREFIX, DC_URI) - - class Feed - include DublinCoreModel - class Entry; include DublinCoreModel; end - end - - class Entry - include DublinCoreModel - end - end -end diff --git a/lib/rss/image.rb b/lib/rss/image.rb deleted file mode 100644 index 837f7d18f4..0000000000 --- a/lib/rss/image.rb +++ /dev/null @@ -1,198 +0,0 @@ -# frozen_string_literal: false -require 'rss/1.0' -require_relative 'dublincore' - -module RSS - - # The prefix for the Image XML namespace. - IMAGE_PREFIX = 'image' - # The URI for the Image specification. - IMAGE_URI = 'http://purl.org/rss/1.0/modules/image/' - - RDF.install_ns(IMAGE_PREFIX, IMAGE_URI) - - # This constant holds strings which contain the names of - # image elements, with the appropriate prefix. - IMAGE_ELEMENTS = [] - - %w(item favicon).each do |name| - class_name = Utils.to_class_name(name) - BaseListener.install_class_name(IMAGE_URI, name, "Image#{class_name}") - IMAGE_ELEMENTS << "#{IMAGE_PREFIX}_#{name}" - end - - module ImageModelUtils - def validate_one_tag_name(ignore_unknown_element, name, tags) - if !ignore_unknown_element - invalid = tags.find {|tag| tag != name} - raise UnknownTagError.new(invalid, IMAGE_URI) if invalid - end - raise TooMuchTagError.new(name, tag_name) if tags.size > 1 - end - end - - module ImageItemModel - include ImageModelUtils - extend BaseModel - - def self.append_features(klass) - super - - klass.install_have_child_element("item", IMAGE_URI, "?", - "#{IMAGE_PREFIX}_item") - klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI) - end - - class ImageItem < Element - include RSS10 - include DublinCoreModel - - @tag_name = "item" - - class << self - def required_prefix - IMAGE_PREFIX - end - - def required_uri - IMAGE_URI - end - end - - install_must_call_validator(IMAGE_PREFIX, IMAGE_URI) - - [ - ["about", ::RSS::RDF::URI, true], - ["resource", ::RSS::RDF::URI, false], - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{::RSS::RDF::PREFIX}:#{name}") - end - - %w(width height).each do |tag| - full_name = "#{IMAGE_PREFIX}_#{tag}" - disp_name = "#{IMAGE_PREFIX}:#{tag}" - install_text_element(tag, IMAGE_URI, "?", - full_name, :integer, disp_name) - BaseListener.install_get_text_element(IMAGE_URI, tag, full_name) - end - - alias width= image_width= - alias width image_width - alias height= image_height= - alias height image_height - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - self.resource = args[1] - end - end - - def full_name - tag_name_with_prefix(IMAGE_PREFIX) - end - - private - def maker_target(target) - target.image_item - end - - def setup_maker_attributes(item) - item.about = self.about - item.resource = self.resource - end - end - end - - module ImageFaviconModel - include ImageModelUtils - extend BaseModel - - def self.append_features(klass) - super - - unless klass.class == Module - klass.install_have_child_element("favicon", IMAGE_URI, "?", - "#{IMAGE_PREFIX}_favicon") - klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI) - end - end - - class ImageFavicon < Element - include RSS10 - include DublinCoreModel - - @tag_name = "favicon" - - class << self - def required_prefix - IMAGE_PREFIX - end - - def required_uri - IMAGE_URI - end - end - - [ - ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX], - ["size", IMAGE_URI, true, IMAGE_PREFIX], - ].each do |name, uri, required, prefix| - install_get_attribute(name, uri, required, nil, nil, - "#{prefix}:#{name}") - end - - AVAILABLE_SIZES = %w(small medium large) - alias_method :set_size, :size= - private :set_size - def size=(new_value) - if @do_validate and !new_value.nil? - new_value = new_value.strip - unless AVAILABLE_SIZES.include?(new_value) - attr_name = "#{IMAGE_PREFIX}:size" - raise NotAvailableValueError.new(full_name, new_value, attr_name) - end - end - set_size(new_value) - end - - alias image_size= size= - alias image_size size - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - self.size = args[1] - end - end - - def full_name - tag_name_with_prefix(IMAGE_PREFIX) - end - - private - def maker_target(target) - target.image_favicon - end - - def setup_maker_attributes(favicon) - favicon.about = self.about - favicon.size = self.size - end - end - - end - - class RDF - class Channel; include ImageFaviconModel; end - class Item; include ImageItemModel; end - end - -end diff --git a/lib/rss/itunes.rb b/lib/rss/itunes.rb deleted file mode 100644 index bc3e25448a..0000000000 --- a/lib/rss/itunes.rb +++ /dev/null @@ -1,425 +0,0 @@ -# frozen_string_literal: false -require 'rss/2.0' - -module RSS - # The prefix for the iTunes XML namespace. - ITUNES_PREFIX = 'itunes' - # The URI of the iTunes specification. - ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd' - - Rss.install_ns(ITUNES_PREFIX, ITUNES_URI) - - module ITunesModelUtils - include Utils - - def def_class_accessor(klass, name, type, *args) - normalized_name = name.gsub(/-/, "_") - full_name = "#{ITUNES_PREFIX}_#{normalized_name}" - klass_name = "ITunes#{Utils.to_class_name(normalized_name)}" - - case type - when :element, :attribute - klass::ELEMENTS << full_name - def_element_class_accessor(klass, name, full_name, klass_name, *args) - when :elements - klass::ELEMENTS << full_name - def_elements_class_accessor(klass, name, full_name, klass_name, *args) - else - klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI) - klass.install_text_element(normalized_name, ITUNES_URI, "?", - full_name, type, name) - end - end - - def def_element_class_accessor(klass, name, full_name, klass_name, - recommended_attribute_name=nil) - klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name) - end - - def def_elements_class_accessor(klass, name, full_name, klass_name, - plural_name, recommended_attribute_name=nil) - full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}" - klass.install_have_children_element(name, ITUNES_PREFIX, "*", - full_name, full_plural_name) - end - end - - module ITunesBaseModel - extend ITunesModelUtils - - ELEMENTS = [] - - ELEMENT_INFOS = [["author"], - ["block", :yes_other], - ["explicit", :explicit_clean_other], - ["keywords", :csv], - ["subtitle"], - ["summary"]] - end - - module ITunesChannelModel - extend BaseModel - extend ITunesModelUtils - include ITunesBaseModel - - ELEMENTS = [] - - class << self - def append_features(klass) - super - - return if klass.instance_of?(Module) - ELEMENT_INFOS.each do |name, type, *additional_infos| - def_class_accessor(klass, name, type, *additional_infos) - end - end - end - - ELEMENT_INFOS = [ - ["category", :elements, "categories", "text"], - ["image", :attribute, "href"], - ["owner", :element], - ["new-feed-url"], - ] + ITunesBaseModel::ELEMENT_INFOS - - class ITunesCategory < Element - include RSS09 - - @tag_name = "category" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - end - - [ - ["text", "", true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required) - end - - ITunesCategory = self - install_have_children_element("category", ITUNES_URI, "*", - "#{ITUNES_PREFIX}_category", - "#{ITUNES_PREFIX}_categories") - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.text = args[0] - end - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def maker_target(categories) - if text or !itunes_categories.empty? - categories.new_category - else - nil - end - end - - def setup_maker_attributes(category) - category.text = text if text - end - - def setup_maker_elements(category) - super(category) - itunes_categories.each do |sub_category| - sub_category.setup_maker(category) - end - end - end - - class ITunesImage < Element - include RSS09 - - @tag_name = "image" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - end - - [ - ["href", "", true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required) - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.href = args[0] - end - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def maker_target(target) - if href - target.itunes_image {|image| image} - else - nil - end - end - - def setup_maker_attributes(image) - image.href = href - end - end - - class ITunesOwner < Element - include RSS09 - - @tag_name = "owner" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - end - - install_must_call_validator(ITUNES_PREFIX, ITUNES_URI) - [ - ["name"], - ["email"], - ].each do |name,| - ITunesBaseModel::ELEMENT_INFOS << name - install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}") - end - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.itunes_name = args[0] - self.itunes_email = args[1] - end - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def maker_target(target) - target.itunes_owner - end - - def setup_maker_element(owner) - super(owner) - owner.itunes_name = itunes_name - owner.itunes_email = itunes_email - end - end - end - - module ITunesItemModel - extend BaseModel - extend ITunesModelUtils - include ITunesBaseModel - - class << self - def append_features(klass) - super - - return if klass.instance_of?(Module) - ELEMENT_INFOS.each do |name, type| - def_class_accessor(klass, name, type) - end - end - end - - ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS + - [["duration", :element, "content"]] - - class ITunesDuration < Element - include RSS09 - - @tag_name = "duration" - - class << self - def required_prefix - ITUNES_PREFIX - end - - def required_uri - ITUNES_URI - end - - def parse(duration, do_validate=true) - if do_validate and /\A(?: - \d?\d:[0-5]\d:[0-5]\d| - [0-5]?\d:[0-5]\d| - \d+ - )\z/x !~ duration - raise ArgumentError, - "must be one of HH:MM:SS, H:MM:SS, MM:SS, M:SS, S+: " + - duration.inspect - end - - if duration.include?(':') - components = duration.split(':') - components[3..-1] = nil if components.size > 3 - - components.unshift("00") until components.size == 3 - components.collect do |component| - component.to_i - end - else - seconds_to_components(duration.to_i) - end - end - - def construct(hours, minutes, seconds) - components = [minutes, seconds] - if components.include?(nil) - nil - else - components.unshift(hours) if hours and hours > 0 - components.collect do |component| - "%02d" % component - end.join(':') - end - end - - private - def seconds_to_components(total_seconds) - hours = total_seconds / (60 * 60) - minutes = (total_seconds / 60) % 60 - seconds = total_seconds % 60 - [hours, minutes, seconds] - end - end - - content_setup - alias_method(:value, :content) - remove_method(:content=) - - attr_reader :hour, :minute, :second - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - args = args[0] if args.size == 1 and args[0].is_a?(Array) - if args.size == 1 - self.content = args[0] - elsif args.size > 3 - raise ArgumentError, - "must be (do_validate, params), (content), " + - "(minute, second), ([minute, second]), " + - "(hour, minute, second) or ([hour, minute, second]): " + - args.inspect - else - @second, @minute, @hour = args.reverse - update_content - end - end - end - - def content=(value) - if value.nil? - @content = nil - elsif value.is_a?(self.class) - self.content = value.content - else - begin - @hour, @minute, @second = self.class.parse(value, @do_validate) - rescue ArgumentError - raise NotAvailableValueError.new(tag_name, value) - end - @content = value - end - end - alias_method(:value=, :content=) - - def hour=(hour) - @hour = @do_validate ? Integer(hour) : hour.to_i - update_content - hour - end - - def minute=(minute) - @minute = @do_validate ? Integer(minute) : minute.to_i - update_content - minute - end - - def second=(second) - @second = @do_validate ? Integer(second) : second.to_i - update_content - second - end - - def full_name - tag_name_with_prefix(ITUNES_PREFIX) - end - - private - def update_content - @content = self.class.construct(hour, minute, second) - end - - def maker_target(target) - if @content - target.itunes_duration {|duration| duration} - else - nil - end - end - - def setup_maker_element(duration) - super(duration) - duration.content = @content - end - end - end - - class Rss - class Channel - include ITunesChannelModel - class Item; include ITunesItemModel; end - end - end - - element_infos = - ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS - element_infos.each do |name, type| - case type - when :element, :elements, :attribute - class_name = Utils.to_class_name(name) - BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}") - else - accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}" - BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base) - end - end -end diff --git a/lib/rss/maker.rb b/lib/rss/maker.rb deleted file mode 100644 index e32de81806..0000000000 --- a/lib/rss/maker.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: false -require_relative "rss" - -module RSS - ## - # - # Provides a set of builders for various RSS objects - # - # * Feeds - # * RSS 0.91 - # * RSS 1.0 - # * RSS 2.0 - # * Atom 1.0 - # - # * Elements - # * Atom::Entry - - module Maker - - # Collection of supported makers - MAKERS = {} - - class << self - # Builder for an RSS object - # Creates an object of the type passed in +args+ - # - # Executes the +block+ to populate elements of the created RSS object - def make(version, &block) - self[version].make(&block) - end - - # Returns the maker for the +version+ - def [](version) - maker_info = maker(version) - raise UnsupportedMakerVersionError.new(version) if maker_info.nil? - maker_info[:maker] - end - - # Adds a maker to the set of supported makers - def add_maker(version, normalized_version, maker) - MAKERS[version] = {:maker => maker, :version => normalized_version} - end - - # Returns collection of supported maker versions - def versions - MAKERS.keys.uniq.sort - end - - # Returns collection of supported makers - def makers - MAKERS.values.collect { |info| info[:maker] }.uniq - end - - # Returns true if the version is supported - def supported?(version) - versions.include?(version) - end - - private - # Can I remove this method? - def maker(version) - MAKERS[version] - end - end - end -end - -require_relative "maker/1.0" -require_relative "maker/2.0" -require_relative "maker/feed" -require_relative "maker/entry" -require_relative "maker/content" -require_relative "maker/dublincore" -require_relative "maker/slash" -require_relative "maker/syndication" -require_relative "maker/taxonomy" -require_relative "maker/trackback" -require_relative "maker/image" -require_relative "maker/itunes" diff --git a/lib/rss/maker/0.9.rb b/lib/rss/maker/0.9.rb deleted file mode 100644 index eb35fc14e1..0000000000 --- a/lib/rss/maker/0.9.rb +++ /dev/null @@ -1,509 +0,0 @@ -# frozen_string_literal: false -require_relative "../0.9" - -require_relative "base" - -module RSS - module Maker - - class RSS09 < RSSBase - - def initialize(feed_version) - super - @feed_type = "rss" - end - - private - def make_feed - Rss.new(@feed_version, @version, @encoding, @standalone) - end - - def setup_elements(rss) - setup_channel(rss) - end - - class Channel < ChannelBase - def to_feed(rss) - channel = Rss::Channel.new - setup_values(channel) - _not_set_required_variables = not_set_required_variables - if _not_set_required_variables.empty? - rss.channel = channel - set_parent(channel, rss) - setup_items(rss) - setup_image(rss) - setup_textinput(rss) - setup_other_elements(rss, channel) - rss - else - raise NotSetError.new("maker.channel", _not_set_required_variables) - end - end - - private - def setup_items(rss) - @maker.items.to_feed(rss) - end - - def setup_image(rss) - @maker.image.to_feed(rss) - end - - def setup_textinput(rss) - @maker.textinput.to_feed(rss) - end - - def variables - super + ["pubDate"] - end - - def required_variable_names - %w(link language) - end - - def not_set_required_variables - vars = super - vars << "description" unless description {|d| d.have_required_values?} - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - class SkipDays < SkipDaysBase - def to_feed(rss, channel) - unless @days.empty? - skipDays = Rss::Channel::SkipDays.new - channel.skipDays = skipDays - set_parent(skipDays, channel) - @days.each do |day| - day.to_feed(rss, skipDays.days) - end - end - end - - class Day < DayBase - def to_feed(rss, days) - day = Rss::Channel::SkipDays::Day.new - set = setup_values(day) - if set - days << day - set_parent(day, days) - setup_other_elements(rss, day) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class SkipHours < SkipHoursBase - def to_feed(rss, channel) - unless @hours.empty? - skipHours = Rss::Channel::SkipHours.new - channel.skipHours = skipHours - set_parent(skipHours, channel) - @hours.each do |hour| - hour.to_feed(rss, skipHours.hours) - end - end - end - - class Hour < HourBase - def to_feed(rss, hours) - hour = Rss::Channel::SkipHours::Hour.new - set = setup_values(hour) - if set - hours << hour - set_parent(hour, hours) - setup_other_elements(rss, hour) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class Cloud < CloudBase - def to_feed(*args) - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Links < LinksBase - def to_feed(rss, channel) - return if @links.empty? - @links.first.to_feed(rss, channel) - end - - class Link < LinkBase - def to_feed(rss, channel) - if have_required_values? - channel.link = href - else - raise NotSetError.new("maker.channel.link", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - end - - class Authors < AuthorsBase - def to_feed(rss, channel) - end - - class Author < AuthorBase - def to_feed(rss, channel) - end - end - end - - class Contributors < ContributorsBase - def to_feed(rss, channel) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(rss, channel) - end - end - - class Copyright < CopyrightBase - def to_feed(rss, channel) - channel.copyright = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Description < DescriptionBase - def to_feed(rss, channel) - channel.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Title < TitleBase - def to_feed(rss, channel) - channel.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - - class Image < ImageBase - def to_feed(rss) - image = Rss::Channel::Image.new - set = setup_values(image) - if set - image.link = link - rss.channel.image = image - set_parent(image, rss.channel) - setup_other_elements(rss, image) - elsif required_element? - raise NotSetError.new("maker.image", not_set_required_variables) - end - end - - private - def required_variable_names - %w(url title link) - end - - def required_element? - true - end - end - - class Items < ItemsBase - def to_feed(rss) - if rss.channel - normalize.each do |item| - item.to_feed(rss) - end - setup_other_elements(rss, rss.items) - end - end - - class Item < ItemBase - def to_feed(rss) - item = Rss::Channel::Item.new - setup_values(item) - _not_set_required_variables = not_set_required_variables - if _not_set_required_variables.empty? - rss.items << item - set_parent(item, rss.channel) - setup_other_elements(rss, item) - elsif variable_is_set? - raise NotSetError.new("maker.items", _not_set_required_variables) - end - end - - private - def required_variable_names - [] - end - - def not_set_required_variables - vars = super - if @maker.feed_version == "0.91" - vars << "title" unless title {|t| t.have_required_values?} - vars << "link" unless link - end - vars - end - - class Guid < GuidBase - def to_feed(*args) - end - end - - class Enclosure < EnclosureBase - def to_feed(*args) - end - end - - class Source < SourceBase - def to_feed(*args) - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Contributors < ContributorsBase - def to_feed(*args) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(*args) - end - end - - class Icon < IconBase - def to_feed(*args) - end - end - - class Links < LinksBase - def to_feed(*args) - end - - class Link < LinkBase - end - end - - class Logo < LogoBase - def to_feed(*args) - end - end - - class Rights < RightsBase - def to_feed(*args) - end - end - - class Subtitle < SubtitleBase - def to_feed(*args) - end - end - - class Title < TitleBase - def to_feed(*args) - end - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Links < LinksBase - def to_feed(rss, item) - return if @links.empty? - @links.first.to_feed(rss, item) - end - - class Link < LinkBase - def to_feed(rss, item) - if have_required_values? - item.link = href - else - raise NotSetError.new("maker.link", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - end - - class Contributors < ContributorsBase - def to_feed(rss, item) - end - - class Contributor < ContributorBase - end - end - - class Rights < RightsBase - def to_feed(rss, item) - end - end - - class Description < DescriptionBase - def to_feed(rss, item) - item.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Content < ContentBase - def to_feed(rss, item) - end - end - - class Title < TitleBase - def to_feed(rss, item) - item.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - end - - class Textinput < TextinputBase - def to_feed(rss) - textInput = Rss::Channel::TextInput.new - set = setup_values(textInput) - if set - rss.channel.textInput = textInput - set_parent(textInput, rss.channel) - setup_other_elements(rss, textInput) - end - end - - private - def required_variable_names - %w(title description name link) - end - end - end - - class RSS091 < RSS09 - def initialize(feed_version="0.91") - super - end - - class Channel < RSS09::Channel - end - - class Items < RSS09::Items - class Item < RSS09::Items::Item - end - end - - class Image < RSS09::Image - end - - class Textinput < RSS09::Textinput - end - end - - class RSS092 < RSS09 - def initialize(feed_version="0.92") - super - end - - class Channel < RSS09::Channel - end - - class Items < RSS09::Items - class Item < RSS09::Items::Item - end - end - - class Image < RSS09::Image - end - - class Textinput < RSS09::Textinput - end - end - - add_maker("0.9", "0.92", RSS092) - add_maker("0.91", "0.91", RSS091) - add_maker("0.92", "0.92", RSS092) - add_maker("rss0.9", "0.92", RSS092) - add_maker("rss0.91", "0.91", RSS091) - add_maker("rss0.92", "0.92", RSS092) - end -end diff --git a/lib/rss/maker/1.0.rb b/lib/rss/maker/1.0.rb deleted file mode 100644 index 3934f9536c..0000000000 --- a/lib/rss/maker/1.0.rb +++ /dev/null @@ -1,436 +0,0 @@ -# frozen_string_literal: false -require_relative "../1.0" - -require_relative "base" - -module RSS - module Maker - - class RSS10 < RSSBase - - def initialize(feed_version="1.0") - super - @feed_type = "rss" - end - - private - def make_feed - RDF.new(@version, @encoding, @standalone) - end - - def setup_elements(rss) - setup_channel(rss) - setup_image(rss) - setup_items(rss) - setup_textinput(rss) - end - - class Channel < ChannelBase - include SetupDefaultLanguage - - def to_feed(rss) - set_default_values do - _not_set_required_variables = not_set_required_variables - if _not_set_required_variables.empty? - channel = RDF::Channel.new(@about) - setup_values(channel) - channel.dc_dates.clear - rss.channel = channel - set_parent(channel, rss) - setup_items(rss) - setup_image(rss) - setup_textinput(rss) - setup_other_elements(rss, channel) - else - raise NotSetError.new("maker.channel", _not_set_required_variables) - end - end - end - - private - def setup_items(rss) - items = RDF::Channel::Items.new - seq = items.Seq - set_parent(items, seq) - target_items = @maker.items.normalize - raise NotSetError.new("maker", ["items"]) if target_items.empty? - target_items.each do |item| - li = RDF::Channel::Items::Seq::Li.new(item.link) - seq.lis << li - set_parent(li, seq) - end - rss.channel.items = items - set_parent(rss.channel, items) - end - - def setup_image(rss) - if @maker.image.have_required_values? - image = RDF::Channel::Image.new(@maker.image.url) - rss.channel.image = image - set_parent(image, rss.channel) - end - end - - def setup_textinput(rss) - if @maker.textinput.have_required_values? - textinput = RDF::Channel::Textinput.new(@maker.textinput.link) - rss.channel.textinput = textinput - set_parent(textinput, rss.channel) - end - end - - def required_variable_names - %w(about link) - end - - def not_set_required_variables - vars = super - vars << "description" unless description {|d| d.have_required_values?} - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - class SkipDays < SkipDaysBase - def to_feed(*args) - end - - class Day < DayBase - end - end - - class SkipHours < SkipHoursBase - def to_feed(*args) - end - - class Hour < HourBase - end - end - - class Cloud < CloudBase - def to_feed(*args) - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Links < LinksBase - def to_feed(rss, channel) - return if @links.empty? - @links.first.to_feed(rss, channel) - end - - class Link < LinkBase - def to_feed(rss, channel) - if have_required_values? - channel.link = href - else - raise NotSetError.new("maker.channel.link", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - end - - class Authors < AuthorsBase - def to_feed(rss, channel) - end - - class Author < AuthorBase - def to_feed(rss, channel) - end - end - end - - class Contributors < ContributorsBase - def to_feed(rss, channel) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(rss, channel) - end - end - - class Copyright < CopyrightBase - def to_feed(rss, channel) - end - end - - class Description < DescriptionBase - def to_feed(rss, channel) - channel.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Title < TitleBase - def to_feed(rss, channel) - channel.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - - class Image < ImageBase - def to_feed(rss) - if @url - image = RDF::Image.new(@url) - set = setup_values(image) - if set - rss.image = image - set_parent(image, rss) - setup_other_elements(rss, image) - end - end - end - - def have_required_values? - super and @maker.channel.have_required_values? - end - - private - def variables - super + ["link"] - end - - def required_variable_names - %w(url title link) - end - end - - class Items < ItemsBase - def to_feed(rss) - if rss.channel - normalize.each do |item| - item.to_feed(rss) - end - setup_other_elements(rss, rss.items) - end - end - - class Item < ItemBase - def to_feed(rss) - set_default_values do - item = RDF::Item.new(link) - set = setup_values(item) - if set - item.dc_dates.clear - rss.items << item - set_parent(item, rss) - setup_other_elements(rss, item) - elsif !have_required_values? - raise NotSetError.new("maker.item", not_set_required_variables) - end - end - end - - private - def required_variable_names - %w(link) - end - - def variables - super + %w(link) - end - - def not_set_required_variables - set_default_values do - vars = super - vars << "title" unless title {|t| t.have_required_values?} - vars - end - end - - class Guid < GuidBase - def to_feed(*args) - end - end - - class Enclosure < EnclosureBase - def to_feed(*args) - end - end - - class Source < SourceBase - def to_feed(*args) - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Contributors < ContributorsBase - def to_feed(*args) - end - - class Contributor < ContributorBase - end - end - - class Generator < GeneratorBase - def to_feed(*args) - end - end - - class Icon < IconBase - def to_feed(*args) - end - end - - class Links < LinksBase - def to_feed(*args) - end - - class Link < LinkBase - end - end - - class Logo < LogoBase - def to_feed(*args) - end - end - - class Rights < RightsBase - def to_feed(*args) - end - end - - class Subtitle < SubtitleBase - def to_feed(*args) - end - end - - class Title < TitleBase - def to_feed(*args) - end - end - end - - class Categories < CategoriesBase - def to_feed(*args) - end - - class Category < CategoryBase - end - end - - class Authors < AuthorsBase - def to_feed(*args) - end - - class Author < AuthorBase - end - end - - class Links < LinksBase - def to_feed(*args) - end - - class Link < LinkBase - end - end - - class Contributors < ContributorsBase - def to_feed(rss, item) - end - - class Contributor < ContributorBase - end - end - - class Rights < RightsBase - def to_feed(rss, item) - end - end - - class Description < DescriptionBase - def to_feed(rss, item) - item.description = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - - class Content < ContentBase - def to_feed(rss, item) - end - end - - class Title < TitleBase - def to_feed(rss, item) - item.title = content if have_required_values? - end - - private - def required_variable_names - %w(content) - end - end - end - end - - class Textinput < TextinputBase - def to_feed(rss) - if @link - textinput = RDF::Textinput.new(@link) - set = setup_values(textinput) - if set - rss.textinput = textinput - set_parent(textinput, rss) - setup_other_elements(rss, textinput) - end - end - end - - def have_required_values? - super and @maker.channel.have_required_values? - end - - private - def required_variable_names - %w(title description name link) - end - end - end - - add_maker("1.0", "1.0", RSS10) - add_maker("rss1.0", "1.0", RSS10) - end -end diff --git a/lib/rss/maker/2.0.rb b/lib/rss/maker/2.0.rb deleted file mode 100644 index 43d00226b7..0000000000 --- a/lib/rss/maker/2.0.rb +++ /dev/null @@ -1,224 +0,0 @@ -# frozen_string_literal: false -require_relative "../2.0" - -require_relative "0.9" - -module RSS - module Maker - - class RSS20 < RSS09 - - def initialize(feed_version="2.0") - super - end - - class Channel < RSS09::Channel - - private - def required_variable_names - %w(link) - end - - class SkipDays < RSS09::Channel::SkipDays - class Day < RSS09::Channel::SkipDays::Day - end - end - - class SkipHours < RSS09::Channel::SkipHours - class Hour < RSS09::Channel::SkipHours::Hour - end - end - - class Cloud < RSS09::Channel::Cloud - def to_feed(rss, channel) - cloud = Rss::Channel::Cloud.new - set = setup_values(cloud) - if set - channel.cloud = cloud - set_parent(cloud, channel) - setup_other_elements(rss, cloud) - end - end - - private - def required_variable_names - %w(domain port path registerProcedure protocol) - end - end - - class Categories < RSS09::Channel::Categories - def to_feed(rss, channel) - @categories.each do |category| - category.to_feed(rss, channel) - end - end - - class Category < RSS09::Channel::Categories::Category - def to_feed(rss, channel) - category = Rss::Channel::Category.new - set = setup_values(category) - if set - channel.categories << category - set_parent(category, channel) - setup_other_elements(rss, category) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class Generator < GeneratorBase - def to_feed(rss, channel) - channel.generator = content - end - - private - def required_variable_names - %w(content) - end - end - end - - class Image < RSS09::Image - private - def required_element? - false - end - end - - class Items < RSS09::Items - class Item < RSS09::Items::Item - private - def required_variable_names - [] - end - - def not_set_required_variables - vars = super - if !title {|t| t.have_required_values?} and - !description {|d| d.have_required_values?} - vars << "title or description" - end - vars - end - - def variables - super + ["pubDate"] - end - - class Guid < RSS09::Items::Item::Guid - def to_feed(rss, item) - guid = Rss::Channel::Item::Guid.new - set = setup_values(guid) - if set - item.guid = guid - set_parent(guid, item) - setup_other_elements(rss, guid) - end - end - - private - def required_variable_names - %w(content) - end - end - - class Enclosure < RSS09::Items::Item::Enclosure - def to_feed(rss, item) - enclosure = Rss::Channel::Item::Enclosure.new - set = setup_values(enclosure) - if set - item.enclosure = enclosure - set_parent(enclosure, item) - setup_other_elements(rss, enclosure) - end - end - - private - def required_variable_names - %w(url length type) - end - end - - class Source < RSS09::Items::Item::Source - def to_feed(rss, item) - source = Rss::Channel::Item::Source.new - set = setup_values(source) - if set - item.source = source - set_parent(source, item) - setup_other_elements(rss, source) - end - end - - private - def required_variable_names - %w(url content) - end - - class Links < RSS09::Items::Item::Source::Links - def to_feed(rss, source) - return if @links.empty? - @links.first.to_feed(rss, source) - end - - class Link < RSS09::Items::Item::Source::Links::Link - def to_feed(rss, source) - source.url = href - end - end - end - end - - class Categories < RSS09::Items::Item::Categories - def to_feed(rss, item) - @categories.each do |category| - category.to_feed(rss, item) - end - end - - class Category < RSS09::Items::Item::Categories::Category - def to_feed(rss, item) - category = Rss::Channel::Item::Category.new - set = setup_values(category) - if set - item.categories << category - set_parent(category, item) - setup_other_elements(rss) - end - end - - private - def required_variable_names - %w(content) - end - end - end - - class Authors < RSS09::Items::Item::Authors - def to_feed(rss, item) - return if @authors.empty? - @authors.first.to_feed(rss, item) - end - - class Author < RSS09::Items::Item::Authors::Author - def to_feed(rss, item) - item.author = name - end - end - end - end - end - - class Textinput < RSS09::Textinput - end - end - - add_maker("2.0", "2.0", RSS20) - add_maker("rss2.0", "2.0", RSS20) - end -end diff --git a/lib/rss/maker/atom.rb b/lib/rss/maker/atom.rb deleted file mode 100644 index cdd1d8753e..0000000000 --- a/lib/rss/maker/atom.rb +++ /dev/null @@ -1,173 +0,0 @@ -# frozen_string_literal: false -require_relative "../atom" - -require_relative "base" - -module RSS - module Maker - module AtomPersons - module_function - def def_atom_persons(klass, name, maker_name, plural=nil) - plural ||= "#{name}s" - klass_name = Utils.to_class_name(name) - plural_klass_name = Utils.to_class_name(plural) - - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{plural_klass_name} < #{plural_klass_name}Base - class #{klass_name} < #{klass_name}Base - def to_feed(feed, current) - #{name} = feed.class::#{klass_name}.new - set = setup_values(#{name}) - unless set - raise NotSetError.new(#{maker_name.dump}, - not_set_required_variables) - end - current.#{plural} << #{name} - set_parent(#{name}, current) - setup_other_elements(#{name}) - end - - private - def required_variable_names - %w(name) - end - end - end -EOC - end - end - - module AtomTextConstruct - class << self - def def_atom_text_construct(klass, name, maker_name, klass_name=nil, - atom_klass_name=nil) - klass_name ||= Utils.to_class_name(name) - atom_klass_name ||= Utils.to_class_name(name) - - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{klass_name} < #{klass_name}Base - include #{self.name} - def to_feed(feed, current) - #{name} = current.class::#{atom_klass_name}.new - if setup_values(#{name}) - current.#{name} = #{name} - set_parent(#{name}, current) - setup_other_elements(feed) - elsif variable_is_set? - raise NotSetError.new(#{maker_name.dump}, - not_set_required_variables) - end - end - end - EOC - end - end - - private - def required_variable_names - if type == "xhtml" - %w(xml_content) - else - %w(content) - end - end - - def variables - if type == "xhtml" - super + %w(xhtml) - else - super - end - end - end - - module AtomCategory - def to_feed(feed, current) - category = feed.class::Category.new - set = setup_values(category) - if set - current.categories << category - set_parent(category, current) - setup_other_elements(feed) - else - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(term) - end - - def variables - super + ["term", "scheme"] - end - end - - module AtomLink - def to_feed(feed, current) - link = feed.class::Link.new - set = setup_values(link) - if set - current.links << link - set_parent(link, current) - setup_other_elements(feed) - else - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(href) - end - end - - module AtomGenerator - def to_feed(feed, current) - generator = current.class::Generator.new - if setup_values(generator) - current.generator = generator - set_parent(generator, current) - setup_other_elements(feed) - elsif variable_is_set? - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(content) - end - end - - module AtomLogo - def to_feed(feed, current) - logo = current.class::Logo.new - class << logo - alias_method(:uri=, :content=) - end - set = setup_values(logo) - class << logo - remove_method(:uri=) - end - if set - current.logo = logo - set_parent(logo, current) - setup_other_elements(feed) - elsif variable_is_set? - raise NotSetError.new(self.class.not_set_name, - not_set_required_variables) - end - end - - private - def required_variable_names - %w(uri) - end - end - end -end diff --git a/lib/rss/maker/base.rb b/lib/rss/maker/base.rb deleted file mode 100644 index 17537b7006..0000000000 --- a/lib/rss/maker/base.rb +++ /dev/null @@ -1,945 +0,0 @@ -# frozen_string_literal: false -require 'forwardable' - -require_relative '../rss' - -module RSS - module Maker - class Base - extend Utils::InheritedReader - - OTHER_ELEMENTS = [] - NEED_INITIALIZE_VARIABLES = [] - - class << self - def other_elements - inherited_array_reader("OTHER_ELEMENTS") - end - def need_initialize_variables - inherited_array_reader("NEED_INITIALIZE_VARIABLES") - end - - def inherited_base - ::RSS::Maker::Base - end - - def inherited(subclass) - subclass.const_set(:OTHER_ELEMENTS, []) - subclass.const_set(:NEED_INITIALIZE_VARIABLES, []) - end - - def add_other_element(variable_name) - self::OTHER_ELEMENTS << variable_name - end - - def add_need_initialize_variable(variable_name, init_value=nil, - &init_block) - init_value ||= init_block - self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value] - end - - def def_array_element(name, plural=nil, klass_name=nil) - include Enumerable - extend Forwardable - - plural ||= "#{name}s" - klass_name ||= Utils.to_class_name(name) - def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last) - def_delegators("@#{plural}", :push, :pop, :shift, :unshift) - def_delegators("@#{plural}", :each, :size, :empty?, :clear) - - add_need_initialize_variable(plural) {[]} - - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def new_#{name} - #{name} = self.class::#{klass_name}.new(@maker) - @#{plural} << #{name} - if block_given? - yield #{name} - else - #{name} - end - end - alias new_child new_#{name} - - def to_feed(*args) - @#{plural}.each do |#{name}| - #{name}.to_feed(*args) - end - end - - def replace(elements) - @#{plural}.replace(elements.to_a) - end - EOC - end - - def def_classed_element_without_accessor(name, class_name=nil) - class_name ||= Utils.to_class_name(name) - add_other_element(name) - add_need_initialize_variable(name) do |object| - object.send("make_#{name}") - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - private - def setup_#{name}(feed, current) - @#{name}.to_feed(feed, current) - end - - def make_#{name} - self.class::#{class_name}.new(@maker) - end - EOC - end - - def def_classed_element(name, class_name=nil, attribute_name=nil) - def_classed_element_without_accessor(name, class_name) - if attribute_name - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name} - if block_given? - yield(@#{name}) - else - @#{name}.#{attribute_name} - end - end - - def #{name}=(new_value) - @#{name}.#{attribute_name} = new_value - end - EOC - else - attr_reader name - end - end - - def def_classed_elements(name, attribute, plural_class_name=nil, - plural_name=nil, new_name=nil) - plural_name ||= "#{name}s" - new_name ||= name - def_classed_element(plural_name, plural_class_name) - local_variable_name = "_#{name}" - new_value_variable_name = "new_value" - additional_setup_code = nil - if block_given? - additional_setup_code = yield(local_variable_name, - new_value_variable_name) - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name} - #{local_variable_name} = #{plural_name}.first - #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil - end - - def #{name}=(#{new_value_variable_name}) - #{local_variable_name} = - #{plural_name}.first || #{plural_name}.new_#{new_name} - #{additional_setup_code} - #{local_variable_name}.#{attribute} = #{new_value_variable_name} - end - EOC - end - - def def_other_element(name) - attr_accessor name - def_other_element_without_accessor(name) - end - - def def_other_element_without_accessor(name) - add_need_initialize_variable(name) - add_other_element(name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def setup_#{name}(feed, current) - if !@#{name}.nil? and current.respond_to?(:#{name}=) - current.#{name} = @#{name} - end - end - EOC - end - - def def_csv_element(name, type=nil) - def_other_element_without_accessor(name) - attr_reader(name) - converter = "" - if type == :integer - converter = "{|v| Integer(v)}" - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(value) - @#{name} = Utils::CSV.parse(value)#{converter} - end - EOC - end - end - - attr_reader :maker - def initialize(maker) - @maker = maker - @default_values_are_set = false - initialize_variables - end - - def have_required_values? - not_set_required_variables.empty? - end - - def variable_is_set? - variables.any? {|var| not __send__(var).nil?} - end - - private - def initialize_variables - self.class.need_initialize_variables.each do |variable_name, init_value| - if init_value.nil? - value = nil - else - if init_value.respond_to?(:call) - value = init_value.call(self) - elsif init_value.is_a?(String) - # just for backward compatibility - value = instance_eval(init_value, __FILE__, __LINE__) - else - value = init_value - end - end - instance_variable_set("@#{variable_name}", value) - end - end - - def setup_other_elements(feed, current=nil) - current ||= current_element(feed) - self.class.other_elements.each do |element| - __send__("setup_#{element}", feed, current) - end - end - - def current_element(feed) - feed - end - - def set_default_values(&block) - return yield if @default_values_are_set - - begin - @default_values_are_set = true - _set_default_values(&block) - ensure - @default_values_are_set = false - end - end - - def _set_default_values(&block) - yield - end - - def setup_values(target) - set = false - if have_required_values? - variables.each do |var| - setter = "#{var}=" - if target.respond_to?(setter) - value = __send__(var) - unless value.nil? - target.__send__(setter, value) - set = true - end - end - end - end - set - end - - def set_parent(target, parent) - target.parent = parent if target.class.need_parent? - end - - def variables - self.class.need_initialize_variables.find_all do |name, init| - # init == "nil" is just for backward compatibility - init.nil? or init == "nil" - end.collect do |name, init| - name - end - end - - def not_set_required_variables - required_variable_names.find_all do |var| - __send__(var).nil? - end - end - - def required_variables_are_set? - required_variable_names.each do |var| - return false if __send__(var).nil? - end - true - end - end - - module AtomPersonConstructBase - def self.append_features(klass) - super - - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) - %w(name uri email).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - EOC - end - end - - module AtomTextConstructBase - module EnsureXMLContent - class << self - def included(base) - super - base.class_eval do - %w(type content xml_content).each do |element| - attr_reader element - attr_writer element if element != "xml_content" - add_need_initialize_variable(element) - end - - alias_method(:xhtml, :xml_content) - end - end - end - - def ensure_xml_content(content) - xhtml_uri = ::RSS::Atom::XHTML_URI - unless content.is_a?(RSS::XML::Element) and - ["div", xhtml_uri] == [content.name, content.uri] - children = content - children = [children] unless content.is_a?(Array) - children = set_xhtml_uri_as_default_uri(children) - content = RSS::XML::Element.new("div", nil, xhtml_uri, - {"xmlns" => xhtml_uri}, - children) - end - content - end - - def xml_content=(content) - @xml_content = ensure_xml_content(content) - end - - def xhtml=(content) - self.xml_content = content - end - - private - def set_xhtml_uri_as_default_uri(children) - children.collect do |child| - if child.is_a?(RSS::XML::Element) and - child.prefix.nil? and child.uri.nil? - RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI, - child.attributes.dup, - set_xhtml_uri_as_default_uri(child.children)) - else - child - end - end - end - end - - def self.append_features(klass) - super - - klass.class_eval do - include EnsureXMLContent - end - end - end - - module SetupDefaultDate - private - def _set_default_values - keep = { - :date => date, - :dc_dates => dc_dates.to_a.dup, - } - _date = _parse_date_if_needed(date) - if _date and !dc_dates.any? {|dc_date| dc_date.value == _date} - dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self) - dc_date.value = _date.dup - dc_dates.unshift(dc_date) - end - self.date ||= self.dc_date - super - ensure - self.date = keep[:date] - dc_dates.replace(keep[:dc_dates]) - end - - def _parse_date_if_needed(date_value) - date_value = Time.parse(date_value) if date_value.is_a?(String) - date_value - end - end - - module SetupDefaultLanguage - private - def _set_default_values - keep = { - :dc_languages => dc_languages.to_a.dup, - } - _language = language - if _language and - !dc_languages.any? {|dc_language| dc_language.value == _language} - dc_language = self.class::DublinCoreLanguages::DublinCoreLanguage.new(self) - dc_language.value = _language.dup - dc_languages.unshift(dc_language) - end - super - ensure - dc_languages.replace(keep[:dc_languages]) - end - end - - class RSSBase < Base - class << self - def make(*args, &block) - new(*args).make(&block) - end - end - - %w(xml_stylesheets channel image items textinput).each do |element| - attr_reader element - add_need_initialize_variable(element) do |object| - object.send("make_#{element}") - end - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - private - def setup_#{element}(feed) - @#{element}.to_feed(feed) - end - - def make_#{element} - self.class::#{Utils.to_class_name(element)}.new(self) - end - EOC - end - - attr_reader :feed_version - alias_method(:rss_version, :feed_version) - attr_accessor :version, :encoding, :standalone - - def initialize(feed_version) - super(self) - @feed_type = nil - @feed_subtype = nil - @feed_version = feed_version - @version = "1.0" - @encoding = "UTF-8" - @standalone = nil - end - - def make - yield(self) - to_feed - end - - def to_feed - feed = make_feed - setup_xml_stylesheets(feed) - setup_elements(feed) - setup_other_elements(feed) - feed.validate - feed - end - - private - remove_method :make_xml_stylesheets - def make_xml_stylesheets - XMLStyleSheets.new(self) - end - end - - class XMLStyleSheets < Base - def_array_element("xml_stylesheet", nil, "XMLStyleSheet") - - class XMLStyleSheet < Base - - ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute| - attr_accessor attribute - add_need_initialize_variable(attribute) - end - - def to_feed(feed) - xss = ::RSS::XMLStyleSheet.new - guess_type_if_need(xss) - set = setup_values(xss) - if set - feed.xml_stylesheets << xss - end - end - - private - def guess_type_if_need(xss) - if @type.nil? - xss.href = @href - @type = xss.type - end - end - - def required_variable_names - %w(href type) - end - end - end - - class ChannelBase < Base - include SetupDefaultDate - - %w(cloud categories skipDays skipHours).each do |name| - def_classed_element(name) - end - - %w(generator copyright description title).each do |name| - def_classed_element(name, nil, "content") - end - - [ - ["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}], - ["author", "name"], - ["contributor", "name"], - ].each do |name, attribute, additional_setup_maker| - def_classed_elements(name, attribute, &additional_setup_maker) - end - - %w(id about language - managingEditor webMaster rating docs ttl).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - %w(date lastBuildDate).each do |date_element| - attr_reader date_element - add_need_initialize_variable(date_element) - end - - def date=(_date) - @date = _parse_date_if_needed(_date) - end - - def lastBuildDate=(_date) - @lastBuildDate = _parse_date_if_needed(_date) - end - - def pubDate - date - end - - def pubDate=(date) - self.date = date - end - - def updated - date - end - - def updated=(date) - self.date = date - end - - alias_method(:rights, :copyright) - alias_method(:rights=, :copyright=) - - alias_method(:subtitle, :description) - alias_method(:subtitle=, :description=) - - def icon - image_favicon.about - end - - def icon=(url) - image_favicon.about = url - end - - def logo - maker.image.url - end - - def logo=(url) - maker.image.url = url - end - - class SkipDaysBase < Base - def_array_element("day") - - class DayBase < Base - %w(content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end - - class SkipHoursBase < Base - def_array_element("hour") - - class HourBase < Base - %w(content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end - - class CloudBase < Base - %w(domain port path registerProcedure protocol).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class CategoriesBase < Base - def_array_element("category", "categories") - - class CategoryBase < Base - %w(domain content label).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - alias_method(:term, :domain) - alias_method(:term=, :domain=) - alias_method(:scheme, :content) - alias_method(:scheme=, :content=) - end - end - - class LinksBase < Base - def_array_element("link") - - class LinkBase < Base - %w(href rel type hreflang title length).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end - - class AuthorsBase < Base - def_array_element("author") - - class AuthorBase < Base - include AtomPersonConstructBase - end - end - - class ContributorsBase < Base - def_array_element("contributor") - - class ContributorBase < Base - include AtomPersonConstructBase - end - end - - class GeneratorBase < Base - %w(uri version content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class CopyrightBase < Base - include AtomTextConstructBase - end - - class DescriptionBase < Base - include AtomTextConstructBase - end - - class TitleBase < Base - include AtomTextConstructBase - end - end - - class ImageBase < Base - %w(title url width height description).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - def link - @maker.channel.link - end - end - - class ItemsBase < Base - def_array_element("item") - - attr_accessor :do_sort, :max_size - - def initialize(maker) - super - @do_sort = false - @max_size = -1 - end - - def normalize - if @max_size >= 0 - sort_if_need[0...@max_size] - else - sort_if_need[0..@max_size] - end - end - - private - def sort_if_need - if @do_sort.respond_to?(:call) - @items.sort do |x, y| - @do_sort.call(x, y) - end - elsif @do_sort - @items.sort do |x, y| - y <=> x - end - else - @items - end - end - - class ItemBase < Base - include SetupDefaultDate - - %w(guid enclosure source categories content).each do |name| - def_classed_element(name) - end - - %w(rights description title).each do |name| - def_classed_element(name, nil, "content") - end - - [ - ["author", "name"], - ["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}], - ["contributor", "name"], - ].each do |name, attribute| - def_classed_elements(name, attribute) - end - - %w(comments id published).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - %w(date).each do |date_element| - attr_reader date_element - add_need_initialize_variable(date_element) - end - - def date=(_date) - @date = _parse_date_if_needed(_date) - end - - def pubDate - date - end - - def pubDate=(date) - self.date = date - end - - def updated - date - end - - def updated=(date) - self.date = date - end - - alias_method(:summary, :description) - alias_method(:summary=, :description=) - - def <=>(other) - _date = date || dc_date - _other_date = other.date || other.dc_date - if _date and _other_date - _date <=> _other_date - elsif _date - 1 - elsif _other_date - -1 - else - 0 - end - end - - class GuidBase < Base - %w(isPermaLink content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - def permanent_link? - isPermaLink - end - - def permanent_link=(bool) - self.isPermaLink = bool - end - end - - class EnclosureBase < Base - %w(url length type).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class SourceBase < Base - include SetupDefaultDate - - %w(authors categories contributors generator icon - logo rights subtitle title).each do |name| - def_classed_element(name) - end - - [ - ["link", "href"], - ].each do |name, attribute| - def_classed_elements(name, attribute) - end - - %w(id content).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - alias_method(:url, :link) - alias_method(:url=, :link=) - - %w(date).each do |date_element| - attr_reader date_element - add_need_initialize_variable(date_element) - end - - def date=(_date) - @date = _parse_date_if_needed(_date) - end - - def updated - date - end - - def updated=(date) - self.date = date - end - - private - AuthorsBase = ChannelBase::AuthorsBase - CategoriesBase = ChannelBase::CategoriesBase - ContributorsBase = ChannelBase::ContributorsBase - GeneratorBase = ChannelBase::GeneratorBase - - class IconBase < Base - %w(url).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - LinksBase = ChannelBase::LinksBase - - class LogoBase < Base - %w(uri).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class RightsBase < Base - include AtomTextConstructBase - end - - class SubtitleBase < Base - include AtomTextConstructBase - end - - class TitleBase < Base - include AtomTextConstructBase - end - end - - CategoriesBase = ChannelBase::CategoriesBase - AuthorsBase = ChannelBase::AuthorsBase - LinksBase = ChannelBase::LinksBase - ContributorsBase = ChannelBase::ContributorsBase - - class RightsBase < Base - include AtomTextConstructBase - end - - class DescriptionBase < Base - include AtomTextConstructBase - end - - class ContentBase < Base - include AtomTextConstructBase::EnsureXMLContent - - %w(src).each do |element| - attr_accessor(element) - add_need_initialize_variable(element) - end - - def xml_content=(content) - content = ensure_xml_content(content) if inline_xhtml? - @xml_content = content - end - - alias_method(:xml, :xml_content) - alias_method(:xml=, :xml_content=) - - def inline_text? - [nil, "text", "html"].include?(@type) - end - - def inline_html? - @type == "html" - end - - def inline_xhtml? - @type == "xhtml" - end - - def inline_other? - !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type) - end - - def inline_other_text? - return false if @type.nil? or out_of_line? - /\Atext\//i.match(@type) ? true : false - end - - def inline_other_xml? - return false if @type.nil? or out_of_line? - /[\+\/]xml\z/i.match(@type) ? true : false - end - - def inline_other_base64? - return false if @type.nil? or out_of_line? - @type.include?("/") and !inline_other_text? and !inline_other_xml? - end - - def out_of_line? - not @src.nil? and @content.nil? - end - end - - class TitleBase < Base - include AtomTextConstructBase - end - end - end - - class TextinputBase < Base - %w(title description name link).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - end -end diff --git a/lib/rss/maker/content.rb b/lib/rss/maker/content.rb deleted file mode 100644 index b3f4e5036e..0000000000 --- a/lib/rss/maker/content.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: false -require_relative '../content' -require_relative '1.0' -require_relative '2.0' - -module RSS - module Maker - module ContentModel - def self.append_features(klass) - super - - ::RSS::ContentModel::ELEMENTS.each do |name| - klass.def_other_element(name) - end - end - end - - class ItemsBase - class ItemBase; include ContentModel; end - end - end -end diff --git a/lib/rss/maker/dublincore.rb b/lib/rss/maker/dublincore.rb deleted file mode 100644 index beea3134b4..0000000000 --- a/lib/rss/maker/dublincore.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: false -require_relative '../dublincore' -require_relative '1.0' - -module RSS - module Maker - module DublinCoreModel - def self.append_features(klass) - super - - ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| - plural_name ||= "#{name}s" - full_name = "#{RSS::DC_PREFIX}_#{name}" - full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}" - plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" - klass.def_classed_elements(full_name, "value", plural_klass_name, - full_plural_name, name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def new_#{full_name}(value=nil) - _#{full_name} = #{full_plural_name}.new_#{name} - _#{full_name}.value = value - if block_given? - yield _#{full_name} - else - _#{full_name} - end - end - EOC - end - - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - # For backward compatibility - alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list - EOC - end - - ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| - plural_name ||= "#{name}s" - full_name ||= "#{DC_PREFIX}_#{name}" - full_plural_name ||= "#{DC_PREFIX}_#{plural_name}" - klass_name = Utils.to_class_name(name) - full_klass_name = "DublinCore#{klass_name}" - plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{plural_klass_name}Base < Base - def_array_element(#{name.dump}, #{full_plural_name.dump}, - #{full_klass_name.dump}) - - class #{full_klass_name}Base < Base - attr_accessor :value - add_need_initialize_variable("value") - alias_method(:content, :value) - alias_method(:content=, :value=) - - def have_required_values? - @value - end - - def to_feed(feed, current) - if value and current.respond_to?(:#{full_name}) - new_item = current.class::#{full_klass_name}.new(value) - current.#{full_plural_name} << new_item - end - end - end - #{klass_name}Base = #{full_klass_name}Base - end - EOC - end - - def self.install_dublin_core(klass) - ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| - plural_name ||= "#{name}s" - klass_name = Utils.to_class_name(name) - full_klass_name = "DublinCore#{klass_name}" - plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class #{plural_klass_name} < #{plural_klass_name}Base - class #{full_klass_name} < #{full_klass_name}Base - end - #{klass_name} = #{full_klass_name} - end -EOC - end - end - end - - class ChannelBase - include DublinCoreModel - end - - class ImageBase; include DublinCoreModel; end - class ItemsBase - class ItemBase - include DublinCoreModel - end - end - class TextinputBase; include DublinCoreModel; end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class Channel - DublinCoreModel.install_dublin_core(self) - end - - class Image - DublinCoreModel.install_dublin_core(self) - end - - class Items - class Item - DublinCoreModel.install_dublin_core(self) - end - end - - class Textinput - DublinCoreModel.install_dublin_core(self) - end - EOC - end - end -end diff --git a/lib/rss/maker/entry.rb b/lib/rss/maker/entry.rb deleted file mode 100644 index ccdf9608ae..0000000000 --- a/lib/rss/maker/entry.rb +++ /dev/null @@ -1,164 +0,0 @@ -# frozen_string_literal: false -require_relative "atom" -require_relative "feed" - -module RSS - module Maker - module Atom - class Entry < RSSBase - def initialize(feed_version="1.0") - super - @feed_type = "atom" - @feed_subtype = "entry" - end - - private - def make_feed - ::RSS::Atom::Entry.new(@version, @encoding, @standalone) - end - - def setup_elements(entry) - setup_items(entry) - end - - class Channel < ChannelBase - class SkipDays < SkipDaysBase - class Day < DayBase - end - end - - class SkipHours < SkipHoursBase - class Hour < HourBase - end - end - - class Cloud < CloudBase - end - - Categories = Feed::Channel::Categories - Links = Feed::Channel::Links - Authors = Feed::Channel::Authors - Contributors = Feed::Channel::Contributors - - class Generator < GeneratorBase - include AtomGenerator - - def self.not_set_name - "maker.channel.generator" - end - end - - Copyright = Feed::Channel::Copyright - - class Description < DescriptionBase - end - - Title = Feed::Channel::Title - end - - class Image < ImageBase - end - - class Items < ItemsBase - def to_feed(entry) - (normalize.first || Item.new(@maker)).to_feed(entry) - end - - class Item < ItemBase - def to_feed(entry) - set_default_values do - setup_values(entry) - entry.dc_dates.clear - setup_other_elements(entry) - unless have_required_values? - raise NotSetError.new("maker.item", not_set_required_variables) - end - end - end - - private - def required_variable_names - %w(id updated) - end - - def variables - super + ["updated"] - end - - def variable_is_set? - super or !authors.empty? - end - - def not_set_required_variables - set_default_values do - vars = super - if authors.all? {|author| !author.have_required_values?} - vars << "author" - end - vars << "title" unless title {|t| t.have_required_values?} - vars - end - end - - def _set_default_values - keep = { - :authors => authors.to_a.dup, - :contributors => contributors.to_a.dup, - :categories => categories.to_a.dup, - :id => id, - :links => links.to_a.dup, - :rights => @rights, - :title => @title, - :updated => updated, - } - authors.replace(@maker.channel.authors) if keep[:authors].empty? - if keep[:contributors].empty? - contributors.replace(@maker.channel.contributors) - end - if keep[:categories].empty? - categories.replace(@maker.channel.categories) - end - self.id ||= link || @maker.channel.id - links.replace(@maker.channel.links) if keep[:links].empty? - unless keep[:rights].variable_is_set? - @maker.channel.rights {|r| @rights = r} - end - unless keep[:title].variable_is_set? - @maker.channel.title {|t| @title = t} - end - self.updated ||= @maker.channel.updated - super - ensure - authors.replace(keep[:authors]) - contributors.replace(keep[:contributors]) - categories.replace(keep[:categories]) - links.replace(keep[:links]) - self.id = keep[:id] - @rights = keep[:rights] - @title = keep[:title] - self.updated = keep[:updated] - end - - Guid = Feed::Items::Item::Guid - Enclosure = Feed::Items::Item::Enclosure - Source = Feed::Items::Item::Source - Categories = Feed::Items::Item::Categories - Authors = Feed::Items::Item::Authors - Contributors = Feed::Items::Item::Contributors - Links = Feed::Items::Item::Links - Rights = Feed::Items::Item::Rights - Description = Feed::Items::Item::Description - Title = Feed::Items::Item::Title - Content = Feed::Items::Item::Content - end - end - - class Textinput < TextinputBase - end - end - end - - add_maker("atom:entry", "1.0", Atom::Entry) - add_maker("atom1.0:entry", "1.0", Atom::Entry) - end -end diff --git a/lib/rss/maker/feed.rb b/lib/rss/maker/feed.rb deleted file mode 100644 index 72ee704d6a..0000000000 --- a/lib/rss/maker/feed.rb +++ /dev/null @@ -1,427 +0,0 @@ -# frozen_string_literal: false -require_relative "atom" - -module RSS - module Maker - module Atom - class Feed < RSSBase - def initialize(feed_version="1.0") - super - @feed_type = "atom" - @feed_subtype = "feed" - end - - private - def make_feed - ::RSS::Atom::Feed.new(@version, @encoding, @standalone) - end - - def setup_elements(feed) - setup_channel(feed) - setup_image(feed) - setup_items(feed) - end - - class Channel < ChannelBase - include SetupDefaultLanguage - - def to_feed(feed) - set_default_values do - setup_values(feed) - feed.dc_dates.clear - setup_other_elements(feed) - if image_favicon.about - icon = feed.class::Icon.new - icon.content = image_favicon.about - feed.icon = icon - end - unless have_required_values? - raise NotSetError.new("maker.channel", - not_set_required_variables) - end - end - end - - def have_required_values? - super and - (!authors.empty? or - @maker.items.any? {|item| !item.authors.empty?}) - end - - private - def required_variable_names - %w(id updated) - end - - def variables - super + %w(id updated) - end - - def variable_is_set? - super or !authors.empty? - end - - def not_set_required_variables - vars = super - if authors.empty? and - @maker.items.all? {|item| item.author.to_s.empty?} - vars << "author" - end - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - def _set_default_values(&block) - keep = { - :id => id, - } - self.id ||= about - super(&block) - ensure - self.id = keep[:id] - end - - class SkipDays < SkipDaysBase - def to_feed(*args) - end - - class Day < DayBase - end - end - - class SkipHours < SkipHoursBase - def to_feed(*args) - end - - class Hour < HourBase - end - end - - class Cloud < CloudBase - def to_feed(*args) - end - end - - class Categories < CategoriesBase - class Category < CategoryBase - include AtomCategory - - def self.not_set_name - "maker.channel.category" - end - end - end - - class Links < LinksBase - class Link < LinkBase - include AtomLink - - def self.not_set_name - "maker.channel.link" - end - end - end - - AtomPersons.def_atom_persons(self, "author", "maker.channel.author") - AtomPersons.def_atom_persons(self, "contributor", - "maker.channel.contributor") - - class Generator < GeneratorBase - include AtomGenerator - - def self.not_set_name - "maker.channel.generator" - end - end - - AtomTextConstruct.def_atom_text_construct(self, "rights", - "maker.channel.copyright", - "Copyright") - AtomTextConstruct.def_atom_text_construct(self, "subtitle", - "maker.channel.description", - "Description") - AtomTextConstruct.def_atom_text_construct(self, "title", - "maker.channel.title") - end - - class Image < ImageBase - def to_feed(feed) - logo = feed.class::Logo.new - class << logo - alias_method(:url=, :content=) - end - set = setup_values(logo) - class << logo - remove_method(:url=) - end - if set - feed.logo = logo - set_parent(logo, feed) - setup_other_elements(feed, logo) - elsif variable_is_set? - raise NotSetError.new("maker.image", not_set_required_variables) - end - end - - private - def required_variable_names - %w(url) - end - end - - class Items < ItemsBase - def to_feed(feed) - normalize.each do |item| - item.to_feed(feed) - end - setup_other_elements(feed, feed.entries) - end - - class Item < ItemBase - def to_feed(feed) - set_default_values do - entry = feed.class::Entry.new - set = setup_values(entry) - entry.dc_dates.clear - setup_other_elements(feed, entry) - if set - feed.entries << entry - set_parent(entry, feed) - elsif variable_is_set? - raise NotSetError.new("maker.item", not_set_required_variables) - end - end - end - - def have_required_values? - set_default_values do - super and title {|t| t.have_required_values?} - end - end - - private - def required_variable_names - %w(id updated) - end - - def variables - super + ["updated"] - end - - def not_set_required_variables - vars = super - vars << "title" unless title {|t| t.have_required_values?} - vars - end - - def _set_default_values(&block) - keep = { - :id => id, - } - self.id ||= link - super(&block) - ensure - self.id = keep[:id] - end - - class Guid < GuidBase - def to_feed(feed, current) - end - end - - class Enclosure < EnclosureBase - def to_feed(feed, current) - end - end - - class Source < SourceBase - def to_feed(feed, current) - source = current.class::Source.new - setup_values(source) - current.source = source - set_parent(source, current) - setup_other_elements(feed, source) - current.source = nil if source.to_s == "" - end - - private - def required_variable_names - [] - end - - def variables - super + ["updated"] - end - - AtomPersons.def_atom_persons(self, "author", - "maker.item.source.author") - AtomPersons.def_atom_persons(self, "contributor", - "maker.item.source.contributor") - - class Categories < CategoriesBase - class Category < CategoryBase - include AtomCategory - - def self.not_set_name - "maker.item.source.category" - end - end - end - - class Generator < GeneratorBase - include AtomGenerator - - def self.not_set_name - "maker.item.source.generator" - end - end - - class Icon < IconBase - def to_feed(feed, current) - icon = current.class::Icon.new - class << icon - alias_method(:url=, :content=) - end - set = setup_values(icon) - class << icon - remove_method(:url=) - end - if set - current.icon = icon - set_parent(icon, current) - setup_other_elements(feed, icon) - elsif variable_is_set? - raise NotSetError.new("maker.item.source.icon", - not_set_required_variables) - end - end - - private - def required_variable_names - %w(url) - end - end - - class Links < LinksBase - class Link < LinkBase - include AtomLink - - def self.not_set_name - "maker.item.source.link" - end - end - end - - class Logo < LogoBase - include AtomLogo - - def self.not_set_name - "maker.item.source.logo" - end - end - - maker_name_base = "maker.item.source." - maker_name = "#{maker_name_base}rights" - AtomTextConstruct.def_atom_text_construct(self, "rights", - maker_name) - maker_name = "#{maker_name_base}subtitle" - AtomTextConstruct.def_atom_text_construct(self, "subtitle", - maker_name) - maker_name = "#{maker_name_base}title" - AtomTextConstruct.def_atom_text_construct(self, "title", - maker_name) - end - - class Categories < CategoriesBase - class Category < CategoryBase - include AtomCategory - - def self.not_set_name - "maker.item.category" - end - end - end - - AtomPersons.def_atom_persons(self, "author", "maker.item.author") - AtomPersons.def_atom_persons(self, "contributor", - "maker.item.contributor") - - class Links < LinksBase - class Link < LinkBase - include AtomLink - - def self.not_set_name - "maker.item.link" - end - end - end - - AtomTextConstruct.def_atom_text_construct(self, "rights", - "maker.item.rights") - AtomTextConstruct.def_atom_text_construct(self, "summary", - "maker.item.description", - "Description") - AtomTextConstruct.def_atom_text_construct(self, "title", - "maker.item.title") - - class Content < ContentBase - def to_feed(feed, current) - content = current.class::Content.new - if setup_values(content) - content.src = nil if content.src and content.content - current.content = content - set_parent(content, current) - setup_other_elements(feed, content) - elsif variable_is_set? - raise NotSetError.new("maker.item.content", - not_set_required_variables) - end - end - - alias_method(:xml, :xml_content) - - private - def required_variable_names - if out_of_line? - %w(type) - elsif xml_type? - %w(xml_content) - else - %w(content) - end - end - - def variables - if out_of_line? - super - elsif xml_type? - super + %w(xml) - else - super - end - end - - def xml_type? - _type = type - return false if _type.nil? - _type == "xhtml" or - /(?:\+xml|\/xml)$/i =~ _type or - %w(text/xml-external-parsed-entity - application/xml-external-parsed-entity - application/xml-dtd).include?(_type.downcase) - end - end - end - end - - class Textinput < TextinputBase - end - end - end - - add_maker("atom", "1.0", Atom::Feed) - add_maker("atom:feed", "1.0", Atom::Feed) - add_maker("atom1.0", "1.0", Atom::Feed) - add_maker("atom1.0:feed", "1.0", Atom::Feed) - end -end diff --git a/lib/rss/maker/image.rb b/lib/rss/maker/image.rb deleted file mode 100644 index e3e62d8b9e..0000000000 --- a/lib/rss/maker/image.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: false -require_relative '../image' -require_relative '1.0' -require_relative 'dublincore' - -module RSS - module Maker - module ImageItemModel - def self.append_features(klass) - super - - name = "#{RSS::IMAGE_PREFIX}_item" - klass.def_classed_element(name) - end - - def self.install_image_item(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class ImageItem < ImageItemBase - DublinCoreModel.install_dublin_core(self) - end -EOC - end - - class ImageItemBase < Base - include Maker::DublinCoreModel - - attr_accessor :about, :resource, :image_width, :image_height - add_need_initialize_variable("about") - add_need_initialize_variable("resource") - add_need_initialize_variable("image_width") - add_need_initialize_variable("image_height") - alias width= image_width= - alias width image_width - alias height= image_height= - alias height image_height - - def have_required_values? - @about - end - - def to_feed(feed, current) - if current.respond_to?(:image_item=) and have_required_values? - item = current.class::ImageItem.new - setup_values(item) - setup_other_elements(item) - current.image_item = item - end - end - end - end - - module ImageFaviconModel - def self.append_features(klass) - super - - name = "#{RSS::IMAGE_PREFIX}_favicon" - klass.def_classed_element(name) - end - - def self.install_image_favicon(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class ImageFavicon < ImageFaviconBase - DublinCoreModel.install_dublin_core(self) - end - EOC - end - - class ImageFaviconBase < Base - include Maker::DublinCoreModel - - attr_accessor :about, :image_size - add_need_initialize_variable("about") - add_need_initialize_variable("image_size") - alias size image_size - alias size= image_size= - - def have_required_values? - @about and @image_size - end - - def to_feed(feed, current) - if current.respond_to?(:image_favicon=) and have_required_values? - favicon = current.class::ImageFavicon.new - setup_values(favicon) - setup_other_elements(favicon) - current.image_favicon = favicon - end - end - end - end - - class ChannelBase; include Maker::ImageFaviconModel; end - - class ItemsBase - class ItemBase; include Maker::ImageItemModel; end - end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class Channel - ImageFaviconModel.install_image_favicon(self) - end - - class Items - class Item - ImageItemModel.install_image_item(self) - end - end - EOC - end - end -end diff --git a/lib/rss/maker/itunes.rb b/lib/rss/maker/itunes.rb deleted file mode 100644 index 28cca32021..0000000000 --- a/lib/rss/maker/itunes.rb +++ /dev/null @@ -1,243 +0,0 @@ -# frozen_string_literal: false -require_relative '../itunes' -require_relative '2.0' - -module RSS - module Maker - module ITunesBaseModel - def def_class_accessor(klass, name, type, *args) - name = name.gsub(/-/, "_").gsub(/^itunes_/, '') - full_name = "#{RSS::ITUNES_PREFIX}_#{name}" - case type - when nil - klass.def_other_element(full_name) - when :yes_other - def_yes_other_accessor(klass, full_name) - when :explicit_clean_other - def_explicit_clean_other_accessor(klass, full_name) - when :csv - def_csv_accessor(klass, full_name) - when :element, :attribute - recommended_attribute_name, = *args - klass_name = "ITunes#{Utils.to_class_name(name)}" - klass.def_classed_element(full_name, klass_name, - recommended_attribute_name) - when :elements - plural_name, recommended_attribute_name = args - plural_name ||= "#{name}s" - full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}" - klass_name = "ITunes#{Utils.to_class_name(name)}" - plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}" - def_elements_class_accessor(klass, name, full_name, full_plural_name, - klass_name, plural_klass_name, - recommended_attribute_name) - end - end - - def def_yes_other_accessor(klass, full_name) - klass.def_other_element(full_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{full_name}? - Utils::YesOther.parse(@#{full_name}) - end - EOC - end - - def def_explicit_clean_other_accessor(klass, full_name) - klass.def_other_element(full_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{full_name}? - Utils::ExplicitCleanOther.parse(#{full_name}) - end - EOC - end - - def def_csv_accessor(klass, full_name) - klass.def_csv_element(full_name) - end - - def def_elements_class_accessor(klass, name, full_name, full_plural_name, - klass_name, plural_klass_name, - recommended_attribute_name=nil) - if recommended_attribute_name - klass.def_classed_elements(full_name, recommended_attribute_name, - plural_klass_name, full_plural_name) - else - klass.def_classed_element(full_plural_name, plural_klass_name) - end - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def new_#{full_name}(text=nil) - #{full_name} = @#{full_plural_name}.new_#{name} - #{full_name}.text = text - if block_given? - yield #{full_name} - else - #{full_name} - end - end - EOC - end - end - - module ITunesChannelModel - extend ITunesBaseModel - - class << self - def append_features(klass) - super - - ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args| - def_class_accessor(klass, name, type, *args) - end - end - end - - class ITunesCategoriesBase < Base - def_array_element("category", "itunes_categories", - "ITunesCategory") - class ITunesCategoryBase < Base - attr_accessor :text - add_need_initialize_variable("text") - def_array_element("category", "itunes_categories", - "ITunesCategory") - - def have_required_values? - text - end - - alias_method :to_feed_for_categories, :to_feed - def to_feed(feed, current) - if text and current.respond_to?(:itunes_category) - new_item = current.class::ITunesCategory.new(text) - to_feed_for_categories(feed, new_item) - current.itunes_categories << new_item - end - end - end - end - - class ITunesImageBase < Base - add_need_initialize_variable("href") - attr_accessor("href") - - def to_feed(feed, current) - if @href and current.respond_to?(:itunes_image) - current.itunes_image ||= current.class::ITunesImage.new - current.itunes_image.href = @href - end - end - end - - class ITunesOwnerBase < Base - %w(itunes_name itunes_email).each do |name| - add_need_initialize_variable(name) - attr_accessor(name) - end - - def to_feed(feed, current) - if current.respond_to?(:itunes_owner=) - _not_set_required_variables = not_set_required_variables - if (required_variable_names - _not_set_required_variables).empty? - return - end - - unless have_required_values? - raise NotSetError.new("maker.channel.itunes_owner", - _not_set_required_variables) - end - current.itunes_owner ||= current.class::ITunesOwner.new - current.itunes_owner.itunes_name = @itunes_name - current.itunes_owner.itunes_email = @itunes_email - end - end - - private - def required_variable_names - %w(itunes_name itunes_email) - end - end - end - - module ITunesItemModel - extend ITunesBaseModel - - class << self - def append_features(klass) - super - - ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args| - def_class_accessor(klass, name, type, *args) - end - end - end - - class ITunesDurationBase < Base - attr_reader :content - add_need_initialize_variable("content") - - %w(hour minute second).each do |name| - attr_reader(name) - add_need_initialize_variable(name, 0) - end - - def content=(content) - if content.nil? - @hour, @minute, @second, @content = nil - else - @hour, @minute, @second = - ::RSS::ITunesItemModel::ITunesDuration.parse(content) - @content = content - end - end - - def hour=(hour) - @hour = Integer(hour) - update_content - end - - def minute=(minute) - @minute = Integer(minute) - update_content - end - - def second=(second) - @second = Integer(second) - update_content - end - - def to_feed(feed, current) - if @content and current.respond_to?(:itunes_duration=) - current.itunes_duration ||= current.class::ITunesDuration.new - current.itunes_duration.content = @content - end - end - - private - def update_content - components = [@hour, @minute, @second] - @content = - ::RSS::ITunesItemModel::ITunesDuration.construct(*components) - end - end - end - - class ChannelBase - include Maker::ITunesChannelModel - class ITunesCategories < ITunesCategoriesBase - class ITunesCategory < ITunesCategoryBase - ITunesCategory = self - end - end - - class ITunesImage < ITunesImageBase; end - class ITunesOwner < ITunesOwnerBase; end - end - - class ItemsBase - class ItemBase - include Maker::ITunesItemModel - class ITunesDuration < ITunesDurationBase; end - end - end - end -end diff --git a/lib/rss/maker/slash.rb b/lib/rss/maker/slash.rb deleted file mode 100644 index 473991903f..0000000000 --- a/lib/rss/maker/slash.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: false -require_relative '../slash' -require_relative '1.0' - -module RSS - module Maker - module SlashModel - def self.append_features(klass) - super - - ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type| - full_name = "#{RSS::SLASH_PREFIX}_#{name}" - case type - when :csv_integer - klass.def_csv_element(full_name, :integer) - else - klass.def_other_element(full_name) - end - end - - klass.module_eval do - alias_method(:slash_hit_parades, :slash_hit_parade) - alias_method(:slash_hit_parades=, :slash_hit_parade=) - end - end - end - - class ItemsBase - class ItemBase - include SlashModel - end - end - end -end diff --git a/lib/rss/maker/syndication.rb b/lib/rss/maker/syndication.rb deleted file mode 100644 index 9fd0efe99e..0000000000 --- a/lib/rss/maker/syndication.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: false -require_relative '../syndication' -require_relative '1.0' - -module RSS - module Maker - module SyndicationModel - def self.append_features(klass) - super - - ::RSS::SyndicationModel::ELEMENTS.each do |name| - klass.def_other_element(name) - end - end - end - - class ChannelBase; include SyndicationModel; end - end -end diff --git a/lib/rss/maker/taxonomy.rb b/lib/rss/maker/taxonomy.rb deleted file mode 100644 index f9858922da..0000000000 --- a/lib/rss/maker/taxonomy.rb +++ /dev/null @@ -1,119 +0,0 @@ -# frozen_string_literal: false -require_relative '../taxonomy' -require_relative '1.0' -require_relative 'dublincore' - -module RSS - module Maker - module TaxonomyTopicsModel - def self.append_features(klass) - super - - klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics", - "TaxonomyTopics") - end - - def self.install_taxo_topics(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class TaxonomyTopics < TaxonomyTopicsBase - def to_feed(feed, current) - if current.respond_to?(:taxo_topics) - topics = current.class::TaxonomyTopics.new - bag = topics.Bag - @resources.each do |resource| - bag.lis << RDF::Bag::Li.new(resource) - end - current.taxo_topics = topics - end - end - end -EOC - end - - class TaxonomyTopicsBase < Base - attr_reader :resources - def_array_element("resource") - remove_method :new_resource - end - end - - module TaxonomyTopicModel - def self.append_features(klass) - super - - class_name = "TaxonomyTopics" - klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name) - end - - def self.install_taxo_topic(klass) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class TaxonomyTopics < TaxonomyTopicsBase - class TaxonomyTopic < TaxonomyTopicBase - DublinCoreModel.install_dublin_core(self) - TaxonomyTopicsModel.install_taxo_topics(self) - - def to_feed(feed, current) - if current.respond_to?(:taxo_topics) - topic = current.class::TaxonomyTopic.new(value) - topic.taxo_link = value - taxo_topics.to_feed(feed, topic) if taxo_topics - current.taxo_topics << topic - setup_other_elements(feed, topic) - end - end - end - end -EOC - end - - class TaxonomyTopicsBase < Base - def_array_element("topic", nil, "TaxonomyTopic") - alias_method(:new_taxo_topic, :new_topic) # For backward compatibility - - class TaxonomyTopicBase < Base - include DublinCoreModel - include TaxonomyTopicsModel - - attr_accessor :value - add_need_initialize_variable("value") - alias_method(:taxo_link, :value) - alias_method(:taxo_link=, :value=) - - def have_required_values? - @value - end - end - end - end - - class RSSBase - include TaxonomyTopicModel - end - - class ChannelBase - include TaxonomyTopicsModel - end - - class ItemsBase - class ItemBase - include TaxonomyTopicsModel - end - end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - TaxonomyTopicModel.install_taxo_topic(self) - - class Channel - TaxonomyTopicsModel.install_taxo_topics(self) - end - - class Items - class Item - TaxonomyTopicsModel.install_taxo_topics(self) - end - end - EOC - end - end -end diff --git a/lib/rss/maker/trackback.rb b/lib/rss/maker/trackback.rb deleted file mode 100644 index f78b4058f9..0000000000 --- a/lib/rss/maker/trackback.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: false -require_relative '../trackback' -require_relative '1.0' -require_relative '2.0' - -module RSS - module Maker - module TrackBackModel - def self.append_features(klass) - super - - klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping") - klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value", - "TrackBackAbouts") - end - - class TrackBackAboutsBase < Base - def_array_element("about", nil, "TrackBackAbout") - - class TrackBackAboutBase < Base - attr_accessor :value - add_need_initialize_variable("value") - - alias_method(:resource, :value) - alias_method(:resource=, :value=) - alias_method(:content, :value) - alias_method(:content=, :value=) - - def have_required_values? - @value - end - - def to_feed(feed, current) - if current.respond_to?(:trackback_abouts) and have_required_values? - about = current.class::TrackBackAbout.new - setup_values(about) - setup_other_elements(about) - current.trackback_abouts << about - end - end - end - end - end - - class ItemsBase - class ItemBase; include TrackBackModel; end - end - - makers.each do |maker| - maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - class Items - class Item - class TrackBackAbouts < TrackBackAboutsBase - class TrackBackAbout < TrackBackAboutBase - end - end - end - end - EOC - end - end -end diff --git a/lib/rss/parser.rb b/lib/rss/parser.rb deleted file mode 100644 index e1bcfc53e3..0000000000 --- a/lib/rss/parser.rb +++ /dev/null @@ -1,589 +0,0 @@ -# frozen_string_literal: false -require "forwardable" -require "open-uri" - -require_relative "rss" -require_relative "xml" - -module RSS - - class NotWellFormedError < Error - attr_reader :line, :element - - # Create a new NotWellFormedError for an error at +line+ - # in +element+. If a block is given the return value of - # the block ends up in the error message. - def initialize(line=nil, element=nil) - message = "This is not well formed XML" - if element or line - message << "\nerror occurred" - message << " in #{element}" if element - message << " at about #{line} line" if line - end - message << "\n#{yield}" if block_given? - super(message) - end - end - - class XMLParserNotFound < Error - def initialize - super("available XML parser was not found in " << - "#{AVAILABLE_PARSER_LIBRARIES.inspect}.") - end - end - - class NotValidXMLParser < Error - def initialize(parser) - super("#{parser} is not an available XML parser. " << - "Available XML parser" << - (AVAILABLE_PARSERS.size > 1 ? "s are " : " is ") << - "#{AVAILABLE_PARSERS.inspect}.") - end - end - - class NSError < InvalidRSSError - attr_reader :tag, :prefix, :uri - def initialize(tag, prefix, require_uri) - @tag, @prefix, @uri = tag, prefix, require_uri - super("prefix <#{prefix}> doesn't associate uri " << - "<#{require_uri}> in tag <#{tag}>") - end - end - - class Parser - - extend Forwardable - - class << self - - @@default_parser = nil - - def default_parser - @@default_parser || AVAILABLE_PARSERS.first - end - - # Set @@default_parser to new_value if it is one of the - # available parsers. Else raise NotValidXMLParser error. - def default_parser=(new_value) - if AVAILABLE_PARSERS.include?(new_value) - @@default_parser = new_value - else - raise NotValidXMLParser.new(new_value) - end - end - - def parse(rss, *args) - if args.last.is_a?(Hash) - options = args.pop - else - options = {} - end - do_validate = boolean_argument(args[0], options[:validate], true) - ignore_unknown_element = - boolean_argument(args[1], options[:ignore_unknown_element], true) - parser_class = args[2] || options[:parser_class] || default_parser - parser = new(rss, parser_class) - parser.do_validate = do_validate - parser.ignore_unknown_element = ignore_unknown_element - parser.parse - end - - private - def boolean_argument(positioned_value, option_value, default) - value = positioned_value - if value.nil? and not option_value.nil? - value = option_value - end - value = default if value.nil? - value - end - end - - def_delegators(:@parser, :parse, :rss, - :ignore_unknown_element, - :ignore_unknown_element=, :do_validate, - :do_validate=) - - def initialize(rss, parser_class=self.class.default_parser) - @parser = parser_class.new(normalize_rss(rss)) - end - - private - - # Try to get the XML associated with +rss+. - # Return +rss+ if it already looks like XML, or treat it as a URI, - # or a file to get the XML, - def normalize_rss(rss) - return rss if maybe_xml?(rss) - - uri = to_uri(rss) - - if uri.respond_to?(:read) - uri.read - elsif (RUBY_VERSION >= '2.7' || !rss.tainted?) and File.readable?(rss) - File.open(rss) {|f| f.read} - else - rss - end - end - - # maybe_xml? tests if source is a string that looks like XML. - def maybe_xml?(source) - source.is_a?(String) and / :xml}] - @tag_stack = [[]] - @text_stack = [''] - @proc_stack = [] - @last_element = nil - @version = @encoding = @standalone = nil - @xml_stylesheets = [] - @xml_child_mode = false - @xml_element = nil - @last_xml_element = nil - end - - # set instance vars for version, encoding, standalone - def xmldecl(version, encoding, standalone) - @version, @encoding, @standalone = version, encoding, standalone - end - - def instruction(name, content) - if name == "xml-stylesheet" - params = parse_pi_content(content) - if params.has_key?("href") - @xml_stylesheets << XMLStyleSheet.new(params) - end - end - end - - def tag_start(name, attributes) - @text_stack.push('') - - ns = @ns_stack.last.dup - attrs = {} - attributes.each do |n, v| - if /\Axmlns(?:\z|:)/ =~ n - ns[$POSTMATCH] = v - else - attrs[n] = v - end - end - @ns_stack.push(ns) - - prefix, local = split_name(name) - @tag_stack.last.push([_ns(ns, prefix), local]) - @tag_stack.push([]) - if @xml_child_mode - previous = @last_xml_element - element_attrs = attributes.dup - unless previous - ns.each do |ns_prefix, value| - next if ns_prefix == "xml" - key = ns_prefix.empty? ? "xmlns" : "xmlns:#{ns_prefix}" - element_attrs[key] ||= value - end - end - next_element = XML::Element.new(local, - prefix.empty? ? nil : prefix, - _ns(ns, prefix), - element_attrs) - previous << next_element if previous - @last_xml_element = next_element - pr = Proc.new do |text, tags| - if previous - @last_xml_element = previous - else - @xml_element = @last_xml_element - @last_xml_element = nil - end - end - @proc_stack.push(pr) - else - if @rss.nil? and respond_to?("initial_start_#{local}", true) - __send__("initial_start_#{local}", local, prefix, attrs, ns.dup) - elsif respond_to?("start_#{local}", true) - __send__("start_#{local}", local, prefix, attrs, ns.dup) - else - start_else_element(local, prefix, attrs, ns.dup) - end - end - end - - def tag_end(name) - if DEBUG - p "end tag #{name}" - p @tag_stack - end - text = @text_stack.pop - tags = @tag_stack.pop - pr = @proc_stack.pop - pr.call(text, tags) unless pr.nil? - @ns_stack.pop - end - - def text(data) - if @xml_child_mode - @last_xml_element << data if @last_xml_element - else - @text_stack.last << data - end - end - - private - def _ns(ns, prefix) - ns.fetch(prefix, "") - end - - CONTENT_PATTERN = /\s*([^=]+)=(["'])([^\2]+?)\2/ - # Extract the first name="value" pair from content. - # Works with single quotes according to the constant - # CONTENT_PATTERN. Return a Hash. - def parse_pi_content(content) - params = {} - content.scan(CONTENT_PATTERN) do |name, quote, value| - params[name] = value - end - params - end - - def start_else_element(local, prefix, attrs, ns) - class_name = self.class.class_name(_ns(ns, prefix), local) - current_class = @last_element.class - if known_class?(current_class, class_name) - next_class = current_class.const_get(class_name) - start_have_something_element(local, prefix, attrs, ns, next_class) - else - if !@do_validate or @ignore_unknown_element - @proc_stack.push(setup_next_element_in_unknown_element) - else - parent = "ROOT ELEMENT???" - if current_class.tag_name - parent = current_class.tag_name - end - raise NotExpectedTagError.new(local, _ns(ns, prefix), parent) - end - end - end - - if Module.method(:const_defined?).arity == -1 - def known_class?(target_class, class_name) - class_name and - (target_class.const_defined?(class_name, false) or - target_class.constants.include?(class_name.to_sym)) - end - else - def known_class?(target_class, class_name) - class_name and - (target_class.const_defined?(class_name) or - target_class.constants.include?(class_name)) - end - end - - NAMESPLIT = /^(?:([\w:][-\w.]*):)?([\w:][-\w.]*)/ - def split_name(name) - name =~ NAMESPLIT - [$1 || '', $2] - end - - def check_ns(tag_name, prefix, ns, require_uri, ignore_unknown_element=nil) - if _ns(ns, prefix) == require_uri - true - else - if ignore_unknown_element.nil? - ignore_unknown_element = @ignore_unknown_element - end - - if ignore_unknown_element - false - elsif @do_validate - raise NSError.new(tag_name, prefix, require_uri) - else - # Force bind required URI with prefix - @ns_stack.last[prefix] = require_uri - true - end - end - end - - def start_get_text_element(tag_name, prefix, ns, required_uri) - pr = Proc.new do |text, tags| - setter = self.class.setter(required_uri, tag_name) - if setter and @last_element.respond_to?(setter) - if @do_validate - getter = self.class.getter(required_uri, tag_name) - if @last_element.__send__(getter) - raise TooMuchTagError.new(tag_name, @last_element.tag_name) - end - end - @last_element.__send__(setter, text.to_s) - else - if @do_validate and !@ignore_unknown_element - raise NotExpectedTagError.new(tag_name, _ns(ns, prefix), - @last_element.tag_name) - end - end - end - @proc_stack.push(pr) - end - - def start_have_something_element(tag_name, prefix, attrs, ns, klass) - if check_ns(tag_name, prefix, ns, klass.required_uri) - attributes = collect_attributes(tag_name, prefix, attrs, ns, klass) - @proc_stack.push(setup_next_element(tag_name, klass, attributes)) - else - @proc_stack.push(setup_next_element_in_unknown_element) - end - end - - def collect_attributes(tag_name, prefix, attrs, ns, klass) - attributes = {} - klass.get_attributes.each do |a_name, a_uri, required, element_name| - if a_uri.is_a?(String) or !a_uri.respond_to?(:include?) - a_uri = [a_uri] - end - unless a_uri == [""] - for prefix, uri in ns - if a_uri.include?(uri) - val = attrs["#{prefix}:#{a_name}"] - break if val - end - end - end - if val.nil? and a_uri.include?("") - val = attrs[a_name] - end - - if @do_validate and required and val.nil? - unless a_uri.include?("") - for prefix, uri in ns - if a_uri.include?(uri) - a_name = "#{prefix}:#{a_name}" - end - end - end - raise MissingAttributeError.new(tag_name, a_name) - end - - attributes[a_name] = val - end - attributes - end - - def setup_next_element(tag_name, klass, attributes) - previous = @last_element - next_element = klass.new(@do_validate, attributes) - previous.set_next_element(tag_name, next_element) - @last_element = next_element - @last_element.parent = previous if klass.need_parent? - @xml_child_mode = @last_element.have_xml_content? - - Proc.new do |text, tags| - p(@last_element.class) if DEBUG - if @xml_child_mode - @last_element.content = @xml_element.to_s - xml_setter = @last_element.class.xml_setter - @last_element.__send__(xml_setter, @xml_element) - @xml_element = nil - @xml_child_mode = false - else - if klass.have_content? - if @last_element.need_base64_encode? - text = text.lstrip.unpack("m").first - end - @last_element.content = text - end - end - if @do_validate - @last_element.validate_for_stream(tags, @ignore_unknown_element) - end - @last_element = previous - end - end - - def setup_next_element_in_unknown_element - current_element, @last_element = @last_element, nil - Proc.new {@last_element = current_element} - end - end - - unless const_defined? :AVAILABLE_PARSER_LIBRARIES - # The list of all available libraries for parsing. - AVAILABLE_PARSER_LIBRARIES = [ - ["rss/xmlparser", :XMLParserParser], - ["rss/xmlscanner", :XMLScanParser], - ["rss/rexmlparser", :REXMLParser], - ] - end - - # The list of all available parsers, in constant form. - AVAILABLE_PARSERS = [] - - AVAILABLE_PARSER_LIBRARIES.each do |lib, parser| - begin - require lib - AVAILABLE_PARSERS.push(const_get(parser)) - rescue LoadError - end - end - - if AVAILABLE_PARSERS.empty? - raise XMLParserNotFound - end -end diff --git a/lib/rss/rexmlparser.rb b/lib/rss/rexmlparser.rb deleted file mode 100644 index ef0595e447..0000000000 --- a/lib/rss/rexmlparser.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: false -require "rexml/document" -require "rexml/streamlistener" - -module RSS - - class REXMLParser < BaseParser - - class << self - def listener - REXMLListener - end - end - - private - def _parse - begin - REXML::Document.parse_stream(@rss, @listener) - rescue RuntimeError => e - raise NotWellFormedError.new{e.message} - rescue REXML::ParseException => e - context = e.context - line = context[0] if context - raise NotWellFormedError.new(line){e.message} - end - end - - end - - class REXMLListener < BaseListener - - include REXML::StreamListener - include ListenerMixin - - class << self - def raise_for_undefined_entity? - false - end - end - - def xmldecl(version, encoding, standalone) - super(version, encoding, standalone == "yes") - # Encoding is converted to UTF-8 when REXML parse XML. - @encoding = 'UTF-8' - end - - alias_method(:cdata, :text) - end - -end diff --git a/lib/rss/rss.gemspec b/lib/rss/rss.gemspec deleted file mode 100644 index 04f2b2f42d..0000000000 --- a/lib/rss/rss.gemspec +++ /dev/null @@ -1,80 +0,0 @@ -begin - require_relative "lib/rss/version" -rescue LoadError - # for Ruby core repository - require_relative "version" -end - -Gem::Specification.new do |spec| - spec.name = "rss" - spec.version = RSS::VERSION - spec.authors = ["Kouhei Sutou"] - spec.email = ["kou@cozmixng.org"] - - spec.summary = %q{Family of libraries that support various formats of XML "feeds".} - spec.description = %q{Family of libraries that support various formats of XML "feeds".} - spec.homepage = "https://github.com/ruby/rss" - spec.license = "BSD-2-Clause" - - spec.files = [ - ".gitignore", - ".travis.yml", - "Gemfile", - "LICENSE.txt", - "NEWS.md", - "README.md", - "Rakefile", - "lib/rss.rb", - "lib/rss/0.9.rb", - "lib/rss/1.0.rb", - "lib/rss/2.0.rb", - "lib/rss/atom.rb", - "lib/rss/content.rb", - "lib/rss/content/1.0.rb", - "lib/rss/content/2.0.rb", - "lib/rss/converter.rb", - "lib/rss/dublincore.rb", - "lib/rss/dublincore/1.0.rb", - "lib/rss/dublincore/2.0.rb", - "lib/rss/dublincore/atom.rb", - "lib/rss/image.rb", - "lib/rss/itunes.rb", - "lib/rss/maker.rb", - "lib/rss/maker/0.9.rb", - "lib/rss/maker/1.0.rb", - "lib/rss/maker/2.0.rb", - "lib/rss/maker/atom.rb", - "lib/rss/maker/base.rb", - "lib/rss/maker/content.rb", - "lib/rss/maker/dublincore.rb", - "lib/rss/maker/entry.rb", - "lib/rss/maker/feed.rb", - "lib/rss/maker/image.rb", - "lib/rss/maker/itunes.rb", - "lib/rss/maker/slash.rb", - "lib/rss/maker/syndication.rb", - "lib/rss/maker/taxonomy.rb", - "lib/rss/maker/trackback.rb", - "lib/rss/parser.rb", - "lib/rss/rexmlparser.rb", - "lib/rss/rss.rb", - "lib/rss/slash.rb", - "lib/rss/syndication.rb", - "lib/rss/taxonomy.rb", - "lib/rss/trackback.rb", - "lib/rss/utils.rb", - "lib/rss/version.rb", - "lib/rss/xml-stylesheet.rb", - "lib/rss/xml.rb", - "lib/rss/xmlparser.rb", - "lib/rss/xmlscanner.rb", - "rss.gemspec", - ] - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] - - spec.add_development_dependency "bundler" - spec.add_development_dependency "rake" - spec.add_development_dependency "test-unit" -end diff --git a/lib/rss/rss.rb b/lib/rss/rss.rb deleted file mode 100644 index daa0837e9c..0000000000 --- a/lib/rss/rss.rb +++ /dev/null @@ -1,1342 +0,0 @@ -# frozen_string_literal: false -require "time" - -class Time - class << self - unless respond_to?(:w3cdtf) - # This method converts a W3CDTF string date/time format to Time object. - # - # The W3CDTF format is defined here: http://www.w3.org/TR/NOTE-datetime - # - # Time.w3cdtf('2003-02-15T13:50:05-05:00') - # # => 2003-02-15 10:50:05 -0800 - # Time.w3cdtf('2003-02-15T13:50:05-05:00').class - # # => Time - def w3cdtf(date) - if /\A\s* - (-?\d+)-(\d\d)-(\d\d) - (?:T - (\d\d):(\d\d)(?::(\d\d))? - (\.\d+)? - (Z|[+-]\d\d:\d\d)?)? - \s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8)) - datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i] - usec = 0 - usec = $7.to_f * 1000000 if $7 - zone = $8 - if zone - off = zone_offset(zone, datetime[0]) - datetime = apply_offset(*(datetime + [off])) - datetime << usec - time = Time.utc(*datetime) - force_zone!(time, zone, off) - time - else - datetime << usec - Time.local(*datetime) - end - else - raise ArgumentError.new("invalid date: #{date.inspect}") - end - end - end - end - - unless method_defined?(:w3cdtf) - # This method converts a Time object to a String. The String contains the - # time in W3CDTF date/time format. - # - # The W3CDTF format is defined here: http://www.w3.org/TR/NOTE-datetime - # - # Time.now.w3cdtf - # # => "2013-08-26T14:12:10.817124-07:00" - def w3cdtf - if usec.zero? - fraction_digits = 0 - else - fraction_digits = strftime('%6N').index(/0*\z/) - end - xmlschema(fraction_digits) - end - end -end - - -require "English" -require_relative "utils" -require_relative "converter" -require_relative "xml-stylesheet" - -module RSS - # The URI of the RSS 1.0 specification - URI = "http://purl.org/rss/1.0/" - - DEBUG = false # :nodoc: - - # The basic error all other RSS errors stem from. Rescue this error if you - # want to handle any given RSS error and you don't care about the details. - class Error < StandardError; end - - # RSS, being an XML-based format, has namespace support. If two namespaces are - # declared with the same name, an OverlappedPrefixError will be raised. - class OverlappedPrefixError < Error - attr_reader :prefix - def initialize(prefix) - @prefix = prefix - end - end - - # The InvalidRSSError error is the base class for a variety of errors - # related to a poorly-formed RSS feed. Rescue this error if you only - # care that a file could be invalid, but don't care how it is invalid. - class InvalidRSSError < Error; end - - # Since RSS is based on XML, it must have opening and closing tags that - # match. If they don't, a MissingTagError will be raised. - class MissingTagError < InvalidRSSError - attr_reader :tag, :parent - def initialize(tag, parent) - @tag, @parent = tag, parent - super("tag <#{tag}> is missing in tag <#{parent}>") - end - end - - # Some tags must only exist a specific number of times in a given RSS feed. - # If a feed has too many occurrences of one of these tags, a TooMuchTagError - # will be raised. - class TooMuchTagError < InvalidRSSError - attr_reader :tag, :parent - def initialize(tag, parent) - @tag, @parent = tag, parent - super("tag <#{tag}> is too much in tag <#{parent}>") - end - end - - # Certain attributes are required on specific tags in an RSS feed. If a feed - # is missing one of these attributes, a MissingAttributeError is raised. - class MissingAttributeError < InvalidRSSError - attr_reader :tag, :attribute - def initialize(tag, attribute) - @tag, @attribute = tag, attribute - super("attribute <#{attribute}> is missing in tag <#{tag}>") - end - end - - # RSS does not allow for free-form tag names, so if an RSS feed contains a - # tag that we don't know about, an UnknownTagError is raised. - class UnknownTagError < InvalidRSSError - attr_reader :tag, :uri - def initialize(tag, uri) - @tag, @uri = tag, uri - super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>") - end - end - - # Raised when an unexpected tag is encountered. - class NotExpectedTagError < InvalidRSSError - attr_reader :tag, :uri, :parent - def initialize(tag, uri, parent) - @tag, @uri, @parent = tag, uri, parent - super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>") - end - end - # For backward compatibility :X - NotExceptedTagError = NotExpectedTagError # :nodoc: - - # Attributes are in key-value form, and if there's no value provided for an - # attribute, a NotAvailableValueError will be raised. - class NotAvailableValueError < InvalidRSSError - attr_reader :tag, :value, :attribute - def initialize(tag, value, attribute=nil) - @tag, @value, @attribute = tag, value, attribute - message = "value <#{value}> of " - message << "attribute <#{attribute}> of " if attribute - message << "tag <#{tag}> is not available." - super(message) - end - end - - # Raised when an unknown conversion error occurs. - class UnknownConversionMethodError < Error - attr_reader :to, :from - def initialize(to, from) - @to = to - @from = from - super("can't convert to #{to} from #{from}.") - end - end - # for backward compatibility - UnknownConvertMethod = UnknownConversionMethodError # :nodoc: - - # Raised when a conversion failure occurs. - class ConversionError < Error - attr_reader :string, :to, :from - def initialize(string, to, from) - @string = string - @to = to - @from = from - super("can't convert #{@string} to #{to} from #{from}.") - end - end - - # Raised when a required variable is not set. - class NotSetError < Error - attr_reader :name, :variables - def initialize(name, variables) - @name = name - @variables = variables - super("required variables of #{@name} are not set: #{@variables.join(', ')}") - end - end - - # Raised when a RSS::Maker attempts to use an unknown maker. - class UnsupportedMakerVersionError < Error - attr_reader :version - def initialize(version) - @version = version - super("Maker doesn't support version: #{@version}") - end - end - - module BaseModel - include Utils - - def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil) - name ||= tag_name - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - writer_type, reader_type = type - def_corresponded_attr_writer name, writer_type - def_corresponded_attr_reader name, reader_type - install_element(name) do |n, elem_name| - <<-EOC - if @#{n} - "\#{@#{n}.to_s(need_convert, indent)}" - else - '' - end -EOC - end - end - alias_method(:install_have_attribute_element, :install_have_child_element) - - def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil) - name ||= tag_name - plural_name ||= "#{name}s" - add_have_children_element(name, plural_name) - add_plural_form(name, plural_name) - install_model(tag_name, uri, occurs, plural_name, true) - - def_children_accessor(name, plural_name) - install_element(name, "s") do |n, elem_name| - <<-EOC - rv = [] - @#{n}.each do |x| - value = "\#{x.to_s(need_convert, indent)}" - rv << value if /\\A\\s*\\z/ !~ value - end - rv.join("\n") -EOC - end - end - - def install_text_element(tag_name, uri, occurs, name=nil, type=nil, - disp_name=nil) - name ||= tag_name - disp_name ||= name - self::ELEMENTS << name unless self::ELEMENTS.include?(name) - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - def_corresponded_attr_writer(name, type, disp_name) - def_corresponded_attr_reader(name, type || :convert) - install_element(name) do |n, elem_name| - <<-EOC - if respond_to?(:#{n}_content) - content = #{n}_content - else - content = @#{n} - end - if content - rv = "\#{indent}<#{elem_name}>" - value = html_escape(content) - if need_convert - rv << convert(value) - else - rv << value - end - rv << "" - rv - else - '' - end -EOC - end - end - - def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil) - name ||= tag_name - type ||= :w3cdtf - disp_name ||= name - self::ELEMENTS << name - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - # accessor - convert_attr_reader name - date_writer(name, type, disp_name) - - install_element(name) do |n, elem_name| - <<-EOC - if @#{n} - rv = "\#{indent}<#{elem_name}>" - value = html_escape(@#{n}.#{type}) - if need_convert - rv << convert(value) - else - rv << value - end - rv << "" - rv - else - '' - end -EOC - end - - end - - private - def install_element(name, postfix="") - elem_name = name.sub('_', ':') - method_name = "#{name}_element#{postfix}" - add_to_element_method(method_name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{method_name}(need_convert=true, indent='') - #{yield(name, elem_name)} - end - private :#{method_name} -EOC - end - - def inherit_convert_attr_reader(*attrs) - attrs.each do |attr| - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{attr}_without_inherit - convert(@#{attr}) - end - - def #{attr} - if @#{attr} - #{attr}_without_inherit - elsif @parent - @parent.#{attr} - else - nil - end - end -EOC - end - end - - def uri_convert_attr_reader(*attrs) - attrs.each do |attr| - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{attr}_without_base - convert(@#{attr}) - end - - def #{attr} - value = #{attr}_without_base - return nil if value.nil? - if /\\A[a-z][a-z0-9+.\\-]*:/i =~ value - value - else - "\#{base}\#{value}" - end - end -EOC - end - end - - def convert_attr_reader(*attrs) - attrs.each do |attr| - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{attr} - convert(@#{attr}) - end -EOC - end - end - - def explicit_clean_other_attr_reader(*attrs) - attrs.each do |attr| - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader(:#{attr}) - def #{attr}? - ExplicitCleanOther.parse(@#{attr}) - end - EOC - end - end - - def yes_other_attr_reader(*attrs) - attrs.each do |attr| - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader(:#{attr}) - def #{attr}? - Utils::YesOther.parse(@#{attr}) - end - EOC - end - end - - def csv_attr_reader(*attrs) - separator = nil - if attrs.last.is_a?(Hash) - options = attrs.pop - separator = options[:separator] - end - separator ||= ", " - attrs.each do |attr| - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader(:#{attr}) - def #{attr}_content - if @#{attr}.nil? - @#{attr} - else - @#{attr}.join(#{separator.dump}) - end - end - EOC - end - end - - def date_writer(name, type, disp_name=name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if new_value.nil? - @#{name} = new_value - elsif new_value.kind_of?(Time) - @#{name} = new_value.dup - else - if @do_validate - begin - @#{name} = Time.__send__('#{type}', new_value) - rescue ArgumentError - raise NotAvailableValueError.new('#{disp_name}', new_value) - end - else - @#{name} = nil - if /\\A\\s*\\z/ !~ new_value.to_s - begin - unless Date._parse(new_value, false).empty? - @#{name} = Time.parse(new_value) - end - rescue ArgumentError - end - end - end - end - - # Is it need? - if @#{name} - class << @#{name} - undef_method(:to_s) - alias_method(:to_s, :#{type}) - end - end - - end -EOC - end - - def integer_writer(name, disp_name=name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if new_value.nil? - @#{name} = new_value - else - if @do_validate - begin - @#{name} = Integer(new_value) - rescue ArgumentError - raise NotAvailableValueError.new('#{disp_name}', new_value) - end - else - @#{name} = new_value.to_i - end - end - end -EOC - end - - def positive_integer_writer(name, disp_name=name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if new_value.nil? - @#{name} = new_value - else - if @do_validate - begin - tmp = Integer(new_value) - raise ArgumentError if tmp <= 0 - @#{name} = tmp - rescue ArgumentError - raise NotAvailableValueError.new('#{disp_name}', new_value) - end - else - @#{name} = new_value.to_i - end - end - end -EOC - end - - def boolean_writer(name, disp_name=name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if new_value.nil? - @#{name} = new_value - else - if @do_validate and - ![true, false, "true", "false"].include?(new_value) - raise NotAvailableValueError.new('#{disp_name}', new_value) - end - if [true, false].include?(new_value) - @#{name} = new_value - else - @#{name} = new_value == "true" - end - end - end -EOC - end - - def text_type_writer(name, disp_name=name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if @do_validate and - !["text", "html", "xhtml", nil].include?(new_value) - raise NotAvailableValueError.new('#{disp_name}', new_value) - end - @#{name} = new_value - end -EOC - end - - def content_writer(name, disp_name=name) - klass_name = "self.class::#{Utils.to_class_name(name)}" - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{name}=(new_value) - if new_value.is_a?(#{klass_name}) - @#{name} = new_value - else - @#{name} = #{klass_name}.new - @#{name}.content = new_value - end - end -EOC - end - - def explicit_clean_other_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(value) - value = (value ? "yes" : "no") if [true, false].include?(value) - @#{name} = value - end - EOC - end - - def yes_other_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(new_value) - if [true, false].include?(new_value) - new_value = new_value ? "yes" : "no" - end - @#{name} = new_value - end - EOC - end - - def csv_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(new_value) - @#{name} = Utils::CSV.parse(new_value) - end - EOC - end - - def csv_integer_writer(name, disp_name=name) - module_eval(<<-EOC, __FILE__, __LINE__ + 1) - def #{name}=(new_value) - @#{name} = Utils::CSV.parse(new_value) {|v| Integer(v)} - end - EOC - end - - def def_children_accessor(accessor_name, plural_name) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{plural_name} - @#{accessor_name} - end - - def #{accessor_name}(*args) - if args.empty? - @#{accessor_name}.first - else - @#{accessor_name}[*args] - end - end - - def #{accessor_name}=(*args) - receiver = self.class.name - warn("Don't use `\#{receiver}\##{accessor_name} = XXX'/" \ - "`\#{receiver}\#set_#{accessor_name}(XXX)'. " \ - "Those APIs are not sense of Ruby. " \ - "Use `\#{receiver}\##{plural_name} << XXX' instead of them.", uplevel: 1) - if args.size == 1 - @#{accessor_name}.push(args[0]) - else - @#{accessor_name}.__send__("[]=", *args) - end - end - alias_method(:set_#{accessor_name}, :#{accessor_name}=) -EOC - end - end - - module SetupMaker - def setup_maker(maker) - target = maker_target(maker) - unless target.nil? - setup_maker_attributes(target) - setup_maker_element(target) - setup_maker_elements(target) - end - end - - private - def maker_target(maker) - nil - end - - def setup_maker_attributes(target) - end - - def setup_maker_element(target) - self.class.need_initialize_variables.each do |var| - value = __send__(var) - next if value.nil? - if value.respond_to?("setup_maker") and - !not_need_to_call_setup_maker_variables.include?(var) - value.setup_maker(target) - else - setter = "#{var}=" - if target.respond_to?(setter) - target.__send__(setter, value) - end - end - end - end - - def not_need_to_call_setup_maker_variables - [] - end - - def setup_maker_elements(parent) - self.class.have_children_elements.each do |name, plural_name| - if parent.respond_to?(plural_name) - target = parent.__send__(plural_name) - __send__(plural_name).each do |elem| - elem.setup_maker(target) - end - end - end - end - end - - class Element - extend BaseModel - include Utils - extend Utils::InheritedReader - include SetupMaker - - INDENT = " " - - MUST_CALL_VALIDATORS = {} - MODELS = [] - GET_ATTRIBUTES = [] - HAVE_CHILDREN_ELEMENTS = [] - TO_ELEMENT_METHODS = [] - NEED_INITIALIZE_VARIABLES = [] - PLURAL_FORMS = {} - - class << self - def must_call_validators - inherited_hash_reader("MUST_CALL_VALIDATORS") - end - def models - inherited_array_reader("MODELS") - end - def get_attributes - inherited_array_reader("GET_ATTRIBUTES") - end - def have_children_elements - inherited_array_reader("HAVE_CHILDREN_ELEMENTS") - end - def to_element_methods - inherited_array_reader("TO_ELEMENT_METHODS") - end - def need_initialize_variables - inherited_array_reader("NEED_INITIALIZE_VARIABLES") - end - def plural_forms - inherited_hash_reader("PLURAL_FORMS") - end - - def inherited_base - ::RSS::Element - end - - def inherited(klass) - klass.const_set(:MUST_CALL_VALIDATORS, {}) - klass.const_set(:MODELS, []) - klass.const_set(:GET_ATTRIBUTES, []) - klass.const_set(:HAVE_CHILDREN_ELEMENTS, []) - klass.const_set(:TO_ELEMENT_METHODS, []) - klass.const_set(:NEED_INITIALIZE_VARIABLES, []) - klass.const_set(:PLURAL_FORMS, {}) - - tag_name = klass.name.split(/::/).last - tag_name[0, 1] = tag_name[0, 1].downcase - klass.instance_variable_set(:@tag_name, tag_name) - klass.instance_variable_set(:@have_content, false) - end - - def install_must_call_validator(prefix, uri) - self::MUST_CALL_VALIDATORS[uri] = prefix - end - - def install_model(tag, uri, occurs=nil, getter=nil, plural=false) - getter ||= tag - if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri} - m[2] = occurs - else - self::MODELS << [tag, uri, occurs, getter, plural] - end - end - - def install_get_attribute(name, uri, required=true, - type=nil, disp_name=nil, - element_name=nil) - disp_name ||= name - element_name ||= name - writer_type, reader_type = type - def_corresponded_attr_writer name, writer_type, disp_name - def_corresponded_attr_reader name, reader_type - if type == :boolean and /^is/ =~ name - alias_method "#{$POSTMATCH}?", name - end - self::GET_ATTRIBUTES << [name, uri, required, element_name] - add_need_initialize_variable(disp_name) - end - - def def_corresponded_attr_writer(name, type=nil, disp_name=nil) - disp_name ||= name - case type - when :integer - integer_writer name, disp_name - when :positive_integer - positive_integer_writer name, disp_name - when :boolean - boolean_writer name, disp_name - when :w3cdtf, :rfc822, :rfc2822 - date_writer name, type, disp_name - when :text_type - text_type_writer name, disp_name - when :content - content_writer name, disp_name - when :explicit_clean_other - explicit_clean_other_writer name, disp_name - when :yes_other - yes_other_writer name, disp_name - when :csv - csv_writer name - when :csv_integer - csv_integer_writer name - else - attr_writer name - end - end - - def def_corresponded_attr_reader(name, type=nil) - case type - when :inherit - inherit_convert_attr_reader name - when :uri - uri_convert_attr_reader name - when :explicit_clean_other - explicit_clean_other_attr_reader name - when :yes_other - yes_other_attr_reader name - when :csv - csv_attr_reader name - when :csv_integer - csv_attr_reader name, :separator => "," - else - convert_attr_reader name - end - end - - def content_setup(type=nil, disp_name=nil) - writer_type, reader_type = type - def_corresponded_attr_writer :content, writer_type, disp_name - def_corresponded_attr_reader :content, reader_type - @have_content = true - end - - def have_content? - @have_content - end - - def add_have_children_element(variable_name, plural_name) - self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name] - end - - def add_to_element_method(method_name) - self::TO_ELEMENT_METHODS << method_name - end - - def add_need_initialize_variable(variable_name) - self::NEED_INITIALIZE_VARIABLES << variable_name - end - - def add_plural_form(singular, plural) - self::PLURAL_FORMS[singular] = plural - end - - def required_prefix - nil - end - - def required_uri - "" - end - - def need_parent? - false - end - - def install_ns(prefix, uri) - if self::NSPOOL.has_key?(prefix) - raise OverlappedPrefixError.new(prefix) - end - self::NSPOOL[prefix] = uri - end - - def tag_name - @tag_name - end - end - - attr_accessor :parent, :do_validate - - def initialize(do_validate=true, attrs=nil) - @parent = nil - @converter = nil - if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array)) - do_validate, attrs = true, do_validate - end - @do_validate = do_validate - initialize_variables(attrs || {}) - end - - def tag_name - self.class.tag_name - end - - def full_name - tag_name - end - - def converter=(converter) - @converter = converter - targets = children.dup - self.class.have_children_elements.each do |variable_name, plural_name| - targets.concat(__send__(plural_name)) - end - targets.each do |target| - target.converter = converter unless target.nil? - end - end - - def convert(value) - if @converter - @converter.convert(value) - else - value - end - end - - def valid?(ignore_unknown_element=true) - validate(ignore_unknown_element) - true - rescue RSS::Error - false - end - - def validate(ignore_unknown_element=true) - do_validate = @do_validate - @do_validate = true - validate_attribute - __validate(ignore_unknown_element) - ensure - @do_validate = do_validate - end - - def validate_for_stream(tags, ignore_unknown_element=true) - validate_attribute - __validate(ignore_unknown_element, tags, false) - end - - def to_s(need_convert=true, indent='') - if self.class.have_content? - return "" if !empty_content? and !content_is_set? - rv = tag(indent) do |next_indent| - if empty_content? - "" - else - xmled_content - end - end - else - rv = tag(indent) do |next_indent| - self.class.to_element_methods.collect do |method_name| - __send__(method_name, false, next_indent) - end - end - end - rv = convert(rv) if need_convert - rv - end - - def have_xml_content? - false - end - - def need_base64_encode? - false - end - - def set_next_element(tag_name, next_element) - klass = next_element.class - prefix = "" - prefix << "#{klass.required_prefix}_" if klass.required_prefix - key = "#{prefix}#{tag_name.gsub(/-/, '_')}" - if self.class.plural_forms.has_key?(key) - ary = __send__("#{self.class.plural_forms[key]}") - ary << next_element - else - __send__("#{key}=", next_element) - end - end - - protected - def have_required_elements? - self.class::MODELS.all? do |tag, uri, occurs, getter| - if occurs.nil? or occurs == "+" - child = __send__(getter) - if child.is_a?(Array) - children = child - children.any? {|c| c.have_required_elements?} - else - not child.nil? - end - else - true - end - end - end - - private - def initialize_variables(attrs) - normalized_attrs = {} - attrs.each do |key, value| - normalized_attrs[key.to_s] = value - end - self.class.need_initialize_variables.each do |variable_name| - value = normalized_attrs[variable_name.to_s] - if value - __send__("#{variable_name}=", value) - else - instance_variable_set("@#{variable_name}", nil) - end - end - initialize_have_children_elements - @content = normalized_attrs["content"] if self.class.have_content? - end - - def initialize_have_children_elements - self.class.have_children_elements.each do |variable_name, plural_name| - instance_variable_set("@#{variable_name}", []) - end - end - - def tag(indent, additional_attrs={}, &block) - next_indent = indent + INDENT - - attrs = collect_attrs - return "" if attrs.nil? - - return "" unless have_required_elements? - - attrs.update(additional_attrs) - start_tag = make_start_tag(indent, next_indent, attrs.dup) - - if block - content = block.call(next_indent) - else - content = [] - end - - if content.is_a?(String) - content = [content] - start_tag << ">" - end_tag = "" - else - content = content.reject{|x| x.empty?} - if content.empty? - return "" if attrs.empty? - end_tag = "/>" - else - start_tag << ">\n" - end_tag = "\n#{indent}" - end - end - - start_tag + content.join("\n") + end_tag - end - - def make_start_tag(indent, next_indent, attrs) - start_tag = ["#{indent}<#{full_name}"] - unless attrs.empty? - start_tag << attrs.collect do |key, value| - %Q[#{h key}="#{h value}"] - end.join("\n#{next_indent}") - end - start_tag.join(" ") - end - - def collect_attrs - attrs = {} - _attrs.each do |name, required, alias_name| - value = __send__(alias_name || name) - return nil if required and value.nil? - next if value.nil? - return nil if attrs.has_key?(name) - attrs[name] = value - end - attrs - end - - def tag_name_with_prefix(prefix) - "#{prefix}:#{tag_name}" - end - - # For backward compatibility - def calc_indent - '' - end - - def children - rv = [] - self.class.models.each do |name, uri, occurs, getter| - value = __send__(getter) - next if value.nil? - value = [value] unless value.is_a?(Array) - value.each do |v| - rv << v if v.is_a?(Element) - end - end - rv - end - - def _tags - rv = [] - self.class.models.each do |name, uri, occurs, getter, plural| - value = __send__(getter) - next if value.nil? - if plural and value.is_a?(Array) - rv.concat([[uri, name]] * value.size) - else - rv << [uri, name] - end - end - rv - end - - def _attrs - self.class.get_attributes.collect do |name, uri, required, element_name| - [element_name, required, name] - end - end - - def __validate(ignore_unknown_element, tags=_tags, recursive=true) - if recursive - children.compact.each do |child| - child.validate - end - end - must_call_validators = self.class.must_call_validators - tags = tag_filter(tags.dup) - p tags if DEBUG - must_call_validators.each do |uri, prefix| - _validate(ignore_unknown_element, tags[uri], uri) - meth = "#{prefix}_validate" - if !prefix.empty? and respond_to?(meth, true) - __send__(meth, ignore_unknown_element, tags[uri], uri) - end - end - end - - def validate_attribute - _attrs.each do |a_name, required, alias_name| - value = instance_variable_get("@#{alias_name || a_name}") - if required and value.nil? - raise MissingAttributeError.new(tag_name, a_name) - end - __send__("#{alias_name || a_name}=", value) - end - end - - def _validate(ignore_unknown_element, tags, uri, models=self.class.models) - count = 1 - do_redo = false - not_shift = false - tag = nil - models = models.find_all {|model| model[1] == uri} - element_names = models.collect {|model| model[0]} - if tags - tags_size = tags.size - tags = tags.sort_by {|x| element_names.index(x) || tags_size} - end - - models.each_with_index do |model, i| - name, _, occurs, = model - - if DEBUG - p "before" - p tags - p model - end - - if not_shift - not_shift = false - elsif tags - tag = tags.shift - end - - if DEBUG - p "mid" - p count - end - - case occurs - when '?' - if count > 2 - raise TooMuchTagError.new(name, tag_name) - else - if name == tag - do_redo = true - else - not_shift = true - end - end - when '*' - if name == tag - do_redo = true - else - not_shift = true - end - when '+' - if name == tag - do_redo = true - else - if count > 1 - not_shift = true - else - raise MissingTagError.new(name, tag_name) - end - end - else - if name == tag - if models[i+1] and models[i+1][0] != name and - tags and tags.first == name - raise TooMuchTagError.new(name, tag_name) - end - else - raise MissingTagError.new(name, tag_name) - end - end - - if DEBUG - p "after" - p not_shift - p do_redo - p tag - end - - if do_redo - do_redo = false - count += 1 - redo - else - count = 1 - end - - end - - if !ignore_unknown_element and !tags.nil? and !tags.empty? - raise NotExpectedTagError.new(tags.first, uri, tag_name) - end - - end - - def tag_filter(tags) - rv = {} - tags.each do |tag| - rv[tag[0]] = [] unless rv.has_key?(tag[0]) - rv[tag[0]].push(tag[1]) - end - rv - end - - def empty_content? - false - end - - def content_is_set? - if have_xml_content? - __send__(self.class.xml_getter) - else - content - end - end - - def xmled_content - if have_xml_content? - __send__(self.class.xml_getter).to_s - else - _content = content - _content = [_content].pack("m0") if need_base64_encode? - h(_content) - end - end - end - - module RootElementMixin - - include XMLStyleSheetMixin - - attr_reader :output_encoding - attr_reader :feed_type, :feed_subtype, :feed_version - attr_accessor :version, :encoding, :standalone - def initialize(feed_version, version=nil, encoding=nil, standalone=nil) - super() - @feed_type = nil - @feed_subtype = nil - @feed_version = feed_version - @version = version || '1.0' - @encoding = encoding - @standalone = standalone - @output_encoding = nil - end - - def feed_info - [@feed_type, @feed_version, @feed_subtype] - end - - def output_encoding=(enc) - @output_encoding = enc - self.converter = Converter.new(@output_encoding, @encoding) - end - - def setup_maker(maker) - maker.version = version - maker.encoding = encoding - maker.standalone = standalone - - xml_stylesheets.each do |xss| - xss.setup_maker(maker) - end - - super - end - - def to_feed(type, &block) - Maker.make(type) do |maker| - setup_maker(maker) - block.call(maker) if block - end - end - - def to_rss(type, &block) - to_feed("rss#{type}", &block) - end - - def to_atom(type, &block) - to_feed("atom:#{type}", &block) - end - - def to_xml(type=nil, &block) - if type.nil? or same_feed_type?(type) - to_s - else - to_feed(type, &block).to_s - end - end - - private - def same_feed_type?(type) - if /^(atom|rss)?(\d+\.\d+)?(?::(.+))?$/i =~ type - feed_type = ($1 || @feed_type).downcase - feed_version = $2 || @feed_version - feed_subtype = $3 || @feed_subtype - [feed_type, feed_version, feed_subtype] == feed_info - else - false - end - end - - def tag(indent, attrs={}, &block) - rv = super(indent, ns_declarations.merge(attrs), &block) - return rv if rv.empty? - "#{xmldecl}#{xml_stylesheet_pi}#{rv}" - end - - def xmldecl - rv = %Q[\n" - rv - end - - def ns_declarations - decls = {} - self.class::NSPOOL.collect do |prefix, uri| - prefix = ":#{prefix}" unless prefix.empty? - decls["xmlns#{prefix}"] = uri - end - decls - end - - def maker_target(target) - target - end - end -end diff --git a/lib/rss/slash.rb b/lib/rss/slash.rb deleted file mode 100644 index 0055fc9f88..0000000000 --- a/lib/rss/slash.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: false -require 'rss/1.0' - -module RSS - # The prefix for the Slash XML namespace. - SLASH_PREFIX = 'slash' - # The URI of the Slash specification. - SLASH_URI = "http://purl.org/rss/1.0/modules/slash/" - - RDF.install_ns(SLASH_PREFIX, SLASH_URI) - - module SlashModel - extend BaseModel - - ELEMENT_INFOS = \ - [ - ["section"], - ["department"], - ["comments", :positive_integer], - ["hit_parade", :csv_integer], - ] - - class << self - def append_features(klass) - super - - return if klass.instance_of?(Module) - klass.install_must_call_validator(SLASH_PREFIX, SLASH_URI) - ELEMENT_INFOS.each do |name, type, *additional_infos| - full_name = "#{SLASH_PREFIX}_#{name}" - klass.install_text_element(full_name, SLASH_URI, "?", - full_name, type, name) - end - - klass.module_eval do - alias_method(:slash_hit_parades, :slash_hit_parade) - undef_method(:slash_hit_parade) - alias_method(:slash_hit_parade, :slash_hit_parade_content) - end - end - end - end - - class RDF - class Item; include SlashModel; end - end - - SlashModel::ELEMENT_INFOS.each do |name, type| - accessor_base = "#{SLASH_PREFIX}_#{name}" - BaseListener.install_get_text_element(SLASH_URI, name, accessor_base) - end -end diff --git a/lib/rss/syndication.rb b/lib/rss/syndication.rb deleted file mode 100644 index 8f9620f9f3..0000000000 --- a/lib/rss/syndication.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: false -require "rss/1.0" - -module RSS - # The prefix for the Syndication XML namespace. - SY_PREFIX = 'sy' - # The URI of the Syndication specification. - SY_URI = "http://purl.org/rss/1.0/modules/syndication/" - - RDF.install_ns(SY_PREFIX, SY_URI) - - module SyndicationModel - - extend BaseModel - - ELEMENTS = [] - - def self.append_features(klass) - super - - klass.install_must_call_validator(SY_PREFIX, SY_URI) - klass.module_eval do - [ - ["updatePeriod"], - ["updateFrequency", :positive_integer] - ].each do |name, type| - install_text_element(name, SY_URI, "?", - "#{SY_PREFIX}_#{name}", type, - "#{SY_PREFIX}:#{name}") - end - - %w(updateBase).each do |name| - install_date_element(name, SY_URI, "?", - "#{SY_PREFIX}_#{name}", 'w3cdtf', - "#{SY_PREFIX}:#{name}") - end - end - - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - alias_method(:_sy_updatePeriod=, :sy_updatePeriod=) - def sy_updatePeriod=(new_value) - new_value = new_value.strip - validate_sy_updatePeriod(new_value) if @do_validate - self._sy_updatePeriod = new_value - end - EOC - end - - private - SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly) - def validate_sy_updatePeriod(value) # :nodoc: - unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value) - raise NotAvailableValueError.new("updatePeriod", value) - end - end - end - - class RDF - class Channel; include SyndicationModel; end - end - - prefix_size = SY_PREFIX.size + 1 - SyndicationModel::ELEMENTS.uniq! - SyndicationModel::ELEMENTS.each do |full_name| - name = full_name[prefix_size..-1] - BaseListener.install_get_text_element(SY_URI, name, full_name) - end - -end diff --git a/lib/rss/taxonomy.rb b/lib/rss/taxonomy.rb deleted file mode 100644 index 50688ee6c1..0000000000 --- a/lib/rss/taxonomy.rb +++ /dev/null @@ -1,148 +0,0 @@ -# frozen_string_literal: false -require "rss/1.0" -require_relative "dublincore" - -module RSS - # The prefix for the Taxonomy XML namespace. - TAXO_PREFIX = "taxo" - # The URI for the specification of the Taxonomy XML namespace. - TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/" - - RDF.install_ns(TAXO_PREFIX, TAXO_URI) - - # The listing of all the taxonomy elements, with the appropriate namespace. - TAXO_ELEMENTS = [] - - %w(link).each do |name| - full_name = "#{TAXO_PREFIX}_#{name}" - BaseListener.install_get_text_element(TAXO_URI, name, full_name) - TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}" - end - - %w(topic topics).each do |name| - class_name = Utils.to_class_name(name) - BaseListener.install_class_name(TAXO_URI, name, "Taxonomy#{class_name}") - TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}" - end - - module TaxonomyTopicsModel - extend BaseModel - - def self.append_features(klass) - super - - klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI) - %w(topics).each do |name| - klass.install_have_child_element(name, TAXO_URI, "?", - "#{TAXO_PREFIX}_#{name}") - end - end - - class TaxonomyTopics < Element - include RSS10 - - Bag = ::RSS::RDF::Bag - - class << self - def required_prefix - TAXO_PREFIX - end - - def required_uri - TAXO_URI - end - end - - @tag_name = "topics" - - install_have_child_element("Bag", RDF::URI, nil) - install_must_call_validator('rdf', RDF::URI) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.Bag = args[0] - end - self.Bag ||= Bag.new - end - - def full_name - tag_name_with_prefix(TAXO_PREFIX) - end - - def maker_target(target) - target.taxo_topics - end - - def resources - if @Bag - @Bag.lis.collect do |li| - li.resource - end - else - [] - end - end - end - end - - module TaxonomyTopicModel - extend BaseModel - - def self.append_features(klass) - super - var_name = "#{TAXO_PREFIX}_topic" - klass.install_have_children_element("topic", TAXO_URI, "*", var_name) - end - - class TaxonomyTopic < Element - include RSS10 - - include DublinCoreModel - include TaxonomyTopicsModel - - class << self - def required_prefix - TAXO_PREFIX - end - - def required_uri - TAXO_URI - end - end - - @tag_name = "topic" - - install_get_attribute("about", ::RSS::RDF::URI, true, nil, nil, - "#{RDF::PREFIX}:about") - install_text_element("link", TAXO_URI, "?", "#{TAXO_PREFIX}_link") - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.about = args[0] - end - end - - def full_name - tag_name_with_prefix(TAXO_PREFIX) - end - - def maker_target(target) - target.new_taxo_topic - end - end - end - - class RDF - include TaxonomyTopicModel - class Channel - include TaxonomyTopicsModel - end - class Item; include TaxonomyTopicsModel; end - end -end diff --git a/lib/rss/trackback.rb b/lib/rss/trackback.rb deleted file mode 100644 index 1a3c3849b5..0000000000 --- a/lib/rss/trackback.rb +++ /dev/null @@ -1,291 +0,0 @@ -# frozen_string_literal: false -# This file contains the implementation of trackbacks. It is entirely internal -# and not useful to outside developers. -require 'rss/1.0' -require 'rss/2.0' - -module RSS # :nodoc: all - - TRACKBACK_PREFIX = 'trackback' - TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/' - - RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) - Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) - - module TrackBackUtils - private - def trackback_validate(ignore_unknown_element, tags, uri) - return if tags.nil? - if tags.find {|tag| tag == "about"} and - !tags.find {|tag| tag == "ping"} - raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name) - end - end - end - - module BaseTrackBackModel - - ELEMENTS = %w(ping about) - - def append_features(klass) - super - - unless klass.class == Module - klass.module_eval {include TrackBackUtils} - - klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI) - %w(ping).each do |name| - var_name = "#{TRACKBACK_PREFIX}_#{name}" - klass_name = "TrackBack#{Utils.to_class_name(name)}" - klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__) - remove_method :#{var_name} - def #{var_name} - @#{var_name} and @#{var_name}.value - end - - remove_method :#{var_name}= - def #{var_name}=(value) - @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value) - end - EOC - end - - [%w(about s)].each do |name, postfix| - var_name = "#{TRACKBACK_PREFIX}_#{name}" - klass_name = "TrackBack#{Utils.to_class_name(name)}" - klass.install_have_children_element(name, TRACKBACK_URI, "*", - var_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__) - remove_method :#{var_name} - def #{var_name}(*args) - if args.empty? - @#{var_name}.first and @#{var_name}.first.value - else - ret = @#{var_name}.__send__("[]", *args) - if ret.is_a?(Array) - ret.collect {|x| x.value} - else - ret.value - end - end - end - - remove_method :#{var_name}= - remove_method :set_#{var_name} - def #{var_name}=(*args) - if args.size == 1 - item = Utils.new_with_value_if_need(#{klass_name}, args[0]) - @#{var_name}.push(item) - else - new_val = args.last - if new_val.is_a?(Array) - new_val = new_value.collect do |val| - Utils.new_with_value_if_need(#{klass_name}, val) - end - else - new_val = Utils.new_with_value_if_need(#{klass_name}, new_val) - end - @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val])) - end - end - alias set_#{var_name} #{var_name}= - EOC - end - end - end - end - - module TrackBackModel10 - extend BaseModel - extend BaseTrackBackModel - - class TrackBackPing < Element - include RSS10 - - class << self - - def required_prefix - TRACKBACK_PREFIX - end - - def required_uri - TRACKBACK_URI - end - - end - - @tag_name = "ping" - - [ - ["resource", ::RSS::RDF::URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{::RSS::RDF::PREFIX}:#{name}") - end - - alias_method(:value, :resource) - alias_method(:value=, :resource=) - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.resource = args[0] - end - end - - def full_name - tag_name_with_prefix(TRACKBACK_PREFIX) - end - end - - class TrackBackAbout < Element - include RSS10 - - class << self - - def required_prefix - TRACKBACK_PREFIX - end - - def required_uri - TRACKBACK_URI - end - - end - - @tag_name = "about" - - [ - ["resource", ::RSS::RDF::URI, true] - ].each do |name, uri, required| - install_get_attribute(name, uri, required, nil, nil, - "#{::RSS::RDF::PREFIX}:#{name}") - end - - alias_method(:value, :resource) - alias_method(:value=, :resource=) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.resource = args[0] - end - end - - def full_name - tag_name_with_prefix(TRACKBACK_PREFIX) - end - - private - def maker_target(abouts) - abouts.new_about - end - - def setup_maker_attributes(about) - about.resource = self.resource - end - - end - end - - module TrackBackModel20 - extend BaseModel - extend BaseTrackBackModel - - class TrackBackPing < Element - include RSS09 - - @tag_name = "ping" - - content_setup - - class << self - - def required_prefix - TRACKBACK_PREFIX - end - - def required_uri - TRACKBACK_URI - end - - end - - alias_method(:value, :content) - alias_method(:value=, :content=) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.content = args[0] - end - end - - def full_name - tag_name_with_prefix(TRACKBACK_PREFIX) - end - - end - - class TrackBackAbout < Element - include RSS09 - - @tag_name = "about" - - content_setup - - class << self - - def required_prefix - TRACKBACK_PREFIX - end - - def required_uri - TRACKBACK_URI - end - - end - - alias_method(:value, :content) - alias_method(:value=, :content=) - - def initialize(*args) - if Utils.element_initialize_arguments?(args) - super - else - super() - self.content = args[0] - end - end - - def full_name - tag_name_with_prefix(TRACKBACK_PREFIX) - end - - end - end - - class RDF - class Item; include TrackBackModel10; end - end - - class Rss - class Channel - class Item; include TrackBackModel20; end - end - end - - BaseTrackBackModel::ELEMENTS.each do |name| - class_name = Utils.to_class_name(name) - BaseListener.install_class_name(TRACKBACK_URI, name, - "TrackBack#{class_name}") - end - - BaseTrackBackModel::ELEMENTS.collect! {|name| "#{TRACKBACK_PREFIX}_#{name}"} -end diff --git a/lib/rss/utils.rb b/lib/rss/utils.rb deleted file mode 100644 index 9203df9a9b..0000000000 --- a/lib/rss/utils.rb +++ /dev/null @@ -1,200 +0,0 @@ -# frozen_string_literal: false -module RSS - - ## - # RSS::Utils is a module that holds various utility functions that are used - # across many parts of the rest of the RSS library. Like most modules named - # some variant of 'util', its methods are probably not particularly useful - # to those who aren't developing the library itself. - module Utils - module_function - - # Given a +name+ in a name_with_underscores or a name-with-dashes format, - # returns the CamelCase version of +name+. - # - # If the +name+ is already CamelCased, nothing happens. - # - # Examples: - # - # require 'rss/utils' - # - # RSS::Utils.to_class_name("sample_name") - # # => "SampleName" - # RSS::Utils.to_class_name("with-dashes") - # # => "WithDashes" - # RSS::Utils.to_class_name("CamelCase") - # # => "CamelCase" - def to_class_name(name) - name.split(/[_\-]/).collect do |part| - "#{part[0, 1].upcase}#{part[1..-1]}" - end.join("") - end - - # Returns an array of two elements: the filename where the calling method - # is located, and the line number where it is defined. - # - # Takes an optional argument +i+, which specifies how many callers up the - # stack to look. - # - # Examples: - # - # require 'rss/utils' - # - # def foo - # p RSS::Utils.get_file_and_line_from_caller - # p RSS::Utils.get_file_and_line_from_caller(1) - # end - # - # def bar - # foo - # end - # - # def baz - # bar - # end - # - # baz - # # => ["test.rb", 5] - # # => ["test.rb", 9] - # - # If +i+ is not given, or is the default value of 0, it attempts to figure - # out the correct value. This is useful when in combination with - # instance_eval. For example: - # - # require 'rss/utils' - # - # def foo - # p RSS::Utils.get_file_and_line_from_caller(1) - # end - # - # def bar - # foo - # end - # - # instance_eval <<-RUBY, *RSS::Utils.get_file_and_line_from_caller - # def baz - # bar - # end - # RUBY - # - # baz - # - # # => ["test.rb", 8] - def get_file_and_line_from_caller(i=0) - file, line, = caller[i].split(':') - line = line.to_i - line += 1 if i.zero? - [file, line] - end - - # Takes a string +s+ with some HTML in it, and escapes '&', '"', '<' and '>', by - # replacing them with the appropriate entities. - # - # This method is also aliased to h, for convenience. - # - # Examples: - # - # require 'rss/utils' - # - # RSS::Utils.html_escape("Dungeons & Dragons") - # # => "Dungeons & Dragons" - # RSS::Utils.h(">_>") - # # => ">_>" - def html_escape(s) - s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/ "text/xsl", - "css" => "text/css", - } - - attr_accessor(*ATTRIBUTES) - attr_accessor(:do_validate) - def initialize(*attrs) - if attrs.size == 1 and - (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array)) - attrs = attrs.first - end - @do_validate = true - ATTRIBUTES.each do |attr| - __send__("#{attr}=", nil) - end - vars = ATTRIBUTES.dup - vars.unshift(:do_validate) - attrs.each do |name, value| - if vars.include?(name.to_s) - __send__("#{name}=", value) - end - end - end - - def to_s - rv = "" - if @href - rv << %Q[] - end - rv - end - - remove_method(:href=) - def href=(value) - @href = value - if @href and @type.nil? - @type = guess_type(@href) - end - @href - end - - remove_method(:alternate=) - def alternate=(value) - if value.nil? or /\A(?:yes|no)\z/ =~ value - @alternate = value - else - if @do_validate - args = ["?xml-stylesheet?", %Q[alternate="#{value}"]] - raise NotAvailableValueError.new(*args) - end - end - @alternate - end - - def setup_maker(maker) - xss = maker.xml_stylesheets.new_xml_stylesheet - ATTRIBUTES.each do |attr| - xss.__send__("#{attr}=", __send__(attr)) - end - end - - private - def guess_type(filename) - /\.([^.]+)$/ =~ filename - GUESS_TABLE[$1] - end - - end -end diff --git a/lib/rss/xml.rb b/lib/rss/xml.rb deleted file mode 100644 index b74630295f..0000000000 --- a/lib/rss/xml.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: false -require_relative "utils" - -module RSS - module XML - class Element - include Enumerable - - attr_reader :name, :prefix, :uri, :attributes, :children - def initialize(name, prefix=nil, uri=nil, attributes={}, children=[]) - @name = name - @prefix = prefix - @uri = uri - @attributes = attributes - if children.is_a?(String) or !children.respond_to?(:each) - @children = [children] - else - @children = children - end - end - - def [](name) - @attributes[name] - end - - def []=(name, value) - @attributes[name] = value - end - - def <<(child) - @children << child - end - - def each(&block) - @children.each(&block) - end - - def ==(other) - other.kind_of?(self.class) and - @name == other.name and - @uri == other.uri and - @attributes == other.attributes and - @children == other.children - end - - def to_s - rv = "<#{full_name}" - attributes.each do |key, value| - rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\"" - end - if children.empty? - rv << "/>" - else - rv << ">" - children.each do |child| - rv << child.to_s - end - rv << "" - end - rv - end - - def full_name - if @prefix - "#{@prefix}:#{@name}" - else - @name - end - end - end - end -end diff --git a/lib/rss/xmlparser.rb b/lib/rss/xmlparser.rb deleted file mode 100644 index cb2dd2afdd..0000000000 --- a/lib/rss/xmlparser.rb +++ /dev/null @@ -1,95 +0,0 @@ -# frozen_string_literal: false -begin - require "xml/parser" -rescue LoadError - require "xmlparser" -end - -begin - require "xml/encoding-ja" -rescue LoadError - require "xmlencoding-ja" - if defined?(Kconv) - module XMLEncoding_ja - class SJISHandler - include Kconv - end - end - end -end - -module XML - class Parser - unless defined?(Error) - # This error is legacy, so we just set it to the new one - Error = ::XMLParserError # :nodoc: - end - end -end - -module RSS - - class REXMLLikeXMLParser < ::XML::Parser - - include ::XML::Encoding_ja - - def listener=(listener) - @listener = listener - end - - def startElement(name, attrs) - @listener.tag_start(name, attrs) - end - - def endElement(name) - @listener.tag_end(name) - end - - def character(data) - @listener.text(data) - end - - def xmlDecl(version, encoding, standalone) - @listener.xmldecl(version, encoding, standalone == 1) - end - - def processingInstruction(target, content) - @listener.instruction(target, content) - end - - end - - class XMLParserParser < BaseParser - - class << self - def listener - XMLParserListener - end - end - - private - def _parse - begin - parser = REXMLLikeXMLParser.new - parser.listener = @listener - parser.parse(@rss) - rescue ::XML::Parser::Error => e - raise NotWellFormedError.new(parser.line){e.message} - end - end - - end - - class XMLParserListener < BaseListener - - include ListenerMixin - - def xmldecl(version, encoding, standalone) - super - # Encoding is converted to UTF-8 when XMLParser parses XML. - @encoding = 'UTF-8' - end - - end - -end diff --git a/lib/rss/xmlscanner.rb b/lib/rss/xmlscanner.rb deleted file mode 100644 index 6e3b13d2f5..0000000000 --- a/lib/rss/xmlscanner.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: false -require 'xmlscan/scanner' -require 'stringio' - -module RSS - - class XMLScanParser < BaseParser - - class << self - def listener - XMLScanListener - end - end - - private - def _parse - begin - if @rss.is_a?(String) - input = StringIO.new(@rss) - else - input = @rss - end - scanner = XMLScan::XMLScanner.new(@listener) - scanner.parse(input) - rescue XMLScan::Error => e - lineno = e.lineno || scanner.lineno || input.lineno - raise NotWellFormedError.new(lineno){e.message} - end - end - - end - - class XMLScanListener < BaseListener - - include XMLScan::Visitor - include ListenerMixin - - ENTITIES = { - 'lt' => '<', - 'gt' => '>', - 'amp' => '&', - 'quot' => '"', - 'apos' => '\'' - } - - def on_xmldecl_version(str) - @version = str - end - - def on_xmldecl_encoding(str) - @encoding = str - end - - def on_xmldecl_standalone(str) - @standalone = str - end - - def on_xmldecl_end - xmldecl(@version, @encoding, @standalone == "yes") - end - - alias_method(:on_pi, :instruction) - alias_method(:on_chardata, :text) - alias_method(:on_cdata, :text) - - def on_etag(name) - tag_end(name) - end - - def on_entityref(ref) - text(entity(ref)) - end - - def on_charref(code) - text([code].pack('U')) - end - - alias_method(:on_charref_hex, :on_charref) - - def on_stag(name) - @attrs = {} - end - - def on_attribute(name) - @attrs[name] = @current_attr = '' - end - - def on_attr_value(str) - @current_attr << str - end - - def on_attr_entityref(ref) - @current_attr << entity(ref) - end - - def on_attr_charref(code) - @current_attr << [code].pack('U') - end - - alias_method(:on_attr_charref_hex, :on_attr_charref) - - def on_stag_end(name) - tag_start(name, @attrs) - end - - def on_stag_end_empty(name) - tag_start(name, @attrs) - tag_end(name) - end - - private - def entity(ref) - ent = ENTITIES[ref] - if ent - ent - else - wellformed_error("undefined entity: #{ref}") - end - end - end - -end -- cgit v1.2.3