yt 0.11.3 → 0.11.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +23 -1
  4. data/lib/yt.rb +1 -0
  5. data/lib/yt/actions/base.rb +12 -0
  6. data/lib/yt/actions/list.rb +21 -3
  7. data/lib/yt/collections/annotations.rb +0 -6
  8. data/lib/yt/collections/assets.rb +0 -4
  9. data/lib/yt/collections/authentications.rb +2 -2
  10. data/lib/yt/collections/claims.rb +1 -5
  11. data/lib/yt/collections/content_details.rb +2 -4
  12. data/lib/yt/collections/content_owner_details.rb +2 -5
  13. data/lib/yt/collections/content_owners.rb +4 -0
  14. data/lib/yt/collections/device_flows.rb +3 -2
  15. data/lib/yt/collections/ids.rb +2 -2
  16. data/lib/yt/collections/live_streaming_details.rb +2 -5
  17. data/lib/yt/collections/ownerships.rb +2 -2
  18. data/lib/yt/collections/partnered_channels.rb +1 -1
  19. data/lib/yt/collections/policies.rb +0 -4
  20. data/lib/yt/collections/ratings.rb +2 -2
  21. data/lib/yt/collections/references.rb +0 -4
  22. data/lib/yt/collections/resources.rb +2 -24
  23. data/lib/yt/collections/resumable_sessions.rb +2 -2
  24. data/lib/yt/collections/snippets.rb +10 -11
  25. data/lib/yt/collections/statistics_sets.rb +2 -4
  26. data/lib/yt/collections/statuses.rb +7 -14
  27. data/lib/yt/collections/subscriptions.rb +2 -6
  28. data/lib/yt/collections/user_infos.rb +0 -6
  29. data/lib/yt/collections/videos.rb +16 -10
  30. data/lib/yt/models/playlist.rb +0 -9
  31. data/lib/yt/models/request.rb +11 -3
  32. data/lib/yt/models/resource.rb +8 -13
  33. data/lib/yt/models/video.rb +0 -10
  34. data/lib/yt/version.rb +1 -1
  35. data/spec/requests/as_account/account_spec.rb +11 -1
  36. data/spec/requests/as_account/channel_spec.rb +8 -0
  37. data/spec/requests/as_server_app/videos_spec.rb +8 -0
  38. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f14047bf293cc77254c5b1568b77772d9162679f
4
- data.tar.gz: 3ceaca9cb7e02268d70c8f74764d94cf699a64a4
3
+ metadata.gz: d4252625265d920e49c56abd24211d37be9881ba
4
+ data.tar.gz: 620dceb9f5722aa8108a06dcc5bc665386a3d1ee
5
5
  SHA512:
6
- metadata.gz: 6e4180dc908977fda2d25ed4f5915db585ac4986d4a1027ec8187297d8c3107813ed724362531805252beee2bdffa76307b5a3261c4974a7719762642887063a
7
- data.tar.gz: 5c7963ef875961822546326461a58f3d77efce3cef08886bccaae8d53597134bc8eee6bc3751ee0d733f16ebd93c38d5c23b6415e72166063ed213d3f5b81f8d
6
+ metadata.gz: 529db7f3f2bc51ccbabd6a42c320406b87f1320877fe182b04f86d087febc406d65fcd9baa16def7dcfd49997cf6394f149634b26d8dcd9172cf19f71b45363e
7
+ data.tar.gz: c6357576d740ca80c940392f6794f739715703a660bdc9a1987ea90a68b8ce7d5ef47013ea63e0d85af5175be69684d88bd28ddb6c90da1bca2a822a197b7868
@@ -6,6 +6,11 @@ For more information about changelogs, check
6
6
  [Keep a Changelog](http://keepachangelog.com) and
7
7
  [Vandamme](http://tech-angels.github.io/vandamme).
8
8
 
9
+ ## 0.11.4 - 2014-08-27
10
+
11
+ * [ENHANCEMENT] Add Video search even by id, chart or rating
12
+ * [FEATURE] Add `ActiveSupport::Notification` to inspect HTTP requests
13
+
9
14
  ## 0.11.3 - 2014-08-21
10
15
 
11
16
  * [FEATURE] Add `update` method to Asset model
data/README.md CHANGED
@@ -41,7 +41,7 @@ To install on your system, run
41
41
 
42
42
  To use inside a bundled Ruby project, add this line to the Gemfile:
43
43
 
44
- gem 'yt', '~> 0.11.3'
44
+ gem 'yt', '~> 0.11.4'
45
45
 
46
46
  Since the gem follows [Semantic Versioning](http://semver.org),
47
47
  indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
@@ -74,6 +74,7 @@ account.videos.first #=> #<Yt::Models::Video @id=...>
74
74
 
75
75
  account.upload_video 'my_video.mp4', title: 'My new video', privacy_status: 'private'
76
76
  account.upload_video 'http://example.com/remote.m4v', title: 'My other video', tags: ['music']
77
+
77
78
  ```
78
79
 
79
80
  *The methods above require to be authenticated as a YouTube account (see below).*
@@ -422,6 +423,8 @@ Use [Yt::Collections::Videos](http://rubydoc.info/github/Fullscreen/yt/master/Yt
422
423
  videos = Yt::Collections::Videos.new
423
424
  videos.where(order: 'viewCount').first.title #=> "PSY - GANGNAM STYLE"
424
425
  videos.where(q: 'Fullscreen CreatorPlatform', safe_search: 'none').size #=> 324
426
+ videos.where(chart: 'mostPopular', video_category_id: 44).first.title #=> "SINISTER - Trailer"
427
+ videos.where(id: 'MESycYJytkU,invalid').map(&:title) #=> ["Fullscreen Creator Platform"]
425
428
  ```
426
429
 
427
430
  *The methods above do not require authentication.*
@@ -511,6 +514,25 @@ ad_options.update ad_formats: %w(standard_instream long) #=> true
511
514
 
512
515
  *The methods above require to be authenticated as the video’s content owner (see below).*
513
516
 
517
+ Instrumentation
518
+ ===============
519
+
520
+ Yt leverages [Active Support Instrumentation](http://edgeguides.rubyonrails.org/active_support_instrumentation.html) to provide a hook which developers can use to be notified when HTTP requests to YouTube are made. This hook may be used to track the number of requests over time, monitor quota usage, provide an audit trail, or track how long a specific request takes to complete.
521
+
522
+ Subscribe to the `request.yt` notification within your application:
523
+
524
+ ```ruby
525
+ ActiveSupport::Notifications.subscribe 'request.yt' do |*args|
526
+ event = ActiveSupport::Notifications::Event.new(*args)
527
+
528
+ event.payload[:request_uri] #=> #<URI::HTTPS URL:https://www.googleapis.com/youtube/v3/channels?id=UCxO1tY8h1AhOz0T4ENwmpow&part=snippet>
529
+ event.payload[:method] #=> :get
530
+ event.payload[:response] #=> #<Net::HTTPOK 200 OK readbody=true>
531
+
532
+ event.end #=> 2014-08-22 16:57:17 -0700
533
+ event.duration #=> 141.867 (ms)
534
+ end
535
+ ```
514
536
 
515
537
  Configuring your app
516
538
  ====================
data/lib/yt.rb CHANGED
@@ -8,6 +8,7 @@ require 'yt/models/playlist'
8
8
  require 'yt/models/playlist_item'
9
9
  require 'yt/models/video'
10
10
  require 'yt/models/ownership'
11
+ require 'yt/models/advertising_options_set'
11
12
 
12
13
  # An object-oriented Ruby client for YouTube.
13
14
  # Helps creating applications that need to interact with YouTube objects.
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module Yt
2
3
  module Actions
3
4
  # Abstract module that contains methods common to every action
@@ -14,6 +15,17 @@ module Yt
14
15
  def underscore(value)
15
16
  value.to_s.underscore.to_sym
16
17
  end
18
+
19
+ # @return [Hash] the original hash with angle brackets characters in its
20
+ # values replaced with similar Unicode characters accepted by Youtube.
21
+ # @see https://support.google.com/youtube/answer/57404?hl=en
22
+ def sanitize_brackets!(source)
23
+ case source
24
+ when String then source.gsub('<', '‹').gsub('>', '›')
25
+ when Array then source.map{|string| sanitize_brackets! string}
26
+ when Hash then source.each{|k,v| source[k] = sanitize_brackets! v}
27
+ end
28
+ end
17
29
  end
18
30
  end
19
31
  end
@@ -42,10 +42,28 @@ module Yt
42
42
  @items[(@last_index +=1) -1]
43
43
  end
44
44
 
45
- # To be overriden by the subclasses
45
+ def resource_class
46
+ resource_name = list_resources.singularize
47
+ require "yt/models/#{resource_name.underscore}"
48
+ "Yt::Models::#{resource_name}".constantize
49
+ end
50
+
51
+ # @return [resource_class] a new resource initialized with one
52
+ # of the items returned by asking YouTube for a list of resources.
53
+ # Can be overwritten by subclasses that initialize instance with
54
+ # a different set of parameters.
46
55
  def new_item(data)
56
+ resource_class.new attributes_for_new_item(data)
57
+ end
58
+
59
+ # @private
60
+ # Can be overwritten by subclasses that initialize instance with
61
+ # a different set of parameters.
62
+ def attributes_for_new_item(data)
63
+ {data: data, auth: @auth}
47
64
  end
48
65
 
66
+
49
67
  def more_pages?
50
68
  @last_index.zero? || !@page_token.nil?
51
69
  end
@@ -74,7 +92,7 @@ module Yt
74
92
  end
75
93
 
76
94
  def list_params
77
- path = "/youtube/v3/#{list_resources.to_s.demodulize.camelize :lower}"
95
+ path = "/youtube/v3/#{list_resources.camelize :lower}"
78
96
 
79
97
  {}.tap do |params|
80
98
  params[:method] = :get
@@ -89,7 +107,7 @@ module Yt
89
107
  end
90
108
 
91
109
  def list_resources
92
- self.class
110
+ self.class.to_s.demodulize
93
111
  end
94
112
  end
95
113
  end
@@ -12,12 +12,6 @@ module Yt
12
12
 
13
13
  private
14
14
 
15
- # @return [Yt::Models::Annotation] a new annotation initialized with one
16
- # of the items returned by asking YouTube for a list of annotations.
17
- def new_item(data)
18
- Yt::Annotation.new data: data
19
- end
20
-
21
15
  # @return [Hash] the parameters to submit to YouTube to list annotations.
22
16
  # @note YouTube does not provide an API endpoint to get annotations for
23
17
  # a video, so we use an "old-style" URL that YouTube still maintains.
@@ -16,10 +16,6 @@ module Yt
16
16
 
17
17
  private
18
18
 
19
- def new_item(data)
20
- Yt::Asset.new data: data, auth: @auth
21
- end
22
-
23
19
  # @return [Hash] the parameters to submit to YouTube to add a asset.
24
20
  # @see https://developers.google.com/youtube/partner/docs/v1/assets/insert
25
21
  def insert_params
@@ -8,9 +8,9 @@ module Yt
8
8
 
9
9
  private
10
10
 
11
- def new_item(data)
11
+ def attributes_for_new_item(data)
12
12
  data['refresh_token'] ||= auth_params[:refresh_token]
13
- Yt::Authentication.new data
13
+ data
14
14
  end
15
15
 
16
16
  def list_params
@@ -17,10 +17,6 @@ module Yt
17
17
 
18
18
  private
19
19
 
20
- def new_item(data)
21
- Yt::Claim.new data: data, auth: @auth
22
- end
23
-
24
20
  # @return [Hash] the parameters to submit to YouTube to list claims
25
21
  # administered by the content owner.
26
22
  # @see https://developers.google.com/youtube/partner/docs/v1/claims/list
@@ -45,7 +41,7 @@ module Yt
45
41
  end
46
42
 
47
43
  # @private
48
- # @todo: This is the only place outside of base.rb where @where_params
44
+ # @todo: This is one of two places outside of base.rb where @where_params
49
45
  # is accessed; it should be replaced with a filter on params instead.
50
46
  def claims_path
51
47
  @where_params ||= {}
@@ -7,10 +7,8 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::ContentDetail] a new content detail initialized
11
- # with one of the items returned by asking YouTube for a list of them.
12
- def new_item(data)
13
- Yt::ContentDetail.new data: data['contentDetails']
10
+ def attributes_for_new_item(data)
11
+ {data: data['contentDetails']}
14
12
  end
15
13
 
16
14
  # @return [Hash] the parameters to submit to YouTube to get the
@@ -7,11 +7,8 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::ContentOwnerDetail] a new content detail
11
- # initialized with one of the items returned by asking YouTube for a
12
- # list of them.
13
- def new_item(data)
14
- Yt::ContentOwnerDetail.new data: data['contentOwnerDetails']
10
+ def attributes_for_new_item(data)
11
+ {data: data['contentOwnerDetails']}
15
12
  end
16
13
 
17
14
  # @return [Hash] the parameters to submit to YouTube to get the
@@ -10,6 +10,10 @@ module Yt
10
10
 
11
11
  private
12
12
 
13
+ def attributes_for_new_item(data)
14
+ {owner_name: data['id'], authentication: @auth.authentication}
15
+ end
16
+
13
17
  def new_item(data)
14
18
  Yt::ContentOwner.new owner_name: data['id'], authentication: @auth.authentication
15
19
  end
@@ -8,8 +8,9 @@ module Yt
8
8
 
9
9
  private
10
10
 
11
- def new_item(data)
12
- Yt::DeviceFlow.new data: data
11
+ # This overrides the parent mehthod defined in Authentications
12
+ def attributes_for_new_item(data)
13
+ {data: data}
13
14
  end
14
15
 
15
16
  def list_params
@@ -7,8 +7,8 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- def new_item(data)
11
- Yt::Id.new data['id']
10
+ def attributes_for_new_item(data)
11
+ data['id']
12
12
  end
13
13
 
14
14
  def list_params
@@ -7,11 +7,8 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::LiveStreamingDetail] a new live streaming detail
11
- # initialized with one of the items returned by asking YouTube for a
12
- # list of them.
13
- def new_item(data)
14
- Yt::LiveStreamingDetail.new data: data['liveStreamingDetails']
10
+ def attributes_for_new_item(data)
11
+ {data: data['liveStreamingDetails']}
15
12
  end
16
13
 
17
14
  # @return [Hash] the parameters to submit to YouTube to get the
@@ -10,8 +10,8 @@ module Yt
10
10
 
11
11
  private
12
12
 
13
- def new_item(data)
14
- Yt::Ownership.new data: data, asset_id: @parent.id, auth: @auth
13
+ def attributes_for_new_item(data)
14
+ {data: data, asset_id: @parent.id, auth: @auth}
15
15
  end
16
16
 
17
17
  # @return [Hash] the parameters to submit to YouTube to get ownerships.
@@ -21,7 +21,7 @@ module Yt
21
21
  # @note Partnered Channels overwrites +list_resources+ since the endpoint
22
22
  # to hit is 'channels', not 'partnered_channels'.
23
23
  def list_resources
24
- self.class.superclass
24
+ self.class.superclass.to_s.demodulize
25
25
  end
26
26
  end
27
27
  end
@@ -10,10 +10,6 @@ module Yt
10
10
 
11
11
  private
12
12
 
13
- def new_item(data)
14
- Yt::Policy.new data: data
15
- end
16
-
17
13
  # @return [Hash] the parameters to submit to YouTube to list policies
18
14
  # saved by the content owner.
19
15
  # @see https://developers.google.com/youtube/partner/docs/v1/policies/list
@@ -7,8 +7,8 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- def new_item(data)
11
- Yt::Rating.new rating: data['rating'], video_id: @parent.id, auth: @auth
10
+ def attributes_for_new_item(data)
11
+ {rating: data['rating'], video_id: @parent.id, auth: @auth}
12
12
  end
13
13
 
14
14
  def list_params
@@ -16,10 +16,6 @@ module Yt
16
16
 
17
17
  private
18
18
 
19
- def new_item(data)
20
- Yt::Reference.new data: data, auth: @auth
21
- end
22
-
23
19
  # @return [Hash] the parameters to submit to YouTube to add a reference.
24
20
  # @see https://developers.google.com/youtube/partner/docs/v1/references/insert
25
21
  def insert_params
@@ -17,25 +17,14 @@ module Yt
17
17
 
18
18
  private
19
19
 
20
- # @return [resource_class] a new resource item initialized with
21
- # one of the items returned by asking YouTube for a list of items.
22
- # @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
23
- # @see https://developers.google.com/youtube/v3/docs/playlists#resource
24
- # @see https://developers.google.com/youtube/v3/docs/channels#resource
25
- def new_item(data)
26
- resource_class.new id: data['id'], snippet: data['snippet'], status: data['status'], auth: @auth
20
+ def attributes_for_new_item(data)
21
+ {id: data['id'], snippet: data['snippet'], status: data['status'], auth: @auth}
27
22
  end
28
23
 
29
24
  def resources_params
30
25
  {max_results: 50, part: 'snippet,status'}
31
26
  end
32
27
 
33
- def resource_class
34
- resource_name = list_resources.name.demodulize.singularize
35
- require "yt/models/#{resource_name.underscore}"
36
- "Yt::Models::#{resource_name}".constantize
37
- end
38
-
39
28
  def build_insert_body(attributes = {})
40
29
  {}.tap do |body|
41
30
  insert_parts.each do |name, part|
@@ -59,17 +48,6 @@ module Yt
59
48
  (part[:keys] & attributes.keys).any?
60
49
  end
61
50
 
62
- # @return [Hash] the original hash with angle brackets characters in its
63
- # values replaced with similar Unicode characters accepted by Youtube.
64
- # @see https://support.google.com/youtube/answer/57404?hl=en
65
- def sanitize_brackets!(source)
66
- case source
67
- when String then source.gsub('<', '‹').gsub('>', '›')
68
- when Array then source.map{|string| sanitize_brackets! string}
69
- when Hash then source.each{|k,v| source[k] = sanitize_brackets! v}
70
- end
71
- end
72
-
73
51
  def camelize(value)
74
52
  value.to_s.camelize(:lower).to_sym
75
53
  end
@@ -34,8 +34,8 @@ module Yt
34
34
 
35
35
  private
36
36
 
37
- def new_item(data)
38
- Yt::ResumableSession.new url: data['Location'], headers: @headers, auth: @auth
37
+ def attributes_for_new_item(data)
38
+ {url: data['Location'], headers: @headers, auth: @auth}
39
39
  end
40
40
 
41
41
  def insert_params
@@ -7,27 +7,26 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::Snippet] a new snippet initialized with
11
- # one of the items returned by asking YouTube for a list of snippets.
12
- def new_item(data)
13
- Yt::Snippet.new data: data['snippet'], auth: @auth
10
+ def attributes_for_new_item(data)
11
+ {data: data['snippet'], auth: @auth}
14
12
  end
15
13
 
14
+ # # @return [Yt::Models::Snippet] a new snippet initialized with
15
+ # # one of the items returned by asking YouTube for a list of snippets.
16
+ # def new_item(data)
17
+ # Yt::Snippet.new data: data['snippet'], auth: @auth
18
+ # end
19
+
16
20
  # @return [Hash] the parameters to submit to YouTube to get the
17
21
  # snippet of a resource, for instance a channel.
18
22
  # @see https://developers.google.com/youtube/v3/docs/channels#resource
19
23
  def list_params
24
+ endpoint = @parent.class.to_s.pluralize.demodulize.camelize :lower
20
25
  super.tap do |params|
26
+ params[:path] = "/youtube/v3/#{endpoint}"
21
27
  params[:params] = {id: @parent.id, part: 'snippet'}
22
28
  end
23
29
  end
24
-
25
- # @private
26
- # @note Snippets overrides +list_resources+ since the endpoint is not
27
- # '/snippets' but the endpoint related to the snippet’s resource.
28
- def list_resources
29
- @parent.class.to_s.pluralize
30
- end
31
30
  end
32
31
  end
33
32
  end
@@ -7,10 +7,8 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::StatisticsSet] a new statistics set initialized
11
- # with one of the items returned by asking YouTube for a list of them.
12
- def new_item(data)
13
- Yt::StatisticsSet.new data: data['statistics']
10
+ def attributes_for_new_item(data)
11
+ {data: data['statistics']}
14
12
  end
15
13
 
16
14
  # @return [Hash] the parameters to submit to YouTube to get the
@@ -7,26 +7,19 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::Status] a new status initialized with
11
- # one of the items returned by asking YouTube for a list of statuses,
12
- # of a resource, for instance a channel.
13
- # @see https://developers.google.com/youtube/v3/docs/playlists#resource
14
- def new_item(data)
15
- Yt::Status.new data: data['status']
10
+ def attributes_for_new_item(data)
11
+ {data: data['status']}
16
12
  end
17
13
 
18
14
  # @return [Hash] the parameters to submit to YouTube to get the status
19
15
  # of a resource, for instance a channel.
20
16
  # @see https://developers.google.com/youtube/v3/docs/channels/list
21
17
  def list_params
22
- super.tap{|params| params[:params] = {id: @parent.id, part: 'status'}}
23
- end
24
-
25
- # @private
26
- # @note Statuses overrides +list_resources+ since the endpoint is not
27
- # '/statuses' but the endpoint related to the snippet’s resource.
28
- def list_resources
29
- @parent.class.to_s.pluralize
18
+ endpoint = @parent.class.to_s.pluralize.demodulize.camelize :lower
19
+ super.tap do |params|
20
+ params[:path] = "/youtube/v3/#{endpoint}"
21
+ params[:params] = {id: @parent.id, part: 'status'}
22
+ end
30
23
  end
31
24
  end
32
25
  end
@@ -21,12 +21,8 @@ module Yt
21
21
 
22
22
  private
23
23
 
24
- # @return [Yt::Models::Subscription] a new subscription initialized with
25
- # one of the items returned by asking YouTube for a list of
26
- # subscriptions to a channel.
27
- # @see https://developers.google.com/youtube/v3/docs/subscriptions#resource
28
- def new_item(data)
29
- Yt::Subscription.new id: data['id'], auth: @auth
24
+ def attributes_for_new_item(data)
25
+ {id: data['id'], auth: @auth}
30
26
  end
31
27
 
32
28
  # @note Google API must have some caching layer by which if we try to
@@ -7,12 +7,6 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::UserInfo] a new user info initialized with
11
- # one of the items returned by asking YouTube for a list of user infos.
12
- def new_item(data)
13
- Yt::UserInfo.new data: data
14
- end
15
-
16
10
  # @return [Hash] the parameters to submit to YouTube to get the
17
11
  # user info of an account
18
12
  # @see https://developers.google.com/+/api/latest/people/getOpenIdConnect
@@ -11,16 +11,9 @@ module Yt
11
11
 
12
12
  private
13
13
 
14
- # @return [Yt::Models::Video] a new video initialized with one of
15
- # the items returned by asking YouTube for a list of videos.
16
- # According to the documentation, tags are only visible to the video's
17
- # uploader, and are not returned when search for all the videos of an
18
- # account. Instead, a separate call to Videos#list is required. Setting
19
- # +includes_tags+ to +false+ makes sure that `video.tags` will do this.
20
- # @see https://developers.google.com/youtube/v3/docs/videos#resource
21
- def new_item(data)
14
+ def attributes_for_new_item(data)
22
15
  snippet = data.fetch('snippet', {}).merge includes_tags: false
23
- Yt::Video.new id: data['id']['videoId'], snippet: snippet, auth: @auth
16
+ {id: data['id']['videoId'], snippet: snippet, auth: @auth}
24
17
  end
25
18
 
26
19
  # @return [Hash] the parameters to submit to YouTube to list videos.
@@ -28,7 +21,7 @@ module Yt
28
21
  def list_params
29
22
  super.tap do |params|
30
23
  params[:params] = videos_params
31
- params[:path] = '/youtube/v3/search'
24
+ params[:path] = videos_path
32
25
  end
33
26
  end
34
27
 
@@ -58,6 +51,19 @@ module Yt
58
51
  apply_where_params! params
59
52
  end
60
53
  end
54
+
55
+ # @private
56
+ # @todo: This is one of two places outside of base.rb where @where_params
57
+ # is accessed; it should be replaced with a filter on params instead.
58
+ # @see https://developers.google.com/youtube/v3/docs/videos/list
59
+ def videos_path
60
+ @where_params ||= {}
61
+ if @parent.nil? && (@where_params.keys & [:id, :chart]).any?
62
+ '/youtube/v3/videos'
63
+ else
64
+ '/youtube/v3/search'
65
+ end
66
+ end
61
67
  end
62
68
  end
63
69
  end
@@ -23,15 +23,6 @@ module Yt
23
23
  !exists?
24
24
  end
25
25
 
26
- def update(attributes = {})
27
- super attributes do |data|
28
- @id = data['id']
29
- @snippet = Snippet.new data: data['snippet'] if data['snippet']
30
- @status = Status.new data: data['status'] if data['status']
31
- true
32
- end
33
- end
34
-
35
26
  def exists?
36
27
  !@id.nil?
37
28
  end
@@ -51,13 +51,21 @@ module Yt
51
51
  private
52
52
 
53
53
  def response
54
- @response ||= Net::HTTP.start(*net_http_options) do |http|
55
- http.request http_request
56
- end
54
+ @response ||= send_http_request
57
55
  rescue OpenSSL::SSL::SSLError, Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::ECONNRESET => e
58
56
  @response ||= e
59
57
  end
60
58
 
59
+ def send_http_request
60
+ ActiveSupport::Notifications.instrument 'request.yt' do |payload|
61
+ payload[:method] = @method
62
+ payload[:request_uri] = uri
63
+ payload[:response] = Net::HTTP.start(*net_http_options) do |http|
64
+ http.request http_request
65
+ end
66
+ end
67
+ end
68
+
61
69
  def http_request
62
70
  @http_request ||= net_http_class.new(uri.request_uri).tap do |request|
63
71
  set_headers! request
@@ -32,13 +32,19 @@ module Yt
32
32
  @url.username if @url
33
33
  end
34
34
 
35
- def update(attributes = {}, &block)
35
+ def update(attributes = {})
36
36
  underscore_keys! attributes
37
37
  body = build_update_body attributes
38
38
  params = {part: body.keys.join(',')}
39
- do_update(params: params, body: body.merge(id: @id), &block)
39
+ do_update params: params, body: body.merge(id: @id) do |data|
40
+ @id = data['id']
41
+ @snippet = Snippet.new data: data['snippet'] if data['snippet']
42
+ @status = Status.new data: data['status'] if data['status']
43
+ true
44
+ end
40
45
  end
41
46
 
47
+
42
48
  private
43
49
 
44
50
  # @return [Hash] the parameters to submit to YouTube to update a playlist.
@@ -80,17 +86,6 @@ module Yt
80
86
  part[:required] || (part[:keys] & attributes.keys).any?
81
87
  end
82
88
 
83
- # @return [Hash] the original hash with angle brackets characters in its
84
- # values replaced with similar Unicode characters accepted by Youtube.
85
- # @see https://support.google.com/youtube/answer/57404?hl=en
86
- def sanitize_brackets!(source)
87
- case source
88
- when String then source.gsub('<', '‹').gsub('>', '›')
89
- when Array then source.map{|string| sanitize_brackets! string}
90
- when Hash then source.each{|k,v| source[k] = sanitize_brackets! v}
91
- end
92
- end
93
-
94
89
  def camelize(value)
95
90
  value.to_s.camelize(:lower).to_sym
96
91
  end
@@ -96,16 +96,6 @@ module Yt
96
96
  !@id.nil?
97
97
  end
98
98
 
99
- def update(attributes = {})
100
- super attributes do |data|
101
- @id = data['id']
102
- @snippet = Snippet.new data: data['snippet'] if data['snippet']
103
- @status = Status.new data: data['status'] if data['status']
104
- true
105
- end
106
- end
107
-
108
-
109
99
  # Returns whether the authenticated account likes the video.
110
100
  #
111
101
  # This method requires {Resource#auth auth} to return an
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.11.3'
2
+ VERSION = '0.11.4'
3
3
  end
@@ -14,7 +14,7 @@ describe Yt::Account, :device_app do
14
14
  describe '.videos' do
15
15
  let(:video) { $account.videos.where(order: 'viewCount').first }
16
16
 
17
- specify 'returns the account’s videos with its tags' do
17
+ specify 'returns the videos uploaded by the account with their tags' do
18
18
  expect(video).to be_a Yt::Video
19
19
  expect(video.tags).not_to be_empty
20
20
  end
@@ -32,6 +32,16 @@ describe Yt::Account, :device_app do
32
32
  it { expect(count).to be_zero }
33
33
  end
34
34
  end
35
+
36
+ describe 'ignores filters by ID (all the videos uploaded by the account are returned)' do
37
+ let(:other_video) { $account.videos.where(order: 'viewCount', id: 'invalid').first }
38
+ it { expect(other_video.id).to eq video.id }
39
+ end
40
+
41
+ describe 'ignores filters by chart (all the videos uploaded by the account are returned)' do
42
+ let(:other_video) { $account.videos.where(order: 'viewCount', chart: 'invalid').first }
43
+ it { expect(other_video.id).to eq video.id }
44
+ end
35
45
  end
36
46
 
37
47
  describe '.upload_video' do
@@ -42,6 +42,14 @@ describe Yt::Channel, :device_app do
42
42
  it { expect(channel.unsubscribe!).to be_truthy }
43
43
  end
44
44
 
45
+ describe 'filtering by ID is ignored when listing videos' do
46
+ it { expect(channel.videos.where(id: 'invalid').first).to be_a Yt::Video }
47
+ end
48
+
49
+ describe 'filtering by chart is ignored when listing videos' do
50
+ it { expect(channel.videos.where(chart: 'invalid').first).to be_a Yt::Video }
51
+ end
52
+
45
53
  # @note: these tests are slow because they go through multiple pages of
46
54
  # results and do so to test that we can overcome YouTube’s limitation of
47
55
  # only returning the first 500 results for each query.
@@ -12,4 +12,12 @@ describe Yt::Collections::Videos, :server_app do
12
12
  specify 'with a query term, only returns some YouTube videos' do
13
13
  expect(videos.where(q: 'Fullscreen CreatorPlatform', video_duration: :long).size).to be < 100_000
14
14
  end
15
+
16
+ specify 'with a list of video IDs, only returns the videos matching those IDs' do
17
+ expect(videos.where(id: 'MESycYJytkU,invalid').size).to be 1
18
+ end
19
+
20
+ specify 'with a chart parameter, only returns videos of that chart', :ruby2 do
21
+ expect(videos.where(chart: 'mostPopular').size).to be 200
22
+ end
15
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.3
4
+ version: 0.11.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-21 00:00:00.000000000 Z
11
+ date: 2014-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport