diff --git a/lib/pleroma/plugs/uploaded_media.ex b/lib/pleroma/plugs/uploaded_media.ex index 94147e0c4..2f3fde002 100644 --- a/lib/pleroma/plugs/uploaded_media.ex +++ b/lib/pleroma/plugs/uploaded_media.ex @@ -10,6 +10,8 @@ defmodule Pleroma.Plugs.UploadedMedia do import Pleroma.Web.Gettext require Logger + alias Pleroma.Web.MediaProxy + @behaviour Plug # no slashes @path "media" @@ -35,8 +37,7 @@ defmodule Pleroma.Plugs.UploadedMedia do %{query_params: %{"name" => name}} = conn -> name = String.replace(name, "\"", "\\\"") - conn - |> put_resp_header("content-disposition", "filename=\"#{name}\"") + put_resp_header(conn, "content-disposition", "filename=\"#{name}\"") conn -> conn @@ -47,7 +48,8 @@ defmodule Pleroma.Plugs.UploadedMedia do with uploader <- Keyword.fetch!(config, :uploader), proxy_remote = Keyword.get(config, :proxy_remote, false), - {:ok, get_method} <- uploader.get_file(file) do + {:ok, get_method} <- uploader.get_file(file), + false <- media_is_deleted(conn, get_method) do get_media(conn, get_method, proxy_remote, opts) else _ -> @@ -59,6 +61,14 @@ defmodule Pleroma.Plugs.UploadedMedia do def call(conn, _opts), do: conn + defp media_is_deleted(%{request_path: path} = _conn, {:static_dir, _}) do + MediaProxy.in_deleted_urls(Pleroma.Web.base_url() <> path) + end + + defp media_is_deleted(_, {:url, url}), do: MediaProxy.in_deleted_urls(url) + + defp media_is_deleted(_, _), do: false + defp get_media(conn, {:static_dir, directory}, _, opts) do static_opts = Map.get(opts, :static_plug_opts) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index d1a4efa28..6e407103f 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -95,7 +95,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do Task.start(fn -> attachments |> Enum.flat_map(fn - %{"url" => urls} -> Enum.map(urls, & &1["href"]) + %{"url" => urls} -> Enum.map(urls, &MediaProxy.url(&1["href"])) _ -> [] end) |> MediaProxy.remove_from_deleted_urls() diff --git a/lib/pleroma/workers/attachments_cleanup_worker.ex b/lib/pleroma/workers/attachments_cleanup_worker.ex index c9f69e85a..e2a37a942 100644 --- a/lib/pleroma/workers/attachments_cleanup_worker.ex +++ b/lib/pleroma/workers/attachments_cleanup_worker.ex @@ -39,19 +39,20 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do ) # find all objects for copies of the attachments, name and actor doesn't matter here - {object_ids, attachment_urls} = + {object_ids, attachment_urls, exclude_urls} = hrefs |> fetch_objects |> prepare_objects(actor, Enum.map(attachments, & &1["name"])) - |> Enum.reduce({[], []}, fn {href, %{id: id, count: count}}, {ids, hrefs} -> + |> Enum.reduce({[], [], []}, fn {href, %{id: id, count: count}}, + {ids, hrefs, exclude_urls} -> with 1 <- count do - {ids ++ [id], hrefs ++ [href]} + {ids ++ [id], hrefs ++ [href], exclude_urls} else - _ -> {ids ++ [id], hrefs} + _ -> {ids ++ [id], hrefs, exclude_urls ++ [href]} end end) - lock_attachments(MediaProxy.Invalidation.enabled(), attachment_urls) + lock_attachments(MediaProxy.Invalidation.enabled(), hrefs -- exclude_urls) Enum.each(attachment_urls, fn href -> href @@ -59,15 +60,21 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do |> uploader.delete_file() end) - Repo.delete_all(from(o in Object, where: o.id in ^object_ids)) + delete_objects(object_ids) - cache_purge(MediaProxy.Invalidation.enabled(), attachment_urls) + cache_purge(MediaProxy.Invalidation.enabled(), hrefs -- exclude_urls) {:ok, :success} end def perform(%{"op" => "cleanup_attachments", "object" => _object}, _job), do: {:ok, :skip} + defp delete_objects([_ | _] = object_ids) do + Repo.delete_all(from(o in Object, where: o.id in ^object_ids)) + end + + defp delete_objects(_), do: :ok + defp cache_purge(true, urls), do: MediaProxy.Invalidation.purge(urls) defp cache_purge(_, _), do: :ok @@ -76,7 +83,7 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do # we should delete 1 object for any given attachment, but don't delete # files if there are more than 1 object for it - defp prepare_objects(objects, actor, names) do + def prepare_objects(objects, actor, names) do objects |> Enum.reduce(%{}, fn %{ id: id, @@ -101,7 +108,7 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do end) end - defp fetch_objects(hrefs) do + def fetch_objects(hrefs) do from(o in Object, where: fragment(