mirror of
https://git.pleroma.social/pleroma/pleroma.git
synced 2025-04-12 14:04:08 +00:00
Merge branch 'backups-chats' into 'develop'
Backup chats and chat messages See merge request pleroma/pleroma!4088
This commit is contained in:
commit
f5e133d44b
4 changed files with 116 additions and 5 deletions
1
changelog.d/backups-chats.add
Normal file
1
changelog.d/backups-chats.add
Normal file
|
@ -0,0 +1 @@
|
|||
Backup chats and chat messages
|
|
@ -17,7 +17,7 @@ defmodule Pleroma.Chat.MessageReference do
|
|||
import Ecto.Changeset
|
||||
import Ecto.Query
|
||||
|
||||
@primary_key {:id, FlakeId.Ecto.Type, autogenerate: true}
|
||||
@primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
|
||||
|
||||
schema "chat_message_references" do
|
||||
belongs_to(:object, Object)
|
||||
|
|
|
@ -14,6 +14,7 @@ defmodule Pleroma.User.Backup do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Bookmark
|
||||
alias Pleroma.Chat
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.SafeZip
|
||||
|
@ -185,7 +186,9 @@ defmodule Pleroma.User.Backup do
|
|||
"likes.json",
|
||||
"bookmarks.json",
|
||||
"followers.json",
|
||||
"following.json"
|
||||
"following.json",
|
||||
"chats.json",
|
||||
"chat_messages.json"
|
||||
]
|
||||
|
||||
@spec run(t()) :: {:ok, t()} | {:error, :failed}
|
||||
|
@ -200,6 +203,8 @@ defmodule Pleroma.User.Backup do
|
|||
{_, :ok} <- {:bookmarks, bookmarks(backup.tempdir, backup.user)},
|
||||
{_, :ok} <- {:followers, followers(backup.tempdir, backup.user)},
|
||||
{_, :ok} <- {:following, following(backup.tempdir, backup.user)},
|
||||
{_, :ok} <- {:chats, chats(backup.tempdir, backup.user)},
|
||||
{_, :ok} <- {:chat_messages, chat_messages(backup.tempdir, backup.user)},
|
||||
{_, {:ok, _zip_path}} <-
|
||||
{:zip, SafeZip.zip(tempfile, @files, backup.tempdir)},
|
||||
{_, {:ok, %File.Stat{size: zip_size}}} <- {:filestat, File.stat(tempfile)},
|
||||
|
@ -252,7 +257,9 @@ defmodule Pleroma.User.Backup do
|
|||
"likes" => "likes.json",
|
||||
"outbox" => "outbox.json",
|
||||
"followers" => "followers.json",
|
||||
"following" => "following.json"
|
||||
"following" => "following.json",
|
||||
"chats" => "chats.json",
|
||||
"chat_messages" => "chat_messages.json"
|
||||
})
|
||||
|> Jason.encode() do
|
||||
File.write(Path.join(dir, "actor.json"), json)
|
||||
|
@ -358,4 +365,52 @@ defmodule Pleroma.User.Backup do
|
|||
User.get_friends_query(user)
|
||||
|> write(dir, "following", fn a -> {:ok, a.ap_id} end)
|
||||
end
|
||||
|
||||
defp chats(dir, user) do
|
||||
Chat.for_user_query(user.id)
|
||||
|> write(
|
||||
dir,
|
||||
"chats",
|
||||
fn chat ->
|
||||
{:ok,
|
||||
%{
|
||||
"type" => "Chat",
|
||||
"id" => "#{Pleroma.Web.Endpoint.url()}/chats/#{chat.id}",
|
||||
"actor" => user.ap_id,
|
||||
"to" => [chat.recipient],
|
||||
"published" =>
|
||||
chat.inserted_at |> DateTime.from_naive!("Etc/UTC") |> DateTime.to_iso8601()
|
||||
}}
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
defp chat_messages(dir, %{id: user_id}) do
|
||||
chats_subquery =
|
||||
from(c in Chat,
|
||||
where: c.user_id == ^user_id,
|
||||
select: c.id
|
||||
)
|
||||
|
||||
from(cr in Chat.MessageReference,
|
||||
where: cr.chat_id in subquery(chats_subquery),
|
||||
preload: [:object]
|
||||
)
|
||||
|> write(
|
||||
dir,
|
||||
"chat_messages",
|
||||
fn reference ->
|
||||
with {:ok, activity} <- Transmogrifier.prepare_outgoing(reference.object.data),
|
||||
{:ok, activity} <-
|
||||
{:ok,
|
||||
Map.put(
|
||||
activity,
|
||||
"context",
|
||||
"#{Pleroma.Web.Endpoint.url()}/chats/#{reference.chat_id}"
|
||||
)} do
|
||||
{:ok, Map.delete(activity, "@context")}
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,9 +11,11 @@ defmodule Pleroma.User.BackupTest do
|
|||
import Mox
|
||||
|
||||
alias Pleroma.Bookmark
|
||||
alias Pleroma.Chat
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Uploaders.S3.ExAwsMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.User.Backup
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Workers.BackupWorker
|
||||
|
@ -150,8 +152,10 @@ defmodule Pleroma.User.BackupTest do
|
|||
end
|
||||
|
||||
test "it creates a zip archive with user data" do
|
||||
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
|
||||
%{ap_id: other_ap_id} = other_user = insert(:user)
|
||||
%User{ap_id: ap_id} =
|
||||
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
|
||||
|
||||
%User{ap_id: other_ap_id} = other_user = insert(:user)
|
||||
|
||||
{:ok, %{object: %{data: %{"id" => id1}}} = status1} =
|
||||
CommonAPI.post(user, %{status: "status1"})
|
||||
|
@ -170,6 +174,11 @@ defmodule Pleroma.User.BackupTest do
|
|||
|
||||
CommonAPI.follow(other_user, user)
|
||||
|
||||
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
|
||||
|
||||
{:ok, _message_1} = CommonAPI.post_chat_message(user, other_user, "hey")
|
||||
{:ok, _message_2} = CommonAPI.post_chat_message(other_user, user, "ho")
|
||||
|
||||
assert {:ok, backup} = Backup.user(user)
|
||||
assert {:ok, run_backup} = Backup.run(backup)
|
||||
|
||||
|
@ -262,6 +271,52 @@ defmodule Pleroma.User.BackupTest do
|
|||
"type" => "OrderedCollection"
|
||||
} = Jason.decode!(json)
|
||||
|
||||
assert {:ok, {~c"chats.json", json}} = :zip.zip_get(~c"chats.json", zipfile)
|
||||
|
||||
chat_id = "http://localhost:4001/chats/#{chat.id}"
|
||||
|
||||
assert %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"id" => "chats.json",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Chat",
|
||||
"id" => ^chat_id,
|
||||
"actor" => ^ap_id,
|
||||
"to" => [^other_ap_id]
|
||||
}
|
||||
],
|
||||
"totalItems" => 1,
|
||||
"type" => "OrderedCollection"
|
||||
} = Jason.decode!(json)
|
||||
|
||||
assert {:ok, {~c"chat_messages.json", json}} = :zip.zip_get(~c"chat_messages.json", zipfile)
|
||||
|
||||
chat_id = "http://localhost:4001/chats/#{chat.id}"
|
||||
|
||||
assert %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"id" => "chat_messages.json",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "ChatMessage",
|
||||
"actor" => ^ap_id,
|
||||
"to" => [^other_ap_id],
|
||||
"context" => ^chat_id,
|
||||
"content" => "hey"
|
||||
},
|
||||
%{
|
||||
"type" => "ChatMessage",
|
||||
"actor" => ^other_ap_id,
|
||||
"to" => [^ap_id],
|
||||
"context" => ^chat_id,
|
||||
"content" => "ho"
|
||||
}
|
||||
],
|
||||
"totalItems" => 2,
|
||||
"type" => "OrderedCollection"
|
||||
} = Jason.decode!(json)
|
||||
|
||||
:zip.zip_close(zipfile)
|
||||
File.rm_rf!(run_backup.tempdir)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue