yt-andrewroth 0.25.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. data/.gitignore +27 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +9 -0
  4. data/.yardopts +5 -0
  5. data/CHANGELOG.md +732 -0
  6. data/Gemfile +4 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +489 -0
  9. data/Rakefile +11 -0
  10. data/YOUTUBE_IT.md +835 -0
  11. data/bin/yt +30 -0
  12. data/gemfiles/Gemfile.activesupport-3.x +4 -0
  13. data/gemfiles/Gemfile.activesupport-4.x +4 -0
  14. data/lib/yt.rb +21 -0
  15. data/lib/yt/actions/base.rb +32 -0
  16. data/lib/yt/actions/delete.rb +19 -0
  17. data/lib/yt/actions/delete_all.rb +32 -0
  18. data/lib/yt/actions/insert.rb +42 -0
  19. data/lib/yt/actions/list.rb +139 -0
  20. data/lib/yt/actions/modify.rb +37 -0
  21. data/lib/yt/actions/patch.rb +19 -0
  22. data/lib/yt/actions/update.rb +19 -0
  23. data/lib/yt/associations/has_attribute.rb +55 -0
  24. data/lib/yt/associations/has_authentication.rb +214 -0
  25. data/lib/yt/associations/has_many.rb +22 -0
  26. data/lib/yt/associations/has_one.rb +22 -0
  27. data/lib/yt/associations/has_reports.rb +320 -0
  28. data/lib/yt/collections/advertising_options_sets.rb +34 -0
  29. data/lib/yt/collections/annotations.rb +62 -0
  30. data/lib/yt/collections/assets.rb +58 -0
  31. data/lib/yt/collections/authentications.rb +47 -0
  32. data/lib/yt/collections/base.rb +62 -0
  33. data/lib/yt/collections/channels.rb +31 -0
  34. data/lib/yt/collections/claim_histories.rb +34 -0
  35. data/lib/yt/collections/claims.rb +56 -0
  36. data/lib/yt/collections/content_details.rb +30 -0
  37. data/lib/yt/collections/content_owner_details.rb +34 -0
  38. data/lib/yt/collections/content_owners.rb +32 -0
  39. data/lib/yt/collections/device_flows.rb +23 -0
  40. data/lib/yt/collections/file_details.rb +30 -0
  41. data/lib/yt/collections/ids.rb +27 -0
  42. data/lib/yt/collections/live_streaming_details.rb +30 -0
  43. data/lib/yt/collections/ownerships.rb +34 -0
  44. data/lib/yt/collections/partnered_channels.rb +28 -0
  45. data/lib/yt/collections/players.rb +30 -0
  46. data/lib/yt/collections/playlist_items.rb +53 -0
  47. data/lib/yt/collections/playlists.rb +28 -0
  48. data/lib/yt/collections/policies.rb +28 -0
  49. data/lib/yt/collections/ratings.rb +23 -0
  50. data/lib/yt/collections/references.rb +46 -0
  51. data/lib/yt/collections/related_playlists.rb +43 -0
  52. data/lib/yt/collections/reports.rb +161 -0
  53. data/lib/yt/collections/resources.rb +57 -0
  54. data/lib/yt/collections/resumable_sessions.rb +51 -0
  55. data/lib/yt/collections/snippets.rb +27 -0
  56. data/lib/yt/collections/statistics_sets.rb +30 -0
  57. data/lib/yt/collections/statuses.rb +27 -0
  58. data/lib/yt/collections/subscribed_channels.rb +46 -0
  59. data/lib/yt/collections/subscribers.rb +33 -0
  60. data/lib/yt/collections/subscriptions.rb +50 -0
  61. data/lib/yt/collections/user_infos.rb +36 -0
  62. data/lib/yt/collections/video_categories.rb +35 -0
  63. data/lib/yt/collections/videos.rb +137 -0
  64. data/lib/yt/config.rb +54 -0
  65. data/lib/yt/errors/forbidden.rb +13 -0
  66. data/lib/yt/errors/missing_auth.rb +81 -0
  67. data/lib/yt/errors/no_items.rb +13 -0
  68. data/lib/yt/errors/request_error.rb +74 -0
  69. data/lib/yt/errors/server_error.rb +13 -0
  70. data/lib/yt/errors/unauthorized.rb +50 -0
  71. data/lib/yt/models/account.rb +216 -0
  72. data/lib/yt/models/advertising_options_set.rb +38 -0
  73. data/lib/yt/models/annotation.rb +132 -0
  74. data/lib/yt/models/asset.rb +111 -0
  75. data/lib/yt/models/asset_metadata.rb +38 -0
  76. data/lib/yt/models/asset_snippet.rb +46 -0
  77. data/lib/yt/models/authentication.rb +83 -0
  78. data/lib/yt/models/base.rb +32 -0
  79. data/lib/yt/models/channel.rb +302 -0
  80. data/lib/yt/models/claim.rb +156 -0
  81. data/lib/yt/models/claim_event.rb +67 -0
  82. data/lib/yt/models/claim_history.rb +29 -0
  83. data/lib/yt/models/configuration.rb +70 -0
  84. data/lib/yt/models/content_detail.rb +65 -0
  85. data/lib/yt/models/content_owner.rb +48 -0
  86. data/lib/yt/models/content_owner_detail.rb +18 -0
  87. data/lib/yt/models/description.rb +58 -0
  88. data/lib/yt/models/device_flow.rb +16 -0
  89. data/lib/yt/models/file_detail.rb +21 -0
  90. data/lib/yt/models/id.rb +9 -0
  91. data/lib/yt/models/iterator.rb +16 -0
  92. data/lib/yt/models/live_streaming_detail.rb +23 -0
  93. data/lib/yt/models/match_policy.rb +34 -0
  94. data/lib/yt/models/ownership.rb +75 -0
  95. data/lib/yt/models/player.rb +18 -0
  96. data/lib/yt/models/playlist.rb +218 -0
  97. data/lib/yt/models/playlist_item.rb +112 -0
  98. data/lib/yt/models/policy.rb +36 -0
  99. data/lib/yt/models/policy_rule.rb +124 -0
  100. data/lib/yt/models/rating.rb +37 -0
  101. data/lib/yt/models/reference.rb +172 -0
  102. data/lib/yt/models/resource.rb +136 -0
  103. data/lib/yt/models/resumable_session.rb +52 -0
  104. data/lib/yt/models/right_owner.rb +58 -0
  105. data/lib/yt/models/snippet.rb +50 -0
  106. data/lib/yt/models/statistics_set.rb +26 -0
  107. data/lib/yt/models/status.rb +32 -0
  108. data/lib/yt/models/subscription.rb +38 -0
  109. data/lib/yt/models/timestamp.rb +13 -0
  110. data/lib/yt/models/url.rb +90 -0
  111. data/lib/yt/models/user_info.rb +26 -0
  112. data/lib/yt/models/video.rb +630 -0
  113. data/lib/yt/models/video_category.rb +12 -0
  114. data/lib/yt/request.rb +278 -0
  115. data/lib/yt/version.rb +3 -0
  116. data/spec/collections/claims_spec.rb +30 -0
  117. data/spec/collections/playlist_items_spec.rb +44 -0
  118. data/spec/collections/playlists_spec.rb +27 -0
  119. data/spec/collections/policies_spec.rb +30 -0
  120. data/spec/collections/references_spec.rb +30 -0
  121. data/spec/collections/reports_spec.rb +30 -0
  122. data/spec/collections/subscriptions_spec.rb +25 -0
  123. data/spec/collections/videos_spec.rb +43 -0
  124. data/spec/errors/forbidden_spec.rb +10 -0
  125. data/spec/errors/missing_auth_spec.rb +24 -0
  126. data/spec/errors/no_items_spec.rb +10 -0
  127. data/spec/errors/request_error_spec.rb +44 -0
  128. data/spec/errors/server_error_spec.rb +10 -0
  129. data/spec/errors/unauthorized_spec.rb +10 -0
  130. data/spec/models/account_spec.rb +138 -0
  131. data/spec/models/annotation_spec.rb +180 -0
  132. data/spec/models/asset_spec.rb +20 -0
  133. data/spec/models/channel_spec.rb +127 -0
  134. data/spec/models/claim_event_spec.rb +62 -0
  135. data/spec/models/claim_history_spec.rb +27 -0
  136. data/spec/models/claim_spec.rb +211 -0
  137. data/spec/models/configuration_spec.rb +44 -0
  138. data/spec/models/content_detail_spec.rb +45 -0
  139. data/spec/models/content_owner_detail_spec.rb +6 -0
  140. data/spec/models/description_spec.rb +94 -0
  141. data/spec/models/file_detail_spec.rb +13 -0
  142. data/spec/models/live_streaming_detail_spec.rb +6 -0
  143. data/spec/models/ownership_spec.rb +59 -0
  144. data/spec/models/player_spec.rb +13 -0
  145. data/spec/models/playlist_item_spec.rb +120 -0
  146. data/spec/models/playlist_spec.rb +138 -0
  147. data/spec/models/policy_rule_spec.rb +63 -0
  148. data/spec/models/policy_spec.rb +41 -0
  149. data/spec/models/rating_spec.rb +12 -0
  150. data/spec/models/reference_spec.rb +249 -0
  151. data/spec/models/request_spec.rb +163 -0
  152. data/spec/models/resource_spec.rb +57 -0
  153. data/spec/models/right_owner_spec.rb +71 -0
  154. data/spec/models/snippet_spec.rb +13 -0
  155. data/spec/models/statistics_set_spec.rb +13 -0
  156. data/spec/models/status_spec.rb +13 -0
  157. data/spec/models/subscription_spec.rb +30 -0
  158. data/spec/models/url_spec.rb +78 -0
  159. data/spec/models/video_category_spec.rb +21 -0
  160. data/spec/models/video_spec.rb +669 -0
  161. data/spec/requests/as_account/account_spec.rb +125 -0
  162. data/spec/requests/as_account/authentications_spec.rb +139 -0
  163. data/spec/requests/as_account/channel_spec.rb +259 -0
  164. data/spec/requests/as_account/channels_spec.rb +18 -0
  165. data/spec/requests/as_account/playlist_item_spec.rb +56 -0
  166. data/spec/requests/as_account/playlist_spec.rb +244 -0
  167. data/spec/requests/as_account/resource_spec.rb +18 -0
  168. data/spec/requests/as_account/thumbnail.jpg +0 -0
  169. data/spec/requests/as_account/video.mp4 +0 -0
  170. data/spec/requests/as_account/video_spec.rb +408 -0
  171. data/spec/requests/as_content_owner/account_spec.rb +25 -0
  172. data/spec/requests/as_content_owner/advertising_options_set_spec.rb +15 -0
  173. data/spec/requests/as_content_owner/asset_spec.rb +20 -0
  174. data/spec/requests/as_content_owner/channel_spec.rb +1934 -0
  175. data/spec/requests/as_content_owner/claim_history_spec.rb +20 -0
  176. data/spec/requests/as_content_owner/content_owner_spec.rb +241 -0
  177. data/spec/requests/as_content_owner/match_policy_spec.rb +17 -0
  178. data/spec/requests/as_content_owner/ownership_spec.rb +25 -0
  179. data/spec/requests/as_content_owner/playlist_spec.rb +782 -0
  180. data/spec/requests/as_content_owner/video_spec.rb +1239 -0
  181. data/spec/requests/as_server_app/channel_spec.rb +74 -0
  182. data/spec/requests/as_server_app/playlist_item_spec.rb +30 -0
  183. data/spec/requests/as_server_app/playlist_spec.rb +53 -0
  184. data/spec/requests/as_server_app/video_spec.rb +58 -0
  185. data/spec/requests/as_server_app/videos_spec.rb +40 -0
  186. data/spec/requests/unauthenticated/video_spec.rb +22 -0
  187. data/spec/spec_helper.rb +20 -0
  188. data/spec/support/fail_matcher.rb +15 -0
  189. data/spec/support/global_hooks.rb +48 -0
  190. data/yt.gemspec +32 -0
  191. metadata +416 -0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in yt.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Fullscreen, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,489 @@
1
+ Yt - a Ruby client for the YouTube API
2
+ ======================================================
3
+
4
+ Yt helps you write apps that need to interact with YouTube.
5
+
6
+ The **source code** is available on [GitHub](https://github.com/Fullscreen/yt) and the **documentation** on [RubyDoc](http://www.rubydoc.info/gems/yt/frames).
7
+
8
+ [![Build Status](http://img.shields.io/travis/Fullscreen/yt/master.svg)](https://travis-ci.org/Fullscreen/yt)
9
+ [![Coverage Status](http://img.shields.io/coveralls/Fullscreen/yt/master.svg)](https://coveralls.io/r/Fullscreen/yt)
10
+ [![Dependency Status](http://img.shields.io/gemnasium/Fullscreen/yt.svg)](https://gemnasium.com/Fullscreen/yt)
11
+ [![Code Climate](http://img.shields.io/codeclimate/github/Fullscreen/yt.svg)](https://codeclimate.com/github/Fullscreen/yt)
12
+ [![Online docs](http://img.shields.io/badge/docs-✓-green.svg)](http://www.rubydoc.info/gems/yt/frames)
13
+ [![Gem Version](http://img.shields.io/gem/v/yt.svg)](http://rubygems.org/gems/yt)
14
+
15
+ After [registering your app](#configuring-your-app), you can run commands like:
16
+
17
+ ```ruby
18
+ channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow'
19
+ channel.title #=> "Fullscreen"
20
+ channel.public? #=> true
21
+ channel.comment_count #=> 773
22
+ channel.videos.count #=> 12
23
+ ```
24
+
25
+ ```ruby
26
+ video = Yt::Video.new id: 'MESycYJytkU'
27
+ video.title #=> "Fullscreen Creator Platform"
28
+ video.comment_count #=> 308
29
+ video.hd? #=> true
30
+ video.annotations.count #=> 1
31
+ ```
32
+
33
+ The **full documentation** is available at [rubydoc.info](http://www.rubydoc.info/gems/yt/frames).
34
+
35
+ How to install
36
+ ==============
37
+
38
+ To install on your system, run
39
+
40
+ gem install yt
41
+
42
+ To use inside a bundled Ruby project, add this line to the Gemfile:
43
+
44
+ gem 'yt', '~> 0.25.5'
45
+
46
+ Since the gem follows [Semantic Versioning](http://semver.org),
47
+ indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
48
+ guarantees that your project won’t occur in any error when you `bundle update`
49
+ and a new version of Yt is released.
50
+
51
+ Available resources
52
+ ===================
53
+
54
+ Yt::Account
55
+ -----------
56
+
57
+ Check [fullscreen.github.io/yt](http://fullscreen.github.io/yt/accounts.html) for the list of methods available for `Yt::Account`.
58
+
59
+
60
+ Yt::ContentOwner
61
+ ----------------
62
+
63
+ Use [Yt::ContentOwner](http://www.rubydoc.info/gems/yt/Yt/Models/ContentOwner) to:
64
+
65
+ * authenticate as a YouTube content owner
66
+ * list the channels partnered with a YouTube content owner
67
+ * list the claims administered by the content owner
68
+ * list and delete the references administered by the content owner
69
+ * list the policies and policy rules administered by the content owner
70
+ * create assets
71
+
72
+ ```ruby
73
+ # Content owners can be initialized with access token, refresh token or an authorization code
74
+ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
75
+
76
+ content_owner.partnered_channels.count #=> 12
77
+ content_owner.partnered_channels.map &:title #=> ["Fullscreen", "Best of Fullscreen", ...]
78
+ content_owner.partnered_channels.where(part: 'statistics').map &:subscriber_count #=> [136925, 56945, ...]
79
+
80
+ content_owner.claims.where(q: 'Fullscreen').count #=> 24
81
+ content_owner.claims.first #=> #<Yt::Models::Claim @id=...>
82
+ content_owner.claims.first.video_id #=> 'MESycYJytkU'
83
+ content_owner.claims.first.status #=> "active"
84
+
85
+ reference = content_owner.references.where(asset_id: "ABCDEFG").first #=> #<Yt::Models::Reference @id=...>
86
+ reference.delete #=> true
87
+
88
+ content_owner.policies.first #=> #<Yt::Models::Policy @id=...>
89
+ content_owner.policies.first.name #=> "Track in all countries"
90
+ content_owner.policies.first.rules.first #=> #<Yt::Models::PolicyRule @id=...>
91
+ content_owner.policies.first.rules.first.action #=> "monetize"
92
+ content_owner.policies.first.rules.first.included_territories #=> ["US", "CA"]
93
+
94
+ content_owner.create_asset type: 'web' #=> #<Yt::Models::Asset @id=...>
95
+ ```
96
+
97
+ *All the above methods require authentication (see below).*
98
+
99
+ Yt::Channel
100
+ -----------
101
+
102
+ Check [fullscreen.github.io/yt](http://fullscreen.github.io/yt/channels.html) for the list of methods available for `Yt::Channel`.
103
+
104
+ Yt::Video
105
+ ---------
106
+
107
+ Check [fullscreen.github.io/yt](http://fullscreen.github.io/yt/videos.html) for the list of methods available for `Yt::Video`.
108
+
109
+ Yt::Playlist
110
+ ------------
111
+
112
+ Check [fullscreen.github.io/yt](http://fullscreen.github.io/yt/playlists.html) for the list of methods available for `Yt::Playlist`.
113
+
114
+ Yt::PlaylistItem
115
+ ----------------
116
+
117
+ Check [fullscreen.github.io/yt](http://fullscreen.github.io/yt/playlist_items.html) for the list of methods available for `Yt::PlaylistItem`.
118
+
119
+ Yt::Collections::Videos
120
+ -----------------------
121
+
122
+ Use [Yt::Collections::Videos](http://www.rubydoc.info/gems/yt/Yt/Collections/Videos) to:
123
+
124
+ * search for videos
125
+
126
+ ```ruby
127
+ videos = Yt::Collections::Videos.new
128
+ videos.where(order: 'viewCount').first.title #=> "PSY - GANGNAM STYLE"
129
+ videos.where(q: 'Fullscreen CreatorPlatform', safe_search: 'none').size #=> 324
130
+ videos.where(chart: 'mostPopular', video_category_id: 44).first.title #=> "SINISTER - Trailer"
131
+ videos.where(id: 'MESycYJytkU,invalid').map(&:title) #=> ["Fullscreen Creator Platform"]
132
+ ```
133
+
134
+ *The methods above do not require authentication.*
135
+
136
+
137
+ Yt::Annotation
138
+ --------------
139
+
140
+ Check [fullscreen.github.io/yt](http://fullscreen.github.io/yt/annotations.html) for the list of methods available for `Yt::Annotation`.
141
+
142
+
143
+ Yt::MatchPolicy
144
+ ---------------
145
+
146
+ Use [Yt::MatchPolicy](http://www.rubydoc.info/gems/yt/Yt/Models/MatchPolicy) to:
147
+
148
+ * update the policy used by an asset
149
+
150
+ ```ruby
151
+ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
152
+ match_policy = Yt::MatchPolicy.new asset_id: 'ABCD12345678', auth: content_owner
153
+ match_policy.update policy_id: 'aBcdEF6g-HJ' #=> true
154
+ ```
155
+
156
+ Yt::Asset
157
+ ---------
158
+
159
+ Use [Yt::Asset](http://www.rubydoc.info/gems/yt/Yt/Models/Asset) to:
160
+
161
+ * read the ownership of an asset
162
+ * update the attributes of an asset
163
+
164
+ ```ruby
165
+
166
+ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
167
+ asset = Yt::Asset.new id: 'ABCD12345678', auth: content_owner
168
+ asset.ownership #=> #<Yt::Models::Ownership @general=...>
169
+ asset.ownership.obtain! #=> true
170
+ asset.general_owners.first.owner #=> 'CMSname'
171
+ asset.general_owners.first.everywhere? #=> true
172
+ asset.ownership.release! #=> true
173
+
174
+ asset.update metadata_mine: {notes: 'Some notes'} #=> true
175
+ ```
176
+
177
+ * to retrieve metadata for an asset (e.g. title, notes, description, custom_id)
178
+
179
+ ```ruby
180
+ content_owner = Yt::ContentOwner.new(...)
181
+ asset = content_owner.assets.where(id: 'A969176766549462', fetch_metadata: 'mine').first
182
+ asset.metadata_mine.title #=> "Master Final Neu La Anh Fix"
183
+
184
+ asset = content_owner.assets.where(id: 'A969176766549462', fetch_metadata: 'effective').first
185
+ asset.metadata_effective.title #=> "Neu la anh" (different due to ownership conflicts)
186
+ ```
187
+
188
+ * to search for an asset
189
+
190
+ ```ruby
191
+ content_owner.assets.where(labels: "campaign:cpiuwdz-8oc").size #=> 417
192
+ content_owner.assets.where(labels: "campaign:cpiuwdz-8oc").first.title #=> "Whoomp! (Supadupafly) (Xxl Hip House Mix)"
193
+ ```
194
+
195
+ Yt::Claim
196
+ ---------
197
+
198
+ Use [Yt::Claim](http://www.rubydoc.info/gems/yt/Yt/Models/Claim) to:
199
+
200
+ * read the attributes of a claim
201
+ * view the history of a claim
202
+ * update the attributes of an claim
203
+
204
+ ```ruby
205
+
206
+ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
207
+ claim = Yt::Claim.new id: 'ABCD12345678', auth: content_owner
208
+ claim.video_id #=> 'va141cJga2'
209
+ claim.asset_id #=> 'A1234'
210
+ claim.content_type #=> 'audiovisual'
211
+ claim.active? #=> true
212
+
213
+ claim.claim_history #=> #<Yt::Models::ClaimHistory ...>
214
+ claim.claim_history.events[0].type #=> "claim_create"
215
+
216
+ claim.delete #=> true
217
+ ```
218
+
219
+ *The methods above require to be authenticated as the video’s content owner (see below).*
220
+
221
+ Yt::Ownership
222
+ -------------
223
+
224
+ Use [Yt::Ownership](http://www.rubydoc.info/gems/yt/Yt/Models/Ownership) to:
225
+
226
+ * update the ownership of an asset
227
+
228
+ ```ruby
229
+ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
230
+ ownership = Yt::Ownership.new asset_id: 'ABCD12345678', auth: $content_owner
231
+ new_general_owner_attrs = {ratio: 100, owner: 'CMSname', type: 'include', territories: ['US', 'CA']}
232
+ ownership.update general: [new_general_owner_attrs]
233
+ ```
234
+
235
+ *The methods above require to be authenticated as the video’s content owner (see below).*
236
+
237
+ Yt::AdvertisingOptionsSet
238
+ -------------------------
239
+
240
+ Use [Yt::AdvertisingOptionsSet](http://www.rubydoc.info/gems/yt/Yt/Models/AdvertisingOptionsSet) to:
241
+
242
+ * update the advertising settings of a video
243
+
244
+ ```ruby
245
+ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
246
+ ad_options = Yt::AdvertisingOptionsSet.new video_id: 'MESycYJytkU', auth: $content_owner
247
+ ad_options.update ad_formats: %w(standard_instream long) #=> true
248
+ ```
249
+
250
+ *The methods above require to be authenticated as the video’s content owner (see below).*
251
+
252
+ Instrumentation
253
+ ===============
254
+
255
+ 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.
256
+
257
+ Subscribe to the `request.yt` notification within your application:
258
+
259
+ ```ruby
260
+ ActiveSupport::Notifications.subscribe 'request.yt' do |*args|
261
+ event = ActiveSupport::Notifications::Event.new(*args)
262
+
263
+ event.payload[:request_uri] #=> #<URI::HTTPS URL:https://www.googleapis.com/youtube/v3/channels?id=UCxO1tY8h1AhOz0T4ENwmpow&part=snippet>
264
+ event.payload[:method] #=> :get
265
+ event.payload[:response] #=> #<Net::HTTPOK 200 OK readbody=true>
266
+
267
+ event.end #=> 2014-08-22 16:57:17 -0700
268
+ event.duration #=> 141.867 (ms)
269
+ end
270
+ ```
271
+
272
+ Configuring your app
273
+ ====================
274
+
275
+ In order to use Yt you must register your app in the [Google Developers Console](https://console.developers.google.com).
276
+
277
+ If you don’t have a registered app, browse to the console and select "Create Project":
278
+ ![01-create-project](https://cloud.githubusercontent.com/assets/7408595/3373043/4224c894-fbb0-11e3-9f8a-4d96bddce136.png)
279
+
280
+ When your project is ready, select APIs & Auth in the menu and individually enable Google+, YouTube Analytics and YouTube Data API:
281
+ ![02-select-api](https://cloud.githubusercontent.com/assets/4453997/8442701/5d0f77f4-1f35-11e5-93d8-07d4459186b5.png)
282
+ ![02a-enable google api](https://cloud.githubusercontent.com/assets/4453997/8442306/0f714cb8-1f33-11e5-99b3-f17a4b1230fe.png)
283
+ ![02b-enable youtube api](https://cloud.githubusercontent.com/assets/4453997/8442304/0f6fd0e0-1f33-11e5-981a-acf90ccd7409.png)
284
+ ![02c-enable youtube analytics api](https://cloud.githubusercontent.com/assets/4453997/8442305/0f71240e-1f33-11e5-9b60-4ecea02da9be.png)
285
+
286
+ The next step is to create an API key. Depending on the nature of your app, you should pick one of the following strategies.
287
+
288
+ Apps that do not require user interactions
289
+ ------------------------------------------
290
+
291
+ If you are building a read-only app that fetches public data from YouTube, then
292
+ all you need is a **Public API access**.
293
+
294
+ Click on "Create new Key" in the Public API section and select "Server Key":
295
+ ![03-create-key](https://cloud.githubusercontent.com/assets/7408595/3373045/42258fcc-fbb0-11e3-821c-699c8a3ce7bc.png)
296
+ ![04-create-server-key](https://cloud.githubusercontent.com/assets/7408595/3373044/42251db2-fbb0-11e3-93f9-8f06f8390b4e.png)
297
+
298
+ Once the key for server application is created, copy the API key and add it
299
+ to your code with the following snippet of code (replacing with your own key):
300
+
301
+ ```ruby
302
+ Yt.configure do |config|
303
+ config.api_key = 'AIzaSyAO8dXpvZcaP2XSDFBD91H8yQ'
304
+ end
305
+ ```
306
+
307
+ Remember: this kind of app is not allowed to perform any destructive operation,
308
+ so you won’t be able to like a video, subscribe to a channel or delete a
309
+ playlist from a specific account. You will only be able to retrieve read-only
310
+ data.
311
+
312
+ Web apps that require user interactions
313
+ ---------------------------------------
314
+
315
+ If you are building a web app that manages YouTube accounts, you need the
316
+ owner of each account to authorize your app. There are three scenarios:
317
+
318
+ Scenario 1. If you already have the account’s **access token**, then you are ready to go.
319
+ Just pass that access token to the account initializer, such as:
320
+
321
+ ```ruby
322
+ account = Yt::Account.new access_token: 'ya29.1.ABCDEFGHIJ'
323
+ account.email #=> (retrieves the account’s e-mail address)
324
+ account.videos #=> (lists a video to an account’s playlist)
325
+ ```
326
+
327
+ Scenario 2. If you don’t have the account’s access token, but you have the
328
+ **refresh token**, then it’s almost as easy.
329
+ In the [Google Developers Console](https://console.developers.google.com),
330
+ find the web application that was used to obtain the refresh token, copy the
331
+ Client ID and Client secret and add them to you code with the following snippet
332
+ of code (replacing with your own keys):
333
+
334
+ ```ruby
335
+ Yt.configure do |config|
336
+ config.client_id = '1234567890.apps.googleusercontent.com'
337
+ config.client_secret = '1234567890'
338
+ end
339
+ ```
340
+ Then you can manage a YouTube account by passing the refresh token to the
341
+ account initializer, such as:
342
+
343
+ ```ruby
344
+ account = Yt::Account.new refresh_token: '1/1234567890'
345
+ account.email #=> (retrieves the account’s e-mail address)
346
+ account.videos #=> (lists a video to an account’s playlist)
347
+ ```
348
+
349
+ Scenario 3. If you don’t have any account’s token, then you can get one by
350
+ having the user authorize your app through the Google OAuth page.
351
+
352
+ In the [Google Developers Console](https://console.developers.google.com),
353
+ click on "Create new Client ID" in the OAuth section and select "Web application":
354
+ ![06-create-client-key](https://cloud.githubusercontent.com/assets/7408595/3373047/42379eba-fbb0-11e3-89c4-16b10e072de6.png)
355
+
356
+ Fill the "Authorized Redirect URI" textarea with the URL of your app where you
357
+ want to redirect users after they authorize their YouTube account.
358
+
359
+ Once the Client ID for web application is created, copy the Client ID and secret
360
+ and add them to your code with the following snippet of code (replacing with your own keys):
361
+
362
+ ```ruby
363
+ Yt.configure do |config|
364
+ config.client_id = '49781862760-4t610gtk35462g.apps.googleusercontent.com'
365
+ config.client_secret = 'NtFHjZkJcwYZDfYVz9mp8skz9'
366
+ end
367
+ ```
368
+
369
+ Finally, in your web app, add a link to the URL generated by running
370
+
371
+ ```ruby
372
+ Yt::Account.new(scopes: scopes, redirect_uri: redirect_uri).authentication_url
373
+ ```
374
+
375
+ where `redirect_uri` is the URL you entered in the form above, and `scopes` is
376
+ the list of YouTube scopes you want the user to authorize. Depending on the
377
+ nature of your app, you can pick one or more among `youtube`, `youtube.readonly` `userinfo.email`.
378
+
379
+ Every user who authorizes your app will be redirected to the `redirect_uri`
380
+ with an extra `code` parameter that looks something like `4/Ja60jJ7_Kw0`.
381
+ Just pass the code to the following method to authenticate and initialize the account:
382
+
383
+ ```ruby
384
+ account = Yt::Account.new authorization_code: '4/Ja60jJ7_Kw0', redirect_uri: redirect_uri
385
+ account.email #=> (retrieves the account’s e-mail address)
386
+ account.videos #=> (lists a video to an account’s playlist)
387
+ ```
388
+
389
+ Configuring with environment variables
390
+ --------------------------------------
391
+
392
+ As an alternative to the approach above, you can configure your app with
393
+ variables. Setting the following environment variables:
394
+
395
+ ```bash
396
+ export YT_CLIENT_ID="1234567890.apps.googleusercontent.com"
397
+ export YT_CLIENT_SECRET="1234567890"
398
+ export YT_API_KEY="123456789012345678901234567890"
399
+ ```
400
+
401
+ is equivalent to configuring your app with the initializer:
402
+
403
+ ```ruby
404
+ Yt.configure do |config|
405
+ config.client_id = '1234567890.apps.googleusercontent.com'
406
+ config.client_secret = '1234567890'
407
+ config.api_key = '123456789012345678901234567890'
408
+ end
409
+ ```
410
+
411
+ so use the approach that you prefer.
412
+ If a variable is set in both places, then `Yt.configure` takes precedence.
413
+
414
+ Why you should use Yt…
415
+ ======================
416
+
417
+ … and not [youtube_it](https://github.com/kylejginavan/youtube_it)?
418
+ Because youtube_it does not support YouTube API V3, and the YouTube API V2 has
419
+ been [officially deprecated as of March 4, 2014](https://developers.google.com/youtube/2.0/developers_guide_protocol_audience).
420
+ If you need help upgrading your code, check [YOUTUBE_IT.md](https://github.com/Fullscreen/yt/blob/master/YOUTUBE_IT.md),
421
+ a step-by-step comparison between youtube_it and Yt to make upgrade easier.
422
+
423
+ … and not [Google Api Client](https://github.com/google/google-api-ruby-client)?
424
+ Because Google Api Client is poorly coded, poorly documented and adds many
425
+ dependencies, bloating the size of your project.
426
+
427
+ … and not your own code? Because Yt is fully tested, well documented,
428
+ has few dependencies and helps you forget about the burden of dealing with
429
+ Google API!
430
+
431
+ How to test
432
+ ===========
433
+
434
+ Yt comes with two different sets of tests:
435
+
436
+ 1. tests in `spec/models`, `spec/collections` and `spec/errors` **do not hit** the YouTube API
437
+ 1. tests in `spec/requests` **hit** the YouTube API and require authentication
438
+
439
+ The reason why some tests actually hit the YouTube API is because they are
440
+ meant to really integrate Yt with YouTube. YouTube API is not exactly
441
+ *the most reliable* API out there, so we need to make sure that the responses
442
+ match the documentation.
443
+
444
+ You don’t have to run all the tests every time you change code.
445
+ Travis CI is already set up to do this for when whenever you push a branch
446
+ or create a pull request for this project.
447
+
448
+ To only run tests against models, collections and errors (which do not hit the API), type:
449
+
450
+ ```bash
451
+ rspec spec/models spec/collections spec/errors
452
+ ```
453
+
454
+ To also run live-tests against the YouTube API, type:
455
+
456
+ ```bash
457
+ rspec
458
+ ```
459
+
460
+ This will fail unless you have set up a test YouTube application and some
461
+ tests YouTube accounts to hit the API. Once again, you probably don’t need
462
+ this, since Travis CI already takes care of running this kind of tests.
463
+
464
+ How to release new versions
465
+ ===========================
466
+
467
+ If you are a manager of this project, remember to upgrade the [Yt gem](http://rubygems.org/gems/yt)
468
+ whenever a new feature is added or a bug gets fixed.
469
+
470
+ Make sure all the tests are passing on [Travis CI](https://travis-ci.org/Fullscreen/yt),
471
+ document the changes in HISTORY.md and README.md, bump the version, then run
472
+
473
+ rake release
474
+
475
+ Remember that the yt gem follows [Semantic Versioning](http://semver.org).
476
+ Any new release that is fully backward-compatible should bump the *patch* version (0.0.x).
477
+ Any new version that breaks compatibility should bump the *minor* version (0.x.0)
478
+
479
+ How to contribute
480
+ =================
481
+
482
+ Yt needs your support!
483
+ The goal of Yt is to provide a Ruby interface for all the methods exposed by
484
+ the [YouTube Data API (v3)](https://developers.google.com/youtube/v3) and by
485
+ the [YouTube Analytics API](https://developers.google.com/youtube/analytics).
486
+
487
+ If you find that a method is missing, fork the project, add the missing code,
488
+ write the appropriate tests, then submit a pull request, and it will gladly
489
+ be merged!