diff --git a/main.py b/main.py index b62c3aa..d5c06d1 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from flask import render_template, redirect, url_for, session, g, request, flash, abort +from flask import render_template, redirect, url_for, session, g, request, flash, abort, Response from flask_restful import Api from markdown import markdown from datetime import datetime, timedelta @@ -265,8 +265,8 @@ def upload_questions(): with form.file.data.stream as ff: x = json.load(ff) for question in x: - q = Question(id=question['num'], title=question['statement'], text=question['extra'], - points=question['points'], number=question['num'] * 10) + q = Question(id=question['num'], title=question['statement'], points=question['points'], + text=question['extra'] or None, number=question['num'] * 10) for i, answer in enumerate(question['choices']): a = Answer(text=answer, is_correct=(i == question['correct']), question_id=question['num']) @@ -274,6 +274,9 @@ def upload_questions(): db.session.add(q) db.session.commit() flash('Успешно импортировано!', 'success') + else: + for err in form.file.errors: + flash(err) return redirect(url_for('manage_questions')) @@ -290,5 +293,23 @@ def delete_question(question_id): return redirect(back('manage_questions')) +@app.route('/admin/questions/export') +@admin_required +def export_questions(): + questions = Question.query.all() + data = [] + for q in questions: + d = {'num': q.id, 'statement': q.title, 'extra': q.text or '', 'choices': [], + 'points': q.points} + for i, a in enumerate(q.answers): + d['choices'].append(a.text) + if a.is_correct: + d['correct'] = i + data.append(d) + json_data = json.dumps(data, indent=4) + return Response(response=json_data, mimetype='application/json', + headers={'Content-Disposition': 'attachment; filename="tasks.json"'}) + + if __name__ == '__main__': app.run() diff --git a/static/css/style.css b/static/css/style.css index 2631edf..c082480 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1,6 +1,6 @@ @import url('https://fonts.googleapis.com/css?family=Roboto'); -.question-card, .mb4 { +.question-card, .bottom-space { margin-bottom: 4rem; } diff --git a/static/js/script.js b/static/js/script.js index 6ff6074..733bbcf 100644 --- a/static/js/script.js +++ b/static/js/script.js @@ -33,6 +33,13 @@ function uploadAllAnswers() { } } +function destructive_confirm(ev) { + if (!confirm('Это — деструктивная операция. Продолжить?')) { + ev.preventDefault(); + ev.stopPropagation(); + } +} + $('textarea').on('input', function (){ $(this).height(0).height(this.scrollHeight); }); @@ -41,11 +48,7 @@ $(document).ready(function () { $('textarea').trigger('input'); }); -$('.destructive-confirm').click(function (ev) { - if (!confirm('Это — деструктивная операция. Продолжить?')) { - ev.preventDefault(); - ev.stopPropagation(); - } -}); +$('a.destructive-confirm').click(destructive_confirm); +$('form.destructive-confirm').submit(destructive_confirm); $('#noscript').hide(); diff --git a/templates/question_form.html b/templates/question_form.html index cac08a8..646ab34 100644 --- a/templates/question_form.html +++ b/templates/question_form.html @@ -1,4 +1,4 @@ -
+ {{ form.hidden_tag() }} {# question, caption, points, +answers, +number #}
diff --git a/templates/questions.html b/templates/questions.html index 8efd0a7..b916a6d 100644 --- a/templates/questions.html +++ b/templates/questions.html @@ -5,22 +5,21 @@

Вопросы

{% for q in questions %} {% include 'card.html' %} {% endfor %} +

Экспортировать вопросы

+

+ Скачать файл с вопросами в формате JSON +

Добавить вопрос

{% include 'question_form.html' %}

Импортировать вопросы

После импорта все вопросы, ответы и решения будут сброшены!

- + {{ import_form.hidden_tag() }}
{{ import_form.file(class='custom-file-input' + (' is-invalid' if import_form.file.errors else ''), accept='application/json') }} {{ import_form.file.label(class='custom-file-label') }} - {% for error in import_form.file.errors %} -
- {{ error }} -
- {% endfor %}
- {{ import_form.submit(class='btn btn-primary destructive-confirm') }} + {{ import_form.submit(class='btn btn-primary') }} {% endblock %} {% block scripts %} diff --git a/templates/result.html b/templates/result.html index fed6b1a..49c7699 100644 --- a/templates/result.html +++ b/templates/result.html @@ -6,7 +6,7 @@

Результаты пользователя {{ user.name }}

{% else %}

Поздравляю!

{% endif %} -

+

{% if admin %} Набрано баллов: {% else %} @@ -27,7 +27,7 @@

{% for q in failed %} {% include 'card.html' %} {% else %} -

Отсутствуют

+

Отсутствуют

{% endfor %}

Пропущенные вопросы

@@ -35,7 +35,7 @@

Пропущенные вопросы

{% for q in skipped %} {% include 'card.html' %} {% else %} -

Отсутствуют

+

Отсутствуют

{% endfor %} {% endblock %}