2020-11-26 11:41:13 +01:00
|
|
|
defmodule Mobilizon.Service.CleanOrphanMedia do
|
|
|
|
@moduledoc """
|
|
|
|
Service to clean orphan media
|
|
|
|
"""
|
|
|
|
|
|
|
|
alias Mobilizon.Actors.Actor
|
|
|
|
alias Mobilizon.Medias
|
|
|
|
alias Mobilizon.Medias.Media
|
|
|
|
alias Mobilizon.Storage.Repo
|
|
|
|
import Ecto.Query
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
Clean orphan media
|
|
|
|
|
|
|
|
Remove media that is not attached to an entity, such as media uploads that were never used in entities.
|
|
|
|
|
|
|
|
Options:
|
|
|
|
* `grace_period` how old in hours can the media be before it's taken into account for deletion
|
|
|
|
* `dry_run` just return the media that would have been deleted, don't actually delete it
|
|
|
|
"""
|
|
|
|
@spec clean(Keyword.t()) :: {:ok, list(Media.t())} | {:error, String.t()}
|
|
|
|
def clean(opts \\ []) do
|
|
|
|
medias = find_media(opts)
|
|
|
|
|
|
|
|
if Keyword.get(opts, :dry_run, false) do
|
|
|
|
{:ok, medias}
|
|
|
|
else
|
|
|
|
Enum.each(medias, fn media ->
|
|
|
|
Medias.delete_media(media, ignore_file_not_found: true)
|
|
|
|
end)
|
|
|
|
|
|
|
|
{:ok, medias}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@spec find_media(Keyword.t()) :: list(Media.t())
|
|
|
|
defp find_media(opts) do
|
2021-06-07 10:24:57 +02:00
|
|
|
default_grace_period =
|
|
|
|
Mobilizon.Config.get([:instance, :orphan_upload_grace_period_hours], 48)
|
|
|
|
|
|
|
|
grace_period = Keyword.get(opts, :grace_period, default_grace_period)
|
2020-11-26 11:41:13 +01:00
|
|
|
expiration_date = DateTime.add(DateTime.utc_now(), grace_period * -3600)
|
|
|
|
|
|
|
|
Media
|
|
|
|
|> where([m], m.inserted_at < ^expiration_date)
|
|
|
|
|> join(:inner, [m], a in Actor)
|
|
|
|
|> where([_m, a], is_nil(a.domain))
|
|
|
|
|> join(:left, [m], e in assoc(m, :events))
|
|
|
|
|> join(:left, [m], ep in assoc(m, :event_picture))
|
|
|
|
|> join(:left, [m], p in assoc(m, :posts))
|
|
|
|
|> join(:left, [m], pp in assoc(m, :posts_picture))
|
|
|
|
|> join(:left, [m], c in assoc(m, :comments))
|
|
|
|
|> where([_m, _a, e], is_nil(e.id))
|
|
|
|
|> where([_m, _a, _e, ep], is_nil(ep.id))
|
|
|
|
|> where([_m, _a, _e, _ep, p], is_nil(p.id))
|
|
|
|
|> where([_m, _a, _e, _ep, _p, pp], is_nil(pp.id))
|
|
|
|
|> where([_m, _a, _e, _ep, _p, _pp, c], is_nil(c.id))
|
|
|
|
|> distinct(true)
|
|
|
|
|> Repo.all()
|
|
|
|
end
|
|
|
|
end
|