Сделал отображение задач, на странице проекта изменил requirements.txt

This commit is contained in:
Andrei 2023-02-13 18:43:15 +05:00
parent 03b523bea8
commit 8e97e40c38
6 changed files with 233 additions and 6 deletions

View File

@ -1,3 +1,4 @@
import datetime
import smtplib
from json import loads
from email.message import EmailMessage
@ -6,6 +7,7 @@ from data.users import User
from data.staff_projects import StaffProjects
from data import db_session
import uuid
import pymorphy2
def check_password(password=''):
@ -90,3 +92,31 @@ def save_project_logo(photo):
with open(filename, 'wb') as f:
photo.save(f)
return filename
def overdue_quest_project(quest):
if str(quest.deadline.date()) == str(datetime.datetime.now().date()):
quest.overdue = 'today'
elif quest.deadline < datetime.datetime.now():
quest.overdue = 'yes'
quest.time_left = 'Просрочено на' + round_date(quest.deadline)
else:
quest.overdue = 'no'
quest.time_left = 'Еще есть: ' + round_date(quest.deadline)
return quest
def round_date(date_time):
morph = pymorphy2.MorphAnalyzer()
difference = abs(date_time - datetime.datetime.now()).days
resp = ''
if difference // 365:
resp += f'{difference // 365} {morph.parse("год")[0].make_agree_with_number(difference // 365).word}'
difference -= 365 * (difference // 365)
if difference // 30:
resp += ', ' if resp else ' ' + f'{difference // 30}' \
f' {morph.parse("месяц")[0].make_agree_with_number(difference // 30).word}'
difference -= 30 * (difference // 30)
if difference:
resp += ', ' if resp else ' ' + f'{difference} {morph.parse("день")[0].make_agree_with_number(difference).word}'
return f'{resp}'

13
main.py
View File

@ -11,7 +11,8 @@ from itsdangerous import URLSafeTimedSerializer, SignatureExpired
from sqlalchemy import or_
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
from forms.edit_profile import EditProfileForm
from forms.login import LoginForm
from forms.find_project import FindProjectForm
@ -115,7 +116,15 @@ def project(id_project):
if current_user.id == current_project.creator or current_user.id in list(map(lambda x: x.user, staff)):
staff = list(map(lambda x: get_user_data(x), data_session.query(User).filter(
User.id.in_(list(map(lambda x: x.user, staff)))).all())) if staff else []
return render_template('project.html', project=current_project, title=current_project.name, staff=staff)
quests = data_session.query(Quests).filter(Quests.project == current_project.id).all()
if quests:
quests.sort(key=lambda x: (x.realized, x.deadline))
quests = list(map(lambda x: overdue_quest_project(x), quests))
return render_template('project.html',
project=current_project,
title=current_project.name,
staff=staff,
quests=quests)
else:
abort(403)
else:

Binary file not shown.

View File

@ -104,6 +104,9 @@
font-size: 3vw;
margin-bottom: 15px;
}
.header_title_2 {
width: 51vw !important;
}
.header_title {
width: 100%;
}
@ -147,4 +150,126 @@
flex-direction: row;
flex-wrap: nowrap;
width: 60vw;
justify-content: center;
align-items: flex-start;
}
.list_quests {
width: 95%;
margin-left: 2.5%;
margin-top: 2vw;
overflow-y: hidden;
overflow-x: hidden;
}
.quest_header_button {
height: 4.5vw;
width: 100%;
text-align: left;
border-radius: 5vw;
background-color: #9E795A;
border-color: #9E795A;
border-bottom-color: #9E795A;
color: #ffffff;
display: flex;
align-items: center;
}
.quest_button_block_one {
width: 50%;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.quest_title_block {
width: 90%;
height: 4vw;
display: flex;
align-items: center;
}
.quest_title {
overflow-y: hidden;
overflow-x: hidden;
max-height: 1.5vw;
font-size: 1.5vw;
display: flex;
align-items: center;
margin-top: 0.7vw;
margin-left: 1.8vw;
}
.deadline_block {
border-radius: 5vw !important;
width: 15vw;
height: 70%;
margin-top: 2%;
font-size: 1vw;
display: flex;
color: #000000 !important;
align-items: center;
justify-content: center;
flex-direction: row;
}
.quest_body_block {
background-color: #9E795A;
width: 100%;
height: 20vw;
border-radius: 2vw;
display: flex;
align-items: center;
justify-content: center;
}
.quest_body {
width: 94%;
height: 94%;
display: flex;
align-items: center;
justify-content: space-around;
}
.quest_description_block {
width: 70%;
height: 90%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.quest_description {
width: 100%;
height: 100%;
background-color: #dcb495;
border-radius: 2vw;
overflow-y: auto;
}
.quest_description::-webkit-scrollbar, .task_block::-webkit-scrollbar-thumb {
width: 0.8vw !important;
}
.quest_description::-webkit-scrollbar-thumb, .task_block::-webkit-scrollbar-thumb {
background-color: #d49d51 !important; /* цвет плашки */
border-radius: 5vw !important; /* закругления плашки */
border: 0.25vw solid #ffffff !important;
}
.quest_description_text {
margin: 20px;
}
.quest_solve_button {
width: 13vw;
height: 5vw;
background-color: #000000;
border: 2px solid #ffffff;
border-radius: 3vw;
margin-left: 2vw;
}
.quest_solve_link:hover {
text-decoration: none;
color: #000000;
}
.quest_solve_text {
width: 13vw;
height: 5vw;
text-align: center;
font-size: 1.5vw;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
#quest_solve_link_id {
display: none;
}

View File

@ -1,2 +1,7 @@
var edit_button = document.getElementById("edit_button");
edit_button.href = String(window.location.href) + '/edit';
var edit_button = document.getElementById("edit_button"),
new_task_link = document.getElementById("new_task_link"),
quest_solve_link = document.getElementById("quest_solve_link"),
quest_solve_link_id = document.getElementById("quest_solve_link_id");
edit_button.href = String(window.location.href) + '/edit';
new_task_link.href = String(window.location.href) + '/task/new';
quest_solve_link.href = String(window.location.href) + '/quest/' + quest_solve_link_id.className;

View File

@ -35,14 +35,72 @@
<div class="head_task">
<h3 class="header_title_2">Задачи</h3>
<div class="new_task_block">
<a class="new_task_link" href="/">
<a class="new_task_link" id="new_task_link" href="/">
<img class="new_task_image" src="../static/images/plus_b.png">
</a>
</div>
</div>
<div class="task_block">
<div class="task">
p
{% for quest in quests %}
<div class="accordion list_quests" id="accordionPanelsStayOpen{{ quest.id }}">
<div class="accordion-item quest">
<h2 class="accordion-header quest_header" id="panelsStayOpen-heading{{ quest.id }}">
<button class="accordion-button quest_header_button" type="button"
data-bs-toggle="collapse"
data-bs-target="#panelsStayOpen-collapse{{ quest.id }}" aria-expanded="true"
aria-controls="panelsStayOpen-collapse{{ quest.id }}">
<div class="quest_button_block_one">
<div class="quest_title_block">
<p class="quest_title">{{ quest.name }}</p>
</div>
</div>
{% if quest.overdue == 'yes' and quest.realized != 1 %}
<div class="deadline_block alert alert-danger" role="alert">
{{ quest.time_left }}
</div>
{% elif quest.overdue == 'today' and quest.realized != 1 %}
<div class="deadline_block alert alert-warning" role="alert">
Дедлайн сегодня
</div>
{% elif quest.overdue == 'no' and quest.realized != 1 %}
<div class="deadline_block alert alert-success" role="alert">
{{ quest.time_left }}
</div>
{% else %}
<div class="deadline_block alert alert-success" role="alert">
Задача выполнена
</div>
{% endif %}
</button>
</h2>
<div id="panelsStayOpen-collapse{{ quest.id }}"
class="accordion-collapse collapse quest_body_block"
aria-labelledby="panelsStayOpen-heading{{ quest.id }}">
<div class="accordion-body quest_body">
{% if quest.realized == 0 %}
<div class="quest_body">
<div class="quest_description_block">
<p class="quest_description_title">Описание</p>
<div class="quest_description">
<p class="quest_description_text">{{ quest.description }}</p>
</div>
</div>
<div class="quest_solve_button">
<a class="quest_solve_link" id="quest_solve_link">
<p id="quest_solve_link_id" class="{{ quest.id }}"></p>
<p class="quest_solve_text">Решить</p>
</a>
</div>
</div>
{% else %}
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>