acts_as_unvlogable_2 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.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
|