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 +4 -4
- data/.idea/activestorage-delayed.iml +56 -33
- data/Gemfile.lock +1 -1
- data/README.md +17 -24
- data/lib/activestorage-delayed/delayed_concern.rb +27 -7
- data/lib/activestorage-delayed/delayed_uploader.rb +35 -21
- data/lib/activestorage-delayed/railtie.rb +0 -4
- data/lib/activestorage-delayed/version.rb +1 -1
- metadata +2 -3
- data/initializers/upload_default_variation.rb +0 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 621bd6e1ad3690b81dfcd6d12ef466046db31741cca14fb529a6d0c0f6fb4089
|
|
4
|
+
data.tar.gz: ef77110cf9d92f5247f2bff431bb2f89507d69709001c063cf3db0ffa017a2ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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-
|
|
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="
|
|
16
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
17
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
18
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
19
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
20
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
21
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
22
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
23
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
24
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
25
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
26
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
27
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
28
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
29
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
30
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
31
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
32
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
33
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
34
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
35
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
36
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
37
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
38
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
39
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
40
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
41
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
42
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
43
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
44
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
45
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
46
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
|
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
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
|
-
|
|
108
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
puts '
|
|
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
|
-
|
|
122
|
-
puts "
|
|
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
16
|
+
upload_photos
|
|
17
|
+
save_changes
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
private
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
-
|
|
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
|
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.
|
|
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-
|
|
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
|