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 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.remove_video_from_playlist(playlist_id, playlist_entry_id)
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.remove_video_from_watchlater(watchlater_entry_id)
225
+ $ client.delete_video_from_watchlater(watchlater_entry_id)
222
226
 
223
227
 
224
228
  List Related Videos
@@ -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 |session|
314
- response = session.get2('https://%s' % session_token_url,session_token_header).body
315
- end
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 |session|
324
- response = session.get2('https://%s' % session_token_url,session_token_header).code
325
- end
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 |session|
334
- response = session.get2('https://%s' % session_token_url,session_token_header)
338
+ response = http_connection.get do |req|
339
+ req.url session_token_url
340
+ req.headers = session_token_header
335
341
  end
336
- {:code => response.code, :body => response.body }
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
- http = Net::HTTP.new("www.google.com")
353
- http.set_debug_output(logger) if @http_debugging
354
- http.start do |session|
355
- yield(session)
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
- @oauth_client ||= ::OAuth2::Client.new(@client_id, @client_secret,
451
- :site => "https://accounts.google.com",
452
- :authorize_url => '/o/oauth2/auth',
453
- :token_url => '/o/oauth2/token')
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
- begin
5
- REXML::Document.new(string).elements["//errors"].inject('') do | all_faults, error|
6
- if error.elements["internalReason"]
7
- msg_error = error.elements["internalReason"].text
8
- elsif error.elements["location"]
9
- msg_error = error.elements["location"].text[/media:group\/media:(.*)\/text\(\)/,1]
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.elements["code"].text if error.elements["code"]
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
- rescue
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
 
@@ -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("entry") || xml.at("feed")
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
- <?xml version="1.0" encoding="UTF-8"?>
242
- <feed 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'>
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 xmlns:batch='http://schemas.google.com/gdata/batch'>
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
- begin
454
- Nokogiri::XML(string).xpath("//errors").inject('') do | all_faults, error|
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
- rescue
466
+ else
466
467
  string[/<TITLE>(.+)<\/TITLE>/, 1] || string
467
468
  end
468
469
  end
@@ -1,4 +1,4 @@
1
1
  class YouTubeIt
2
- VERSION = '2.1.5'
2
+ VERSION = '2.1.7'
3
3
  end
4
4
 
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.5
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-05-29 00:00:00.000000000 Z
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: &70301580031620 !ruby/object:Gem::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: *70301580031620
26
+ version_requirements: *70273407416220
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: oauth
29
- requirement: &70301580031120 !ruby/object:Gem::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: *70301580031120
37
+ version_requirements: *70273407413640
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: oauth2
40
- requirement: &70301580030660 !ruby/object:Gem::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: *70301580030660
48
+ version_requirements: *70273407413140
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: simple_oauth
51
- requirement: &70301580030200 !ruby/object:Gem::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: *70301580030200
59
+ version_requirements: *70273407412680
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: faraday
62
- requirement: &70301580029740 !ruby/object:Gem::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: *70301580029740
70
+ version_requirements: *70273407412060
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: builder
73
- requirement: &70301580029280 !ruby/object:Gem::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: *70301580029280
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