acts_as_unvlogable_fork 1.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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +16 -0
- data/Gemfile +14 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +130 -0
- data/Rakefile +2 -0
- data/acts_as_unvlogable.gemspec +25 -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 +48 -0
- data/lib/acts_as_unvlogable/vg_blip.rb +48 -0
- data/lib/acts_as_unvlogable/vg_collegehumor.rb +58 -0
- data/lib/acts_as_unvlogable/vg_dailymotion.rb +67 -0
- data/lib/acts_as_unvlogable/vg_dalealplay.rb +50 -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_myspace.rb +48 -0
- data/lib/acts_as_unvlogable/vg_prostopleer.rb +46 -0
- data/lib/acts_as_unvlogable/vg_qik.rb +64 -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 +89 -0
- data/lib/acts_as_unvlogable/vg_youtu.rb +11 -0
- data/lib/acts_as_unvlogable/vg_youtube.rb +67 -0
- data/lib/acts_as_unvlogable.rb +117 -0
- data/test/acts_as_unvlogable_test.rb +392 -0
- data/test/video_factory_test.rb +66 -0
- data/unvlogable_sample.yml +5 -0
- metadata +137 -0
@@ -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={}, params={})
|
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/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("ted 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={}, params={})
|
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,89 @@
|
|
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
|
+
|
14
|
+
if !(@vimeo_id =~ /^[0-9]+$/)
|
15
|
+
r = Net::HTTP.get_response(URI.parse(url))
|
16
|
+
|
17
|
+
if r.code == "301"
|
18
|
+
@url = "http://vimeo.com#{r.header['location']}"
|
19
|
+
@video_id = parse_url(@url)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
res = Net::HTTP.get(URI.parse("http://vimeo.com/api/v2/video/#{@video_id}.xml"))
|
24
|
+
@feed = REXML::Document.new(res)
|
25
|
+
end
|
26
|
+
|
27
|
+
def video_id
|
28
|
+
@video_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def title
|
32
|
+
REXML::XPath.first( @feed, "//title" )[0].to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def thumbnail
|
36
|
+
REXML::XPath.first( @feed, "//thumbnail_medium" )[0].to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def duration
|
40
|
+
REXML::XPath.first( @feed, "//duration" )[0].to_s.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
def embed_url
|
44
|
+
"http://vimeo.com/moogaloop.swf?clip_id=#{@video_id}&force_embed=1&server=vimeo.com&show_title=1&show_byline=0&show_portrait=1&color=ffffff&fullscreen=1&autoplay=0&loop=0"
|
45
|
+
end
|
46
|
+
|
47
|
+
def embed_html(width=425, height=344, options={}, params={})
|
48
|
+
"<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>"
|
49
|
+
end
|
50
|
+
|
51
|
+
def flv
|
52
|
+
res = Net::HTTP.get(URI.parse("http://vimeo.com/42966264?action=download"))
|
53
|
+
request_signature = res.split("\"signature\":\"")[1].split("\"")[0]
|
54
|
+
request_cached_timestamp = res.split("\"cached_timestamp\":")[1].split(",")[0]
|
55
|
+
"http://player.vimeo.com/play_redirect?clip_id=#{@video_id}&sig=#{request_signature}&time=#{request_cached_timestamp}&quality=sd&codecs=H264,VP8,VP6&type=moogaloop&embed_location="
|
56
|
+
end
|
57
|
+
|
58
|
+
def download_url
|
59
|
+
request_signature = REXML::XPath.first( @feed, "//request_signature" )[0]
|
60
|
+
request_signature_expires = REXML::XPath.first( @feed, "//request_signature_expires" )[0]
|
61
|
+
"http://www.vimeo.com/moogaloop/play/clip:#{@video_id}/#{request_signature}/#{request_signature_expires}/?q=hd"
|
62
|
+
end
|
63
|
+
|
64
|
+
def service
|
65
|
+
"Vimeo"
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
# formats: http://vimeo.com/<video_id> or http://vimeo.com/channels/hd#<video_id>
|
71
|
+
def parse_url(url)
|
72
|
+
uri = URI.parse(url)
|
73
|
+
path = uri.path
|
74
|
+
videoargs = ''
|
75
|
+
|
76
|
+
return uri.fragment if uri.fragment
|
77
|
+
|
78
|
+
if uri.path and path.split("/").size > 0
|
79
|
+
videoargs = path.split("/")
|
80
|
+
raise unless videoargs.size > 0
|
81
|
+
else
|
82
|
+
raise
|
83
|
+
end
|
84
|
+
videoargs[1]
|
85
|
+
rescue
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "acts_as_unvlogable/vg_youtube"
|
2
|
+
|
3
|
+
class VgYoutu < VgYoutube
|
4
|
+
def initialize(url=nil, options={})
|
5
|
+
url = URI(url)
|
6
|
+
url.host = 'www.youtube.com'
|
7
|
+
url.query = "#{url.query}&v=#{url.path[1..-1]}"
|
8
|
+
url.path = '/watch'
|
9
|
+
super(url.to_s, options)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Youtube (youtube.com)
|
3
|
+
# http://www.youtube.com/watch?v=25AsfkriHQc
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
class VgYoutube
|
7
|
+
|
8
|
+
def initialize(url=nil, options={})
|
9
|
+
object = YouTubeIt::Client.new({})
|
10
|
+
@url = url
|
11
|
+
@video_id = @url.query_param('v')
|
12
|
+
begin
|
13
|
+
@details = object.video_by(@video_id)
|
14
|
+
raise if @details.blank?
|
15
|
+
raise ArgumentError, "Embedding disabled by request" unless @details.embeddable?
|
16
|
+
@details.instance_variable_set(:@noembed, false)
|
17
|
+
rescue
|
18
|
+
raise ArgumentError, "Unsuported url or service"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def title
|
23
|
+
@details.title
|
24
|
+
end
|
25
|
+
|
26
|
+
def thumbnail
|
27
|
+
@details.thumbnails.first.url
|
28
|
+
end
|
29
|
+
|
30
|
+
def duration
|
31
|
+
@details.duration
|
32
|
+
end
|
33
|
+
|
34
|
+
def embed_url
|
35
|
+
@details.media_content.first.url if @details.noembed == false
|
36
|
+
end
|
37
|
+
|
38
|
+
# options
|
39
|
+
# You can read more about the youtube player options in
|
40
|
+
# http://code.google.com/intl/en/apis/youtube/player_parameters.html
|
41
|
+
# Use them in options (ex {:rel => 0, :color1 => '0x333333'})
|
42
|
+
#
|
43
|
+
def embed_html(width=425, height=344, options={}, params={})
|
44
|
+
"<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>#{params.map{|k,v|"<param name='#{k}' value='#{v}'></param>"}.join}<embed src='#{embed_url}#{options.map {|k,v| "&#{k}=#{v}"}}' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' width='#{width}' height='#{height}' #{params.map {|k,v| "#{k}=#{v}"}.join(" ")}></embed></object>" if @details.noembed == false
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def flv
|
49
|
+
doc = URI::parse("http://www.youtube.com/get_video_info?&video_id=#{@video_id}").read
|
50
|
+
CGI::unescape(doc.split("&url_encoded_fmt_stream_map=")[1]).split("url=").each do |u|
|
51
|
+
u = CGI::unescape(u)
|
52
|
+
unless u.index("x-flv").nil?
|
53
|
+
return u.split("&quality").first
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def download_url
|
60
|
+
flv
|
61
|
+
end
|
62
|
+
|
63
|
+
def service
|
64
|
+
"Youtube"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require "xmlsimple"
|
5
|
+
require "youtube_it"
|
6
|
+
require "hpricot"
|
7
|
+
require "net/http"
|
8
|
+
require "json"
|
9
|
+
|
10
|
+
require "acts_as_unvlogable/flickr"
|
11
|
+
# Extensions
|
12
|
+
if defined?(ActiveSupport).nil?
|
13
|
+
require "acts_as_unvlogable/string_base"
|
14
|
+
require "acts_as_unvlogable/object_base"
|
15
|
+
end
|
16
|
+
require "acts_as_unvlogable/string_extend"
|
17
|
+
|
18
|
+
# Video classes
|
19
|
+
videolibs = File.join(File.dirname(__FILE__), "acts_as_unvlogable", "vg_*.rb")
|
20
|
+
Dir.glob(videolibs).each {|file| require file}
|
21
|
+
|
22
|
+
class UnvlogIt
|
23
|
+
|
24
|
+
def initialize(url=nil, options={})
|
25
|
+
@object = VideoFactory.new(url, options).load_service
|
26
|
+
end
|
27
|
+
|
28
|
+
def title
|
29
|
+
@object.title #rescue nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def thumbnail
|
33
|
+
@object.thumbnail rescue nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def duration # duration is in seconds
|
37
|
+
@object.duration rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def embed_url
|
41
|
+
@object.embed_url rescue nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def video_id
|
45
|
+
@object.video_id rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def embed_html(width=425, height=344, options={}, params={})
|
49
|
+
@object.embed_html(width, height, options, params) rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def flv
|
53
|
+
@object.flv #rescue nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def download_url
|
57
|
+
@object.download_url rescue nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def service
|
61
|
+
@object.service rescue nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def video_details(width=425, height=344)
|
65
|
+
{
|
66
|
+
:title => @object.title,
|
67
|
+
:thumbnail => @object.thumbnail,
|
68
|
+
:embed_url => @object.embed_url,
|
69
|
+
:embed_html => @object.embed_html(width, height),
|
70
|
+
:flv => @object.flv,
|
71
|
+
:download_url => @object.download_url,
|
72
|
+
:service => @object.service,
|
73
|
+
:duration => @object.duration
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
class VideoFactory
|
78
|
+
def initialize(url, options = {})
|
79
|
+
raise ArgumentError.new("We need a video url") if url.blank?
|
80
|
+
@url = url
|
81
|
+
@options = options
|
82
|
+
end
|
83
|
+
|
84
|
+
def load_service
|
85
|
+
@object = service_object
|
86
|
+
|
87
|
+
validate_embed(@object)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def validate_embed(object)
|
93
|
+
unless object.instance_variable_get("@details").nil? || !object.instance_variable_get("@details").respond_to?("noembed")
|
94
|
+
if object.instance_variable_get("@details").noembed
|
95
|
+
raise ArgumentError.new("Embedding disabled by request")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
object
|
99
|
+
end
|
100
|
+
|
101
|
+
def service_object
|
102
|
+
class_name = "vg_#{get_domain.downcase}".camelize
|
103
|
+
class_name.constantize.new(@url, @options)
|
104
|
+
rescue NameError
|
105
|
+
raise ArgumentError.new("Unsuported url or service. class: #{class_name}, url: #{@url}")
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_domain
|
109
|
+
host = URI::parse(@url).host.split(".")
|
110
|
+
unless host.size == 1
|
111
|
+
host[host.size-2]
|
112
|
+
else
|
113
|
+
host[0]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|