sedi-relay/relay/processors.py

124 lines
2.7 KiB
Python
Raw Normal View History

2022-05-06 07:04:51 +00:00
import asyncio
import logging
from uuid import uuid4
from . import app, misc
2022-11-07 10:30:13 +00:00
async def handle_relay(request, actor, data, software):
2022-05-06 07:04:51 +00:00
cache = app['cache'].objects
2022-11-07 10:30:13 +00:00
config = app['config']
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
if data.objectid in cache:
logging.verbose(f'already relayed {data.objectid} as {cache[data.objectid]}')
2022-05-06 07:04:51 +00:00
return
2022-11-07 10:30:13 +00:00
logging.verbose(f'Relaying post from {data.actorid}')
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
message = misc.Message.new_announce(
host = config.host,
object = data.objectid
)
2022-05-06 07:04:51 +00:00
logging.debug(f'>> relay: {message}')
2022-11-07 10:30:13 +00:00
inboxes = misc.distill_inboxes(actor, data.objectid)
2022-05-06 07:04:51 +00:00
futures = [misc.request(inbox, data=message) for inbox in inboxes]
asyncio.ensure_future(asyncio.gather(*futures))
2022-11-07 10:30:13 +00:00
cache[data.objectid] = message.id
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
async def handle_forward(request, actor, data, software):
2022-05-06 07:04:51 +00:00
cache = app['cache'].objects
2022-11-07 10:30:13 +00:00
config = app['config']
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
if data.id in cache:
logging.verbose(f'already forwarded {data.id}')
2022-05-06 07:04:51 +00:00
return
2022-11-07 10:30:13 +00:00
message = misc.Message.new_announce(
host = config.host,
object = data
)
2022-11-06 06:11:36 +00:00
2022-11-07 10:30:13 +00:00
logging.verbose(f'Forwarding post from {actor.id}')
2022-05-06 07:04:51 +00:00
logging.debug(f'>> Relay {data}')
2022-11-07 10:30:13 +00:00
inboxes = misc.distill_inboxes(actor, data.id)
2022-11-06 06:11:36 +00:00
futures = [misc.request(inbox, data=message) for inbox in inboxes]
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
asyncio.ensure_future(asyncio.gather(*futures))
cache[data.id] = message.id
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
async def handle_follow(request, actor, data, software):
2022-05-06 07:04:51 +00:00
config = app['config']
database = app['database']
2022-11-07 10:30:13 +00:00
if database.add_inbox(inbox, data.id):
database.set_followid(actor.id, data.id)
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
database.save()
2022-05-06 07:04:51 +00:00
2022-11-07 10:30:13 +00:00
await misc.request(
actor.shared_inbox,
misc.Message.new_response(
host = config.host,
actor = actor.id,
followid = data.id,
accept = True
)
)
# Are Akkoma and Pleroma the only two that expect a follow back?
# Ignoring only Mastodon for now
if software != 'mastodon':
misc.request(
actor.shared_inbox,
misc.Message.new_follow(
host = config.host,
actor = actor.id
)
)
async def handle_undo(request, actor, data, software):
2022-11-06 00:15:40 +00:00
## If the object is not a Follow, forward it
if data['object']['type'] != 'Follow':
2022-11-07 10:30:13 +00:00
return await handle_forward(request, actor, data, software)
2022-05-06 07:04:51 +00:00
database = app['database']
2022-11-07 10:30:13 +00:00
if not database.del_inbox(actor.domain, data.id):
2022-05-06 07:04:51 +00:00
return
database.save()
2022-11-07 10:30:13 +00:00
message = misc.Message.new_unfollow(
host = config.host,
actor = actor.id,
follow = data
)
await misc.request(actor.shared_inbox, message)
2022-05-06 07:04:51 +00:00
processors = {
'Announce': handle_relay,
'Create': handle_relay,
'Delete': handle_forward,
'Follow': handle_follow,
'Undo': handle_undo,
'Update': handle_forward,
}
2022-11-07 10:30:13 +00:00
async def run_processor(request, actor, data, software):
if data.type not in processors:
return
2022-11-07 10:30:13 +00:00
logging.verbose(f'New "{data.type}" from actor: {actor.id}')
return await processors[data.type](request, actor, data, software)