Better exception handling and stuff
This commit is contained in:
parent
c742a0bd55
commit
6aa1d541df
1 changed files with 80 additions and 61 deletions
141
main.py
141
main.py
|
@ -42,30 +42,40 @@ message_store = {}
|
||||||
|
|
||||||
|
|
||||||
class MatrixClient(nio.AsyncClient):
|
class MatrixClient(nio.AsyncClient):
|
||||||
def __init__(self, discord_client, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.logger = logging.getLogger("matrix_logger")
|
self.logger = logging.getLogger("matrix_logger")
|
||||||
|
|
||||||
self.discord_client = discord_client
|
self.listen = False
|
||||||
|
|
||||||
self.ready = asyncio.Event()
|
|
||||||
|
|
||||||
self.uploaded_emotes = {}
|
self.uploaded_emotes = {}
|
||||||
|
self.ready = asyncio.Event()
|
||||||
|
self.loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
async def start(self):
|
self.start_discord()
|
||||||
password = config["password"]
|
self.add_callbacks()
|
||||||
timeout = 30000
|
|
||||||
|
|
||||||
self.logger.info(await self.login(password))
|
def start_discord(self):
|
||||||
|
# Disable everyone and role mentions.
|
||||||
|
allowed_mentions = discord.AllowedMentions(everyone=False, roles=False)
|
||||||
|
# Set command prefix for Discord bot.
|
||||||
|
command_prefix = config["discord_prefix"]
|
||||||
|
# Intents to fetch members from guild.
|
||||||
|
intents = discord.Intents.default()
|
||||||
|
intents.members = True
|
||||||
|
|
||||||
self.logger.info("Doing initial sync.")
|
self.discord_client = DiscordClient(
|
||||||
await self.sync(timeout)
|
self, allowed_mentions=allowed_mentions,
|
||||||
|
command_prefix=command_prefix, intents=intents
|
||||||
|
)
|
||||||
|
|
||||||
# Set up event callbacks after syncing once to ignore old messages.
|
self.bg_task = self.loop.create_task(
|
||||||
|
self.discord_client.start(config["token"])
|
||||||
|
)
|
||||||
|
|
||||||
|
def add_callbacks(self):
|
||||||
callbacks = Callbacks(self.discord_client, self)
|
callbacks = Callbacks(self.discord_client, self)
|
||||||
|
|
||||||
self.logger.info("Adding callbacks.")
|
|
||||||
self.add_event_callback(
|
self.add_event_callback(
|
||||||
callbacks.message_callback,
|
callbacks.message_callback,
|
||||||
(nio.RoomMessageText, nio.RoomMessageMedia,
|
(nio.RoomMessageText, nio.RoomMessageMedia,
|
||||||
|
@ -80,18 +90,6 @@ class MatrixClient(nio.AsyncClient):
|
||||||
callbacks.typing_callback, nio.EphemeralEvent
|
callbacks.typing_callback, nio.EphemeralEvent
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.discord_client.ready.wait()
|
|
||||||
self.ready.set()
|
|
||||||
|
|
||||||
self.logger.info("Clients ready.")
|
|
||||||
|
|
||||||
self.logger.info("Syncing forever.")
|
|
||||||
await self.sync_forever(timeout=timeout)
|
|
||||||
|
|
||||||
# Logout
|
|
||||||
await self.logout()
|
|
||||||
await self.close()
|
|
||||||
|
|
||||||
async def upload_emote(self, emote_id):
|
async def upload_emote(self, emote_id):
|
||||||
if emote_id in self.uploaded_emotes.keys():
|
if emote_id in self.uploaded_emotes.keys():
|
||||||
return self.uploaded_emotes[emote_id]
|
return self.uploaded_emotes[emote_id]
|
||||||
|
@ -235,7 +233,7 @@ height=\"32\" src=\"{emote_}\" data-mx-emoticon />"""
|
||||||
|
|
||||||
|
|
||||||
class DiscordClient(discord.ext.commands.Bot):
|
class DiscordClient(discord.ext.commands.Bot):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, matrix_client, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.channel_store = {}
|
self.channel_store = {}
|
||||||
|
@ -244,13 +242,7 @@ class DiscordClient(discord.ext.commands.Bot):
|
||||||
|
|
||||||
self.add_cogs()
|
self.add_cogs()
|
||||||
|
|
||||||
self.matrix_client = MatrixClient(
|
self.matrix_client = matrix_client
|
||||||
self, config["homeserver"], config["username"]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.bg_task = self.loop.create_task(
|
|
||||||
self.log_exceptions(self.matrix_client)
|
|
||||||
)
|
|
||||||
|
|
||||||
def add_cogs(self):
|
def add_cogs(self):
|
||||||
cogs_dir = "./cogs"
|
cogs_dir = "./cogs"
|
||||||
|
@ -270,16 +262,6 @@ class DiscordClient(discord.ext.commands.Bot):
|
||||||
or str(channel_id) not in config["bridge"].keys():
|
or str(channel_id) not in config["bridge"].keys():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def log_exceptions(self, matrix_client):
|
|
||||||
try:
|
|
||||||
return await matrix_client.start()
|
|
||||||
except Exception:
|
|
||||||
matrix_client.logger.warning(
|
|
||||||
f"Unknown exception occurred\n{traceback.format_exc()}"
|
|
||||||
)
|
|
||||||
|
|
||||||
await matrix_client.close()
|
|
||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
for channel in config["bridge"].keys():
|
for channel in config["bridge"].keys():
|
||||||
self.channel_store[channel] = self.get_channel(int(channel))
|
self.channel_store[channel] = self.get_channel(int(channel))
|
||||||
|
@ -383,16 +365,19 @@ class Callbacks(object):
|
||||||
|
|
||||||
return channel_id
|
return channel_id
|
||||||
|
|
||||||
def to_return(self, room, event):
|
async def to_return(self, room, event):
|
||||||
|
await self.matrix_client.discord_client.ready.wait()
|
||||||
|
|
||||||
if room.room_id not in config["bridge"].values() or \
|
if room.room_id not in config["bridge"].values() or \
|
||||||
event.sender == self.matrix_client.user:
|
event.sender == self.matrix_client.user or \
|
||||||
|
not self.matrix_client.listen:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def message_callback(self, room, event):
|
async def message_callback(self, room, event):
|
||||||
message = event.body
|
message = event.body
|
||||||
|
|
||||||
# Ignore messages having an empty body.
|
# Ignore messages having an empty body.
|
||||||
if self.to_return(room, event) or not message:
|
if await self.to_return(room, event) or not message:
|
||||||
return
|
return
|
||||||
|
|
||||||
content_dict = event.source.get("content")
|
content_dict = event.source.get("content")
|
||||||
|
@ -476,7 +461,7 @@ class Callbacks(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def redaction_callback(self, room, event):
|
async def redaction_callback(self, room, event):
|
||||||
if self.to_return(room, event):
|
if await self.to_return(room, event):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Try to fetch the message from cache.
|
# Try to fetch the message from cache.
|
||||||
|
@ -538,23 +523,57 @@ class Callbacks(object):
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
def main():
|
async def main():
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
# Disable everyone and role mentions.
|
retry = 2
|
||||||
allowed_mentions = discord.AllowedMentions(everyone=False, roles=False)
|
|
||||||
# Set command prefix for Discord bot.
|
|
||||||
command_prefix = config["discord_prefix"]
|
|
||||||
# Intents to fetch members from guild.
|
|
||||||
intents = discord.Intents.default()
|
|
||||||
intents.members = True
|
|
||||||
|
|
||||||
# Start Discord bot.
|
matrix_client = MatrixClient(
|
||||||
DiscordClient(
|
config["homeserver"], config["username"]
|
||||||
allowed_mentions=allowed_mentions,
|
)
|
||||||
command_prefix=command_prefix, intents=intents
|
|
||||||
).run(config["token"])
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
resp = await matrix_client.login(config["password"])
|
||||||
|
|
||||||
|
if type(resp) == nio.LoginError:
|
||||||
|
matrix_client.logger.error(f"Failed to login: {resp}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Login successful.
|
||||||
|
matrix_client.logger.info(resp)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await matrix_client.sync(full_state=True)
|
||||||
|
except Exception:
|
||||||
|
matrix_client.logger.error(
|
||||||
|
f"Initial sync failed!\n{traceback.format_exc()}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
matrix_client.ready.set()
|
||||||
|
matrix_client.listen = True
|
||||||
|
|
||||||
|
matrix_client.logger.info("Clients ready!")
|
||||||
|
|
||||||
|
await matrix_client.sync_forever(timeout=30000, full_state=True)
|
||||||
|
except Exception:
|
||||||
|
matrix_client.logger.error(
|
||||||
|
f"Unknown exception occured\n{traceback.format_exc()}\n"
|
||||||
|
f"Retrying in {retry} seconds..."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clear "ready" status.
|
||||||
|
matrix_client.ready.clear()
|
||||||
|
|
||||||
|
await matrix_client.close()
|
||||||
|
await asyncio.sleep(retry)
|
||||||
|
|
||||||
|
matrix_client.listen = False
|
||||||
|
finally:
|
||||||
|
if matrix_client.listen:
|
||||||
|
await matrix_client.close()
|
||||||
|
return False
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
asyncio.run(main())
|
||||||
|
|
Loading…
Reference in a new issue