youtube_it 2.3.2 → 2.4.0
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.
- data/CHANGELOG.md +9 -0
- data/README.rdoc +9 -3
- data/lib/youtube_it.rb +0 -9
- data/lib/youtube_it/client.rb +4 -4
- data/lib/youtube_it/middleware/faraday_youtubeit.rb +17 -10
- data/lib/youtube_it/model/comment.rb +2 -0
- data/lib/youtube_it/model/subscription.rb +1 -1
- data/lib/youtube_it/model/user.rb +1 -0
- data/lib/youtube_it/model/video.rb +19 -17
- data/lib/youtube_it/parser.rb +8 -4
- data/lib/youtube_it/request/error.rb +18 -12
- data/lib/youtube_it/request/remote_file.rb +3 -1
- data/lib/youtube_it/request/standard_search.rb +7 -1
- data/lib/youtube_it/request/video_upload.rb +2 -7
- data/lib/youtube_it/version.rb +1 -1
- data/youtube_it.gemspec +3 -3
- metadata +6 -4
data/CHANGELOG.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
2.3.x 2013-xx-xx
|
2
|
+
----------------
|
3
|
+
|
4
|
+
Changes:
|
5
|
+
- All YouTubeIt errors are now defined under the YouTubeIt namespace and inherit from YouTubeIt::Error
|
6
|
+
- All 404 responses from the YouTube api now raise YouTubeIt::ResourceNotFoundError instead of UploadError
|
7
|
+
|
8
|
+
Improvements:
|
9
|
+
- Added this CHANGELOG
|
data/README.rdoc
CHANGED
@@ -93,6 +93,7 @@ Standard Queries:
|
|
93
93
|
$ client.videos_by(:most_linked, :page => 3)
|
94
94
|
$ client.videos_by(:top_rated, :time => :today)
|
95
95
|
$ client.get_all_videos(:top_rated, :time => :today)
|
96
|
+
$ client.videos_by(:top_rated, :region => "RU", :category => "News")
|
96
97
|
Advanced Queries (with boolean operators OR (either), AND (include), NOT (exclude)):
|
97
98
|
$ client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] }, :tags => { :include => ['football'], :exclude => ['soccer'] })
|
98
99
|
|
@@ -112,8 +113,8 @@ Fields Parameter(experimental features):
|
|
112
113
|
$ client.videos_by(:fields => {:view_count => "1000"})
|
113
114
|
|
114
115
|
Filter by date
|
115
|
-
$ client.videos_by(:fields => {:published => (
|
116
|
-
$ client.videos_by(:fields => {:recorded => (
|
116
|
+
$ client.videos_by(:fields => {:published => (Date.today)})
|
117
|
+
$ client.videos_by(:fields => {:recorded => (Date.today)})
|
117
118
|
|
118
119
|
Filter by date with range
|
119
120
|
$ client.videos_by(:fields => {:published => ((Date.today - 30)..(Date.today))})
|
@@ -130,6 +131,10 @@ Note: YouTube account, OAuth or AuthSub enables video management.
|
|
130
131
|
Upload Video:
|
131
132
|
$ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test])
|
132
133
|
|
134
|
+
Upload Remote Video:
|
135
|
+
$ client.video_upload("http://url/myvideo.mp4", :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test])
|
136
|
+
|
137
|
+
|
133
138
|
Upload Video With A Developer Tag (Note the tags are not immediately available):
|
134
139
|
$ client.video_upload(File.open("test.mov"), :title => "test",:description => 'some description', :category => 'People',:keywords => %w[cool blah test], :dev_tag => 'tagdev')
|
135
140
|
|
@@ -319,7 +324,8 @@ Note: you can specify width or just use the default of 1280.
|
|
319
324
|
Now you can embed videos without use flash using html5, usefull for mobiles that not support flash but has html5 browser
|
320
325
|
|
321
326
|
You can specify these options
|
322
|
-
$ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1', :url_params => {:option_one => "value", :option_two => "value"}
|
327
|
+
$ video.embed_html5({:class => 'video-player', :id => 'my-video', :width => '425', :height => '350', :frameborder => '1', :url_params => {:option_one => "value", :option_two => "value"},
|
328
|
+
fullscreen: true, :sandbox => "value"})
|
323
329
|
|
324
330
|
or just use with default options
|
325
331
|
$ video.embed_html5 #default: width: 425, height: 350, frameborder: 0
|
data/lib/youtube_it.rb
CHANGED
@@ -11,15 +11,6 @@ require 'faraday'
|
|
11
11
|
class YouTubeIt
|
12
12
|
API_VERSION = "2.1"
|
13
13
|
|
14
|
-
# Base error class for the extension
|
15
|
-
class Error < RuntimeError
|
16
|
-
attr_reader :code
|
17
|
-
def initialize(msg, code = 0)
|
18
|
-
super(msg)
|
19
|
-
@code = code
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
14
|
def self.esc(s) #:nodoc:
|
24
15
|
CGI.escape(s.to_s)
|
25
16
|
end
|
data/lib/youtube_it/client.rb
CHANGED
@@ -465,9 +465,9 @@ class YouTubeIt
|
|
465
465
|
if (response_code / 10).to_i == 20 # success
|
466
466
|
Nokogiri::XML(profile.body).at("//yt:username").text
|
467
467
|
elsif response_code == 403 || response_code == 401 # auth failure
|
468
|
-
raise
|
468
|
+
raise AuthenticationError.new(profile.inspect, response_code)
|
469
469
|
else
|
470
|
-
raise
|
470
|
+
raise UploadError.new(profile.inspect, response_code)
|
471
471
|
end
|
472
472
|
end
|
473
473
|
|
@@ -526,9 +526,9 @@ class YouTubeIt
|
|
526
526
|
if (response_code / 10).to_i == 20 # success
|
527
527
|
Nokogiri::XML(profile.body).at("//yt:username").text
|
528
528
|
elsif response_code == 403 || response_code == 401 # auth failure
|
529
|
-
raise
|
529
|
+
raise AuthenticationError.new(profile.inspect, response_code)
|
530
530
|
else
|
531
|
-
raise
|
531
|
+
raise UploadError.new(profile.inspect, response_code)
|
532
532
|
end
|
533
533
|
end
|
534
534
|
|
@@ -1,6 +1,22 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Response::YouTubeIt < Response::Middleware
|
3
|
-
def
|
3
|
+
def on_complete(env) #this method is called after finish request
|
4
|
+
msg = parse_error_from(env[:body])
|
5
|
+
if env[:status] == 404
|
6
|
+
raise ::YouTubeIt::ResourceNotFoundError.new(msg)
|
7
|
+
elsif env[:status] == 403 || env[:status] == 401
|
8
|
+
raise ::YouTubeIt::AuthenticationError.new(msg, env[:status])
|
9
|
+
elsif (env[:status] / 10).to_i != 20
|
10
|
+
raise ::YouTubeIt::UploadError.new(msg, env[:status])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def parse_error_from(string)
|
16
|
+
return "" unless string
|
17
|
+
|
18
|
+
string.gsub!("\n", "")
|
19
|
+
|
4
20
|
xml = Nokogiri::XML(string).at('errors')
|
5
21
|
if xml
|
6
22
|
xml.css("error").inject('') do |all_faults, error|
|
@@ -18,14 +34,5 @@ module Faraday
|
|
18
34
|
string[/<TITLE>(.+)<\/TITLE>/, 1] || string
|
19
35
|
end
|
20
36
|
end
|
21
|
-
|
22
|
-
def on_complete(env) #this method is called after finish request
|
23
|
-
msg = env[:body] ? parse_upload_error_from((env[:body] || '').gsub(/\n/, '')) : ''
|
24
|
-
if env[:status] == 403 || env[:status] == 401
|
25
|
-
raise ::AuthenticationError.new(msg, env[:status])
|
26
|
-
elsif (env[:status] / 10).to_i != 20
|
27
|
-
raise ::UploadError.new(msg, env[:status])
|
28
|
-
end
|
29
|
-
end
|
30
37
|
end
|
31
38
|
end
|
@@ -247,24 +247,26 @@ class YouTubeIt
|
|
247
247
|
EDOC
|
248
248
|
end
|
249
249
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
250
|
+
# Gives you the HTML 5 to embed the video on your website.
|
251
|
+
# Usefull for mobile that not support flash but has html5 browser
|
252
|
+
# === Returns
|
253
|
+
# String: The HTML for embedding the video on your website.
|
254
|
+
def embed_html5(params = {})
|
255
|
+
opts = {:class => params[:class] || "",
|
256
|
+
:id => params[:id] || "",
|
257
|
+
:width => params[:width] || "425",
|
258
|
+
:height => params[:height] || "350",
|
259
|
+
:protocol => params[:protocol] || "http",
|
260
|
+
:frameborder => params[:frameborder] || "0",
|
261
|
+
:url_params => params[:url_params] || {},
|
262
|
+
:sandbox => params[:sandbox] || false,
|
263
|
+
:fullscreen => params[:fullscreen] || false,
|
264
|
+
}
|
265
|
+
url_opts = opts[:url_params].empty? ? "" : "?#{Rack::Utils::build_query(opts[:url_params])}"
|
266
|
+
<<EDOC
|
267
|
+
<iframe class="#{opts[:class]}" id="#{opts[:id]}" type="text/html" width="#{opts[:width]}" height="#{opts[:height]}" src="#{opts[:protocol]}://www.youtube.com/embed/#{unique_id}#{url_opts}" frameborder="#{opts[:frameborder]}" #{" sandbox=\"#{opts[:sandbox]}\" " if opts[:sandbox]} #{"allowfullscreen" if opts[:fullscreen]}></iframe>
|
266
268
|
EDOC
|
267
|
-
|
269
|
+
end
|
268
270
|
|
269
271
|
# Gives you the HTML to embed the video on your website.
|
270
272
|
#
|
data/lib/youtube_it/parser.rb
CHANGED
@@ -62,7 +62,9 @@ class YouTubeIt
|
|
62
62
|
:title => remove_bom(entry.at("title").text),
|
63
63
|
:updated => entry.at("updated").text,
|
64
64
|
:url => entry.at("id").text,
|
65
|
-
:reply_to => parse_reply(entry)
|
65
|
+
:reply_to => parse_reply(entry),
|
66
|
+
:channel_id => (entry.at("yt|channelId").text rescue nil),
|
67
|
+
:gp_user_id => (entry.at("yt|googlePlusUserId").text rescue nil)
|
66
68
|
)
|
67
69
|
end
|
68
70
|
|
@@ -320,7 +322,8 @@ class YouTubeIt
|
|
320
322
|
:videos_watched => entry.at_xpath("yt:statistics")["videoWatchCount"],
|
321
323
|
:view_count => entry.at_xpath("yt:statistics")["viewCount"],
|
322
324
|
:upload_views => entry.at_xpath("yt:statistics")["totalUploadViews"],
|
323
|
-
:insight_uri => (entry.at_xpath('xmlns:link[@rel="http://gdata.youtube.com/schemas/2007#insight.views"]')['href'] rescue nil)
|
325
|
+
:insight_uri => (entry.at_xpath('xmlns:link[@rel="http://gdata.youtube.com/schemas/2007#insight.views"]')['href'] rescue nil),
|
326
|
+
:channel_uri => (entry.at_xpath('xmlns:link[@rel="alternate"]')['href'] rescue nil),
|
324
327
|
)
|
325
328
|
end
|
326
329
|
end
|
@@ -360,7 +363,8 @@ class YouTubeIt
|
|
360
363
|
YouTubeIt::Model::Subscription.new(
|
361
364
|
:title => entry.at("title").text,
|
362
365
|
:id => entry.at("id").text[/subscription([^<]+)/, 1].sub(':',''),
|
363
|
-
:published => entry.at("published") ? entry.at("published").text : nil
|
366
|
+
:published => entry.at("published") ? entry.at("published").text : nil,
|
367
|
+
:youtube_user_name => entry.to_s.split(/\<|\>/)[-4]
|
364
368
|
)
|
365
369
|
end
|
366
370
|
end
|
@@ -574,7 +578,7 @@ class YouTubeIt
|
|
574
578
|
|
575
579
|
def parse_media_content (elem)
|
576
580
|
content_url = elem["url"]
|
577
|
-
format_code = elem["format"].to_i
|
581
|
+
format_code = elem["yt:format"].to_i
|
578
582
|
format = YouTubeIt::Model::Video::Format.by_code(format_code)
|
579
583
|
duration = elem["duration"].to_i
|
580
584
|
mime_type = elem["type"]
|
@@ -1,15 +1,21 @@
|
|
1
|
-
class
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
class YouTubeIt
|
2
|
+
class Error < RuntimeError
|
3
|
+
attr_reader :code
|
4
|
+
def initialize(msg, code = 0)
|
5
|
+
super(msg)
|
6
|
+
@code = code
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ResourceNotFoundError < Error
|
11
|
+
def initialize(msg)
|
12
|
+
super(msg, 404)
|
13
|
+
end
|
6
14
|
end
|
7
|
-
end
|
8
15
|
|
9
|
-
class
|
10
|
-
attr_reader :code
|
11
|
-
def initialize(msg, code = 0)
|
12
|
-
super(msg)
|
13
|
-
@code = code
|
16
|
+
class UploadError < Error
|
14
17
|
end
|
15
|
-
|
18
|
+
|
19
|
+
class AuthenticationError < Error
|
20
|
+
end
|
21
|
+
end
|
@@ -5,6 +5,8 @@ class YouTubeIt
|
|
5
5
|
attr_reader :order_by # orderby, ([relevance], viewCount, published, rating)
|
6
6
|
attr_reader :offset # start-index
|
7
7
|
attr_reader :time # time
|
8
|
+
attr_reader :region # region
|
9
|
+
attr_reader :category # category
|
8
10
|
|
9
11
|
TYPES = [ :top_rated, :top_favorites, :most_viewed, :most_popular,
|
10
12
|
:most_recent, :most_discussed, :most_linked, :most_responded,
|
@@ -15,7 +17,11 @@ class YouTubeIt
|
|
15
17
|
if TYPES.include?(type)
|
16
18
|
@max_results, @order_by, @offset, @time = nil
|
17
19
|
set_instance_variables(options)
|
18
|
-
@url = base_url
|
20
|
+
@url = base_url
|
21
|
+
@url << @region << "/" if @region
|
22
|
+
@url << type.to_s
|
23
|
+
@url << "_" << @category if @category
|
24
|
+
@url << build_query_params(to_youtube_params)
|
19
25
|
else
|
20
26
|
raise "Invalid type, must be one of: #{ TYPES.map { |t| t.to_s }.join(", ") }"
|
21
27
|
end
|
@@ -1,10 +1,5 @@
|
|
1
1
|
class YouTubeIt
|
2
2
|
module Upload
|
3
|
-
|
4
|
-
class UploadError < YouTubeIt::Error; end
|
5
|
-
|
6
|
-
class AuthenticationError < YouTubeIt::Error; end
|
7
|
-
|
8
3
|
# Implements video uploads/updates/deletions
|
9
4
|
#
|
10
5
|
# require 'youtube_it'
|
@@ -82,7 +77,7 @@ class YouTubeIt
|
|
82
77
|
def upload(video_data, opts = {})
|
83
78
|
|
84
79
|
if video_data.is_a?(String) && uri?(video_data)
|
85
|
-
data = YouTubeIt::Upload::RemoteFile.new(video_data)
|
80
|
+
data = YouTubeIt::Upload::RemoteFile.new(video_data, opts)
|
86
81
|
else
|
87
82
|
data = video_data
|
88
83
|
end
|
@@ -590,7 +585,7 @@ class YouTubeIt
|
|
590
585
|
http = Faraday.new("https://www.google.com", :ssl => {:verify => false})
|
591
586
|
body = "Email=#{YouTubeIt.esc @user}&Passwd=#{YouTubeIt.esc @password}&service=youtube&source=#{YouTubeIt.esc @client_id}"
|
592
587
|
response = http.post("/accounts/ClientLogin", body, "Content-Type" => "application/x-www-form-urlencoded")
|
593
|
-
raise ::AuthenticationError.new(response.body[/Error=(.+)/,1], response.status.to_i) if response.status.to_i != 200
|
588
|
+
raise ::YouTubeIt::AuthenticationError.new(response.body[/Error=(.+)/,1], response.status.to_i) if response.status.to_i != 200
|
594
589
|
@auth_token = response.body[/Auth=(.+)/, 1]
|
595
590
|
end
|
596
591
|
end
|
data/lib/youtube_it/version.rb
CHANGED
data/youtube_it.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.summary = "The most complete Ruby wrapper for youtube api's"
|
15
15
|
s.homepage = "http://github.com/kylejginavan/youtube_it"
|
16
16
|
|
17
|
-
s.add_runtime_dependency("nokogiri", "~> 1.
|
17
|
+
s.add_runtime_dependency("nokogiri", "~> 1.6.0")
|
18
18
|
s.add_runtime_dependency("oauth", "~> 0.4.4")
|
19
19
|
s.add_runtime_dependency("oauth2", "~> 0.6")
|
20
20
|
s.add_runtime_dependency("simple_oauth", ">= 0.1.5")
|
@@ -22,9 +22,9 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_runtime_dependency("builder", ">= 0")
|
23
23
|
s.add_runtime_dependency("webmock")
|
24
24
|
s.add_runtime_dependency("excon")
|
25
|
-
s.add_runtime_dependency("json", "~> 1.
|
25
|
+
s.add_runtime_dependency("json", "~> 1.7.7")
|
26
26
|
s.files = Dir.glob("lib/**/*") + %w(README.rdoc youtube_it.gemspec)
|
27
27
|
|
28
|
-
s.extra_rdoc_files = %w(README.rdoc)
|
28
|
+
s.extra_rdoc_files = %w(README.rdoc CHANGELOG.md)
|
29
29
|
end
|
30
30
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: youtube_it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 2.
|
5
|
+
version: 2.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- kylejginavan
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-11-15 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: nokogiri
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ~>
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 1.
|
24
|
+
version: 1.6.0
|
25
25
|
type: :runtime
|
26
26
|
version_requirements: *id001
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
requirements:
|
110
110
|
- - ~>
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version: 1.
|
112
|
+
version: 1.7.7
|
113
113
|
type: :runtime
|
114
114
|
version_requirements: *id009
|
115
115
|
description: Upload, delete, update, comment on youtube videos all from one gem.
|
@@ -122,6 +122,7 @@ extensions: []
|
|
122
122
|
|
123
123
|
extra_rdoc_files:
|
124
124
|
- README.rdoc
|
125
|
+
- CHANGELOG.md
|
125
126
|
files:
|
126
127
|
- lib/youtube_it.rb
|
127
128
|
- lib/youtube_it/chain_io.rb
|
@@ -157,6 +158,7 @@ files:
|
|
157
158
|
- lib/youtube_it/response/video_search.rb
|
158
159
|
- README.rdoc
|
159
160
|
- youtube_it.gemspec
|
161
|
+
- CHANGELOG.md
|
160
162
|
homepage: http://github.com/kylejginavan/youtube_it
|
161
163
|
licenses: []
|
162
164
|
|