youtube_it 2.1.7 → 2.1.8
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.
- data/README.rdoc +4 -0
- data/lib/youtube_it.rb +1 -0
- data/lib/youtube_it/client.rb +120 -103
- data/lib/youtube_it/middleware/faraday_youtubeit.rb +2 -2
- data/lib/youtube_it/model/caption.rb +7 -0
- data/lib/youtube_it/model/thumbnail.rb +3 -0
- data/lib/youtube_it/model/video.rb +18 -1
- data/lib/youtube_it/parser.rb +22 -2
- data/lib/youtube_it/request/video_upload.rb +33 -16
- data/lib/youtube_it/version.rb +1 -1
- metadata +132 -124
data/README.rdoc
CHANGED
@@ -118,6 +118,10 @@ Fields Parameter(experimental features):
|
|
118
118
|
$ client.videos_by(:fields => {:published => ((Date.today - 30)..(Date.today))})
|
119
119
|
$ client.videos_by(:fields => {:recorded => ((Date.today - 30)..(Date.today))})
|
120
120
|
|
121
|
+
Note: These queries do not find private videos! Use these methods instead:
|
122
|
+
$ client.get_my_video("FQK1URcxmb4")
|
123
|
+
$ client.get_my_videos(:query => "penguin")
|
124
|
+
|
121
125
|
== VIDEO MANAGEMENT
|
122
126
|
|
123
127
|
Note: YouTube account, OAuth or AuthSub enables video management.
|
data/lib/youtube_it.rb
CHANGED
data/lib/youtube_it/client.rb
CHANGED
@@ -6,18 +6,18 @@ class YouTubeIt
|
|
6
6
|
def initialize *params
|
7
7
|
if params.first.is_a?(Hash)
|
8
8
|
hash_options = params.first
|
9
|
-
@user
|
10
|
-
@pass
|
11
|
-
@dev_key
|
12
|
-
@client_id
|
13
|
-
@legacy_debug_flag
|
9
|
+
@user = hash_options[:username]
|
10
|
+
@pass = hash_options[:password]
|
11
|
+
@dev_key = hash_options[:dev_key]
|
12
|
+
@client_id = hash_options[:client_id] || "youtube_it"
|
13
|
+
@legacy_debug_flag = hash_options[:debug]
|
14
14
|
elsif params.first
|
15
15
|
puts "* warning: the method YouTubeIt::Client.new(user, passwd, dev_key) is deprecated, use YouTubeIt::Client.new(:username => 'user', :password => 'passwd', :dev_key => 'dev_key')"
|
16
|
-
@user
|
17
|
-
@pass
|
18
|
-
@dev_key
|
19
|
-
@client_id
|
20
|
-
@legacy_debug_flag
|
16
|
+
@user = params.shift
|
17
|
+
@pass = params.shift
|
18
|
+
@dev_key = params.shift
|
19
|
+
@client_id = params.shift || "youtube_it"
|
20
|
+
@legacy_debug_flag = params.shift
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -59,7 +59,7 @@ class YouTubeIt
|
|
59
59
|
end
|
60
60
|
|
61
61
|
unless request_params[:offset]
|
62
|
-
request_params[:offset] = calculate_offset(request_params[:page], request_params[:max_results]
|
62
|
+
request_params[:offset] = calculate_offset(request_params[:page], request_params[:max_results])
|
63
63
|
end
|
64
64
|
|
65
65
|
if params.respond_to?(:to_hash) and not params[:user]
|
@@ -110,10 +110,14 @@ class YouTubeIt
|
|
110
110
|
client.update(video_id, opts)
|
111
111
|
end
|
112
112
|
|
113
|
+
def captions_update(video_id, data, opts = {})
|
114
|
+
client.captions_update(video_id, data, opts)
|
115
|
+
end
|
116
|
+
|
113
117
|
def video_delete(video_id)
|
114
118
|
client.delete(video_id)
|
115
119
|
end
|
116
|
-
|
120
|
+
|
117
121
|
def message_delete(message_id)
|
118
122
|
client.delete_message(message_id)
|
119
123
|
end
|
@@ -156,7 +160,7 @@ class YouTubeIt
|
|
156
160
|
def profiles(*users)
|
157
161
|
client.profiles(*users)
|
158
162
|
end
|
159
|
-
|
163
|
+
|
160
164
|
# Fetches a user's activity feed.
|
161
165
|
def activity(user = nil, opts = {})
|
162
166
|
client.get_activity(user, opts)
|
@@ -165,7 +169,7 @@ class YouTubeIt
|
|
165
169
|
def watchlater(user = nil)
|
166
170
|
client.watchlater(user)
|
167
171
|
end
|
168
|
-
|
172
|
+
|
169
173
|
def add_video_to_watchlater(video_id)
|
170
174
|
client.add_video_to_watchlater(video_id)
|
171
175
|
end
|
@@ -178,8 +182,24 @@ class YouTubeIt
|
|
178
182
|
client.playlist(playlist_id, order_by)
|
179
183
|
end
|
180
184
|
|
181
|
-
def playlists(user = nil)
|
182
|
-
client.playlists(user)
|
185
|
+
def playlists(user = nil, opts = nil)
|
186
|
+
client.playlists(user, opts)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Fetches all playlists for a given user by repeatedly making requests for
|
190
|
+
# as many pages of playlists as the user has. Note that this can take a
|
191
|
+
# long time if the user has many playlists.
|
192
|
+
def all_playlists(user = nil)
|
193
|
+
newest_playlists, all_playlists_for_user = [], []
|
194
|
+
start_index, page_size = 1, 25
|
195
|
+
|
196
|
+
begin
|
197
|
+
newest_playlists = playlists(user, {'start-index' => start_index, 'max-results' => page_size})
|
198
|
+
all_playlists_for_user += newest_playlists
|
199
|
+
start_index += page_size
|
200
|
+
end while newest_playlists && newest_playlists.size == page_size
|
201
|
+
|
202
|
+
all_playlists_for_user
|
183
203
|
end
|
184
204
|
|
185
205
|
def add_playlist(options)
|
@@ -209,7 +229,7 @@ class YouTubeIt
|
|
209
229
|
def dislike_video(video_id)
|
210
230
|
client.rate_video(video_id, 'dislike')
|
211
231
|
end
|
212
|
-
|
232
|
+
|
213
233
|
def subscribe_channel(channel_name)
|
214
234
|
client.subscribe_channel(channel_name)
|
215
235
|
end
|
@@ -217,7 +237,7 @@ class YouTubeIt
|
|
217
237
|
def unsubscribe_channel(subscription_id)
|
218
238
|
client.unsubscribe_channel(subscription_id)
|
219
239
|
end
|
220
|
-
|
240
|
+
|
221
241
|
def subscriptions(user_id = nil)
|
222
242
|
client.subscriptions(user_id)
|
223
243
|
end
|
@@ -225,7 +245,7 @@ class YouTubeIt
|
|
225
245
|
def enable_http_debugging
|
226
246
|
client.enable_http_debugging
|
227
247
|
end
|
228
|
-
|
248
|
+
|
229
249
|
def add_response(original_video_id, response_video_id)
|
230
250
|
client.add_response(original_video_id, response_video_id)
|
231
251
|
end
|
@@ -237,7 +257,7 @@ class YouTubeIt
|
|
237
257
|
def current_user
|
238
258
|
client.get_current_user
|
239
259
|
end
|
240
|
-
|
260
|
+
|
241
261
|
# Gets the authenticated users video with the given ID. It may be private.
|
242
262
|
def my_video(video_id)
|
243
263
|
client.get_my_video(video_id)
|
@@ -247,27 +267,27 @@ class YouTubeIt
|
|
247
267
|
def my_videos(opts = {})
|
248
268
|
client.get_my_videos(opts)
|
249
269
|
end
|
250
|
-
|
270
|
+
|
251
271
|
# Gets all of the user's contacts/friends.
|
252
272
|
def my_contacts(opts = {})
|
253
273
|
client.get_my_contacts(opts)
|
254
274
|
end
|
255
|
-
|
275
|
+
|
256
276
|
# Send video message
|
257
277
|
def send_message(opts = {})
|
258
278
|
client.send_message(opts)
|
259
279
|
end
|
260
|
-
|
280
|
+
|
261
281
|
# Gets all of the user's messages/inbox.
|
262
282
|
def my_messages(opts = {})
|
263
283
|
client.get_my_messages(opts)
|
264
284
|
end
|
265
|
-
|
285
|
+
|
266
286
|
# Gets the user's watch history
|
267
287
|
def watch_history
|
268
288
|
client.get_watch_history
|
269
289
|
end
|
270
|
-
|
290
|
+
|
271
291
|
# Gets new subscription videos
|
272
292
|
def new_subscription_videos(user_id = nil)
|
273
293
|
client.new_subscription_videos(user_id)
|
@@ -294,12 +314,12 @@ class YouTubeIt
|
|
294
314
|
puts "* AuthSubClient will be deprecated. Use OAuth2 Client."
|
295
315
|
if params.first.is_a?(Hash)
|
296
316
|
hash_options = params.first
|
297
|
-
@authsub_token
|
298
|
-
@dev_key
|
299
|
-
@client_id
|
300
|
-
@legacy_debug_flag
|
317
|
+
@authsub_token = hash_options[:token]
|
318
|
+
@dev_key = hash_options[:dev_key]
|
319
|
+
@client_id = hash_options[:client_id] || "youtube_it"
|
320
|
+
@legacy_debug_flag = hash_options[:debug]
|
301
321
|
else
|
302
|
-
puts "* warning: the method YouTubeIt::AuthSubClient.new(token, dev_key) is
|
322
|
+
puts "* warning: the method YouTubeIt::AuthSubClient.new(token, dev_key) is deprecated, use YouTubeIt::AuthSubClient.new(:token => 'token', :dev_key => 'dev_key')"
|
303
323
|
@authsub_token = params.shift
|
304
324
|
@dev_key = params.shift
|
305
325
|
@client_id = params.shift || "youtube_it"
|
@@ -311,23 +331,19 @@ class YouTubeIt
|
|
311
331
|
response = nil
|
312
332
|
session_token_url = "/accounts/AuthSubSessionToken"
|
313
333
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
@authsub_token = response.sub('Token=','')
|
334
|
+
http_connection do |session|
|
335
|
+
response = session.get2('https://%s' % session_token_url, session_token_header).body
|
336
|
+
end
|
337
|
+
@authsub_token = response.sub('Token=', '')
|
320
338
|
end
|
321
339
|
|
322
340
|
def revoke_session_token
|
323
341
|
response = nil
|
324
342
|
session_token_url = "/accounts/AuthSubRevokeToken"
|
325
343
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
end.status
|
330
|
-
|
344
|
+
http_connection do |session|
|
345
|
+
response = session.get2('https://%s' % session_token_url, session_token_header).code
|
346
|
+
end
|
331
347
|
response.to_s == '200' ? true : false
|
332
348
|
end
|
333
349
|
|
@@ -335,34 +351,31 @@ class YouTubeIt
|
|
335
351
|
response = nil
|
336
352
|
session_token_url = "/accounts/AuthSubTokenInfo"
|
337
353
|
|
338
|
-
|
339
|
-
|
340
|
-
req.headers = session_token_header
|
354
|
+
http_connection do |session|
|
355
|
+
response = session.get2('https://%s' % session_token_url, session_token_header)
|
341
356
|
end
|
342
|
-
|
343
|
-
{:code => response.status, :body => response.body }
|
357
|
+
{:code => response.code, :body => response.body}
|
344
358
|
end
|
345
359
|
|
346
360
|
private
|
347
|
-
|
348
|
-
|
349
|
-
|
361
|
+
def client
|
362
|
+
@client ||= YouTubeIt::Upload::VideoUpload.new(:dev_key => @dev_key, :authsub_token => @authsub_token)
|
363
|
+
end
|
350
364
|
|
351
|
-
|
352
|
-
|
353
|
-
"Content-Type"
|
354
|
-
"Authorization"
|
355
|
-
|
356
|
-
|
365
|
+
def session_token_header
|
366
|
+
{
|
367
|
+
"Content-Type" => "application/x-www-form-urlencoded",
|
368
|
+
"Authorization" => "AuthSub token=#{@authsub_token}"
|
369
|
+
}
|
370
|
+
end
|
357
371
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
end
|
372
|
+
def http_connection
|
373
|
+
http = Net::HTTP.new("www.google.com")
|
374
|
+
http.set_debug_output(logger) if @http_debugging
|
375
|
+
http.start do |session|
|
376
|
+
yield(session)
|
364
377
|
end
|
365
|
-
|
378
|
+
end
|
366
379
|
end
|
367
380
|
|
368
381
|
class OAuthClient < Client
|
@@ -370,33 +383,33 @@ class YouTubeIt
|
|
370
383
|
puts "* OAuth 1.0 Client will be deprecated. Use OAuth2 Client."
|
371
384
|
if params.first.is_a?(Hash)
|
372
385
|
hash_options = params.first
|
373
|
-
@consumer_key
|
374
|
-
@consumer_secret
|
375
|
-
@user
|
376
|
-
@dev_key
|
377
|
-
@client_id
|
378
|
-
@legacy_debug_flag
|
386
|
+
@consumer_key = hash_options[:consumer_key]
|
387
|
+
@consumer_secret = hash_options[:consumer_secret]
|
388
|
+
@user = hash_options[:username]
|
389
|
+
@dev_key = hash_options[:dev_key]
|
390
|
+
@client_id = hash_options[:client_id] || "youtube_it"
|
391
|
+
@legacy_debug_flag = hash_options[:debug]
|
379
392
|
else
|
380
393
|
puts "* warning: the method YouTubeIt::OAuthClient.new(consumer_key, consumer_secrect, dev_key) is depricated, use YouTubeIt::OAuthClient.new(:consumer_key => 'consumer key', :consumer_secret => 'consumer secret', :dev_key => 'dev_key')"
|
381
|
-
@consumer_key
|
382
|
-
@consumer_secret
|
383
|
-
@dev_key
|
384
|
-
@user
|
385
|
-
@client_id
|
386
|
-
@legacy_debug_flag
|
394
|
+
@consumer_key = params.shift
|
395
|
+
@consumer_secret = params.shift
|
396
|
+
@dev_key = params.shift
|
397
|
+
@user = params.shift
|
398
|
+
@client_id = params.shift || "youtube_it"
|
399
|
+
@legacy_debug_flag = params.shift
|
387
400
|
end
|
388
401
|
end
|
389
402
|
|
390
403
|
def consumer
|
391
|
-
@consumer ||= ::OAuth::Consumer.new(@consumer_key
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
404
|
+
@consumer ||= ::OAuth::Consumer.new(@consumer_key, @consumer_secret, {
|
405
|
+
:site => "https://www.google.com",
|
406
|
+
:request_token_path => "/accounts/OAuthGetRequestToken",
|
407
|
+
:authorize_path => "/accounts/OAuthAuthorizeToken",
|
408
|
+
:access_token_path => "/accounts/OAuthGetAccessToken"})
|
396
409
|
end
|
397
410
|
|
398
411
|
def request_token(callback)
|
399
|
-
@request_token = consumer.get_request_token({:oauth_callback => callback},{:scope => "http://gdata.youtube.com"})
|
412
|
+
@request_token = consumer.get_request_token({:oauth_callback => callback}, {:scope => "http://gdata.youtube.com"})
|
400
413
|
end
|
401
414
|
|
402
415
|
def access_token
|
@@ -405,29 +418,29 @@ class YouTubeIt
|
|
405
418
|
|
406
419
|
def config_token
|
407
420
|
{
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
421
|
+
:consumer_key => @consumer_key,
|
422
|
+
:consumer_secret => @consumer_secret,
|
423
|
+
:token => @atoken,
|
424
|
+
:token_secret => @asecret
|
425
|
+
}
|
413
426
|
end
|
414
427
|
|
415
|
-
def authorize_from_request(rtoken,rsecret,verifier)
|
416
|
-
request_token = ::OAuth::RequestToken.new(consumer,rtoken,rsecret)
|
428
|
+
def authorize_from_request(rtoken, rsecret, verifier)
|
429
|
+
request_token = ::OAuth::RequestToken.new(consumer, rtoken, rsecret)
|
417
430
|
access_token = request_token.get_access_token({:oauth_verifier => verifier})
|
418
|
-
@atoken
|
431
|
+
@atoken, @asecret = access_token.token, access_token.secret
|
419
432
|
end
|
420
433
|
|
421
|
-
def authorize_from_access(atoken,asecret)
|
422
|
-
@atoken
|
434
|
+
def authorize_from_access(atoken, asecret)
|
435
|
+
@atoken, @asecret = atoken, asecret
|
423
436
|
end
|
424
437
|
|
425
438
|
def current_user
|
426
439
|
profile = access_token.get("http://gdata.youtube.com/feeds/api/users/default")
|
427
440
|
response_code = profile.code.to_i
|
428
441
|
|
429
|
-
if response_code/10 == 20 # success
|
430
|
-
Nokogiri::XML(profile.body).at("
|
442
|
+
if (response_code / 10).to_i == 20 # success
|
443
|
+
Nokogiri::XML(profile.body).at("//yt:username").text
|
431
444
|
elsif response_code == 403 || response_code == 401 # auth failure
|
432
445
|
raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
|
433
446
|
else
|
@@ -446,14 +459,13 @@ class YouTubeIt
|
|
446
459
|
|
447
460
|
class OAuth2Client < YouTubeIt::Client
|
448
461
|
def initialize(options)
|
449
|
-
@client_id
|
450
|
-
@client_secret
|
451
|
-
@client_access_token
|
452
|
-
@client_refresh_token
|
462
|
+
@client_id = options[:client_id]
|
463
|
+
@client_secret = options[:client_secret]
|
464
|
+
@client_access_token = options[:client_access_token]
|
465
|
+
@client_refresh_token = options[:client_refresh_token]
|
453
466
|
@client_token_expires_at = options[:client_token_expires_at]
|
454
|
-
@dev_key
|
455
|
-
@legacy_debug_flag
|
456
|
-
@connection_opts = options[:connection_opts]
|
467
|
+
@dev_key = options[:dev_key]
|
468
|
+
@legacy_debug_flag = options[:debug]
|
457
469
|
end
|
458
470
|
|
459
471
|
def oauth_client
|
@@ -464,7 +476,7 @@ class YouTubeIt
|
|
464
476
|
options.merge(:connection_opts => @connection_opts) if @connection_opts
|
465
477
|
@oauth_client ||= ::OAuth2::Client.new(@client_id, @client_secret, options)
|
466
478
|
end
|
467
|
-
|
479
|
+
|
468
480
|
def access_token
|
469
481
|
@access_token ||= ::OAuth2::AccessToken.new(oauth_client, @client_access_token, :refresh_token => @client_refresh_token, :expires_at => @client_token_expires_at)
|
470
482
|
end
|
@@ -478,20 +490,25 @@ class YouTubeIt
|
|
478
490
|
end
|
479
491
|
@access_token
|
480
492
|
end
|
493
|
+
|
494
|
+
def session_token_info
|
495
|
+
response = Faraday.get("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=#{@client_access_token}")
|
496
|
+
{:code => response.status, :body => response.body }
|
497
|
+
end
|
481
498
|
|
482
499
|
def current_user
|
483
500
|
profile = access_token.get("http://gdata.youtube.com/feeds/api/users/default")
|
484
501
|
response_code = profile.status
|
485
502
|
|
486
|
-
if response_code/10 == 20 # success
|
487
|
-
Nokogiri::XML(profile.body).at("
|
503
|
+
if (response_code / 10).to_i == 20 # success
|
504
|
+
Nokogiri::XML(profile.body).at("//yt:username").text
|
488
505
|
elsif response_code == 403 || response_code == 401 # auth failure
|
489
506
|
raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
|
490
507
|
else
|
491
508
|
raise YouTubeIt::Upload::UploadError.new(profile.inspect, response_code)
|
492
509
|
end
|
493
510
|
end
|
494
|
-
|
511
|
+
|
495
512
|
private
|
496
513
|
|
497
514
|
def client
|
@@ -20,10 +20,10 @@ module Faraday
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def on_complete(env) #this method is called after finish request
|
23
|
-
msg = parse_upload_error_from(env[:body].gsub(/\n/, ''))
|
23
|
+
msg = env[:body] ? parse_upload_error_from(env[:body].gsub(/\n/, '')) : ''
|
24
24
|
if env[:status] == 403 || env[:status] == 401
|
25
25
|
raise ::AuthenticationError.new(msg, env[:status])
|
26
|
-
elsif env[:status] / 10 != 20
|
26
|
+
elsif (env[:status] / 10).to_i != 20
|
27
27
|
raise ::UploadError.new(msg, env[:status])
|
28
28
|
end
|
29
29
|
end
|
@@ -12,6 +12,9 @@ class YouTubeIt
|
|
12
12
|
|
13
13
|
# *String*:: Specifies the time offset at which the frame shown in the thumbnail image appears in the video.
|
14
14
|
attr_reader :time
|
15
|
+
|
16
|
+
# *String*:: Specified type of the thumbnail, attribute yt:name in feed
|
17
|
+
attr_reader :name
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
@@ -155,6 +155,22 @@ class YouTubeIt
|
|
155
155
|
def responses
|
156
156
|
YouTubeIt::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/responses?v=2").parse
|
157
157
|
end
|
158
|
+
|
159
|
+
|
160
|
+
# ID of video in playlist listing
|
161
|
+
# Useful if you have to delete this video from a playlist
|
162
|
+
#
|
163
|
+
# === Example
|
164
|
+
# >> video.in_playlist_id
|
165
|
+
# => "PLk3UVPlPEkey09s2W02R48WMDKjvSb6Hq"
|
166
|
+
#
|
167
|
+
# === Returns
|
168
|
+
# String the video id
|
169
|
+
#
|
170
|
+
def in_playlist_id
|
171
|
+
@video_id.split(':').last
|
172
|
+
end
|
173
|
+
|
158
174
|
# The ID of the video, useful for searching for the video again without having to store it anywhere.
|
159
175
|
# A regular query search, with this id will return the same video.
|
160
176
|
#
|
@@ -234,12 +250,13 @@ EDOC
|
|
234
250
|
:id => params[:id] || "",
|
235
251
|
:width => params[:width] || "425",
|
236
252
|
:height => params[:height] || "350",
|
253
|
+
:protocol => params[:protocol] || "http",
|
237
254
|
:frameborder => params[:frameborder] || "0",
|
238
255
|
:url_params => params[:url_params] || {}
|
239
256
|
}
|
240
257
|
url_opts = opts[:url_params].empty? ? "" : "?#{Rack::Utils::build_query(opts[:url_params])}"
|
241
258
|
<<EDOC
|
242
|
-
<iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="
|
259
|
+
<iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="#{opts[:protocol]}://www.youtube.com/embed/#{unique_id}#{url_opts}" frameborder="#{opts[:frameborder]}"></iframe>
|
243
260
|
EDOC
|
244
261
|
end
|
245
262
|
|
data/lib/youtube_it/parser.rb
CHANGED
@@ -82,7 +82,7 @@ class YouTubeIt
|
|
82
82
|
:title => entry.at("title") && entry.at("title").text,
|
83
83
|
:summary => ((entry.at("summary") || entry.at_xpath("media:group").at_xpath("media:description")).text rescue nil),
|
84
84
|
:description => ((entry.at("summary") || entry.at_xpath("media:group").at_xpath("media:description")).text rescue nil),
|
85
|
-
:playlist_id => (entry.at("id").text[/playlist:(\w+)/, 1] rescue nil),
|
85
|
+
:playlist_id => (entry.at("id").text[/playlist:([\w\-]+)/, 1] rescue nil),
|
86
86
|
:published => entry.at("published") ? entry.at("published").text : nil,
|
87
87
|
:response_code => content.status,
|
88
88
|
:xml => content.body)
|
@@ -365,6 +365,25 @@ class YouTubeIt
|
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
+
class CaptionFeedParser < FeedParser #:nodoc:
|
369
|
+
|
370
|
+
def parse_content(content)
|
371
|
+
doc = (content.is_a?(Nokogiri::XML::Document)) ? content : Nokogiri::XML(content)
|
372
|
+
|
373
|
+
entry = doc.at "entry"
|
374
|
+
parse_entry(entry)
|
375
|
+
end
|
376
|
+
|
377
|
+
protected
|
378
|
+
|
379
|
+
def parse_entry(entry)
|
380
|
+
YouTubeIt::Model::Caption.new(
|
381
|
+
:title => entry.at("title").text,
|
382
|
+
:id => entry.at("id").text[/captions([^<]+)/, 1].sub(':',''),
|
383
|
+
:published => entry.at("published") ? entry.at("published").text : nil
|
384
|
+
)
|
385
|
+
end
|
386
|
+
end
|
368
387
|
|
369
388
|
class VideoFeedParser < FeedParser #:nodoc:
|
370
389
|
|
@@ -454,7 +473,8 @@ class YouTubeIt
|
|
454
473
|
:url => thumb_element["url"],
|
455
474
|
:height => thumb_element["height"].to_i,
|
456
475
|
:width => thumb_element["width"].to_i,
|
457
|
-
:time => thumb_element["time"]
|
476
|
+
:time => thumb_element["time"],
|
477
|
+
:name => thumb_element["name"])
|
458
478
|
end
|
459
479
|
|
460
480
|
rating_element = entry.at_xpath("gd:rating")
|
@@ -29,7 +29,7 @@ class YouTubeIt
|
|
29
29
|
@client_id = hash_options[:client_id] || "youtube_it"
|
30
30
|
@config_token = hash_options[:config_token]
|
31
31
|
else
|
32
|
-
puts "* warning: the method YouTubeIt::Upload::VideoUpload.new(username, password, dev_key) is
|
32
|
+
puts "* warning: the method YouTubeIt::Upload::VideoUpload.new(username, password, dev_key) is deprecated, use YouTubeIt::Upload::VideoUpload.new(:username => 'user', :password => 'passwd', :dev_key => 'dev_key')"
|
33
33
|
@user = params.shift
|
34
34
|
@password = params.shift
|
35
35
|
@dev_key = params.shift
|
@@ -115,6 +115,24 @@ class YouTubeIt
|
|
115
115
|
return YouTubeIt::Parser::VideoFeedParser.new(response.body).parse
|
116
116
|
end
|
117
117
|
|
118
|
+
|
119
|
+
def captions_update(video_id, data, options)
|
120
|
+
@opts = {
|
121
|
+
:language => 'en-US',
|
122
|
+
:slug => ''
|
123
|
+
}.merge(options)
|
124
|
+
|
125
|
+
upload_header = {
|
126
|
+
"Slug" => "#{URI.escape(@opts[:slug])}",
|
127
|
+
"Content-Language"=>@opts[:language],
|
128
|
+
"Content-Type" => "application/vnd.youtube.timedtext; charset=UTF-8",
|
129
|
+
"Content-Length" => "#{data.length}",
|
130
|
+
}
|
131
|
+
upload_url = "/feeds/api/videos/#{video_id}/captions"
|
132
|
+
response = yt_session(base_url).post(upload_url, data, upload_header)
|
133
|
+
return YouTubeIt::Parser::CaptionFeedParser.new(response.body).parse
|
134
|
+
end
|
135
|
+
|
118
136
|
# Fetches the currently authenticated user's contacts (i.e. friends).
|
119
137
|
# When the authentication credentials are incorrect, an AuthenticationError will be raised.
|
120
138
|
def get_my_contacts(opts)
|
@@ -306,9 +324,20 @@ class YouTubeIt
|
|
306
324
|
return YouTubeIt::Parser::PlaylistFeedParser.new(response).parse
|
307
325
|
end
|
308
326
|
|
309
|
-
|
310
|
-
|
311
|
-
|
327
|
+
# Fetches playlists for the given user. An optional hash of parameters can be given and will
|
328
|
+
# be appended to the request. Paging parameters will need to be used to access playlists
|
329
|
+
# beyond the most recent 25 (page size default for YouTube API at the time of this writing)
|
330
|
+
# if a user has more than 25 playlists.
|
331
|
+
#
|
332
|
+
# Paging parameters include the following
|
333
|
+
# start-index - 1-based index of which playlist to start from (default is 1)
|
334
|
+
# max-results - maximum number of playlists to fetch, up to 25 (default is 25)
|
335
|
+
def playlists(user, opts={})
|
336
|
+
playlist_url = "/feeds/api/users/%s/playlists" % (user ? user : "default")
|
337
|
+
params = {'v' => 2}
|
338
|
+
params.merge!(opts) if opts
|
339
|
+
playlist_url << "?#{params.collect { |k,v| [k,v].join '=' }.join('&')}"
|
340
|
+
response = yt_session.get(playlist_url)
|
312
341
|
|
313
342
|
return YouTubeIt::Parser::PlaylistsFeedParser.new(response).parse
|
314
343
|
end
|
@@ -468,18 +497,6 @@ class YouTubeIt
|
|
468
497
|
end
|
469
498
|
end
|
470
499
|
|
471
|
-
def raise_on_faulty_response(response)
|
472
|
-
response_code = response.code.to_i
|
473
|
-
msg = parse_upload_error_from(response.body.gsub(/\n/, ''))
|
474
|
-
|
475
|
-
if response_code == 403 || response_code == 401
|
476
|
-
#if response_code / 10 == 40
|
477
|
-
raise AuthenticationError.new(msg, response_code)
|
478
|
-
elsif response_code / 10 != 20 # Response in 20x means success
|
479
|
-
raise UploadError.new(msg, response_code)
|
480
|
-
end
|
481
|
-
end
|
482
|
-
|
483
500
|
def uploaded_video_id_from(string)
|
484
501
|
xml = Nokogiri::XML(string)
|
485
502
|
xml.at("id").text[/videos\/(.+)/, 1]
|
data/lib/youtube_it/version.rb
CHANGED
metadata
CHANGED
@@ -1,146 +1,154 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: youtube_it
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.7
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 2.1.8
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
- kylejginavan
|
9
|
-
- chebyte
|
10
|
-
- mseppae
|
7
|
+
authors:
|
8
|
+
- kylejginavan
|
9
|
+
- chebyte
|
10
|
+
- mseppae
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
14
|
+
|
15
|
+
date: 2012-11-10 00:00:00 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: nokogiri
|
19
|
+
prerelease: false
|
20
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
none: false
|
22
|
+
requirements:
|
23
|
+
- - ~>
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 1.5.2
|
26
|
+
type: :runtime
|
27
|
+
version_requirements: *id001
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: oauth
|
30
|
+
prerelease: false
|
31
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.4.4
|
37
|
+
type: :runtime
|
38
|
+
version_requirements: *id002
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: oauth2
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0.6"
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id003
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: simple_oauth
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 0.1.5
|
59
|
+
type: :runtime
|
60
|
+
version_requirements: *id004
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: faraday
|
63
|
+
prerelease: false
|
64
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0.8"
|
70
|
+
type: :runtime
|
71
|
+
version_requirements: *id005
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: builder
|
74
|
+
prerelease: false
|
75
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
type: :runtime
|
82
|
+
version_requirements: *id006
|
82
83
|
description: Upload, delete, update, comment on youtube videos all from one gem.
|
83
|
-
email:
|
84
|
-
- kylejginavan@gmail.com
|
84
|
+
email:
|
85
|
+
- kylejginavan@gmail.com
|
85
86
|
executables: []
|
87
|
+
|
86
88
|
extensions: []
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
- lib/youtube_it
|
92
|
-
- lib/youtube_it/
|
93
|
-
- lib/youtube_it/
|
94
|
-
- lib/youtube_it/
|
95
|
-
- lib/youtube_it/
|
96
|
-
- lib/youtube_it/
|
97
|
-
- lib/youtube_it/
|
98
|
-
- lib/youtube_it/
|
99
|
-
- lib/youtube_it/
|
100
|
-
- lib/youtube_it/
|
101
|
-
- lib/youtube_it/model/
|
102
|
-
- lib/youtube_it/model/
|
103
|
-
- lib/youtube_it/model/
|
104
|
-
- lib/youtube_it/model/
|
105
|
-
- lib/youtube_it/model/
|
106
|
-
- lib/youtube_it/model/
|
107
|
-
- lib/youtube_it/model/
|
108
|
-
- lib/youtube_it/model/
|
109
|
-
- lib/youtube_it/
|
110
|
-
- lib/youtube_it/
|
111
|
-
- lib/youtube_it/
|
112
|
-
- lib/youtube_it/
|
113
|
-
- lib/youtube_it/
|
114
|
-
- lib/youtube_it/
|
115
|
-
- lib/youtube_it/request/
|
116
|
-
- lib/youtube_it/request/
|
117
|
-
- lib/youtube_it/
|
118
|
-
- lib/youtube_it/
|
119
|
-
- lib/youtube_it.rb
|
120
|
-
-
|
121
|
-
- youtube_it.
|
89
|
+
|
90
|
+
extra_rdoc_files:
|
91
|
+
- README.rdoc
|
92
|
+
files:
|
93
|
+
- lib/youtube_it.rb
|
94
|
+
- lib/youtube_it/chain_io.rb
|
95
|
+
- lib/youtube_it/client.rb
|
96
|
+
- lib/youtube_it/parser.rb
|
97
|
+
- lib/youtube_it/record.rb
|
98
|
+
- lib/youtube_it/version.rb
|
99
|
+
- lib/youtube_it/middleware/faraday_authheader.rb
|
100
|
+
- lib/youtube_it/middleware/faraday_oauth.rb
|
101
|
+
- lib/youtube_it/middleware/faraday_oauth2.rb
|
102
|
+
- lib/youtube_it/middleware/faraday_youtubeit.rb
|
103
|
+
- lib/youtube_it/model/activity.rb
|
104
|
+
- lib/youtube_it/model/author.rb
|
105
|
+
- lib/youtube_it/model/caption.rb
|
106
|
+
- lib/youtube_it/model/category.rb
|
107
|
+
- lib/youtube_it/model/comment.rb
|
108
|
+
- lib/youtube_it/model/contact.rb
|
109
|
+
- lib/youtube_it/model/content.rb
|
110
|
+
- lib/youtube_it/model/message.rb
|
111
|
+
- lib/youtube_it/model/playlist.rb
|
112
|
+
- lib/youtube_it/model/rating.rb
|
113
|
+
- lib/youtube_it/model/subscription.rb
|
114
|
+
- lib/youtube_it/model/thumbnail.rb
|
115
|
+
- lib/youtube_it/model/user.rb
|
116
|
+
- lib/youtube_it/model/video.rb
|
117
|
+
- lib/youtube_it/request/base_search.rb
|
118
|
+
- lib/youtube_it/request/error.rb
|
119
|
+
- lib/youtube_it/request/standard_search.rb
|
120
|
+
- lib/youtube_it/request/user_search.rb
|
121
|
+
- lib/youtube_it/request/video_search.rb
|
122
|
+
- lib/youtube_it/request/video_upload.rb
|
123
|
+
- lib/youtube_it/response/video_search.rb
|
124
|
+
- README.rdoc
|
125
|
+
- youtube_it.gemspec
|
122
126
|
homepage: http://github.com/kylejginavan/youtube_it
|
123
127
|
licenses: []
|
128
|
+
|
124
129
|
post_install_message:
|
125
130
|
rdoc_options: []
|
126
|
-
|
127
|
-
|
128
|
-
|
131
|
+
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
135
|
none: false
|
130
|
-
requirements:
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: "0"
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
141
|
none: false
|
136
|
-
requirements:
|
137
|
-
|
138
|
-
|
139
|
-
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: "0"
|
140
146
|
requirements: []
|
147
|
+
|
141
148
|
rubyforge_project:
|
142
149
|
rubygems_version: 1.8.15
|
143
150
|
signing_key:
|
144
151
|
specification_version: 3
|
145
152
|
summary: The most complete Ruby wrapper for youtube api's
|
146
153
|
test_files: []
|
154
|
+
|