-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
117 lines (86 loc) · 2.94 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import json
import shutil
from atexit import register
from dataclasses import dataclass
from pathlib import Path
from random import randint
from tempfile import TemporaryDirectory
from typing import TYPE_CHECKING
from bs4 import BeautifulSoup
from flask import Flask, render_template
if TYPE_CHECKING:
from os import PathLike
type StrPath = str | PathLike[str]
app = Flask(__name__)
@dataclass
class Question:
text: str
answers: tuple[str, str, str, str]
correct_answer_id: int
def prefix_image_src(html: str, relative_path: Path, dir: Path) -> str:
if "<img" not in html:
return html
soup = BeautifulSoup(html, "lxml")
for img in soup("img"):
shutil.copy(f"{relative_path}/{img["src"]}", dir)
final_path = f"/static/{str(dir.name)}/{Path(img["src"]).name}"
img["src"] = final_path
return soup.prettify()
def json_to_questions(path: StrPath, dir: Path) -> list[Question]:
path = Path(path)
questions_files = path.glob("**/questions.json")
ret: list[Question] = []
for questions_file in questions_files:
with open(questions_file) as f:
questions = json.load(f)
for question in questions:
ret.append(
Question(
prefix_image_src(
questions_file.parent.joinpath(
question["text_file"]
).read_text(),
questions_file.parent,
dir,
),
tuple(question["answers"]),
question["correct_answer_id"],
)
)
return ret
with TemporaryDirectory(dir="static", delete=False) as tmpdir:
questions = json_to_questions("questions", Path(tmpdir))
register(lambda: shutil.rmtree(tmpdir))
@app.get("/")
def index():
return render_template("index.html")
@app.get("/question/<int:id>")
def get_question(id: int):
if id >= len(questions):
return f"<p>question {id} not found</p>"
question = questions[id]
return render_template(
"question.html", question=question, enumerate=enumerate, id=id
)
@app.get("/question/random")
def get_question_random():
id = randint(0, len(questions) - 1)
question = questions[id]
return render_template(
"question.html", question=question, enumerate=enumerate, id=id
)
@app.get("/question/<int:question_id>/answer/<int:answer_id>")
def check_answer(question_id: int, answer_id: int):
question = questions[question_id]
correct_answer_id = question.correct_answer_id
is_correct = False
if answer_id == correct_answer_id:
is_correct = True
return render_template(
"light_up_answer.html",
question=question,
is_correct=is_correct,
correct_answer_id=correct_answer_id,
answer_id=answer_id,
enumerate=enumerate,
)