s3_streamer 0.1.1 → 0.2.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: 158368a84fcdfe9ac40904f3a922b4da9b4ccae2
4
- data.tar.gz: 4d659a39ebde78e65b0b878a0def086789a43299
3
+ metadata.gz: 08b8b13f35734bff5cbdcb9a4cf1ba0770b0671d
4
+ data.tar.gz: 570918eb21651ecd7a1bd3545395c1eccd1691db
5
5
  SHA512:
6
- metadata.gz: 5bcec56c4f9cd00f6873c086fd8b12f5a6e59b511b927b20de747129ebab426c644b8002e23a39634213bb007ac0b28a2d370652be242696c40775738749b58a
7
- data.tar.gz: ff0fb774181964ac67cefc507c32c9ba4213751d5267674cfdd53d5eb270b9aaca26a6b5fc790594a6720f61867b5a468f42f1333b468c12ebedc67dca779836
6
+ metadata.gz: 8a7cfe74390bd782a5f5b7af9e440b8260dc7a8c215d1e1a9fcb573ecc42ea466a1d4ff35976181b4f7e8b3bcbb11238f62754c811ad0fb74bb43e6a6e317083
7
+ data.tar.gz: 6bc5a341149f6d92ddce682fd5904f9a19260bdb901a166390a28d8d7f79995914d87c8af27f1c30726269750b1bd1361fbf595cbf7b7210eac3958f4e724d81
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.org/thilonel/s3_streamer.svg?branch=master)](https://travis-ci.org/thilonel/s3_streamer)
2
+
1
3
  # S3 Streamer
2
4
 
3
5
  Stream a file from a remote url using the Ruby AWS SDK to an Amazon S3 bucket.
@@ -0,0 +1,35 @@
1
+ module S3Streamer
2
+ class BufferedWriter
3
+ attr_reader :options, :buffer
4
+
5
+ def initialize(options, &block)
6
+ @options = options
7
+ @block = block
8
+ clear
9
+ end
10
+
11
+ def push(chunk)
12
+ @buffer << chunk
13
+ write if @buffer.size > min_part_size
14
+ end
15
+
16
+ def finish
17
+ write if @buffer.size > 0
18
+ end
19
+
20
+ private
21
+
22
+ def write
23
+ @block.call buffer
24
+ clear
25
+ end
26
+
27
+ def min_part_size
28
+ options[:min_part_size] || 1024
29
+ end
30
+
31
+ def clear
32
+ @buffer = ""
33
+ end
34
+ end
35
+ end
@@ -1,18 +1,20 @@
1
1
  require 'aws-sdk'
2
2
 
3
- require 's3_streamer/client/downstream'
4
- require 's3_streamer/client/upstream'
3
+ require 's3_streamer/downstream'
4
+ require 's3_streamer/upstream'
5
5
 
6
6
  module S3Streamer
7
7
  class Client
8
+ attr_reader :client
9
+
8
10
  def initialize(options)
9
11
  @client = Aws::S3::Client.new(options)
10
12
  end
11
13
 
12
- def stream(source_uri, bucket, destination_file)
13
- upstream = Upstream.new @client, bucket, destination_file
14
+ def stream(source_uri, bucket, destination_file, options={})
15
+ upstream = Upstream.new client, bucket, destination_file
14
16
 
15
- Downstream.new(URI(source_uri)).each do |chunk|
17
+ Downstream.new(URI(source_uri), options).each do |chunk|
16
18
  upstream.upload chunk
17
19
  end
18
20
 
@@ -0,0 +1,33 @@
1
+ require 'net/http'
2
+ require 's3_streamer/buffered_writer'
3
+
4
+ module S3Streamer
5
+ class Downstream
6
+ DEFAULT_PART_SIZE = 10 * 1024 * 1024
7
+
8
+ def initialize(uri, options={})
9
+ @uri = uri
10
+ @options = options
11
+ end
12
+
13
+ def each
14
+ Net::HTTP.start(@uri.host) do |http|
15
+ http.request(Net::HTTP::Get.new @uri) do |response|
16
+ buffer = BufferedWriter.new(min_part_size: part_size) do |part|
17
+ yield part
18
+ end
19
+
20
+ response.read_body { |chunk| buffer.push chunk }
21
+
22
+ buffer.finish
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def part_size
30
+ @options[:part_size] || DEFAULT_PART_SIZE
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,37 @@
1
+ module S3Streamer
2
+ class Upstream
3
+ def initialize(client, bucket, destination_file)
4
+ @client = client
5
+ @bucket = bucket
6
+ @destination_file = destination_file
7
+ @parts = []
8
+ @part_number = 1
9
+ @upload_id = create
10
+ end
11
+
12
+ def upload(chunk)
13
+ uploaded_part = @client.upload_part(body: chunk,
14
+ bucket: @bucket,
15
+ key: @destination_file,
16
+ part_number: @part_number,
17
+ upload_id: @upload_id)
18
+
19
+ @parts << {etag: uploaded_part.etag, part_number: @part_number}
20
+
21
+ @part_number += 1
22
+ end
23
+
24
+ def complete
25
+ @client.complete_multipart_upload(bucket: @bucket,
26
+ key: @destination_file,
27
+ upload_id: @upload_id,
28
+ multipart_upload: {parts: @parts})
29
+ end
30
+
31
+ private
32
+
33
+ def create
34
+ @client.create_multipart_upload(bucket: @bucket, key: @destination_file).upload_id
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  module S3Streamer
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_streamer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thilonel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-02 00:00:00.000000000 Z
11
+ date: 2016-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -99,10 +99,10 @@ files:
99
99
  - bin/console
100
100
  - bin/setup
101
101
  - lib/s3_streamer.rb
102
+ - lib/s3_streamer/buffered_writer.rb
102
103
  - lib/s3_streamer/client.rb
103
- - lib/s3_streamer/client/downstream.rb
104
- - lib/s3_streamer/client/downstream/chunk_buffer.rb
105
- - lib/s3_streamer/client/upstream.rb
104
+ - lib/s3_streamer/downstream.rb
105
+ - lib/s3_streamer/upstream.rb
106
106
  - lib/s3_streamer/version.rb
107
107
  - s3_streamer.gemspec
108
108
  homepage: https://github.com/thilonel/s3_streamer
@@ -1,18 +0,0 @@
1
- class ChunkBuffer
2
- def initialize(response, chunks_per_buffer = 10240)
3
- @response = response
4
- @chunks_per_buffer = chunks_per_buffer
5
- end
6
-
7
- def each
8
- buffer = []
9
- @response.read_body do |chunk|
10
- buffer << chunk
11
- if buffer.size >= @chunks_per_buffer
12
- yield buffer.join
13
- buffer = []
14
- end
15
- end
16
- yield buffer.join if buffer.size > 0
17
- end
18
- end
@@ -1,18 +0,0 @@
1
- require 'net/http'
2
- require_relative 'downstream/chunk_buffer'
3
-
4
- class Downstream
5
- def initialize(uri)
6
- @uri = uri
7
- end
8
-
9
- def each
10
- Net::HTTP.start(@uri.host) do |http|
11
- http.request(Net::HTTP::Get.new @uri) do |response|
12
- ChunkBuffer.new(response).each do |chunk|
13
- yield chunk
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,35 +0,0 @@
1
- class Upstream
2
- def initialize(client, bucket, destination_file)
3
- @client = client
4
- @bucket = bucket
5
- @destination_file = destination_file
6
- @parts = []
7
- @part_number = 1
8
- @upload_id = create
9
- end
10
-
11
- def upload(chunk)
12
- uploaded_part = @client.upload_part(body: chunk,
13
- bucket: @bucket,
14
- key: @destination_file,
15
- part_number: @part_number,
16
- upload_id: @upload_id)
17
-
18
- @parts << {etag: uploaded_part.etag, part_number: @part_number}
19
-
20
- @part_number += 1
21
- end
22
-
23
- def complete
24
- @client.complete_multipart_upload(bucket: @bucket,
25
- key: @destination_file,
26
- upload_id: @upload_id,
27
- multipart_upload: {parts: @parts})
28
- end
29
-
30
- private
31
-
32
- def create
33
- @client.create_multipart_upload(bucket: @bucket, key: @destination_file).upload_id
34
- end
35
- end