vzaar 1.5.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OWFiMzNjOTQxM2I2M2YzZDNiYWIxNTRiNzA0YTk5ZDcwNzk3ZmNlZQ==
5
- data.tar.gz: !binary |-
6
- OWM0OThiZjlhYWMwOWE3ZjI1NWI2ZWY1YjBjZTZkNmI5NjhhM2VkMA==
2
+ SHA1:
3
+ metadata.gz: c1f51bc51dfb2661ea560ab755d5d259ecf5bc9a
4
+ data.tar.gz: af11b53d12bd5a8e36e2ad787c0f14de5a7a1307
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- Y2I5YTM4MmMxMGE5NzQyOTBiOTkzZGVlNDc4ZWExZDEzNWVmMDRkY2VlYWYx
10
- ZTczOGY1YzcxNWRiYjkyNGQwMWYzZmRhODk2Y2I2MjQ1Mjc4YjUwNDY5MTM1
11
- MDc2MThjYzQ0MTM1OTMxM2IyYjBjYzlkOTc1YWYzM2RmZGU1M2U=
12
- data.tar.gz: !binary |-
13
- MTQ4ZGNmYzhjZjUyOGFlMmM1YWIyOTY3NDkyNDY3YjRhNTI3MzU0NzNmY2Jh
14
- NmFiZDQ3MWFlMWUyNDczMmQyOWQ0ZWU3YTZhZmI3OWM5ODhjM2ZmMTYyNjBk
15
- NWQ1MGNhYmZkM2E2YzJkNGYwOWYxZTZhMjc4OWFhYTU1YWMwZDQ=
6
+ metadata.gz: 7850014b6cd0aa53d6fe9ddfc94fb919a90ef738bb7f76d1936909a65f74e044a899a34261c5c9279322cd4fa0a5e91a679cbbee58ebe16c91b613f698a7236f
7
+ data.tar.gz: faa4b22a4362cc33fa6a6e23d49cf969a40fa64ab9102aa1e17d734b4ef20bd17c34af63d01dee74744b2c59b138a46d4616ca7989016660b2d51e535cbd9bcc
@@ -1 +1 @@
1
- 2.1.2
1
+ 2.3.0
@@ -1,4 +1,4 @@
1
1
  rvm:
2
- - 1.9.3
3
- - 2.1.6
4
- - 2.2.2
2
+ - 2.1.8
3
+ - 2.2.4
4
+ - 2.3.0
data/ChangeLog CHANGED
@@ -1,11 +1,19 @@
1
- [1.5.2] 2015-03-30 JC <jozef@vzaar.com>
1
+ [1.6.0] 2015-07-07 EJ <ed@vzaar.com>
2
+
3
+ * support for chunked uploads
4
+
5
+ [1.5.3] 2015-07-07 Raz Itzhakian <raz.itzhakian@fiverr.com>
6
+
7
+ * timeout option added for API calls
8
+
9
+ [1.5.2] 2015-03-30 JC <jozef@vzaar.com>
2
10
 
3
11
  * call CGI.escape against link_upload/url and video/seo_url params
4
12
 
5
- [1.5.1] 2015-03-27 JC <jozef@vzaar.com>
13
+ [1.5.1] 2015-03-27 JC <jozef@vzaar.com>
14
+
15
+ * escaping special chars from xml added
6
16
 
7
- * escaping special chars from xml added
8
-
9
17
  2015-02-19 JC <jozef@vzaar.com>
10
18
 
11
19
  * renditions added to Vzaar::Resource::Video
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ gem 'rake'
10
10
 
11
11
  group :development, :test do
12
12
  gem 'pry'
13
+ gem 'pry-nav'
13
14
  gem 'fuubar', '2.0.0.rc1'
14
15
  gem 'growl'
15
16
  gem 'guard-rspec'
data/Guardfile CHANGED
@@ -1,7 +1,54 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard :rspec, all_after_pass: true, all_on_start: true do
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features)
6
+
7
+ ## Uncomment to clear the screen before every task
8
+ # clearing :on
9
+
10
+ ## Guard internally checks for changes in the Guardfile and exits.
11
+ ## If you want Guard to automatically start up again, run guard in a
12
+ ## shell loop, e.g.:
13
+ ##
14
+ ## $ while bundle exec guard; do echo "Restarting Guard..."; done
15
+ ##
16
+ ## Note: if you are using the `directories` clause above and you are not
17
+ ## watching the project directory ('.'), then you will want to move
18
+ ## the Guardfile to a watched dir and symlink it back, e.g.
19
+ #
20
+ # $ mkdir config
21
+ # $ mv Guardfile config/
22
+ # $ ln -s config/Guardfile .
23
+ #
24
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
25
+
26
+ # Note: The cmd option is now required due to the increasing number of ways
27
+ # rspec may be run, below are examples of the most common uses.
28
+ # * bundler: 'bundle exec rspec'
29
+ # * bundler binstubs: 'bin/rspec'
30
+ # * spring: 'bin/rspec' (This will use spring if running and you have
31
+ # installed the spring binstubs per the docs)
32
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
33
+ # * 'just' rspec: 'rspec'
34
+
35
+ guard :rspec, cmd: "bundle exec rspec", all_on_start: true do
36
+ require "guard/rspec/dsl"
37
+ dsl = Guard::RSpec::Dsl.new(self)
38
+ clearing :on
39
+
40
+ # Feel free to open issues for suggestions and improvements
41
+
42
+ # RSpec files
43
+ rspec = dsl.rspec
44
+ watch(rspec.spec_helper) { rspec.spec_dir }
45
+ watch(rspec.spec_support) { rspec.spec_dir }
46
+ watch(rspec.spec_files)
47
+
48
+ # Ruby files
49
+ ruby = dsl.ruby
50
+ dsl.watch_spec_files_for(ruby.lib_files)
51
+
5
52
  watch(%r{^spec/.+_spec\.rb$})
6
53
  watch(%r{^lib/vzaar.rb$}) { "spec" }
7
54
  watch(%r{^lib/vzaar/(.+)\.rb$}) { "spec" }
@@ -3,63 +3,52 @@ require_relative './spec_helper'
3
3
  describe "Signature" do
4
4
  describe "signature" do
5
5
  context "when user is unauthenticated" do
6
- it_behaves_like "Unauthenticated", ->(api) { api.signature }
6
+ it_behaves_like "Unauthenticated", ->(api) do
7
+ api.signature(path: './spec/support/video.mov')
8
+ end
7
9
  end
8
10
 
9
11
  context "with no :sucess_action_redirect" do
10
12
  it "should be successful" do
11
- api = _api(login: user1["login"],
12
- application_token: user1["rw_token"])
13
-
14
- expect(api.signature.http_status_code).to eq(200)
13
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
14
+ signature = api.signature(path: './spec/support/video.mov')
15
+ expect(signature.http_status_code).to eq 200
15
16
  end
16
17
  end
17
18
 
18
19
  context "with unencoded :success_action_redirect" do
19
20
  it "should be successful" do
20
- api = _api(login: user1["login"],
21
- application_token: user1["rw_token"])
22
- expect(
23
- api.signature(
24
- :success_action_redirect => "http://test.com"
25
- ).http_status_code
26
- ).to eq(200)
21
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
22
+ signature = api.signature(path: './spec/support/video.mov',
23
+ success_action_redirect: 'http://test.com')
24
+ expect(signature.http_status_code).to eq 200
27
25
  end
28
26
  end
29
27
 
30
28
  context "with URI encoded :success_action_redirect" do
31
29
  it "should be successful" do
32
- api = _api(login: user1["login"],
33
- application_token: user1["rw_token"])
34
- expect(
35
- api.signature(
36
- :success_action_redirect => CGI.escape("http://test.com")
37
- ).http_status_code
38
- ).to eq(200)
30
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
31
+ signature = api.signature(path: './spec/support/video.mov',
32
+ success_action_redirect: CGI.escape("http://test.com"))
33
+ expect(signature.http_status_code).to eq 200
39
34
  end
40
35
  end
41
36
 
42
37
  context "encoded :success_action_redirect with qs parameters" do
43
38
  it "should be successful" do
44
- api = _api(login: user1["login"],
45
- application_token: user1["rw_token"])
46
- expect(
47
- api.signature(
48
- :success_action_redirect => CGI.escape("http://test.com?x=y")
49
- ).http_status_code
50
- ).to eq(200)
39
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
40
+ signature = api.signature(path: './spec/support/video.mov',
41
+ success_action_redirect: CGI.escape("http://test.com?x=y"))
42
+ expect(signature.http_status_code).to eq 200
51
43
  end
52
44
  end
53
45
 
54
46
  context "with a :success_action_redirect with qs parameters" do
55
47
  it "should be successful" do
56
- api = _api(login: user1["login"],
57
- application_token: user1["rw_token"])
58
- expect(
59
- api.signature(
60
- :success_action_redirect => "http://test.com?x"
61
- ).http_status_code
62
- ).to eq(200)
48
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
49
+ signature = api.signature(path: './spec/support/video.mov',
50
+ success_action_redirect: "http://test.com?x")
51
+ expect(signature.http_status_code).to eq 200
63
52
  end
64
53
  end
65
54
  end
@@ -8,40 +8,18 @@ describe "Upload Video" do
8
8
 
9
9
  context "Authenticated User" do
10
10
  context "RW token" do
11
- describe "xml" do
12
- before(:all) do
13
- api = _api(login: user1["login"],
14
- application_token: user1["rw_token"])
11
+ before(:all) do
12
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
15
13
 
16
- title = "api-test-#{rand_str}"
17
- @res = api.upload_video(path: file_path, title: title, description: desc, profile: "boom")
14
+ title = "api-test-#{rand_str}"
15
+ @res = api.upload_video(path: file_path, title: title, description: desc, profile: "boom")
18
16
 
19
- # cleanup
20
- api.delete_video(@res.id)
21
- end
22
-
23
- specify { expect(@res.http_status_code).to eq 201 }
24
- specify { expect(@res.id.to_s).to match(/^[0-9]+$/) }
25
-
26
- after(:all) do
27
-
28
- end
17
+ # cleanup
18
+ api.delete_video(@res.id)
29
19
  end
30
20
 
31
- describe "json" do
32
- before(:all) do
33
- api = _api(login: user1["login"],
34
- application_token: user1["rw_token"])
35
-
36
- title = "api-test-#{rand_str}"
37
- @res = api.upload_video(path: file_path, title: title, description: desc, format: :json)
38
-
39
- # cleanup
40
- api.delete_video(@res["id"])
41
- end
42
-
43
- specify { expect(@res["id"].to_s).to match(/^[0-9]+$/) }
44
- end
21
+ specify { expect(@res.http_status_code).to eq 201 }
22
+ specify { expect(@res.id.to_s).to match(/^[0-9]+$/) }
45
23
  end
46
24
 
47
25
  context "RO token" do
@@ -58,16 +36,13 @@ describe "Upload Video" do
58
36
  end
59
37
  end
60
38
 
61
-
62
-
63
39
  context "Link uploads" do
64
40
  desc = "Upload Video/Link Uploads"
65
41
  file_url = "http://samples.mplayerhq.hu/MPEG-4/turn-on-off.mp4"
66
42
 
67
43
  context "Authenticated User" do
68
44
  before(:all) do
69
- api = _api(login: user1["login"],
70
- application_token: user1["rw_token"])
45
+ api = _api(login: user1["login"], application_token: user1["rw_token"])
71
46
 
72
47
  title = "api-test-#{rand_str}"
73
48
  @res = api.upload_video(url: file_url, title: title, description: desc)
@@ -39,6 +39,7 @@ module Vzaar
39
39
  end
40
40
 
41
41
  def signature(opts={})
42
+ opts.delete(:format)
42
43
  Request::Signature.new(conn, opts).execute
43
44
  end
44
45
 
@@ -51,14 +52,15 @@ module Vzaar
51
52
  end
52
53
 
53
54
  def upload_audio(opts={})
54
- uploader = Uploader.new(conn, signature, opts)
55
+ uploader = Uploader.new(conn, signature(opts), opts)
55
56
  uploader.upload do |u|
56
57
  process_audio(u.processing_params)
57
58
  end
58
59
  end
59
60
 
60
61
  def upload_video(opts={})
61
- uploader = Uploader.new(conn, signature, opts)
62
+ sig = signature(opts)
63
+ uploader = Uploader.new(conn, sig, opts)
62
64
  uploader.upload do |u|
63
65
  process_video(u.processing_params)
64
66
  end
@@ -76,12 +78,14 @@ module Vzaar
76
78
  Request::GenerateThumbnail.new(conn, opts.merge(video_id: video_id)).execute
77
79
  end
78
80
 
81
+ # TODO: remove
79
82
  def link_upload(url, opts={})
80
83
  sig = signature
81
84
  _opts = opts.merge({ guid: sig.guid, key: sig.key, url: url })
82
85
  Request::LinkUpload.new(conn, _opts).execute
83
86
  end
84
87
 
88
+ # TODO: remove
85
89
  def s3_upload(file_path)
86
90
  uploader = Uploader.new(conn, signature, path: file_path)
87
91
  uploader.upload
@@ -1,7 +1,7 @@
1
1
  module Vzaar
2
2
  module Request
3
3
  class ProcessVideo < Base
4
- endpoint '/api/videos'
4
+ endpoint '/api/v1.1/videos'
5
5
  authenticated true
6
6
  http_verb :post
7
7
  resource "ProcessedVideo"
@@ -1,15 +1,26 @@
1
1
  module Vzaar
2
2
  module Request
3
3
  class Signature < Base
4
- endpoint "/api/videos/signature"
4
+ endpoint "/api/v1.1/videos/signature"
5
5
  authenticated true
6
6
  resource :signature
7
7
 
8
8
  private
9
9
 
10
+ def ensure_valid_params!
11
+ if !options.has_key?(:path) && !options.has_key?(:url)
12
+ raise Vzaar::Error, "Path or url parameter required to generate signature."
13
+ end
14
+ end
15
+
10
16
  def url_params
11
- # JC: refactor it
12
- _params = {}
17
+ ensure_valid_params!
18
+ _params = { multipart: 'true' }
19
+
20
+ if options[:path]
21
+ _params[:filename] = File.basename(options[:path])
22
+ _params[:filesize] = File::Stat.new(options[:path]).size
23
+ end
13
24
  if options[:success_action_redirect]
14
25
  _params[:success_action_redirect] = options[:success_action_redirect]
15
26
  end
@@ -19,6 +30,7 @@ module Vzaar
19
30
  if options[:flash_request]
20
31
  _params[:flash_request] = 'yes'
21
32
  end
33
+
22
34
  super.merge(_params)
23
35
  end
24
36
  end
@@ -15,6 +15,8 @@ module Vzaar
15
15
  attribute :guid
16
16
  attribute :key
17
17
  attribute :bucket
18
+ attribute :upload_hostname
19
+ attribute :chunk_size
18
20
 
19
21
  end
20
22
  end
@@ -5,16 +5,17 @@ module Vzaar
5
5
  attr_reader :guid
6
6
 
7
7
  def upload
8
- begin
9
- if link_upload?
10
- link
11
- else
12
- success = s3.upload
13
- yield(self) if block_given? && success
8
+ if link_upload?
9
+ link
10
+ else
11
+ result = s3.upload
12
+ if result[:success]
13
+ opts[:chunks] = result[:total_chunks]
14
+ yield(self) if block_given?
14
15
  end
15
- rescue Exception => e
16
- raise(Vzaar::Error, "Upload error: " + e.message)
17
16
  end
17
+ rescue Exception => e
18
+ raise(Vzaar::Error, "Upload error: " + e.message)
18
19
  end
19
20
 
20
21
  def processing_params
@@ -4,28 +4,91 @@ module Vzaar
4
4
  SEND_TIMEOUT = 1800
5
5
 
6
6
  def upload
7
- client = HTTPClient.new
8
- client.send_timeout = SEND_TIMEOUT
9
- begin
10
- file = File.open(path)
11
- res = client.post url, [
12
- ['acl', signature.acl],
13
- ['bucket', signature.bucket],
14
- ['success_action_status', '201'],
15
- ['policy', signature.policy],
16
- ['AWSAccessKeyId', signature.access_key_id],
17
- ['signature', signature.signature],
18
- ['key', signature.key],
19
- ['file', file]
20
- ]
21
- ensure
22
- file.close if file
7
+ if signature.chunk_size.to_s.empty?
8
+ single_part_upload
9
+ else
10
+ multipart_upload
11
+ end
12
+ end
13
+
14
+ class VirtualFile < StringIO
15
+ attr_reader :path
16
+ def initialize(file, chunk_size)
17
+ @path = File.basename file.path
18
+ super file.read(chunk_size)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def single_part_upload
25
+ File.open(path, "r") do |file|
26
+ _headers = headers.dup
27
+ _headers['chunk'] = '0'
28
+ _headers['chunks'] = '0'
29
+ _headers['key'] = signature.key
30
+ _headers['file'] = file
31
+ res = http_client.post url, _headers
32
+ { success: res.status_code == 201 }
33
+ end
34
+ end
35
+
36
+ def file_size
37
+ @file_size ||= File.stat(path).size
38
+ end
39
+
40
+ def chunk_size_bytes
41
+ @chunk_size_bytes ||= signature.chunk_size.to_i * (1024 ** 2)
42
+ end
43
+
44
+ def total_chunks
45
+ @total_chunks ||= begin
46
+ val = file_size / chunk_size_bytes
47
+ val += 1 if (file_size % chunk_size_bytes) > 0
48
+ val
49
+ end
50
+ end
51
+
52
+ def multipart_upload
53
+ _headers = headers.dup
54
+ _headers['chunks'] = total_chunks
55
+
56
+ chunk = 0
57
+ File.open(path, "r") do |file|
58
+ until file.eof?
59
+ _headers['chunk'] = chunk
60
+ _headers['key'] = "#{signature.key}.#{chunk}"
61
+ _headers['file'] = VirtualFile.new(file, chunk_size_bytes)
62
+
63
+ res = http_client.post url, _headers
64
+ unless res.status_code == 201
65
+ return { success: false }
66
+ end
67
+ chunk += 1
68
+ end
69
+ end
70
+ { success: true, total_chunks: total_chunks }
71
+ end
72
+
73
+ def headers
74
+ @headers ||= {
75
+ 'acl' => signature.acl,
76
+ 'bucket' => signature.bucket,
77
+ 'success_action_status' => '201',
78
+ 'policy' => signature.policy,
79
+ 'AWSAccessKeyId' => signature.access_key_id,
80
+ 'signature' => signature.signature
81
+ }
82
+ end
83
+
84
+ def http_client
85
+ @http_client ||= begin
86
+ HTTPClient.new.tap { |c| c.send_timeout = SEND_TIMEOUT }
23
87
  end
24
- res.status_code == 201
25
88
  end
26
89
 
27
90
  def url
28
- "https://#{signature.bucket}.s3.amazonaws.com/"
91
+ signature.upload_hostname
29
92
  end
30
93
  end
31
94
  end