Class: CarrierWave::FileCardUploader

Inherits:
Uploader::Base
  • Object
show all
Includes:
Card::Env::Location, Path
Defined in:
lib/carrier_wave/file_card_uploader.rb,
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_<attachment_type>_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"

<mark> can be one of the following options

  • <card name>

  • ~<card id>

  • :<code name>

<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

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

Instance Attribute Details

#modObject

Returns the value of attribute mod.



127
128
129
# File 'lib/carrier_wave/file_card_uploader.rb', line 127

def mod
  @mod
end

Instance Method Details

#action_idObject



201
202
203
204
205
# File 'lib/carrier_wave/file_card_uploader.rb', line 201

def action_id
  model.selected_content_action_id ||
    model.last_content_action_id ||
    action_id_stand_in
end

#asset_hostObject



216
217
218
# File 'lib/carrier_wave/file_card_uploader.rb', line 216

def asset_host
  bucket_config(:asset_host) || super
end

#bucket_config(option) ⇒ Object



212
213
214
# File 'lib/carrier_wave/file_card_uploader.rb', line 212

def bucket_config option
  @model.bucket_config[option]
end

#create_versions?(new_file) ⇒ Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/carrier_wave/file_card_uploader.rb', line 193

def create_versions? new_file
  model.create_versions? new_file
end

#db_contentObject



163
164
165
166
167
168
# File 'lib/carrier_wave/file_card_uploader.rb', line 163

def db_content
  return model.content if model.web?
  return "" unless file.present?

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

#extensionObject



154
155
156
157
158
159
160
161
# 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

#filenameObject



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

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

#original_filenameObject



197
198
199
# File 'lib/carrier_wave/file_card_uploader.rb', line 197

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

#temporary_identifierObject



178
179
180
# File 'lib/carrier_wave/file_card_uploader.rb', line 178

def temporary_identifier
  db_content
end

#url(opts = {}) ⇒ Object

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :absolute (Symbol)
    • return absolute url



183
184
185
186
187
188
189
190
191
# File 'lib/carrier_wave/file_card_uploader.rb', line 183

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

#url_filenameObject



170
171
172
173
174
175
176
# File 'lib/carrier_wave/file_card_uploader.rb', line 170

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

#valid?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/carrier_wave/file_card_uploader.rb', line 142

def valid?
  extension.present?
end