diff --git a/app/activitypub.py b/app/activitypub.py index 3080649..968929d 100644 --- a/app/activitypub.py +++ b/app/activitypub.py @@ -11,6 +11,7 @@ from markdown import markdown from app import config from app.config import ALSO_KNOWN_AS from app.config import AP_CONTENT_TYPE # noqa: F401 +from app.config import MOVED_TO from app.httpsig import auth from app.key import get_pubkey_as_pem from app.source import hashtagify @@ -131,6 +132,9 @@ ME = { if ALSO_KNOWN_AS: ME["alsoKnownAs"] = [ALSO_KNOWN_AS] +if MOVED_TO: + ME["movedTo"] = MOVED_TO + class NotAnObjectError(Exception): def __init__(self, url: str, resp: httpx.Response | None = None) -> None: diff --git a/app/actor.py b/app/actor.py index a8dc734..32c8434 100644 --- a/app/actor.py +++ b/app/actor.py @@ -322,4 +322,7 @@ def _actor_hash(actor: Actor) -> bytes: h.update(actor.public_key_id.encode()) h.update(actor.public_key_as_pem.encode()) + if actor.moved_to: + h.update(actor.moved_to.encode()) + return h.digest() diff --git a/app/boxes.py b/app/boxes.py index bf8e708..f38c296 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -29,6 +29,7 @@ from app.config import BASE_URL from app.config import BLOCKED_SERVERS from app.config import ID from app.config import MANUALLY_APPROVES_FOLLOWERS +from app.config import set_moved_to from app.database import AsyncSession from app.outgoing_activities import new_outgoing_activity from app.source import markdownify @@ -394,10 +395,13 @@ async def send_move( if not outbox_object.id: raise ValueError("Should never happen") - recipients = await compute_all_known_recipients(db_session) + recipients = await _get_followers_recipients(db_session) for rcp in recipients: await new_outgoing_activity(db_session, rcp, outbox_object.id) + # Store the moved to in order to update the profile + set_moved_to(target) + await db_session.commit() diff --git a/app/config.py b/app/config.py index c5f80e6..e27f8bd 100644 --- a/app/config.py +++ b/app/config.py @@ -48,6 +48,19 @@ try: except FileNotFoundError: pass +MOVED_TO_FILE = ROOT_DIR / "data" / "moved_to.dat" + + +def _get_moved_to() -> str | None: + if not MOVED_TO_FILE.exists(): + return None + + return MOVED_TO_FILE.read_text() + + +def set_moved_to(moved_to: str) -> None: + MOVED_TO_FILE.write_text(moved_to) + VERSION = f"2.0.0+{VERSION_COMMIT}" USER_AGENT = f"microblogpub/{VERSION}" @@ -165,6 +178,8 @@ _load_emojis(ROOT_DIR, BASE_URL) CODE_HIGHLIGHTING_THEME = CONFIG.code_highlighting_theme +MOVED_TO = _get_moved_to() + session_serializer = URLSafeTimedSerializer( CONFIG.secret, diff --git a/app/outgoing_activities.py b/app/outgoing_activities.py index c5327d3..1d992a9 100644 --- a/app/outgoing_activities.py +++ b/app/outgoing_activities.py @@ -67,6 +67,7 @@ async def _send_actor_update_if_needed( logger.info("Will send an Update for the local actor") from app.boxes import allocate_outbox_id + from app.boxes import compute_all_known_recipients from app.boxes import outbox_object_id from app.boxes import save_outbox_object @@ -85,24 +86,8 @@ async def _send_actor_update_if_needed( # Send the update to the followers collection and all the actor we have ever # contacted - followers = ( - ( - await db_session.scalars( - select(models.Follower).options(joinedload(models.Follower.actor)) - ) - ) - .unique() - .all() - ) - for rcp in { - follower.actor.shared_inbox_url or follower.actor.inbox_url - for follower in followers - } | { - row.recipient - for row in await db_session.execute( - select(func.distinct(models.OutgoingActivity.recipient).label("recipient")) - ) - }: # type: ignore + recipients = await compute_all_known_recipients(db_session) + for rcp in recipients: await new_outgoing_activity( db_session, recipient=rcp,