Switch to v3.4 branch

This commit is contained in:
nemunaire 2014-08-13 15:53:55 +02:00
parent ef50f6a1c9
commit 94a9a9a30b
50 changed files with 26 additions and 1666 deletions

4
bot.py
View File

@ -36,8 +36,8 @@ ID_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
class Bot:
def __init__(self, ip, realname, mp=list()):
# Bot general informations
self.version = 3.3
self.version_txt = "3.3"
self.version = 3.4
self.version_txt = "3.4-dev"
# Save various informations
self.ip = ip

View File

@ -6,7 +6,7 @@ from datetime import datetime
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
"""Load this module"""

View File

@ -8,7 +8,7 @@ from datetime import date
from hooks import hook
from xmlparser.node import ModuleState
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
global DATAS

View File

@ -4,7 +4,7 @@ from datetime import datetime
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
yr = datetime.today().year
yrn = datetime.today().year + 1

View File

@ -1,96 +0,0 @@
# coding=utf-8
from datetime import datetime
from datetime import timedelta
from urllib.parse import quote
from tools import web
nemubotversion = 3.3
def help_tiny ():
"""Line inserted in the response to the command !help"""
return "Gets informations about current and next Épita courses"
def help_full ():
return "!chronos [spé] : gives current and next courses."
def get_courses(classe=None, room=None, teacher=None, date=None):
url = CONF.getNode("server")["url"]
if classe is not None:
url += "&class=" + quote(classe)
if room is not None:
url += "&room=" + quote(room)
if teacher is not None:
url += "&teacher=" + quote(teacher)
#TODO: date, not implemented at 23.tf
print_debug(url)
response = web.getXML(url)
if response is not None:
print_debug(response)
return response.getNodes("course")
else:
return None
def get_next_courses(classe=None, room=None, teacher=None, date=None):
courses = get_courses(classe, room, teacher, date)
now = datetime.now()
for c in courses:
start = c.getFirstNode("start").getDate()
if now > start:
return c
return None
def get_near_courses(classe=None, room=None, teacher=None, date=None):
courses = get_courses(classe, room, teacher, date)
return courses[0]
def cmd_chronos(msg):
if len(msg.cmds) > 1:
classe = msg.cmds[1]
else:
classe = ""
res = Response(msg.sender, channel=msg.channel, nomore="Je n'ai pas d'autre cours à afficher")
courses = get_courses(classe)
print_debug(courses)
if courses is not None:
now = datetime.now()
tomorrow = now + timedelta(days=1)
for c in courses:
idc = c.getFirstNode("id").getContent()
crs = c.getFirstNode("title").getContent()
start = c.getFirstNode("start").getDate()
end = c.getFirstNode("end").getDate()
where = c.getFirstNode("where").getContent()
teacher = c.getFirstNode("teacher").getContent()
students = c.getFirstNode("students").getContent()
if now > start:
title = "Actuellement "
msg = "\x03\x02" + crs + "\x03\x02 jusqu'"
if end < tomorrow:
msg += "à \x03\x02" + end.strftime("%H:%M")
else:
msg += "au \x03\x02" + end.strftime("%a %d à %H:%M")
msg += "\x03\x02 en \x03\x02" + where + "\x03\x02"
else:
title = "Prochainement "
duration = (end - start).total_seconds() / 60
msg = "\x03\x02" + crs + "\x03\x02 le \x03\x02" + start.strftime("%a %d à %H:%M") + "\x03\x02 pour " + "%dh%02d" % (int(duration / 60), duration % 60) + " en \x03\x02" + where + "\x03\x02"
if teacher != "":
msg += " avec " + teacher
if students != "":
msg += " pour les " + students
res.append_message(msg, title)
else:
res.append_message("Aucun cours n'a été trouvé")
return res

View File

@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<nemubotmodule name="chronos">
<server url="http://chronos.23.tf/index.php?xml" />
<message type="cmd" name="chronos" call="cmd_chronos" />
<message type="cmd" name="Χρονος" call="cmd_chronos" />
</nemubotmodule>

View File

@ -21,7 +21,7 @@ import sys
from networkbot import NetworkBot
nemubotversion = 3.3
nemubotversion = 3.4
NODATA = True
def getserver(toks, context, prompt):

View File

@ -10,7 +10,7 @@ from tools import web
from tools.web import striphtml
from collections import defaultdict
nemubotversion = 3.3
nemubotversion = 3.4
s = [('present', '0'), ('présent', '0'), ('pr', '0'),
('passé simple', '12'), ('passe simple', '12'), ('ps', '12'),

View File

@ -4,7 +4,7 @@ import imp
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
from . import DDGSearch
from . import UrbanDictionnary

View File

@ -9,7 +9,7 @@ import time
import threading
import traceback
nemubotversion = 3.3
nemubotversion = 3.4
from event import ModuleEvent
from hooks import Hook, hook

View File

@ -5,7 +5,7 @@ import json
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny ():
return "Show many information about a movie or serie"

View File

@ -6,7 +6,7 @@ import os
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny():
"""Line inserted in the response to the command !help"""

View File

@ -10,7 +10,7 @@ import urllib
from hooks import Hook, hook
from tools import web
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
if not CONF or not CONF.hasNode("whoisxmlapi") or not CONF.getNode("whoisxmlapi").hasAttribute("username") or not CONF.getNode("whoisxmlapi").hasAttribute("password"):

View File

@ -6,7 +6,7 @@ from xml.dom.minidom import parseString
from .external.src import ratp
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
global DATAS

View File

@ -1,7 +0,0 @@
<?xml version="1.0" ?>
<nemubotmodule name="qcm">
<file name="main" url="/var/www/nemunai.re/bot/htdocs/questions.xml"/>
<file name="courses" url="/var/www/nemunai.re/bot/htdocs/courses.xml"/>
<file name="users" url="/var/www/nemunai.re/bot/htdocs/users.xml"/>
<server url="bot.nemunai.re" />
</nemubotmodule>

View File

@ -1,31 +0,0 @@
# coding=utf-8
COURSES = None
class Course:
def __init__(self, iden):
global COURSES
if iden in COURSES.index:
self.node = COURSES.index[iden]
else:
self.node = { "code":"N/A", "name":"N/A", "branch":"N/A" }
@property
def id(self):
return self.node["xml:id"]
@property
def code(self):
return self.node["code"]
@property
def name(self):
return self.node["name"]
@property
def branch(self):
return self.node["branch"]
@property
def validated(self):
return int(self.node["validated"]) > 0

View File

@ -1,93 +0,0 @@
# coding=utf-8
from datetime import datetime
import hashlib
import http.client
import socket
from urllib.parse import quote
from .Course import Course
from .User import User
QUESTIONS = None
class Question:
def __init__(self, node):
self.node = node
@property
def ident(self):
return self.node["xml:id"]
@property
def id(self):
return self.node["xml:id"]
@property
def question(self):
return self.node["question"]
@property
def course(self):
return Course(self.node["course"])
@property
def answers(self):
return self.node.getNodes("answer")
@property
def validator(self):
return User(self.node["validator"])
@property
def writer(self):
return User(self.node["writer"])
@property
def validated(self):
return self.node["validated"]
@property
def addedtime(self):
return datetime.fromtimestamp(float(self.node["addedtime"]))
@property
def author(self):
return User(self.node["writer"])
def report(self, raison="Sans raison"):
conn = http.client.HTTPConnection(CONF.getNode("server")["url"], timeout=10)
try:
conn.request("GET", "report.php?id=" + hashlib.md5(self.id.encode()).hexdigest() + "&raison=" + quote(raison))
except socket.gaierror:
print ("[%s] impossible de récupérer la page %s."%(s, p))
return False
res = conn.getresponse()
conn.close()
return (res.status == http.client.OK)
@property
def tupleInfo(self):
return (self.author.username, self.validator.username, self.addedtime)
@property
def bestAnswer(self):
best = self.answers[0]
for answer in self.answers:
if best.getInt("score") < answer.getInt("score"):
best = answer
return best["answer"]
def isCorrect(self, msg):
msg = msg.lower().replace(" ", "")
for answer in self.answers:
if msg == answer["answer"].lower().replace(" ", ""):
return True
return False
def getScore(self, msg):
msg = msg.lower().replace(" ", "")
for answer in self.answers:
if msg == answer["answer"].lower().replace(" ", ""):
return answer.getInt("score")
return 0

View File

@ -1,16 +0,0 @@
# coding=utf-8
import module_states_file as xmlparser
from .Question import Question
class QuestionFile:
def __init__(self, filename):
self.questions = xmlparser.parse_file(filename)
self.questions.setIndex("xml:id")
def getQuestion(self, ident):
if ident in self.questions.index:
return Question(self.questions.index[ident])
else:
return None

View File

@ -1,67 +0,0 @@
# coding=utf-8
import threading
SESSIONS = dict()
from . import Question
from response import Response
class Session:
def __init__(self, srv, chan, sender):
self.questions = list()
self.current = -1
self.score = 0
self.good = 0
self.bad = 0
self.trys = 0
self.timer = None
self.server = srv
self.channel = chan
self.sender = sender
def addQuestion(self, ident):
if ident not in self.questions:
self.questions.append(ident)
return True
return False
def next_question(self):
self.trys = 0
self.current += 1
return self.question
@property
def question(self):
if self.current >= 0 and self.current < len(self.questions):
return Question.Question(Question.QUESTIONS.index[self.questions[self.current]])
else:
return None
def askNext(self, bfr = ""):
global SESSIONS
self.timer = None
nextQ = self.next_question()
if nextQ is not None:
if self.sender.split("!")[0] != self.channel:
self.server.send_response(Response(self.sender, "%s%s" % (bfr, nextQ.question), self.channel, nick=self.sender.split("!")[0]))
else:
self.server.send_response(Response(self.sender, "%s%s" % (bfr, nextQ.question), self.channel))
else:
if self.good > 1:
goodS = "s"
else:
goodS = ""
if self.sender.split("!")[0] != self.channel:
self.server.send_response(Response(self.sender, "%sFini, tu as donné %d bonne%s réponse%s sur %d questions." % (self.sender, bfr, self.good, goodS, goodS, len(self.questions)), self.channel, nick=self.sender.split("!")[0]))
else:
self.server.send_response(Response(self.sender, "%sFini, tu as donné %d bonne%s réponse%s sur %d questions." % (self.sender, bfr, self.good, goodS, goodS, len(self.questions)), self.channel))
del SESSIONS[self.sender]
def prepareNext(self, lag = 3):
if self.timer is None:
self.timer = threading.Timer(lag, self.askNext)
self.timer.start()

View File

@ -1,27 +0,0 @@
# coding=utf-8
USERS = None
class User:
def __init__(self, iden):
global USERS
if iden in USERS.index:
self.node = USERS.index[iden]
else:
self.node = { "username":"N/A", "email":"N/A" }
@property
def id(self):
return self.node["xml:id"]
@property
def username(self):
return self.node["username"]
@property
def email(self):
return self.node["email"]
@property
def validated(self):
return int(self.node["validated"]) > 0

View File

@ -1,197 +0,0 @@
# coding=utf-8
from datetime import datetime
import http.client
import re
import random
import sys
import time
import xmlparser
nemubotversion = 3.2
def help_tiny ():
"""Line inserted in the response to the command !help"""
return "MCQ module, working with http://bot.nemunai.re/"
def help_full ():
return "!qcm [<nbQuest>] [<theme>]"
from . import Question
from . import Course
from . import Session
def load(context):
CONF.setIndex("name", "file")
def buildSession(msg, categ = None, nbQuest = 10, channel = False):
if Question.QUESTIONS is None:
Question.QUESTIONS = xmlparser.parse_file(CONF.index["main"]["url"])
Question.QUESTIONS.setIndex("xml:id")
Course.COURSES = xmlparser.parse_file(CONF.index["courses"]["url"])
Course.COURSES.setIndex("xml:id")
User.USERS = xmlparser.parse_file(CONF.index["users"]["url"])
User.USERS.setIndex("xml:id")
#Remove no validated questions
keys = list()
for k in Question.QUESTIONS.index.keys():
keys.append(k)
for ques in keys:
if Question.QUESTIONS.index[ques]["validated"] != "1" or Question.QUESTIONS.index[ques]["reported"] == "1":
del Question.QUESTIONS.index[ques]
#Apply filter
QS = list()
if categ is not None and len(categ) > 0:
#Find course id corresponding to categ
courses = list()
for c in Course.COURSES.childs:
if c["code"] in categ:
courses.append(c["xml:id"])
#Keep only questions matching course or branch
for q in Question.QUESTIONS.index.keys():
if (Question.QUESTIONS.index[q]["branch"] is not None and Question.QUESTIONS.index[q]["branch"].find(categ)) or Question.QUESTIONS.index[q]["course"] in courses:
QS.append(q)
else:
for q in Question.QUESTIONS.index.keys():
QS.append(q)
nbQuest = min(nbQuest, len(QS))
if channel:
sess = Session.Session(msg.srv, msg.channel, msg.channel)
else:
sess = Session.Session(msg.srv, msg.channel, msg.sender)
maxQuest = len(QS) - 1
for i in range(0, nbQuest):
while True:
q = QS[random.randint(0, maxQuest)]
if sess.addQuestion(q):
break
if channel:
Session.SESSIONS[msg.channel] = sess
else:
Session.SESSIONS[msg.realname] = sess
def askQuestion(msg, bfr = ""):
return Session.SESSIONS[msg.realname].askNext(bfr)
def parseanswer(msg):
global DATAS
if msg.cmd[0] == "qcm" or msg.cmd[0] == "qcmchan" or msg.cmd[0] == "simulateqcm":
if msg.realname in Session.SESSIONS:
if len(msg.cmd) > 1:
if msg.cmd[1] == "stop" or msg.cmd[1] == "end":
sess = Session.SESSIONS[msg.realname]
if sess.good > 1: goodS = "s"
else: goodS = ""
del Session.SESSIONS[msg.realname]
return Response(msg.sender,
"Fini, tu as donné %d bonne%s réponse%s sur %d questions." % (sess.good, goodS, goodS, sess.current),
msg.channel, nick=msg.nick)
elif msg.cmd[1] == "next" or msg.cmd[1] == "suivant" or msg.cmd[1] == "suivante":
return askQuestion(msg)
return Response(msg.sender, "tu as déjà une session de QCM en cours, finis-la avant d'en commencer une nouvelle.", msg.channel, msg.nick)
elif msg.channel in Session.SESSIONS:
if len(msg.cmd) > 1:
if msg.cmd[1] == "stop" or msg.cmd[1] == "end":
sess = Session.SESSIONS[msg.channel]
if sess.good > 1: goodS = "s"
else: goodS = ""
del Session.SESSIONS[msg.channel]
return Response(msg.sender, "Fini, vous avez donné %d bonne%s réponse%s sur %d questions." % (sess.good, goodS, goodS, sess.current), msg.channel)
elif msg.cmd[1] == "next" or msg.cmd[1] == "suivant" or msg.cmd[1] == "suivante":
Session.SESSIONS[msg.channel].prepareNext(1)
return True
else:
nbQuest = 10
filtre = list()
if len(msg.cmd) > 1:
for cmd in msg.cmd[1:]:
try:
tmp = int(cmd)
nbQuest = tmp
except ValueError:
filtre.append(cmd.upper())
if len(filtre) == 0:
filtre = None
if msg.channel in Session.SESSIONS:
return Response(msg.sender, "Il y a deja une session de QCM sur ce chan.")
else:
buildSession(msg, filtre, nbQuest, msg.cmd[0] == "qcmchan")
if msg.cmd[0] == "qcm":
return askQuestion(msg)
elif msg.cmd[0] == "qcmchan":
return Session.SESSIONS[msg.channel].askNext()
else:
del Session.SESSIONS[msg.realname]
return Response(msg.sender, "QCM de %d questions" % len(Session.SESSIONS[msg.realname].questions), msg.channel)
return True
elif msg.realname in Session.SESSIONS:
if msg.cmd[0] == "info" or msg.cmd[0] == "infoquestion":
return Response(msg.sender, "Cette question a été écrite par %s et validée par %s, le %s" % Session.SESSIONS[msg.realname].question.tupleInfo, msg.channel)
elif msg.cmd[0] == "report" or msg.cmd[0] == "reportquestion":
if len(msg.cmd) == 1:
return Response(msg.sender, "Veuillez indiquer une raison de report", msg.channel)
elif Session.SESSIONS[msg.realname].question.report(' '.join(msg.cmd[1:])):
return Response(msg.sender, "Cette question vient d'être signalée.", msg.channel)
Session.SESSIONS[msg.realname].askNext()
else:
return Response(msg.sender, "Une erreur s'est produite lors du signalement de la question, veuillez recommencer plus tard.", msg.channel)
elif msg.channel in Session.SESSIONS:
if msg.cmd[0] == "info" or msg.cmd[0] == "infoquestion":
return Response(msg.sender, "Cette question a été écrite par %s et validée par %s, le %s" % Session.SESSIONS[msg.channel].question.tupleInfo, msg.channel)
elif msg.cmd[0] == "report" or msg.cmd[0] == "reportquestion":
if len(msg.cmd) == 1:
return Response(msg.sender, "Veuillez indiquer une raison de report", msg.channel)
elif Session.SESSIONS[msg.channel].question.report(' '.join(msg.cmd[1:])):
Session.SESSIONS[msg.channel].prepareNext()
return Response(msg.sender, "Cette question vient d'être signalée.", msg.channel)
else:
return Response(msg.sender, "Une erreur s'est produite lors du signalement de la question, veuillez recommencer plus tard.", msg.channel)
else:
if msg.cmd[0] == "listecours":
if Course.COURSES is None:
return Response(msg.sender, "La liste de cours n'est pas encore construite, lancez un QCM pour la construire.", msg.channel)
else:
res = Response(msg.sender, channel=msg.channel, title="Liste des cours existants : ")
res.append_message([cours["code"] + " (" + cours["name"] + ")" for cours in Course.COURSES.getNodes("course")])
return res
elif msg.cmd[0] == "refreshqcm":
Question.QUESTIONS = None
Course.COURSES = None
User.USERS = None
return True
return False
def parseask(msg):
if msg.realname in Session.SESSIONS:
dest = msg.realname
if Session.SESSIONS[dest].question.isCorrect(msg.content):
Session.SESSIONS[dest].good += 1
Session.SESSIONS[dest].score += Session.SESSIONS[dest].question.getScore(msg.content)
return askQuestion(msg, "correct ; ")
else:
Session.SESSIONS[dest].bad += 1
if Session.SESSIONS[dest].trys == 0:
Session.SESSIONS[dest].trys = 1
return Response(msg.sender, "non, essaie encore :p", msg.channel, msg.nick)
else:
return askQuestion(msg, "non, la bonne reponse était : %s ; " % Session.SESSIONS[dest].question.bestAnswer)
elif msg.channel in Session.SESSIONS:
dest = msg.channel
if Session.SESSIONS[dest].question.isCorrect(msg.content):
Session.SESSIONS[dest].good += 1
Session.SESSIONS[dest].score += Session.SESSIONS[dest].question.getScore(msg.content)
Session.SESSIONS[dest].prepareNext()
return Response(msg.sender, "correct :)", msg.channel, nick=msg.nick)
else:
Session.SESSIONS[dest].bad += 1
return Response(msg.sender, "non, essaie encore :p", msg.channel, nick=msg.nick)
return False

View File

@ -1,32 +0,0 @@
# coding=utf-8
import re
import threading
class DelayedTuple:
def __init__(self, regexp, great):
self.delayEvnt = threading.Event()
self.msg = None
self.regexp = regexp
self.great = great
def triche(self, res):
if res is not None:
return re.match(".*" + self.regexp + ".*", res.lower() + " ") is None
else:
return True
def perfect(self, res):
if res is not None:
return re.match(".*" + self.great + ".*", res.lower() + " ") is not None
else:
return False
def good(self, res):
if res is not None:
return re.match(".*" + self.regexp + ".*", res.lower() + " ") is not None
else:
return False
def wait(self, timeout):
self.delayEvnt.wait(timeout)

View File

@ -1,60 +0,0 @@
# coding=utf-8
from datetime import datetime
import random
import threading
from .DelayedTuple import DelayedTuple
DELAYED = dict()
LASTQUESTION = 99999
class GameUpdater(threading.Thread):
def __init__(self, msg, bfrseen):
self.msg = msg
self.bfrseen = bfrseen
threading.Thread.__init__(self)
def run(self):
global DELAYED, LASTQUESTION
if self.bfrseen is not None:
seen = datetime.now() - self.bfrseen
rnd = random.randint(0, int(seen.seconds/90))
else:
rnd = 1
if rnd != 0:
QUESTIONS = CONF.getNodes("question")
if self.msg.channel == "#nemutest":
quest = 9
else:
if LASTQUESTION >= len(QUESTIONS):
print (QUESTIONS)
random.shuffle(QUESTIONS)
LASTQUESTION = 0
quest = LASTQUESTION
LASTQUESTION += 1
question = QUESTIONS[quest]["question"]
regexp = QUESTIONS[quest]["regexp"]
great = QUESTIONS[quest]["great"]
self.msg.send_chn("%s: %s" % (self.msg.nick, question))
DELAYED[self.msg.nick] = DelayedTuple(regexp, great)
DELAYED[self.msg.nick].wait(20)
if DELAYED[self.msg.nick].triche(DELAYED[self.msg.nick].msg):
getUser(self.msg.nick).playTriche()
self.msg.send_chn("%s: Tricheur !" % self.msg.nick)
elif DELAYED[self.msg.nick].perfect(DELAYED[self.msg.nick].msg):
if random.randint(0, 10) == 1:
getUser(self.msg.nick).bonusQuestion()
self.msg.send_chn("%s: Correct !" % self.msg.nick)
else:
self.msg.send_chn("%s: J'accepte" % self.msg.nick)
del DELAYED[self.msg.nick]
SCORES.save(self.msg.nick)
save()

View File

@ -1,20 +0,0 @@
# coding=utf-8
from tools.wrapper import Wrapper
from .Score import Score
class QDWrapper(Wrapper):
def __init__(self, datas):
Wrapper.__init__(self)
self.DATAS = datas
self.stateName = "player"
self.attName = "name"
def __getitem__(self, i):
if i in self.cache:
return self.cache[i]
else:
sc = Score()
sc.parse(Wrapper.__getitem__(self, i))
self.cache[i] = sc
return sc

View File

@ -1,126 +0,0 @@
# coding=utf-8
from datetime import datetime
class Score:
"""Manage the user's scores"""
def __init__(self):
#FourtyTwo
self.ftt = 0
#TwentyThree
self.twt = 0
self.pi = 0
self.notfound = 0
self.tententen = 0
self.leet = 0
self.great = 0
self.bad = 0
self.triche = 0
self.last = None
self.changed = False
def parse(self, item):
self.ftt = item.getInt("fourtytwo")
self.twt = item.getInt("twentythree")
self.pi = item.getInt("pi")
self.notfound = item.getInt("notfound")
self.tententen = item.getInt("tententen")
self.leet = item.getInt("leet")
self.great = item.getInt("great")
self.bad = item.getInt("bad")
self.triche = item.getInt("triche")
def save(self, state):
state.setAttribute("fourtytwo", self.ftt)
state.setAttribute("twentythree", self.twt)
state.setAttribute("pi", self.pi)
state.setAttribute("notfound", self.notfound)
state.setAttribute("tententen", self.tententen)
state.setAttribute("leet", self.leet)
state.setAttribute("great", self.great)
state.setAttribute("bad", self.bad)
state.setAttribute("triche", self.triche)
def merge(self, other):
self.ftt += other.ftt
self.twt += other.twt
self.pi += other.pi
self.notfound += other.notfound
self.tententen += other.tententen
self.leet += other.leet
self.great += other.great
self.bad += other.bad
self.triche += other.triche
def newWinner(self):
self.ftt = 0
self.twt = 0
self.pi = 1
self.notfound = 1
self.tententen = 0
self.leet = 1
self.great = -1
self.bad = -4
self.triche = 0
def isWinner(self):
return self.great >= 42
def playFtt(self):
if self.canPlay():
self.ftt += 1
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 playNotfound(self):
if self.canPlay():
self.notfound += 1
def playTen(self):
if self.canPlay():
self.tententen += 1
def playLeet(self):
if self.canPlay():
self.leet += 1
def playGreat(self):
if self.canPlay():
self.great += 1
def playBad(self):
if self.canPlay():
self.bad += 1
self.great += 1
def playTriche(self):
self.triche += 1
def oupsTriche(self):
self.triche -= 1
def bonusQuestion(self):
return
def toTuple(self):
return (self.ftt, self.twt, self.pi, self.notfound, self.tententen, self.leet, self.great, self.bad, self.triche)
def canPlay(self):
now = datetime.now()
ret = self.last == None or self.last.minute != now.minute or self.last.hour != now.hour or self.last.day != now.day
self.changed = self.changed or ret
return ret
def hasChanged(self):
if self.changed:
self.changed = False
self.last = datetime.now()
return True
else:
return False
def score(self):
return (self.ftt * 2 + self.great * 5 + self.leet * 13.37 + (self.pi + 1) * 3.1415 * (self.notfound + 1) + self.tententen * 10 + self.twt - (self.bad + 1) * 10 * (self.triche * 5 + 1) + 7)
def details(self):
return "42: %d, 23: %d, leet: %d, pi: %d, 404: %d, 10: %d, great: %d, bad: %d, triche: %d = %d."%(self.ftt, self.twt, self.leet, self.pi, self.notfound, self.tententen, self.great, self.bad, self.triche, self.score())

View File

@ -1,224 +0,0 @@
# coding=utf-8
import re
import imp
from datetime import datetime
nemubotversion = 3.0
from . import GameUpdater
from . import QDWrapper
from . import Score
channels = "#nemutest #42sh #ykar #epitagueule"
LASTSEEN = dict ()
temps = dict ()
SCORES = None
def load(context):
global DATAS, SCORES, CONF
DATAS.setIndex("name", "player")
SCORES = QDWrapper.QDWrapper(DATAS)
GameUpdater.SCORES = SCORES
GameUpdater.CONF = CONF
GameUpdater.save = save
GameUpdater.getUser = getUser
def reload():
imp.reload(GameUpdater)
imp.reload(QDWrapper)
imp.reload(Score)
def help_tiny ():
"""Line inserted in the response to the command !help"""
return "42 game!"
def help_full ():
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 parseanswer (msg):
if msg.cmd[0] == "42" or msg.cmd[0] == "score" or msg.cmd[0] == "scores":
global SCORES
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])
elif msg.cmd[3] not in SCORES:
msg.send_chn ("%s n'est pas un joueur connu."%msg.cmd[3])
elif len(msg.cmd) > 1 and (msg.cmd[1] == "help" or msg.cmd[1] == "aide"):
msg.send_chn ("Formule : \"42\" * 2 + great * 5 + leet * 13.37 + (pi + 1) * 3.1415 * (not_found + 1) + tententen * 10 + \"23\" - (bad + 1) * 10 * (triche * 5 + 1) + 7")
elif len(msg.cmd) > 1 and (msg.cmd[1] == "manche" or msg.cmd[1] == "round"):
manche = DATAS.getNode("manche")
msg.send_chn ("Nous sommes dans la %de manche, gagnée par %s avec %d points et commencée par %s le %s." % (manche.getInt("number"), manche["winner"], manche.getInt("winner_score"), manche["who"], manche.getDate("date")))
#elif msg.channel == "#nemutest":
else:
phrase = ""
if len(msg.cmd) > 1:
if msg.cmd[1] in SCORES:
phrase += " " + msg.cmd[1] + ": " + SCORES[msg.cmd[1]].details()
else:
phrase = " %s n'a encore jamais joué,"%(msg.cmd[1])
else:
for nom, scr in sorted(SCORES.items(), key=rev, reverse=True):
score = scr.score()
if score != 0:
if phrase == "":
phrase = " *%s.%s: %d*,"%(nom[0:1], nom[1:len(nom)], score)
else:
phrase += " %s.%s: %d,"%(nom[0:1], nom[1:len(nom)], score)
msg.send_chn ("Scores :%s" % (phrase[0:len(phrase)-1]))
return True
else:
return False
def win(msg):
global SCORES
who = msg.nick
manche = DATAS.getNode("manche")
maxi_scor = 0
maxi_name = None
for player in DATAS.index.keys():
scr = SCORES[player].score()
if scr > maxi_scor:
maxi_scor = scr
maxi_name = player
for player in DATAS.index.keys():
scr = SCORES[player].score()
if scr > maxi_scor / 3:
del SCORES[player]
else:
DATAS.index[player]["great"] = 0
SCORES.flush()
if who != maxi_name:
msg.send_chn ("Félicitations %s, tu remportes cette manche terminée par %s, avec un score de %d !"%(maxi_name, who, maxi_scor))
else:
msg.send_chn ("Félicitations %s, tu remportes cette manche avec %d points !"%(maxi_name, maxi_scor))
manche.setAttribute("number", manche.getInt("number") + 1)
manche.setAttribute("winner", maxi_name)
manche.setAttribute("winner_score", maxi_scor)
manche.setAttribute("who", who)
manche.setAttribute("date", datetime.now())
print ("Nouvelle manche !")
save()
def parseask (msg):
if len(GameUpdater.DELAYED) > 0:
if msg.nick in GameUpdater.DELAYED:
GameUpdater.DELAYED[msg.nick].msg = msg.content
GameUpdater.DELAYED[msg.nick].delayEvnt.set()
return True
return False
def rev (tupl):
(k, v) = tupl
return (v.score(), k)
def getUser(name):
global SCORES
if name not in SCORES:
SCORES[name] = Score.Score()
return SCORES[name]
def parselisten (msg):
if len(GameUpdater.DELAYED) > 0 and msg.nick in GameUpdater.DELAYED and GameUpdater.DELAYED[msg.nick].good(msg.content):
msg.send_chn("%s: n'oublie pas le nemubot: devant ta réponse pour qu'elle soit prise en compte !" % msg.nick)
bfrseen = None
if msg.realname in LASTSEEN:
bfrseen = LASTSEEN[msg.realname]
LASTSEEN[msg.realname] = datetime.now()
# if msg.channel == "#nemutest" and msg.nick not in GameUpdater.DELAYED:
if msg.channel != "#nemutest" and msg.nick not in GameUpdater.DELAYED:
if re.match("^(42|quarante[- ]?deux).{,2}$", msg.content.strip().lower()):
if msg.time.minute == 10 and msg.time.second == 10 and msg.time.hour == 10:
getUser(msg.nick).playTen()
getUser(msg.nick).playGreat()
elif msg.time.minute == 42:
if msg.time.second == 0:
getUser(msg.nick).playGreat()
getUser(msg.nick).playFtt()
else:
getUser(msg.nick).playBad()
if re.match("^(23|vingt[ -]?trois).{,2}$", msg.content.strip().lower()):
if msg.time.minute == 23:
if msg.time.second == 0:
getUser(msg.nick).playGreat()
getUser(msg.nick).playTwt()
else:
getUser(msg.nick).playBad()
if re.match("^(10){3}.{,2}$", msg.content.strip().lower()):
if msg.time.minute == 10 and msg.time.hour == 10:
if msg.time.second == 10:
getUser(msg.nick).playGreat()
getUser(msg.nick).playTen()
else:
getUser(msg.nick).playBad()
if re.match("^0?12345.{,2}$", msg.content.strip().lower()):
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.nick).playSuite()
else:
getUser(msg.nick).playBad()
if re.match("^[1l][e3]{2}[t7] ?t?ime.{,2}$", msg.content.strip().lower()):
if msg.time.hour == 13 and msg.time.minute == 37:
if msg.time.second == 0:
getUser(msg.nick).playGreat()
getUser(msg.nick).playLeet()
else:
getUser(msg.nick).playBad()
if re.match("^(pi|3.14) ?time.{,2}$", msg.content.strip().lower()):
if msg.time.hour == 3 and msg.time.minute == 14:
if msg.time.second == 15 or msg.time.second == 16:
getUser(msg.nick).playGreat()
getUser(msg.nick).playPi()
else:
getUser(msg.nick).playBad()
if re.match("^(404( ?time)?|time ?not ?found).{,2}$", msg.content.strip().lower()):
if msg.time.hour == 4 and msg.time.minute == 4:
if msg.time.second == 0 or msg.time.second == 4:
getUser(msg.nick).playGreat()
getUser(msg.nick).playNotfound()
else:
getUser(msg.nick).playBad()
if getUser(msg.nick).isWinner():
print ("Nous avons un vainqueur ! Nouvelle manche :p")
win(msg)
return True
elif getUser(msg.nick).hasChanged():
gu = GameUpdater.GameUpdater(msg, bfrseen)
gu.start()
return True
return False

View File

@ -4,7 +4,7 @@ import json
import re
import urllib
nemubotversion = 3.3
nemubotversion = 3.4
from hooks import hook

View File

@ -4,7 +4,7 @@ import random
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
@hook("cmd_hook", "choice")
def cmd_choice(msg):

View File

@ -8,7 +8,7 @@ from hooks import hook
from tools import web
from tools.web import striphtml
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny ():
return "Find information about an SAP transaction codes"

View File

@ -7,7 +7,7 @@ from datetime import timedelta
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny():
"""Line inserted in the response to the command !help"""

View File

@ -9,7 +9,7 @@ import urllib.parse
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
global DATAS

View File

@ -1,5 +0,0 @@
<?xml version="1.0" ?>
<nemubotmodule name="soutenance">
<server ip="www.acu.epita.fr" url="/intra/sout_liste.html" />
<message type="cmd" name="soutenance" call="ask_soutenance" />
</nemubotmodule>

View File

@ -1,13 +0,0 @@
# coding=utf-8
import threading
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)

View File

@ -1,179 +0,0 @@
# coding=utf-8
from datetime import datetime
from datetime import timedelta
import http.client
import re
import threading
import time
from response import Response
from .Soutenance import Soutenance
class SiteSoutenances(threading.Thread):
def __init__(self, datas):
self.souts = list()
self.updated = datetime.now()
self.datas = datas
threading.Thread.__init__(self)
def getPage(self):
conn = http.client.HTTPSConnection(CONF.getNode("server")["ip"], timeout=10)
try:
conn.request("GET", CONF.getNode("server")["url"])
res = conn.getresponse()
page = res.read()
except:
print ("[%s] impossible de récupérer la page %s."%(s, p))
return ""
conn.close()
return page
def parsePage(self, page):
save = False
for line in page.split("\n"):
if re.match("</tr>", line) is not None:
save = False
elif re.match("<tr.*>", line) is not None:
save = True
last = Soutenance()
self.souts.append(last)
elif save:
result = re.match("<td[^>]+>(.*)</td>", line)
if last.hour is None:
try:
last.hour = datetime.fromtimestamp(time.mktime(time.strptime(result.group(1), "%Y-%m-%d %H:%M")))
except ValueError:
continue
elif last.rank == 0:
last.rank = int (result.group(1))
elif last.login == None:
last.login = result.group(1)
elif last.state == None:
last.state = result.group(1)
elif last.assistant == None:
last.assistant = result.group(1)
elif last.start == None:
try:
last.start = datetime.fromtimestamp(time.mktime(time.strptime(result.group(1), "%Y-%m-%d %H:%M")))
except ValueError:
last.start = None
elif last.end == None:
try:
last.end = datetime.fromtimestamp(time.mktime(time.strptime(result.group(1), "%Y-%m-%d %H:%M")))
except ValueError:
last.end = None
def gen_response(self, req, msg):
"""Generate a text response on right server and channel"""
return Response(req["sender"], msg, req["channel"], server=req["server"])
def res_next(self, req):
soutenance = self.findLast()
if soutenance is None:
return self.gen_response(req, "Il ne semble pas y avoir de soutenance pour le moment.")
else:
if soutenance.start > soutenance.hour:
avre = "%s de *retard*"%msg.just_countdown(soutenance.start - soutenance.hour, 4)
else:
avre = "%s *d'avance*"%msg.just_countdown(soutenance.hour - soutenance.start, 4)
self.gen_response(req, "Actuellement à la soutenance numéro %d, commencée il y a %s avec %s."%(soutenance.rank, msg.just_countdown(datetime.now () - soutenance.start, 4), avre))
def res_assistants(self, req):
assistants = self.findAssistants()
if len(assistants) > 0:
return self.gen_response(req, "Les %d assistants faisant passer les soutenances sont : %s." % (len(assistants), ', '.join(assistants.keys())))
else:
return self.gen_response(req, "Il ne semble pas y avoir de soutenance pour le moment.")
def res_soutenance(self, req):
name = req["user"]
if name == "acu" or name == "yaka" or name == "acus" or name == "yakas" or name == "assistant" or name == "assistants":
return self.res_assistants(req)
elif name == "next":
return self.res_next(req)
soutenance = self.findClose(name)
if soutenance is None:
return self.gen_response(req, "Pas d'horaire de soutenance pour %s."%name)
else:
if soutenance.state == "En cours":
return self.gen_response(req, "%s est actuellement en soutenance avec %s. Elle était prévue à %s, position %d."%(name, soutenance.assistant, soutenance.hour, soutenance.rank))
elif soutenance.state == "Effectue":
return self.gen_response(req, "%s a passé sa soutenance avec %s. Elle a duré %s."%(name, soutenance.assistant, msg.just_countdown(soutenance.end - soutenance.start, 4)))
elif soutenance.state == "Retard":
return self.gen_response(req, "%s était en retard à sa soutenance de %s."%(name, soutenance.hour))
else:
last = self.findLast()
if last is not None:
if soutenance.hour + (last.start - last.hour) > datetime.now ():
return self.gen_response(req, "Soutenance de %s : %s, position %d ; estimation du passage : dans %s."%(name, soutenance.hour, soutenance.rank, msg.just_countdown((soutenance.hour - datetime.now ()) + (last.start - last.hour))))
else:
return self.gen_response(req, "Soutenance de %s : %s, position %d ; passage imminent."%(name, soutenance.hour, soutenance.rank))
else:
return self.gen_response(req, "Soutenance de %s : %s, position %d."%(name, soutenance.hour, soutenance.rank))
def res_list(self, req):
name = req["user"]
souts = self.findAll(name)
if souts is None:
self.gen_response(req, "Pas de soutenance prévues pour %s."%name)
else:
first = True
for s in souts:
if first:
self.gen_response(req, "Soutenance(s) de %s : - %s (position %d) ;"%(name, s.hour, s.rank))
first = False
else:
self.gen_response(req, " %s - %s (position %d) ;"%(len(name)*' ', s.hour, s.rank))
def run(self):
self.parsePage(self.getPage().decode())
res = list()
for u in self.datas.getNodes("request"):
res.append(self.res_soutenance(u))
return res
def needUpdate(self):
if self.findLast() is not None and datetime.now () - self.updated > timedelta(minutes=2):
return True
elif datetime.now () - self.updated < timedelta(hours=1):
return False
else:
return True
def findAssistants(self):
h = dict()
for s in self.souts:
if s.assistant is not None and s.assistant != "":
h[s.assistant] = (s.start, s.end)
return h
def findLast(self):
close = None
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)) and (close is None or s.hour - close.hour < timedelta(seconds=2499)):
close = s
return close
def findAll(self, login):
ss = list()
for s in self.souts:
if s.login == login:
ss.append(s)
return ss
def findClose(self, login):
ss = self.findAll(login)
close = None
for s in ss:
if close is not None:
print (close.hour)
print (s.hour)
if close is None or (close.hour < s.hour and close.hour.day >= datetime.datetime().day):
close = s
return close

View File

@ -1,11 +0,0 @@
# coding=utf-8
class Soutenance:
def __init__(self):
self.hour = None
self.rank = 0
self.login = None
self.state = None
self.assistant = None
self.start = None
self.end = None

View File

@ -1,48 +0,0 @@
# coding=utf-8
import time
import re
import threading
from datetime import date
from datetime import datetime
from . import SiteSoutenances
nemubotversion = 3.3
def help_tiny():
"""Line inserted in the response to the command !help"""
return "EPITA ING1 defenses module"
def help_full():
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/"
def load(context):
global CONF
SiteSoutenances.CONF = CONF
def ask_soutenance(msg):
req = ModuleState("request")
if len(msg.cmds) > 1:
req.setAttribute("user", msg.cmds[1])
else:
req.setAttribute("user", "next")
req.setAttribute("server", msg.server)
req.setAttribute("channel", msg.channel)
req.setAttribute("sender", msg.sender)
#An instance of this module is already running?
if not DATAS.hasAttribute("_running") or DATAS["_running"].needUpdate():
DATAS.addChild(req)
site = SiteSoutenances.SiteSoutenances(DATAS)
DATAS.setAttribute("_running", site)
res = site.run()
for n in DATAS.getNodes("request"):
DATAS.delChild(n)
return res
else:
site = DATAS["_running"]
return site.res_soutenance(req)

View File

@ -8,7 +8,7 @@ from hooks import hook
from .pyaspell import Aspell
from .pyaspell import AspellError
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny():
return "Check words spelling"

View File

@ -8,7 +8,7 @@ from urllib.parse import quote
from hooks import hook
from tools import web
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny():
return "Find french synonyms"

View File

@ -7,7 +7,7 @@ import json
from urllib.parse import quote
from urllib.request import urlopen
nemubotversion = 3.3
nemubotversion = 3.4
import xmlparser

View File

@ -4,7 +4,7 @@ import re
from tools import web
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
global DATAS

View File

@ -15,7 +15,7 @@ from hooks import hook
from .atom import Atom
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny ():
"""Line inserted in the response to the command !help"""

View File

@ -6,7 +6,7 @@ import re
from urllib.parse import quote
from urllib.request import urlopen
nemubotversion = 3.3
nemubotversion = 3.4
def load(context):
global DATAS

View File

@ -1,28 +0,0 @@
<?xml version="1.0" ?>
<nemubotmodule name="whereis">
<server url="ns-server.epita.fr" port="4242" />
<sm name="adm" ip="10.2." />
<sm name="vpn" ip="10.10." />
<sm name="wifi" ip="10.41" />
<sm name="sm02" ip="10.200.2" />
<sm name="sm14" ip="10.200.14." />
<sm name="sm15" ip="10.200.15." />
<sm name="épimac" ip="10.223.3." />
<sm name="wcube" ip="10.223.4." />
<sm name="cycom" ip="10.223.5" />
<sm name="eptv" ip="10.223.6" />
<sm name="prologin" ip="10.223.7" />
<sm name="assos" ip="10.223" />
<sm name="gistre" ip="10.226.7." />
<sm name="astek" ip="10.224.1." />
<sm name="acu" ip="10.224.2." />
<sm name="lse" ip="10.224.4." />
<sm name="eip" ip="10.224.8." />
<sm name="evolutek" ip="10.224.16." />
<sm name="mslab" ip="10.224.18." />
<sm name="bocal" ip="10.242" />
<sm name="pasteur" ip="10.247" />
<sm name="srlab" ip="10.248" />
<sm name="midlab" ip="10.249" />
<sm name="cisco" ip="10.250" />
</nemubotmodule>

View File

@ -1,5 +0,0 @@
# coding=utf-8
class Delayed:
def __init__(self):
self.names = dict()

View File

@ -1,57 +0,0 @@
# coding=utf-8
import socket
from datetime import datetime
from datetime import timedelta
from .User import User
class UpdatedStorage:
def __init__(self, url, port):
sock = connect_to_ns(url, port)
self.users = dict()
if sock != None:
users = list_users(sock)
if users is not None:
for l in users:
u = User(l)
if u.login not in self.users:
self.users[u.login] = list()
self.users[u.login].append(u)
self.lastUpdate = datetime.now ()
else:
self.users = None
sock.close()
else:
self.users = None
def update(self):
if datetime.now () - self.lastUpdate < timedelta(minutes=10):
return self
else:
return None
def connect_to_ns(server, port):
try:
s = socket.socket()
s.settimeout(3)
s.connect((server, port))
except socket.error:
return None
s.recv(8192)
return s
def list_users(sock):
try:
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]
except socket.error:
return None

View File

@ -1,35 +0,0 @@
# coding=utf-8
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):
for sm in CONF.getNodes("sm"):
if self.ip.startswith(sm["ip"]):
return sm["name"]
return None
@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:
if self.ip.startswith('10.247') or self.ip.startswith('10.248') or self.ip.startswith('10.249') or self.ip.startswith('10.250'):
return "en " + self.sm + " rangée " + self.ip.split('.')[2] + " poste " + self.ip.split('.')[3]
else:
return "en " + self.sm
def __cmp__(self, other):
return cmp(self.login, other.login)
def __hash__(self):
return hash(self.login)

View File

@ -1,206 +0,0 @@
# coding=utf-8
import re
import sys
import socket
import time
import _thread
import threading
from datetime import datetime
from datetime import date
from datetime import timedelta
from urllib.parse import unquote
from module_state import ModuleState
from . import User
from .UpdatedStorage import UpdatedStorage
from .Delayed import Delayed
nemubotversion = 3.0
THREAD = None
search = list()
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/.\n!whereare <who> [<other who> ...]: gives the position of these <who>.\n!peoplein <sm>: gives the number of people in this /sm/.\n!ip <who>: gets the IP adress of /who/.\n!whoison <location>: gives the name or the number (if > 15) of people at this /location/.\n!whoisin <sm>: gives the name or the number of people in this /sm/"
def load():
global CONF
User.CONF = CONF
datas = None
def startWhereis(msg):
global datas, THREAD, search
if datas is not None:
datas = datas.update ()
if datas is None:
datas = UpdatedStorage(CONF.getNode("server")["url"], CONF.getNode("server").getInt("port"))
if datas is None or datas.users is None:
msg.send_chn("Hmm c'est embarassant, serait-ce la fin du monde ou juste netsoul qui est mort ?")
return
if msg.cmd[0] == "peoplein":
peoplein(msg)
elif msg.cmd[0] == "whoison" or msg.cmd[0] == "whoisin":
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" or pc == "whoisin":
continue
else:
found = list()
for userC in datas.users:
for user in datas.users[userC]:
if (msg.cmd[0] == "whoison" and (user.ip[:len(pc)] == pc or user.location.lower() == pc)) or (msg.cmd[0] == "whoisin" and user.sm == pc):
found.append(user.login)
if len(found) > 0:
if len(found) <= 15:
if pc == "whoisin":
msg.send_chn ("En %s, il y a %s" % (pb, ", ".join(found)))
else:
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.nick))
DELAYED = dict()
delayEvnt = threading.Event()
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.nick
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":
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:
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)
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" or msg.cmd[0] == "peoplein" or msg.cmd[0] == "whoison" or msg.cmd[0] == "whoisin":
if len(msg.cmd) > 10:
msg.send_snd ("Demande moi moins de personnes à la fois dans ton !%s" % msg.cmd[0])
return True
if THREAD is None:
THREAD = _thread.start_new_thread (startWhereis, (msg,))
else:
search.append(msg)
return True
return False
def parseask (msg):
if len(DELAYED) > 0 and msg.nick == msg.srv.partner:
treat = False
for part in msg.content.split(';'):
if part is None:
continue
for d in DELAYED.keys():
nKeys = list()
for n in DELAYED[d].names.keys():
nKeys.append(n)
for n in nKeys:
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

View File

@ -6,7 +6,7 @@ import re
from urllib.parse import quote
from urllib.request import urlopen
nemubotversion = 3.3
nemubotversion = 3.4
API_URL="http://worldcup.sfg.io/%s"

View File

@ -7,7 +7,7 @@ from urllib.request import urlopen
from hooks import hook
nemubotversion = 3.3
nemubotversion = 3.4
def help_tiny():
"""Line inserted in the response to the command !help"""

View File

@ -1,51 +0,0 @@
# coding=utf-8
import re
import http.client
idAtom = "http://musik.p0m.fr/atom.php?nemubot"
URLS = dict ()
def load_module(datas_path):
"""Load this module"""
global URLS
URLS = dict ()
def save_module():
"""Save the dates"""
return
def help_tiny ():
"""Line inserted in the response to the command !help"""
return "music extractor"
def help_full ():
return "To launch a convertion task, juste paste a youtube link (or compatible service) and wait for nemubot answer!"
def parseanswer(msg):
return False
def parseask(msg):
return False
def parselisten (msg):
global URLS
matches = [".*(http://(www\.)?youtube.com/watch\?v=([a-zA-Z0-9_-]{11})).*",
".*(http://(www\.)?youtu.be/([a-zA-Z0-9_-]{11})).*"]
for m in matches:
res = re.match (m, msg.content)
if res is not None:
#print ("seen : %s"%res.group(1))
URLS[res.group(1)] = msg
conn = http.client.HTTPConnection("musik.p0m.fr", timeout=10)
conn.request("GET", "/?nemubot&a=add&url=%s"%(res.group (1)))
conn.getresponse()
conn.close()
return True
return False
def send_global (origin, msg):
if origin in URLS:
URLS[origin].send_chn (msg)
del URLS[origin]