feat: simple, but not stupid, uploader for IPFS

fix: format fix with credo
This commit is contained in:
Claudio Maradonna 2022-04-07 18:25:02 +02:00
parent 29f4ab640b
commit fa2a6d5d6b
No known key found for this signature in database
GPG Key ID: 0CBA58694C5680D9
5 changed files with 107 additions and 2 deletions

View File

@ -82,6 +82,10 @@ config :ex_aws, :s3,
# region: "us-east-1", # may be required for Amazon AWS # region: "us-east-1", # may be required for Amazon AWS
scheme: "https://" scheme: "https://"
config :pleroma, Pleroma.Uploaders.IPFS,
post_gateway_url: nil,
get_gateway_url: nil
config :pleroma, :emoji, config :pleroma, :emoji,
shortcode_globs: ["/emoji/custom/**/*.png"], shortcode_globs: ["/emoji/custom/**/*.png"],
pack_extensions: [".png", ".gif"], pack_extensions: [".png", ".gif"],

View File

@ -136,6 +136,30 @@ config :pleroma, :config_description, [
} }
] ]
}, },
%{
group: :pleroma,
key: Pleroma.Uploaders.IPFS,
type: :group,
description: "IPFS uploader-related settings",
children: [
%{
key: :get_gateway_url,
type: :string,
description: "GET Gateway URL",
suggestions: [
"get_gateway_url"
]
},
%{
key: :post_gateway_url,
type: :string,
description: "POST Gateway URL",
suggestions: [
"post_gateway_url"
]
}
]
},
%{ %{
group: :pleroma, group: :pleroma,
key: Pleroma.Uploaders.S3, key: Pleroma.Uploaders.S3,

View File

@ -58,6 +58,10 @@ config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true
# https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects # https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects
config :phoenix, :plug_init_mode, :runtime config :phoenix, :plug_init_mode, :runtime
config :pleroma, Pleroma.Uploaders.IPFS,
post_gateway_url: nil,
get_gateway_url: nil
if File.exists?("./config/dev.secret.exs") do if File.exists?("./config/dev.secret.exs") do
import_config "dev.secret.exs" import_config "dev.secret.exs"
else else

View File

@ -235,8 +235,14 @@ defmodule Pleroma.Upload do
"" ""
end end
[base_url, path] uploader = Config.get([Pleroma.Upload, :uploader])
|> Path.join()
if uploader == Pleroma.Uploaders.IPFS && String.contains?(base_url, "{CID}") do
String.replace(base_url, "{CID}", path)
else
[base_url, path]
|> Path.join()
end
end end
defp url_from_spec(_upload, _base_url, {:url, url}), do: url defp url_from_spec(_upload, _base_url, {:url, url}), do: url
@ -273,6 +279,9 @@ defmodule Pleroma.Upload do
Path.join([upload_base_url, bucket_with_namespace]) Path.join([upload_base_url, bucket_with_namespace])
end end
Pleroma.Uploaders.IPFS ->
Config.get([Pleroma.Uploaders.IPFS, :get_gateway_url])
_ -> _ ->
public_endpoint || upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/" public_endpoint || upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"
end end

View File

@ -0,0 +1,64 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Uploaders.IPFS do
@behaviour Pleroma.Uploaders.Uploader
require Logger
alias Pleroma.Config
alias Tesla.Multipart
@impl true
def get_file(file) do
b_url = Pleroma.Upload.base_url()
if String.contains?(b_url, "{CID}") do
{:ok, {:url, String.replace(b_url, "{CID}", URI.decode(file))}}
else
{:error, "IPFS Get URL doesn't contain '{CID}' placeholder"}
end
end
@impl true
def put_file(%Pleroma.Upload{} = upload) do
config = Config.get([__MODULE__])
post_base_url = Keyword.get(config, :post_gateway_url)
mp =
Multipart.new()
|> Multipart.add_content_type_param("charset=utf-8")
|> Multipart.add_file(upload.tempfile)
final_url = Path.join([post_base_url, "/api/v0/add"])
case Pleroma.HTTP.post(final_url, mp, [], params: ["cid-version": "1"]) do
{:ok, ret} ->
case Jason.decode(ret.body) do
{:ok, ret} ->
{:ok, {:file, ret["Hash"]}}
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
config = Config.get([__MODULE__])
post_base_url = Keyword.get(config, :post_gateway_url)
final_url = Path.join([post_base_url, "/api/v0/files/rm"])
case Pleroma.HTTP.post(final_url, "", [], params: [arg: file]) do
{:ok, %{status_code: 204}} -> :ok
error -> {:error, inspect(error)}
end
end
end