Delete files when updating parent identities

Closes #127

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2019-06-05 18:29:39 +02:00
parent 10dbe14a52
commit e8cabd38d4
10 changed files with 263 additions and 25 deletions

View File

@@ -70,8 +70,8 @@ defmodule Mobilizon.Actors.Actor do
many_to_many(:memberships, Actor, join_through: Member)
belongs_to(:user, User)
has_many(:feed_tokens, FeedToken, foreign_key: :actor_id)
embeds_one(:avatar, File)
embeds_one(:banner, File)
embeds_one(:avatar, File, on_replace: :update)
embeds_one(:banner, File, on_replace: :update)
timestamps()
end

View File

@@ -9,6 +9,8 @@ defmodule Mobilizon.Actors do
alias Mobilizon.Repo
alias Mobilizon.Actors.{Actor, Bot, Member, Follower}
alias Mobilizon.Media.File
alias Ecto.Multi
alias Mobilizon.Service.ActivityPub
require Logger
@@ -119,9 +121,24 @@ defmodule Mobilizon.Actors do
def update_actor(%Actor{} = actor, attrs) do
actor
|> Actor.changeset(attrs)
|> delete_files_if_media_changed()
|> Repo.update()
end
defp delete_files_if_media_changed(%Ecto.Changeset{changes: changes} = changeset) do
Enum.each([:avatar, :banner], fn key ->
if Map.has_key?(changes, key) do
with %Ecto.Changeset{changes: %{url: new_url}} <- changes[key],
old_url <- Map.from_struct(changeset.data) |> Map.get(key) |> Map.get(:url),
false <- new_url == old_url do
MobilizonWeb.Upload.remove(old_url)
end
end
end)
changeset
end
@doc """
Deletes a Actor.
@@ -135,6 +152,26 @@ defmodule Mobilizon.Actors do
"""
@spec delete_actor(Actor.t()) :: {:ok, Actor.t()} | {:error, Ecto.Changeset.t()}
def delete_actor(%Actor{domain: nil} = actor) do
case Multi.new()
|> Multi.delete(:actor, actor)
|> Multi.run(:remove_banner, fn _repo,
%{actor: %Actor{banner: %File{url: url}}} = _picture ->
MobilizonWeb.Upload.remove(url)
end)
|> Multi.run(:remove_avatar, fn _repo,
%{actor: %Actor{avatar: %File{url: url}}} = _picture ->
MobilizonWeb.Upload.remove(url)
end)
|> Repo.transaction() do
{:ok, %{actor: %Actor{} = actor}} ->
{:ok, actor}
{:error, remove, error, _} when remove in [:remove_banner, :remove_avatar] ->
{:error, error}
end
end
def delete_actor(%Actor{} = actor) do
Repo.delete(actor)
end

View File

@@ -7,6 +7,8 @@ defmodule Mobilizon.Media do
alias Mobilizon.Repo
alias Mobilizon.Media.Picture
alias Mobilizon.Media.File
alias Ecto.Multi
@doc false
def data() do
@@ -97,7 +99,15 @@ defmodule Mobilizon.Media do
"""
def delete_picture(%Picture{} = picture) do
Repo.delete(picture)
case Multi.new()
|> Multi.delete(:picture, picture)
|> Multi.run(:remove, fn _repo, %{picture: %Picture{file: %File{url: url}}} = _picture ->
MobilizonWeb.Upload.remove(url)
end)
|> Repo.transaction() do
{:ok, %{picture: %Picture{} = picture}} -> {:ok, picture}
{:error, :remove, error, _} -> {:error, error}
end
end
@doc """