Lot of fixes

Use a partner to transform nick to login_x
Add questions support into qd.py
This commit is contained in:
Némunaire 2012-05-14 17:50:11 +02:00
parent 69c5d06ed7
commit 5004752660
10 changed files with 462 additions and 72 deletions

View File

@ -134,7 +134,7 @@ def parseanswer(msg):
def parseask(msg): def parseask(msg):
msgl = msg.content.lower () msgl = msg.content.lower ()
if re.match("^.*(date de naissance|birthday|geburtstag|née?|nee? le|born on).*$", msgl) is not None: if re.match("^.*(date de naissance|birthday|geburtstag|née? |nee? le|born on).*$", msgl) is not None:
try: try:
extDate = msg.extractDate () extDate = msg.extractDate ()
if extDate is None: if extDate is None:

View File

@ -6,6 +6,7 @@ from datetime import timedelta
from datetime import datetime from datetime import datetime
from datetime import date from datetime import date
import time import time
import threading
from xml.dom.minidom import parse from xml.dom.minidom import parse
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
from xml.dom.minidom import getDOMImplementation from xml.dom.minidom import getDOMImplementation
@ -13,6 +14,46 @@ from xml.dom.minidom import getDOMImplementation
filename = "" filename = ""
EVENTS = {} EVENTS = {}
STREND = {} STREND = {}
threadManager = None
newStrendEvt = threading.Event()
class Manager(threading.Thread):
def __init__(self, servers):
self.servers = servers
self.stop = False
threading.Thread.__init__(self)
def run(self):
global STREND
while not self.stop:
newStrendEvt.clear()
closer = None
#Gets the closer event
for evt in STREND.keys():
if ((closer is None or closer.end is None) or (STREND[evt].end is not None and STREND[evt].end < closer.end)) and STREND[evt].end is not None and STREND[evt].end > datetime.now():
closer = STREND[evt]
if closer is not None and closer.end is not None:
#print ("Closer: %s à %s"%(closer.name, closer.end))
timeleft = (closer.end - datetime.now()).seconds
timer = threading.Timer(timeleft, closer.alertEnd, (self.servers,))
timer.start()
#print ("Start timer (%ds)"%timeleft)
newStrendEvt.wait()
if closer is not None and closer.end is not None and closer.end > datetime.now():
timer.cancel()
def launch (servers):
global threadManager
stop()
threadManager = Manager(servers)
threadManager.start()
def stop ():
if threadManager is not None:
threadManager.stop = True
newStrendEvt.set()
class Strend: class Strend:
def __init__(self, item): def __init__(self, item):
@ -20,9 +61,28 @@ class Strend:
self.name = item.getAttribute("name") self.name = item.getAttribute("name")
self.start = datetime.fromtimestamp (time.mktime (time.strptime (item.getAttribute("start")[:19], "%Y-%m-%d %H:%M:%S"))) self.start = datetime.fromtimestamp (time.mktime (time.strptime (item.getAttribute("start")[:19], "%Y-%m-%d %H:%M:%S")))
self.proprio = item.getAttribute("proprio") self.proprio = item.getAttribute("proprio")
self.server = item.getAttribute("server")
self.channel = item.getAttribute("channel")
if item.getAttribute("end") is not None and item.getAttribute("end") != "":
try:
self.end = datetime.fromtimestamp (time.mktime (time.strptime (item.getAttribute("end")[:19], "%Y-%m-%d %H:%M:%S")))
except:
self.end = None
else:
self.end = None
else: else:
self.start = datetime.now() self.start = datetime.now()
self.end = None
def alertEnd(self, SRVS):
for server in SRVS.keys():
if server == self.server:
if self.channel == SRVS[server].nick:
SRVS[server].send_msg_usr(self.proprio, "%s: %s arrivé à échéance."%(self.proprio, self.name))
else:
SRVS[server].send_msg(self.channel, "%s: %s arrivé à échéance."%(self.proprio, self.name))
del STREND[self.name]
newStrendEvt.set()
def xmlparse(node): def xmlparse(node):
"""Parse the given node and add events to the global list.""" """Parse the given node and add events to the global list."""
@ -84,7 +144,10 @@ def save_module():
top = newdoc.documentElement top = newdoc.documentElement
for name in STREND.keys(): for name in STREND.keys():
item = parseString ('<strend name="%s" start="%s" proprio="%s" />' % (name, STREND[name].start, STREND[name].proprio)).documentElement iend = ""
if STREND[name].end is not None:
iend = ' end="%s"'%STREND[name].end
item = parseString ('<strend name="%s" start="%s" proprio="%s" server="%s" channel="%s"%s />' % (name, STREND[name].start, STREND[name].proprio, STREND[name].server, STREND[name].channel, iend)).documentElement
top.appendChild(item); top.appendChild(item);
for name in EVENTS.keys(): for name in EVENTS.keys():
@ -112,7 +175,7 @@ def help_tiny ():
return "events manager" return "events manager"
def help_full (): def help_full ():
return "This module store a lot of events: ny, we, vacs, " + (", ".join(EVENTS.keys())) return "This module store a lot of events: ny, we, vacs, " + (", ".join(EVENTS.keys())) + "\n!eventslist: gets list of timer\n!start /something/: launch a timer"
def parseanswer(msg): def parseanswer(msg):
@ -140,18 +203,38 @@ def parseanswer(msg):
elif msg.cmd[0] == "start" and len(msg.cmd) > 1: elif msg.cmd[0] == "start" and len(msg.cmd) > 1:
if msg.cmd[1] not in STREND: if msg.cmd[1] not in STREND:
STREND[msg.cmd[1]] = Strend(None) STREND[msg.cmd[1]] = Strend(None)
STREND[msg.cmd[1]].server = msg.srv.id
STREND[msg.cmd[1]].channel = msg.channel
STREND[msg.cmd[1]].proprio = msg.sender STREND[msg.cmd[1]].proprio = msg.sender
STREND[msg.cmd[1]].name = msg.cmd[1] STREND[msg.cmd[1]].name = msg.cmd[1]
if len(msg.cmd) > 2:
msg.send_snd ("%s commencé le %s"% (msg.cmd[1], datetime.now())) result = re.match("([0-9]+)([smhdjSMHDJ])?", msg.cmd[2])
if result is not None:
try:
if result.group(2) is not None and (result.group(2) == "m" or result.group(2) == "M"):
STREND[msg.cmd[1]].end = datetime.now() + timedelta(minutes=int(result.group(1)))
elif result.group(2) is not None and (result.group(2) == "h" or result.group(2) == "H"):
STREND[msg.cmd[1]].end = datetime.now() + timedelta(hours=int(result.group(1)))
elif result.group(2) is not None and (result.group(2) == "d" or result.group(2) == "D" or result.group(2) == "j" or result.group(2) == "J"):
STREND[msg.cmd[1]].end = datetime.now() + timedelta(days=int(result.group(1)))
else:
STREND[msg.cmd[1]].end = datetime.now() + timedelta(seconds=int(result.group(1)))
newStrendEvt.set()
msg.send_snd ("%s commencé le %s et se terminera le %s."% (msg.cmd[1], datetime.now(), STREND[msg.cmd[1]].end))
except:
msg.send_snd ("Impossible de définir la fin de %s."% (msg.cmd[1]))
msg.send_snd ("%s commencé le %s."% (msg.cmd[1], datetime.now()))
else:
msg.send_snd ("%s commencé le %s"% (msg.cmd[1], datetime.now()))
else: else:
msg.send_snd ("%s existe déjà."% (msg.cmd[1])) msg.send_snd ("%s existe déjà."% (msg.cmd[1]))
elif msg.cmd[0] == "end" and len(msg.cmd) > 1: elif (msg.cmd[0] == "end" or msg.cmd[0] == "forceend") and len(msg.cmd) > 1:
if msg.cmd[1] in STREND: if msg.cmd[1] in STREND:
msg.send_chn ("%s a duré %s." % (msg.cmd[1], msg.just_countdown(datetime.now () - STREND[msg.cmd[1]].start))) msg.send_chn ("%s a duré %s." % (msg.cmd[1], msg.just_countdown(datetime.now () - STREND[msg.cmd[1]].start)))
if STREND[msg.cmd[1]].proprio == msg.sender: if STREND[msg.cmd[1]].proprio == msg.sender or (msg.cmd[0] == "forceend" and msg.sender == msg.srv.owner):
del STREND[msg.cmd[1]] del STREND[msg.cmd[1]]
newStrendEvt.set()
else: else:
msg.send_snd ("Vous ne pouvez pas terminer le compteur %s, créé par %s."% (msg.cmd[1], STREND[msg.cmd[1]].proprio)) msg.send_snd ("Vous ne pouvez pas terminer le compteur %s, créé par %s."% (msg.cmd[1], STREND[msg.cmd[1]].proprio))
else: else:

View File

@ -95,8 +95,23 @@ class Message:
if line.find(' PRIVMSG ') != -1: #Call a parsing function if line.find(' PRIVMSG ') != -1: #Call a parsing function
complete = line[1:].split(':',1) #Parse the message into useful data complete = line[1:].split(':',1) #Parse the message into useful data
info = complete[0].split(' ') info = complete[0].split(' ')
self.cmd = "PRIVMSG" self.cmd = "PRIVMSG"
if len(complete) < 2 or len (info) < 3:
last = ""
info = list()
for lettre in line:
if len(info) > 2:
complete[1] += lettre
elif lettre == ":" or lettre == " ":
if last != "":
info.append(last)
if len(info) > 2:
complete = list()
complete.append(" ".join(info))
complete.append("")
else:
last += lettre
self.sender = (info[0].split('!'))[0] self.sender = (info[0].split('!'))[0]
self.realname = (info[0].split('!'))[1] self.realname = (info[0].split('!'))[1]
self.channel = info[2] self.channel = info[2]
@ -149,6 +164,19 @@ class Message:
else: else:
self.content = "" self.content = ""
elif line.find(' QUIT ') != -1:
complete = line[1:].split(':',1) #Parse the message into useful data
info = complete[0].split(' ')
self.cmd = "QUIT"
self.sender = (info[0].split('!'))[0]
self.realname = (info[0].split('!'))[1]
self.channel = info[2]
if len (complete) > 1:
self.content = complete[1]
else:
self.content = ""
elif line.find(' MODE ') != -1: elif line.find(' MODE ') != -1:
complete = line[1:].split(' ') complete = line[1:].split(' ')
if len(complete) >= 5: if len(complete) >= 5:
@ -242,6 +270,10 @@ class Message:
now = datetime.now() now = datetime.now()
self.send_chn ("%s: j'envoie ce message à %s:%d:%d."%(self.sender, now.hour, now.minute, now.second)) self.send_chn ("%s: j'envoie ce message à %s:%d:%d."%(self.sender, now.hour, now.minute, now.second))
elif re.match(".*qui est ([a-zA-Z0-9_-]+)", messagel) is not None:
result = re.match(".*qui est ([a-zA-Z0-9_-]+).*", self.content)
self.send_chn ("!whois %s"%(result.group(1)))
elif re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (.+)$", messagel) is not None: 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) 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))) self.send_chn ("%s: %s"%(result.group(2), result.group(5)))
@ -265,10 +297,11 @@ class Message:
#Owner commands #Owner commands
elif self.content[0] == '`' and self.sender == self.srv.owner: elif self.content[0] == '`' and self.sender == self.srv.owner:
self.cmd = self.content[1:].split(' ') self.cmd = self.content[1:].split(' ')
if self.cmd[0] == "reload": if self.cmd[0] == "reload" or self.cmd[0] == "reload_nosave":
if len(self.cmd) > 1: if len(self.cmd) > 1:
if self.cmd[1] in mods: if self.cmd[1] in mods:
mods[self.cmd[1]].save_module () if self.cmd[0] == "reload":
mods[self.cmd[1]].save_module ()
imp.reload(mods[self.cmd[1]]) imp.reload(mods[self.cmd[1]])
mods[self.cmd[1]].load_module (self.srv.datas_dir) mods[self.cmd[1]].load_module (self.srv.datas_dir)
self.send_snd ("Module %s rechargé avec succès."%self.cmd[1]) self.send_snd ("Module %s rechargé avec succès."%self.cmd[1])
@ -312,8 +345,12 @@ class Message:
self.send_snd(" - !help %s: %s" % (im, mods[im].help_tiny ())) self.send_snd(" - !help %s: %s" % (im, mods[im].help_tiny ()))
for im in mods.keys(): for im in mods.keys():
if im == "alias":
continue
if mods[im].parseanswer(self): if mods[im].parseanswer(self):
return return
if mods["alias"].parseanswer(self):
return
else: else:
for im in mods.keys(): for im in mods.keys():

View File

@ -11,7 +11,7 @@ from datetime import timedelta
from xml.dom.minidom import parse from xml.dom.minidom import parse
imports = ["birthday", "qd", "events", "youtube", "watchWebsite", "soutenance", "whereis", "alias"] imports = ["birthday", "qd", "events", "youtube", "watchWebsite", "soutenance", "whereis", "alias"]
imports_launch = ["watchWebsite"] imports_launch = ["watchWebsite", "events"]
mods = {} mods = {}
import server, message import server, message
@ -26,6 +26,9 @@ def onSignal(signum, frame):
for imp in mods.keys(): for imp in mods.keys():
mods[imp].save_module () mods[imp].save_module ()
for imp in imports_launch:
mods[imp].stop ()
#Save banlist before quit #Save banlist before quit
message.save_module () message.save_module ()
@ -39,7 +42,7 @@ else:
dom = parse(sys.argv[1]) dom = parse(sys.argv[1])
config = dom.getElementsByTagName('config')[0] config = dom.getElementsByTagName('config')[0]
servers = list () servers = dict ()
message.load_module (basedir + "/datas/") message.load_module (basedir + "/datas/")
@ -51,7 +54,7 @@ for imp in imports:
for serveur in config.getElementsByTagName('server'): for serveur in config.getElementsByTagName('server'):
srv = server.Server(serveur, config.getAttribute('nick'), config.getAttribute('owner'), config.getAttribute('realname')) srv = server.Server(serveur, config.getAttribute('nick'), config.getAttribute('owner'), config.getAttribute('realname'))
srv.launch(mods, basedir + "/datas/") srv.launch(mods, basedir + "/datas/")
servers.append (srv) servers[srv.id] = srv
for imp in imports_launch: for imp in imports_launch:
mod = __import__ (imp) mod = __import__ (imp)

View File

@ -176,7 +176,11 @@ class Server:
readbuffer = temp.pop( ) readbuffer = temp.pop( )
for line in temp: for line in temp:
msg = message.Message(self, line) try:
msg = message.Message(self, line)
except:
continue
if msg.cmd == "PING": if msg.cmd == "PING":
self.s.send(("PONG %s\r\n" % msg.content).encode ()) self.s.send(("PONG %s\r\n" % msg.content).encode ())
elif msg.cmd == "PRIVMSG" and (self.authorize(msg) or msg.content[0] == '`'): elif msg.cmd == "PRIVMSG" and (self.authorize(msg) or msg.content[0] == '`'):
@ -227,14 +231,16 @@ for server in config.getElementsByTagName('server'):
srv.launch() srv.launch()
def sighup_h(signum, frame): def sighup_h(signum, frame):
print ("Signal reçu...") global talkEC, stopSpk
sys.stdout.write ("Signal reçu ... ")
if os.path.exists("/tmp/isPresent"): if os.path.exists("/tmp/isPresent"):
thread.start_new_thread(speak, (0,)) _thread.start_new_thread(speak, (0,))
print ("Morning!")
else: else:
print ("Sleeping!")
if talkEC == 0: if talkEC == 0:
talkEC = 1 talkEC = 1
stopSpk = 1 stopSpk = 1
signal.signal(signal.SIGHUP, sighup_h) signal.signal(signal.SIGHUP, sighup_h)
print ("Nemuspeak ready, waiting for new messages...") print ("Nemuspeak ready, waiting for new messages...")

112
qd.py
View File

@ -2,7 +2,9 @@
import re import re
import time import time
import random
import sys import sys
import threading
from datetime import timedelta from datetime import timedelta
from datetime import datetime from datetime import datetime
from datetime import date from datetime import date
@ -13,6 +15,7 @@ from xml.dom.minidom import getDOMImplementation
filename = "" filename = ""
channels = "#nemutest #42sh #epitagueule" channels = "#nemutest #42sh #epitagueule"
MANCHE = None MANCHE = None
QUESTIONS = list()
SCORES = dict () SCORES = dict ()
temps = dict () temps = dict ()
@ -70,10 +73,14 @@ class Score:
def playTwt(self): def playTwt(self):
if self.canPlay(): if self.canPlay():
self.twt += 1 self.twt += 1
def playSuite(self):
self.canPlay()
self.twt += 1
self.great += 1
def playPi(self): def playPi(self):
if self.canPlay(): if self.canPlay():
self.pi += 1 self.pi += 1
def playNoutfound(self): def playNotfound(self):
if self.canPlay(): if self.canPlay():
self.notfound += 1 self.notfound += 1
def playTen(self): def playTen(self):
@ -88,6 +95,10 @@ class Score:
def playBad(self): def playBad(self):
if self.canPlay(): if self.canPlay():
self.bad += 1 self.bad += 1
def playTriche(self):
self.bad += 5
def oupsTriche(self):
self.bad -= 5
def toTuple(self): def toTuple(self):
return (self.ftt, self.twt, self.pi, self.notfound, self.tententen, self.leet, self.great, self.bad) return (self.ftt, self.twt, self.pi, self.notfound, self.tententen, self.leet, self.great, self.bad)
@ -118,6 +129,9 @@ def xmlparse(node):
SCORES[item.getAttribute("name")] = Score () SCORES[item.getAttribute("name")] = Score ()
SCORES[item.getAttribute("name")].parse(item) SCORES[item.getAttribute("name")].parse(item)
for item in node.getElementsByTagName("question"):
QUESTIONS.append((item.getAttribute("question"),item.getAttribute("regexp"),item.getAttribute("great")))
manche = node.getElementsByTagName("manche")[0] manche = node.getElementsByTagName("manche")[0]
MANCHE = (int(manche.getAttribute("number")), MANCHE = (int(manche.getAttribute("number")),
manche.getAttribute("winner"), manche.getAttribute("winner"),
@ -136,7 +150,7 @@ def load_module(datas_path):
sys.stdout.write ("Loading 42scores ... ") sys.stdout.write ("Loading 42scores ... ")
dom = parse(filename) dom = parse(filename)
xmlparse (dom.documentElement) xmlparse (dom.documentElement)
print ("done (%d loaded, currently in round %d)" % (len(SCORES), -42)) print ("done (%d loaded, %d questions, currently in round %d)" % (len(SCORES), len(QUESTIONS), -42))
def save_module(): def save_module():
"""Save the scores""" """Save the scores"""
@ -154,6 +168,9 @@ def save_module():
top.appendChild(parseString ('<manche number="%d" winner="%s" winner_score="%d" who="%s" date="%s" />' % MANCHE).documentElement) top.appendChild(parseString ('<manche number="%d" winner="%s" winner_score="%d" who="%s" date="%s" />' % MANCHE).documentElement)
for q in QUESTIONS:
top.appendChild(parseString ('<question question="%s" regexp="%s" great="%s" />' % q).documentElement)
with open(filename, "w") as f: with open(filename, "w") as f:
newdoc.writexml (f) newdoc.writexml (f)
print ("done") print ("done")
@ -174,11 +191,14 @@ def rev (tupl):
def parseanswer (msg): def parseanswer (msg):
if msg.cmd[0] == "42" or msg.cmd[0] == "score" or msg.cmd[0] == "scores": if msg.cmd[0] == "42" or msg.cmd[0] == "score" or msg.cmd[0] == "scores":
global SCORES, MANCHE global SCORES, MANCHE
if len(msg.cmd) > 3 and msg.is_owner and (msg.cmd[1] == "merge"): if len(msg.cmd) > 2 and msg.is_owner and ((msg.cmd[1] == "merge" and len(msg.cmd) > 3) or msg.cmd[1] == "oupstriche"):
if msg.cmd[2] in SCORES and msg.cmd[3] in SCORES: if msg.cmd[2] in SCORES and (len(msg.cmd) <= 3 or msg.cmd[3] in SCORES):
SCORES[msg.cmd[2]].merge (SCORES[msg.cmd[3]]) if msg.cmd[1] == "merge":
del SCORES[msg.cmd[3]] SCORES[msg.cmd[2]].merge (SCORES[msg.cmd[3]])
msg.send_chn ("%s a été correctement fusionné avec %s."%(msg.cmd[3], msg.cmd[2])) del SCORES[msg.cmd[3]]
msg.send_chn ("%s a été correctement fusionné avec %s."%(msg.cmd[3], msg.cmd[2]))
elif msg.cmd[1] == "oupstriche":
SCORES[msg.cmd[2]].oupsTriche()
else: else:
if msg.cmd[2] not in SCORES: if msg.cmd[2] not in SCORES:
msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[2]) msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[2])
@ -202,9 +222,9 @@ def parseanswer (msg):
score = scr.score() score = scr.score()
if score != 0: if score != 0:
if phrase == "": if phrase == "":
phrase = " *%s: %d*,"%(nom, score) phrase = " *%s.%s: %d*,"%(nom[0:1], nom[1:len(nom)], score)
else: else:
phrase += " %s: %d,"%(nom, score) phrase += " %s.%s: %d,"%(nom[0:1], nom[1:len(nom)], score)
msg.send_chn ("Scores :%s" % (phrase[0:len(phrase)-1])) msg.send_chn ("Scores :%s" % (phrase[0:len(phrase)-1]))
return True return True
@ -231,6 +251,7 @@ def win(msg):
SCORES = dict() SCORES = dict()
# SCORES[maxi_name] = (-10, 0, -4, 0, 0, -2, 0) # SCORES[maxi_name] = (-10, 0, -4, 0, 0, -2, 0)
# SCORES[maxi_name] = (0, 0, 0, 0, 0, 0, 0) # SCORES[maxi_name] = (0, 0, 0, 0, 0, 0, 0)
SCORES[who] = Score()
SCORES[who].newWinner() SCORES[who].newWinner()
if who != maxi_name: if who != maxi_name:
@ -245,6 +266,11 @@ def win(msg):
def parseask (msg): def parseask (msg):
if len(DELAYED) > 0:
if msg.sender in DELAYED:
DELAYED[msg.sender].msg = msg.content[9:]
DELAYED[msg.sender].delayEvnt.set()
return True
return False return False
@ -256,8 +282,12 @@ def getUser(name):
def parselisten (msg): def parselisten (msg):
# if msg.channel == "#nemutest": # if msg.channel == "#nemutest" and msg.sender not in DELAYED:
if msg.channel != "#nemutest": if msg.channel != "#nemutest" and msg.sender not in DELAYED:
if len(DELAYED) > 0:
if msg.sender in DELAYED and not DELAYED[msg.sender].triche(msg.content):
msg.send_chn("%s: n'oublie pas le nemubot: devant ta réponse pour qu'elle soit prise en compte !" % msg.sender)
if (msg.content.strip().startswith("42") and len (msg.content) < 5) or ((msg.content.strip().lower().startswith("quarante-deux") or msg.content.strip().lower().startswith("quarante deux")) and len (msg.content) < 17): if (msg.content.strip().startswith("42") and len (msg.content) < 5) or ((msg.content.strip().lower().startswith("quarante-deux") or msg.content.strip().lower().startswith("quarante deux")) and len (msg.content) < 17):
if msg.time.minute == 10 and msg.time.second == 10 and msg.time.hour == 10: if msg.time.minute == 10 and msg.time.second == 10 and msg.time.hour == 10:
getUser(msg.sender).playTen() getUser(msg.sender).playTen()
@ -286,9 +316,8 @@ def parselisten (msg):
getUser(msg.sender).playBad() getUser(msg.sender).playBad()
if (msg.content.strip().startswith("12345") and len (msg.content) < 8) or (msg.content.strip().startswith("012345") and len (msg.content) < 9): if (msg.content.strip().startswith("12345") and len (msg.content) < 8) or (msg.content.strip().startswith("012345") and len (msg.content) < 9):
if msg.time.hour == 1 and msg.time.minute == 23 and msg.time.second == 45: if msg.time.hour == 1 and msg.time.minute == 23 and (msg.time.second == 45 or (msg.time.second == 46 and msg.time.microsecond < 330000)):
getUser(msg.sender).playGreat() getUser(msg.sender).playSuite()
getUser(msg.sender).playTwt()
else: else:
getUser(msg.sender).playBad() getUser(msg.sender).playBad()
@ -319,6 +348,59 @@ def parselisten (msg):
if getUser(msg.sender).isWinner(): if getUser(msg.sender).isWinner():
print ("Nous avons un vainqueur ! Nouvelle manche :p") print ("Nous avons un vainqueur ! Nouvelle manche :p")
win(msg) win(msg)
return True
elif getUser(msg.sender).hasChanged(): elif getUser(msg.sender).hasChanged():
save_module () gu = GameUpdater(msg)
gu.start()
return True
return False return False
DELAYED = dict()
class DelayedTuple:
def __init__(self, regexp):
self.delayEvnt = threading.Event()
self.msg = None
self.regexp = regexp
def triche(self, res):
if res is not None:
return re.match(".*" + self.regexp + ".*", res.lower() + " ") is None
else:
return True
#<question question="Quel avion commercial est l'un des seuls a avoir volé à Mach 2 ?" regexp="(tu.[0-9]{3}|concorde|boeing|airbus)"/>
#<question question="Quelle célébre barre est produite par Mars Incorporated ?" regexp="(mars|kite?kat|balisto|bounty|milky way|snickers|twix|skittles|freedent)"/>
#<question question="Quel fleuve traverse Paris ?" regexp="(seine|fion|loire|garonn?e|rhin)"/>
#<question question="Du roman et du gothique, lequel de ces arts est le plus récent ?" regexp="(roman|gothique)"/>
#<question question="Quel célébre roi des éléphants, créé par Jean de Brunhoff, a épousé Céleste ?" regexp="babar"/>
#<question question=" ?" regexp=""/>
def wait(self, timeout):
self.delayEvnt.wait(timeout)
class GameUpdater(threading.Thread):
def __init__(self, msg):
self.msg = msg
threading.Thread.__init__(self)
def run(self):
global DELAYED, QUESTIONS
quest = random.randint(0, len(QUESTIONS) * 2)
if self.msg.channel == "#nemutest":
quest = 9
if quest < len(QUESTIONS):
(question, regexp, great) = QUESTIONS[quest]
self.msg.send_chn("%s: %s" % (self.msg.sender, question))
DELAYED[self.msg.sender] = DelayedTuple(regexp)
DELAYED[self.msg.sender].wait(20)
if DELAYED[self.msg.sender].triche(DELAYED[self.msg.sender].msg):
getUser(self.msg.sender).playTriche()
self.msg.send_chn("%s: Tricheur !" % self.msg.sender)
del DELAYED[self.msg.sender]
save_module ()

View File

@ -6,6 +6,11 @@ import time
import message import message
#class WaitedAnswer:
# def __init__(self, channel):
# self.channel = channel
# self.module
class Server: class Server:
def __init__(self, server, nick, owner, realname): def __init__(self, server, nick, owner, realname):
self.nick = nick self.nick = nick
@ -25,18 +30,28 @@ class Server:
else: else:
self.password = None self.password = None
self.waited_answer = list()
self.listen_nick = True self.listen_nick = True
self.partner = "nbr23"
self.channels = list() self.channels = list()
for channel in server.getElementsByTagName('channel'): for channel in server.getElementsByTagName('channel'):
self.channels.append(channel.getAttribute("name")) self.channels.append(channel.getAttribute("name"))
@property
def id(self):
return self.host + ":" + str(self.port)
def send_msg_final(self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"): def send_msg_final(self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"):
if msg is not None and channel is not None: if msg is not None and channel is not None:
for line in msg.split("\n"): for line in msg.split("\n"):
if line != "": if line != "":
self.s.send (("%s %s :%s%s" % (cmd, channel, line, endl)).encode ()) self.s.send (("%s %s :%s%s" % (cmd, channel, line, endl)).encode ())
def send_msg_prtn (self, msg):
self.send_msg_final(self.partner, msg)
def send_msg_usr (self, user, msg): def send_msg_usr (self, user, msg):
if user is not None and user[0] != "#": if user is not None and user[0] != "#":
self.send_msg_final(user, msg) self.send_msg_final(user, msg)
@ -50,6 +65,9 @@ class Server:
self.send_msg (channel, msg, cmd, endl) self.send_msg (channel, msg, cmd, endl)
def register_answer(self, channel, ):
self.waited_answer.append(channel)
def launch(self, mods, datas_dir): def launch(self, mods, datas_dir):
self.datas_dir = datas_dir self.datas_dir = datas_dir
_thread.start_new_thread(self.connect, (mods,)) _thread.start_new_thread(self.connect, (mods,))

View File

@ -4,6 +4,7 @@ import http.client
import time import time
import re import re
import _thread import _thread
import threading
from datetime import date from datetime import date
from datetime import datetime from datetime import datetime
from datetime import timedelta from datetime import timedelta
@ -28,6 +29,18 @@ class Soutenance:
self.start = None self.start = None
self.end = None self.end = None
DELAYED = dict()
class Delayed:
def __init__(self, name):
self.name = name
self.res = None
self.evt = threading.Event()
def wait(self, timeout):
self.evt.clear()
self.evt.wait(timeout)
class SiteSoutenances: class SiteSoutenances:
def __init__(self, page): def __init__(self, page):
save = False save = False
@ -170,6 +183,15 @@ def startSoutenance (msg):
if msg.cmd[0] == "soutenance": if msg.cmd[0] == "soutenance":
soutenance = datas.findClose(name) soutenance = datas.findClose(name)
if soutenance is None:
global DELAYED
DELAYED[msg] = Delayed(name)
msg.srv.send_msg_prtn ("~whois %s" % name)
DELAYED[msg].wait(5)
if DELAYED[msg].res is not None:
name = DELAYED[msg].res
soutenance = datas.findClose(name)
if soutenance is None: if soutenance is None:
msg.send_chn ("Pas d'horaire de soutenance pour %s."%name) msg.send_chn ("Pas d'horaire de soutenance pour %s."%name)
else: else:
@ -207,6 +229,18 @@ def startSoutenance (msg):
def parseask (msg): def parseask (msg):
if len(DELAYED) > 0 and msg.sender == msg.srv.partner:
treat = False
for part in msg.content.split(';'):
if part is None:
continue
for d in DELAYED.keys():
if DELAYED[d].res is None and part.find(DELAYED[d].name) >= 0:
result = re.match(".* est (.*[^.])\.?", part)
if result is not None:
DELAYED[d].res = result.group(1)
DELAYED[d].evt.set()
return treat
return False return False
def parselisten (msg): def parselisten (msg):

View File

@ -4,8 +4,8 @@ import http.client
import hashlib import hashlib
import sys import sys
import traceback import traceback
import socket
import time import time
import pickle
import base64 import base64
import _thread import _thread
from urllib.parse import unquote from urllib.parse import unquote
@ -36,13 +36,7 @@ class Site:
else: else:
self.updateTime = 60 self.updateTime = 60
self.lastChange = 0 self.lastChange = 0
if len(item.childNodes) > 0 and item.childNodes[0].nodeValue is not None: self.lastpage = None
self.lastpage = pickle.loads(base64.b64decode(item.childNodes[0].nodeValue.encode()))
elif item.nodeValue is not None:
self.lastpage = pickle.loads(base64.b64decode(item.nodeValue.encode()))
else:
self.lastpage = None
print (self.server, self.lastpage)
self.run = True self.run = True
@ -57,12 +51,12 @@ class Site:
def send_message (self, msg): def send_message (self, msg):
global SRVS global SRVS
if len(self.channels) > 0: if len(self.channels) > 0:
for server in SRVS: for server in SRVS.keys():
for chan in self.channels: for chan in self.channels:
server.send_msg (chan, msg) SRVS[server].send_msg (chan, msg)
else: else:
for server in SRVS: for server in SRVS.keys():
server.send_global (msg) SRVS[server].send_global (msg)
def treat_atom (self, content): def treat_atom (self, content):
change=False change=False
@ -103,6 +97,8 @@ class Site:
try: try:
# print ("Check %s/%s"%(self.server, self.page)) # print ("Check %s/%s"%(self.server, self.page))
content = getPage(self.server, self.page) content = getPage(self.server, self.page)
if content is None:
return
if self.type == "atom": if self.type == "atom":
(self.lastpage, change) = self.treat_atom (content) (self.lastpage, change) = self.treat_atom (content)
@ -161,6 +157,8 @@ def launch (servers):
SRVS = servers SRVS = servers
for site in SITES: for site in SITES:
site.start () site.start ()
def stop():
return
def save_module(): def save_module():
"""Save the module state""" """Save the module state"""
@ -175,8 +173,6 @@ def save_module():
if len(site.channels) > 0: if len(site.channels) > 0:
for chan in site.channels: for chan in site.channels:
item.appendChild(parseString ('<channel name="%s" />' % (chan)).documentElement); item.appendChild(parseString ('<channel name="%s" />' % (chan)).documentElement);
b64 = base64.b64encode(pickle.dumps(site.lastpage)).decode()
item.appendChild(newdoc.createTextNode(b64));
#print (site.server) #print (site.server)
top.appendChild(item); top.appendChild(item);
@ -207,7 +203,11 @@ def parselisten (msg):
def getPage (s, p): def getPage (s, p):
conn = http.client.HTTPConnection(s) conn = http.client.HTTPConnection(s)
conn.request("GET", "/%s"%(p)) try:
conn.request("GET", "/%s"%(p))
except socket.gaierror:
print ("[%s] impossible de récupérer la page %s."%(s, p))
return None
res = conn.getresponse() res = conn.getresponse()
data = res.read() data = res.read()

View File

@ -5,6 +5,7 @@ import sys
import socket import socket
import time import time
import _thread import _thread
import threading
from datetime import datetime from datetime import datetime
from datetime import date from datetime import date
from datetime import timedelta from datetime import timedelta
@ -26,7 +27,9 @@ class UpdatedStorage:
if sock != None: if sock != None:
for l in list_users(sock): for l in list_users(sock):
u = User(l) u = User(l)
self.users[u.login] = u if u.login not in self.users:
self.users[u.login] = list()
self.users[u.login].append(u)
sock.close() sock.close()
self.lastUpdate = datetime.now () self.lastUpdate = datetime.now ()
@ -48,17 +51,23 @@ class User(object):
@property @property
def sm(self): def sm(self):
if self.ip.startswith('10.200'): if self.ip.startswith('10.200'):
return 'en SM' + self.ip.split('.')[2] ip = self.ip.split('.')
if 20 < int(ip[2]) < 30:
return 'SM02'
else:
return 'SM' + self.ip.split('.')[2]
elif self.ip.startswith('10.242'):
return 'bocal'
elif self.ip.startswith('10.247'): elif self.ip.startswith('10.247'):
return 'en pasteur' return 'pasteur'
elif self.ip.startswith('10.248'): elif self.ip.startswith('10.248'):
return 'en srlab' return 'srlab'
elif self.ip.startswith('10.249'): elif self.ip.startswith('10.249'):
return 'en midlab' return 'midlab'
elif self.ip.startswith('10.250'): elif self.ip.startswith('10.250'):
return 'en cisco' return 'cisco'
elif self.ip.startswith('10.41'): elif self.ip.startswith('10.41.'):
return 'sur le wifi' return 'wifi'
else: else:
return None return None
@ -71,9 +80,13 @@ class User(object):
return "chez lui" return "chez lui"
else: else:
if self.ip.startswith('10.200'): if self.ip.startswith('10.200'):
return self.sm + " poste " + self.ip.split('.')[3] sm = self.sm
if sm == "SM02":
return "en " + sm
else:
return "en " + sm + " poste " + self.ip.split('.')[3]
else: else:
return self.sm + " rangée " + self.ip.split('.')[2] + " poste " + self.ip.split('.')[3] return "en " + self.sm + " rangée " + self.ip.split('.')[2] + " poste " + self.ip.split('.')[3]
def __cmp__(self, other): def __cmp__(self, other):
return cmp(self.login, other.login) return cmp(self.login, other.login)
@ -88,7 +101,7 @@ def connect_to_ns(server, port):
s.connect((server, port)) s.connect((server, port))
except socket.error: except socket.error:
return None return None
s.recv(8192) # salut ... s.recv(8192)
return s return s
def list_users(sock): def list_users(sock):
@ -108,10 +121,9 @@ def load_module(datas_path):
def save_module(): def save_module():
"""Save the module state""" """Save the module state"""
if THREAD is not None:
THREAD.exit()
return return
def help_tiny (): def help_tiny ():
"""Line inserted in the response to the command !help""" """Line inserted in the response to the command !help"""
return "Find a user on the PIE" return "Find a user on the PIE"
@ -131,36 +143,138 @@ def startWhereis(msg):
msg.send_chn("Hmm c'est embarassant, serait-ce la fin du monde ou juste netsoul qui est mort ?") msg.send_chn("Hmm c'est embarassant, serait-ce la fin du monde ou juste netsoul qui est mort ?")
return return
pasla = list() if msg.cmd[0] == "peoplein":
peoplein(msg)
elif msg.cmd[0] == "whoison":
whoison(msg)
else:
whereis_msg(msg)
THREAD = None
if len(search) > 0:
startWhereis(search.pop())
def peoplein(msg):
if len(msg.cmd) > 1:
for sm in msg.cmd:
sm = sm.lower()
if sm == "peoplein":
continue
else:
count = 0
for userC in datas.users:
for user in datas.users[userC]:
usersm = user.sm
if usersm is not None and usersm.lower() == sm:
count += 1
if count > 1:
sOrNot = "s"
else:
sOrNot = ""
msg.send_chn ("Il y a %d personne%s en %s." % (count, sOrNot, sm))
def whoison(msg):
if len(msg.cmd) > 1:
for pb in msg.cmd:
pc = pb.lower()
if pc == "whoison":
continue
else:
found = list()
print (len(datas.users))
for userC in datas.users:
for user in datas.users[userC]:
if user.ip[:len(pc)] == pc or user.location.lower() == pc:
found.append(user.login)
if len(found) > 0:
if len(found) <= 15:
msg.send_chn ("%s correspond à %s" % (pb, ", ".join(found)))
else:
msg.send_chn ("%s: %d personnes" % (pb, len(found)))
else:
msg.send_chn ("%s: personne ne match ta demande :(" % (msg.sender))
DELAYED = dict()
delayEvnt = threading.Event()
class Delayed:
def __init__(self):
self.names = dict()
def whereis_msg(msg):
names = list()
for name in msg.cmd: for name in msg.cmd:
if name == "whereis" or name == "whereare" or name == "ouest" or name == "ousont" or name == "ip": if name == "whereis" or name == "whereare" or name == "ouest" or name == "ousont" or name == "ip":
if len(msg.cmd) >= 2: if len(msg.cmd) >= 2:
continue continue
else: else:
name = msg.sender name = msg.sender
else:
names.append(name)
pasla = whereis(msg, names)
if len(pasla) > 0:
global DELAYED
DELAYED[msg] = Delayed()
for name in pasla:
DELAYED[msg].names[name] = None
#msg.srv.send_msg_prtn ("~whois %s" % name)
msg.srv.send_msg_prtn ("~whois %s" % " ".join(pasla))
startTime = datetime.now()
names = list()
while len(DELAYED[msg].names) > 0 and startTime + timedelta(seconds=4) > datetime.now():
delayEvnt.clear()
delayEvnt.wait(2)
rem = list()
for name in DELAYED[msg].names.keys():
if DELAYED[msg].names[name] is not None:
pasla = whereis(msg, (DELAYED[msg].names[name],))
if len(pasla) != 0:
names.append(pasla[0])
rem.append(name)
for r in rem:
del DELAYED[msg].names[r]
for name in DELAYED[msg].names.keys():
if DELAYED[msg].names[name] is None:
names.append(name)
else:
names.append(DELAYED[msg].names[name])
if len(names) > 1:
msg.send_chn ("%s ne sont pas connectés sur le PIE." % (", ".join(names)))
else:
for name in names:
msg.send_chn ("%s n'est pas connecté sur le PIE." % name)
def whereis(msg, names):
pasla = list()
for name in names:
if name in datas.users: if name in datas.users:
if msg.cmd[0] == "ip": if msg.cmd[0] == "ip":
msg.send_chn ("L'ip de %s est %s." %(name, datas.users[name].ip)) if len(datas.users[name]) == 1:
msg.send_chn ("L'ip de %s est %s." %(name, datas.users[name][0].ip))
else:
out = ""
for local in datas.users[name]:
out += ", " + local.ip
msg.send_chn ("%s est connecté à plusieurs endroits : %s." %(name, out[2:]))
else: else:
msg.send_chn ("%s est %s (%s)." %(name, datas.users[name].poste, unquote(datas.users[name].location))) if len(datas.users[name]) == 1:
msg.send_chn ("%s est %s (%s)." %(name, datas.users[name][0].poste, unquote(datas.users[name][0].location)))
else:
out = ""
for local in datas.users[name]:
out += ", " + local.poste + " (" + unquote(local.location) + ")"
msg.send_chn ("%s est %s." %(name, out[2:]))
else: else:
pasla.append(name) pasla.append(name)
if len(pasla) == 1: return pasla
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): def parseanswer (msg):
global datas, THREAD, search 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 msg.cmd[0] == "whereis" or msg.cmd[0] == "whereare" or msg.cmd[0] == "ouest" or msg.cmd[0] == "ousont" or msg.cmd[0] == "ip" or msg.cmd[0] == "peoplein" or msg.cmd[0] == "whoison":
if len(msg.cmd) > 10: if len(msg.cmd) > 10:
msg.send_snd ("Demande moi moins de personnes à la fois dans ton !%s" % msg.cmd[0]) msg.send_snd ("Demande moi moins de personnes à la fois dans ton !%s" % msg.cmd[0])
return True return True
@ -173,6 +287,19 @@ def parseanswer (msg):
return False return False
def parseask (msg): def parseask (msg):
if len(DELAYED) > 0 and msg.sender == msg.srv.partner:
treat = False
for part in msg.content.split(';'):
if part is None:
continue
for d in DELAYED.keys():
for n in DELAYED[d].names.keys():
if DELAYED[d].names[n] is None and part.find(n) >= 0:
result = re.match(".* est (.*[^.])\.?", part)
if result is not None:
DELAYED[d].names[n] = result.group(1)
delayEvnt.set()
return treat
return False return False
def parselisten (msg): def parselisten (msg):