acts_as_unvlogable_2 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.rb +117 -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/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,77 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Metacafe (www.metacafe.com)
|
3
|
+
# http://www.metacafe.com/watch/476621/experiments_with_the_myth_busters_with_diet_coke_and_mentos_dry/
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
|
7
|
+
class VgMetacafe
|
8
|
+
|
9
|
+
def initialize(url=nil, options={})
|
10
|
+
@url = url
|
11
|
+
@args = parse_url(url)
|
12
|
+
|
13
|
+
#is the video 'youtubed'?
|
14
|
+
@youtubed = @args[1].index("yt-").nil? ? false : true
|
15
|
+
@yt = @youtubed ? VgYoutube.new("http://www.youtube.com/watch?v=#{@args[1].sub('yt-', '')}") : nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def title
|
19
|
+
@youtubed ? @yt.title : (@args[2].humanize unless @args[2].blank?)
|
20
|
+
end
|
21
|
+
|
22
|
+
def thumbnail
|
23
|
+
"http://www.metacafe.com/thumb/#{@args[1]}.jpg"
|
24
|
+
end
|
25
|
+
|
26
|
+
def embed_url
|
27
|
+
"http://www.metacafe.com/fplayer/#{@args[1]}/#{@args[2]}.swf"
|
28
|
+
end
|
29
|
+
|
30
|
+
def embed_html(width=425, height=344, options={}, params={})
|
31
|
+
"<embed src='#{embed_url}' width='#{width}' height='#{height}' wmode='transparent' pluginspage='http://www.macromedia.com/go/getflashplayer' type='application/x-shockwave-flash'></embed>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def flv
|
35
|
+
if @youtubed
|
36
|
+
@yt.flv
|
37
|
+
else
|
38
|
+
params = Hash.new
|
39
|
+
open(self.embed_url) {|f|
|
40
|
+
params = CGI::parse(f.base_uri.request_uri.split("?")[1])
|
41
|
+
}
|
42
|
+
CGI::unescape "#{ params['mediaURL']}?__gda__=#{params['gdaKey']}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def duration
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def download_url
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def service
|
55
|
+
"Metacafe"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def parse_url(url)
|
61
|
+
uri = URI.parse(url)
|
62
|
+
path = uri.path
|
63
|
+
@args = ''
|
64
|
+
if path and path.split("/").size >=1
|
65
|
+
@args = path.split("/")
|
66
|
+
@args.delete("watch")
|
67
|
+
|
68
|
+
raise unless @args.size > 0
|
69
|
+
else
|
70
|
+
raise
|
71
|
+
end
|
72
|
+
@args
|
73
|
+
rescue
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for Myspace (vids.myspace.com)
|
3
|
+
# http://vids.myspace.com/index.cfm?fuseaction=vids.individual&VideoID=27111431
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
|
7
|
+
class VgMyspace
|
8
|
+
|
9
|
+
def initialize(url=nil, options={})
|
10
|
+
@url = url
|
11
|
+
@video_id = @url.query_param('videoid').blank? ? @url.query_param('VideoID') : @url.query_param('videoid')
|
12
|
+
res = Net::HTTP.get(URI.parse("http://mediaservices.myspace.com/services/rss.ashx?type=video&videoID=#{@video_id}"))
|
13
|
+
@feed = REXML::Document.new(res)
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
REXML::XPath.first(@feed, "//item/title")[0].to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def thumbnail
|
21
|
+
REXML::XPath.first(@feed, "//media:thumbnail").attributes['url']
|
22
|
+
end
|
23
|
+
|
24
|
+
def duration
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def embed_url
|
29
|
+
"http://lads.myspace.com/videos/vplayer.swf?m=#{REXML::XPath.first( @feed, "//myspace:itemID" )[0]}&v=2&type=video"
|
30
|
+
end
|
31
|
+
|
32
|
+
def embed_html(width=425, height=344, options={}, params={})
|
33
|
+
"<embed src='#{embed_url}' type='application/x-shockwave-flash' width='#{width}' height='#{height}'></embed>"
|
34
|
+
end
|
35
|
+
|
36
|
+
def flv
|
37
|
+
REXML::XPath.first(@feed, "//media:content").attributes['url']
|
38
|
+
end
|
39
|
+
|
40
|
+
def download_url
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def service
|
45
|
+
"Myspace"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# ----------------------------------------------
|
2
|
+
# Class for prostopleer.com
|
3
|
+
# http://prostopleer.com/tracks/401758bI6n
|
4
|
+
# ----------------------------------------------
|
5
|
+
|
6
|
+
require 'hpricot'
|
7
|
+
|
8
|
+
class VgProstopleer
|
9
|
+
|
10
|
+
attr_accessor :track_id
|
11
|
+
|
12
|
+
def initialize(url, options={})
|
13
|
+
@uri = URI.parse(url)
|
14
|
+
@track_id = @uri.path.match(/tracks\/([\w\d]+)/)[1]
|
15
|
+
@url = url
|
16
|
+
raise ArgumentError unless @track_id
|
17
|
+
end
|
18
|
+
|
19
|
+
def title
|
20
|
+
@title ||= [pp_data[:singer], pp_data[:song]].join(' - ')
|
21
|
+
end
|
22
|
+
|
23
|
+
def embed_html(width=425, height=344, options={}, params={})
|
24
|
+
return "<object width=\"#{width}\" height=\"#{height}\"><param name=\"movie\" value=\"http://embed.prostopleer.com/track?id=#{track_id}\"></param><embed src=\"http://embed.prostopleer.com/track?id=#{track_id}\" type=\"application/x-shockwave-flash\" width=\"#{width}\" height=\"#{height}\"></embed></object>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def service
|
28
|
+
"ProstoPleer"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def pp_data
|
33
|
+
return @pp_data if defined? @pp_data
|
34
|
+
hp = Hpricot.parse(Net::HTTP.get(@uri))
|
35
|
+
info = (hp/'li[@singer]').first
|
36
|
+
@pp_data = {
|
37
|
+
:singer => info['singer'], # artist name
|
38
|
+
:song => info['song'], # song title
|
39
|
+
:file_id => info['file_id'], # wtf
|
40
|
+
:link => info['link'], # same as @track_id
|
41
|
+
:duration => info['duration'], # duration of the song in seconds
|
42
|
+
:size => info['size'], # file size
|
43
|
+
:rate => info['rate'] # bit rate
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,64 @@
|
|
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
|
+
h = {"Content-Type" => "application/json"}
|
13
|
+
@page = Net::HTTP.start("engine.qik.com", "80") do |connection|
|
14
|
+
JSON.parse(connection.post("/api/jsonrpc?apikey=e53d41680124e6d0", {:method => "qik.stream.public_info", :params => [340982]}.to_json, h).body)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def title
|
19
|
+
@page[0]['title']
|
20
|
+
end
|
21
|
+
|
22
|
+
def thumbnail
|
23
|
+
@page[0]['large_thumbnail_url']
|
24
|
+
end
|
25
|
+
|
26
|
+
def embed_url
|
27
|
+
"http://qik.com/swfs/qikPlayer5.swf?streamID=#{@page[0]['embed_html'].split("streamID=")[1].split("&")[0]}&autoplay=false"
|
28
|
+
end
|
29
|
+
|
30
|
+
def embed_html(width=425, height=344, options={}, params={})
|
31
|
+
@page[0]['embed_html']
|
32
|
+
end
|
33
|
+
|
34
|
+
def flv
|
35
|
+
"http://media.qik.com/vod/flvs-play?assetId=#{@page[0]['embed_html'].split("streamID=")[1].split("&")[0]}&profile=flvs-normal"
|
36
|
+
end
|
37
|
+
|
38
|
+
def download_url
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def duration
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def service
|
47
|
+
"Qik"
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def parse_url(url)
|
53
|
+
video_id = nil
|
54
|
+
if url.split('#').size > 1
|
55
|
+
pieces = url.split(/#|=/)
|
56
|
+
hash = Hash[*pieces]
|
57
|
+
video_id = hash['v']
|
58
|
+
else
|
59
|
+
video_id = url.split("/")[4]
|
60
|
+
end
|
61
|
+
video_id
|
62
|
+
end
|
63
|
+
|
64
|
+
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={}, 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
|