telestream_cloud 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5dc2f13d4e17fe9964e6e290c5ceac66423355b3
4
- data.tar.gz: 0fde90a8a2260b9e942315ab7396ccb7296bd8e9
3
+ metadata.gz: bcd0c04f728a476514ec1af7312b4d3e27babfde
4
+ data.tar.gz: 253b327eea8a868994a8819b8bbd4b816061b182
5
5
  SHA512:
6
- metadata.gz: a5a925523a87ec792fcd7ea053b460417acca47162439608af56bd433cc49711af782880c17a66254e70383851b4a3dfbefbd22b45b043831ced59b234169a1d
7
- data.tar.gz: ecd712a9a7c57afdf4f648545e24549cc486af3eece50a8ca77fb13eeefe68acca28a7fd1c12618c6dd5992f150560e22d0a5444f4bee85517b9d6a3ed16baf8
6
+ metadata.gz: b71fa00a53c0b687bad6ae0ec2ce23b56a7ce8ef510211688985684321827f089cd76352c372b86a841a7999d57889c9f8479e71fae6e336b3a106eae46959aa
7
+ data.tar.gz: 1b0d873ec086449daa6057faf2b3b805b32bfa8c708fd76c08237718673db1cfd568b4074c201df123b283cd77dd91ec62106d3f6e8c6741652af294211293cd
data/README.md CHANGED
@@ -17,17 +17,17 @@ TelestreamCloud gem provides an interface to access the [TelestreamCloud](http:/
17
17
  You can just set the default Panda adapter if you are not happy with the current one.
18
18
 
19
19
  TelestreamCloud.default_adapter = :excon
20
-
20
+
21
21
  For rails 4, try the net_http adapter. This fixes disable_ssl_peer_verification related errors caused by the default adapter.
22
-
22
+
23
23
  TelestreamCloud.default_adapter = :net_http
24
-
24
+
25
25
  ### Creating an instance of the client
26
26
  ```ruby
27
27
  TelestreamCloud.configure do
28
28
  access_key "your_access_key"
29
29
  secret_key "your_secret_key"
30
- # api_host "api.cloud.telestream.net" # this will be set bu default
30
+ # api_host "api.cloud.telestream.net" # this will be set by default
31
31
  end
32
32
  ```
33
33
  or
@@ -80,7 +80,7 @@ end
80
80
 
81
81
  # Accessing specific Factory
82
82
  f1 = flip.factories.all[0]
83
- # or
83
+ # or
84
84
  f2 = flip.factories.find('factory_id')
85
85
  ```
86
86
 
@@ -93,7 +93,7 @@ videos.first.id
93
93
  => "abcde"
94
94
 
95
95
  videos = factory.videos.all(:page => 2, :per_page => 20)
96
- # or
96
+ # or
97
97
  videos = factory.videos.page(1).per_page(20)
98
98
  videos.size
99
99
  => 20
@@ -135,6 +135,35 @@ video.delete
135
135
  => true
136
136
  ```
137
137
 
138
+ ### Parallel and fail-safe upload
139
+
140
+ ```ruby
141
+ # Create video using parallel uploader
142
+
143
+ video = TelestreamCloud::ParallelUploader.upload(
144
+ file: File.new('movie.mp4'),
145
+ concurrency: 8,
146
+ profiles: 'webm'
147
+ )
148
+
149
+ # Create video using standard uploader
150
+ video = TelestreamCloud::Uploader.upload(
151
+ file: File.new("/path/to/my/movie.mp4"),
152
+ profiles: "h264,webm",
153
+ retries: 3
154
+ )
155
+
156
+ # You can also upload video manually
157
+ uploader = TelestreamCloud::Uploader.new(
158
+ file: File.new("/path/to/my/movie.mp4"),
159
+ profiles: "h264,webm",
160
+ )
161
+
162
+ uploader.upload(3)
163
+ uploader.status # => :success
164
+ video = uploader.video
165
+ ```
166
+
138
167
  ### Encodings
139
168
 
140
169
  ```ruby
@@ -176,7 +205,7 @@ encoding.screenshots[0]
176
205
 
177
206
  # Create new encoding for a video that already exists
178
207
  encoding = factory.encodings.create(:video_id => 1234, :profile_id => 6789)
179
- # or
208
+ # or
180
209
  video.encodings.create(:profile_id => 6789)
181
210
 
182
211
  # Delete encoding
@@ -303,12 +332,12 @@ TelestreamCloud.get('/videos.json')
303
332
  "status"=>"success",
304
333
  "width"=>300}]
305
334
 
306
- # Getting video encodings
335
+ # Getting video encodings
307
336
  TelestreamCloud.get('/videos/0ee6b656-0063-11df-a433-1231390041c1/encodings.json')
308
337
  => [{"encoder_id"=>nil,
309
338
  "created_at"=>"2010/01/13 16:45:30 +0000",
310
339
  "video_id"=>"0ee6b656-0063-11df-a433-1231390041c1",
311
- "video_url"=>
340
+ "video_url"=>
312
341
  "http://s3.amazonaws.com/panda-videos/0f815986-0063-11df-a433-1231390041c1.flv",
313
342
  "started_encoding_at"=>"2010/01/13 16:47:35 +0000",
314
343
  "updated_at"=>"2010/01/13 16:47:40 +0000",
@@ -333,25 +362,5 @@ bundler install
333
362
  rake spec
334
363
  ```
335
364
 
336
- ### Resumable upload
337
- ```ruby
338
- us = TelestreamCloud::UploadSession.new("movie.mp4", profiles: "webm")
339
-
340
- retry_count = 0
341
- begin
342
- us.start()
343
- rescue Exception => e
344
- while retru_count < 5 and us.status != "success"
345
- begin
346
- sleep(5)
347
- us.resume()
348
- rescue Exception => e
349
- retry_count += 1
350
- end
351
- end
352
- end
353
- ```
354
-
355
-
356
365
 
357
366
  Copyright (c) 2016 Telestream Cloud. See LICENSE for details.
@@ -27,4 +27,6 @@ require 'telestream_cloud/flip'
27
27
  require 'telestream_cloud/telestream_cloud'
28
28
  require 'telestream_cloud/faraday'
29
29
  require 'telestream_cloud/upload_session'
30
-
30
+ require 'telestream_cloud/uploader'
31
+ require 'telestream_cloud/uploader/file_reader'
32
+ require 'telestream_cloud/parallel_uploader'
@@ -0,0 +1,52 @@
1
+ module TelestreamCloud
2
+ class ParallelUploader < Uploader
3
+ class ThreadPool
4
+ attr_reader :queue, :size, :worker
5
+
6
+ def initialize(size, &block)
7
+ @size = size
8
+ @queue = Queue.new
9
+ @worker = block
10
+ end
11
+
12
+ def <<(*args)
13
+ queue.push(args)
14
+ end
15
+
16
+ def join
17
+ size.times.map do
18
+ Thread.new(queue) do
19
+ begin
20
+ while args = queue.pop(true)
21
+ worker.call(*args)
22
+ end
23
+ rescue ThreadError
24
+ end
25
+ end
26
+ end.map(&:join)
27
+ end
28
+ end
29
+
30
+ attr_reader :concurrency
31
+
32
+ def initialize(options)
33
+ @concurrency = options.delete(:concurrency)
34
+ super
35
+ end
36
+
37
+ private
38
+
39
+ def upload_chunks(ids)
40
+ ids.each { |i| thread_pool << i }
41
+ thread_pool.join
42
+ end
43
+
44
+ def concurrency
45
+ [@concurrency || max_connections, max_connections].min
46
+ end
47
+
48
+ def thread_pool
49
+ @thread_pool ||= ThreadPool.new(concurrency, &method(:send_chunk))
50
+ end
51
+ end
52
+ end
@@ -1,102 +1,40 @@
1
- CHUNK_SIZE = 100 * 1024 # 5 * 1024 * 1024
1
+ module TelestreamCloud
2
+ class UploadSession
3
+ attr_reader :uploader
2
4
 
3
- class File
4
- def each_chunk_with_index()
5
- i = 0
6
- until eof?
7
- yield(read(CHUNK_SIZE), i)
8
- i = i+1
5
+ def initialize(file_name, options = {})
6
+ @uploader = Uploader.new(options.merge(file: File.new(file_name)))
9
7
  end
10
- end
11
- end
12
8
 
13
- module TelestreamCloud
14
- class UploadSession
15
- attr_reader :location, :status, :video, :error_message, :file_name, :file_size
9
+ def error_message
10
+ uploader.error && uploader.error.message
11
+ end
12
+
13
+ def start(_ = nil)
14
+ uploader.upload
15
+ end
16
16
 
17
- def initialize(file_name, options={})
18
- @file_name = file_name
19
- @file_size = File.size(file_name)
20
- params = {
21
- :file_size => @file_size,
22
- :file_name => @file_name,
23
- }.merge(options)
17
+ def status
18
+ uploader.status.to_s
19
+ end
20
+
21
+ def resume
22
+ start
23
+ end
24
24
 
25
- data = TelestreamCloud.post("/videos/upload.json", params)
26
- @location = URI.parse(data["location"])
27
- @status = "initialized"
28
- @video = nil
29
- @error_message = nil
25
+ def video
26
+ uploader.video
30
27
  end
31
28
 
32
- def start(pos=0)
33
- if @status == "initialized"
34
- @status = "uploading"
35
- open(@file_name, "rb") do |f|
36
- f.seek(pos)
37
- f.each_chunk_with_index() { |chunk, i|
38
- begin
39
- index = i * CHUNK_SIZE
40
- uri = URI.parse(URI.encode(@location.to_s))
41
- https = Net::HTTP.new(uri.host, uri.port)
42
- https.use_ssl = true
43
-
44
- request = Net::HTTP::Post.new(uri.request_uri, initheader = {
45
- 'Content-Type' =>'application/octet-stream',
46
- 'Cache-Control' => 'no-cache',
47
- 'Content-Range' => "bytes #{pos+index}-#{pos+index+CHUNK_SIZE-1}/#{@file_size}",
48
- 'Content-Length' => "#{CHUNK_SIZE}"
49
- })
50
- request.body = chunk
51
-
52
- response = https.request(request)
53
- if response.code == '200'
54
- @status = "uploaded"
55
- @video = TelestreamCloud::Video.new(JSON.parse(response.body))
56
- elsif response.code != '204'
57
- @statys = "error"
58
- break
59
- end
60
- rescue Exception => e
61
- @status = "error"
62
- @error_mesage = e.message
63
- raise e
64
- end
65
- }
66
- end
67
- else
68
- raise "Already started"
69
- end
29
+ def file_name
30
+ uploader.reader.name
70
31
  end
71
32
 
72
- def resume()
73
- if @status != "uploaded"
74
- uri = URI.parse(URI.encode(@location.to_s))
75
- https = Net::HTTP.new(uri.host, uri.port)
76
- https.use_ssl = true
77
-
78
- request = Net::HTTP::Post.new(uri.request_uri, initheader = {
79
- 'Content-Type' =>'application/octet-stream',
80
- 'Cache-Control' => 'no-cache',
81
- 'Content-Range' => "bytes */#{@file_size}",
82
- 'Content-Length' => "0"
83
- })
84
- response = https.request(request)
85
- pos = response["Range"].split("-")[1]
86
- @status = "initialized"
87
- self.start(pos.to_i)
88
- else
89
- raise ("Already succeed")
90
- end
33
+ def file_size
34
+ uploader.reader.size
91
35
  end
92
36
 
93
- def abort()
94
- if @status != "success"
95
- @status = "aborted"
96
- @error_message = nil
97
- else
98
- raise "Already succeed"
99
- end
37
+ def abort
100
38
  end
101
39
  end
102
40
  end
@@ -0,0 +1,123 @@
1
+ require 'pathname'
2
+ require 'json'
3
+
4
+ module TelestreamCloud
5
+ class Uploader
6
+ class UploadError < StandardError; end
7
+ class MissingPartError < StandardError; end
8
+
9
+ attr_reader :reader, :video, :status, :error
10
+
11
+ def self.upload(options)
12
+ retries = options.delete(:retries)
13
+ new(options).tap { |x| x.upload(*[retries].compact) }.video
14
+ end
15
+
16
+ def initialize(options)
17
+ file = options.delete(:file) { |key| fail KeyError, "key not found: #{key}" }
18
+
19
+ @reader = FileReader.new(file)
20
+
21
+ defaults = {
22
+ file_size: reader.size,
23
+ file_name: reader.name,
24
+ multi_chunk: true
25
+ }
26
+
27
+ @params = defaults.merge(options)
28
+ @status = :ready
29
+ end
30
+
31
+ def upload(retries = 5)
32
+ count = 0
33
+ begin
34
+ count += 1
35
+ upload!
36
+ fail MissingPartError unless success?
37
+ rescue => e
38
+ @error = e
39
+ retry if count < retries
40
+ self.status = :failed
41
+ end
42
+
43
+ success?
44
+ end
45
+
46
+ def success?
47
+ status == :success
48
+ end
49
+
50
+ private
51
+
52
+ def upload!
53
+ self.status = :uploading
54
+ upload_chunks(missing_parts)
55
+ end
56
+
57
+ def upload_chunks(ids)
58
+ ids.each(&method(:send_chunk))
59
+ end
60
+
61
+ def missing_parts
62
+ return (0...parts).to_a unless @session
63
+ upload_status['missing_parts']
64
+ end
65
+
66
+ def send_chunk(index)
67
+ range = (index * part_size...[(index + 1) * part_size, reader.size].min)
68
+
69
+ # TODO: remove when 1.9 dropped
70
+ unless range.respond_to?(:size)
71
+ def range.size; self.end - self.begin + (exclude_end? ? 0 : 1); end
72
+ end
73
+
74
+ response = http.put do |request|
75
+ request.headers['Content-Type'] = 'application/octet-stream'
76
+ request.headers['X-Part'] = "#{index}"
77
+ request.headers['Content-Length'] = "#{range.size}"
78
+ request.body = reader[range]
79
+ end
80
+
81
+ set_video(response)
82
+ response
83
+ end
84
+
85
+ def set_video(response)
86
+ return if response.status != 200 || response.body.empty?
87
+ @video = Video.new(JSON.parse(response.body))
88
+ self.status = :success
89
+ end
90
+
91
+ def status=(status)
92
+ @status = status
93
+ @error = nil if success?
94
+ @status
95
+ end
96
+
97
+ def http
98
+ @http ||= ::Faraday.new(url: URI(session['location'])) do |builder|
99
+ builder.request :multipart
100
+ builder.request :url_encoded
101
+ builder.adapter TelestreamCloud.default_adapter
102
+ end
103
+ end
104
+
105
+ def upload_status
106
+ JSON.parse(http.get.body)
107
+ end
108
+
109
+ def parts; session['parts'].to_i; end
110
+ def part_size; session['part_size'].to_i; end
111
+ def max_connections; session['max_connections'].to_i; end
112
+
113
+ def session
114
+ @session ||= TelestreamCloud.post('/videos/upload.json', @params)
115
+
116
+ if !@session || @session['error']
117
+ fail UploadError, @session && @session.values_at('error', 'message')
118
+ end
119
+
120
+ @session
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,27 @@
1
+ module TelestreamCloud
2
+ class Uploader
3
+ class FileReader
4
+ attr_reader :file
5
+
6
+ def initialize(file)
7
+ @file = file
8
+ @mutex = Mutex.new
9
+ end
10
+
11
+ def [](range)
12
+ @mutex.synchronize do
13
+ file.seek(range.begin)
14
+ file.read(range.size)
15
+ end
16
+ end
17
+
18
+ def size
19
+ @size ||= file.size
20
+ end
21
+
22
+ def name
23
+ Pathname.new(file.path).basename
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module TelestreamCloud
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,143 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ shared_examples_for "uploader" do
4
+ let(:file_size) { 45_000_000 }
5
+ let(:file) do
6
+ double(:file,
7
+ path: '/foo/bar.mp4',
8
+ size: file_size
9
+ )
10
+ end
11
+
12
+ before(:each) do
13
+ TelestreamCloud.configure do
14
+ access_key "my_access_key"
15
+ secret_key "my_secret_key"
16
+ api_host "api.example.com"
17
+ factory_id 'my_cloud_id'
18
+ api_port 85
19
+ end
20
+ end
21
+
22
+ describe '#upload' do
23
+ let(:part_size) { 10_000_000 }
24
+ let(:session_url) { 'http://api.example.com:1234/upload/session?id=1234' }
25
+
26
+ let(:video_json) do
27
+ "{\"id\":\"12345\"}"
28
+ end
29
+
30
+ context 'with valid session' do
31
+ let(:session_json) do
32
+ "{\"id\":\"1234\",\"location\":\"#{session_url}\",\"parts\":\"5\",\"part_size\":\"#{part_size}\",\"max_connections\":\"16\"}"
33
+ end
34
+
35
+ before do
36
+ stub_request(:post, "http://api.example.com:85/v3.0/videos/upload.json")
37
+ .to_return(body: session_json)
38
+
39
+ expect(file).to receive(:read).with(part_size).and_return("chunk").exactly(4).times
40
+ expect(file).to receive(:read).with(file_size % part_size).and_return("chunk").once
41
+
42
+ 5.times do |i|
43
+ expect(file).to receive(:seek).with(i * part_size)
44
+ end
45
+ end
46
+
47
+ it 'uploads file' do
48
+ stub_request(:put, session_url).with(headers: { "X-Part" => /[0-3]/ })
49
+
50
+ stub_request(:put, session_url)
51
+ .with(headers: { "X-Part" => 4 }, body: "chunk")
52
+ .to_return(body: "{\"id\":\"12345\"}")
53
+
54
+
55
+ subject.upload
56
+ expect(subject).to be_success
57
+ expect(subject.video).not_to be_nil
58
+ expect(subject.video.id).to eq("12345")
59
+ end
60
+
61
+ it 'retries missing chunks' do
62
+ stub_request(:put, session_url)
63
+ stub_request(:put, session_url).with(headers: { "X-Part" => 3 })
64
+ .to_return({body: ""}).then.to_return({body: video_json})
65
+
66
+ stub_request(:get, session_url).to_return(body: JSON.generate(missing_parts: [3]))
67
+
68
+ expect(file).to receive(:read).with(part_size).and_return("chunk")
69
+ expect(file).to receive(:seek).with(3 * part_size)
70
+
71
+ subject.upload
72
+
73
+ expect(subject).to be_success
74
+ expect(subject.video).not_to be_nil
75
+ expect(subject.video.id).to eq("12345")
76
+ end
77
+
78
+ it 'fails after few tries' do
79
+ stub_request(:put, session_url)
80
+ stub_request(:get, session_url).to_return(body: JSON.generate(missing_parts: [3]))
81
+
82
+ expect(file).to receive(:read).with(part_size).and_return("chunk").exactly(4).times
83
+ expect(file).to receive(:seek).with(3 * part_size).exactly(4).times
84
+
85
+ subject.upload
86
+
87
+ expect(subject.status).to eq(:failed)
88
+ expect(subject.video).to be_nil
89
+ expect(subject.error).to be_a(TelestreamCloud::Uploader::MissingPartError)
90
+ end
91
+ end
92
+
93
+ context 'with invalid session' do
94
+ let(:session_json) do
95
+ "{\"error\":\"NotAuthorized\",\"message\":\"Message\"}"
96
+ end
97
+
98
+ it 'fails' do
99
+ stub_request(:post, "http://api.example.com:85/v3.0/videos/upload.json")
100
+ .to_return(body: session_json)
101
+
102
+ subject.upload
103
+
104
+ expect(subject.status).to eq(:failed)
105
+ expect(subject.error).to be_a(TelestreamCloud::Uploader::UploadError)
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '.upload' do
111
+ it 'calls #upload' do
112
+ video = double(:video)
113
+ expect_any_instance_of(subject.class).to receive(:upload)
114
+ expect_any_instance_of(subject.class).to receive(:video).and_return(video)
115
+
116
+ expect(subject.class.upload(file: file)).to eq(video)
117
+ end
118
+
119
+ it 'calls #upload with retries options' do
120
+ video = double(:video)
121
+ expect_any_instance_of(subject.class).to receive(:upload).with(5)
122
+ expect_any_instance_of(subject.class).to receive(:video).and_return(video)
123
+
124
+ expect(subject.class.upload(file: file, retries: 5)).to eq(video)
125
+ end
126
+ end
127
+ end
128
+
129
+ describe TelestreamCloud::Uploader do
130
+ subject do
131
+ TelestreamCloud::Uploader.new(file: file)
132
+ end
133
+
134
+ it_behaves_like "uploader"
135
+ end
136
+
137
+ describe TelestreamCloud::ParallelUploader do
138
+ subject do
139
+ TelestreamCloud::ParallelUploader.new(file: file)
140
+ end
141
+
142
+ it_behaves_like "uploader"
143
+ end
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Telestream Cloud"]
10
10
  s.email = ["cloudsupport@telestream.net"]
11
- s.homepage = "http://github.com/pandastream/panda_gem"
11
+ s.homepage = "https://github.com/Telestream/telestream-cloud-ruby-sdk"
12
12
  s.summary = %q{Telestream Cloud Client}
13
13
  s.description = %q{Telestream Cloud Client}
14
14
 
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_development_dependency "timecop"
21
21
  s.add_development_dependency "rspec", ">= 2.8.0"
22
22
  s.add_development_dependency "webmock", ">= 1.8.2"
23
-
23
+
24
24
  s.rubyforge_project = "telestream_cloud"
25
25
 
26
26
  s.files = `git ls-files`.split("\n")
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: telestream_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Telestream Cloud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-29 00:00:00.000000000 Z
11
+ date: 2016-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-hmac
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.3.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: faraday
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.7.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.7.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: multi_json
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.2.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.2.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: timecop
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: 2.8.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: 2.8.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: webmock
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: 1.8.2
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 1.8.2
111
111
  description: Telestream Cloud Client
@@ -115,8 +115,8 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
- - .gitignore
119
- - .rspec
118
+ - ".gitignore"
119
+ - ".rspec"
120
120
  - Gemfile
121
121
  - LICENSE
122
122
  - README.md
@@ -137,6 +137,7 @@ files:
137
137
  - lib/telestream_cloud/modules/router.rb
138
138
  - lib/telestream_cloud/modules/updatable.rb
139
139
  - lib/telestream_cloud/modules/video_state.rb
140
+ - lib/telestream_cloud/parallel_uploader.rb
140
141
  - lib/telestream_cloud/proxies/encoding_scope.rb
141
142
  - lib/telestream_cloud/proxies/profile_scope.rb
142
143
  - lib/telestream_cloud/proxies/proxy.rb
@@ -149,6 +150,8 @@ files:
149
150
  - lib/telestream_cloud/resources/video.rb
150
151
  - lib/telestream_cloud/telestream_cloud.rb
151
152
  - lib/telestream_cloud/upload_session.rb
153
+ - lib/telestream_cloud/uploader.rb
154
+ - lib/telestream_cloud/uploader/file_reader.rb
152
155
  - lib/telestream_cloud/version.rb
153
156
  - spec/cloud_spec.rb
154
157
  - spec/encoding_spec.rb
@@ -156,9 +159,10 @@ files:
156
159
  - spec/panda_spec.rb
157
160
  - spec/profile_spec.rb
158
161
  - spec/spec_helper.rb
162
+ - spec/uploader_spec.rb
159
163
  - spec/video_spec.rb
160
164
  - telestream_cloud.gemspec
161
- homepage: http://github.com/pandastream/panda_gem
165
+ homepage: https://github.com/Telestream/telestream-cloud-ruby-sdk
162
166
  licenses: []
163
167
  metadata: {}
164
168
  post_install_message:
@@ -167,17 +171,17 @@ require_paths:
167
171
  - lib
168
172
  required_ruby_version: !ruby/object:Gem::Requirement
169
173
  requirements:
170
- - - '>='
174
+ - - ">="
171
175
  - !ruby/object:Gem::Version
172
176
  version: '0'
173
177
  required_rubygems_version: !ruby/object:Gem::Requirement
174
178
  requirements:
175
- - - '>='
179
+ - - ">="
176
180
  - !ruby/object:Gem::Version
177
181
  version: '0'
178
182
  requirements: []
179
183
  rubyforge_project: telestream_cloud
180
- rubygems_version: 2.0.14
184
+ rubygems_version: 2.5.1
181
185
  signing_key:
182
186
  specification_version: 4
183
187
  summary: Telestream Cloud Client
@@ -188,4 +192,5 @@ test_files:
188
192
  - spec/panda_spec.rb
189
193
  - spec/profile_spec.rb
190
194
  - spec/spec_helper.rb
195
+ - spec/uploader_spec.rb
191
196
  - spec/video_spec.rb