From 2e461f26f49a4adcb7a777b0ae9e37313bc6b1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 16 Apr 2012 18:28:43 +0200 Subject: [PATCH] Stability improvements --- birthday.py | 58 +++++++++++++++++++++++++-------------- message.py | 76 +++++++++++++++++++++++++++++++++++++++------------ nemubot.py | 10 +++---- qd.py | 4 +-- server.py | 11 ++++---- soutenance.py | 38 +++++++++++++++++++------- 6 files changed, 136 insertions(+), 61 deletions(-) diff --git a/birthday.py b/birthday.py index 6f8fdf4..2f73e2c 100644 --- a/birthday.py +++ b/birthday.py @@ -84,22 +84,26 @@ def help_full (): return "!anniv /who/: gives the remaining time before the anniversary of /who/\nIf /who/ is not given, gives the remaining time before your anniversary.\n\n To set yout birthday, say it to nemubot :)" +def findName(msg): + if len(msg.cmd) < 2 or msg.cmd[1].lower() == "moi" or msg.cmd[1].lower() == "me": + name = msg.sender.lower() + else: + name = msg.cmd[1].lower() + + matches = [] + + if name in BIRTHDAYS: + matches.append(name) + else: + for k in BIRTHDAYS.keys (): + if k.find (name) == 0: + matches.append (k) + return (matches, name) + + def parseanswer(msg): if msg.cmd[0] == "anniv": - if len(msg.cmd) < 2 or msg.cmd[1].lower() == "moi" or msg.cmd[1].lower() == "me": - name = msg.sender.lower() - else: - name = msg.cmd[1].lower() - - matches = [] - - if name in BIRTHDAYS: - matches.append(name) - else: - for k in BIRTHDAYS.keys (): - if k.find (name) == 0: - matches.append (k) - + (matches, name) = findName(msg) if len(matches) == 1: (n, d) = (matches[0], BIRTHDAYS[matches[0]]) tyd = d @@ -111,10 +115,19 @@ def parseanswer(msg): if tyd < datetime.today(): tyd = datetime(date.today().year + 1, tyd.month, tyd.day) - msg.send_chn (msg.countdown_format (tyd, "Il reste%s avant l'anniversaire de %s !" % ("%s", n), "")) + msg.send_chn (msg.countdown_format (tyd, "Il reste %s avant l'anniversaire de %s !" % ("%s", n), "")) else: msg.send_chn ("%s: désolé, je ne connais pas la date d'anniversaire de %s. Quand est-il né ?"%(msg.sender, name)) return True + elif msg.cmd[0] == "age": + (matches, name) = findName(msg) + if len(matches) == 1: + (n, d) = (matches[0], BIRTHDAYS[matches[0]]) + + msg.send_chn (msg.countdown_format (d, "", "%s a %s." % (n, "%s"))) + else: + msg.send_chn ("%s: désolé, je ne connais pas l'âge de %s. Quand est-il né ?"%(msg.sender, name)) + return True else: return False @@ -122,13 +135,16 @@ def parseanswer(msg): def parseask(msg): msgl = msg.content.lower () if re.match("^.*(date de naissance|birthday|geburtstag|née?|nee? le|born on).*$", msgl) is not None: - extDate = msg.extractDate () - if extDate is None: + try: + extDate = msg.extractDate () + if extDate is None: + msg.send_chn ("%s: ta date de naissance ne paraît pas valide..." % (msg.sender)) + else: + BIRTHDAYS[msg.sender.lower()] = extDate + msg.send_chn ("%s: ok, c'est noté, ta date de naissance est le %s" % (msg.sender, extDate.strftime("%A %d %B %Y à %H:%M"))) + save_module () + except: msg.send_chn ("%s: ta date de naissance ne paraît pas valide..." % (msg.sender)) - else: - BIRTHDAYS[msg.sender.lower()] = extDate - msg.send_chn ("%s: ok, c'est noté, ta date de naissance est le %s" % (msg.sender, extDate.strftime("%A %d %B %Y à %H:%M"))) - save_module () return True return False diff --git a/message.py b/message.py index ad130e0..a264293 100644 --- a/message.py +++ b/message.py @@ -6,6 +6,7 @@ import re import socket import string import time +import imp class Message: def __init__ (self, srv, line): @@ -82,37 +83,57 @@ class Message: self.srv.send_msg (self.sender, msg) - def just_countdown (self, delta): + def just_countdown (self, delta, resolution = 5): sec = delta.seconds hours, remainder = divmod(sec, 3600) minutes, seconds = divmod(remainder, 60) + an = int(delta.days / 365.25) + days = delta.days % 365.25 sentence = "" force = False - if force or delta.days > 0: + if resolution > 0 and (force or an > 0): force = True - sentence += " %i jour"%(delta.days) + sentence += " %i an"%(an) - if delta.days > 1: + if an > 1: sentence += "s" - sentence += "," + if resolution > 2: + sentence += "," + elif resolution > 1: + sentence += " et" - if force or hours > 0: + if resolution > 1 and (force or days > 0): + force = True + sentence += " %i jour"%(days) + + if days > 1: + sentence += "s" + if resolution > 3: + sentence += "," + elif resolution > 2: + sentence += " et" + + if resolution > 2 and (force or hours > 0): force = True sentence += " %i heure"%(hours) if hours > 1: sentence += "s" - sentence += "," + if resolution > 4: + sentence += "," + elif resolution > 3: + sentence += " et" - if force or minutes > 0: + if resolution > 3 and (force or minutes > 0): force = True sentence += " %i minute"%(minutes) if minutes > 1: sentence += "s" - sentence += " et" + if resolution > 4: + sentence += " et" - if force or seconds > 0: + if resolution > 4 and (force or seconds > 0): force = True sentence += " %i seconde"%(seconds) if seconds > 1: @@ -165,6 +186,10 @@ class Message: if re.match(".*(m[' ]?entends?[ -]+tu|h?ear me|do you copy|ping)", messagel) is not None: self.send_chn ("%s: pong"%(self.sender)) + elif re.match(".*(quel(le)? heure est[ -]il|what time is it)", messagel) is not None: + now = datetime.now() + self.send_chn ("%s: j'envoie ce message à %s:%d:%d."%(self.sender, now.hour, now.minute, now.second)) + elif re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (.+)$", messagel) is not None: result = re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (qu(e |'))?(.+)$", self.content) self.send_chn ("%s: %s"%(result.group(2), result.group(5))) @@ -182,10 +207,25 @@ class Message: self.send_msg(result.group(2), result.group(1)) else: - for imp in mods: - if imp.parseask(self): + for im in mods.keys(): + if mods[im].parseask(self): return + elif self.content[0] == '`' and self.sender == self.srv.owner: + self.cmd = self.content[1:].split(' ') + if self.cmd[0] == "reload": + if len(self.cmd) > 1: + if self.cmd[1] in mods: + mods[self.cmd[1]].save_module () + imp.reload(mods[self.cmd[1]]) + mods[self.cmd[1]].load_module (self.srv.datas_dir) + self.send_snd ("Module %s rechargé avec succès."%self.cmd[1]) + else: + self.send_snd ("Module inconnu %s."%self.cmd[1]) + else: + self.send_snd ("Usage: `reload /module/.") + self.send_snd ("Loaded modules: " + ', '.join(mods.keys()) + ".") + elif self.content[0] == '!': self.cmd = self.content[1:].split(' ') if self.cmd[0] == "help": @@ -196,16 +236,16 @@ class Message: self.send_snd("No help for command %s" % self.cmd[1]) else: self.send_snd("Pour me demander quelque chose, commencez votre message par mon nom ou par l'une des commandes suivantes :") - for imp in mods: - self.send_snd(" - %s" % imp.help_tiny ()) + for im in mods: + self.send_snd(" - %s" % im.help_tiny ()) - for imp in mods: - if imp.parseanswer(self): + for im in mods.keys(): + if mods[im].parseanswer(self): return else: - for imp in mods: - if imp.parselisten(self): + for im in mods.keys(): + if mods[im].parselisten(self): return def extractDate (self): diff --git a/nemubot.py b/nemubot.py index e25f061..47c6bb8 100755 --- a/nemubot.py +++ b/nemubot.py @@ -12,7 +12,7 @@ from xml.dom.minidom import parse imports = ["birthday", "qd", "events", "youtube", "watchWebsite", "soutenance"] imports_launch = ["watchWebsite"] -mods = list () +mods = {} import server if len(sys.argv) != 2 and len(sys.argv) != 3: @@ -23,8 +23,8 @@ if len(sys.argv) != 2 and len(sys.argv) != 3: def onSignal(signum, frame): print ("\nSIGINT receive, saving states and close") - for imp in mods: - imp.save_module () + for imp in mods.keys(): + mods[imp].save_module () sys.exit (0) signal.signal(signal.SIGINT, onSignal) @@ -41,12 +41,12 @@ servers = list () for imp in imports: mod = __import__ (imp) - mods.append (mod) + mods[imp] = mod mod.load_module (basedir + "/datas/") for serveur in config.getElementsByTagName('server'): srv = server.Server(serveur, config.getAttribute('nick'), config.getAttribute('owner'), config.getAttribute('realname')) - srv.launch(mods) + srv.launch(mods, basedir + "/datas/") servers.append (srv) for imp in imports_launch: diff --git a/qd.py b/qd.py index 0b4afd4..b0c67b0 100644 --- a/qd.py +++ b/qd.py @@ -161,7 +161,7 @@ def help_tiny (): return "!42: display scores\n!42 help: display the performed calculate\n!42 manche: display information about current round\n!42 /who/: show the /who/'s scores" def help_full (): - return "!anniv /who/: gives the remaining time before the anniversary of /who/\nIf /who/ is not given, gives the remaining time before your anniversary.\n\n To set yout birthday, say it to nemubot :)" + return "Help for 42 todo" def rev (tupl): @@ -277,7 +277,7 @@ def parselisten (msg): else: getUser(msg.sender).playBad() - if len (msg.content) < 12 and (msg.content.strip().lower().startswith("leet time") or msg.content.strip().lower().startswith("leettime") or msg.content.strip().lower().startswith("l33t time") or msg.content.strip().lower().startswith("1337")): + if len (msg.content) < 12 and (msg.content.strip().lower().startswith("leet time") or msg.content.strip().lower().startswith("leettime") or msg.content.strip().lower().startswith("leetime") or msg.content.strip().lower().startswith("l33t time") or msg.content.strip().lower().startswith("1337")): if datetime.now().hour == 13 and datetime.now().minute == 37: if datetime.now().second == 0: getUser(msg.sender).playGreat() diff --git a/server.py b/server.py index f77ee91..d3fead1 100644 --- a/server.py +++ b/server.py @@ -37,7 +37,8 @@ class Server: self.send_msg (channel, msg, cmd, endl) - def launch(self, mods): + def launch(self, mods, datas_dir): + self.datas_dir = datas_dir _thread.start_new_thread(self.connect, (mods,)) def accepted_channel(self, channel): @@ -56,10 +57,10 @@ class Server: for line in temp: msg = message.Message (self, line) -# try: - msg.treat (mods) -# except: -# print ("Une erreur est survenue lors du traitement du message : %s"%line) + try: + msg.treat (mods) + except: + print ("Une erreur est survenue lors du traitement du message : %s"%line) def connect(self, mods): diff --git a/soutenance.py b/soutenance.py index 81a3e88..0f9d2ed 100644 --- a/soutenance.py +++ b/soutenance.py @@ -69,7 +69,9 @@ class SiteSoutenances: last.end = None def update(self): - if datetime.now () - self.updated < timedelta(hours=1): + if self.findLast() is not None and datetime.now () - self.updated > timedelta(minutes=2): + return None + elif datetime.now () - self.updated < timedelta(hours=1): return self else: return None @@ -85,7 +87,7 @@ class SiteSoutenances: def findLast(self): close = None for s in self.souts: - if s.state != "En attente" and s.start is not None and (close.start is None or close.start < s.start): + if s.state != "En attente" and s.start is not None and (close is None or close.rank < s.rank or close.hour.day > s.hour.day): close = s return close @@ -100,7 +102,10 @@ class SiteSoutenances: ss = self.findAll(login) close = None for s in ss: - if close is None or close.hour > s.hour: + if close is not None: + print (close.hour) + print (s.hour) + if close is None or (close.hour < s.hour and close.hour.day >= datetime.datetime().day): close = s return close @@ -137,11 +142,17 @@ def parseanswer (msg): 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.hour - soutenance.start) + avre = "%s de *retard*"%msg.just_countdown(soutenance.start - soutenance.hour, 4) else: - avre = "%s d'avance"%msg.just_countdown(soutenance.start - soutenance.hour) - 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), avre)) + 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] @@ -153,11 +164,18 @@ def parseanswer (msg): 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))) + 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: - msg.send_chn ("Soutenance de %s : %s, position %d."%(name, soutenance.hour, soutenance.rank)) + 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) @@ -167,10 +185,10 @@ def parseanswer (msg): first = True for s in souts: if first: - msg.send_snd ("Soutenance(s) de %s : - %s ;"%(name, s.hour)) + msg.send_snd ("Soutenance(s) de %s : - %s (position %d) ;"%(name, s.hour, s.rank)) first = False else: - msg.send_snd (" %s - %s ;"%(len(name)*' ', s.hour)) + msg.send_snd (" %s - %s (position %d) ;"%(len(name)*' ', s.hour, s.rank)) return True return False