mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	- 0.1.9 -> 0.2.0. - supported Slash module. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13446 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			410 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
require 'rss/2.0'
 | 
						|
 | 
						|
module RSS
 | 
						|
  ITUNES_PREFIX = 'itunes'
 | 
						|
  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", :yes_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
 | 
						|
                                )\z/x !~ duration
 | 
						|
            raise ArgumentError,
 | 
						|
                    "must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
 | 
						|
                    duration.inspect
 | 
						|
          end
 | 
						|
 | 
						|
          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
 | 
						|
        end
 | 
						|
 | 
						|
        def construct(hour, minute, second)
 | 
						|
          components = [minute, second]
 | 
						|
          if components.include?(nil)
 | 
						|
            nil
 | 
						|
          else
 | 
						|
            components.unshift(hour) if hour and hour > 0
 | 
						|
            components.collect do |component|
 | 
						|
              "%02d" % component
 | 
						|
            end.join(":")
 | 
						|
          end
 | 
						|
        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
 |