234 lines
6.0 KiB
Python
234 lines
6.0 KiB
Python
#!/usr/bin/env python
|
|
# encoding: utf-8
|
|
|
|
|
|
from prompt_toolkit import prompt, HTML, ANSI
|
|
from prompt_toolkit import print_formatted_text as print
|
|
from prompt_toolkit.styles import Style
|
|
from prompt_toolkit.validation import Validator
|
|
from prompt_toolkit.completion import WordCompleter
|
|
from unidecode import unidecode
|
|
from datetime import datetime
|
|
from functools import wraps
|
|
import sys
|
|
|
|
from .getconfig import config
|
|
|
|
|
|
VALIDATE = [
|
|
"o",
|
|
"ok",
|
|
"OK",
|
|
"oui",
|
|
"OUI",
|
|
"yes",
|
|
"YES",
|
|
]
|
|
REFUSE = ["n", "non", "NON", "no", "NO"]
|
|
CANCEL = ["a", "annuler"]
|
|
|
|
STYLE = Style.from_dict(
|
|
{
|
|
"": "#93A1A1",
|
|
"validation": "#884444",
|
|
"appending": "#448844",
|
|
}
|
|
)
|
|
|
|
|
|
class CancelError(Exception):
|
|
pass
|
|
|
|
|
|
def prompt_validate(question, cancelable=False, empty_means=1, style="validation"):
|
|
"""Prompt for validation
|
|
|
|
:param question: Text to print to ask the question.
|
|
:param cancelable: enable cancel answer
|
|
:param empty_means: result for no answer
|
|
:return:
|
|
0 -> Refuse
|
|
1 -> Validate
|
|
-1 -> cancel
|
|
"""
|
|
question_ = question
|
|
choices = VALIDATE + REFUSE
|
|
|
|
if cancelable:
|
|
question_ += "(a ou annuler pour sortir)"
|
|
choices += CANCEL
|
|
|
|
ans = prompt(
|
|
[
|
|
(f"class:{style}", question_),
|
|
],
|
|
completer=WordCompleter(choices),
|
|
style=STYLE,
|
|
).lower()
|
|
|
|
if ans == "":
|
|
return empty_means
|
|
if ans in VALIDATE:
|
|
return 1
|
|
if cancelable and ans in CANCEL:
|
|
return -1
|
|
return 0
|
|
|
|
|
|
def prompt_until_validate(question="C'est ok? ", cancelable=False):
|
|
def decorator(func):
|
|
@wraps(func)
|
|
def wrapper(*args, **kwrd):
|
|
ans = func(*args, **kwrd)
|
|
|
|
confirm = prompt_validate(question, cancelable)
|
|
|
|
if confirm == -1:
|
|
raise CancelError
|
|
|
|
while not confirm:
|
|
sys.stdout.flush()
|
|
ans = func(*args, **ans, **kwrd)
|
|
confirm = prompt_validate(question, cancelable)
|
|
if confirm == -1:
|
|
raise CancelError
|
|
return ans
|
|
|
|
return wrapper
|
|
|
|
return decorator
|
|
|
|
|
|
@prompt_until_validate()
|
|
def prompt_exam(**kwrd):
|
|
""" Prompt questions to edit an exam """
|
|
print(HTML("<b>Nouvelle évaluation</b>"))
|
|
exam = {}
|
|
exam["name"] = prompt("Nom de l'évaluation: ", default=kwrd.get("name", "DS"))
|
|
|
|
tribes_name = [t["name"] for t in config["tribes"]]
|
|
|
|
exam["tribename"] = prompt(
|
|
"Nom de la classe: ",
|
|
default=kwrd.get("tribename", ""),
|
|
completer=WordCompleter(tribes_name),
|
|
validator=Validator.from_callable(lambda x: x in tribes_name),
|
|
)
|
|
exam["tribe"] = [t for t in config["tribes"] if t["name"] == exam["tribename"]][0]
|
|
|
|
exam["date"] = prompt(
|
|
"Date de l'évaluation (%y%m%d): ",
|
|
default=kwrd.get("date", datetime.today()).strftime("%y%m%d"),
|
|
validator=Validator.from_callable(lambda x: (len(x) == 6) and x.isdigit()),
|
|
)
|
|
exam["date"] = datetime.strptime(exam["date"], "%y%m%d")
|
|
|
|
exam["term"] = prompt(
|
|
"Trimestre: ",
|
|
validator=Validator.from_callable(lambda x: x.isdigit()),
|
|
default=kwrd.get("term", "1"),
|
|
)
|
|
|
|
return exam
|
|
|
|
|
|
@prompt_until_validate()
|
|
def prompt_exercise(number=1, completer={}, **kwrd):
|
|
exercise = {}
|
|
try:
|
|
kwrd["name"]
|
|
except KeyError:
|
|
print(HTML("<b>Nouvel exercice</b>"))
|
|
exercise["name"] = prompt(
|
|
"Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}")
|
|
)
|
|
else:
|
|
print(HTML(f"<b>Modification de l'exercice: {kwrd['name']}</b>"))
|
|
exercise["name"] = kwrd["name"]
|
|
|
|
exercise["questions"] = []
|
|
|
|
try:
|
|
kwrd["questions"][0]
|
|
except KeyError:
|
|
last_question_id = "1a"
|
|
except IndexError:
|
|
last_question_id = "1a"
|
|
else:
|
|
for ques in kwrd["questions"]:
|
|
try:
|
|
exercise["questions"].append(
|
|
prompt_question(completer=completer, **ques)
|
|
)
|
|
except CancelError:
|
|
print("Cette question a été supprimée")
|
|
last_question_id = exercise["questions"][-1]["id"]
|
|
|
|
appending = prompt_validate(
|
|
question="Ajouter un élément de notation? ", style="appending"
|
|
)
|
|
while appending:
|
|
try:
|
|
exercise["questions"].append(
|
|
prompt_question(last_question_id, completer=completer)
|
|
)
|
|
except CancelError:
|
|
print("Cette question a été supprimée")
|
|
else:
|
|
last_question_id = exercise["questions"][-1]["id"]
|
|
appending = prompt_validate(
|
|
question="Ajouter un élément de notation? ", style="appending"
|
|
)
|
|
|
|
return exercise
|
|
|
|
|
|
@prompt_until_validate(cancelable=True)
|
|
def prompt_question(last_question_id="1a", completer={}, **kwrd):
|
|
try:
|
|
kwrd["id"]
|
|
except KeyError:
|
|
print(HTML("<b>Nouvel élément de notation</b>"))
|
|
else:
|
|
print(
|
|
HTML(f"<b>Modification de l'élément {kwrd['id']} ({kwrd['comment']})</b>")
|
|
)
|
|
|
|
question = {}
|
|
question["id"] = prompt(
|
|
"Identifiant de la question: ",
|
|
default=kwrd.get("id", "1a"),
|
|
)
|
|
|
|
question["competence"] = prompt(
|
|
"Competence: ",
|
|
default=kwrd.get("competence", list(config["competences"].keys())[0]),
|
|
completer=WordCompleter(config["competences"].keys()),
|
|
validator=Validator.from_callable(lambda x: x in config["competences"].keys()),
|
|
)
|
|
|
|
question["theme"] = prompt(
|
|
"Domaine: ",
|
|
default=kwrd.get("theme", ""),
|
|
completer=WordCompleter(completer.get("theme", [])),
|
|
)
|
|
|
|
question["comment"] = prompt(
|
|
"Commentaire: ",
|
|
default=kwrd.get("comment", ""),
|
|
)
|
|
|
|
question["is_leveled"] = prompt(
|
|
"Évaluation par niveau: ",
|
|
default=kwrd.get("is_leveled", "1"),
|
|
# validate
|
|
)
|
|
|
|
question["score_rate"] = prompt(
|
|
"Barème: ",
|
|
default=kwrd.get("score_rate", "1"),
|
|
# validate
|
|
)
|
|
|
|
return question
|