Update uploader.ex

This commit is contained in:
Mirai Kumiko 2025-06-20 19:42:39 +02:00
parent ea667243e0
commit 4a79081fc8
Signed by: miraikumiko
GPG key ID: 3F178B1B5E0CB278

View file

@ -1,25 +1,64 @@
defmodule Nulla.Uploader do
def upload(%Plug.Upload{path: temp_path, filename: original_name}) do
alias Nulla.Snowflake
alias Nulla.Models.MediaAttachment
@upload_base "priv/static"
@upload_prefix "system"
def upload(
%Plug.Upload{path: temp_path, filename: original_name},
dir,
description,
domain
) do
{:ok, binary} = File.read(temp_path)
hash = :crypto.hash(:sha1, binary) |> Base.encode16(case: :lower)
file_type = Path.extname(original_name)
ext = Path.extname(original_name)
mimetype = MIME.type(ext)
segments =
hash
|> String.slice(0, 15)
|> String.codepoints()
type =
cond do
mimetype =~ "image" -> "Image"
mimetype =~ "video" -> "Video"
mimetype =~ "audio" -> "Audio"
true -> "Document"
end
filename = Base.encode16(:crypto.strong_rand_bytes(8), case: :lower) <> ext
media_attachment_id = Snowflake.next_id()
relative_path =
Path.join([
@upload_prefix,
dir,
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)
MediaAttachment.create_media_attachment(%{
id: media_attachment_id,
type: type,
mediaType: mimetype,
url: "https://#{domain}/#{relative_path}",
name: description,
width: 1,
height: 1
})
end
defp partition_id(id) do
id
|> Integer.to_string()
|> String.pad_leading(18, "0")
|> String.graphemes()
|> Enum.chunk_every(3)
|> Enum.map(&Enum.join/1)
filename = String.slice(hash, 15..-1//1) <> file_type
relative_path = Path.join(segments) <> "/" <> filename
dest_path = Path.join(["priv/static/files", relative_path])
dest_path |> Path.dirname() |> File.mkdir_p!()
File.write!(dest_path, binary)
relative_path
|> Enum.map_join("/", &Enum.join/1)
end
end