diff --git a/config/config.exs b/config/config.exs index 2e6b0796a..1f10167e5 100644 --- a/config/config.exs +++ b/config/config.exs @@ -551,6 +551,7 @@ queues: [ activity_expiration: 10, token_expiration: 5, + backup: 1, federator_incoming: 50, federator_outgoing: 50, ingestion_queue: 50, diff --git a/config/description.exs b/config/description.exs index 6fa78a5d1..13e44afe8 100644 --- a/config/description.exs +++ b/config/description.exs @@ -2288,6 +2288,12 @@ description: "Activity expiration queue", suggestions: [10] }, + %{ + key: :backup, + type: :integer, + description: "Backup queue", + suggestions: [1] + }, %{ key: :attachments_cleanup, type: :integer, diff --git a/lib/pleroma/backup.ex b/lib/pleroma/backup.ex index 4580d8f92..9b5d2625f 100644 --- a/lib/pleroma/backup.ex +++ b/lib/pleroma/backup.ex @@ -30,7 +30,7 @@ defmodule Pleroma.Backup do def create(user) do with :ok <- validate_limit(user), {:ok, backup} <- user |> new() |> Repo.insert() do - {:ok, backup} + Pleroma.Workers.BackupWorker.enqueue("process", %{"backup_id" => backup.id}) end end @@ -71,6 +71,15 @@ def get_last(user_id) do |> Repo.one() end + def remove_outdated(%__MODULE__{id: latest_id, user_id: user_id}) do + __MODULE__ + |> where(user_id: ^user_id) + |> where([b], b.id != ^latest_id) + |> Repo.delete_all() + end + + def get(id), do: Repo.get(__MODULE__, id) + def process(%__MODULE__{} = backup) do with {:ok, zip_file} <- zip(backup), {:ok, %{size: size}} <- File.stat(zip_file), diff --git a/lib/pleroma/workers/backup_worker.ex b/lib/pleroma/workers/backup_worker.ex new file mode 100644 index 000000000..c982ffa3a --- /dev/null +++ b/lib/pleroma/workers/backup_worker.ex @@ -0,0 +1,17 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Workers.BackupWorker do + alias Pleroma.Backup + + use Pleroma.Workers.WorkerHelper, queue: "backup" + + @impl Oban.Worker + def perform(%Job{args: %{"op" => "process", "backup_id" => backup_id}}) do + with {:ok, %Backup{} = backup} <- + backup_id |> Backup.get() |> Backup.process() do + {:ok, backup} + end + end +end diff --git a/test/backup_test.exs b/test/backup_test.exs index 27f5cb7f7..5b1f76dd9 100644 --- a/test/backup_test.exs +++ b/test/backup_test.exs @@ -3,35 +3,43 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.BackupTest do + use Oban.Testing, repo: Pleroma.Repo use Pleroma.DataCase + import Pleroma.Factory import Mock alias Pleroma.Backup alias Pleroma.Bookmark alias Pleroma.Web.CommonAPI + alias Pleroma.Workers.BackupWorker - test "it creates a backup record" do + setup do: clear_config([Pleroma.Upload, :uploader]) + + test "it creates a backup record and an Oban job" do %{id: user_id} = user = insert(:user) - assert {:ok, backup} = Backup.create(user) + assert {:ok, %Oban.Job{args: args}} = Backup.create(user) + assert_enqueued(worker: BackupWorker, args: args) + backup = Backup.get(args["backup_id"]) assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup end test "it return an error if the export limit is over" do %{id: user_id} = user = insert(:user) limit_days = 7 - - assert {:ok, backup} = Backup.create(user) + assert {:ok, %Oban.Job{args: args}} = Backup.create(user) + backup = Backup.get(args["backup_id"]) assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup assert Backup.create(user) == {:error, "Last export was less than #{limit_days} days ago"} end test "it process a backup record" do + Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) %{id: user_id} = user = insert(:user) - assert {:ok, %{id: backup_id} = backup} = Backup.create(user) - assert {:ok, %Backup{} = backup} = Backup.process(backup) + assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id}} = job} = Backup.create(user) + assert {:ok, backup} = BackupWorker.perform(job) assert backup.file_size > 0 assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup end