Skip to content

marat-dev-samples/wsgi_framework

Repository files navigation

Задание 1

  1. Создан класс фреймворка согласно примера, название CustomFramework лежит в файле src/custom_framework (PEP8).
  2. Реализация шаблонов Page controller и Front controller как в примере (немного сократил код через get(..., NotFound())).
  3. Контроллеры view пока такие же как в примере, немного улучшил render() - при отсутствующем шаблоне возвращает 406.
  4. Создан wsgi файл запуска. Для разработки использовался python 3.9.0.
  5. P.S. Установлен шаблон, но так как статика не подключалась страница рассыпается.

cd custom_framework
gunicorn wsgi:'run()' --reload

Задание 2

  1. (0,1,2) Создан модуль querylib для обработки параметров wsgi запросов (GET, POST). Данные возвращаются в виде словаря.
  2. Добавлена форма контакта Contacts согласно задания. Форма пока добавлена в базовый шаблон чтобы не терять время.
  3. Данные формы выводятся в терминал, для читабельности словаря используем json.dums(data, indent=4).

P.S. Парсинг данных производим при помощи библиотеки urllib также решается и проблема % символов. Могу создать кастомную функцию, если это принципиально в учебном процессе. На мой взгляд знание библиотек важнее...

Задание 3

  1. Изменен согласно задания модуль templator, используем общий метод для загрузки шаблонов как из примера.
  2. Создан базовый шаблон для всех страниц.
  3. Добавлено меню для всех страниц, подключено через базовый шаблон. Подключены стили через статику.
  4. Отключен боковой сайдбар на странице Content для демонстрации возможности перегрузки шаблона.
  5. Добавлен полезный функционал: В меню применен способ выделения активной страницы используя переменную шаблона -> (демонстрация паттерна FrontController). Текущую страницу получаем из переменной окружения и передаем в шаблонон используя переменную active_page :)

Задание 4

  1. Создан модуль creational и классы порождающего паттерна согласно ДЗ.
  2. Логгер реализован на основе Singletone с использованием метакласса, добавлена возможность указывать уровень логгирования при инициализации, реализована фильтрация соответственно для того чтобы его можно было использовать как обычный log.info(message).
  3. Обучающий сайт будет посвящен DIY автоматике на основе Raspberry Pi и Arduino. Используем обучающие статьи и вебинары.
  4. Добавлена страница категорий статей categories содержащая список ссылок категорий и форму добавления новой (пока нет БД так что для удобства добавляем пару при инициализации).
  5. При переходе по ссылке категории попадаем на страницу списка статей content, id категории передаем в строке запроса, что позволяет отображать список статей по данной категории. Также страница содержит форму для создания новой статьи (курса).

P.S. Пришлось немного модифицировать Engine для того чтобы он отдавал список типов доступных статей (курсов) для формы создания.

Задание 5

  1. Создан модуль structural для классов структурного паттерна согласно ДЗ. Создан класс декоратор @AppRoute для назначения путей через декоратор. Общий массив routes вынесен в переменную класса для удобства. Также декоратор возвращает 404 если указанный путь не найден.
  2. Добавлен декоратор @debug в виде функции и размещен над обработчиком категорий курсов. Для логгирования каждого запроса к странице необходимо разместить его над _call_, в противном случае он сработает только один раз во времи инициализации класса. 3.Добавлена возможность указывать родительскую категорию при создании категории статьи (курса). Можно выбрать из списка существующих категорий.
  3. Функционал по выводу параметров запроса реализован путем добавления к нашемму логгеру обработчика StreamHandler выводящего логи в консоль и строки логгирования в орбаботчике входных данных модуля querylib соответственно. Для большей читабельности используем json.dumps(result, ensure_ascii=False, indent=4).

Задание 6

  1. Создана страница пользователей. Введен дополнительный признак is_author для авторов статей. При создании статьи теперь нужно указывать автора. автор.
  2. Добавлена страница статьи (курса) /content/. Предлагаемый функционал изменен (для избежания плагиата) на следующий: На странице отображается контент статьи (туториал, курс), форма для редактирования конента и форма для подписки на статью (можно сделать еще формму комментариев). При подписке на статью пользователем автор статьи получает уведомление, а при изменении статьи автором - уведомление получают все подписанные на данную статью пользователи. В принципе если добавить форму комментирования статьи то получится более логично :)
  3. Добавлена поддержка PUT, PATCH, DELETE запросов через скрытое поле формы и дополнительного обработчика на стороне сайта.
  4. Добавлен итератор к объекту категории отдающий статью в категории. Таким образом возможна итерация for article in category...
  5. Создано api для категории. Ссылки на api_call присутствуют в списке категорий рядом с названием категории, в демонстраии выводятся все статьи по категории. Объект статьи (курса) для этого улучшет кастомным методом as_dict().
  6. Логгер был изменен и работает по анологии с настоящим. Присутстует уровень логгирования. Может нести в себе одновременно несколько обработчиков, добавляемых через метод например logger.add_handler(StreamHaneler()) logger.add_handler(FileHandler(file_name='base.log')).
  7. Наблюдатель немного изменен, теперь дочерние классы (PrintNotifyer, SmsNotify, EmailNotify) получают не объект наблюдения (в случае примера объект курса), а список объектов пользователей для уведомления. Это позволяет контролируя этот список через дополнительные методы класса Observer notify_admin, notify_subscibers организовать уведомление например только автора статьи или всех подписчиков статьи (курса) или всех пользователей сайта. 8.Реализовны согласно концепции Class Based VIews классы ApiListView (применили в api списка категорий) и CreateView который в свою очередь дополнен возможностью перенаправления ответа, для этого в дочернем классе должен присутствовать параметр перенаправления как это сделано на контроллере создания категории CreateCategory, сам контроллер находится на адресе /create-category/, однако redirect=/categories/ позволяет после создания категории перенаправить обратно на страницу списка категорий. Очень удобно :)

Задание 7

  1. Добавлена база данных sqlite3, скрипт инициализации помещен в тест test.development.py.
  2. Создан DataMapper для класса пользователя UserMapper, вынесен в отдельный модуль mappers.
  3. Реализован метакласс RegistryHolder как хранилище. Для этого он имеет дополнительный метод get_mapper_for(cls, obj_name) который возвращает нужный класс маппера. Для этого класс маппера должен иметь RegistryHolder указанным как метакласс и дополнительный параметр mapper_for с указанием списка классов для которых может быть применен данный маппер. Подобный подход расширяет возможности RegistryHolder по поиску путем внедрения дополнительных параметров в дочерние классы. Также маппер может быть применен к нескольким классам. P.S. Не понятно зачем использовать при этом MapperRegistry по сути это обычный словарь, его функционал передан в RegistryHolder.
  4. UnitOfWork взят из примера, немного адаптирован под использование RegistryHolder взамен MapperRegistry.

P.S. Под использование UserMapper и UnitOfWork адаптирован процесс создания пользователей, доработан класс Engine в части поиска пользователя по id и вывода списка пользователей. Класс UserMapper может быть применен к классам User, Author, Contributor.

Задания 8, 9 Общие улучшения по проекту:

  1. Логгер способен использовать различные обработчики (как это делает настоящий логгер), также добавлена возможность использования log_level
  2. Наблюдатель: заменен объект передаваемый в дочерние классы Observer (SmsNotify, EmailNotify) списком объектов пользователей которых необходимо уведомить. Это позволяет контролируя этот список через дополнительные методы класса Observer организовать уведомление например только автора статьи или всех подписчиков статьи (курса).
  3. Добавлен front_controller для считыватия скрытого поля _method что позволило использовать дополнительно PUT, PATCH, DELETE запросы (необходимые в том числе для API). Таким образом запросы можно не только разделять по url но и обрабатывать по типу в одном view контроллере.
  4. Добавлена возможность перенаправления на другую страницу, для этого реализована функция redirect() модуля patterns.structural. Также добавлена такая же возможность в подкласс CreateView, что позволяет после создания объекта перенаправить браузер обратно на страницу.

Перед запуском проекта необходимо запустить тестирование и инициализацию базы данных

python -m unittest -v tests.development

Для запуска проекта

gunicorn wsgi:'run()' --reload

About

GB homework repository

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published