From 71976790ec02f88d9fb51fab151312124f6df223 Mon Sep 17 00:00:00 2001 From: kou Date: Sun, 5 Aug 2007 03:03:05 +0000 Subject: * lib/rss, sample/rss, test/rss: - 0.1.7 -> 0.1.8. - supported . - reverted backward incompatibility API changes introduced 0.1.7. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rss/maker/0.9.rb | 13 +- lib/rss/maker/1.0.rb | 6 +- lib/rss/maker/2.0.rb | 8 +- lib/rss/maker/atom.rb | 4 +- lib/rss/maker/base.rb | 518 ++++++++++++++++++------------------------- lib/rss/maker/content.rb | 13 +- lib/rss/maker/dublincore.rb | 62 ++---- lib/rss/maker/entry.rb | 14 +- lib/rss/maker/feed.rb | 14 +- lib/rss/maker/image.rb | 38 +--- lib/rss/maker/itunes.rb | 248 +++++++++++++++++++++ lib/rss/maker/syndication.rb | 13 +- lib/rss/maker/taxonomy.rb | 52 +---- lib/rss/maker/trackback.rb | 38 +--- 14 files changed, 536 insertions(+), 505 deletions(-) create mode 100644 lib/rss/maker/itunes.rb (limited to 'lib/rss/maker') diff --git a/lib/rss/maker/0.9.rb b/lib/rss/maker/0.9.rb index dd75c9289b..c83597dfd5 100644 --- a/lib/rss/maker/0.9.rb +++ b/lib/rss/maker/0.9.rb @@ -22,7 +22,6 @@ module RSS end class Channel < ChannelBase - def to_feed(rss) channel = Rss::Channel.new set = setup_values(channel) @@ -63,8 +62,8 @@ module RSS def not_set_required_variables vars = super - vars << "description" unless description.have_required_values? - vars << "title" unless title.have_required_values? + vars << "description" unless description {|d| d.have_required_values?} + vars << "title" unless title {|t| t.have_required_values?} vars end @@ -259,7 +258,7 @@ module RSS def to_feed(rss) item = Rss::Channel::Item.new set = setup_values(item) - if set or title.have_required_values? + if set or title {|t| t.have_required_values?} rss.items << item set_parent(item, rss.channel) setup_other_elements(rss, item) @@ -268,10 +267,6 @@ module RSS end end - def have_required_values? - super and title.have_required_values? - end - private def required_variable_names %w(link) @@ -279,7 +274,7 @@ module RSS def not_set_required_variables vars = super - vars << "title" unless title.have_required_values? + vars << "title" unless title {|t| t.have_required_values?} vars end diff --git a/lib/rss/maker/1.0.rb b/lib/rss/maker/1.0.rb index 12608ad94a..c4af6e9b2e 100644 --- a/lib/rss/maker/1.0.rb +++ b/lib/rss/maker/1.0.rb @@ -83,8 +83,8 @@ module RSS def not_set_required_variables vars = super - vars << "description" unless description.have_required_values? - vars << "title" unless title.have_required_values? + vars << "description" unless description {|d| d.have_required_values?} + vars << "title" unless title {|t| t.have_required_values?} vars end @@ -256,7 +256,7 @@ module RSS def not_set_required_variables set_default_values do vars = super - vars << "title" unless title.have_required_values? + vars << "title" unless title {|t| t.have_required_values?} vars end end diff --git a/lib/rss/maker/2.0.rb b/lib/rss/maker/2.0.rb index d93ba94d4a..9149c0e24b 100644 --- a/lib/rss/maker/2.0.rb +++ b/lib/rss/maker/2.0.rb @@ -15,7 +15,7 @@ module RSS private def required_variable_names - %w(title link description) + %w(link) end class SkipDays < RSS09::Channel::SkipDays @@ -90,13 +90,7 @@ module RSS end class Items < RSS09::Items - class Item < RSS09::Items::Item - - def have_required_values? - @title or @description - end - private def required_variable_names %w(title description) diff --git a/lib/rss/maker/atom.rb b/lib/rss/maker/atom.rb index 27d30c6d89..fd3198cd9e 100644 --- a/lib/rss/maker/atom.rb +++ b/lib/rss/maker/atom.rb @@ -147,11 +147,11 @@ EOC def to_feed(feed, current) logo = current.class::Logo.new class << logo - alias uri= content= + alias_method(:uri=, :content=) end set = setup_values(logo) class << logo - undef uri= + remove_method(:uri=) end if set current.logo = logo diff --git a/lib/rss/maker/base.rb b/lib/rss/maker/base.rb index ad47ff29cc..752b2fa58f 100644 --- a/lib/rss/maker/base.rb +++ b/lib/rss/maker/base.rb @@ -4,85 +4,155 @@ require 'rss/rss' module RSS module Maker - module Base - def self.append_features(klass) - super - - klass.module_eval(<<-EOC, __FILE__, __LINE__) + class Base + extend Utils::InheritedReader - OTHER_ELEMENTS = [] - NEED_INITIALIZE_VARIABLES = [] + OTHER_ELEMENTS = [] + NEED_INITIALIZE_VARIABLES = [] - def self.inherited(subclass) - subclass.const_set("OTHER_ELEMENTS", []) - subclass.const_set("NEED_INITIALIZE_VARIABLES", []) - - subclass.module_eval(<<-EOEOC, __FILE__, __LINE__) - def self.other_elements - OTHER_ELEMENTS + super - end - - def self.need_initialize_variables - NEED_INITIALIZE_VARIABLES + super - end - EOEOC + class << self + def other_elements + inherited_array_reader("OTHER_ELEMENTS") + end + def need_initialize_variables + inherited_array_reader("NEED_INITIALIZE_VARIABLES") end - def self.add_other_element(variable_name) - OTHER_ELEMENTS << variable_name + def inherited_base + ::RSS::Maker::Base end - def self.other_elements - OTHER_ELEMENTS + def inherited(subclass) + subclass.const_set("OTHER_ELEMENTS", []) + subclass.const_set("NEED_INITIALIZE_VARIABLES", []) end - def self.add_need_initialize_variable(variable_name, init_value="nil") - NEED_INITIALIZE_VARIABLES << [variable_name, init_value] + def add_other_element(variable_name) + self::OTHER_ELEMENTS << variable_name end - def self.need_initialize_variables - NEED_INITIALIZE_VARIABLES + def add_need_initialize_variable(variable_name, init_value="nil") + self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value] end - def self.def_array_element(name, plural=nil, klass=nil) + def def_array_element(name, plural=nil, klass_name=nil) include Enumerable extend Forwardable - plural ||= "\#{name}s" - klass ||= "self.class::\#{Utils.to_class_name(name)}" - - def_delegators("@\#{plural}", :<<, :[], :[]=, :first, :last) - def_delegators("@\#{plural}", :push, :pop, :shift, :unshift) - def_delegators("@\#{plural}", :each, :size, :empty?, :clear) + 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(<<-EOM, __FILE__, __LINE__ + 1) - def new_\#{name} - \#{name} = \#{klass}.new(@maker) - @\#{plural} << \#{name} + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def new_#{name} + #{name} = self.class::#{klass_name}.new(@maker) + @#{plural} << #{name} if block_given? - yield \#{name} + yield #{name} else - \#{name} + #{name} end end - alias new_child new_\#{name} + alias new_child new_#{name} def to_feed(*args) - @\#{plural}.each do |\#{name}| - \#{name}.to_feed(*args) + @#{plural}.each do |#{name}| + #{name}.to_feed(*args) end end def replace(elements) - @\#{plural}.replace(elements.to_a) + @#{plural}.replace(elements.to_a) end -EOM + 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, "make_#{name}") + 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 - EOC end - + attr_reader :maker def initialize(maker) @maker = maker @@ -183,12 +253,27 @@ EOM attr_accessor element add_need_initialize_variable(element) end -EOC + 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 @@ -203,6 +288,14 @@ EOC 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| @@ -221,21 +314,9 @@ EOC def self.append_features(klass) super - klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) + klass.class_eval do include EnsureXMLContent - - %w(type content xml_content).each do |element| - attr element, element != "xml_content" - add_need_initialize_variable(element) - end - - def xml_content=(content) - @xml_content = ensure_xml_content(content) - end - - alias_method(:xhtml, :xml_content) - alias_method(:xhtml=, :xml_content=) -EOC + end end end @@ -248,7 +329,7 @@ EOC } _date = date if _date and !dc_dates.any? {|dc_date| dc_date.value == _date} - dc_date = self.class::DublinCoreDates::Date.new(self) + dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self) dc_date.value = _date.dup dc_dates.unshift(dc_date) end @@ -260,9 +341,7 @@ EOC end end - class RSSBase - include Base - + class RSSBase < Base class << self def make(&block) new.make(&block) @@ -281,7 +360,7 @@ EOC def make_#{element} self.class::#{Utils.to_class_name(element)}.new(self) end -EOC + EOC end attr_reader :feed_version @@ -326,13 +405,10 @@ EOC end end - class XMLStyleSheets - include Base - + class XMLStyleSheets < Base def_array_element("xml_stylesheet", nil, "XMLStyleSheet") - class XMLStyleSheet - include Base + class XMLStyleSheet < Base ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute| attr_accessor attribute @@ -362,26 +438,23 @@ EOC end end - class ChannelBase - include Base + class ChannelBase < Base include SetupDefaultDate - %w(cloud categories skipDays skipHours links authors - contributors generator copyright description - title).each do |element| - attr_reader element - add_other_element(element) - add_need_initialize_variable(element, "make_#{element}") - module_eval(<<-EOC, __FILE__, __LINE__) - private - def setup_#{element}(feed, current) - @#{element}.to_feed(feed, current) - end + %w(cloud categories skipDays skipHours).each do |name| + def_classed_element(name) + end - def make_#{element} - self.class::#{Utils.to_class_name(element)}.new(@maker) - end -EOC + %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 @@ -407,59 +480,12 @@ EOC self.date = date end - def link - _link = links.first - _link ? _link.href : nil - end - - def link=(href) - _link = links.first || links.new_link - _link.rel = "self" - _link.href = href - end - - def author - _author = authors.first - _author ? _author.name : nil - end - - def author=(name) - _author = authors.first || authors.new_author - _author.name = name - end - - def contributor - _contributor = contributors.first - _contributor ? _contributor.name : nil - end - - def contributor=(name) - _contributor = contributors.first || contributors.new_contributor - _contributor.name = name - end - - def generator=(content) - @generator.content = content - end - - def copyright=(content) - @copyright.content = content - end - alias_method(:rights, :copyright) alias_method(:rights=, :copyright=) - def description=(content) - @description.content = content - end - alias_method(:subtitle, :description) alias_method(:subtitle=, :description=) - def title=(content) - @title.content = content - end - def icon image_favicon.about end @@ -476,14 +502,10 @@ EOC maker.image.url = url end - class SkipDaysBase - include Base - + class SkipDaysBase < Base def_array_element("day") - class DayBase - include Base - + class DayBase < Base %w(content).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -491,14 +513,10 @@ EOC end end - class SkipHoursBase - include Base - + class SkipHoursBase < Base def_array_element("hour") - class HourBase - include Base - + class HourBase < Base %w(content).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -506,23 +524,17 @@ EOC end end - class CloudBase - include Base - + class CloudBase < Base %w(domain port path registerProcedure protocol).each do |element| attr_accessor element add_need_initialize_variable(element) end end - class CategoriesBase - include Base - + class CategoriesBase < Base def_array_element("category", "categories") - class CategoryBase - include Base - + class CategoryBase < Base %w(domain content label).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -535,14 +547,10 @@ EOC end end - class LinksBase - include Base - + class LinksBase < Base def_array_element("link") - class LinkBase - include Base - + class LinkBase < Base %w(href rel type hreflang title length).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -550,56 +558,43 @@ EOC end end - class AuthorsBase - include Base - + class AuthorsBase < Base def_array_element("author") - class AuthorBase - include Base + class AuthorBase < Base include AtomPersonConstructBase end end - class ContributorsBase - include Base - + class ContributorsBase < Base def_array_element("contributor") - class ContributorBase - include Base + class ContributorBase < Base include AtomPersonConstructBase end end - class GeneratorBase - include Base - + class GeneratorBase < Base %w(uri version content).each do |element| attr_accessor element add_need_initialize_variable(element) end end - class CopyrightBase - include Base + class CopyrightBase < Base include AtomTextConstructBase end - class DescriptionBase - include Base + class DescriptionBase < Base include AtomTextConstructBase end - class TitleBase - include Base + class TitleBase < Base include AtomTextConstructBase end end - class ImageBase - include Base - + class ImageBase < Base %w(title url width height description).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -610,9 +605,7 @@ EOC end end - class ItemsBase - include Base - + class ItemsBase < Base def_array_element("item") attr_accessor :do_sort, :max_size @@ -646,27 +639,25 @@ EOC end end - class ItemBase - include Base + class ItemBase < Base include SetupDefaultDate - %w(guid enclosure source categories authors links - contributors rights description content title).each do |element| - attr_reader element - add_other_element(element) - add_need_initialize_variable(element, "make_#{element}") - module_eval(<<-EOC, __FILE__, __LINE__) - private - def setup_#{element}(feed, current) - @#{element}.to_feed(feed, current) - end + %w(guid enclosure source categories content).each do |name| + def_classed_element(name) + end - def make_#{element} - self.class::#{Utils.to_class_name(element)}.new(@maker) - end -EOC + %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(date comments id published).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -688,42 +679,9 @@ EOC self.date = date end - def author - _link = authors.first - _link ? _author.name : nil - end - - def author=(name) - _author = authors.first || authors.new_author - _author.name = name - end - - def link - _link = links.first - _link ? _link.href : nil - end - - def link=(href) - _link = links.first || links.new_link - _link.rel = "alternate" - _link.href = href - end - - def rights=(content) - @rights.content = content - end - - def description=(content) - @description.content = content - end - alias_method(:summary, :description) alias_method(:summary=, :description=) - def title=(content) - @title.content = content - end - def <=>(other) _date = date || dc_date _other_date = other.date || other.dc_date @@ -738,42 +696,30 @@ EOC end end - class GuidBase - include Base - + class GuidBase < Base %w(isPermaLink content).each do |element| attr_accessor element add_need_initialize_variable(element) end end - class EnclosureBase - include Base - + class EnclosureBase < Base %w(url length type).each do |element| attr_accessor element add_need_initialize_variable(element) end end - class SourceBase - include Base - + class SourceBase < Base %w(authors categories contributors generator icon - links logo rights subtitle title).each do |element| - attr_reader element - add_other_element(element) - add_need_initialize_variable(element, "make_#{element}") - module_eval(<<-EOC, __FILE__, __LINE__) - private - def setup_#{element}(feed, current) - @#{element}.to_feed(feed, current) - end + logo rights subtitle title).each do |name| + def_classed_element(name) + end - def make_#{element} - self.class::#{Utils.to_class_name(element)}.new(@maker) - end - EOC + [ + ["link", "href"], + ].each do |name, attribute| + def_classed_elements(name, attribute) end %w(id content date).each do |element| @@ -781,15 +727,8 @@ EOC add_need_initialize_variable(element) end - def url - link = links.first - link ? link.href : nil - end - - def url=(value) - link = links.first || links.new_link - link.href = value - end + alias_method(:url, :link) + alias_method(:url=, :link=) def updated date @@ -805,9 +744,7 @@ EOC ContributorsBase = ChannelBase::ContributorsBase GeneratorBase = ChannelBase::GeneratorBase - class IconBase - include Base - + class IconBase < Base %w(url).each do |element| attr_accessor element add_need_initialize_variable(element) @@ -816,27 +753,22 @@ EOC LinksBase = ChannelBase::LinksBase - class LogoBase - include Base - + class LogoBase < Base %w(uri).each do |element| attr_accessor element add_need_initialize_variable(element) end end - class RightsBase - include Base + class RightsBase < Base include AtomTextConstructBase end - class SubtitleBase - include Base + class SubtitleBase < Base include AtomTextConstructBase end - class TitleBase - include Base + class TitleBase < Base include AtomTextConstructBase end end @@ -846,22 +778,19 @@ EOC LinksBase = ChannelBase::LinksBase ContributorsBase = ChannelBase::ContributorsBase - class RightsBase - include Base + class RightsBase < Base include AtomTextConstructBase end - class DescriptionBase - include Base + class DescriptionBase < Base include AtomTextConstructBase end - class ContentBase - include Base + class ContentBase < Base include AtomTextConstructBase::EnsureXMLContent - %w(type src content xml_content).each do |element| - attr element, element != "xml_content" + %w(src).each do |element| + attr_accessor(element) add_need_initialize_variable(element) end @@ -870,13 +799,9 @@ EOC @xml_content = content end - alias_method(:xhtml, :xml_content) - alias_method(:xhtml=, :xml_content=) - alias_method(:xml, :xml_content) alias_method(:xml=, :xml_content=) - private def inline_text? [nil, "text", "html"].include?(@type) end @@ -913,16 +838,13 @@ EOC end end - class TitleBase - include Base + class TitleBase < Base include AtomTextConstructBase end end end - class TextinputBase - include Base - + class TextinputBase < Base %w(title description name link).each do |element| attr_accessor element add_need_initialize_variable(element) diff --git a/lib/rss/maker/content.rb b/lib/rss/maker/content.rb index 18590d0cf8..a1fd283116 100644 --- a/lib/rss/maker/content.rb +++ b/lib/rss/maker/content.rb @@ -7,17 +7,8 @@ module RSS def self.append_features(klass) super - ::RSS::ContentModel::ELEMENTS.each do |element| - klass.add_need_initialize_variable(element) - klass.add_other_element(element) - klass.module_eval(<<-EOC, __FILE__, __LINE__+1) - attr_accessor :#{element} - def setup_#{element}(rss, current) - if #{element} and current.respond_to?(:#{element}=) - current.#{element} = @#{element} if @#{element} - end - end - EOC + ::RSS::ContentModel::ELEMENTS.each do |name| + klass.def_other_element(name) end end end diff --git a/lib/rss/maker/dublincore.rb b/lib/rss/maker/dublincore.rb index 088ae60942..ff4813fe19 100644 --- a/lib/rss/maker/dublincore.rb +++ b/lib/rss/maker/dublincore.rb @@ -15,61 +15,40 @@ module RSS plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" full_plural_klass_name = "self.class::#{plural_klass_name}" full_klass_name = "#{full_plural_klass_name}::#{klass_name}" - klass.add_need_initialize_variable(full_plural_name, - "make_#{full_plural_name}") - klass.add_other_element(full_plural_name) - klass.module_eval(<<-EOC, __FILE__, __LINE__+1) - attr_accessor :#{full_plural_name} - def make_#{full_plural_name} - #{full_plural_klass_name}.new(@maker) - end - - def setup_#{full_plural_name}(feed, current) - @#{full_plural_name}.to_feed(feed, current) - end - - def #{full_name} - @#{full_plural_name}[0] and @#{full_plural_name}[0].value - end - - def #{full_name}=(new_value) - @#{full_plural_name}[0] = #{full_klass_name}.new(self) - @#{full_plural_name}[0].value = new_value - end - + 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_klass_name}.new(self) - #{full_name}.value = value - @#{full_plural_name} << #{full_name} + _#{full_name} = #{full_plural_name}.new_#{name} + _#{full_name}.value = value if block_given? - yield #{full_name} + yield _#{full_name} else - #{full_name} + _#{full_name} end end -EOC + EOC end klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) # For backward compatibility alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list -EOC + 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__) - class #{plural_klass_name}Base - include Base - - def_array_element(#{name.dump}, #{plural_name.dump}) - - class #{klass_name}Base - include Base + 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) @@ -80,12 +59,13 @@ EOC end def to_feed(feed, current) - if value and current.respond_to?(:dc_#{name}) + if value and current.respond_to?(:#{full_name}) new_item = current.class::#{full_klass_name}.new(value) - current.dc_#{plural_name} << new_item + current.#{full_plural_name} << new_item end end end + #{klass_name}Base = #{full_klass_name}Base end EOC end @@ -94,11 +74,13 @@ EOC ::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 #{klass_name} < #{klass_name}Base + class #{full_klass_name} < #{full_klass_name}Base end + #{klass_name} = #{full_klass_name} end EOC end diff --git a/lib/rss/maker/entry.rb b/lib/rss/maker/entry.rb index baa22c5bf1..be648832c3 100644 --- a/lib/rss/maker/entry.rb +++ b/lib/rss/maker/entry.rb @@ -75,12 +75,6 @@ module RSS end end - def have_required_values? - set_default_values do - super and title.have_required_values? - end - end - private def required_variable_names %w(id updated) @@ -100,7 +94,7 @@ module RSS if authors.all? {|author| !author.have_required_values?} vars << "author" end - vars << "title" unless title.have_required_values? + vars << "title" unless title {|t| t.have_required_values?} vars end end @@ -126,9 +120,11 @@ module RSS self.id ||= link || @maker.channel.id links.replace(@maker.channel.links) if keep[:links].empty? unless keep[:rights].variable_is_set? - @rights = @maker.channel.rights + @maker.channel.rights {|r| @rights = r} + end + unless keep[:title].variable_is_set? + @maker.channel.title {|t| @title = t} end - @title = @maker.channel.title unless keep[:title].variable_is_set? self.updated ||= @maker.channel.updated super(&block) ensure diff --git a/lib/rss/maker/feed.rb b/lib/rss/maker/feed.rb index ac26788102..95ae735c6b 100644 --- a/lib/rss/maker/feed.rb +++ b/lib/rss/maker/feed.rb @@ -64,7 +64,7 @@ module RSS @maker.items.all? {|item| item.author.to_s.empty?} vars << "author" end - vars << "title" unless title.have_required_values? + vars << "title" unless title {|t| t.have_required_values?} vars end @@ -148,11 +148,11 @@ module RSS def to_feed(feed) logo = feed.class::Logo.new class << logo - alias url= content= + alias_method(:url=, :content=) end set = setup_values(logo) class << logo - undef url= + remove_method(:url=) end if set feed.logo = logo @@ -194,7 +194,7 @@ module RSS def have_required_values? set_default_values do - super and title.have_required_values? + super and title {|t| t.have_required_values?} end end @@ -209,7 +209,7 @@ module RSS def not_set_required_variables vars = super - vars << "title" unless title.have_required_values? + vars << "title" unless title {|t| t.have_required_values?} vars end @@ -282,11 +282,11 @@ module RSS def to_feed(feed, current) icon = current.class::Icon.new class << icon - alias url= content= + alias_method(:url=, :content=) end set = setup_values(icon) class << icon - undef url= + remove_method(:url=) end if set current.icon = icon diff --git a/lib/rss/maker/image.rb b/lib/rss/maker/image.rb index e3469d0597..b95cf4c714 100644 --- a/lib/rss/maker/image.rb +++ b/lib/rss/maker/image.rb @@ -9,20 +9,7 @@ module RSS super name = "#{RSS::IMAGE_PREFIX}_item" - klass.add_need_initialize_variable(name, "make_#{name}") - klass.add_other_element(name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader :#{name} - def setup_#{name}(feed, current) - if @#{name} - @#{name}.to_feed(feed, current) - end - end - - def make_#{name} - self.class::#{Utils.to_class_name(name)}.new(@maker) - end -EOC + klass.def_classed_element(name) end def self.install_image_item(klass) @@ -33,8 +20,7 @@ EOC EOC end - class ImageItemBase - include Base + class ImageItemBase < Base include Maker::DublinCoreModel attr_accessor :about, :resource, :image_width, :image_height @@ -67,20 +53,7 @@ EOC super name = "#{RSS::IMAGE_PREFIX}_favicon" - klass.add_need_initialize_variable(name, "make_#{name}") - klass.add_other_element(name) - klass.module_eval(<<-EOC, __FILE__, __LINE__+1) - attr_reader :#{name} - def setup_#{name}(feed, current) - if @#{name} - @#{name}.to_feed(feed, current) - end - end - - def make_#{name} - self.class::#{Utils.to_class_name(name)}.new(@maker) - end -EOC + klass.def_classed_element(name) end def self.install_image_favicon(klass) @@ -88,11 +61,10 @@ EOC class ImageFavicon < ImageFaviconBase DublinCoreModel.install_dublin_core(self) end -EOC + EOC end - class ImageFaviconBase - include Base + class ImageFaviconBase < Base include Maker::DublinCoreModel attr_accessor :about, :image_size diff --git a/lib/rss/maker/itunes.rb b/lib/rss/maker/itunes.rb new file mode 100644 index 0000000000..86f41e2fd7 --- /dev/null +++ b/lib/rss/maker/itunes.rb @@ -0,0 +1,248 @@ +require 'rss/itunes' +require 'rss/maker/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 :yes_clean_other + def_yes_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, 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_yes_clean_other_accessor(klass, full_name) + klass.def_other_element(full_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def #{full_name}? + Utils::YesCleanOther.parse(#{full_name}) + end + EOC + end + + def def_csv_accessor(klass, full_name) + klass.def_other_element_without_accessor(full_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + attr_reader :#{full_name} + def #{full_name}=(value) + @#{full_name} = Utils::CSV.parse(value) + end + EOC + end + + def def_elements_class_accessor(klass, 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_#{full_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/syndication.rb b/lib/rss/maker/syndication.rb index 3717086257..b81230457c 100644 --- a/lib/rss/maker/syndication.rb +++ b/lib/rss/maker/syndication.rb @@ -7,17 +7,8 @@ module RSS def self.append_features(klass) super - ::RSS::SyndicationModel::ELEMENTS.each do |element| - klass.add_need_initialize_variable(element) - klass.add_other_element(element) - klass.module_eval(<<-EOC, __FILE__, __LINE__+1) - attr_accessor :#{element} - def setup_#{element}(rss, current) - if #{element} and current.respond_to?(:#{element}=) - current.#{element} = @#{element} if @#{element} - end - end - EOC + ::RSS::SyndicationModel::ELEMENTS.each do |name| + klass.def_other_element(name) end end end diff --git a/lib/rss/maker/taxonomy.rb b/lib/rss/maker/taxonomy.rb index 2e53a4e1f4..798b239df9 100644 --- a/lib/rss/maker/taxonomy.rb +++ b/lib/rss/maker/taxonomy.rb @@ -8,18 +8,8 @@ module RSS def self.append_features(klass) super - klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics") - klass.add_other_element("taxo_topics") - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader :taxo_topics - def make_taxo_topics - self.class::TaxonomyTopics.new(@maker) - end - - def setup_taxo_topics(feed, current) - @taxo_topics.to_feed(feed, current) - end -EOC + klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics", + "TaxonomyTopics") end def self.install_taxo_topics(klass) @@ -39,9 +29,7 @@ EOC EOC end - class TaxonomyTopicsBase - include Base - + class TaxonomyTopicsBase < Base attr_reader :resources def_array_element("resource") remove_method :new_resource @@ -52,29 +40,10 @@ EOC def self.append_features(klass) super - klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics") - klass.add_other_element("taxo_topics") - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_reader :taxo_topics - def make_taxo_topics - self.class::TaxonomyTopics.new(@maker) - end - - def setup_taxo_topics(feed, current) - @taxo_topics.to_feed(feed, current) - end - - def taxo_topic - @taxo_topics[0] and @taxo_topics[0].value - end - - def taxo_topic=(new_value) - @taxo_topic[0] = self.class::TaxonomyTopic.new(self) - @taxo_topic[0].value = new_value - end -EOC + 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 @@ -96,13 +65,10 @@ EOC EOC end - class TaxonomyTopicsBase - include Base - - def_array_element("taxo_topic", nil, "self.class::TaxonomyTopic") + class TaxonomyTopicsBase < Base + def_array_element("taxo_topic", nil, "TaxonomyTopic") - class TaxonomyTopicBase - include Base + class TaxonomyTopicBase < Base include DublinCoreModel include TaxonomyTopicsModel diff --git a/lib/rss/maker/trackback.rb b/lib/rss/maker/trackback.rb index 09a2fceb2d..278fe53ebe 100644 --- a/lib/rss/maker/trackback.rb +++ b/lib/rss/maker/trackback.rb @@ -8,41 +8,15 @@ module RSS def self.append_features(klass) super - name = "#{RSS::TRACKBACK_PREFIX}_ping" - klass.add_need_initialize_variable(name) - klass.add_other_element(name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_accessor :#{name} - def setup_#{name}(feed, current) - if #{name} and current.respond_to?(:#{name}=) - current.#{name} = #{name} - end - end - EOC - - name = "#{RSS::TRACKBACK_PREFIX}_abouts" - klass.add_need_initialize_variable(name, "make_#{name}") - klass.add_other_element(name) - klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) - attr_accessor :#{name} - def make_#{name} - self.class::TrackBackAbouts.new(self) - end - - def setup_#{name}(feed, current) - @#{name}.to_feed(feed, current) - end - EOC + klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping") + klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value", + "TrackBackAbouts") end - class TrackBackAboutsBase - include Base - - def_array_element("about", nil, "self.class::TrackBackAbout") - - class TrackBackAboutBase - include Base + class TrackBackAboutsBase < Base + def_array_element("about", nil, "TrackBackAbout") + class TrackBackAboutBase < Base attr_accessor :value add_need_initialize_variable("value") -- cgit v1.2.3