class CarrierWave::FileCardUploader

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.

@example Attaching a file to a file card

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

@example Attaching a image to a image card

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

It's possible to upload files using a url. The card attribute for that is remote_<attachment_type>_url

@example Create a file card using a remote url

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

@example Updating a image card using a remote url

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

## 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”.

@example Creating a hard-coded file

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

@example 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

@example 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

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"

<mark> can be one of the following options

<revision> 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

Constants

CONFIG_CREDENTIAL_OPTIONS
CONFIG_OPTIONS
STORAGE_TYPES

Attributes

mod[RW]

Public Instance Methods

action_id() click to toggle source
# File lib/carrier_wave/file_card_uploader.rb, line 208
def action_id
  model.selected_content_action_id || action_id_stand_in
end
asset_host() click to toggle source
Calls superclass method
# File lib/carrier_wave/file_card_uploader.rb, line 221
def asset_host
  bucket_config(:asset_host) || super
end
bucket_config(option) click to toggle source
# File lib/carrier_wave/file_card_uploader.rb, line 217
def bucket_config option
  @model.bucket_config[option]
end
create_versions?(new_file) click to toggle source
# File lib/carrier_wave/file_card_uploader.rb, line 200
def create_versions? new_file
  model.create_versions? new_file
end
db_content(opts={}) click to toggle source

generate identifier that gets stored in the card's db_content field @param opts [Hash] generate an identifier using the given storage options

instead of the storage options derived from the model and
the global configuration

@option opts [Symbol] storage_type @option opts [String] mod @option opts [Symbol] bucket

# File 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
extension() click to toggle source
# File 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
filename() click to toggle source
# File 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_filename() click to toggle source
# File lib/carrier_wave/file_card_uploader.rb, line 204
def original_filename
  @original_filename ||= model.selected_action&.comment
end
url(opts={}) click to toggle source

@option opts [Symbol] :absolute - return absolute url

# File 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={}) click to toggle source
# File 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?() click to toggle source
# File lib/carrier_wave/file_card_uploader.rb, line 142
def valid?
  extension.present?
end

Private Instance Methods

action_id_stand_in() click to toggle source

used as action_id in the filename if card is not actionable?

# File lib/carrier_wave/file_card_uploader.rb, line 229
def action_id_stand_in
  Time.now.to_i
end
storage() click to toggle source
# File lib/carrier_wave/file_card_uploader.rb, line 233
def storage
  case @model.storage_type
  when :cloud
    Storage::Fog.new self
  else
    Storage::File.new self
  end
end