open_graph_reader 0.7.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/open_graph_reader/base.rb +3 -3
- data/lib/open_graph_reader/builder.rb +2 -2
- data/lib/open_graph_reader/configuration.rb +8 -8
- data/lib/open_graph_reader/definitions.rb +21 -17
- data/lib/open_graph_reader/fetcher.rb +6 -3
- data/lib/open_graph_reader/object/dsl/types.rb +19 -25
- data/lib/open_graph_reader/object/dsl.rb +3 -3
- data/lib/open_graph_reader/object/registry.rb +1 -2
- data/lib/open_graph_reader/object.rb +1 -1
- data/lib/open_graph_reader/parser/graph.rb +9 -9
- data/lib/open_graph_reader/parser.rb +8 -3
- data/lib/open_graph_reader/version.rb +2 -2
- data/lib/open_graph_reader.rb +3 -3
- data/spec/fixtures/test_cases/image_alt_before_image.html +13 -0
- data/spec/integration/real_world_spec.rb +140 -140
- data/spec/integration/test_cases_spec.rb +17 -0
- data/spec/integration/valid_examples_spec.rb +5 -5
- data/spec/open_graph_reader/fetcher_spec.rb +1 -1
- data/spec/open_graph_reader_spec.rb +15 -15
- data/spec/spec_helper.rb +1 -1
- metadata +16 -88
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e7c1f4b9ce43af3f0ba0a120f14bdd14bf5f91aacac242e3c9d8f000d06b861
|
4
|
+
data.tar.gz: f8300efb032e1f687f5c99d8b53b2a553c7b6de9cd45f6c323ac86b8b9761646
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da884cc904c76766f0fa5e6cce33e224511be0c489c7ae99cc589a639efdfdb8c48aa90b4c51ad312f86a8133012c96efbb11f001b4a9d134c913884b697d277
|
7
|
+
data.tar.gz: '028e2821d6a628a266d8c365254518d3e3758f2ea94ab612addae5a875dd280eecc287e7c087aef3d957288581cdd4839bf6177ec21c2c576d17a07c798aa44c'
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# OpenGraphReader [![Gem Version](https://badge.fury.io/rb/open_graph_reader.svg)](http://badge.fury.io/rb/open_graph_reader)
|
1
|
+
# OpenGraphReader [![Gem Version](https://badge.fury.io/rb/open_graph_reader.svg)](http://badge.fury.io/rb/open_graph_reader)
|
2
2
|
|
3
3
|
A library to fetch and parse OpenGraph properties from an URL or a given string.
|
4
4
|
|
@@ -17,14 +17,14 @@ A library to fetch and parse OpenGraph properties from an URL or a given string.
|
|
17
17
|
* Objects and their properties are defined in code, not by parsing the response at the namespace identifier.
|
18
18
|
|
19
19
|
|
20
|
-
Ruby
|
20
|
+
Ruby 3.1 and later are supported. Compatibility with earlier versions might exist but is not verified.
|
21
21
|
|
22
22
|
## Installation
|
23
23
|
|
24
24
|
Add this line to your application's Gemfile:
|
25
25
|
|
26
26
|
```ruby
|
27
|
-
gem
|
27
|
+
gem "open_graph_reader"
|
28
28
|
```
|
29
29
|
|
30
30
|
And then execute:
|
@@ -38,13 +38,13 @@ Or install it yourself as:
|
|
38
38
|
|
39
39
|
Install the following gems the same way for a higher success rate at fetching websites:
|
40
40
|
|
41
|
-
* [
|
41
|
+
* [faraday-follow_redirects](https://github.com/tisba/faraday-follow-redirects)
|
42
42
|
* [faraday-cookie_jar](https://github.com/miyagawa/faraday-cookie_jar)
|
43
43
|
|
44
44
|
## Usage
|
45
45
|
|
46
46
|
```ruby
|
47
|
-
require
|
47
|
+
require "open_graph_reader"
|
48
48
|
|
49
49
|
# Returns nil if anything on the object is invalid
|
50
50
|
object = OpenGraphReader.fetch("http://examples.opengraphprotocol.us/article.html")
|
@@ -52,18 +52,18 @@ module OpenGraphReader
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# @private
|
55
|
-
def respond_to_missing?(method, _include_private=false)
|
55
|
+
def respond_to_missing?(method, _include_private = false)
|
56
56
|
@bases.has_key? method.to_s
|
57
57
|
end
|
58
58
|
|
59
59
|
# Makes the found root objects available.
|
60
60
|
# @return [Object]
|
61
|
-
def method_missing(method,
|
61
|
+
def method_missing(method, ...)
|
62
62
|
name = method.to_s
|
63
63
|
if respond_to_missing? name
|
64
64
|
@bases[name]
|
65
65
|
else
|
66
|
-
super
|
66
|
+
super
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
@@ -7,7 +7,7 @@ module OpenGraphReader
|
|
7
7
|
# Well-known types from
|
8
8
|
#
|
9
9
|
# @see http://ogp.me
|
10
|
-
KNOWN_TYPES = %w
|
10
|
+
KNOWN_TYPES = %w[website article book profile].freeze
|
11
11
|
|
12
12
|
# Create a new builder.
|
13
13
|
#
|
@@ -188,7 +188,7 @@ module OpenGraphReader
|
|
188
188
|
|
189
189
|
def extra_properties object, type, verticals
|
190
190
|
valid_properties = verticals[type]
|
191
|
-
set_properties
|
191
|
+
set_properties = object.class.available_properties.select { |property| object[property] }
|
192
192
|
|
193
193
|
set_properties - valid_properties
|
194
194
|
end
|
@@ -98,15 +98,15 @@ module OpenGraphReader
|
|
98
98
|
|
99
99
|
# Reset configuration to their defaults
|
100
100
|
def reset_to_defaults!
|
101
|
-
@strict
|
102
|
-
@validate_required
|
103
|
-
@validate_references
|
101
|
+
@strict = false
|
102
|
+
@validate_required = true
|
103
|
+
@validate_references = true
|
104
104
|
@discard_invalid_optional_properties = false
|
105
|
-
@synthesize_title
|
106
|
-
@synthesize_url
|
107
|
-
@synthesize_full_url
|
108
|
-
@synthesize_image_url
|
109
|
-
@guess_datetime_format
|
105
|
+
@synthesize_title = false
|
106
|
+
@synthesize_url = false
|
107
|
+
@synthesize_full_url = false
|
108
|
+
@synthesize_image_url = false
|
109
|
+
@guess_datetime_format = false
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
@@ -9,7 +9,7 @@ module OpenGraphReader
|
|
9
9
|
|
10
10
|
# @!macro property
|
11
11
|
# @return [String]
|
12
|
-
string :type,
|
12
|
+
string :type, required: true, downcase: true, default: "website"
|
13
13
|
|
14
14
|
# @!macro property
|
15
15
|
# @return [String]
|
@@ -74,6 +74,10 @@ module OpenGraphReader
|
|
74
74
|
# @return [Integer, nil]
|
75
75
|
integer :height
|
76
76
|
|
77
|
+
# @!macro property
|
78
|
+
# @return [String, nil]
|
79
|
+
string :alt
|
80
|
+
|
77
81
|
# @return [String, nil]
|
78
82
|
def url
|
79
83
|
secure_url || properties[:url] || content
|
@@ -169,7 +173,7 @@ module OpenGraphReader
|
|
169
173
|
|
170
174
|
# @!macro property
|
171
175
|
# @return [String, nil]
|
172
|
-
enum :gender, %w
|
176
|
+
enum :gender, %w[male female]
|
173
177
|
|
174
178
|
# @!macro property
|
175
179
|
# @return [String, nil]
|
@@ -224,38 +228,38 @@ module OpenGraphReader
|
|
224
228
|
# @return [Array<Profile>]
|
225
229
|
# @!macro property
|
226
230
|
# @return [Profile, nil]
|
227
|
-
url :actor,
|
231
|
+
url :actor, to: Profile, verticals: %w[movie episode tv_show other], collection: true
|
228
232
|
|
229
233
|
# @!attribute [r] directors
|
230
234
|
# @return [Array<Profile>]
|
231
235
|
# @!macro property
|
232
236
|
# @return [Profile, nil]
|
233
|
-
url :director, to: Profile, verticals: %w
|
237
|
+
url :director, to: Profile, verticals: %w[movie episode tv_show other], collection: true
|
234
238
|
|
235
239
|
# @!attribute [r] writers
|
236
240
|
# @return [Array<Profile>]
|
237
241
|
# @!macro property
|
238
242
|
# @return [Profile, nil]
|
239
|
-
url :writer,
|
243
|
+
url :writer, to: Profile, verticals: %w[movie episode tv_show other], collection: true
|
240
244
|
|
241
245
|
# @!macro property
|
242
246
|
# @return [Integer, nil]
|
243
|
-
integer :duration,
|
247
|
+
integer :duration, verticals: %w[movie episode tv_show other]
|
244
248
|
|
245
249
|
# @!macro property
|
246
250
|
# @return [DateTime, nil]
|
247
|
-
datetime :release_date,
|
251
|
+
datetime :release_date, verticals: %w[movie episode tv_show other]
|
248
252
|
|
249
253
|
# @!attribute [r] tags
|
250
254
|
# @return [Array<String>]
|
251
255
|
# @!macro property
|
252
256
|
# @return [String, nil]
|
253
|
-
string :tag,
|
257
|
+
string :tag, verticals: %w[movie episode tv_show other], collection: true
|
254
258
|
|
255
259
|
# @todo validate that target vertical is video.tv_show ?
|
256
260
|
# @!macro property
|
257
261
|
# @return [Sring, nil]
|
258
|
-
url :series,
|
262
|
+
url :series, to: Video, verticals: %w[episode]
|
259
263
|
end
|
260
264
|
|
261
265
|
# @see http://ogp.me/#type_book
|
@@ -294,39 +298,39 @@ module OpenGraphReader
|
|
294
298
|
|
295
299
|
# @!macro property
|
296
300
|
# @return [Integer, nil]
|
297
|
-
integer :duration, verticals: %w
|
301
|
+
integer :duration, verticals: %w[song]
|
298
302
|
|
299
303
|
# @todo validate that target vertical is music.album/music.song ?
|
300
304
|
# @!attribute [r] albums
|
301
305
|
# @return [Array<Music>]
|
302
306
|
# @macro property
|
303
307
|
# @return [Music, nil]
|
304
|
-
url :album, to: Music,
|
308
|
+
url :album, to: Music, verticals: %w[song], collection: true
|
305
309
|
|
306
310
|
# @macro property
|
307
311
|
# @return [Integer, nil]
|
308
|
-
integer :disc,
|
312
|
+
integer :disc, verticals: %w[song album playlist]
|
309
313
|
|
310
314
|
# @macro property
|
311
315
|
# @return [Integer, nil]
|
312
|
-
integer :track,
|
316
|
+
integer :track, verticals: %w[song album playlist]
|
313
317
|
|
314
318
|
# @!attribute [r] musicians
|
315
319
|
# @return [Array<Profile>]
|
316
320
|
# @!macro property
|
317
321
|
# @return [Profile, nil]
|
318
|
-
url :musician, to: Profile, verticals: %w
|
322
|
+
url :musician, to: Profile, verticals: %w[song album], collection: true
|
319
323
|
|
320
324
|
# @macro property
|
321
325
|
# @return [Music, nil]
|
322
|
-
url :song, to: Music,
|
326
|
+
url :song, to: Music, verticals: %w[album playlist]
|
323
327
|
|
324
328
|
# @macro property
|
325
329
|
# @return [DateTime, nil]
|
326
|
-
datetime :release_date,
|
330
|
+
datetime :release_date, verticals: %w[album]
|
327
331
|
|
328
332
|
# @macro property
|
329
333
|
# @return [Profile, nil]
|
330
|
-
url :creator, to: Profile,
|
334
|
+
url :creator, to: Profile, verticals: %w[playlist radio_station]
|
331
335
|
end
|
332
336
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "faraday"
|
2
2
|
|
3
3
|
begin
|
4
|
-
require "
|
4
|
+
require "faraday/follow_redirects"
|
5
5
|
rescue LoadError; end
|
6
6
|
|
7
7
|
begin
|
@@ -16,7 +16,7 @@ module OpenGraphReader
|
|
16
16
|
# @api private
|
17
17
|
class Fetcher
|
18
18
|
HEADERS = {
|
19
|
-
"Accept"
|
19
|
+
"Accept" => "text/html",
|
20
20
|
"User-Agent" => "OpenGraphReader/#{OpenGraphReader::VERSION} (+https://github.com/jhass/open_graph_reader)"
|
21
21
|
}.freeze
|
22
22
|
|
@@ -25,6 +25,7 @@ module OpenGraphReader
|
|
25
25
|
# @param [URI] uri the URI to fetch.
|
26
26
|
def initialize uri
|
27
27
|
raise ArgumentError, "url needs to be an instance of URI" unless uri.is_a? URI
|
28
|
+
|
28
29
|
@uri = uri
|
29
30
|
@fetch_failed = false
|
30
31
|
@connection = Faraday.default_connection.dup
|
@@ -33,7 +34,7 @@ module OpenGraphReader
|
|
33
34
|
@get_response = nil
|
34
35
|
|
35
36
|
prepend_middleware Faraday::CookieJar if defined? Faraday::CookieJar
|
36
|
-
prepend_middleware
|
37
|
+
prepend_middleware Faraday::FollowRedirects::Middleware if defined? Faraday::FollowRedirects
|
37
38
|
end
|
38
39
|
|
39
40
|
# The URL to fetch
|
@@ -71,6 +72,7 @@ module OpenGraphReader
|
|
71
72
|
fetch_body unless fetched?
|
72
73
|
raise NoOpenGraphDataError, "No response body received for #{@uri}" if fetch_failed?
|
73
74
|
raise NoOpenGraphDataError, "Did not receive a HTML site at #{@uri}" unless html?
|
75
|
+
|
74
76
|
@get_response.body
|
75
77
|
end
|
76
78
|
|
@@ -84,6 +86,7 @@ module OpenGraphReader
|
|
84
86
|
return false unless response
|
85
87
|
return false unless response.success?
|
86
88
|
return false unless response["content-type"]
|
89
|
+
|
87
90
|
response["content-type"].include? "text/html"
|
88
91
|
end
|
89
92
|
|
@@ -40,8 +40,8 @@ module OpenGraphReader
|
|
40
40
|
rescue
|
41
41
|
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
42
42
|
raise InvalidObjectError,
|
43
|
-
|
44
|
-
|
43
|
+
"URL #{value.inspect} does not start with http:// or https:// and failed to " \
|
44
|
+
"synthesize a full URL"
|
45
45
|
end
|
46
46
|
elsif options.has_key?(:to) && OpenGraphReader.config.validate_references
|
47
47
|
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
@@ -67,32 +67,28 @@ module OpenGraphReader
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# @see http://ogp.me/#integer
|
70
|
-
define_type :integer do
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
raise InvalidObjectError, "Integer expected, but was #{value.inspect}"
|
76
|
-
end
|
70
|
+
define_type :integer do |value, options|
|
71
|
+
Integer(value)
|
72
|
+
rescue ArgumentError
|
73
|
+
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
74
|
+
raise InvalidObjectError, "Integer expected, but was #{value.inspect}"
|
77
75
|
end
|
78
76
|
|
79
77
|
# @see http://ogp.me/#datetime
|
80
78
|
define_type :datetime do |value, options|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
DateTime.iso8601 value
|
86
|
-
end
|
87
|
-
rescue ArgumentError
|
88
|
-
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
89
|
-
raise InvalidObjectError, "ISO8601 datetime expected, but was #{value.inspect}"
|
79
|
+
if OpenGraphReader.config.guess_datetime_format
|
80
|
+
DateTime.parse value
|
81
|
+
else
|
82
|
+
DateTime.iso8601 value
|
90
83
|
end
|
84
|
+
rescue ArgumentError
|
85
|
+
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
86
|
+
raise InvalidObjectError, "ISO8601 datetime expected, but was #{value.inspect}"
|
91
87
|
end
|
92
88
|
|
93
89
|
# @see http://ogp.me/#bool
|
94
90
|
define_type :boolean do |value, options|
|
95
|
-
{"true" => true, "false" => false, "1" => true, "0" => false}[value].tap {|bool|
|
91
|
+
{"true" => true, "false" => false, "1" => true, "0" => false}[value].tap { |bool|
|
96
92
|
if bool.nil?
|
97
93
|
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
98
94
|
raise InvalidObjectError, "Boolean expected, but was #{value.inspect}"
|
@@ -102,12 +98,10 @@ module OpenGraphReader
|
|
102
98
|
|
103
99
|
# @see http://ogp.me/#float
|
104
100
|
define_type :float do |value, options|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
raise InvalidObjectError, "Float expected, but was #{value.inspect}"
|
110
|
-
end
|
101
|
+
Float(value)
|
102
|
+
rescue ArgumentError
|
103
|
+
next unless options[:required] || !OpenGraphReader.config.discard_invalid_optional_properties
|
104
|
+
raise InvalidObjectError, "Float expected, but was #{value.inspect}"
|
111
105
|
end
|
112
106
|
end
|
113
107
|
end
|
@@ -72,7 +72,7 @@ module OpenGraphReader
|
|
72
72
|
define_method(name) do
|
73
73
|
value = children[name.to_s].first
|
74
74
|
# @todo figure out a sane way to distinguish subobject properties
|
75
|
-
value.content if value
|
75
|
+
value.content if value&.is_a?(Object)
|
76
76
|
value || options[:default]
|
77
77
|
end
|
78
78
|
end
|
@@ -130,7 +130,7 @@ module OpenGraphReader
|
|
130
130
|
options = args.pop if args.last.is_a? Hash
|
131
131
|
options ||= {}
|
132
132
|
|
133
|
-
@content_processor = proc {|value|
|
133
|
+
@content_processor = proc { |value|
|
134
134
|
value.downcase! if options[:downcase]
|
135
135
|
options[:to] ||= self
|
136
136
|
DSL.processors[type].call(value, *args, options)
|
@@ -164,7 +164,7 @@ module OpenGraphReader
|
|
164
164
|
# @api private
|
165
165
|
# @return [{String => Array<Strin>}]
|
166
166
|
def verticals
|
167
|
-
@verticals ||= Hash.new {|h, k| h[k] = [] }
|
167
|
+
@verticals ||= Hash.new { |h, k| h[k] = [] }
|
168
168
|
end
|
169
169
|
end
|
170
170
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require "singleton"
|
2
2
|
require "forwardable"
|
3
|
-
require "set"
|
4
3
|
|
5
4
|
module OpenGraphReader
|
6
5
|
module Object
|
@@ -44,7 +43,7 @@ module OpenGraphReader
|
|
44
43
|
|
45
44
|
def_delegators :@namespaces, :[]=, :has_key?
|
46
45
|
alias_method :register, :[]=
|
47
|
-
alias_method :registered?,
|
46
|
+
alias_method :registered?, :has_key?
|
48
47
|
|
49
48
|
# @see Registry.verticals
|
50
49
|
attr_reader :verticals
|
@@ -39,7 +39,7 @@ module OpenGraphReader
|
|
39
39
|
# Create a new object. If your class overrides this don't forget to call <tt>super</tt>.
|
40
40
|
def initialize
|
41
41
|
@properties = {}
|
42
|
-
@children = Hash.new {|h, k| h[k] = [] }
|
42
|
+
@children = Hash.new { |h, k| h[k] = [] }
|
43
43
|
end
|
44
44
|
|
45
45
|
# Whether this object has the given property
|
@@ -48,7 +48,7 @@ module OpenGraphReader
|
|
48
48
|
#
|
49
49
|
# @return [String]
|
50
50
|
def namespace
|
51
|
-
parent
|
51
|
+
parent&.fullname
|
52
52
|
end
|
53
53
|
|
54
54
|
# Get node's namespace as array.
|
@@ -69,7 +69,7 @@ module OpenGraphReader
|
|
69
69
|
def inspect
|
70
70
|
"#{super.chop} children=#{children.inspect}>"
|
71
71
|
end
|
72
|
-
|
72
|
+
alias_method :to_s, :inspect
|
73
73
|
end
|
74
74
|
|
75
75
|
extend Forwardable
|
@@ -109,8 +109,8 @@ module OpenGraphReader
|
|
109
109
|
# @return [Bool] Whether the given property exists in the graph.
|
110
110
|
def exist? property
|
111
111
|
path = property.split(":")
|
112
|
-
child = path.inject(root) {|node, name|
|
113
|
-
node.children.find {|child| child.name == name } || break
|
112
|
+
child = path.inject(root) { |node, name|
|
113
|
+
node.children.find { |child| child.name == name } || break
|
114
114
|
}
|
115
115
|
!child.nil? && !child.empty?
|
116
116
|
end
|
@@ -121,7 +121,7 @@ module OpenGraphReader
|
|
121
121
|
# @param [String] default The default in case the a value is not found.
|
122
122
|
# @yield Return a default in case the value is not found. Supersedes the default parameter.
|
123
123
|
# @return [String, Bool, Integer, Float, DateTime, nil]
|
124
|
-
def fetch property, default=nil
|
124
|
+
def fetch property, default = nil
|
125
125
|
node = find_by(property)
|
126
126
|
return yield if node.nil? && block_given?
|
127
127
|
return default if node.nil?
|
@@ -134,7 +134,7 @@ module OpenGraphReader
|
|
134
134
|
# @return [Node, nil]
|
135
135
|
def find_by property
|
136
136
|
property = normalize_property property
|
137
|
-
find {|node| node.fullname == property }
|
137
|
+
find { |node| node.fullname == property }
|
138
138
|
end
|
139
139
|
|
140
140
|
# Fetch all nodes
|
@@ -143,12 +143,12 @@ module OpenGraphReader
|
|
143
143
|
# @return [Array<Node>]
|
144
144
|
def select_by property
|
145
145
|
property = normalize_property property
|
146
|
-
select {|node| node.fullname == property }
|
146
|
+
select { |node| node.fullname == property }
|
147
147
|
end
|
148
148
|
|
149
149
|
def find_or_create_path path
|
150
|
-
path.inject(root) {|node, name|
|
151
|
-
child = node.children.reverse.find {|child| child.name == name }
|
150
|
+
path.inject(root) { |node, name|
|
151
|
+
child = node.children.reverse.find { |child| child.name == name }
|
152
152
|
|
153
153
|
unless child
|
154
154
|
child = Node.new name
|
@@ -11,7 +11,7 @@ module OpenGraphReader
|
|
11
11
|
module XPathHelpers
|
12
12
|
# Helper to lowercase all given properties
|
13
13
|
def self.ci_starts_with node_set, string
|
14
|
-
node_set.select {|node|
|
14
|
+
node_set.select { |node|
|
15
15
|
node.to_s.downcase.start_with? string.downcase
|
16
16
|
}
|
17
17
|
end
|
@@ -56,7 +56,7 @@ module OpenGraphReader
|
|
56
56
|
def build_graph
|
57
57
|
graph = Graph.new
|
58
58
|
|
59
|
-
|
59
|
+
sorted_meta_tags.each do |tag|
|
60
60
|
*path, leaf = tag["property"].downcase.split(":")
|
61
61
|
node = graph.find_or_create_path path
|
62
62
|
|
@@ -67,6 +67,11 @@ module OpenGraphReader
|
|
67
67
|
graph
|
68
68
|
end
|
69
69
|
|
70
|
+
# Ensure the tags are sorted by their hierarchy, that is sort a:b before a:b:c.
|
71
|
+
def sorted_meta_tags
|
72
|
+
meta_tags.sort_by { |tag| tag["property"] }
|
73
|
+
end
|
74
|
+
|
70
75
|
def meta_tags
|
71
76
|
head = @doc.xpath("/html/head").first
|
72
77
|
|
@@ -80,7 +85,7 @@ module OpenGraphReader
|
|
80
85
|
|
81
86
|
if head["prefix"]
|
82
87
|
@additional_namespaces = head["prefix"].scan(/(\w+):\s*([^ ]+)/)
|
83
|
-
@additional_namespaces.map! {|prefix, _| prefix.downcase }
|
88
|
+
@additional_namespaces.map! { |prefix, _| prefix.downcase }
|
84
89
|
@additional_namespaces.each do |additional_namespace|
|
85
90
|
next if additional_namespace == "og"
|
86
91
|
condition << " or ci_starts_with(@property, '#{additional_namespace}')"
|
data/lib/open_graph_reader.rb
CHANGED
@@ -37,11 +37,11 @@ module OpenGraphReader
|
|
37
37
|
# @return [Base] The base object from which you can obtain the root objects.
|
38
38
|
# @raise [NoOpenGraphDataError] {include:NoOpenGraphDataError}
|
39
39
|
# @raise [InvalidObjectError] {include:InvalidObjectError}
|
40
|
-
def self.parse! html, origin=nil
|
40
|
+
def self.parse! html, origin = nil
|
41
41
|
self.current_origin = origin
|
42
42
|
parser = Parser.new html
|
43
43
|
raise NoOpenGraphDataError, "#{origin || html} does not contain any OpenGraph tags" unless parser.any_tags?
|
44
|
-
Builder.new(parser).base.tap {|base|
|
44
|
+
Builder.new(parser).base.tap { |base|
|
45
45
|
base.origin = origin.to_s if origin
|
46
46
|
self.current_origin = nil
|
47
47
|
}
|
@@ -65,7 +65,7 @@ module OpenGraphReader
|
|
65
65
|
# @param [#to_s] origin The source from where the given document was fetched.
|
66
66
|
# @return [Base, nil] The base object from which you can obtain the root objects.
|
67
67
|
# @see OpenGraphReader.parse!
|
68
|
-
def self.parse html, origin=nil
|
68
|
+
def self.parse html, origin = nil
|
69
69
|
parse! html, origin
|
70
70
|
rescue NoOpenGraphDataError, InvalidObjectError
|
71
71
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta property="og:title" content="title">
|
6
|
+
<meta property="og:description" content="desc">
|
7
|
+
<meta property="og:url" content="https://example.com">
|
8
|
+
|
9
|
+
<meta property="og:image:alt" content="image:alt">
|
10
|
+
<meta property="og:image" content="https://example.com/example.png">
|
11
|
+
</head>
|
12
|
+
<body></body>
|
13
|
+
</html>
|