Improve replies handling

This commit is contained in:
Thomas Sileo 2019-08-25 12:48:04 +02:00
parent bb43aec474
commit 3f65368547
3 changed files with 29 additions and 11 deletions

View file

@ -2,6 +2,8 @@ import json
import traceback import traceback
from datetime import datetime from datetime import datetime
from datetime import timezone from datetime import timezone
from typing import Any
from typing import Dict
import flask import flask
import requests import requests
@ -559,9 +561,6 @@ def task_process_reply() -> _Response:
if reply.has_type(ap.ActivityType.CREATE): if reply.has_type(ap.ActivityType.CREATE):
reply = reply.get_object() reply = reply.get_object()
# Store some metadata for the UI
# FIXME(tsileo): be able to display: "In reply to @user@domain.tld"?
new_replies = [activity, reply] new_replies = [activity, reply]
while 1: while 1:
@ -579,29 +578,36 @@ def task_process_reply() -> _Response:
app.logger.info(f"root_reply={reply!r} for activity={activity!r}") app.logger.info(f"root_reply={reply!r} for activity={activity!r}")
# Ensure the "root reply" is present in the inbox/outbox
if not find_one_activity(
{**by_object_id(root_reply), **by_type(ap.ActivityType.CREATE)}
):
return ""
# In case the activity was from the inbox # In case the activity was from the inbox
update_one_activity( update_one_activity(
{**by_object_id(activity.id), **by_type(ap.ActivityType.CREATE)}, {**by_object_id(activity.id), **by_type(ap.ActivityType.CREATE)},
upsert({MetaKey.THREAD_ROOT_PARENT: root_reply}), upsert({MetaKey.THREAD_ROOT_PARENT: root_reply}),
) )
for new_reply in new_replies: for (new_reply_idx, new_reply) in enumerate(new_replies):
if find_one_activity( if find_one_activity(
{**by_object_id(new_reply.id), **by_type(ap.ActivityType.CREATE)} {**by_object_id(new_reply.id), **by_type(ap.ActivityType.CREATE)}
) or DB.replies.find_one(by_remote_id(new_reply.id)): ) or DB.replies.find_one(by_remote_id(new_reply.id)):
continue continue
actor = new_reply.get_actor() actor = new_reply.get_actor()
is_root_reply = new_reply_idx == len(new_replies) - 1
if is_root_reply:
reply_flags: Dict[str, Any] = {}
else:
reply_actor = new_replies[new_reply_idx + 1].get_actor()
is_in_reply_to_self = actor.id == reply_actor.id
reply_flags = {MetaKey.IN_REPLY_TO_SELF.value: is_in_reply_to_self}
if not is_in_reply_to_self:
reply_flags[MetaKey.IN_REPLY_TO_ACTOR.value] = reply_actor.to_dict(
embed=True
)
# Save the reply with the cached actor and the thread flag/ID # Save the reply with the cached actor and the thread flag/ID
save_reply( save_reply(
new_reply, new_reply,
{ {
**reply_flags,
MetaKey.THREAD_ROOT_PARENT.value: root_reply, MetaKey.THREAD_ROOT_PARENT.value: root_reply,
MetaKey.ACTOR.value: actor.to_dict(embed=True), MetaKey.ACTOR.value: actor.to_dict(embed=True),
MetaKey.ACTOR_HASH.value: _actor_hash(actor), MetaKey.ACTOR_HASH.value: _actor_hash(actor),

View file

@ -735,6 +735,15 @@ def handle_replies(create: ap.Create) -> None:
) )
return None return None
# Update the activity to save some data about the reply
if reply.get_actor().id == create.get_actor().id:
in_reply_to_data = {MetaKey.IN_REPLY_TO_SELF: True}
else:
in_reply_to_data = {
MetaKey.IN_REPLY_TO_ACTOR: reply.get_actor().to_dict(embed=True)
}
update_one_activity(by_remote_id(create.id), upsert(in_reply_to_data))
# It's a regular reply, try to increment the reply counter # It's a regular reply, try to increment the reply counter
creply = DB.activities.find_one_and_update( creply = DB.activities.find_one_and_update(
{**by_object_id(in_reply_to), **by_type(ap.ActivityType.CREATE)}, {**by_object_id(in_reply_to), **by_type(ap.ActivityType.CREATE)},
@ -747,4 +756,4 @@ def handle_replies(create: ap.Create) -> None:
) )
# Spawn a task to process it (and determine if it needs to be saved) # Spawn a task to process it (and determine if it needs to be saved)
Tasks.process_reply(create.get_object().id) Tasks.process_reply(create.get_object_id())

View file

@ -40,6 +40,9 @@ class MetaKey(Enum):
PUBLIC = "public" PUBLIC = "public"
THREAD_ROOT_PARENT = "thread_root_parent" THREAD_ROOT_PARENT = "thread_root_parent"
IN_REPLY_TO_SELF = "in_reply_to_self"
IN_REPLY_TO_ACTOR = "in_reply_to_actor"
SERVER = "server" SERVER = "server"
VISIBILITY = "visibility" VISIBILITY = "visibility"
OBJECT_VISIBILITY = "object_visibility" OBJECT_VISIBILITY = "object_visibility"