class OpenGraph

Attributes

description[RW]
html_content[RW]
images[RW]
metadata[RW]
original_images[RW]
response[RW]
src[RW]
title[RW]
type[RW]
url[RW]

Public Class Methods

new(src, fallback = true, options = {}) click to toggle source
# File lib/open_graph.rb, line 9
def initialize(src, fallback = true, options = {})
  if fallback.is_a? Hash
    options = fallback
    fallback = true
  end
  @src = src
  @body = nil
  @images = []
  @metadata = {}
  parse_opengraph(options)
  load_fallback if fallback
  check_images_path
end

Private Instance Methods

add_image(image_url) click to toggle source
# File lib/open_graph.rb, line 99
def add_image(image_url)
  @images << image_url unless @images.include?(image_url) || image_url.to_s.empty?
end
add_metadata(metadata_container, path, content) click to toggle source
# File lib/open_graph.rb, line 116
def add_metadata(metadata_container, path, content)
  path_elements = path.split(':')
  if path_elements.size > 1
    current_element = path_elements.delete_at(0)
    path = path_elements.join(':')
    if metadata_container[current_element.to_sym]
      path_pointer = metadata_container[current_element.to_sym].last
      index_count = metadata_container[current_element.to_sym].size
      metadata_container[current_element.to_sym][index_count - 1] = add_metadata(path_pointer, path, content)
      metadata_container
    else
      metadata_container[current_element.to_sym] = []
      metadata_container[current_element.to_sym] << add_metadata({}, path, content)
      metadata_container
    end
  else
    metadata_container[path.to_sym] ||= []
    metadata_container[path.to_sym] << {'_value'.to_sym => content}
    metadata_container
  end
end
check_images_path() click to toggle source
# File lib/open_graph.rb, line 80
def check_images_path
  @original_images = @images.dup

  uri = Addressable::URI.parse(@url || @src)

  return unless uri

  imgs = @images.dup
  @images = []
  imgs.each do |img|
    if Addressable::URI.parse(img).host.nil?
      full_path = uri.join(img).to_s
      add_image(full_path)
    else
      add_image(img)
    end
  end
end
fetch_first_text(doc) click to toggle source
# File lib/open_graph.rb, line 109
def fetch_first_text(doc)
  doc.xpath('//p').each do |p|
    s = p.text.to_s.strip
    return s if s.length > 20
  end
end
fetch_images(doc, xpath_str, attr) click to toggle source
# File lib/open_graph.rb, line 103
def fetch_images(doc, xpath_str, attr)
  doc.xpath(xpath_str).each do |link|
    add_image(link.attribute(attr).to_s.strip)
  end
end
load_fallback() click to toggle source
# File lib/open_graph.rb, line 57
def load_fallback
  if @body
    doc = Nokogiri.parse(@body)

    if @title.to_s.empty? && doc.xpath("//head//title").size > 0
      @title = doc.xpath("//head//title").first.text.to_s.strip
    end

    @url = @src if @url.to_s.empty?

    if @description.to_s.empty? && description_meta = doc.xpath("//head//meta[@name='description']").first
      @description = description_meta.attribute("content").to_s.strip
    end

    if @description.to_s.empty?
      @description = fetch_first_text(doc)
    end

    fetch_images(doc, "//head//link[@rel='image_src']", "href") if @images.empty?
    fetch_images(doc, "//img", "src") if @images.empty?
  end
end
parse_opengraph(options = {}) click to toggle source
# File lib/open_graph.rb, line 24
def parse_opengraph(options = {})
  begin
    if @src.include? '</html>'
      @body = @src
      @html_content = true
    else
      @body = RedirectFollower.new(@src, options).resolve.body
      @html_content = false
    end
  rescue
    @title = @url = @src
    return
  end

  if @body
    attrs_list = %w(title url type description)
    doc = Nokogiri.parse(@body)
    doc.css('meta').each do |m|
      if m.attribute('property') && m.attribute('property').to_s.match(/^og:(.+)$/i)
        m_content = m.attribute('content').to_s.strip
        metadata_name = m.attribute('property').to_s.gsub("og:", "")
        @metadata = add_metadata(@metadata, metadata_name, m_content)
        case metadata_name
          when *attrs_list
            self.instance_variable_set("@#{metadata_name}", m_content) unless m_content.empty?
          when "image"
            add_image(m_content)
        end
      end
    end
  end
end