Better exception handling and stuff

This commit is contained in:
git-bruh 2021-02-01 11:33:27 +05:30
parent c742a0bd55
commit 6aa1d541df
No known key found for this signature in database
GPG key ID: E1475C50075ADCE6

141
main.py
View file

@ -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())