2022-05-06 07:04:51 +00:00
|
|
|
import asyncio
|
|
|
|
import logging
|
|
|
|
|
|
|
|
from uuid import uuid4
|
|
|
|
|
2022-11-07 12:54:32 +00:00
|
|
|
from . import misc
|
2022-05-06 07:04:51 +00:00
|
|
|
|
|
|
|
|
2022-11-18 18:45:26 +00:00
|
|
|
async def handle_relay(request, actor, data, nodeinfo):
|
2022-11-07 12:54:32 +00:00
|
|
|
if data.objectid in request.app.cache.objects:
|
|
|
|
logging.verbose(f'already relayed {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(
|
2022-11-07 12:54:32 +00:00
|
|
|
host = request.app.config.host,
|
2022-11-07 10:30:13 +00:00
|
|
|
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 12:54:32 +00:00
|
|
|
request.app.cache.objects[data.objectid] = message.id
|
2022-05-06 07:04:51 +00:00
|
|
|
|
|
|
|
|
2022-11-18 18:45:26 +00:00
|
|
|
async def handle_forward(request, actor, data, nodeinfo):
|
2022-11-07 12:54:32 +00:00
|
|
|
if data.id in request.app.cache.objects:
|
2022-11-07 10:30:13 +00:00
|
|
|
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(
|
2022-11-07 12:54:32 +00:00
|
|
|
host = request.app.config.host,
|
2022-11-07 10:30:13 +00:00
|
|
|
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))
|
2022-11-07 12:54:32 +00:00
|
|
|
request.app.cache.objects[data.id] = message.id
|
2022-05-06 07:04:51 +00:00
|
|
|
|
|
|
|
|
2022-11-18 18:45:26 +00:00
|
|
|
async def handle_follow(request, actor, data, nodeinfo):
|
2022-11-10 18:08:25 +00:00
|
|
|
if not request.app.database.add_inbox(actor.shared_inbox, data.id):
|
2022-11-07 12:54:32 +00:00
|
|
|
request.app.database.set_followid(actor.id, data.id)
|
2022-05-06 07:04:51 +00:00
|
|
|
|
2022-11-07 12:54:32 +00:00
|
|
|
request.app.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(
|
2022-11-07 12:54:32 +00:00
|
|
|
host = request.app.config.host,
|
2022-11-07 10:30:13 +00:00
|
|
|
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
|
2022-11-18 18:45:26 +00:00
|
|
|
if nodeinfo.swname != 'mastodon':
|
2022-11-16 19:22:50 +00:00
|
|
|
await misc.request(
|
2022-11-07 10:30:13 +00:00
|
|
|
actor.shared_inbox,
|
|
|
|
misc.Message.new_follow(
|
2022-11-07 12:54:32 +00:00
|
|
|
host = request.app.config.host,
|
2022-11-07 10:30:13 +00:00
|
|
|
actor = actor.id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-11-18 18:45:26 +00:00
|
|
|
async def handle_undo(request, actor, data, nodeinfo):
|
2022-11-06 00:15:40 +00:00
|
|
|
## If the object is not a Follow, forward it
|
|
|
|
if data['object']['type'] != 'Follow':
|
2022-11-18 18:45:26 +00:00
|
|
|
return await handle_forward(request, actor, data, nodeinfo)
|
2022-05-06 07:04:51 +00:00
|
|
|
|
2022-11-07 12:54:32 +00:00
|
|
|
if not request.app.database.del_inbox(actor.domain, data.id):
|
2022-05-06 07:04:51 +00:00
|
|
|
return
|
|
|
|
|
2022-11-07 12:54:32 +00:00
|
|
|
request.app.database.save()
|
2022-05-06 07:04:51 +00:00
|
|
|
|
2022-11-07 10:30:13 +00:00
|
|
|
message = misc.Message.new_unfollow(
|
2022-11-07 12:54:32 +00:00
|
|
|
host = request.app.config.host,
|
2022-11-07 10:30:13 +00:00
|
|
|
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-18 18:45:26 +00:00
|
|
|
async def run_processor(request, actor, data, nodeinfo):
|
2022-11-07 10:30:13 +00:00
|
|
|
if data.type not in processors:
|
2022-08-12 06:36:08 +00:00
|
|
|
return
|
|
|
|
|
2022-11-07 10:30:13 +00:00
|
|
|
logging.verbose(f'New "{data.type}" from actor: {actor.id}')
|
2022-11-18 18:45:26 +00:00
|
|
|
return await processors[data.type](request, actor, data, nodeinfo)
|