#!/usr/bin/env python3 # -*- coding: utf-8 -*- # file: hackbot.py # date: 24.07.2020 # desc: class to deal with presence and messages in the given muc. import sys import logging import common from idlebot import IdleBot from manager import PluginManager class HackBot(IdleBot): ''' Deals with the messages and presences from the muc. ''' def __init__(self, jid, password, room, nick, plugin_dir): IdleBot.__init__(self, jid, password, room, nick) self.add_event_handler("groupchat_message", self.muc_message) self.plugin_manager = PluginManager(plugin_dir) self.plugin_store = self.plugin_manager.collect_plugins() def muc_message(self, msg): """ Process incoming message stanzas from any chat room. Be aware that if you also have any handlers for the 'message' event, message stanzas may be processed by both handlers, so check the 'type' attribute when using a 'message' event handler. Arguments: msg -- The received message stanza. See the documentation for stanza objects and the Message stanza to see how it may be used. """ # dont answer myself ... prevent self flooding if msg['mucnick'] == self.nick: logging.debug('Message from myself ... ignored') return # check for command command = common.get_command_from_body(msg) if command is not False: logging.debug('Command received: {}'.format(command)) # if command is help (needs a better argument handling) if command == 'help': arguments = common.get_arguments_from_body(msg) logging.debug('Arguments: {}'.format(arguments)) if arguments is False: msg.reply(self.help()).send() else: msg.reply(self.help(arguments[0].strip())).send() # command refernces a plugin elif command in self.plugin_store.keys(): logging.debug('Valid comand: {}'.format(command)) self.run_plugin(command, msg, self.answer_muc) # command is unknown else: logging.warning('Unknown command: {}'.format(command)) message = ': '.join((msg['mucnick'], '"{}" is not a valid command'.format(command))) self.answer_muc(message) # only for debugging else: logging.debug('No command found') def run_plugin(self, command, stanza, callback): ''' Creates a instance from the module is stored in plugin store under the given command key and runs it. Arguments: command -- The command is received in MUC and matched a key in the plugin store (string). stanza -- The message object caused the call. callback -- Function to post the response from plugin. ''' instance = self.plugin_store[command].Plugin(self.answer_muc) instance.run(stanza) def answer_muc(self, message, room=None): ''' Sends a message to the given room. Arguments: message -- The message to send (string). room -- The room where to send (string). ''' if room is None: room = self.room self.send_message(mto = room, mbody = message, mtype = 'groupchat') def help(self, *command): ''' Checks if arguments is false or not. Depends on this result it calles long or short help. Arguments: command -- The command for which help requests. Optional. Returns: help -- string ''' if not command or command is False: logging.debug('Empty help request. Send all commands.') return self.help_overview() else: return self.help_command(command) def help_overview(self): ''' Grabs short desciptions from all available plugins an deliver it to MUC. Returns: helpstring -- string ''' commands = [] helpstring = 'Available commands:' for key in self.plugin_store.keys(): if key == 'help': continue commands.append(key) commands.sort() for key in commands: description = self.plugin_store[key].Plugin.get_description() line = '{0:10s}: {1}'.format(key, description) helpstring = '\n'.join((helpstring, line)) return helpstring def help_command(self, command): ''' param 1: tuple (with one element) ''' for i in command: if i not in self.plugin_store.keys(): msg = '"{}" is not a valid argument for help'.format(i) return msg instance = self.plugin_store[i].Plugin() return instance.help()