From c9ae302103742599d6cef69844298f33dd4c51f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=B5=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=20=D0=9E=D0=BB=D1=8C=D0=B3=D0=B0?= Date: Sun, 14 Mar 2021 12:42:18 +0300 Subject: [PATCH] Add documentation to new forms, and first part of extra_func --- main/extra_func.py | 132 +++++++++++++++++++++++---------------------- main/forms.py | 36 +++++++++---- main/views.py | 52 ++++++++++++++---- 3 files changed, 138 insertions(+), 82 deletions(-) diff --git a/main/extra_func.py b/main/extra_func.py index f51be0f..627a93c 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -43,8 +43,8 @@ class ZendeskAdmin: """ Функция осуществляет проверку существования пользователя в Zendesk по email. - :param email: - :return: + :param email: Email пользователя + :return: Является ли зарегистрированным """ return True if self.admin.search(email, type='user') else False @@ -52,8 +52,8 @@ class ZendeskAdmin: """ Функция возвращает имя пользователя по его email. - :param email: - :return: + :param email: Email пользователя + :return: Имя пользователя """ user = self.admin.users.search(email).values[0] return user.name @@ -62,8 +62,8 @@ class ZendeskAdmin: """ Функция возвращает роль пользователя по его email. - :param email: - :return: + :param email: Email пользователя + :return: Роль пользователя """ user = self.admin.users.search(email).values[0] return user.role @@ -72,8 +72,8 @@ class ZendeskAdmin: """ Функция возвращает id пользователя по его email - :param email: - :return: + :param email: Email пользователя + :return: ID пользователя """ user = self.admin.users.search(email).values[0] return user.id @@ -82,18 +82,18 @@ class ZendeskAdmin: """ Функция возвращает url-ссылку на аватар пользователя по его email. - :param email: - :return: + :param email: Email пользователя + :return: Аватар пользователя """ user = self.admin.users.search(email).values[0] return user.photo['content_url'] if user.photo else None def get_user(self, email: str): """ - Функция возвращает пользователя (объект) по его email + Функция возвращает пользователя (объект) по его email. - :param email: email пользователя - :return: email пользователя, найденного в БД + :param email: Email пользователя + :return: Объект пользователя, найденного в БД """ return self.admin.users.search(email).values[0] @@ -101,8 +101,8 @@ class ZendeskAdmin: """ Функция возвращает организацию, к которой относится пользователь по его email. - :param email: - :return: + :param email: Email пользователя + :return: Организация пользователя """ user = self.admin.users.search(email).values[0] 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 role: - :return: + :param user_profile: Профиль пользователя + :param role: Новая роль + :return: Пользователь с обновленной ролью """ zendesk = ZendeskAdmin() user = zendesk.get_user(user_profile.user.email) @@ -152,8 +152,8 @@ def make_engineer(user_profile: UserProfile) -> UserProfile: """ Функция устанавливапет пользователю роль инженера. - :param user_profile: - :return: + :param user_profile: Профиль пользователя + :return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "endineer" """ update_role(user_profile, ROLES['engineer']) @@ -162,8 +162,8 @@ def make_light_agent(user_profile: UserProfile) -> UserProfile: """ Функция устанавливапет пользователю роль легкого агента. - :param user_profile: - :return: + :param user_profile: Профиль пользователя + :return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "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: """ Функция возвращает список пользователей Zendesk, относящихся к организации. - :return: """ zendesk = ZendeskAdmin() admin = zendesk.get_user(zendesk.email) @@ -183,8 +182,8 @@ def update_profile(user_profile: UserProfile) -> UserProfile: """ Функция обновляет профиль пользователя в соотвтетствии с текущим в Zendesk. - :param user_profile: - :return: + :param user_profile: Профиль пользователя + :return: Обновленный, в соответствие с текущими данными в Zendesk, профиль пользователя """ user = ZendeskAdmin().get_user(user_profile.user.email) user_profile.name = user.name @@ -198,8 +197,8 @@ def check_user_exist(email: str) -> bool: """ Функция проверяет, существует ли пользователь. - :param email: - :return: + :param email: Email пользователя + :return: Зарегистрирован ли пользователь в Zendesk """ return ZendeskAdmin().check_user(email) @@ -208,19 +207,19 @@ def get_user_organization(email: str) -> str: """ Функция возвращает организацию пользователя. - :param email: - :return: + :param email: Email пользователя + :return: Организацния пользователя """ 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, исключая правую границу. - :param start_date: - :param end_date: - :return: + :param start_date: Начальная дата + :param end_date: Конечная дата + :return: Список дней, не включая конечную дату """ dates = [] for n in range(int((end_date - start_date).days)): @@ -228,14 +227,14 @@ def daterange(start_date, end_date) -> list: return dates -def get_timedelta(log, time=None) -> timedelta: +def get_timedelta(log: RoleChangeLogs, time=None) -> timedelta: """ Функция возвращает объект класса timedelta, который хранит промежуток времени от начала суток до момента, который находится в log (объект класса RoleChangeLogs) или в time(datetime.time), если введён. - :param log: - :param time: - :return: + :param log: Лог + :param time: Время + :return: Сколько времени прошло от начала суток до события """ if time is None: time = log.change_time.time() @@ -245,16 +244,26 @@ def get_timedelta(log, time=None) -> timedelta: def last_day_of_month(day): """ - Функция возвращает последний день любого месяца. + Функция возвращает последний день текущего месяца. - :param day: - :return: + .. todo:: + Дописать документацию по данной функции (не поняла типы и суть) + + :param day: Текущий день + :return: Последний день месяца """ next_month = day.replace(day=28) + timedelta(days=4) return next_month - timedelta(days=next_month.day) class StatisticData: + """ + Класс для учета статистики интервалов работы пользователей. + Передаваемые параметры: start_date, end_date, user_email. + + .. todo:: + Дописать описание данного класса + """ def __init__(self, start_date, end_date, user_email, stat=None): self.display = None self.interval = None @@ -271,12 +280,11 @@ class StatisticData: else: self.statistic = stat - def get_statistic(self): + def get_statistic(self) -> dict: """ - Функция возвращает словарь statistic с применением формата отображения и интеравала работы(если они есть). - None, если были ошибки при создании. + Функция возвращает статистику работы пользователя. - :return: + :return: Cловарь statistic с применением формата отображения и интеравала работы(если они есть). None, если были ошибки при создании. """ if self.is_valid_statistic(): stat = self.statistic @@ -286,20 +294,20 @@ class StatisticData: else: return None - def is_valid_statistic(self): + def is_valid_statistic(self) -> bool: """ Функция проверяет были ли ошибки при создании статистики. - :return: + :return: True, при отутствии ошибок """ return not self.errors and self.statistic - def set_interval(self, interval): + def set_interval(self, interval: list) -> bool: """ - Функция устанавливает интервал работы. + Функция проверяет корректность представления интервала работы. - :param interval: - :return: + :param interval: Интервал должен быть указан в днях или месяцах. + :return: True, если указан верно """ if interval not in ['months', 'days']: self.errors += ['Интервал работы должен быть в днях или месяцах'] @@ -307,12 +315,12 @@ class StatisticData: self.interval = interval return True - def set_display(self, display_format): + def set_display(self, display_format: list) -> bool: """ - Функция устанавливает формат отображения. + Функция проверяет корректность формата отображения интервала. - :param display_format: - :return: + :param display_format: Формат отображения должен быть указан в днях или месяцах. + :return: True, если указан верно """ if display_format not in ['days', 'hours']: self.errors += ['Формат отображения должен быть в часах или днях'] @@ -320,31 +328,29 @@ class StatisticData: self.display = display_format return True - def get_data(self): + def get_data(self) -> list: """ - Функция возвращает данные - массив объектов RoleChangeLogs. - - :return: + Функция возвращает данные - список объектов RoleChangeLogs. """ if self.is_valid_data(): return self.data else: return None - def is_valid_data(self): + def is_valid_data(self) -> bool: """ Функция определяет были ли ошибки при получении логов. - :return: + :return: True, если ошибок нет """ return not self.errors - def _use_display(self, stat): + def _use_display(self, stat: list) -> list: """ Функция приводит данные к формату отображения. - :param stat: - :return: + :param stat: Список данных статистики пользователя + :return: Обновленный список """ if not self.is_valid_statistic() or not self.display: return stat diff --git a/main/forms.py b/main/forms.py index dab07bb..5f4531f 100644 --- a/main/forms.py +++ b/main/forms.py @@ -8,12 +8,11 @@ from main.models import UserProfile 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: super().__init__(*args, **kwargs) @@ -32,10 +31,10 @@ class CustomRegistrationForm(RegistrationFormUniqueEmail): class AdminPageUsers(forms.Form): """ - Форма для установки статусов engineer или light_agent пользователям. + Форма для установки статусов engineer или light_agent пользователям. - :param users: Поле для установки статуса - :type users: :class:`ModelMultipleChoiceField` + :param users: Поле для установки статуса + :type users: :class:`ModelMultipleChoiceField` """ users = forms.ModelMultipleChoiceField( @@ -52,8 +51,11 @@ class AdminPageUsers(forms.Form): class CustomAuthenticationForm(AuthenticationForm): """ - Форма для авторизации :class:`django.contrib.auth.forms.AuthenticationForm` - с изменением поля username на email + Форма для авторизации :class:`django.contrib.auth.forms.AuthenticationForm` + с изменением поля username на email. + + :param username: Поле для ввода email пользователя + :type username: :class:`django.forms.fields.CharField` """ username = forms.CharField( label="Электронная почта", @@ -69,6 +71,20 @@ class CustomAuthenticationForm(AuthenticationForm): 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( label='Электроная почта', ) diff --git a/main/views.py b/main/views.py index d1155e0..e20be04 100644 --- a/main/views.py +++ b/main/views.py @@ -29,9 +29,14 @@ class CustomRegistrationView(RegistrationView): """ Класс отображения и логики работы страницы регистрации пользователя - 1. Ввод email пользователя, указанный на Zendesk - 2. В случае если пользователь с данным паролем зарегистрирован на Zendesk и относится к определенной организации, происходит сброс ссылки с установлением пароля на указанный email - 3. Создается пользователь class User, а также его профиль + :param form_class: Форма, которую необходимо заполнить для регистрации + :type form_class: :class:`forms.CustomRegistrationForm` + :param template_name: Указание пути к html-странице django регистрации + :type template_name: :class:`str` + :param success_url: Указание пути к html-странице завершения регистрации + :type success_url: :class:`django.utils.functional.lazy..__proxy__` + :param is_allowed: Определение зарегистрирован ли пользователь с введенным email на Zendesk и принадлежит ли он к организации SYSTEM + :type is_allowed: :class:`bool` """ form_class = CustomRegistrationForm template_name = 'django_registration/registration_form.html' @@ -39,6 +44,16 @@ class CustomRegistrationView(RegistrationView): is_allowed = True 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 if check_user_exist(form.data['email']) and get_user_organization(form.data['email']) == 'SYSTEM': forms = PasswordResetForm(self.request.POST) @@ -72,7 +87,7 @@ class CustomRegistrationView(RegistrationView): """ Функция дает разрешение на просмотр страница администратора, если пользователь имеет роль admin. - :param user: авторизованный пользователь (получает разрешение, имея роль "admin" + :param user: авторизованный пользователь (получает разрешение, имея роль "admin") """ if user.userprofile.role == 'admin': 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,))) -def main_page(request): +def main_page(request: WSGIRequest) -> HttpResponse: """ - Отображение логгирования на главной странице + Функция отображения логгирования на главной странице. + + .. todo:: + Дописать параметры в документацию: + + :param request: + :return: """ logger = logging.getLogger('main.index') logger.info('Index page opened') @@ -205,6 +226,13 @@ def main_page(request): class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView): + """ + Класс отображения страницы администратора. + + .. todo:: + Документация для данного класса: + + """ permission_required = 'main.has_control_access' template_name = 'pages/adm_ruleset.html' form_class = AdminPageUsers @@ -231,7 +259,7 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView): @staticmethod def count_users(users) -> tuple: """ - Функция подсчета количества сотрудников с ролями engineer и light_a + Функция подсчета количества сотрудников с ролями "engineer" и "light_agent". .. todo:: 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): """ - Отображение страницы авторизации пользователя + Классс отображения страницы авторизации пользователя. """ form_class = CustomAuthenticationForm @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: return redirect('index') context = {