yt 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/HISTORY.md +2 -0
  5. data/README.md +1 -1
  6. data/lib/yt/actions/list.rb +9 -1
  7. data/lib/yt/collections/annotations.rb +1 -0
  8. data/lib/yt/collections/authentications.rb +1 -1
  9. data/lib/yt/collections/base.rb +10 -3
  10. data/lib/yt/collections/channels.rb +5 -1
  11. data/lib/yt/collections/claims.rb +7 -8
  12. data/lib/yt/collections/content_details.rb +5 -1
  13. data/lib/yt/collections/content_owners.rb +1 -1
  14. data/lib/yt/collections/ids.rb +5 -1
  15. data/lib/yt/collections/partnered_channels.rb +7 -6
  16. data/lib/yt/collections/playlist_items.rb +7 -3
  17. data/lib/yt/collections/playlists.rb +7 -3
  18. data/lib/yt/collections/policies.rb +1 -6
  19. data/lib/yt/collections/references.rb +1 -5
  20. data/lib/yt/collections/reports.rb +3 -2
  21. data/lib/yt/collections/resources.rb +2 -7
  22. data/lib/yt/collections/statistics_sets.rb +6 -2
  23. data/lib/yt/collections/statuses.rb +2 -4
  24. data/lib/yt/collections/subscriptions.rb +10 -1
  25. data/lib/yt/collections/videos.rb +10 -6
  26. data/lib/yt/collections/viewer_percentages.rb +3 -2
  27. data/lib/yt/models/claim.rb +14 -0
  28. data/lib/yt/models/playlist.rb +1 -28
  29. data/lib/yt/models/resource.rb +35 -0
  30. data/lib/yt/models/video.rb +12 -9
  31. data/lib/yt/version.rb +1 -1
  32. data/spec/collections/claims_spec.rb +30 -0
  33. data/spec/collections/playlist_items_spec.rb +1 -0
  34. data/spec/collections/policies_spec.rb +30 -0
  35. data/spec/collections/references_spec.rb +30 -0
  36. data/spec/collections/videos_spec.rb +25 -1
  37. data/spec/models/claim_spec.rb +12 -0
  38. data/spec/requests/as_account/account_spec.rb +1 -1
  39. data/spec/requests/as_account/video_spec.rb +58 -12
  40. data/spec/requests/as_content_owner/content_owner_spec.rb +14 -1
  41. metadata +27 -33
  42. data/spec/collections/annotations_spec.rb +0 -6
  43. data/spec/collections/channels_spec.rb +0 -6
  44. data/spec/collections/content_details_spec.rb +0 -6
  45. data/spec/collections/ratings_spec.rb +0 -6
  46. data/spec/collections/snippets_spec.rb +0 -6
  47. data/spec/collections/user_infos_spec.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5fe9ccf19b87eba1932a8381ec62e4c7e18bb997
4
- data.tar.gz: bcc2aefb8c393bac857f94157267d66ab96301ae
3
+ metadata.gz: ab23bb89da9f80619391db9f6d8a490609631147
4
+ data.tar.gz: 4e2cc2d536a284e70f43f6c94fd80cd44dc63b4f
5
5
  SHA512:
6
- metadata.gz: f3f0ddfe5fcf4c20b72a77478efba519a33db0bf9565b52a47daaa6f768fe68015d3436d4535fdd759443462903c5ec788750ef5595317672c7492d903c25db2
7
- data.tar.gz: 0dcc83e353408a679b723516e3801eafd2b1710ee25584040a9d9c359fa8dadac24b44949779b6b4f042a09e3ebd633b737b3c64815bf826ed571bdb0f0169e2
6
+ metadata.gz: 24ecc8fe727d82e972d568310e9d463f1a51f1028184ca99bf122b63e647857ec62174a214882eb1b81e681eec36127cf9b3dadb1c23544235d11ec9acfc1312
7
+ data.tar.gz: c118aa416a094bee9ecd3027756045720d3409c1a9c0d99479f9fe1b0e6d2544b855d4b63c299bdbbe47cfa7d55fbfa786ff1c07497b92d72a98656fcfab0cc5
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  notifications:
3
- email: false
3
+ email: true
4
4
  matrix:
5
5
  include:
6
6
  - rvm: 1.9.3
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yt (0.9.2)
4
+ yt (0.9.3)
5
5
  activesupport
6
6
 
7
7
  GEM
data/HISTORY.md CHANGED
@@ -4,6 +4,8 @@ v0.9 - 2014/07/28
4
4
  * [breaking change] Rename rating.update to rating.set
5
5
  * Add content_owner.references to retrieve ContentID references
6
6
  * Add content_owner.policies to list ContentID policies
7
+ * Let 'update' methods understand both under_score and camelCased parameters
8
+ * Add claim.third_party?
7
9
 
8
10
 
9
11
  v0.8 - 2014/07/18
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.9.2'
44
+ gem 'yt', '~> 0.9.3'
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*)
@@ -19,6 +19,7 @@ module Yt
19
19
  while next_item = find_next
20
20
  items << next_item
21
21
  end
22
+ @where_params = {}
22
23
  end
23
24
  end
24
25
 
@@ -41,7 +42,7 @@ module Yt
41
42
 
42
43
  def next_page
43
44
  params = list_params.dup
44
- params[:params][:pageToken] = @page_token if @page_token
45
+ params[:params][:page_token] = @page_token if @page_token
45
46
  next_page = fetch_page params
46
47
  @page_token = next_page[:token]
47
48
  next_page[:items]
@@ -55,6 +56,7 @@ module Yt
55
56
  end
56
57
 
57
58
  def request(params = {})
59
+ camelize_keys! params[:params] if params.fetch(:camelize_params, true)
58
60
  @last_request = Yt::Request.new params
59
61
  end
60
62
 
@@ -80,6 +82,12 @@ module Yt
80
82
  def list_resources
81
83
  self.class
82
84
  end
85
+
86
+ def camelize_keys!(hash = {})
87
+ hash.dup.each_key do |key|
88
+ hash[key.to_s.camelize(:lower).to_sym] = hash.delete key
89
+ end
90
+ end
83
91
  end
84
92
  end
85
93
  end
@@ -27,6 +27,7 @@ module Yt
27
27
  params[:host] = 'www.youtube.com'
28
28
  params[:path] = '/annotations_invideo'
29
29
  params[:params] = {video_id: @parent.id}
30
+ params[:camelize_params] = false
30
31
  params[:expected_response] = Net::HTTPOK
31
32
  end
32
33
  end
@@ -40,4 +40,4 @@ module Yt
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -20,9 +20,16 @@ module Yt
20
20
  end
21
21
 
22
22
  def where(conditions = {})
23
- @items = []
24
- @extra_params = conditions
25
- self
23
+ self.tap do
24
+ @items = []
25
+ @where_params = conditions
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def apply_where_params!(params = {})
32
+ params.merge!(@where_params ||= {})
26
33
  end
27
34
  end
28
35
  end
@@ -12,7 +12,11 @@ module Yt
12
12
  # @return [Hash] the parameters to submit to YouTube to list channels.
13
13
  # @see https://developers.google.com/youtube/v3/docs/channels/list
14
14
  def list_params
15
- super.tap{|params| params[:params].merge! mine: true}
15
+ super.tap{|params| params[:params] = channels_params}
16
+ end
17
+
18
+ def channels_params
19
+ resources_params.merge mine: true
16
20
  end
17
21
  end
18
22
  end
@@ -19,23 +19,22 @@ module Yt
19
19
  # @see https://developers.google.com/youtube/partner/docs/v1/claims/list
20
20
  # @see https://developers.google.com/youtube/partner/docs/v1/claimSearch/list
21
21
  def list_params
22
-
23
22
  super.tap do |params|
24
- params[:params] = claims_params
25
23
  params[:path] = claims_path
24
+ params[:params] = claims_params
26
25
  end
27
26
  end
28
27
 
29
28
  def claims_params
30
- {onBehalfOfContentOwner: @parent.owner_name}.tap do |params|
31
- (@extra_params ||= {}).each do |key, value|
32
- params[key.to_s.camelize :lower] = value
33
- end
34
- end
29
+ apply_where_params! on_behalf_of_content_owner: @parent.owner_name
35
30
  end
36
31
 
32
+ # @private
33
+ # @todo: This is the only place outside of base.rb where @where_params
34
+ # is accessed; it should be replaced with a filter on params instead.
37
35
  def claims_path
38
- if @extra_params.empty? || @extra_params.key?(:id)
36
+ @where_params ||= {}
37
+ if @where_params.empty? || @where_params.key?(:id)
39
38
  '/youtube/partner/v1/claims'
40
39
  else
41
40
  '/youtube/partner/v1/claimSearch'
@@ -18,10 +18,14 @@ module Yt
18
18
  # @see https://developers.google.com/youtube/v3/docs/videos#resource
19
19
  def list_params
20
20
  super.tap do |params|
21
- params[:params] = {maxResults: 50, part: 'contentDetails', id: @parent.id}
21
+ params[:params] = content_details_params
22
22
  params[:path] = '/youtube/v3/videos'
23
23
  end
24
24
  end
25
+
26
+ def content_details_params
27
+ {max_results: 50, part: 'contentDetails', id: @parent.id}
28
+ end
25
29
  end
26
30
  end
27
31
  end
@@ -25,7 +25,7 @@ module Yt
25
25
  end
26
26
 
27
27
  def content_owners_params
28
- {fetchMine: true}
28
+ {fetch_mine: true}
29
29
  end
30
30
  end
31
31
  end
@@ -13,10 +13,14 @@ module Yt
13
13
 
14
14
  def list_params
15
15
  super.tap do |params|
16
- params[:params] = {forUsername: @parent.username, part: 'id'}
16
+ params[:params] = ids_params
17
17
  params[:path] = "/youtube/v3/#{@parent.kind.pluralize}"
18
18
  end
19
19
  end
20
+
21
+ def ids_params
22
+ {for_username: @parent.username, part: 'id'}
23
+ end
20
24
  end
21
25
  end
22
26
  end
@@ -6,13 +6,14 @@ module Yt
6
6
 
7
7
  private
8
8
 
9
- # @return [Hash] the parameters to submit to YouTube to list partnered channels.
10
- # @see https://developers.google.com/youtube/v3/docs/channels/list
11
- def list_params
9
+ # @private
10
+ # @note Partnered Channels overwrites +channel_params+ since the query
11
+ # is slightly different.
12
+ def channels_params
12
13
  super.tap do |params|
13
- params[:params].delete :mine
14
- params[:params][:managedByMe] = true
15
- params[:params][:onBehalfOfContentOwner] = @parent.owner_name
14
+ params.delete :mine
15
+ params[:managed_by_me] = true
16
+ params[:on_behalf_of_content_owner] = @parent.owner_name
16
17
  end
17
18
  end
18
19
 
@@ -17,10 +17,14 @@ module Yt
17
17
 
18
18
  private
19
19
 
20
- # @return [Hash] the parameters to submit to YouTube to list items.
21
- # @see https://developers.google.com/youtube/v3/docs/playlistItems/list
20
+ # @return [Hash] the parameters to submit to YouTube to list channels.
21
+ # @see https://developers.google.com/youtube/v3/docs/channels/list
22
22
  def list_params
23
- super.tap{|params| params[:params].merge! playlistId: @parent.id}
23
+ super.tap{|params| params[:params] = playlist_items_params}
24
+ end
25
+
26
+ def playlist_items_params
27
+ resources_params.merge playlist_id: @parent.id
24
28
  end
25
29
  end
26
30
  end
@@ -20,10 +20,14 @@ module Yt
20
20
 
21
21
  private
22
22
 
23
- # @return [Hash] the parameters to submit to YouTube to list playlists.
24
- # @see https://developers.google.com/youtube/v3/docs/playlist/list
23
+ # @return [Hash] the parameters to submit to YouTube to list channels.
24
+ # @see https://developers.google.com/youtube/v3/docs/channels/list
25
25
  def list_params
26
- super.tap{|params| params[:params].merge! channelId: @parent.id}
26
+ super.tap{|params| params[:params] = playlists_params}
27
+ end
28
+
29
+ def playlists_params
30
+ resources_params.merge channel_id: @parent.id
27
31
  end
28
32
  end
29
33
  end
@@ -18,7 +18,6 @@ module Yt
18
18
  # saved by the content owner.
19
19
  # @see https://developers.google.com/youtube/partner/docs/v1/policies/list
20
20
  def list_params
21
-
22
21
  super.tap do |params|
23
22
  params[:params] = policies_params
24
23
  params[:path] = '/youtube/partner/v1/policies'
@@ -26,11 +25,7 @@ module Yt
26
25
  end
27
26
 
28
27
  def policies_params
29
- {onBehalfOfContentOwner: @parent.owner_name}.tap do |params|
30
- (@extra_params ||= {}).each do |key, value|
31
- params[key.to_s.camelize :lower] = value
32
- end
33
- end
28
+ apply_where_params! on_behalf_of_content_owner: @parent.owner_name
34
29
  end
35
30
  end
36
31
  end
@@ -25,11 +25,7 @@ module Yt
25
25
  end
26
26
 
27
27
  def references_params
28
- {onBehalfOfContentOwner: @parent.owner_name}.tap do |params|
29
- (@extra_params ||= {}).each do |key, value|
30
- params[key.to_s.camelize :lower] = value
31
- end
32
- end
28
+ apply_where_params! on_behalf_of_content_owner: @parent.owner_name
33
29
  end
34
30
  end
35
31
  end
@@ -20,12 +20,13 @@ module Yt
20
20
  def list_params
21
21
  super.tap do |params|
22
22
  params[:path] = '/youtube/analytics/v1/reports'
23
- params[:params] = @parent.reports_params.merge reports_params
23
+ params[:params] = reports_params
24
+ params[:camelize_params] = false
24
25
  end
25
26
  end
26
27
 
27
28
  def reports_params
28
- {}.tap do |params|
29
+ @parent.reports_params.tap do |params|
29
30
  params['start-date'] = @days_range.begin
30
31
  params['end-date'] = @days_range.end
31
32
  params['metrics'] = @metric
@@ -18,13 +18,8 @@ module Yt
18
18
  resource_class.new id: data['id'], snippet: data['snippet'], status: data['status'], auth: @auth
19
19
  end
20
20
 
21
- # @return [Hash] the parameters to submit to YouTube to list items.
22
- # @see https://developers.google.com/youtube/v3/docs/playlistItems/list
23
- # @see https://developers.google.com/youtube/v3/docs/playlists/list
24
- def list_params
25
- super.tap do |params|
26
- params[:params] = {maxResults: 50, part: 'snippet,status'}
27
- end
21
+ def resources_params
22
+ {max_results: 50, part: 'snippet,status'}
28
23
  end
29
24
 
30
25
  def resource_class
@@ -7,7 +7,7 @@ module Yt
7
7
 
8
8
  private
9
9
 
10
- # @return [Yt::Models::StatisticsSet] a new statistics set initialized
10
+ # @return [Yt::Models::StatisticsSet] a new statistics set initialized
11
11
  # with one of the items returned by asking YouTube for a list of them.
12
12
  def new_item(data)
13
13
  Yt::StatisticsSet.new data: data['statistics']
@@ -18,10 +18,14 @@ module Yt
18
18
  # @see https://developers.google.com/youtube/v3/docs/videos#resource
19
19
  def list_params
20
20
  super.tap do |params|
21
- params[:params] = {maxResults: 50, part: 'statistics', id: @parent.id}
22
21
  params[:path] = "/youtube/v3/#{@parent.kind.pluralize}"
22
+ params[:params] = statistics_sets_params
23
23
  end
24
24
  end
25
+
26
+ def statistics_sets_params
27
+ {max_results: 50, part: 'statistics', id: @parent.id}
28
+ end
25
29
  end
26
30
  end
27
31
  end
@@ -19,13 +19,11 @@ module Yt
19
19
  # of a resource, for instance a channel.
20
20
  # @see https://developers.google.com/youtube/v3/docs/channels/list
21
21
  def list_params
22
- super.tap do |params|
23
- params[:params] = {id: @parent.id, part: 'status'}
24
- end
22
+ super.tap{|params| params[:params] = {id: @parent.id, part: 'status'}}
25
23
  end
26
24
 
27
25
  # @private
28
- # @note Statuses overrides +list_resources+ since the endpoint is not
26
+ # @note Statuses overrides +list_resources+ since the endpoint is not
29
27
  # '/statuses' but the endpoint related to the snippet’s resource.
30
28
  def list_resources
31
29
  @parent.class.to_s.pluralize
@@ -50,7 +50,16 @@ module Yt
50
50
  # @see https://developers.google.com/youtube/v3/docs/subscriptions/list
51
51
  def list_params
52
52
  super.tap do |params|
53
- params[:params] = {maxResults: 50, forChannelId: @parent.id, mine: true, part: 'snippet'}
53
+ params[:params] = subscriptions_params
54
+ end
55
+ end
56
+
57
+ def subscriptions_params
58
+ {}.tap do |params|
59
+ params[:max_results] = 50
60
+ params[:for_channel_id] = @parent.id
61
+ params[:mine] = true
62
+ params[:part] = 'snippet'
54
63
  end
55
64
  end
56
65
 
@@ -22,7 +22,7 @@ module Yt
22
22
  # @see https://developers.google.com/youtube/v3/docs/search/list
23
23
  def list_params
24
24
  super.tap do |params|
25
- params[:params] = @parent.videos_params.merge videos_params
25
+ params[:params] = videos_params
26
26
  params[:path] = '/youtube/v3/search'
27
27
  end
28
28
  end
@@ -36,17 +36,21 @@ module Yt
36
36
  # that limit, the query is restarted with a publishedBefore filter in
37
37
  # case there are more videos to be listed for a channel
38
38
  def add_offset_to(items)
39
- if items.count == videos_params[:maxResults]
39
+ if items.count == videos_params[:max_results]
40
40
  last_published = items.last['snippet']['publishedAt']
41
41
  @page_token, @published_before = '', last_published
42
42
  end
43
43
  end
44
44
 
45
45
  def videos_params
46
- params = {type: :video, maxResults: 50, part: 'snippet', order: 'date'}
47
- params[:publishedBefore] = @published_before if @published_before
48
- @extra_params ||= {}
49
- params.merge @extra_params
46
+ @parent.videos_params.tap do |params|
47
+ params[:type] = :video
48
+ params[:max_results] = 50
49
+ params[:part] = 'snippet'
50
+ params[:order] = 'date'
51
+ params[:published_before] = @published_before if @published_before
52
+ apply_where_params! params
53
+ end
50
54
  end
51
55
  end
52
56
  end
@@ -24,12 +24,13 @@ module Yt
24
24
  def list_params
25
25
  super.tap do |params|
26
26
  params[:path] = '/youtube/analytics/v1/reports'
27
- params[:params] = @parent.reports_params.merge reports_params
27
+ params[:params] = reports_params
28
+ params[:capitalize_params] = false
28
29
  end
29
30
  end
30
31
 
31
32
  def reports_params
32
- {}.tap do |params|
33
+ @parent.reports_params.tap do |params|
33
34
  params['start-date'] = 3.months.ago.to_date
34
35
  params['end-date'] = Date.today.to_date
35
36
  params['metrics'] = :viewerPercentage
@@ -27,6 +27,11 @@ module Yt
27
27
  @video_id ||= @data["videoId"]
28
28
  end
29
29
 
30
+ # Status
31
+
32
+ STATUSES = %q(active appealed disputed inactive pending potential
33
+ takedown unknown)
34
+
30
35
  # @return [String] the claim’s status. Valid values are: active,
31
36
  # appealed, disputed, inactive, pending, potential, takedown, unknown.
32
37
  # @note When updating a claim, you can update its status from active to
@@ -76,6 +81,10 @@ module Yt
76
81
  status == 'unknown'
77
82
  end
78
83
 
84
+ # Content Type
85
+
86
+ CONTENT_TYPES = %q(audio video audiovisual)
87
+
79
88
  # @return [String] whether the claim covers the audio, video, or
80
89
  # audiovisual portion of the claimed content. Valid values are: audio,
81
90
  # audiovisual, video.
@@ -103,6 +112,11 @@ module Yt
103
112
  @created_at ||= Time.parse @data["timeCreated"]
104
113
  end
105
114
 
115
+ # @return [Boolean] whether a third party created the claim.
116
+ def third_party?
117
+ @third_party_claim ||= @data['thirdPartyClaim'] == true
118
+ end
119
+
106
120
  # Return whether the video should be blocked where not explicitly owned.
107
121
  # @return [Boolean] whether the claimed video should be blocked anywhere
108
122
  # it is not explicitly owned. For example, if you upload a video for an
@@ -24,22 +24,7 @@ module Yt
24
24
  end
25
25
 
26
26
  def update(attributes = {})
27
- underscore_keys! attributes
28
-
29
- body = {id: @id}.tap do |body|
30
- update_parts.each do |part, options|
31
- if (options[:keys] & attributes.keys).any? || options[:required]
32
- body[part] = {}.tap do |hash|
33
- options[:keys].map do |key|
34
- hash[camelize key] = attributes[key] || send(key)
35
- end
36
- end
37
- end
38
- end
39
- end
40
-
41
- part = body.except(:id).keys.join(',')
42
- do_update(params: {part: part}, body: body) do |data|
27
+ super attributes do |data|
43
28
  @id = data['id']
44
29
  @snippet = Snippet.new data: data['snippet'] if data['snippet']
45
30
  @status = Status.new data: data['status'] if data['status']
@@ -88,18 +73,6 @@ module Yt
88
73
  {snippet: snippet, status: status}
89
74
  end
90
75
 
91
- # @note If we dropped support for ActiveSupport 3, then we could simply
92
- # invoke transform_keys!{|key| key.to_s.underscore.to_sym}
93
- def underscore_keys!(hash)
94
- hash.dup.each_key do |key|
95
- hash[key.to_s.underscore.to_sym] = hash.delete key
96
- end
97
- end
98
-
99
- def camelize(value)
100
- value.to_s.camelize(:lower).to_sym
101
- end
102
-
103
76
  def video_params(video_id)
104
77
  {id: video_id, kind: :video}
105
78
  end
@@ -30,6 +30,13 @@ module Yt
30
30
  @url.username if @url
31
31
  end
32
32
 
33
+ def update(attributes = {}, &block)
34
+ underscore_keys! attributes
35
+ body = build_update_body attributes
36
+ params = {part: body.keys.join(',')}
37
+ do_update(params: params, body: body.merge(id: @id), &block)
38
+ end
39
+
33
40
  private
34
41
 
35
42
  # @return [Hash] the parameters to submit to YouTube to update a playlist.
@@ -47,6 +54,34 @@ module Yt
47
54
  def delete_params
48
55
  super.tap{|params| params[:params] = {id: @id}}
49
56
  end
57
+
58
+ def build_update_body(attributes = {})
59
+ body = {}
60
+ update_parts.each do |name, part|
61
+ body[name] = {}.tap do |hash|
62
+ part[:keys].map{|k| hash[camelize k] = attributes.fetch k, send(k)}
63
+ end if should_include_part_in_update?(part, attributes)
64
+ end
65
+ body
66
+ end
67
+
68
+ def should_include_part_in_update?(part, attributes = {})
69
+ part[:required] || (part[:keys] & attributes.keys).any?
70
+ end
71
+
72
+ # If we dropped support for ActiveSupport 3, then we could simply
73
+ # invoke transform_keys!{|key| key.to_s.underscore.to_sym}
74
+ def underscore_keys!(hash)
75
+ hash.dup.each_key{|key| hash[underscore key] = hash.delete key}
76
+ end
77
+
78
+ def camelize(value)
79
+ value.to_s.camelize(:lower).to_sym
80
+ end
81
+
82
+ def underscore(value)
83
+ value.to_s.underscore.to_sym
84
+ end
50
85
  end
51
86
  end
52
87
  end
@@ -81,21 +81,15 @@ module Yt
81
81
  # caution, as the whole status object needs to be updated, not just
82
82
  # privacyStatus, but also embeddable, license, publicStatsViewable,
83
83
  # and publishAt
84
- def update(options = {})
85
- options[:title] ||= title
86
- options[:description] ||= description
87
- options[:tags] ||= tags
88
- options[:categoryId] ||= category_id
89
- snippet = options.slice :title, :description, :tags, :categoryId
90
- body = {id: @id, snippet: snippet}
91
-
92
- do_update(params: {part: 'snippet'}, body: body) do |data|
84
+ def update(attributes = {})
85
+ super attributes do |data|
93
86
  @id = data['id']
94
87
  @snippet = Snippet.new data: data['snippet'] if data['snippet']
95
88
  true
96
89
  end
97
90
  end
98
91
 
92
+
99
93
  # Returns whether the authenticated account likes the video.
100
94
  #
101
95
  # This method requires {Resource#auth auth} to return an
@@ -157,6 +151,15 @@ module Yt
157
151
  params['filters'] = "video==#{id}"
158
152
  end
159
153
  end
154
+
155
+ private
156
+
157
+ # @see https://developers.google.com/youtube/v3/docs/videos/update
158
+ # @todo: Add status, recording details keys
159
+ def update_parts
160
+ snippet_keys = [:title, :description, :tags, :category_id]
161
+ {snippet: {keys: snippet_keys}}
162
+ end
160
163
  end
161
164
  end
162
165
  end
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.9.2'
2
+ VERSION = '0.9.3'
3
3
  end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'yt/collections/claims'
3
+ require 'yt/models/content_owner'
4
+
5
+ describe Yt::Collections::Claims do
6
+ subject(:collection) { Yt::Collections::Claims.new parent: content_owner }
7
+ let(:content_owner) { Yt::ContentOwner.new owner_name: 'any-name' }
8
+ let(:page) { {items: [], token: 'any-token'} }
9
+ let(:query) { {q: 'search string'} }
10
+
11
+ describe '#count' do
12
+ context 'called once with .where(query) and once without' do
13
+ after do
14
+ collection.where(query).count
15
+ collection.count
16
+ end
17
+
18
+ it 'only applies the query on the first call' do
19
+ expect(collection).to receive(:fetch_page) do |options|
20
+ expect(options[:params]).to include query
21
+ page
22
+ end
23
+ expect(collection).to receive(:fetch_page) do |options|
24
+ expect(options[:params]).not_to include query
25
+ page
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'yt/models/playlist'
3
+ require 'yt/models/playlist_item'
3
4
  require 'yt/collections/playlist_items'
4
5
 
5
6
  describe Yt::Collections::PlaylistItems do
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'yt/collections/policies'
3
+ require 'yt/models/content_owner'
4
+
5
+ describe Yt::Collections::Policies do
6
+ subject(:collection) { Yt::Collections::Policies.new parent: content_owner }
7
+ let(:content_owner) { Yt::ContentOwner.new owner_name: 'any-name' }
8
+ let(:page) { {items: [], token: 'any-token'} }
9
+ let(:query) { {id: 'any-id'} }
10
+
11
+ describe '#count' do
12
+ context 'called once with .where(query) and once without' do
13
+ after do
14
+ collection.where(query).count
15
+ collection.count
16
+ end
17
+
18
+ it 'only applies the query on the first call' do
19
+ expect(collection).to receive(:fetch_page) do |options|
20
+ expect(options[:params]).to include query
21
+ page
22
+ end
23
+ expect(collection).to receive(:fetch_page) do |options|
24
+ expect(options[:params]).not_to include query
25
+ page
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'yt/collections/references'
3
+ require 'yt/models/content_owner'
4
+
5
+ describe Yt::Collections::References do
6
+ subject(:collection) { Yt::Collections::References.new parent: content_owner }
7
+ let(:content_owner) { Yt::ContentOwner.new id: 'any-id' }
8
+ let(:page) { {items: [], token: 'any-token'} }
9
+ let(:query) { {id: 'reference-id'} }
10
+
11
+ describe '#count' do
12
+ context 'called once with .where(query) and once without' do
13
+ after do
14
+ collection.where(query).count
15
+ collection.count
16
+ end
17
+
18
+ it 'only applies the query on the first call' do
19
+ expect(collection).to receive(:fetch_page) do |options|
20
+ expect(options[:params]).to include query
21
+ page
22
+ end
23
+ expect(collection).to receive(:fetch_page) do |options|
24
+ expect(options[:params]).not_to include query
25
+ page
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,6 +1,30 @@
1
1
  require 'spec_helper'
2
2
  require 'yt/collections/videos'
3
+ require 'yt/models/channel'
3
4
 
4
5
  describe Yt::Collections::Videos do
5
- # Nothing to test
6
+ subject(:collection) { Yt::Collections::Videos.new parent: channel }
7
+ let(:channel) { Yt::Channel.new id: 'any-id' }
8
+ let(:page) { {items: [], token: 'any-token'} }
9
+ let(:query) { {q: 'search string'} }
10
+
11
+ describe '#count' do
12
+ context 'called once with .where(query) and once without' do
13
+ after do
14
+ collection.where(query).count
15
+ collection.count
16
+ end
17
+
18
+ it 'only applies the query on the first call' do
19
+ expect(collection).to receive(:fetch_page) do |options|
20
+ expect(options[:params]).to include query
21
+ page
22
+ end
23
+ expect(collection).to receive(:fetch_page) do |options|
24
+ expect(options[:params]).not_to include query
25
+ page
26
+ end
27
+ end
28
+ end
29
+ end
6
30
  end
@@ -189,4 +189,16 @@ describe Yt::Claim do
189
189
  it { expect(claim.block_outside_ownership?).to be false }
190
190
  end
191
191
  end
192
+
193
+ describe '#third_party?' do
194
+ context 'given fetching a claim returns thirdPartyClaim true' do
195
+ let(:data) { {"thirdPartyClaim"=>true} }
196
+ it { expect(claim.third_party?).to be true }
197
+ end
198
+
199
+ context 'given fetching a claim returns thirdPartyClaim true' do
200
+ let(:data) { {"thirdPartyClaim"=>false} }
201
+ it { expect(claim.third_party?).to be false }
202
+ end
203
+ end
192
204
  end
@@ -12,7 +12,7 @@ describe Yt::Account, :device_app do
12
12
 
13
13
  describe '.videos' do
14
14
  it { expect($account.videos).to be_a Yt::Collections::Videos }
15
- it { expect($account.videos.first).to be_a Yt::Video }
15
+ it { expect($account.videos.where(order: 'viewCount').first).to be_a Yt::Video }
16
16
 
17
17
  describe '.where(q: query_string)' do
18
18
  let(:count) { $account.videos.where(q: query).count }
@@ -100,24 +100,70 @@ describe Yt::Video, :device_app do
100
100
  end
101
101
 
102
102
  context 'given one of my own videos that I want to update' do
103
- let(:id) { $account.videos.first.id }
103
+ let(:id) { $account.videos.where(order: 'viewCount').first.id }
104
+ let!(:old_title) { video.title }
105
+ let!(:old_privacy_status) { video.privacy_status }
106
+ let(:update) { video.update attrs }
104
107
 
105
- describe 'updates the attributes that I specify explicitly' do
108
+ context 'given I update the title' do
106
109
  # NOTE: The use of UTF-8 characters is to test that we can pass up to
107
110
  # 50 characters, independently of their representation
108
111
  let(:attrs) { {title: "Yt Example Update Video #{rand} - ®•♡❥❦❧☙"} }
109
- it { expect(video.update attrs).to eq true }
110
- it { expect{video.update attrs}.to change{video.title} }
112
+
113
+ specify 'only updates the title' do
114
+ expect(update).to be true
115
+ expect(video.title).not_to eq old_title
116
+ expect(video.privacy_status).to eq old_privacy_status
117
+ end
118
+ end
119
+
120
+ context 'given I update the description' do
121
+ let!(:old_description) { video.description }
122
+ let(:attrs) { {description: "Yt Example Description #{rand} - ®•♡❥❦❧☙"} }
123
+
124
+ specify 'only updates the description' do
125
+ expect(update).to be true
126
+ expect(video.description).not_to eq old_description
127
+ expect(video.title).to eq old_title
128
+ expect(video.privacy_status).to eq old_privacy_status
129
+ end
130
+ end
131
+
132
+ context 'given I update the tags' do
133
+ let!(:old_tags) { video.tags }
134
+ let(:attrs) { {tags: ["Yt Test Tag #{rand}"]} }
135
+
136
+ specify 'only updates the tag' do
137
+ expect(update).to be true
138
+ expect(video.tags).not_to eq old_tags
139
+ expect(video.title).to eq old_title
140
+ expect(video.privacy_status).to eq old_privacy_status
141
+ end
111
142
  end
112
143
 
113
- describe 'does not update the other attributes' do
114
- let(:attrs) { {} }
115
- it { expect(video.update attrs).to eq true }
116
- it { expect{video.update attrs}.not_to change{video.title} }
117
- it { expect{video.update attrs}.not_to change{video.description} }
118
- it { expect{video.update attrs}.not_to change{video.tags} }
119
- it { expect{video.update attrs}.not_to change{video.category_id} }
120
- it { expect{video.update attrs}.not_to change{video.privacy_status} }
144
+ context 'given I update the category ID' do
145
+ let!(:old_category_id) { video.category_id }
146
+ let!(:new_category_id) { old_category_id == '22' ? '21' : '22' }
147
+
148
+ context 'passing the parameter in underscore syntax' do
149
+ let(:attrs) { {category_id: new_category_id} }
150
+
151
+ specify 'only updates the category ID' do
152
+ expect(update).to be true
153
+ expect(video.category_id).not_to eq old_category_id
154
+ expect(video.title).to eq old_title
155
+ expect(video.privacy_status).to eq old_privacy_status
156
+ end
157
+ end
158
+
159
+ context 'passing the parameter in camel-case syntax' do
160
+ let(:attrs) { {categoryId: new_category_id} }
161
+
162
+ specify 'only updates the category ID' do
163
+ expect(update).to be true
164
+ expect(video.category_id).not_to eq old_category_id
165
+ end
166
+ end
121
167
  end
122
168
 
123
169
  it 'returns valid reports for video-related metrics' do
@@ -9,7 +9,20 @@ describe Yt::ContentOwner, :partner do
9
9
  end
10
10
 
11
11
  describe '.claims' do
12
- it { expect($content_owner.claims.first).to be_a Yt::Claim }
12
+ describe 'given the content owner has policies' do
13
+ let(:claim) { $content_owner.claims.first }
14
+
15
+ it 'returns valid metadata' do
16
+ expect(claim.id).to be_a String
17
+ expect(claim.asset_id).to be_a String
18
+ expect(claim.video_id).to be_a String
19
+ expect(claim.status).to be_in Yt::Claim::STATUSES
20
+ expect(claim.content_type).to be_in Yt::Claim::CONTENT_TYPES
21
+ expect(claim.created_at).to be_a Time
22
+ expect(claim).not_to be_third_party
23
+ expect(claim.block_outside_ownership?).to be_in [true, false]
24
+ end
25
+ end
13
26
 
14
27
  describe '.where(id: claim_id)' do
15
28
  let(:count) { $content_owner.claims.where(id: claim_id).count }
metadata CHANGED
@@ -1,97 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
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-07-29 00:00:00.000000000 Z
11
+ date: 2014-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: coveralls
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  description: Youtube V3 API client.
@@ -102,10 +102,10 @@ executables:
102
102
  extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
- - ".gitignore"
106
- - ".rspec"
107
- - ".travis.yml"
108
- - ".yardopts"
105
+ - .gitignore
106
+ - .rspec
107
+ - .travis.yml
108
+ - .yardopts
109
109
  - Gemfile
110
110
  - Gemfile.lock
111
111
  - HISTORY.md
@@ -189,15 +189,12 @@ files:
189
189
  - lib/yt/models/user_info.rb
190
190
  - lib/yt/models/video.rb
191
191
  - lib/yt/version.rb
192
- - spec/collections/annotations_spec.rb
193
- - spec/collections/channels_spec.rb
194
- - spec/collections/content_details_spec.rb
192
+ - spec/collections/claims_spec.rb
195
193
  - spec/collections/playlist_items_spec.rb
196
194
  - spec/collections/playlists_spec.rb
197
- - spec/collections/ratings_spec.rb
198
- - spec/collections/snippets_spec.rb
195
+ - spec/collections/policies_spec.rb
196
+ - spec/collections/references_spec.rb
199
197
  - spec/collections/subscriptions_spec.rb
200
- - spec/collections/user_infos_spec.rb
201
198
  - spec/collections/videos_spec.rb
202
199
  - spec/errors/missing_auth_spec.rb
203
200
  - spec/errors/no_items_spec.rb
@@ -257,31 +254,28 @@ require_paths:
257
254
  - lib
258
255
  required_ruby_version: !ruby/object:Gem::Requirement
259
256
  requirements:
260
- - - ">="
257
+ - - '>='
261
258
  - !ruby/object:Gem::Version
262
259
  version: 1.9.3
263
260
  required_rubygems_version: !ruby/object:Gem::Requirement
264
261
  requirements:
265
- - - ">="
262
+ - - '>='
266
263
  - !ruby/object:Gem::Version
267
264
  version: '0'
268
265
  requirements: []
269
266
  rubyforge_project:
270
- rubygems_version: 2.2.2
267
+ rubygems_version: 2.2.1
271
268
  signing_key:
272
269
  specification_version: 4
273
270
  summary: Yt makes it easy to interact with Youtube V3 API by providing a modular,
274
271
  intuitive and tested Ruby-style API.
275
272
  test_files:
276
- - spec/collections/annotations_spec.rb
277
- - spec/collections/channels_spec.rb
278
- - spec/collections/content_details_spec.rb
273
+ - spec/collections/claims_spec.rb
279
274
  - spec/collections/playlist_items_spec.rb
280
275
  - spec/collections/playlists_spec.rb
281
- - spec/collections/ratings_spec.rb
282
- - spec/collections/snippets_spec.rb
276
+ - spec/collections/policies_spec.rb
277
+ - spec/collections/references_spec.rb
283
278
  - spec/collections/subscriptions_spec.rb
284
- - spec/collections/user_infos_spec.rb
285
279
  - spec/collections/videos_spec.rb
286
280
  - spec/errors/missing_auth_spec.rb
287
281
  - spec/errors/no_items_spec.rb
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/collections/annotations'
3
-
4
- describe Yt::Collections::Annotations do
5
- # Nothing to test
6
- end
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/collections/channels'
3
-
4
- describe Yt::Collections::Channels do
5
- # Nothing to test
6
- end
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/collections/content_details'
3
-
4
- describe Yt::Collections::ContentDetails do
5
- # Nothing to test
6
- end
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/collections/ratings'
3
-
4
- describe Yt::Collections::Ratings do
5
- # Nothing to test
6
- end
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/collections/snippets'
3
-
4
- describe Yt::Collections::Snippets do
5
- # Nothing to test
6
- end
@@ -1,6 +0,0 @@
1
- require 'spec_helper'
2
- require 'yt/collections/user_infos'
3
-
4
- describe Yt::Collections::UserInfos do
5
- # Nothing to test
6
- end