diff --git a/README.md b/README.md index dcf696c..79ef86f 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,10 @@ Support room: #hemppa:hacklab.fi - https://matrix.to/#/#hemppa:hacklab.fi Bot management commands. -* !bot version - print version of 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 stats - show statistics on matrix users seen by bot ### Help @@ -44,10 +46,6 @@ Aviation weather TAF service access. * !taf eftp -### Uptime - -Prints bot uptime. - ### Teamup Can access Teamup ( https://teamup.com/ ) calendar. Teamup has nice API and is easier to set up than Google so diff --git a/bot.py b/bot.py index afb4912..a370cef 100755 --- a/bot.py +++ b/bot.py @@ -12,6 +12,7 @@ import urllib.parse import requests from nio import AsyncClient, InviteEvent, JoinError, RoomMessageText +from importlib import reload # Couple of custom exceptions @@ -141,6 +142,7 @@ class Bot: def load_module(self, modulename): try: module = importlib.import_module('modules.' + modulename) + module = reload(module) cls = getattr(module, 'MatrixModule') return cls() except ModuleNotFoundError: @@ -148,6 +150,10 @@ class Bot: traceback.print_exc(file=sys.stderr) return None + def reload_module(self, modulename): + print('Reloading', modulename) + self.modules[modulename] = self.load_module(modulename) + def get_modules(self): modulefiles = glob.glob('./modules/*.py') @@ -156,6 +162,9 @@ class Bot: moduleobject = self.load_module(modulename) if moduleobject: self.modules[modulename] = moduleobject + + def clear_modules(self): + self.modules = dict() async def poll_timer(self): while True: @@ -197,6 +206,16 @@ class Bot: self.owners = os.environ['BOT_OWNERS'].split(',') self.get_modules() + def start(self): + print(f'Starting {len(self.modules)} modules..') + for modulename, moduleobject in self.modules.items(): + print('Starting', modulename, '..') + if "matrix_start" in dir(moduleobject): + try: + moduleobject.matrix_start(bot) + except Exception: + traceback.print_exc(file=sys.stderr) + def stop(self): print(f'Stopping {len(self.modules)} modules..') for modulename, moduleobject in self.modules.items(): @@ -215,14 +234,7 @@ class Bot: await self.client.sync() - print(f'Starting {len(self.modules)} modules..') - for modulename, moduleobject in self.modules.items(): - print('Starting', modulename, '..') - if "matrix_start" in dir(moduleobject): - try: - moduleobject.matrix_start(bot) - except Exception: - traceback.print_exc(file=sys.stderr) + self.start() self.poll_task = asyncio.get_event_loop().create_task(self.poll_timer()) diff --git a/modules/bot.py b/modules/bot.py index 15caf25..078f022 100644 --- a/modules/bot.py +++ b/modules/bot.py @@ -1,7 +1,10 @@ import urllib.request - +from datetime import datetime, timedelta class MatrixModule: + def matrix_start(self, bot): + self.starttime = datetime.now() + async def matrix_message(self, bot, room, event): args = event.body.split() if len(args) == 2: @@ -11,7 +14,36 @@ class MatrixModule: print(f'{event.sender} commanded bot to quit, so quitting..') bot.bot_task.cancel() elif args[1]=='version': - await bot.send_text(room, f'Hemppa version {bot.version} - https://github.com/vranki/hemppa') + uptme = datetime.now() - self.starttime + await bot.send_text(room, f'Hemppa version {bot.version} - Uptime {uptme} - https://github.com/vranki/hemppa') + elif args[1]=='reload': + bot.must_be_admin(room, event) + await bot.send_text(room, f'Reloading modules..') + bot.stop() + for modulename in bot.modules: + bot.reload_module(modulename) + bot.start() + elif args[1]=='stats': + roomcount = len(bot.client.rooms) + usercount = 0 + homeservers = dict() + + for croomid in bot.client.rooms: + room = bot.client.rooms[croomid] + usercount = usercount + len(room.users) + for user in room.users: + hs = user.split(':')[1] + if homeservers.get(hs): + homeservers[hs] = homeservers[hs] + 1 + else: + homeservers[hs] = 1 + + homeservers = sorted(homeservers.items(), key=lambda kv: (kv[1], kv[0]), reverse=True) + + if len(homeservers) > 5: + homeservers = homeservers[0:5] + + await bot.send_text(room, f'I\'m seeing {usercount} users in {roomcount} rooms. Top 5 homeservers: {homeservers}') else: await bot.send_text(room, 'Unknown command, sorry.') diff --git a/modules/uptime.py b/modules/uptime.py deleted file mode 100644 index 04495c5..0000000 --- a/modules/uptime.py +++ /dev/null @@ -1,15 +0,0 @@ -import time - - -class MatrixModule: - def matrix_start(self, bot): - self.starttime = time.time() - - async def matrix_message(self, bot, room, event): - await bot.send_text(room, 'Uptime: ' + str(int(time.time() - self.starttime)) + ' seconds.') - - def matrix_stop(self, bot): - pass - - def help(self): - return('Tells how many seconds the bot has been up.')