downthetube 0.0.9 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/README +10 -50
- data/downthetube.gemspec +5 -5
- data/lib/play_list.rb +62 -32
- data/lib/video.rb +59 -32
- data/lib/youtube.rb +33 -6
- metadata +33 -54
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
downthetube (0.0.9)
|
5
|
+
gdata_19 (>= 1.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
gdata_19 (1.1.3)
|
12
|
+
rspec (2.7.0)
|
13
|
+
rspec-core (~> 2.7.0)
|
14
|
+
rspec-expectations (~> 2.7.0)
|
15
|
+
rspec-mocks (~> 2.7.0)
|
16
|
+
rspec-core (2.7.1)
|
17
|
+
rspec-expectations (2.7.0)
|
18
|
+
diff-lcs (~> 1.1.2)
|
19
|
+
rspec-mocks (2.7.0)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
downthetube!
|
26
|
+
rspec
|
data/README
CHANGED
@@ -16,61 +16,21 @@ require 'downthetube'
|
|
16
16
|
|
17
17
|
And then play. I've tried to make it do what you would expect:
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
irb(main):022:0> playlists.class
|
29
|
-
=> Array
|
30
|
-
|
31
|
-
irb(main):023:0> vids = playlists.first.videos 2
|
32
|
-
=> [#<Youtube::Video:0x7ff91cf63098 @xml=<entry gd:etag='W/"AkQDQ3s-fCp7ImA9WhZUEkk."'> ... </>>, #<Youtube::Video:0x7ff91cf59bd8 @xml=<entry gd:etag='W/"AkQDQ3s-fCp7ImA9WhZUEkk."'> ... </>>]
|
33
|
-
|
34
|
-
irb(main):024:0> vid = vids.last
|
35
|
-
=> #<Youtube::Video:0x7ff91cf59bd8 @xml=<entry gd:etag='W/"AkQDQ3s-fCp7ImA9WhZUEkk."'> ... </>>
|
36
|
-
|
37
|
-
irb(main):025:0> vid.title
|
38
|
-
=> "Mestre Jogo De Dentro e Mestra Tisza,Ilheus 2008"
|
39
|
-
|
40
|
-
irb(main):026:0> vid.description
|
41
|
-
=> "Roda de fim de ano na praca de Ilheus 2008,gravado por CM Denis."
|
42
|
-
|
43
|
-
irb(main):027:0> vid.url
|
44
|
-
=> "http://www.youtube.com/watch?v=4I_4JgV-y8s"
|
45
|
-
|
46
|
-
irb(main):028:0> vid.thumbnail :large
|
47
|
-
=> "http://i.ytimg.com/vi/4I_4JgV-y8s/hqdefault.jpg"
|
48
|
-
|
49
|
-
irb(main):029:0> itapua = Youtube::Video.new "5Pg6a3TbF68"
|
50
|
-
=> #<Youtube::Video:0x7ff91cf097a0 @url="http://gdata.youtube.com/feeds/api/videos/5Pg6a3TbF68?v=2">
|
51
|
-
|
52
|
-
irb(main):030:0> itapua.thumbnail
|
53
|
-
=> "http://i.ytimg.com/vi/5Pg6a3TbF68/default.jpg"
|
54
|
-
|
55
|
-
irb(main):031:0> itapua.title
|
56
|
-
=> "Itapuã e Gibi - Roda Lavradio"
|
57
|
-
|
58
|
-
irb(main):032:0> itapua.url
|
59
|
-
=> "http://www.youtube.com/watch?v=5Pg6a3TbF68"
|
60
|
-
|
61
|
-
You can also get the video object to return a hash of its important info by calling to_h:
|
62
|
-
|
63
|
-
irb(main):009:0> vid = Youtube::Video.new "QSiGw6noULA"
|
64
|
-
=> #<Youtube::Video:0x7fec0cbc9300 @url="http://gdata.youtube.com/feeds/api/videos/QSiGw6noULA?v=2">
|
65
|
-
|
66
|
-
irb(main):010:0> vid.to_h
|
67
|
-
=> {:title=>"Semente do Jogo de Angola - Tradição - Parte 1", :small_thumbnail=>"http://i.ytimg.com/vi/QSiGw6noULA/default.jpg", :description=>"Video produzido pelo Grupo de capoeira Semente do Jogo de Angola - Mestre Jogo de Dentro\nwww.sementedojogodeangola.org.br", :large_thumbnail=>"http://i.ytimg.com/vi/QSiGw6noULA/hqdefault.jpg", :uploader=>"valmirmauricio", :duration=>"120", :url=>"http://www.youtube.com/watch?v=QSiGw6noULA", :id=>"QSiGw6noULA"}
|
19
|
+
Youtube::Playlist.new("76E01802262A6694")
|
20
|
+
playlists = Youtube.playlists_for "stephensam"
|
21
|
+
playlists.first.title # "Capoeira Angola"
|
22
|
+
vids = playlists.first.videos 2
|
23
|
+
vid = vids.last
|
24
|
+
vid.title # "Mestre Jogo De Dentro e Mestra Tisza,Ilheus 2008"
|
25
|
+
vid.description # "Roda de fim de ano na praca de Ilheus 2008,gravado por CM Denis."
|
26
|
+
vid.url # "http://www.youtube.com/watch?v=4I_4JgV-y8s"
|
27
|
+
vid.thumbnail(:large) # "http://i.ytimg.com/vi/4I_4JgV-y8s/hqdefault.jpg"
|
68
28
|
|
69
29
|
LICENSE:
|
70
30
|
|
71
31
|
(The MIT License)
|
72
32
|
|
73
|
-
Copyright ©
|
33
|
+
Copyright © 2011 Mike Williamson
|
74
34
|
|
75
35
|
|
76
36
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
data/downthetube.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
specification = Gem::Specification.new do |spec|
|
2
2
|
# Descriptive and source information for this gem.
|
3
3
|
spec.name = "downthetube"
|
4
|
-
spec.version = "
|
4
|
+
spec.version = "1.0"
|
5
5
|
spec.description = "A library to make downloading playlists and videos from Youtube less nasty."
|
6
6
|
spec.summary = "Downloads playlists and videos from Youtube."
|
7
7
|
spec.author = "Mike Williamson"
|
8
8
|
spec.email = "blessedbyvirtuosity@gmail.com"
|
9
|
-
spec.homepage = ""
|
9
|
+
spec.homepage = "http://mikewilliamson.wordpress.com"
|
10
10
|
require 'rake'
|
11
|
-
spec.files = %w(README lib/downthetube.rb lib/youtube.rb lib/video.rb lib/play_list.rb downthetube.gemspec)
|
12
|
-
spec.has_rdoc =
|
11
|
+
spec.files = %w(README CHANGELOG.md Gemfile Gemfile.lock lib/downthetube.rb lib/youtube.rb lib/video.rb lib/play_list.rb downthetube.gemspec)
|
12
|
+
spec.has_rdoc = true
|
13
13
|
spec.add_dependency("gdata_19", ">= 1.0.0")
|
14
14
|
spec.extra_rdoc_files = ["README"]
|
15
15
|
spec.require_path = ["lib"]
|
16
|
-
|
16
|
+
spec.test_files = ["spec"]
|
17
17
|
end
|
18
18
|
|
data/lib/play_list.rb
CHANGED
@@ -1,7 +1,21 @@
|
|
1
1
|
module Youtube
|
2
|
-
|
3
|
-
|
2
|
+
##
|
3
|
+
# Represents an individual playlist. A single Playlist object can be
|
4
|
+
# instantiated with a playlist id. The id can be found in the url
|
5
|
+
# and a few other places: gdata.youtube.com/feeds/api/playlists/<b>AAE42E282C4AD007</b>?v=2
|
6
|
+
#
|
7
|
+
# === Example
|
8
|
+
# playlist = Youtube::Playlist.new "AAE42E282C4AD007"
|
9
|
+
# playlist.title # "Mestre Jogo de Dentro & Seus Alunos"
|
10
|
+
# playlist.id # "AAE42E282C4AD007"
|
11
|
+
# playlist.author # "stephensam"
|
12
|
+
# playlist.url #"\http://gdata.youtube.com/feeds/api/playlists/AAE42E282C4AD007"
|
13
|
+
# videos = playlist.videos(3) # returns 3 videos
|
4
14
|
|
15
|
+
class Playlist
|
16
|
+
#--
|
17
|
+
# TODO reduce the duplication between this and the video class
|
18
|
+
#++
|
5
19
|
#include Naming from ActiveRecord if its here.
|
6
20
|
begin
|
7
21
|
self.extend ActiveModel::Naming
|
@@ -9,54 +23,45 @@ module Youtube
|
|
9
23
|
#do nothing
|
10
24
|
end
|
11
25
|
|
12
|
-
|
13
|
-
|
26
|
+
##
|
27
|
+
# Instantiate individual instances of this class with a
|
28
|
+
# YouTube id.
|
29
|
+
|
14
30
|
def initialize entry
|
15
31
|
|
16
32
|
define_attrs
|
17
33
|
|
18
34
|
if ((entry) && (entry.class == REXML::Element))
|
19
35
|
@xml = entry
|
36
|
+
@id = /\w{16}/.match(@xml.elements['id'].text).to_s
|
20
37
|
populate_attrs
|
21
38
|
|
22
39
|
elsif((entry.class==String)&&(entry =~ /\w{16}/))
|
23
40
|
@url = "http://gdata.youtube.com/feeds/api/playlists/#{entry}"
|
41
|
+
@id = entry.to_s
|
24
42
|
else
|
25
43
|
raise "The Playlist class did not understand the parameter it was initialized with."
|
26
44
|
end
|
27
45
|
end
|
28
46
|
|
29
|
-
def populate_attrs
|
30
|
-
@client ||= GData::Client::YouTube.new
|
31
|
-
@xml ||= @client.get(self.url).to_xml
|
32
47
|
|
33
|
-
@id = @xml.get_text('yt:playlistId')
|
34
|
-
@title = @xml.get_text('title')
|
35
|
-
@author = @xml.get_text('author/name')
|
36
|
-
@xml.each_element_with_attribute('src'){|a| @url = a.attribute('src').to_s }
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
def define_attrs
|
41
|
-
[:title, :author, :id].each do |attr|
|
42
|
-
method_def = <<-EOM
|
43
|
-
def #{attr}
|
44
|
-
if @#{attr}
|
45
|
-
@#{attr}
|
46
|
-
else
|
47
|
-
populate_attrs
|
48
|
-
@#{attr}
|
49
|
-
end
|
50
|
-
end
|
51
|
-
EOM
|
52
|
-
Playlist.class_eval method_def
|
53
|
-
end
|
54
|
-
end
|
55
48
|
|
56
|
-
def self.name
|
49
|
+
def self.name # :nodoc:
|
57
50
|
"Playlist"
|
58
51
|
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns the gdata api url of the playlist.
|
55
|
+
# If you want the human friendly url pass in :human as an argument.
|
56
|
+
def url type = :api
|
57
|
+
type == :human ? @human_url : @url
|
58
|
+
end
|
59
59
|
|
60
|
+
##
|
61
|
+
# This is the main raison d'être of the Playlist class:
|
62
|
+
# to retrieve a set of videos. If you want/need to you can
|
63
|
+
# pass a integer like 5 to limit the number of videos returned.
|
64
|
+
#
|
60
65
|
def videos limit=nil
|
61
66
|
|
62
67
|
case
|
@@ -77,6 +82,31 @@ module Youtube
|
|
77
82
|
|
78
83
|
private
|
79
84
|
|
85
|
+
def populate_attrs # :nodoc:
|
86
|
+
@client ||= GData::Client::YouTube.new
|
87
|
+
@xml ||= @client.get(self.url).to_xml
|
88
|
+
|
89
|
+
@title = @xml.elements['title'].text
|
90
|
+
@author = @xml.elements['author/name'].text
|
91
|
+
@human_url = @xml.elements['link'].attribute('href').value
|
92
|
+
@url = @xml.elements.collect('link'){|l| l}[1].attribute('href').value
|
93
|
+
end
|
94
|
+
|
95
|
+
def define_attrs # :nodoc:
|
96
|
+
[:title, :author, :id].each do |attr|
|
97
|
+
method_def = <<-EOM
|
98
|
+
def #{attr}
|
99
|
+
if @#{attr}
|
100
|
+
@#{attr}.to_s
|
101
|
+
else
|
102
|
+
populate_attrs
|
103
|
+
@#{attr}.to_s
|
104
|
+
end
|
105
|
+
end
|
106
|
+
EOM
|
107
|
+
Playlist.class_eval method_def
|
108
|
+
end
|
109
|
+
end
|
80
110
|
def get_videos number=nil
|
81
111
|
@client ||= GData::Client::YouTube.new
|
82
112
|
feed = @client.get(self.url).to_xml
|
@@ -85,13 +115,13 @@ module Youtube
|
|
85
115
|
if number
|
86
116
|
feed.elements.each('entry') do |entry|
|
87
117
|
if counter <= number
|
88
|
-
@videos<< Video.new(entry)
|
118
|
+
@videos<< Youtube::Video.new(entry)
|
89
119
|
counter += 1
|
90
120
|
end
|
91
121
|
end
|
92
122
|
else
|
93
123
|
feed.elements.each('entry') do |entry|
|
94
|
-
@videos<< Video.new(entry)
|
124
|
+
@videos<< Youtube::Video.new(entry)
|
95
125
|
end
|
96
126
|
end
|
97
127
|
end
|
data/lib/video.rb
CHANGED
@@ -1,6 +1,20 @@
|
|
1
|
+
require 'open-uri'
|
1
2
|
module Youtube
|
3
|
+
##
|
4
|
+
# The video class rather unsurprisingly represents an individual
|
5
|
+
# YouTube video.
|
6
|
+
#
|
7
|
+
# === Example
|
8
|
+
# video = playlist.videos.first
|
9
|
+
# video.title # "Semeando 2010 - Mestre Jogo de Dentro"
|
10
|
+
# video.duration #returns number of seconds: "93"
|
11
|
+
# video.description # "2010 o VII Encontro Internacional de Capoeira Angola... "
|
12
|
+
# video.thumbnail(:large) # "\http://i.ytimg.com/vi/4YMMWt2808U/hqdefault.jpg"
|
13
|
+
# video.id # "4YMMWt2808U"
|
14
|
+
# video.uploader # "micheldezen"
|
15
|
+
# video.url # "http://www.youtube.com/watch?v=4YMMWt2808U"
|
16
|
+
|
2
17
|
class Video
|
3
|
-
require 'gdata'
|
4
18
|
#include Naming from ActiveRecord if its here.
|
5
19
|
begin
|
6
20
|
self.extend ActiveModel::Naming
|
@@ -8,8 +22,6 @@ module Youtube
|
|
8
22
|
#do nothing
|
9
23
|
end
|
10
24
|
|
11
|
-
attr_reader :url
|
12
|
-
|
13
25
|
def initialize entry
|
14
26
|
|
15
27
|
define_attrs
|
@@ -23,27 +35,22 @@ module Youtube
|
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@#{attr}
|
32
|
-
else
|
33
|
-
populate_attrs
|
34
|
-
@#{attr}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
EOM
|
38
|
-
Video.class_eval method_def
|
39
|
-
end
|
38
|
+
##
|
39
|
+
# Returns the url of the video
|
40
|
+
def url
|
41
|
+
populate_attrs unless @url
|
42
|
+
@url
|
40
43
|
end
|
41
44
|
|
42
45
|
|
43
|
-
def self.name
|
46
|
+
def self.name # :nodoc:
|
44
47
|
"Video"
|
45
48
|
end
|
46
49
|
|
50
|
+
##
|
51
|
+
# Returns the url of the thumbnail image for the video.
|
52
|
+
# If you want the large thumbnail pass :large as a parameter.
|
53
|
+
|
47
54
|
def thumbnail size=:small
|
48
55
|
populate_attrs unless @large_thumbnail && @small_thumbnail
|
49
56
|
if size == :large
|
@@ -52,7 +59,41 @@ module Youtube
|
|
52
59
|
@small_thumbnail
|
53
60
|
end
|
54
61
|
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Returns that the video was instantiated with.
|
65
|
+
def to_xml
|
66
|
+
@xml.to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Returns a hash with the video attributes in it.
|
71
|
+
def to_h
|
72
|
+
populate_attrs unless @xml
|
73
|
+
h = {}
|
74
|
+
instance_variables.each do |var|
|
75
|
+
h[var.to_s.gsub('@', '').to_sym]= self.instance_variable_get(var.to_sym).to_s unless [:@client, :@xml].include? var
|
76
|
+
end
|
77
|
+
h
|
78
|
+
end
|
55
79
|
|
80
|
+
private
|
81
|
+
|
82
|
+
def define_attrs
|
83
|
+
[:title, :description, :id, :uploader, :duration].each do |attr|
|
84
|
+
method_def = <<-EOM
|
85
|
+
def #{attr}
|
86
|
+
if @#{attr}
|
87
|
+
@#{attr}.to_s
|
88
|
+
else
|
89
|
+
populate_attrs
|
90
|
+
@#{attr}.to_s
|
91
|
+
end
|
92
|
+
end
|
93
|
+
EOM
|
94
|
+
Video.class_eval method_def
|
95
|
+
end
|
96
|
+
end
|
56
97
|
|
57
98
|
def populate_attrs
|
58
99
|
|
@@ -77,20 +118,6 @@ module Youtube
|
|
77
118
|
end
|
78
119
|
end
|
79
120
|
end
|
80
|
-
|
81
|
-
def to_xml
|
82
|
-
@xml.to_s
|
83
|
-
end
|
84
|
-
|
85
|
-
def to_h
|
86
|
-
populate_attrs unless @xml
|
87
|
-
h = {}
|
88
|
-
instance_variables.each do |var|
|
89
|
-
h[var.gsub('@', '').to_sym]= self.instance_variable_get(var.to_sym).to_s unless %w( @client @xml ).include? var
|
90
|
-
end
|
91
|
-
h
|
92
|
-
end
|
93
|
-
|
94
121
|
end
|
95
122
|
end
|
96
123
|
|
data/lib/youtube.rb
CHANGED
@@ -2,17 +2,44 @@ module Youtube
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'gdata'
|
4
4
|
require 'rexml/document'
|
5
|
+
|
6
|
+
##
|
7
|
+
# This is the main entry point. It accepts a YouTube
|
8
|
+
# username such as <tt>stephensam</tt> and returning an array
|
9
|
+
# of playlists belonging to that user.
|
10
|
+
#
|
11
|
+
# === Example
|
12
|
+
# playlists = Youtube.playlists_for("stephensam") # returns playlists for user <tt>stephensam</tt>
|
13
|
+
|
14
|
+
|
5
15
|
def Youtube.playlists_for user
|
6
|
-
|
7
|
-
feed =
|
16
|
+
youtube = YT.new()
|
17
|
+
feed = youtube.feed_for(user)
|
8
18
|
playlists = []
|
9
19
|
feed.elements.each('entry') do |entry|
|
10
20
|
playlists<< Playlist.new(entry)
|
11
21
|
end
|
12
22
|
playlists
|
13
23
|
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
24
|
+
|
25
|
+
|
26
|
+
class RetrievalError < StandardError
|
27
|
+
end
|
28
|
+
|
29
|
+
class YT # :nodoc: all
|
30
|
+
|
31
|
+
def feed_for user
|
32
|
+
client = get_client
|
33
|
+
begin
|
34
|
+
response = client.get("http://gdata.youtube.com/feeds/api/users/#{user}/playlists?v=2")
|
35
|
+
response.to_xml
|
36
|
+
rescue Exception => e
|
37
|
+
raise Youtube::RetrievalError.new(e.message)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_client
|
42
|
+
client = GData::Client::YouTube.new
|
43
|
+
end
|
44
|
+
end
|
18
45
|
end
|
metadata
CHANGED
@@ -1,87 +1,66 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: downthetube
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 9
|
10
|
-
version: 0.0.9
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Mike Williamson
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-11-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: gdata_19
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &21505680 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 23
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 0
|
33
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 1.0.0
|
35
22
|
type: :runtime
|
36
|
-
|
37
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *21505680
|
25
|
+
description: A library to make downloading playlists and videos from Youtube less
|
26
|
+
nasty.
|
38
27
|
email: blessedbyvirtuosity@gmail.com
|
39
28
|
executables: []
|
40
|
-
|
41
29
|
extensions: []
|
42
|
-
|
43
|
-
extra_rdoc_files:
|
30
|
+
extra_rdoc_files:
|
44
31
|
- README
|
45
|
-
files:
|
32
|
+
files:
|
46
33
|
- README
|
34
|
+
- CHANGELOG.md
|
35
|
+
- Gemfile
|
36
|
+
- Gemfile.lock
|
47
37
|
- lib/downthetube.rb
|
48
38
|
- lib/youtube.rb
|
49
39
|
- lib/video.rb
|
50
40
|
- lib/play_list.rb
|
51
41
|
- downthetube.gemspec
|
52
|
-
|
53
|
-
homepage: ""
|
42
|
+
homepage: http://mikewilliamson.wordpress.com
|
54
43
|
licenses: []
|
55
|
-
|
56
44
|
post_install_message:
|
57
45
|
rdoc_options: []
|
58
|
-
|
59
|
-
require_paths:
|
46
|
+
require_paths:
|
60
47
|
- - lib
|
61
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
49
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
|
67
|
-
|
68
|
-
- 0
|
69
|
-
version: "0"
|
70
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
55
|
none: false
|
72
|
-
requirements:
|
73
|
-
- -
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
segments:
|
77
|
-
- 0
|
78
|
-
version: "0"
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
79
60
|
requirements: []
|
80
|
-
|
81
61
|
rubyforge_project:
|
82
|
-
rubygems_version: 1.
|
62
|
+
rubygems_version: 1.8.10
|
83
63
|
signing_key:
|
84
64
|
specification_version: 3
|
85
65
|
summary: Downloads playlists and videos from Youtube.
|
86
66
|
test_files: []
|
87
|
-
|