186 lines
8.1 KiB
Python
186 lines
8.1 KiB
Python
import mariadb as mdb
|
|
import json
|
|
import os
|
|
|
|
from test_list import TestList
|
|
from question_list import QuestionList
|
|
from response_option_list import ResponseOptionList
|
|
|
|
from httputils import escape_html
|
|
|
|
def readfile(path):
|
|
if os.path.exists(path):
|
|
return open(path).read()
|
|
|
|
class View:
|
|
def __init__(self, query_args, connector_data = {}):
|
|
self.args = query_args
|
|
self.connector_data = connector_data
|
|
self.db_connection = None
|
|
self.supported_modes = {
|
|
"test-list": self.render_test_list,
|
|
"create-test": self.render_create_test,
|
|
"view-test": self.render_view_test,
|
|
"create-question": self.render_create_question,
|
|
"edit-question": self.render_edit_question,
|
|
"view-question": self.render_view_question,
|
|
"create-response-option": self.render_create_response_option,
|
|
}
|
|
|
|
def get_db_connection(self):
|
|
if not self.db_connection:
|
|
args = {"host": "127.0.0.1",
|
|
"port": 3306,
|
|
"user": "root",
|
|
"password": "",
|
|
"database": "test_holder"}
|
|
|
|
settings = json.loads(readfile("cgi/db-settings.json"))
|
|
args.update(settings)
|
|
|
|
args.update(self.connector_data)
|
|
|
|
self.db_connection = mdb.connect(**args)
|
|
|
|
return self.db_connection
|
|
|
|
def format_page(self, header, subheader, content):
|
|
base_layout = readfile("html/base_layout.html")
|
|
|
|
base_layout = base_layout.replace("%HEADER%", header)
|
|
base_layout = base_layout.replace("%SUBHEADER%", subheader)
|
|
base_layout = base_layout.replace("%CONTENT%", content)
|
|
|
|
return base_layout
|
|
|
|
def render_page(self):
|
|
dbc = self.get_db_connection()
|
|
cur = dbc.cursor()
|
|
|
|
if 'mode' in self.args:
|
|
mode = self.args['mode']
|
|
else:
|
|
mode = "test-list"
|
|
|
|
if mode not in self.supported_modes:
|
|
header = f"<h2>No such view mode: {mode}</h2>"
|
|
subheader = f'<a href="/index.py">Повернутися на головну сторінку</a>'
|
|
content = ""
|
|
else:
|
|
header, subheader, content = self.supported_modes[mode](cur)
|
|
|
|
dbc.close()
|
|
return self.format_page(header, subheader, content)
|
|
|
|
def render_test_list(self, cur):
|
|
cur.execute("SELECT id FROM test;")
|
|
test_amount = len(list(cur))
|
|
header = f'<h2>Всього тестів: {test_amount}</h2>'
|
|
|
|
subheader = f'<input placeholder="Шукати тести"><br><a class="generic-button" href="?mode=create-test">Створити новий тест</a>'
|
|
|
|
content = TestList(cur).render()
|
|
|
|
return header, subheader, content
|
|
|
|
def render_create_test(self, cur):
|
|
header = f"<h2>Створити новий тест</h2>"
|
|
subheader = "<i>Введіть властивості нового тесту нижче</i>"
|
|
|
|
content = f'''<form action="/create-test.py">
|
|
<label for="name">Назва тесту:</label>
|
|
<input type="text" name="name" placeholder="Введіть назву..." required><br>
|
|
<input type="submit" value="Створити">
|
|
</form>'''
|
|
|
|
return header, subheader, content
|
|
|
|
def render_view_test(self, cur):
|
|
cur.execute(f"SELECT name FROM test WHERE id = {self.args['id']};")
|
|
test_name = next(iter(cur), [None])[0]
|
|
|
|
if not test_name:
|
|
header = f"<h2>Такого тесту не існує: {self.args['id']}</h2>"
|
|
subheader = f'<a href="/index.py">Повернутися на головну сторінку</a>'
|
|
content = ""
|
|
return header, subheader, content
|
|
|
|
header = f'<span class="view-test-id-tag">#{self.args["id"]}</span><span class="view-test-main-tag">{test_name}</span>'
|
|
|
|
subheader = f'<a class="generic-button" href="?mode=create-question&test_id={self.args["id"]}">Додати запитання</a>'
|
|
|
|
content = QuestionList(cur).render(self.args['id'])
|
|
|
|
return header, subheader, content
|
|
|
|
def render_create_question(self, cur):
|
|
header = f"<h2>Додати нове запитання</h2>"
|
|
subheader = "<i>Введіть властивості нового запитання нижче</i>"
|
|
|
|
content = f'''<form action="/create-question.py">
|
|
<input type="text" name="test_id" value="{self.args["test_id"]}" style="display:none;">
|
|
<label for="title">Текст запитання:</label>
|
|
<input type="text" name="title" placeholder="Введіть запитання..." required><br>
|
|
<label for="mtime">Максимальний час на відповідь (в сек):</label>
|
|
<input type="number" name="mtime" placeholder="Наприклад, 120"><br>
|
|
<input type="submit" value="Додати">
|
|
</form>'''
|
|
|
|
return header, subheader, content
|
|
|
|
def render_edit_question(self, cur):
|
|
cur.execute(f"SELECT title, mtime FROM question WHERE id = {self.args['id']};")
|
|
question_title, question_max_time = next(iter(cur), [None, None])
|
|
|
|
if not question_title:
|
|
header = f"<h2>Такого запитання не існує: {self.args['id']}</h2>"
|
|
subheader = f'<a href="/index.py">Повернутися на головну сторінку</a>'
|
|
content = ""
|
|
return header, subheader, content
|
|
|
|
header = f"<h2>Змінити запитання</h2>"
|
|
subheader = "<i>Відредагуйте властивості запитання нижче</i>"
|
|
|
|
content = f'''<form action="/edit-question.py">
|
|
<input type="text" name="question_id" value="{self.args["id"]}" style="display:none;">
|
|
<label for="title">Текст запитання:</label>
|
|
<input type="text" name="title" placeholder="Введіть запитання..." value="{escape_html(question_title)}" required><br>
|
|
<label for="mtime">Максимальний час на відповідь (в сек):</label>
|
|
<input type="number" name="mtime" placeholder="Наприклад, 120"><br>
|
|
<input type="submit" value="Зберегти зміни">
|
|
</form>'''
|
|
|
|
return header, subheader, content
|
|
|
|
def render_view_question(self, cur):
|
|
cur.execute(f"SELECT title FROM question WHERE id = {self.args['id']};")
|
|
question_name = next(iter(cur), [None])[0]
|
|
|
|
if not question_name:
|
|
header = f"<h2>Такого запитання не існує: {self.args['id']}</h2>"
|
|
subheader = f'<a href="/index.py">Повернутися на головну сторінку</a>'
|
|
content = ""
|
|
return header, subheader, content
|
|
|
|
header = f'<span class="view-test-id-tag">#{self.args["id"]}</span><span class="view-test-main-tag">{question_name}</span>'
|
|
|
|
subheader = f'<a class="generic-button" href="?mode=create-response-option&question_id={self.args["id"]}">Додати варіант відповіді</a>' + \
|
|
f'<a class="sub-button" href="?mode=edit-question&id={self.args["id"]}">Редагувати запитання</a>'
|
|
|
|
content = ResponseOptionList(cur).render(self.args['id'])
|
|
|
|
return header, subheader, content
|
|
|
|
def render_create_response_option(self, cur):
|
|
header = f"<h2>Додати новий варіант відповіді</h2>"
|
|
subheader = "<i>Введіть властивості варіанту відповіді нижче</i>"
|
|
|
|
content = f'''<form action="/create-response-option.py">
|
|
<input type="text" name="question_id" value="{self.args["question_id"]}" style="display:none;">
|
|
<label for="label">Текст відповіді:</label>
|
|
<input type="text" name="label" placeholder="Введіть текст відповіді..." required><br>
|
|
<input type="submit" value="Додати">
|
|
</form>'''
|
|
|
|
return header, subheader, content
|