mix/database/resync_inlined_caches: also resync reactions

Relies on the fixups from preceding commits being applied.
This commit is contained in:
Oneric 2025-08-06 00:00:00 +00:00
parent 7a77e7fbd1
commit 86988e71f0
2 changed files with 54 additions and 2 deletions

View file

@ -298,4 +298,5 @@ Run this task to detect and fix such desyncs.
- `--no-announcements` - Skip fixing announcement counters and lists
- `--no-likes` - Skip fixing like counters and lists
- `--no-reactions` - Skip fixing inlined emoji reaction data
- `--no-replies-count` - Skip fixing replies counters (purely cosmetic)

View file

@ -530,8 +530,8 @@ def run(["resync_inlined_caches" | args]) do
strict: [
replies_count: :boolean,
announcements: :boolean,
likes: :boolean
# TODO: reactions (emoji reacts)
likes: :boolean,
reactions: :boolean
]
)
@ -548,6 +548,10 @@ def run(["resync_inlined_caches" | args]) do
if Keyword.get(options, :likes, true) do
resync_inlined_array("Like", "like")
end
if Keyword.get(options, :reactions, true) do
resync_inlined_reactions()
end
end
def run(["clean_inlined_replies"]) do
@ -725,4 +729,51 @@ defp resync_inlined_array(activity_type, basename) do
Logger.info("Fixed inlined #{basename} array and counter for #{update_cnt} objects.")
end
defp resync_inlined_reactions() do
expanded_ref =
Pleroma.Activity
|> select([a], %{
apid: selected_as(fragment("?->>'object'", a.data), :apid),
emoji_name: selected_as(fragment("TRIM(?->>'content', ':')", a.data), :emoji_name),
actors: fragment("ARRAY_AGG(DISTINCT ?->>'actor')", a.data),
url: selected_as(fragment("?#>>'{tag,0,icon,url}'", a.data), :url)
})
|> where(
[a],
fragment("?->>'type' = 'EmojiReact'", a.data) and
fragment("?->>'actor' IS NOT NULL", a.data) and
fragment("TRIM(?->>'content', ':') IS NOT NULL", a.data)
)
|> group_by([_], [selected_as(:apid), selected_as(:emoji_name), selected_as(:url)])
ref =
from(e in subquery(expanded_ref))
|> select([e], %{
apid: e.apid,
correct:
fragment(
"jsonb_agg(DISTINCT ARRAY[to_jsonb(?), to_jsonb(?), to_jsonb(?)])",
e.emoji_name,
e.actors,
e.url
)
})
|> group_by([e], e.apid)
{update_cnt, _} =
Pleroma.Object
|> join(:inner, [o], r in subquery(ref), on: r.apid == fragment("?->>'id'", o.data))
|> where(
[o, r],
not (fragment("? @> (?->'reactions')", r.correct, o.data) and
fragment("? <@ (?->'reactions')", r.correct, o.data))
)
|> update([o, r],
set: [data: fragment("jsonb_set(?, '{reactions}', ?)", o.data, r.correct)]
)
|> Pleroma.Repo.update_all([], timeout: :infinity)
Logger.info("Fixed inlined emoji reactions for #{update_cnt} objects.")
end
end