wip oembed refactor. still need to make a oembed_helper, and move some tests to their new home, but e but we are looking preeeetttttyyyy good.
This commit is contained in:
parent
963d5c1a69
commit
139ddd726a
10 changed files with 79 additions and 62 deletions
|
|
@ -31,14 +31,7 @@ module MarkdownifyHelper
|
|||
|
||||
return '' if message.blank?
|
||||
|
||||
#renderer = Redcarpet::Render::HTML.new(render_options)
|
||||
if render_options[:oembed]
|
||||
puts "oembed"
|
||||
renderer = Diaspora::Markdownify::HTMLwithOEmbed.new(render_options)
|
||||
else
|
||||
puts "not oembed"
|
||||
renderer = Diaspora::Markdownify::HTML.new(render_options)
|
||||
end
|
||||
renderer = Diaspora::Markdownify::HTML.new(render_options)
|
||||
markdown = Redcarpet::Markdown.new(renderer, markdown_options)
|
||||
|
||||
message = markdown.render(message).html_safe
|
||||
|
|
|
|||
|
|
@ -7,39 +7,10 @@ module Jobs
|
|||
class GatherOEmbedData < Base
|
||||
@queue = :http_service
|
||||
|
||||
class GatherOEmbedRenderer < Redcarpet::Render::HTML
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ActionView::Helpers::TagHelper
|
||||
|
||||
def isHttp?(url)
|
||||
URI.parse(url).scheme.downcase == 'http'
|
||||
end
|
||||
|
||||
def autolink(link, type)
|
||||
url = auto_link(link, :link => :urls).scan(/href=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?/).first.first
|
||||
url = CGI::unescapeHTML(url)
|
||||
|
||||
return url if OEmbedCache.exists?(:url => url) or not isHttp?(url)
|
||||
|
||||
begin
|
||||
res = ::OEmbed::Providers.get(url, {:maxwidth => 420, :maxheight => 420, :frame => 1, :iframe => 1})
|
||||
rescue Exception => e
|
||||
# noop
|
||||
else
|
||||
data = res.fields
|
||||
data['trusted_endpoint_url'] = res.provider.endpoint
|
||||
cache = OEmbedCache.new(:url => url, :data => data)
|
||||
cache.save
|
||||
end
|
||||
|
||||
return url
|
||||
end
|
||||
end
|
||||
|
||||
def self.perform(text)
|
||||
renderer = GatherOEmbedRenderer.new({})
|
||||
markdown = Redcarpet::Markdown.new(renderer, {:autolink => true})
|
||||
message = markdown.render(text)
|
||||
def self.perform(post_id, url)
|
||||
post = Post.find(post_id)
|
||||
post.o_embed_cache = OEmbedCache.find_or_create_by_url(url)
|
||||
post.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
class OEmbedCache < ActiveRecord::Base
|
||||
serialize :data
|
||||
attr_accessible :url
|
||||
|
||||
has_many :posts
|
||||
|
||||
def self.find_or_create_by_url(url)
|
||||
cache = OEmbedCache.find_or_build_by_url(url)
|
||||
return cache if cache.persisted?
|
||||
cache.fetch_and_save_oembed_data!
|
||||
cache
|
||||
end
|
||||
|
||||
def fetch_and_save_oembed_data!
|
||||
begin
|
||||
response = OEmbed::Providers.get(self.url, {:maxwidth => 420, :maxheight => 420, :frame => 1, :iframe => 1})
|
||||
rescue Exception => e
|
||||
# noop
|
||||
else
|
||||
self.data = response.fields
|
||||
self.data['trusted_endpoint_url'] = response.provider.endpoint
|
||||
cache.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ class Post < ActiveRecord::Base
|
|||
has_many :reshares, :class_name => "Reshare", :foreign_key => :root_guid, :primary_key => :guid
|
||||
has_many :resharers, :class_name => 'Person', :through => :reshares, :source => :author
|
||||
|
||||
has_one :o_embed_cache
|
||||
|
||||
belongs_to :author, :class_name => 'Person'
|
||||
|
||||
validates :guid, :uniqueness => true
|
||||
|
|
@ -66,11 +68,6 @@ class Post < ActiveRecord::Base
|
|||
@reshare_count ||= Post.where(:root_guid => self.guid).count
|
||||
end
|
||||
|
||||
def text= nd
|
||||
Resque.enqueue(Jobs::GatherOEmbedData, nd)
|
||||
write_attribute(:text, nd)
|
||||
end
|
||||
|
||||
def diaspora_handle= nd
|
||||
self.author = Person.where(:diaspora_handle => nd).first
|
||||
write_attribute(:diaspora_handle, nd)
|
||||
|
|
|
|||
|
|
@ -22,10 +22,13 @@ class StatusMessage < Post
|
|||
validate :presence_of_content
|
||||
|
||||
attr_accessible :text, :provider_display_name
|
||||
attr_accessor :oembed_url
|
||||
serialize :youtube_titles, Hash
|
||||
|
||||
after_create :create_mentions
|
||||
|
||||
after_create :queue_gather_oembed_data, :if => :contains_oembed_url_in_text?
|
||||
|
||||
#scopes
|
||||
scope :where_person_is_mentioned, lambda{|person| joins(:mentions).where(:mentions => {:person_id => person.id})}
|
||||
|
||||
|
|
@ -153,6 +156,16 @@ class StatusMessage < Post
|
|||
self.text.blank? && self.photos.blank?
|
||||
end
|
||||
|
||||
def queue_gather_oembed_data
|
||||
Resque.enqueue(Jobs::GatherOEmbedData, self.oembed_url)
|
||||
end
|
||||
|
||||
def contains_oembed_url_in_text?
|
||||
require 'uri'
|
||||
urls = URI.extract(self.raw_message, ['http', 'https'])
|
||||
self.oembed_url = urls.find{|url| ENDPOINT_HOSTS_STRING.match(URI.parse(url).host)}
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def presence_of_content
|
||||
|
|
|
|||
|
|
@ -1,4 +1,20 @@
|
|||
require 'oembed'
|
||||
require 'uri'
|
||||
|
||||
OEmbed::Providers.register_all
|
||||
OEmbed::Providers.register_fallback(OEmbed::ProviderDiscovery)
|
||||
|
||||
#
|
||||
# SECURITY NOTICE! CROSS-SITE SCRIPTING!
|
||||
# these endpoints may inject html code into our page
|
||||
# note that 'trusted_endpoint_url' is the only information
|
||||
# in OEmbed that we can trust. anything else may be spoofed!
|
||||
SECURE_ENDPOINTS = [::OEmbed::Providers::Youtube.endpoint,
|
||||
::OEmbed::Providers::Viddler.endpoint,
|
||||
::OEmbed::Providers::Qik.endpoint,
|
||||
::OEmbed::Providers::Revision3.endpoint,
|
||||
::OEmbed::Providers::Hulu.endpoint,
|
||||
::OEmbed::Providers::Vimeo.endpoint,
|
||||
'http://soundcloud.com/oembed',
|
||||
'http://cubbi.es/oembed'
|
||||
]
|
||||
ENDPOINT_HOSTS_STRING = SECURE_ENDPOINTS.map{|e| URI.parse(e.split('{')[0]).host}.to_s
|
||||
|
|
|
|||
9
db/migrate/20111011193702_add_oembed_cache_to_posts.rb
Normal file
9
db/migrate/20111011193702_add_oembed_cache_to_posts.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class AddOembedCacheToPosts < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :posts, :o_embed_cache_id, :integer
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :posts, :o_embed_cache_id
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20111003232053) do
|
||||
ActiveRecord::Schema.define(:version => 20111011193702) do
|
||||
|
||||
create_table "aspect_memberships", :force => true do |t|
|
||||
t.integer "aspect_id", :null => false
|
||||
|
|
@ -290,6 +290,7 @@ ActiveRecord::Schema.define(:version => 20111003232053) do
|
|||
t.string "status_message_guid"
|
||||
t.integer "likes_count", :default => 0
|
||||
t.integer "comments_count", :default => 0
|
||||
t.integer "o_embed_cache_id"
|
||||
end
|
||||
|
||||
add_index "posts", ["author_id", "root_guid"], :name => "index_posts_on_author_id_and_root_guid", :unique => true
|
||||
|
|
|
|||
|
|
@ -25,24 +25,11 @@ module Diaspora
|
|||
url = auto_link(link, :link => :urls).scan(/href=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?/).first.first
|
||||
url = CGI::unescapeHTML(url)
|
||||
|
||||
# SECURITY NOTICE! CROSS-SITE SCRIPTING!
|
||||
# these endpoints may inject html code into our page
|
||||
secure_endpoints = [::OEmbed::Providers::Youtube.endpoint,
|
||||
::OEmbed::Providers::Viddler.endpoint,
|
||||
::OEmbed::Providers::Qik.endpoint,
|
||||
::OEmbed::Providers::Revision3.endpoint,
|
||||
::OEmbed::Providers::Hulu.endpoint,
|
||||
::OEmbed::Providers::Vimeo.endpoint,
|
||||
'http://soundcloud.com/oembed',
|
||||
]
|
||||
|
||||
# note that 'trusted_endpoint_url' is the only information
|
||||
# in OEmbed that we can trust. anything else may be spoofed!
|
||||
cache = OEmbedCache.find_by_url(url)
|
||||
if not cache.nil? and cache.data.has_key?('type')
|
||||
case cache.data['type']
|
||||
when 'video', 'rich'
|
||||
if secure_endpoints.include?(cache.data['trusted_endpoint_url']) and cache.data.has_key?('html')
|
||||
if SECURE_ENDPOINTS.include?(cache.data['trusted_endpoint_url']) and cache.data.has_key?('html')
|
||||
rep = raw(cache.data['html'])
|
||||
elsif cache.data.has_key?('thumbnail_url')
|
||||
img_options = {}
|
||||
|
|
|
|||
|
|
@ -312,4 +312,12 @@ STR
|
|||
@status_message.after_dispatch(alice)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#contains_url_in_text?' do
|
||||
it 'returns an array of all urls found in the raw message' do
|
||||
sm = Factory(:status_message, :text => 'http://youtube.com is so cool. so is https://joindiaspora.com')
|
||||
sm.contains_oembed_url_in_text?.should_not be_nil
|
||||
sm.oembed_url.should == 'http://youtube.com'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue