youtube_it 2.1.4 → 2.1.5
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.
- data/README.rdoc +57 -5
- data/lib/youtube_it.rb +3 -3
- data/lib/youtube_it/chain_io.rb +1 -1
- data/lib/youtube_it/client.rb +48 -11
- data/lib/youtube_it/model/comment.rb +3 -3
- data/lib/youtube_it/model/playlist.rb +1 -1
- data/lib/youtube_it/model/user.rb +7 -0
- data/lib/youtube_it/model/video.rb +37 -4
- data/lib/youtube_it/parser.rb +269 -218
- data/lib/youtube_it/request/base_search.rb +4 -0
- data/lib/youtube_it/request/video_search.rb +20 -4
- data/lib/youtube_it/request/video_upload.rb +166 -70
- data/lib/youtube_it/version.rb +1 -1
- data/youtube_it.gemspec +20 -91
- metadata +72 -134
- data/Gemfile +0 -12
- data/Gemfile.lock +0 -43
- data/Manifest.txt +0 -37
- data/Rakefile +0 -58
- data/VERSION +0 -1
- data/test/files/recorded_response.xml +0 -1
- data/test/files/youtube_video_response.xml +0 -53
- data/test/helper.rb +0 -9
- data/test/test.mov +0 -0
- data/test/test_chain_io.rb +0 -63
- data/test/test_client.rb +0 -454
- data/test/test_field_search.rb +0 -48
- data/test/test_video.rb +0 -48
- data/test/test_video_feed_parser.rb +0 -271
- data/test/test_video_search.rb +0 -147
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(
|
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 '
|
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
|
-
|
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
|
data/lib/youtube_it/chain_io.rb
CHANGED
data/lib/youtube_it/client.rb
CHANGED
@@ -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, :
|
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
|
158
|
-
client.
|
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
|
-
#
|
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
|
256
|
+
# Send video message
|
237
257
|
def send_message(opts = {})
|
238
258
|
client.send_message(opts)
|
239
259
|
end
|
240
260
|
|
241
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
|
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("
|
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(
|
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 :
|
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
|
|