card-mod-carrierwave 0.11.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 +7 -0
- data/config/core_initializers/carrierwave.rb +5 -0
- data/lib/carrier_wave/card_mount.rb +134 -0
- data/lib/carrier_wave/file_card_uploader.rb +320 -0
- data/lib/carrier_wave/image_card_uploader.rb +59 -0
- data/set/abstract/attachment.rb +112 -0
- data/set/abstract/attachment/cloud.rb +133 -0
- data/set/abstract/attachment/coded.rb +22 -0
- data/set/abstract/attachment/local.rb +40 -0
- data/set/abstract/attachment/paths.rb +58 -0
- data/set/abstract/attachment/storage_type.rb +170 -0
- data/set/abstract/attachment/upload_cache.rb +85 -0
- data/set/abstract/attachment/web.rb +3 -0
- data/set/all/file_utils.rb +41 -0
- data/set/self/admin.rb +23 -0
- data/set/self/favicon.rb +16 -0
- data/set/self/new_file.rb +13 -0
- data/set/self/new_image.rb +13 -0
- data/set/type/file.rb +116 -0
- data/set/type/file/file_chooser.haml +15 -0
- data/set/type/file/preview_editor.haml +19 -0
- data/set/type/image.rb +101 -0
- data/set/type/image/html_views.rb +69 -0
- metadata +138 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
require "mini_magick"
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
# Adds image specific version handling to {FileCardUploader}.
|
5
|
+
# The ImageCardUploader creates five versions of different sizes when it
|
6
|
+
# uploads an imagae file:
|
7
|
+
# icon (16x16), small (75x75), medium (200X200), large (500x500) and
|
8
|
+
# the original size.
|
9
|
+
class ImageCardUploader < FileCardUploader
|
10
|
+
include CarrierWave::MiniMagick
|
11
|
+
|
12
|
+
def path version=nil
|
13
|
+
(version && version != :original) ? versions[version].path : super()
|
14
|
+
end
|
15
|
+
|
16
|
+
version :icon, if: :create_versions?, from_version: :small do
|
17
|
+
process resize_and_pad: [16, 16]
|
18
|
+
end
|
19
|
+
version :small, if: :create_versions?, from_version: :medium do
|
20
|
+
process resize_to_fit: [75, 75]
|
21
|
+
end
|
22
|
+
version :medium, if: :create_versions? do
|
23
|
+
process resize_to_limit: [200, 200]
|
24
|
+
end
|
25
|
+
version :large, if: :create_versions? do
|
26
|
+
process resize_to_limit: [500, 500]
|
27
|
+
end
|
28
|
+
|
29
|
+
# version :small_square, if: :create_versions?,
|
30
|
+
# from_version: :medium_square do
|
31
|
+
# process resize_to_fill: [75, 75]
|
32
|
+
# end
|
33
|
+
# version :medium_square, if: :create_versions? do
|
34
|
+
# process resize_to_fill: [200, 200]
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# In case we decide to support the squared versions
|
38
|
+
# we have to update all existing images with the following snippet:
|
39
|
+
# Card.search(type_id: Card::ImageID) do |card|
|
40
|
+
# card.image.cache_stored_file!
|
41
|
+
# card.image.recreate_versions!
|
42
|
+
# end
|
43
|
+
|
44
|
+
def identifier
|
45
|
+
full_filename(super())
|
46
|
+
end
|
47
|
+
|
48
|
+
# add 'original' if no version is given
|
49
|
+
def full_filename for_file
|
50
|
+
name = super(for_file)
|
51
|
+
if version_name
|
52
|
+
name
|
53
|
+
else
|
54
|
+
parts = name.split "."
|
55
|
+
"#{parts.shift}-original.#{parts.join('.')}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
attr_writer :empty_ok
|
2
|
+
|
3
|
+
def self.included host_class
|
4
|
+
host_class.extend CarrierWave::CardMount
|
5
|
+
end
|
6
|
+
|
7
|
+
event :select_file_revision, after: :select_action do
|
8
|
+
attachment.retrieve_from_store!(attachment.identifier)
|
9
|
+
end
|
10
|
+
|
11
|
+
# we need a card id for the path so we have to update db_content when we have
|
12
|
+
# an id
|
13
|
+
event :correct_identifier, :finalize, on: :create, when: proc { |c| !c.web? } do
|
14
|
+
update_column(:db_content, attachment.db_content)
|
15
|
+
expire
|
16
|
+
end
|
17
|
+
|
18
|
+
event :save_original_filename, :prepare_to_store, on: :save, when: :file_ready_to_save? do
|
19
|
+
return unless @current_action
|
20
|
+
@current_action.update! comment: original_filename
|
21
|
+
end
|
22
|
+
|
23
|
+
event :validate_file_exist, :validate, on: :create do
|
24
|
+
return if empty_ok?
|
25
|
+
if will_be_stored_as == :web
|
26
|
+
errors.add "url is missing" if content.blank?
|
27
|
+
elsif !attachment.file.present?
|
28
|
+
errors.add attachment_name, "is missing"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
event :write_identifier, after: :save_original_filename, when: proc { |c| !c.web? } do
|
33
|
+
self.content = attachment.db_content
|
34
|
+
end
|
35
|
+
|
36
|
+
def file_ready_to_save?
|
37
|
+
attachment.file.present? &&
|
38
|
+
!preliminary_upload? &&
|
39
|
+
!save_preliminary_upload? &&
|
40
|
+
attachment_is_changing?
|
41
|
+
end
|
42
|
+
|
43
|
+
def item_names _args={} # needed for flexmail attachments. hacky.
|
44
|
+
[name]
|
45
|
+
end
|
46
|
+
|
47
|
+
def original_filename
|
48
|
+
return content.split("/").last if web?
|
49
|
+
attachment.original_filename
|
50
|
+
end
|
51
|
+
|
52
|
+
def unfilled?
|
53
|
+
!attachment.present? && !save_preliminary_upload? && !subcards? && blank_content?
|
54
|
+
end
|
55
|
+
|
56
|
+
def attachment_changed?
|
57
|
+
send "#{attachment_name}_changed?"
|
58
|
+
end
|
59
|
+
|
60
|
+
def attachment_is_changing?
|
61
|
+
send "#{attachment_name}_is_changing?"
|
62
|
+
end
|
63
|
+
|
64
|
+
def attachment_before_act
|
65
|
+
send "#{attachment_name}_before_act"
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_versions? _new_file
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
def empty_ok?
|
73
|
+
@empty_ok
|
74
|
+
end
|
75
|
+
|
76
|
+
def assign_set_specific_attributes
|
77
|
+
# reset content if we really have something to upload
|
78
|
+
self.content = nil if set_specific[attachment_name.to_s].present?
|
79
|
+
super
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_files_for_action action
|
83
|
+
with_selected_action_id(action.id) do
|
84
|
+
attachment.file.delete
|
85
|
+
attachment.versions.each_value do |version|
|
86
|
+
version.file.delete
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def revision action, before_action=false
|
92
|
+
return unless (result = super)
|
93
|
+
result[:empty_ok] = true
|
94
|
+
result
|
95
|
+
end
|
96
|
+
|
97
|
+
def attachment_format ext
|
98
|
+
if ext.present? && attachment && (original_ext = attachment.extension.sub(/^\./, ""))
|
99
|
+
if ["file", original_ext].member? ext
|
100
|
+
original_ext
|
101
|
+
elsif (exts = Mime::Types[attachment.content_type])
|
102
|
+
if exts.find { |mt| mt.extensions.member? ext }
|
103
|
+
ext
|
104
|
+
else
|
105
|
+
exts[0].extensions[0]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
rescue => e
|
110
|
+
Rails.logger.info "attachment_format issue: #{e.message}"
|
111
|
+
nil
|
112
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
event :change_bucket_if_read_only, :initialize,
|
2
|
+
on: :update, when: :change_bucket_if_read_only? do
|
3
|
+
@new_storage_type = storage_type_from_config
|
4
|
+
end
|
5
|
+
|
6
|
+
event :validate_storage_type_update, :validate, on: :update, when: :cloud? do
|
7
|
+
# FIXME: make it possible to retrieve the file from cloud storage
|
8
|
+
# to store it somewhere else. Currently, it only works to change the
|
9
|
+
# storage type if a new file is provided
|
10
|
+
# i.e. `update storage_type: :local` fails but
|
11
|
+
# `update storage_type: :local, file: [file handle]` is ok
|
12
|
+
return unless storage_type_changed? && !attachment_is_changing?
|
13
|
+
|
14
|
+
errors.add :storage_type, tr(:moving_files_is_not_supported)
|
15
|
+
end
|
16
|
+
|
17
|
+
def bucket
|
18
|
+
@bucket ||= cloud? && (new_card_bucket || bucket_from_content || bucket_from_config)
|
19
|
+
end
|
20
|
+
|
21
|
+
def new_card_bucket
|
22
|
+
return unless new_card?
|
23
|
+
# If the file is assigned before the bucket option we have to
|
24
|
+
# check if there is a bucket options in set_specific.
|
25
|
+
# That happens for exmaple when the file appears before the bucket in the
|
26
|
+
# options hash:
|
27
|
+
# Card.create file: file_handle, bucket: "my_bucket"
|
28
|
+
set_specific[:bucket] || set_specific["bucket"] || bucket_from_config
|
29
|
+
end
|
30
|
+
|
31
|
+
def bucket_config
|
32
|
+
@bucket_config ||= load_bucket_config
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_bucket_config
|
36
|
+
return {} unless bucket
|
37
|
+
bucket_config = Cardio.config.file_buckets&.dig(bucket.to_sym) || {}
|
38
|
+
bucket_config.symbolize_keys!
|
39
|
+
bucket_config[:credentials]&.symbolize_keys!
|
40
|
+
# we don't want :attributes hash symbolized, so we can't use
|
41
|
+
# deep_symbolize_keys
|
42
|
+
ensure_bucket_config do
|
43
|
+
load_bucket_config_from_env bucket_config
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def ensure_bucket_config
|
48
|
+
yield.tap do |config|
|
49
|
+
require_configuration! config
|
50
|
+
require_credentials! config
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def require_configuration! config
|
55
|
+
cant_find_in_bucket! "configuration" unless config.present?
|
56
|
+
end
|
57
|
+
|
58
|
+
def require_credentials! config
|
59
|
+
cant_find_in_bucket! "credentials" unless config[:credentials]
|
60
|
+
end
|
61
|
+
|
62
|
+
def cant_find_in_bucket! need
|
63
|
+
raise Card::Error, "couldn't find #{need} for bucket #{bucket}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_bucket_config_from_env config
|
67
|
+
config ||= {}
|
68
|
+
each_config_option_from_env do |key|
|
69
|
+
replace_with_env_variable config, key
|
70
|
+
end
|
71
|
+
credential_config config do |cred_hash|
|
72
|
+
load_bucket_credentials_from_env cred_hash
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def credential_config config
|
77
|
+
config[:credentials] ||= {}
|
78
|
+
yield config[:credentials]
|
79
|
+
config.delete :credentials if config[:credentials].blank?
|
80
|
+
config
|
81
|
+
end
|
82
|
+
|
83
|
+
def each_config_option_from_env
|
84
|
+
CarrierWave::FileCardUploader::CONFIG_OPTIONS.each do |key|
|
85
|
+
yield key unless key.in? %i[attributes credentials]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def load_bucket_credentials_from_env cred_config
|
90
|
+
each_credential_from_env do |option|
|
91
|
+
replace_with_env_variable cred_config, option, "credentials"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def each_credential_from_env
|
96
|
+
regexp = credential_from_env_regexp
|
97
|
+
ENV.each_key do |env_key|
|
98
|
+
next unless (m = regexp.match env_key)
|
99
|
+
yield m[:option].downcase.to_sym
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def credential_from_env_regexp
|
104
|
+
Regexp.new "^(?:#{bucket.to_s.upcase}_)?CREDENTIALS_(?<option>.+)$"
|
105
|
+
end
|
106
|
+
|
107
|
+
def replace_with_env_variable config, option, prefix=nil
|
108
|
+
env_key = [prefix, option].compact.join("_").upcase
|
109
|
+
new_value = ENV["#{bucket.to_s.upcase}_#{env_key}"] || ENV[env_key]
|
110
|
+
config[option] = new_value if new_value
|
111
|
+
end
|
112
|
+
|
113
|
+
def bucket_from_content
|
114
|
+
return unless content
|
115
|
+
content.match(/^\((?<bucket>[^)]+)\)/) { |m| m[:bucket] }
|
116
|
+
end
|
117
|
+
|
118
|
+
def bucket_from_config
|
119
|
+
cnf = Cardio.config
|
120
|
+
cnf.file_default_bucket || cnf.file_buckets&.keys&.first
|
121
|
+
end
|
122
|
+
|
123
|
+
def change_bucket_if_read_only?
|
124
|
+
cloud? && bucket_config[:read_only] && attachment_is_changing?
|
125
|
+
end
|
126
|
+
|
127
|
+
def bucket= value
|
128
|
+
if @action == :update
|
129
|
+
@new_bucket = value
|
130
|
+
else
|
131
|
+
@bucket = value
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
event :lose_coded_status_on_update, :initialize, on: :update, when: :coded? do
|
2
|
+
# unless explicit
|
3
|
+
return if @new_mod
|
4
|
+
@new_storage_type ||= storage_type_from_config
|
5
|
+
end
|
6
|
+
|
7
|
+
event :validate_coded_storage_type, :validate, on: :save, when: :will_become_coded? do
|
8
|
+
errors.add :storage_type, tr(:mod_argument_needed_to_save) unless mod || @new_mod
|
9
|
+
errors.add :storage_type, tr(:codename_needed_for_storage) if codename.blank?
|
10
|
+
end
|
11
|
+
|
12
|
+
def will_become_coded?
|
13
|
+
will_be_stored_as == :coded
|
14
|
+
end
|
15
|
+
|
16
|
+
def mod= value
|
17
|
+
if @action == :update && mod != value
|
18
|
+
@new_mod = value.to_s
|
19
|
+
else
|
20
|
+
@mod = value.to_s
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
event :update_public_link_on_create, :integrate, on: :create, when: :local? do
|
3
|
+
update_public_link
|
4
|
+
end
|
5
|
+
|
6
|
+
event :remove_public_link_on_delete, :integrate, on: :delete, when: :local? do
|
7
|
+
remove_public_links
|
8
|
+
end
|
9
|
+
|
10
|
+
event :update_public_link, after: :update_read_rule, when: :local? do
|
11
|
+
return if content.blank?
|
12
|
+
if who_can(:read).include? Card::AnyoneID
|
13
|
+
create_public_links
|
14
|
+
else
|
15
|
+
remove_public_links
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def create_public_links
|
22
|
+
path = attachment.public_path
|
23
|
+
return if File.exist? path
|
24
|
+
FileUtils.mkdir_p File.dirname(path)
|
25
|
+
File.symlink attachment.path, path unless File.symlink? path
|
26
|
+
create_versions_public_links
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_versions_public_links
|
30
|
+
attachment.versions.each_value do |version|
|
31
|
+
next if File.symlink? version.public_path
|
32
|
+
File.symlink version.path, version.public_path
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_public_links
|
37
|
+
symlink_dir = File.dirname attachment.public_path
|
38
|
+
return unless Dir.exist? symlink_dir
|
39
|
+
FileUtils.rm_rf symlink_dir
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
MOD_FILE_DIR = "file".freeze
|
2
|
+
|
3
|
+
def store_dir
|
4
|
+
will_become_coded? ? coded_dir(@new_mod) : upload_dir
|
5
|
+
end
|
6
|
+
|
7
|
+
def retrieve_dir
|
8
|
+
coded? ? coded_dir : upload_dir
|
9
|
+
end
|
10
|
+
|
11
|
+
# place for files of regular file cards
|
12
|
+
def upload_dir
|
13
|
+
id ? "#{files_base_dir}/#{id}" : tmp_upload_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
# place for files of mod file cards
|
17
|
+
def coded_dir new_mod=nil
|
18
|
+
dir = File.join mod_dir(new_mod), MOD_FILE_DIR, codename.to_s
|
19
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
20
|
+
dir
|
21
|
+
end
|
22
|
+
|
23
|
+
def mod_dir new_mod=nil
|
24
|
+
mod_name = new_mod || mod
|
25
|
+
dir = Cardio::Mod.dirs.path(mod_name) || (mod_name.to_sym == :test && "test")
|
26
|
+
|
27
|
+
raise Error, "can't find mod \"#{mod_name}\"" unless dir
|
28
|
+
dir
|
29
|
+
end
|
30
|
+
|
31
|
+
def files_base_dir
|
32
|
+
dir = bucket ? bucket_config[:subdirectory] : Card.paths["files"].existent.first
|
33
|
+
dir || files_base_dir_configuration_error
|
34
|
+
end
|
35
|
+
|
36
|
+
def files_base_dir_configuration_error
|
37
|
+
raise StandardError,
|
38
|
+
"missing directory for file cache (default is `files` in deck root)"
|
39
|
+
end
|
40
|
+
|
41
|
+
# used in the indentifier
|
42
|
+
def file_dir
|
43
|
+
if coded?
|
44
|
+
":#{codename}"
|
45
|
+
elsif cloud?
|
46
|
+
"(#{bucket})/#{file_id}"
|
47
|
+
else
|
48
|
+
"~#{file_id}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def public?
|
53
|
+
who_can(:read).include? Card::AnyoneID
|
54
|
+
end
|
55
|
+
|
56
|
+
def file_id
|
57
|
+
id? ? id : upload_cache_card.id
|
58
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
attr_writer :bucket, :storage_type
|
2
|
+
|
3
|
+
event :storage_type_change, :store, on: :update, when: :storage_type_changed? do
|
4
|
+
# carrierwave stores file if @cache_id is not nil
|
5
|
+
attachment.cache_stored_file!
|
6
|
+
# attachment.retrieve_from_cache!(attachment.cache_name)
|
7
|
+
update_storage_attributes
|
8
|
+
# next line might be necessary to move files to cloud
|
9
|
+
|
10
|
+
# make sure that we get the new identifier
|
11
|
+
# otherwise action_id will return wrong id for new identifier
|
12
|
+
db_content_will_change!
|
13
|
+
write_identifier
|
14
|
+
end
|
15
|
+
|
16
|
+
event :validate_storage_type, :validate, on: :save do
|
17
|
+
unless known_storage_type? will_be_stored_as
|
18
|
+
errors.add :storage_type, tr(
|
19
|
+
:unknown_storage_type,
|
20
|
+
new_storage_type: @new_storage_type
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def will_be_stored_as
|
26
|
+
@new_storage_type || storage_type
|
27
|
+
end
|
28
|
+
|
29
|
+
def read_only?
|
30
|
+
web? || (cloud? && bucket_config[:read_only])
|
31
|
+
end
|
32
|
+
|
33
|
+
def cloud?
|
34
|
+
storage_type == :cloud
|
35
|
+
end
|
36
|
+
|
37
|
+
def web?
|
38
|
+
storage_type == :web
|
39
|
+
end
|
40
|
+
|
41
|
+
def local?
|
42
|
+
storage_type == :local
|
43
|
+
end
|
44
|
+
|
45
|
+
def coded?
|
46
|
+
storage_type == :coded
|
47
|
+
end
|
48
|
+
|
49
|
+
def remote_storage?
|
50
|
+
cloud? || web?
|
51
|
+
end
|
52
|
+
|
53
|
+
def storage_type
|
54
|
+
@storage_type ||=
|
55
|
+
new_card? ? storage_type_from_config : storage_type_from_content
|
56
|
+
end
|
57
|
+
|
58
|
+
def deprecated_mod_file?
|
59
|
+
content && (lines = content.split("\n")) && lines.size == 4
|
60
|
+
end
|
61
|
+
|
62
|
+
def mod
|
63
|
+
@mod ||= coded? && mod_from_content
|
64
|
+
end
|
65
|
+
|
66
|
+
def mod_from_content
|
67
|
+
if content =~ %r{^:[^/]+/([^.]+)}
|
68
|
+
Regexp.last_match(1) # current mod_file format
|
69
|
+
else
|
70
|
+
mod_from_deprecated_content
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# old format is still used in card_changes
|
75
|
+
def mod_from_deprecated_content
|
76
|
+
return if content =~ /^\~/
|
77
|
+
return unless (lines = content.split("\n")) && lines.size == 4
|
78
|
+
lines.last
|
79
|
+
end
|
80
|
+
|
81
|
+
def storage_type_from_config
|
82
|
+
valid_storage_type ENV["FILE_STORAGE"] || Cardio.config.file_storage
|
83
|
+
end
|
84
|
+
|
85
|
+
def valid_storage_type storage_type
|
86
|
+
storage_type.to_sym.tap do |type|
|
87
|
+
invalid_storage_type! type unless type.in? valid_storage_type_list
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def valid_storage_type_list
|
92
|
+
CarrierWave::FileCardUploader::STORAGE_TYPES
|
93
|
+
end
|
94
|
+
|
95
|
+
def invalid_storage_type! type
|
96
|
+
raise Card::Error, tr(:error_invalid_storage_type, type: type)
|
97
|
+
end
|
98
|
+
|
99
|
+
def storage_type_from_content
|
100
|
+
case content
|
101
|
+
when /^\(/ then :cloud
|
102
|
+
when %r{/^https?\:/} then :web
|
103
|
+
when /^~/ then :local
|
104
|
+
when /^\:/ then :coded
|
105
|
+
else
|
106
|
+
if deprecated_mod_file?
|
107
|
+
:coded
|
108
|
+
else
|
109
|
+
storage_type_from_config
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def update_storage_attributes
|
115
|
+
@mod = @new_mod if @new_mod
|
116
|
+
@bucket = @new_bucket if @new_bucket
|
117
|
+
@storage_type = @new_storage_type
|
118
|
+
end
|
119
|
+
|
120
|
+
def storage_type_changed?
|
121
|
+
@new_bucket || (@new_storage_type && @new_storage_type != storage_type) || @new_mod
|
122
|
+
end
|
123
|
+
|
124
|
+
def storage_type= value
|
125
|
+
known_storage_type? value
|
126
|
+
if @action == :update #&& storage_type != value
|
127
|
+
# we cant update the storage type directly here
|
128
|
+
# if we do then the uploader doesn't find the file we want to update
|
129
|
+
@new_storage_type = value
|
130
|
+
else
|
131
|
+
@storage_type = value
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def with_storage_options opts={}
|
136
|
+
old_values = {}
|
137
|
+
validate_temporary_storage_type_change opts[:storage_type]
|
138
|
+
%i[storage_type mod bucket].each do |opt_name|
|
139
|
+
next unless opts[opt_name]
|
140
|
+
old_values[opt_name] = instance_variable_get "@#{opt_name}"
|
141
|
+
instance_variable_set "@#{opt_name}", opts[opt_name]
|
142
|
+
@temp_storage_type = true
|
143
|
+
end
|
144
|
+
yield
|
145
|
+
ensure
|
146
|
+
@temp_storage_type = false
|
147
|
+
old_values.each do |key, val|
|
148
|
+
instance_variable_set "@#{key}", val
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def temporary_storage_type_change?
|
153
|
+
@temp_storage_type
|
154
|
+
end
|
155
|
+
|
156
|
+
def validate_temporary_storage_type_change new_storage_type=nil
|
157
|
+
new_storage_type ||= @new_storage_type
|
158
|
+
return unless new_storage_type
|
159
|
+
unless known_storage_type? new_storage_type
|
160
|
+
raise Error, tr(:unknown_storage_type, new_storage_type: new_storage_type)
|
161
|
+
end
|
162
|
+
|
163
|
+
if new_storage_type == :coded && codename.blank?
|
164
|
+
raise Error, "codename needed for storage type :coded"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def known_storage_type? type=storage_type
|
169
|
+
type.in? CarrierWave::FileCardUploader::STORAGE_TYPES
|
170
|
+
end
|