Parent

Class/Module Index [+]

Quicksearch

FeedTools::FeedItem

The FeedTools::FeedItem class represents the structure of a single item within a web feed.

Public Class Methods

new() click to toggle source

Initialize the feed object

# File lib/feed_tools/feed_item.rb, line 31
def initialize
  super
  @feed_data = nil
  @feed_data_type = :xml
  @xml_document = nil
  @root_node = nil
  @title = nil
  @id = nil
  @time = Time.now.gmtime
  @version = FeedTools::FEED_TOOLS_VERSION::STRING
end

Public Instance Methods

abstract() click to toggle source
Alias for: summary
abstract=(new_summary) click to toggle source
Alias for: summary=
author() click to toggle source

Returns the feed item author

# File lib/feed_tools/feed_item.rb, line 1420
def author
  if @author.nil?
    @author = FeedTools::Author.new
    author_node = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:author",
      "atom03:author",
      "atom:author",
      "author",
      "managingEditor",
      "dc:author",
      "dc:creator",
      "creator"
    ])
    unless author_node.nil?
      @author.raw = FeedTools::XmlHelper.try_xpaths(
        author_node, ["text()"], :select_result_value => true)
      @author.raw = FeedTools::HtmlHelper.unescape_entities(@author.raw)
      unless @author.raw.nil?
        raw_scan = @author.raw.scan(
          /(.*)\((\b[A-Z0-9._%-\+]+@[A-Z0-9._%-]+\.[A-Z]{2,4}\b)\)/)
        if raw_scan.nil? || raw_scan.size == 0
          raw_scan = @author.raw.scan(
            /(\b[A-Z0-9._%-\+]+@[A-Z0-9._%-]+\.[A-Z]{2,4}\b)\s*\((.*)\)/)
          unless raw_scan.size == 0
            author_raw_pair = raw_scan.first.reverse
          end
        else
          author_raw_pair = raw_scan.first
        end
        if raw_scan.nil? || raw_scan.size == 0
          email_scan = @author.raw.scan(
            /\b[A-Z0-9._%-\+]+@[A-Z0-9._%-]+\.[A-Z]{2,4}\b/)
          if email_scan != nil && email_scan.size > 0
            @author.email = email_scan.first.strip
          end
        end
        unless author_raw_pair.nil? || author_raw_pair.size == 0
          @author.name = author_raw_pair.first.strip
          @author.email = author_raw_pair.last.strip
        else
          unless @author.raw.include?("@")
            # We can be reasonably sure we are looking at something
            # that the creator didn't intend to contain an email address
            # if it got through the preceeding regexes and it doesn't
            # contain the tell-tale '@' symbol.
            @author.name = @author.raw
          end
        end
      end
      if @author.name.blank?
        @author.name = FeedTools::HtmlHelper.unescape_entities(
          FeedTools::XmlHelper.try_xpaths(author_node, [
            "atom10:name/text()",
            "atom03:name/text()",
            "atom:name/text()",
            "name/text()",
            "@name"
          ], :select_result_value => true)
        )
      end
      if @author.email.blank?
        @author.email = FeedTools::HtmlHelper.unescape_entities(
          FeedTools::XmlHelper.try_xpaths(author_node, [
            "atom10:email/text()",
            "atom03:email/text()",
            "atom:email/text()",
            "email/text()",
            "@email"
          ], :select_result_value => true)
        )
      end
      if @author.url.blank?
        @author.url = FeedTools::HtmlHelper.unescape_entities(
          FeedTools::XmlHelper.try_xpaths(author_node, [
            "atom10:url/text()",
            "atom03:url/text()",
            "atom:url/text()",
            "url/text()",
            "atom10:uri/text()",
            "atom03:uri/text()",
            "atom:uri/text()",
            "uri/text()",
            "@url",
            "@uri",
            "@href"
          ], :select_result_value => true)
        )
      end
      if @author.name.blank? && !@author.raw.blank? &&
          !@author.email.blank?
        name_scan = @author.raw.scan(
          /"?([^"]*)"? ?[\(<].*#{@author.email}.*[\)>].*/)
        if name_scan.flatten.size == 1
          @author.name = name_scan.flatten[0].strip
        end
        if @author.name.blank?
          name_scan = @author.raw.scan(
            /.*#{@author.email} ?[\(<]"?([^"]*)"?[\)>].*/)
          if name_scan.flatten.size == 1
            @author.name = name_scan.flatten[0].strip
          end
        end
      end
      @author.name = nil if @author.name.blank?
      @author.raw = nil if @author.raw.blank?
      @author.email = nil if @author.email.blank?
      @author.url = nil if @author.url.blank?
      if @author.url != nil
        begin
          if !(@author.url =~ /^file:/) &&
              !FeedTools::UriHelper.is_uri?(@author.url)
            @author.url = FeedTools::UriHelper.resolve_relative_uri(
              @author.url, [author_node.base_uri, self.base_uri])
          end
        rescue
        end
      end
      if FeedTools::XmlHelper.try_xpaths(author_node,
          ["@gr:unknown-author"], :select_result_value => true) == "true"
        if @author.name == "(author unknown)"
          @author.name = nil
        end
      end
    end
    # Fallback on the itunes module if we didn't find an author name
    begin
      @author.name = self.itunes_author if @author.name.nil?
    rescue
      @author.name = nil
    end
    if @author.name.blank? && @author.email.blank? &&
        @author.href.blank?
      parent_feed = self.feed
      if parent_feed != nil
        @author = parent_feed.author.dup
      end
    end
  end
  return @author
end
author=(new_author) click to toggle source

Sets the feed item author

# File lib/feed_tools/feed_item.rb, line 1562
def author=(new_author)
  if new_author.respond_to?(:name) &&
      new_author.respond_to?(:email) &&
      new_author.respond_to?(:url)
    # It's a complete author object, just set it.
    @author = new_author
  else
    # We're not looking at an author object, this is probably a string,
    # default to setting the author's name.
    if @author.nil?
      @author = FeedTools::Author.new
    end
    @author.name = new_author
  end
end
base_uri() click to toggle source

Returns the parent feed's base_uri if any.

# File lib/feed_tools/feed_item.rb, line 633
def base_uri
  parent_feed = self.feed
  if parent_feed != nil
    return parent_feed.base_uri
  else
    return nil
  end
end
build_xml(feed_type=(self.feed.feed_type or "atom"), version=nil, xml_builder=Builder::XmlMarkup.new( :indent => 2, :escape_attrs => false)) click to toggle source

Generates xml based on the content of the feed item

# File lib/feed_tools/feed_item.rb, line 2034
def build_xml(feed_type=(self.feed.feed_type or "atom"), version=nil,
    xml_builder=Builder::XmlMarkup.new(
      :indent => 2, :escape_attrs => false))
      
  parent_feed = self.feed
  if parent_feed.find_node(
      "access:restriction/@relationship").to_s == "deny"
    raise StandardError,
      "Operation not permitted.  This feed denies redistribution."
  elsif parent_feed.find_node("@indexing:index").to_s == "no"
    raise StandardError,
      "Operation not permitted.  This feed denies redistribution."
  end
  if self.find_node(
      "access:restriction/@relationship").to_s == "deny"
    raise StandardError,
      "Operation not permitted.  This feed item denies redistribution."
  end
  
  self.full_parse()
  
  if feed_type == "rss" && (version == nil || version == 0.0)
    version = 1.0
  elsif feed_type == "atom" && (version == nil || version == 0.0)
    version = 1.0
  end
  if feed_type == "rss" &&
      (version == 0.9 || version == 1.0 || version == 1.1)
    # RDF-based rss format
    if link.nil?
      raise "Cannot generate an rdf-based feed item with a " +
        "nil link field."
    end
    return xml_builder.item("rdf:about" =>
        FeedTools::HtmlHelper.escape_entities(link)) do
      unless self.title.blank?
        xml_builder.title(
          FeedTools::HtmlHelper.strip_html_tags(self.title))
      else
        xml_builder.title
      end
      unless self.link.blank?
        xml_builder.link(self.link)
      else
        xml_builder.link
      end
      unless self.author.nil? || self.author.name.nil?
        xml_builder.tag!("dc:creator", self.author.name)
      end
      unless self.summary.blank?
        xml_builder.description(self.summary)
      else
        xml_builder.description
      end
      unless self.content.blank?
        xml_builder.tag!("content:encoded") do
          xml_builder.cdata!(self.content)
        end
      end
      unless time.nil?
        xml_builder.tag!("dc:date", time.iso8601)            
      end
      unless self.rights.blank?
        xml_builder.tag!("dc:rights", self.rights)
      end
      unless tags.nil? || tags.size == 0
        for tag in tags
          xml_builder.tag!("dc:subject", tag)
        end
        if self.feed.podcast?
          xml_builder.tag!("itunes:keywords", tags.join(", "))
        end
      end
      build_xml_hook(feed_type, version, xml_builder)
    end
  elsif feed_type == "rss"
    # normal rss format
    return xml_builder.item do
      unless self.title.blank?
        xml_builder.title(
          FeedTools::HtmlHelper.strip_html_tags(self.title))
      end
      unless self.link.blank?
        xml_builder.link(self.link)
      end
      unless self.author.nil? || self.author.name.nil?
        xml_builder.tag!("dc:creator", self.author.name)
      end
      unless self.author.nil? || self.author.email.nil? ||
          self.author.name.nil?
        xml_builder.author("#{self.author.email} (#{self.author.name})")
      end
      unless self.summary.blank?
        xml_builder.description(self.summary)
      end
      unless self.content.blank?
        xml_builder.tag!("content:encoded") do
          xml_builder.cdata!(self.content)
        end
      end
      if !self.published.nil?
        xml_builder.pubDate(self.published.rfc822)            
      elsif !self.time.nil?
        xml_builder.pubDate(self.time.rfc822)            
      end
      unless self.rights.blank?
        xml_builder.tag!("dc:rights", self.rights)
      end
      unless self.guid.blank?
        if FeedTools::UriHelper.is_uri?(self.guid) &&
            (self.guid =~ /^http/)
          xml_builder.guid(self.guid, "isPermaLink" => "true")
        else
          xml_builder.guid(self.guid, "isPermaLink" => "false")
        end
      else
        unless self.link.blank?
          xml_builder.guid(self.link, "isPermaLink" => "true")
        end
      end
      unless tags.nil? || tags.size == 0
        for tag in tags
          xml_builder.tag!("category", tag)
        end
        if self.feed.podcast?
          xml_builder.tag!("itunes:keywords", tags.join(", "))
        end
      end
      unless self.enclosures.blank? || self.enclosures.size == 0
        for enclosure in self.enclosures
          attribute_hash = {}
          next if enclosure.url.blank?
          begin
            if enclosure.file_size.blank? || enclosure.file_size.to_i == 0
              # We can't use this enclosure because it's missing the
              # required file size.  Check alternate versions for
              # file_size.
              if !enclosure.versions.blank? && enclosure.versions.size > 0
                for alternate in enclosure.versions
                  if alternate.file_size != nil &&
                      alternate.file_size.to_i > 0
                    enclosure = alternate
                    break
                  end
                end
              end
            end
          rescue
          end
          attribute_hash["url"] =
            FeedTools::UriHelper.normalize_url(enclosure.url)
          if enclosure.type != nil
            attribute_hash["type"] = enclosure.type
          end
          if enclosure.file_size != nil && enclosure.file_size.to_i > 0
            attribute_hash["length"] = enclosure.file_size.to_s
          else
            # We couldn't find an alternate and the problem is still
            # there.  Give up and go on.
            xml_builder.comment!(
              "*** Enclosure failed to include file size. Ignoring. ***")
            next
          end
          xml_builder.enclosure(attribute_hash)
        end
      end
      build_xml_hook(feed_type, version, xml_builder)
    end
  elsif feed_type == "atom" && version == 0.3
    raise "Atom 0.3 is obsolete."
  elsif feed_type == "atom" && version == 1.0
    # normal atom format
    return xml_builder.entry("xmlns" =>
        FEED_TOOLS_NAMESPACES['atom10']) do
      unless title.nil? || title == ""
        xml_builder.title(
          FeedTools::HtmlHelper.strip_html_tags(self.title),
            "type" => "html")
      end
      xml_builder.author do
        unless self.author.nil? || self.author.name.nil?
          xml_builder.name(self.author.name)
        else
          xml_builder.name("n/a")
        end
        unless self.author.nil? || self.author.email.nil?
          xml_builder.email(self.author.email)
        end
        unless self.author.nil? || self.author.url.nil?
          xml_builder.uri(self.author.url)
        end
      end
      unless link.nil? || link == ""
        xml_builder.link(
            "href" =>
              FeedTools::HtmlHelper.escape_entities(self.link),
            "rel" => "alternate")
      end
      if !self.content.blank?
        xml_builder.content(self.content,
            "type" => "html")
      end
      if !self.summary.blank?
        xml_builder.summary(self.summary,
            "type" => "html")
      end
      if self.updated != nil
        xml_builder.updated(self.updated.iso8601)
      elsif self.time != nil
        # Not technically correct, but a heck of a lot better
        # than the Time.now fall-back.
        xml_builder.updated(self.time.iso8601)
      else
        xml_builder.updated(Time.now.gmtime.iso8601)
      end
      unless self.published.nil?
        xml_builder.published(self.published.iso8601)            
      end
      unless self.rights.blank?
        xml_builder.rights(self.rights)
      end
      if self.id != nil
        unless FeedTools::UriHelper.is_uri? self.id
          if self.time != nil && self.link != nil
            xml_builder.id(FeedTools::UriHelper.build_tag_uri(
              self.link, self.time))
          elsif self.link != nil
            xml_builder.id(FeedTools.build_urn_uuid_uri(self.link))
          else
            raise "The unique id must be a URI. " +
              "(Attempted to generate id, but failed.)"
          end
        else
          xml_builder.id(self.id)
        end
      elsif self.time != nil && self.link != nil
        xml_builder.id(FeedTools::UriHelper.build_tag_uri(
          self.link, self.time))
      else
        raise "Cannot build feed, missing feed unique id."
      end
      unless self.tags.nil? || self.tags.size == 0
        for tag in self.tags
          xml_builder.category("term" => tag)
        end
      end
      unless self.enclosures.blank? || self.enclosures.size == 0
        for enclosure in self.enclosures
          attribute_hash = {}
          next if enclosure.url.blank?
          attribute_hash["rel"] = "enclosure"
          attribute_hash["href"] =
            FeedTools::UriHelper.normalize_url(enclosure.url)
          if enclosure.type != nil
            attribute_hash["type"] = enclosure.type
          end
          if enclosure.file_size != nil && enclosure.file_size.to_i > 0
            attribute_hash["length"] = enclosure.file_size.to_s
          end
          xml_builder.link(attribute_hash)
        end
      end
      build_xml_hook(feed_type, version, xml_builder)
    end
  else
    raise "Unsupported feed format/version."
  end
end
build_xml_hook(feed_type, version, xml_builder) click to toggle source

A hook method that is called during the feed generation process. Overriding this method will enable additional content to be inserted into the feed.

# File lib/feed_tools/feed_item.rb, line 2029
def build_xml_hook(feed_type, version, xml_builder)
  return nil
end
categories() click to toggle source

Returns a list of the feed item's categories

# File lib/feed_tools/feed_item.rb, line 743
def categories
  if @categories.nil?
    @categories = []
    category_nodes = FeedTools::XmlHelper.try_xpaths_all(self.root_node, [
      "category",
      "dc:subject"
    ])
    for category_node in category_nodes
      category = FeedTools::Category.new
      category.term = FeedTools::XmlHelper.try_xpaths(
        category_node, ["@term", "text()"],
        :select_result_value => true)
      category.term.strip! unless category.term.nil?
      category.label = FeedTools::XmlHelper.try_xpaths(
        category_node, ["@label"],
        :select_result_value => true)
      category.label.strip! unless category.label.nil?
      category.scheme = FeedTools::XmlHelper.try_xpaths(
        category_node, [
          "@scheme",
          "@domain"
        ], :select_result_value => true)
      category.scheme.strip! unless category.scheme.nil?
      @categories << category
    end
  end
  return @categories
end
comments() click to toggle source

Returns the url for posting comments

# File lib/feed_tools/feed_item.rb, line 643
def comments
  if @comments.nil?
    @comments = FeedTools::XmlHelper.try_xpaths(
      self.root_node, ["comments/text()"],
      :select_result_value => true)
    begin
      if !(@comments =~ /^file:/) &&
          !FeedTools::UriHelper.is_uri?(@comments)
        root_base_uri = nil
        unless self.root_node.nil?
          root_base_uri = self.root_node.base_uri
        end
        @comments = FeedTools::UriHelper.resolve_relative_uri(
          @comments, [root_base_uri, self.base_uri])
      end
    rescue
    end
    if self.configurations[:url_normalization_enabled]
      @comments = FeedTools::UriHelper.normalize_url(@comments)
    end
  end
  return @comments
end
comments=(new_comments) click to toggle source

Sets the url for posting comments

# File lib/feed_tools/feed_item.rb, line 668
def comments=(new_comments)
  @comments = new_comments
end
configurations() click to toggle source

Returns the load options for this feed.

# File lib/feed_tools/feed_item.rb, line 139
def configurations
  if @configurations.blank?
    parent_feed = self.feed
    if parent_feed != nil
      @configurations = parent_feed.configurations.dup
    else
      @configurations = FeedTools.configurations.dup
    end
  end
  return @configurations
end
configurations=(new_configurations) click to toggle source

Sets the load options for this feed.

# File lib/feed_tools/feed_item.rb, line 152
def configurations=(new_configurations)
  @configurations = new_configurations
end
content() click to toggle source

Returns the feed item content

# File lib/feed_tools/feed_item.rb, line 328
def content
  if @content.nil?
    repair_entities = false
    content_node = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:content",
      "atom03:content",
      "atom:content",
      "body/datacontent",
      "xhtml:body",
      "body",
      "xhtml:div",
      "div",
      "p:payload",
      "payload",
      "content:encoded",
      "content",
      "fullitem",
      "encoded",
      "description",
      "tagline",
      "subtitle",
      "atom10:summary",
      "atom03:summary",
      "atom:summary",
      "summary",
      "abstract",
      "blurb",
      "info"
    ])
    @content = FeedTools::HtmlHelper.process_text_construct(content_node,
      self.feed_type, self.feed_version, [self.base_uri])
    if self.feed_type == "atom" ||
        self.configurations[:always_strip_wrapper_elements]
      @content = FeedTools::HtmlHelper.strip_wrapper_element(@content)
    end
    if @content.nil?
      @content = self.media_text
    end
    if @content.nil?
      @content = self.itunes_summary
    end
    if @content.nil?
      @content = self.itunes_subtitle
    end
  end
  return @content
end
content=(new_content) click to toggle source

Sets the feed item content

# File lib/feed_tools/feed_item.rb, line 377
def content=(new_content)
  @content = new_content
end
description() click to toggle source
Alias for: summary
description=(new_summary) click to toggle source
Alias for: summary=
dispose() click to toggle source

Breaks any references that the feed entry may be keeping around, thus making the job of the garbage collector much, much easier. Call this method prior to feed entries going out of scope to prevent memory leaks.

# File lib/feed_tools/feed_item.rb, line 46
def dispose()
  @feed_data = nil
  @feed_data_type = nil
  @xml_document = nil
  @root_node = nil
  @title = nil
  @id = nil
  @time = nil
end
enclosures() click to toggle source

Returns all feed item enclosures

# File lib/feed_tools/feed_item.rb, line 937
def enclosures
  if @enclosures.nil?
    @enclosures = []
    
    # First, load up all the different possible sources of enclosures
    rss_enclosures =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node, ["enclosure"])
    atom_enclosures =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node, [
        "atom10:link[@rel='enclosure']",
        "atom03:link[@rel='enclosure']",
        "atom:link[@rel='enclosure']",
        "link[@rel='enclosure']"
      ])
    media_content_enclosures =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["media:content"])
    media_group_enclosures =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node, ["media:group"])
      
    bogus_enclosures =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node, ["video"])
      
    # TODO: Implement this
    bittorrent_enclosures =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["bitTorrent:torrent"])
    

    # Parse RSS-type enclosures.  Thanks to a few buggy enclosures
    # implementations, sometimes these also manage to show up in atom
    # files.
    for enclosure_node in rss_enclosures
      enclosure = FeedTools::Enclosure.new
      enclosure.url = FeedTools::HtmlHelper.unescape_entities(
        enclosure_node.attributes["url"].to_s)
      enclosure.type = enclosure_node.attributes["type"].to_s
      enclosure.file_size = enclosure_node.attributes["length"].to_i
      enclosure.credits = []
      enclosure.explicit = false
      @enclosures << enclosure
    end
    
    # Parse atom-type enclosures.  If there are repeats of the same
    # enclosure object, we merge the two together.
    for enclosure_node in atom_enclosures
      enclosure_url = FeedTools::HtmlHelper.unescape_entities(
        enclosure_node.attributes["href"].to_s)
      enclosure = nil
      new_enclosure = false
      for existing_enclosure in @enclosures
        if existing_enclosure.url == enclosure_url
          enclosure = existing_enclosure
          break
        end
      end
      if enclosure.nil?
        new_enclosure = true
        enclosure = FeedTools::Enclosure.new
      end
      enclosure.url = enclosure_url
      enclosure.type = enclosure_node.attributes["type"].to_s
      enclosure.file_size = enclosure_node.attributes["length"].to_i
      enclosure.credits = []
      enclosure.explicit = false
      if new_enclosure
        @enclosures << enclosure
      end
    end
    
    # Parse atom-type enclosures.  If there are repeats of the same
    # enclosure object, we merge the two together.
    for enclosure_node in bogus_enclosures
      enclosure_url = FeedTools::HtmlHelper.unescape_entities(
        enclosure_node.attributes["url"].to_s)
      enclosure = nil
      new_enclosure = false
      for existing_enclosure in @enclosures
        if existing_enclosure.url == enclosure_url
          enclosure = existing_enclosure
          break
        end
      end
      if enclosure.nil?
        new_enclosure = true
        enclosure = FeedTools::Enclosure.new
      end
      enclosure.url = enclosure_url
      if File.extname(enclosure_url) == ".wmv"
        enclosure.type = "video/x-ms-wmv"
      end
      enclosure.explicit = false
      if new_enclosure
        @enclosures << enclosure
      end
    end

    # Creates an anonymous method to parse content objects from the media
    # module.  We do this to avoid excessive duplication of code since we
    # have to do identical processing for content objects within group
    # objects.
    parse_media_content = lambda do |media_content_nodes|
      affected_enclosures = []
      for enclosure_node in media_content_nodes
        enclosure_url = FeedTools::HtmlHelper.unescape_entities(
          enclosure_node.attributes["url"].to_s)
        enclosure = nil
        new_enclosure = false
        for existing_enclosure in @enclosures
          if existing_enclosure.url == enclosure_url
            enclosure = existing_enclosure
            break
          end
        end
        if enclosure.nil?
          new_enclosure = true
          enclosure = FeedTools::Enclosure.new
        end
        enclosure.url = enclosure_url
        enclosure.type = enclosure_node.attributes["type"].to_s
        enclosure.file_size = enclosure_node.attributes["fileSize"].to_i
        enclosure.duration = enclosure_node.attributes["duration"].to_s
        enclosure.height = enclosure_node.attributes["height"].to_i
        enclosure.width = enclosure_node.attributes["width"].to_i
        enclosure.bitrate = enclosure_node.attributes["bitrate"].to_i
        enclosure.framerate = enclosure_node.attributes["framerate"].to_i
        enclosure.expression =
          enclosure_node.attributes["expression"].to_s
        enclosure.is_default =
          (enclosure_node.attributes["isDefault"].to_s.downcase == "true")
        enclosure_thumbnail_url =
          FeedTools::XmlHelper.try_xpaths(enclosure_node,
            ["media:thumbnail/@url"], :select_result_value => true)
        if !enclosure_thumbnail_url.blank?
          enclosure.thumbnail = FeedTools::EnclosureThumbnail.new(
            FeedTools::HtmlHelper.unescape_entities(
              enclosure_thumbnail_url),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(enclosure_node,
                ["media:thumbnail/@height"],
                :select_result_value => true)),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(enclosure_node,
                ["media:thumbnail/@width"],
                :select_result_value => true))
          )
        end
        enclosure.categories = []
        for category in FeedTools::XmlHelper.try_xpaths_all(
            enclosure_node, ["media:category"])
          enclosure.categories << FeedTools::Category.new
          enclosure.categories.last.term =
            FeedTools::HtmlHelper.unescape_entities(category.inner_xml)
          enclosure.categories.last.scheme =
            FeedTools::HtmlHelper.unescape_entities(
              category.attributes["scheme"].to_s)
          enclosure.categories.last.label =
            FeedTools::HtmlHelper.unescape_entities(
              category.attributes["label"].to_s)
          if enclosure.categories.last.scheme.blank?
            enclosure.categories.last.scheme = nil
          end
          if enclosure.categories.last.label.blank?
            enclosure.categories.last.label = nil
          end
        end
        enclosure_media_hash =
          FeedTools::XmlHelper.try_xpaths(enclosure_node,
            ["media:hash/text()"], :select_result_value => true)
        if !enclosure_media_hash.nil?
          enclosure.hash = FeedTools::EnclosureHash.new(
            FeedTools::HtmlHelper.sanitize_html(
              FeedTools::HtmlHelper.unescape_entities(
                enclosure_media_hash), :strip),
            "md5"
          )
        end
        enclosure_media_player_url =
          FeedTools::XmlHelper.try_xpaths(enclosure_node,
            ["media:player/@url"], :select_result_value => true)
        if !enclosure_media_player_url.blank?
          enclosure.player = FeedTools::EnclosurePlayer.new(
            FeedTools::HtmlHelper.unescape_entities(
              enclosure_media_player_url),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(enclosure_node,
                ["media:player/@height"], :select_result_value => true)),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(enclosure_node,
                ["media:player/@width"], :select_result_value => true))
          )
        end
        enclosure.credits = []
        for credit in FeedTools::XmlHelper.try_xpaths_all(
            enclosure_node, ["media:credit"])
          enclosure.credits << FeedTools::EnclosureCredit.new(
            FeedTools::HtmlHelper.unescape_entities(
              credit.inner_xml.to_s.strip),
            FeedTools::HtmlHelper.unescape_entities(
              credit.attributes["role"].to_s.downcase)
          )
          if enclosure.credits.last.name.blank?
            enclosure.credits.last.name = nil
          end
          if enclosure.credits.last.role.blank?
            enclosure.credits.last.role = nil
          end
        end
        enclosure.explicit =
          (FeedTools::XmlHelper.try_xpaths(enclosure_node,
            ["media:adult/text()"]).to_s.downcase == "true")
        enclosure_media_text =
          FeedTools::XmlHelper.try_xpaths(enclosure_node,
            ["media:text/text()"])
        if !enclosure_media_text.blank?
          enclosure.text = FeedTools::HtmlHelper.unescape_entities(
            enclosure_media_text)
        end
        affected_enclosures << enclosure
        if new_enclosure
          @enclosures << enclosure
        end
      end
      affected_enclosures
    end
    
    # Parse the independant content objects.
    parse_media_content.call(media_content_enclosures)
    
    media_groups = []
    
    # Parse the group objects.
    for media_group in media_group_enclosures
      group_media_content_enclosures =
        FeedTools::XmlHelper.try_xpaths_all(media_group,
          ["media:content"])
      
      # Parse the content objects within the group objects.
      affected_enclosures =
        parse_media_content.call(group_media_content_enclosures)
      
      # Now make sure that content objects inherit certain properties from
      # the group objects.
      for enclosure in affected_enclosures
        media_group_thumbnail =
          FeedTools::XmlHelper.try_xpaths(media_group,
            ["media:thumbnail/@url"], :select_result_value => true)
        if enclosure.thumbnail.nil? && !media_group_thumbnail.blank?
          enclosure.thumbnail = FeedTools::EnclosureThumbnail.new(
            FeedTools::HtmlHelper.unescape_entities(
              media_group_thumbnail),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(media_group,
                ["media:thumbnail/@height"],
                :select_result_value => true)),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(media_group,
                ["media:thumbnail/@width"],
                :select_result_value => true))
          )
        end
        if (enclosure.categories.blank?)
          enclosure.categories = []
          for category in FeedTools::XmlHelper.try_xpaths_all(
              media_group, ["media:category"])
            enclosure.categories << FeedTools::Category.new
            enclosure.categories.last.term =
              FeedTools::HtmlHelper.unescape_entities(category.inner_xml)
            enclosure.categories.last.scheme =
              FeedTools::HtmlHelper.unescape_entities(
                category.attributes["scheme"].to_s)
            enclosure.categories.last.label =
              FeedTools::HtmlHelper.unescape_entities(
                category.attributes["label"].to_s)
            if enclosure.categories.last.scheme.blank?
              enclosure.categories.last.scheme = nil
            end
            if enclosure.categories.last.label.blank?
              enclosure.categories.last.label = nil
            end
          end
        end
        enclosure_media_group_hash =
          FeedTools::XmlHelper.try_xpaths(enclosure_node,
            ["media:hash/text()"], :select_result_value => true)
        if enclosure.hash.nil? && !enclosure_media_group_hash.blank?
          enclosure.hash = FeedTools::EnclosureHash.new(
            FeedTools::HtmlHelper.sanitize_html(
              FeedTools::HtmlHelper.unescape_entities(
                enclosure_media_group_hash), :strip),
            "md5"
          )
        end
        enclosure_media_group_url = FeedTools::XmlHelper.try_xpaths(
          media_group,
          "media:player/@url",
          :select_result_value => true
        )
        if enclosure.player.nil? && !enclosure_media_group_url.blank?
          enclosure.player = FeedTools::EnclosurePlayer.new(
            FeedTools::HtmlHelper.unescape_entities(
              enclosure_media_group_url),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(media_group,
                ["media:player/@height"],
                :select_result_value => true)),
            FeedTools::HtmlHelper.unescape_entities(
              FeedTools::XmlHelper.try_xpaths(media_group,
                ["media:player/@width"],
                :select_result_value => true
              )
            )
          )
        end
        if enclosure.credits.nil? || enclosure.credits.size == 0
          enclosure.credits = []
          for credit in FeedTools::XmlHelper.try_xpaths_all(
              media_group, ["media:credit"])
            enclosure.credits << FeedTools::EnclosureCredit.new(
              FeedTools::HtmlHelper.unescape_entities(credit.inner_xml),
              FeedTools::HtmlHelper.unescape_entities(
                credit.attributes["role"].to_s.downcase)
            )
            if enclosure.credits.last.role.blank?
              enclosure.credits.last.role = nil
            end
          end
        end
        if enclosure.explicit?.nil?
          enclosure.explicit =
            ((FeedTools::XmlHelper.try_xpaths(media_group, [
              "media:adult/text()"
            ], :select_result_value => true).downcase == "true") ?
              true : false)
        end
        enclosure_media_group_text =
          FeedTools::XmlHelper.try_xpaths(media_group,
            ["media:text/text()"], :select_result_value => true)
        if enclosure.text.nil? && !enclosure_media_group_text.blank?
          enclosure.text = FeedTools::HtmlHelper.sanitize_html(
            FeedTools::HtmlHelper.unescape_entities(
              enclosure_media_group_text), :strip)
        end
      end
      
      # Keep track of the media groups
      media_groups << affected_enclosures
    end
    
    # Now we need to inherit any relevant item level information.
    if self.explicit?
      for enclosure in @enclosures
        enclosure.explicit = true
      end
    end
    
    # Add all the itunes categories
    itunes_categories =
      FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["itunes:category"])
    for itunes_category in itunes_categories
      genre = "Podcasts"
      category = itunes_category.attributes["text"].to_s
      subcategory =
        FeedTools::XmlHelper.try_xpaths(itunes_category,
          ["itunes:category/@text"],
          :select_result_value => true)
      category_path = genre
      if !category.blank?
        category_path << "/" + category
      end
      if !subcategory.blank?
        category_path << "/" + subcategory
      end          
      for enclosure in @enclosures
        if enclosure.categories.nil?
          enclosure.categories = []
        end
        enclosure.categories << FeedTools::Category.new
        enclosure.categories.last.term =
          FeedTools::HtmlHelper.unescape_entities(category_path)
        enclosure.categories.last.scheme =
          "http://www.apple.com/itunes/store/"
        enclosure.categories.last.label =
          "iTunes Music Store Categories"
      end
    end

    for enclosure in @enclosures
      # Clean up any of those attributes that incorrectly have ""
      # or 0 as their values        
      if enclosure.type.blank?
        enclosure.type = nil
      end
      if enclosure.file_size == 0
        enclosure.file_size = nil
      end
      if enclosure.duration == 0
        enclosure.duration = nil
      end
      if enclosure.height == 0
        enclosure.height = nil
      end
      if enclosure.width == 0
        enclosure.width = nil
      end
      if enclosure.bitrate == 0
        enclosure.bitrate = nil
      end
      if enclosure.framerate == 0
        enclosure.framerate = nil
      end
      if enclosure.expression.blank?
        enclosure.expression = "full"
      end

      # If an enclosure is missing the text field, fall back on the
      # itunes:summary field
      if enclosure.text.blank?
        enclosure.text = self.itunes_summary
      end

      # Make sure we don't have duplicate categories
      unless enclosure.categories.nil?
        enclosure.categories.uniq!
      end
      
      # Normalize enclosure URIs
      if !enclosure.href.blank?
        enclosure.href =
          FeedTools::UriHelper.normalize_url(enclosure.href)
      else
        enclosure.href = nil
      end
    end
    
    # And finally, now things get complicated.  This is where we make
    # sure that the enclosures method only returns either default
    # enclosures or enclosures with only one version.  Any enclosures
    # that are wrapped in a media:group will be placed in the appropriate
    # versions field.
    affected_enclosure_urls = []
    for media_group in media_groups
      affected_enclosure_urls =
        affected_enclosure_urls | (media_group.map do |enclosure|
          enclosure.url
        end)
    end
    @enclosures.delete_if do |enclosure|
      (affected_enclosure_urls.include? enclosure.url)
    end
    for media_group in media_groups
      default_enclosure = nil
      for enclosure in media_group
        if enclosure.is_default?
          default_enclosure = enclosure
        end
      end
      for enclosure in media_group
        enclosure.default_version = default_enclosure
        enclosure.versions = media_group.clone
        enclosure.versions.delete(enclosure)
      end
      @enclosures << default_enclosure
    end
  end

  # If we have a single enclosure, it's safe to inherit the
  # itunes:duration field if it's missing.
  if @enclosures.size == 1
    if @enclosures.first.duration.nil? || @enclosures.first.duration == 0
      @enclosures.first.duration = self.itunes_duration
    end
  end

  return @enclosures
end
enclosures=(new_enclosures) click to toggle source
# File lib/feed_tools/feed_item.rb, line 1415
def enclosures=(new_enclosures)
  @enclosures = new_enclosures
end
encoding() click to toggle source

Returns the feed item's encoding.

# File lib/feed_tools/feed_item.rb, line 157
def encoding
  if @encoding.nil?
    parent_feed = self.feed
    if parent_feed != nil
      @encoding = parent_feed.encoding
    else
      @encoding = nil
    end
  end
  return @encoding
end
explicit=(new_explicit) click to toggle source

Sets whether or not the feed contains explicit material

# File lib/feed_tools/feed_item.rb, line 2022
def explicit=(new_explicit)
  @explicit = (new_explicit ? true : false)
end
explicit?() click to toggle source

Returns true if this feed item contains explicit material. If the whole feed has been marked as explicit, this will return true even if the item isn't explicitly marked as explicit.

# File lib/feed_tools/feed_item.rb, line 2003
def explicit?
  if @explicit.nil?
    explicit_string = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "media:adult/text()",
      "itunes:explicit/text()"
    ], :select_result_value => true)
    parent_feed = self.feed
    if explicit_string == "true" || explicit_string == "yes"
      @explicit = true
    elsif parent_feed != nil && parent_feed.explicit?
      @explicit = true
    else
      @explicit = false
    end
  end
  return @explicit
end
feed() click to toggle source

Returns the parent feed of this feed item Warning, this method may be slow if you have a large number of FeedTools::Feed objects. Can't use a direct reference to the parent because it plays havoc with the garbage collector. Could've used a WeakRef object, but really, if there are multiple parent feeds, something is going to go wrong, and the programmer needs to be notified. A WeakRef implementation can't detect this condition.

# File lib/feed_tools/feed_item.rb, line 65
def feed
  parent_feed = nil
  ObjectSpace.each_object(FeedTools::Feed) do |feed|
    if feed.instance_variable_get("@entries").nil?
      feed.items
    end
    unsorted_items = feed.instance_variable_get("@entries")
    for item in unsorted_items
      if item.object_id == self.object_id
        if parent_feed.nil?
          parent_feed = feed
          break
        else
          raise "Multiple parent feeds found."
        end
      end
    end
  end
  return parent_feed
end
feed_data() click to toggle source

Returns the feed item's raw data.

# File lib/feed_tools/feed_item.rb, line 170
def feed_data
  return @feed_data
end
feed_data=(new_feed_data) click to toggle source

Sets the feed item's data.

# File lib/feed_tools/feed_item.rb, line 175
def feed_data=(new_feed_data)
  @time = nil
  @feed_data = new_feed_data
end
feed_data_type() click to toggle source

Returns the feed item's data type.

# File lib/feed_tools/feed_item.rb, line 181
def feed_data_type
  return @feed_data_type
end
feed_data_type=(new_feed_data_type) click to toggle source

Sets the feed item's data type.

# File lib/feed_tools/feed_item.rb, line 186
def feed_data_type=(new_feed_data_type)
  @feed_data_type = new_feed_data_type
  if self.feed_data_type != :xml
    @xml_document = nil
  end
end
feed_type() click to toggle source

Returns the feed type of this item

# File lib/feed_tools/feed_item.rb, line 249
def feed_type
  if @feed_type.nil?
    parent_feed = self.feed
    @feed_type = parent_feed.feed_type unless parent_feed.nil?
  end
  return @feed_type
end
feed_version() click to toggle source

Returns the feed version of this item

# File lib/feed_tools/feed_item.rb, line 258
def feed_version
  if @feed_version.nil?
    parent_feed = self.feed
    @feed_version = parent_feed.feed_version unless parent_feed.nil?
  end
  return @feed_version
end
find_all_nodes(xpath, select_result_value=false) click to toggle source

Returns all nodes within the root_node that match the xpath query.

# File lib/feed_tools/feed_item.rb, line 220
def find_all_nodes(xpath, select_result_value=false)
  if self.feed_data_type != :xml
    raise "The feed data type is not xml."
  end
  return FeedTools::XmlHelper.try_xpaths_all(self.root_node, [xpath],
    :select_result_value => select_result_value)
end
find_node(xpath, select_result_value=false) click to toggle source

Returns the first node within the root_node that matches the xpath query.

# File lib/feed_tools/feed_item.rb, line 211
def find_node(xpath, select_result_value=false)
  if self.feed_data_type != :xml
    raise "The feed data type is not xml."
  end
  return FeedTools::XmlHelper.try_xpaths(self.root_node, [xpath],
    :select_result_value => select_result_value)
end
full_parse() click to toggle source

Does a full parse of the feed item.

# File lib/feed_tools/feed_item.rb, line 87
def full_parse
  self.configurations
  
  self.encoding
  self.xml_document
  self.root_node
  
  self.feed_type
  self.feed_version
  
  self.id
  self.title
  self.content
  self.summary
  self.links
  self.link
  self.comments
  self.time
  self.updated
  self.published
  self.source
  self.categories
  self.tags
  self.images
  self.rights
  self.author
  self.publisher

  self.itunes_summary
  self.itunes_subtitle
  self.itunes_image_link
  self.itunes_author
  self.itunes_duration

  self.media_text
  self.media_thumbnail_link

  self.explicit?
end
guid() click to toggle source
Alias for: id
guid=(new_id) click to toggle source
Alias for: id=
id() click to toggle source

Returns the feed items's unique id

# File lib/feed_tools/feed_item.rb, line 267
def id
  if @id.nil?
    @id = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:id/@gr:original-id",
      "atom03:id/@gr:original-id",
      "atom:id/@gr:original-id",
      "id/@gr:original-id",
      "atom10:id/text()",
      "atom03:id/text()",
      "atom:id/text()",
      "id/text()",
      "guid/text()"
    ], :select_result_value => true)
  end
  return @id
end
Also aliased as: guid
id=(new_id) click to toggle source

Sets the feed item's unique id

# File lib/feed_tools/feed_item.rb, line 285
def id=(new_id)
  @id = new_id
end
Also aliased as: guid=
images() click to toggle source

Returns a list of the feed items's images

# File lib/feed_tools/feed_item.rb, line 773
def images
  if @images.nil?
    @images = []
    image_nodes = FeedTools::XmlHelper.try_xpaths_all(self.root_node, [
      "image",
      "logo",
      "apple-wallpapers:image",
      "imageUrl"
    ])
    unless image_nodes.blank?
      for image_node in image_nodes
        image = FeedTools::Image.new
        image.href = FeedTools::XmlHelper.try_xpaths(image_node, [
          "url/text()",
          "@rdf:resource",
          "@href",
          "@url",
          "text()"
        ], :select_result_value => true)
        if image.href.nil? && image_node.base_uri != nil
          image.href = ""
        end
        begin
          if !(image.href =~ /^file:/) &&
              !FeedTools::UriHelper.is_uri?(image.href)
            stored_base_uri =
              FeedTools::GenericHelper.recursion_trap(:feed_link) do
                self.base_uri if self.feed != nil
              end
            image.href = FeedTools::UriHelper.resolve_relative_uri(
              image.href, [image_node.base_uri, stored_base_uri])
          end
        rescue
        end
        if self.configurations[:url_normalization_enabled]
          image.href = FeedTools::UriHelper.normalize_url(image.href)
        end            
        image.href.strip! unless image.href.nil?
        next if image.href.blank?
        image.title = FeedTools::XmlHelper.try_xpaths(image_node,
          ["title/text()"], :select_result_value => true)
        image.title.strip! unless image.title.nil?
        image.description = FeedTools::XmlHelper.try_xpaths(image_node,
          ["description/text()"], :select_result_value => true)
        image.description.strip! unless image.description.nil?
        image.link = FeedTools::XmlHelper.try_xpaths(image_node,
          ["link/text()"], :select_result_value => true)
        image.link.strip! unless image.link.nil?
        image.height = FeedTools::XmlHelper.try_xpaths(image_node,
          ["height/text()"], :select_result_value => true).to_i
        image.height = nil if image.height <= 0
        image.width = FeedTools::XmlHelper.try_xpaths(image_node,
          ["width/text()"], :select_result_value => true).to_i
        image.width = nil if image.width <= 0
        image.style = FeedTools::XmlHelper.try_xpaths(image_node, [
          "style/text()",
          "@style"
        ], :select_result_value => true)
        image.style.strip! unless image.style.nil?
        image.style.downcase! unless image.style.nil?
        @images << image unless image.url.nil?
      end
    end
    for link_object in self.links
      if link_object.type != nil && link_object.type =~ /^image/
        image = FeedTools::Image.new
        image.href = link_object.href
        image.title = link_object.title
        @images << image unless image.href.nil?
      end
    end
  end
  return @images
end
inspect() click to toggle source

Returns a simple representation of the feed item object's state.

# File lib/feed_tools/feed_item.rb, line 2313
def inspect
  return "#<FeedTools::FeedItem:0x#{self.object_id.to_s(16)} " +
    "LINK:#{self.link}>"
end
itunes_author() click to toggle source

Returns the contents of the itunes:author element

This inherits from any incorrectly placed channel-level itunes:author elements. They're actually amazingly common. People don't read specs.

# File lib/feed_tools/feed_item.rb, line 1672
def itunes_author
  if @itunes_author.nil?
    @itunes_author = FeedTools::HtmlHelper.unescape_entities(
      FeedTools::XmlHelper.try_xpaths(self.root_node,
        ["itunes:author/text()"], :select_result_value => true))
    if @itunes_author.blank?
      parent_feed = self.feed
      if parent_feed != nil
        @itunes_author = parent_feed.itunes_author
      end
    end
  end
  return @itunes_author
end
itunes_author=(new_itunes_author) click to toggle source

Sets the contents of the itunes:author element

# File lib/feed_tools/feed_item.rb, line 1688
def itunes_author=(new_itunes_author)
  @itunes_author = new_itunes_author
end
itunes_duration() click to toggle source

Returns the number of seconds that the associated media runs for

# File lib/feed_tools/feed_item.rb, line 1693
def itunes_duration
  if @itunes_duration.nil?
    raw_duration = FeedTools::HtmlHelper.unescape_entities(
      FeedTools::XmlHelper.try_xpaths(self.root_node,
        ["itunes:duration/text()"], :select_result_value => true))
    if !raw_duration.blank?
      hms = raw_duration.split(":").map { |x| x.to_i }
      if hms.size == 3
        @itunes_duration = hms[0].hours + hms[1].minutes + hms[2]
      elsif hms.size == 2
        @itunes_duration = hms[0].minutes + hms[1]
      elsif hms.size == 1
        @itunes_duration = hms[0]
      end
    end
  end
  return @itunes_duration
end
itunes_duration=(new_itunes_duration) click to toggle source

Sets the number of seconds that the associate media runs for

# File lib/feed_tools/feed_item.rb, line 1713
def itunes_duration=(new_itunes_duration)
  @itunes_duration = new_itunes_duration
end
itunes_subtitle() click to toggle source

Returns the contents of the itunes:subtitle element

# File lib/feed_tools/feed_item.rb, line 697
def itunes_subtitle
  if @itunes_subtitle.nil?
    @itunes_subtitle = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "itunes:subtitle/text()"
    ], :select_result_value => true)
    unless @itunes_subtitle.blank?
      @itunes_subtitle =
        FeedTools::HtmlHelper.unescape_entities(@itunes_subtitle)
      @itunes_subtitle =
        FeedTools::HtmlHelper.sanitize_html(@itunes_subtitle)
      @itunes_subtitle.strip!
    else
      @itunes_subtitle = nil
    end
  end
  return @itunes_subtitle
end
itunes_subtitle=(new_itunes_subtitle) click to toggle source

Sets the contents of the itunes:subtitle element

# File lib/feed_tools/feed_item.rb, line 716
def itunes_subtitle=(new_itunes_subtitle)
  @itunes_subtitle = new_itunes_subtitle
end
itunes_summary() click to toggle source

Returns the contents of the itunes:summary element

# File lib/feed_tools/feed_item.rb, line 673
def itunes_summary
  if @itunes_summary.nil?
    @itunes_summary = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "itunes:summary/text()"
    ], :select_result_value => true)
    unless @itunes_summary.blank?
      @itunes_summary =
        FeedTools::HtmlHelper.unescape_entities(@itunes_summary)
      @itunes_summary =
        FeedTools::HtmlHelper.sanitize_html(@itunes_summary)
      @itunes_summary.strip!
    else
      @itunes_summary = nil
    end
  end
  return @itunes_summary
end
itunes_summary=(new_itunes_summary) click to toggle source

Sets the contents of the itunes:summary element

# File lib/feed_tools/feed_item.rb, line 692
def itunes_summary=(new_itunes_summary)
  @itunes_summary = new_itunes_summary
end
license() click to toggle source

Returns the first license link for the feed item.

# File lib/feed_tools/feed_item.rb, line 917
def license
  return self.licenses.first
end
licenses() click to toggle source

Returns all licenses linked from this feed item.

# File lib/feed_tools/feed_item.rb, line 922
def licenses
  if @licenses.nil?
    @licenses = self.links.select do |link|
      link.rel == "license"
    end
  end
  return @licenses
end
licenses=(new_licenses) click to toggle source

Sets the feed item's licenses.

# File lib/feed_tools/feed_item.rb, line 932
def licenses=(new_licenses)
  @licenses = new_licenses
end
media_text() click to toggle source

Returns the contents of the media:text element

# File lib/feed_tools/feed_item.rb, line 721
def media_text
  if @media_text.nil?
    @media_text = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "media:text/text()"
    ], :select_result_value => true)
    unless @media_text.blank?
      @media_text = FeedTools::HtmlHelper.unescape_entities(@media_text)
      @media_text = FeedTools::HtmlHelper.sanitize_html(@media_text)
      @media_text.strip!
    else
      @media_text = nil
    end
  end
  return @media_text
end
media_text=(new_media_text) click to toggle source

Sets the contents of the media:text element

# File lib/feed_tools/feed_item.rb, line 738
def media_text=(new_media_text)
  @media_text = new_media_text
end
published() click to toggle source

Returns the feed item published time

# File lib/feed_tools/feed_item.rb, line 1864
def published
  if @published.nil?
    published_string = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:issued/text()",
      "atom03:issued/text()",
      "atom:issued/text()",
      "issued/text()",
      "atom10:published/text()",
      "atom03:published/text()",
      "atom:published/text()",
      "published/text()",
      "dc:date/text()",
      "pubDate/text()",
      "date/text()"
    ], :select_result_value => true)
    if !published_string.blank?
      @published = Time.parse(published_string).gmtime rescue nil
    else
      @published = nil
    end
  end
  return @published
end
published=(new_published) click to toggle source

Sets the feed item published time

# File lib/feed_tools/feed_item.rb, line 1889
def published=(new_published)
  @published = new_published
end
publisher() click to toggle source

Returns the feed publisher

# File lib/feed_tools/feed_item.rb, line 1579
def publisher
  if @publisher.nil?
    @publisher = FeedTools::Author.new

    # Set the author name
    @publisher.raw = FeedTools::HtmlHelper.unescape_entities(
      FeedTools::XmlHelper.try_xpaths(self.root_node, [
        "dc:publisher/text()",
        "webMaster/text()"
      ], :select_result_value => true))
    unless @publisher.raw.blank?
      raw_scan = @publisher.raw.scan(
        /(.*)\((\b[A-Z0-9._%-\+]+@[A-Z0-9._%-]+\.[A-Z]{2,4}\b)\)/)
      if raw_scan.nil? || raw_scan.size == 0
        raw_scan = @publisher.raw.scan(
          /(\b[A-Z0-9._%-\+]+@[A-Z0-9._%-]+\.[A-Z]{2,4}\b)\s*\((.*)\)/)
        unless raw_scan.size == 0
          publisher_raw_pair = raw_scan.first.reverse
        end
      else
        publisher_raw_pair = raw_scan.first
      end
      if raw_scan.nil? || raw_scan.size == 0
        email_scan = @publisher.raw.scan(
          /\b[A-Z0-9._%-\+]+@[A-Z0-9._%-]+\.[A-Z]{2,4}\b/)
        if email_scan != nil && email_scan.size > 0
          @publisher.email = email_scan.first.strip
        end
      end
      unless publisher_raw_pair.nil? || publisher_raw_pair.size == 0
        @publisher.name = publisher_raw_pair.first.strip
        @publisher.email = publisher_raw_pair.last.strip
      else
        unless @publisher.raw.include?("@")
          # We can be reasonably sure we are looking at something
          # that the creator didn't intend to contain an email address if
          # it got through the preceeding regexes and it doesn't
          # contain the tell-tale '@' symbol.
          @publisher.name = @publisher.raw
        end
      end
    end

    @publisher.name = nil if @publisher.name.blank?
    @publisher.raw = nil if @publisher.raw.blank?
    @publisher.email = nil if @publisher.email.blank?
    @publisher.url = nil if @publisher.url.blank?
    if @publisher.url != nil
      begin
        if !(@publisher.url =~ /^file:/) &&
            !FeedTools::UriHelper.is_uri?(@publisher.url)
          root_base_uri = nil
          unless self.root_node.nil?
            root_base_uri = self.root_node.base_uri
          end
          @publisher.url = FeedTools::UriHelper.resolve_relative_uri(
            @publisher.url, [root_base_uri, self.base_uri])
        end
      rescue
      end
    end
    if @publisher.name.blank? && @publisher.email.blank? &&
        @publisher.href.blank?
      parent_feed = self.feed
      if parent_feed != nil
        @publisher = parent_feed.publisher.dup
      end
    end
  end
  return @publisher
end
publisher=(new_publisher) click to toggle source

Sets the feed publisher

# File lib/feed_tools/feed_item.rb, line 1652
def publisher=(new_publisher)
  if new_publisher.respond_to?(:name) &&
      new_publisher.respond_to?(:email) &&
      new_publisher.respond_to?(:url)
    # It's a complete Author object, just set it.
    @publisher = new_publisher
  else
    # We're not looking at an Author object, this is probably a string,
    # default to setting the publisher's name.
    if @publisher.nil?
      @publisher = FeedTools::Author.new
    end
    @publisher.name = new_publisher
  end
end
rights() click to toggle source

Returns the feed item's rights information

# File lib/feed_tools/feed_item.rb, line 889
def rights
  if @rights.nil?
    repair_entities = false
    rights_node = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:copyright",
      "atom03:copyright",
      "atom:copyright",
      "copyright",
      "copyrights",
      "dc:rights",
      "rights"
    ])
    @rights = FeedTools::HtmlHelper.process_text_construct(rights_node,
      self.feed_type, self.feed_version, [self.base_uri])
    if self.feed_type == "atom" ||
        self.configurations[:always_strip_wrapper_elements]
      @rights = FeedTools::HtmlHelper.strip_wrapper_element(@rights)
    end
  end
  return @rights
end
Also aliased as: copyright
rights=(new_rights) click to toggle source

Sets the feed item's rights information

# File lib/feed_tools/feed_item.rb, line 912
def rights=(new_rights)
  @rights = new_rights
end
Also aliased as: copyright=
root_node() click to toggle source

Returns the root node of the feed item.

# File lib/feed_tools/feed_item.rb, line 229
def root_node
  if @root_node.nil?
    if self.xml_document.nil?
      return nil
    end
    @root_node = self.xml_document.root
  end
  return @root_node
end
root_node=(new_root_node) click to toggle source

Sets the root node of the feed item.

This allows namespace information to be inherited by the feed item from the feed itself. When creating individual nodes from scratch, the feed_data= method should be used instead.

# File lib/feed_tools/feed_item.rb, line 244
def root_node=(new_root_node)
  @root_node = new_root_node
end
serializable() click to toggle source

Returns a duplicate object suitable for serialization

# File lib/feed_tools/feed_item.rb, line 128
def serializable
  self.full_parse()
  feed_item_to_dump = self.dup
  feed_item_to_dump.author
  feed_item_to_dump.publisher
  feed_item_to_dump.instance_variable_set("@xml_document", nil)
  feed_item_to_dump.instance_variable_set("@root_node", nil)
  return feed_item_to_dump
end
source() click to toggle source

TODO: FIX ME! This code is completely wrong. The source that this post was based on

# File lib/feed_tools/feed_item.rb, line 1895
def source
  if @source.nil?
    @source = FeedTools::Link.new
    @source.href = FeedTools::XmlHelper.try_xpaths(
      self.root_node, ["source/@url"],
      :select_result_value => true)
    @source.title = FeedTools::XmlHelper.try_xpaths(
      self.root_node, ["source/text()"],
      :select_result_value => true)
  end
  return @source
end
summary() click to toggle source

Returns the feed item summary

# File lib/feed_tools/feed_item.rb, line 382
def summary
  if @summary.nil?
    repair_entities = false
    summary_node = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:summary",
      "atom03:summary",
      "atom:summary",
      "summary",
      "abstract",
      "blurb",
      "description",
      "tagline",
      "subtitle",
      "xhtml:body",
      "body",
      "xhtml:div",
      "div",
      "p:payload",
      "payload",
      "fullitem",
      "content:encoded",
      "encoded",
      "atom10:content",
      "atom03:content",
      "atom:content",
      "content",
      "info",
      "body/datacontent"
    ])
    @summary = FeedTools::HtmlHelper.process_text_construct(summary_node,
      self.feed_type, self.feed_version, [self.base_uri])
    if self.feed_type == "atom" ||
        self.configurations[:always_strip_wrapper_elements]
      @summary = FeedTools::HtmlHelper.strip_wrapper_element(@summary)
    end
    if @summary.blank?
      @summary = self.media_text
    end
    if @summary.blank?
      @summary = self.itunes_summary
    end
    if @summary.blank?
      @summary = self.itunes_subtitle
    end
  end
  return @summary
end
Also aliased as: abstract, description
summary=(new_summary) click to toggle source

Sets the feed item summary

# File lib/feed_tools/feed_item.rb, line 431
def summary=(new_summary)
  @summary = new_summary
end
Also aliased as: abstract=, description=
tags() click to toggle source

Returns the feed item tags

# File lib/feed_tools/feed_item.rb, line 1909
def tags
  # TODO: support the rel="tag" microformat
  # =======================================
  if @tags.nil?
    @tags = []
    if root_node.nil?
      return @tags
    end
    if @tags.nil? || @tags.size == 0
      @tags = []
      tag_list = FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["dc:subject/rdf:Bag/rdf:li/text()"],
        :select_result_value => true)
      if tag_list != nil && tag_list.size > 0
        for tag in tag_list
          @tags << tag.downcase.strip
        end
      end
    end
    if @tags.nil? || @tags.size == 0
      # messy effort to find ourselves some tags, mainly for del.icio.us
      @tags = []
      rdf_bag = FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["taxo:topics/rdf:Bag/rdf:li"])
      if rdf_bag != nil && rdf_bag.size > 0
        for tag_node in rdf_bag
          begin
            tag_url = FeedTools::XmlHelper.try_xpaths(tag_node,
              ["@resource"],
              :select_result_value => true)
            tag_match = tag_url.scan(/\/(tag|tags)\/(\w+)$/)
            if tag_match.size > 0
              @tags << tag_match.first.last.downcase.strip
            end
          rescue
          end
        end
      end
    end
    if @tags.nil? || @tags.size == 0
      @tags = []
      tag_list = FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["category/text()"],
        :select_result_value => true)
      for tag in tag_list
        @tags << tag.to_s.downcase.strip
      end
    end
    if @tags.nil? || @tags.size == 0
      @tags = []
      tag_list = FeedTools::XmlHelper.try_xpaths_all(self.root_node,
        ["dc:subject/text()"],
        :select_result_value => true)
      for tag in tag_list
        @tags << tag.to_s.downcase.strip
      end
    end
    if @tags.blank?
      begin
        itunes_keywords_string =
          FeedTools::XmlHelper.try_xpaths(self.root_node, [
            "itunes:keywords/text()"
          ], :select_result_value => true)
        unless itunes_keywords_string.blank?
          @tags = itunes_keywords_string.downcase.split(",")
          if @tags.size == 1
            @tags = itunes_keywords_string.downcase.split(" ")
            @tags = @tags.map { |tag| tag.chomp(",") }
          end
          if @tags.size == 1
            @tags = itunes_keywords_string.downcase.split(",")
          end
          @tags = @tags.map { |tag| tag.strip }
        end
      rescue
        @tags = []
      end
    end
    if @tags.nil?
      @tags = []
    end
    @tags.uniq!
  end
  return @tags
end
tags=(new_tags) click to toggle source

Sets the feed item tags

# File lib/feed_tools/feed_item.rb, line 1996
def tags=(new_tags)
  @tags = new_tags
end
time(options = {}) click to toggle source

Returns the feed item time

# File lib/feed_tools/feed_item.rb, line 1718
def time(options = {})
  FeedTools::GenericHelper.validate_options([ :estimate_timestamp ],
                   options.keys)
  options = { :estimate_timestamp => true }.merge(options)
  if @time.nil?
    time_string = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:updated/text()",
      "atom03:updated/text()",
      "atom:updated/text()",
      "updated/text()",
      "atom10:modified/text()",
      "atom03:modified/text()",
      "atom:modified/text()",
      "modified/text()",
      "time/text()",
      "lastBuildDate/text()",
      "atom10:issued/text()",
      "atom03:issued/text()",
      "atom:issued/text()",
      "issued/text()",
      "atom10:published/text()",
      "atom03:published/text()",
      "atom:published/text()",
      "published/text()",
      "dc:date/text()",
      "pubDate/text()",
      "date/text()",
      "lastupdated/text()"
    ], :select_result_value => true)
    begin
      if !time_string.blank?
        @time = Time.parse(time_string).gmtime
      elsif self.configurations[:timestamp_estimation_enabled] &&
          !self.title.nil? &&
          (Time.parse(self.title) - Time.now).abs > 100
        @time = Time.parse(self.title).gmtime
      end
    rescue
    end
    if self.configurations[:timestamp_estimation_enabled]
      if options[:estimate_timestamp]
        if @time.nil?
          begin
            @time = succ_time
            if @time.nil?
              @time = prev_time
            end
          rescue
          end
          if @time.nil?
            @time = Time.now.gmtime
          end
        end
      end
    end
  end
  return @time
end
time=(new_time) click to toggle source

Sets the feed item time

# File lib/feed_tools/feed_item.rb, line 1778
def time=(new_time)
  @time = new_time
end
title() click to toggle source

Returns the feed item title

# File lib/feed_tools/feed_item.rb, line 290
def title
  if @title.nil?
    repair_entities = false
    title_node = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:title",
      "atom03:title",
      "atom:title",
      "title",
      "dc:title",
      "headline"
    ])
    @title = FeedTools::HtmlHelper.process_text_construct(title_node,
      self.feed_type, self.feed_version, [self.base_uri])
    if self.feed_type == "atom" ||
        self.configurations[:always_strip_wrapper_elements]
      @title = FeedTools::HtmlHelper.strip_wrapper_element(@title)
    end
    if !@title.blank? && self.configurations[:strip_comment_count]
      # Some blogging tools include the number of comments in a post
      # in the title... this is supremely ugly, and breaks any
      # applications which expect the title to be static, so we're
      # gonna strip them out.
      #
      # If for some incredibly wierd reason you need the actual
      # unstripped title, just use find_node("title/text()").to_s
      @title = @title.strip.gsub(/\[\d*\]$/, "").strip
    end
    @title = nil if @title.blank?
  end
  return @title
end
title=(new_title) click to toggle source

Sets the feed item title

# File lib/feed_tools/feed_item.rb, line 323
def title=(new_title)
  @title = new_title
end
updated() click to toggle source

Returns the feed item updated time

# File lib/feed_tools/feed_item.rb, line 1835
def updated
  if @updated.nil?
    updated_string = FeedTools::XmlHelper.try_xpaths(self.root_node, [
      "atom10:updated/text()",
      "atom03:updated/text()",
      "atom:updated/text()",
      "updated/text()",
      "atom10:modified/text()",
      "atom03:modified/text()",
      "atom:modified/text()",
      "modified/text()",
      "lastBuildDate/text()",
      "lastupdated/text()"
    ], :select_result_value => true)
    if !updated_string.blank?
      @updated = Time.parse(updated_string).gmtime rescue nil
    else
      @updated = nil
    end
  end
  return @updated
end
updated=(new_updated) click to toggle source

Sets the feed item updated time

# File lib/feed_tools/feed_item.rb, line 1859
def updated=(new_updated)
  @updated = new_updated
end
xml_document() click to toggle source

Returns a REXML Document of the feed_data

# File lib/feed_tools/feed_item.rb, line 194
def xml_document
  if @xml_document.nil?
    return nil if self.feed_data.blank?
    if self.feed_data_type != :xml
      @xml_document = nil
    else
      # TODO: :ignore_whitespace_nodes => :all
      # Add that?
      # ======================================
      @xml_document = REXML::Document.new(self.feed_data)
    end
  end
  return @xml_document
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.