mini_paperclip 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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