mini_paperclip 0.1.2 → 0.2.0

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
  SHA256:
3
- metadata.gz: 29ef73b42c1c7ef6755a3af5907bab7f285f7fdacb4a6d15d283366d4f46d073
4
- data.tar.gz: 877efe3a37db1c2f888df9785ad84bc4220507cfc970ec8bc3632ad3bf5908b2
3
+ metadata.gz: cda880f15d0e468fe2e0468658dbd11bf52a933e79f936fdc1a16ade88536e79
4
+ data.tar.gz: 9bf633f6dd48be4fc3f41b4539568039ab710a0a61e43e47ea297221599588af
5
5
  SHA512:
6
- metadata.gz: 0a2395e2c209b4dcee1d518d87bcc972b2c253530edd1926800f2b1e0ab1fc9ab2b3b21c0760248e54d14ea0d74c41e8045d9717870947368e0ca5395d577ec7
7
- data.tar.gz: a4dead2af2ebb2c0146b37196b4344683039ba302b0c174a9371b458e4121dd3b4613b5b00622f1d2171c0561d63d44297f5b17d1452b0a817f874c87d108ff5
6
+ metadata.gz: e0fd8c9651b0bfbb7e9c79faf6476644983a56256ebe856fdb0e379e97b6f35e5b30ec64ab2d8dc474f3f5617965b0bf598d48d712bf211d9d8c30d3162d4697
7
+ data.tar.gz: 35aeb9655dc45afd56b72ad0e98659218035a26494a345af6352a505d123945c113f1947946341c526e8a2314b6ea2974dd6c2678142105dd4f6e6a459d31d3e
@@ -62,63 +62,24 @@ module MiniPaperclip
62
62
  @meta_content_type = nil
63
63
 
64
64
  if file.nil?
65
- # clear
66
- @record.write_attribute("#{@attachment_name}_file_name", nil)
67
- @record.write_attribute("#{@attachment_name}_content_type", nil)
68
- @record.write_attribute("#{@attachment_name}_file_size", nil)
69
- @record.write_attribute("#{@attachment_name}_updated_at", nil)
65
+ assign_nil
70
66
  elsif file.instance_of?(Attachment)
71
- # copy
72
- @record.write_attribute("#{@attachment_name}_file_name", file.record.read_attribute("#{@attachment_name}_file_name"))
73
- @record.write_attribute("#{@attachment_name}_content_type", file.record.read_attribute("#{@attachment_name}_content_type"))
74
- @record.write_attribute("#{@attachment_name}_file_size", file.record.read_attribute("#{@attachment_name}_file_size"))
75
- @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
76
- @waiting_copy_attachment = file
67
+ if file.present?
68
+ assign_attachment(file)
69
+ else
70
+ assign_nil
71
+ end
77
72
  elsif file.respond_to?(:original_filename)
78
- # e.g. ActionDispatch::Http::UploadedFile
79
- @record.write_attribute("#{@attachment_name}_file_name", file.original_filename)
80
- @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(file.to_io))
81
- @record.write_attribute("#{@attachment_name}_file_size", file.size)
82
- @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
83
- @waiting_write_file = build_tempfile(file.tap(&:rewind))
84
- @meta_content_type = file.content_type
73
+ assign_uploaded_file(file)
85
74
  elsif file.respond_to?(:path)
86
- # e.g. File
87
- @record.write_attribute("#{@attachment_name}_file_name", File.basename(file.path))
88
- @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(file))
89
- @record.write_attribute("#{@attachment_name}_file_size", file.size)
90
- @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
91
- @waiting_write_file = build_tempfile(file.tap(&:rewind))
75
+ assign_file(file)
92
76
  elsif file.instance_of?(String)
93
77
  if file.empty?
94
78
  # do nothing
95
79
  elsif file.start_with?('http')
96
- # download from url
97
- open_uri_option = {
98
- read_timeout: MiniPaperclip.config.read_timeout || 60
99
- }
100
- uri = URI.parse(file)
101
- uri.open(open_uri_option) do |io|
102
- @record.write_attribute("#{@attachment_name}_file_name", File.basename(uri.path))
103
- @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(io))
104
- @record.write_attribute("#{@attachment_name}_file_size", io.size)
105
- @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
106
- @waiting_write_file = build_tempfile(io.tap(&:rewind))
107
- @meta_content_type = io.meta["content-type"]
108
- end
80
+ assign_http(file)
109
81
  elsif file.start_with?('data:')
110
- # data-uri
111
- match_data = file.match(/\Adata:([-\w]+\/[-\w\+\.]+)?;base64,(.*)/m)
112
- if match_data.nil?
113
- raise UnsupportedError, "attachment for \"#{file[0..100]}\" is not supported"
114
- end
115
- raw = Base64.decode64(match_data[2])
116
- @record.write_attribute("#{@attachment_name}_file_name", nil)
117
- @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(StringIO.new(raw)))
118
- @record.write_attribute("#{@attachment_name}_file_size", raw.bytesize)
119
- @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
120
- @waiting_write_file = build_tempfile(StringIO.new(raw))
121
- @meta_content_type = match_data[1]
82
+ assign_data_uri(file)
122
83
  else
123
84
  raise UnsupportedError, "attachment for \"#{file[0..100]}\" is not supported"
124
85
  end
@@ -129,26 +90,18 @@ module MiniPaperclip
129
90
 
130
91
  def process_and_store
131
92
  return unless file?
132
-
133
- if @waiting_copy_attachment
134
- debug("start attachment copy")
135
- @storage.copy(:original, @waiting_copy_attachment)
136
- @config.styles&.each do |style, size_arg|
137
- @storage.copy(style, @waiting_copy_attachment)
138
- end
139
- @waiting_copy_attachment = nil
140
- return
141
- end
142
-
143
- return if @waiting_write_file.nil?
93
+ return unless @waiting_write_file
144
94
 
145
95
  begin
146
96
  debug("start attachment styles process")
147
97
  @storage.write(:original, @waiting_write_file)
148
98
  @config.styles&.each do |style, size_arg|
149
99
  Tempfile.create([style.to_s, File.extname(@waiting_write_file.path)]) do |temp|
100
+ temp.binmode
150
101
  MiniMagick::Tool::Convert.new do |convert|
151
102
  convert << @waiting_write_file.path
103
+ convert.coalesce if animated?
104
+ convert.auto_orient
152
105
  if size_arg.end_with?('#')
153
106
  # crop option
154
107
  convert.resize("#{size_arg[0..-2]}^")
@@ -157,13 +110,18 @@ module MiniPaperclip
157
110
  else
158
111
  convert.resize(size_arg)
159
112
  end
113
+ convert.layers("optimize") if animated?
160
114
  convert << temp.path
161
115
  end
162
116
  @storage.write(style, temp)
163
117
  end
164
118
  end
165
119
  ensure
166
- @waiting_write_file.close!
120
+ if @waiting_write_file.respond_to?(:close!)
121
+ @waiting_write_file.close!
122
+ elsif @waiting_write_file.respond_to?(:close)
123
+ @waiting_write_file.close
124
+ end
167
125
  end
168
126
  @waiting_write_file = nil
169
127
  end
@@ -179,9 +137,81 @@ module MiniPaperclip
179
137
  @storage.do_delete_files
180
138
  end
181
139
 
140
+ def animated?
141
+ content_type == 'image/gif'
142
+ end
143
+
182
144
  private
183
145
 
146
+ def assign_nil
147
+ # clear
148
+ @record.write_attribute("#{@attachment_name}_file_name", nil)
149
+ @record.write_attribute("#{@attachment_name}_content_type", nil)
150
+ @record.write_attribute("#{@attachment_name}_file_size", nil)
151
+ @record.write_attribute("#{@attachment_name}_updated_at", nil)
152
+ end
153
+
154
+ def assign_attachment(attachment)
155
+ # copy
156
+ @waiting_write_file = attachment.storage.open(:original)
157
+ @record.write_attribute("#{@attachment_name}_file_name", attachment.original_filename)
158
+ @record.write_attribute("#{@attachment_name}_content_type", attachment.content_type)
159
+ @record.write_attribute("#{@attachment_name}_file_size", attachment.size)
160
+ @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
161
+ end
162
+
163
+ def assign_uploaded_file(file)
164
+ # e.g. ActionDispatch::Http::UploadedFile
165
+ @record.write_attribute("#{@attachment_name}_file_name", file.original_filename)
166
+ @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(file.to_io))
167
+ @record.write_attribute("#{@attachment_name}_file_size", file.size)
168
+ @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
169
+ @waiting_write_file = build_tempfile(file.tap(&:rewind))
170
+ @meta_content_type = file.content_type
171
+ end
172
+
173
+ def assign_file(file)
174
+ # e.g. File
175
+ @record.write_attribute("#{@attachment_name}_file_name", File.basename(file.path))
176
+ @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(file))
177
+ @record.write_attribute("#{@attachment_name}_file_size", file.size)
178
+ @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
179
+ @waiting_write_file = build_tempfile(file.tap(&:rewind))
180
+ end
181
+
182
+ def assign_http(url)
183
+ # download from url
184
+ open_uri_option = {
185
+ read_timeout: MiniPaperclip.config.read_timeout || 60
186
+ }
187
+ uri = URI.parse(url)
188
+ uri.open(open_uri_option) do |io|
189
+ @record.write_attribute("#{@attachment_name}_file_name", File.basename(uri.path))
190
+ @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(io))
191
+ @record.write_attribute("#{@attachment_name}_file_size", io.size)
192
+ @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
193
+ @waiting_write_file = build_tempfile(io.tap(&:rewind))
194
+ @meta_content_type = io.meta["content-type"]
195
+ end
196
+ end
197
+
198
+ def assign_data_uri(data_uri)
199
+ # data-uri
200
+ match_data = data_uri.match(/\Adata:([-\w]+\/[-\w\+\.]+)?;base64,(.*)/m)
201
+ if match_data.nil?
202
+ raise UnsupportedError, "attachment for \"#{data_uri[0..100]}\" is not supported"
203
+ end
204
+ raw = Base64.decode64(match_data[2])
205
+ @record.write_attribute("#{@attachment_name}_file_name", nil)
206
+ @record.write_attribute("#{@attachment_name}_content_type", strict_content_type(StringIO.new(raw)))
207
+ @record.write_attribute("#{@attachment_name}_file_size", raw.bytesize)
208
+ @record.write_attribute("#{@attachment_name}_updated_at", Time.current)
209
+ @waiting_write_file = build_tempfile(StringIO.new(raw))
210
+ @meta_content_type = match_data[1]
211
+ end
212
+
184
213
  def strict_content_type(io)
214
+ io.rewind
185
215
  MimeMagic.by_magic(io)&.type
186
216
  end
187
217
 
@@ -96,6 +96,7 @@ module MiniPaperclip
96
96
 
97
97
  def create_dummy_image(width:, height:)
98
98
  Tempfile.create(['MiniPaperclip::Shoulda::Matchers::ValidateAttachmentGeometryMatcher', ".#{@format}"]) do |f|
99
+ f.binmode
99
100
  MiniMagick::Tool::Convert.new do |convert|
100
101
  convert.size("#{width}x#{height}")
101
102
  convert.xc("none")
@@ -5,17 +5,9 @@ module MiniPaperclip
5
5
  class Filesystem < Base
6
6
  def write(style, file)
7
7
  path = file_path(style)
8
- debug("writing by filesystem to #{path}")
8
+ debug("writing by filesystem from:#{file.path} to:#{path}")
9
9
  FileUtils.mkdir_p(File.dirname(path))
10
- FileUtils.cp(file.path, path)
11
- end
12
-
13
- def copy(style, from_attachment)
14
- raise "not supported" unless from_attachment.storage.instance_of?(Filesystem)
15
- to_path = file_path(style)
16
- from_path = from_attachment.storage.file_path(style)
17
- debug("copying by filesystem from:#{from_path} to:#{to_path}")
18
- FileUtils.cp(from_path, to_path)
10
+ FileUtils.cp(file.path, path) if file.path != path
19
11
  end
20
12
 
21
13
  def file_path(style)
@@ -38,6 +30,10 @@ module MiniPaperclip
38
30
  debug("deleting by filesystem #{@deletes}")
39
31
  FileUtils.rm_f(@deletes)
40
32
  end
33
+
34
+ def open(style, &block)
35
+ File.open(file_path(style), 'r', &block)
36
+ end
41
37
  end
42
38
  end
43
39
  end
@@ -15,19 +15,6 @@ module MiniPaperclip
15
15
  )
16
16
  end
17
17
 
18
- def copy(style, from_attachment)
19
- raise "not supported yet" unless from_attachment.storage.instance_of?(S3)
20
- debug("copying by S3 to bucket:#{@config.s3_bucket_name},key:#{s3_object_key(style)}")
21
- Aws::S3::Client.new.copy_object(
22
- acl: @config.s3_acl,
23
- cache_control: @config.s3_cache_control,
24
- content_type: @attachment.content_type,
25
- copy_source: from_attachment.storage.object_key(style),
26
- bucket: @config.s3_bucket_name,
27
- key: s3_object_key(style),
28
- )
29
- end
30
-
31
18
  def s3_object_key(style)
32
19
  interpolate(@config.url_path, style)
33
20
  end
@@ -61,6 +48,18 @@ module MiniPaperclip
61
48
  }
62
49
  )
63
50
  end
51
+
52
+ def open(style)
53
+ Tempfile.new(['MiniPaperclip::Storage::S3']).tap do |response_target|
54
+ response_target.binmode
55
+ Aws::S3::Client.new.get_object(
56
+ bucket: @config.s3_bucket_name,
57
+ key: s3_object_key(style),
58
+ response_target: response_target,
59
+ )
60
+ yield response_target if block_given?
61
+ end
62
+ end
64
63
  end
65
64
  end
66
65
  end
@@ -23,9 +23,13 @@ module MiniPaperclip
23
23
  # height: { less_than_or_equal_to: 3000 } }
24
24
  def validate_each(record, attribute, value)
25
25
  return unless value.waiting_write_file
26
+ value.waiting_write_file.rewind
26
27
  image_size = ImageSize.new(value.waiting_write_file)
27
28
  # invalid format should not relate geometry
28
- return unless image_size.format
29
+ unless image_size.format
30
+ MiniPaperclip.config.logger.info("[mini_paperclip] cannot get image_size from #{value.waiting_write_file.inspect}")
31
+ return
32
+ end
29
33
 
30
34
  expected_width_less_than_or_equal_to = options.dig(:width, :less_than_or_equal_to)
31
35
  expected_height_less_than_or_equal_to = options.dig(:height, :less_than_or_equal_to)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniPaperclip
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_paperclip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-03 00:00:00.000000000 Z
11
+ date: 2020-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_magick
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  - !ruby/object:Gem::Version
160
160
  version: '0'
161
161
  requirements: []
162
- rubygems_version: 3.1.2
162
+ rubygems_version: 3.0.3
163
163
  signing_key:
164
164
  specification_version: 4
165
165
  summary: MiniPaperclip is a mini paperclip