youtube_it 2.1.4 → 2.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +57 -5
- data/lib/youtube_it.rb +3 -3
- data/lib/youtube_it/chain_io.rb +1 -1
- data/lib/youtube_it/client.rb +48 -11
- data/lib/youtube_it/model/comment.rb +3 -3
- data/lib/youtube_it/model/playlist.rb +1 -1
- data/lib/youtube_it/model/user.rb +7 -0
- data/lib/youtube_it/model/video.rb +37 -4
- data/lib/youtube_it/parser.rb +269 -218
- data/lib/youtube_it/request/base_search.rb +4 -0
- data/lib/youtube_it/request/video_search.rb +20 -4
- data/lib/youtube_it/request/video_upload.rb +166 -70
- data/lib/youtube_it/version.rb +1 -1
- data/youtube_it.gemspec +20 -91
- metadata +72 -134
- data/Gemfile +0 -12
- data/Gemfile.lock +0 -43
- data/Manifest.txt +0 -37
- data/Rakefile +0 -58
- data/VERSION +0 -1
- data/test/files/recorded_response.xml +0 -1
- data/test/files/youtube_video_response.xml +0 -53
- data/test/helper.rb +0 -9
- data/test/test.mov +0 -0
- data/test/test_chain_io.rb +0 -63
- data/test/test_client.rb +0 -454
- data/test/test_field_search.rb +0 -48
- data/test/test_video.rb +0 -48
- data/test/test_video_feed_parser.rb +0 -271
- data/test/test_video_search.rb +0 -147
data/README.rdoc
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
== YOUTUBE_IT {<img src="https://secure.travis-ci.org/kylejginavan/youtube_it.png"/>}[http://travis-ci.org/kylejginavan/youtube_it]
|
2
|
+
|
1
3
|
== DONATION
|
2
4
|
|
3
5
|
YOUTUBE_IT is developed by many contributors who are passioned about opensource projects
|
@@ -58,6 +60,12 @@ If your access token is still valid (be careful, access tokens may only be valid
|
|
58
60
|
|
59
61
|
$ client.refresh_access_token!
|
60
62
|
|
63
|
+
== PROFILES
|
64
|
+
you can use multiple profiles in the same account like that
|
65
|
+
|
66
|
+
$ profiles = client.profiles(['username1','username2'])
|
67
|
+
$ profiles['username1'].username, "username1"
|
68
|
+
|
61
69
|
== VIDEO QUERIES
|
62
70
|
|
63
71
|
Note: Each type of client enables searching capabilities.
|
@@ -84,6 +92,16 @@ Advanced Queries (with boolean operators OR (either), AND (include), NOT (exclud
|
|
84
92
|
$ client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] }, :tags => { :include => ['football'], :exclude => ['soccer'] })
|
85
93
|
|
86
94
|
|
95
|
+
Custom Query Params
|
96
|
+
You can use custom query params like that:
|
97
|
+
|
98
|
+
$ client.videos_by(:query => "penguin", :safe_search => "strict")
|
99
|
+
$ client.videos_by(:query => "penguin", :duration => "long")
|
100
|
+
$ client.videos_by(:query => "penguin", :hd => "true")
|
101
|
+
$ client.videos_by(:query => "penguin", :region => "AR")
|
102
|
+
|
103
|
+
you can see more options here https://developers.google.com/youtube/2.0/reference#yt_format
|
104
|
+
|
87
105
|
Fields Parameter(experimental features):
|
88
106
|
Return videos more than 1000 views
|
89
107
|
$ client.videos_by(:fields => {:view_count => "1000"})
|
@@ -106,6 +124,10 @@ Upload Video:
|
|
106
124
|
Upload Video With A Developer Tag (Note the tags are not immediately available):
|
107
125
|
$ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :dev_tag => 'tagdev')
|
108
126
|
|
127
|
+
Upload Private Video:
|
128
|
+
$ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :private => true)
|
129
|
+
|
130
|
+
|
109
131
|
Update Video:
|
110
132
|
$ client.video_update("FQK1URcxmb4", :title => "new test",:description => 'new description', :category => 'People',:keywords => %w[cool blah test])
|
111
133
|
|
@@ -117,7 +139,7 @@ My Videos:
|
|
117
139
|
|
118
140
|
My Video:
|
119
141
|
$ client.my_video(video_id)
|
120
|
-
|
142
|
+
|
121
143
|
Profile Details:
|
122
144
|
$ client.profile(user) #default: current user
|
123
145
|
|
@@ -127,6 +149,12 @@ List Comments:
|
|
127
149
|
Add A Comment:
|
128
150
|
$ client.add_comment(video_id, "test comment!")
|
129
151
|
|
152
|
+
Add A Reply Comment:
|
153
|
+
$ client.add_comment(video_id, "test reply!", :reply_to => another_comment)
|
154
|
+
|
155
|
+
Delete A Comment:
|
156
|
+
$ client.delete_comment(video_id, comment_id)
|
157
|
+
|
130
158
|
List Favorites:
|
131
159
|
$ client.favorites(user) # default: current user
|
132
160
|
|
@@ -134,7 +162,7 @@ Add Favorite:
|
|
134
162
|
$ client.add_favorite(video_id)
|
135
163
|
|
136
164
|
Delete Favorite:
|
137
|
-
$ client.delete_favorite(
|
165
|
+
$ client.delete_favorite(favorite_entry_id)
|
138
166
|
|
139
167
|
Like A Video:
|
140
168
|
$ client.like_video(video_id)
|
@@ -151,8 +179,17 @@ Subscribe To A Channel:
|
|
151
179
|
Unsubscribe To A Channel:
|
152
180
|
$ client.unsubscribe_channel(subscription_id)
|
153
181
|
|
182
|
+
List New Subscription Videos:
|
183
|
+
$ client.new_subscription_videos(user) # default: current user
|
184
|
+
|
154
185
|
List Playlists:
|
155
|
-
$ client.playlists(user) # default: current user
|
186
|
+
$ client.playlists(user, order_by) # default: current user, position
|
187
|
+
|
188
|
+
for example you can get the videos of your playlist ordered by title
|
189
|
+
|
190
|
+
$ client.playlists(user, "title")
|
191
|
+
|
192
|
+
you can see more about options for order_by here: https://developers.google.com/youtube/2.0/reference#orderbysp
|
156
193
|
|
157
194
|
Select Playlist:
|
158
195
|
$ client.playlist(playlist_id)
|
@@ -173,6 +210,17 @@ Add Video To Playlist:
|
|
173
210
|
Remove Video From Playlist:
|
174
211
|
$ client.remove_video_from_playlist(playlist_id, playlist_entry_id)
|
175
212
|
|
213
|
+
Select All Videos From your Watch Later Playlist:
|
214
|
+
$ watcher_later = client.watcherlater(user) #default: current user
|
215
|
+
$ watcher_later.videos
|
216
|
+
|
217
|
+
Add Video To Watcher Later Playlist:
|
218
|
+
$ client.add_video_to_watchlater(video_id)
|
219
|
+
|
220
|
+
Remove Video From Watch Later Playlist:
|
221
|
+
$ client.remove_video_from_watchlater(watchlater_entry_id)
|
222
|
+
|
223
|
+
|
176
224
|
List Related Videos
|
177
225
|
$ video = client.video_by("https://www.youtube.com/watch?v=QsbmrCtiEUU&feature=player_embedded")
|
178
226
|
$ video.related.videos
|
@@ -207,7 +255,11 @@ List Response Videos
|
|
207
255
|
|
208
256
|
client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :comment => "denied")
|
209
257
|
|
210
|
-
|
258
|
+
== User Activity
|
259
|
+
You can get user activity with the followings params:
|
260
|
+
|
261
|
+
$ client.activity(user) #default current user
|
262
|
+
|
211
263
|
== Video Upload From Browser:
|
212
264
|
|
213
265
|
When uploading a video from your browser you need make a form upload with the followings params:
|
@@ -241,7 +293,7 @@ Note: you can specify width or just use the default of 1280.
|
|
241
293
|
Now you can embed videos without use flash using html5, usefull for mobiles that not support flash but has html5 browser
|
242
294
|
|
243
295
|
You can specify these options
|
244
|
-
$ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1'})
|
296
|
+
$ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1', :url_params => {:option_one => "value", :option_two => "value"}})
|
245
297
|
|
246
298
|
or just use with default options
|
247
299
|
$ video.embed_html5 #default: width: 425, height: 350, frameborder: 0
|
data/lib/youtube_it.rb
CHANGED
@@ -2,9 +2,10 @@ require 'logger'
|
|
2
2
|
require 'open-uri'
|
3
3
|
require 'net/https'
|
4
4
|
require 'digest/md5'
|
5
|
-
require '
|
5
|
+
require 'nokogiri'
|
6
6
|
require 'builder'
|
7
7
|
require 'oauth'
|
8
|
+
require 'oauth2'
|
8
9
|
require 'faraday'
|
9
10
|
|
10
11
|
class YouTubeIt
|
@@ -19,8 +20,7 @@ class YouTubeIt
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.esc(s) #:nodoc:
|
22
|
-
|
23
|
-
URI.encode(s.to_s.tr(' ','+'))
|
23
|
+
CGI.escape(s.to_s)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Set the logger for the library
|
data/lib/youtube_it/chain_io.rb
CHANGED
data/lib/youtube_it/client.rb
CHANGED
@@ -38,7 +38,7 @@ class YouTubeIt
|
|
38
38
|
#
|
39
39
|
# If fetching videos by tags, categories, query:
|
40
40
|
# params<Hash>:: Accepts the keys :tags, :categories, :query, :order_by,
|
41
|
-
# :author, :
|
41
|
+
# :author, :safe_search, :response_format, :video_format, :page (default is 1),
|
42
42
|
# and :per_page(default is 25)
|
43
43
|
#
|
44
44
|
# options<Hash>:: Not used. (Optional)
|
@@ -122,8 +122,12 @@ class YouTubeIt
|
|
122
122
|
client.get_upload_token(options, nexturl)
|
123
123
|
end
|
124
124
|
|
125
|
-
def add_comment(video_id, comment)
|
126
|
-
client.add_comment(video_id, comment)
|
125
|
+
def add_comment(video_id, comment, opts = {})
|
126
|
+
client.add_comment(video_id, comment, opts)
|
127
|
+
end
|
128
|
+
|
129
|
+
def delete_comment(video_id, comment_id)
|
130
|
+
client.delete_comment(video_id, comment_id)
|
127
131
|
end
|
128
132
|
|
129
133
|
# opts is converted to get params and appended to comments gdata api url
|
@@ -148,14 +152,30 @@ class YouTubeIt
|
|
148
152
|
def profile(user = nil)
|
149
153
|
client.profile(user)
|
150
154
|
end
|
155
|
+
|
156
|
+
def profiles(*users)
|
157
|
+
client.profiles(*users)
|
158
|
+
end
|
151
159
|
|
152
160
|
# Fetches a user's activity feed.
|
153
161
|
def activity(user = nil, opts = {})
|
154
162
|
client.get_activity(user, opts)
|
155
163
|
end
|
156
164
|
|
157
|
-
def
|
158
|
-
client.
|
165
|
+
def watchlater(user = nil)
|
166
|
+
client.watchlater(user)
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_video_to_watchlater(video_id)
|
170
|
+
client.add_video_to_watchlater(video_id)
|
171
|
+
end
|
172
|
+
|
173
|
+
def delete_video_from_watchlater(video_id)
|
174
|
+
client.delete_video_from_watchlater(video_id)
|
175
|
+
end
|
176
|
+
|
177
|
+
def playlist(playlist_id, order_by = :position)
|
178
|
+
client.playlist(playlist_id, order_by)
|
159
179
|
end
|
160
180
|
|
161
181
|
def playlists(user = nil)
|
@@ -228,20 +248,30 @@ class YouTubeIt
|
|
228
248
|
client.get_my_videos(opts)
|
229
249
|
end
|
230
250
|
|
231
|
-
#
|
251
|
+
# Gets all of the user's contacts/friends.
|
232
252
|
def my_contacts(opts = {})
|
233
253
|
client.get_my_contacts(opts)
|
234
254
|
end
|
235
255
|
|
236
|
-
# Send
|
256
|
+
# Send video message
|
237
257
|
def send_message(opts = {})
|
238
258
|
client.send_message(opts)
|
239
259
|
end
|
240
260
|
|
241
|
-
#
|
261
|
+
# Gets all of the user's messages/inbox.
|
242
262
|
def my_messages(opts = {})
|
243
263
|
client.get_my_messages(opts)
|
244
264
|
end
|
265
|
+
|
266
|
+
# Gets the user's watch history
|
267
|
+
def watch_history
|
268
|
+
client.get_watch_history
|
269
|
+
end
|
270
|
+
|
271
|
+
# Gets new subscription videos
|
272
|
+
def new_subscription_videos(user_id = nil)
|
273
|
+
client.new_subscription_videos(user_id)
|
274
|
+
end
|
245
275
|
|
246
276
|
private
|
247
277
|
|
@@ -388,7 +418,7 @@ class YouTubeIt
|
|
388
418
|
response_code = profile.code.to_i
|
389
419
|
|
390
420
|
if response_code/10 == 20 # success
|
391
|
-
|
421
|
+
Nokogiri::XML(profile.body).at("entry/author/name").text
|
392
422
|
elsif response_code == 403 || response_code == 401 # auth failure
|
393
423
|
raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
|
394
424
|
else
|
@@ -413,6 +443,7 @@ class YouTubeIt
|
|
413
443
|
@client_refresh_token = options[:client_refresh_token]
|
414
444
|
@client_token_expires_at = options[:client_token_expires_at]
|
415
445
|
@dev_key = options[:dev_key]
|
446
|
+
@legacy_debug_flag = options[:debug]
|
416
447
|
end
|
417
448
|
|
418
449
|
def oauth_client
|
@@ -427,7 +458,13 @@ class YouTubeIt
|
|
427
458
|
end
|
428
459
|
|
429
460
|
def refresh_access_token!
|
430
|
-
|
461
|
+
new_access_token = access_token.refresh!
|
462
|
+
require 'thread' unless Thread.respond_to?(:exclusive)
|
463
|
+
Thread.exclusive do
|
464
|
+
@access_token = new_access_token
|
465
|
+
@client = nil
|
466
|
+
end
|
467
|
+
@access_token
|
431
468
|
end
|
432
469
|
|
433
470
|
def current_user
|
@@ -435,7 +472,7 @@ class YouTubeIt
|
|
435
472
|
response_code = profile.status
|
436
473
|
|
437
474
|
if response_code/10 == 20 # success
|
438
|
-
|
475
|
+
Nokogiri::XML(profile.body).at("entry/author/name").text
|
439
476
|
elsif response_code == 403 || response_code == 401 # auth failure
|
440
477
|
raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
|
441
478
|
else
|
@@ -1,14 +1,14 @@
|
|
1
1
|
class YouTubeIt
|
2
2
|
module Model
|
3
3
|
class Comment < YouTubeIt::Record
|
4
|
-
attr_reader :content, :published, :title, :updated, :url
|
4
|
+
attr_reader :content, :published, :title, :updated, :url, :reply_to
|
5
5
|
|
6
6
|
# YouTubeIt::Model::Author:: Information about the YouTube user who owns a piece of video content.
|
7
7
|
attr_reader :author
|
8
|
-
|
8
|
+
|
9
9
|
# unique ID of the comment.
|
10
10
|
def unique_id
|
11
|
-
url.split("
|
11
|
+
url.split(":").last
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -3,7 +3,7 @@ class YouTubeIt
|
|
3
3
|
class Playlist < YouTubeIt::Record
|
4
4
|
attr_reader :title, :description, :summary, :playlist_id, :xml, :published, :response_code
|
5
5
|
def videos
|
6
|
-
YouTubeIt::Parser::VideosFeedParser.new(
|
6
|
+
YouTubeIt::Parser::VideosFeedParser.new(@xml).parse_videos
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -5,23 +5,30 @@ class YouTubeIt
|
|
5
5
|
attr_reader :books
|
6
6
|
attr_reader :company
|
7
7
|
attr_reader :description
|
8
|
+
attr_reader :first_name
|
8
9
|
attr_reader :gender
|
9
10
|
attr_reader :hobbies
|
10
11
|
attr_reader :hometown
|
11
12
|
attr_reader :last_login
|
13
|
+
attr_reader :last_name
|
12
14
|
attr_reader :location
|
13
15
|
attr_reader :join_date
|
16
|
+
attr_reader :max_upload_duration
|
14
17
|
attr_reader :movies
|
15
18
|
attr_reader :music
|
16
19
|
attr_reader :occupation
|
17
20
|
attr_reader :relationship
|
18
21
|
attr_reader :school
|
19
22
|
attr_reader :subscribers
|
23
|
+
attr_reader :upload_count
|
20
24
|
attr_reader :upload_views
|
25
|
+
attr_reader :user_id
|
21
26
|
attr_reader :username
|
27
|
+
attr_reader :username_display
|
22
28
|
attr_reader :videos_watched
|
23
29
|
attr_reader :view_count
|
24
30
|
attr_reader :avatar
|
31
|
+
attr_reader :insight_uri
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -68,7 +68,7 @@ class YouTubeIt
|
|
68
68
|
attr_reader :position
|
69
69
|
|
70
70
|
# *Boolean*:: Specifies that a video is flagged as adult or not.
|
71
|
-
attr_reader :
|
71
|
+
attr_reader :safe_search
|
72
72
|
|
73
73
|
# *String*: Specifies a URI that uniquely and permanently identifies the video.
|
74
74
|
attr_reader :video_id
|
@@ -79,6 +79,9 @@ class YouTubeIt
|
|
79
79
|
# *Time*:: When the video's data was last updated.
|
80
80
|
attr_reader :updated_at
|
81
81
|
|
82
|
+
# *Time*:: When the video's was uploaded.
|
83
|
+
attr_reader :uploaded_at
|
84
|
+
|
82
85
|
# *Array*:: A array of YouTubeIt::Model::Category objects that describe the videos categories.
|
83
86
|
attr_reader :categories
|
84
87
|
|
@@ -100,6 +103,9 @@ class YouTubeIt
|
|
100
103
|
# *Array*:: An array of YouTubeIt::Model::Content objects describing the individual media content data available for this video. Most, but not all, videos offer this.
|
101
104
|
attr_reader :media_content
|
102
105
|
|
106
|
+
# *Hash*:: string-keyed, string-valued permissions e.g., {'comment'=>'allowed','videoRespond'=>'moderated'}
|
107
|
+
attr_reader :access_control
|
108
|
+
|
103
109
|
# *Array*:: An array of YouTubeIt::Model::Thumbnail objects that contain information regarding the videos thumbnail images.
|
104
110
|
attr_reader :thumbnails
|
105
111
|
|
@@ -114,13 +120,20 @@ class YouTubeIt
|
|
114
120
|
|
115
121
|
# *Fixnum*:: Number of times that the video has been favorited
|
116
122
|
attr_reader :favorite_count
|
123
|
+
|
124
|
+
# *Fixnum*:: Number of comments for this video
|
125
|
+
attr_reader :comment_count
|
117
126
|
|
118
127
|
# *String*:: State of the video (processing, restricted, deleted, rejected and failed)
|
119
128
|
attr_reader :state
|
120
129
|
|
130
|
+
# *String*:: URI for insight for this video, if present; nil otherwise
|
131
|
+
attr_reader :insight_uri
|
121
132
|
|
133
|
+
# *Boolean*:: Whether or not a video is private. Non-standard name to avoid collision with Rubys own 'private' stuff.
|
134
|
+
attr_reader :perm_private
|
135
|
+
|
122
136
|
# Geodata
|
123
|
-
attr_reader :where
|
124
137
|
attr_reader :position
|
125
138
|
attr_reader :latitude
|
126
139
|
attr_reader :longitude
|
@@ -152,6 +165,16 @@ class YouTubeIt
|
|
152
165
|
@unique_id || video_id[/videos\/([^<]+)/, 1] || video_id[/video\:([^<]+)/, 1]
|
153
166
|
end
|
154
167
|
|
168
|
+
# ID of this video in the watch later list (work only if you are listing watch later videos)
|
169
|
+
# Can be use to modify or remove the entry from the watch later list
|
170
|
+
#
|
171
|
+
# === Example
|
172
|
+
# >> @client.watchlater.videos.first.watch_later_id
|
173
|
+
# => "PL78jdHcOatSF7DGMd4O9K6Mbo0cNlxm_j"
|
174
|
+
def watch_later_id
|
175
|
+
video_id[/watch_later\:([^:]+)/, 1]
|
176
|
+
end
|
177
|
+
|
155
178
|
# Allows you to check whether the video can be embedded on a webpage.
|
156
179
|
#
|
157
180
|
# === Returns
|
@@ -160,6 +183,14 @@ class YouTubeIt
|
|
160
183
|
not @noembed
|
161
184
|
end
|
162
185
|
|
186
|
+
# Allows you to check whether the video is listed and searchable on youtube.
|
187
|
+
#
|
188
|
+
# === Returns
|
189
|
+
# Boolean
|
190
|
+
def listed?
|
191
|
+
access_control['list'] == 'allowed'
|
192
|
+
end
|
193
|
+
|
163
194
|
# Allows you to check whether the video is widescreen (16:9) or not.
|
164
195
|
#
|
165
196
|
# === Returns
|
@@ -200,10 +231,12 @@ EDOC
|
|
200
231
|
:id => params[:id] || "",
|
201
232
|
:width => params[:width] || "425",
|
202
233
|
:height => params[:height] || "350",
|
203
|
-
:frameborder => params[:frameborder] || "0"
|
234
|
+
:frameborder => params[:frameborder] || "0",
|
235
|
+
:url_params => params[:url_params] || {}
|
204
236
|
}
|
237
|
+
url_opts = opts[:url_params].empty? ? "" : "?#{Rack::Utils::build_query(opts[:url_params])}"
|
205
238
|
<<EDOC
|
206
|
-
<iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="http://www.youtube.com/embed/#{unique_id}" frameborder="#{opts[:frameborder]}"></iframe>
|
239
|
+
<iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="http://www.youtube.com/embed/#{unique_id}#{url_opts}" frameborder="#{opts[:frameborder]}"></iframe>
|
207
240
|
EDOC
|
208
241
|
end
|
209
242
|
|