diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index 2833911f1..a557d71fa 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -309,35 +309,41 @@ defmodule Pleroma.Upload do end def list_duplicate_attachments(%{"id" => id, "url" => [%{"href" => href}]}) do - clean_href = %URI{ URI.parse(href) | query: nil } |> URI.to_string() + clean_href = %URI{URI.parse(href) | query: nil} |> URI.to_string() same_attachment_count = from( o in Object, - where: fragment("STARTS_WITH((?)->'url'->0->>'href', (?))", o.data, ^clean_href) and fragment("(?)->>'id' <> (?)", o.data, ^id), - ) |> Repo.all() + where: + fragment("STARTS_WITH((?)->'url'->0->>'href', (?))", o.data, ^clean_href) and + fragment("(?)->>'id' <> (?)", o.data, ^id) + ) + |> Repo.all() end def list_objects_with_attachment(href) do - clean_href = %URI{ URI.parse(href) | query: nil } |> URI.to_string() + clean_href = %URI{URI.parse(href) | query: nil} |> URI.to_string() # Ugly as sin, but I could not figure out a better way to do this in ecto # This tries to find any objects with this attachment # This DOES NOT handle chat messages and SKIPS them, because they have attachments as an object instead of an array Repo.query!( - """ - SELECT * FROM - (SELECT objects.data->>'id' AS id, jsonb_array_elements(objects.data->'attachment') as json_attachments FROM objects WHERE jsonb_typeof(objects.data->'attachment') = 'array') - WHERE STARTS_WITH(json_attachments->'url'->0->>'href', $1) - """, - [clean_href] - ).rows |> Enum.map(&List.first(&1)) + """ + SELECT * FROM + (SELECT objects.data->>'id' AS id, jsonb_array_elements(objects.data->'attachment') as json_attachments FROM objects WHERE jsonb_typeof(objects.data->'attachment') = 'array') + WHERE STARTS_WITH(json_attachments->'url'->0->>'href', $1) + """, + [clean_href] + ).rows + |> Enum.map(&List.first(&1)) end def list_uploaded_by(user, offset, limit) do from(obj in Object, - where: fragment("(?)->>'type' = ?", obj.data, "Document") and fragment("(?)->>'actor' = ?", obj.data, ^user.ap_id), - order_by: [desc: obj.id] + where: + fragment("(?)->>'type' = ?", obj.data, "Document") and + fragment("(?)->>'actor' = ?", obj.data, ^user.ap_id), + order_by: [desc: obj.id] ) |> Pagination.fetch_paginated(%{"offset" => offset, "limit" => limit}, :offset) end diff --git a/lib/pleroma/web/api_spec/operations/pleroma_util_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_util_operation.ex index 2558f4df0..e19268c4b 100644 --- a/lib/pleroma/web/api_spec/operations/pleroma_util_operation.ex +++ b/lib/pleroma/web/api_spec/operations/pleroma_util_operation.ex @@ -417,7 +417,9 @@ defmodule Pleroma.Web.ApiSpec.PleromaUtilOperation do type: :object, properties: %{ uploaded: %Schema{ - type: :string, description: "Date and time when the attachment was uploaded", format: :"date-time" + type: :string, + description: "Date and time when the attachment was uploaded", + format: :"date-time" }, attachment: Attachment } diff --git a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex index cb72b4d13..76c68e9bb 100644 --- a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex @@ -89,7 +89,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do ) do with %Object{} = object <- Object.get_by_id(id), :ok <- Object.authorize_access(object, user), - href <- object.data["url"] |> List.first |> Map.get("href"), + href <- object.data["url"] |> List.first() |> Map.get("href"), {:used, []} <- {:used, Pleroma.Upload.list_objects_with_attachment(href)}, {:ok, _, _} <- Object.delete(object) do conn @@ -99,26 +99,34 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do {:used, list} -> conn |> put_status(:bad_request) - |> json(%{error: "Refusing to delete attachment that is still used by #{Enum.count(list)} objects"}) + |> json(%{ + error: "Refusing to delete attachment that is still used by #{Enum.count(list)} objects" + }) end end def update(conn, data), do: show(conn, data) @doc "GET /api/v1/media/:id" - def show(%{assigns: %{user: user}, private: %{open_api_spex: %{params: %{id: id, attachment_usage: attachment_usage}}}} = conn, _) do + def show( + %{ + assigns: %{user: user}, + private: %{open_api_spex: %{params: %{id: id, attachment_usage: attachment_usage}}} + } = conn, + _ + ) do with %Object{data: data, id: object_id} = object <- Object.get_by_id(id), :ok <- Object.authorize_access(object, user) do - attachment_data = Map.put(data, "id", object_id) + attachment_data = if attachment_usage do - href = data["url"] |> List.first |> Map.get("href") + href = data["url"] |> List.first() |> Map.get("href") used_in_objects = Pleroma.Upload.list_objects_with_attachment(href) attachment_duplicates = Pleroma.Upload.list_duplicate_attachments(object.data) - |> Enum.group_by(& if &1.data["actor"] == user.ap_id, do: :own, else: :other) + |> Enum.group_by(&if &1.data["actor"] == user.ap_id, do: :own, else: :other) |> Map.new(fn {key, val} -> {key, length(val)} end) put_in( diff --git a/lib/pleroma/web/pleroma_api/controllers/util_controller.ex b/lib/pleroma/web/pleroma_api/controllers/util_controller.ex index bc72e197e..4ec9e92e7 100644 --- a/lib/pleroma/web/pleroma_api/controllers/util_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/util_controller.ex @@ -278,21 +278,27 @@ defmodule Pleroma.Web.PleromaAPI.UtilController do end def uploaded_media( - %{assigns: %{user: user}, private: %{open_api_spex: %{params: %{ offset: offset }}}} = conn, + %{assigns: %{user: user}, private: %{open_api_spex: %{params: %{offset: offset}}}} = conn, _ ) do - result = Pleroma.Upload.list_uploaded_by(user, offset, 50) - |> Enum.map( - fn %Pleroma.Object{ id: id, data: %{ "url" => [ mediaUrl ], "name" => name }, inserted_at: uploaded } -> - %{ - uploaded: uploaded, attachment: %{ - description: name, id: to_string(id), url: mediaUrl["href"], pleroma: %{ mime_type: mediaUrl["mediaType"] }, type: "unknown" - } + |> Enum.map(fn %Pleroma.Object{ + id: id, + data: %{"url" => [mediaUrl], "name" => name}, + inserted_at: uploaded + } -> + %{ + uploaded: uploaded, + attachment: %{ + description: name, + id: to_string(id), + url: mediaUrl["href"], + pleroma: %{mime_type: mediaUrl["mediaType"]}, + type: "unknown" } - end - ) + } + end) json(conn, result) end diff --git a/lib/pleroma/workers/attachments_cleanup_worker.ex b/lib/pleroma/workers/attachments_cleanup_worker.ex index 441e1fcea..74d296093 100644 --- a/lib/pleroma/workers/attachments_cleanup_worker.ex +++ b/lib/pleroma/workers/attachments_cleanup_worker.ex @@ -17,7 +17,6 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do "object" => %{"data" => %{"attachment" => [_ | _] = attachments, "actor" => actor}} } }) do - if Pleroma.Config.get([:instance, :cleanup_attachments], false) do attachments |> Enum.flat_map(fn item -> Enum.map(item["url"], & &1["href"]) end) @@ -33,12 +32,12 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do def perform(%Job{ args: %{ "op" => "cleanup_attachments", - "object" => %{"data" => %{ "type" => "Document", "url" => [%{"href" => href}]}} = object_data + "object" => + %{"data" => %{"type" => "Document", "url" => [%{"href" => href}]}} = object_data } }) do - if Pleroma.Config.get([:instance, :cleanup_attachments], false) do - clean_href = %URI{ URI.parse(href) | query: nil } |> URI.to_string() + clean_href = %URI{URI.parse(href) | query: nil} |> URI.to_string() same_attachment_count = Pleroma.Upload.list_duplicate_attachments(object_data) @@ -48,17 +47,17 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do # No posts with this attachment, either if attachment_post_ids == [] do base_url = - String.trim_trailing( - Pleroma.Upload.base_url(), - "/" - ) + String.trim_trailing( + Pleroma.Upload.base_url(), + "/" + ) - uploader = Pleroma.Config.get([Pleroma.Upload, :uploader]) + uploader = Pleroma.Config.get([Pleroma.Upload, :uploader]) - clean_href - |> String.trim_leading("#{base_url}") - |> uploader.delete_file() - end + clean_href + |> String.trim_leading("#{base_url}") + |> uploader.delete_file() + end end end @@ -97,8 +96,6 @@ 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 filter_objects(objects) do - IO.inspect(objects) - Enum.reduce(objects, {[], []}, fn {href, %{id: id, count: count}}, {ids, hrefs} -> with 1 <- count do {ids ++ [id], hrefs ++ [href]}