提交 562f3a2d 编写于 作者: G George Claghorn

Add ActiveStorage::Service#open

上级 e3f5f1c9
......@@ -193,17 +193,18 @@ def download(&block)
#
# The tempfile's name is prefixed with +ActiveStorage-+ and the blob's ID. Its extension matches that of the blob.
#
# By default, the tempfile is created in <tt>Dir.tmpdir</tt>. Pass +tempdir:+ to create it in a different directory:
# By default, the tempfile is created in <tt>Dir.tmpdir</tt>. Pass +tmpdir:+ to create it in a different directory:
#
# blob.open(tempdir: "/path/to/tmp") do |file|
# blob.open(tmpdir: "/path/to/tmp") do |file|
# # ...
# end
#
# The tempfile is automatically closed and unlinked after the given block is executed.
#
# Raises ActiveStorage::IntegrityError if the downloaded data does not match the blob's checksum.
def open(tempdir: nil, &block)
ActiveStorage::Downloader.new(self, tempdir: tempdir).download_blob_to_tempfile(&block)
def open(tmpdir: nil, &block)
service.open key, checksum: checksum,
name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ], tmpdir: tmpdir, &block
end
......
......@@ -24,14 +24,14 @@ def metadata
private
# Downloads the blob to a tempfile on disk. Yields the tempfile.
def download_blob_to_tempfile(&block) #:doc:
blob.open tempdir: tempdir, &block
blob.open tmpdir: tmpdir, &block
end
def logger #:doc:
ActiveStorage.logger
end
def tempdir #:doc:
def tmpdir #:doc:
Dir.tmpdir
end
end
......
......@@ -2,24 +2,23 @@
module ActiveStorage
class Downloader #:nodoc:
def initialize(blob, tempdir: nil)
@blob = blob
@tempdir = tempdir
attr_reader :service
def initialize(service)
@service = service
end
def download_blob_to_tempfile
open_tempfile do |file|
download_blob_to file
verify_integrity_of file
def open(key, checksum:, name: "ActiveStorage-", tmpdir: nil)
open_tempfile(name, tmpdir) do |file|
download key, file
verify_integrity_of file, checksum: checksum
yield file
end
end
private
attr_reader :blob, :tempdir
def open_tempfile
file = Tempfile.open([ "ActiveStorage-#{blob.id}-", blob.filename.extension_with_delimiter ], tempdir)
def open_tempfile(name, tmpdir = nil)
file = Tempfile.open(name, tmpdir)
begin
yield file
......@@ -28,15 +27,15 @@ def open_tempfile
end
end
def download_blob_to(file)
def download(key, file)
file.binmode
blob.download { |chunk| file.write(chunk) }
service.download(key) { |chunk| file.write(chunk) }
file.flush
file.rewind
end
def verify_integrity_of(file)
unless Digest::MD5.file(file).base64digest == blob.checksum
def verify_integrity_of(file, checksum:)
unless Digest::MD5.file(file).base64digest == checksum
raise ActiveStorage::IntegrityError
end
end
......
......@@ -26,7 +26,7 @@ def preview
private
# Downloads the blob to a tempfile on disk. Yields the tempfile.
def download_blob_to_tempfile(&block) #:doc:
blob.open tempdir: tempdir, &block
blob.open tmpdir: tmpdir, &block
end
# Executes a system command, capturing its binary output in a tempfile. Yields the tempfile.
......@@ -42,7 +42,7 @@ def download_blob_to_tempfile(&block) #:doc:
# end
# end
#
# The output tempfile is opened in the directory returned by #tempdir.
# The output tempfile is opened in the directory returned by #tmpdir.
def draw(*argv) #:doc:
open_tempfile do |file|
instrument :preview, key: blob.key do
......@@ -54,7 +54,7 @@ def draw(*argv) #:doc:
end
def open_tempfile
tempfile = Tempfile.open("ActiveStorage-", tempdir)
tempfile = Tempfile.open("ActiveStorage-", tmpdir)
begin
yield tempfile
......@@ -77,7 +77,7 @@ def logger #:doc:
ActiveStorage.logger
end
def tempdir #:doc:
def tmpdir #:doc:
Dir.tmpdir
end
end
......
......@@ -82,6 +82,10 @@ def download_chunk(key, range)
raise NotImplementedError
end
def open(*args, &block)
ActiveStorage::Downloader.new(self).open(*args, &block)
end
# Delete the file at the +key+.
def delete(key)
raise NotImplementedError
......
......@@ -104,14 +104,12 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
end
end
test "open in a custom tempdir" do
tempdir = Dir.mktmpdir
create_file_blob(filename: "racecar.jpg").open(tempdir: tempdir) do |file|
test "open in a custom tmpdir" do
create_file_blob(filename: "racecar.jpg").open(tmpdir: tmpdir = Dir.mktmpdir) do |file|
assert file.binmode?
assert_equal 0, file.pos
assert_match(/\.jpg\z/, file.path)
assert file.path.starts_with?(tempdir)
assert file.path.starts_with?(tmpdir)
assert_equal file_fixture("racecar.jpg").binread, file.read, "Expected downloaded file to match fixture file"
end
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册