require "rss/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