refile 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of refile might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -2
- data/.travis.yml +2 -0
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +33 -0
- data/History.md +9 -0
- data/README.md +67 -16
- data/app/assets/javascripts/refile.js +19 -17
- data/lib/refile.rb +36 -6
- data/lib/refile/app.rb +15 -12
- data/lib/refile/attacher.rb +119 -49
- data/lib/refile/attachment.rb +29 -16
- data/lib/refile/attachment/active_record.rb +5 -2
- data/lib/refile/backend/file_system.rb +61 -1
- data/lib/refile/backend/s3.rb +66 -0
- data/lib/refile/custom_logger.rb +46 -0
- data/lib/refile/file.rb +32 -1
- data/lib/refile/image_processing.rb +72 -3
- data/lib/refile/rails.rb +2 -8
- data/lib/refile/rails/attachment_helper.rb +77 -19
- data/lib/refile/signature.rb +16 -1
- data/lib/refile/type.rb +28 -0
- data/lib/refile/version.rb +1 -1
- data/refile.gemspec +1 -1
- data/spec/refile/active_record_helper.rb +27 -0
- data/spec/refile/attachment/active_record_spec.rb +92 -0
- data/spec/refile/attachment_spec.rb +153 -28
- data/spec/refile/custom_logger_spec.rb +22 -0
- data/spec/refile/features/direct_upload_spec.rb +19 -2
- data/spec/refile/features/normal_upload_spec.rb +41 -11
- data/spec/refile/features/presigned_upload_spec.rb +1 -2
- data/spec/refile/rails/attachment_helper_spec.rb +1 -1
- data/spec/refile/test_app.rb +16 -14
- data/spec/refile/test_app/app/controllers/direct_posts_controller.rb +1 -1
- data/spec/refile/test_app/app/controllers/normal_posts_controller.rb +1 -1
- data/spec/refile/test_app/app/controllers/presigned_posts_controller.rb +1 -1
- data/spec/refile/test_app/app/views/direct_posts/new.html.erb +4 -0
- data/spec/refile/test_app/app/views/normal_posts/show.html.erb +5 -3
- metadata +27 -17
data/lib/refile/backend/s3.rb
CHANGED
@@ -4,9 +4,30 @@ require "open-uri"
|
|
4
4
|
module Refile
|
5
5
|
module Backend
|
6
6
|
# A refile backend which stores files in Amazon S3
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# backend = Refile::Backend::S3.new(
|
10
|
+
# access_key_id: "xyz",
|
11
|
+
# secret_access_key: "abcd1234",
|
12
|
+
# bucket: "my-bucket",
|
13
|
+
# prefix: "files"
|
14
|
+
# )
|
15
|
+
# file = backend.upload(StringIO.new("hello"))
|
16
|
+
# backend.read(file.id) # => "hello"
|
7
17
|
class S3
|
8
18
|
attr_reader :access_key_id, :max_size
|
9
19
|
|
20
|
+
# Sets up an S3 backend with the given credentials.
|
21
|
+
#
|
22
|
+
# @param [String] access_key_id
|
23
|
+
# @param [String] secret_access_key
|
24
|
+
# @param [String] bucket The name of the bucket where files will be stored
|
25
|
+
# @param [String] prefix A prefix to add to all files. Prefixes on S3 are kind of like folders.
|
26
|
+
# @param [Integer, nil] max_size The maximum size of an uploaded file
|
27
|
+
# @param [#hash] hasher A hasher which is used to generate ids from files
|
28
|
+
# @param [Hash] s3_options Additional options to initialize S3 with
|
29
|
+
# @see http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Core/Configuration.html
|
30
|
+
# @see http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3.html
|
10
31
|
def initialize(access_key_id:, secret_access_key:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options)
|
11
32
|
@access_key_id = access_key_id
|
12
33
|
@secret_access_key = secret_access_key
|
@@ -19,6 +40,10 @@ module Refile
|
|
19
40
|
@max_size = max_size
|
20
41
|
end
|
21
42
|
|
43
|
+
# Upload a file into this backend
|
44
|
+
#
|
45
|
+
# @param [IO] uploadable An uploadable IO-like object.
|
46
|
+
# @return [Refile::File] The uploaded file
|
22
47
|
def upload(uploadable)
|
23
48
|
Refile.verify_uploadable(uploadable, @max_size)
|
24
49
|
|
@@ -33,39 +58,80 @@ module Refile
|
|
33
58
|
Refile::File.new(self, id)
|
34
59
|
end
|
35
60
|
|
61
|
+
# Get a file from this backend.
|
62
|
+
#
|
63
|
+
# Note that this method will always return a {Refile::File} object, even
|
64
|
+
# if a file with the given id does not exist in this backend. Use
|
65
|
+
# {FileSystem#exists?} to check if the file actually exists.
|
66
|
+
#
|
67
|
+
# @param [Sring] id The id of the file
|
68
|
+
# @return [Refile::File] The retrieved file
|
36
69
|
def get(id)
|
37
70
|
Refile::File.new(self, id)
|
38
71
|
end
|
39
72
|
|
73
|
+
# Delete a file from this backend
|
74
|
+
#
|
75
|
+
# @param [Sring] id The id of the file
|
76
|
+
# @return [void]
|
40
77
|
def delete(id)
|
41
78
|
object(id).delete
|
42
79
|
end
|
43
80
|
|
81
|
+
# Return an IO object for the uploaded file which can be used to read its
|
82
|
+
# content.
|
83
|
+
#
|
84
|
+
# @param [Sring] id The id of the file
|
85
|
+
# @return [IO] An IO object containing the file contents
|
44
86
|
def open(id)
|
45
87
|
Kernel.open(object(id).url_for(:read))
|
46
88
|
end
|
47
89
|
|
90
|
+
# Return the entire contents of the uploaded file as a String.
|
91
|
+
#
|
92
|
+
# @param [String] id The id of the file
|
93
|
+
# @return [String] The file's contents
|
48
94
|
def read(id)
|
49
95
|
object(id).read
|
50
96
|
rescue AWS::S3::Errors::NoSuchKey
|
51
97
|
nil
|
52
98
|
end
|
53
99
|
|
100
|
+
# Return the size in bytes of the uploaded file.
|
101
|
+
#
|
102
|
+
# @param [Sring] id The id of the file
|
103
|
+
# @return [Integer] The file's size
|
54
104
|
def size(id)
|
55
105
|
object(id).content_length
|
56
106
|
rescue AWS::S3::Errors::NoSuchKey
|
57
107
|
nil
|
58
108
|
end
|
59
109
|
|
110
|
+
# Return whether the file with the given id exists in this backend.
|
111
|
+
#
|
112
|
+
# @param [Sring] id The id of the file
|
113
|
+
# @return [Boolean]
|
60
114
|
def exists?(id)
|
61
115
|
object(id).exists?
|
62
116
|
end
|
63
117
|
|
118
|
+
# Remove all files in this backend. You must confirm the deletion by
|
119
|
+
# passing the symbol `:confirm` as an argument to this method.
|
120
|
+
#
|
121
|
+
# @example
|
122
|
+
# backend.clear!(:confirm)
|
123
|
+
# @raise [Refile::Confirm] Unless the `:confirm` symbol has been passed.
|
124
|
+
# @param [:confirm] confirm Pass the symbol `:confirm` to confirm deletion.
|
125
|
+
# @return [void]
|
64
126
|
def clear!(confirm = nil)
|
65
127
|
raise Refile::Confirm unless confirm == :confirm
|
66
128
|
@bucket.objects.with_prefix(@prefix).delete_all
|
67
129
|
end
|
68
130
|
|
131
|
+
# Return a presign signature which can be used to upload a file into this
|
132
|
+
# backend directly.
|
133
|
+
#
|
134
|
+
# @return [Refile::Signature]
|
69
135
|
def presign
|
70
136
|
id = RandomHasher.new.hash
|
71
137
|
signature = @bucket.presigned_post(key: [*@prefix, id].join("/"))
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "rack/body_proxy"
|
2
|
+
|
3
|
+
module Refile
|
4
|
+
# @api private
|
5
|
+
class CustomLogger
|
6
|
+
LOG_FORMAT = %(%s: [%s] %s "%s%s" %d %0.1fms\n)
|
7
|
+
|
8
|
+
def initialize(app, prefix, logger_proc)
|
9
|
+
@app, @prefix, @logger_proc = app, prefix, logger_proc
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
began_at = Time.now
|
14
|
+
status, header, body = @app.call(env)
|
15
|
+
body = Rack::BodyProxy.new(body) { log(env, status, began_at) }
|
16
|
+
[status, header, body]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def log(env, status, began_at)
|
22
|
+
now = Time.now
|
23
|
+
logger.info do
|
24
|
+
format(
|
25
|
+
LOG_FORMAT,
|
26
|
+
@prefix,
|
27
|
+
now.strftime("%F %T %z"),
|
28
|
+
env["REQUEST_METHOD"],
|
29
|
+
env["PATH_INFO"],
|
30
|
+
env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"],
|
31
|
+
status.to_s[0..3],
|
32
|
+
(now - began_at) * 1000
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def logger
|
38
|
+
@logger ||= @logger_proc.call
|
39
|
+
@logger || fallback_logger
|
40
|
+
end
|
41
|
+
|
42
|
+
def fallback_logger
|
43
|
+
@fallback_logger ||= Logger.new(nil)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/refile/file.rb
CHANGED
@@ -1,40 +1,71 @@
|
|
1
1
|
module Refile
|
2
2
|
class File
|
3
|
-
|
3
|
+
# @return [Backend] the backend the file is stored in
|
4
|
+
attr_reader :backend
|
4
5
|
|
6
|
+
# @return [String] the id of the file
|
7
|
+
attr_reader :id
|
8
|
+
|
9
|
+
# @api private
|
5
10
|
def initialize(backend, id)
|
6
11
|
@backend = backend
|
7
12
|
@id = id
|
8
13
|
end
|
9
14
|
|
15
|
+
# Reads from the file.
|
16
|
+
#
|
17
|
+
# @see http://www.ruby-doc.org/core-2.2.0/IO.html#method-i-read
|
18
|
+
#
|
19
|
+
# @return [String] The contents of the read chunk
|
10
20
|
def read(*args)
|
11
21
|
io.read(*args)
|
12
22
|
end
|
13
23
|
|
24
|
+
# Returns whether there is more data to read. Returns true if the end of
|
25
|
+
# the data has been reached.
|
26
|
+
#
|
27
|
+
# @return [Boolean]
|
14
28
|
def eof?
|
15
29
|
io.eof?
|
16
30
|
end
|
17
31
|
|
32
|
+
# Close the file object and release its file descriptor.
|
33
|
+
#
|
34
|
+
# @return [void]
|
18
35
|
def close
|
19
36
|
io.close
|
20
37
|
end
|
21
38
|
|
39
|
+
# @return [Integer] the size of the file in bytes
|
22
40
|
def size
|
23
41
|
backend.size(id)
|
24
42
|
end
|
25
43
|
|
44
|
+
# Remove the file from the backend.
|
45
|
+
#
|
46
|
+
# @return [void]
|
26
47
|
def delete
|
27
48
|
backend.delete(id)
|
28
49
|
end
|
29
50
|
|
51
|
+
# @return [Boolean] whether the file exists in the backend
|
30
52
|
def exists?
|
31
53
|
backend.exists?(id)
|
32
54
|
end
|
33
55
|
|
56
|
+
# @return [IO] an IO object which contains the contents of the file
|
34
57
|
def to_io
|
35
58
|
io
|
36
59
|
end
|
37
60
|
|
61
|
+
# Downloads the file to a Tempfile on disk and returns this tempfile.
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# file = backend.upload(StringIO.new("hello"))
|
65
|
+
# tempfile = file.download
|
66
|
+
# File.read(tempfile.path) # => "hello"
|
67
|
+
#
|
68
|
+
# @return [Tempfile] a tempfile with the file's content
|
38
69
|
def download
|
39
70
|
return io if io.is_a?(Tempfile)
|
40
71
|
|
@@ -2,27 +2,67 @@ require "refile"
|
|
2
2
|
require "mini_magick"
|
3
3
|
|
4
4
|
module Refile
|
5
|
+
# Processes images via MiniMagick, resizing cropping and padding them.
|
5
6
|
class ImageProcessor
|
7
|
+
# @param [Symbol] method The method to invoke on {#call}
|
6
8
|
def initialize(method)
|
7
9
|
@method = method
|
8
10
|
end
|
9
11
|
|
12
|
+
# Changes the image encoding format to the given format
|
13
|
+
#
|
14
|
+
# @see http://www.imagemagick.org/script/command-line-options.php#format
|
15
|
+
# @param [MiniMagick::Image] img the image to convert
|
16
|
+
# @param [String] format the format to convert to
|
17
|
+
# @return [void]
|
10
18
|
def convert(img, format)
|
11
19
|
img.format(format.to_s.downcase)
|
12
20
|
end
|
13
21
|
|
22
|
+
# Resize the image to fit within the specified dimensions while retaining
|
23
|
+
# the original aspect ratio. Will only resize the image if it is larger
|
24
|
+
# than the specified dimensions. The resulting image may be shorter or
|
25
|
+
# narrower than specified in either dimension but will not be larger than
|
26
|
+
# the specified values.
|
27
|
+
#
|
28
|
+
# @param [MiniMagick::Image] img the image to convert
|
29
|
+
# @param [#to_s] width the maximum width
|
30
|
+
# @param [#to_s] height the maximum height
|
31
|
+
# @return [void]
|
14
32
|
def limit(img, width, height)
|
15
33
|
img.resize "#{width}x#{height}>"
|
16
34
|
end
|
17
35
|
|
36
|
+
# Resize the image to fit within the specified dimensions while retaining
|
37
|
+
# the original aspect ratio. The image may be shorter or narrower than
|
38
|
+
# specified in the smaller dimension but will not be larger than the
|
39
|
+
# specified values.
|
40
|
+
#
|
41
|
+
# @param [MiniMagick::Image] img the image to convert
|
42
|
+
# @param [#to_s] width the width to fit into
|
43
|
+
# @param [#to_s] height the height to fit into
|
44
|
+
# @return [void]
|
18
45
|
def fit(img, width, height)
|
19
46
|
img.resize "#{width}x#{height}"
|
20
47
|
end
|
21
48
|
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
49
|
+
# Resize the image so that it is at least as large in both dimensions as
|
50
|
+
# specified, then crops any excess outside the specified dimensions.
|
51
|
+
#
|
52
|
+
# The resulting image will always be exactly as large as the specified
|
53
|
+
# dimensions.
|
54
|
+
#
|
55
|
+
# By default, the center part of the image is kept, and the remainder
|
56
|
+
# cropped off, but this can be changed via the `gravity` option.
|
57
|
+
#
|
58
|
+
# @param [MiniMagick::Image] img the image to convert
|
59
|
+
# @param [#to_s] width the width to fill out
|
60
|
+
# @param [#to_s] height the height to fill out
|
61
|
+
# @param [String] gravity which part of the image to focus on
|
62
|
+
# @return [void]
|
63
|
+
# @see http://www.imagemagick.org/script/command-line-options.php#gravity
|
25
64
|
def fill(img, width, height, gravity = "Center")
|
65
|
+
# FIXME: test and rewrite to simpler implementation!
|
26
66
|
width = width.to_i
|
27
67
|
height = height.to_i
|
28
68
|
cols, rows = img[:dimensions]
|
@@ -46,6 +86,26 @@ module Refile
|
|
46
86
|
end
|
47
87
|
end
|
48
88
|
|
89
|
+
# resize the image to fit within the specified dimensions while retaining
|
90
|
+
# the original aspect ratio in the same way as {#fill}. unlike {#fill} it
|
91
|
+
# will, if necessary, pad the remaining area with the given color, which
|
92
|
+
# defaults to transparent where supported by the image format and white
|
93
|
+
# otherwise.
|
94
|
+
#
|
95
|
+
# the resulting image will always be exactly as large as the specified
|
96
|
+
# dimensions.
|
97
|
+
#
|
98
|
+
# by default, the image will be placed in the center but this can be
|
99
|
+
# changed via the `gravity` option.
|
100
|
+
#
|
101
|
+
# @param [minimagick::image] img the image to convert
|
102
|
+
# @param [#to_s] width the width to fill out
|
103
|
+
# @param [#to_s] height the height to fill out
|
104
|
+
# @param [string] background the color to use as a background
|
105
|
+
# @param [string] gravity which part of the image to focus on
|
106
|
+
# @return [void]
|
107
|
+
# @see http://www.imagemagick.org/script/color.php
|
108
|
+
# @see http://www.imagemagick.org/script/command-line-options.php#gravity
|
49
109
|
def pad(img, width, height, background = "transparent", gravity = "Center")
|
50
110
|
img.combine_options do |cmd|
|
51
111
|
cmd.thumbnail "#{width}x#{height}>"
|
@@ -59,6 +119,15 @@ module Refile
|
|
59
119
|
end
|
60
120
|
end
|
61
121
|
|
122
|
+
# Process the given file. The file will be processed via one of the
|
123
|
+
# instance methods of this class, depending on the `method` argument passed
|
124
|
+
# to the constructor on initialization.
|
125
|
+
#
|
126
|
+
# If the format is given it will convert the image to the given file format.
|
127
|
+
#
|
128
|
+
# @param [Tempfile] file the file to manipulate
|
129
|
+
# @param [String] format the file format to convert to
|
130
|
+
# @return [File] the processed file
|
62
131
|
def call(file, *args, format: nil)
|
63
132
|
img = ::MiniMagick::Image.new(file.path)
|
64
133
|
img.format(format.to_s.downcase) if format
|
data/lib/refile/rails.rb
CHANGED
@@ -2,13 +2,7 @@ require "refile"
|
|
2
2
|
require "refile/rails/attachment_helper"
|
3
3
|
|
4
4
|
module Refile
|
5
|
-
|
6
|
-
def attachment_field(method, options = {})
|
7
|
-
self.multipart = true
|
8
|
-
@template.attachment_field(@object_name, method, objectify_options(options))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
5
|
+
# @api private
|
12
6
|
class Engine < Rails::Engine
|
13
7
|
initializer "refile.setup", before: :load_environment_config do
|
14
8
|
Refile.store ||= Refile::Backend::FileSystem.new(Rails.root.join("tmp/uploads/store").to_s)
|
@@ -19,7 +13,7 @@ module Refile
|
|
19
13
|
end
|
20
14
|
|
21
15
|
ActionView::Base.send(:include, Refile::AttachmentHelper)
|
22
|
-
ActionView::Helpers::FormBuilder.send(:include,
|
16
|
+
ActionView::Helpers::FormBuilder.send(:include, AttachmentHelper::FormBuilder)
|
23
17
|
end
|
24
18
|
|
25
19
|
initializer "refile.app" do
|
@@ -1,10 +1,49 @@
|
|
1
1
|
module Refile
|
2
|
+
# Rails view helpers which aid in using Refile from views.
|
2
3
|
module AttachmentHelper
|
4
|
+
# Form builder extension
|
5
|
+
module FormBuilder
|
6
|
+
# @see AttachmentHelper#attachment_field
|
7
|
+
def attachment_field(method, options = {})
|
8
|
+
self.multipart = true
|
9
|
+
@template.attachment_field(@object_name, method, objectify_options(options))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# View helper which generates a url for an attachment. This generates a URL
|
14
|
+
# to the {Refile::App} which is assumed to be mounted in the Rails
|
15
|
+
# application.
|
16
|
+
#
|
17
|
+
# Optionally the name of a processor and a arguments to it can be appended.
|
18
|
+
#
|
19
|
+
# If the filename option is not given, the filename falls back to the
|
20
|
+
# `name`.
|
21
|
+
#
|
22
|
+
# The host defaults to {Refile.host}, which is useful for serving all
|
23
|
+
# attachments from a CDN. You can also override the host via the `host`
|
24
|
+
# option.
|
25
|
+
#
|
26
|
+
# Returns `nil` if there is no file attached.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# attachment_url(@post, :document)
|
30
|
+
#
|
31
|
+
# @example With processor
|
32
|
+
# attachment_url(@post, :image, :fill, 300, 300, format: "jpg")
|
33
|
+
#
|
34
|
+
# @param [Refile::Attachment] record Instance of a class which has an attached file
|
35
|
+
# @param [Symbol] name The name of the attachment column
|
36
|
+
# @param [String, nil] filename The filename to be appended to the URL
|
37
|
+
# @param [String, nil] format A file extension to be appended to the URL
|
38
|
+
# @param [String, nil] host Override the host
|
39
|
+
# @return [String, nil] The generated URL
|
3
40
|
def attachment_url(record, name, *args, filename: nil, format: nil, host: nil)
|
4
|
-
|
41
|
+
attacher = record.send(:"#{name}_attacher")
|
42
|
+
file = attacher.get
|
5
43
|
return unless file
|
6
44
|
|
7
|
-
filename ||= name.to_s
|
45
|
+
filename ||= attacher.basename || name.to_s
|
46
|
+
format ||= attacher.extension
|
8
47
|
|
9
48
|
backend_name = Refile.backends.key(file.backend)
|
10
49
|
host = host || Refile.host || request.base_url
|
@@ -15,6 +54,16 @@ module Refile
|
|
15
54
|
::File.join(host, main_app.refile_app_path, backend_name, *args.map(&:to_s), file.id.to_s, filename)
|
16
55
|
end
|
17
56
|
|
57
|
+
# Generates an image tag for the given attachment, adding appropriate
|
58
|
+
# classes and optionally falling back to the given fallback image if there
|
59
|
+
# is no file attached.
|
60
|
+
#
|
61
|
+
# Returns `nil` if there is no file attached and no fallback specified.
|
62
|
+
#
|
63
|
+
# @param [String] fallback The path to an image asset to be used as a fallback
|
64
|
+
# @param [Hash] options Additional options for the image tag
|
65
|
+
# @see #attachment_url
|
66
|
+
# @return [ActiveSupport::SafeBuffer, nil] The generated image tag
|
18
67
|
def attachment_image_tag(record, name, *args, fallback: nil, format: nil, host: nil, **options)
|
19
68
|
file = record.send(name)
|
20
69
|
classes = ["attachment", record.class.model_name.singular, name, *options[:class]]
|
@@ -27,29 +76,38 @@ module Refile
|
|
27
76
|
end
|
28
77
|
end
|
29
78
|
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
79
|
+
# Generates a form field which can be used with records which have
|
80
|
+
# attachments. This will generate both a file field as well as a hidden
|
81
|
+
# field which tracks the id of the file in the cache before it is
|
82
|
+
# permanently stored.
|
83
|
+
#
|
84
|
+
# @param object_name The name of the object to generate a field for
|
85
|
+
# @param method The name of the field
|
86
|
+
# @param [Hash] options
|
87
|
+
# @option options [Object] object Set by the form builder, currently required for direct/presigned uploads to work.
|
88
|
+
# @option options [Boolean] direct If set to true, adds the appropriate data attributes for direct uploads with refile.js.
|
89
|
+
# @option options [Boolean] presign If set to true, adds the appropriate data attributes for presigned uploads with refile.js.
|
90
|
+
# @return [ActiveSupport::SafeBuffer] The generated form field
|
91
|
+
def attachment_field(object_name, method, object:, **options)
|
33
92
|
options[:data] ||= {}
|
34
93
|
|
35
|
-
|
36
|
-
|
37
|
-
options[:accept] = attacher.accept
|
94
|
+
attacher = object.send(:"#{method}_attacher")
|
95
|
+
options[:accept] = attacher.accept
|
38
96
|
|
39
|
-
|
40
|
-
|
41
|
-
|
97
|
+
if options[:direct]
|
98
|
+
host = options[:host] || Refile.host || request.base_url
|
99
|
+
backend_name = Refile.backends.key(attacher.cache)
|
42
100
|
|
43
|
-
|
44
|
-
|
45
|
-
|
101
|
+
url = ::File.join(host, main_app.refile_app_path, backend_name)
|
102
|
+
options[:data].merge!(direct: true, as: "file", url: url)
|
103
|
+
end
|
46
104
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
105
|
+
if options[:presigned] and attacher.cache.respond_to?(:presign)
|
106
|
+
options[:data].merge!(direct: true).merge!(attacher.cache.presign.as_json)
|
50
107
|
end
|
51
|
-
|
52
|
-
|
108
|
+
|
109
|
+
html = hidden_field(object_name, method, value: attacher.data.to_json, object: object)
|
110
|
+
html + file_field(object_name, method, options)
|
53
111
|
end
|
54
112
|
end
|
55
113
|
end
|