hackbot/hackbot.py
2020-08-26 19:05:27 +02:00

146 lines
5 KiB
Python

#!/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()