agiley-youtube-g 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ class YouTubeG
2
+ module Response
3
+ class CommentsSearch < YouTubeG::Record
4
+ # *String*:: Unique feed identifying url.
5
+ attr_reader :feed_id
6
+
7
+ # *Fixnum*:: Number of results per page.
8
+ attr_reader :max_result_count
9
+
10
+ # *Fixnum*:: 1-based offset index into the full result set.
11
+ attr_reader :offset
12
+
13
+ # *Fixnum*:: Total number of results available for the original request.
14
+ attr_reader :total_result_count
15
+
16
+ # *Time*:: Date and time at which the feed was last updated
17
+ attr_reader :updated_at
18
+
19
+ # *Array*:: Array of YouTubeG::Model::Video records
20
+ attr_reader :comments
21
+
22
+ def current_page
23
+ ((offset - 1) / max_result_count) + 1
24
+ end
25
+
26
+ # current_page + 1 or nil if there is no next page
27
+ def next_page
28
+ current_page < total_pages ? (current_page + 1) : nil
29
+ end
30
+
31
+ # current_page - 1 or nil if there is no previous page
32
+ def previous_page
33
+ current_page > 1 ? (current_page - 1) : nil
34
+ end
35
+
36
+ def total_pages
37
+ (total_result_count / max_result_count.to_f).ceil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ class YouTubeG
2
+ module Response
3
+ class VideoSearch < YouTubeG::Record
4
+ # *String*:: Unique feed identifying url.
5
+ attr_reader :feed_id
6
+
7
+ # *Fixnum*:: Number of results per page.
8
+ attr_reader :max_result_count
9
+
10
+ # *Fixnum*:: 1-based offset index into the full result set.
11
+ attr_reader :offset
12
+
13
+ # *Fixnum*:: Total number of results available for the original request.
14
+ attr_reader :total_result_count
15
+
16
+ # *Time*:: Date and time at which the feed was last updated
17
+ attr_reader :updated_at
18
+
19
+ # *Array*:: Array of YouTubeG::Model::Video records
20
+ attr_reader :videos
21
+
22
+ def current_page
23
+ ((offset - 1) / max_result_count) + 1
24
+ end
25
+
26
+ # current_page + 1 or nil if there is no next page
27
+ def next_page
28
+ current_page < total_pages ? (current_page + 1) : nil
29
+ end
30
+
31
+ # current_page - 1 or nil if there is no previous page
32
+ def previous_page
33
+ current_page > 1 ? (current_page - 1) : nil
34
+ end
35
+
36
+ def total_pages
37
+ (total_result_count / max_result_count.to_f).ceil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ class YouTubeG
2
+ VERSION = '0.6.2'
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'pp'
4
+ require File.dirname(__FILE__) + '/../lib/youtube_g'
5
+
6
+ YouTubeG.logger.level = Logger::ERROR
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestChainIO < Test::Unit::TestCase
4
+ def setup
5
+ @klass = YouTubeG::ChainIO # save typing
6
+ end
7
+
8
+ def test_should_support_read_from_one_io
9
+ io = @klass.new "abcd"
10
+ assert io.respond_to?(:read)
11
+ assert_equal "ab", io.read(2)
12
+ assert_equal "cd", io.read(2)
13
+ assert_equal false, io.read(2)
14
+ end
15
+
16
+ def test_should_skip_over_depleted_streams
17
+ io = @klass.new '', '', '', '', 'ab'
18
+ assert_equal 'ab', io.read(2)
19
+ end
20
+
21
+ def test_should_read_across_nultiple_streams_with_large_offset
22
+ io = @klass.new 'abc', '', 'def', '', 'ghij'
23
+ assert_equal 'abcdefgh', io.read(8)
24
+ end
25
+
26
+ def test_should_return_false_for_empty_items
27
+ io = @klass.new '', '', '', '', ''
28
+ assert_equal false, io.read(8)
29
+ end
30
+
31
+ def test_should_support_overzealous_read
32
+ io = @klass.new "ab"
33
+ assert_equal "ab", io.read(5000)
34
+ end
35
+
36
+ def test_should_predict_expected_length
37
+ io = @klass.new "ab", "cde"
38
+ assert_equal 5, io.expected_length
39
+ end
40
+
41
+ def test_should_predict_expected_length_with_prepositioned_io
42
+ first_buf = StringIO.new("ab")
43
+ first_buf.read(1)
44
+
45
+ io = @klass.new first_buf, "cde"
46
+ assert_equal 4, io.expected_length
47
+ end
48
+
49
+ def test_should_predict_expected_length_with_file_handle
50
+ test_size = File.size(__FILE__)
51
+ first_buf = StringIO.new("ab")
52
+ first_buf.read(1)
53
+
54
+ io = @klass.new File.open(__FILE__), first_buf
55
+ assert_equal test_size + 1, io.expected_length
56
+ end
57
+
58
+ def test_greedy
59
+ io = YouTubeG::GreedyChainIO.new("a" * (1024 * 513))
60
+ chunk = io.read(123)
61
+ assert_equal 1024 * 512, chunk.length, "Should have read the first 512 KB chunk at once instead"
62
+ end
63
+ end
@@ -0,0 +1,265 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+ def setup
5
+ @client = YouTubeG::Client.new
6
+ end
7
+
8
+ def test_should_respond_to_a_basic_query
9
+ response = @client.videos_by(:query => "penguin")
10
+
11
+ assert_equal "http://gdata.youtube.com/feeds/api/videos", response.feed_id
12
+ assert_equal 25, response.max_result_count
13
+ assert_equal 25, response.videos.length
14
+ assert_equal 1, response.offset
15
+ assert(response.total_result_count > 100)
16
+ assert_instance_of Time, response.updated_at
17
+
18
+ response.videos.each { |v| assert_valid_video v }
19
+ end
20
+
21
+ def test_should_respond_to_a_basic_query_with_offset_and_max_results
22
+ response = @client.videos_by(:query => "penguin", :offset => 15, :max_results => 30)
23
+
24
+ assert_equal "http://gdata.youtube.com/feeds/api/videos", response.feed_id
25
+ assert_equal 30, response.max_result_count
26
+ assert_equal 30, response.videos.length
27
+ assert_equal 15, response.offset
28
+ assert(response.total_result_count > 100)
29
+ assert_instance_of Time, response.updated_at
30
+
31
+ response.videos.each { |v| assert_valid_video v }
32
+ end
33
+
34
+ def test_should_respond_to_a_basic_query_with_paging
35
+ response = @client.videos_by(:query => "penguin")
36
+ assert_equal "http://gdata.youtube.com/feeds/api/videos", response.feed_id
37
+ assert_equal 25, response.max_result_count
38
+ assert_equal 1, response.offset
39
+
40
+ response = @client.videos_by(:query => "penguin", :page => 2)
41
+ assert_equal "http://gdata.youtube.com/feeds/api/videos", response.feed_id
42
+ assert_equal 25, response.max_result_count
43
+ assert_equal 26, response.offset
44
+
45
+ response2 = @client.videos_by(:query => "penguin", :page => 3)
46
+ assert_equal "http://gdata.youtube.com/feeds/api/videos", response2.feed_id
47
+ assert_equal 25, response2.max_result_count
48
+ assert_equal 51, response2.offset
49
+ end
50
+
51
+ def test_should_get_videos_for_multiword_metasearch_query
52
+ response = @client.videos_by(:query => 'christina ricci')
53
+
54
+ assert_equal "http://gdata.youtube.com/feeds/api/videos", response.feed_id
55
+ assert_equal 25, response.max_result_count
56
+ assert_equal 25, response.videos.length
57
+ assert_equal 1, response.offset
58
+ assert(response.total_result_count > 100)
59
+ assert_instance_of Time, response.updated_at
60
+
61
+ response.videos.each { |v| assert_valid_video v }
62
+ end
63
+
64
+ def test_should_handle_video_not_yet_viewed
65
+ response = @client.videos_by(:query => "YnqHZDh_t2Q")
66
+
67
+ assert_equal 1, response.videos.length
68
+ response.videos.each { |v| assert_valid_video v }
69
+ end
70
+
71
+ # TODO: this doesn't work because the returned feed is in an unknown format
72
+ # def test_should_get_video_for_search_by_video_id
73
+ # response = @client.videos_by(:video_id => "T7YazwP8GtY")
74
+ # response.videos.each { |v| assert_valid_video v }
75
+ # end
76
+
77
+ def test_should_get_videos_for_one_tag
78
+ response = @client.videos_by(:tags => ['panther'])
79
+ response.videos.each { |v| assert_valid_video v }
80
+ end
81
+
82
+ def test_should_get_videos_for_multiple_tags
83
+ response = @client.videos_by(:tags => ['tiger', 'leopard'])
84
+ response.videos.each { |v| assert_valid_video v }
85
+ end
86
+
87
+ def test_should_get_videos_for_one_category
88
+ response = @client.videos_by(:categories => [:news])
89
+ response.videos.each { |v| assert_valid_video v }
90
+ end
91
+
92
+ def test_should_get_videos_for_multiple_categories
93
+ response = @client.videos_by(:categories => [:news, :sports])
94
+ response.videos.each { |v| assert_valid_video v }
95
+ end
96
+
97
+ # TODO: Need to do more specific checking in these tests
98
+ # Currently, if a URL is valid, and videos are found, the test passes regardless of search criteria
99
+ def test_should_get_videos_for_categories_and_tags
100
+ response = @client.videos_by(:categories => [:news, :sports], :tags => ['soccer', 'football'])
101
+ response.videos.each { |v| assert_valid_video v }
102
+ end
103
+
104
+ def test_should_get_most_viewed_videos
105
+ response = @client.videos_by(:most_viewed)
106
+ response.videos.each { |v| assert_valid_video v }
107
+ end
108
+
109
+ def test_should_get_top_rated_videos_for_today
110
+ response = @client.videos_by(:top_rated, :time => :today)
111
+ response.videos.each { |v| assert_valid_video v }
112
+ end
113
+
114
+ def test_should_get_videos_for_categories_and_tags_with_category_boolean_operators
115
+ response = @client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
116
+ :tags => { :include => ['football'], :exclude => ['soccer'] })
117
+ response.videos.each { |v| assert_valid_video v }
118
+ end
119
+
120
+ def test_should_get_videos_for_categories_and_tags_with_tag_boolean_operators
121
+ response = @client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
122
+ :tags => { :either => ['football', 'soccer', 'polo'] })
123
+ response.videos.each { |v| assert_valid_video v }
124
+ end
125
+
126
+ def test_should_get_videos_by_user
127
+ response = @client.videos_by(:user => 'liz')
128
+ response.videos.each { |v| assert_valid_video v }
129
+ end
130
+
131
+ def test_should_get_videos_by_user_with_pagination_and_ordering
132
+ response = @client.videos_by(:user => 'liz', :page => 2, :per_page => '2', :order_by => 'published')
133
+ response.videos.each { |v| assert_valid_video v }
134
+ assert_equal 3, response.offset
135
+ assert_equal 2, response.max_result_count
136
+ end
137
+
138
+ # HTTP 403 Error
139
+ # def test_should_get_favorite_videos_by_user
140
+ # response = @client.videos_by(:favorites, :user => 'liz')
141
+ # response.videos.each { |v| assert_valid_video v }
142
+ # end
143
+
144
+ def test_should_get_favorite_videos_by_user
145
+ response = @client.videos_by(:favorites, :user => 'drnicwilliams')
146
+ assert_equal "http://gdata.youtube.com/feeds/api/users/drnicwilliams/favorites", response.feed_id
147
+ response.videos.each { |v| assert_valid_video v }
148
+ end
149
+
150
+ def test_should_get_videos_for_query_search_with_categories_excluded
151
+ video = @client.video_by("EkF4JD2rO3Q")
152
+ # assert_equal "<object width=\"425\" height=\"350\">\n <param name=\"movie\" value=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata\"></param>\n <param name=\"wmode\" value=\"transparent\"></param>\n <embed src=\"http://www.youtube.com/v/EkF4JD2rO3Q\" type=\"application/x-shockwave-flash\" \n wmode=\"transparent\" width=\"425\" height=\"350\"></embed>\n</object>\n", video.embed_html
153
+ assert_equal "<object width=\"425\" height=\"350\">\n <param name=\"movie\" value=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata\"></param>\n <param name=\"wmode\" value=\"transparent\"></param>\n <embed src=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata\" type=\"application/x-shockwave-flash\" \n wmode=\"transparent\" width=\"425\" height=\"350\"></embed>\n</object>\n", video.embed_html
154
+ assert_valid_video video
155
+ end
156
+
157
+ def test_should_always_return_a_logger
158
+ @client = YouTubeG::Client.new
159
+ assert_not_nil @client.logger
160
+ end
161
+
162
+ def test_should_not_bail_if_debug_is_true
163
+ assert_nothing_raised { YouTubeG::Client.new(true) }
164
+ end
165
+
166
+ def test_should_determine_if_nonembeddable_video_is_embeddable
167
+ response = @client.videos_by(:query => "avril lavigne girlfriend")
168
+
169
+ video = response.videos.first
170
+ assert !video.embeddable?
171
+ end
172
+
173
+ def test_should_determine_if_embeddable_video_is_embeddable
174
+ response = @client.videos_by(:query => "strongbad")
175
+
176
+ video = response.videos.first
177
+ assert video.embeddable?
178
+ end
179
+
180
+ def test_should_retrieve_video_by_id
181
+ video = @client.video_by("http://gdata.youtube.com/feeds/videos/EkF4JD2rO3Q")
182
+ assert_valid_video video
183
+
184
+ video = @client.video_by("EkF4JD2rO3Q")
185
+ assert_valid_video video
186
+ end
187
+
188
+ private
189
+
190
+ def assert_valid_video (video)
191
+ # pp video
192
+
193
+ # check general attributes
194
+ assert_instance_of YouTubeG::Model::Video, video
195
+ assert_instance_of Fixnum, video.duration
196
+ assert(video.duration > 0)
197
+ #assert_match(/^<div style=.*?<\/div>/m, video.html_content)
198
+ assert_instance_of String, video.html_content
199
+
200
+ # validate media content records
201
+ video.media_content.each do |media_content|
202
+ # http://www.youtube.com/v/IHVaXG1thXM
203
+ assert_valid_url media_content.url
204
+ assert(media_content.duration > 0)
205
+ assert_instance_of YouTubeG::Model::Video::Format, media_content.format
206
+ assert_instance_of String, media_content.mime_type
207
+ assert_match(/^[^\/]+\/[^\/]+$/, media_content.mime_type)
208
+ end
209
+
210
+ default_content = video.default_media_content
211
+ if default_content
212
+ assert_instance_of YouTubeG::Model::Content, default_content
213
+ assert default_content.is_default?
214
+ end
215
+
216
+ # validate keywords
217
+ video.keywords.each { |kw| assert_instance_of(String, kw) }
218
+
219
+ # http://www.youtube.com/watch?v=IHVaXG1thXM
220
+ assert_valid_url video.player_url
221
+ assert_instance_of Time, video.published_at
222
+
223
+ # validate optionally-present rating
224
+ if video.rating
225
+ assert_instance_of YouTubeG::Model::Rating, video.rating
226
+ assert_instance_of Float, video.rating.average
227
+ assert_instance_of Fixnum, video.rating.max
228
+ assert_instance_of Fixnum, video.rating.min
229
+ assert_instance_of Fixnum, video.rating.rater_count
230
+ end
231
+
232
+ # validate thumbnails
233
+ assert(video.thumbnails.size > 0)
234
+
235
+ assert_not_nil video.title
236
+ assert_instance_of String, video.title
237
+ assert(video.title.length > 0)
238
+
239
+ assert_instance_of Time, video.updated_at
240
+ # http://gdata.youtube.com/feeds/videos/IHVaXG1thXM
241
+ assert_valid_url video.video_id
242
+ assert_instance_of Fixnum, video.view_count
243
+ assert_instance_of Fixnum, video.favorite_count
244
+
245
+ # validate author
246
+ assert_instance_of YouTubeG::Model::Author, video.author
247
+ assert_instance_of String, video.author.name
248
+ assert(video.author.name.length > 0)
249
+ assert_valid_url video.author.uri
250
+
251
+ # validate categories
252
+ video.categories.each do |cat|
253
+ assert_instance_of YouTubeG::Model::Category, cat
254
+ assert_instance_of String, cat.label
255
+ assert_instance_of String, cat.term
256
+ end
257
+ end
258
+
259
+ def assert_valid_url (url)
260
+ URI::parse(url)
261
+ return true
262
+ rescue
263
+ return false
264
+ end
265
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestVideo < Test::Unit::TestCase
4
+ def test_should_extract_unique_id_from_video_id
5
+ video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/ZTUVgYoeN_o")
6
+ assert_equal "ZTUVgYoeN_o", video.unique_id
7
+ end
8
+
9
+ def test_should_extract_unique_id_with_hypen_from_video_id
10
+ video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/BDqs-OZWw9o")
11
+ assert_equal "BDqs-OZWw9o", video.unique_id
12
+ end
13
+
14
+ def test_should_have_related_videos
15
+ video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/BDqs-OZWw9o")
16
+ response = video.related
17
+
18
+ assert_equal "http://gdata.youtube.com/feeds/api/videos/BDqs-OZWw9o/related", response.feed_id
19
+ assert_equal 25, response.max_result_count
20
+ assert_equal 25, response.videos.length
21
+ assert_equal 1, response.offset
22
+ assert(response.total_result_count > 0)
23
+ assert_instance_of Time, response.updated_at
24
+ end
25
+
26
+ def test_should_have_response_videos
27
+ video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/BDqs-OZWw9o")
28
+ response = video.responses
29
+
30
+ assert_equal "http://gdata.youtube.com/feeds/api/videos/BDqs-OZWw9o/responses", response.feed_id
31
+ assert_equal 25, response.max_result_count
32
+ assert_equal 25, response.videos.length
33
+ assert_equal 1, response.offset
34
+ assert(response.total_result_count > 0)
35
+ assert_instance_of Time, response.updated_at
36
+ end
37
+
38
+ end