Ça prend forme !

This commit is contained in:
Adrien Bourmault 2022-02-06 01:29:59 +01:00 committed by admin666
parent 674c5e26b3
commit 9365de1dcb
5 changed files with 241 additions and 54 deletions

View File

@ -7,6 +7,7 @@ import slixmpp
import random import random
import threading import threading
import socket import socket
import time
from hintTables import * from hintTables import *
from commands import * from commands import *
@ -26,6 +27,8 @@ class MUCBot(slixmpp.ClientXMPP):
self.room = room self.room = room
self.nick = nick self.nick = nick
self.owners = {}
self.sbuf = None
# The session_start event will be triggered when # The session_start event will be triggered when
# the bot establishes its connection with the server # the bot establishes its connection with the server
@ -51,46 +54,20 @@ class MUCBot(slixmpp.ClientXMPP):
async def start(self, event): async def start(self, event):
""" """
Process the session_start event. Requestthe roster and broadcast initial presence stanza.
Typical actions for the session_start event are
requesting the roster and broadcasting an initial
presence stanza.
Arguments:
event -- An empty dictionary. The session_start
event does not provide any additional
data.
""" """
await self.get_roster() await self.get_roster()
self.send_presence() self.send_presence()
self.plugin['xep_0045'].join_muc(self.room, self.plugin['xep_0045'].join_muc(self.room,
self.nick, self.nick,
# If a room password is needed, use:
# password=the_room_password, # password=the_room_password,
) )
def muc_message(self, msg): 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.
Whenever the bot's nickname is mentioned, respond to Whenever the bot's nickname is mentioned, respond to
the message. the message from any muc
IMPORTANT: Always check that a message is not from yourself,
otherwise you will create an infinite loop responding
to your own messages.
This handler will reply to messages that mention
the bot's nickname.
Arguments:
msg -- The received message stanza. See the documentation
for stanza objects and the Message stanza to see
how it may be used.
""" """
if msg['mucnick'] == self.nick: if msg['mucnick'] == self.nick:
@ -102,10 +79,13 @@ class MUCBot(slixmpp.ClientXMPP):
random.shuffle(cmdhints) random.shuffle(cmdhints)
for opcod in cmdhints: for opcod in cmdhints:
if opcod in msg['body']: if msg['body'][0] == "!" and opcod in msg['body']:
self.send_message(mto=msg['from'].bare, self.send_message(mto=msg['from'].bare,
mbody="%s, %s" % (msg['mucnick'], mbody="%s, %s" % (msg['mucnick'],
commandtable[opcod]() ), commandtable[opcod](self.owners[msg['from'].bare],
msg['mucnick'],
msg['body'],
self.sbuf)),
mtype='groupchat') mtype='groupchat')
return return
@ -144,26 +124,26 @@ class MUCBot(slixmpp.ClientXMPP):
# And fallback # And fallback
self.send_message(mto=msg['from'].bare, self.send_message(mto=msg['from'].bare,
mbody="%s, je n'ai pas compris (je suis un peu bête) mais j'ai bien lu!" % msg['mucnick'], mbody="%s, je n'ai pas compris (je suis un peu bot)" % msg['mucnick'],
mtype='groupchat') mtype='groupchat')
def muc_online(self, presence): def muc_online(self, presence):
""" """
Process a presence stanza from a chat room. In this case, Send a welcome message that includes
presences from users that have just come online are the user's nickname
handled by sending a welcome message that includes
the user's nickname and role in the room.
Arguments:
presence -- The received presence stanza. See the
documentation for the Presence stanza
to see how else it may be used.
""" """
if presence['muc']['nick'] != self.nick: if presence['muc']['nick'] != self.nick:
self.send_message(mto=presence['from'].bare, self.send_message(mto=presence['from'].bare,
mbody="Salut %s !" % (presence['muc']['nick']), mbody="Salut %s !" % (presence['muc']['nick']),
mtype='groupchat') 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__': if __name__ == '__main__':
# Setup the command line arguments. # Setup the command line arguments.
parser = ArgumentParser() parser = ArgumentParser()
@ -202,11 +182,18 @@ if __name__ == '__main__':
# Create buffer # Create buffer
sBuffer = SharedBuffer(xmpp) sBuffer = SharedBuffer(xmpp)
xmpp.sbuf = sBuffer
# Connect to the XMPP server and start processing XMPP stanzas. # Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect() xmpp.connect()
localservthread = LocalServer(sBuffer) localservthread = LocalServer(sBuffer)
localservthread.daemon = True
localservthread.start() localservthread.start()
time.sleep(1)
if not localservthread.is_alive():
exit(1)
xmpp.process() xmpp.process()

View File

@ -2,7 +2,7 @@
# Isengard commands # Isengard commands
def cmdping(): def cmdping(owners, nick, text, sbuf):
""" """
Ping command. Ping command.
""" """
@ -10,9 +10,38 @@ def cmdping():
return "pong !" return "pong !"
def cmdmainteneur(owners, nick, text, sbuf):
"""
Change maintainer for an host
"""
if not nick in owners:
return "désolé mais vous n'êtes pas autorisé à utiliser cette commande."
try:
splittedtext = text.split(" ")
# print maintainer
if len(splittedtext) == 2:
host = splittedtext[1]
return "le responsable de cette machine est " \
+ sbuf.buf[host]["maintainer"]
if len(splittedtext) == 3:
host = splittedtext[1]
maintainer = splittedtext[2]
sbuf.buf[host]["maintainer"] = maintainer
return "le responsable est à présent " \
+ sbuf.buf[host]["maintainer"]
except Exception as e:
print(repr(e))
return "Erreur à l'exécution"
return "Syntaxe invalide"
@ -24,6 +53,7 @@ def cmdping():
commandtable = { commandtable = {
"ping" : cmdping, "ping" : cmdping,
"mainteneur" : cmdmainteneur,
} }

View File

@ -8,9 +8,10 @@ class LocalServer(threading.Thread):
self.sharedBuffer = sharedBuffer self.sharedBuffer = sharedBuffer
def run(self): def run(self):
sockfd = socket.socket() sockfd = socket.socket()
print("Socket successfully created") print("Socket successfully created")
port = 12345 # Reserve a port on your computer...in our case it is 12345, but it can be anything port = 12346 # Reserve a port on your computer...in our case it is 12345, but it can be anything
sockfd.bind(('127.0.0.1', port)) sockfd.bind(('127.0.0.1', port))
print("Socket binded to %s" %(port)) print("Socket binded to %s" %(port))
sockfd.listen(5) # Put the socket into listening mode sockfd.listen(5) # Put the socket into listening mode

View File

@ -1,18 +1,167 @@
class SharedBuffer: class SharedBuffer:
def __init__(self, linkedBot): def __init__(self, linkedBot):
self.buf = [] self.buf = {}
self.linkedBot = linkedBot self.linkedBot = linkedBot
def flush(self): def flush(self):
for msg in self.buf:
self.linkedBot.send_message( for host in self.buf:
mto=msg.split("|")[0], if not isinstance(self.buf[host], dict):
mbody=msg.split("|")[1], continue
maintainer = self.buf[host]["maintainer"]
if self.buf[host]["needUpdate"]:
destmuc = self.buf[host]["destmuc"]
text = self.buf[host]["text"]
msg = "(néant)"
if self.buf[host]["status_type"] == "PROBLEM":
msg = "{}, je détecte un problème sur {} ({})".format(maintainer, host, text)
elif self.buf[host]["status_type"] == "UNKNOWN":
msg = "{}, état de {} inconnu ({})".format(maintainer, host, text)
elif self.buf[host]["status_type"] == "RECOVERY":
msg = "{}, problème résolu sur {} ({})".format(maintainer, host, text)
self.linkedBot.send_message(
mto=destmuc,
mbody=msg,
mtype='groupchat')
self.buf[host]["needUpdate"] = False
print("Sent to {}, msg: {}".format(destmuc, msg))
for service in self.buf[host]:
if not isinstance(self.buf[host][service], dict):
continue
if self.buf[host][service]["needUpdate"]:
destmuc = self.buf[host][service]["destmuc"]
text = self.buf[host][service]["text"]
msg = "(néant)"
if self.buf[host][service]["status_type"] == "PROBLEM":
msg = "{}, je détecte un problème de {} sur {} ({})".format(maintainer, service, host, text)
elif self.buf[host][service]["status_type"] == "UNKNOWN":
msg = "{}, état de {} inconnu pour {} ({})".format(maintainer, service, host, text)
elif self.buf[host][service]["status_type"] == "RECOVERY":
msg = "{}, problème de {} résolu sur {} ({})".format(maintainer, service, host, text)
self.linkedBot.send_message(
mto=destmuc,
mbody=msg,
mtype='groupchat') mtype='groupchat')
self.buf.pop(self.buf.index(msg))
self.buf[host][service]["needUpdate"] = False
print("Sent to {}, msg: {}".format(destmuc, msg))
print("End of flush")
def push(self, msg): def push(self, msg):
self.buf.append(msg)
if len(self.buf) > 0: # separate dest and message
self.flush() destmuc, rmsg = msg.split("|")
# separate and parse lines
cutmsg_l0 = rmsg.split("\n")[0].split(" ")
cutmsg_l1 = rmsg.split("\n")[1].split("-")
# get the status of location
status_type = cutmsg_l0[0].replace(" ", "")
status_state = cutmsg_l0[-1].replace(" ", "")
# get the location
location = ""
for i in range(len(cutmsg_l0) - 2):
location += cutmsg_l0[i+1] + " "
location = location[:-1]
# check if message is about a service or host
if len(location.split("/")) > 1:
host, service = location.split("/")
else:
host = location
service = False
text = status_state + ": " + cutmsg_l1[1].split("(")[0][1:]
raw = rmsg.split("\n")[1]
print("Dest: %s, Msg: %s" % (destmuc, rmsg))
print("Status: %s" % (status_type + " (" + status_state + ")"))
print("Host: %s, Service: %s" % (host, service))
print("Text: %s" % (text))
if host in self.buf:
if service and service in self.buf[host]:
if status_state != self.buf[host][service]["status_state"] \
or status_type != self.buf[host][service]["status_type"]:
self.buf[host][service]["status_state"] = status_state
self.buf[host][service]["status_type"] = status_type
self.buf[host][service]["destmuc"] = destmuc
self.buf[host][service]["text"] = text
self.buf[host][service]["raw"] = raw
self.buf[host][service]["needUpdate"] = True
else:
# exit if problem resolved (but unkown in the first place)
if status_type == "RECOVERY":
return
# create zone for service
self.buf[host][service] = {}
self.buf[host][service]["destmuc"] = destmuc
self.buf[host][service]["status_state"] = status_state
self.buf[host][service]["status_type"] = status_type
self.buf[host][service]["text"] = text
self.buf[host][service]["raw"] = raw
self.buf[host][service]["needUpdate"] = True
else:
# exit if problem resolved (but unkown in the first place)
if status_type == "RECOVERY":
return
# create zone for service
if service:
self.buf[host] = {}
self.buf[host]["destmuc"] = None
self.buf[host]["status_state"] = None
self.buf[host]["status_type"] = None
self.buf[host]["text"] = None
self.buf[host]["raw"] = None
self.buf[host]["maintainer"] = None
self.buf[host]["needUpdate"] = False
self.buf[host][service] = {}
self.buf[host][service]["destmuc"] = destmuc
self.buf[host][service]["status_state"] = status_state
self.buf[host][service]["status_type"] = status_type
self.buf[host][service]["text"] = text
self.buf[host][service]["raw"] = raw
self.buf[host][service]["needUpdate"] = True
else:
self.buf[host] = {}
self.buf[host]["destmuc"] = destmuc
self.buf[host]["status_state"] = status_state
self.buf[host]["status_type"] = status_type
self.buf[host]["text"] = text
self.buf[host]["raw"] = raw
self.buf[host]["maintainer"] = None
self.buf[host]["needUpdate"] = True
print(self.buf)
print("Sending...")
self.flush()
print("Sent.")
print(self.buf)
print("End of push")
#PROBLEM video.chalec.org/System load CRITICAL
#CRITICAL - Charge moyenne: 6.45, 5.61, 4.12 (Commentaire: [] )

20
xmpp-notification.py Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
import socket
import sys,os
s = socket.socket()
port = 12346 # Define the port on which you want to connect
s.connect(('127.0.0.1', port)) # Connect to the server on local computer
str = "%s|%s" % (sys.argv[1], sys.argv[2])
s.send(str.encode())
if s.recv(1024) != b'': # Receive data from the server
exit(1)
s.close()
exit(0)