5923602f0a
I didn't want to do this unless we had to but Mastodon is introducing requirming signed requests soon, so even if a user doesn't use bitbot as an instance, we'll still need to be able to serve Actor (and key) over the REST API
99 lines
3.8 KiB
Python
99 lines
3.8 KiB
Python
#--depends-on rest_api
|
|
|
|
import urllib.parse
|
|
from src import IRCBot, ModuleManager, utils
|
|
from . import ap_actor, ap_security, ap_server, ap_utils
|
|
|
|
def _format_username(username, instance):
|
|
return "@%s@%s" % (username, instance)
|
|
def _setting_parse(s):
|
|
username, instance = ap_utils.split_username(s)
|
|
if username and instance:
|
|
return _format_username(username, instance)
|
|
return None
|
|
|
|
@utils.export("botset", utils.FunctionSetting(_setting_parse,
|
|
"fediverse-server", "The bot's local fediverse server username",
|
|
example="@bot@bitbot.dev"))
|
|
@utils.export("set", utils.FunctionSetting(_setting_parse, "fediverse",
|
|
help="Set your fediverse account", example="@gargron@mastodon.social"))
|
|
class Module(ModuleManager.BaseModule):
|
|
_name = "Fedi"
|
|
|
|
def on_load(self):
|
|
server_username = self.bot.get_setting("fediverse-server", None)
|
|
if server_username:
|
|
if not "tls-key" in self.bot.config:
|
|
raise ValueError("`tls-key` not provided in bot config")
|
|
if not "tls-certificate" in self.bot.config:
|
|
raise ValueError("`tls-certificate` not provided in bot config")
|
|
if not ap_security.has_crypto:
|
|
raise ValueError("cyprography library is not installed "
|
|
"(https://pypi.org/project/cryptography/)")
|
|
|
|
server_username, instance = ap_utils.split_username(server_username)
|
|
self.server = ap_server.Server(self.bot, self.exports,
|
|
server_username, instance)
|
|
|
|
self.events.on("api.get.ap-webfinger").hook(
|
|
self.server.ap_webfinger, authenticated=False)
|
|
self.events.on("api.get.ap-user").hook(
|
|
self.server.ap_user, authenticated=False)
|
|
self.events.on("api.post.ap-inbox").hook(
|
|
self.server.ap_inbox, authenticated=False)
|
|
self.events.on("api.get.ap-outbox").hook(
|
|
self.server.ap_outbox, authenticated=False)
|
|
def unload(self):
|
|
if not self.server == None:
|
|
self.server.unload()
|
|
|
|
@utils.hook("received.command.fediverse")
|
|
@utils.hook("received.command.fedi", alias_of="fediverse")
|
|
@utils.kwarg("help", "Get someone's latest toot")
|
|
@utils.kwarg("usage", "@<user>@<instance>")
|
|
def fedi(self, event):
|
|
account = None
|
|
if not event["args"]:
|
|
account = event["user"].get_setting("fediverse", None)
|
|
elif not "@" in event["args"]:
|
|
target = event["args_split"][0]
|
|
if event["server"].has_user_id(target):
|
|
target_user = event["server"].get_user(target)
|
|
account = target_user.get_setting("fediverse", None)
|
|
else:
|
|
account = event["args_split"][0]
|
|
|
|
username = None
|
|
instance = None
|
|
if account:
|
|
username, instance = ap_utils.split_username(account)
|
|
|
|
if not username or not instance:
|
|
raise utils.EventError("Please provide @<user>@<instance>")
|
|
|
|
actor_url = ap_utils.find_actor(username, instance)
|
|
|
|
if not actor_url:
|
|
raise utils.EventError("Failed to find user")
|
|
|
|
actor = ap_actor.Actor(actor_url)
|
|
if not actor.load():
|
|
raise utils.EventError("Failed to find user")
|
|
|
|
items = actor.outbox.load()
|
|
for item in items:
|
|
if item["object"]["inReplyTo"] == None:
|
|
first_item = item
|
|
|
|
if not first_item:
|
|
raise utils.EventError("No toots found")
|
|
|
|
cw, out, url = ap_utils.format_note(actor, first_item)
|
|
shorturl = self.exports.get_one("shorturl")(event["server"], url,
|
|
context=event["target"])
|
|
|
|
if not cw == None:
|
|
out = "CW: %s - %s" % (cw, shorturl)
|
|
else:
|
|
out = "%s - %s" % (out, shorturl)
|
|
event["stdout"].write(out)
|