Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
charset = utf-8
end_of_file = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
8 changes: 6 additions & 2 deletions ennead/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

from ennead.config import Config

from ennead.views.file import upload_file, uploaded_file, files_page
from ennead.views.auth import register, register_page, login, login_page, logout
from ennead.views.tasks import index
from ennead.views.admin import adm_task_list_page, task_edit_page, task_edit, task_delete
from ennead.views.system import render_markdown_endpoint
from ennead.views.file import upload_file, uploaded_file, files_page
from ennead.views.admin import (adm_task_list_page, add_task_set, choose_task_set,
task_edit_page, task_edit, task_delete)

from ennead.models.base import database
from ennead.models.file import File
Expand Down Expand Up @@ -63,6 +64,9 @@ def create_app(config_path: Optional[str] = None) -> Flask:
app.add_url_rule('/login', 'login', login, methods=['POST'])
app.add_url_rule('/logout', 'logout', logout)

app.add_url_rule('/adm/task_set', 'add_task_set', add_task_set, methods=['POST'])
app.add_url_rule('/adm/task_set/choose', 'choose_task_set', choose_task_set, methods=['POST'])

app.add_url_rule('/adm/tasks', 'adm_task_list_page', adm_task_list_page)
app.add_url_rule('/adm/tasks/<int:task_id>', 'task_edit_page', task_edit_page)
app.add_url_rule('/adm/tasks', 'task_edit', task_edit, methods=['POST'])
Expand Down
77 changes: 60 additions & 17 deletions ennead/templates/adm_task_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,68 @@

{% block title %}Редактирование задач{% endblock %}

{% set current_task_set = task_set %}

{% block head %}
<script>
window.addEventListener('load', function() {
var taskSetSelector = document.getElementById('task_set_selector');
taskSetSelector.addEventListener('change', function() {
window.location.href = '?task_set=' + taskSetSelector.value;
});
});
</script>
{% endblock %}

{% block body %}
<h2>Задачи {{task_set.name}}</h2>
{% for task in task_set.tasks %}
<div class="card mb-3">
<div class="card-body">
<div class="card-title">
<h3>
{{task.name}}
</h3>
<div class="mt-2 mb-3">
<form method="POST" action="{{url_for('choose_task_set')}}">
<div class="form-row mb-2 mr-0">
<div class="col-md-10">
<select id="task_set_selector" name="task_set" class="custom-select">
{% for task_set in task_set_list %}
<option value="{{task_set.id}}"
{% if task_set.id == current_task_set.id %}selected{% endif %}>
{{task_set.name}}
</option>
{% endfor %}
</select>
</div>
<div class="card-text text-muted">
Баллы: {{task.base_score}}
<input
type="submit"
class="btn btn-primary col-md-2"
value="Сделать активным"
{% if task_set.active %}disabled{% endif %}>
</div>
</form>
<form method="POST" action="{{url_for('add_task_set')}}">
<div class="form-row mr-0">
<div class="col-md-10">
<input name="name" id="name" class="form-control">
</div>
<input type="submit" class="btn btn-primary col-md-2" value="Добавить набор задач">
</div>
</form>
</div>
{% if task_set %}
{% for task in task_set.tasks %}
<div class="card mb-2">
<div class="card-body">
<div class="card-title">
<h3>
{{task.name}}
</h3>
</div>
<div class="card-text text-muted">
Баллы: {{task.base_score}}
</div>
<a href="{{url_for('task_edit_page', task_id=task.id)}}">
Редактировать
</a>
</div>
<a href="{{url_for('task_edit_page', task_id=task.id)}}">
Редактировать
</a>
</div>
</div>
{% endfor %}
<h2>Добавить задачу</h2>
{% include 'task_edit_form.html' %}
{% endfor %}
<h2>Добавить задачу</h2>
{% include 'task_edit_form.html' %}
{% endif %}
{% endblock %}
66 changes: 65 additions & 1 deletion ennead/views/admin.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
"""Views, used for task creation and editing"""

from typing import Any, Dict

from flask import abort, redirect, render_template, request, url_for
from werkzeug.wrappers import Response

from peewee import PeeweeException

from ennead.utils import require_teacher
from ennead.models.base import database
from ennead.models.task import Task, TaskSet


@require_teacher
def adm_task_list_page() -> Response:
"""GET /adm/tasks: list of tasks & creation of new"""

return render_template('adm_task_list.html', task_set=TaskSet.get(active=True))
task_set = None
task_set_criterion: Dict[str, Any] = {'active': True}
task_set_id = request.args.get('task_set')
if isinstance(task_set_id, (str, int)):
try:
task_set_criterion = {'id': int(task_set_id)}
except (TypeError, ValueError):
abort(400)
try:
task_set = TaskSet.get(**task_set_criterion)
except TaskSet.DoesNotExist:
pass

return render_template('adm_task_list.html', task_set=task_set, task_set_list=TaskSet.select())


@require_teacher
Expand Down Expand Up @@ -62,3 +80,49 @@ def task_delete(task_id: int) -> Response:

Task.delete().where(Task.id == task_id).execute()
return redirect(url_for('adm_task_list_page'))


@require_teacher
def add_task_set() -> Response:
"""POST /adm/task_set: add a new task set"""

if 'name' not in request.form:
abort(400)

task_set = TaskSet()
task_set.name = request.form['name']
task_set.active = True

with database.atomic() as transaction:
try:
TaskSet.update({TaskSet.active: False}).execute(database)
task_set.save()
except PeeweeException:
transaction.rollback()
abort(500)

return redirect(url_for('adm_task_list_page'))


@require_teacher
def choose_task_set() -> Response:
""""POST /adm/task_set/choose: select active task set"""

if 'task_set' not in request.form:
abort(400)

try:
task_set = TaskSet.get_by_id(int(request.form['task_set']))
except (ValueError, TypeError, TaskSet.DoesNotExist):
abort(400)

task_set.active = True
with database.atomic() as transaction:
try:
TaskSet.update({TaskSet.active: False}).execute(database)
task_set.save()
except PeeweeException:
transaction.rollback()
abort(500)

return redirect(url_for('adm_task_list_page'))