From e88ddea4b4bc2f41057da26972ffb0110f976d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 29 Jan 2012 15:28:02 +0100 Subject: [PATCH] Some improvements --- nemubot.py | 168 ++++++++++++++++++++++++++++++++++++++++++++++-- nemuspeak.py | 126 ++++++++++++++++++++++++++++++++---- newyear.py | 23 ++++--- ontime.py | 13 ++-- watchWebsite.py | 28 ++++++++ 5 files changed, 323 insertions(+), 35 deletions(-) create mode 100644 watchWebsite.py diff --git a/nemubot.py b/nemubot.py index 070b716..ad38a29 100755 --- a/nemubot.py +++ b/nemubot.py @@ -8,10 +8,14 @@ import string import os import re import thread +from datetime import date +from datetime import datetime +from datetime import timedelta import norme import newyear import ontime +import watchWebsite if len(sys.argv) > 1: sys.exit(0) @@ -25,9 +29,16 @@ IDENT='nemubot' REALNAME='nemubot' OWNER='nemunaire' #The bot owner's nick #CHANLIST='#nemutest' -CHANLIST='#42sh #nemutest' +CHANLIST='#42sh #nemutest #tc' readbuffer='' #Here we store all the messages from server +birthdays = {"maxence23": datetime(1991, 8, 11), + "nemunaire": datetime(1991, 12, 4, 6, 42), + "xetal": datetime(1991, 2, 23), + "bob": datetime(1991, 2, 2), + "test": datetime(1991, 1, 25), + "colona": datetime(1991, 7, 16)} + s = socket.socket( ) #Create the socket s.connect((HOST, PORT)) #Connect to server s.send("PASS %s\r\n" % "McsuapTesbuf") @@ -38,6 +49,7 @@ s.send("USER %s %s bla :%s\r\n" % (IDENT, HOST, REALNAME)) print("Welcome on Nemubot. I operate on %s. My PID is %i" % (CHANLIST, os.getpid())) def parsemsg(msg): + global birthdays complete = msg[1:].split(':',1) #Parse the message into useful data info = complete[0].split(' ') msgpart = complete[1] @@ -46,10 +58,149 @@ def parsemsg(msg): if CHANLIST.find(info[2]) != -1 and re.match(".*(norme|coding style).*", msgpart) is not None and re.match(".*(please|give|obtenir|now|plz|stp|svp|s'il (te|vous) pla.t|check).*", msgpart) is not None: norme.launch (s, sender, msgpart) - elif msgpart[0] == '!' and CHANLIST.find(info[2]) != -1: #Treat all messages starting with '!' as command - cmd=msgpart[1:].split(' ') + elif CHANLIST.find(info[2]) != -1 and msgpart.find("%s:"%NICK) == 0: #Treat all messages starting with 'nemubot:' as distinct commands + msgpartl = msgpart.lower() + print msgpartl + if re.match(".*(m[' ]?entends?[ -]+tu|h?ear me|ping).*", msgpartl) is not None: + s.send("PRIVMSG {0} :{1}: pong\r\n".format(info[2], sender[0])) + elif re.match(".*(date de naissance|birthday|geburtstag|née?|nee? le|born on).*", msgpartl) is not None: + 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|obtobre|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}))?.*", msgpartl) + +# if re.match(".*(je|i|I).*") is not None: +# target = sender[0] +# elif re.match(".*().*") is not None: + + if result is None: + s.send("PRIVMSG {0} :{1}: je ne reconnais pas le format de ta date de naissance :(\r\n".format(info[2], sender[0])) + else: + day = result.group(2) + if len(day) == 4: + year = day + day = 0 + month = result.group(3) + if month == "janvier" or month == "january" or month == "januar": + month = 1 + elif month == "fevrier" or month == "février" or month == "february": + month = 2 + elif month == "mars" or month == "march": + month = 3 + elif month == "avril" or month == "april": + month = 4 + elif month == "mai" or month == "may" or month == "maï": + month = 5 + elif month == "juin" or month == "juni" or month == "junni": + month = 6 + elif month == "juillet" or month == "jully" or month == "july": + month = 7 + elif month == "aout" or month == "août" or month == "august": + month = 8 + elif month == "september" or month == "septembre": + month = 9 + elif month == "october" or month == "october" or month == "oktober": + month = 10 + elif month == "november" or month == "novembre": + month = 11 + elif month == "december" or month == "decembre" or month == "décembre": + month = 12 + if day == 0: + day = result.group(5) + else: + year = result.group(5) + + hour = result.group(7) + minute = result.group(8) + + print "Chaîne reconnue : %s/%s/%s %s:%s"%(day, month, year, hour, minute) + if year == None: + year = date.today().year + if hour == None: + hour = 0 + if minute == None: + minute = 0 + + try: + newdate = datetime(int(year), int(month), int(day), int(hour), int(minute)) + birthdays[sender[0].lower()] = newdate + s.send("PRIVMSG {0} :{1}: ok, c'est noté, ta date de naissance est le {2}\r\n".format(info[2], sender[0], newdate.strftime("%A %d %B %Y à %H:%M"))) + except ValueError: + s.send("PRIVMSG {0} :{1}: ta date de naissance me paraît peu probable...\r\n".format(info[2], sender[0])) + + elif CHANLIST.find(info[2]) != -1 and msgpart[0] == '!': #Treat all messages starting with '!' as command + cmd = msgpart[1:].split(' ') + if cmd[0] == 'help' or cmd[0] == 'h': + s.send("PRIVMSG {0} :Pour me demander quelque chose, commencer votre message par !.\nVoici ce dont je suis capable :\r\n".format(sender[0])) + s.send("PRIVMSG {0} : - !new-year !newyear !ny : Affiche le temps restant avant la nouvelle année\r\n".format(sender[0])) + s.send("PRIVMSG {0} : - !end-of-world !worldend !eow : Temps restant avant la fin du monde\r\n".format(sender[0])) + s.send("PRIVMSG {0} : - !weekend !week-end !we : Affiche le temps restant avant le prochain week-end\r\n".format(sender[0])) + s.send("PRIVMSG {0} : - !partiels : Affiche le temps restant avant les prochains partiels\r\n".format(sender[0])) + s.send("PRIVMSG {0} : - !vacs !vacances !holidays !free-time : Affiche le temps restant avant les prochaines vacances\r\n".format(sender[0])) + s.send("PRIVMSG {0} : - !jpo !next-jpo : Affiche le temps restant avant la prochaine JPO\r\n".format(sender[0])) + if cmd[0] == 'new-year' or cmd[0] == 'newyear' or cmd[0] == 'ny': - newyear.launch (s, info[2], cmd) + #What is the next year? + nyear = datetime.today().year + 1 + ndate = datetime(nyear, 1, 1, 0, 0, 1) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant la nouvelle année", "Nous faisons déjà la fête depuis{0}"], cmd) + if cmd[0] == 'end-of-world' or cmd[0] == 'endofworld' or cmd[0] == 'worldend' or cmd[0] == 'eow': + ndate = datetime(2012, 12, 12, 12, 12, 13) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant la fin du monde", "Non, cela ne peut pas arriver, la fin du monde s'est produite il y a maintenant {0}. Vous n'êtes vraiment pas mort ? :("], cmd) + if cmd[0] == 'weekend' or cmd[0] == 'week-end' or cmd[0] == 'we': + ndate = datetime.today() + timedelta(5 - datetime.today().weekday()) + ndate = datetime(ndate.year, ndate.month, ndate.day, 0, 0, 1) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant le week-end, courrage ;)", "Youhou, on est en week-end depuis{0}"], cmd) + if cmd[0] == 'endweekend' or cmd[0] == 'end-week-end' or cmd[0] == 'endwe' or cmd[0] == 'eowe': + ndate = datetime.today() + timedelta(7 - datetime.today().weekday()) + ndate = datetime(ndate.year, ndate.month, ndate.day, 0, 0, 1) + if datetime.today().weekday() >= 5: + newyear.launch (s, info[2], ndate, ["Plus que{0} avant la fin du week-end :(", ""], cmd) + else: + newyear.launch (s, info[2], ndate, ["Encore{0} avant la prochaine semaine", ""], cmd) + if cmd[0] == 'partiels' or cmd[0] == 'partiel': + ndate = datetime(2012, 3, 26, 9, 0, 1) + #ndate = datetime(2012, 1, 23, 9, 0, 1) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant les partiels :-o", "Les partiels ont commencés depuis maintenant{0}"], cmd) + if cmd[0] == 'vacs' or cmd[0] == 'vacances' or cmd[0] == 'holiday' or cmd[0] == 'holidays' or cmd[0] == 'free-time': + ndate = datetime(2012, 3, 30, 18, 0, 1) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant les vacances :)", "Profitons, c'est les vacances depuis{0}"], cmd) + if cmd[0] == 'anniv': + if len(cmd) < 2 or cmd[1].lower() == "moi": + name = sender[0].lower() + else: + name = cmd[1].lower() + + matches = [] + + if name in birthdays: + matches.append(name) + else: + for k in birthdays.keys(): + if k.find(name) == 0: + matches.append(k) + + if len(matches) == 1: + (n, d) = (matches[0], birthdays[matches[0]]) + tyd = d + tyd = datetime(date.today().year, tyd.month, tyd.day) + + if tyd.day == datetime.today().day and tyd.month == datetime.today().month: + newyear.launch (s, info[2], d, ["", "C'est aujourd'hui l'anniversaire de %s ! Il a{0}. Joyeux anniversaire :)" % n], cmd) + else: + if tyd < datetime.today(): + tyd = datetime(date.today().year + 1, tyd.month, tyd.day) + + newyear.launch (s, info[2], tyd, ["Il reste{0} avant l'anniversaire de %s !" % n, ""], cmd) + else: + s.send("PRIVMSG {0} :{1}: désolé, je ne connais pas la date d'anniversaire de {2}. Quand est-il né ?\r\n".format(info[2], sender[0], name)) + + if cmd[0] == 'jpo' or cmd[0] == 'JPO' or cmd[0] == 'next-jpo': + #ndate = datetime(2012, 5, 12, 8, 30, 1) + #ndate = datetime(2012, 3, 31, 8, 30, 1) + #ndate = datetime(2012, 3, 17, 8, 30, 1) + ndate = datetime(2012, 2, 4, 8, 30, 1) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant la prochaine JPO... We want you!", "Nous somme en pleine JPO depuis{0}"], cmd) + if cmd[0] == 'professional-project' or cmd[0] == 'project-professionnel' or cmd[0] == 'projet-professionnel' or cmd[0] == 'project-professionel' or cmd[0] == 'projet-professionel' or cmd[0] == 'next-rendu' or cmd[0] == 'pp' or cmd[0] == 'rendu': + ndate = datetime(2012, 1, 18, 16, 0, 1) + newyear.launch (s, info[2], ndate, ["Il reste{0} avant la fermeture du rendu du projet professionnel, vite bullshitons !", "À {0} près, il aurait encore été possible de rendre"], cmd) elif msgpart[0] == '`' and sender[0] == OWNER and CHANLIST.find(info[2]) != -1: #Treat all messages starting with '`' as command @@ -64,7 +215,7 @@ def parsemsg(msg): s.send('MODE '+info[2]+' -v '+cmd[1]+'n') if cmd[0]=='restart': print "Restarting thread" - thread.start_new_thread(ontime.startThread, (s,CHANLIST)) + launch(s) if cmd[0]=='stop': print "Bye!" s.send("PRIVMSG {0} :Bye!\r\n".format(info[2])) @@ -97,5 +248,10 @@ def read(): if(line[0] == 'PING'): #If server pings then pong s.send("PONG %s\r\n" % line[1]) -thread.start_new_thread(ontime.startThread, (s,CHANLIST)) +def launch(s): +# thread.start_new_thread(ontime.startThread, (s,datetime(2012, 1, 18, 6, 0, 1),["Il reste{0} avant la fin de Wikipédia", "C'est fini, Wikipédia a sombrée depuis{0}"],CHANLIST)) + thread.start_new_thread(watchWebsite.startThread, (s, "you.p0m.fr", "", "#42sh")) + print "Launched successfuly" + +launch(s) read() diff --git a/nemuspeak.py b/nemuspeak.py index 0b48fbe..710b2a2 100755 --- a/nemuspeak.py +++ b/nemuspeak.py @@ -11,19 +11,26 @@ from datetime import datetime from datetime import timedelta import thread -if len(sys.argv) > 1: +if len(sys.argv) < 3: + print "This script takes at least 2 args: server port [channel [channel [...]]]" sys.exit(0) #HOST='192.168.0.242' -HOST = 'nemunai.re' -PORT = 2778 +#HOST = 'nemunai.re' +#PORT = 2778 +HOST = sys.argv[1] +PORT = int(sys.argv[2]) #HOST = 'irc.rezosup.org' #PORT = 6667 NICK = 'nemunaire' IDENT = 'nemuspeak' REALNAME = 'nemubot speaker' OWNER = 'nemunaire' #The bot owner's nick -CHANLIST = ['#42sh', '#korteam'] +#CHANLIST = ['#42sh', '#korteam'] +CHANLIST = [] +if len(sys.argv) > 3: + for i in range(3, len(sys.argv)): + CHANLIST.append(sys.argv[i]) readbuffer = '' #Here we store all the messages from server queue = [] @@ -41,7 +48,7 @@ s.send("USER %s %s bla :%s\r\n" % (IDENT, HOST, REALNAME)) print("Welcome on Nemubot speaker. I operate on %s. My PID is %i" % (CHANLIST, os.getpid())) def speak(endstate): - global lastmsg + global lastmsg, queue, talkEC, stopSpk talkEC = 1 stopSpk = 0 @@ -50,6 +57,7 @@ def speak(endstate): while not stopSpk and len(queue) > 0: msg = queue.pop(0) + lang = "fr" sentence = "" force = 0 @@ -65,26 +73,100 @@ def speak(endstate): sentence += "Sur " + msg[0] + ". " force = 1 - if force or msg[1] != lastmsg[1]: + if msg[3].find("ACTION ") == 1: + sentence += msg[1] + " " + msg[3] = msg[3].replace("ACTION ", "") + elif msg[3].find(":)") >= 0: + sentence += msg[1] + " sourit : " + msg[3] = msg[3].replace(":)", "") + elif msg[3].find(";)") >= 0: + sentence += msg[1] + " fait un clin d'oeil : " + msg[3] = msg[3].replace(";)", "") + elif msg[3].find(":(") >= 0: + sentence += msg[1] + " est triste : " + msg[3] = msg[3].replace(":(", "") + elif msg[3].find("<3") >= 0: + sentence += msg[1] + " aime : " + msg[3] = msg[3].replace("<3", "") + elif msg[3].find(":'(") >= 0 or msg[3].find(";(") >= 0: + sentence += msg[1] + " pleure : " + msg[3] = msg[3].replace(":'(", "") + msg[3] = msg[3].replace(";(", "") + elif msg[3].find(":D") >= 0 or msg[3].find(":d") >= 0: + sentence += msg[1] + " rit : " + msg[3] = msg[3].replace(":D", "") + msg[3] = msg[3].replace(":d", "") + elif msg[3].find(":P") >= 0 or msg[3].find(":p") >= 0: + sentence += msg[1] + " tire la langue : " + msg[3] = msg[3].replace(":P", "") + msg[3] = msg[3].replace(":p", "") + elif msg[3].find(":S") >= 0 or msg[3].find(":s") >= 0: + sentence += msg[1] + " est embarassé : " + msg[3] = msg[3].replace(":S", "") + msg[3] = msg[3].replace(":s", "") + elif msg[3].find("XD") >= 0 or msg[3].find("xd") >= 0 or msg[3].find("xD") >= 0 or msg[3].find("Xd") >= 0 or msg[3].find("X)") >= 0 or msg[3].find("x)") >= 0: + sentence += msg[1] + " se marre : " + msg[3] = msg[3].replace("xd", "") + msg[3] = msg[3].replace("XD", "") + msg[3] = msg[3].replace("Xd", "") + msg[3] = msg[3].replace("xD", "") + msg[3] = msg[3].replace("X)", "") + msg[3] = msg[3].replace("x)", "") + elif msg[3].find("\\o/") >= 0 or msg[3].find("\\O/") >= 0: + sentence += msg[1] + " fait une accolade : " + msg[3] = msg[3].replace("\\o/", "") + msg[3] = msg[3].replace("\\O/", "") + elif msg[3].find("/o/") >= 0 or msg[3].find("\\o\\") >= 0: + sentence += msg[1] + " danse : " + msg[3] = msg[3].replace("/o/", "") + msg[3] = msg[3].replace("\\o\\", "") + + elif force or msg[1] != lastmsg[1]: sentence += msg[1] + " dit : " - sentence += msg[3] + if re.match(".*(https?://)?(www\\.)?ycc.fr/[a-z0-9A-Z]+.*", msg[3]) is not None: + msg[3] = re.sub("(https?://)?(www\\.)?ycc.fr/[a-z0-9A-Z]+", " U.R.L Y.C.C ", msg[3]) - print "Blabla: " + sentence - subprocess.call(["espeak", "-v", "fr", sentence]) + if re.match(".*https?://.*", msg[3]) is not None: + msg[3] = re.sub(r'https?://[^ ]+', " U.R.L ", msg[3]) + + if re.match("^ *[^a-zA-Z0-9 ][a-zA-Z]{2}[^a-zA-Z0-9 ]", msg[3]) is not None: + if sentence != "": + subprocess.call(["espeak", "-v", "fr", sentence]) + + lang = msg[3][1:3].lower() + sentence = msg[3][4:] + else: + sentence += msg[3] + + subprocess.call(["espeak", "-v", lang, sentence]) lastmsg = msg - talkEC = endstate + if not stopSpk: + talkEC = endstate + else: + talkEC = 1 def parsemsg(msg): + global talkEC, stopSpk, queue complete = msg[1:].split(':',1) #Parse the message into useful data info = complete[0].split(' ') msgpart = complete[1] sender = info[0].split('!') - if CHANLIST.count(info[2]) >= 0 or info[2] == NICK: + #Bad format, try to fix that + if len(info) == 1: + pv = msg.index(" ", msg.index("PRIVMSG") + 9) + complete = [ msg[1:pv], msg[pv:] ] + info = complete[0].split(' ') + msgpart = complete[1].strip() + if msgpart[0] == ":": + msgpart = msgpart[1:] + sender = info[0].split('!') + + if len(CHANLIST) == 0 or CHANLIST.count(info[2]) >= 0 or info[2] == NICK: #Treat all messages starting with '`' as command if msgpart[0] == '`' and sender[0] == OWNER: cmd=msgpart[1:].split(' ') @@ -96,15 +178,33 @@ def parsemsg(msg): elif cmd[0] == 'speak': thread.start_new_thread(speak, (0,)) + elif cmd[0] == 'reset': + while len(queue) > 0: + queue.pop() + elif cmd[0] == 'save': + if talkEC == 0: + talkEC = 1 stopSpk = 1 + elif cmd[0] == 'list': + print "Currently listened channels:" + for chan in CHANLIST: + print chan + print "-- " + elif cmd[0] == 'add' and len(cmd) > 1: CHANLIST.append(cmd[1]) - print cmd[1] + " added to listed channels" + print cmd[1] + " added to listened channels" + elif cmd[0] == 'del' and len(cmd) > 1: + if CHANLIST.count(cmd[1]) > 0: + CHANLIST.remove(cmd[1]) + print cmd[1] + " removed from listened channels" + else: + print cmd[1] + " not in listened channels" - elif sender[0] != OWNER: + elif sender[0] != OWNER and (len(CHANLIST) == 0 or CHANLIST.count(info[2]) > 0 or info[2] == NICK): queue.append([info[2], sender[0], datetime.now(), msgpart]) if talkEC == 0: thread.start_new_thread(speak, (0,)) diff --git a/newyear.py b/newyear.py index 20e03cd..61a5981 100644 --- a/newyear.py +++ b/newyear.py @@ -4,24 +4,22 @@ import os from datetime import datetime import time -def launch(s, chan, msgpart): - #What is the next year? - nyear = datetime.today().year + 1; +def launch(s, chan, ndate, sentences, msgpart): - if msgpart != 0 and len(msgpart) > 1: - os.environ['TZ'] = msgpart[1] - time.tzset() +# if msgpart != 0 and len(msgpart) > 1: +# os.environ['TZ'] = msgpart[1] +# time.tzset() sentence_c = "PRIVMSG " + chan + " :" #Calculate time before new year - if datetime.now() > datetime(nyear, 1, 1, 0, 0, 1): - sentence_c += "Nous faisons déjà la fête depuis{0}" - delta = datetime.now() - datetime(nyear, 1, 1, 0, 0, 1) + if datetime.now() > ndate: + sentence_c += sentences[1] + delta = datetime.now() - ndate else: - sentence_c += "Il reste{0} avant la nouvelle année" - delta = datetime(nyear, 1, 1, 0, 0, 1) - datetime.now() + sentence_c += sentences[0] + delta = ndate - datetime.now() sec = delta.seconds hours, remainder = divmod(sec, 3600) @@ -64,4 +62,5 @@ def launch(s, chan, msgpart): os.environ['TZ'] = "Europe/Paris" def special(s, chan): - s.send("PRIVMSG {0} :Bonne année {1} !\r\n".format(chan, datetime.today().year)) +# s.send("PRIVMSG {0} :Bonne année {1} !\r\n".format(chan, datetime.today().year)) + s.send("PRIVMSG {0} :Wikipédia vient de sombrer :(\r\n".format(chan)) diff --git a/ontime.py b/ontime.py index 375f2c2..0ebcce7 100644 --- a/ontime.py +++ b/ontime.py @@ -17,7 +17,7 @@ def sync(sec): print "Synchonized on {0}={1} seconds...".format(sec, datetime.now().second) -def startThread(s, CHANLIST): +def startThread(s, ndate, sentences, CHANLIST): sync (60); while 1: minute = datetime.now ().minute @@ -27,15 +27,20 @@ def startThread(s, CHANLIST): for chan in CHANLIST.split(): newyear.special (s, chan) + elif minute == 0 and datetime.now ().hour == 6 and datetime.now ().day == 18 and datetime.now ().month == 1: + print("WikiEnd!") + for chan in CHANLIST.split(): + newyear.special (s, chan) + if minute == 18: for chan in CHANLIST.split(): - newyear.launch (s, chan, 0) + newyear.launch (s, chan, datetime(2012, 1, 18, 6, 0, 1), sentences, 0) if minute == 42: sync(42) print("42!") - for chan in CHANLIST.split(): - s.send("PRIVMSG %s :42 !\r\n" % chan) +# for chan in CHANLIST.split(): +# s.send("PRIVMSG %s :42 !\r\n" % chan) if datetime.now ().second != 0: sync(60) diff --git a/watchWebsite.py b/watchWebsite.py new file mode 100644 index 0000000..b1b7d64 --- /dev/null +++ b/watchWebsite.py @@ -0,0 +1,28 @@ +# coding=utf-8 +import httplib +import hashlib +import time + +def getPage(s, p): + conn = httplib.HTTPConnection(s) + conn.request("GET", "/{0}".format(p)) + + res = conn.getresponse() + data = res.read() + + conn.close() + return data + +def startThread(s, a, p, CHANLIST): + lastpage = hashlib.sha224(getPage(a, p)).hexdigest() + time.sleep(2) + while 1: + page = hashlib.sha224(getPage(a, p)).hexdigest() + + if page != lastpage: + print("Page differ!") + for chan in CHANLIST.split(): + s.send("PRIVMSG %s :Oh, quelle est cette nouvelle image sur http://you.p0m.fr/ ? :p\r\n" % chan) + lastpage = page + + time.sleep(60)