Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

First trial: upload to R2

standalones/upload-to-r2.livemd

First trial: upload to R2

Mix.install(
  [
    {:aws_signature, "~> 0.3.1"},
    {:finch, "~> 0.13"},
    {:kino, "~> 0.11.0"},
    {:ex_image_info, "~> 0.2.4"}
  ]
  # config: Config.Reader.read!("#{__DIR__}/code/elixir/up_img/config/dev.exs")
)

{:ok, conn_f} = Finch.start_link(name: MyFinch)

Section

path = Kino.FS.file_path("Screenshot_2023-08-04_at_21.04.26.png")

filename = Path.basename(path)
defmodule R2 do
  def create_url(filename) do
    System.fetch_env!("LB_R2_ENDPOINT") <>
      "/" <>
      System.fetch_env!("LB_R2_BUCKET") <>
      "/" <>
      URI.encode(filename)
  end

  def aws_sgn(filename) do
    :aws_signature.sign_v4_query_params(
      System.fetch_env!("LB_R2_CLIENT_ID"),
      System.fetch_env!("LB_R2_CLIENT_SECRET"),
      "auto",
      "s3",
      :calendar.universal_time(),
      "PUT",
      create_url(filename),
      body_digest: "UNSIGNED-PAYLOAD",
      ttl: 3600
    )
    |> dbg()
  end

  def size(path) do
    %{size: size} = File.stat!(path)
    Integer.to_string(size) |> dbg()
  end

  def find_mime(path) do
    {mime, _, _, _} =
      path
      |> File.read!()
      |> ExImageInfo.info()

    mime
  end

  def upload(path, filename) do
    mime = find_mime(path) |> dbg()
    stream_file = File.stream!(path, [], 16_384)

    headers =
      [
        {"Content-Type", mime},
        {"Content-Length", size(path)}
      ]
      |> dbg()

    Finch.build(
      "PUT",
      aws_sgn(filename),
      headers,
      {:stream, stream_file}
    )
    |> Finch.request(MyFinch)
  end
end
R2.upload(path, filename)