ruby-oembed 0.7.6 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -1
- data/CHANGELOG.rdoc +49 -0
- data/Gemfile.lock +13 -8
- data/README.rdoc +79 -0
- data/Rakefile +21 -6
- data/lib/oembed/errors.rb +23 -4
- data/lib/oembed/formatter/json/backends/activesupportjson.rb +28 -0
- data/lib/oembed/formatter/json/backends/jsongem.rb +31 -0
- data/lib/oembed/formatter/json/backends/yaml.rb +85 -0
- data/lib/oembed/formatter/json.rb +69 -0
- data/lib/oembed/formatter/xml/backends/rexml.rb +44 -0
- data/lib/oembed/formatter/xml/backends/xmlsimple.rb +39 -0
- data/lib/oembed/formatter/xml.rb +76 -0
- data/lib/oembed/formatter.rb +97 -0
- data/lib/oembed/provider.rb +102 -38
- data/lib/oembed/provider_discovery.rb +19 -7
- data/lib/oembed/providers/embedly_urls.yml +487 -0
- data/lib/oembed/providers/oohembed_urls.yml +17 -0
- data/lib/oembed/providers.rb +68 -11
- data/lib/oembed/response/link.rb +14 -0
- data/lib/oembed/response/photo.rb +12 -0
- data/lib/oembed/response/rich.rb +11 -0
- data/lib/oembed/response/video.rb +10 -0
- data/lib/oembed/response.rb +58 -10
- data/lib/oembed/version.rb +18 -0
- data/lib/oembed.rb +2 -1
- data/lib/tasks/oembed.rake +45 -0
- data/lib/tasks/rspec.rake +5 -0
- data/ruby-oembed.gemspec +38 -17
- data/spec/formatter/json/.DS_Store +0 -0
- data/spec/formatter/json/jsongem_backend_spec.rb +34 -0
- data/spec/formatter/json/yaml_backend_spec.rb +30 -0
- data/spec/formatter/xml/rexml_backend_spec.rb +30 -0
- data/spec/formatter/xml/xmlsimple_backend_spec.rb +34 -0
- data/spec/formatter_spec.rb +35 -0
- data/spec/provider_spec.rb +189 -24
- data/spec/providers_spec.rb +20 -1
- data/spec/response_spec.rb +129 -48
- data/spec/spec_helper.rb +5 -6
- metadata +45 -38
- data/CHANGELOG.md +0 -29
- data/README.md +0 -50
- data/VERSION +0 -1
- data/lib/oembed/embedly_urls.json +0 -227
- data/lib/oembed/formatters.rb +0 -40
- data/rails/init.rb +0 -3
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
= CHANGELOG
|
2
|
+
|
3
|
+
== 0.8.1 - 27 February 2011
|
4
|
+
|
5
|
+
* Removed all dependencies on external gems. XML is parsed using REXML and JSON can be parsed using YAML thanks to the convert_json_to_yaml method borrowed from Rails! (Marcos Wright Kuhns)
|
6
|
+
* Fixed several errors that cropped up when the json gem wasn't installed. (Marcos Wright Kuhns)
|
7
|
+
* OEmbed::Response#field now always return Strings. Previously, some JSON values were parsed into other Object types, like Integer and Float instances.
|
8
|
+
* OEmbed::Response#url has been renamed OEmbed::Response#request_url because OEmbed::Response::Photo#url should be the URL of the static photo to be used by the oEmbed consumer.
|
9
|
+
* OEmbed::Response.create_for now requires the format parameter.
|
10
|
+
* OEmbed::Formatter backends won't try to load gems that haven't already been loaded. (Marcos Wright Kuhns)
|
11
|
+
* Better code documentation, all around. (Marcos Wright Kuhns)
|
12
|
+
|
13
|
+
=== Deprecations & Removals
|
14
|
+
|
15
|
+
* Removed the OEmbed::Response::METHODS constant.
|
16
|
+
* OEmbed::Provders::Pownce has been removed since pownce.com is no longer active.
|
17
|
+
* Provider#url and Provider#name will be removed at some point in the future.
|
18
|
+
* All direct raw calls will be made private at some point in the future (i.e. Provider#raw, Providers#raw, and ProviderDiscovery#raw)
|
19
|
+
|
20
|
+
== 0.8.0 - Unreleased
|
21
|
+
|
22
|
+
* Added OEmbed::Formatter Backends, to remove the dependency on the json gem and make adding support for other parsing libraries easier. This also fixes GitHub Issue =1. (Marcos Wright Kuhns)
|
23
|
+
* Catch invalid endpoint URLs on OEmbed::Provider instantiation. (Marcos Wright Kuhns)
|
24
|
+
* Jeweler uses the new OEmbed::Version Class. (Marcos Wright Kuhns)
|
25
|
+
* Corrected syntax for Youtube provider in the README (Ryan Richards)
|
26
|
+
* Removed the deprecated rails/init.rb file. (Marcos Wright Kuhns)
|
27
|
+
|
28
|
+
== 0.7.6 - 11 October 2010
|
29
|
+
|
30
|
+
* Released all recent changes to judofyr/master on GitHub. (Marcos Wright Kuhns)
|
31
|
+
* Added CHANGELOG & LICENSE information. (Marcos Wright Kuhns)
|
32
|
+
|
33
|
+
== 0.7.5 - 29 September 2010
|
34
|
+
|
35
|
+
* Updated the list of {Embedly}[http://embed.ly] URL schemes. (Aris Bartee)
|
36
|
+
* {rvmrc file}[http://rvm.beginrescueend.com/workflow/rvmrc/] added. (Aris Bartee)
|
37
|
+
|
38
|
+
== 0.7.0 - 23 August 2010
|
39
|
+
|
40
|
+
* Gemified. (Aris Bartee)
|
41
|
+
* Added the {Embedly}[http://embed.ly] Provider. (Alex Kessinger)
|
42
|
+
* OEmbed::Response now includes the original request url. (Colin Shea)
|
43
|
+
* Unregistering providers with duplicate URL patterns works. (Marcos Wright Kuhns)
|
44
|
+
|
45
|
+
== 0.0.0 - May 2008 - July 2010
|
46
|
+
|
47
|
+
* Initial work & release as a library (Magnus Holm, et al.)
|
48
|
+
* Many Providers supported, including {OohEmbed}[http://oohembed.com].
|
49
|
+
* Support for JSON (via the json gem) and XML (via the xml-simple gem).
|
data/Gemfile.lock
CHANGED
@@ -1,25 +1,31 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-oembed (0.
|
5
|
-
json
|
6
|
-
xml-simple
|
4
|
+
ruby-oembed (0.8.0)
|
7
5
|
|
8
6
|
GEM
|
9
7
|
remote: http://rubygems.org/
|
10
8
|
specs:
|
9
|
+
diff-lcs (1.1.2)
|
11
10
|
gemcutter (0.6.1)
|
12
11
|
git (1.2.5)
|
13
12
|
jeweler (1.4.0)
|
14
13
|
gemcutter (>= 0.1.0)
|
15
14
|
git (>= 1.2.5)
|
16
15
|
rubyforge (>= 2.0.0)
|
17
|
-
json (1.
|
16
|
+
json (1.5.1)
|
18
17
|
json_pure (1.4.6)
|
19
|
-
rspec (
|
18
|
+
rspec (2.5.0)
|
19
|
+
rspec-core (~> 2.5.0)
|
20
|
+
rspec-expectations (~> 2.5.0)
|
21
|
+
rspec-mocks (~> 2.5.0)
|
22
|
+
rspec-core (2.5.1)
|
23
|
+
rspec-expectations (2.5.0)
|
24
|
+
diff-lcs (~> 1.1.2)
|
25
|
+
rspec-mocks (2.5.0)
|
20
26
|
rubyforge (2.0.4)
|
21
27
|
json_pure (>= 1.1.7)
|
22
|
-
xml-simple (1.0.
|
28
|
+
xml-simple (1.0.14)
|
23
29
|
|
24
30
|
PLATFORMS
|
25
31
|
ruby
|
@@ -27,6 +33,5 @@ PLATFORMS
|
|
27
33
|
DEPENDENCIES
|
28
34
|
jeweler
|
29
35
|
json
|
30
|
-
rspec
|
36
|
+
rspec (>= 2.0)
|
31
37
|
ruby-oembed!
|
32
|
-
xml-simple
|
data/README.rdoc
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
= ruby-oembed http://stillmaintained.com/metavida/ruby-oembed.png
|
2
|
+
|
3
|
+
An oEmbed consumer library written in Ruby, letting you easily get embeddable HTML representations of supported web pages, based on their URLs. See {oembed.com}[http://oembed.com] for more about the protocol.
|
4
|
+
|
5
|
+
= Installation
|
6
|
+
|
7
|
+
gem install ruby-oembed
|
8
|
+
|
9
|
+
= Get Started
|
10
|
+
|
11
|
+
== Providers
|
12
|
+
|
13
|
+
Get information about a URL via an OEmbed::Provider. This library comes with many Providers built right in, to make your life easy.
|
14
|
+
|
15
|
+
resource = OEmbed::Providers::Youtube.get("http://www.youtube.com/watch?v=2BYXBC8WQ5k")
|
16
|
+
resource.video? #=> true
|
17
|
+
resource.thumbnail_url #=> "http://i3.ytimg.com/vi/2BYXBC8WQ5k/hqdefault.jpg"
|
18
|
+
resource.html #=> <<-HTML
|
19
|
+
<object width="425" height="344">
|
20
|
+
<param name="movie" value="http://www.youtube.com/v/2BYXBC8WQ5k?fs=1"></param>
|
21
|
+
<param name="allowFullScreen" value="true"></param>
|
22
|
+
<param name="allowscriptaccess" value="always"></param>
|
23
|
+
<embed src="http://www.youtube.com/v/2BYXBC8WQ5k?fs=1" type="application/x-shockwave-flash" width="425" height="344" allowscriptaccess="always" allowfullscreen="true"></embed>
|
24
|
+
</object>
|
25
|
+
HTML
|
26
|
+
|
27
|
+
If you'd like to use a provider that isn't included in the library, it's easy to create one. Just provide the oEmbed API endpoint and URL scheme(s).
|
28
|
+
|
29
|
+
my_provider = OEmbed::Provider.new("http://my.cool-service.com/api/oembed_endpoint.{format}")
|
30
|
+
my_provider << "http://*.cool-service.com/image/*"
|
31
|
+
my_provider << "http://*.cool-service.com/video/*"
|
32
|
+
resource = my_provider.get("http://a.cool-service.com/video/1") #=> OEmbed::Response
|
33
|
+
resource.provider.name #=> "My Cool Service"
|
34
|
+
|
35
|
+
To use multiple Providers at once, simply register them.
|
36
|
+
|
37
|
+
OEmbed::Providers.register(OEmbed::Providers::Youtube, my_provider)
|
38
|
+
resource = OEmbed::Providers.get("http://www.youtube.com/watch?v=2BYXBC8WQ5k") #=> OEmbed::Response
|
39
|
+
resource.type #=> "video"
|
40
|
+
resource.provider.name #=> "Youtube"
|
41
|
+
|
42
|
+
Last but not least, ruby-oembed supports both {oohEmbed}[http://oohembed.com] and {Embedly}[http://embed.ly]. These services are provider aggregators. Each supports a wide array of websites ranging from {Amazon.com}[http://www.amazon.com] to {xkcd}[http://www.xkcd.com].
|
43
|
+
|
44
|
+
== Formatters
|
45
|
+
|
46
|
+
This library works wonderfully on it's on, but can get a speed boost by using 3rd party libraries to parse oEmbed data. To use a 3rd party Formatter, just be sure to require the library _before_ ruby-oembed.
|
47
|
+
|
48
|
+
require 'json'
|
49
|
+
require 'xmlsimple'
|
50
|
+
require 'oembed'
|
51
|
+
|
52
|
+
OEmbed::Formatter::JSON.backend #=> OEmbed::Formatter::JSON::Backends::JSONGem
|
53
|
+
OEmbed::Formatter::XML.backend #=> OEmbed::Formatter::XML::Backends::XmlSimple
|
54
|
+
|
55
|
+
The following, optional, backends are currently supported:
|
56
|
+
* The {JSON implementation for Ruby}[http://flori.github.com/json/]
|
57
|
+
* Rails' ActiveSupport::JSON (confirmed to work with Rails 3.0.x and should work with Rails 2.0+)
|
58
|
+
* {XmlSimple}[http://xml-simple.rubyforge.org/]
|
59
|
+
|
60
|
+
= Lend a Hand
|
61
|
+
|
62
|
+
Code for the ruby-oembed library is {hosted on GitHub}[http://github.com/judofyr/ruby-oembed].
|
63
|
+
|
64
|
+
# Get the code.
|
65
|
+
git clone git://github.com/judofyr/ruby-oembed.git
|
66
|
+
cd ruby-oembed
|
67
|
+
# Install all development-related gems.
|
68
|
+
gem install bundler
|
69
|
+
bundle install
|
70
|
+
# Run the tests.
|
71
|
+
rake specs
|
72
|
+
|
73
|
+
If you encounter any bug, feel free to {create an Issue}[http://github.com/judofyr/ruby-oembed/issues].
|
74
|
+
|
75
|
+
To submit a patch, please {fork}[http://help.github.com/forking/] the library and commit your changes along with relevant tests. Once you're happy with the changes, {send a pull request}[http://help.github.com/pull-requests/].
|
76
|
+
|
77
|
+
= License
|
78
|
+
|
79
|
+
This code is free to use under the terms of the MIT license.
|
data/Rakefile
CHANGED
@@ -1,17 +1,32 @@
|
|
1
|
+
require File.expand_path(File.join(__FILE__, '../lib/oembed/version'))
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'jeweler'
|
5
|
+
|
6
|
+
Dir[File.join(File.dirname(__FILE__), "lib/tasks/*.rake")].sort.each { |ext| load ext }
|
7
|
+
|
3
8
|
Jeweler::Tasks.new do |gemspec|
|
4
9
|
gemspec.name = "ruby-oembed"
|
10
|
+
gemspec.version = OEmbed::Version
|
11
|
+
gemspec.homepage = "http://github.com/judofyr/ruby-oembed"
|
5
12
|
gemspec.summary = "oEmbed for Ruby"
|
6
|
-
gemspec.description = "An oEmbed
|
13
|
+
gemspec.description = "An oEmbed consumer library written in Ruby, letting you easily get embeddable HTML representations of supported web pages, based on their URLs. See http://oembed.com for more information about the protocol."
|
14
|
+
gemspec.license = "MIT"
|
7
15
|
gemspec.email = "arisbartee@gmail.com"
|
8
|
-
gemspec.homepage = "http://github.com/judofyr/ruby-oembed"
|
9
16
|
gemspec.authors = ["Magnus Holm","Alex Kessinger","Aris Bartee","Marcos Wright Kuhns"]
|
10
|
-
gemspec.
|
11
|
-
gemspec.
|
12
|
-
gemspec.add_development_dependency("rspec")
|
17
|
+
gemspec.add_development_dependency("json")
|
18
|
+
gemspec.add_development_dependency("xml-simple")
|
19
|
+
gemspec.add_development_dependency("rspec", ">=2.0")
|
20
|
+
|
21
|
+
gemspec.rdoc_options = %W(
|
22
|
+
--main README.rdoc
|
23
|
+
--title #{gemspec.full_name}
|
24
|
+
--inline-source
|
25
|
+
--exclude tasks
|
26
|
+
CHANGELOG.rdoc
|
27
|
+
)
|
13
28
|
end
|
14
29
|
Jeweler::GemcutterTasks.new
|
15
30
|
rescue LoadError
|
16
31
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
17
|
-
end
|
32
|
+
end
|
data/lib/oembed/errors.rb
CHANGED
@@ -1,28 +1,47 @@
|
|
1
1
|
module OEmbed
|
2
|
+
|
3
|
+
# A generic OEmbed-related Error. The OEmbed library does its best to capture all internal
|
4
|
+
# errors and wrap them in an OEmbed::Error class so that the error-handling code in your
|
5
|
+
# application can more easily identify the source of errors.
|
6
|
+
#
|
7
|
+
# The following Classes inherit from OEmbed::Error
|
8
|
+
# * OEmbed::FormatNotSupported
|
9
|
+
# * OEmbed::NotFound
|
10
|
+
# * OEmbed::ParseError
|
11
|
+
# * OEmbed::UnknownFormat
|
12
|
+
# * OEmbed::UnknownResponse
|
2
13
|
class Error < StandardError
|
3
14
|
end
|
4
15
|
|
5
|
-
|
16
|
+
# This is a test
|
17
|
+
class NotFound < OEmbed::Error # :nodoc:
|
6
18
|
def to_s
|
7
19
|
"No embeddable content at '#{super}'"
|
8
20
|
end
|
9
21
|
end
|
10
22
|
|
11
|
-
class UnknownFormat < OEmbed::Error
|
23
|
+
class UnknownFormat < OEmbed::Error # :nodoc:
|
12
24
|
def to_s
|
13
25
|
"The provider doesn't support the '#{super}' format"
|
14
26
|
end
|
15
27
|
end
|
16
28
|
|
17
|
-
class FormatNotSupported < OEmbed::Error
|
29
|
+
class FormatNotSupported < OEmbed::Error # :nodoc:
|
18
30
|
def to_s
|
19
31
|
"This server doesn't have the correct libraries installed to support the '#{super}' format"
|
20
32
|
end
|
21
33
|
end
|
22
34
|
|
23
|
-
class UnknownResponse < OEmbed::Error
|
35
|
+
class UnknownResponse < OEmbed::Error # :nodoc:
|
24
36
|
def to_s
|
25
37
|
"Got unknown response (#{super}) from server"
|
26
38
|
end
|
27
39
|
end
|
40
|
+
|
41
|
+
class ParseError < OEmbed::Error # :nodoc:
|
42
|
+
def to_s
|
43
|
+
"There was an error parsing the server response (#{super})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
28
47
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Only allow this backend if ActiveSupport::JSON is already loaded
|
2
|
+
raise LoadError, "ActiveSupport::JSON isn't available. require 'activesupport/json'" unless defined?(ActiveSupport::JSON)
|
3
|
+
|
4
|
+
module OEmbed
|
5
|
+
module Formatter
|
6
|
+
module JSON
|
7
|
+
module Backends
|
8
|
+
module ActiveSupportJSON
|
9
|
+
ParseError = ::ActiveSupport::JSON.parse_error
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# Parses a JSON string or IO and convert it into an object.
|
13
|
+
def decode(json)
|
14
|
+
::ActiveSupport::JSON.decode(json)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Only allow this backend if it parses JSON strings the way we expect it to
|
24
|
+
begin
|
25
|
+
raise unless OEmbed::Formatter.test_backend(OEmbed::Formatter::JSON::Backends::ActiveSupportJSON)
|
26
|
+
rescue
|
27
|
+
raise LoadError, "The version of ActiveSupport::JSON you have installed isn't parsing JSON like ruby-oembed expected."
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Only allow this backend the json gem is already loaded
|
2
|
+
raise LoadError, "The json library isn't available. require 'json'" unless defined?(JSON)
|
3
|
+
|
4
|
+
module OEmbed
|
5
|
+
module Formatter
|
6
|
+
module JSON
|
7
|
+
module Backends
|
8
|
+
module JSONGem
|
9
|
+
ParseError = ::JSON::ParserError
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# Parses a JSON string or IO and convert it into an object.
|
13
|
+
def decode(json)
|
14
|
+
if json.respond_to?(:read)
|
15
|
+
json = json.read
|
16
|
+
end
|
17
|
+
::JSON.parse(json)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Only allow this backend if it parses JSON strings the way we expect it to
|
27
|
+
begin
|
28
|
+
raise unless OEmbed::Formatter.test_backend(OEmbed::Formatter::JSON::Backends::JSONGem)
|
29
|
+
rescue
|
30
|
+
raise LoadError, "The version of the json library you have installed isn't parsing JSON like ruby-oembed expected."
|
31
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Unlike other backends, require YAML if it's not already loaded
|
2
|
+
require 'yaml' unless defined?(YAML)
|
3
|
+
|
4
|
+
module OEmbed
|
5
|
+
module Formatter
|
6
|
+
module JSON
|
7
|
+
module Backends
|
8
|
+
# Use the YAML library, part of the standard library, to parse JSON values that has been converted to YAML.
|
9
|
+
module Yaml
|
10
|
+
ParseError = ::StandardError
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# Parses a JSON string or IO and converts it into an object.
|
14
|
+
def decode(json)
|
15
|
+
if json.respond_to?(:read)
|
16
|
+
json = json.read
|
17
|
+
end
|
18
|
+
YAML.load(convert_json_to_yaml(json))
|
19
|
+
rescue ArgumentError
|
20
|
+
raise ParseError, "Invalid JSON string"
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
# Ensure that ":" and "," are always followed by a space
|
25
|
+
def convert_json_to_yaml(json) #:nodoc:
|
26
|
+
require 'strscan' unless defined? ::StringScanner
|
27
|
+
scanner, quoting, marks, pos = ::StringScanner.new(json), false, [], nil
|
28
|
+
scanner.scan_until(/\{/)
|
29
|
+
while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
|
30
|
+
case char = scanner[1]
|
31
|
+
when '"', "'"
|
32
|
+
if !quoting
|
33
|
+
quoting = char
|
34
|
+
pos = scanner.pos
|
35
|
+
elsif quoting == char
|
36
|
+
quoting = false
|
37
|
+
end
|
38
|
+
when ":",","
|
39
|
+
marks << scanner.pos - 1 unless quoting
|
40
|
+
when "\\"
|
41
|
+
scanner.skip(/\\/)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
raise ParseError unless scanner.scan_until(/\}/)
|
45
|
+
|
46
|
+
if marks.empty?
|
47
|
+
raise ParseError
|
48
|
+
else
|
49
|
+
left_pos = [-1].push(*marks)
|
50
|
+
right_pos = marks << scanner.pos + scanner.rest_size
|
51
|
+
output = []
|
52
|
+
left_pos.each_with_index do |left, i|
|
53
|
+
scanner.pos = left.succ
|
54
|
+
chunk = scanner.peek(right_pos[i] - scanner.pos + 1)
|
55
|
+
chunk.gsub!(/\\([\\\/]|u[[:xdigit:]]{4})/) do
|
56
|
+
ustr = $1
|
57
|
+
if ustr.index('u') == 0
|
58
|
+
[ustr[1..-1].to_i(16)].pack("U")
|
59
|
+
elsif ustr == '\\'
|
60
|
+
'\\\\'
|
61
|
+
else
|
62
|
+
ustr
|
63
|
+
end
|
64
|
+
end
|
65
|
+
output << chunk
|
66
|
+
end
|
67
|
+
output = output * " "
|
68
|
+
|
69
|
+
output.gsub!(/\\\//, '/')
|
70
|
+
output
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Only allow this backend if it parses JSON strings the way we expect it to
|
81
|
+
begin
|
82
|
+
raise unless OEmbed::Formatter.test_backend(OEmbed::Formatter::JSON::Backends::Yaml)
|
83
|
+
rescue
|
84
|
+
raise LoadError, "The version of the YAML library you have installed isn't parsing JSON like ruby-oembed expected."
|
85
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module OEmbed
|
2
|
+
module Formatter
|
3
|
+
# Handles parsing JSON values using the best available backend.
|
4
|
+
module JSON
|
5
|
+
# A Array of all available backends, listed in order of preference.
|
6
|
+
DECODERS = %w(ActiveSupportJSON JSONGem Yaml)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Returns true if there is a valid JSON backend. Otherwise, raises OEmbed::FormatNotSupported
|
11
|
+
def supported?
|
12
|
+
!!backend
|
13
|
+
end
|
14
|
+
|
15
|
+
# Parses a JSON string or IO and convert it into an object
|
16
|
+
def decode(json)
|
17
|
+
backend.decode(json)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the current JSON backend.
|
21
|
+
def backend
|
22
|
+
set_default_backend unless defined?(@backend)
|
23
|
+
raise OEmbed::FormatNotSupported, :json unless defined?(@backend)
|
24
|
+
@backend
|
25
|
+
end
|
26
|
+
|
27
|
+
def backend=(name)
|
28
|
+
if name.is_a?(Module)
|
29
|
+
@backend = name
|
30
|
+
else
|
31
|
+
already_required = false
|
32
|
+
begin
|
33
|
+
already_required = OEmbed::Formatter::JSON::Backends.const_defined?(name, false)
|
34
|
+
rescue ArgumentError # we're dealing with ruby < 1.9 where const_defined? only takes 1 argument, but behaves the way we want it to.
|
35
|
+
already_required = OEmbed::Formatter::JSON::Backends.const_defined?(name)
|
36
|
+
rescue NameError # no backends have been loaded yet
|
37
|
+
already_required = false
|
38
|
+
end
|
39
|
+
|
40
|
+
require "oembed/formatter/json/backends/#{name.to_s.downcase}" unless already_required
|
41
|
+
@backend = OEmbed::Formatter::JSON::Backends::const_get(name)
|
42
|
+
end
|
43
|
+
@parse_error = @backend::ParseError
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_backend(name)
|
47
|
+
old_backend, self.backend = backend, name
|
48
|
+
yield
|
49
|
+
ensure
|
50
|
+
self.backend = old_backend
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_default_backend
|
54
|
+
DECODERS.find do |name|
|
55
|
+
begin
|
56
|
+
self.backend = name
|
57
|
+
true
|
58
|
+
rescue LoadError
|
59
|
+
# Try next decoder.
|
60
|
+
false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end # JSON
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Unlike other backends, require REXML if it's not already loaded
|
2
|
+
require 'rexml/document' unless defined?(REXML)
|
3
|
+
|
4
|
+
module OEmbed
|
5
|
+
module Formatter
|
6
|
+
module XML
|
7
|
+
module Backends
|
8
|
+
# Use the REXML library, part of the standard library, to parse XML values.
|
9
|
+
module REXML
|
10
|
+
ParseError = ::REXML::ParseException
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# Parses an XML string or IO and convert it into an object
|
14
|
+
def decode(xml)
|
15
|
+
if !xml.respond_to?(:read)
|
16
|
+
xml = StringIO.new(xml)
|
17
|
+
end
|
18
|
+
obj = {}
|
19
|
+
doc = ::REXML::Document.new(xml)
|
20
|
+
doc.elements[1].elements.each do |el|
|
21
|
+
obj[el.name] = el.text
|
22
|
+
end
|
23
|
+
obj
|
24
|
+
rescue
|
25
|
+
case $!
|
26
|
+
when ParseError
|
27
|
+
raise $!
|
28
|
+
else
|
29
|
+
raise ParseError, "Couldn't parse the given document."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Only allow this backend if it parses XML strings the way we expect it to
|
40
|
+
begin
|
41
|
+
raise unless OEmbed::Formatter.test_backend(OEmbed::Formatter::XML::Backends::REXML)
|
42
|
+
rescue
|
43
|
+
raise LoadError, "The version of the REXML library you have installed isn't parsing XML like ruby-oembed expected."
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Only allow this backend the xml-simple gem is already loaded
|
2
|
+
raise ::LoadError, "The xml-simple library isn't available. require 'xmlsimple'" unless defined?(XmlSimple)
|
3
|
+
|
4
|
+
module OEmbed
|
5
|
+
module Formatter
|
6
|
+
module XML
|
7
|
+
module Backends
|
8
|
+
# Use the xml-simple gem to parse XML values.
|
9
|
+
module XmlSimple
|
10
|
+
ParseError = ::ArgumentError
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# Parses an XML string or IO and convert it into an object.
|
14
|
+
def decode(xml)
|
15
|
+
if !xml.respond_to?(:read)
|
16
|
+
xml = StringIO.new(xml)
|
17
|
+
end
|
18
|
+
::XmlSimple.xml_in(xml, 'ForceArray'=>false)
|
19
|
+
rescue
|
20
|
+
case $!
|
21
|
+
when ::ArgumentError
|
22
|
+
raise $!
|
23
|
+
else
|
24
|
+
raise ::ArgumentError, "Couldn't parse the given document."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Only allow this backend if it parses XML strings the way we expect it to
|
35
|
+
begin
|
36
|
+
raise unless OEmbed::Formatter.test_backend(OEmbed::Formatter::XML::Backends::XmlSimple)
|
37
|
+
rescue
|
38
|
+
raise ::LoadError, "The version of the xml-simple library you have installed isn't parsing XML like ruby-oembed expected."
|
39
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module OEmbed
|
2
|
+
module Formatter
|
3
|
+
# Handles parsing XML values using the best available backend.
|
4
|
+
module XML
|
5
|
+
# A Array of all available backends, listed in order of preference.
|
6
|
+
DECODERS = %w(XmlSimple REXML)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Returns true if there is a valid XML backend. Otherwise, raises OEmbed::FormatNotSupported
|
11
|
+
def supported?
|
12
|
+
!!backend
|
13
|
+
end
|
14
|
+
|
15
|
+
# Parses an XML string or IO and convert it into an object
|
16
|
+
def decode(xml)
|
17
|
+
backend.decode(xml)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the current XML backend.
|
21
|
+
def backend
|
22
|
+
set_default_backend unless defined?(@backend)
|
23
|
+
raise OEmbed::FormatNotSupported, :xml unless defined?(@backend)
|
24
|
+
@backend
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sets the current XML backend. Raises a LoadError if the given
|
28
|
+
# backend cannot be loaded
|
29
|
+
# OEmbed::Formatter::XML.backend = 'REXML'
|
30
|
+
def backend=(name)
|
31
|
+
if name.is_a?(Module)
|
32
|
+
@backend = name
|
33
|
+
else
|
34
|
+
already_required = false
|
35
|
+
begin
|
36
|
+
already_required = OEmbed::Formatter::XML::Backends.const_defined?(name, false)
|
37
|
+
rescue ArgumentError # we're dealing with ruby < 1.9 where const_defined? only takes 1 argument, but behaves the way we want it to.
|
38
|
+
already_required = OEmbed::Formatter::XML::Backends.const_defined?(name)
|
39
|
+
rescue NameError # no backends have been loaded yet
|
40
|
+
already_required = false
|
41
|
+
end
|
42
|
+
|
43
|
+
require "oembed/formatter/xml/backends/#{name.to_s.downcase}" unless already_required
|
44
|
+
@backend = OEmbed::Formatter::XML::Backends.const_get(name)
|
45
|
+
end
|
46
|
+
@parse_error = @backend::ParseError
|
47
|
+
end
|
48
|
+
|
49
|
+
# Perform a set of operations using a backend other than the current one.
|
50
|
+
# OEmbed::Formatter::XML.with_backend('XmlSimple') do
|
51
|
+
# OEmbed::Formatter::XML.decode(xml_value)
|
52
|
+
# end
|
53
|
+
def with_backend(name)
|
54
|
+
old_backend, self.backend = backend, name
|
55
|
+
yield
|
56
|
+
ensure
|
57
|
+
self.backend = old_backend
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_default_backend
|
61
|
+
DECODERS.find do |name|
|
62
|
+
begin
|
63
|
+
self.backend = name
|
64
|
+
true
|
65
|
+
rescue LoadError
|
66
|
+
# Try next decoder.
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end # XML
|
75
|
+
end
|
76
|
+
end
|