recopytex/recopytex/scripts/prompts.py

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