Last active
September 18, 2017 15:28
-
-
Save rsgrafx/21746ddf4c3dc6a2ebf2a17de5055408 to your computer and use it in GitHub Desktop.
Setting up Arc in a phoenix app that was ported from a rails app using paperclip.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ecto - Model | |
defmodule YourPhoenixApp.PaperclipAvatar do | |
use YourPhoenixApp.Web, :model | |
alias YourPhoenixApp.{Repo, PaperclipAvatar} | |
# | |
# There are places in my existing app where only the avatar image is required. | |
# So I created a module that sole purpose was to read that data. | |
# | |
schema "users" do | |
field :avatar_file_name, :string | |
field :avatar_content_type, :string | |
field :avatar_file_size, :integer | |
field :avatar_updated_at, Ecto.DateTime | |
end | |
@_epoch :calendar.datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}) | |
def paperclip_hash do | |
System.get_env("PAPERCLIP_HASH_SECRET") | |
end | |
def to_timestamp(datetime) do | |
datetime | |
|> Ecto.DateTime.to_erl | |
|> :calendar.datetime_to_gregorian_seconds | |
|> -@_epoch | |
end | |
end | |
# Arc Uploader | |
defmodule YourPhoenixApp.Avatar do | |
use Arc.Definition | |
use Arc.Ecto.Definition | |
alias YourPhoenixApp.{PaperclipAvatar, Repo} | |
# Include ecto support (requires package arc_ecto installed): | |
# use Arc.Ecto.Definition | |
# Override the persisted filenames: | |
@acl :public_read_write | |
@versions [:original, :thumb] | |
# To add a thumbnail version: | |
# Whitelist file extensions: | |
def validate({file, _}) do | |
~w(.jpg .jpeg .gif .png) |> Enum.member?(Path.extname(file.file_name)) | |
end | |
# Define a thumbnail transformation: | |
# def transform(:thumb, _) do | |
# {:convert, "-strip -thumbnail 250x250^ -gravity center -extent 250x250 -format png"} | |
# end | |
# Override the persisted filenames: | |
# def filename(version, _) do | |
# version | |
# end | |
def __storage, do: Arc.Storage.S3 | |
def storage_dir(style, base) do | |
{_, legacy} = base | |
case legacy do | |
%YourPhoenixApp.PaperclipAvatar{} -> paperclip_url(style, legacy) | |
_ -> _avatar_url_hash(style, legacy) | |
end | |
end | |
defp _avatar_url_hash(style, legacy) do | |
ecto_date = case Mix.env do | |
:dev -> legacy.created_at | |
:prod -> legacy.created_at | |
:test -> legacy.inserted_at | |
end | |
timestamp = ecto_date |> PaperclipAvatar.to_timestamp | |
hash = "users/avatars/#{legacy.id}/#{style}/#{timestamp}" | |
|> _encode |> String.downcase | |
"users/#{hash}/#{legacy.id}/#{style}" | |
end | |
def paperclip_url(style, legacy) do | |
coded = _storage_dir(style, legacy) | |
|> _encode | |
|> String.downcase | |
"users/#{coded}/#{legacy.id}/#{style}/" | |
end | |
defp _storage_dir(hash, legacy) do | |
timestamp = paperclip_timestamp(legacy) | |
"users/avatars/#{legacy.id}/#{hash}/#{timestamp}" | |
end | |
def paperclip_timestamp(%YourPhoenixApp.PaperclipAvatar{}=legacy) do | |
legacy.avatar_updated_at | |
|> YourPhoenixApp.PaperclipAvatar.to_timestamp | |
end | |
def paperclip_timestamp(not_legacy), do: :os.system_time(:seconds) | |
def _encode(url) do | |
:crypto.hmac(:sha, System.get_env("PAPERCLIP_HASH_SECRET"), url) | |
|> Base.encode16 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment