#!/usr/bin/env python3 import logging from getpass import getpass from argparse import ArgumentParser import slixmpp import random import threading import socket import time import signal from hintTables import * from commands import * from serviceData import ServiceData from localServer import LocalServer class MUCBot(slixmpp.ClientXMPP): """ A simple Slixmpp bot that will greets those who enter the room, and acknowledge any messages that mentions the bot's nickname. """ def __init__(self, jid, password, room, nick): slixmpp.ClientXMPP.__init__(self, jid + "/Isengard", password) self.room = room self.nick = nick self.owners = {} self.serviceData = None # The session_start event will be triggered when # the bot establishes its connection with the server # and the XML streams are ready for use. We want to # listen for this event so that we we can initialize # our roster. self.add_event_handler("session_start", self.start) # The groupchat_message event is triggered whenever a message # stanza is received from any chat room. If you also also # register a handler for the 'message' event, MUC messages # will be processed by both handlers. self.add_event_handler("groupchat_message", self.muc_message) # The groupchat_presence event is triggered whenever a # presence stanza is received from any chat room, including # any presences you send yourself. To limit event handling # to a single room, use the events muc::room@server::presence, # muc::room@server::got_online, or muc::room@server::got_offline. self.add_event_handler("muc::%s::got_online" % self.room, self.muc_online) async def start(self, event): """ Requestthe roster and broadcast initial presence stanza. """ await self.get_roster() self.send_presence() self.plugin['xep_0045'].join_muc(self.room, self.nick, # password=the_room_password, ) def push(self, destmuc, msg): self.send_message( mto=destmuc, mbody=msg, mtype='groupchat') print("To: %s\nBody: %s" % (destmuc, msg)) def muc_message(self, msg): """ Whenever the bot's nickname is mentioned, respond to the message from any muc """ if msg['mucnick'] == self.nick: return # Commands cmdhints = list(commandtable.keys()) random.shuffle(cmdhints) for opcod in cmdhints: if msg['body'][0] == "!" and opcod in msg['body']: self.send_message(mto=msg['from'].bare, mbody="%s, %s" % (msg['mucnick'], commandtable[opcod](self.owners[msg['from'].bare], msg['mucnick'], msg['body'], self.serviceData)), mtype='groupchat') return # When people speak to each other without necessarily highlighting Isengard anechints = list(annecdotetable.keys()) random.shuffle(anechints) for hint in anechints: if hint in msg['body']: self.send_message(mto=msg['from'].bare, mbody="%s" % (annecdotetable[hint][ random.randrange(0,len(annecdotetable[hint])) ]), mtype='groupchat') return if self.nick not in msg['body']: return # When people talk to Isengard topichints = list(topictable.keys()) random.shuffle(topichints) for hint in topichints: if hint in msg['body']: self.send_message(mto=msg['from'].bare, mbody="%s, %s" % (msg['mucnick'], topictable[hint][ random.randrange(0,len(topictable[hint])) ]), mtype='groupchat') return # And fallback self.send_message(mto=msg['from'].bare, mbody="%s, je n'ai pas compris (je suis un peu bot)" % msg['mucnick'], mtype='groupchat') def muc_online(self, presence): """ Send a welcome message that includes the user's nickname """ if presence['muc']['nick'] in self.serviceData.maintainerData: self.send_message(mto=presence['from'].bare, mbody="Salut %s, vos services ont produit des " + "alertes en votre absence !\nUtilisez la commande"+ " `hist` pour consulter l'historique" % (presence['muc']['nick']), mtype='groupchat') if presence['muc']['affiliation'] == "owner": if not presence['from'].bare in self.owners: self.owners[presence['from'].bare] = [] self.owners[presence['from'].bare].append(presence['muc']['nick']) if __name__ == '__main__': def cleanExit(): global localservthread localservthread.pleaseStop = True # stop tcp server sockfd = socket.socket() port = 12346 sockfd.connect(('127.0.0.1', port)) sockfd.send(b'') sockfd.close() exit(0) def signalHandler(sig, frame): print("Exiting...") cleanExit() signal.signal(signal.SIGINT, signalHandler) # Setup the command line arguments. parser = ArgumentParser() # Output verbosity options. parser.add_argument("-q", "--quiet", help="set logging to ERROR", action="store_const", dest="loglevel", const=logging.ERROR, default=logging.INFO) parser.add_argument("-d", "--debug", help="set logging to DEBUG", action="store_const", dest="loglevel", const=logging.DEBUG, default=logging.INFO) # JID and password options. parser.add_argument("-j", "--jid", dest="jid", help="JID to use") parser.add_argument("-p", "--password", dest="password", help="password to use") parser.add_argument("-r", "--room", dest="room", help="MUC room to join") parser.add_argument("-n", "--nick", dest="nick", help="MUC nickname") args = parser.parse_args() # Setup logging. logging.basicConfig(level=args.loglevel, format='%(levelname)-8s %(message)s') # Setup the MUCBot and register plugins. Note that while plugins may # have interdependencies, the order in which you register them does # not matter. xmpp = MUCBot(args.jid, args.password, args.room, args.nick) xmpp.register_plugin('xep_0030') # Service Discovery xmpp.register_plugin('xep_0045') # Multi-User Chat xmpp.register_plugin('xep_0199') # XMPP Ping # Create buffer sBuffer = ServiceData(xmpp) xmpp.serviceData = sBuffer # Connect to the XMPP server and start processing XMPP stanzas. xmpp.connect() localservthread = LocalServer(sBuffer) localservthread.start() time.sleep(1) if not localservthread.is_alive(): exit(1) try: xmpp.process() except KeyboardInterrupt: cleanExit()