Сделал "файлы" на странице проекта
This commit is contained in:
parent
88c2430ef4
commit
3a7b651960
@ -1,5 +1,5 @@
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import StringField, SubmitField, TextAreaField, FileField
|
from wtforms import StringField, SubmitField, TextAreaField, FileField, MultipleFileField
|
||||||
from wtforms.validators import DataRequired
|
from wtforms.validators import DataRequired
|
||||||
|
|
||||||
|
|
||||||
@ -10,3 +10,8 @@ class ProjectForm(FlaskForm):
|
|||||||
submit = SubmitField('Создать')
|
submit = SubmitField('Создать')
|
||||||
del_photo = SubmitField('Удалить фотографию')
|
del_photo = SubmitField('Удалить фотографию')
|
||||||
save = SubmitField('Сохранить')
|
save = SubmitField('Сохранить')
|
||||||
|
|
||||||
|
|
||||||
|
class AddFileProject(FlaskForm):
|
||||||
|
file = MultipleFileField()
|
||||||
|
submit = SubmitField('Сохранить')
|
||||||
|
|||||||
31
functions.py
31
functions.py
@ -6,7 +6,6 @@ from email.message import EmailMessage
|
|||||||
from data.roles import Roles
|
from data.roles import Roles
|
||||||
from data.users import User
|
from data.users import User
|
||||||
from data.staff_projects import StaffProjects
|
from data.staff_projects import StaffProjects
|
||||||
from data.answer import Answer
|
|
||||||
from data.files import Files
|
from data.files import Files
|
||||||
from data import db_session
|
from data import db_session
|
||||||
import uuid
|
import uuid
|
||||||
@ -153,3 +152,33 @@ def find_files_answer(file_id):
|
|||||||
file = data_session.query(Files).filter(Files.id == file_id).first()
|
file = data_session.query(Files).filter(Files.id == file_id).first()
|
||||||
return {'id': file.id, 'path': file.path, 'user': file.user, 'up_date': file.up_date,
|
return {'id': file.id, 'path': file.path, 'user': file.user, 'up_date': file.up_date,
|
||||||
'current_path': file.path[str(file.path).find('all_projects') + 13:].split('/')}
|
'current_path': file.path[str(file.path).find('all_projects') + 13:].split('/')}
|
||||||
|
|
||||||
|
|
||||||
|
def file_tree(path):
|
||||||
|
tree = []
|
||||||
|
data_session = db_session.create_session()
|
||||||
|
h = 1
|
||||||
|
for i in os.listdir(path):
|
||||||
|
if os.path.isfile(f'{path}/{i}'):
|
||||||
|
file = data_session.query(Files).filter(Files.path == f'{path}/{i}').first()
|
||||||
|
tree.append(
|
||||||
|
{
|
||||||
|
'path': f'{path}/{i}',
|
||||||
|
'type': 'file',
|
||||||
|
'object': file if file else None,
|
||||||
|
'current_path': f'{path}/{i}'[str(file.path).find('all_projects') + 13:].split('/')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
tree.append(
|
||||||
|
{
|
||||||
|
'id': h,
|
||||||
|
'name': i,
|
||||||
|
'path': f'{path}/{i}',
|
||||||
|
'type': 'folder',
|
||||||
|
'tree': file_tree(f'{path}/{i}')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
h += 1
|
||||||
|
data_session.close()
|
||||||
|
return tree
|
||||||
|
|||||||
19
main.py
19
main.py
@ -12,12 +12,12 @@ from sqlalchemy import or_
|
|||||||
from json import loads
|
from json import loads
|
||||||
|
|
||||||
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
|
overdue_quest_project, save_proof_quest, find_files_answer, file_tree
|
||||||
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
|
||||||
from forms.register import RegisterForm
|
from forms.register import RegisterForm
|
||||||
from forms.project import ProjectForm
|
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 NewTask, AnswerTask
|
from forms.task import NewTask, AnswerTask
|
||||||
@ -55,6 +55,7 @@ def base():
|
|||||||
@app.route('/project/<int:id_project>/file/<int:id_file>/delete')
|
@app.route('/project/<int:id_project>/file/<int:id_file>/delete')
|
||||||
def delete_file(id_project, id_file):
|
def delete_file(id_project, id_file):
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
|
from_path = request.args.get('from') if request.args.get('from') else ''
|
||||||
data_session = db_session.create_session()
|
data_session = db_session.create_session()
|
||||||
current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
|
current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
|
||||||
current_file = data_session.query(Files).filter(Files.id == id_file).first()
|
current_file = data_session.query(Files).filter(Files.id == id_file).first()
|
||||||
@ -69,6 +70,8 @@ def delete_file(id_project, id_file):
|
|||||||
for i in current_proof:
|
for i in current_proof:
|
||||||
data_session.delete(i)
|
data_session.delete(i)
|
||||||
data_session.commit()
|
data_session.commit()
|
||||||
|
if from_path == 'project':
|
||||||
|
return redirect(f'/project/{current_project.id}')
|
||||||
return redirect(f'/project/{current_project.id}/quest/{quest[0]}')
|
return redirect(f'/project/{current_project.id}/quest/{quest[0]}')
|
||||||
data_session.commit()
|
data_session.commit()
|
||||||
return redirect(f'/project/{current_project.id}')
|
return redirect(f'/project/{current_project.id}')
|
||||||
@ -244,7 +247,7 @@ def edit_project(id_project):
|
|||||||
return redirect('/login')
|
return redirect('/login')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/project/<int:id_project>')
|
@app.route('/project/<int:id_project>', methods=['POST', 'GET'])
|
||||||
def project(id_project):
|
def project(id_project):
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
data_session = db_session.create_session()
|
data_session = db_session.create_session()
|
||||||
@ -262,11 +265,19 @@ def project(id_project):
|
|||||||
filter(lambda x: x.deadline is None, quests)) + list(
|
filter(lambda x: x.deadline is None, quests)) + list(
|
||||||
filter(lambda x: x.realized == 1, quests_sort))
|
filter(lambda x: x.realized == 1, quests_sort))
|
||||||
quests = list(map(lambda x: overdue_quest_project(x), quests))
|
quests = list(map(lambda x: overdue_quest_project(x), quests))
|
||||||
|
files_list = file_tree(f'static/app_files/all_projects/{current_project.id}')
|
||||||
|
form_file = AddFileProject()
|
||||||
|
if form_file.validate_on_submit():
|
||||||
|
if form_file.file.data[0].filename:
|
||||||
|
files = list(
|
||||||
|
map(lambda x: save_proof_quest(current_project, x, current_user.id), form_file.file.data))
|
||||||
return render_template('project.html',
|
return render_template('project.html',
|
||||||
project=current_project,
|
project=current_project,
|
||||||
title=current_project.name,
|
title=current_project.name,
|
||||||
staff=staff,
|
staff=staff,
|
||||||
quests=quests)
|
quests=quests,
|
||||||
|
file_tree=files_list,
|
||||||
|
form_file=form_file)
|
||||||
else:
|
else:
|
||||||
abort(403)
|
abort(403)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -83,6 +83,7 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
|
font-size: 1.5vw;
|
||||||
}
|
}
|
||||||
.link_to_user {
|
.link_to_user {
|
||||||
width: 26vw;
|
width: 26vw;
|
||||||
@ -122,7 +123,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.task_block {
|
.task_block, .list_files_block {
|
||||||
background-color: #EDCBB0;
|
background-color: #EDCBB0;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
height: 25vw;
|
height: 25vw;
|
||||||
@ -201,8 +202,8 @@
|
|||||||
}
|
}
|
||||||
.deadline_block {
|
.deadline_block {
|
||||||
border-radius: 5vw !important;
|
border-radius: 5vw !important;
|
||||||
width: 15vw;
|
width: 15vw !important;
|
||||||
height: 70%;
|
height: 3vw !important;
|
||||||
margin-top: 2%;
|
margin-top: 2%;
|
||||||
font-size: 1vw;
|
font-size: 1vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -306,4 +307,63 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.files_block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 95%;
|
||||||
|
height: 50vw;
|
||||||
|
}
|
||||||
|
.list_files {
|
||||||
|
margin: 2vw;
|
||||||
|
}
|
||||||
|
.files_title {
|
||||||
|
text-align: center;
|
||||||
|
color: #000000;
|
||||||
|
font-size: 4vw;
|
||||||
|
}
|
||||||
|
.file {
|
||||||
|
width: 98%;
|
||||||
|
display: flex;
|
||||||
|
background-color: #9E795A;
|
||||||
|
margin: 0.5vw;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: row;
|
||||||
|
height: 4.5vw;
|
||||||
|
border-radius: 2vw;
|
||||||
|
}
|
||||||
|
.file_head {
|
||||||
|
width: 30vw;
|
||||||
|
margin-left: 1vw;
|
||||||
|
height: 4vw;
|
||||||
|
background-color: #9E795A !important;
|
||||||
|
overflow-y: hidden;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
.file_head_path, .file_path {
|
||||||
|
font-size: 1.5vw;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 3vw;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #9E795A !important;
|
||||||
|
}
|
||||||
|
.file_buttons {
|
||||||
|
margin-right: 2vw;
|
||||||
|
}
|
||||||
|
.file_delete, .file_download, .upload_button {
|
||||||
|
border-radius: 1vw !important;
|
||||||
|
margin: 1vw;
|
||||||
|
width: 8vw;
|
||||||
|
height: 3vw;
|
||||||
|
}
|
||||||
|
.file_delete {
|
||||||
|
background-color: hsla(0, 100%, 62%, 0.785) !important;
|
||||||
|
border-color: hsla(0, 100%, 62%, 0.785) !important;
|
||||||
|
}
|
||||||
|
.button_text {
|
||||||
|
font-size: 1.3vw;
|
||||||
}
|
}
|
||||||
@ -5,4 +5,10 @@ quest_solve_link_id = document.getElementById("quest_solve_link_id");
|
|||||||
|
|
||||||
edit_button.href = String(window.location.href) + '/edit';
|
edit_button.href = String(window.location.href) + '/edit';
|
||||||
new_task_link.href = String(window.location.href) + '/quest/new';
|
new_task_link.href = String(window.location.href) + '/quest/new';
|
||||||
quest_solve_link.href = String(window.location.href) + '/quest/' + quest_solve_link_id.className;
|
|
||||||
|
function push_file()
|
||||||
|
{
|
||||||
|
document.getElementById('selectedFile').click();
|
||||||
|
document.getElementById('upload_button').style = 'display: block;';
|
||||||
|
document.getElementById('select_file_button').style = 'display: none;';
|
||||||
|
}
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="file_buttons">
|
<div class="file_buttons">
|
||||||
<div class="btn-group file_buttons_groud">
|
<div class="btn-group file_buttons_groud">
|
||||||
{% if current_user.id == project.creator or task.creator == current_user.id or file.user == current_user.id %}
|
{% if current_user.id == project.creator or task.creator == current_user.id or file['user'] == current_user.id %}
|
||||||
<a href="../file/{{ file.id }}/delete" class="btn btn-primary file_delete"><p class="button_text">Удалить</p></a>
|
<a href="../file/{{ file.id }}/delete" class="btn btn-primary file_delete"><p class="button_text">Удалить</p></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="../../../{{ file['path'] }}" download="" class="btn btn-primary file_download"><p class="button_text">Скачать</p></a>
|
<a href="../../../{{ file['path'] }}" download="" class="btn btn-primary file_download"><p class="button_text">Скачать</p></a>
|
||||||
|
|||||||
@ -126,7 +126,54 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="files_block">
|
<div class="files_block">
|
||||||
|
<div class="head_files">
|
||||||
|
<h2 class="files_title">Файлы</h2>
|
||||||
|
<form action="" method="post" class="file_form" id="file_form" enctype="multipart/form-data">
|
||||||
|
{{ form_file.hidden_tag() }}
|
||||||
|
<div class="form_data bottom_data">
|
||||||
|
{{ form_file.file(class="input_data", id="selectedFile", type="file", style="display: none;") }}
|
||||||
|
{% for error in form_file.file.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">{{ error }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{{ form_file.submit(type="submit", id="upload_button", class="btn btn-success upload_button",
|
||||||
|
style="display: none;") }}
|
||||||
|
<button type="button" class="upload_button btn btn-primary" id="select_file_button"
|
||||||
|
onclick="push_file()">Добавить
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="list_files_block">
|
||||||
|
<div class="list_files">
|
||||||
|
{% for item in file_tree %}
|
||||||
|
{% if item['type'] == 'file' %}
|
||||||
|
<div class="file">
|
||||||
|
<div class="file_head">
|
||||||
|
<nav class="file_head_group" style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb file_head_path">
|
||||||
|
{% for path in item['current_path'] %}
|
||||||
|
<li class="breadcrumb-item active file_path" aria-current="page">{{ path }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="file_buttons">
|
||||||
|
<div class="btn-group file_buttons_groud">
|
||||||
|
{% if current_user.id == project.creator or item['object'].user == current_user.id %}
|
||||||
|
<a href="../project/{{ project.id }}/file/{{ item['object'].id }}/delete?from=project"
|
||||||
|
class="btn btn-primary file_delete"><p class="button_text">Удалить</p></a>
|
||||||
|
{% endif %}
|
||||||
|
<a href="../../../{{ item['path'] }}" download="" class="btn btn-primary file_download"><p
|
||||||
|
class="button_text">Скачать</p></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% elif item['type'] == 'folder' %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="../static/js/project.js"></script>
|
<script type="text/javascript" src="../static/js/project.js"></script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user