Switch to v3.4 branch
This commit is contained in:
parent
ef50f6a1c9
commit
94a9a9a30b
4
bot.py
4
bot.py
@ -36,8 +36,8 @@ ID_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|||||||
class Bot:
|
class Bot:
|
||||||
def __init__(self, ip, realname, mp=list()):
|
def __init__(self, ip, realname, mp=list()):
|
||||||
# Bot general informations
|
# Bot general informations
|
||||||
self.version = 3.3
|
self.version = 3.4
|
||||||
self.version_txt = "3.3"
|
self.version_txt = "3.4-dev"
|
||||||
|
|
||||||
# Save various informations
|
# Save various informations
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
@ -6,7 +6,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
def load(context):
|
||||||
"""Load this module"""
|
"""Load this module"""
|
||||||
|
@ -8,7 +8,7 @@ from datetime import date
|
|||||||
from hooks import hook
|
from hooks import hook
|
||||||
from xmlparser.node import ModuleState
|
from xmlparser.node import ModuleState
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
def load(context):
|
||||||
global DATAS
|
global DATAS
|
||||||
|
@ -4,7 +4,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
yr = datetime.today().year
|
yr = datetime.today().year
|
||||||
yrn = datetime.today().year + 1
|
yrn = datetime.today().year + 1
|
||||||
|
@ -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
|
|
@ -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>
|
|
@ -21,7 +21,7 @@ import sys
|
|||||||
|
|
||||||
from networkbot import NetworkBot
|
from networkbot import NetworkBot
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
NODATA = True
|
NODATA = True
|
||||||
|
|
||||||
def getserver(toks, context, prompt):
|
def getserver(toks, context, prompt):
|
||||||
|
@ -10,7 +10,7 @@ from tools import web
|
|||||||
from tools.web import striphtml
|
from tools.web import striphtml
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
s = [('present', '0'), ('présent', '0'), ('pr', '0'),
|
s = [('present', '0'), ('présent', '0'), ('pr', '0'),
|
||||||
('passé simple', '12'), ('passe simple', '12'), ('ps', '12'),
|
('passé simple', '12'), ('passe simple', '12'), ('ps', '12'),
|
||||||
|
@ -4,7 +4,7 @@ import imp
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
from . import DDGSearch
|
from . import DDGSearch
|
||||||
from . import UrbanDictionnary
|
from . import UrbanDictionnary
|
||||||
|
@ -9,7 +9,7 @@ import time
|
|||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
from event import ModuleEvent
|
from event import ModuleEvent
|
||||||
from hooks import Hook, hook
|
from hooks import Hook, hook
|
||||||
|
@ -5,7 +5,7 @@ import json
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny ():
|
def help_tiny ():
|
||||||
return "Show many information about a movie or serie"
|
return "Show many information about a movie or serie"
|
||||||
|
@ -6,7 +6,7 @@ import os
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny():
|
def help_tiny():
|
||||||
"""Line inserted in the response to the command !help"""
|
"""Line inserted in the response to the command !help"""
|
||||||
|
@ -10,7 +10,7 @@ import urllib
|
|||||||
from hooks import Hook, hook
|
from hooks import Hook, hook
|
||||||
from tools import web
|
from tools import web
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
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"):
|
if not CONF or not CONF.hasNode("whoisxmlapi") or not CONF.getNode("whoisxmlapi").hasAttribute("username") or not CONF.getNode("whoisxmlapi").hasAttribute("password"):
|
||||||
|
@ -6,7 +6,7 @@ from xml.dom.minidom import parseString
|
|||||||
|
|
||||||
from .external.src import ratp
|
from .external.src import ratp
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
def load(context):
|
||||||
global DATAS
|
global DATAS
|
||||||
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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()
|
|
||||||
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -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()
|
|
@ -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
|
|
@ -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())
|
|
@ -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
|
|
@ -4,7 +4,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import random
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
@hook("cmd_hook", "choice")
|
@hook("cmd_hook", "choice")
|
||||||
def cmd_choice(msg):
|
def cmd_choice(msg):
|
||||||
|
@ -8,7 +8,7 @@ from hooks import hook
|
|||||||
from tools import web
|
from tools import web
|
||||||
from tools.web import striphtml
|
from tools.web import striphtml
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny ():
|
def help_tiny ():
|
||||||
return "Find information about an SAP transaction codes"
|
return "Find information about an SAP transaction codes"
|
||||||
|
@ -7,7 +7,7 @@ from datetime import timedelta
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny():
|
def help_tiny():
|
||||||
"""Line inserted in the response to the command !help"""
|
"""Line inserted in the response to the command !help"""
|
||||||
|
@ -9,7 +9,7 @@ import urllib.parse
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
def load(context):
|
||||||
global DATAS
|
global DATAS
|
||||||
|
@ -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>
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -8,7 +8,7 @@ from hooks import hook
|
|||||||
from .pyaspell import Aspell
|
from .pyaspell import Aspell
|
||||||
from .pyaspell import AspellError
|
from .pyaspell import AspellError
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny():
|
def help_tiny():
|
||||||
return "Check words spelling"
|
return "Check words spelling"
|
||||||
|
@ -8,7 +8,7 @@ from urllib.parse import quote
|
|||||||
from hooks import hook
|
from hooks import hook
|
||||||
from tools import web
|
from tools import web
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny():
|
def help_tiny():
|
||||||
return "Find french synonyms"
|
return "Find french synonyms"
|
||||||
|
@ -7,7 +7,7 @@ import json
|
|||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
import xmlparser
|
import xmlparser
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import re
|
|||||||
|
|
||||||
from tools import web
|
from tools import web
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
def load(context):
|
||||||
global DATAS
|
global DATAS
|
||||||
|
@ -15,7 +15,7 @@ from hooks import hook
|
|||||||
|
|
||||||
from .atom import Atom
|
from .atom import Atom
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny ():
|
def help_tiny ():
|
||||||
"""Line inserted in the response to the command !help"""
|
"""Line inserted in the response to the command !help"""
|
||||||
|
@ -6,7 +6,7 @@ import re
|
|||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def load(context):
|
def load(context):
|
||||||
global DATAS
|
global DATAS
|
||||||
|
@ -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>
|
|
@ -1,5 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
|
|
||||||
class Delayed:
|
|
||||||
def __init__(self):
|
|
||||||
self.names = dict()
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -6,7 +6,7 @@ import re
|
|||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
API_URL="http://worldcup.sfg.io/%s"
|
API_URL="http://worldcup.sfg.io/%s"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from urllib.request import urlopen
|
|||||||
|
|
||||||
from hooks import hook
|
from hooks import hook
|
||||||
|
|
||||||
nemubotversion = 3.3
|
nemubotversion = 3.4
|
||||||
|
|
||||||
def help_tiny():
|
def help_tiny():
|
||||||
"""Line inserted in the response to the command !help"""
|
"""Line inserted in the response to the command !help"""
|
||||||
|
@ -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]
|
|
Loading…
x
Reference in New Issue
Block a user