WIP: refactoring

This commit is contained in:
Adrien Bourmault 2022-02-08 15:46:34 +01:00 committed by admin666
parent 87ca8a5e43
commit 0a88053e0c
3 changed files with 340 additions and 0 deletions

150
bot.py Normal file
View File

@ -0,0 +1,150 @@
import slixmpp
import logging
from systemd.journal import JournalHandler
from hintTables import annecdotetable, topictable
from commands import commandtable
# Logging
log = logging.getLogger(__name__)
log.addHandler(JournalHandler())
log.setLevel(logging.INFO)
class MUCBot(slixmpp.ClientXMPP):
def __init__(self, jid, password, rooms, nick):
slixmpp.ClientXMPP.__init__(self, jid + "/Isengard", password)
self.rooms = rooms
self.nick = nick
# Per channel owners
self.owners = {}
self.datastore = 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.rooms[0],
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.datastore)),
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.datastore.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'])

90
data.py Normal file
View File

@ -0,0 +1,90 @@
import datetime
import logging
from systemd.journal import JournalHandler
# Logging
log = logging.getLogger(__name__)
log.addHandler(JournalHandler())
log.setLevel(logging.INFO)
class HostData:
"""
Data related to notifications related to a given host
"""
def __init__(self, name):
self.name = name
# Concerning services
self.serviceLastType = ""
self.serviceLastStatus = ""
self.serviceLastText = ""
# Concerning host
self.lastType = ""
self.lastStatus = ""
# Tools
self.linkedMUC = ""
self.notifCount = 0
self.needUpdate = False
self.maintainer = "Tout le monde"
class DataStore:
def __init__(self, linkedBot):
log.info("Created DataStore")
self.knownHosts = {}
self.knownMaintainers = {}
self.linkedBot = linkedBot
def push(self, msg):
# TYPE|HOST/SERVICE|STATE|OUTPUT|SENDER|COMMENT
# Get current time
curtime = datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
# Get all params
destmuc, status_type, location, status_state, text, sender, comment = msg.split("|")
print("Dest: %s, Msg: %s" % (destmuc, msg))
print("Status: %s" % (status_type + " (" + status_state + ")"))
# check if message is about a service or host
if len(location.split("/")) > 1:
host, service = location.split("/")
else:
host = location
service = False
print("Host: %s, Service: %s" % (host, service))
print("Text: %s" % (text))

100
main.py Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env python3
from systemd.journal import JournalHandler
from getpass import getpass
from argparse import ArgumentParser
import random
import threading
import socket
import time
import signal
import logging
from bot import MUCBot
from data import DataStore
from localServer import LocalServer
# Logging
log = logging.getLogger(__name__)
log.addHandler(JournalHandler())
log.setLevel(logging.INFO)
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):
log.info("Exiting...")
cleanExit()
# Register SIGINT signal handler
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
store = DataStore(xmpp)
xmpp.datastore = store
localservthread = LocalServer(store)
localservthread.start()
while True:
time.sleep(1)
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
# Check local server status
if not localservthread.is_alive():
exit(1)
try:
xmpp.process()
except KeyboardInterrupt:
cleanExit()