activestorage-delayed 0.1.4 → 0.3.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: 76f19f1856294d83f52a92dbbc1ea9eb52c216c021726437ff513727426c65e4
4
- data.tar.gz: 923f537ec4dbbfd797c72157f46b58a1a1f20f04127f53034f444fd6a2cd8ac2
3
+ metadata.gz: 621bd6e1ad3690b81dfcd6d12ef466046db31741cca14fb529a6d0c0f6fb4089
4
+ data.tar.gz: ef77110cf9d92f5247f2bff431bb2f89507d69709001c063cf3db0ffa017a2ec
5
5
  SHA512:
6
- metadata.gz: ea37e642bef6ef9ba231b0bc0b2c8c1676b569679be5373bd45cd5f6cbd7f8aff4d1ac3642e1f6853fddf8e46f55f19293a38cf9fee4a60061b671c5cb27a3b0
7
- data.tar.gz: 80d2123dec2953c7c8778e0f7fa9449e73b7f25625863e05f0edaf5c07e3c6782c3e4b44f824c14ab61bb3dc03a834ec94c6eebc340b298fb7061d11f02208fe
6
+ metadata.gz: add4b74f833f2dc0c3a39a82c7750cdb1a38d4d1ef98abc9affd3189e8f010d82d495c03452edb5c502e06938abd64ab7bfd40b8d6ce4b1eee514bcb18d7d2c8
7
+ data.tar.gz: 372c5fe7906804d59a60281a130e6f697a21a96644ae592622b0a1dbe69c4b5943aaf9006958f804800c95190c45ef15a61d91ba6595b6901a7b5e9e5258ab75
@@ -10,40 +10,63 @@
10
10
  <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
11
11
  <excludeFolder url="file://$MODULE_DIR$/spec/dummy/tmp/cache" />
12
12
  </content>
13
- <orderEntry type="jdk" jdkName="Remote: ruby-2.5.9-p229" jdkType="RUBY_SDK" />
13
+ <orderEntry type="jdk" jdkName="Remote: ruby-3.1.1-p18" jdkType="RUBY_SDK" />
14
14
  <orderEntry type="sourceFolder" forTests="false" />
15
- <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, Remote: ruby-2.5.9-p229) [gem]" level="application" />
16
- <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.4, Remote: ruby-2.5.9-p229) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="bundler (v2.3.10, Remote: ruby-2.5.9-p229) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.10, Remote: ruby-2.5.9-p229) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="crass (v1.0.6, Remote: ruby-2.5.9-p229) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.5.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="erubi (v1.10.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="factory_bot (v6.2.1, Remote: ruby-2.5.9-p229) [gem]" level="application" />
23
- <orderEntry type="library" scope="PROVIDED" name="factory_bot_rails (v6.2.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
24
- <orderEntry type="library" scope="PROVIDED" name="globalid (v1.0.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
25
- <orderEntry type="library" scope="PROVIDED" name="i18n (v1.10.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
26
- <orderEntry type="library" scope="PROVIDED" name="mail (v2.7.1, Remote: ruby-2.5.9-p229) [gem]" level="application" />
27
- <orderEntry type="library" scope="PROVIDED" name="marcel (v1.0.2, Remote: ruby-2.5.9-p229) [gem]" level="application" />
28
- <orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
29
- <orderEntry type="library" scope="PROVIDED" name="mini_mime (v1.1.2, Remote: ruby-2.5.9-p229) [gem]" level="application" />
30
- <orderEntry type="library" scope="PROVIDED" name="minitest (v5.15.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
31
- <orderEntry type="library" scope="PROVIDED" name="nio4r (v2.5.8, Remote: ruby-2.5.9-p229) [gem]" level="application" />
32
- <orderEntry type="library" scope="PROVIDED" name="racc (v1.6.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
33
- <orderEntry type="library" scope="PROVIDED" name="rack (v2.2.3, Remote: ruby-2.5.9-p229) [gem]" level="application" />
34
- <orderEntry type="library" scope="PROVIDED" name="rack-test (v1.1.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
35
- <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, Remote: ruby-2.5.9-p229) [gem]" level="application" />
36
- <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.4.2, Remote: ruby-2.5.9-p229) [gem]" level="application" />
37
- <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, Remote: ruby-2.5.9-p229) [gem]" level="application" />
38
- <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, Remote: ruby-2.5.9-p229) [gem]" level="application" />
39
- <orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.5, Remote: ruby-2.5.9-p229) [gem]" level="application" />
40
- <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.11.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
41
- <orderEntry type="library" scope="PROVIDED" name="thor (v1.2.1, Remote: ruby-2.5.9-p229) [gem]" level="application" />
42
- <orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.4, Remote: ruby-2.5.9-p229) [gem]" level="application" />
43
- <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.1.0, Remote: ruby-2.5.9-p229) [gem]" level="application" />
44
- <orderEntry type="library" scope="PROVIDED" name="websocket-driver (v0.7.5, Remote: ruby-2.5.9-p229) [gem]" level="application" />
45
- <orderEntry type="library" scope="PROVIDED" name="websocket-extensions (v0.1.5, Remote: ruby-2.5.9-p229) [gem]" level="application" />
46
- <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.5.4, Remote: ruby-2.5.9-p229) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="actioncable (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="actionmailbox (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="actionmailer (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="actionpack (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="actiontext (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="actionview (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="activejob (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="activemodel (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="activerecord (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="activestorage (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
26
+ <orderEntry type="library" scope="PROVIDED" name="addressable (v2.8.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
27
+ <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, Remote: ruby-3.1.1-p18) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.4, Remote: ruby-3.1.1-p18) [gem]" level="application" />
29
+ <orderEntry type="library" scope="PROVIDED" name="byebug (v11.1.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
30
+ <orderEntry type="library" scope="PROVIDED" name="capybara (v3.36.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
31
+ <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.10, Remote: ruby-3.1.1-p18) [gem]" level="application" />
32
+ <orderEntry type="library" scope="PROVIDED" name="crass (v1.0.6, Remote: ruby-3.1.1-p18) [gem]" level="application" />
33
+ <orderEntry type="library" scope="PROVIDED" name="database_cleaner-active_record (v2.0.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
34
+ <orderEntry type="library" scope="PROVIDED" name="database_cleaner-core (v2.0.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
35
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.5.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="digest (v3.1.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="erubi (v1.10.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="factory_bot_rails (v6.2.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
39
+ <orderEntry type="library" scope="PROVIDED" name="globalid (v1.0.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
40
+ <orderEntry type="library" scope="PROVIDED" name="i18n (v1.10.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
41
+ <orderEntry type="library" scope="PROVIDED" name="mail (v2.7.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
42
+ <orderEntry type="library" scope="PROVIDED" name="marcel (v1.0.2, Remote: ruby-3.1.1-p18) [gem]" level="application" />
43
+ <orderEntry type="library" scope="PROVIDED" name="matrix (v0.4.2, Remote: ruby-3.1.1-p18) [gem]" level="application" />
44
+ <orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
45
+ <orderEntry type="library" scope="PROVIDED" name="mini_mime (v1.1.2, Remote: ruby-3.1.1-p18) [gem]" level="application" />
46
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.15.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
47
+ <orderEntry type="library" scope="PROVIDED" name="net-imap (v0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
48
+ <orderEntry type="library" scope="PROVIDED" name="net-pop (v0.1.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
49
+ <orderEntry type="library" scope="PROVIDED" name="net-smtp (v0.3.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
50
+ <orderEntry type="library" scope="PROVIDED" name="nio4r (v2.5.8, Remote: ruby-3.1.1-p18) [gem]" level="application" />
51
+ <orderEntry type="library" scope="PROVIDED" name="racc (v1.6.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
52
+ <orderEntry type="library" scope="PROVIDED" name="rack (v2.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
53
+ <orderEntry type="library" scope="PROVIDED" name="rack-test (v1.1.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
54
+ <orderEntry type="library" scope="PROVIDED" name="rails (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
55
+ <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
56
+ <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.4.2, Remote: ruby-3.1.1-p18) [gem]" level="application" />
57
+ <orderEntry type="library" scope="PROVIDED" name="railties (v7.0.2.3, Remote: ruby-3.1.1-p18) [gem]" level="application" />
58
+ <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
59
+ <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, Remote: ruby-3.1.1-p18) [gem]" level="application" />
60
+ <orderEntry type="library" scope="PROVIDED" name="rbs (v2.1.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
61
+ <orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.5, Remote: ruby-3.1.1-p18) [gem]" level="application" />
62
+ <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.11.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
63
+ <orderEntry type="library" scope="PROVIDED" name="thor (v1.2.1, Remote: ruby-3.1.1-p18) [gem]" level="application" />
64
+ <orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.4, Remote: ruby-3.1.1-p18) [gem]" level="application" />
65
+ <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.1.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
66
+ <orderEntry type="library" scope="PROVIDED" name="websocket-driver (v0.7.5, Remote: ruby-3.1.1-p18) [gem]" level="application" />
67
+ <orderEntry type="library" scope="PROVIDED" name="websocket-extensions (v0.1.5, Remote: ruby-3.1.1-p18) [gem]" level="application" />
68
+ <orderEntry type="library" scope="PROVIDED" name="xpath (v3.2.0, Remote: ruby-3.1.1-p18) [gem]" level="application" />
69
+ <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.5.4, Remote: ruby-3.1.1-p18) [gem]" level="application" />
47
70
  </component>
48
71
  <component name="RakeTasksCache">
49
72
  <option name="myRootTask">
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- activestorage-delayed (0.1.3)
4
+ activestorage-delayed (0.2.0)
5
5
  activestorage
6
6
  rails
7
7
 
data/README.md CHANGED
@@ -39,7 +39,7 @@ Note: This gem assumes that the app has already configured activestorage.
39
39
  class User < ApplicationRecord
40
40
  include ActivestorageDelayed::DelayedConcern
41
41
 
42
- has_one_attached :photo, required: true, use_filename: true
42
+ has_one_attached :photo, required: true, use_filename: true, variant_info: { resize_to_fit: [400, 400], convert: 'jpg' }
43
43
  delayed_attach :photo
44
44
 
45
45
  has_many_attached :certificates
@@ -50,6 +50,7 @@ end
50
50
  ### `delayed_attach` accepts an optional hash with the following options:
51
51
  - `required`: If set to `true`, the `photo` or the `photo_tmp` will be required before saving.
52
52
  - `use_filename`: If set to `true`, the image filename will be used as the name of uploaded file instead of the hash-key used by `activestorage`
53
+ - `variant_info`: (Hash) Variant information to be performed before uploading the file.
53
54
 
54
55
  ### Examples to upload files in background
55
56
  - Upload a single file
@@ -90,7 +91,7 @@ end
90
91
  User.first.update(certificates_tmp: { clean_before: true, files: [File.open('my_file.png')] })
91
92
  ```
92
93
 
93
- - Upload files with custom names (requires `use_filename: true`)
94
+ - Upload files with custom names (requires `use_filename: true`): `<attr_name>_filename`
94
95
  ```ruby
95
96
  class User < ApplicationRecord
96
97
  def photo_filename(filename)
@@ -101,42 +102,34 @@ end
101
102
  When `<attr_name>_filename` is defined, then it is called to fetch the uploaded file name.
102
103
  Note: Check [this](https://gist.github.com/owen2345/33730a452d73b6b292326bb602b0ee6b) if you want to rename an already uploaded file (remote file)
103
104
 
104
- - Capture event when file upload has failed
105
+ - Capture event when file upload has failed: `<attr_name>_error_upload`
105
106
  ```ruby
106
107
  class User < ApplicationRecord
107
- def ast_delayed_on_error(attr_name, error)
108
- puts "Failed #{attr_name} with #{error}"
108
+ # @param error [StandardError]
109
+ # @param file_data [Hash<'filename'>]
110
+ def photo_error_upload(error, file_data)
111
+ puts "Failed uploading photo #{file_data['filename']}: #{error.message}"
109
112
  end
110
113
  end
111
114
  ```
112
115
 
113
- - Capture event when file has been uploaded
116
+ - Capture event when file has been uploaded: `<attr_name>_after_upload`
114
117
  ```ruby
115
118
  class User < ApplicationRecord
116
- after_save_commit do
117
- puts 'Photo has been uploaded' if photo.blob.present?
118
- puts 'No pending enqueued photo uploads' unless photo_delayed_uploads.any?
119
+ # @param file_data [Hash<'filename'>]
120
+ def photo_after_upload(file_data)
121
+ puts "Photo #{file_data['filename']} has been uploaded"
119
122
  end
120
-
121
- before_save do
122
- puts "current assigned tmp photo: #{photo_tmp.inspect}"
123
+
124
+ def photo_after_upload_all
125
+ puts "All photos have been uploaded"
123
126
  end
124
127
  end
125
128
  ```
129
+
130
+ Note:
126
131
  `<attr_name>_delayed_uploads` is a `has_many` association that contains the list of scheduled uploads for the corresponding attribute.
127
132
 
128
-
129
- ## Preprocessing original files before uploading (Rails 7+)
130
- ```ruby
131
- class User < ApplicationRecord
132
- has_one_attached :photo do |attachable|
133
- attachable.variant :default, strip: true, quality: 70, resize_to_fill: [200, 200]
134
- end
135
- end
136
- ```
137
- `:default` variant will be used to pre-preprocess the original file before uploading (if defined). By this way you have your desired image size and quality as the original image.
138
-
139
-
140
133
 
141
134
  ## Contributing
142
135
  Bug reports and pull requests are welcome on https://github.com/owen2345/activestorage-delayed. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -3,10 +3,14 @@
3
3
  module ActivestorageDelayed
4
4
  module DelayedConcern
5
5
  extend ActiveSupport::Concern
6
- included do
6
+ included do # rubocop:disable Metrics/BlockLength
7
7
  @ast_delayed_settings = {}
8
- def self.delayed_attach(attr_name, required: false, use_filename: false) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
9
- @ast_delayed_settings[attr_name] = { use_filename: use_filename }
8
+
9
+ # @param settings (Hash)
10
+ # use_filename: (Boolean)
11
+ # variant_info: (Hash) Sample: { resize_to_fit: [400, 400], convert: 'jpg' }
12
+ def self.delayed_attach(attr_name, required: false, **settings) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
13
+ @ast_delayed_settings[attr_name] = settings
10
14
  tmp_attr_name = :"#{attr_name}_tmp"
11
15
  has_many_attr = :"#{attr_name}_delayed_uploads"
12
16
  attr_accessor tmp_attr_name
@@ -27,11 +31,27 @@ module ActivestorageDelayed
27
31
  delayed_data[:attr_name] = attr_name
28
32
  send(has_many_attr) << send(has_many_attr).new(delayed_data)
29
33
  end
34
+
35
+ # @param filename (String) File name
36
+ define_method "#{attr_name}_filename" do |filename|
37
+ name = File.basename(filename, '.*').parameterize
38
+ is_multiple = send(attr_name).class.name.include?('Many')
39
+ name = "#{SecureRandom.uuid}-#{name}" if is_multiple
40
+ "#{send(:id)}-#{name}#{File.extname(filename)}"
41
+ end
42
+
43
+ # @param _file_data [Hash<'filename'>]
44
+ define_method "#{attr_name}_after_upload" do |_file_data|
45
+ end
46
+
47
+ define_method "#{attr_name}_after_upload_all" do
48
+ end
49
+
50
+ # @param _error (Exception)
51
+ # @param _file_data [Hash<'filename'>]
52
+ define_method "#{attr_name}_error_upload" do |_error, _file_data|
53
+ end
30
54
  end
31
55
  end
32
-
33
- # @param _attr_name (String)
34
- # @param _error (Exception)
35
- def ast_delayed_on_error(_attr_name, _error); end
36
56
  end
37
57
  end
@@ -13,22 +13,31 @@ module ActivestorageDelayed
13
13
  return unless delayed_upload
14
14
 
15
15
  remove_files
16
- save_changes if upload_photos
16
+ upload_photos
17
+ save_changes
17
18
  end
18
19
 
19
20
  private
20
21
 
21
- # TODO: check the ability to delete io with save or upload method
22
- # file_data['io'].close
23
- def upload_photos # rubocop:disable Metrics/AbcSize
24
- tmp_files_data.each do |file_data|
22
+ def upload_photos
23
+ tmp_files_data.each(&method(:upload_photo))
24
+ model.send("#{attr_name}_after_upload_all")
25
+ end
26
+
27
+ def upload_photo(file_data)
28
+ parse_file_io(file_data) do |io|
29
+ file_data['io'] = io
25
30
  model.send(attr_name).attach(file_data.transform_keys(&:to_sym))
31
+ model.send("#{attr_name}_after_upload", file_data)
32
+ rescue => e # rubocop:disable Style/RescueStandardError
33
+ print_failure(e, file_data)
26
34
  end
27
- true
28
- rescue => e # rubocop:disable Style/RescueStandardError
29
- Rails.logger.error("********* #{self.class.name} -> Failed uploading files: #{e.message}. #{e.backtrace[0..20]}")
30
- model.ast_delayed_on_error(attr_name, e)
31
- false
35
+ end
36
+
37
+ def print_failure(error, file_data = {})
38
+ details = "#{error.message}. #{error.backtrace[0..20]}"
39
+ Rails.logger.error("***#{self.class.name} -> Failed uploading file (#{file_data['filename']}): #{details}")
40
+ model.send("#{attr_name}_error_upload", error, file_data)
32
41
  end
33
42
 
34
43
  def save_changes
@@ -36,12 +45,11 @@ module ActivestorageDelayed
36
45
  delayed_upload.destroy!
37
46
  end
38
47
 
39
- # @return [Array<Hash<io: StringIO, filename: String, content_type: String>]
48
+ # @return [Array<Hash<io: StringIO, filename: String, content_type: String>>]
40
49
  def tmp_files_data
41
50
  @tmp_files_data ||= begin
42
51
  files = JSON.parse(delayed_upload.files || '[]')
43
52
  files.each do |file_data|
44
- file_data['io'] = base64_to_file(file_data)
45
53
  if attr_settings[:use_filename]
46
54
  file_data['key'] = filename_for(file_data['filename'])
47
55
  file_data['filename'] = file_data['key']
@@ -50,12 +58,22 @@ module ActivestorageDelayed
50
58
  end
51
59
  end
52
60
 
53
- def base64_to_file(file_data)
54
- tempfile = Tempfile.new(file_data['filename'])
55
- tempfile.binmode
61
+ def parse_file_io(file_data, &block)
62
+ tempfile = Tempfile.new(file_data['filename'], binmode: true)
56
63
  tempfile.write Base64.decode64(file_data['io'])
57
64
  tempfile.rewind
58
- tempfile
65
+ transform_variation(tempfile, attr_settings[:variant_info]) do |io|
66
+ block.call(io)
67
+ tempfile.close
68
+ end
69
+ end
70
+
71
+ # @param io [StringIO, File]
72
+ # @param variant_info [Hash, Nil] ActiveStorage variant info. Sample: { resize_to_fit: [400, 400], convert: 'jpg' }
73
+ def transform_variation(io, variant_info, &block)
74
+ return block.call(io) unless variant_info
75
+
76
+ ActiveStorage::Variation.wrap(variant_info).transform(io, &block)
59
77
  end
60
78
 
61
79
  def model
@@ -64,11 +82,7 @@ module ActivestorageDelayed
64
82
 
65
83
  def filename_for(filename)
66
84
  method_name = "#{attr_name}_filename".to_sym
67
- return model.send(method_name, filename) if model.respond_to?(method_name)
68
-
69
- name = File.basename(filename, '.*').parameterize
70
- name = "#{SecureRandom.uuid}-#{name}" if support_multiple?
71
- "#{model.id}-#{name}#{File.extname(filename)}"
85
+ model.send(method_name, filename)
72
86
  end
73
87
 
74
88
  def remove_files
@@ -4,9 +4,5 @@ require 'rails'
4
4
  module ActivestorageDelayed
5
5
  class Railtie < ::Rails::Railtie
6
6
  railtie_name :activestorage_delayed
7
-
8
- config.after_initialize do |_app|
9
- require_relative '../../initializers/upload_default_variation'
10
- end
11
7
  end
12
8
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActivestorageDelayed
4
- VERSION = '0.1.4'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activestorage-delayed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Owen Peredo Diaz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-04 00:00:00.000000000 Z
11
+ date: 2022-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage
@@ -64,7 +64,6 @@ files:
64
64
  - bin/test
65
65
  - db/test.sqlite3
66
66
  - docker-compose.yaml
67
- - initializers/upload_default_variation.rb
68
67
  - lib/activestorage-delayed.rb
69
68
  - lib/activestorage-delayed/delayed_concern.rb
70
69
  - lib/activestorage-delayed/delayed_uploader.rb
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Ability to auto apply :default variant before uploading original image
4
- module ActivetoragePreprocessDefaultVariation
5
- def self.prepended(base)
6
- base.extend(ClassMethods)
7
- end
8
-
9
- def upload_without_unfurling(io) # rubocop:disable Metrics/MethodLength
10
- variant = attachments.first.try(:send, :variants)
11
- default_variant = variant ? variant[:default] : nil
12
- if default_variant && self.class.enabled_default_variant?
13
- ActiveStorage::Variation.wrap(default_variant).transform(io) do |output|
14
- unfurl output, identify: identify
15
- save! if id.present? # update new unfurl information
16
- super(output)
17
- end
18
- else
19
- super(io)
20
- end
21
- end
22
-
23
- module ClassMethods
24
- # To improve testing performance, we don't want to preprocess images in test environment
25
- def enabled_default_variant?
26
- !Rails.env.test?
27
- end
28
- end
29
- end
30
-
31
- ActiveStorage::Blob.prepend ActivetoragePreprocessDefaultVariation