A Phoenix.LiveView.UploadWriter that streams an upload straight into a
Dropbox upload session — the bytes never touch your server's disk.
LiveView's default writer spools each entry into a temporary file, so a
500 MB upload is written to disk in full before consume_uploaded_entry/3
can hand it to Magpie.Files.upload_file/4. This writer skips that round
trip: chunks are buffered in memory up to :chunk_size and appended to an
upload session as they arrive.
Usage
socket =
allow_upload(socket, :report,
accept: ~w(.pdf),
max_file_size: 500_000_000,
writer: fn _name, entry, _socket ->
{Magpie.LiveView.UploadWriter,
client: MyApp.dropbox_client(), path: "/Reports/" <> entry.client_name}
end
)consume_uploaded_entries/3 then receives whatever meta/1 returns, so the
Dropbox metadata of the committed file is already there — nothing left to
upload:
consume_uploaded_entries(socket, :report, fn %{metadata: metadata}, _entry ->
{:ok, metadata}
end)Options
:client(required) — aMagpie.Client:path(required) — the destination path in Dropbox:chunk_size— bytes buffered before each append (default 8 MiB). Dropbox wants every append but the last to be a multiple of 4 MiB, so keep this a multiple of 4 MiB.:mode—"add"(default) or"overwrite":autorename— defaulttrue:mute— defaultfalse
Notes
Magpie does not depend on :phoenix_live_view — the behaviour is a plain
set of callbacks, and declaring it would drag Phoenix into every project
that only wants a Dropbox client. The callbacks below match
Phoenix.LiveView.UploadWriter as of LiveView 1.0.
They run in the per-entry Phoenix.LiveView.UploadChannel process, not in
the LiveView itself: a slow append backpressures that one upload instead of
blocking the rest of the page.
The session is opened in init/1. A cancelled or failed upload leaves it
dangling, which is harmless — Dropbox drops incomplete sessions after 7 days
and nothing is committed without a finish.
Summary
Functions
Commits the session on :done, sending whatever is left in the buffer along
with the finish call. Any other reason (:cancel, an upstream error) leaves
the session uncommitted.
Opens the upload session. See the module docs for the accepted options.
What consume_uploaded_entries/3 receives: the destination path and the
Dropbox metadata of the committed file.
Buffers data, appending to the session whenever :chunk_size is reached.
Functions
Commits the session on :done, sending whatever is left in the buffer along
with the finish call. Any other reason (:cancel, an upstream error) leaves
the session uncommitted.
Opens the upload session. See the module docs for the accepted options.
What consume_uploaded_entries/3 receives: the destination path and the
Dropbox metadata of the committed file.
Buffers data, appending to the session whenever :chunk_size is reached.