slainer68_youtube_it 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'oauth'
4
+ gem 'simple_oauth'
5
+ gem 'faraday'
6
+ gem 'builder'
7
+
8
+ group :test do
9
+ gem 'webmock'
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,27 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.2.6)
5
+ builder (3.0.0)
6
+ crack (0.3.1)
7
+ faraday (0.7.5)
8
+ addressable (~> 2.2.6)
9
+ multipart-post (~> 1.1.3)
10
+ rack (>= 1.1.0, < 2)
11
+ multipart-post (1.1.4)
12
+ oauth (0.4.5)
13
+ rack (1.4.0)
14
+ simple_oauth (0.1.5)
15
+ webmock (1.7.8)
16
+ addressable (~> 2.2, > 2.2.5)
17
+ crack (>= 0.1.7)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ builder
24
+ faraday
25
+ oauth
26
+ simple_oauth
27
+ webmock
data/Manifest.txt ADDED
@@ -0,0 +1,37 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ TODO.txt
6
+ lib/youtube_it.rb
7
+ lib/youtube_it/chain_io.rb
8
+ lib/youtube_it/client.rb
9
+ lib/youtube_it/model/author.rb
10
+ lib/youtube_it/model/category.rb
11
+ lib/youtube_it/model/contact.rb
12
+ lib/youtube_it/model/content.rb
13
+ lib/youtube_it/model/message.rb
14
+ lib/youtube_it/model/playlist.rb
15
+ lib/youtube_it/model/rating.rb
16
+ lib/youtube_it/model/thumbnail.rb
17
+ lib/youtube_it/model/user.rb
18
+ lib/youtube_it/model/video.rb
19
+ lib/youtube_it/parser.rb
20
+ lib/youtube_it/record.rb
21
+ lib/youtube_it/request/base_search.rb
22
+ lib/youtube_it/request/error.rb
23
+ lib/youtube_it/request/standard_search.rb
24
+ lib/youtube_it/request/user_search.rb
25
+ lib/youtube_it/request/video_search.rb
26
+ lib/youtube_it/request/video_upload.rb
27
+ lib/youtube_it/response/video_search.rb
28
+ lib/youtube_it/middleware/faraday_authheader.rb
29
+ lib/youtube_it/middleware/faraday_oauth.rb
30
+ lib/youtube_it/middleware/faraday_youtubeit.rb
31
+ lib/youtube_it/version.rb
32
+ test/helper.rb
33
+ test/test_chain_io.rb
34
+ test/test_client.rb
35
+ test/test_video.rb
36
+ test/test_video_search.rb
37
+
data/README.rdoc ADDED
@@ -0,0 +1,270 @@
1
+ == DESCRIPTION
2
+
3
+ youtube_it is the most complete Ruby client for the YouTube GData API. It provides an easy
4
+ way to access the latest and most complete access to YouTube's video API.
5
+ In comparison with the earlier Youtube interfaces, this new API and
6
+ library offers much-improved flexibility around executing complex search
7
+ queries to obtain well-targeted video search results. In addition, standard video management
8
+ including but not limited to uploading, deleting, updating, like, dislike, ratings and
9
+ comments.
10
+
11
+ == INSTALLATION & SETUP:
12
+ * Create a youtube account.
13
+ * Create a developer key here http://code.google.com/apis/youtube/dashboard.
14
+ * sudo gem install youtube_it
15
+
16
+ Note: youtube_it supports ClientLogin(YouTube account), OAuth or AuthSub authentication methods.
17
+
18
+ == Example Rails 3 App
19
+
20
+ You can get an example how you can use youtube_it with Rails 3 here: http://github.com/chebyte/youtube_it_rails_app_example
21
+
22
+ == DEMO
23
+
24
+ You can see to youtube_it in action here: http://youtube-it.heroku.com
25
+
26
+ == ESTABLISHING A CLIENT
27
+
28
+ Creating a client:
29
+ $ require 'youtube_it'
30
+ $ client = YouTubeIt::Client.new
31
+
32
+ Client with developer key:
33
+ $ client = YouTubeIt::Client.new(:dev_key => "developer_key")
34
+
35
+ Client with youtube account and developer key:
36
+ $ client = YouTubeIt::Client.new(:username => "youtube_username", :password => "youtube_passwd", :dev_key => "developer_key")
37
+
38
+ Client with AuthSub:
39
+ $ client = YouTubeIt::AuthSubClient.new(:token => "token" , :dev_key => "developer_key")
40
+
41
+ Client with OAuth:
42
+ $ client = YouTubeIt::OAuthClient.new("consumer_key", "consumer_secret", "youtube_username", "developer_key")
43
+ $ client.authorize_from_access("access_token", "access_secret")
44
+
45
+ == VIDEO QUERIES
46
+
47
+ Note: Each type of client enables searching capabilities.
48
+
49
+ Basic Queries:
50
+ $ client.videos_by(:query => "penguin")
51
+ $ client.videos_by(:query => "penguin", :page => 2, :per_page => 15)
52
+ $ client.videos_by(:tags => ['tiger', 'leopard'])
53
+ $ client.videos_by(:categories => [:news, :sports])
54
+ $ client.videos_by(:categories => [:news, :sports], :tags => ['soccer', 'football'])
55
+ $ client.videos_by(:user => 'liz')
56
+ $ client.videos_by(:favorites, :user => 'liz')
57
+ $ client.video_by("FQK1URcxmb4")
58
+ $ client.video_by("https://www.youtube.com/watch?v=QsbmrCtiEUU")
59
+ $ client.video_by_user("chebyte","FQK1URcxmb4")
60
+
61
+ Standard Queries:
62
+ $ client.videos_by(:most_viewed)
63
+ $ client.videos_by(:most_linked, :page => 3)
64
+ $ client.videos_by(:top_rated, :time => :today)
65
+
66
+ Advanced Queries (with boolean operators OR (either), AND (include), NOT (exclude)):
67
+ $ client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] }, :tags => { :include => ['football'], :exclude => ['soccer'] })
68
+
69
+
70
+ Fields Parameter(experimental features):
71
+ Return videos more than 1000 views
72
+ $ client.videos_by(:fields => {:view_count => "1000"})
73
+
74
+ Filter by date
75
+ $ client.videos_by(:fields => {:published => ((Date.today)})
76
+ $ client.videos_by(:fields => {:recorded => ((Date.today)})
77
+
78
+ Filter by date with range
79
+ $ client.videos_by(:fields => {:published => ((Date.today - 30)..(Date.today))})
80
+ $ client.videos_by(:fields => {:recorded => ((Date.today - 30)..(Date.today))})
81
+
82
+ == VIDEO MANAGEMENT
83
+
84
+ Note: YouTube account, OAuth or AuthSub enables video management.
85
+
86
+ Upload Video:
87
+ $ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test])
88
+
89
+ Upload Video With A Developer Tag (Note the tags are not immediately available):
90
+ $ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :dev_tag => 'tagdev')
91
+
92
+ Update Video:
93
+ $ client.video_update("FQK1URcxmb4", :title => "new test",:description => 'new description', :category => 'People',:keywords => %w[cool blah test])
94
+
95
+ Delete Video:
96
+ $ client.video_delete("FQK1URcxmb4")
97
+
98
+ My Videos:
99
+ $ client.my_videos
100
+
101
+ My Video:
102
+ $ client.my_video(video_id)
103
+
104
+ Profile Details:
105
+ $ client.profile(user) #default: current user
106
+
107
+ List Comments:
108
+ $ client.comments(video_id)
109
+
110
+ Add A Comment:
111
+ $ client.add_comment(video_id, "test comment!")
112
+
113
+ List Favorites:
114
+ $ client.favorites(user) # default: current user
115
+
116
+ Add Favorite:
117
+ $ client.add_favorite(video_id)
118
+
119
+ Delete Favorite:
120
+ $ client.delete_favorite(video_id)
121
+
122
+ Like A Video:
123
+ $ client.like_video(video_id)
124
+
125
+ Dislike A Video:
126
+ $ client.dislike_video(video_id)
127
+
128
+ List Subscriptions:
129
+ $ client.subscriptions(user) # default: current user
130
+
131
+ Subscribe To A Channel:
132
+ $ client.subscribe_channel(channel_name)
133
+
134
+ Unsubscribe To A Channel:
135
+ $ client.unsubscribe_channel(subscription_id)
136
+
137
+ List Playlists:
138
+ $ client.playlists(user) # default: current user
139
+
140
+ Select Playlist:
141
+ $ client.playlist(playlist_id)
142
+
143
+ Select All Videos From A Playlist:
144
+ $ playlist = client.playlist(playlist_id)
145
+ $ playlist.videos
146
+
147
+ Create Playlist:
148
+ $ playlist = client.add_playlist(:title => "new playlist", :description => "playlist description")
149
+
150
+ Delete Playlist:
151
+ $ client.delete_playlist(playlist_id)
152
+
153
+ Add Video To Playlist:
154
+ $ client.add_video_to_playlist(playlist_id, video_id)
155
+
156
+ Remove Video From Playlist:
157
+ $ client.remove_video_from_playlist(playlist_id, playlist_entry_id)
158
+
159
+ List Related Videos
160
+ $ video = client.video_by("https://www.youtube.com/watch?v=QsbmrCtiEUU&feature=player_embedded")
161
+ $ video.related.videos
162
+
163
+ Add Response Video
164
+ $ video.add_response(original_video_id, response_video_id)
165
+
166
+ Delete Response Video
167
+ $ video.delete_response(original_video_id, response_video_id)
168
+
169
+ List Response Videos
170
+ $ video = client.video_by("https://www.youtube.com/watch?v=QsbmrCtiEUU&feature=player_embedded")
171
+ $ video.responses.videos
172
+
173
+
174
+ == ACCESS CONTROL LIST
175
+
176
+ You can give permissions in your videos, for example denied comments, rate, etc...
177
+ you can read more there http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_yt:accessControl
178
+ you have available the followings options:
179
+
180
+ * :rate, :comment, :commentVote, :videoRespond, :list, :embed, :syndicate
181
+
182
+ with just two values:
183
+ * allowed or denied
184
+
185
+ Example
186
+
187
+ client = YouTubeIt::Client.new(:username => "youtube_username", :password => "youtube_passwd", :dev_key => "developer_key")
188
+
189
+ * upload video with denied comments
190
+
191
+ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :comment => "denied")
192
+
193
+
194
+ == Video Upload From Browser:
195
+
196
+ When uploading a video from your browser you need make a form upload with the followings params:
197
+ $ upload_token(params, nexturl)
198
+ params => params like :title => "title", :description => "description", :category => "People", :tags => ["test"]
199
+ nexturl => redirect to this url after upload
200
+
201
+
202
+ Controller
203
+ def upload
204
+ @upload_info = YouTubeIt::Client.new.upload_token(params, videos_url)
205
+ end
206
+
207
+ View (upload.html.erb)
208
+ <% form_tag @upload_info[:url], :multipart => true do %>
209
+ <%= hidden_field_tag :token, @upload_info[:token] %>
210
+ <%= label_tag :file %>
211
+ <%= file_field_tag :file %>
212
+ <%= submit_tag "Upload video" %>
213
+ <% end %>
214
+
215
+ == WIDESCREEN VIDEOS
216
+
217
+ If the videos has support for widescreen:
218
+ $ video.embed_html_with_width(1280)
219
+
220
+ Note: you can specify width or just use the default of 1280.
221
+
222
+ == USING HTML5
223
+
224
+ Now you can embed videos without use flash using html5, usefull for mobiles that not support flash but has html5 browser
225
+
226
+ You can specify these options
227
+ $ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1'})
228
+
229
+ or just use with default options
230
+ $ video.embed_html5 #default: width: 425, height: 350, frameborder: 0
231
+
232
+ == LOGGING
233
+
234
+ YouTubeIt passes all logs through the logger variable on the class itself. In Rails context, assign the Rails logger to that variable to collect the messages
235
+ (don't forget to set the level to debug):
236
+ $ YouTubeIt.logger = RAILS_DEFAULT_LOGGER
237
+ $ RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
238
+
239
+ == CONTRIBUTORS:
240
+
241
+ * Kyle J. Ginavan.
242
+ * Mauro Torres - http://github.com/chebyte
243
+ * Marko Seppa - https://github.com/mseppae
244
+ * Walter Korman - https://github.com/shaper
245
+ * Shane Vitarana - https://github.com/shanev
246
+
247
+ == LICENSE:
248
+
249
+ MIT License
250
+
251
+ Copyright (c) 2010 Kyle J. Ginavan
252
+
253
+ Permission is hereby granted, free of charge, to any person obtaining
254
+ a copy of this software and associated documentation files (the
255
+ 'Software'), to deal in the Software without restriction, including
256
+ without limitation the rights to use, copy, modify, merge, publish,
257
+ distribute, sublicense, and/or sell copies of the Software, and to
258
+ permit persons to whom the Software is furnished to do so, subject to
259
+ the following conditions:
260
+
261
+ The above copyright notice and this permission notice shall be
262
+ included in all copies or substantial portions of the Software.
263
+
264
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
265
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
266
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
267
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
268
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
269
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
270
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "slainer68_youtube_it"
8
+ gem.summary = %Q{The most complete Ruby wrapper for youtube api's}
9
+ gem.description = %Q{Upload, delete, update, comment on youtube videos all from one gem.}
10
+ gem.email = "slainer68@gmail.com"
11
+ gem.homepage = "http://github.com/slainer68/youtube_it"
12
+ gem.add_dependency('oauth2')
13
+ gem.add_dependency('faraday','>=0.7.3')
14
+ gem.add_dependency('builder')
15
+ gem.authors = ["kylejginavan","chebyte", "mseppae", "slainer68"]
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "youtube_it (or a dependency) not available. Install it with: gem install youtube_it"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "constantations #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
53
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
@@ -0,0 +1,76 @@
1
+ require 'delegate'
2
+ #:stopdoc:
3
+
4
+ # Stream wrapper that reads IOs in succession. Can be fed to Net::HTTP as post body stream. We use it internally to stream file content
5
+ # instead of reading whole video files into memory. Strings passed to the constructor will be wrapped in StringIOs. By default it will auto-close
6
+ # file handles when they have been read completely to prevent our uploader from leaking file handles
7
+ #
8
+ # chain = ChainIO.new(File.open(__FILE__), File.open('/etc/passwd'), "abcd")
9
+ class YouTubeIt::ChainIO
10
+ attr_accessor :autoclose
11
+
12
+ def initialize(*any_ios)
13
+ @autoclose = true
14
+ @chain = any_ios.flatten.map{|e| e.respond_to?(:read) ? e : StringIO.new(e.to_s) }
15
+ end
16
+
17
+ def read(buffer_size = 1024)
18
+ # Read off the first element in the stack
19
+ current_io = @chain.shift
20
+ return false if !current_io
21
+
22
+ buf = current_io.read(buffer_size)
23
+ if !buf && @chain.empty? # End of streams
24
+ release_handle(current_io) if @autoclose
25
+ false
26
+ elsif !buf # This IO is depleted, but next one is available
27
+ release_handle(current_io) if @autoclose
28
+ read(buffer_size)
29
+ elsif buf.length < buffer_size # This IO is depleted, but we were asked for more
30
+ release_handle(current_io) if @autoclose
31
+ buf + (read(buffer_size - buf.length) || '') # and recurse
32
+ else # just return the buffer
33
+ @chain.unshift(current_io) # put the current back
34
+ buf
35
+ end
36
+ end
37
+
38
+ # Predict the length of all embedded IOs. Will automatically send file size.
39
+ def expected_length
40
+ @chain.inject(0) do | len, io |
41
+ if io.respond_to?(:length)
42
+ len + (io.length - io.pos)
43
+ elsif io.is_a?(File)
44
+ len + File.size(io.path) - io.pos
45
+ else
46
+ raise "Cannot predict length of #{io.inspect}"
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+ def release_handle(io)
53
+ io.close if io.respond_to?(:close)
54
+ end
55
+ end
56
+
57
+ # Net::HTTP only can send chunks of 1024 bytes. This is very inefficient, so we have a spare IO that will send more when asked for 1024.
58
+ # We use delegation because the read call is recursive.
59
+ class YouTubeIt::GreedyChainIO < DelegateClass(YouTubeIt::ChainIO)
60
+ BIG_CHUNK = 512 * 1024 # 500 kb
61
+
62
+ def initialize(*with_ios)
63
+ __setobj__(YouTubeIt::ChainIO.new(with_ios))
64
+ end
65
+
66
+ def read(any_buffer_size)
67
+ __getobj__.read(BIG_CHUNK)
68
+ end
69
+
70
+ def length()
71
+ __getobj__.expected_length
72
+ end
73
+
74
+ end
75
+
76
+ #:startdoc: