diff --git a/recopytex/scripts/prompts.py b/recopytex/scripts/prompts.py index e63ba3f..fd2c76d 100644 --- a/recopytex/scripts/prompts.py +++ b/recopytex/scripts/prompts.py @@ -2,15 +2,19 @@ # encoding: utf-8 -from prompt_toolkit import prompt +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", @@ -23,74 +27,95 @@ VALIDATE = [ REFUSE = ["n", "non", "NON", "no", "NO"] CANCEL = ["a", "annuler"] +STYLE = Style.from_dict( + { + "": "#93A1A1", + "validation": "#884444", + "appending": "#448844", + } +) + class CancelError(Exception): pass -def prompt_until_validate_or_cancel(func): - @wraps(func) - def wrapper(*args, **kwrd): - ans = func(*args, **kwrd) +def prompt_validate(question, cancelable=False, empty_means=1, style="validation"): + """Prompt for validation - confirm = prompt( - "C'est ok? (a ou annuler pour sortir) ", - completer=WordCompleter(VALIDATE + REFUSE + CANCEL), - ).lower() + :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 confirm in CANCEL: - raise CancelError + if cancelable: + question_ += "(a ou annuler pour sortir)" + choices += CANCEL - while confirm not in VALIDATE: - ans = func(*args, **ans, **kwrd) - confirm = prompt( - "C'est ok? (a ou annuler pour sortir) ", - completer=WordCompleter(VALIDATE + REFUSE + CANCEL), - ).lower() - if confirm in ["a", "annuler"]: + 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 - return ans - return wrapper + 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 -def prompt_until_validate(func): - @wraps(func) - def wrapper(*args, **kwrd): - ans = func(*args, **kwrd) - - confirm = prompt( - "C'est ok? ", - completer=WordCompleter(VALIDATE + REFUSE), - ).lower() - - while confirm not in VALIDATE: - ans = func(*args, **ans, **kwrd) - confirm = prompt( - "C'est ok? ", - completer=WordCompleter(VALIDATE + REFUSE), - ).lower() - return ans - - return wrapper - - -@prompt_until_validate +@prompt_until_validate() def prompt_exam(**kwrd): """ Prompt questions to edit an exam """ - - print("Nouvelle évaluation") + print(HTML("Nouvelle évaluation")) exam = {} exam["name"] = prompt("Nom de l'évaluation: ", default=kwrd.get("name", "DS")) tribes_name = [t["name"] for t in config["tribes"]] - exam["tribe"] = prompt( + exam["tribename"] = prompt( "Nom de la classe: ", - default=kwrd.get("tribe", ""), + 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"), @@ -112,98 +137,100 @@ def prompt_exam(**kwrd): return exam -@prompt_until_validate +@prompt_until_validate() def prompt_exercise(number=1, **kwrd): try: kwrd["name"] except KeyError: - print("Nouvel exercice") + print(HTML("Nouvel exercice")) else: - print(f"Modification de la questions {kwrd['name']}") + print(HTML(f"Modification de l'exercice: {kwrd['name']}")) exercise = {} exercise["name"] = prompt( - "Nom de l'exercice", default=kwrd.get("name", f"Exercice {number}") + "Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}") ) exercise["questions"] = [] try: - kwrd["questions"] + 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()) + exercise["questions"].append(prompt_question(**ques)) except CancelError: print("Cette question a été supprimée") last_question_id = exercise["questions"][-1]["id"] - # append = prompt("Ajouter une élément de notation", - # { - # "message": "Ajouter un élément de notation", - # "type": "confirm", - # "name": "append", - # - # ] - while prompt(append)["append"]: + appending = prompt_validate( + question="Ajouter un élément de notation? ", style="appending" + ) + while appending: try: exercise["questions"].append(prompt_question(last_question_id)) 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_or_cancel +@prompt_until_validate(cancelable=True) def prompt_question(last_question_id="1a", **kwrd): try: kwrd["id"] except KeyError: - print("Nouvelle question") + print(HTML("Nouvel élément de notation")) else: - print(f"Modification de la questions {kwrd['id']}") + print( + HTML( + f"Modification de l'élément {kwrd['id']} ({kwrd['commentaire']})" + ) + ) - questions = [ - { - "message": "Identifiant de la question", - "type": "input", - "name": "id", - "default": kwrd.get("id", "1a"), - }, - { - "message": "Competence", - "type": "input", - "name": "competence", - "default": kwrd.get("competence", "Cal"), - }, - { - "message": "Domaine", - "type": "input", - "name": "theme", - "default": kwrd.get("domain", ""), - }, - { - "message": "Commentaire", - "type": "input", - "name": "comment", - "default": kwrd.get("comment", ""), - }, - { - "message": "Évaluation par niveau", - "type": "confirm", - "name": "is_leveled", - "default": kwrd.get("is_leveled", True), - }, - { - "message": "Bareme", - "type": "input", - "name": "score_rate", - "default": kwrd.get("score_rate", "1"), - "validate": lambda x: x.isdigit(), - }, - ] - return prompt(questions) + question = {} + question["id"] = prompt( + "Identifiant de la question: ", + default=kwrd.get("id", "1a"), + ) + + question["competence"] = prompt( + "Competence: ", + default=kwrd.get("competence", "Cal"), + # validate + # completer + ) + + question["theme"] = prompt( + "Domaine: ", + default=kwrd.get("theme", ""), + # completer + ) + + 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 diff --git a/recopytex/scripts/recopytex.py b/recopytex/scripts/recopytex.py index 179e1c8..6404898 100644 --- a/recopytex/scripts/recopytex.py +++ b/recopytex/scripts/recopytex.py @@ -8,7 +8,7 @@ import papermill as pm import pandas as pd from datetime import datetime -from .getconfig import config +from .getconfig import config, CONFIGPATH from .prompts import prompt_exam, prompt_exercise from ..config import NO_ST_COLUMNS @@ -69,11 +69,10 @@ def new_exam(): for student in students: base_df[student] = "" - dest = ( - Path(config["source"]) - / exam["tribe"]["name"] - / f"{exam['date'].strftime('%y%m%d')}_{exam['name']}.csv" - ) + path = Path(config["source"]) / exam["tribe"]["name"] + path.mkdir(exist_ok=True) + + dest = path / f"{exam['date'].strftime('%y%m%d')}_{exam['name']}.csv" base_df.to_csv(dest, index=False) print(f"Le fichier note a été enregistré à {dest}") diff --git a/requirements.txt b/requirements.txt index 8d9d8e4..847f9d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ pandas click papermill -PyInquirer +prompt_toolkit