youtube_it 2.1.5 → 2.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -2
- data/lib/youtube_it/client.rb +29 -17
- data/lib/youtube_it/middleware/faraday_youtubeit.rb +9 -8
- data/lib/youtube_it/model/video.rb +3 -0
- data/lib/youtube_it/parser.rb +8 -2
- data/lib/youtube_it/request/video_search.rb +5 -1
- data/lib/youtube_it/request/video_upload.rb +15 -14
- data/lib/youtube_it/version.rb +1 -1
- metadata +14 -14
data/README.rdoc
CHANGED
@@ -36,6 +36,8 @@ You can see to youtube_it in action here: http://youtube-it.heroku.com
|
|
36
36
|
|
37
37
|
== ESTABLISHING A CLIENT
|
38
38
|
|
39
|
+
Important: The Account Authentication API for OAuth 1.0, AuthSub and Client Login has been officially deprecated as of April 20, 2012. It will continue to work as per our deprecation policy(https://developers.google.com/accounts/terms), but we encourage you to migrate to OAuth 2.0 authentication as soon as possible. If you are building a new application, you should use OAuth 2.0 authentication.
|
40
|
+
|
39
41
|
Creating a client:
|
40
42
|
$ require 'youtube_it'
|
41
43
|
$ client = YouTubeIt::Client.new
|
@@ -60,6 +62,8 @@ If your access token is still valid (be careful, access tokens may only be valid
|
|
60
62
|
|
61
63
|
$ client.refresh_access_token!
|
62
64
|
|
65
|
+
* You can see more about oauth 2 in the wiki: https://github.com/kylejginavan/youtube_it/wiki/How-To:-Use-OAuth-2
|
66
|
+
|
63
67
|
== PROFILES
|
64
68
|
you can use multiple profiles in the same account like that
|
65
69
|
|
@@ -208,7 +212,7 @@ Add Video To Playlist:
|
|
208
212
|
$ client.add_video_to_playlist(playlist_id, video_id)
|
209
213
|
|
210
214
|
Remove Video From Playlist:
|
211
|
-
$ client.
|
215
|
+
$ client.delete_video_from_playlist(playlist_id, playlist_entry_id)
|
212
216
|
|
213
217
|
Select All Videos From your Watch Later Playlist:
|
214
218
|
$ watcher_later = client.watcherlater(user) #default: current user
|
@@ -218,7 +222,7 @@ Add Video To Watcher Later Playlist:
|
|
218
222
|
$ client.add_video_to_watchlater(video_id)
|
219
223
|
|
220
224
|
Remove Video From Watch Later Playlist:
|
221
|
-
$ client.
|
225
|
+
$ client.delete_video_from_watchlater(watchlater_entry_id)
|
222
226
|
|
223
227
|
|
224
228
|
List Related Videos
|
data/lib/youtube_it/client.rb
CHANGED
@@ -291,6 +291,7 @@ class YouTubeIt
|
|
291
291
|
|
292
292
|
class AuthSubClient < Client
|
293
293
|
def initialize *params
|
294
|
+
puts "* AuthSubClient will be deprecated. Use OAuth2 Client."
|
294
295
|
if params.first.is_a?(Hash)
|
295
296
|
hash_options = params.first
|
296
297
|
@authsub_token = hash_options[:token]
|
@@ -310,9 +311,11 @@ class YouTubeIt
|
|
310
311
|
response = nil
|
311
312
|
session_token_url = "/accounts/AuthSubSessionToken"
|
312
313
|
|
313
|
-
http_connection do |
|
314
|
-
|
315
|
-
|
314
|
+
response = http_connection.get do |req|
|
315
|
+
req.url session_token_url
|
316
|
+
req.headers = session_token_header
|
317
|
+
end.body
|
318
|
+
|
316
319
|
@authsub_token = response.sub('Token=','')
|
317
320
|
end
|
318
321
|
|
@@ -320,9 +323,11 @@ class YouTubeIt
|
|
320
323
|
response = nil
|
321
324
|
session_token_url = "/accounts/AuthSubRevokeToken"
|
322
325
|
|
323
|
-
http_connection do |
|
324
|
-
|
325
|
-
|
326
|
+
response = http_connection.get do |req|
|
327
|
+
req.url session_token_url
|
328
|
+
req.headers = session_token_header
|
329
|
+
end.status
|
330
|
+
|
326
331
|
response.to_s == '200' ? true : false
|
327
332
|
end
|
328
333
|
|
@@ -330,10 +335,12 @@ class YouTubeIt
|
|
330
335
|
response = nil
|
331
336
|
session_token_url = "/accounts/AuthSubTokenInfo"
|
332
337
|
|
333
|
-
http_connection do |
|
334
|
-
|
338
|
+
response = http_connection.get do |req|
|
339
|
+
req.url session_token_url
|
340
|
+
req.headers = session_token_header
|
335
341
|
end
|
336
|
-
|
342
|
+
|
343
|
+
{:code => response.status, :body => response.body }
|
337
344
|
end
|
338
345
|
|
339
346
|
private
|
@@ -349,16 +356,18 @@ class YouTubeIt
|
|
349
356
|
end
|
350
357
|
|
351
358
|
def http_connection
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
359
|
+
Faraday.new(:url => 'https://www.google.com', :ssl => {:verify => false}) do |builder|
|
360
|
+
builder.request :url_encoded
|
361
|
+
builder.response :logger if @legacy_debug_flag
|
362
|
+
builder.adapter Faraday.default_adapter
|
356
363
|
end
|
357
364
|
end
|
365
|
+
|
358
366
|
end
|
359
367
|
|
360
368
|
class OAuthClient < Client
|
361
369
|
def initialize *params
|
370
|
+
puts "* OAuth 1.0 Client will be deprecated. Use OAuth2 Client."
|
362
371
|
if params.first.is_a?(Hash)
|
363
372
|
hash_options = params.first
|
364
373
|
@consumer_key = hash_options[:consumer_key]
|
@@ -444,13 +453,16 @@ class YouTubeIt
|
|
444
453
|
@client_token_expires_at = options[:client_token_expires_at]
|
445
454
|
@dev_key = options[:dev_key]
|
446
455
|
@legacy_debug_flag = options[:debug]
|
456
|
+
@connection_opts = options[:connection_opts]
|
447
457
|
end
|
448
458
|
|
449
459
|
def oauth_client
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
460
|
+
options = {:site => "https://accounts.google.com",
|
461
|
+
:authorize_url => '/o/oauth2/auth',
|
462
|
+
:token_url => '/o/oauth2/token'
|
463
|
+
}
|
464
|
+
options.merge(:connection_opts => @connection_opts) if @connection_opts
|
465
|
+
@oauth_client ||= ::OAuth2::Client.new(@client_id, @client_secret, options)
|
454
466
|
end
|
455
467
|
|
456
468
|
def access_token
|
@@ -1,19 +1,20 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Response::YouTubeIt < Response::Middleware
|
3
3
|
def parse_upload_error_from(string)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
xml = Nokogiri::XML(string).at('errors')
|
5
|
+
if xml
|
6
|
+
xml.css("error").inject('') do |all_faults, error|
|
7
|
+
if error.at("internalReason")
|
8
|
+
msg_error = error.at("internalReason").text
|
9
|
+
elsif error.at("location")
|
10
|
+
msg_error = error.at("location").text[/media:group\/media:(.*)\/text\(\)/,1]
|
10
11
|
else
|
11
12
|
msg_error = "Unspecified error"
|
12
13
|
end
|
13
|
-
code = error.
|
14
|
+
code = error.at("code").text if error.at("code")
|
14
15
|
all_faults + sprintf("%s: %s\n", msg_error, code)
|
15
16
|
end
|
16
|
-
|
17
|
+
else
|
17
18
|
string[/<TITLE>(.+)<\/TITLE>/, 1] || string
|
18
19
|
end
|
19
20
|
end
|
@@ -82,6 +82,9 @@ class YouTubeIt
|
|
82
82
|
# *Time*:: When the video's was uploaded.
|
83
83
|
attr_reader :uploaded_at
|
84
84
|
|
85
|
+
# *Time*:: When the video's was recorded.
|
86
|
+
attr_reader :recorded_at
|
87
|
+
|
85
88
|
# *Array*:: A array of YouTubeIt::Model::Category objects that describe the videos categories.
|
86
89
|
attr_reader :categories
|
87
90
|
|
data/lib/youtube_it/parser.rb
CHANGED
@@ -17,6 +17,11 @@ class YouTubeIt
|
|
17
17
|
parse_content @content
|
18
18
|
end
|
19
19
|
|
20
|
+
def parse_single_entry
|
21
|
+
doc = Nokogiri::XML(@content)
|
22
|
+
parse_entry(doc.at("entry") || doc)
|
23
|
+
end
|
24
|
+
|
20
25
|
def parse_videos
|
21
26
|
doc = Nokogiri::XML(@content)
|
22
27
|
videos = []
|
@@ -72,7 +77,7 @@ class YouTubeIt
|
|
72
77
|
|
73
78
|
def parse_content(content)
|
74
79
|
xml = Nokogiri::XML(content.body)
|
75
|
-
entry = xml.at("
|
80
|
+
entry = xml.at("feed") || xml.at("entry")
|
76
81
|
YouTubeIt::Model::Playlist.new(
|
77
82
|
:title => entry.at("title") && entry.at("title").text,
|
78
83
|
:summary => ((entry.at("summary") || entry.at_xpath("media:group").at_xpath("media:description")).text rescue nil),
|
@@ -376,6 +381,7 @@ class YouTubeIt
|
|
376
381
|
published_at = entry.at("published") ? Time.parse(entry.at("published").text) : nil
|
377
382
|
uploaded_at = entry.at_xpath("media:group/yt:uploaded") ? Time.parse(entry.at_xpath("media:group/yt:uploaded").text) : nil
|
378
383
|
updated_at = entry.at("updated") ? Time.parse(entry.at("updated").text) : nil
|
384
|
+
recorded_at = entry.at_xpath("yt:recorded") ? Time.parse(entry.at_xpath("yt:recorded").text) : nil
|
379
385
|
|
380
386
|
# parse the category and keyword lists
|
381
387
|
categories = []
|
@@ -479,7 +485,6 @@ class YouTubeIt
|
|
479
485
|
|
480
486
|
comment_feed = entry.at_xpath('gd:comments/gd:feedLink[@rel="http://gdata.youtube.com/schemas/2007#comments"]')
|
481
487
|
comment_count = comment_feed ? comment_feed['countHint'].to_i : 0
|
482
|
-
#puts comment_count.inspect
|
483
488
|
|
484
489
|
access_control = entry.xpath('yt:accessControl').map do |e|
|
485
490
|
{ e['action'] => e['permission'] }
|
@@ -515,6 +520,7 @@ class YouTubeIt
|
|
515
520
|
:published_at => published_at,
|
516
521
|
:updated_at => updated_at,
|
517
522
|
:uploaded_at => uploaded_at,
|
523
|
+
:recorded_at => recorded_at,
|
518
524
|
:categories => categories,
|
519
525
|
:keywords => keywords,
|
520
526
|
:title => title,
|
@@ -25,6 +25,8 @@ class YouTubeIt
|
|
25
25
|
attr_reader :uploader
|
26
26
|
attr_reader :region
|
27
27
|
attr_reader :paid_content
|
28
|
+
attr_reader :location
|
29
|
+
attr_reader :location_radius
|
28
30
|
|
29
31
|
|
30
32
|
def initialize(params={})
|
@@ -35,7 +37,7 @@ class YouTubeIt
|
|
35
37
|
@response_format, @video_format,
|
36
38
|
@safe_search, @author, @lang,
|
37
39
|
@duration, @time, @hd, @caption,
|
38
|
-
@uploader, @region, @paid_content = nil
|
40
|
+
@uploader, @region, @location, @location_radius, @paid_content = nil
|
39
41
|
@url = base_url
|
40
42
|
@dev_key = params[:dev_key] if params[:dev_key]
|
41
43
|
|
@@ -80,6 +82,8 @@ class YouTubeIt
|
|
80
82
|
'hd' => @hd,
|
81
83
|
'caption' => @caption,
|
82
84
|
'region' => @region,
|
85
|
+
'location' => @location,
|
86
|
+
'location-radius' => @location_radius,
|
83
87
|
'paid-content' => @paid_content,
|
84
88
|
'uploader' => @uploader
|
85
89
|
}
|
@@ -195,8 +195,8 @@ class YouTubeIt
|
|
195
195
|
comment_body = comment_xml_for(:comment => comment, :reply_to => reply_to_url(video_id, reply_to))
|
196
196
|
comment_url = "/feeds/api/videos/%s/comments" % video_id
|
197
197
|
response = yt_session.post(comment_url, comment_body)
|
198
|
-
|
199
|
-
return {:code => response.status, :body => response.body}
|
198
|
+
comment = YouTubeIt::Parser::CommentsFeedParser.new(response.body).parse_single_entry
|
199
|
+
return {:code => response.status, :body => response.body, :comment => comment}
|
200
200
|
end
|
201
201
|
|
202
202
|
def delete_comment(video_id, comment_id)
|
@@ -238,26 +238,26 @@ class YouTubeIt
|
|
238
238
|
def profiles(usernames_to_fetch)
|
239
239
|
usernames_to_fetch.each_slice(50).map do |usernames|
|
240
240
|
post = Nokogiri::XML <<-BATCH
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
<batch:operation type="query" />
|
241
|
+
<feed
|
242
|
+
xmlns='http://www.w3.org/2005/Atom'
|
243
|
+
xmlns:media='http://search.yahoo.com/mrss/'
|
244
|
+
xmlns:batch='http://schemas.google.com/gdata/batch'
|
245
|
+
xmlns:yt='http://gdata.youtube.com/schemas/2007'>
|
247
246
|
</feed>
|
248
247
|
BATCH
|
249
248
|
usernames.each do |username|
|
250
249
|
post.at('feed').add_child <<-ENTRY
|
251
|
-
<entry
|
250
|
+
<entry>
|
251
|
+
<batch:operation type="query" />
|
252
252
|
<id>#{profile_url(username)}</id>
|
253
253
|
<batch:id>#{username}</batch:id>
|
254
254
|
</entry>
|
255
255
|
ENTRY
|
256
256
|
end
|
257
257
|
|
258
|
-
post_body = ''
|
258
|
+
post_body = StringIO.new('')
|
259
259
|
post.write_to( post_body, :indent => 2 )
|
260
|
-
post_body_io = StringIO.new(post_body)
|
260
|
+
post_body_io = StringIO.new(post_body.string)
|
261
261
|
|
262
262
|
response = yt_session.post('feeds/api/users/batch', post_body_io )
|
263
263
|
YouTubeIt::Parser::BatchProfileFeedParser.new(response).parse
|
@@ -450,8 +450,9 @@ class YouTubeIt
|
|
450
450
|
end
|
451
451
|
|
452
452
|
def parse_upload_error_from(string)
|
453
|
-
|
454
|
-
|
453
|
+
xml = Nokogiri::XML(string).at('errors')
|
454
|
+
if xml
|
455
|
+
xml.css("error").inject('') do |all_faults, error|
|
455
456
|
if error.at("internalReason")
|
456
457
|
msg_error = error.at("internalReason").text
|
457
458
|
elsif error.at("location")
|
@@ -462,7 +463,7 @@ class YouTubeIt
|
|
462
463
|
code = error.at("code").text if error.at("code")
|
463
464
|
all_faults + sprintf("%s: %s\n", msg_error, code)
|
464
465
|
end
|
465
|
-
|
466
|
+
else
|
466
467
|
string[/<TITLE>(.+)<\/TITLE>/, 1] || string
|
467
468
|
end
|
468
469
|
end
|
data/lib/youtube_it/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: youtube_it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-07-12 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: nokogiri
|
18
|
-
requirement: &
|
18
|
+
requirement: &70273407416220 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: 1.5.2
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *70273407416220
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: oauth
|
29
|
-
requirement: &
|
29
|
+
requirement: &70273407413640 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: 0.4.4
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *70273407413640
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: oauth2
|
40
|
-
requirement: &
|
40
|
+
requirement: &70273407413140 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0.6'
|
46
46
|
type: :runtime
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *70273407413140
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: simple_oauth
|
51
|
-
requirement: &
|
51
|
+
requirement: &70273407412680 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ~>
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: 0.1.5
|
57
57
|
type: :runtime
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *70273407412680
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: faraday
|
62
|
-
requirement: &
|
62
|
+
requirement: &70273407412060 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ~>
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '0.8'
|
68
68
|
type: :runtime
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *70273407412060
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: builder
|
73
|
-
requirement: &
|
73
|
+
requirement: &70273407411540 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,7 +78,7 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *70273407411540
|
82
82
|
description: Upload, delete, update, comment on youtube videos all from one gem.
|
83
83
|
email:
|
84
84
|
- kylejginavan@gmail.com
|