acts_as_unvlogable 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +15 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +130 -0
- data/Rakefile +2 -0
- data/acts_as_unvlogable.gemspec +26 -0
- data/lib/acts_as_unvlogable/flickr.rb +713 -0
- data/lib/acts_as_unvlogable/object_base.rb +15 -0
- data/lib/acts_as_unvlogable/string_base.rb +24 -0
- data/lib/acts_as_unvlogable/string_extend.rb +8 -0
- data/lib/acts_as_unvlogable/version.rb +3 -0
- data/lib/acts_as_unvlogable/vg_11870.rb +57 -0
- data/lib/acts_as_unvlogable/vg_blip.rb +48 -0
- data/lib/acts_as_unvlogable/vg_collegehumor.rb +66 -0
- data/lib/acts_as_unvlogable/vg_dailymotion.rb +66 -0
- data/lib/acts_as_unvlogable/vg_dalealplay.rb +49 -0
- data/lib/acts_as_unvlogable/vg_flickr.rb +70 -0
- data/lib/acts_as_unvlogable/vg_marca.rb +48 -0
- data/lib/acts_as_unvlogable/vg_metacafe.rb +77 -0
- data/lib/acts_as_unvlogable/vg_mtvmusic.rb +65 -0
- data/lib/acts_as_unvlogable/vg_myspace.rb +48 -0
- data/lib/acts_as_unvlogable/vg_qik.rb +66 -0
- data/lib/acts_as_unvlogable/vg_rutube.rb +80 -0
- data/lib/acts_as_unvlogable/vg_ted.rb +51 -0
- data/lib/acts_as_unvlogable/vg_vimeo.rb +78 -0
- data/lib/acts_as_unvlogable/vg_youtube.rb +57 -0
- data/lib/acts_as_unvlogable.rb +91 -0
- data/test/acts_as_unvlogable_test.rb +392 -0
- data/unvlogable_sample.yml +5 -0
- metadata +169 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Qik (qik.com)
|
3
|
+
# http://qik.com/video/340982
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
|
7
|
+
class VgQik
|
8
|
+
|
9
|
+
def initialize(url=nil, options={})
|
10
|
+
@url = url
|
11
|
+
@video_id = parse_url(url)
|
12
|
+
@page = Hpricot(open("http://qik.com/video/#{@video_id}"))
|
13
|
+
emb = @page.search('//input[@value^="<object"]').first.attributes['value']
|
14
|
+
tx = Hpricot(emb)
|
15
|
+
@feed_url = CGI::parse(tx.search('//embed').first.attributes['flashvars'].to_s)["rssURL"].to_s
|
16
|
+
res = Net::HTTP.get(URI::parse(@feed_url))
|
17
|
+
@feed = REXML::Document.new(res)
|
18
|
+
end
|
19
|
+
|
20
|
+
def title
|
21
|
+
REXML::XPath.first(@feed, "//item/title")[0].to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def thumbnail
|
25
|
+
REXML::XPath.first(@feed, "//item/media:thumbnail").attributes['url']
|
26
|
+
end
|
27
|
+
|
28
|
+
def embed_url
|
29
|
+
"http://qik.com/swfs/qikPlayer4.swf?rssURL=#{@feed_url}&autoPlay=false"
|
30
|
+
end
|
31
|
+
|
32
|
+
def embed_html(width=425, height=344, options={})
|
33
|
+
"<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0' width='#{width}' height='#{height}' id='qikPlayer' align='middle'><param name='allowScriptAccess' value='sameDomain' /><param name='allowFullScreen' value='true' /><param name='movie' value='#{embed_url}' /><param name='quality' value='high' /><param name='bgcolor' value='#333333' /><embed src='#{embed_url}' quality='high' bgcolor='#333333' width='#{width}' height='#{height}' name='qikPlayer' align='middle' allowScriptAccess='sameDomain' allowFullScreen='true' type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/go/getflashplayer'/></object>"
|
34
|
+
end
|
35
|
+
|
36
|
+
def flv
|
37
|
+
REXML::XPath.first(@feed, "//item/media:content[@type='video/x-flv']").attributes['url']
|
38
|
+
end
|
39
|
+
|
40
|
+
def download_url
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def duration
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def service
|
49
|
+
"Qik"
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def parse_url(url)
|
55
|
+
video_id = nil
|
56
|
+
if url.split('#').size > 1
|
57
|
+
pieces = url.split(/#|=/)
|
58
|
+
hash = Hash[*pieces]
|
59
|
+
video_id = hash['v']
|
60
|
+
else
|
61
|
+
video_id = url.split("/")[4]
|
62
|
+
end
|
63
|
+
video_id
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class VgRutube
|
2
|
+
|
3
|
+
def initialize(url=nil, options={})
|
4
|
+
@url = url
|
5
|
+
parse_url(url)
|
6
|
+
end
|
7
|
+
|
8
|
+
def title
|
9
|
+
rt_info["movie"][0]["title"][0].strip
|
10
|
+
end
|
11
|
+
|
12
|
+
# this method of extraction is somewhat fragile to changes in RuTube urls
|
13
|
+
# more correct way would be using rt_info structure, like it was done in title()
|
14
|
+
def thumbnail
|
15
|
+
# size=1 gives bigger thumbnail.
|
16
|
+
# I'm not sure how to add size parameter in compatible way
|
17
|
+
size = 2
|
18
|
+
"http://img.rutube.ru/thumbs/#{movie_hash[0,2]}/#{movie_hash[2,2]}/#{movie_hash}-#{size}.jpg"
|
19
|
+
end
|
20
|
+
|
21
|
+
def embed_url
|
22
|
+
# path to swf
|
23
|
+
"http://video.rutube.ru/#{movie_hash}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def embed_html(width=425, height=344, options={})
|
27
|
+
# overridden cause we have to change default size if needed
|
28
|
+
return <<-"END"
|
29
|
+
<object width="#{width}" height="#{height}"><param
|
30
|
+
name="movie" value="#{embed_url}"></param><param
|
31
|
+
name="wmode" value="window"></param><param
|
32
|
+
name="allowFullScreen" value="true"></param><embed
|
33
|
+
src="#{embed_url}" type="application/x-shockwave-flash"
|
34
|
+
wmode="window" width="#{width}" height="#{height}"
|
35
|
+
allowFullScreen="true"></embed>
|
36
|
+
</object>
|
37
|
+
END
|
38
|
+
end
|
39
|
+
|
40
|
+
def flv
|
41
|
+
# Fragile, untested, issues one redirect to actual location
|
42
|
+
# can't be extracted from rt_info
|
43
|
+
"http://bl.rutube.ru/#{movie_hash}.iflv"
|
44
|
+
end
|
45
|
+
|
46
|
+
def download_url
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def duration
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def service
|
55
|
+
"Rutube"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
attr_accessor :movie_id
|
61
|
+
RT_XML_API = "http://rutube.ru/cgi-bin/xmlapi.cgi"
|
62
|
+
|
63
|
+
def movie_hash
|
64
|
+
@movie_hash ||= rt_info["movie"][0]["playerLink"][0].match( %r{[a-f0-9]+$} )[0]
|
65
|
+
end
|
66
|
+
|
67
|
+
def rt_info
|
68
|
+
url = RT_XML_API + "?rt_movie_id=#{movie_id}&rt_mode=movie"
|
69
|
+
@rt_info ||= XmlSimple.xml_in( Net::HTTP.get_response( URI.parse(url) ).body )
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_url(url)
|
73
|
+
uri = URI.parse(url)
|
74
|
+
@movie_id = uri.path.match(/\d+/)[0]
|
75
|
+
# this doesn't work reliably:
|
76
|
+
# @movie_hash = uri.query.match(/(^|&)v=([^&]+)/)[2]
|
77
|
+
# we'll cut it from rt_info instead
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Ted Talks (www.ted.com/talks)
|
3
|
+
# http://www.ted.com/index.php/talks/benjamin_wallace_on_the_price_of_happiness.html
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
|
7
|
+
class VgTed
|
8
|
+
|
9
|
+
def initialize(url=nil, options={})
|
10
|
+
@url = url
|
11
|
+
raise unless URI::parse(url).path.split("/").include? "talks"
|
12
|
+
@page = Hpricot(open(url))
|
13
|
+
id = @page.to_s.split("/id/")[1].split("\"")[0]
|
14
|
+
@emb = Hpricot(open("http://www.ted.com/talks/embed/id/#{id}"))
|
15
|
+
@flashvars = CGI::unescapeHTML(@emb.to_s).split("param name=\"flashvars\" value=\"")[1].split("\"")[0]
|
16
|
+
@args = CGI::parse(@flashvars)
|
17
|
+
end
|
18
|
+
|
19
|
+
def title
|
20
|
+
@page.search("//h1/span").first.inner_html.strip
|
21
|
+
end
|
22
|
+
|
23
|
+
def thumbnail
|
24
|
+
"#{@args['su']}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def duration
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def embed_url
|
32
|
+
"http://video.ted.com/assets/player/swf/EmbedPlayer.swf?#{@flashvars}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def embed_html(width=425, height=344, options={})
|
36
|
+
"<object width='#{width}' height='#{height}'><param name='movie' value='#{embed_url}'></param><param name='allowFullScreen' value='true' /><param name='wmode' value='transparent'></param><param name='bgColor' value='#ffffff'></param><embed src='#{embed_url}' pluginspace='http://www.macromedia.com/go/getflashplayer' type='application/x-shockwave-flash' wmode='transparent' bgColor='#ffffff' width='#{width}' height='#{height}' allowFullScreen='true'></embed></object>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def flv
|
40
|
+
"#{@args['vu'].to_s}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def download_url
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def service
|
48
|
+
"Ted Talks"
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Vimeo (vimeo.com)
|
3
|
+
# http://vimeo.com/5362441
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
|
7
|
+
class VgVimeo
|
8
|
+
|
9
|
+
def initialize(url=nil, options={})
|
10
|
+
# general settings
|
11
|
+
@url = url
|
12
|
+
@video_id = parse_url(url)
|
13
|
+
res = Net::HTTP.get(URI.parse("http://vimeo.com/moogaloop/load/clip:#{@video_id}/embed?param_server=vimeo.com¶m_clip_id=#{@video_id}"))
|
14
|
+
@feed = REXML::Document.new(res)
|
15
|
+
end
|
16
|
+
|
17
|
+
def video_id
|
18
|
+
@video_id
|
19
|
+
end
|
20
|
+
|
21
|
+
def title
|
22
|
+
REXML::XPath.first( @feed, "//caption" )[0].to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def thumbnail
|
26
|
+
REXML::XPath.first( @feed, "//thumbnail" )[0].to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def duration
|
30
|
+
REXML::XPath.first( @feed, "//duration" )[0].to_s.to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def embed_url
|
34
|
+
"http://vimeo.com/moogaloop.swf?clip_id=#{@video_id}&server=vimeo.com&fullscreen=1&show_title=1&show_byline=1&show_portrait=1"
|
35
|
+
end
|
36
|
+
|
37
|
+
def embed_html(width=425, height=344, options={})
|
38
|
+
"<object width='#{width}' height='#{height}'><param name='movie' value='#{embed_url}'></param><param name='allowFullScreen' value='true'></param><param name='allowscriptaccess' value='always'></param><embed src='#{embed_url}' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' width='#{width}' height='#{height}'></embed></object>"
|
39
|
+
end
|
40
|
+
|
41
|
+
def flv
|
42
|
+
request_signature = REXML::XPath.first( @feed, "//request_signature" )[0]
|
43
|
+
request_signature_expires = REXML::XPath.first( @feed, "//request_signature_expires" )[0]
|
44
|
+
"http://www.vimeo.com/moogaloop/play/clip:#{@video_id}/#{request_signature}/#{request_signature_expires}/"
|
45
|
+
end
|
46
|
+
|
47
|
+
def download_url
|
48
|
+
request_signature = REXML::XPath.first( @feed, "//request_signature" )[0]
|
49
|
+
request_signature_expires = REXML::XPath.first( @feed, "//request_signature_expires" )[0]
|
50
|
+
"http://www.vimeo.com/moogaloop/play/clip:#{@video_id}/#{request_signature}/#{request_signature_expires}/?q=hd"
|
51
|
+
end
|
52
|
+
|
53
|
+
def service
|
54
|
+
"Vimeo"
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
# formats: http://vimeo.com/<video_id> or http://vimeo.com/channels/hd#<video_id>
|
60
|
+
def parse_url(url)
|
61
|
+
uri = URI.parse(url)
|
62
|
+
path = uri.path
|
63
|
+
videoargs = ''
|
64
|
+
|
65
|
+
return uri.fragment if uri.fragment
|
66
|
+
|
67
|
+
if uri.path and path.split("/").size > 0
|
68
|
+
videoargs = path.split("/")
|
69
|
+
raise unless videoargs.size > 0
|
70
|
+
else
|
71
|
+
raise
|
72
|
+
end
|
73
|
+
videoargs[1]
|
74
|
+
rescue
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Youtube (youtube.com)
|
3
|
+
# http://www.youtube.com/watch?v=25AsfkriHQc
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
|
7
|
+
class VgYoutube
|
8
|
+
|
9
|
+
def initialize(url=nil, options={})
|
10
|
+
object = YouTubeIt::Client.new({})
|
11
|
+
@url = url
|
12
|
+
@video_id = @url.query_param('v')
|
13
|
+
@details = object.video_by(@video_id)
|
14
|
+
@details.instance_variable_set(:@noembed, false)
|
15
|
+
raise if @details.blank?
|
16
|
+
end
|
17
|
+
|
18
|
+
def title
|
19
|
+
@details.title
|
20
|
+
end
|
21
|
+
|
22
|
+
def thumbnail
|
23
|
+
@details.thumbnails.first.url
|
24
|
+
end
|
25
|
+
|
26
|
+
def duration
|
27
|
+
@details.duration
|
28
|
+
end
|
29
|
+
|
30
|
+
def embed_url
|
31
|
+
@details.media_content.first.url if @details.noembed == false
|
32
|
+
end
|
33
|
+
|
34
|
+
# options
|
35
|
+
# You can read more about the youtube player options in
|
36
|
+
# http://code.google.com/intl/en/apis/youtube/player_parameters.html
|
37
|
+
# Use them in options (ex {:rel => 0, :color1 => '0x333333'})
|
38
|
+
#
|
39
|
+
def embed_html(width=425, height=344, options={})
|
40
|
+
"<object width='#{width}' height='#{height}'><param name='movie' value='#{embed_url}#{options.map {|k,v| "&#{k}=#{v}"}}'></param><param name='allowFullScreen' value='true'></param><param name='allowscriptaccess' value='always'></param><embed src='#{embed_url}#{options.map {|k,v| "&#{k}=#{v}"}}' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' width='#{width}' height='#{height}'></embed></object>" if @details.noembed == false
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def flv
|
45
|
+
doc = URI::parse("http://www.youtube.com/get_video_info?&video_id=#{@video_id}").read
|
46
|
+
CGI::unescape(doc.split("&fmt_url_map=")[1].split("&")[0]).split("|")[1].split(",")[0]
|
47
|
+
end
|
48
|
+
|
49
|
+
def download_url
|
50
|
+
flv
|
51
|
+
end
|
52
|
+
|
53
|
+
def service
|
54
|
+
"Youtube"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require "xmlsimple"
|
5
|
+
require "youtube_it"
|
6
|
+
require "hpricot"
|
7
|
+
require "iconv"
|
8
|
+
|
9
|
+
require "acts_as_unvlogable/flickr"
|
10
|
+
# Extensions
|
11
|
+
if defined?(ActiveSupport).nil?
|
12
|
+
require "acts_as_unvlogable/string_base"
|
13
|
+
require "acts_as_unvlogable/object_base"
|
14
|
+
end
|
15
|
+
require "acts_as_unvlogable/string_extend"
|
16
|
+
|
17
|
+
# Video classes
|
18
|
+
videolibs = File.join(File.dirname(__FILE__), "acts_as_unvlogable", "vg_*.rb")
|
19
|
+
Dir.glob(videolibs).each {|file| require file}
|
20
|
+
|
21
|
+
class UnvlogIt
|
22
|
+
|
23
|
+
def initialize(url=nil, options={})
|
24
|
+
raise ArgumentError.new("We need a video url") if url.blank?
|
25
|
+
@object ||= "vg_#{get_domain(url).downcase}".camelize.constantize.new(url, options) rescue nil
|
26
|
+
raise ArgumentError.new("Unsuported url or service") and return if @object.nil?
|
27
|
+
unless @object.instance_variable_get("@details").nil? || !@object.instance_variable_get("@details").respond_to?("noembed")
|
28
|
+
raise ArgumentError.new("Embedding disabled by request") and return if @object.instance_variable_get("@details").noembed
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def title
|
33
|
+
@object.title #rescue nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def thumbnail
|
37
|
+
@object.thumbnail rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def duration # duration is in seconds
|
41
|
+
@object.duration rescue nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def embed_url
|
45
|
+
@object.embed_url rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def video_id
|
49
|
+
@object.video_id rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def embed_html(width=425, height=344, options={})
|
53
|
+
@object.embed_html(width, height, options) rescue nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def flv
|
57
|
+
@object.flv rescue nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def download_url
|
61
|
+
@object.download_url rescue nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def service
|
65
|
+
@object.service rescue nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def video_details(width=425, height=344)
|
69
|
+
{
|
70
|
+
:title => @object.title,
|
71
|
+
:thumbnail => @object.thumbnail,
|
72
|
+
:embed_url => @object.embed_url,
|
73
|
+
:embed_html => @object.embed_html(width, height),
|
74
|
+
:flv => @object.flv,
|
75
|
+
:download_url => @object.download_url,
|
76
|
+
:service => @object.service,
|
77
|
+
:duration => @object.duration
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def get_domain(url)
|
83
|
+
host = URI::parse(url).host.split(".")
|
84
|
+
unless host.size == 1
|
85
|
+
host[host.size-2]
|
86
|
+
else
|
87
|
+
host[0]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|