Class: CarrierWave::FileCardUploader

Inherits:
Uploader::Base
  • Object
show all
Includes:
Card::Env::Location, Path
Defined in:
card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb,
card-mod-carrierwave/lib/carrier_wave/file_card_uploader/path.rb

Overview

Takes care of the file upload for cards with attached files. Most of the upload behaviour depends on the card itself. (e.g. card type and storage option chosen for the card). So in contrary to CarrierWave’s default uploader we depend very much on the model (= card object) to get the correct paths for retrieving and storing the file.

Cards that support attachments (by default those are cards of type “file” and “image”) accept a file handle as a card attribute.

It’s possible to upload files using a url. The card attribute for that is remote__url

Storage types

You can choose between four different storage options - coded: These files are in the codebase, like the default logo. Every view is a decko request. - local: Uploaded files which are stored in a local upload directory (upload path is configurable via config.paths[“files”]). If read permissions are set such that “Anyone” can read, then there is a symlink from the public directory. Otherwise every view is a decko request. - cloud: You can configure buckets that refer to an external storage service. Link is rendered as absolute url - web: A fixed url (to external source). No upload or other file processing. Link is just the saved url.

Currently, there is no web interface that let’s a user or administrator choose a storage option for a specific card or set of cards. There is only a global config option to set the storage type for all new uploads (config.storage_type). On the *admin card it’s possible to update all existing file cards according to the current global config.

Storage types for single cards can be changed by developers using the card attributes “storage_type”, “bucket”, and “mod”.

Depending on the storage type the uploader uses the following paths and identifiers. ### Identifier (stored in the database as db_content) - coded: :codename/mod_name.ext - local: ~card_id/action_id.ext - cloud: (bucket)/card_id/action_id.ext - web: http://url

Storage path

  • coded: mod_dir/file/codename/type_code(-variant).ext (no colon on codename!)
  • local: files_dir/card_id/action_id(-variant).ext (no tilde on id!)
  • cloud: bucket/bucket_subdir/id/action_id(-variant).ext
  • web: no storage

Variants are only used for images. Possible options are icon|small|medium|large|original. files_dir, bucket, and bucket_subdir can be changed via config options.

Supported url patterns

mark.ext mark/revision.ext mark/revision-variant.ext /files/mark/revision-variant.ext # <- public symlink if readable by # “Anyone”

can be one of the following options - - ~ - :

is the mod name if the file is coded or and action_id in any case Examples: *logo.png ~22/33-medium.png # local :yeti_skin/standard-large.png # coded

Examples:

Attaching a file to a file card

Card.create name: "file card", type: :file,
            file: File.new(path_to_file)

Attaching a image to a image card

Card.create name: "file card", type: :image,
            image: File.new(path_to_image)

Create a file card using a remote url

Card.create name: "file_card", type: :file,
            remote_file_url: "http://a.file.in/the.web"

Updating a image card using a remote url

card.update remote_image_url: "http://a.image/somewhere.png"

Creating a hard-coded file

Card.create name: "file card", type_id: Card::FileID,
            file: File.new(path),
            storage_type: :coded, mod: "account"

Moving a file to a cloud service

# my_deck/config/application.rb:
config.file_buckets = {
  aws_bucket: {
    provider: "fog/aws",
    directory: "bucket-name",
    subdirectory: "files",
    credentials: {
       provider: 'AWS'                         # required
       aws_access_key_id: 'key'                # required
       aws_secret_access_key: 'secret-key'     # required
    public: true,
   }
}

# decko console or rake task:
card.update storage_type: :cloud, bucket: :aws_bucket

Creating a file card with fixed external link

Card.create name: "file card", type_id: Card::FileID,
            content: "http://animals.org/cat.png"
            storage_type: :web

Card.create name: "file card", type_id: Card::FileID,
            file: "http://animals.org/cat.png"
            storage_type: :web

Direct Known Subclasses

ImageCardUploader

Defined Under Namespace

Modules: Path

Constant Summary collapse

STORAGE_TYPES =
%i[cloud web coded local].freeze
CONFIG_OPTIONS =
%i[provider attributes directory public credentials
authenticated_url_expiration use_ssl_for_aws].freeze
CONFIG_CREDENTIAL_OPTIONS =
%i[
  provider
  aws_access_key_id aws_secret_access_key region host endpoint
  google_access_key_id google_secret_access_key
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Path

#cache_dir, #local_url, #local_url_base, #path, #public_path, #retrieve_path, #store_path, #tmp_path

Methods included from Card::Env::Location

#card_path, #card_url, #cardname_from_url, #protocol_and_host

Instance Attribute Details

#modObject

Returns the value of attribute mod.



127
128
129
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 127

def mod
  @mod
end

Instance Method Details

#action_idObject



208
209
210
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 208

def action_id
  model.selected_content_action_id || action_id_stand_in
end

#asset_hostObject



221
222
223
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 221

def asset_host
  bucket_config(:asset_host) || super
end

#bucket_config(option) ⇒ Object



217
218
219
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 217

def bucket_config option
  @model.bucket_config[option]
end

#create_versions?(new_file) ⇒ Boolean

Returns:

  • (Boolean)


200
201
202
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 200

def create_versions? new_file
  model.create_versions? new_file
end

#db_content(opts = {}) ⇒ Object

generate identifier that gets stored in the card’s db_content field

Parameters:

  • opts (Hash) (defaults to: {})

    generate an identifier using the given storage options instead of the storage options derived from the model and the global configuration

Options Hash (opts):

  • storage_type (Symbol)
  • mod (String)
  • bucket (Symbol)


170
171
172
173
174
175
176
177
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 170

def db_content opts={}
  model.with_storage_options opts do
    return model.content if model.web?
    return "" unless file.present?

    "%s/%s" % [file_dir, url_filename]
  end
end

#extensionObject



154
155
156
157
158
159
160
161
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 154

def extension
  case
  when file&.extension.present?     then ".#{file.extension}"
  when card_content = model.content then File.extname(card_content)
  when orig = original_filename     then File.extname(orig)
  else                              ""
  end.downcase
end

#filenameObject



146
147
148
149
150
151
152
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 146

def filename
  if model.coded?
    "#{model.type_code}#{extension}"
  else
    "#{action_id}#{extension}"
  end
end

#original_filenameObject



204
205
206
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 204

def original_filename
  @original_filename ||= model.selected_action&.comment
end

#url(opts = {}) ⇒ Object

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :absolute (Symbol)
    • return absolute url


190
191
192
193
194
195
196
197
198
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 190

def url opts={}
  if model.cloud?
    file&.url
  elsif model.web?
    model.content
  else
    local_url opts
  end
end

#url_filename(opts = {}) ⇒ Object



179
180
181
182
183
184
185
186
187
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 179

def url_filename opts={}
  model.with_storage_options opts do
    if model.coded?
      "#{model.mod}#{extension}"
    else
      "#{action_id}#{extension}"
    end
  end
end

#valid?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'card-mod-carrierwave/lib/carrier_wave/file_card_uploader.rb', line 142

def valid?
  extension.present?
end