natedaiger-youtube-g 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +5 -0
- data/lib/youtube_g.rb +3 -0
- data/lib/youtube_g/client.rb +15 -0
- data/lib/youtube_g/model/video.rb +10 -0
- data/lib/youtube_g/parser.rb +74 -1
- data/lib/youtube_g/version.rb +1 -1
- data/test/test_client.rb +2 -1
- metadata +12 -25
data/README.txt
CHANGED
@@ -54,6 +54,11 @@ Standard feeds:
|
|
54
54
|
Advanced queries (with boolean operators OR (either), AND (include), NOT (exclude)):
|
55
55
|
|
56
56
|
client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] }, :tags => { :include => ['football'], :exclude => ['soccer'] })
|
57
|
+
|
58
|
+
Comment feeds for videos:
|
59
|
+
client.comments_for('some_youtube_id').comments
|
60
|
+
video = client.video_by('some_youtube_id')
|
61
|
+
video.comments_seach(:page => 2, :per_page => 12).comments
|
57
62
|
|
58
63
|
== LOGGING
|
59
64
|
|
data/lib/youtube_g.rb
CHANGED
@@ -50,6 +50,7 @@ end
|
|
50
50
|
parser
|
51
51
|
model/author
|
52
52
|
model/category
|
53
|
+
model/comment
|
53
54
|
model/contact
|
54
55
|
model/content
|
55
56
|
model/playlist
|
@@ -58,10 +59,12 @@ end
|
|
58
59
|
model/user
|
59
60
|
model/video
|
60
61
|
request/base_search
|
62
|
+
request/comments_search
|
61
63
|
request/user_search
|
62
64
|
request/standard_search
|
63
65
|
request/video_upload
|
64
66
|
request/video_search
|
67
|
+
response/comments_search
|
65
68
|
response/video_search
|
66
69
|
chain_io
|
67
70
|
).each{|m| require File.dirname(__FILE__) + '/youtube_g/' + m }
|
data/lib/youtube_g/client.rb
CHANGED
@@ -70,6 +70,21 @@ class YouTubeG
|
|
70
70
|
parser = YouTubeG::Parser::VideoFeedParser.new(video_id)
|
71
71
|
parser.parse
|
72
72
|
end
|
73
|
+
|
74
|
+
# Retrieves a single YouTube video.
|
75
|
+
#
|
76
|
+
# === Parameters
|
77
|
+
# vid<String>:: The ID of the video whose contents you'd like to retrieve
|
78
|
+
#
|
79
|
+
# options<Hash> (optional):: Accepts the options of :page (default is 1),
|
80
|
+
# and :per_page (default is 25). :offset and :max_results
|
81
|
+
# can also be passed for a custom offset.
|
82
|
+
# === Returns
|
83
|
+
# YouTubeG::Response::CommentsSearch
|
84
|
+
def comments_for(vid, options={})
|
85
|
+
url = YouTubeG::Request::CommentsSearch.new(vid, options).url
|
86
|
+
YouTubeG::Parser::CommentsFeedParser.new(url).parse
|
87
|
+
end
|
73
88
|
|
74
89
|
private
|
75
90
|
|
@@ -136,6 +136,16 @@ class YouTubeG
|
|
136
136
|
def responses
|
137
137
|
YouTubeG::Parser::VideosFeedParser.new("http://gdata.youtube.com/feeds/api/videos/#{unique_id}/responses").parse
|
138
138
|
end
|
139
|
+
|
140
|
+
# Comments on the current video.
|
141
|
+
#
|
142
|
+
# === Returns
|
143
|
+
# YouTubeG::Response::CommentsSearch
|
144
|
+
def comments_search(options={})
|
145
|
+
url = YouTubeG::Request::CommentsSearch.new(unique_id,options).url
|
146
|
+
YouTubeG::Parser::CommentsFeedParser.new(url).parse
|
147
|
+
end
|
148
|
+
|
139
149
|
|
140
150
|
# The ID of the video, useful for searching for the video again without having to store it anywhere.
|
141
151
|
# A regular query search, with this id will return the same video.
|
data/lib/youtube_g/parser.rb
CHANGED
@@ -21,6 +21,23 @@ class YouTubeG
|
|
21
21
|
protected
|
22
22
|
def parse_entry(entry)
|
23
23
|
video_id = entry.elements["id"].text
|
24
|
+
|
25
|
+
if entry.elements["app:control/yt:state"]
|
26
|
+
# yt:state generally indicates a video is unavailable
|
27
|
+
# see: http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_yt:state
|
28
|
+
unless entry.elements["app:control/yt:state[@name='restricted']"]
|
29
|
+
# the exception I've found is for *restricted* videos, which generally
|
30
|
+
# means they're not available for viewing on a device other than a web browser
|
31
|
+
# or in a certain region
|
32
|
+
return nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# if there's no content we're going to puke later
|
37
|
+
unless entry.elements['content']
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
24
41
|
published_at = Time.parse(entry.elements["published"].text)
|
25
42
|
updated_at = Time.parse(entry.elements["updated"].text)
|
26
43
|
|
@@ -157,7 +174,9 @@ class YouTubeG
|
|
157
174
|
|
158
175
|
videos = []
|
159
176
|
feed.elements.each("entry") do |entry|
|
160
|
-
|
177
|
+
if video = parse_entry(entry)
|
178
|
+
videos << video
|
179
|
+
end
|
161
180
|
end
|
162
181
|
|
163
182
|
YouTubeG::Response::VideoSearch.new(
|
@@ -169,6 +188,60 @@ class YouTubeG
|
|
169
188
|
:videos => videos)
|
170
189
|
end
|
171
190
|
end
|
191
|
+
|
192
|
+
class CommentsFeedParser < FeedParser
|
172
193
|
|
194
|
+
def parse_content(content)
|
195
|
+
doc = REXML::Document.new(content)
|
196
|
+
feed = doc.elements['feed']
|
197
|
+
|
198
|
+
feed_id = feed.elements["id"].text
|
199
|
+
updated_at = Time.parse(feed.elements["updated"].text)
|
200
|
+
total_result_count = feed.elements["openSearch:totalResults"].text.to_i
|
201
|
+
offset = feed.elements["openSearch:startIndex"].text.to_i
|
202
|
+
max_result_count = feed.elements["openSearch:itemsPerPage"].text.to_i
|
203
|
+
|
204
|
+
comments = []
|
205
|
+
feed.elements.each('entry') do |entry|
|
206
|
+
comments << parse_entry(entry)
|
207
|
+
end
|
208
|
+
YouTubeG::Response::CommentsSearch.new(
|
209
|
+
:feed_id => feed_id,
|
210
|
+
:updated_at => updated_at,
|
211
|
+
:total_result_count => total_result_count,
|
212
|
+
:offset => offset,
|
213
|
+
:max_result_count => max_result_count,
|
214
|
+
:comments => comments)
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
def parse_entry(entry)
|
219
|
+
comment_id = entry.elements["id"].text
|
220
|
+
|
221
|
+
published_at = Time.parse(entry.elements["published"].text)
|
222
|
+
updated_at = Time.parse(entry.elements["updated"].text)
|
223
|
+
|
224
|
+
title = entry.elements["title"].text
|
225
|
+
content = entry.elements["content"].text
|
226
|
+
|
227
|
+
# parse the author
|
228
|
+
author_element = entry.elements["author"]
|
229
|
+
author = nil
|
230
|
+
if author_element
|
231
|
+
author = YouTubeG::Model::Author.new(
|
232
|
+
:name => author_element.elements["name"].text,
|
233
|
+
:uri => author_element.elements["uri"].text)
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
comment = YouTubeG::Model::Comment.new(
|
238
|
+
:published_at => published_at,
|
239
|
+
:updated_at => updated_at,
|
240
|
+
:title => title,
|
241
|
+
:content => content,
|
242
|
+
:author => author)
|
243
|
+
return comment
|
244
|
+
end
|
245
|
+
end
|
173
246
|
end
|
174
247
|
end
|
data/lib/youtube_g/version.rb
CHANGED
data/test/test_client.rb
CHANGED
@@ -149,7 +149,8 @@ class TestClient < Test::Unit::TestCase
|
|
149
149
|
|
150
150
|
def test_should_get_videos_for_query_search_with_categories_excluded
|
151
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\"></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
|
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
|
153
154
|
assert_valid_video video
|
154
155
|
end
|
155
156
|
|
metadata
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: natedaiger-youtube-g
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 0
|
7
|
-
- 5
|
8
|
-
- 1
|
9
|
-
version: 0.5.1
|
4
|
+
version: 0.6.0
|
10
5
|
platform: ruby
|
11
6
|
authors:
|
12
7
|
- Shane Vitarana
|
@@ -23,30 +18,24 @@ default_executable:
|
|
23
18
|
dependencies:
|
24
19
|
- !ruby/object:Gem::Dependency
|
25
20
|
name: builder
|
26
|
-
|
27
|
-
|
21
|
+
type: :runtime
|
22
|
+
version_requirement:
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
24
|
requirements:
|
29
25
|
- - ">="
|
30
26
|
- !ruby/object:Gem::Version
|
31
|
-
segments:
|
32
|
-
- 0
|
33
27
|
version: "0"
|
34
|
-
|
35
|
-
version_requirements: *id001
|
28
|
+
version:
|
36
29
|
- !ruby/object:Gem::Dependency
|
37
30
|
name: hoe
|
38
|
-
|
39
|
-
|
31
|
+
type: :development
|
32
|
+
version_requirement:
|
33
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
34
|
requirements:
|
41
35
|
- - ">="
|
42
36
|
- !ruby/object:Gem::Version
|
43
|
-
segments:
|
44
|
-
- 1
|
45
|
-
- 8
|
46
|
-
- 3
|
47
37
|
version: 1.8.3
|
48
|
-
|
49
|
-
version_requirements: *id002
|
38
|
+
version:
|
50
39
|
description: "youtube-g is a pure Ruby client for the YouTube GData API. It provides an easy way to access the latest YouTube video search results from your own programs. In comparison with the earlier Youtube search interfaces, this new API and library offers much-improved flexibility around executing complex search queries to obtain well-targeted video search results. More detail on the underlying source Google-provided API is available at: http://code.google.com/apis/youtube/overview.html"
|
51
40
|
email: shanev@gmail.com
|
52
41
|
executables: []
|
@@ -104,20 +93,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
93
|
requirements:
|
105
94
|
- - ">="
|
106
95
|
- !ruby/object:Gem::Version
|
107
|
-
segments:
|
108
|
-
- 0
|
109
96
|
version: "0"
|
97
|
+
version:
|
110
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
99
|
requirements:
|
112
100
|
- - ">="
|
113
101
|
- !ruby/object:Gem::Version
|
114
|
-
segments:
|
115
|
-
- 0
|
116
102
|
version: "0"
|
103
|
+
version:
|
117
104
|
requirements: []
|
118
105
|
|
119
106
|
rubyforge_project: youtube-g
|
120
|
-
rubygems_version: 1.3.
|
107
|
+
rubygems_version: 1.3.5
|
121
108
|
signing_key:
|
122
109
|
specification_version: 2
|
123
110
|
summary: Ruby client for the YouTube GData API
|