ruby-uploader 0.1.0 → 0.2.0beta1

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: b93b4e72c413098bf95988e6f3d5ba6ab4f89af0
4
- data.tar.gz: 3ea0d6b6c6c68974fc6a82e8cc7517a43bca2032
3
+ metadata.gz: fd101106d2a196a4187ee88b081104e82a89fcbf
4
+ data.tar.gz: fa919f1520c308250e993ae9e819e74a8c0165a8
5
5
  SHA512:
6
- metadata.gz: 89d5c96002f7a444ab483f36724995d37639c8c7f5e5e3b0ef77c3a691684f4fd6dcb136f286f3d0b6c12568f438a3dd7bdc1e30eee51871ff9338b3f93ba589
7
- data.tar.gz: 19c0ef8fe7aefa7492d14ea980e2e9d80aec16558375914a67eda10260a726c5c5e63cf6836f40658de3a2764e0c0b780dda814702459b7bdd3b7ecf730d57d1
6
+ metadata.gz: 5b035118f2a4f99eb92183303e33ed4a8f2562a5ac0965829428c7f6297f34eb1884f3a6d40bb0af5e1f21168e08563a7d51f0ebb1756be357b9f3c9789e9e20
7
+ data.tar.gz: 9df18c686fca68a7522c3e663246b514a414091f8e7c2e06514d057b73060b9cf64608af9b192523dceae9abf90fcbdb23c499692c7988f879aad2fcd4a1eccf
data/.gitignore CHANGED
@@ -2,3 +2,5 @@
2
2
  *.swp
3
3
  *.iml
4
4
  Gemfile.lock
5
+ .bundle
6
+ pkg
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ Style/FileName:
2
+ Enabled: false
3
+
1
4
  Style/Documentation:
2
5
  Enabled: false
3
6
 
@@ -6,3 +9,6 @@ Style/LineLength:
6
9
 
7
10
  Style/MethodLength:
8
11
  Max: 35
12
+
13
+ Style/Encoding:
14
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ install:
7
+ - travis_retry bundle install --without debug
8
+ script:
9
+ - bundle exec rake
data/Gemfile CHANGED
@@ -7,6 +7,10 @@ group :development do
7
7
  gem 'rake'
8
8
  end
9
9
 
10
+ group :samples do
11
+ gem 'ruby-progressbar'
12
+ end
13
+
10
14
  group :debug do
11
15
  gem 'byebug'
12
16
  end
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Ruby Uploader
2
2
 
3
+ [![Build Status](https://api.travis-ci.org/ggiamarchi/ruby-uploader.png?branch=master)](https://travis-ci.org/ggiamarchi/ruby-uploader)
4
+ [![Gem Version](https://badge.fury.io/rb/ruby-uploader.svg)](http://badge.fury.io/rb/ruby-uploader)
5
+
3
6
  This library provides a simple HTTP uploader based on chunks transfer. It supports handlers,
4
7
  useful to make custom request configuration and to read the progression of the file transfer.
5
8
 
@@ -15,19 +18,27 @@ gem install ruby-uploader
15
18
  Below, the most basic example do not require any configuration
16
19
 
17
20
  ```ruby
18
- require 'ruby-uploader/uploader'
21
+ require 'ruby-uploader'
19
22
 
20
23
  uploader = Uploader::Upload.new(URI('https://server/path/to/upload'), 'myfile.bin')
21
24
 
22
25
  uploader.execute
23
26
  ```
24
27
 
25
- Optionally, headers can be set using a Hash parameter
28
+ or with the more user friendly block syntax
26
29
 
27
30
  ```ruby
28
- uploader = Uploader::Upload.new(URI('https://server/path/to/upload'), 'myfile.bin', { 'custom-header' => 'value' })
31
+ Uploader::Upload.new(URI('https://server/path/to/upload'), 'myfile.bin') do
32
+ execute
33
+ end
34
+ ```
29
35
 
30
- uploader.execute
36
+ Optionally, headers can be set using a Hash parameter
37
+
38
+ ```ruby
39
+ Uploader::Upload.new(URI('https://server/path/to/upload'), 'myfile.bin', { 'custom-header' => 'value' }) do
40
+ execute
41
+ end
31
42
  ```
32
43
 
33
44
  For more configuration capabilities, see the Handlers section
@@ -106,3 +117,50 @@ end
106
117
 
107
118
  uploader.add_handler :after, AfterRequest.new
108
119
  ```
120
+
121
+ ## Putting all together
122
+
123
+ An uploader with one handler of each kind that just do log.
124
+
125
+ ```ruby
126
+ require 'ruby-uploader'
127
+ require 'logger'
128
+
129
+ class Handler
130
+ def initialize
131
+ @logger = Logger.new(STDOUT)
132
+ end
133
+ end
134
+
135
+ class BeforeRequest < Handler
136
+ def execute(request)
137
+ @logger.info('start processing request')
138
+ end
139
+ end
140
+
141
+ class AfterResponse < Handler
142
+ def execute(response)
143
+ @logger.info('finished processing request')
144
+ end
145
+ end
146
+
147
+ class BeforeChunk < Handler
148
+ def execute(buf, count, total_count, content_length)
149
+ puts "start processing chunk #{count} of #{total_count}"
150
+ end
151
+ end
152
+
153
+ class AfterChunk < Handler
154
+ def execute(buf, count, total_count, content_length)
155
+ puts "finished processing chunk #{count} of #{total_count}"
156
+ end
157
+ end
158
+
159
+ Uploader::Upload.new(URI('https://server/path/to/upload'), 'myfile.bin') do
160
+ add_handler :before, BeforeRequest.new
161
+ add_handler :after, AfterResponse.new
162
+ add_handler :before_chunk, BeforeChunk.new
163
+ add_handler :after_chunk, AfterChunk.new
164
+ execute
165
+ end
166
+ ```
@@ -0,0 +1,56 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Uploader
5
+ class Put < Net::HTTP::Put
6
+ def initialize(path, headers, handlers)
7
+ @handlers = handlers
8
+ super path, headers
9
+ end
10
+
11
+ private
12
+
13
+ def send_request_with_body_stream(sock, ver, path, f)
14
+ write_header sock, ver, path
15
+ wait_for_continue sock, ver if sock.continue_timeout
16
+ chunker = Chunker.new(sock, self['Content-Length'], @handlers)
17
+ IO.copy_stream(f, chunker)
18
+ chunker.finish
19
+ end
20
+ end
21
+
22
+ class Chunker
23
+ def initialize(sock, content_length, handlers)
24
+ @sock = sock
25
+ @prev = nil
26
+ @count = 0
27
+ @total_count = nil
28
+ @content_length = content_length.to_i
29
+ @handlers = handlers
30
+ end
31
+
32
+ def write(buf)
33
+ @total_count = @content_length / buf.bytesize.to_i if @total_count.nil?
34
+
35
+ @handlers[:before_chunk].each do |handler|
36
+ handler.execute buf, @count, @total_count, @content_length
37
+ end
38
+
39
+ @sock.write("#{buf.bytesize.to_s(16)}\r\n")
40
+ rv = @sock.write(buf)
41
+ @sock.write("\r\n")
42
+
43
+ @handlers[:after_chunk].each do |handler|
44
+ handler.execute buf, @count, @total_count, @content_length
45
+ end
46
+
47
+ @count += 1
48
+
49
+ rv
50
+ end
51
+
52
+ def finish
53
+ @sock.write("0\r\n\r\n")
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,57 @@
1
+ require 'ruby-uploader/put'
2
+
3
+ module Uploader
4
+ class Upload
5
+ def initialize(url, path, headers = nil, &block)
6
+ @url = url
7
+ @headers = headers
8
+ @path = path
9
+ @response = nil
10
+ @handlers = {
11
+ before: [],
12
+ after: [],
13
+ before_chunk: [],
14
+ after_chunk: []
15
+ }
16
+ instance_eval(&block) if block_given?
17
+ end
18
+
19
+ def execute
20
+ Net::HTTP.start(@url.host, @url.port, use_ssl: @url.scheme == 'https') do |http|
21
+
22
+ headers = @headers ? default_headers.merge(@headers) : default_headers
23
+
24
+ request = Put.new(@url, headers, @handlers).tap do |r|
25
+ r.body_stream = File.open(@path)
26
+ end
27
+
28
+ @handlers[:before].each do |handler|
29
+ handler.execute request
30
+ end
31
+
32
+ @response = http.request(request)
33
+
34
+ @handlers[:after].each do |handler|
35
+ handler.execute @response
36
+ end
37
+
38
+ @response
39
+ end
40
+ end
41
+
42
+ def add_handler(phase, handler)
43
+ fail "Handler phase #{phase} does not exists" unless @handlers.key? phase
44
+ @handlers[phase] << handler
45
+ end
46
+
47
+ private
48
+
49
+ def default_headers
50
+ {
51
+ 'Content-Type' => 'application/octet-stream',
52
+ 'Content-Length' => File.stat(@path).size.to_s,
53
+ 'Transfer-Encoding' => 'chunked'
54
+ }
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module Uploader
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0beta1'
3
3
  end
@@ -0,0 +1 @@
1
+ require 'ruby-uploader/upload'
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.authors = ['Guillaume Giamarchi']
9
9
  gem.email = ['guillaume.giamarchi@gmail.com']
10
10
  gem.licenses = ['MIT']
11
- gem.description = 'Ruby HTTP chunked uploader with transfert progress'
12
- gem.summary = 'Ruby HTTP chunked uploader with transfert progress'
11
+ gem.description = 'Ruby HTTP chunked uploader with transfer progress'
12
+ gem.summary = 'Ruby HTTP chunked uploader with transfer progress'
13
13
  gem.homepage = 'https://github.com/ggiamarchi/ruby-uploader'
14
14
  gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
15
15
  gem.require_paths = ['lib']
@@ -0,0 +1,42 @@
1
+ #
2
+ # Sample upload code that shows a progressbar
3
+ # using the library 'ruby-progressbar'
4
+ #
5
+ # Usage:
6
+ # ruby upload_progressbar.rb http://server file_to_upload
7
+ #
8
+
9
+ url = ARGV[0]
10
+ path = ARGV[1]
11
+
12
+ require 'ruby-uploader'
13
+ require 'logger'
14
+ require 'ruby-progressbar'
15
+
16
+ class BeforeChunk
17
+ def initialize(holder)
18
+ @holder = holder
19
+ end
20
+
21
+ def execute(_, count, total_count, _)
22
+ return unless count == 0
23
+ @holder[:progressbar] = ProgressBar.create(starting_at: 0, total: total_count + 1)
24
+ end
25
+ end
26
+
27
+ class AfterChunk
28
+ def initialize(holder)
29
+ @holder = holder
30
+ end
31
+
32
+ def execute(_, _, _, _)
33
+ @holder[:progressbar].increment
34
+ end
35
+ end
36
+
37
+ Uploader::Upload.new(URI(url), path) do
38
+ holder = {}
39
+ add_handler :before_chunk, BeforeChunk.new(holder)
40
+ add_handler :after_chunk, AfterChunk.new(holder)
41
+ execute
42
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-uploader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guillaume Giamarchi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-28 00:00:00.000000000 Z
11
+ date: 2014-11-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Ruby HTTP chunked uploader with transfert progress
13
+ description: Ruby HTTP chunked uploader with transfer progress
14
14
  email:
15
15
  - guillaume.giamarchi@gmail.com
16
16
  executables: []
@@ -19,13 +19,17 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - .gitignore
21
21
  - .rubocop.yml
22
+ - .travis.yml
22
23
  - Gemfile
23
24
  - LICENSE.txt
24
25
  - README.md
25
26
  - Rakefile
26
- - lib/ruby-uploader/uploader.rb
27
+ - lib/ruby-uploader.rb
28
+ - lib/ruby-uploader/put.rb
29
+ - lib/ruby-uploader/upload.rb
27
30
  - lib/ruby-uploader/version.rb
28
31
  - ruby-uploader.gemspec
32
+ - samples/upload_progressbar.rb
29
33
  homepage: https://github.com/ggiamarchi/ruby-uploader
30
34
  licenses:
31
35
  - MIT
@@ -41,13 +45,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
41
45
  version: '0'
42
46
  required_rubygems_version: !ruby/object:Gem::Requirement
43
47
  requirements:
44
- - - '>='
48
+ - - '>'
45
49
  - !ruby/object:Gem::Version
46
- version: '0'
50
+ version: 1.3.1
47
51
  requirements: []
48
52
  rubyforge_project:
49
53
  rubygems_version: 2.0.14
50
54
  signing_key:
51
55
  specification_version: 4
52
- summary: Ruby HTTP chunked uploader with transfert progress
56
+ summary: Ruby HTTP chunked uploader with transfer progress
53
57
  test_files: []
@@ -1,111 +0,0 @@
1
- require 'net/http'
2
- require 'uri'
3
-
4
- module Uploader
5
- class Upload
6
- def initialize(url, path, headers = nil)
7
- @url = url
8
- @headers = headers
9
- @path = path
10
- @response = nil
11
- @handlers = {
12
- before: [],
13
- after: [],
14
- before_chunk: [],
15
- after_chunk: []
16
- }
17
- end
18
-
19
- def execute
20
- Net::HTTP.start(@url.host, @url.port, use_ssl: @url.scheme == 'https') do |http|
21
-
22
- headers = @headers ? default_headers.merge(@headers) : default_headers
23
-
24
- request = Put.new(@url, headers, @handlers).tap do |r|
25
- r.body_stream = File.open(@path)
26
- end
27
-
28
- @handlers[:before].each do |handler|
29
- handler.execute request
30
- end
31
-
32
- @response = http.request(request)
33
-
34
- @handlers[:after].each do |handler|
35
- handler.execute @response
36
- end
37
-
38
- @response
39
- end
40
- end
41
-
42
- def add_handler(phase, handler)
43
- fail "Handler phase #{phase} does not exists" unless @handlers.key? phase
44
- @handlers[phase] << handler
45
- end
46
-
47
- private
48
-
49
- def default_headers
50
- {
51
- 'Content-Type' => 'application/octet-stream',
52
- 'Content-Length' => File.stat(@path).size.to_s,
53
- 'Transfer-Encoding' => 'chunked'
54
- }
55
- end
56
-
57
- class Put < Net::HTTP::Put
58
- def initialize(path, headers, handlers)
59
- @handlers = handlers
60
- super path, headers
61
- end
62
-
63
- private
64
-
65
- def send_request_with_body_stream(sock, ver, path, f)
66
- write_header sock, ver, path
67
- wait_for_continue sock, ver if sock.continue_timeout
68
- chunker = Chunker.new(sock, self['Content-Length'], @handlers)
69
- IO.copy_stream(f, chunker)
70
- chunker.finish
71
- end
72
-
73
- class Chunker
74
- def initialize(sock, content_length, handlers)
75
- @sock = sock
76
- @prev = nil
77
- @count = 0
78
- @total_count = nil
79
- @content_length = content_length.to_i
80
- @handlers = handlers
81
- end
82
-
83
- def write(buf)
84
- @total_count = @content_length / buf.bytesize.to_i if @total_count.nil?
85
-
86
- @handlers[:before_chunk].each do |handler|
87
- handler.execute buf, @count, @total_count, @content_length
88
- end
89
-
90
- puts "#{@count} / #{@total_count}"
91
-
92
- @sock.write("#{buf.bytesize.to_s(16)}\r\n")
93
- rv = @sock.write(buf)
94
- @sock.write("\r\n")
95
-
96
- @count += 1
97
-
98
- @handlers[:after_chunk].each do |handler|
99
- handler.execute buf, @count, @total_count, @content_length
100
- end
101
-
102
- rv
103
- end
104
-
105
- def finish
106
- @sock.write("0\r\n\r\n")
107
- end
108
- end
109
- end
110
- end
111
- end