diff --git a/README.md b/README.md index 522196f..c316248 100644 --- a/README.md +++ b/README.md @@ -35,20 +35,24 @@ Bot management commands. * !bot status - print bot status information * !bot ping - print the ping time between the server and the bot * !bot version - print version and uptime of the bot -* !bot quit - quit the bot process (Must be done as bot owner) -* !bot reload - reload all bot modules (Must be done as bot owner) -* !bot export - export all bot settings as json (Must be done as bot owner) -* !bot export [module] - export a module's settings as json (Must be done as bot owner) -* !bot import [json object] - Update all bot settings from json (Must be done as bot owner) -* !bot import [module] [json object] - Update a module's settings from json (Must be done as bot owner) -* !bot import [module] [key ...] [json object] - Update a sub-object in a module from json (Must be done as bot owner) - * Example: !bot import alias aliases {"osm": "loc", "sh": "cmd"} -* !bot logs [module] ([count]) - Print the [count] most recent messages the given module has reported (Must be done as bot owner) * !bot stats - show statistics on matrix users seen by bot -* !bot leave - ask bot to leave this room (Must be done as admin in room) + +The following must be done as the bot owner: +* !bot enable [module] - enable module +* !bot disable [module] - disable module +* !bot quit - quit the bot process +* !bot reload - reload all bot modules +* !bot export - export all bot settings as json +* !bot export [module] - export a module's settings as json +* !bot import [json object] - Update all bot settings from json +* !bot import [module] [json object] - Update a module's settings from json +* !bot import [module] [key ...] [json object] - Update a sub-object in a module from json + * Example: !bot import alias aliases {"osm": "loc", "sh": "cmd"} +* !bot logs [module] ([count]) - Print the [count] most recent messages the given module has reported +* !bot uricache (view|clean|clear) - View the uri cache, or clear it. +The uri cache prevents the bot from uploading a blob from a url repeatedly +* !bot leave - ask bot to leave this room * !bot modules - list all modules including enabled status -* !bot enable [module] - enable module (Must be done as admin in room) -* !bot disable [module] - disable module (Must be done as admin in room) ### Help diff --git a/bot.py b/bot.py index bde25ec..cf13484 100755 --- a/bot.py +++ b/bot.py @@ -44,6 +44,7 @@ class Bot: self.modules = dict() self.module_aliases = dict() self.leave_empty_rooms = True + self.uri_cache = dict() self.pollcount = 0 self.poll_task = None self.owners = [] @@ -83,15 +84,20 @@ class Bot: :param blob_content_type: Content type of the image in case of binary content :return: """ - matrix_uri, mimetype, w, h, size = await self.upload_image(url, blob, blob_content_type) + try: + matrix_uri, mimetype, w, h, size = self.uri_cache[url] + except KeyError: + res = await self.upload_image(url, blob, blob_content_type) + matrix_uri, mimetype, w, h, size = res + if matrix_uri: + self.uri_cache[url] = list(res) + self.save_settings() + else: + return await self.send_text(room, "sorry. something went wrong uploading the image to matrix server :(") if not text and not blob: text = f"{url}" - - if matrix_uri is not None: - await self.send_image(room, matrix_uri, text, mimetype, w, h, size) - else: - await self.send_text(room, "sorry. something went wrong uploading the image to matrix server :(") + return await self.send_image(room, matrix_uri, text, mimetype, w, h, size) # Helper function to upload a image from URL to homeserver. Use send_image() to actually send it to room. async def upload_image(self, url, blob=False, blob_content_type="image/png"): @@ -225,7 +231,7 @@ class Bot: if size: msg["info"]["size"] = size - await self.client.room_send(room.room_id, 'm.room.message', msg) + return await self.client.room_send(room.room_id, 'm.room.message', msg) async def send_msg(self, mxid, roomname, message): """ @@ -318,7 +324,7 @@ class Bot: module_settings[modulename] = moduleobject.get_settings() except Exception: self.logger.exception(f'unhandled exception {modulename}.get_settings') - data = {self.appid: self.version, 'module_settings': module_settings} + data = {self.appid: self.version, 'module_settings': module_settings, 'uri_cache': self.uri_cache} self.set_account_data(data) def load_settings(self, data): @@ -326,6 +332,8 @@ class Bot: return if not data.get('module_settings'): return + if data.get('uri_cache'): + self.uri_cache = data['uri_cache'] for modulename, moduleobject in self.modules.items(): if data['module_settings'].get(modulename): try: diff --git a/modules/apod.py b/modules/apod.py index 040b475..0f68959 100644 --- a/modules/apod.py +++ b/modules/apod.py @@ -76,7 +76,9 @@ class MatrixModule(BotModule): self.logger.debug(apod) if apod.media_type == "image": - await self.upload_and_send_image(room, bot, apod) + await bot.send_text(room, f"{apod.title} ({apod.date})") + await bot.upload_and_send_image(room, apod.hdurl, f"{apod.title}") + await bot.send_text(room, f"{apod.explanation}") else: await self.send_unknown_mediatype(room, bot, apod) elif response.status_code == 400: @@ -91,25 +93,6 @@ class MatrixModule(BotModule): await bot.send_text(room, f"{apod.title}") await bot.send_text(room, f"{apod.explanation} || date: {apod.date} || original-url: {apod.url}") - async def upload_and_send_image(self, room, bot, apod): - send_again = True - await bot.send_text(room, f"{apod.title} ({apod.date})") - if apod.date in self.matrix_uri_cache: - matrix_uri = self.matrix_uri_cache.get(apod.date) - self.logger.debug(f"already uploaded picture {matrix_uri} for date {apod.date}") - else: - matrix_uri = await bot.upload_and_send_image(room, apod.hdurl, f"{apod.title}") - send_again = False - - if matrix_uri is not None: - self.matrix_uri_cache[apod.date] = matrix_uri - bot.save_settings() - if send_again: - await bot.send_image(room, matrix_uri, f"{apod.title}") - else: - await bot.send_text(room, "Sorry. Something went wrong uploading the image to Matrix server :(") - await bot.send_text(room, f"{apod.explanation}") - def get_settings(self): data = super().get_settings() data["matrix_uri_cache"] = self.matrix_uri_cache diff --git a/modules/bot.py b/modules/bot.py index ee340a6..45b074b 100644 --- a/modules/bot.py +++ b/modules/bot.py @@ -69,6 +69,8 @@ class MatrixModule(BotModule): await self.import_settings(bot, event) elif args[1] == 'logs': await self.last_logs(bot, room, event, args[2]) + elif args[1] == 'uricache': + await self.manage_uri_cache(bot, room, event, args[2]) else: pass @@ -269,6 +271,19 @@ class MatrixModule(BotModule): return await bot.send_html(msg_room, f'Logs for {key}:\n
{escape(logs)}
', f'Logs for {key}:\n' + logs) + async def manage_uri_cache(self, bot, room, event, action): + bot.must_be_owner(event) + if action == 'view': + self.logger.info(f"{event.sender} wants to see the uri cache") + msg = [f'uri cache size: {len(bot.uri_cache)}'] + for key, val in bot.uri_cache.items(): + msg.append('- ' + key + ': ' + val[0]) + return await bot.send_text(room, '\n'.join(msg)) + if action in ['clean', 'clear']: + self.logger.info(f"{event.sender} wants to clear the uri cache") + bot.uri_cache = dict() + bot.save_settings() + def disable(self): raise ModuleCannotBeDisabled diff --git a/modules/tautulli.py b/modules/tautulli.py index 8e89920..8a1d161 100644 --- a/modules/tautulli.py +++ b/modules/tautulli.py @@ -46,10 +46,7 @@ async def send_entry(bot, room, entry): pms_image = pms.get_image(entry["art"], 600, 300) if pms_image: (blob, content_type) = pms_image - matrix_uri = await bot.upload_and_send_image(room, blob, "", True, content_type) - - if matrix_uri is not None: - await bot.send_image(room, matrix_uri, "") + await bot.upload_and_send_image(room, blob, "", True, content_type) fmt_params = { "title": entry["title"],