File: open_graph_reader.rb

package info (click to toggle)
ruby-open-graph-reader 0.7.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 9,976 kB
  • sloc: ruby: 1,525; xml: 22; makefile: 2
file content (122 lines) | stat: -rw-r--r-- 4,122 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
require "uri"

require "open_graph_reader/base"
require "open_graph_reader/builder"
require "open_graph_reader/configuration"
require "open_graph_reader/definitions"
require "open_graph_reader/fetcher"
require "open_graph_reader/object"
require "open_graph_reader/parser"
require "open_graph_reader/version"

# @todo 1.1 compatibility mode?
# This module provides the main entry to the library. Please see the
# {file:README.md} for usage examples.
module OpenGraphReader
  # Fetch the OpenGraph object at the given URL. Raise if there are any issues.
  #
  # @param [URI,#to_s] url The URL of the OpenGraph object to retrieve.
  # @return [Base] The base object from which you can obtain the root objects.
  # @raise [NoOpenGraphDataError] {include:NoOpenGraphDataError}
  # @raise [InvalidObjectError] {include:InvalidObjectError}
  def self.fetch! url
    case url
    when URI
      target = Fetcher.new(url)
      raise NoOpenGraphDataError, "#{url} doesn't contain any HTML" unless target.html?
      parse! target.body, target.url
    else
      fetch! URI.parse(url.to_s)
    end
  end

  # Parse the OpenGraph object in the given HTML document. Raise if there are any issues.
  #
  # @param [#to_s, Nokogiri::XML::Node] html A HTML document that contains an OpenGraph object.
  # @param [#to_s] origin The source from where the given document was fetched.
  # @return [Base] The base object from which you can obtain the root objects.
  # @raise [NoOpenGraphDataError] {include:NoOpenGraphDataError}
  # @raise [InvalidObjectError] {include:InvalidObjectError}
  def self.parse! html, origin=nil
    self.current_origin = origin
    parser = Parser.new html
    raise NoOpenGraphDataError, "#{origin || html} does not contain any OpenGraph tags" unless parser.any_tags?
    Builder.new(parser).base.tap {|base|
      base.origin = origin.to_s if origin
      self.current_origin = nil
    }
  end

  # Convenience wrapper around {OpenGraphReader.fetch!} that swallows the esceptions
  # and returns nil instead.
  #
  # @param [URI,#to_s] url The URL of the OpenGraph object to retrieve.
  # @return [Base, nil] The base object from which you can obtain the root objects.
  # @see OpenGraphReader.fetch!
  def self.fetch url
    fetch! url
  rescue NoOpenGraphDataError, InvalidObjectError
  end

  # Convenience wrapper around {OpenGraphReader.parse!} that swallows the esceptions
  # and returns nil instead.
  #
  # @param [#to_s] html A HTML document that contains an OpenGraph object.
  # @param [#to_s] origin The source from where the given document was fetched.
  # @return [Base, nil] The base object from which you can obtain the root objects.
  # @see OpenGraphReader.parse!
  def self.parse html, origin=nil
    parse! html, origin
  rescue NoOpenGraphDataError, InvalidObjectError
  end

  # Configure the library, see {Configuration} for the list of available
  # options and their defaults. Changing configuration at runtime is not
  # thread safe.
  #
  # @yieldparam [Configuration] the configuration object
  # @see Configuration
  def self.configure
    yield config
  end

  # Get the current {Configuration} instance
  #
  # @api private
  # @return [Configuration]
  def self.config
    Configuration.instance
  end

  # Thread local to retrieve the current origin if available.
  # See {Base#origin} if you want to know the origin of a parsed object.
  #
  # @api private
  # @return [String,nil]
  def self.current_origin
    Thread.current[:_open_graph_reader_current_origin]
  end

  def self.current_origin= value
    Thread.current[:_open_graph_reader_current_origin] = value
  end

  # The target couldn't be fetched, didn't contain any HTML or
  # any OpenGraph tags.
  class NoOpenGraphDataError < StandardError
  end

  # The target did contain OpenGraph tags, but they're not valid.
  class InvalidObjectError < StandardError
  end

  # The target defines a namespace we have no definition for
  #
  # @api private
  class UnknownNamespaceError < StandardError
  end

  # The target does not define the requested property.
  class UndefinedPropertyError < StandardError
  end
end