youtube_it 2.1.5 → 2.1.7

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 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