Сделал тестовую версию системы администрирования
This commit is contained in:
parent
3617afce1b
commit
e4b97e7616
6
forms/encrypt_form.py
Normal file
6
forms/encrypt_form.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import SubmitField
|
||||||
|
|
||||||
|
|
||||||
|
class EncryptForm(FlaskForm):
|
||||||
|
submit = SubmitField('Сохранить')
|
||||||
@ -4,7 +4,6 @@ import shutil
|
|||||||
import smtplib
|
import smtplib
|
||||||
from json import loads
|
from json import loads
|
||||||
from email.message import EmailMessage
|
from email.message import EmailMessage
|
||||||
from sqlalchemy import or_
|
|
||||||
|
|
||||||
from data.answer import Answer
|
from data.answer import Answer
|
||||||
from data.proof_file import FileProof
|
from data.proof_file import FileProof
|
||||||
@ -14,6 +13,7 @@ from data.users import User
|
|||||||
from data.staff_projects import StaffProjects
|
from data.staff_projects import StaffProjects
|
||||||
from data.files import Files
|
from data.files import Files
|
||||||
from data import db_session
|
from data import db_session
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
import pymorphy2
|
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),
|
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.query(Quests).filter(Quests.project == template.id).all()))
|
||||||
data_session.commit()
|
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]
|
||||||
|
|||||||
29
main.py
29
main.py
@ -1,7 +1,6 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import shutil
|
|
||||||
|
|
||||||
from flask import Flask, render_template, request, url_for
|
from flask import Flask, render_template, request, url_for
|
||||||
from flask_login import login_user, current_user, LoginManager, logout_user, login_required
|
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 itsdangerous import URLSafeTimedSerializer, SignatureExpired
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
from json import loads
|
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, \
|
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, \
|
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.edit_profile import EditProfileForm
|
||||||
from forms.login import LoginForm
|
from forms.login import LoginForm
|
||||||
from forms.find_project import FindProjectForm
|
from forms.find_project import FindProjectForm
|
||||||
@ -24,6 +25,7 @@ from forms.project import ProjectForm, AddFileProject
|
|||||||
from forms.recovery import RecoveryForm, NewPasswordForm
|
from forms.recovery import RecoveryForm, NewPasswordForm
|
||||||
from forms.conf_delete_project import DeleteProjectForm
|
from forms.conf_delete_project import DeleteProjectForm
|
||||||
from forms.task import Task, AnswerTask
|
from forms.task import Task, AnswerTask
|
||||||
|
from forms.encrypt_form import EncryptForm
|
||||||
|
|
||||||
from data.users import User
|
from data.users import User
|
||||||
from data.quests import Quests
|
from data.quests import Quests
|
||||||
@ -32,7 +34,7 @@ from data.proof_file import FileProof
|
|||||||
from data.files import Files
|
from data.files import Files
|
||||||
from data.projects import Projects
|
from data.projects import Projects
|
||||||
from data.staff_projects import StaffProjects
|
from data.staff_projects import StaffProjects
|
||||||
from waitress import serve
|
from data.roles import Roles
|
||||||
from data import db_session
|
from data import db_session
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@ -58,6 +60,24 @@ def base():
|
|||||||
return redirect('/projects')
|
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/<int:id_template>/create')
|
@app.route('/template/<int:id_template>/create')
|
||||||
def create_by_template(id_template):
|
def create_by_template(id_template):
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
@ -533,6 +553,7 @@ def projects():
|
|||||||
@app.route('/profile', methods=['GET', 'POST'])
|
@app.route('/profile', methods=['GET', 'POST'])
|
||||||
def profile():
|
def profile():
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
|
data_session = db_session.create_session()
|
||||||
form = EditProfileForm(
|
form = EditProfileForm(
|
||||||
CombinedMultiDict((request.files, request.form)),
|
CombinedMultiDict((request.files, request.form)),
|
||||||
email=current_user.email,
|
email=current_user.email,
|
||||||
@ -542,7 +563,6 @@ def profile():
|
|||||||
birthday=current_user.birthday
|
birthday=current_user.birthday
|
||||||
)
|
)
|
||||||
if form.del_photo.data:
|
if form.del_photo.data:
|
||||||
data_session = db_session.create_session()
|
|
||||||
user = data_session.query(User).filter(User.id == current_user.id).first()
|
user = data_session.query(User).filter(User.id == current_user.id).first()
|
||||||
if not user:
|
if not user:
|
||||||
return render_template('profile.html', title='Профиль', form=form,
|
return render_template('profile.html', title='Профиль', form=form,
|
||||||
@ -551,7 +571,6 @@ def profile():
|
|||||||
user.photo = 'static/images/none_logo.png'
|
user.photo = 'static/images/none_logo.png'
|
||||||
data_session.commit()
|
data_session.commit()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
data_session = db_session.create_session()
|
|
||||||
user = data_session.query(User).filter(User.id == current_user.id).first()
|
user = data_session.query(User).filter(User.id == current_user.id).first()
|
||||||
if not user:
|
if not user:
|
||||||
return render_template('profile.html', title='Профиль', form=form,
|
return render_template('profile.html', title='Профиль', form=form,
|
||||||
|
|||||||
92
static/css/admin.css
Normal file
92
static/css/admin.css
Normal file
@ -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;
|
||||||
|
}
|
||||||
@ -116,6 +116,16 @@
|
|||||||
}
|
}
|
||||||
.project_title {
|
.project_title {
|
||||||
font-size: 3.5vw;
|
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 {
|
.project_button_block_one {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|||||||
BIN
static/images/showcase.jpg
Normal file
BIN
static/images/showcase.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
29
templates/admin.html
Normal file
29
templates/admin.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<link rel="stylesheet" href="../static/css/admin.css"/>
|
||||||
|
{% extends "base.html" %} {% block content %}
|
||||||
|
<div class="admin_page">
|
||||||
|
<h2 class="roles_title">Изменение ролей</h2>
|
||||||
|
<form action="" method="post" class="edit_user_form" enctype="multipart/form-data">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<div class="roles_block">
|
||||||
|
<div class="users_block">
|
||||||
|
{% for user in users %}
|
||||||
|
<div class="user">
|
||||||
|
<a class="link_to_user" href="/user/{{ user.login }}">
|
||||||
|
<img class="user_logo" src="{{user.photo}}">
|
||||||
|
<p class="user_names">{{user.name}}</p>
|
||||||
|
</a>
|
||||||
|
<select name="role_{{ user.id }}" class="form-select role_div" aria-label="Default select example">
|
||||||
|
{% for role in roles %}
|
||||||
|
<option class="role" value="{{ loop.index }}" {% if user.role == loop.index %}selected{%
|
||||||
|
endif %}>{{ roles[loop.index0].name }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ form.submit(type="submit", class="save_button") }}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -30,6 +30,11 @@
|
|||||||
<a class="nav_chapter" href="/showcase">
|
<a class="nav_chapter" href="/showcase">
|
||||||
<p class="nav_chapter_text">Витрина</p>
|
<p class="nav_chapter_text">Витрина</p>
|
||||||
</a>
|
</a>
|
||||||
|
{% if current_user.role == 1 %}
|
||||||
|
<a class="nav_chapter" href="/admin">
|
||||||
|
<p class="nav_chapter_text">Админ</p>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user