Stability improvements

New module whereis
This commit is contained in:
Némunaire 2012-04-18 23:35:58 +02:00
parent 2e461f26f4
commit e375f23f71
11 changed files with 293 additions and 120 deletions

View File

@ -53,7 +53,7 @@ class Atom:
differ = list () differ = list ()
for k in other.entries.keys (): for k in other.entries.keys ():
if self.updated is None and k not in self.entries: if self.updated is None and k not in self.entries:
self.updated = entry.updated self.updated = other.entries[k].updated
if k not in self.entries and other.entries[k].updated >= self.updated: if k not in self.entries and other.entries[k].updated >= self.updated:
differ.append (other.entries[k]) differ.append (other.entries[k])
return differ return differ
@ -61,11 +61,11 @@ class Atom:
if __name__ == "__main__": if __name__ == "__main__":
content1 = "" content1 = ""
with open("rss.php", "r") as f: with open("rss.php.1", "r") as f:
for line in f: for line in f:
content1 += line content1 += line
content2 = "" content2 = ""
with open("rss.php.1", "r") as f: with open("rss.php", "r") as f:
for line in f: for line in f:
content2 += line content2 += line
a = Atom (content1) a = Atom (content1)

View File

@ -77,11 +77,11 @@ def save_module():
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 "!anniv /who/: gives the remaining time before the anniversary of /who/" return "People birthdays and ages"
def help_full (): def help_full ():
return "!anniv /who/: gives the remaining time before the anniversary of /who/\nIf /who/ is not given, gives the remaining time before your anniversary.\n\n To set yout birthday, say it to nemubot :)" return "!anniv /who/: gives the remaining time before the anniversary of /who/\n!age /who/: gives the age of /who/\nIf /who/ is not given, gives the remaining time before your anniversary.\n\n To set yout birthday, say it to nemubot :)"
def findName(msg): def findName(msg):

View File

@ -89,11 +89,10 @@ def save_module():
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 "!events FIXME" return "events manager"
def help_full (): def help_full ():
return "FIXME" return "This module store a lot of events: ny, we, vacs, " + (", ".join(EVENTS.keys()))
def parseanswer(msg): def parseanswer(msg):

View File

@ -83,6 +83,106 @@ class Message:
self.srv.send_msg (self.sender, msg) self.srv.send_msg (self.sender, msg)
def treat (self, mods):
if self.cmd == "PING":
self.pong ()
elif self.cmd == "PRIVMSG" and self.srv.accepted_channel(self.channel):
self.parsemsg (mods)
elif self.cmd == "NICK":
print ("%s change de nom pour %s" % (self.sender, self.content))
elif self.cmd == "PART":
print ("%s vient de quitter %s" % (self.sender, self.channel))
elif self.cmd == "JOIN":
print ("%s arrive sur %s" % (self.sender, self.channel))
def pong (self):
self.srv.s.send(("PONG %s\r\n" % self.content).encode ())
def parsemsg (self, mods):
#Treat all messages starting with 'nemubot:' as distinct commands
if self.content.find("%s:"%self.srv.nick) == 0:
messagel = self.content.lower()
#Is it a simple response?
if re.match(".*(m[' ]?entends?[ -]+tu|h?ear me|do you copy|ping)", messagel) is not None:
self.send_chn ("%s: pong"%(self.sender))
elif re.match(".*(quel(le)? heure est[ -]il|what time is it)", messagel) is not None:
now = datetime.now()
self.send_chn ("%s: j'envoie ce message à %s:%d:%d."%(self.sender, now.hour, now.minute, now.second))
elif re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (.+)$", messagel) is not None:
result = re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (qu(e |'))?(.+)$", self.content)
self.send_chn ("%s: %s"%(result.group(2), result.group(5)))
elif re.match(".*di[st] (.+) (a|à) ([a-zA-Z0-9_]+)$", messagel) is not None:
result = re.match(".*di[st] (.+) (à|a) ([a-zA-Z0-9_]+)$", self.content)
self.send_chn ("%s: %s"%(result.group(3), result.group(1)))
elif re.match(".*di[st] sur (#[a-zA-Z0-9]+) (.+)$", self.content) is not None:
result = re.match(".*di[st] sur (#[a-zA-Z0-9]+) (.+)$", self.content)
if self.srv.channels.count(result.group(1)):
self.send_msg(result.group(1), result.group(2))
elif re.match(".*di[st] (.+) sur (#[a-zA-Z0-9]+)$", self.content) is not None:
result = re.match(".*di[st] (.+) sur (#[a-zA-Z0-9]+)$", self.content)
if self.srv.channels.count(result.group(2)):
self.send_msg(result.group(2), result.group(1))
#Try modules
else:
for im in mods.keys():
if mods[im].parseask(self):
return
#Owner commands
elif self.content[0] == '`' and self.sender == self.srv.owner:
self.cmd = self.content[1:].split(' ')
if self.cmd[0] == "reload":
if len(self.cmd) > 1:
if self.cmd[1] in mods:
mods[self.cmd[1]].save_module ()
imp.reload(mods[self.cmd[1]])
mods[self.cmd[1]].load_module (self.srv.datas_dir)
self.send_snd ("Module %s rechargé avec succès."%self.cmd[1])
else:
self.send_snd ("Module inconnu %s."%self.cmd[1])
else:
self.send_snd ("Usage: `reload /module/.")
self.send_snd ("Loaded modules: " + ', '.join(mods.keys()) + ".")
#Messages stating with !
elif self.content[0] == '!':
self.cmd = self.content[1:].split(' ')
if self.cmd[0] == "help":
if len (self.cmd) > 1:
if self.cmd[1] in mods:
self.send_snd(mods[self.cmd[1]].help_full ())
else:
self.send_snd("No help for command %s" % self.cmd[1])
else:
self.send_snd("Pour me demander quelque chose, commencez votre message par mon nom ; je réagis à certain messages commençant par !, consulter l'aide de chaque module :")
for im in mods.keys():
self.send_snd(" - !help %s: %s" % (im, mods[im].help_tiny ()))
for im in mods.keys():
if mods[im].parseanswer(self):
return
else:
for im in mods.keys():
if mods[im].parselisten(self):
return
##############################
# #
# Extraction/Format text #
# #
##############################
def just_countdown (self, delta, resolution = 5): def just_countdown (self, delta, resolution = 5):
sec = delta.seconds sec = delta.seconds
hours, remainder = divmod(sec, 3600) hours, remainder = divmod(sec, 3600)
@ -142,6 +242,7 @@ class Message:
def countdown_format (self, date, msg_before, msg_after, timezone = None): def countdown_format (self, date, msg_before, msg_after, timezone = None):
"""Replace in a text %s by a sentence incidated the remaining time before/after an event"""
if timezone != None: if timezone != None:
os.environ['TZ'] = timezone os.environ['TZ'] = timezone
time.tzset() time.tzset()
@ -160,95 +261,8 @@ class Message:
return sentence_c % self.just_countdown(delta) return sentence_c % self.just_countdown(delta)
def treat (self, mods):
if self.cmd == "PING":
self.pong ()
elif self.cmd == "PRIVMSG":
self.parsemsg (mods)
elif self.cmd == "NICK":
print ("%s change de nom pour %s" % (self.sender, self.content))
elif self.cmd == "PART":
print ("%s vient de quitter %s" % (self.sender, self.channel))
elif self.cmd == "JOIN":
print ("%s arrive sur %s" % (self.sender, self.channel))
def pong (self):
self.srv.s.send(("PONG %s\r\n" % self.content).encode ())
def parsemsg (self, mods):
#Treat all messages starting with 'nemubot:' as distinct commands
if self.content.find("%s:"%self.srv.nick) == 0:
messagel = self.content.lower()
#Is it a simple response?
if re.match(".*(m[' ]?entends?[ -]+tu|h?ear me|do you copy|ping)", messagel) is not None:
self.send_chn ("%s: pong"%(self.sender))
elif re.match(".*(quel(le)? heure est[ -]il|what time is it)", messagel) is not None:
now = datetime.now()
self.send_chn ("%s: j'envoie ce message à %s:%d:%d."%(self.sender, now.hour, now.minute, now.second))
elif re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (.+)$", messagel) is not None:
result = re.match(".*di[st] (a|à) ([a-zA-Z0-9_]+) (qu(e |'))?(.+)$", self.content)
self.send_chn ("%s: %s"%(result.group(2), result.group(5)))
elif re.match(".*di[st] (.+) (a|à) ([a-zA-Z0-9_]+)$", messagel) is not None:
result = re.match(".*di[st] (.+) (à|a) ([a-zA-Z0-9_]+)$", self.content)
self.send_chn ("%s: %s"%(result.group(3), result.group(1)))
elif re.match(".*di[st] sur (#[a-zA-Z0-9]+) (.+)$", self.content) is not None:
result = re.match(".*di[st] sur (#[a-zA-Z0-9]+) (.+)$", self.content)
if self.srv.channels.count(result.group(1)):
self.send_msg(result.group(1), result.group(2))
elif re.match(".*di[st] (.+) sur (#[a-zA-Z0-9]+)$", self.content) is not None:
result = re.match(".*di[st] (.+) sur (#[a-zA-Z0-9]+)$", self.content)
if self.srv.channels.count(result.group(2)):
self.send_msg(result.group(2), result.group(1))
else:
for im in mods.keys():
if mods[im].parseask(self):
return
elif self.content[0] == '`' and self.sender == self.srv.owner:
self.cmd = self.content[1:].split(' ')
if self.cmd[0] == "reload":
if len(self.cmd) > 1:
if self.cmd[1] in mods:
mods[self.cmd[1]].save_module ()
imp.reload(mods[self.cmd[1]])
mods[self.cmd[1]].load_module (self.srv.datas_dir)
self.send_snd ("Module %s rechargé avec succès."%self.cmd[1])
else:
self.send_snd ("Module inconnu %s."%self.cmd[1])
else:
self.send_snd ("Usage: `reload /module/.")
self.send_snd ("Loaded modules: " + ', '.join(mods.keys()) + ".")
elif self.content[0] == '!':
self.cmd = self.content[1:].split(' ')
if self.cmd[0] == "help":
if len (self.cmd) > 1:
if self.cmd[1] in mods:
self.send_snd(mods[self.cmd[1]].help_full ())
else:
self.send_snd("No help for command %s" % self.cmd[1])
else:
self.send_snd("Pour me demander quelque chose, commencez votre message par mon nom ou par l'une des commandes suivantes :")
for im in mods:
self.send_snd(" - %s" % im.help_tiny ())
for im in mods.keys():
if mods[im].parseanswer(self):
return
else:
for im in mods.keys():
if mods[im].parselisten(self):
return
def extractDate (self): def extractDate (self):
"""Parse a message to extract a time and date"""
msgl = self.content.lower () msgl = self.content.lower ()
result = re.match("^[^0-9]+(([0-9]{1,4})[^0-9]+([0-9]{1,2}|janvier|january|fevrier|février|february|mars|march|avril|april|mai|maï|may|juin|juni|juillet|july|jully|august|aout|août|septembre|september|october|octobre|oktober|novembre|november|decembre|décembre|december)([^0-9]+([0-9]{1,4}))?)[^0-9]+(([0-9]{1,2})[^0-9]*[h':]([^0-9]*([0-9]{1,2})([^0-9]*[m\":][^0-9]*([0-9]{1,2}))?)?)?.*$", msgl + " TXT") result = re.match("^[^0-9]+(([0-9]{1,4})[^0-9]+([0-9]{1,2}|janvier|january|fevrier|février|february|mars|march|avril|april|mai|maï|may|juin|juni|juillet|july|jully|august|aout|août|septembre|september|october|octobre|oktober|novembre|november|decembre|décembre|december)([^0-9]+([0-9]{1,4}))?)[^0-9]+(([0-9]{1,2})[^0-9]*[h':]([^0-9]*([0-9]{1,2})([^0-9]*[m\":][^0-9]*([0-9]{1,2}))?)?)?.*$", msgl + " TXT")
if result is not None: if result is not None:

View File

@ -10,7 +10,7 @@ from datetime import datetime
from datetime import timedelta from datetime import timedelta
from xml.dom.minidom import parse from xml.dom.minidom import parse
imports = ["birthday", "qd", "events", "youtube", "watchWebsite", "soutenance"] imports = ["birthday", "qd", "events", "youtube", "watchWebsite", "soutenance", "whereis"]
imports_launch = ["watchWebsite"] imports_launch = ["watchWebsite"]
mods = {} mods = {}
import server import server

4
qd.py
View File

@ -158,10 +158,10 @@ def save_module():
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 "!42: display scores\n!42 help: display the performed calculate\n!42 manche: display information about current round\n!42 /who/: show the /who/'s scores" return "42 game!"
def help_full (): def help_full ():
return "Help for 42 todo" return "!42: display scores\n!42 help: display the performed calculate\n!42 manche: display information about current round\n!42 /who/: show the /who/'s scores"
def rev (tupl): def rev (tupl):

View File

@ -28,13 +28,14 @@ class Server:
self.channels.append(channel.getAttribute("name")) self.channels.append(channel.getAttribute("name"))
def send_msg (self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"): def send_msg (self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"):
for line in msg.split("\n"): if msg is not None and channel is not None:
if line != "" and self.accepted_channel(channel): for line in msg.split("\n"):
self.s.send (("%s %s :%s%s" % (cmd, channel, line, endl)).encode ()) if line != "" and self.accepted_channel(channel):
self.s.send (("%s %s :%s%s" % (cmd, channel, line, endl)).encode ())
def send_global (self, msg, cmd = "PRIVMSG", endl = "\r\n"): def send_global (self, msg, cmd = "PRIVMSG", endl = "\r\n"):
for channel in self.channels: for channel in self.channels:
self.send_msg (channel, msg, cmd, endl) self.send_msg (channel, msg, cmd, endl)
def launch(self, mods, datas_dir): def launch(self, mods, datas_dir):
@ -57,10 +58,10 @@ class Server:
for line in temp: for line in temp:
msg = message.Message (self, line) msg = message.Message (self, line)
try: #try:
msg.treat (mods) msg.treat (mods)
except: #except:
print ("Une erreur est survenue lors du traitement du message : %s"%line) #print ("Une erreur est survenue lors du traitement du message : %s"%line)
def connect(self, mods): def connect(self, mods):

View File

@ -7,8 +7,6 @@ from datetime import date
from datetime import datetime from datetime import datetime
from datetime import timedelta from datetime import timedelta
stack = list()
def getPage (): def getPage ():
conn = http.client.HTTPSConnection("intra.acu.epita.fr") conn = http.client.HTTPSConnection("intra.acu.epita.fr")
conn.request("GET", "/intra/sout_liste.html") conn.request("GET", "/intra/sout_liste.html")
@ -87,7 +85,7 @@ class SiteSoutenances:
def findLast(self): def findLast(self):
close = None close = None
for s in self.souts: for s in self.souts:
if s.state != "En attente" and s.start is not None and (close is None or close.rank < s.rank or close.hour.day > s.hour.day): if (s.state != "En attente" and s.start is not None and (close is None or close.rank < s.rank or close.hour.day > s.hour.day)) and (close is None or s.hour - close.hour < timedelta(seconds=1499)):
close = s close = s
return close return close
@ -120,10 +118,10 @@ def save_module():
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 None return "EPITA ING1 defenses module"
def help_full (): def help_full ():
return None return "!soutenance: gives information about current defenses state\n!soutenance /who/: gives the date of the next defense of /who/.\n!soutenances /who/: gives all defense dates of /who/"
datas = None datas = None

View File

@ -3,7 +3,10 @@
import http.client import http.client
import hashlib import hashlib
import sys import sys
import traceback
import time import time
import pickle
import base64
import _thread import _thread
from urllib.parse import unquote from urllib.parse import unquote
from xml.dom.minidom import parse from xml.dom.minidom import parse
@ -33,7 +36,14 @@ class Site:
else: else:
self.updateTime = 60 self.updateTime = 60
self.lastChange = 0 self.lastChange = 0
self.lastpage = None 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.run = True self.run = True
self.channels = list() self.channels = list()
@ -126,8 +136,10 @@ class Site:
time.sleep(self.updateTime) time.sleep(self.updateTime)
except: except:
print ("Une erreur est survenue lors de la récupération de la page " + self.server + "/" + self.page) print ("Une erreur est survenue lors de la récupération de la page " + self.server + "/" + self.page)
time.sleep(self.updateTime * 3) exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_tb(exc_traceback)
time.sleep(self.updateTime * 3)
@ -163,6 +175,9 @@ 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)
top.appendChild(item); top.appendChild(item);
with open(filename, "w") as f: with open(filename, "w") as f:
@ -172,10 +187,10 @@ def save_module():
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 None return "Alert on changes on websites"
def help_full (): def help_full ():
return None return "This module is autonomous you can't interract with it."
def parseanswer (msg): def parseanswer (msg):
if msg.cmd[0] == "watch": if msg.cmd[0] == "watch":

146
whereis.py Normal file
View File

@ -0,0 +1,146 @@
# coding=utf-8
import re
import sys
import socket
import time
from datetime import datetime
from datetime import date
from datetime import timedelta
from urllib.parse import unquote
from xml.dom.minidom import parse
from xml.dom.minidom import parseString
from xml.dom.minidom import getDOMImplementation
NS_SERVER = 'ns-server.epita.fr'
NS_PORT = 4242
class UpdatedStorage:
def __init__(self):
sock = connect_to_ns(NS_SERVER, NS_PORT)
self.users = dict()
for l in list_users(sock):
u = User(l)
self.users[u.login] = u
sock.close()
self.lastUpdate = datetime.now ()
def update(self):
if datetime.now () - self.lastUpdate < timedelta(minutes=10):
return self
else:
return None
class User(object):
def __init__(self, line):
fields = line.split()
self.login = fields[1]
self.ip = fields[2]
self.location = fields[8]
self.promo = fields[9]
@property
def sm(self):
if self.ip.startswith('10.200'):
return 'en SM' + self.ip.split('.')[2]
elif self.ip.startswith('10.247'):
return 'en pasteur'
elif self.ip.startswith('10.248'):
return 'en srlab'
elif self.ip.startswith('10.249'):
return 'en midlab'
elif self.ip.startswith('10.250'):
return 'en cisco'
elif self.ip.startswith('10'):
return 'quelque part sur le PIE (%s)'%self.ip
else:
return "chez lui"
@property
def poste(self):
if self.sm is None:
if self.ip.startswith('10'):
return 'quelque part sur le PIE (%s)'%self.ip
else:
return "chez lui"
else:
return self.sm + " rangée " + self.ip.split('.')[2] + " poste " + self.ip.split('.')[3]
def __cmp__(self, other):
return cmp(self.login, other.login)
def __hash__(self):
return hash(self.login)
def connect_to_ns(server, port):
s = socket.socket()
s.connect((server, port))
s.recv(8192) # salut ...
return s
def list_users(sock):
sock.send('list_users\n'.encode())
buf = ''
while True:
tmp = sock.recv(8192).decode()
buf += tmp
if '\nrep 002' in tmp or tmp == '':
break
return buf.split('\n')[:-2]
def load_module(datas_path):
"""Load this module"""
return
def save_module():
"""Save the module state"""
return
def help_tiny ():
"""Line inserted in the response to the command !help"""
return "Find a user on the PIE"
def help_full ():
return "!whereis /who/: gives the position of /who/."
datas = None
def parseanswer (msg):
global datas
if msg.cmd[0] == "whereis" or msg.cmd[0] == "ouest":
if datas is not None:
datas = datas.update ()
if datas is None:
datas = UpdatedStorage()
if len(msg.cmd) >= 2:
name = msg.cmd[1]
else:
name = msg.sender
if name in datas.users:
msg.send_chn ("%s est %s (%s)." %(name, datas.users[name].poste, unquote(datas.users[name].location)))
else:
msg.send_chn ("%s n'est pas connecté sur le PIE." % name)
return True
elif msg.cmd[0] == "ip":
if len(msg.cmd) >= 2:
name = msg.cmd[1]
else:
name = msg.sender
if name in datas.users:
msg.send_chn ("L'ip de %s est %s." %(name, datas.users[name].ip))
else:
msg.send_chn ("%s n'est pas connecté à netsoul." % name)
return True
return False
def parseask (msg):
return False
def parselisten (msg):
return False

View File

@ -16,10 +16,10 @@ def save_module():
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 return "music extractor"
def help_full (): def help_full ():
return return "To launch a convertion task, juste paste a youtube link (or compatible service) and wait for nemubot answer!"
def parseanswer(msg): def parseanswer(msg):
return False return False