Add fediverse social features: followers/following lists, actor timelines
Adds get_followers_paginated and get_actor_timeline to FederationService protocol + SQL implementation + stubs. Includes accumulated federation changes: models, DTOs, delivery handler, webfinger, inline publishing, widget nav templates, and migration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,10 @@ from .dtos import (
|
||||
ActorProfileDTO,
|
||||
APActivityDTO,
|
||||
APFollowerDTO,
|
||||
RemoteActorDTO,
|
||||
RemotePostDTO,
|
||||
TimelineItemDTO,
|
||||
NotificationDTO,
|
||||
)
|
||||
|
||||
|
||||
@@ -217,6 +221,11 @@ class FederationService(Protocol):
|
||||
self, session: AsyncSession, username: str,
|
||||
) -> list[APFollowerDTO]: ...
|
||||
|
||||
async def get_followers_paginated(
|
||||
self, session: AsyncSession, username: str,
|
||||
page: int = 1, per_page: int = 20,
|
||||
) -> tuple[list[RemoteActorDTO], int]: ...
|
||||
|
||||
async def add_follower(
|
||||
self, session: AsyncSession, username: str,
|
||||
follower_acct: str, follower_inbox: str, follower_actor_url: str,
|
||||
@@ -227,5 +236,108 @@ class FederationService(Protocol):
|
||||
self, session: AsyncSession, username: str, follower_acct: str,
|
||||
) -> bool: ...
|
||||
|
||||
# -- Remote actors --------------------------------------------------------
|
||||
async def get_or_fetch_remote_actor(
|
||||
self, session: AsyncSession, actor_url: str,
|
||||
) -> RemoteActorDTO | None: ...
|
||||
|
||||
async def search_remote_actor(
|
||||
self, session: AsyncSession, acct: str,
|
||||
) -> RemoteActorDTO | None: ...
|
||||
|
||||
# -- Following (outbound) -------------------------------------------------
|
||||
async def send_follow(
|
||||
self, session: AsyncSession, local_username: str, remote_actor_url: str,
|
||||
) -> None: ...
|
||||
|
||||
async def get_following(
|
||||
self, session: AsyncSession, username: str,
|
||||
page: int = 1, per_page: int = 20,
|
||||
) -> tuple[list[RemoteActorDTO], int]: ...
|
||||
|
||||
async def accept_follow_response(
|
||||
self, session: AsyncSession, local_username: str, remote_actor_url: str,
|
||||
) -> None: ...
|
||||
|
||||
async def unfollow(
|
||||
self, session: AsyncSession, local_username: str, remote_actor_url: str,
|
||||
) -> None: ...
|
||||
|
||||
# -- Remote posts ---------------------------------------------------------
|
||||
async def ingest_remote_post(
|
||||
self, session: AsyncSession, remote_actor_id: int,
|
||||
activity_json: dict, object_json: dict,
|
||||
) -> None: ...
|
||||
|
||||
async def delete_remote_post(
|
||||
self, session: AsyncSession, object_id: str,
|
||||
) -> None: ...
|
||||
|
||||
async def get_remote_post(
|
||||
self, session: AsyncSession, object_id: str,
|
||||
) -> RemotePostDTO | None: ...
|
||||
|
||||
# -- Timelines ------------------------------------------------------------
|
||||
async def get_home_timeline(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
before: datetime | None = None, limit: int = 20,
|
||||
) -> list[TimelineItemDTO]: ...
|
||||
|
||||
async def get_public_timeline(
|
||||
self, session: AsyncSession,
|
||||
before: datetime | None = None, limit: int = 20,
|
||||
) -> list[TimelineItemDTO]: ...
|
||||
|
||||
async def get_actor_timeline(
|
||||
self, session: AsyncSession, remote_actor_id: int,
|
||||
before: datetime | None = None, limit: int = 20,
|
||||
) -> list[TimelineItemDTO]: ...
|
||||
|
||||
# -- Local posts ----------------------------------------------------------
|
||||
async def create_local_post(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
content: str, visibility: str = "public",
|
||||
in_reply_to: str | None = None,
|
||||
) -> int: ...
|
||||
|
||||
async def delete_local_post(
|
||||
self, session: AsyncSession, actor_profile_id: int, post_id: int,
|
||||
) -> None: ...
|
||||
|
||||
# -- Interactions ---------------------------------------------------------
|
||||
async def like_post(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
object_id: str, author_inbox: str,
|
||||
) -> None: ...
|
||||
|
||||
async def unlike_post(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
object_id: str, author_inbox: str,
|
||||
) -> None: ...
|
||||
|
||||
async def boost_post(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
object_id: str, author_inbox: str,
|
||||
) -> None: ...
|
||||
|
||||
async def unboost_post(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
object_id: str, author_inbox: str,
|
||||
) -> None: ...
|
||||
|
||||
# -- Notifications --------------------------------------------------------
|
||||
async def get_notifications(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
before: datetime | None = None, limit: int = 20,
|
||||
) -> list[NotificationDTO]: ...
|
||||
|
||||
async def unread_notification_count(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
) -> int: ...
|
||||
|
||||
async def mark_notifications_read(
|
||||
self, session: AsyncSession, actor_profile_id: int,
|
||||
) -> None: ...
|
||||
|
||||
# -- Stats ----------------------------------------------------------------
|
||||
async def get_stats(self, session: AsyncSession) -> dict: ...
|
||||
|
||||
Reference in New Issue
Block a user