oembed_provider_engine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +40 -0
  4. data/app/controllers/oembed_provider_engine/application_controller.rb +2 -0
  5. data/app/controllers/oembed_provider_engine/oembed_provider_controller.rb +56 -0
  6. data/app/helpers/oembed_provider_engine/application_helper.rb +4 -0
  7. data/app/helpers/oembed_provider_engine/oembed_provider_helper.rb +20 -0
  8. data/app/models/oembed_provider_engine/oembed_providable.rb +204 -0
  9. data/app/models/oembed_provider_engine/oembed_provider.rb +95 -0
  10. data/app/views/layouts/oembed_provider_engine/application.html.erb +14 -0
  11. data/config/routes.rb +3 -0
  12. data/lib/oembed_provider_engine/engine.rb +11 -0
  13. data/lib/oembed_provider_engine/version.rb +3 -0
  14. data/lib/oembed_provider_engine.rb +4 -0
  15. data/lib/tasks/oembed_providerengine_tasks.rake +4 -0
  16. data/test/dummy/README.rdoc +261 -0
  17. data/test/dummy/Rakefile +7 -0
  18. data/test/dummy/app/assets/javascripts/application.js +15 -0
  19. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  20. data/test/dummy/app/controllers/application_controller.rb +3 -0
  21. data/test/dummy/app/controllers/photos_controller.rb +11 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/models/item.rb +4 -0
  24. data/test/dummy/app/models/photo.rb +4 -0
  25. data/test/dummy/app/views/items/edit.html.erb +24 -0
  26. data/test/dummy/app/views/items/index.html.erb +24 -0
  27. data/test/dummy/app/views/items/new.html.erb +23 -0
  28. data/test/dummy/app/views/items/show.html.erb +21 -0
  29. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  30. data/test/dummy/app/views/layouts/items.html.erb +20 -0
  31. data/test/dummy/app/views/layouts/photos.html.erb +18 -0
  32. data/test/dummy/app/views/photos/edit.html.erb +12 -0
  33. data/test/dummy/app/views/photos/index.html.erb +18 -0
  34. data/test/dummy/app/views/photos/new.html.erb +11 -0
  35. data/test/dummy/app/views/photos/show.html.erb +3 -0
  36. data/test/dummy/config/application.rb +59 -0
  37. data/test/dummy/config/boot.rb +10 -0
  38. data/test/dummy/config/database.yml +25 -0
  39. data/test/dummy/config/environment.rb +5 -0
  40. data/test/dummy/config/environments/development.rb +37 -0
  41. data/test/dummy/config/environments/production.rb +67 -0
  42. data/test/dummy/config/environments/test.rb +37 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/inflections.rb +15 -0
  45. data/test/dummy/config/initializers/mime_types.rb +5 -0
  46. data/test/dummy/config/initializers/oembed_provider.rb +2 -0
  47. data/test/dummy/config/initializers/secret_token.rb +7 -0
  48. data/test/dummy/config/initializers/session_store.rb +8 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/locales/en.yml +5 -0
  51. data/test/dummy/config/routes.rb +7 -0
  52. data/test/dummy/config.ru +4 -0
  53. data/test/dummy/db/migrate/20110212010602_create_items.rb +13 -0
  54. data/test/dummy/db/migrate/20110212022722_create_photos.rb +15 -0
  55. data/test/dummy/db/schema.rb +37 -0
  56. data/test/dummy/public/404.html +26 -0
  57. data/test/dummy/public/422.html +26 -0
  58. data/test/dummy/public/500.html +25 -0
  59. data/test/dummy/public/favicon.ico +0 -0
  60. data/test/dummy/script/rails +6 -0
  61. data/test/factories/photos.rb +14 -0
  62. data/test/functional/oembed_provider_controller_test.rb +52 -0
  63. data/test/integration/navigation_test.rb +10 -0
  64. data/test/integration/oembed_test.rb +84 -0
  65. data/test/oembed_providable_test.rb +215 -0
  66. data/test/oembed_provider_test.rb +110 -0
  67. data/test/test_helper.rb +25 -0
  68. 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,2 @@
1
+ class OembedProviderEngine::ApplicationController < ApplicationController
2
+ end
@@ -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,4 @@
1
+ module OembedProviderEngine
2
+ module ApplicationHelper
3
+ end
4
+ 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,3 @@
1
+ OembedProviderEngine::Engine.routes.draw do
2
+ match "/(.:format)" => "oembed_provider#endpoint"
3
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module OembedProviderEngine
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ require "oembed_provider_engine/engine"
2
+
3
+ module OembedProviderEngine
4
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :oembed_provider do
3
+ # # Task goes here
4
+ # end