ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - keichan34/exfile: File upload persistence and processing for Phoenix / Plug
File upload persistence and processing for Phoenix / Plug - keichan34/exfile
Visit Site

GitHub - keichan34/exfile: File upload persistence and processing for Phoenix / Plug

GitHub - keichan34/exfile: File upload persistence and processing for Phoenix / Plug

Exfile

Build Status hex.pm hexdocs Deps Status

File upload persistence and processing for Phoenix / Plug, with a focus on flexibility and extendability.

Inspired heavily by Refile. If you use Ruby, check Refile out. I like it. 👍

Requires Elixir ~> 1.2. At this point, it is tested against the most recent versions of Elixir (1.2.6 and 1.3.1). Feel free to check the Travis build out.

Exfile is used in a production environment at this point, but it still may go through some breaking changes. Exfile aims to adheres to semver v2.0.

Storage Adapters

Exfile supports storage backend adapters. A local filesystem based adapter is included (Exfile.Backend.FileSystem) as an example.

File Processors

Exfile also supports file processors / filters. If you're working with images, exfile-imagemagick is recommended.

  • exfile-imagemagick -- uses ImageMagick to resize, crop, and transform images.
  • exfile-encryption -- encrypts files before uploading them and decrypts them after downloading them from the backend.

Usage Overview

Exfile applies transforms on the fly; it only stores the original file in the storage backend. It is expected to be behind a caching HTTP proxy and/or a caching CDN for performance. Because dimensions and processors are determined by the path, it is authenticated with a HMAC to make sure it is not tampered with.

The Phoenix integration comes with two helper functions, exfile_url and exfile_path.

For example, the following code will return a path to the user's profile_picture that is converted to JPEG (if not already in JPEG format) and limited to 1024 × 1024.

exfile_url(@conn, @user.profile_picture, format: "jpg", processor: "limit", processor_args: [1024, 1024])

For more information about what processors are available for images, check out exfile-imagemagick.

Installation

  1. Add exfile to your list of dependencies in mix.exs:

    def deps do
      [{:exfile, "~> 0.3.0"}]
    end
    
  2. Ensure exfile is started before your application:

    def application do
      [applications: [:exfile]]
    end
    
  3. Mount the Exfile routes in your router.

Phoenix

There is a sample Phoenix application with Exfile integrated you can check out.

defmodule MyApp.Router do
  use MyApp.Web, :router

  forward "/attachments", Exfile.Router
  ...

To use the exfile_path and exfile_url helpers, include the Exfile.Phoenix.Helpers module where you need it (probably in the view section of your web/web.ex file).

Phoenix uses Plug.Parsers with a 8 MB limit by default -- this affects Exfile too. To increase it, find Plug.Parsers in MyApp.Endpoint and add the length option:

defmodule MyApp.Endpoint do
  use Phoenix.Endpoint, otp_app: :my_app

  plug Plug.Parsers,
    ...
    length: 25_000_000 # bytes; any value you deem necessary
end

Plug

defmodule MyApp.Router do
  use Plug.Router

  forward "/attachments", to: Exfile.Router
  ...

Ecto Integration

The following example will upload a file to the backend configured as "store". If you want to upload files to an alternate backend, please take a look at Exfile.Ecto.File and Exfile.Ecto.FileTemplate for instructions on making a custom Ecto.Type for your needs.

defmodule MyApp.User do
  use Ecto.Schema

  schema "users" do
    field :profile_picture, Exfile.Ecto.File
  end
end
defmodule MyApp.Repo.Migrations.AddProfilePictureToUsers do
  use Ecto.Migration

  def change do
    alter table(:users) do
      add :profile_picture, :string
    end
  end
end

Validations

Exfile supports content type validation. Example of usage:

defmodule MyApp.User do
  # definitions here

  import Exfile.Ecto.ValidateContentType

  def changeset(model, params) do
    model
    |> cast(params, [:avatar])
    |> validate_content_type(:avatar, :image)
    |> validate_file_size(:avatar, 1_000_000) # Amount of bytes
    |> Exfile.Ecto.prepare_uploads([:avatar])
  end
end

You can specify either an atom (could be :image, :audio, :video) or a list of strings ~w(image/bmp image/gif image/jpeg).

Storing metadata to the database

You can cast_content_type and store it to the database as a separate field. You need to have a string field in your database and go:

defmodule MyApp.User do
  # definitions here

  import Exfile.Ecto.CastContentType
  import Exfile.Ecto.CastFilename

  def changeset(model, params) do
    model
    |> cast(params, [:avatar])
    |> cast_content_type(:avatar)
    |> cast_filename(:avatar)
    |> Exfile.Ecto.prepare_uploads([:avatar])
  end
end

By default, exfile will save content type to the avatar_content_type field. The filename will be saved to the avatar_filename field. You can specify custom field as the third parameter of the cast_content_type or cast_filename function.

Configuration

In config.exs:

config :exfile, Exfile,
  secret: "secret string to generate the token used to authenticate requests",
  cdn_host: "root_url", # nginx/other webserver endpoint for your website. Defaults to Phoenix HTTP endpoint
  backends: %{
    "store" => configuration for the default persistent store
    "cache" => configuration for an ephemeral store holding temporarily uploaded content
  }

See Exfile.Config for defaults.

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory