diff --git a/forms/encrypt_form.py b/forms/encrypt_form.py new file mode 100644 index 0000000..341e4e7 --- /dev/null +++ b/forms/encrypt_form.py @@ -0,0 +1,6 @@ +from flask_wtf import FlaskForm +from wtforms import SubmitField + + +class EncryptForm(FlaskForm): + submit = SubmitField('Сохранить') diff --git a/functions.py b/functions.py index 287e043..a80cf07 100644 --- a/functions.py +++ b/functions.py @@ -4,7 +4,6 @@ import shutil import smtplib from json import loads from email.message import EmailMessage -from sqlalchemy import or_ from data.answer import Answer from data.proof_file import FileProof @@ -14,6 +13,7 @@ from data.users import User from data.staff_projects import StaffProjects from data.files import Files from data import db_session + import uuid import pymorphy2 @@ -259,3 +259,9 @@ def copy_template(template, new_project, data_session, current_user): list(map(lambda quest: copy_quests_from_template(quest, new_project, data_session, current_user), data_session.query(Quests).filter(Quests.project == template.id).all())) data_session.commit() + + +def save_admin_data(data, data_session): + user = data_session.query(User).filter(User.id == data[0][5:]).first() + if user.role != data[1]: + user.role = data[1] diff --git a/main.py b/main.py index 0a80e6c..cab86c2 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,6 @@ import datetime import os import logging -import shutil from flask import Flask, render_template, request, url_for from flask_login import login_user, current_user, LoginManager, logout_user, login_required @@ -12,10 +11,12 @@ from werkzeug.utils import redirect from itsdangerous import URLSafeTimedSerializer, SignatureExpired from sqlalchemy import or_ from json import loads +from waitress import serve from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo, \ overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data, delete_quest_data, \ - copy_template + copy_template, save_admin_data + from forms.edit_profile import EditProfileForm from forms.login import LoginForm from forms.find_project import FindProjectForm @@ -24,6 +25,7 @@ from forms.project import ProjectForm, AddFileProject from forms.recovery import RecoveryForm, NewPasswordForm from forms.conf_delete_project import DeleteProjectForm from forms.task import Task, AnswerTask +from forms.encrypt_form import EncryptForm from data.users import User from data.quests import Quests @@ -32,7 +34,7 @@ from data.proof_file import FileProof from data.files import Files from data.projects import Projects from data.staff_projects import StaffProjects -from waitress import serve +from data.roles import Roles from data import db_session app = Flask(__name__) @@ -58,6 +60,24 @@ def base(): return redirect('/projects') +@app.route('/admin', methods=['GET', 'POST']) +def admin(): + if current_user.is_authenticated: + if current_user.role == 1: + data_session = db_session.create_session() + roles, users = data_session.query(Roles).all(), \ + data_session.query(User).filter(User.id != current_user.id).all() + form = EncryptForm() + if request.method == 'POST': + data_form = request.form.to_dict() + del data_form['csrf_token'], data_form['submit'] + data_form = list(map(lambda x: (x[0], x[1]), data_form.items())) + list(map(lambda x: save_admin_data(x, data_session), data_form)) + data_session.commit() + return render_template('admin.html', title='Панель админа', roles=roles, users=users, form=form) + abort(404) + + @app.route('/template//create') def create_by_template(id_template): if current_user.is_authenticated: @@ -533,6 +553,7 @@ def projects(): @app.route('/profile', methods=['GET', 'POST']) def profile(): if current_user.is_authenticated: + data_session = db_session.create_session() form = EditProfileForm( CombinedMultiDict((request.files, request.form)), email=current_user.email, @@ -542,7 +563,6 @@ def profile(): birthday=current_user.birthday ) if form.del_photo.data: - data_session = db_session.create_session() user = data_session.query(User).filter(User.id == current_user.id).first() if not user: return render_template('profile.html', title='Профиль', form=form, @@ -551,7 +571,6 @@ def profile(): user.photo = 'static/images/none_logo.png' data_session.commit() if form.validate_on_submit(): - data_session = db_session.create_session() user = data_session.query(User).filter(User.id == current_user.id).first() if not user: return render_template('profile.html', title='Профиль', form=form, diff --git a/static/css/admin.css b/static/css/admin.css new file mode 100644 index 0000000..a140031 --- /dev/null +++ b/static/css/admin.css @@ -0,0 +1,92 @@ +.admin_page { + height: 120vw; + background-color: #dcb495; + display: flex; + flex-direction: column; + align-items: center; +} +.roles_block { + width: 90%; + height: 35vw; + background-color: #EDCBB0; + border-radius: 2vw; + overflow-y: auto; + overflow-x: hidden; +} +.roles_block::-webkit-scrollbar { + width: 0.8vw; /* ширина scrollbar */ +} +.roles_block::-webkit-scrollbar-thumb { + background-color: #d49d51; /* цвет плашки */ + border-radius: 5vw; /* закругления плашки */ + border: 0.25vw solid #ffffff; +} +.users_block { + margin: 20px; + display: flex; + flex-direction: column; + align-items: center; +} +.user { + width: 90%; + height: 5vw; + background-color: #ffffff; + border: 2px solid #9E795A; + border-radius: 3vw; + margin-top: 5px; + display: flex; + align-items: center; + justify-content: flex-start; + flex-direction: row; +} +.user_logo { + margin-left: 3px; + width: 4vw; + height: 4vw; + border-radius: 5vw; + background-color: #000000; +} +.user_names { + margin-left: 9px; + margin-top: 10px; + overflow-x: auto; + color: #000000 !important; + font-size: 2vw; +} +.roles_title { + font-size: 3vw; +} +.link_to_user { + width: 16vw; + height: 3.5vw; + display: flex; + align-items: center; + justify-content: flex-start; + flex-direction: row; + flex-wrap: no-wrap; + text-decoration: none; +} +.link_to_user:hover { + text-decoration: none; +} +.role_div { + width: 8vw; + height: 3vw; + border-radius: 2vw; +} +.save_button { + margin-top: 15px; + width: 35vw; + height: 5vw; + background-color: #000000; + color: #ffffff; + border-radius: 5vw; + vertical-align: middle; + font-size: 1.5vw; +} +.edit_user_form { + width: 90%; + display: flex; + flex-direction: column; + align-items: center; +} \ No newline at end of file diff --git a/static/css/projects.css b/static/css/projects.css index c9807b4..dfac4c2 100644 --- a/static/css/projects.css +++ b/static/css/projects.css @@ -116,6 +116,16 @@ } .project_title { font-size: 3.5vw; + overflow-y: hidden; + overflow-x: auto; +} +.project_title::-webkit-scrollbar { + height: 0.8vw; /* ширина scrollbar */ +} +.project_title::-webkit-scrollbar-thumb { + background-color: #d49d51; /* цвет плашки */ + border-radius: 5vw; /* закругления плашки */ + border: 0.25vw solid #ffffff; } .project_button_block_one { width: 50%; diff --git a/static/images/showcase.jpg b/static/images/showcase.jpg new file mode 100644 index 0000000..730881b Binary files /dev/null and b/static/images/showcase.jpg differ diff --git a/templates/admin.html b/templates/admin.html new file mode 100644 index 0000000..ec3f6c0 --- /dev/null +++ b/templates/admin.html @@ -0,0 +1,29 @@ + +{% extends "base.html" %} {% block content %} +
+

Изменение ролей

+
+ {{ form.hidden_tag() }} +
+
+ {% for user in users %} +
+ + +

{{user.name}}

+
+ +
+ {% endfor %} +
+
+ {{ form.submit(type="submit", class="save_button") }} +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 6561a81..8db6faf 100644 --- a/templates/base.html +++ b/templates/base.html @@ -30,6 +30,11 @@ + {% if current_user.role == 1 %} + + + + {% endif %} {% else %}