youtube_it 2.1.4 → 2.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,3 +1,5 @@
1
+ == YOUTUBE_IT {<img src="https://secure.travis-ci.org/kylejginavan/youtube_it.png"/>}[http://travis-ci.org/kylejginavan/youtube_it]
2
+
1
3
  == DONATION
2
4
 
3
5
  YOUTUBE_IT is developed by many contributors who are passioned about opensource projects
@@ -58,6 +60,12 @@ If your access token is still valid (be careful, access tokens may only be valid
58
60
 
59
61
  $ client.refresh_access_token!
60
62
 
63
+ == PROFILES
64
+ you can use multiple profiles in the same account like that
65
+
66
+ $ profiles = client.profiles(['username1','username2'])
67
+ $ profiles['username1'].username, "username1"
68
+
61
69
  == VIDEO QUERIES
62
70
 
63
71
  Note: Each type of client enables searching capabilities.
@@ -84,6 +92,16 @@ Advanced Queries (with boolean operators OR (either), AND (include), NOT (exclud
84
92
  $ client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] }, :tags => { :include => ['football'], :exclude => ['soccer'] })
85
93
 
86
94
 
95
+ Custom Query Params
96
+ You can use custom query params like that:
97
+
98
+ $ client.videos_by(:query => "penguin", :safe_search => "strict")
99
+ $ client.videos_by(:query => "penguin", :duration => "long")
100
+ $ client.videos_by(:query => "penguin", :hd => "true")
101
+ $ client.videos_by(:query => "penguin", :region => "AR")
102
+
103
+ you can see more options here https://developers.google.com/youtube/2.0/reference#yt_format
104
+
87
105
  Fields Parameter(experimental features):
88
106
  Return videos more than 1000 views
89
107
  $ client.videos_by(:fields => {:view_count => "1000"})
@@ -106,6 +124,10 @@ Upload Video:
106
124
  Upload Video With A Developer Tag (Note the tags are not immediately available):
107
125
  $ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :dev_tag => 'tagdev')
108
126
 
127
+ Upload Private Video:
128
+ $ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :private => true)
129
+
130
+
109
131
  Update Video:
110
132
  $ client.video_update("FQK1URcxmb4", :title => "new test",:description => 'new description', :category => 'People',:keywords => %w[cool blah test])
111
133
 
@@ -117,7 +139,7 @@ My Videos:
117
139
 
118
140
  My Video:
119
141
  $ client.my_video(video_id)
120
-
142
+
121
143
  Profile Details:
122
144
  $ client.profile(user) #default: current user
123
145
 
@@ -127,6 +149,12 @@ List Comments:
127
149
  Add A Comment:
128
150
  $ client.add_comment(video_id, "test comment!")
129
151
 
152
+ Add A Reply Comment:
153
+ $ client.add_comment(video_id, "test reply!", :reply_to => another_comment)
154
+
155
+ Delete A Comment:
156
+ $ client.delete_comment(video_id, comment_id)
157
+
130
158
  List Favorites:
131
159
  $ client.favorites(user) # default: current user
132
160
 
@@ -134,7 +162,7 @@ Add Favorite:
134
162
  $ client.add_favorite(video_id)
135
163
 
136
164
  Delete Favorite:
137
- $ client.delete_favorite(video_id)
165
+ $ client.delete_favorite(favorite_entry_id)
138
166
 
139
167
  Like A Video:
140
168
  $ client.like_video(video_id)
@@ -151,8 +179,17 @@ Subscribe To A Channel:
151
179
  Unsubscribe To A Channel:
152
180
  $ client.unsubscribe_channel(subscription_id)
153
181
 
182
+ List New Subscription Videos:
183
+ $ client.new_subscription_videos(user) # default: current user
184
+
154
185
  List Playlists:
155
- $ client.playlists(user) # default: current user
186
+ $ client.playlists(user, order_by) # default: current user, position
187
+
188
+ for example you can get the videos of your playlist ordered by title
189
+
190
+ $ client.playlists(user, "title")
191
+
192
+ you can see more about options for order_by here: https://developers.google.com/youtube/2.0/reference#orderbysp
156
193
 
157
194
  Select Playlist:
158
195
  $ client.playlist(playlist_id)
@@ -173,6 +210,17 @@ Add Video To Playlist:
173
210
  Remove Video From Playlist:
174
211
  $ client.remove_video_from_playlist(playlist_id, playlist_entry_id)
175
212
 
213
+ Select All Videos From your Watch Later Playlist:
214
+ $ watcher_later = client.watcherlater(user) #default: current user
215
+ $ watcher_later.videos
216
+
217
+ Add Video To Watcher Later Playlist:
218
+ $ client.add_video_to_watchlater(video_id)
219
+
220
+ Remove Video From Watch Later Playlist:
221
+ $ client.remove_video_from_watchlater(watchlater_entry_id)
222
+
223
+
176
224
  List Related Videos
177
225
  $ video = client.video_by("https://www.youtube.com/watch?v=QsbmrCtiEUU&feature=player_embedded")
178
226
  $ video.related.videos
@@ -207,7 +255,11 @@ List Response Videos
207
255
 
208
256
  client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :comment => "denied")
209
257
 
210
-
258
+ == User Activity
259
+ You can get user activity with the followings params:
260
+
261
+ $ client.activity(user) #default current user
262
+
211
263
  == Video Upload From Browser:
212
264
 
213
265
  When uploading a video from your browser you need make a form upload with the followings params:
@@ -241,7 +293,7 @@ Note: you can specify width or just use the default of 1280.
241
293
  Now you can embed videos without use flash using html5, usefull for mobiles that not support flash but has html5 browser
242
294
 
243
295
  You can specify these options
244
- $ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1'})
296
+ $ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1', :url_params => {:option_one => "value", :option_two => "value"}})
245
297
 
246
298
  or just use with default options
247
299
  $ video.embed_html5 #default: width: 425, height: 350, frameborder: 0
data/lib/youtube_it.rb CHANGED
@@ -2,9 +2,10 @@ require 'logger'
2
2
  require 'open-uri'
3
3
  require 'net/https'
4
4
  require 'digest/md5'
5
- require 'rexml/document'
5
+ require 'nokogiri'
6
6
  require 'builder'
7
7
  require 'oauth'
8
+ require 'oauth2'
8
9
  require 'faraday'
9
10
 
10
11
  class YouTubeIt
@@ -19,8 +20,7 @@ class YouTubeIt
19
20
  end
20
21
 
21
22
  def self.esc(s) #:nodoc:
22
- # URI encodes correctly Unicode characters
23
- URI.encode(s.to_s.tr(' ','+'))
23
+ CGI.escape(s.to_s)
24
24
  end
25
25
 
26
26
  # Set the logger for the library
@@ -63,7 +63,7 @@ class YouTubeIt::GreedyChainIO < DelegateClass(YouTubeIt::ChainIO)
63
63
  __setobj__(YouTubeIt::ChainIO.new(with_ios))
64
64
  end
65
65
 
66
- def read(any_buffer_size)
66
+ def read(any_buffer_size = nil)
67
67
  __getobj__.read(BIG_CHUNK)
68
68
  end
69
69
 
@@ -38,7 +38,7 @@ class YouTubeIt
38
38
  #
39
39
  # If fetching videos by tags, categories, query:
40
40
  # params<Hash>:: Accepts the keys :tags, :categories, :query, :order_by,
41
- # :author, :racy, :response_format, :video_format, :page (default is 1),
41
+ # :author, :safe_search, :response_format, :video_format, :page (default is 1),
42
42
  # and :per_page(default is 25)
43
43
  #
44
44
  # options<Hash>:: Not used. (Optional)
@@ -122,8 +122,12 @@ class YouTubeIt
122
122
  client.get_upload_token(options, nexturl)
123
123
  end
124
124
 
125
- def add_comment(video_id, comment)
126
- client.add_comment(video_id, comment)
125
+ def add_comment(video_id, comment, opts = {})
126
+ client.add_comment(video_id, comment, opts)
127
+ end
128
+
129
+ def delete_comment(video_id, comment_id)
130
+ client.delete_comment(video_id, comment_id)
127
131
  end
128
132
 
129
133
  # opts is converted to get params and appended to comments gdata api url
@@ -148,14 +152,30 @@ class YouTubeIt
148
152
  def profile(user = nil)
149
153
  client.profile(user)
150
154
  end
155
+
156
+ def profiles(*users)
157
+ client.profiles(*users)
158
+ end
151
159
 
152
160
  # Fetches a user's activity feed.
153
161
  def activity(user = nil, opts = {})
154
162
  client.get_activity(user, opts)
155
163
  end
156
164
 
157
- def playlist(playlist_id)
158
- client.playlist playlist_id
165
+ def watchlater(user = nil)
166
+ client.watchlater(user)
167
+ end
168
+
169
+ def add_video_to_watchlater(video_id)
170
+ client.add_video_to_watchlater(video_id)
171
+ end
172
+
173
+ def delete_video_from_watchlater(video_id)
174
+ client.delete_video_from_watchlater(video_id)
175
+ end
176
+
177
+ def playlist(playlist_id, order_by = :position)
178
+ client.playlist(playlist_id, order_by)
159
179
  end
160
180
 
161
181
  def playlists(user = nil)
@@ -228,20 +248,30 @@ class YouTubeIt
228
248
  client.get_my_videos(opts)
229
249
  end
230
250
 
231
- # Get's all of the user's contacts/friends.
251
+ # Gets all of the user's contacts/friends.
232
252
  def my_contacts(opts = {})
233
253
  client.get_my_contacts(opts)
234
254
  end
235
255
 
236
- # Send vedio message
256
+ # Send video message
237
257
  def send_message(opts = {})
238
258
  client.send_message(opts)
239
259
  end
240
260
 
241
- # Get's all of the user's messages/inbox.
261
+ # Gets all of the user's messages/inbox.
242
262
  def my_messages(opts = {})
243
263
  client.get_my_messages(opts)
244
264
  end
265
+
266
+ # Gets the user's watch history
267
+ def watch_history
268
+ client.get_watch_history
269
+ end
270
+
271
+ # Gets new subscription videos
272
+ def new_subscription_videos(user_id = nil)
273
+ client.new_subscription_videos(user_id)
274
+ end
245
275
 
246
276
  private
247
277
 
@@ -388,7 +418,7 @@ class YouTubeIt
388
418
  response_code = profile.code.to_i
389
419
 
390
420
  if response_code/10 == 20 # success
391
- REXML::Document.new(profile.body).elements["entry"].elements['author'].elements['name'].text
421
+ Nokogiri::XML(profile.body).at("entry/author/name").text
392
422
  elsif response_code == 403 || response_code == 401 # auth failure
393
423
  raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
394
424
  else
@@ -413,6 +443,7 @@ class YouTubeIt
413
443
  @client_refresh_token = options[:client_refresh_token]
414
444
  @client_token_expires_at = options[:client_token_expires_at]
415
445
  @dev_key = options[:dev_key]
446
+ @legacy_debug_flag = options[:debug]
416
447
  end
417
448
 
418
449
  def oauth_client
@@ -427,7 +458,13 @@ class YouTubeIt
427
458
  end
428
459
 
429
460
  def refresh_access_token!
430
- @access_token = access_token.refresh!
461
+ new_access_token = access_token.refresh!
462
+ require 'thread' unless Thread.respond_to?(:exclusive)
463
+ Thread.exclusive do
464
+ @access_token = new_access_token
465
+ @client = nil
466
+ end
467
+ @access_token
431
468
  end
432
469
 
433
470
  def current_user
@@ -435,7 +472,7 @@ class YouTubeIt
435
472
  response_code = profile.status
436
473
 
437
474
  if response_code/10 == 20 # success
438
- REXML::Document.new(profile.body).elements["entry"].elements['author'].elements['name'].text
475
+ Nokogiri::XML(profile.body).at("entry/author/name").text
439
476
  elsif response_code == 403 || response_code == 401 # auth failure
440
477
  raise YouTubeIt::Upload::AuthenticationError.new(profile.inspect, response_code)
441
478
  else
@@ -1,14 +1,14 @@
1
1
  class YouTubeIt
2
2
  module Model
3
3
  class Comment < YouTubeIt::Record
4
- attr_reader :content, :published, :title, :updated, :url
4
+ attr_reader :content, :published, :title, :updated, :url, :reply_to
5
5
 
6
6
  # YouTubeIt::Model::Author:: Information about the YouTube user who owns a piece of video content.
7
7
  attr_reader :author
8
-
8
+
9
9
  # unique ID of the comment.
10
10
  def unique_id
11
- url.split("/").last
11
+ url.split(":").last
12
12
  end
13
13
  end
14
14
  end
@@ -3,7 +3,7 @@ class YouTubeIt
3
3
  class Playlist < YouTubeIt::Record
4
4
  attr_reader :title, :description, :summary, :playlist_id, :xml, :published, :response_code
5
5
  def videos
6
- YouTubeIt::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/playlists/#{playlist_id}?v=2").parse_videos
6
+ YouTubeIt::Parser::VideosFeedParser.new(@xml).parse_videos
7
7
  end
8
8
  end
9
9
  end
@@ -5,23 +5,30 @@ class YouTubeIt
5
5
  attr_reader :books
6
6
  attr_reader :company
7
7
  attr_reader :description
8
+ attr_reader :first_name
8
9
  attr_reader :gender
9
10
  attr_reader :hobbies
10
11
  attr_reader :hometown
11
12
  attr_reader :last_login
13
+ attr_reader :last_name
12
14
  attr_reader :location
13
15
  attr_reader :join_date
16
+ attr_reader :max_upload_duration
14
17
  attr_reader :movies
15
18
  attr_reader :music
16
19
  attr_reader :occupation
17
20
  attr_reader :relationship
18
21
  attr_reader :school
19
22
  attr_reader :subscribers
23
+ attr_reader :upload_count
20
24
  attr_reader :upload_views
25
+ attr_reader :user_id
21
26
  attr_reader :username
27
+ attr_reader :username_display
22
28
  attr_reader :videos_watched
23
29
  attr_reader :view_count
24
30
  attr_reader :avatar
31
+ attr_reader :insight_uri
25
32
  end
26
33
  end
27
34
  end
@@ -68,7 +68,7 @@ class YouTubeIt
68
68
  attr_reader :position
69
69
 
70
70
  # *Boolean*:: Specifies that a video is flagged as adult or not.
71
- attr_reader :racy
71
+ attr_reader :safe_search
72
72
 
73
73
  # *String*: Specifies a URI that uniquely and permanently identifies the video.
74
74
  attr_reader :video_id
@@ -79,6 +79,9 @@ class YouTubeIt
79
79
  # *Time*:: When the video's data was last updated.
80
80
  attr_reader :updated_at
81
81
 
82
+ # *Time*:: When the video's was uploaded.
83
+ attr_reader :uploaded_at
84
+
82
85
  # *Array*:: A array of YouTubeIt::Model::Category objects that describe the videos categories.
83
86
  attr_reader :categories
84
87
 
@@ -100,6 +103,9 @@ class YouTubeIt
100
103
  # *Array*:: An array of YouTubeIt::Model::Content objects describing the individual media content data available for this video. Most, but not all, videos offer this.
101
104
  attr_reader :media_content
102
105
 
106
+ # *Hash*:: string-keyed, string-valued permissions e.g., {'comment'=>'allowed','videoRespond'=>'moderated'}
107
+ attr_reader :access_control
108
+
103
109
  # *Array*:: An array of YouTubeIt::Model::Thumbnail objects that contain information regarding the videos thumbnail images.
104
110
  attr_reader :thumbnails
105
111
 
@@ -114,13 +120,20 @@ class YouTubeIt
114
120
 
115
121
  # *Fixnum*:: Number of times that the video has been favorited
116
122
  attr_reader :favorite_count
123
+
124
+ # *Fixnum*:: Number of comments for this video
125
+ attr_reader :comment_count
117
126
 
118
127
  # *String*:: State of the video (processing, restricted, deleted, rejected and failed)
119
128
  attr_reader :state
120
129
 
130
+ # *String*:: URI for insight for this video, if present; nil otherwise
131
+ attr_reader :insight_uri
121
132
 
133
+ # *Boolean*:: Whether or not a video is private. Non-standard name to avoid collision with Rubys own 'private' stuff.
134
+ attr_reader :perm_private
135
+
122
136
  # Geodata
123
- attr_reader :where
124
137
  attr_reader :position
125
138
  attr_reader :latitude
126
139
  attr_reader :longitude
@@ -152,6 +165,16 @@ class YouTubeIt
152
165
  @unique_id || video_id[/videos\/([^<]+)/, 1] || video_id[/video\:([^<]+)/, 1]
153
166
  end
154
167
 
168
+ # ID of this video in the watch later list (work only if you are listing watch later videos)
169
+ # Can be use to modify or remove the entry from the watch later list
170
+ #
171
+ # === Example
172
+ # >> @client.watchlater.videos.first.watch_later_id
173
+ # => "PL78jdHcOatSF7DGMd4O9K6Mbo0cNlxm_j"
174
+ def watch_later_id
175
+ video_id[/watch_later\:([^:]+)/, 1]
176
+ end
177
+
155
178
  # Allows you to check whether the video can be embedded on a webpage.
156
179
  #
157
180
  # === Returns
@@ -160,6 +183,14 @@ class YouTubeIt
160
183
  not @noembed
161
184
  end
162
185
 
186
+ # Allows you to check whether the video is listed and searchable on youtube.
187
+ #
188
+ # === Returns
189
+ # Boolean
190
+ def listed?
191
+ access_control['list'] == 'allowed'
192
+ end
193
+
163
194
  # Allows you to check whether the video is widescreen (16:9) or not.
164
195
  #
165
196
  # === Returns
@@ -200,10 +231,12 @@ EDOC
200
231
  :id => params[:id] || "",
201
232
  :width => params[:width] || "425",
202
233
  :height => params[:height] || "350",
203
- :frameborder => params[:frameborder] || "0"
234
+ :frameborder => params[:frameborder] || "0",
235
+ :url_params => params[:url_params] || {}
204
236
  }
237
+ url_opts = opts[:url_params].empty? ? "" : "?#{Rack::Utils::build_query(opts[:url_params])}"
205
238
  <<EDOC
206
- <iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="http://www.youtube.com/embed/#{unique_id}" frameborder="#{opts[:frameborder]}"></iframe>
239
+ <iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="http://www.youtube.com/embed/#{unique_id}#{url_opts}" frameborder="#{opts[:frameborder]}"></iframe>
207
240
  EDOC
208
241
  end
209
242