2023-03-18 14:51:36 +01:00
|
|
|
#!/usr/bin/env python3
|
2023-07-29 04:56:39 +02:00
|
|
|
"""Actor stuff."""
|
2023-03-21 07:24:57 +01:00
|
|
|
import typing
|
2024-02-26 16:55:18 +01:00
|
|
|
import hy
|
|
|
|
|
2023-07-29 04:56:39 +02:00
|
|
|
from urllib.parse import urlparse
|
|
|
|
from sqlalchemy import select
|
2023-03-18 14:51:36 +01:00
|
|
|
from loguru import logger
|
2023-07-29 04:56:39 +02:00
|
|
|
|
2024-02-26 16:55:18 +01:00
|
|
|
from app.hyap import fetch # type: ignore
|
2023-03-21 07:24:57 +01:00
|
|
|
from app import models
|
2023-07-29 04:56:39 +02:00
|
|
|
from app.database import AsyncSession
|
|
|
|
|
|
|
|
|
2023-03-21 07:24:57 +01:00
|
|
|
if typing.TYPE_CHECKING:
|
|
|
|
from app.models import Actor as ActorModel
|
|
|
|
|
|
|
|
|
2023-03-18 14:51:36 +01:00
|
|
|
async def fetch_actor(
|
2023-07-29 14:49:01 +02:00
|
|
|
db_session: AsyncSession,
|
|
|
|
actor_id: str,
|
2023-03-21 07:24:57 +01:00
|
|
|
) -> "ActorModel":
|
2023-07-29 04:56:39 +02:00
|
|
|
"""Fetch actor on db, if not exist will be grabed and stored
|
|
|
|
in db."""
|
2023-03-18 14:51:36 +01:00
|
|
|
exist_actor = (
|
|
|
|
await db_session.scalars(
|
2023-03-21 07:24:57 +01:00
|
|
|
select(models.Actor).where(
|
|
|
|
models.Actor.ap_id == actor_id
|
2023-03-18 14:51:36 +01:00
|
|
|
)
|
|
|
|
)
|
|
|
|
).one_or_none()
|
|
|
|
|
2023-07-29 04:56:39 +02:00
|
|
|
if exist_actor:
|
2023-04-01 11:17:01 +02:00
|
|
|
return exist_actor
|
2023-03-18 14:51:36 +01:00
|
|
|
|
2024-02-26 16:55:18 +01:00
|
|
|
ap_object = await fetch(actor_id)
|
2023-07-29 04:56:39 +02:00
|
|
|
exist_actor = await save_actor(ap_object, db_session)
|
|
|
|
return exist_actor
|
|
|
|
|
|
|
|
|
2023-03-18 14:51:36 +01:00
|
|
|
async def save_actor(
|
2023-07-29 14:49:01 +02:00
|
|
|
ap_object: dict,
|
|
|
|
db_session: AsyncSession
|
2023-03-21 07:24:57 +01:00
|
|
|
) -> "ActorModel":
|
2023-07-29 04:56:39 +02:00
|
|
|
"""Save actor to db."""
|
2023-03-18 14:51:36 +01:00
|
|
|
logger.info("save actor " + ap_object["id"])
|
2023-03-21 07:24:57 +01:00
|
|
|
actor = models.Actor(
|
2023-03-18 14:51:36 +01:00
|
|
|
ap_id=ap_object["id"],
|
|
|
|
ap_actor=ap_object,
|
|
|
|
ap_type=ap_object["type"],
|
|
|
|
handle=_handle(ap_object),
|
|
|
|
)
|
|
|
|
|
|
|
|
db_session.add(actor)
|
|
|
|
await db_session.flush()
|
|
|
|
await db_session.refresh(actor)
|
|
|
|
return actor
|
|
|
|
|
2023-07-29 04:56:39 +02:00
|
|
|
|
2023-07-29 14:49:01 +02:00
|
|
|
def _handle(
|
|
|
|
ap_object: dict,
|
2023-03-18 14:51:36 +01:00
|
|
|
) -> str:
|
|
|
|
ap_id = urlparse(ap_object["id"])
|
|
|
|
if not ap_id.hostname:
|
|
|
|
raise ValueError(f"Invalid actor ID {ap_id}")
|
|
|
|
|
|
|
|
handle = '@' + ap_object["preferredUsername"] + '@' + ap_id.hostname
|
|
|
|
|
|
|
|
return handle
|
2023-04-01 18:13:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
async def get_public_key(
|
|
|
|
db_session: AsyncSession,
|
|
|
|
key_id: str
|
|
|
|
) -> str:
|
2023-07-29 04:56:39 +02:00
|
|
|
"""Give key id and reutrn public key."""
|
2023-04-01 18:13:16 +02:00
|
|
|
existing_actor = (
|
|
|
|
await db_session.scalars(
|
2023-07-29 14:49:01 +02:00
|
|
|
select(models.Actor).where(
|
|
|
|
models.Actor.ap_id == key_id.split("#")[0])
|
2023-04-01 18:13:16 +02:00
|
|
|
)
|
|
|
|
).one_or_none()
|
2024-03-03 17:34:58 +01:00
|
|
|
public_key = existing_actor.ap_actor["publicKey"]["publicKeyPem"]
|
2023-04-01 18:13:16 +02:00
|
|
|
return public_key
|