diff --git a/birthday.py b/birthday.py
index 1a2d79d..22462d9 100644
--- a/birthday.py
+++ b/birthday.py
@@ -134,7 +134,7 @@ 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:
+ if re.match("^.*(date de naissance|birthday|geburtstag|née? |nee? le|born on).*$", msgl) is not None:
try:
extDate = msg.extractDate ()
if extDate is None:
diff --git a/events.py b/events.py
index 7ae76b7..2219cf2 100644
--- a/events.py
+++ b/events.py
@@ -6,6 +6,7 @@ from datetime import timedelta
from datetime import datetime
from datetime import date
import time
+import threading
from xml.dom.minidom import parse
from xml.dom.minidom import parseString
from xml.dom.minidom import getDOMImplementation
@@ -13,6 +14,46 @@ from xml.dom.minidom import getDOMImplementation
filename = ""
EVENTS = {}
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:
def __init__(self, item):
@@ -20,9 +61,28 @@ class Strend:
self.name = item.getAttribute("name")
self.start = datetime.fromtimestamp (time.mktime (time.strptime (item.getAttribute("start")[:19], "%Y-%m-%d %H:%M:%S")))
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:
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):
"""Parse the given node and add events to the global list."""
@@ -84,7 +144,10 @@ def save_module():
top = newdoc.documentElement
for name in STREND.keys():
- item = parseString ('' % (name, STREND[name].start, STREND[name].proprio)).documentElement
+ iend = ""
+ if STREND[name].end is not None:
+ iend = ' end="%s"'%STREND[name].end
+ item = parseString ('' % (name, STREND[name].start, STREND[name].proprio, STREND[name].server, STREND[name].channel, iend)).documentElement
top.appendChild(item);
for name in EVENTS.keys():
@@ -112,7 +175,7 @@ def help_tiny ():
return "events manager"
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):
@@ -140,18 +203,38 @@ def parseanswer(msg):
elif msg.cmd[0] == "start" and len(msg.cmd) > 1:
if msg.cmd[1] not in STREND:
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]].name = msg.cmd[1]
-
- msg.send_snd ("%s commencé le %s"% (msg.cmd[1], datetime.now()))
+ if len(msg.cmd) > 2:
+ 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:
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:
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]]
+ newStrendEvt.set()
else:
msg.send_snd ("Vous ne pouvez pas terminer le compteur %s, créé par %s."% (msg.cmd[1], STREND[msg.cmd[1]].proprio))
else:
diff --git a/message.py b/message.py
index e1d3a1f..4b9f209 100644
--- a/message.py
+++ b/message.py
@@ -95,8 +95,23 @@ class Message:
if line.find(' PRIVMSG ') != -1: #Call a parsing function
complete = line[1:].split(':',1) #Parse the message into useful data
info = complete[0].split(' ')
-
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.realname = (info[0].split('!'))[1]
self.channel = info[2]
@@ -149,6 +164,19 @@ class Message:
else:
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:
complete = line[1:].split(' ')
if len(complete) >= 5:
@@ -242,6 +270,10 @@ class Message:
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(".*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:
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)))
@@ -265,10 +297,11 @@ class Message:
#Owner commands
elif self.content[0] == '`' and self.sender == self.srv.owner:
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 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]])
mods[self.cmd[1]].load_module (self.srv.datas_dir)
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 ()))
for im in mods.keys():
+ if im == "alias":
+ continue
if mods[im].parseanswer(self):
return
+ if mods["alias"].parseanswer(self):
+ return
else:
for im in mods.keys():
diff --git a/nemubot.py b/nemubot.py
index 346aa26..fb7d8bf 100755
--- a/nemubot.py
+++ b/nemubot.py
@@ -11,7 +11,7 @@ from datetime import timedelta
from xml.dom.minidom import parse
imports = ["birthday", "qd", "events", "youtube", "watchWebsite", "soutenance", "whereis", "alias"]
-imports_launch = ["watchWebsite"]
+imports_launch = ["watchWebsite", "events"]
mods = {}
import server, message
@@ -26,6 +26,9 @@ def onSignal(signum, frame):
for imp in mods.keys():
mods[imp].save_module ()
+ for imp in imports_launch:
+ mods[imp].stop ()
+
#Save banlist before quit
message.save_module ()
@@ -39,7 +42,7 @@ else:
dom = parse(sys.argv[1])
config = dom.getElementsByTagName('config')[0]
-servers = list ()
+servers = dict ()
message.load_module (basedir + "/datas/")
@@ -51,7 +54,7 @@ for imp in imports:
for serveur in config.getElementsByTagName('server'):
srv = server.Server(serveur, config.getAttribute('nick'), config.getAttribute('owner'), config.getAttribute('realname'))
srv.launch(mods, basedir + "/datas/")
- servers.append (srv)
+ servers[srv.id] = srv
for imp in imports_launch:
mod = __import__ (imp)
diff --git a/nemuspeak.py b/nemuspeak.py
index 1fb1f4f..dd0083f 100755
--- a/nemuspeak.py
+++ b/nemuspeak.py
@@ -176,7 +176,11 @@ class Server:
readbuffer = temp.pop( )
for line in temp:
- msg = message.Message(self, line)
+ try:
+ msg = message.Message(self, line)
+ except:
+ continue
+
if msg.cmd == "PING":
self.s.send(("PONG %s\r\n" % msg.content).encode ())
elif msg.cmd == "PRIVMSG" and (self.authorize(msg) or msg.content[0] == '`'):
@@ -227,14 +231,16 @@ for server in config.getElementsByTagName('server'):
srv.launch()
def sighup_h(signum, frame):
- print ("Signal reçu...")
+ global talkEC, stopSpk
+ sys.stdout.write ("Signal reçu ... ")
if os.path.exists("/tmp/isPresent"):
- thread.start_new_thread(speak, (0,))
+ _thread.start_new_thread(speak, (0,))
+ print ("Morning!")
else:
+ print ("Sleeping!")
if talkEC == 0:
talkEC = 1
stopSpk = 1
-
signal.signal(signal.SIGHUP, sighup_h)
print ("Nemuspeak ready, waiting for new messages...")
diff --git a/qd.py b/qd.py
index 7a9602b..412111d 100644
--- a/qd.py
+++ b/qd.py
@@ -2,7 +2,9 @@
import re
import time
+import random
import sys
+import threading
from datetime import timedelta
from datetime import datetime
from datetime import date
@@ -13,6 +15,7 @@ from xml.dom.minidom import getDOMImplementation
filename = ""
channels = "#nemutest #42sh #epitagueule"
MANCHE = None
+QUESTIONS = list()
SCORES = dict ()
temps = dict ()
@@ -70,10 +73,14 @@ class Score:
def playTwt(self):
if self.canPlay():
self.twt += 1
+ def playSuite(self):
+ self.canPlay()
+ self.twt += 1
+ self.great += 1
def playPi(self):
if self.canPlay():
self.pi += 1
- def playNoutfound(self):
+ def playNotfound(self):
if self.canPlay():
self.notfound += 1
def playTen(self):
@@ -88,6 +95,10 @@ class Score:
def playBad(self):
if self.canPlay():
self.bad += 1
+ def playTriche(self):
+ self.bad += 5
+ def oupsTriche(self):
+ self.bad -= 5
def toTuple(self):
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")].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 = (int(manche.getAttribute("number")),
manche.getAttribute("winner"),
@@ -136,7 +150,7 @@ def load_module(datas_path):
sys.stdout.write ("Loading 42scores ... ")
dom = parse(filename)
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():
"""Save the scores"""
@@ -154,6 +168,9 @@ def save_module():
top.appendChild(parseString ('' % MANCHE).documentElement)
+ for q in QUESTIONS:
+ top.appendChild(parseString ('' % q).documentElement)
+
with open(filename, "w") as f:
newdoc.writexml (f)
print ("done")
@@ -174,11 +191,14 @@ 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) > 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]))
+ 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 (len(msg.cmd) <= 3 or msg.cmd[3] in SCORES):
+ if msg.cmd[1] == "merge":
+ 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]))
+ elif msg.cmd[1] == "oupstriche":
+ SCORES[msg.cmd[2]].oupsTriche()
else:
if msg.cmd[2] not in SCORES:
msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[2])
@@ -202,9 +222,9 @@ def parseanswer (msg):
score = scr.score()
if score != 0:
if phrase == "":
- phrase = " *%s: %d*,"%(nom, score)
+ phrase = " *%s.%s: %d*,"%(nom[0:1], nom[1:len(nom)], score)
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]))
return True
@@ -231,6 +251,7 @@ def win(msg):
SCORES = dict()
# SCORES[maxi_name] = (-10, 0, -4, 0, 0, -2, 0)
# SCORES[maxi_name] = (0, 0, 0, 0, 0, 0, 0)
+ SCORES[who] = Score()
SCORES[who].newWinner()
if who != maxi_name:
@@ -245,6 +266,11 @@ def win(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
@@ -256,8 +282,12 @@ def getUser(name):
def parselisten (msg):
-# if msg.channel == "#nemutest":
- if msg.channel != "#nemutest":
+# if msg.channel == "#nemutest" and msg.sender not in DELAYED:
+ 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.time.minute == 10 and msg.time.second == 10 and msg.time.hour == 10:
getUser(msg.sender).playTen()
@@ -286,9 +316,8 @@ def parselisten (msg):
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.time.hour == 1 and msg.time.minute == 23 and msg.time.second == 45:
- getUser(msg.sender).playGreat()
- getUser(msg.sender).playTwt()
+ 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).playSuite()
else:
getUser(msg.sender).playBad()
@@ -319,6 +348,59 @@ def parselisten (msg):
if getUser(msg.sender).isWinner():
print ("Nous avons un vainqueur ! Nouvelle manche :p")
win(msg)
+ return True
elif getUser(msg.sender).hasChanged():
- save_module ()
+ gu = GameUpdater(msg)
+ gu.start()
+ return True
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
+
+#
+#
+#
+#
+#
+#
+
+ 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 ()
diff --git a/server.py b/server.py
index abffefa..c1ede7d 100644
--- a/server.py
+++ b/server.py
@@ -6,6 +6,11 @@ import time
import message
+#class WaitedAnswer:
+# def __init__(self, channel):
+# self.channel = channel
+# self.module
+
class Server:
def __init__(self, server, nick, owner, realname):
self.nick = nick
@@ -25,18 +30,28 @@ class Server:
else:
self.password = None
+ self.waited_answer = list()
+
self.listen_nick = True
+ self.partner = "nbr23"
self.channels = list()
for channel in server.getElementsByTagName('channel'):
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"):
if msg is not None and channel is not None:
for line in msg.split("\n"):
if line != "":
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):
if user is not None and user[0] != "#":
self.send_msg_final(user, msg)
@@ -50,6 +65,9 @@ class Server:
self.send_msg (channel, msg, cmd, endl)
+ def register_answer(self, channel, ):
+ self.waited_answer.append(channel)
+
def launch(self, mods, datas_dir):
self.datas_dir = datas_dir
_thread.start_new_thread(self.connect, (mods,))
diff --git a/soutenance.py b/soutenance.py
index 17b228b..cd1e315 100644
--- a/soutenance.py
+++ b/soutenance.py
@@ -4,6 +4,7 @@ import http.client
import time
import re
import _thread
+import threading
from datetime import date
from datetime import datetime
from datetime import timedelta
@@ -28,6 +29,18 @@ class Soutenance:
self.start = 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:
def __init__(self, page):
save = False
@@ -170,6 +183,15 @@ def startSoutenance (msg):
if msg.cmd[0] == "soutenance":
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:
msg.send_chn ("Pas d'horaire de soutenance pour %s."%name)
else:
@@ -207,6 +229,18 @@ def startSoutenance (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
def parselisten (msg):
diff --git a/watchWebsite.py b/watchWebsite.py
index e304635..bd1403f 100644
--- a/watchWebsite.py
+++ b/watchWebsite.py
@@ -4,8 +4,8 @@ import http.client
import hashlib
import sys
import traceback
+import socket
import time
-import pickle
import base64
import _thread
from urllib.parse import unquote
@@ -36,13 +36,7 @@ class Site:
else:
self.updateTime = 60
self.lastChange = 0
- if len(item.childNodes) > 0 and item.childNodes[0].nodeValue is not 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.lastpage = None
self.run = True
@@ -57,12 +51,12 @@ class Site:
def send_message (self, msg):
global SRVS
if len(self.channels) > 0:
- for server in SRVS:
+ for server in SRVS.keys():
for chan in self.channels:
- server.send_msg (chan, msg)
+ SRVS[server].send_msg (chan, msg)
else:
- for server in SRVS:
- server.send_global (msg)
+ for server in SRVS.keys():
+ SRVS[server].send_global (msg)
def treat_atom (self, content):
change=False
@@ -103,6 +97,8 @@ class Site:
try:
# print ("Check %s/%s"%(self.server, self.page))
content = getPage(self.server, self.page)
+ if content is None:
+ return
if self.type == "atom":
(self.lastpage, change) = self.treat_atom (content)
@@ -161,6 +157,8 @@ def launch (servers):
SRVS = servers
for site in SITES:
site.start ()
+def stop():
+ return
def save_module():
"""Save the module state"""
@@ -175,8 +173,6 @@ def save_module():
if len(site.channels) > 0:
for chan in site.channels:
item.appendChild(parseString ('' % (chan)).documentElement);
- b64 = base64.b64encode(pickle.dumps(site.lastpage)).decode()
- item.appendChild(newdoc.createTextNode(b64));
#print (site.server)
top.appendChild(item);
@@ -207,7 +203,11 @@ def parselisten (msg):
def getPage (s, p):
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()
data = res.read()
diff --git a/whereis.py b/whereis.py
index 52b5245..3661e67 100644
--- a/whereis.py
+++ b/whereis.py
@@ -5,6 +5,7 @@ import sys
import socket
import time
import _thread
+import threading
from datetime import datetime
from datetime import date
from datetime import timedelta
@@ -26,7 +27,9 @@ class UpdatedStorage:
if sock != None:
for l in list_users(sock):
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()
self.lastUpdate = datetime.now ()
@@ -48,17 +51,23 @@ class User(object):
@property
def sm(self):
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'):
- return 'en pasteur'
+ return 'pasteur'
elif self.ip.startswith('10.248'):
- return 'en srlab'
+ return 'srlab'
elif self.ip.startswith('10.249'):
- return 'en midlab'
+ return 'midlab'
elif self.ip.startswith('10.250'):
- return 'en cisco'
- elif self.ip.startswith('10.41'):
- return 'sur le wifi'
+ return 'cisco'
+ elif self.ip.startswith('10.41.'):
+ return 'wifi'
else:
return None
@@ -71,9 +80,13 @@ class User(object):
return "chez lui"
else:
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:
- 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):
return cmp(self.login, other.login)
@@ -88,7 +101,7 @@ def connect_to_ns(server, port):
s.connect((server, port))
except socket.error:
return None
- s.recv(8192) # salut ...
+ s.recv(8192)
return s
def list_users(sock):
@@ -108,10 +121,9 @@ def load_module(datas_path):
def save_module():
"""Save the module state"""
- if THREAD is not None:
- THREAD.exit()
return
+
def help_tiny ():
"""Line inserted in the response to the command !help"""
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 ?")
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:
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
+ 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 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:
- 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:
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())
+ return pasla
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 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:
msg.send_snd ("Demande moi moins de personnes à la fois dans ton !%s" % msg.cmd[0])
return True
@@ -173,6 +287,19 @@ def parseanswer (msg):
return False
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
def parselisten (msg):