diff --git a/message.py b/message.py index 75089d6..e1d3a1f 100644 --- a/message.py +++ b/message.py @@ -62,8 +62,8 @@ class Credits: now = datetime.now() + self.randsec if self.lastmessage.minute == now.minute and (self.lastmessage.second == now.second or self.lastmessage.second == now.second - 1): print("AUTOBAN %s: too low time between messages" % self.name) - BANLIST.append(self.name) - #self.credits -= self.credits / 2 #Une alternative + #BANLIST.append(self.name) + self.credits -= self.credits / 2 #Une alternative return False self.iask = True @@ -169,6 +169,10 @@ class Message: self.cmd = "UNKNOWN" print (line) + @property + def is_owner(self): + return self.sender == self.srv.owner + def send_msg (self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"): if CREDITS[self.realname].speak(): diff --git a/nemuspeak.py b/nemuspeak.py index a3d1c71..1fb1f4f 100755 --- a/nemuspeak.py +++ b/nemuspeak.py @@ -164,6 +164,7 @@ class Server: return msg.sender != OWNER and (msg.channel == OWNER or msg.channel in self.channels) def read(self): + global stopSpk, talkEC, g_queue readbuffer = "" #Here we store all the messages from server while 1: try: @@ -178,10 +179,39 @@ class Server: msg = message.Message(self, line) if msg.cmd == "PING": self.s.send(("PONG %s\r\n" % msg.content).encode ()) - elif msg.cmd == "PRIVMSG" and self.authorize(msg): - g_queue.append(msg) - if talkEC == 0: - _thread.start_new_thread(speak, (0,)) + elif msg.cmd == "PRIVMSG" and (self.authorize(msg) or msg.content[0] == '`'): + if msg.content[0] == '`' and msg.sender == OWNER: + cmd = msg.content[1:].split(' ') + if cmd[0] == "speak": + _thread.start_new_thread(speak, (0,)) + elif cmd[0] == 'reset': + while len(g_queue) > 0: + g_queue.pop() + elif cmd[0] == 'save': + if talkEC == 0: + talkEC = 1 + stopSpk = 1 + elif cmd[0] == 'test': + g_queue.append(message.Message(self, ":Quelqun!someone@p0m.fr PRIVMSG %s :Ceci est un message de test ;)"%(self.channels))) + elif cmd[0] == 'list': + print ("Currently listened channels:") + for chan in self.channels: + print (chan) + print ("-- ") + elif cmd[0] == 'add' and len(cmd) > 1: + self.channels.append(cmd[1]) + print (cmd[1] + " added to listened channels") + elif cmd[0] == 'del' and len(cmd) > 1: + if self.channels.count(cmd[1]) > 0: + self.channels.remove(cmd[1]) + print (cmd[1] + " removed from listened channels") + else: + print (cmd[1] + " not in listened channels") + + else: + g_queue.append(msg) + if talkEC == 0: + _thread.start_new_thread(speak, (0,)) def connect(self): self.s = socket.socket( ) #Create the socket diff --git a/qd.py b/qd.py index 06e96ff..7a9602b 100644 --- a/qd.py +++ b/qd.py @@ -41,6 +41,16 @@ class Score: self.great = int(item.getAttribute("great")) self.bad = int(item.getAttribute("bad")) + def merge(self, other): + self.ftt += other.ftt + self.twt += other.twt + self.pi += other.pi + self.notfound += other.notfound + self.tententen += other.tententen + self.leet += other.leet + self.great += other.great + self.bad += other.bad + def newWinner(self): self.ftt = 0 self.twt = 0 @@ -164,7 +174,17 @@ def rev (tupl): def parseanswer (msg): if msg.cmd[0] == "42" or msg.cmd[0] == "score" or msg.cmd[0] == "scores": global SCORES, MANCHE - if len(msg.cmd) > 1 and (msg.cmd[1] == "help" or msg.cmd[1] == "aide"): + if len(msg.cmd) > 3 and msg.is_owner and (msg.cmd[1] == "merge"): + if msg.cmd[2] in SCORES and msg.cmd[3] in SCORES: + SCORES[msg.cmd[2]].merge (SCORES[msg.cmd[3]]) + del SCORES[msg.cmd[3]] + msg.send_chn ("%s a été correctement fusionné avec %s."%(msg.cmd[3], msg.cmd[2])) + else: + if msg.cmd[2] not in SCORES: + msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[2]) + elif msg.cmd[3] not in SCORES: + msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[3]) + elif len(msg.cmd) > 1 and (msg.cmd[1] == "help" or msg.cmd[1] == "aide"): msg.send_chn ("Formule : normal * 2 - bad * 10 + great * 5 + leet * 3 + pi * 3.1415 + dt + not_found * 4.04") elif len(msg.cmd) > 1 and (msg.cmd[1] == "manche" or msg.cmd[1] == "round"): msg.send_chn ("Nous sommes dans la %de manche, gagnée par %s avec %d points et commencée par %s le %s"%MANCHE) @@ -173,8 +193,8 @@ def parseanswer (msg): phrase = "" if len(msg.cmd) > 1: - if msg.cmd[1].lower() in SCORES: - phrase += " " + msg.cmd[1] + ": " + SCORES[msg.cmd[1].lower()].details() + if msg.cmd[1] in SCORES: + phrase += " " + msg.cmd[1] + ": " + SCORES[msg.cmd[1]].details() else: phrase = " %s n'a encore jamais joué,"%(msg.cmd[1]) else: @@ -194,7 +214,7 @@ def parseanswer (msg): def win(msg): global SCORES, MANCHE - who = msg.sender.lower() + who = msg.sender (num_manche, winner, nb_points, whosef, dayte) = MANCHE diff --git a/soutenance.py b/soutenance.py index 321eab9..17b228b 100644 --- a/soutenance.py +++ b/soutenance.py @@ -3,6 +3,7 @@ import http.client import time import re +import _thread from datetime import date from datetime import datetime from datetime import timedelta @@ -124,73 +125,87 @@ def help_full (): return "!soutenance: gives information about current defenses state\n!soutenance /who/: gives the date of the next defense of /who/.\n!soutenances /who/: gives all defense dates of /who/" datas = None +THREAD = None +wait = list() def parseanswer (msg): - global datas + global THREAD, wait if msg.cmd[0] == "soutenance" or msg.cmd[0] == "soutenances": - #Starts by updating datas - if datas is not None: - datas = datas.update () - if datas is None: - datas = SiteSoutenances(getPage().decode()) - - if len(msg.cmd) == 1 or msg.cmd[1] == "next": - soutenance = datas.findLast() - if soutenance is None: - msg.send_chn ("Il ne semble pas y avoir de soutenance pour le moment.") - else: - if soutenance.start > soutenance.hour: - avre = "%s de *retard*"%msg.just_countdown(soutenance.start - soutenance.hour, 4) - else: - avre = "%s *d'avance*"%msg.just_countdown(soutenance.hour - soutenance.start, 4) - msg.send_chn ("Actuellement à la soutenance numéro %d, commencée il y a %s avec %s."%(soutenance.rank, msg.just_countdown(datetime.now () - soutenance.start, 4), avre)) - - elif msg.cmd[1] == "assistants" or msg.cmd[1] == "assistant" or msg.cmd[1] == "yaka" or msg.cmd[1] == "yakas" or msg.cmd[1] == "acu" or msg.cmd[1] == "acus": - assistants = datas.findAssistants() - if len(assistants) > 0: - msg.send_chn ("Les %d assistants faisant passer les soutenances sont : %s." % (len(assistants), ', '.join(assistants.keys()))) - else: - msg.send_chn ("Il ne semble pas y avoir de soutenance pour le moment.") + if THREAD is None: + THREAD = _thread.start_new_thread (startSoutenance, (msg,)) else: - name = msg.cmd[1] - - if msg.cmd[0] == "soutenance": - soutenance = datas.findClose(name) - if soutenance is None: - msg.send_chn ("Pas d'horaire de soutenance pour %s."%name) - else: - if soutenance.state == "En cours": - msg.send_chn ("%s est actuellement en soutenance avec %s. Elle était prévue à %s, position %d."%(name, soutenance.assistant, soutenance.hour, soutenance.rank)) - elif soutenance.state == "Effectue": - msg.send_chn ("%s a passé sa soutenance avec %s. Elle a duré %s."%(name, soutenance.assistant, msg.just_countdown(soutenance.end - soutenance.start, 4))) - elif soutenance.state == "Retard": - msg.send_chn ("%s était en retard à sa soutenance de %s."%(name, soutenance.hour)) - else: - last = datas.findLast() - if last is not None: - if soutenance.hour + (last.start - last.hour) > datetime.now (): - msg.send_chn ("Soutenance de %s : %s, position %d ; estimation du passage : dans %s."%(name, soutenance.hour, soutenance.rank, msg.just_countdown((soutenance.hour - datetime.now ()) + (last.start - last.hour)))) - else: - msg.send_chn ("Soutenance de %s : %s, position %d ; passage imminent."%(name, soutenance.hour, soutenance.rank)) - else: - msg.send_chn ("Soutenance de %s : %s, position %d."%(name, soutenance.hour, soutenance.rank)) - - elif msg.cmd[0] == "soutenances": - souts = datas.findAll(name) - if souts is None: - msg.send_snd ("Pas de soutenance prévues pour %s."%name) - else: - first = True - for s in souts: - if first: - msg.send_snd ("Soutenance(s) de %s : - %s (position %d) ;"%(name, s.hour, s.rank)) - first = False - else: - msg.send_snd (" %s - %s (position %d) ;"%(len(name)*' ', s.hour, s.rank)) - + wait.append(msg) return True return False + +def startSoutenance (msg): + global datas, THREAD, wait + + #Starts by updating datas + if datas is not None: + datas = datas.update () + if datas is None: + datas = SiteSoutenances(getPage().decode()) + + if len(msg.cmd) == 1 or msg.cmd[1] == "next": + soutenance = datas.findLast() + if soutenance is None: + msg.send_chn ("Il ne semble pas y avoir de soutenance pour le moment.") + else: + if soutenance.start > soutenance.hour: + avre = "%s de *retard*"%msg.just_countdown(soutenance.start - soutenance.hour, 4) + else: + avre = "%s *d'avance*"%msg.just_countdown(soutenance.hour - soutenance.start, 4) + msg.send_chn ("Actuellement à la soutenance numéro %d, commencée il y a %s avec %s."%(soutenance.rank, msg.just_countdown(datetime.now () - soutenance.start, 4), avre)) + + elif msg.cmd[1] == "assistants" or msg.cmd[1] == "assistant" or msg.cmd[1] == "yaka" or msg.cmd[1] == "yakas" or msg.cmd[1] == "acu" or msg.cmd[1] == "acus": + assistants = datas.findAssistants() + if len(assistants) > 0: + msg.send_chn ("Les %d assistants faisant passer les soutenances sont : %s." % (len(assistants), ', '.join(assistants.keys()))) + else: + msg.send_chn ("Il ne semble pas y avoir de soutenance pour le moment.") + else: + name = msg.cmd[1] + + if msg.cmd[0] == "soutenance": + soutenance = datas.findClose(name) + if soutenance is None: + msg.send_chn ("Pas d'horaire de soutenance pour %s."%name) + else: + if soutenance.state == "En cours": + msg.send_chn ("%s est actuellement en soutenance avec %s. Elle était prévue à %s, position %d."%(name, soutenance.assistant, soutenance.hour, soutenance.rank)) + elif soutenance.state == "Effectue": + msg.send_chn ("%s a passé sa soutenance avec %s. Elle a duré %s."%(name, soutenance.assistant, msg.just_countdown(soutenance.end - soutenance.start, 4))) + elif soutenance.state == "Retard": + msg.send_chn ("%s était en retard à sa soutenance de %s."%(name, soutenance.hour)) + else: + last = datas.findLast() + if last is not None: + if soutenance.hour + (last.start - last.hour) > datetime.now (): + msg.send_chn ("Soutenance de %s : %s, position %d ; estimation du passage : dans %s."%(name, soutenance.hour, soutenance.rank, msg.just_countdown((soutenance.hour - datetime.now ()) + (last.start - last.hour)))) + else: + msg.send_chn ("Soutenance de %s : %s, position %d ; passage imminent."%(name, soutenance.hour, soutenance.rank)) + else: + msg.send_chn ("Soutenance de %s : %s, position %d."%(name, soutenance.hour, soutenance.rank)) + + elif msg.cmd[0] == "soutenances": + souts = datas.findAll(name) + if souts is None: + msg.send_snd ("Pas de soutenance prévues pour %s."%name) + else: + first = True + for s in souts: + if first: + msg.send_snd ("Soutenance(s) de %s : - %s (position %d) ;"%(name, s.hour, s.rank)) + first = False + else: + msg.send_snd (" %s - %s (position %d) ;"%(len(name)*' ', s.hour, s.rank)) + THREAD = None + if len(wait) > 0: + startSoutenance(wait.pop()) + + def parseask (msg): return False diff --git a/whereis.py b/whereis.py index be06134..52b5245 100644 --- a/whereis.py +++ b/whereis.py @@ -4,6 +4,7 @@ import re import sys import socket import time +import _thread from datetime import datetime from datetime import date from datetime import timedelta @@ -15,15 +16,19 @@ from xml.dom.minidom import getDOMImplementation NS_SERVER = 'ns-server.epita.fr' NS_PORT = 4242 +THREAD = None +search = list() + class UpdatedStorage: def __init__(self): sock = connect_to_ns(NS_SERVER, NS_PORT) self.users = dict() - for l in list_users(sock): - u = User(l) - self.users[u.login] = u - sock.close() - self.lastUpdate = datetime.now () + if sock != None: + for l in list_users(sock): + u = User(l) + self.users[u.login] = u + sock.close() + self.lastUpdate = datetime.now () def update(self): if datetime.now () - self.lastUpdate < timedelta(minutes=10): @@ -52,6 +57,8 @@ class User(object): return 'en midlab' elif self.ip.startswith('10.250'): return 'en cisco' + elif self.ip.startswith('10.41'): + return 'sur le wifi' else: return None @@ -63,7 +70,10 @@ class User(object): else: return "chez lui" else: - return self.sm + " rangée " + self.ip.split('.')[2] + " poste " + self.ip.split('.')[3] + if self.ip.startswith('10.200'): + return self.sm + " poste " + self.ip.split('.')[3] + else: + return self.sm + " rangée " + self.ip.split('.')[2] + " poste " + self.ip.split('.')[3] def __cmp__(self, other): return cmp(self.login, other.login) @@ -72,10 +82,14 @@ class User(object): return hash(self.login) def connect_to_ns(server, port): + try: s = socket.socket() + s.settimeout(1) s.connect((server, port)) - s.recv(8192) # salut ... - return s + except socket.error: + return None + s.recv(8192) # salut ... + return s def list_users(sock): sock.send('list_users\n'.encode()) @@ -94,6 +108,8 @@ def load_module(datas_path): def save_module(): """Save the module state""" + if THREAD is not None: + THREAD.exit() return def help_tiny (): @@ -105,48 +121,54 @@ def help_full (): datas = None -def parseanswer (msg): - global datas - if msg.cmd[0] == "whereis" or msg.cmd[0] == "whereare" or msg.cmd[0] == "ouest" or msg.cmd[0] == "ousont": - if datas is not None: - datas = datas.update () - if datas is None: - datas = UpdatedStorage() +def startWhereis(msg): + global datas, THREAD, search + if datas is not None: + datas = datas.update () + if datas is None: + datas = UpdatedStorage() + if datas is None: + msg.send_chn("Hmm c'est embarassant, serait-ce la fin du monde ou juste netsoul qui est mort ?") + return + pasla = list() + + for name in msg.cmd: + if name == "whereis" or name == "whereare" or name == "ouest" or name == "ousont" or name == "ip": + if len(msg.cmd) >= 2: + continue + else: + name = msg.sender + + if name in datas.users: + if msg.cmd[0] == "ip": + msg.send_chn ("L'ip de %s est %s." %(name, datas.users[name].ip)) + else: + msg.send_chn ("%s est %s (%s)." %(name, datas.users[name].poste, unquote(datas.users[name].location))) + else: + pasla.append(name) + + if len(pasla) == 1: + msg.send_chn ("%s n'est pas connecté sur le PIE." % pasla[0]) + elif len(pasla) > 1: + msg.send_chn ("%s ne sont pas connectés sur le PIE." % ", ".join(pasla)) + + THREAD = None + if len(search) > 0: + startWhereis(search.pop()) + + +def parseanswer (msg): + global datas, THREAD, search + if msg.cmd[0] == "whereis" or msg.cmd[0] == "whereare" or msg.cmd[0] == "ouest" or msg.cmd[0] == "ousont" or msg.cmd[0] == "ip": if len(msg.cmd) > 10: msg.send_snd ("Demande moi moins de personnes à la fois dans ton !%s" % msg.cmd[0]) return True - pasla = list() - - for name in msg.cmd: - if name == "whereis" or name == "whereare" or name == "ouest" or name == "ousont": - if len(msg.cmd) >= 2: - continue - else: - name = msg.sender - - if name in datas.users: - msg.send_chn ("%s est %s (%s)." %(name, datas.users[name].poste, unquote(datas.users[name].location))) - else: - pasla.append(name) - - if len(pasla) == 1: - msg.send_chn ("%s n'est pas connecté sur le PIE." % pasla[0]) - elif len(pasla) > 1: - msg.send_chn ("%s ne sont pas connectés sur le PIE." % ", ".join(pasla)) - - return True - elif msg.cmd[0] == "ip": - if len(msg.cmd) >= 2: - name = msg.cmd[1] + if THREAD is None: + THREAD = _thread.start_new_thread (startWhereis, (msg,)) else: - name = msg.sender - - if name in datas.users: - msg.send_chn ("L'ip de %s est %s." %(name, datas.users[name].ip)) - else: - msg.send_chn ("%s n'est pas connecté à netsoul." % name) + search.append(msg) return True return False