diff options
Diffstat (limited to 'trunk/lib/rss/maker/base.rb')
-rw-r--r-- | trunk/lib/rss/maker/base.rb | 880 |
1 files changed, 0 insertions, 880 deletions
diff --git a/trunk/lib/rss/maker/base.rb b/trunk/lib/rss/maker/base.rb deleted file mode 100644 index 2262a764ec..0000000000 --- a/trunk/lib/rss/maker/base.rb +++ /dev/null @@ -1,880 +0,0 @@ -require 'forwardable' - -require 'rss/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) - if value - 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(&block) - keep = { - :date => date, - :dc_dates => dc_dates.to_a.dup, - } - _date = 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(&block) - ensure - date = keep[:date] - dc_dates.replace(keep[:dc_dates]) - end - end - - class RSSBase < Base - class << self - def make(version, &block) - new(version).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__) - 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 date - lastBuildDate ttl).each do |element| - attr_accessor element - add_need_initialize_variable(element) - 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(date comments id published).each do |element| - attr_accessor element - add_need_initialize_variable(element) - 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 - end - - class EnclosureBase < Base - %w(url length type).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - end - - class SourceBase < Base - %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 date).each do |element| - attr_accessor element - add_need_initialize_variable(element) - end - - alias_method(:url, :link) - alias_method(:url=, :link=) - - 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 |