s3_multi_upload 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/s3_multi_upload +26 -0
  2. data/lib/s3_multi_upload.rb +87 -0
  3. metadata +82 -0
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join File.dirname(__FILE__), *%w[.. lib]
3
+ %w[thor s3_multi_upload].each {|l| require l}
4
+
5
+ module S3_Multi_Upload
6
+ class Task < Thor
7
+
8
+ desc 'upload', 'upload a file to s3 in parallel'
9
+ method_option :access_key_id, :required => true
10
+ method_option :secret_access_key, :required => true
11
+ method_option :bucket, :required => true
12
+ method_option :file, :required => true
13
+ method_option :threads, :required => true, :type => :numeric, :default => 5
14
+ method_option :chunk_size, :required => true, :type => :hash, :default => {10 => :mb}
15
+ method_option :progress_bar, :type => :boolean, :default => true
16
+ method_option :key, :desc => 's3 object key (default: file name)'
17
+
18
+ def upload
19
+ Upload.new(options).process
20
+ end
21
+
22
+ default_task :upload
23
+ end
24
+ end
25
+
26
+ S3_Multi_Upload::Task.start
@@ -0,0 +1,87 @@
1
+ require 'pathname'
2
+ require 'aws-sdk'
3
+ require 'progressbar'
4
+
5
+ module S3_Multi_Upload
6
+ class Upload
7
+ attr_accessor :options, :file, :s3, :bucket, :object, :progress
8
+
9
+ def initialize options
10
+
11
+ AWS.config :access_key_id => options[:access_key_id],
12
+ :secret_access_key => options[:secret_access_key]
13
+
14
+ @options = options
15
+ @file = Pathname.new options[:file]
16
+
17
+ @s3 = AWS::S3.new
18
+ @bucket = @s3.buckets.create options[:bucket]
19
+ @object = @bucket.objects[options[:key] || @file.basename]
20
+
21
+ enqueue
22
+ end
23
+
24
+ def normalize value, unit = nil
25
+ case unit.to_sym.downcase
26
+ when nil, :b, :byte, :bytes
27
+ value.to_f
28
+ when :k, :kb, :kilobyte, :kilobytes
29
+ value.to_f * 1024
30
+ when :m, :mb, :megabyte, :megabytes
31
+ value.to_f * 1024 ** 2
32
+ when :g, :gb, :gigabyte, :gigabytes
33
+ value.to_f * 1024 ** 3
34
+ end
35
+ end
36
+
37
+ def chunk_size
38
+ normalize *options[:chunk_size].first
39
+ end
40
+
41
+ def queue
42
+ @queue ||= Queue.new
43
+ end
44
+
45
+ def enqueue
46
+ (file.size.to_f / chunk_size).ceil.times do |index|
47
+ queue << [chunk_size * index, index + 1]
48
+ end
49
+ end
50
+
51
+ def upload
52
+ object.multipart_upload do |upload|
53
+ threads = []
54
+
55
+ options[:threads].times do
56
+ threads << Thread.new do
57
+ until queue.empty?
58
+ offset, index = queue.deq :asynchronously rescue nil
59
+
60
+ unless offset.nil?
61
+ upload.add_part :data => file.read(chunk_size, offset),
62
+ :part_number => index
63
+
64
+ progress.inc if options[:progress_bar]
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ threads.each &:join
71
+ end
72
+ end
73
+
74
+ def progress
75
+ @progress ||= ProgressBar.new :upload, queue.size
76
+ end
77
+
78
+ def process
79
+ value, unit = *options[:chunk_size].first
80
+ puts "uploading #{file} to s3://#{options[:bucket]}/#{object.key} using #{options[:threads]} threads in chunks of #{value} #{unit}"
81
+ progress if options[:progress_bar]
82
+ abort 'upload failed' unless upload
83
+ progress.finish if options[:progress_bar]
84
+ end
85
+
86
+ end
87
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3_multi_upload
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - dallas marlow
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk
16
+ requirement: &70295147055820 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70295147055820
25
+ - !ruby/object:Gem::Dependency
26
+ name: thor
27
+ requirement: &70295147055280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70295147055280
36
+ - !ruby/object:Gem::Dependency
37
+ name: progressbar
38
+ requirement: &70295147054780 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70295147054780
47
+ description:
48
+ email:
49
+ - dallasmarlow@gmail.com
50
+ executables:
51
+ - s3_multi_upload
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - bin/s3_multi_upload
56
+ - lib/s3_multi_upload.rb
57
+ homepage: https://github.com/dallasmarlow/s3_multi_upload
58
+ licenses: []
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 1.8.10
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: s3 multipart uploads in parallel
81
+ test_files: []
82
+ has_rdoc: