Add uploader.ex
This commit is contained in:
parent
82f55f7afe
commit
188bc08494
1 changed files with 91 additions and 0 deletions
91
lib/nulla/uploader.ex
Normal file
91
lib/nulla/uploader.ex
Normal file
|
@ -0,0 +1,91 @@
|
|||
defmodule Nulla.Uploader do
|
||||
alias Nulla.Snowflake
|
||||
alias Nulla.MediaAttachments
|
||||
|
||||
@upload_base "priv/static/system"
|
||||
|
||||
def upload(%Plug.Upload{path: temp_path, filename: original_name}, domain, name, note_id) do
|
||||
{:ok, binary} = File.read(temp_path)
|
||||
ext = Path.extname(original_name)
|
||||
mimetype = MIME.type(ext)
|
||||
filename = Base.encode16(:crypto.strong_rand_bytes(8), case: :lower) <> ext
|
||||
media_attachment_id = Snowflake.next_id()
|
||||
|
||||
relative_path =
|
||||
Path.join([
|
||||
"media_attachments/files",
|
||||
partition_id(media_attachment_id),
|
||||
"original",
|
||||
filename
|
||||
])
|
||||
|
||||
full_path = Path.join(@upload_base, relative_path)
|
||||
|
||||
full_path |> Path.dirname() |> File.mkdir_p!()
|
||||
|
||||
File.write!(full_path, binary)
|
||||
|
||||
type =
|
||||
cond do
|
||||
mimetype =~ "image" -> "Image"
|
||||
mimetype =~ "video" -> "Video"
|
||||
mimetype =~ "audio" -> "Audio"
|
||||
true -> "Document"
|
||||
end
|
||||
|
||||
{width, height} = get_width_and_height(temp_path, mimetype)
|
||||
|
||||
MediaAttachments.create_media_attachment(%{
|
||||
id: media_attachment_id,
|
||||
type: type,
|
||||
mediaType: mimetype,
|
||||
url: "https://#{domain}/#{relative_path}",
|
||||
name: name,
|
||||
width: width,
|
||||
height: height,
|
||||
note_id: note_id
|
||||
})
|
||||
end
|
||||
|
||||
defp get_width_and_height(path, mimetype) do
|
||||
cond do
|
||||
mimetype =~ "image" or "video" ->
|
||||
{output, 0} =
|
||||
System.cmd("ffprobe", [
|
||||
"-v",
|
||||
"error",
|
||||
"-select_streams",
|
||||
"v:0",
|
||||
"-show_entries",
|
||||
"stream=width,height",
|
||||
"-of",
|
||||
"default=noprint_wrappers=1",
|
||||
path
|
||||
])
|
||||
|
||||
width =
|
||||
Regex.run(~r/width=(\d+)/, output)
|
||||
|> List.last()
|
||||
|> String.to_integer()
|
||||
|
||||
height =
|
||||
Regex.run(~r/height=(\d+)/, output)
|
||||
|> List.last()
|
||||
|> String.to_integer()
|
||||
|
||||
{width, height}
|
||||
|
||||
true ->
|
||||
{nil, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp partition_id(id) do
|
||||
id
|
||||
|> Integer.to_string()
|
||||
|> String.pad_leading(18, "0")
|
||||
|> String.graphemes()
|
||||
|> Enum.chunk_every(3)
|
||||
|> Enum.map_join("/", &Enum.join/1)
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue