distraction.party/lib/pleroma/uploaders/s3.ex

91 lines
2.2 KiB
Elixir
Raw Normal View History

# Pleroma: A lightweight social networking server
2018-12-31 15:41:47 +00:00
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
2018-08-28 01:20:54 +00:00
defmodule Pleroma.Uploaders.S3 do
@behaviour Pleroma.Uploaders.Uploader
2018-11-23 16:40:45 +00:00
require Logger
alias Pleroma.Config
# The file name is re-encoded with S3's constraints here to comply with previous
# links with less strict filenames
@impl true
2018-11-23 16:40:45 +00:00
def get_file(file) do
config = Config.get([__MODULE__])
2019-01-21 13:42:16 +00:00
bucket = Keyword.fetch!(config, :bucket)
bucket_with_namespace =
cond do
truncated_namespace = Keyword.get(config, :truncated_namespace) ->
truncated_namespace
namespace = Keyword.get(config, :bucket_namespace) ->
namespace <> ":" <> bucket
true ->
bucket
2019-01-21 13:42:16 +00:00
end
2018-11-23 16:40:45 +00:00
{:ok,
{:url,
Path.join([
Keyword.fetch!(config, :public_endpoint),
2019-01-21 13:42:16 +00:00
bucket_with_namespace,
2018-11-23 16:40:45 +00:00
strict_encode(URI.decode(file))
])}}
end
2018-08-28 01:20:54 +00:00
@impl true
2019-02-06 19:19:39 +00:00
def put_file(%Pleroma.Upload{} = upload) do
config = Config.get([__MODULE__])
2018-11-23 16:40:45 +00:00
bucket = Keyword.get(config, :bucket)
streaming = Keyword.get(config, :streaming_enabled)
2018-08-28 01:20:54 +00:00
2018-11-29 20:11:45 +00:00
s3_name = strict_encode(upload.path)
2018-08-28 01:20:54 +00:00
2018-11-23 16:40:45 +00:00
op =
if streaming do
upload.tempfile
|> ExAws.S3.Upload.stream_file()
|> ExAws.S3.upload(bucket, s3_name, [
{:acl, :public_read},
{:content_type, upload.content_type}
])
else
{:ok, file_data} = File.read(upload.tempfile)
ExAws.S3.put_object(bucket, s3_name, file_data, [
{:acl, :public_read},
{:content_type, upload.content_type}
])
end
2018-11-23 16:40:45 +00:00
case ExAws.request(op) do
{:ok, _} ->
{:ok, {:file, s3_name}}
2018-11-23 16:40:45 +00:00
error ->
Logger.error("#{__MODULE__}: #{inspect(error)}")
{:error, "S3 Upload failed"}
end
2018-08-28 01:20:54 +00:00
end
@impl true
def delete_file(file) do
[__MODULE__, :bucket]
|> Config.get()
|> ExAws.S3.delete_object(file)
|> ExAws.request()
|> case do
{:ok, %{status_code: 204}} -> :ok
error -> {:error, inspect(error)}
end
end
2018-11-23 16:40:45 +00:00
@regex Regex.compile!("[^0-9a-zA-Z!.*/'()_-]")
def strict_encode(name) do
String.replace(name, @regex, "-")
end
2018-08-28 01:20:54 +00:00
end