oembed_proxy 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +15 -0
- data/.travis.yml +10 -0
- data/Gemfile +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +106 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/rspec +21 -0
- data/bin/rubocop +21 -0
- data/bin/setup +8 -0
- data/lib/oembed_proxy/associated_press.rb +30 -0
- data/lib/oembed_proxy/embedly.rb +29 -0
- data/lib/oembed_proxy/first_party.rb +96 -0
- data/lib/oembed_proxy/fusiontable_map.rb +30 -0
- data/lib/oembed_proxy/google_document.rb +30 -0
- data/lib/oembed_proxy/google_mapsengine.rb +39 -0
- data/lib/oembed_proxy/google_spreadsheet.rb +30 -0
- data/lib/oembed_proxy/handler.rb +30 -0
- data/lib/oembed_proxy/inactive_support.rb +23 -0
- data/lib/oembed_proxy/oembed_exception.rb +5 -0
- data/lib/oembed_proxy/tableau.rb +50 -0
- data/lib/oembed_proxy/utility.rb +16 -0
- data/lib/oembed_proxy/version.rb +5 -0
- data/lib/oembed_proxy.rb +17 -0
- data/lib/providers/embedly_patterns.def +647 -0
- data/lib/providers/first_party.yml +91 -0
- data/oembed_proxy.gemspec +29 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 956cb22dbe2035e94f2b5f3847559b595ff322f64d4fbf162a7b680c3b76c9e0
|
4
|
+
data.tar.gz: af361ad48515fb78f564505e922970ca477eb1cf4542c88c7f545e65b7fdaa76
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8b16de65cd28d1af9afd4c7be2e3ec52df3acaa093d56a1c635ddc854dda94eb0030b4efdf171bec88716f366737a875aeeff7833b1748f236f0184c5d1e1e9
|
7
|
+
data.tar.gz: 2d1071f20224c557ec04ff41024ff28c1a65653d53ffa6bd67b8b45aa9c349a3a53ac15cbffeb3e6c9b3f4a53edaea8005597ea76a65ae269d870a1fb95ed445
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
Exclude:
|
4
|
+
- 'bin/*'
|
5
|
+
|
6
|
+
Metrics/LineLength:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
Metrics/BlockLength:
|
10
|
+
Exclude:
|
11
|
+
- 'spec/**/*'
|
12
|
+
Style/TrailingCommaInLiteral:
|
13
|
+
EnforcedStyleForMultiline: comma
|
14
|
+
Style/RescueStandardError:
|
15
|
+
EnforcedStyle: implicit
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'rubocop'
|
9
|
+
end
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem 'webmock'
|
13
|
+
end
|
14
|
+
|
15
|
+
group :development, :test do
|
16
|
+
gem 'pry'
|
17
|
+
gem 'pry-byebug'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Specify your gem's dependencies in oembed_proxy.gemspec
|
21
|
+
gemspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 William Johnston
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# OembedProxy
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/APMG/oembed_proxy.svg?branch=master)](https://travis-ci.org/APMG/oembed_proxy)
|
4
|
+
|
5
|
+
Library to manage multiple oEmbed providers, including officially supported oEmbeds, custom implemented "fauxembeds", and Embed.ly providers.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'oembed_proxy'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install oembed_proxy
|
22
|
+
|
23
|
+
## Short Example
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'oembed_proxy'
|
27
|
+
|
28
|
+
my_url = 'https://www.youtube.com/watch?v=yxMxQrX6dOQ'
|
29
|
+
handler = OembedProxy::Handler.new(
|
30
|
+
OembedProxy::FirstParty.new,
|
31
|
+
OembedProxy::AssociatedPress.new,
|
32
|
+
OembedProxy::FusiontableMap.new,
|
33
|
+
OembedProxy::GoogleDocument.new,
|
34
|
+
OembedProxy::GoogleMapsengine.new,
|
35
|
+
OembedProxy::GoogleSpreadsheet.new,
|
36
|
+
OembedProxy::Tableau.new,
|
37
|
+
OembedProxy::Embedly.new('myembedlykey'),
|
38
|
+
)
|
39
|
+
handler.handles_url?(my_url) # => true
|
40
|
+
handler.get_data(my_url) # =>
|
41
|
+
# {
|
42
|
+
# "type" => "video",
|
43
|
+
# "thumbnail_height" => 360,
|
44
|
+
# "thumbnail_url" => "https://i.ytimg.com/vi/yxMxQrX6dOQ/hqdefault.jpg",
|
45
|
+
# "provider_url" => "https://www.youtube.com/",
|
46
|
+
# "thumbnail_width" => 480,
|
47
|
+
# "title" => "Inside MPR News",
|
48
|
+
# "author_url" => "https://www.youtube.com/user/AmericanPublicMedia",
|
49
|
+
# "provider_name" => "YouTube",
|
50
|
+
# "width" => 480,
|
51
|
+
# "author_name" => "AmericanPublicMedia",
|
52
|
+
# "height" => 270,
|
53
|
+
# "version" => "1.0",
|
54
|
+
# "html" => "<iframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/yxMxQrX6dOQ?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen></iframe>"
|
55
|
+
# }
|
56
|
+
```
|
57
|
+
|
58
|
+
## Architecture
|
59
|
+
|
60
|
+
Each provider and the handler implement the following API:
|
61
|
+
|
62
|
+
* `#handles_url?(url)`
|
63
|
+
* `#get_data(url, other_params)`
|
64
|
+
|
65
|
+
The `#handles_url?(url)` method takes a URL and returns a boolean describing whether a given provider (or the composition of the registered providers in the case of the handler) supports the given URL.
|
66
|
+
|
67
|
+
The `#get_data(url, other_params)` method takes a URL and optional additional hash params (like `width:` and `height:`), and then returns a hash containing the oembed response.
|
68
|
+
|
69
|
+
### Handler
|
70
|
+
|
71
|
+
In addition to the two methods above, the handler also allows registration of provider classes. This can be done by providing a list of providers to the constructor:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
handler = OembedProxy::Handler.new([
|
75
|
+
OembedProxy::FirstParty.new,
|
76
|
+
OembedProxy::AssociatedPress.new,
|
77
|
+
])
|
78
|
+
```
|
79
|
+
|
80
|
+
Or this can be done by calling `#register(provider)`:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
handler = OembedProxy::Handler.new
|
84
|
+
handler.register OembedProxy::FirstParty.new
|
85
|
+
handler.register OembedProxy::AssociatedPress.new
|
86
|
+
```
|
87
|
+
|
88
|
+
Once providers have been registered, calling `#handles_url?` and `#get_data` on the handler will operate on the composition of the registered providers.
|
89
|
+
|
90
|
+
### Implementing your own providers
|
91
|
+
|
92
|
+
You are able to easily implement additional providers by creating an object which implements the `#handles_url?(url)` and `#get_data(url, other_params)` methods. Take a look at the existing provider classes for examples.
|
93
|
+
|
94
|
+
## Development
|
95
|
+
|
96
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Before sending a pull request, you will want to run `bin/rubocop` to lint your work.
|
97
|
+
|
98
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
99
|
+
|
100
|
+
## Contributing
|
101
|
+
|
102
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/APMG/oembed_proxy.
|
103
|
+
|
104
|
+
## License
|
105
|
+
|
106
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'oembed_proxy'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/rspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
12
|
+
load(bundle_binstub) if File.file?(bundle_binstub)
|
13
|
+
|
14
|
+
require "pathname"
|
15
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
16
|
+
Pathname.new(__FILE__).realpath)
|
17
|
+
|
18
|
+
require "rubygems"
|
19
|
+
require "bundler/setup"
|
20
|
+
|
21
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/rubocop
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
12
|
+
load(bundle_binstub) if File.file?(bundle_binstub)
|
13
|
+
|
14
|
+
require "pathname"
|
15
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
16
|
+
Pathname.new(__FILE__).realpath)
|
17
|
+
|
18
|
+
require "rubygems"
|
19
|
+
require "bundler/setup"
|
20
|
+
|
21
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/setup
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# Associated Press Interactives Fauxembed
|
5
|
+
class AssociatedPress
|
6
|
+
AP_REGEX = %r{\Ahttps?:\/\/(?:hosted\.ap\.org\/interactives|interactives\.ap\.org)\/.+}
|
7
|
+
|
8
|
+
def handles_url?(url)
|
9
|
+
!AP_REGEX.match(url).nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_data(url, _other_params = {})
|
13
|
+
return nil unless handles_url? url
|
14
|
+
|
15
|
+
oembed = {}
|
16
|
+
|
17
|
+
oembed['type'] = 'rich'
|
18
|
+
oembed['version'] = '1.0'
|
19
|
+
|
20
|
+
oembed['provider_name'] = 'Associated Press'
|
21
|
+
oembed['provider_url'] = 'http://www.ap.org/'
|
22
|
+
|
23
|
+
oembed['html'] = '<iframe class="ap-embed" width="100%" height="600" frameborder="0" scrolling="yes" marginheight="0" marginwidth="0" src="' + url + '"></iframe>'
|
24
|
+
oembed['width'] = 600
|
25
|
+
oembed['height'] = 600
|
26
|
+
|
27
|
+
oembed
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oembed_proxy/first_party'
|
4
|
+
require 'oembed_proxy/utility'
|
5
|
+
|
6
|
+
module OembedProxy
|
7
|
+
# Embedly provider
|
8
|
+
class Embedly < FirstParty
|
9
|
+
EMBEDLY_URL = 'https://api.embed.ly/1/oembed'
|
10
|
+
|
11
|
+
def initialize(embedly_key)
|
12
|
+
# Import the expected embed.ly providers.
|
13
|
+
@pattern_hash = {}
|
14
|
+
@embedly_key = embedly_key
|
15
|
+
|
16
|
+
File.open('lib/providers/embedly_patterns.def', 'r') do |f|
|
17
|
+
f.each do |line|
|
18
|
+
regex = Utility.clean_pattern(line)
|
19
|
+
@pattern_hash[regex] = EMBEDLY_URL
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_data(url, other_params = {})
|
25
|
+
other_params[:key] = @embedly_key
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'cgi'
|
5
|
+
require 'net/http'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
require 'oembed_proxy/utility'
|
9
|
+
require 'oembed_proxy/oembed_exception'
|
10
|
+
|
11
|
+
module OembedProxy
|
12
|
+
# Handles all sites with officially supported oEmbed providers
|
13
|
+
class FirstParty
|
14
|
+
USER_AGENT = 'Ruby oEmbed Proxy'
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
# Import the expected first party providers.
|
18
|
+
@pattern_hash = {}
|
19
|
+
|
20
|
+
yaml_hash = YAML.load_file('lib/providers/first_party.yml')
|
21
|
+
yaml_hash.each_value do |hsh|
|
22
|
+
hsh['pattern_list'].each do |pattern|
|
23
|
+
regex = Utility.clean_pattern(pattern)
|
24
|
+
@pattern_hash[regex] = hsh['endpoint']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def handles_url?(url)
|
30
|
+
!find_endpoint(url).nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_data(url, other_params = {})
|
34
|
+
endpoint = find_endpoint(url)
|
35
|
+
return nil if endpoint.nil?
|
36
|
+
|
37
|
+
uri = URI(endpoint)
|
38
|
+
new_params = { url: url, format: 'json' }
|
39
|
+
new_params.merge! other_params
|
40
|
+
# Merge in existing params.
|
41
|
+
new_params.merge! CGI.parse(uri.query) if uri.query
|
42
|
+
uri.query = URI.encode_www_form(new_params)
|
43
|
+
|
44
|
+
fetch(uri)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
ERROR_CLASS_MAPPING = {
|
50
|
+
Net::HTTPBadRequest => '400 Bad Request',
|
51
|
+
Net::HTTPUnauthorized => '401 Unauthorized',
|
52
|
+
Net::HTTPForbidden => '403 Forbidden',
|
53
|
+
Net::HTTPNotFound => '404 Not Found',
|
54
|
+
Net::HTTPInternalServerError => '500 Internal Server Error',
|
55
|
+
Net::HTTPNotImplemented => '501 Not Implemented',
|
56
|
+
Net::HTTPServiceUnavailable => '503 Service Unavailable',
|
57
|
+
}.freeze
|
58
|
+
|
59
|
+
MAX_REDIRECTS = 10
|
60
|
+
|
61
|
+
def fetch(uri, times_recursed: 0) # rubocop:disable Metrics/MethodLength
|
62
|
+
raise OembedException, '500 Internal Server Error' if times_recursed > MAX_REDIRECTS
|
63
|
+
|
64
|
+
res = request_builder(uri)
|
65
|
+
|
66
|
+
case res
|
67
|
+
when Net::HTTPSuccess
|
68
|
+
JSON[res.body]
|
69
|
+
when Net::HTTPMovedPermanently, Net::HTTPFound
|
70
|
+
fetch(URI(res['location']), times_recursed: (times_recursed + 1))
|
71
|
+
else
|
72
|
+
raise OembedException, (ERROR_CLASS_MAPPING[res.class] || "Unknown response: #{res.class}")
|
73
|
+
end
|
74
|
+
rescue JSON::ParserError
|
75
|
+
return nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def request_builder(uri)
|
79
|
+
req = Net::HTTP::Get.new(uri)
|
80
|
+
req['User-Agent'] = USER_AGENT
|
81
|
+
|
82
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: (uri.scheme == 'https')) do |http|
|
83
|
+
http.request(req)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def find_endpoint(url)
|
88
|
+
@pattern_hash.each_key do |p|
|
89
|
+
return @pattern_hash[p] if url.to_s.match(p)
|
90
|
+
end
|
91
|
+
|
92
|
+
# If all else fails, return nil.
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# Google Apps Fusiontable Map Fauxembeds
|
5
|
+
class FusiontableMap
|
6
|
+
FUSIONTABLE_REGEX = %r{\Ahttps://www\.google\.com/fusiontables.+}
|
7
|
+
|
8
|
+
def handles_url?(url)
|
9
|
+
!(url =~ FUSIONTABLE_REGEX).nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_data(url, _other_params = {})
|
13
|
+
return nil unless handles_url? url
|
14
|
+
|
15
|
+
oembed = {}
|
16
|
+
|
17
|
+
oembed['type'] = 'rich'
|
18
|
+
oembed['version'] = '1.0'
|
19
|
+
|
20
|
+
oembed['provider_name'] = 'Google Apps Fusion Tables'
|
21
|
+
oembed['provider_url'] = 'https://www.google.com/drive/apps.html#fusiontables'
|
22
|
+
|
23
|
+
oembed['html'] = '<iframe class="google-map" width="100%" height="500" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' + url + '"></iframe>'
|
24
|
+
oembed['width'] = 500
|
25
|
+
oembed['height'] = 500
|
26
|
+
|
27
|
+
oembed
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# Google Docs Fauxembed
|
5
|
+
class GoogleDocument
|
6
|
+
GOOGLE_DOCUMENT_REGEX = %r{\Ahttps://docs\.google\.com/document.+}
|
7
|
+
|
8
|
+
def handles_url?(url)
|
9
|
+
!(url =~ GOOGLE_DOCUMENT_REGEX).nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_data(url, _other_params = {})
|
13
|
+
return nil unless handles_url? url
|
14
|
+
|
15
|
+
oembed = {}
|
16
|
+
|
17
|
+
oembed['type'] = 'rich'
|
18
|
+
oembed['version'] = '1.0'
|
19
|
+
|
20
|
+
oembed['provider_name'] = 'Google Apps Documents'
|
21
|
+
oembed['provider_url'] = 'https://docs.google.com/document/'
|
22
|
+
|
23
|
+
oembed['html'] = '<iframe class="google-docs document" width="100%" height="500" frameborder="0" scrolling="yes" marginheight="0" marginwidth="0" src="' + url + '"></iframe>'
|
24
|
+
oembed['width'] = 500
|
25
|
+
oembed['height'] = 500
|
26
|
+
|
27
|
+
oembed
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# Google Maps Engine Fauxembed
|
5
|
+
class GoogleMapsengine
|
6
|
+
MAPSENGINE_REGEXES = [
|
7
|
+
%r{\Ahttps://mapsengine\.google\.com/map/(?:edit|view)\?mid=(.+)},
|
8
|
+
%r{\Ahttps://www\.google\.com/maps/d/edit\?mid=(.+)},
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
def handles_url?(url)
|
12
|
+
!get_matching_regex(url).nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_data(url, _other_params = {})
|
16
|
+
return nil unless handles_url? url
|
17
|
+
|
18
|
+
{
|
19
|
+
'type' => 'rich',
|
20
|
+
'version' => '1.0',
|
21
|
+
'provider_name' => 'Google Maps Engine',
|
22
|
+
'provider_url' => 'https://mapsengine.google.com/',
|
23
|
+
'html' => "<iframe class=\"google-map\" width=\"640\" height=\"480\" frameborder=\"0\" scrolling=\"no\" marginheight=\"0\" marginwidth=\"0\" src=\"https://mapsengine.google.com/map/embed?mid=#{url.match(get_matching_regex(url))[1]}\"></iframe>",
|
24
|
+
'width' => 500,
|
25
|
+
'height' => 500,
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def get_matching_regex(str)
|
32
|
+
MAPSENGINE_REGEXES.each do |regex|
|
33
|
+
return regex unless (str =~ regex).nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# Google Spreadsheet Fauxembed
|
5
|
+
class GoogleSpreadsheet
|
6
|
+
GOOGLE_SPREADSHEET_REGEX = %r{\Ahttps://docs\.google\.com/spreadsheet.+}
|
7
|
+
|
8
|
+
def handles_url?(url)
|
9
|
+
!(url =~ GOOGLE_SPREADSHEET_REGEX).nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_data(url, _other_params = {})
|
13
|
+
return nil unless handles_url? url
|
14
|
+
|
15
|
+
oembed = {}
|
16
|
+
|
17
|
+
oembed['type'] = 'rich'
|
18
|
+
oembed['version'] = '1.0'
|
19
|
+
|
20
|
+
oembed['provider_name'] = 'Google Apps Spreadsheets'
|
21
|
+
oembed['provider_url'] = 'https://docs.google.com/spreadsheet/'
|
22
|
+
|
23
|
+
oembed['html'] = '<iframe class="google-docs spreadsheet" width="100%" height="500" frameborder="0" scrolling="yes" marginheight="0" marginwidth="0" src="' + url + '&output=html"></iframe>'
|
24
|
+
oembed['width'] = 500
|
25
|
+
oembed['height'] = 500
|
26
|
+
|
27
|
+
oembed
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# Generic composing handler
|
5
|
+
class Handler
|
6
|
+
def initialize(*providers)
|
7
|
+
@registered_providers = providers
|
8
|
+
end
|
9
|
+
|
10
|
+
def register(provider)
|
11
|
+
@registered_providers << provider
|
12
|
+
end
|
13
|
+
|
14
|
+
def handles_url?(url)
|
15
|
+
!provider_for_url(url).nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_data(url, other_params = {})
|
19
|
+
provider = provider_for_url(url)
|
20
|
+
return provider.get_data(url, other_params) unless provider.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def provider_for_url(url)
|
26
|
+
# TODO: Switch to #find
|
27
|
+
@registered_providers.select { |p| p.handles_url? url }.first
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OembedProxy
|
4
|
+
# A couple of things pulled in from ActiveSupport, but using refinements
|
5
|
+
# instead of monkeypatching.
|
6
|
+
module InactiveSupport
|
7
|
+
refine String do
|
8
|
+
def parameterize(sep = '-')
|
9
|
+
parameterized_string = dup.downcase
|
10
|
+
# Turn unwanted chars into the separator
|
11
|
+
parameterized_string.gsub!(/[^a-z0-9\-_]+/, sep)
|
12
|
+
unless sep.nil? || sep.empty?
|
13
|
+
re_sep = Regexp.escape(sep)
|
14
|
+
# No more than one of the separator in a row.
|
15
|
+
parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
|
16
|
+
# Remove leading/trailing separator.
|
17
|
+
parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/, '')
|
18
|
+
end
|
19
|
+
parameterized_string.downcase
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|