oembed_provider_engine 0.0.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/MIT-LICENSE +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +40 -0
- data/app/controllers/oembed_provider_engine/application_controller.rb +2 -0
- data/app/controllers/oembed_provider_engine/oembed_provider_controller.rb +56 -0
- data/app/helpers/oembed_provider_engine/application_helper.rb +4 -0
- data/app/helpers/oembed_provider_engine/oembed_provider_helper.rb +20 -0
- data/app/models/oembed_provider_engine/oembed_providable.rb +204 -0
- data/app/models/oembed_provider_engine/oembed_provider.rb +95 -0
- data/app/views/layouts/oembed_provider_engine/application.html.erb +14 -0
- data/config/routes.rb +3 -0
- data/lib/oembed_provider_engine/engine.rb +11 -0
- data/lib/oembed_provider_engine/version.rb +3 -0
- data/lib/oembed_provider_engine.rb +4 -0
- data/lib/tasks/oembed_providerengine_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/photos_controller.rb +11 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/item.rb +4 -0
- data/test/dummy/app/models/photo.rb +4 -0
- data/test/dummy/app/views/items/edit.html.erb +24 -0
- data/test/dummy/app/views/items/index.html.erb +24 -0
- data/test/dummy/app/views/items/new.html.erb +23 -0
- data/test/dummy/app/views/items/show.html.erb +21 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/items.html.erb +20 -0
- data/test/dummy/app/views/layouts/photos.html.erb +18 -0
- data/test/dummy/app/views/photos/edit.html.erb +12 -0
- data/test/dummy/app/views/photos/index.html.erb +18 -0
- data/test/dummy/app/views/photos/new.html.erb +11 -0
- data/test/dummy/app/views/photos/show.html.erb +3 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/oembed_provider.rb +2 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +7 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/migrate/20110212010602_create_items.rb +13 -0
- data/test/dummy/db/migrate/20110212022722_create_photos.rb +15 -0
- data/test/dummy/db/schema.rb +37 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/factories/photos.rb +14 -0
- data/test/functional/oembed_provider_controller_test.rb +52 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/integration/oembed_test.rb +84 -0
- data/test/oembed_providable_test.rb +215 -0
- data/test/oembed_provider_test.rb +110 -0
- data/test/test_helper.rb +25 -0
- metadata +378 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 XING AG
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
= OembedProviderEngine
|
2
|
+
|
3
|
+
Turns your rails app into an {oembed}[http://oembed.com/] provider
|
4
|
+
|
5
|
+
== About
|
6
|
+
{Oembed}[http://oembed.com/] is an open format for embedding media from third-party providers. This gem is a mountable engine that turns your rails 3 app into an oembed provider allowing oembed consumers to easily embed your media resources into their site.
|
7
|
+
|
8
|
+
== Usage
|
9
|
+
=== Installation
|
10
|
+
Add the following to your Gemfile:
|
11
|
+
|
12
|
+
gem "oembed-provider-engine"
|
13
|
+
|
14
|
+
=== Provider Settings
|
15
|
+
Add a config/initializers/oembed_provider.rb file to configure your provider settings:
|
16
|
+
|
17
|
+
OembedProviderEngine::OembedProvider.provider_name = "Example Provider"
|
18
|
+
OembedProviderEngine::OembedProvider.provider_url = "http://example.com"
|
19
|
+
|
20
|
+
If a controller doesn't map to model name as per tablize convention, map it like this:
|
21
|
+
|
22
|
+
OembedProviderEngine::OembedProvider.controller_model_maps = { 'example' => 'FooBar' }
|
23
|
+
|
24
|
+
=== Providable Model
|
25
|
+
To declare your model providable, include the following:
|
26
|
+
|
27
|
+
include OembedProvider::OembedProvidable
|
28
|
+
# the first argument is the oembed type, that is one of :rich, :link, :photo, or :video
|
29
|
+
oembed_providable_as :rich
|
30
|
+
|
31
|
+
Your model has to provide methods to give what oembed_provider expects for your oembed type. Those methods need to make sure that request parameters maxheight and maxwidth are obeyed, see {oembed specs}[http://oembed.com/] for details.
|
32
|
+
|
33
|
+
If the methods have names different from the respective oembed attributes, you need to match them here:
|
34
|
+
|
35
|
+
# data for the oembed attribute 'title' is provided by a method named 'label'
|
36
|
+
oembed_providable_as :link, title: :label
|
37
|
+
|
38
|
+
You can also override the provider settings from the initializer:
|
39
|
+
|
40
|
+
oembed_providable_as :link, provider_name: 'Example'
|
41
|
+
|
42
|
+
=== Discovery
|
43
|
+
If you want to allow for oembed discovery, you can use the helper function from this engine to add links to the HTML head:
|
44
|
+
|
45
|
+
<%= oembed_provider_links %>
|
46
|
+
|
47
|
+
=== Routing
|
48
|
+
The engine adds a route +/oembed+ to your app, which is your oembed api endpoint. By default, it returns json, but it may as well return xml or json-p. Following the oembed specs, a request parameter format can be used to specify the requested format (xml or json). If you add request parameters variable or callback, json-p is returned instead of json. The engine also provides the additional endpoints +/oembed.xml+ and +/oembed.json+ which return the respective format.
|
49
|
+
|
50
|
+
== Security
|
51
|
+
The current implementation directly accesses your application's model to fetch the data for the response. This may bypass your applicaton's authorization and expose non-public data via oembed if your model does not take this into account!
|
52
|
+
|
53
|
+
== TODO
|
54
|
+
* proper handling of unauthorized
|
55
|
+
* migrate from shoulda to rspec
|
56
|
+
* caching
|
57
|
+
* allow the providable model to omit methods corresponding to optional oembed fields
|
58
|
+
|
59
|
+
== Contribute
|
60
|
+
Feel free to fork the project and send us pull requests.
|
61
|
+
|
62
|
+
|
63
|
+
== Credits
|
64
|
+
This gem is heavily based upon the rails 2 gem {oembed-provider}[https://github.com/kete/oembed_provider/] originally developed by {Walter McGinnis}[https://github.com/walter] for {kete}[https://github.com/kete].
|
65
|
+
|
66
|
+
== Authors
|
67
|
+
|
68
|
+
{Kerstin Puschke}[http://github.com/titanoboa],
|
69
|
+
{Hinnerk Altenburg}[http://github.com/hinnerk-a],
|
70
|
+
{George Avramidis}[http://github.com/tdgs] and
|
71
|
+
{Ömür Özkir}[http://github.com/oem]
|
72
|
+
|
73
|
+
You can find out more about our work on our {dev blog}[http://devblog.xing.com].
|
74
|
+
|
75
|
+
== Contributors
|
76
|
+
|
77
|
+
Thanks to all who have made contributions {to this gem}[https://github.com/xing/oembed-provider-engine/contributors] as well as {its rails 2 predecessor}[https://github.com/kete/oembed_provider/contributors].
|
78
|
+
|
79
|
+
Copyright (c) 2012 {XING AG}[http://www.xing.com/]
|
80
|
+
|
81
|
+
Released under the MIT license. For full details see MIT-LICENSE included in this
|
82
|
+
distribution.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'OembedProviderEngine'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module OembedProviderEngine
|
2
|
+
class OembedProviderController < ApplicationController
|
3
|
+
# Prevents the following error from showing up, common in Rails engines
|
4
|
+
# A copy of ApplicationController has been removed from the module tree but is still active!
|
5
|
+
unloadable
|
6
|
+
|
7
|
+
# GET /oembed?url=... json by default
|
8
|
+
# GET /oembed.json?url=...
|
9
|
+
# GET /oembed.json?url=...&callback=myCallback
|
10
|
+
# GET /oembed.xml?url=...
|
11
|
+
def endpoint
|
12
|
+
# get object that we want an oembed_response from
|
13
|
+
# based on url
|
14
|
+
# and get its oembed_response
|
15
|
+
media_item = ::OembedProviderEngine::OembedProvider.find_provided_from(params[:url])
|
16
|
+
options = Hash.new
|
17
|
+
max_dimensions = [:maxwidth, :maxheight]
|
18
|
+
unless media_item.class::OembedResponse.providable_oembed_type == :link
|
19
|
+
max_dimensions.each { |dimension| options[dimension] = params[dimension] if params[dimension].present? }
|
20
|
+
end
|
21
|
+
|
22
|
+
@oembed_response = media_item.oembed_response(options)
|
23
|
+
|
24
|
+
# to_xml and to_json overidden in oembed_providable module
|
25
|
+
# to be properly formatted
|
26
|
+
# TODO: handle unauthorized case
|
27
|
+
respond_to do |format|
|
28
|
+
if @oembed_response
|
29
|
+
format.html { render_json @oembed_response.to_json } # return json for default
|
30
|
+
format.json { render_json @oembed_response.to_json }
|
31
|
+
format.xml { render :xml => @oembed_response }
|
32
|
+
else
|
33
|
+
format.all { render_404 }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
# thanks to http://blogs.sitepoint.com/2006/10/05/json-p-output-with-rails/
|
40
|
+
def render_json(json, options={})
|
41
|
+
callback, variable = params[:callback], params[:variable]
|
42
|
+
response = begin
|
43
|
+
if callback && variable
|
44
|
+
"var #{variable} = #{json};\n#{callback}(#{variable});"
|
45
|
+
elsif variable
|
46
|
+
"var #{variable} = #{json};"
|
47
|
+
elsif callback
|
48
|
+
"#{callback}(#{json});"
|
49
|
+
else
|
50
|
+
json
|
51
|
+
end
|
52
|
+
end
|
53
|
+
render({:content_type => :js, :text => response}.merge(options))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OembedProviderEngine
|
2
|
+
# include this in your relevant helpers
|
3
|
+
# to add discoverability link, etc.
|
4
|
+
module OembedProviderHelper
|
5
|
+
# hardcodes http as protocol
|
6
|
+
# http is specified in http://oembed.com/
|
7
|
+
def oembed_provider_links
|
8
|
+
host_url = request.host
|
9
|
+
escaped_request_url = request.url.sub('://', '%3A//')
|
10
|
+
html = tag(:link, :rel => "alternate",
|
11
|
+
:type => "application/json+oembed",
|
12
|
+
:href => "http://#{host_url}/oembed?url=#{escaped_request_url}",
|
13
|
+
:title => "JSON oEmbed for #{@title}")
|
14
|
+
html += tag(:link, :rel => "alternate",
|
15
|
+
:type => "application/xml+oembed",
|
16
|
+
:href => "http://#{host_url}/oembed.xml?url=#{escaped_request_url}",
|
17
|
+
:title => "XML oEmbed for #{@title}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'builder'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module OembedProviderEngine
|
5
|
+
module OembedProvidable #:nodoc:
|
6
|
+
def self.included(base)
|
7
|
+
base.send(:include, OembedProvidable::Provided)
|
8
|
+
end
|
9
|
+
|
10
|
+
# use this to make your model able to respond to requests
|
11
|
+
# against the OembedProviderController
|
12
|
+
module Provided
|
13
|
+
def self.included(base)
|
14
|
+
base.extend(ClassMethods)
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def oembed_providable_as(*args)
|
19
|
+
# don't allow multiple calls
|
20
|
+
return if self.included_modules.include?(OembedProvidable::Provided::InstanceMethods)
|
21
|
+
|
22
|
+
send :include, OembedProvidable::Provided::InstanceMethods
|
23
|
+
|
24
|
+
specs = args.last.is_a?(Hash) ? args.pop : Hash.new
|
25
|
+
|
26
|
+
oembed_type = args.first
|
27
|
+
|
28
|
+
if ![:photo, :video, :link, :rich].include?(oembed_type)
|
29
|
+
raise ArgumentError, "oEmbed type must be :photo, :video, :link, or :rich"
|
30
|
+
end
|
31
|
+
|
32
|
+
# create the scoped oembed_response model
|
33
|
+
const_set("OembedResponse", Class.new).class_eval do
|
34
|
+
cattr_accessor :providable_class
|
35
|
+
self.providable_class = self.name.split('::').first.constantize
|
36
|
+
|
37
|
+
cattr_accessor :providable_specs
|
38
|
+
self.providable_specs = specs
|
39
|
+
|
40
|
+
cattr_accessor :oembed_version
|
41
|
+
self.oembed_version = OembedProvider.version
|
42
|
+
|
43
|
+
cattr_accessor :providable_oembed_type
|
44
|
+
self.providable_oembed_type = oembed_type
|
45
|
+
|
46
|
+
the_provider_name = specs[:provider_name].present? ? specs[:provider_name] : OembedProvider.provider_name
|
47
|
+
|
48
|
+
raise ArgumentError, "Missing provider_name setting in either OembedProvider.provider_name or oembed_providable_as spec." unless the_provider_name.present?
|
49
|
+
cattr_accessor :providable_provider_name
|
50
|
+
self.providable_provider_name = the_provider_name
|
51
|
+
|
52
|
+
the_provider_url = specs[:provider_url].present? ? specs[:provider_url] : OembedProvider.provider_url
|
53
|
+
raise ArgumentError, "Missing provider_url setting in either OembedProvider.provider_url or oembed_providable_as spec." unless the_provider_url.present?
|
54
|
+
cattr_accessor :providable_provider_url
|
55
|
+
self.providable_provider_url = the_provider_url
|
56
|
+
|
57
|
+
# cache_age is optional and can be nil
|
58
|
+
the_cache_age = specs[:cache_age].present? ? specs[:cache_age] : OembedProvider.cache_age
|
59
|
+
cattr_accessor :providable_cache_age
|
60
|
+
self.providable_cache_age = the_cache_age
|
61
|
+
|
62
|
+
# these are what the response should return
|
63
|
+
# as per the oEmbed Spec
|
64
|
+
# http://oembed.com/#section2 - 2.3.4
|
65
|
+
# :type is required, but is model wide and set via oembed_providable_as
|
66
|
+
# :version is required and is handled below
|
67
|
+
attributes_to_define = OembedProvider.optional_attributes
|
68
|
+
|
69
|
+
attributes_to_define += OembedProvider.required_attributes[oembed_type]
|
70
|
+
|
71
|
+
# site wide values
|
72
|
+
# :provider_name, :provider_url, :cache_age
|
73
|
+
# can be set via oembed_providable_as
|
74
|
+
# or set via OembedProvider initialization
|
75
|
+
attributes_to_define += OembedProvider.base_attributes
|
76
|
+
|
77
|
+
# not relevant to links, but everything else
|
78
|
+
attributes_to_define += [:maxheight, :maxwidth] unless oembed_type == :link
|
79
|
+
|
80
|
+
cattr_accessor :providable_all_attributes
|
81
|
+
self.providable_all_attributes = attributes_to_define
|
82
|
+
|
83
|
+
attributes_to_define.each do |attr|
|
84
|
+
attr_accessor attr
|
85
|
+
end
|
86
|
+
|
87
|
+
# datastructure is hash
|
88
|
+
# with attribute name as key
|
89
|
+
# and method to call on providable as value
|
90
|
+
# both as symbol
|
91
|
+
# oembed_providable_as can specify method to call for an attribute
|
92
|
+
def self.method_specs_for(attributes)
|
93
|
+
method_specs = Hash.new
|
94
|
+
|
95
|
+
attributes.each do |attr|
|
96
|
+
if providable_specs.keys.include?(attr)
|
97
|
+
method_specs[attr] = providable_specs[attr]
|
98
|
+
else
|
99
|
+
method_specs[attr] = attr
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
method_specs
|
104
|
+
end
|
105
|
+
|
106
|
+
cattr_accessor :optional_attributes_specs
|
107
|
+
self.optional_attributes_specs = method_specs_for(OembedProvider.optional_attributes)
|
108
|
+
|
109
|
+
cattr_accessor :required_attributes_specs
|
110
|
+
self.required_attributes_specs = method_specs_for(OembedProvider.required_attributes[oembed_type])
|
111
|
+
|
112
|
+
# options are added to handle passing maxwidth and maxheight
|
113
|
+
# relevant to oembed types photo, video, and rich
|
114
|
+
# if they have a thumbnail, then these also much not be bigger
|
115
|
+
# than maxwidth, maxheight
|
116
|
+
def initialize(providable, options = {})
|
117
|
+
self.version = self.class.oembed_version
|
118
|
+
|
119
|
+
# we set maxwidth, maxheight first
|
120
|
+
# so subsequent calls to providable.send(some_method_name)
|
121
|
+
# can use them to adjust their values
|
122
|
+
unless type == :link
|
123
|
+
self.maxheight = options[:maxheight].to_i if options[:maxheight].present?
|
124
|
+
self.maxwidth = options[:maxwidth].to_i if options[:maxwidth].present?
|
125
|
+
|
126
|
+
providable.oembed_max_dimensions = { :height => maxheight, :width => maxwidth }
|
127
|
+
end
|
128
|
+
|
129
|
+
self.class.required_attributes_specs.each do |k,v|
|
130
|
+
value = providable.send(v)
|
131
|
+
raise ArgumentError, "#{k} is required for an oEmbed response." if value.blank?
|
132
|
+
|
133
|
+
send(k.to_s + '=', value)
|
134
|
+
end
|
135
|
+
|
136
|
+
self.class.optional_attributes_specs.each do |k,v|
|
137
|
+
send(k.to_s + '=', providable.send(v))
|
138
|
+
end
|
139
|
+
|
140
|
+
self.provider_name = self.class.providable_provider_name
|
141
|
+
self.provider_url = self.class.providable_provider_url
|
142
|
+
self.cache_age = self.class.providable_cache_age
|
143
|
+
end
|
144
|
+
|
145
|
+
def type
|
146
|
+
self.class.providable_oembed_type
|
147
|
+
end
|
148
|
+
|
149
|
+
# because this isn't an AR record, doesn't include to_xml
|
150
|
+
# plus we need a custom
|
151
|
+
# root node needs to replaced with oembed rather than oembed_response
|
152
|
+
def to_xml(opts = {}, &block)
|
153
|
+
attributes = self.class.providable_all_attributes
|
154
|
+
|
155
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
156
|
+
xml.oembed {
|
157
|
+
attributes.each do |attr|
|
158
|
+
next if attr.to_s.include?('max')
|
159
|
+
value = self.send(attr)
|
160
|
+
xml.send(attr, value) if value.present?
|
161
|
+
end
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
builder.to_xml
|
166
|
+
end
|
167
|
+
|
168
|
+
# override default to_json
|
169
|
+
def as_json(options = {})
|
170
|
+
as_json = {}
|
171
|
+
|
172
|
+
self.class.providable_all_attributes.each do |attr|
|
173
|
+
next if attr.to_s.include?("max")
|
174
|
+
v = self.send(attr)
|
175
|
+
as_json[attr] = self.send(attr) if v.present?
|
176
|
+
end
|
177
|
+
|
178
|
+
as_json
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def oembed_type
|
184
|
+
self::OembedResponse.providable_oembed_type
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
module InstanceMethods
|
189
|
+
# FIXME: There is a bug here. Do we really want to memoize?
|
190
|
+
def oembed_response(options = {})
|
191
|
+
@oembed_response ||= self.class::OembedResponse.new(self, options)
|
192
|
+
end
|
193
|
+
|
194
|
+
def oembed_max_dimensions=(options)
|
195
|
+
@oembed_max_dimensions = options
|
196
|
+
end
|
197
|
+
|
198
|
+
def oembed_max_dimensions
|
199
|
+
@oembed_max_dimensions || { :height => nil, :width => nil }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module OembedProviderEngine
|
4
|
+
# set OembedProvider.provider_name, etc. in your config/initializers or somewhere
|
5
|
+
class OembedProvider
|
6
|
+
class << self
|
7
|
+
def provider_url
|
8
|
+
@@provider_url ||= String.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def provider_url=(url)
|
12
|
+
@@provider_url = url
|
13
|
+
end
|
14
|
+
|
15
|
+
def provider_name
|
16
|
+
@@provider_name ||= String.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def provider_name=(name)
|
20
|
+
@@provider_name = name
|
21
|
+
end
|
22
|
+
|
23
|
+
def cache_age
|
24
|
+
@@cache_age ||= nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def cache_age=(age)
|
28
|
+
@@cache_age = age
|
29
|
+
end
|
30
|
+
|
31
|
+
def version
|
32
|
+
"1.0"
|
33
|
+
end
|
34
|
+
|
35
|
+
# every request has these, mostly required
|
36
|
+
# mostly site wide
|
37
|
+
# version is special case
|
38
|
+
def base_attributes
|
39
|
+
[:provider_url,
|
40
|
+
:provider_name,
|
41
|
+
:cache_age,
|
42
|
+
:type,
|
43
|
+
:version]
|
44
|
+
end
|
45
|
+
|
46
|
+
# optional attributes
|
47
|
+
# that are specific to an instance of the providable model
|
48
|
+
def optional_attributes
|
49
|
+
[:title,
|
50
|
+
:author_name,
|
51
|
+
:author_url,
|
52
|
+
:thumbnail_url,
|
53
|
+
:thumbnail_width,
|
54
|
+
:thumbnail_height]
|
55
|
+
end
|
56
|
+
|
57
|
+
# these may be required depending on type
|
58
|
+
# see 2.3.4.1 - 2.3.4.4 of spec
|
59
|
+
# type specific attributes
|
60
|
+
# all attributes listed for these types are required
|
61
|
+
# the empty link array shows that nothing is required
|
62
|
+
def required_attributes
|
63
|
+
{ :photo => [:url, :width, :height],
|
64
|
+
:video => [:html, :width, :height],
|
65
|
+
:link => [],
|
66
|
+
:rich => [:html, :width, :height] }
|
67
|
+
end
|
68
|
+
|
69
|
+
def controller_model_maps
|
70
|
+
@@controller_model_maps ||= Hash.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def controller_model_maps=(hash_map)
|
74
|
+
@@controller_model_maps = hash_map
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_provided_from(url)
|
78
|
+
url = Addressable::URI.parse(url)
|
79
|
+
#TODO smell
|
80
|
+
submitted_url_params = Rails.application.routes.recognize_path(url.path, :method=>:get)
|
81
|
+
|
82
|
+
controller = submitted_url_params[:controller]
|
83
|
+
id = submitted_url_params[:id]
|
84
|
+
|
85
|
+
# handle special cases where controllers are directly configured to point at a specific model
|
86
|
+
model = OembedProvider.controller_model_maps[controller]
|
87
|
+
|
88
|
+
# otherwise we use convention over configuration to determine model
|
89
|
+
model = controller.singularize.camelize unless model
|
90
|
+
|
91
|
+
model.constantize.find(id)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>OembedProvider</title>
|
5
|
+
<%= stylesheet_link_tag "oembed_provider/application", :media => "all" %>
|
6
|
+
<%= javascript_include_tag "oembed_provider/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module OembedProviderEngine
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace OembedProviderEngine
|
4
|
+
|
5
|
+
initializer 'oembed_provider_engine.action_controller' do |app|
|
6
|
+
ActiveSupport.on_load :action_controller do
|
7
|
+
helper ::OembedProviderEngine::OembedProviderHelper
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|