Pylint 7.5

This commit is contained in:
Степаненко Ольга 2021-04-27 19:41:47 +03:00
parent 3f6cf23f4e
commit 8e0610840d
7 changed files with 113 additions and 50 deletions

View File

@ -148,7 +148,10 @@ docker run -d -p 8000:8000 \
Пример полной конфигурации можно найти в [.env.example](.env.example). Почту и токен админа ZenDesk взять у руководителя (если вы не админ).
## Для проверки pylint используем:
pylint --load-plugins pylint_django ../access_controller
pylint --load-plugins pylint_django --disable=E5110,C0415 ../access_controller
## Для приведения файлов к стандарту PEP8 используем:
autopep8 --in-place <filename>
## Read more
- Zenpy: [http://docs.facetoe.com.au](http://docs.facetoe.com.au)

View File

@ -1,5 +1,11 @@
"""
Стандартный файл Django конфигурации приложения.
"""
from django.apps import AppConfig
class MainConfig(AppConfig):
"""
Старт приложения
"""
name = 'main'

View File

@ -38,7 +38,8 @@ def make_engineer(user_profile: UserProfile, who_changes: User) -> None:
Функция устанавливает пользователю роль инженера.
:param user_profile: Профиль пользователя
:return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "engineer"
:return: Вызов функции **update_role** с параметрами:
профиль пользователя, роль "engineer"
"""
update_role(user_profile, ROLES['engineer'])
@ -48,7 +49,8 @@ def make_light_agent(user_profile: UserProfile) -> None:
Функция устанавливает пользователю роль легкого агента.
:param user_profile: Профиль пользователя
:return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "light_agent"
:return: Вызов функции **update_role** с параметрами:
профиль пользователя, роль "light_agent"
"""
tickets = get_tickets_list(user_profile.user.email)
ticket: ZenpyTicket
@ -56,7 +58,8 @@ def make_light_agent(user_profile: UserProfile) -> None:
UnassignedTicket.objects.create(
assignee=user_profile.user,
ticket_id=ticket.id,
status=UnassignedTicketStatus.SOLVED if ticket.status == 'solved' else UnassignedTicketStatus.UNASSIGNED
status=UnassignedTicketStatus.SOLVED if ticket.status == 'solved'
else UnassignedTicketStatus.UNASSIGNED
)
if ticket.status == 'solved':
ticket.assignee_id = zenpy.solved_tickets_user_id
@ -79,7 +82,8 @@ def make_light_agent(user_profile: UserProfile) -> None:
def get_users_list() -> list:
"""
Функция **get_users_list** возвращает список пользователей Zendesk, относящихся к организации SYSTEM.
Функция **get_users_list** возвращает список
пользователей Zendesk, относящихся к организации SYSTEM.
"""
zendesk = zenpy
@ -101,7 +105,8 @@ def update_profile(user_profile: UserProfile) -> None:
Функция обновляет профиль пользователя в соответствии с текущим в Zendesk.
:param user_profile: Профиль пользователя
:return: Обновленный, в соответствие с текущими данными в Zendesk, профиль пользователя
:return: Обновленный, в соответствие с текущими данными
в Zendesk, профиль пользователя
"""
user = zenpy.get_user(user_profile.user.email)
user_profile.name = user.name
@ -135,7 +140,8 @@ def check_user_auth(email: str, password: str) -> bool:
"""
Функция проверяет, верны ли входные данные.
:raise: :class:`APIException`: исключение, вызываемое если пользователь не аутентифицирован
:raise: :class:`APIException`: исключение,
вызываемое если пользователь не аутентифицирован
"""
creds = {
'email': email,
@ -207,10 +213,12 @@ def daterange(start_date: timedelta, end_date: timedelta) -> list:
return dates
def get_timedelta(log: RoleChangeLogs, time: timedelta=None) -> timedelta:
def get_timedelta(log: RoleChangeLogs, time: timedelta = None) -> timedelta:
"""
Функция возвращает объект класса timedelta, который хранит промежуток времени от начала суток до момента,
который находится в log (объект класса RoleChangeLogs) или в time(datetime.time), если введён.
Функция возвращает объект класса timedelta,
который хранит промежуток времени от начала суток до момента,
который находится в log (объект класса RoleChangeLogs)
или в time(datetime.time), если введён.
:param log: Лог
:param time: Время
@ -278,7 +286,9 @@ class StatisticData:
"""
Функция возвращает статистику работы пользователя.
:return: Словарь statistic с применением формата отображения и интервала работы(если они есть). None, если были ошибки при создании.
:return: Словарь statistic с применением формата отображения
и интервала работы(если они есть).
None, если были ошибки при создании.
"""
if self.is_valid_statistic():
stat = self.statistic
@ -369,9 +379,12 @@ class StatisticData:
if self.interval == 'months':
# Переделываем ключи под формат('началоесяца - конец_месяца')
for key, value in stat.items():
current_month_start = max(self.start_date, date(year=key.year, month=key.month, day=1))
current_month_end = min(self.end_date, last_day_of_month(date(year=key.year, month=key.month, day=1)))
index = ' - '.join([str(current_month_start), str(current_month_end)])
current_month_start = max(self.start_date, date(
year=key.year, month=key.month, day=1))
current_month_end = min(self.end_date, last_day_of_month(
date(year=key.year, month=key.month, day=1)))
index = ' - '.join([str(current_month_start),
str(current_month_end)])
if new_stat.get(index):
new_stat[index] += value
else:
@ -392,16 +405,20 @@ class StatisticData:
def _init_data(self) -> None:
"""
Функция возвращает логи в диапазоне дат start_date - end_date для пользователя с указанным email.
Функция возвращает логи в диапазоне дат
start_date - end_date для пользователя с указанным email.
:return: Данные о смене статусов пользователя. Если пользователь не найден или интервал времени некорректен - ошибку.
:return: Данные о смене статусов пользователя.
Если пользователь не найден или интервал времени некорректен - ошибку.
"""
if not self.check_time():
self.errors += ['Конец диапазона должен быть позже начала диапазона и раньше текущего времени']
self.errors += [
'Конец диапазона должен быть позже начала диапазона и раньше текущего времени']
return
try:
self.data = RoleChangeLogs.objects.filter(
change_time__range=[self.start_date, self.end_date + timedelta(days=1)],
change_time__range=[self.start_date,
self.end_date + timedelta(days=1)],
user=User.objects.get(email=self.email),
).order_by('change_time')
except User.DoesNotExist:
@ -409,7 +426,8 @@ class StatisticData:
def _init_statistic(self) -> None:
"""
Функция заполняет словарь, в котором ключ - дата, значение - кол-во проработанных в этот день секунд.
Функция заполняет словарь, в котором ключ - дата,
значение - кол-во проработанных в этот день секунд.
:return: Статистика работы пользователя (statistic)
"""
@ -439,11 +457,14 @@ class StatisticData:
if current_log.change_time.date() != next_log.change_time.date():
self.statistic[current_log.change_time.date()] += (
timedelta(days=1) - get_timedelta(current_log)).total_seconds()
self.statistic[next_log.change_time.date()] += get_timedelta(next_log).total_seconds()
self.fill_daterange(current_log.change_time.date() + timedelta(days=1), next_log.change_time.date())
self.statistic[next_log.change_time.date(
)] += get_timedelta(next_log).total_seconds()
self.fill_daterange(current_log.change_time.date(
) + timedelta(days=1), next_log.change_time.date())
else:
elapsed_time = next_log.change_time - current_log.change_time
self.statistic[current_log.change_time.date()] += elapsed_time.total_seconds()
self.statistic[current_log.change_time.date(
)] += elapsed_time.total_seconds()
def post_engineer_logic(self, last_log: RoleChangeLogs) -> None:
"""
@ -451,16 +472,19 @@ class StatisticData:
:param last_log: Последний лог
"""
self.fill_daterange(last_log.change_time.date() + timedelta(days=1), self.end_date + timedelta(days=1))
self.fill_daterange(last_log.change_time.date(
) + timedelta(days=1), self.end_date + timedelta(days=1))
if last_log.change_time.date() == timezone.now().date():
self.statistic[last_log.change_time.date()] += (
get_timedelta(None, timezone.now().time()) - get_timedelta(last_log)
get_timedelta(None, timezone.now().time()) -
get_timedelta(last_log)
).total_seconds()
else:
self.statistic[last_log.change_time.date()] += (
timedelta(days=1) - get_timedelta(last_log)).total_seconds()
if self.end_date == timezone.now().date():
self.statistic[self.end_date] = get_timedelta(None, timezone.now().time()).total_seconds()
self.statistic[self.end_date] = get_timedelta(
None, timezone.now().time()).total_seconds()
def prev_engineer_logic(self, first_log: RoleChangeLogs) -> None:
"""
@ -470,7 +494,8 @@ class StatisticData:
"""
self.fill_daterange(max(User.objects.get(email=self.email).date_joined.date(), self.start_date),
first_log.change_time.date())
self.statistic[first_log.change_time.date()] += get_timedelta(first_log).total_seconds()
self.statistic[first_log.change_time.date(
)] += get_timedelta(first_log).total_seconds()
def fill_daterange(self, first: date, last: date, val: int = 24 * 3600) -> None:
"""
@ -488,7 +513,8 @@ class StatisticData:
Функция осуществляет обновление всех дней.
"""
self.statistic.clear()
self.fill_daterange(self.start_date, self.end_date + timedelta(days=1), 0)
self.fill_daterange(
self.start_date, self.end_date + timedelta(days=1), 0)
class DatabaseHandler(logging.Handler):
@ -571,9 +597,10 @@ def log(user: User, admin: int = 0) -> None:
def set_session_params_for_work_page(request: WSGIRequest, count: int = None, is_confirm: bool = True) -> \
Union[HttpResponsePermanentRedirect, HttpResponseRedirect]:
Union[HttpResponsePermanentRedirect, HttpResponseRedirect]:
"""
Функция для страницы получения прав, устанавливает данные сессии о успешности запроса и количестве назначенных тикетов.
Функция для страницы получения прав, устанавливает данные сессии
о успешности запроса и количестве назначенных тикетов.
:param request: Получение данных с рабочей страницы пользователя
:param count: Количество запрошенных тикетов

View File

@ -66,8 +66,7 @@ class CustomAuthenticationForm(AuthenticationForm):
error_messages = {
'invalid_login':
"Пожалуйста, введите правильные электронную почту и пароль. Оба поля "
"могут быть чувствительны к регистру."
,
"могут быть чувствительны к регистру.",
'inactive': "Аккаунт не активен.",
}

View File

@ -19,11 +19,15 @@ class UserProfile(models.Model):
('has_control_access', 'Can view admin page'),
)
user = models.OneToOneField(to=User, on_delete=models.CASCADE, help_text='Пользователь')
role = models.CharField(default='None', max_length=100, help_text='Глобальное имя роли пользователя')
custom_role_id = models.IntegerField(default=0, help_text='Код роли пользователя')
user = models.OneToOneField(
to=User, on_delete=models.CASCADE, help_text='Пользователь')
role = models.CharField(default='None', max_length=100,
help_text='Глобальное имя роли пользователя')
custom_role_id = models.IntegerField(
default=0, help_text='Код роли пользователя')
image = models.URLField(null=True, blank=True, help_text='Аватарка')
name = models.CharField(default='None', max_length=100, help_text='Имя пользователя на нашем сайте')
name = models.CharField(default='None', max_length=100,
help_text='Имя пользователя на нашем сайте')
@property
def zendesk_role(self):
@ -49,12 +53,16 @@ class RoleChangeLogs(models.Model):
"""
Модель для логирования изменений ролей пользователя.
"""
user = models.ForeignKey(to=User, on_delete=models.CASCADE,
user = models.ForeignKey(to=User,
on_delete=models.CASCADE,
help_text='Пользователь, которому присвоили другую роль')
old_role = models.IntegerField(default=0, help_text='Старая роль')
new_role = models.IntegerField(default=0, help_text='Присвоенная роль')
change_time = models.DateTimeField(default=timezone.now, help_text='Дата и время изменения роли')
changed_by = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='changed_by',
change_time = models.DateTimeField(
default=timezone.now, help_text='Дата и время изменения роли')
changed_by = models.ForeignKey(to=User,
on_delete=models.CASCADE,
related_name='changed_by',
help_text='Кем была изменена роль')
@ -64,13 +72,15 @@ class UnassignedTicketStatus(models.IntegerChoices):
:param UNASSIGNED: Снят с пользователя, перенесён в буферную группу
:param RESTORED: Авторство восстановлено
:param NOT_FOUND: Пока нас не было, тикет испарился из буферной группы. Дополнительные действия не требуются
:param NOT_FOUND: Пока нас не было, тикет испарился из буферной группы.
Дополнительные действия не требуются
:param CLOSED: Тикет уже был закрыт. Дополнительные действия не требуются
:param SOLVED: Тикет решён. Записан на пользователя с почтой SOLVED_TICKETS_EMAIL
"""
UNASSIGNED = 0, 'Снят с пользователя, перенесён в буферную группу'
RESTORED = 1, 'Авторство восстановлено'
NOT_FOUND = 2, 'Пока нас не было, тикет испарился из буферной группы. Дополнительные действия не требуются'
NOT_FOUND = 2, 'Пока нас не было, тикет испарился из ' \
'буферной группы. Дополнительные действия не требуются'
CLOSED = 3, 'Тикет уже был закрыт. Дополнительные действия не требуются'
SOLVED = 4, 'Тикет решён. Записан на пользователя с почтой SOLVED_TICKETS_EMAIL'
@ -79,6 +89,11 @@ class UnassignedTicket(models.Model):
"""
Модель не распределенного тикета.
"""
assignee = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='tickets', help_text='Пользователь, с которого снят тикет')
ticket_id = models.IntegerField(help_text='Номер тикера, для которого сняли ответственного')
status = models.IntegerField(choices=UnassignedTicketStatus.choices, default=UnassignedTicketStatus.UNASSIGNED, help_text='Статус тикета')
assignee = models.ForeignKey(to=User, on_delete=models.CASCADE,
related_name='tickets',
help_text='Пользователь, с которого снят тикет')
ticket_id = models.IntegerField(
help_text='Номер тикера, для которого сняли ответственного')
status = models.IntegerField(choices=UnassignedTicketStatus.choices,
default=UnassignedTicketStatus.UNASSIGNED,
help_text='Статус тикета')

View File

@ -1,3 +1,7 @@
"""
Основной функционал приложения.
"""
from smtplib import SMTPException
from typing import Dict, Any
@ -117,7 +121,8 @@ class CustomRegistrationView(RegistrationView):
@staticmethod
def set_permission(user: User) -> None:
"""
Функция дает разрешение на просмотр страница администратора, если пользователь имеет роль admin.
Функция дает разрешение на просмотр страница администратора,
если пользователь имеет роль admin.
:param user: авторизованный пользователь (получает разрешение, имея роль "admin")
"""
@ -131,7 +136,8 @@ class CustomRegistrationView(RegistrationView):
def get_success_url(self, user: User = None) -> Dict:
"""
Функция возвращает url-адрес страницы, куда нужно перейти после успешной/не успешной регистрации.
Функция возвращает url-адрес страницы, куда нужно перейти после
успешной/не успешной регистрации.
Используется самой django-registration.
:param user: пользователь, пытающийся зарегистрироваться
@ -172,11 +178,13 @@ def profile_page(request: WSGIRequest) -> HttpResponse:
@login_required()
def work_page(request: WSGIRequest, id: int) -> HttpResponse:
"""
Функция отображения страницы "Управления правами" для текущего пользователя (login_required).
Функция отображения страницы "Управления правами"
для текущего пользователя (login_required).
:param request: объект пользователя
:param id: id пользователя, используется для динамической адресации
:return: адресация на страницу "Управления правами" (либо на страницу "Авторизации", если id и user.id не совпадают
:return: адресация на страницу "Управления правами"
(либо на страницу "Авторизации", если id и user.id не совпадают)
"""
users = get_users_list()
if request.user.id == id:
@ -212,7 +220,8 @@ def work_page(request: WSGIRequest, id: int) -> HttpResponse:
@login_required()
def work_hand_over(request: WSGIRequest) -> HttpResponseRedirect:
"""
Функция позволяет текущему пользователю сдать права, а именно сменить в Zendesk роль с "engineer" на "light_agent"
Функция позволяет текущему пользователю сдать права,
а именно сменить в Zendesk роль с "engineer" на "light_agent"
:param request: данные текущего пользователя (login_required)
:return: перезагрузка текущей страницы после выполнения смены роли
@ -224,7 +233,9 @@ def work_hand_over(request: WSGIRequest) -> HttpResponseRedirect:
@login_required()
def work_become_engineer(request: WSGIRequest) -> HttpResponseRedirect:
"""
Функция позволяет текущему пользователю получить права, а именно сменить в Zendesk роль с "light_agent" на "engineer"
Функция позволяет текущему пользователю получить права,
а именно сменить в Zendesk роль с "light_agent" на
"engineer"
:param request: данные текущего пользователя (login_required)
:return: перезагрузка текущей страницы после выполнения смены роли
@ -371,7 +382,8 @@ def statistic_page(request: WSGIRequest) -> HttpResponse:
"""
Функция отображения страницы статистики (для "superuser").
:param request: данные о пользователе: email, время и интервал работы. Данные получаем через forms.StatisticForm
:param request: данные о пользователе: email, время и интервал работы.
Данные получаем через forms.StatisticForm
:return: адресация на страницу статистики
"""

View File

@ -17,3 +17,4 @@ sphinxcontrib-spelling==7.1.0
m2r == 0.2.1
pylint == 2.8.2
pylint-django == 2.4.4
autopep8 = 1.5.6