Module: Refile
- Defined in:
- lib/refile.rb,
lib/refile/app.rb,
lib/refile/file.rb,
lib/refile/type.rb,
lib/refile/rails.rb,
lib/refile/version.rb,
lib/refile/attacher.rb,
lib/refile/signature.rb,
lib/refile/attachment.rb,
lib/refile/custom_logger.rb,
lib/refile/random_hasher.rb,
lib/refile/backend_macros.rb,
lib/refile/backend/file_system.rb,
lib/refile/attachment_definition.rb,
lib/refile/rails/attachment_helper.rb,
lib/refile/attachment/active_record.rb
Defined Under Namespace
Modules: ActiveRecord, Attachment, AttachmentHelper, Backend, BackendMacros Classes: App, Attacher, AttachmentDefinition, Confirm, CustomLogger, Engine, File, Invalid, InvalidFile, InvalidID, InvalidMaxSize, RandomHasher, Signature, Type
Constant Summary collapse
- VERSION =
"0.6.2"
Class Attribute Summary collapse
-
.allow_downloads_from ⇒ Array[String], :all
A list of names which identify backends in the global backend registry.
-
.allow_origin ⇒ String
Value for Access-Control-Allow-Origin header.
-
.allow_uploads_to ⇒ Array[String], :all
A list of names which identify backends in the global backend registry.
-
.app ⇒ Refile::App?
A shortcut to the instance of the Rack application.
-
.app_host ⇒ String?
The host name that the Rack application can be reached at.
-
.automount ⇒ Boolean
Should the rack application be automounted in a Rails app?.
-
.cdn_host ⇒ String?
The host name of a CDN distribution that the Rack application can be reached at.
-
.content_max_age ⇒ Integer
Value for Cache-Control: max-age=<value in seconds> header.
-
.logger ⇒ Logger
Logger that should be used by rack application.
-
.mount_point ⇒ String
Where should the rack application be mounted? The default is ‘attachments’.
-
.secret_key ⇒ String
Value for generating signed attachment urls to protect from DoS.
Class Method Summary collapse
-
.app_url(host: nil, prefix: nil) ⇒ String
Generates a URL to the Refile application.
-
.attachment_presign_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where a presign object for the backend can be retrieved.
-
.attachment_upload_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where files can be uploaded.
-
.attachment_url(object, name, *args, host: nil, prefix: nil, filename: nil, format: nil) ⇒ String?
Generate a URL to an attachment.
-
.backends ⇒ Hash{String => Backend}
A global registry of backends.
-
.cache ⇒ Backend
A shortcut to retrieving the backend named “cache” from the global registry.
-
.cache=(backend) ⇒ Object
A shortcut to setting the backend named “cache” in the global registry.
-
.configure { ... } ⇒ Object
Yield the Refile module as a convenience for configuring multiple config options at once.
-
.extract_content_type(uploadable) ⇒ String?
Extract the content type from an uploadable object.
-
.extract_filename(uploadable) ⇒ String?
Extract the filename from an uploadable object.
-
.file_url(file, *args, host: nil, prefix: nil, filename:, format: nil) ⇒ String?
Receives a File and generates a URL to it.
-
.host ⇒ Object
deprecated
Deprecated.
use Refile.cdn_host instead
-
.host=(host) ⇒ Object
deprecated
Deprecated.
use Refile.cdn_host instead
- .parse_json(data, *args) ⇒ Object private
-
.presign_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where a presign object for the backend can be retrieved.
-
.processor(name, processor = nil) {|Refile::File| ... } ⇒ void
Adds a processor.
-
.processors ⇒ Hash{String => Proc}
A global registry of processors.
-
.store ⇒ Backend
A shortcut to retrieving the backend named “store” from the global registry.
-
.store=(backend) ⇒ Object
A shortcut to setting the backend named “store” in the global registry.
-
.token(path) ⇒ String?
Generate a signature for a given path concatenated with the configured secret token.
-
.types ⇒ Hash{Symbol => Refile::Type}
A global registry of types.
-
.upload_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where files can be uploaded.
-
.valid_token?(path, token) ⇒ Boolean
Check if the given token is a valid token for the given path.
Class Attribute Details
.allow_downloads_from ⇒ Array[String], :all
A list of names which identify backends in the global backend registry. The Rack application allows GET requests to only the backends specified in this config option. This defaults to ‘:all`, allowing files from all backends to be downloaded.
95 96 97 |
# File 'lib/refile.rb', line 95 def allow_downloads_from @allow_downloads_from end |
.allow_origin ⇒ String
Value for Access-Control-Allow-Origin header
105 106 107 |
# File 'lib/refile.rb', line 105 def allow_origin @allow_origin end |
.allow_uploads_to ⇒ Array[String], :all
A list of names which identify backends in the global backend registry. The Rack application allows POST requests to only the backends specified in this config option. This defaults to ‘[“cache”]`, only allowing direct uploads to the cache backend.
87 88 89 |
# File 'lib/refile.rb', line 87 def allow_uploads_to @allow_uploads_to end |
.app ⇒ Refile::App?
A shortcut to the instance of the Rack application. This should be set when the application is initialized. ‘refile/rails` sets this value.
35 36 37 |
# File 'lib/refile.rb', line 35 def app @app end |
.app_host ⇒ String?
The host name that the Rack application can be reached at. If not set, Refile will use an absolute URL without hostname. You should only change this setting if you are running the Refile app on a different domain than your main application.
If you are simply running the Refile app behind a CDN you’ll want to change cdn_host instead.
The difference between app_host and cdn_host is that the latter only affects URLs generated by file_url and the Refile::AttachmentHelper#attachment_url and Refile::AttachmentHelper#attachment_image_tag helpers, whereas the former also affects upload_url, presign_url and the Refile::AttachmentHelper#attachment_field helper.
67 68 69 |
# File 'lib/refile.rb', line 67 def app_host @app_host end |
.automount ⇒ Boolean
Should the rack application be automounted in a Rails app?
If set to false then Refile.app should be mounted in the Rails application routes.rb with the options ‘at: Refile.mount_point, as: :refile_app`
The default is true.
125 126 127 |
# File 'lib/refile.rb', line 125 def automount @automount end |
.cdn_host ⇒ String?
The host name of a CDN distribution that the Rack application can be reached at. If not set, Refile will use an absolute URL without hostname. It is strongly recommended to run Refile behind a CDN and to set this to the hostname of the CDN distribution.
The ‘cdn_host` setting is used when retrieving files, but not when uploading new files, since uploads should normally not go through the CDN.
A protocol relative URL is recommended for this value.
49 50 51 |
# File 'lib/refile.rb', line 49 def cdn_host @cdn_host end |
.content_max_age ⇒ Integer
Value for Cache-Control: max-age=<value in seconds> header
110 111 112 |
# File 'lib/refile.rb', line 110 def content_max_age @content_max_age end |
.logger ⇒ Logger
Logger that should be used by rack application
100 101 102 |
# File 'lib/refile.rb', line 100 def logger @logger end |
.mount_point ⇒ String
Where should the rack application be mounted? The default is ‘attachments’.
115 116 117 |
# File 'lib/refile.rb', line 115 def mount_point @mount_point end |
.secret_key ⇒ String
Value for generating signed attachment urls to protect from DoS
130 131 132 |
# File 'lib/refile.rb', line 130 def secret_key @secret_key end |
Class Method Details
.app_url(host: nil, prefix: nil) ⇒ String
Generates a URL to the Refile application.
The host defaults to app_host. You can also override the host via the ‘host` option. Normally the Refile app will not be mounted at the root but rather at some other path, the `prefix` option allows you to override this setting, and if not set it will fall back to mount_point.
276 277 278 279 280 281 282 283 |
# File 'lib/refile.rb', line 276 def app_url(host: nil, prefix: nil) host ||= Refile.app_host prefix ||= Refile.mount_point uri = URI(host.to_s) uri.path = prefix || "/" uri.to_s end |
.attachment_presign_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Refile::Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where a presign object for the backend can be retrieved.
426 427 428 429 430 |
# File 'lib/refile.rb', line 426 def (object, name, host: nil, prefix: nil) backend = object.send(:"#{name}_attachment_definition").cache presign_url(backend, host: host, prefix: prefix) end |
.attachment_upload_url(object, name, host: nil, prefix: nil) ⇒ String
Receives an instance of a class which has used the Refile::Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App where files can be uploaded.
407 408 409 410 411 |
# File 'lib/refile.rb', line 407 def (object, name, host: nil, prefix: nil) backend = object.send(:"#{name}_attachment_definition").cache upload_url(backend, host: host, prefix: prefix) end |
.attachment_url(object, name, *args, host: nil, prefix: nil, filename: nil, format: nil) ⇒ String?
Generate a URL to an attachment. Receives an instance of a class which has used the Refile::Attachment#attachment macro to generate an attachment column, and the name of this column, and based on this generates a URL to a App.
Optionally the name of a processor and arguments to it can be appended.
If the filename option is not given, the filename is taken from the metadata stored in the attachment, or eventually falls back to the ‘name`.
The host defaults to cdn_host, which is useful for serving all attachments from a CDN. You can also override the host via the ‘host` option.
Returns ‘nil` if there is no file attached.
383 384 385 386 387 388 389 390 391 392 |
# File 'lib/refile.rb', line 383 def (object, name, *args, host: nil, prefix: nil, filename: nil, format: nil) attacher = object.send(:"#{name}_attacher") file = attacher.get return unless file filename ||= attacher.basename || name.to_s format ||= attacher.extension file_url(file, *args, host: host, prefix: prefix, filename: filename, format: format) end |
.backends ⇒ Hash{String => Backend}
A global registry of backends.
135 136 137 |
# File 'lib/refile.rb', line 135 def backends @backends ||= {} end |
.cache ⇒ Backend
A shortcut to retrieving the backend named “cache” from the global registry.
209 210 211 |
# File 'lib/refile.rb', line 209 def cache backends["cache"] end |
.cache=(backend) ⇒ Object
A shortcut to setting the backend named “cache” in the global registry.
216 217 218 |
# File 'lib/refile.rb', line 216 def cache=(backend) backends["cache"] = backend end |
.configure { ... } ⇒ Object
Yield the Refile module as a convenience for configuring multiple config options at once.
224 225 226 |
# File 'lib/refile.rb', line 224 def configure yield self end |
.extract_content_type(uploadable) ⇒ String?
Extract the content type from an uploadable object. If the content type cannot be determined, this method will return ‘nil`.
247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/refile.rb', line 247 def extract_content_type(uploadable) if uploadable.respond_to?(:content_type) uploadable.content_type else filename = extract_filename(uploadable) if filename content_type = MIME::Types.of(filename).first content_type.to_s if content_type end end end |
.extract_filename(uploadable) ⇒ String?
Extract the filename from an uploadable object. If the filename cannot be determined, this method will return ‘nil`.
233 234 235 236 237 238 239 240 |
# File 'lib/refile.rb', line 233 def extract_filename(uploadable) path = if uploadable.respond_to?(:original_filename) uploadable.original_filename elsif uploadable.respond_to?(:path) uploadable.path end ::File.basename(path) if path end |
.file_url(file, *args, host: nil, prefix: nil, filename:, format: nil) ⇒ String?
Receives a File and generates a URL to it.
Optionally the name of a processor and arguments to it can be appended.
The ‘filename` option must be given.
The host defaults to cdn_host, which is useful for serving all attachments from a CDN. You can also override the host via the ‘host` option.
Returns ‘nil` if the supplied file is `nil`.
309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/refile.rb', line 309 def file_url(file, *args, host: nil, prefix: nil, filename:, format: nil) return unless file host ||= Refile.cdn_host backend_name = Refile.backends.key(file.backend) filename = Rack::Utils.escape(filename) filename << "." << format.to_s if format base_path = ::File.join("", backend_name, *args.map(&:to_s), file.id.to_s, filename) ::File.join(app_url(prefix: prefix, host: host), token(base_path), base_path) end |
.host ⇒ Object
use cdn_host instead
70 71 72 73 |
# File 'lib/refile.rb', line 70 def host warn "Refile.host is deprecated, please use Refile.cdn_host instead" cdn_host end |
.host=(host) ⇒ Object
use cdn_host instead
76 77 78 79 |
# File 'lib/refile.rb', line 76 def host=(host) warn "Refile.host is deprecated, please use Refile.cdn_host instead" self.cdn_host = host end |
.parse_json(data, *args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
471 472 473 474 475 |
# File 'lib/refile.rb', line 471 def parse_json(data, *args) JSON.parse(data.to_s, *args) rescue JSON::ParserError nil end |
.presign_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where a presign object for the backend can be retrieved.
349 350 351 |
# File 'lib/refile.rb', line 349 def presign_url(backend, host: nil, prefix: nil) ::File.join(upload_url(backend, host: host, prefix: prefix), "presign") end |
.processor(name, processor = nil) {|Refile::File| ... } ⇒ void
This method returns an undefined value.
Adds a processor. The processor must respond to ‘call`, both receiving and returning an IO-like object. Alternatively a block can be given to this method which also receives and returns an IO-like object.
An IO-like object is recommended to be an instance of the ‘IO` class or one of its subclasses, like `File` or a `StringIO`, or a `Refile::File`. It can also be any other object which responds to `size`, `read`, `eof`? `rewind` and `close` and mimics the behaviour of IO objects for these methods.
185 186 187 188 |
# File 'lib/refile.rb', line 185 def processor(name, processor = nil, &block) processor ||= block processors[name.to_s] = processor end |
.processors ⇒ Hash{String => Proc}
A global registry of processors. These will be used by the Rack application to manipulate files prior to serving them up to the user, based on options sent trough the URL. This can be used for example to resize images or to convert files to another file format.
145 146 147 |
# File 'lib/refile.rb', line 145 def processors @processors ||= {} end |
.store ⇒ Backend
A shortcut to retrieving the backend named “store” from the global registry.
194 195 196 |
# File 'lib/refile.rb', line 194 def store backends["store"] end |
.store=(backend) ⇒ Object
A shortcut to setting the backend named “store” in the global registry.
201 202 203 |
# File 'lib/refile.rb', line 201 def store=(backend) backends["store"] = backend end |
.token(path) ⇒ String?
Generate a signature for a given path concatenated with the configured secret token.
Raises an error if no secret token is configured.
442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/refile.rb', line 442 def token(path) if secret_key.nil? error = "Refile.secret_key was not set.\n\n" error << "Please add the following to your Refile configuration and restart your application:\n\n" error << "```\nRefile.secret_key = '#{SecureRandom.hex(64)}'\n```\n\n" raise error end OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), secret_key, path) end |
.types ⇒ Hash{Symbol => Refile::Type}
A global registry of types. Currently, types are simply aliases for a set of content types, but their functionality may expand in the future.
153 154 155 |
# File 'lib/refile.rb', line 153 def types @types ||= {} end |
.upload_url(backend, host: nil, prefix: nil) ⇒ String
Receives a Refile backend and returns a URL to the Refile application where files can be uploaded.
333 334 335 336 337 |
# File 'lib/refile.rb', line 333 def upload_url(backend, host: nil, prefix: nil) backend_name = Refile.backends.key(backend) ::File.join(app_url(host: host, prefix: prefix), backend_name) end |
.valid_token?(path, token) ⇒ Boolean
Check if the given token is a valid token for the given path.
463 464 465 466 467 468 |
# File 'lib/refile.rb', line 463 def valid_token?(path, token) expected = Digest::SHA1.hexdigest(token(path)) actual = Digest::SHA1.hexdigest(token) expected == actual end |