refile 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 07f335bddd4f808d06e31efe59579f85ddaa635b
4
- data.tar.gz: bb5c872f88e17f6756988f2c3cb0bd65ecac9843
3
+ metadata.gz: b4a6a01330f6055b1ea8d4ff4f2c38bd830b586a
4
+ data.tar.gz: 63e43f184dd10c69678e2bfaa881a496e86a73ec
5
5
  SHA512:
6
- metadata.gz: 277ff85d62eb22974311570c0f8245aec981ef1f9bc6e7f9086f8d0ee8890dd4af89154efba369acc52071d20f11641a0b54b2687cfd831b3139f6ef75d95a1a
7
- data.tar.gz: 8f22cf639037cb0ed933f5a399abc1f9534dd8c4b6e60e76f9f55452653cb25679bd8e2c5e5655cabbae6d8fd00739526dfd55c9f60afd19b56c88228414bd8c
6
+ metadata.gz: c233739353d69946b16d3332532bb2394eb0bcb292207e4f51045c9a1209070a19a5447f2cde2e7ea91861d36a3a29c71d4cd931ea342b5832527590d7fada57
7
+ data.tar.gz: 294c22cbbf9da075a6c6609b9b79c2345ecacd28a071db5b9c00c2ed45121719c5345164eb316070cbdf9910a3dae385459570b37f2c7b6972b847edebbfd339
@@ -2,7 +2,7 @@ language: ruby
2
2
 
3
3
  rvm:
4
4
  - 2.1
5
- - 2.1.5
5
+ - 2.2
6
6
  - ruby-head
7
7
 
8
8
  gemfile:
data/History.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 0.4.1
2
+
3
+ Release date: 2014-12-26
4
+
5
+ - [CHANGED] Improved IO performance
6
+ - [FIXED] Work around a bug in Ruby 2.2
7
+
1
8
  # 0.4.0
2
9
 
3
10
  Release date: 2014-12-26
@@ -16,14 +16,6 @@ module Refile
16
16
  ONE_YEAR_IN_SECONDS = 31_557_600
17
17
 
18
18
  class << self
19
- # The number of bytes to read when files are streamed. Refile
20
- # uses this in a couple of places where files should be streamed
21
- # in a memory efficient way instead of reading the entire file into
22
- # memory at once. The default value of this is `3000`.
23
- #
24
- # @return [Fixnum]
25
- attr_accessor :read_chunk_size
26
-
27
19
  # A shortcut to the instance of the Rack application. This should be
28
20
  # set when the application is initialized. `refile/rails` sets this
29
21
  # value.
@@ -210,10 +202,6 @@ module Refile
210
202
  end
211
203
 
212
204
  Refile.configure do |config|
213
- # FIXME: what is a sane default here? This is a little less than a
214
- # memory page, which seemed like a good default, is there a better
215
- # one?
216
- config.read_chunk_size = 3000
217
205
  config.direct_upload = ["cache"]
218
206
  config.allow_origin = "*"
219
207
  config.logger = Logger.new(STDOUT)
@@ -1,5 +1,6 @@
1
1
  require "json"
2
2
  require "sinatra/base"
3
+ require "tempfile"
3
4
 
4
5
  module Refile
5
6
  class App < Sinatra::Base
@@ -22,7 +23,7 @@ module Refile
22
23
 
23
24
  get "/:backend/:id/:filename" do
24
25
  set_expires_header
25
- stream_file(file)
26
+ stream_file file
26
27
  end
27
28
 
28
29
  get "/:backend/:processor/:id/:file_basename.:extension" do
@@ -83,11 +84,16 @@ module Refile
83
84
  end
84
85
 
85
86
  def stream_file(file)
86
- stream do |out|
87
- file.each do |chunk|
88
- out << chunk
89
- end
87
+ if file.respond_to?(:path)
88
+ path = file.path
89
+ else
90
+ path = Dir::Tmpname.create(params[:id]) {}
91
+ IO.copy_stream file, path
90
92
  end
93
+
94
+ filename = request.path.split("/").last
95
+
96
+ send_file path, filename: filename, disposition: "inline"
91
97
  end
92
98
 
93
99
  def backend
@@ -105,7 +111,7 @@ module Refile
105
111
  log_error("Could not find attachment by id: #{params[:id]}")
106
112
  halt 404
107
113
  end
108
- file
114
+ file.download
109
115
  end
110
116
 
111
117
  def processor
@@ -6,7 +6,7 @@ module Refile
6
6
  # Attachment method which hooks into ActiveRecord models
7
7
  #
8
8
  # @see Refile::Attachment#attachment
9
- def attachment(name, raise_errors: false, **)
9
+ def attachment(name, raise_errors: false, **options)
10
10
  super
11
11
 
12
12
  attacher = "#{name}_attacher"
@@ -15,19 +15,7 @@ module Refile
15
15
  Refile.verify_uploadable(uploadable, @max_size)
16
16
 
17
17
  id = @hasher.hash(uploadable)
18
-
19
- if uploadable.respond_to?(:path) and ::File.exist?(uploadable.path)
20
- FileUtils.cp(uploadable.path, path(id))
21
- else
22
- ::File.open(path(id), "wb") do |file|
23
- buffer = "" # reuse the same buffer
24
- until uploadable.eof?
25
- uploadable.read(Refile.read_chunk_size, buffer)
26
- file.write(buffer)
27
- end
28
- uploadable.close
29
- end
30
- end
18
+ IO.copy_stream(uploadable, path(id))
31
19
 
32
20
  Refile::File.new(self, id)
33
21
  end
@@ -1,56 +1,10 @@
1
1
  require "aws-sdk"
2
+ require "open-uri"
2
3
 
3
4
  module Refile
4
5
  module Backend
5
6
  # A refile backend which stores files in Amazon S3
6
7
  class S3
7
- # Emulates an IO-object like interface on top of S3Object#read. To avoid
8
- # memory allocations and unnecessary complexity, this treats the `length`
9
- # parameter to read as a boolean flag instead. If given, it will read the
10
- # file in chunks of undetermined size, if not given it will read the
11
- # entire file.
12
- class Reader
13
- def initialize(object)
14
- @object = object
15
- @closed = false
16
- end
17
-
18
- def read(length = nil, buffer = nil)
19
- result = if length
20
- raise "closed" if @closed
21
-
22
- @peek unless eof? # sets @peek
23
- else
24
- @object.read
25
- end
26
- buffer.replace(result) if buffer and result
27
- result
28
- ensure
29
- @peek = nil
30
- end
31
-
32
- def eof?
33
- @peek ||= enumerator.next
34
- false
35
- rescue StopIteration
36
- true
37
- end
38
-
39
- def size
40
- @object.content_length
41
- end
42
-
43
- def close
44
- @closed = true
45
- end
46
-
47
- private
48
-
49
- def enumerator
50
- @enumerator ||= @object.to_enum(:read)
51
- end
52
- end
53
-
54
8
  attr_reader :access_key_id, :max_size
55
9
 
56
10
  def initialize(access_key_id:, secret_access_key:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options)
@@ -88,7 +42,7 @@ module Refile
88
42
  end
89
43
 
90
44
  def open(id)
91
- Reader.new(object(id))
45
+ Kernel.open(object(id).url_for(:read))
92
46
  end
93
47
 
94
48
  def read(id)
@@ -36,21 +36,10 @@ module Refile
36
36
  end
37
37
 
38
38
  def download
39
- tempfile = Tempfile.new(id)
40
- tempfile.binmode
41
- each do |chunk|
42
- tempfile.write(chunk)
43
- end
44
- close
45
- tempfile.close
46
- tempfile
47
- end
39
+ return io if io.is_a?(Tempfile)
48
40
 
49
- def each
50
- if block_given?
51
- yield(read(Refile.read_chunk_size)) until eof?
52
- else
53
- to_enum
41
+ Tempfile.new(id, binmode: true).tap do |tempfile|
42
+ IO.copy_stream(io, tempfile)
54
43
  end
55
44
  end
56
45
 
@@ -60,14 +60,11 @@ module Refile
60
60
  end
61
61
 
62
62
  def call(file, *args, format: nil)
63
- path = file.download.path
64
- img = ::MiniMagick::Image.open(path)
63
+ img = ::MiniMagick::Image.new(file.path)
65
64
  img.format(format.to_s.downcase) if format
66
65
  send(@method, img, *args)
67
66
 
68
- img.write(path)
69
-
70
- ::File.open(path, "rb")
67
+ ::File.open(img.path, "rb")
71
68
  end
72
69
  end
73
70
  end
@@ -1,3 +1,3 @@
1
1
  module Refile
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -2,29 +2,4 @@ RSpec.describe Refile::Backend::FileSystem do
2
2
  let(:backend) { Refile::Backend::FileSystem.new(File.expand_path("tmp/store1", Dir.pwd), max_size: 100) }
3
3
 
4
4
  it_behaves_like :backend
5
-
6
- describe "#upload" do
7
- it "efficiently copies a file if it has a path" do
8
- path = File.expand_path("tmp/test.txt", Dir.pwd)
9
- File.write(path, "hello")
10
-
11
- uploadable = Refile::FileDouble.new("wrong")
12
- allow(uploadable).to receive(:path).and_return(path)
13
-
14
- file = backend.upload(uploadable)
15
-
16
- expect(backend.get(file.id).read).to eq("hello")
17
- end
18
-
19
- it "ignores path if it doesn't exist" do
20
- path = File.expand_path("tmp/doesnotexist.txt", Dir.pwd)
21
-
22
- uploadable = Refile::FileDouble.new("yes")
23
- allow(uploadable).to receive(:path).and_return(path)
24
-
25
- file = backend.upload(uploadable)
26
-
27
- expect(backend.get(file.id).read).to eq("yes")
28
- end
29
- end
30
5
  end
@@ -179,25 +179,6 @@ RSpec.shared_examples_for :backend do
179
179
  end
180
180
  end
181
181
 
182
- describe "#each" do
183
- it "can read file contents" do
184
- file = backend.upload(uploadable)
185
-
186
- buffer = ""
187
- file.each do |chunk|
188
- buffer << chunk
189
- end
190
-
191
- expect(buffer).to eq("hello")
192
- end
193
-
194
- it "returns an enumerator when no block given" do
195
- file = backend.upload(uploadable)
196
-
197
- expect(file.each.to_a.join).to eq("hello")
198
- end
199
- end
200
-
201
182
  describe "#download" do
202
183
  it "returns a downloaded tempfile" do
203
184
  file = backend.upload(uploadable)
@@ -31,9 +31,8 @@ end
31
31
  Refile.processor(:upcase, proc { |file| StringIO.new(file.read.upcase) })
32
32
 
33
33
  Refile.processor(:concat) do |file, *words|
34
- content = File.read(file.download.path)
35
34
  tempfile = Tempfile.new("concat")
36
- tempfile.write(content)
35
+ tempfile.write(file.read)
37
36
  words.each do |word|
38
37
  tempfile.write(word)
39
38
  end
@@ -86,6 +85,10 @@ RSpec.configure do |config|
86
85
  config.include PathHelper
87
86
  config.before(:all) do
88
87
  Refile.logger = Logger.new(nil)
89
- WebMock.disable_net_connect!(allow_localhost: true)
88
+ if ENV["S3"]
89
+ WebMock.allow_net_connect!
90
+ else
91
+ WebMock.disable_net_connect!(allow_localhost: true)
92
+ end
90
93
  end
91
94
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: refile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
@@ -351,7 +351,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
351
  version: '0'
352
352
  requirements: []
353
353
  rubyforge_project:
354
- rubygems_version: 2.4.3
354
+ rubygems_version: 2.4.5
355
355
  signing_key:
356
356
  specification_version: 4
357
357
  summary: Simple and powerful file upload library