yt 0.9.2 → 0.9.3

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