slainer68_youtube_it 2.1.1

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 (48) hide show
  1. data/Gemfile +10 -0
  2. data/Gemfile.lock +27 -0
  3. data/Manifest.txt +37 -0
  4. data/README.rdoc +270 -0
  5. data/Rakefile +53 -0
  6. data/VERSION +1 -0
  7. data/lib/youtube_it/chain_io.rb +76 -0
  8. data/lib/youtube_it/client.rb +447 -0
  9. data/lib/youtube_it/middleware/faraday_authheader.rb +24 -0
  10. data/lib/youtube_it/middleware/faraday_oauth.rb +21 -0
  11. data/lib/youtube_it/middleware/faraday_oauth2.rb +13 -0
  12. data/lib/youtube_it/middleware/faraday_youtubeit.rb +30 -0
  13. data/lib/youtube_it/model/activity.rb +17 -0
  14. data/lib/youtube_it/model/author.rb +13 -0
  15. data/lib/youtube_it/model/category.rb +11 -0
  16. data/lib/youtube_it/model/comment.rb +16 -0
  17. data/lib/youtube_it/model/contact.rb +19 -0
  18. data/lib/youtube_it/model/content.rb +18 -0
  19. data/lib/youtube_it/model/message.rb +12 -0
  20. data/lib/youtube_it/model/playlist.rb +11 -0
  21. data/lib/youtube_it/model/rating.rb +23 -0
  22. data/lib/youtube_it/model/subscription.rb +7 -0
  23. data/lib/youtube_it/model/thumbnail.rb +17 -0
  24. data/lib/youtube_it/model/user.rb +27 -0
  25. data/lib/youtube_it/model/video.rb +239 -0
  26. data/lib/youtube_it/parser.rb +534 -0
  27. data/lib/youtube_it/record.rb +12 -0
  28. data/lib/youtube_it/request/base_search.rb +72 -0
  29. data/lib/youtube_it/request/error.rb +15 -0
  30. data/lib/youtube_it/request/standard_search.rb +43 -0
  31. data/lib/youtube_it/request/user_search.rb +47 -0
  32. data/lib/youtube_it/request/video_search.rb +102 -0
  33. data/lib/youtube_it/request/video_upload.rb +538 -0
  34. data/lib/youtube_it/response/video_search.rb +41 -0
  35. data/lib/youtube_it/version.rb +4 -0
  36. data/lib/youtube_it.rb +83 -0
  37. data/slainer68_youtube_it.gemspec +102 -0
  38. data/test/files/recorded_response.xml +1 -0
  39. data/test/files/youtube_video_response.xml +53 -0
  40. data/test/helper.rb +9 -0
  41. data/test/test.mov +0 -0
  42. data/test/test_chain_io.rb +63 -0
  43. data/test/test_client.rb +435 -0
  44. data/test/test_field_search.rb +48 -0
  45. data/test/test_video.rb +48 -0
  46. data/test/test_video_feed_parser.rb +271 -0
  47. data/test/test_video_search.rb +141 -0
  48. metadata +172 -0
@@ -0,0 +1,447 @@
1
+ class YouTubeIt
2
+ class Client
3
+ include YouTubeIt::Logging
4
+ # Previously this was a logger instance but we now do it globally
5
+
6
+ def initialize *params
7
+ if params.first.is_a?(Hash)
8
+ hash_options = params.first
9
+ @user = hash_options[:username]
10
+ @pass = hash_options[:password]
11
+ @dev_key = hash_options[:dev_key]
12
+ @client_id = hash_options[:client_id] || "youtube_it"
13
+ @legacy_debug_flag = hash_options[:debug]
14
+ elsif params.first
15
+ puts "* warning: the method YouTubeIt::Client.new(user, passwd, dev_key) is deprecated, use YouTubeIt::Client.new(:username => 'user', :password => 'passwd', :dev_key => 'dev_key')"
16
+ @user = params.shift
17
+ @pass = params.shift
18
+ @dev_key = params.shift
19
+ @client_id = params.shift || "youtube_it"
20
+ @legacy_debug_flag = params.shift
21
+ end
22
+ end
23
+
24
+ # Retrieves an array of standard feed, custom query, or user videos.
25
+ #
26
+ # === Parameters
27
+ # If fetching videos for a standard feed:
28
+ # params<Symbol>:: Accepts a symbol of :top_rated, :top_favorites, :most_viewed,
29
+ # :most_popular, :most_recent, :most_discussed, :most_linked,
30
+ # :most_responded, :recently_featured, and :watch_on_mobile.
31
+ #
32
+ # You can find out more specific information about what each standard feed provides
33
+ # by visiting: http://code.google.com/apis/youtube/reference.html#Standard_feeds
34
+ #
35
+ # options<Hash> (optional):: Accepts the options of :time, :page (default is 1),
36
+ # and :per_page (default is 25). :offset and :max_results
37
+ # can also be passed for a custom offset.
38
+ #
39
+ # If fetching videos by tags, categories, query:
40
+ # params<Hash>:: Accepts the keys :tags, :categories, :query, :order_by,
41
+ # :author, :racy, :response_format, :video_format, :page (default is 1),
42
+ # and :per_page(default is 25)
43
+ #
44
+ # options<Hash>:: Not used. (Optional)
45
+ #
46
+ # If fetching videos for a particular user:
47
+ # params<Hash>:: Key of :user with a value of the username.
48
+ # options<Hash>:: Not used. (Optional)
49
+ # === Returns
50
+ # YouTubeIt::Response::VideoSearch
51
+ def videos_by(params, options={})
52
+ request_params = params.respond_to?(:to_hash) ? params : options
53
+ request_params[:page] = integer_or_default(request_params[:page], 1)
54
+
55
+ request_params[:dev_key] = @dev_key if @dev_key
56
+
57
+ unless request_params[:max_results]
58
+ request_params[:max_results] = integer_or_default(request_params[:per_page], 25)
59
+ end
60
+
61
+ unless request_params[:offset]
62
+ request_params[:offset] = calculate_offset(request_params[:page], request_params[:max_results] )
63
+ end
64
+
65
+ if params.respond_to?(:to_hash) and not params[:user]
66
+ request = YouTubeIt::Request::VideoSearch.new(request_params)
67
+ elsif (params.respond_to?(:to_hash) && params[:user]) || (params == :favorites)
68
+ request = YouTubeIt::Request::UserSearch.new(params, request_params)
69
+ else
70
+ request = YouTubeIt::Request::StandardSearch.new(params, request_params)
71
+ end
72
+
73
+ logger.debug "Submitting request [url=#{request.url}]." if @legacy_debug_flag
74
+ parser = YouTubeIt::Parser::VideosFeedParser.new(request.url)
75
+ parser.parse
76
+ end
77
+
78
+ # Retrieves a single YouTube video.
79
+ #
80
+ # === Parameters
81
+ # vid<String>:: The ID or URL of the video that you'd like to retrieve.
82
+ # user<String>:: The user that uploaded the video that you'd like to retrieve.
83
+ #
84
+ # === Returns
85
+ # YouTubeIt::Model::Video
86
+ def video_by(video)
87
+ vid = nil
88
+ vid_regex = /(?:youtube.com|youtu.be).*(?:\/|v=)(\w+)/
89
+ if video =~ vid_regex
90
+ vid = $1
91
+ else
92
+ vid = video
93
+ end
94
+ video_id ="http://gdata.youtube.com/feeds/api/videos/#{vid}?v=2#{@dev_key ? '&key='+@dev_key : ''}"
95
+ parser = YouTubeIt::Parser::VideoFeedParser.new(video_id)
96
+ parser.parse
97
+ end
98
+
99
+ def video_by_user(user, vid)
100
+ video_id = "http://gdata.youtube.com/feeds/api/users/#{user}/uploads/#{vid}?v=2#{@dev_key ? '&key='+@dev_key : ''}"
101
+ parser = YouTubeIt::Parser::VideoFeedParser.new(video_id)
102
+ parser.parse
103
+ end
104
+
105
+ def video_upload(data, opts = {})
106
+ client.upload(data, opts)
107
+ end
108
+
109
+ def video_update(video_id, opts = {})
110
+ client.update(video_id, opts)
111
+ end
112
+
113
+ def video_delete(video_id)
114
+ client.delete(video_id)
115
+ end
116
+
117
+ def message_delete(message_id)
118
+ client.delete_message(message_id)
119
+ end
120
+
121
+ def upload_token(options, nexturl = "http://www.youtube.com/my_videos")
122
+ client.get_upload_token(options, nexturl)
123
+ end
124
+
125
+ def add_comment(video_id, comment)
126
+ client.add_comment(video_id, comment)
127
+ end
128
+
129
+ # opts is converted to get params and appended to comments gdata api url
130
+ # eg opts = { 'max-results' => 10, 'start-index' => 20 }
131
+ # hash does _not_ play nice with symbols
132
+ def comments(video_id, opts = {})
133
+ client.comments(video_id, opts)
134
+ end
135
+
136
+ def add_favorite(video_id)
137
+ client.add_favorite(video_id)
138
+ end
139
+
140
+ def delete_favorite(video_id)
141
+ client.delete_favorite(video_id)
142
+ end
143
+
144
+ def favorites(user = nil, opts = {})
145
+ client.favorites(user, opts)
146
+ end
147
+
148
+ def profile(user = nil)
149
+ client.profile(user)
150
+ end
151
+
152
+ # Fetches a user's activity feed.
153
+ def activity(user = nil, opts = {})
154
+ client.get_activity(user, opts)
155
+ end
156
+
157
+ def playlist(playlist_id)
158
+ client.playlist playlist_id
159
+ end
160
+
161
+ def playlists(user = nil)
162
+ client.playlists(user)
163
+ end
164
+
165
+ def add_playlist(options)
166
+ client.add_playlist(options)
167
+ end
168
+
169
+ def update_playlist(playlist_id, options)
170
+ client.update_playlist(playlist_id, options)
171
+ end
172
+
173
+ def add_video_to_playlist(playlist_id, video_id)
174
+ client.add_video_to_playlist(playlist_id, video_id)
175
+ end
176
+
177
+ def delete_video_from_playlist(playlist_id, playlist_entry_id)
178
+ client.delete_video_from_playlist(playlist_id, playlist_entry_id)
179
+ end
180
+
181
+ def delete_playlist(playlist_id)
182
+ client.delete_playlist(playlist_id)
183
+ end
184
+
185
+ def like_video(video_id)
186
+ client.rate_video(video_id, 'like')
187
+ end
188
+
189
+ def dislike_video(video_id)
190
+ client.rate_video(video_id, 'dislike')
191
+ end
192
+
193
+ def subscribe_channel(channel_name)
194
+ client.subscribe_channel(channel_name)
195
+ end
196
+
197
+ def unsubscribe_channel(subscription_id)
198
+ client.unsubscribe_channel(subscription_id)
199
+ end
200
+
201
+ def subscriptions(user_id = nil)
202
+ client.subscriptions(user_id)
203
+ end
204
+
205
+ def enable_http_debugging
206
+ client.enable_http_debugging
207
+ end
208
+
209
+ def add_response(original_video_id, response_video_id)
210
+ client.add_response(original_video_id, response_video_id)
211
+ end
212
+
213
+ def delete_response(original_video_id, response_video_id)
214
+ client.delete_response(original_video_id, response_video_id)
215
+ end
216
+
217
+ def current_user
218
+ client.get_current_user
219
+ end
220
+
221
+ # Gets the authenticated users video with the given ID. It may be private.
222
+ def my_video(video_id)
223
+ client.get_my_video(video_id)
224
+ end
225
+
226
+ # Gets all videos
227
+ def my_videos(opts = {})
228
+ client.get_my_videos(opts)
229
+ end
230
+
231
+ # Get's all of the user's contacts/friends.
232
+ def my_contacts(opts = {})
233
+ client.get_my_contacts(opts)
234
+ end
235
+
236
+ # Send vedio message
237
+ def send_message(opts = {})
238
+ client.send_message(opts)
239
+ end
240
+
241
+ # Get's all of the user's messages/inbox.
242
+ def my_messages(opts = {})
243
+ client.get_my_messages(opts)
244
+ end
245
+
246
+ private
247
+
248
+ def client
249
+ @client ||= YouTubeIt::Upload::VideoUpload.new(:username => @user, :password => @pass, :dev_key => @dev_key)
250
+ end
251
+
252
+ def calculate_offset(page, per_page)
253
+ page == 1 ? 1 : ((per_page * page) - per_page + 1)
254
+ end
255
+
256
+ def integer_or_default(value, default)
257
+ value = value.to_i
258
+ value > 0 ? value : default
259
+ end
260
+ end
261
+
262
+ class AuthSubClient < Client
263
+ def initialize *params
264
+ if params.first.is_a?(Hash)
265
+ hash_options = params.first
266
+ @authsub_token = hash_options[:token]
267
+ @dev_key = hash_options[:dev_key]
268
+ @client_id = hash_options[:client_id] || "youtube_it"
269
+ @legacy_debug_flag = hash_options[:debug]
270
+ else
271
+ puts "* warning: the method YouTubeIt::AuthSubClient.new(token, dev_key) is depricated, use YouTubeIt::AuthSubClient.new(:token => 'token', :dev_key => 'dev_key')"
272
+ @authsub_token = params.shift
273
+ @dev_key = params.shift
274
+ @client_id = params.shift || "youtube_it"
275
+ @legacy_debug_flag = params.shift
276
+ end
277
+ end
278
+
279
+ def create_session_token
280
+ response = nil
281
+ session_token_url = "/accounts/AuthSubSessionToken"
282
+
283
+ http_connection do |session|
284
+ response = session.get2('https://%s' % session_token_url,session_token_header).body
285
+ end
286
+ @authsub_token = response.sub('Token=','')
287
+ end
288
+
289
+ def revoke_session_token
290
+ response = nil
291
+ session_token_url = "/accounts/AuthSubRevokeToken"
292
+
293
+ http_connection do |session|
294
+ response = session.get2('https://%s' % session_token_url,session_token_header).code
295
+ end
296
+ response.to_s == '200' ? true : false
297
+ end
298
+
299
+ def session_token_info
300
+ response = nil
301
+ session_token_url = "/accounts/AuthSubTokenInfo"
302
+
303
+ http_connection do |session|
304
+ response = session.get2('https://%s' % session_token_url,session_token_header)
305
+ end
306
+ {:code => response.code, :body => response.body }
307
+ end
308
+
309
+ private
310
+ def client
311
+ @client ||= YouTubeIt::Upload::VideoUpload.new(:dev_key => @dev_key, :authsub_token => @authsub_token)
312
+ end
313
+
314
+ def session_token_header
315
+ {
316
+ "Content-Type" => "application/x-www-form-urlencoded",
317
+ "Authorization" => "AuthSub token=#{@authsub_token}"
318
+ }
319
+ end
320
+
321
+ def http_connection
322
+ http = Net::HTTP.new("www.google.com")
323
+ http.set_debug_output(logger) if @http_debugging
324
+ http.start do |session|
325
+ yield(session)
326
+ end
327
+ end
328
+ end
329
+
330
+ class OAuthClient < Client
331
+ def initialize *params
332
+ if params.first.is_a?(Hash)
333
+ hash_options = params.first
334
+ @consumer_key = hash_options[:consumer_key]
335
+ @consumer_secret = hash_options[:consumer_secret]
336
+ @user = hash_options[:username]
337
+ @dev_key = hash_options[:dev_key]
338
+ @client_id = hash_options[:client_id] || "youtube_it"
339
+ @legacy_debug_flag = hash_options[:debug]
340
+ else
341
+ puts "* warning: the method YouTubeIt::OAuthClient.new(consumer_key, consumer_secrect, dev_key) is depricated, use YouTubeIt::OAuthClient.new(:consumer_key => 'consumer key', :consumer_secret => 'consumer secret', :dev_key => 'dev_key')"
342
+ @consumer_key = params.shift
343
+ @consumer_secret = params.shift
344
+ @dev_key = params.shift
345
+ @user = params.shift
346
+ @client_id = params.shift || "youtube_it"
347
+ @legacy_debug_flag = params.shift
348
+ end
349
+ end
350
+
351
+ def consumer
352
+ @consumer ||= ::OAuth::Consumer.new(@consumer_key,@consumer_secret,{
353
+ :site=>"https://www.google.com",
354
+ :request_token_path=>"/accounts/OAuthGetRequestToken",
355
+ :authorize_path=>"/accounts/OAuthAuthorizeToken",
356
+ :access_token_path=>"/accounts/OAuthGetAccessToken"})
357
+ end
358
+
359
+ def request_token(callback)
360
+ @request_token = consumer.get_request_token({:oauth_callback => callback},{:scope => "http://gdata.youtube.com"})
361
+ end
362
+
363
+ def access_token
364
+ @access_token = ::OAuth::AccessToken.new(consumer, @atoken, @asecret)
365
+ end
366
+
367
+ def config_token
368
+ {
369
+ :consumer_key => @consumer_key,
370
+ :consumer_secret => @consumer_secret,
371
+ :token => @atoken,
372
+ :token_secret => @asecret
373
+ }
374
+ end
375
+
376
+ def authorize_from_request(rtoken,rsecret,verifier)
377
+ request_token = ::OAuth::RequestToken.new(consumer,rtoken,rsecret)
378
+ access_token = request_token.get_access_token({:oauth_verifier => verifier})
379
+ @atoken,@asecret = access_token.token, access_token.secret
380
+ end
381
+
382
+ def authorize_from_access(atoken,asecret)
383
+ @atoken,@asecret = atoken, asecret
384
+ end
385
+
386
+ def current_user
387
+ profile = access_token.get("http://gdata.youtube.com/feeds/api/users/default")
388
+ response_code = profile.code.to_i
389
+
390
+ if response_code/10 == 20 # success
391
+ REXML::Document.new(profile.body).elements["entry"].elements['author'].elements['name'].text
392
+ elsif response_code == 403 || response_code == 401 # auth failure
393
+ raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
394
+ else
395
+ raise YouTubeIt::Upload::UploadError.new(profile.inspect, response_code)
396
+ end
397
+ end
398
+
399
+ private
400
+
401
+ def client
402
+ # IMPORTANT: make sure authorize_from_access is called before client is fetched
403
+ @client ||= YouTubeIt::Upload::VideoUpload.new(:username => current_user, :dev_key => @dev_key, :access_token => access_token, :config_token => config_token)
404
+ end
405
+
406
+ end
407
+
408
+ class OAuth2Client < YouTubeIt::Client
409
+ def initialize(options)
410
+ @client_id = options[:client_id]
411
+ @client_secret = options[:client_secret]
412
+ @client_access_token = options[:client_access_token]
413
+ @client_refresh_token = options[:client_refresh_token]
414
+ @dev_key = options[:dev_key]
415
+ end
416
+
417
+ def oauth_client
418
+ @oauth_client ||= ::OAuth2::Client.new(@client_id, @client_secret,
419
+ :site => "https://accounts.google.com",
420
+ :authorize_url => '/o/oauth2/auth',
421
+ :token_url => '/o/oauth2/token')
422
+ end
423
+
424
+ def access_token
425
+ @access_token ||= ::OAuth2::AccessToken.new(oauth_client, @client_access_token, :refresh_token => @client_refresh_token)
426
+ end
427
+
428
+ def current_user
429
+ profile = access_token.get("http://gdata.youtube.com/feeds/api/users/default")
430
+ response_code = profile.status
431
+
432
+ if response_code/10 == 20 # success
433
+ REXML::Document.new(profile.body).elements["entry"].elements['author'].elements['name'].text
434
+ elsif response_code == 403 || response_code == 401 # auth failure
435
+ raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
436
+ else
437
+ raise YouTubeIt::Upload::UploadError.new(profile.inspect, response_code)
438
+ end
439
+ end
440
+
441
+ private
442
+
443
+ def client
444
+ @client ||= YouTubeIt::Upload::VideoUpload.new(:username => current_user, :access_token => access_token, :dev_key => @dev_key)
445
+ end
446
+ end
447
+ end
@@ -0,0 +1,24 @@
1
+ module Faraday
2
+ class Request::AuthHeader < Faraday::Middleware
3
+
4
+ def call(env)
5
+ req_headers = env[:request_headers]
6
+ req_headers.merge!(@headers)
7
+ unless req_headers.include?("GData-Version")
8
+ req_headers.merge!("GData-Version" => "2")
9
+ end
10
+ unless req_headers.include?("Content-Type")
11
+ req_headers.merge!("Content-Type" => "application/atom+xml; charset=UTF-8")
12
+ end
13
+ unless req_headers.include?("Content-Length")
14
+ req_headers.merge!("Content-Length" => env[:body] ? "#{env[:body].length}" : "0")
15
+ end
16
+
17
+ @app.call(env)
18
+ end
19
+
20
+ def initialize(app, headers)
21
+ @app, @headers = app, headers
22
+ end
23
+ end
24
+ end