agiley-youtube-g 0.6.2

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.
@@ -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