# Copyright © 2022 Claudio Maradonna # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Uploaders.IPFS do @behaviour Pleroma.Uploaders.Uploader require Logger alias Pleroma.Config alias Tesla.Multipart defp get_final_url(method) do config = Config.get([__MODULE__]) post_base_url = Keyword.get(config, :post_gateway_url) Path.join([post_base_url, method]) end def put_file_endpoint do get_final_url("/api/v0/add") end def delete_file_endpoint do get_final_url("/api/v0/files/rm") end def api_add_params do config = Config.get([__MODULE__]) default_params = ["cid-version": "1"] user_params = Keyword.get(config, :api_add_params, default_params) if is_list(user_params) do user_params else default_params end end @placeholder "{CID}" def placeholder, do: @placeholder @impl true def get_file(file) do b_url = Pleroma.Upload.base_url() if String.contains?(b_url, @placeholder) do {:ok, {:url, String.replace(b_url, @placeholder, URI.decode(file))}} else {:error, "IPFS Get URL doesn't contain 'cid' placeholder"} end end @impl true def put_file(%Pleroma.Upload{} = upload) do mp = Multipart.new() |> Multipart.add_content_type_param("charset=utf-8") |> Multipart.add_file(upload.tempfile) case Pleroma.HTTP.post(put_file_endpoint(), mp, [], params: api_add_params()) do {:ok, ret} -> Logger.error(ret) case Jason.decode(ret.body) do {:ok, ret} -> if Map.has_key?(ret, "Hash") do {:ok, {:file, ret["Hash"]}} else {:error, "JSON doesn't contain Hash key"} end error -> Logger.error("#{__MODULE__}: #{inspect(error)}") {:error, "JSON decode failed"} end error -> Logger.error("#{__MODULE__}: #{inspect(error)}") {:error, "IPFS Gateway upload failed"} end end @impl true def delete_file(file) do case Pleroma.HTTP.post(delete_file_endpoint(), "", [], params: [arg: file]) do {:ok, %{status_code: 204}} -> :ok error -> {:error, inspect(error)} end end end