diff options
Diffstat (limited to 'ruby_1_8_5/lib/rss/rss.rb')
-rw-r--r-- | ruby_1_8_5/lib/rss/rss.rb | 1015 |
1 files changed, 0 insertions, 1015 deletions
diff --git a/ruby_1_8_5/lib/rss/rss.rb b/ruby_1_8_5/lib/rss/rss.rb deleted file mode 100644 index a06985af94..0000000000 --- a/ruby_1_8_5/lib/rss/rss.rb +++ /dev/null @@ -1,1015 +0,0 @@ -require "time" - -class Time - class << self - unless respond_to?(:w3cdtf) - 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] - datetime << $7.to_f * 1000000 if $7 - if $8 - Time.utc(*datetime) - zone_offset($8) - else - Time.local(*datetime) - end - else - raise ArgumentError.new("invalid date: #{date.inspect}") - end - end - end - end - - unless instance_methods.include?("w3cdtf") - alias w3cdtf iso8601 - end -end - -require "English" -require "rss/utils" -require "rss/converter" -require "rss/xml-stylesheet" - -module RSS - - VERSION = "0.1.6" - - URI = "http://purl.org/rss/1.0/" - - DEBUG = false - - class Error < StandardError; end - - class OverlappedPrefixError < Error - attr_reader :prefix - def initialize(prefix) - @prefix = prefix - end - end - - class InvalidRSSError < Error; end - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - module BaseModel - - include Utils - - def install_have_child_element(tag_name, uri, occurs, name=nil) - name ||= tag_name - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - attr_accessor name - 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) - - 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 - add_need_initialize_variable(name) - install_model(tag_name, uri, occurs, name) - - def_corresponded_attr_writer name, type, disp_name - convert_attr_reader name - install_element(name) do |n, elem_name| - <<-EOC - if @#{n} - rv = "\#{indent}<#{elem_name}>" - value = html_escape(@#{n}) - if need_convert - rv << convert(value) - else - rv << value - end - rv << "</#{elem_name}>" - 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 << "</#{elem_name}>" - 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 convert_attr_reader(*attrs) - attrs.each do |attr| - attr = attr.id2name if attr.kind_of?(Integer) - module_eval(<<-EOC, *get_file_and_line_from_caller(2)) - def #{attr} - if @converter - @converter.convert(@#{attr}) - else - @#{attr} - 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? or new_value.kind_of?(Time) - @#{name} = new_value - 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 - @#{name} = Time.parse(new_value) - 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 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) - warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \ - "Don't use `#{accessor_name} = XXX'/`set_#{accessor_name}(XXX)'. " \ - "Those APIs are not sense of Ruby. " \ - "Use `#{plural_name} << XXX' instead of them.") - 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 - - class Element - - extend BaseModel - include Utils - - INDENT = " " - - MUST_CALL_VALIDATORS = {} - MODELS = [] - GET_ATTRIBUTES = [] - HAVE_CHILDREN_ELEMENTS = [] - TO_ELEMENT_METHODS = [] - NEED_INITIALIZE_VARIABLES = [] - PLURAL_FORMS = {} - - class << self - - def must_call_validators - MUST_CALL_VALIDATORS - end - def models - MODELS - end - def get_attributes - GET_ATTRIBUTES - end - def have_children_elements - HAVE_CHILDREN_ELEMENTS - end - def to_element_methods - TO_ELEMENT_METHODS - end - def need_initialize_variables - NEED_INITIALIZE_VARIABLES - end - def plural_forms - PLURAL_FORMS - 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", {}) - - klass.module_eval(<<-EOC) - public - - @tag_name = name.split(/::/).last - @tag_name[0,1] = @tag_name[0,1].downcase - @have_content = false - - def self.must_call_validators - super.merge(MUST_CALL_VALIDATORS) - end - def self.models - MODELS + super - end - def self.get_attributes - GET_ATTRIBUTES + super - end - def self.have_children_elements - HAVE_CHILDREN_ELEMENTS + super - end - def self.to_element_methods - TO_ELEMENT_METHODS + super - end - def self.need_initialize_variables - NEED_INITIALIZE_VARIABLES + super - end - def self.plural_forms - super.merge(PLURAL_FORMS) - end - - - def self.install_must_call_validator(prefix, uri) - MUST_CALL_VALIDATORS[uri] = prefix - end - - def self.install_model(tag, uri, occurs=nil, getter=nil) - getter ||= tag - if m = MODELS.find {|t, u, o, g| t == tag and u == uri} - m[2] = occurs - else - MODELS << [tag, uri, occurs, getter] - end - end - - def self.install_get_attribute(name, uri, required=true, - type=nil, disp_name=nil, - element_name=nil) - disp_name ||= name - element_name ||= name - def_corresponded_attr_writer name, type, disp_name - convert_attr_reader name - if type == :boolean and /^is/ =~ name - alias_method "\#{$POSTMATCH}?", name - end - GET_ATTRIBUTES << [name, uri, required, element_name] - add_need_initialize_variable(disp_name) - end - - def self.def_corresponded_attr_writer(name, type=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 - else - attr_writer name - end - end - - def self.content_setup(type=nil) - def_corresponded_attr_writer "content", type - convert_attr_reader :content - @have_content = true - end - - def self.have_content? - @have_content - end - - def self.add_have_children_element(variable_name, plural_name) - HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name] - end - - def self.add_to_element_method(method_name) - TO_ELEMENT_METHODS << method_name - end - - def self.add_need_initialize_variable(variable_name) - NEED_INITIALIZE_VARIABLES << variable_name - end - - def self.add_plural_form(singular, plural) - PLURAL_FORMS[singular] = plural - end - - EOC - end - - def required_prefix - nil - end - - def required_uri - "" - 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 :do_validate - - def initialize(do_validate=true, attrs={}) - @converter = nil - @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 validate(ignore_unknown_element=true) - validate_attribute - __validate(ignore_unknown_element) - end - - def validate_for_stream(tags, ignore_unknown_element=true) - validate_attribute - __validate(ignore_unknown_element, tags, false) - end - - 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 - - def to_s(need_convert=true, indent='') - if self.class.have_content? - return "" unless @content - rv = tag(indent) do |next_indent| - h(@content) - 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 - - 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_eval("@#{variable_name} = nil") - end - end - initialize_have_children_elements - @content = "" if self.class.have_content? - end - - def initialize_have_children_elements - self.class.have_children_elements.each do |variable_name, plural_name| - instance_eval("@#{variable_name} = []") - end - end - - def tag(indent, additional_attrs={}, &block) - next_indent = indent + INDENT - - attrs = collect_attrs - return "" if attrs.nil? - - attrs.update(additional_attrs) - start_tag = make_start_tag(indent, next_indent, attrs) - - if block - content = block.call(next_indent) - else - content = [] - end - - if content.is_a?(String) - content = [content] - start_tag << ">" - end_tag = "</#{full_name}>" - else - content = content.reject{|x| x.empty?} - if content.empty? - end_tag = "/>" - else - start_tag << ">\n" - end_tag = "\n#{indent}</#{full_name}>" - 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 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) - 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 - - 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}" - if self.class.plural_forms.has_key?(key) - ary = __send__("#{self.class.plural_forms[key]}") - ary << next_element - else - __send__("#{prefix}#{tag_name}=", next_element) - end - 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| - value = __send__(getter) - next if value.nil? - if 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 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| - if required and __send__(alias_name || a_name).nil? - raise MissingAttributeError.new(tag_name, a_name) - end - 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, model_uri, occurs, getter = 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 - - end - - module RootElementMixin - - include XMLStyleSheetMixin - - attr_reader :output_encoding - - def initialize(rss_version, version=nil, encoding=nil, standalone=nil) - super() - @rss_version = rss_version - @version = version || '1.0' - @encoding = encoding - @standalone = standalone - @output_encoding = nil - 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 - - setup_maker_elements(maker) - end - - def to_xml(version=nil, &block) - if version.nil? or version == @rss_version - to_s - else - RSS::Maker.make(version) do |maker| - setup_maker(maker) - block.call(maker) if block - end.to_s - end - end - - private - def tag(indent, attrs={}, &block) - rv = xmldecl + xml_stylesheet_pi - rv << super(indent, ns_declarations.merge(attrs), &block) - rv - end - - def xmldecl - rv = %Q[<?xml version="#{@version}"] - if @output_encoding or @encoding - rv << %Q[ encoding="#{@output_encoding or @encoding}"] - end - rv << %Q[ standalone="yes"] if @standalone - rv << "?>\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 setup_maker_elements(maker) - channel.setup_maker(maker) if channel - image.setup_maker(maker) if image - textinput.setup_maker(maker) if textinput - super(maker) - end - end - -end |