This repository has been archived by the owner on Jul 13, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
file_adapter.rb
83 lines (69 loc) · 1.94 KB
/
file_adapter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
module Paperclip
class FileAdapter
def initialize(target)
@target = target
@tempfile = copy_to_tempfile(@target)
end
def original_filename
if @target.respond_to?(:original_filename)
@target.original_filename
else
File.basename(@target.path)
end
end
def content_type
types = MIME::Types.type_for(original_filename)
if types.length == 0
type_from_file_command
elsif types.length == 1
types.first.content_type
else
best_content_type_option(types)
end
end
def fingerprint
@fingerprint ||= Digest::MD5.file(path).to_s
end
def size
File.size(@tempfile)
end
def nil?
@target.nil?
end
def read(length = nil, buffer = nil)
@tempfile.read(length, buffer)
end
# We don't use this directly, but aws/sdk does.
def rewind
@tempfile.rewind
end
def eof?
@tempfile.eof?
end
def path
@tempfile.path
end
private
def copy_to_tempfile(src)
extension = File.extname(original_filename)
basename = File.basename(original_filename, extension)
dest = Tempfile.new([basename, extension])
dest.binmode
FileUtils.cp(src.path, dest.path)
dest
end
def best_content_type_option(types)
types.reject {|type| type.content_type.match(/\/x-/) }.first.content_type
end
def type_from_file_command
# On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
mime_type = (Paperclip.run("file", "-b --mime :file", :file => self.path).split(/[:;\s]+/)[0] rescue "application/x-#{type}")
mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/)
mime_type
end
end
end
Paperclip.io_adapters.register Paperclip::FileAdapter do |target|
File === target || Tempfile === target
end