Add documentation to new forms, and first part of extra_func

This commit is contained in:
Степаненко Ольга 2021-03-14 12:42:18 +03:00
parent be6005c4be
commit c9ae302103
3 changed files with 138 additions and 82 deletions

View File

@ -43,8 +43,8 @@ class ZendeskAdmin:
""" """
Функция осуществляет проверку существования пользователя в Zendesk по email. Функция осуществляет проверку существования пользователя в Zendesk по email.
:param email: :param email: Email пользователя
:return: :return: Является ли зарегистрированным
""" """
return True if self.admin.search(email, type='user') else False return True if self.admin.search(email, type='user') else False
@ -52,8 +52,8 @@ class ZendeskAdmin:
""" """
Функция возвращает имя пользователя по его email. Функция возвращает имя пользователя по его email.
:param email: :param email: Email пользователя
:return: :return: Имя пользователя
""" """
user = self.admin.users.search(email).values[0] user = self.admin.users.search(email).values[0]
return user.name return user.name
@ -62,8 +62,8 @@ class ZendeskAdmin:
""" """
Функция возвращает роль пользователя по его email. Функция возвращает роль пользователя по его email.
:param email: :param email: Email пользователя
:return: :return: Роль пользователя
""" """
user = self.admin.users.search(email).values[0] user = self.admin.users.search(email).values[0]
return user.role return user.role
@ -72,8 +72,8 @@ class ZendeskAdmin:
""" """
Функция возвращает id пользователя по его email Функция возвращает id пользователя по его email
:param email: :param email: Email пользователя
:return: :return: ID пользователя
""" """
user = self.admin.users.search(email).values[0] user = self.admin.users.search(email).values[0]
return user.id return user.id
@ -82,18 +82,18 @@ class ZendeskAdmin:
""" """
Функция возвращает url-ссылку на аватар пользователя по его email. Функция возвращает url-ссылку на аватар пользователя по его email.
:param email: :param email: Email пользователя
:return: :return: Аватар пользователя
""" """
user = self.admin.users.search(email).values[0] user = self.admin.users.search(email).values[0]
return user.photo['content_url'] if user.photo else None return user.photo['content_url'] if user.photo else None
def get_user(self, email: str): def get_user(self, email: str):
""" """
Функция возвращает пользователя (объект) по его email Функция возвращает пользователя (объект) по его email.
:param email: email пользователя :param email: Email пользователя
:return: email пользователя, найденного в БД :return: Объект пользователя, найденного в БД
""" """
return self.admin.users.search(email).values[0] return self.admin.users.search(email).values[0]
@ -101,8 +101,8 @@ class ZendeskAdmin:
""" """
Функция возвращает организацию, к которой относится пользователь по его email. Функция возвращает организацию, к которой относится пользователь по его email.
:param email: :param email: Email пользователя
:return: :return: Организация пользователя
""" """
user = self.admin.users.search(email).values[0] user = self.admin.users.search(email).values[0]
return user.organization.name if user.organization else None return user.organization.name if user.organization else None
@ -138,9 +138,9 @@ def update_role(user_profile: UserProfile, role: str) -> UserProfile:
""" """
Функция меняет роль пользователя. Функция меняет роль пользователя.
:param user_profile: :param user_profile: Профиль пользователя
:param role: :param role: Новая роль
:return: :return: Пользователь с обновленной ролью
""" """
zendesk = ZendeskAdmin() zendesk = ZendeskAdmin()
user = zendesk.get_user(user_profile.user.email) user = zendesk.get_user(user_profile.user.email)
@ -152,8 +152,8 @@ def make_engineer(user_profile: UserProfile) -> UserProfile:
""" """
Функция устанавливапет пользователю роль инженера. Функция устанавливапет пользователю роль инженера.
:param user_profile: :param user_profile: Профиль пользователя
:return: :return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "endineer"
""" """
update_role(user_profile, ROLES['engineer']) update_role(user_profile, ROLES['engineer'])
@ -162,8 +162,8 @@ def make_light_agent(user_profile: UserProfile) -> UserProfile:
""" """
Функция устанавливапет пользователю роль легкого агента. Функция устанавливапет пользователю роль легкого агента.
:param user_profile: :param user_profile: Профиль пользователя
:return: :return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "light_agent"
""" """
update_role(user_profile, ROLES['light_agent']) update_role(user_profile, ROLES['light_agent'])
@ -171,7 +171,6 @@ def make_light_agent(user_profile: UserProfile) -> UserProfile:
def get_users_list() -> list: def get_users_list() -> list:
""" """
Функция возвращает список пользователей Zendesk, относящихся к организации. Функция возвращает список пользователей Zendesk, относящихся к организации.
:return:
""" """
zendesk = ZendeskAdmin() zendesk = ZendeskAdmin()
admin = zendesk.get_user(zendesk.email) admin = zendesk.get_user(zendesk.email)
@ -183,8 +182,8 @@ def update_profile(user_profile: UserProfile) -> UserProfile:
""" """
Функция обновляет профиль пользователя в соотвтетствии с текущим в Zendesk. Функция обновляет профиль пользователя в соотвтетствии с текущим в Zendesk.
:param user_profile: :param user_profile: Профиль пользователя
:return: :return: Обновленный, в соответствие с текущими данными в Zendesk, профиль пользователя
""" """
user = ZendeskAdmin().get_user(user_profile.user.email) user = ZendeskAdmin().get_user(user_profile.user.email)
user_profile.name = user.name user_profile.name = user.name
@ -198,8 +197,8 @@ def check_user_exist(email: str) -> bool:
""" """
Функция проверяет, существует ли пользователь. Функция проверяет, существует ли пользователь.
:param email: :param email: Email пользователя
:return: :return: Зарегистрирован ли пользователь в Zendesk
""" """
return ZendeskAdmin().check_user(email) return ZendeskAdmin().check_user(email)
@ -208,19 +207,19 @@ def get_user_organization(email: str) -> str:
""" """
Функция возвращает организацию пользователя. Функция возвращает организацию пользователя.
:param email: :param email: Email пользователя
:return: :return: Организацния пользователя
""" """
return ZendeskAdmin().get_user_org(email) return ZendeskAdmin().get_user_org(email)
def daterange(start_date, end_date) -> list: def daterange(start_date: date, end_date: date) -> list:
""" """
Функция возвращает список дней с start_date по end_date, исключая правую границу. Функция возвращает список дней с start_date по end_date, исключая правую границу.
:param start_date: :param start_date: Начальная дата
:param end_date: :param end_date: Конечная дата
:return: :return: Список дней, не включая конечную дату
""" """
dates = [] dates = []
for n in range(int((end_date - start_date).days)): for n in range(int((end_date - start_date).days)):
@ -228,14 +227,14 @@ def daterange(start_date, end_date) -> list:
return dates return dates
def get_timedelta(log, time=None) -> timedelta: def get_timedelta(log: RoleChangeLogs, time=None) -> timedelta:
""" """
Функция возвращает объект класса timedelta, который хранит промежуток времени от начала суток до момента, Функция возвращает объект класса timedelta, который хранит промежуток времени от начала суток до момента,
который находится в log (объект класса RoleChangeLogs) или в time(datetime.time), если введён. который находится в log (объект класса RoleChangeLogs) или в time(datetime.time), если введён.
:param log: :param log: Лог
:param time: :param time: Время
:return: :return: Сколько времени прошло от начала суток до события
""" """
if time is None: if time is None:
time = log.change_time.time() time = log.change_time.time()
@ -245,16 +244,26 @@ def get_timedelta(log, time=None) -> timedelta:
def last_day_of_month(day): def last_day_of_month(day):
""" """
Функция возвращает последний день любого месяца. Функция возвращает последний день текущего месяца.
:param day: .. todo::
:return: Дописать документацию по данной функции (не поняла типы и суть)
:param day: Текущий день
:return: Последний день месяца
""" """
next_month = day.replace(day=28) + timedelta(days=4) next_month = day.replace(day=28) + timedelta(days=4)
return next_month - timedelta(days=next_month.day) return next_month - timedelta(days=next_month.day)
class StatisticData: class StatisticData:
"""
Класс для учета статистики интервалов работы пользователей.
Передаваемые параметры: start_date, end_date, user_email.
.. todo::
Дописать описание данного класса
"""
def __init__(self, start_date, end_date, user_email, stat=None): def __init__(self, start_date, end_date, user_email, stat=None):
self.display = None self.display = None
self.interval = None self.interval = None
@ -271,12 +280,11 @@ class StatisticData:
else: else:
self.statistic = stat self.statistic = stat
def get_statistic(self): def get_statistic(self) -> dict:
""" """
Функция возвращает словарь statistic с применением формата отображения и интеравала работы(если они есть). Функция возвращает статистику работы пользователя.
None, если были ошибки при создании.
:return: :return: оварь statistic с применением формата отображения и интеравала работы(если они есть). None, если были ошибки при создании.
""" """
if self.is_valid_statistic(): if self.is_valid_statistic():
stat = self.statistic stat = self.statistic
@ -286,20 +294,20 @@ class StatisticData:
else: else:
return None return None
def is_valid_statistic(self): def is_valid_statistic(self) -> bool:
""" """
Функция проверяет были ли ошибки при создании статистики. Функция проверяет были ли ошибки при создании статистики.
:return: :return: True, при отутствии ошибок
""" """
return not self.errors and self.statistic return not self.errors and self.statistic
def set_interval(self, interval): def set_interval(self, interval: list) -> bool:
""" """
Функция устанавливает интервал работы. Функция проверяет корректность представления интервала работы.
:param interval: :param interval: Интервал должен быть указан в днях или месяцах.
:return: :return: True, если указан верно
""" """
if interval not in ['months', 'days']: if interval not in ['months', 'days']:
self.errors += ['Интервал работы должен быть в днях или месяцах'] self.errors += ['Интервал работы должен быть в днях или месяцах']
@ -307,12 +315,12 @@ class StatisticData:
self.interval = interval self.interval = interval
return True return True
def set_display(self, display_format): def set_display(self, display_format: list) -> bool:
""" """
Функция устанавливает формат отображения. Функция проверяет корректность формата отображения интервала.
:param display_format: :param display_format: Формат отображения должен быть указан в днях или месяцах.
:return: :return: True, если указан верно
""" """
if display_format not in ['days', 'hours']: if display_format not in ['days', 'hours']:
self.errors += ['Формат отображения должен быть в часах или днях'] self.errors += ['Формат отображения должен быть в часах или днях']
@ -320,31 +328,29 @@ class StatisticData:
self.display = display_format self.display = display_format
return True return True
def get_data(self): def get_data(self) -> list:
""" """
Функция возвращает данные - массив объектов RoleChangeLogs. Функция возвращает данные - список объектов RoleChangeLogs.
:return:
""" """
if self.is_valid_data(): if self.is_valid_data():
return self.data return self.data
else: else:
return None return None
def is_valid_data(self): def is_valid_data(self) -> bool:
""" """
Функция определяет были ли ошибки при получении логов. Функция определяет были ли ошибки при получении логов.
:return: :return: True, если ошибок нет
""" """
return not self.errors return not self.errors
def _use_display(self, stat): def _use_display(self, stat: list) -> list:
""" """
Функция приводит данные к формату отображения. Функция приводит данные к формату отображения.
:param stat: :param stat: Список данных статистики пользователя
:return: :return: Обновленный список
""" """
if not self.is_valid_statistic() or not self.display: if not self.is_valid_statistic() or not self.display:
return stat return stat

View File

@ -8,12 +8,11 @@ from main.models import UserProfile
class CustomRegistrationForm(RegistrationFormUniqueEmail): class CustomRegistrationForm(RegistrationFormUniqueEmail):
""" """
Форма для регистрации :class:`django_registration.forms.RegistrationFormUniqueEmail` Форма для регистрации :class:`django_registration.forms.RegistrationFormUniqueEmail`
с добавлением bootstrap-класса "form-control".
с добавлением bootstrap-класса "form-control" :param visible_fields.email: Поле для ввода email, зарегистирированного на Zendesk
:type visible_fields.email: :class:`django_registration.forms.RegistrationFormUniqueEmail`
:param visible_fields.email: Поле для ввода email, зарегистирированного на Zendesk
:type visible_fields.email: :class:`django_registration.forms.RegistrationFormUniqueEmail`
""" """
def __init__(self, *args, **kwargs) -> RegistrationFormUniqueEmail: def __init__(self, *args, **kwargs) -> RegistrationFormUniqueEmail:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -32,10 +31,10 @@ class CustomRegistrationForm(RegistrationFormUniqueEmail):
class AdminPageUsers(forms.Form): class AdminPageUsers(forms.Form):
""" """
Форма для установки статусов engineer или light_agent пользователям. Форма для установки статусов engineer или light_agent пользователям.
:param users: Поле для установки статуса :param users: Поле для установки статуса
:type users: :class:`ModelMultipleChoiceField` :type users: :class:`ModelMultipleChoiceField`
""" """
users = forms.ModelMultipleChoiceField( users = forms.ModelMultipleChoiceField(
@ -52,8 +51,11 @@ class AdminPageUsers(forms.Form):
class CustomAuthenticationForm(AuthenticationForm): class CustomAuthenticationForm(AuthenticationForm):
""" """
Форма для авторизации :class:`django.contrib.auth.forms.AuthenticationForm` Форма для авторизации :class:`django.contrib.auth.forms.AuthenticationForm`
с изменением поля username на email с изменением поля username на email.
:param username: Поле для ввода email пользователя
:type username: :class:`django.forms.fields.CharField`
""" """
username = forms.CharField( username = forms.CharField(
label="Электронная почта", label="Электронная почта",
@ -69,6 +71,20 @@ class CustomAuthenticationForm(AuthenticationForm):
class StatisticForm(forms.Form): class StatisticForm(forms.Form):
"""
Форма отображения интервалов работы пользователя.
:param email: Поле для ввода email пользователя
:type email: :class:`django.forms.fields.EmailField`
:param interval: Расчет интервала рабочего времени
:type interval: :class:`django.forms.fields.CharField`
:param display_format: Формат отображения данных
:type display_format: :class:`django.forms.fields.CharField`
:param range_start: Дата и время начала работы
:type range_start: :class:`django.forms.fields.DateField`
:param range_end: Дата и время окончания работы
:type range_end: :class:`django.forms.fields.DateField`
"""
email = forms.EmailField( email = forms.EmailField(
label='Электроная почта', label='Электроная почта',
) )

View File

@ -29,9 +29,14 @@ class CustomRegistrationView(RegistrationView):
""" """
Класс отображения и логики работы страницы регистрации пользователя Класс отображения и логики работы страницы регистрации пользователя
1. Ввод email пользователя, указанный на Zendesk :param form_class: Форма, которую необходимо заполнить для регистрации
2. В случае если пользователь с данным паролем зарегистрирован на Zendesk и относится к определенной организации, происходит сброс ссылки с установлением пароля на указанный email :type form_class: :class:`forms.CustomRegistrationForm`
3. Создается пользователь class User, а также его профиль :param template_name: Указание пути к html-странице django регистрации
:type template_name: :class:`str`
:param success_url: Указание пути к html-странице завершения регистрации
:type success_url: :class:`django.utils.functional.lazy.<locals>.__proxy__`
:param is_allowed: Определение зарегистрирован ли пользователь с введенным email на Zendesk и принадлежит ли он к организации SYSTEM
:type is_allowed: :class:`bool`
""" """
form_class = CustomRegistrationForm form_class = CustomRegistrationForm
template_name = 'django_registration/registration_form.html' template_name = 'django_registration/registration_form.html'
@ -39,6 +44,16 @@ class CustomRegistrationView(RegistrationView):
is_allowed = True is_allowed = True
def register(self, form: CustomRegistrationForm) -> User: def register(self, form: CustomRegistrationForm) -> User:
"""
Функция регистрации пользователя.
1. Ввод email пользователя, указанный на Zendesk
2. В случае если пользователь с данным паролем зарегистрирован на Zendesk и относится к организации SYSTEM,
происходит сброс ссылки с установлением пароля на указанный email
3. Создается пользователь class User, а также его профиль.
:param form: Email пользователя на Zendesk
:return: user
"""
self.is_allowed = True self.is_allowed = True
if check_user_exist(form.data['email']) and get_user_organization(form.data['email']) == 'SYSTEM': if check_user_exist(form.data['email']) and get_user_organization(form.data['email']) == 'SYSTEM':
forms = PasswordResetForm(self.request.POST) forms = PasswordResetForm(self.request.POST)
@ -72,7 +87,7 @@ class CustomRegistrationView(RegistrationView):
""" """
Функция дает разрешение на просмотр страница администратора, если пользователь имеет роль admin. Функция дает разрешение на просмотр страница администратора, если пользователь имеет роль admin.
:param user: авторизованный пользователь (получает разрешение, имея роль "admin" :param user: авторизованный пользователь (получает разрешение, имея роль "admin")
""" """
if user.userprofile.role == 'admin': if user.userprofile.role == 'admin':
content_type = ContentType.objects.get_for_model(UserProfile) content_type = ContentType.objects.get_for_model(UserProfile)
@ -195,9 +210,15 @@ def work_become_engineer(request: WSGIRequest) -> HttpResponseRedirect:
return HttpResponseRedirect(reverse('work', args=(request.user.id,))) return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
def main_page(request): def main_page(request: WSGIRequest) -> HttpResponse:
""" """
Отображение логгирования на главной странице Функция отображения логгирования на главной странице.
.. todo::
Дописать параметры в документацию:
:param request:
:return:
""" """
logger = logging.getLogger('main.index') logger = logging.getLogger('main.index')
logger.info('Index page opened') logger.info('Index page opened')
@ -205,6 +226,13 @@ def main_page(request):
class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView): class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
"""
Класс отображения страницы администратора.
.. todo::
Документация для данного класса:
"""
permission_required = 'main.has_control_access' permission_required = 'main.has_control_access'
template_name = 'pages/adm_ruleset.html' template_name = 'pages/adm_ruleset.html'
form_class = AdminPageUsers form_class = AdminPageUsers
@ -231,7 +259,7 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
@staticmethod @staticmethod
def count_users(users) -> tuple: def count_users(users) -> tuple:
""" """
Функция подсчета количества сотрудников с ролями engineer и light_a Функция подсчета количества сотрудников с ролями "engineer" и "light_agent".
.. todo:: .. todo::
this func counts users from all zendesk instead of just from a model: this func counts users from all zendesk instead of just from a model:
@ -259,13 +287,19 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
class CustomLoginView(LoginView): class CustomLoginView(LoginView):
""" """
Отображение страницы авторизации пользователя Классс отображения страницы авторизации пользователя.
""" """
form_class = CustomAuthenticationForm form_class = CustomAuthenticationForm
@login_required() @login_required()
def statistic_page(request): def statistic_page(request: WSGIRequest) -> HttpResponse:
"""
Функция отображения страницы статистики (для "superuser").
:param request: данные о пользователе: email, время и интервал работы. Данные получаем через forms.StatisticForm
:return: адресация на страницу статистики
"""
if not request.user.is_superuser: if not request.user.is_superuser:
return redirect('index') return redirect('index')
context = { context = {