feat/process follower

This commit is contained in:
SouthFox 2023-03-20 23:33:10 +08:00
parent 02a01d29c7
commit 9d0bca641b

View file

@ -19,6 +19,8 @@ import app.activitypub as ap
from urllib.parse import urlparse from urllib.parse import urlparse
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy import delete
from sqlalchemy.orm import joinedload
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from loguru import logger from loguru import logger
from uuid import uuid4 from uuid import uuid4
@ -51,10 +53,11 @@ async def save_incoming(
ap_id=ap_id, ap_id=ap_id,
ap_object=payload, ap_object=payload,
) )
await process_incoming(db_session, payload)
if db_session.add(incoming_activity): if process_incoming(db_session, payload):
return incoming_activity return incoming_activity
db_session.add(incoming_activity)
await db_session.commit() await db_session.commit()
await db_session.refresh(incoming_activity) await db_session.refresh(incoming_activity)
return incoming_activity return incoming_activity
@ -66,7 +69,7 @@ async def process_incoming(
) -> bool: ) -> bool:
actor = await fetch_actor(ap_object["actor"], db_session) actor = await fetch_actor(ap_object["actor"], db_session)
def save_to_db(object) -> InboxObject: def build_object(object) -> InboxObject:
inbox_object = models.InboxObject( inbox_object = models.InboxObject(
actor_id=actor.id, actor_id=actor.id,
server=urlparse(object["id"]).hostname, server=urlparse(object["id"]).hostname,
@ -83,7 +86,7 @@ async def process_incoming(
return inbox_object return inbox_object
if "Follow" == ap_object["type"]: if "Follow" == ap_object["type"]:
inbox_object = save_to_db(ap_object) inbox_object = build_object(ap_object)
db_session.add(inbox_object) db_session.add(inbox_object)
await db_session.flush() await db_session.flush()
await db_session.refresh(inbox_object) await db_session.refresh(inbox_object)
@ -91,6 +94,11 @@ async def process_incoming(
if await _handle_follow(db_session, actor, inbox_object): if await _handle_follow(db_session, actor, inbox_object):
return True return True
return False return False
elif "Undo" == ap_object["type"]:
#inbox_object = build_object(ap_object)
#db_session.add(inbox_object)
if await _handle_undo(db_session, ap_object):
return True
return False return False
@ -144,3 +152,39 @@ async def _send_accept(
} }
#TODO outcoming #TODO outcoming
await ap.post(url, out) # type: ignore await ap.post(url, out) # type: ignore
async def _handle_undo(
db_session : AsyncSession,
inbox_object : dict
) -> bool:
if inbox_object["object"]["object"] != ME["id"]:
logger.warning("Wrong undo object! "
+ inbox_object["object"]["actor"])
return False
if "Follow" == inbox_object["object"]["type"]:
relate_object = (await db_session.execute(
select(models.InboxObject)
.where(models.InboxObject.ap_id == inbox_object["object"]["id"])
.options(
joinedload(models.InboxObject.actor),
joinedload(models.InboxObject.relates_to_inbox_object),
joinedload(models.InboxObject.relates_to_outbox_object),
)
)
).scalar_one_or_none() # type: ignore
if relate_object:
relate_object.undo_id=inbox_object["object"]["id"]
relate_object.is_deleted=True
await db_session.execute(
delete(models.Follower).where(
models.Follower.ap_actor_id == inbox_object["actor"]
)
)
logger.info("undo follow " + inbox_object["actor"])
return True
return False