1
0
Fork 0

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):
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:

View File

@ -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 ('<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);
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:

View File

@ -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():

View File

@ -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)

View File

@ -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...")

112
qd.py
View File

@ -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 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:
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
#<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
#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,))

View File

@ -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):

View File

@ -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 ('<channel name="%s" />' % (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()

View File

@ -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):