youtube_it 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -27,6 +27,9 @@ Client with developer key:
27
27
  Client with youtube account and developer key:
28
28
  $ client = YouTubeIt::Client.new(:username => "youtube_username", :password => "youtube_passwd", :dev_key => "developer_key")
29
29
 
30
+ Client with AuthSub:
31
+ $ client = YouTubeIt::AuthSubClient.new(:token => "token" , :dev_key => "developer_key")
32
+
30
33
  Client with OAuth:
31
34
  $ client = YouTubeIt::OAuthClient.new("consumer_key", "consumer_secret", "youtube_username", "developer_key")
32
35
  $ client.authorize_from_access("access_token", "access_secret")
@@ -58,9 +61,11 @@ Advanced Queries (with boolean operators OR (either), AND (include), NOT (exclud
58
61
  Fields Parameter(experimental features):
59
62
  Return videos more than 1000 views
60
63
  $ client.videos_by(:fields => {:view_count => "1000"})
64
+
61
65
  Filter by date
62
66
  $ client.videos_by(:fields => {:published => ((Date.today)})
63
67
  $ client.videos_by(:fields => {:recorded => ((Date.today)})
68
+
64
69
  Filter by date with range
65
70
  $ client.videos_by(:fields => {:published => ((Date.today - 30)..(Date.today))})
66
71
  $ client.videos_by(:fields => {:recorded => ((Date.today - 30)..(Date.today))})
@@ -88,7 +93,7 @@ My Video:
88
93
  $ client.my_video(video_id)
89
94
 
90
95
  Profile Details:
91
- $ client.profile(user_id)
96
+ $ client.profile(user) #default: current user
92
97
 
93
98
  List Comments:
94
99
  $ client.comments(video_id)
@@ -97,7 +102,7 @@ Add A Comment:
97
102
  $ client.add_comment(video_id, "test comment!")
98
103
 
99
104
  List Favorites:
100
- $ client.favorites(user) # current user by default
105
+ $ client.favorites(user) # default: current user
101
106
 
102
107
  Add Favorite:
103
108
  $ client.add_favorite(video_id)
@@ -112,7 +117,7 @@ Dislike A Video:
112
117
  $ client.dislike_video(video_id)
113
118
 
114
119
  List Subscriptions:
115
- $ client.subscriptions(user) #default: current user
120
+ $ client.subscriptions(user) # default: current user
116
121
 
117
122
  Subscribe To A Channel:
118
123
  $ client.subscribe_channel(channel_name)
@@ -121,7 +126,7 @@ Unsubscribe To A Channel:
121
126
  $ client.unsubscribe_channel(subscription_id)
122
127
 
123
128
  List Playlists:
124
- $ client.playlists(user) # current user by default
129
+ $ client.playlists(user) # default: current user
125
130
 
126
131
  Select Playlist:
127
132
  $ client.playlist(playlist_id)
@@ -190,6 +195,16 @@ If the videos has support for widescreen:
190
195
 
191
196
  Note: you can specify width or just use the default of 1280.
192
197
 
198
+ == USING HTML5
199
+
200
+ Now you can embed videos without use flash using html5, usefull for mobiles that not support flash but has html5 browser
201
+
202
+ You can specify these options
203
+ $ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1'})
204
+
205
+ or just use with default options
206
+ $ video.embed_html5 #default: width: 425, height: 350, frameborder: 0
207
+
193
208
  == LOGGING
194
209
 
195
210
  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
@@ -197,11 +212,19 @@ YouTubeIt passes all logs through the logger variable on the class itself. In Ra
197
212
  $ YouTubeIt.logger = RAILS_DEFAULT_LOGGER
198
213
  $ RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
199
214
 
215
+ == Example Rails 3 App
216
+
217
+ You can get an example how you can use youtube_it with Rails 3 here: http://github.com/chebyte/youtube_it_rails_app_example
218
+
219
+ == DEMO
220
+
221
+ You can see to youtube_it in action here: http://youtube-it.heroku.com
222
+
200
223
  == CONTRIBUTORS:
201
224
 
202
225
  * Kyle J. Ginavan.
203
226
  * Mauro Torres - http://github.com/chebyte
204
- * Marko Seppa - https://github.com/mseppae
227
+ * Marko Seppa - https://github.com/mseppae
205
228
 
206
229
  == LICENSE:
207
230
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 2.0.1
@@ -137,6 +137,11 @@ class YouTubeIt
137
137
  def profile(user = nil)
138
138
  client.profile(user)
139
139
  end
140
+
141
+ # Fetches a user's activity feed.
142
+ def activity(user = nil, opts = {})
143
+ client.get_activity(user, opts)
144
+ end
140
145
 
141
146
  def playlist(playlist_id)
142
147
  client.playlist playlist_id
@@ -203,6 +208,11 @@ class YouTubeIt
203
208
  def my_videos(opts = {})
204
209
  client.get_my_videos(opts)
205
210
  end
211
+
212
+ # Get's all of the user's contacts/friends.
213
+ def my_contacts(opts = {})
214
+ client.get_my_contacts(opts)
215
+ end
206
216
 
207
217
  private
208
218
 
@@ -345,7 +355,13 @@ class YouTubeIt
345
355
  end
346
356
 
347
357
  def current_user
348
- body = access_token.get("http://gdata.youtube.com/feeds/api/users/default").body
358
+ yt_session = Faraday.new(:url => "http://gdata.youtube.com") do |builder|
359
+ builder.use Faraday::Response::YouTubeIt
360
+ builder.use Faraday::Request::OAuth, config_token
361
+ builder.adapter Faraday.default_adapter
362
+ end
363
+
364
+ body = yt_session.get("/feeds/api/users/default").body
349
365
  REXML::Document.new(body).elements["entry"].elements['author'].elements['name'].text
350
366
  end
351
367
 
@@ -2,7 +2,18 @@ module Faraday
2
2
  class Request::AuthHeader < Faraday::Middleware
3
3
 
4
4
  def call(env)
5
- env[:request_headers].merge!(@headers)
5
+ req_headers = env[:request_headers]
6
+ req_headers.merge!(@headers)
7
+ unless req_headers.include?("GData-Version")
8
+ req_headers.merge!("GData-Version" => "2")
9
+ end
10
+ unless req_headers.include?("Content-Type")
11
+ req_headers.merge!("Content-Type" => "application/atom+xml; charset=UTF-8")
12
+ end
13
+ unless req_headers.include?("Content-Length")
14
+ req_headers.merge!("Content-Length" => env[:body] ? "#{env[:body].length}" : "0")
15
+ end
16
+
6
17
  @app.call(env)
7
18
  end
8
19
 
@@ -0,0 +1,17 @@
1
+ class YouTubeIt
2
+ module Model
3
+ class Activity < YouTubeIt::Record
4
+ # Attributes common to multiple activity types
5
+ attr_reader :type, :author, :videos, :video_id, :time
6
+
7
+ # video_rated
8
+ attr_reader :user_rating, :video_rating
9
+
10
+ # video_commented
11
+ attr_reader :comment_thread_url, :video_url
12
+
13
+ # friend_added and user_subscription_added
14
+ attr_reader :username
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,8 @@ class YouTubeIt
6
6
 
7
7
  # *String*: Feed URL of the author.
8
8
  attr_reader :uri
9
+
10
+ attr_reader :thumbnail_url
9
11
  end
10
12
  end
11
13
  end
@@ -5,6 +5,11 @@ class YouTubeIt
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
+
9
+ # unique ID of the comment.
10
+ def unique_id
11
+ url.split("/").last
12
+ end
8
13
  end
9
14
  end
10
15
  end
@@ -11,6 +11,9 @@ class YouTubeIt
11
11
 
12
12
  # *String*:: The Youtube username of the contact.
13
13
  attr_reader :username
14
+
15
+ # *String*:: The Youtube title of the contact.
16
+ attr_reader :title
14
17
  end
15
18
  end
16
19
  end
@@ -21,6 +21,7 @@ class YouTubeIt
21
21
  attr_reader :username
22
22
  attr_reader :videos_watched
23
23
  attr_reader :view_count
24
+ attr_reader :avatar
24
25
  end
25
26
  end
26
27
  end
@@ -193,6 +193,22 @@ class YouTubeIt
193
193
  EDOC
194
194
  end
195
195
 
196
+ # Gives you the HTML 5 to embed the video on your website.
197
+ # Usefull for mobile that not support flash but has html5 browser
198
+ # === Returns
199
+ # String: The HTML for embedding the video on your website.
200
+ def embed_html5(params = {})
201
+ opts = {:class => params[:class] || "",
202
+ :id => params[:id] || "",
203
+ :width => params[:width] || "425",
204
+ :height => params[:height] || "350",
205
+ :frameborder => params[:frameborder] || "0"
206
+ }
207
+ <<EDOC
208
+ <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]}">
209
+ EDOC
210
+ end
211
+
196
212
  # Gives you the HTML to embed the video on your website.
197
213
  #
198
214
  # === Returns
@@ -2,7 +2,13 @@ class YouTubeIt
2
2
  module Parser #:nodoc:
3
3
  class FeedParser #:nodoc:
4
4
  def initialize(content)
5
- @content = open(content).read rescue content
5
+ @content = open(content).read
6
+
7
+ rescue OpenURI::HTTPError => e
8
+ raise OpenURI::HTTPError.new(e.io.status[0],e)
9
+ rescue
10
+ @content = content
11
+
6
12
  end
7
13
 
8
14
  def parse
@@ -92,6 +98,155 @@ class YouTubeIt
92
98
  :xml => nil)
93
99
  end
94
100
  end
101
+
102
+ # Returns an array of the user's activity
103
+ class ActivityParser < FeedParser
104
+ def parse_content(content)
105
+ doc = REXML::Document.new(content.body)
106
+ feed = doc.elements["feed"]
107
+
108
+ activity = []
109
+ feed.elements.each("entry") do |entry|
110
+ parsed_activity = parse_activity(entry)
111
+ if parsed_activity
112
+ activity << parsed_activity
113
+ end
114
+ end
115
+
116
+ return activity
117
+ end
118
+
119
+ protected
120
+
121
+ # Parses the user's activity feed.
122
+ def parse_activity(entry)
123
+ # Figure out what kind of activity we have
124
+ video_type = nil
125
+ parsed_activity = nil
126
+ entry.elements.each("category") do |category_tag|
127
+ if category_tag.attributes["scheme"]=="http://gdata.youtube.com/schemas/2007/userevents.cat"
128
+ video_type = category_tag.attributes["term"]
129
+ end
130
+ end
131
+
132
+ if video_type
133
+ case video_type
134
+ when "video_rated"
135
+ parsed_activity = YouTubeIt::Model::Activity.new(
136
+ :type => "video_rated",
137
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
138
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
139
+ :videos => parse_activity_videos(entry),
140
+ :video_id => entry.elements["yt:videoid"] ? entry.elements["yt:videoid"].text : nil
141
+ )
142
+ when "video_shared"
143
+ parsed_activity = YouTubeIt::Model::Activity.new(
144
+ :type => "video_shared",
145
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
146
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
147
+ :videos => parse_activity_videos(entry),
148
+ :video_id => entry.elements["yt:videoid"] ? entry.elements["yt:videoid"].text : nil
149
+ )
150
+ when "video_favorited"
151
+ parsed_activity = YouTubeIt::Model::Activity.new(
152
+ :type => "video_favorited",
153
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
154
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
155
+ :videos => parse_activity_videos(entry),
156
+ :video_id => entry.elements["yt:videoid"] ? entry.elements["yt:videoid"].text : nil
157
+ )
158
+ when "video_commented"
159
+ # Load the comment and video URL
160
+ comment_thread_url = nil
161
+ video_url = nil
162
+ entry.elements.each("link") do |link_tag|
163
+ case link_tag.attributes["rel"]
164
+ when "http://gdata.youtube.com/schemas/2007#comments"
165
+ comment_thread_url = link_tag.attributes["href"]
166
+ when "http://gdata.youtube.com/schemas/2007#video"
167
+ video_url = link_tag.attributes["href"]
168
+ else
169
+ # Invalid rel type, do nothing
170
+ end
171
+ end
172
+
173
+ parsed_activity = YouTubeIt::Model::Activity.new(
174
+ :type => "video_commented",
175
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
176
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
177
+ :videos => parse_activity_videos(entry),
178
+ :video_id => entry.elements["yt:videoid"] ? entry.elements["yt:videoid"].text : nil,
179
+ :comment_thread_url => comment_thread_url,
180
+ :video_url => video_url
181
+ )
182
+ when "video_uploaded"
183
+ parsed_activity = YouTubeIt::Model::Activity.new(
184
+ :type => "video_uploaded",
185
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
186
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
187
+ :videos => parse_activity_videos(entry),
188
+ :video_id => entry.elements["yt:videoid"] ? entry.elements["yt:videoid"].text : nil
189
+ )
190
+ when "friend_added"
191
+ parsed_activity = YouTubeIt::Model::Activity.new(
192
+ :type => "friend_added",
193
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
194
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
195
+ :username => entry.elements["yt:username"] ? entry.elements["yt:username"].text : nil
196
+ )
197
+ when "user_subscription_added"
198
+ parsed_activity = YouTubeIt::Model::Activity.new(
199
+ :type => "user_subscription_added",
200
+ :time => entry.elements["updated"] ? entry.elements["updated"].text : nil,
201
+ :author => entry.elements["author"].elements["name"] ? entry.elements["author"].elements["name"].text : nil,
202
+ :username => entry.elements["yt:username"] ? entry.elements["yt:username"].text : nil
203
+ )
204
+ else
205
+ # Invalid activity type, just let it return nil
206
+ end
207
+ end
208
+
209
+ return parsed_activity
210
+ end
211
+
212
+ # If a user enabled inline attribute videos may be included in results.
213
+ def parse_activity_videos(entry)
214
+ videos = []
215
+
216
+ entry.elements.each("link") do |link_tag|
217
+ if link_tag.attributes["rel"]=="http://gdata.youtube.com/schemas/2007#video"
218
+ videos << YouTubeIt::Parser::VideoFeedParser.new(link_tag).parse
219
+ end
220
+ end
221
+
222
+ if videos.size <= 0
223
+ videos = nil
224
+ end
225
+
226
+ return videos
227
+ end
228
+ end
229
+
230
+ # Returns an array of the user's contacts
231
+ class ContactsParser < FeedParser
232
+ def parse_content(content)
233
+ doc = REXML::Document.new(content.body)
234
+ feed = doc.elements["feed"]
235
+
236
+ contacts = []
237
+ feed.elements.each("entry") do |entry|
238
+ temp_contact = YouTubeIt::Model::Contact.new(
239
+ :title => entry.elements["title"] ? entry.elements["title"].text : nil,
240
+ :username => entry.elements["yt:username"] ? entry.elements["yt:username"].text : nil,
241
+ :status => entry.elements["yt:status"] ? entry.elements["yt:status"].text : nil
242
+ )
243
+
244
+ contacts << temp_contact
245
+ end
246
+
247
+ return contacts
248
+ end
249
+ end
95
250
 
96
251
  class ProfileFeedParser < FeedParser #:nodoc:
97
252
  def parse_content(content)
@@ -112,6 +267,7 @@ class YouTubeIt
112
267
  :occupation => entry.elements["yt:occupation"] ? entry.elements["yt:occupation"].text : nil,
113
268
  :relationship => entry.elements["yt:relationship"] ? entry.elements["yt:relationship"].text : nil,
114
269
  :school => entry.elements["yt:school"] ? entry.elements["yt:school"].text : nil,
270
+ :avatar => entry.elements["media:thumbnail"] ? entry.elements["media:thumbnail"].attributes["url"] : nil,
115
271
  :subscribers => entry.elements["yt:statistics"].attributes["subscriberCount"],
116
272
  :videos_watched => entry.elements["yt:statistics"].attributes["videoWatchCount"],
117
273
  :view_count => entry.elements["yt:statistics"].attributes["viewCount"],
@@ -148,12 +304,13 @@ class YouTubeIt
148
304
  class VideoFeedParser < FeedParser #:nodoc:
149
305
 
150
306
  def parse_content(content)
151
- doc = REXML::Document.new(content)
307
+ doc = (content.is_a?(REXML::Element)) ? content : REXML::Document.new(content)
308
+
152
309
  entry = doc.elements["entry"]
153
310
  parse_entry(entry)
154
311
  end
155
312
 
156
- protected
313
+ protected
157
314
  def parse_entry(entry)
158
315
  video_id = entry.elements["id"].text
159
316
  published_at = entry.elements["published"] ? Time.parse(entry.elements["published"].text) : nil
@@ -88,27 +88,29 @@ class YouTubeIt
88
88
  # :private
89
89
  # When the authentication credentials are incorrect, an AuthenticationError will be raised.
90
90
  def update(video_id, options)
91
- @opts = options
92
- update_body = video_xml
93
- update_header = {
94
- "Content-Type" => "application/atom+xml",
95
- "Content-Length" => "#{update_body.length}",
96
- }
97
- update_url = "/feeds/api/users/default/uploads/%s" % video_id
98
- response = yt_session.put(update_url, update_body, update_header)
91
+ @opts = options
92
+ update_body = video_xml
93
+ update_url = "/feeds/api/users/default/uploads/%s" % video_id
94
+ response = yt_session.put(update_url, update_body)
99
95
 
100
96
  return YouTubeIt::Parser::VideoFeedParser.new(response.body).parse
101
97
  end
98
+
99
+ # Fetches the currently authenticated user's contacts (i.e. friends).
100
+ # When the authentication credentials are incorrect, an AuthenticationError will be raised.
101
+ def get_my_contacts(opts)
102
+ contacts_url = "/feeds/api/users/default/contacts?v=2"
103
+ contacts_url << opts.collect { |k,p| [k,p].join '=' }.join('&')
104
+ response = yt_session.get(contacts_url)
105
+
106
+ return YouTubeIt::Parser::ContactsParser.new(response).parse
107
+ end
102
108
 
103
109
  # Fetches the data of a video, which may be private. The video must be owned by this user.
104
110
  # When the authentication credentials are incorrect, an AuthenticationError will be raised.
105
111
  def get_my_video(video_id)
106
- get_header = {
107
- "Content-Type" => "application/atom+xml",
108
- "Content-Length" => "0",
109
- }
110
112
  get_url = "/feeds/api/users/default/uploads/%s" % video_id
111
- response = yt_session.get(get_url, get_header)
113
+ response = yt_session.get(get_url)
112
114
 
113
115
  return YouTubeIt::Parser::VideoFeedParser.new(response.body).parse
114
116
  end
@@ -118,51 +120,34 @@ class YouTubeIt
118
120
  def get_my_videos(opts)
119
121
  max_results = opts[:per_page] || 50
120
122
  start_index = ((opts[:page] || 1) -1) * max_results +1
121
- get_header = {
122
- "Content-Type" => "application/atom+xml",
123
- "Content-Length" => "0",
124
- }
125
- get_url = "/feeds/api/users/default/uploads?max-results=#{max_results}&start-index=#{start_index}"
126
- response = yt_session.get(get_url, get_header)
123
+ get_url = "/feeds/api/users/default/uploads?max-results=#{max_results}&start-index=#{start_index}"
124
+ response = yt_session.get(get_url)
127
125
 
128
126
  return YouTubeIt::Parser::VideosFeedParser.new(response.body).parse
129
127
  end
130
128
 
131
129
  # Delete a video on YouTube
132
130
  def delete(video_id)
133
- delete_header = {
134
- "Content-Type" => "application/atom+xml; charset=UTF-8",
135
- "Content-Length" => "0",
136
- }
137
131
  delete_url = "/feeds/api/users/default/uploads/%s" % video_id
138
- response = yt_session.delete(delete_url, delete_header)
132
+ response = yt_session.delete(delete_url)
139
133
 
140
134
  return true
141
135
  end
142
136
 
143
137
  def get_upload_token(options, nexturl)
144
- @opts = options
145
- token_body = video_xml
146
- token_header = {
147
- "Content-Type" => "application/atom+xml; charset=UTF-8",
148
- "Content-Length" => "#{token_body.length}",
149
- }
150
- token_url = "/action/GetUploadToken"
151
- response = yt_session.post(token_url, token_body, token_header)
138
+ @opts = options
139
+ token_body = video_xml
140
+ token_url = "/action/GetUploadToken"
141
+ response = yt_session.post(token_url, token_body)
152
142
 
153
143
  return {:url => "#{response.body[/<url>(.+)<\/url>/, 1]}?nexturl=#{nexturl}",
154
144
  :token => response.body[/<token>(.+)<\/token>/, 1]}
155
145
  end
156
146
 
157
147
  def add_comment(video_id, comment)
158
- comment_body = video_xml_for(:comment => comment)
159
- comment_header = {
160
- "Content-Type" => "application/atom+xml",
161
- "Content-Length" => "#{comment_body.length}",
162
- }
163
- comment_url = "/feeds/api/videos/%s/comments" % video_id
164
-
165
- response = yt_session.post(comment_url, comment_body, comment_header)
148
+ comment_body = video_xml_for(:comment => comment)
149
+ comment_url = "/feeds/api/videos/%s/comments" % video_id
150
+ response = yt_session.post(comment_url, comment_body)
166
151
 
167
152
  return {:code => response.status, :body => response.body}
168
153
  end
@@ -170,43 +155,44 @@ class YouTubeIt
170
155
  def comments(video_id, opts = {})
171
156
  comment_url = "/feeds/api/videos/%s/comments?" % video_id
172
157
  comment_url << opts.collect { |k,p| [k,p].join '=' }.join('&')
173
- response = yt_session.get(comment_url)
158
+ response = yt_session.get(comment_url)
174
159
 
175
160
  return YouTubeIt::Parser::CommentsFeedParser.new(response).parse
176
161
  end
177
162
 
178
163
  def add_favorite(video_id)
179
- favorite_body = video_xml_for(:favorite => video_id)
180
- favorite_header = {
181
- "Content-Type" => "application/atom+xml",
182
- "Content-Length" => "#{favorite_body.length}",
183
- }
184
- favorite_url = "/feeds/api/users/default/favorites"
185
- response = yt_session.post(favorite_url, favorite_body, favorite_header)
164
+ favorite_body = video_xml_for(:favorite => video_id)
165
+ favorite_url = "/feeds/api/users/default/favorites"
166
+ response = yt_session.post(favorite_url, favorite_body)
186
167
 
187
168
  return {:code => response.status, :body => response.body}
188
169
  end
189
170
 
190
171
  def delete_favorite(video_id)
191
172
  favorite_header = {
192
- "Content-Type" => "application/atom+xml; charset=UTF-8",
193
- "Content-Length" => "0",
173
+ "GData-Version" => "1",
194
174
  }
195
- favorite_url = "/feeds/api/users/default/favorites/%s" % video_id
196
- response = yt_session.delete(favorite_url, favorite_header)
175
+ favorite_url = "/feeds/api/users/default/favorites/%s" % video_id
176
+ response = yt_session.delete(favorite_url, favorite_header)
197
177
 
198
178
  return true
199
179
  end
200
180
 
201
181
  def profile(user)
202
- profile_url = "/feeds/api/users/%s?v=2" % (user ? user : "default")
203
- profile_header = {
204
- "Content-Type" => "application/atom+xml; charset=UTF-8"
205
- }
206
- response = yt_session.get(profile_url, profile_header)
182
+ profile_url = "/feeds/api/users/%s?v=2" % (user ? user : "default")
183
+ response = yt_session.get(profile_url)
207
184
 
208
185
  return YouTubeIt::Parser::ProfileFeedParser.new(response).parse
209
186
  end
187
+
188
+ # Return's a user's activity feed.
189
+ def get_activity(user, opts)
190
+ activity_url = "/feeds/api/events?author=%s&v=2&" % (user ? user : "default")
191
+ activity_url << opts.collect { |k,p| [k,p].join '=' }.join('&')
192
+ response = yt_session.get(activity_url)
193
+
194
+ return YouTubeIt::Parser::ActivityParser.new(response).parse
195
+ end
210
196
 
211
197
  def playlist(playlist_id)
212
198
  playlist_url = "/feeds/api/playlists/%s?v=2" % playlist_id
@@ -223,101 +209,69 @@ class YouTubeIt
223
209
  end
224
210
 
225
211
  def add_playlist(options)
226
- playlist_body = video_xml_for_playlist(options)
227
- playlist_header = {
228
- "Content-Type" => "application/atom+xml",
229
- "Content-Length" => "#{playlist_body.length}",
230
- }
231
- playlist_url = "/feeds/api/users/default/playlists"
232
- response = yt_session.post(playlist_url, playlist_body, playlist_header)
212
+ playlist_body = video_xml_for_playlist(options)
213
+ playlist_url = "/feeds/api/users/default/playlists"
214
+ response = yt_session.post(playlist_url, playlist_body)
233
215
 
234
216
  return YouTubeIt::Parser::PlaylistFeedParser.new(response).parse
235
217
  end
236
218
 
237
219
  def add_video_to_playlist(playlist_id, video_id)
238
- playlist_body = video_xml_for(:playlist => video_id)
239
- playlist_header = {
240
- "Content-Type" => "application/atom+xml",
241
- "Content-Length" => "#{playlist_body.length}",
242
- }
243
- playlist_url = "/feeds/api/playlists/%s" % playlist_id
244
- response = yt_session.post(playlist_url, playlist_body, playlist_header)
220
+ playlist_body = video_xml_for(:playlist => video_id)
221
+ playlist_url = "/feeds/api/playlists/%s" % playlist_id
222
+ response = yt_session.post(playlist_url, playlist_body)
245
223
 
246
224
  return {:code => response.status, :body => response.body, :playlist_entry_id => playlist_entry_id_from_playlist(response.body)}
247
225
  end
248
226
 
249
227
  def update_playlist(playlist_id, options)
250
- playlist_body = video_xml_for_playlist(options)
251
- playlist_header = {
252
- "Content-Type" => "application/atom+xml",
253
- "Content-Length" => "#{playlist_body.length}",
254
- }
255
- playlist_url = "/feeds/api/users/default/playlists/%s" % playlist_id
256
- response = yt_session.put(playlist_url, playlist_body, playlist_header)
228
+ playlist_body = video_xml_for_playlist(options)
229
+ playlist_url = "/feeds/api/users/default/playlists/%s" % playlist_id
230
+ response = yt_session.put(playlist_url, playlist_body)
257
231
 
258
232
  return YouTubeIt::Parser::PlaylistFeedParser.new(response).parse
259
233
  end
260
234
 
261
235
  def delete_video_from_playlist(playlist_id, playlist_entry_id)
262
- playlist_header = {
263
- "Content-Type" => "application/atom+xml",
264
- }
265
236
  playlist_url = "/feeds/api/playlists/%s/%s" % [playlist_id, playlist_entry_id]
266
- response = yt_session.delete(playlist_url, playlist_header)
237
+ response = yt_session.delete(playlist_url)
267
238
 
268
239
  return true
269
240
  end
270
241
 
271
242
  def delete_playlist(playlist_id)
272
- playlist_header = {
273
- "Content-Type" => "application/atom+xml; charset=UTF-8",
274
- }
275
- playlist_url = "/feeds/api/users/default/playlists/%s" % playlist_id
276
- response = yt_session.delete(playlist_url, playlist_header)
243
+ playlist_url = "/feeds/api/users/default/playlists/%s" % playlist_id
244
+ response = yt_session.delete(playlist_url)
277
245
 
278
246
  return true
279
247
  end
280
248
 
281
249
  def rate_video(video_id, rating)
282
- rating_body = video_xml_for(:rating => rating)
283
- rating_header = {
284
- "Content-Type" => "application/atom+xml",
285
- "Content-Length" => "#{rating_body.length}",
286
- }
287
- rating_url = "/feeds/api/videos/#{video_id}/ratings"
288
- response = yt_session.post(rating_url, rating_body, rating_header)
250
+ rating_body = video_xml_for(:rating => rating)
251
+ rating_url = "/feeds/api/videos/#{video_id}/ratings"
252
+ response = yt_session.post(rating_url, rating_body)
289
253
 
290
254
  return {:code => response.status, :body => response.body}
291
255
  end
292
256
 
293
257
  def subscriptions(user)
294
- subscription_url = "/feeds/api/users/%s/subscriptions?v=2" % (user ? user : "default")
295
- subscription_header = {
296
- "Content-Type" => "application/atom+xml",
297
- }
298
- response = yt_session.get(subscription_url, subscription_header)
258
+ subscription_url = "/feeds/api/users/%s/subscriptions?v=2" % (user ? user : "default")
259
+ response = yt_session.get(subscription_url)
299
260
 
300
261
  return YouTubeIt::Parser::SubscriptionFeedParser.new(response).parse
301
262
  end
302
263
 
303
264
  def subscribe_channel(channel_name)
304
- subscribe_body = video_xml_for(:subscribe => channel_name)
305
- subscribe_header = {
306
- "Content-Type" => "application/atom+xml",
307
- "Content-Length" => "#{subscribe_body.length}",
308
- }
309
- subscribe_url = "/feeds/api/users/default/subscriptions"
310
- response = yt_session.post(subscribe_url, subscribe_body, subscribe_header)
265
+ subscribe_body = video_xml_for(:subscribe => channel_name)
266
+ subscribe_url = "/feeds/api/users/default/subscriptions"
267
+ response = yt_session.post(subscribe_url, subscribe_body)
311
268
 
312
269
  return {:code => response.status, :body => response.body}
313
270
  end
314
271
 
315
272
  def unsubscribe_channel(subscription_id)
316
- unsubscribe_header = {
317
- "Content-Type" => "application/atom+xml"
318
- }
319
273
  unsubscribe_url = "/feeds/api/users/default/subscriptions/%s" % subscription_id
320
- response = yt_session.delete(unsubscribe_url, unsubscribe_header)
274
+ response = yt_session.delete(unsubscribe_url)
321
275
 
322
276
  return {:code => response.status, :body => response.body}
323
277
  end
@@ -325,12 +279,13 @@ class YouTubeIt
325
279
  def favorites(user, opts = {})
326
280
  favorite_url = "/feeds/api/users/%s/favorites#{opts.empty? ? '' : '?#{opts.to_param}'}" % (user ? user : "default")
327
281
  response = yt_session.get(favorite_url)
282
+
328
283
  return YouTubeIt::Parser::VideosFeedParser.new(response.body).parse
329
284
  end
330
285
 
331
286
  def get_current_user
332
287
  current_user_url = "/feeds/api/users/default"
333
- response = yt_session.get(current_user_url, authorization_headers)
288
+ response = yt_session.get(current_user_url)
334
289
 
335
290
  return REXML::Document.new(response.body).elements["entry"].elements['author'].elements['name'].text
336
291
  end
@@ -350,14 +305,11 @@ class YouTubeIt
350
305
  end
351
306
 
352
307
  def authorization_headers
353
- header = {
354
- "X-GData-Client" => "#{@client_id}",
355
- "X-GData-Key" => "key=#{@dev_key}",
356
- "GData-Version" => "2",
357
- }
308
+ header = {"X-GData-Client" => "#{@client_id}"}
309
+ header.merge!("X-GData-Key" => "key=#{@dev_key}") if @dev_key
358
310
  if @authsub_token
359
311
  header.merge!("Authorization" => "AuthSub token=#{@authsub_token}")
360
- elsif @access_token.nil? && @authsub_token.nil?
312
+ elsif @access_token.nil? && @authsub_token.nil? && @user
361
313
  header.merge!("Authorization" => "GoogleLogin auth=#{auth_token}")
362
314
  end
363
315
  header
data/lib/youtube_it.rb CHANGED
@@ -61,6 +61,7 @@ end
61
61
  model/thumbnail
62
62
  model/user
63
63
  model/video
64
+ model/activity
64
65
  request/base_search
65
66
  request/error
66
67
  request/user_search
data/test/test_client.rb CHANGED
@@ -234,16 +234,18 @@ class TestClient < Test::Unit::TestCase
234
234
  @client.video_delete(video.unique_id)
235
235
  end
236
236
 
237
+
237
238
  def test_should_add_new_comment
238
- video_id ="aDlw5j28X3U"
239
- @client.add_comment(video_id, "test comment")
240
- comment = @client.comments(video_id).first.content
239
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
240
+ @client.add_comment(video.unique_id, "test comment")
241
+ comment = @client.comments(video.unique_id).first.content
241
242
  assert comment.match(/test comment/)
243
+ @client.video_delete(video.unique_id)
242
244
  end
243
-
245
+
244
246
  def test_should_add_and_delete_video_from_playlist
245
247
  playlist = @client.add_playlist(:title => "youtube_it test!", :description => "test playlist")
246
- video = @client.add_video_to_playlist(playlist.playlist_id,"iKqJ8z1DPrQ")
248
+ video = @client.add_video_to_playlist(playlist.playlist_id,"CE62FSEoY28")
247
249
  assert_equal video[:code].to_i, 201
248
250
  assert @client.delete_video_from_playlist(playlist.playlist_id, video[:playlist_entry_id])
249
251
  assert @client.delete_playlist(playlist.playlist_id)
@@ -270,15 +272,15 @@ class TestClient < Test::Unit::TestCase
270
272
 
271
273
  def test_should_determine_if_widescreen_video_is_widescreen
272
274
  widescreen_id = 'QqQVll-MP3I'
273
-
275
+
274
276
  video = @client.video_by(widescreen_id)
275
277
  assert video.widescreen?
276
278
  end
277
-
279
+
278
280
  def test_get_current_user
279
281
  assert_equal @client.current_user, 'tubeit20101'
280
282
  end
281
-
283
+
282
284
  def test_should_get_my_videos
283
285
  video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
284
286
  assert_valid_video video
@@ -286,7 +288,7 @@ class TestClient < Test::Unit::TestCase
286
288
  assert_equal result.videos.first.unique_id, video.unique_id
287
289
  @client.video_delete(video.unique_id)
288
290
  end
289
-
291
+
290
292
  def test_should_get_my_video
291
293
  video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
292
294
  assert_valid_video video
@@ -294,33 +296,33 @@ class TestClient < Test::Unit::TestCase
294
296
  assert_equal result.unique_id, video.unique_id
295
297
  @client.video_delete(video.unique_id)
296
298
  end
297
-
299
+
298
300
  def test_should_add_like_to_video
299
301
  r = @client.like_video("CE62FSEoY28")
300
302
  assert_equal r[:code], 201
301
303
  @client.dislike_video("CE62FSEoY28")
302
304
  end
303
-
305
+
304
306
  def test_should_dislike_to_video
305
307
  @client.like_video("CE62FSEoY28")
306
308
  r = @client.dislike_video("CE62FSEoY28")
307
309
  assert_equal r[:code], 201
308
310
  end
309
-
310
-
311
+
312
+
311
313
  def test_should_subscribe_to_channel
312
314
  r = @client.subscribe_channel("TheWoWArthas")
313
315
  assert_equal r[:code], 201
314
316
  assert_equal @client.subscriptions.first.title, "Videos published by : TheWoWArthas"
315
317
  @client.unsubscribe_channel(@client.subscriptions.first.id)
316
318
  end
317
-
319
+
318
320
  def test_should_unsubscribe_to_channel
319
321
  @client.subscribe_channel("TheWoWArthas")
320
322
  r = @client.unsubscribe_channel(@client.subscriptions.first.id)
321
323
  assert_equal r[:code], 200
322
324
  end
323
-
325
+
324
326
  def test_should_list_subscriptions
325
327
  @client.subscribe_channel("TheWoWArthas")
326
328
  assert @client.subscriptions.count == 1
@@ -332,6 +334,15 @@ class TestClient < Test::Unit::TestCase
332
334
  profile = @client.profile
333
335
  assert_equal profile.username, "tubeit20101"
334
336
  end
337
+
338
+ def test_should_add_and_delete_video_to_favorite
339
+ video_id ="j5raG94IGCc"
340
+ result = @client.add_favorite(video_id)
341
+ assert_equal result[:code], 201
342
+ sleep 4
343
+ assert @client.delete_favorite(video_id)
344
+ end
345
+
335
346
  private
336
347
 
337
348
  def assert_valid_video (video)
@@ -2,6 +2,14 @@ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
2
 
3
3
  class TestVideoFeedParser < Test::Unit::TestCase
4
4
 
5
+ def test_should_raise_bad_request_exception_when_id_not_found
6
+ bad_url = "http://gdata.youtube.com/feeds/api/videos/abc?v=2"
7
+
8
+ assert_raise(OpenURI::HTTPError) do
9
+ parser = YouTubeIt::Parser::VideoFeedParser.new bad_url
10
+ end
11
+ end
12
+
5
13
  # VIDEO ATTRIBUTES AFFECTED BY PARSING
6
14
 
7
15
  def test_should_display_unique_id_correctly_after_parsing
@@ -259,4 +267,5 @@ class TestVideoFeedParser < Test::Unit::TestCase
259
267
  yield parser
260
268
  end
261
269
  end
270
+
262
271
  end
data/youtube_it.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{youtube_it}
8
- s.version = "2.0.0"
8
+ s.version = "2.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["kylejginavan", "chebyte", "mseppae"]
12
- s.date = %q{2011-07-02}
11
+ s.authors = [%q{kylejginavan}, %q{chebyte}, %q{mseppae}]
12
+ s.date = %q{2011-09-02}
13
13
  s.description = %q{Upload, delete, update, comment on youtube videos all from one gem.}
14
14
  s.email = %q{kylejginavan@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "lib/youtube_it/middleware/faraday_authheader.rb",
27
27
  "lib/youtube_it/middleware/faraday_oauth.rb",
28
28
  "lib/youtube_it/middleware/faraday_youtubeit.rb",
29
+ "lib/youtube_it/model/activity.rb",
29
30
  "lib/youtube_it/model/author.rb",
30
31
  "lib/youtube_it/model/category.rb",
31
32
  "lib/youtube_it/model/comment.rb",
@@ -60,8 +61,8 @@ Gem::Specification.new do |s|
60
61
  "youtube_it.gemspec"
61
62
  ]
62
63
  s.homepage = %q{http://github.com/kylejginavan/youtube_it}
63
- s.require_paths = ["lib"]
64
- s.rubygems_version = %q{1.5.2}
64
+ s.require_paths = [%q{lib}]
65
+ s.rubygems_version = %q{1.8.8}
65
66
  s.summary = %q{The most complete Ruby wrapper for youtube api's}
66
67
  s.test_files = [
67
68
  "test/helper.rb",
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: youtube_it
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.0.0
5
+ version: 2.0.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - kylejginavan
@@ -12,8 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2011-07-02 00:00:00 -05:00
16
- default_executable:
15
+ date: 2011-09-02 00:00:00 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
18
  name: oauth
@@ -78,6 +77,7 @@ files:
78
77
  - lib/youtube_it/middleware/faraday_authheader.rb
79
78
  - lib/youtube_it/middleware/faraday_oauth.rb
80
79
  - lib/youtube_it/middleware/faraday_youtubeit.rb
80
+ - lib/youtube_it/model/activity.rb
81
81
  - lib/youtube_it/model/author.rb
82
82
  - lib/youtube_it/model/category.rb
83
83
  - lib/youtube_it/model/comment.rb
@@ -110,7 +110,6 @@ files:
110
110
  - test/test_video_feed_parser.rb
111
111
  - test/test_video_search.rb
112
112
  - youtube_it.gemspec
113
- has_rdoc: true
114
113
  homepage: http://github.com/kylejginavan/youtube_it
115
114
  licenses: []
116
115
 
@@ -134,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
133
  requirements: []
135
134
 
136
135
  rubyforge_project:
137
- rubygems_version: 1.5.2
136
+ rubygems_version: 1.8.8
138
137
  signing_key:
139
138
  specification_version: 3
140
139
  summary: The most complete Ruby wrapper for youtube api's