diff --git a/NOTE.md b/NOTE.md new file mode 100644 index 0000000..0559ac5 --- /dev/null +++ b/NOTE.md @@ -0,0 +1,32 @@ +# Заметки по деплою проекту + + В финальном комите перед новой версией (*ТОЛЬ ПОСЛЕ ТЕСТИРОВАНИЯ:) не забываем менять: + - `CHANGELOG.md` делать описание изменений. + - `typograph/templates/typograph/base.html` в шаблоне циферки в подвале + + + Затем, когда код готов к релизу, нужно обновить версию в `pyproject.toml`: + ```shell + poetry version patch + ``` + + Финальный коммит, таким образом, должен включать в себя: + - Обновление `CHANGELOG.md` с описанием изменений. + - Обновление версии в `pyproject.toml` (через `poetry version patch`). + - Обновление шаблона `base.html` (циферки в подвале). + — Обновление в `etpgrf_site/__init__.py`. + - И, конечно же, все изменения, которые были сделаны в коде. + +После комита и пуша: +```shell +git add . +git commit -am "Обновление версии для релиза vX.Y.Z" +git push origin main +``` + +Для запуска деплоя CI/CD, через Gitea Actions, создаем `git tag` и пушим его в репозиторий: +```shell +git tag vX.Y.Z && git push origin vX.Y.Z +``` + + diff --git a/_prj_blueprint/backend.md b/_prj_blueprint/backend.md new file mode 100644 index 0000000..1b47036 --- /dev/null +++ b/_prj_blueprint/backend.md @@ -0,0 +1,57 @@ +# Бэкенд: Архитектура и модули + +## 1. Django Конфигурация (`etpgrf_site/etpgrf_site/`) +- **`settings.py`**: + - `DEBUG` и `SECRET_KEY` считываются из переменных окружения. + - `ADMIN_URL`: настраиваемый префикс панели администратора (по умолчанию `admin/`). + - База данных: SQLite в `data/db-etpgrf.sqlite3` с `timeout: 20` для надежности при конкурентных запросах. + - Статика: `STATICFILES_DIRS = [BASE_DIR.parent / 'public' / 'static']`, `STATIC_ROOT = BASE_DIR.parent / 'public' / 'static_collected'`. + - Медиа: `MEDIA_ROOT = BASE_DIR.parent / 'media'`, `MEDIA_URL = '/media/'`. + - Защита за прокси: в `not DEBUG` активированы `SECURE_PROXY_SSL_HEADER`, `SECURE_SSL_REDIRECT`, `SESSION_COOKIE_SECURE`, `CSRF_COOKIE_SECURE`, `USE_X_FORWARDED_HOST`, `USE_X_FORWARDED_PORT`. +- **`urls.py`**: + - `/{ADMIN_URL}` -> админка Django. + - `/` -> `typograph.urls` (главная страница типографа, API обработки и статистики). + - `/blog/` -> `blog.urls` (список постов, детальная страница поста). + - `/sitemap.xml` -> карта сайта (`PostSitemap`). + - `//` -> ловушка для статических страниц (например, `/about/`, `/privacy-policy/`, `/donate/`). + +## 2. Приложение `typograph` +Отвечает за взаимодействие с библиотекой типографирования `etpgrf` и сбор агрегированной аналитики. + +### Модели (`typograph/models.py`) +- **`DailyStat`**: + - Агрегированные посуточные показатели (`date` - уникальная дата). + - Метрики активности: `index_views`, `process_requests`, `copy_count`. + - Объемы данных: `chars_in`, `chars_out`, `chars_copied`. + - Производительность: `total_processing_time_ms`, вычисляемое свойство `avg_processing_time_ms`. + - `settings_stats`: JSONField со статистикой популярности опций (языки, кавычки, переносы, висячая пунктуация и т.д.). + +### Представления и Эндпоинты (`typograph/views.py`) +- `index` (`/`): главная страница, инкрементирует просмотры `index_views`. +- `process_text` (`/process/`, POST): + - Принимает текст и параметры типографирования из формы. + - Инициализирует `LayoutProcessor`, `Hyphenator`, `Typographer` из пакета `etpgrf`. + - Производит замер времени обработки `time.perf_counter()`. + - Атомарно обновляет счетчики в `DailyStat`. + - Возвращает HTML-фрагмент `typograph/result_fragment.html` и заголовок `X-Processing-Time`. +- `track_copy` (`/track-copy/`, POST): фиксирует факт и длину скопированного в буфер текста. +- `get_stats_summary` (`/stats-summary/`, GET): возвращает компактный HTMX-фрагмент со статистикой для футера. + +## 3. Приложение `blog` +Отвечает за публикации, статьи и произвольные статические страницы. + +### Модели (`blog/models.py`) +- **`Post`**: + - `post_type`: `B` (Пост блога) или `P` (Страница). + - `title`, `slug` (автоматическая транслитерация через `pytils.translit.slugify` с обработкой коллизий). + - `is_published`, `published_at`, `updated_at`. + - `content` (HTML-разметка), `excerpt` (тизер). + - `image` (обложка для превью и Open Graph). + - SEO-поля: `seo_title`, `seo_description`, `seo_keywords`. + - Метод `get_absolute_url()`: возвращает `/blog//` для постов или `//` для страниц. + +### Представления (`blog/views.py`) +- `post_list` (`/blog/`): список опубликованных статей блога с пагинацией. +- `post_detail` (`/blog//`): детальная страница поста с Open Graph мета-тегами и разметкой. +- `page_detail` (`//`): отображение статических страниц. +- `sitemaps.py`: генерация `sitemap.xml` по опубликованным записям. diff --git a/_prj_blueprint/deployment.md b/_prj_blueprint/deployment.md new file mode 100644 index 0000000..4b91582 --- /dev/null +++ b/_prj_blueprint/deployment.md @@ -0,0 +1,33 @@ +# Деплой, окружение и регламент релизов + +## 1. Конфигурация окружения (.env) +Обязательные переменные: +- `SECRET_KEY`: секретный ключ Django. +- `DEBUG`: `True` для локальной разработки, `False` для продакшена. +- `ALLOWED_HOSTS`: разрешенные хосты через запятую (например, `typograph.cube2.ru,localhost`). +- `CSRF_TRUSTED_ORIGINS`: доверенные URL (например, `https://typograph.cube2.ru,http://localhost:8000`). +- `ADMIN_URL`: путь к панели администратора (например, `mysecretadmin/`). + +## 2. Docker и инфраструктура +- **`Dockerfile`**: базовый образ `python:3.13-slim`, установка Poetry, сборка зависимостей, запуск через Gunicorn. +- **`docker-compose.yml`**: конфигурация для разработки (монтирование исходного кода, базы данных и папок статики/медиа). +- **`docker-compose.prod.yml`**: конфигурация для продакшена со связанным сервисом Nginx (`config/nginx/`). + +## 3. Чек-лист выпуска релиза (согласно NOTE.md) +Перед созданием релизного тега: +1. Протестировать функционал и миграции. +2. Внести описание изменений в `CHANGELOG.md`. +3. Обновить версии в: + - `pyproject.toml` (командой `poetry version patch` или вручную). + - `etpgrf_site/__init__.py` (при наличии `__version__`). + - `etpgrf_site/typograph/templates/typograph/base.html` (версия библиотеки и версия сайта в футере). +4. Закоммитить изменения: + ```bash + git add . + git commit -am "Обновление версии для релиза vX.Y.Z" + git push origin main + ``` +5. Запустить пайплайн сборки и деплоя через Gitea Actions путем простановки тега: + ```bash + git tag vX.Y.Z && git push origin vX.Y.Z + ``` diff --git a/_prj_blueprint/frontend.md b/_prj_blueprint/frontend.md new file mode 100644 index 0000000..b243bcd --- /dev/null +++ b/_prj_blueprint/frontend.md @@ -0,0 +1,34 @@ +# Фронтенд: Структура и сборка + +## 1. Стек и библиотеки +- **HTML / Django Templates:** шаблоны `base.html`, компоненты `typograph/` и `blog/`. +- **CSS:** Bootstrap 5, Bootstrap Icons, кастомные стили `public/static/css/etpgrf.css` с поддержкой темной/светлой темы. +- **Интерактивность:** + - **HTMX:** асинхронные запросы (отправка формы типографирования, динамическое обновление плашки со статистикой без перезагрузки). + - **Alpine.js:** управление состоянием клиентских виджетов и раскрывающихся списков опций. +- **Редактор текста:** CodeMirror 6. + +## 2. Сборка фронтенда и вендорных библиотек (`frontend-assembly/`) +- Каталог `frontend-assembly/` управляет сборкой редактора и подготовкой локальных копий всех сторонних библиотек для автономной работы и CDN-fallback: + - `src/editor.js`: инициализация CodeMirror 6, подсветка спецсимволов (` `, `­`, тире, кавычки), интеграция темной/светлой темы. + - `copy-vendor.js`: копирование дистрибутивов Bootstrap 5, Bootstrap Icons (включая шрифты), HTMX и Alpine.js из `node_modules` в `public/static/vendor/`. + - `package.json`: зависимости `@codemirror/*`, `bootstrap`, `bootstrap-icons`, `htmx.org`, `alpinejs`, `esbuild`. +- Команды сборки: + - `npm run build`: выполняет `build:codemirror` (сборка `editor.js`) и `build:vendor` (копирование всех библиотек в `static/vendor/`). + - `npm run build:codemirror`: компилирует бандл в `public/static/codemirror/editor.js`. + - `npm run build:vendor`: экспортирует вендорные CSS/JS/шрифты в `public/static/vendor/`. + - `npm run watch`: отслеживание изменений CodeMirror в реальном времени. + +## 3. CDN Fallback стратегия (`base.html`) +- Основные библиотеки подключаются из публичных CDN (jsDelivr, unpkg) для быстрой доставки и кэширования в браузерах. +- При блокировке или недоступности CDN срабатывает автоматический fallback на локальные статические копии: + - **CSS (Bootstrap, Bootstrap Icons):** атрибут `onerror="this.onerror=null;this.href='{% static ... %}';"` на тегах ``. + - **JS (HTMX, Bootstrap Bundle):** проверка глобального объекта (`window.htmx`, `window.bootstrap`) и подгрузка локальной копии через `document.write`. + - **JS (Alpine.js):** `onerror` динамически подключает локальный deferred-скрипт, а также предусмотрена резервная проверка в `DOMContentLoaded`. + +## 4. Клиентская статика (`public/static/`) +- `css/etpgrf.css` — основные стили сайта, оформление типографа и блога. +- `js/base.js` — вспомогательные клиентские скрипты (обработка куки-баннера, копирование текста, переключение тем). +- `codemirror/` — собранный esm-бандл редактора. +- `vendor/` — локальные копии сторонних библиотек (`bootstrap`, `bootstrap-icons`, `htmx`, `alpinejs`). +- `svg/` и `img/` — векторные и растровые логотипы для светлой/темной темы и мета-тегов Open Graph. diff --git a/_prj_blueprint/overview.md b/_prj_blueprint/overview.md new file mode 100644 index 0000000..2202ec4 --- /dev/null +++ b/_prj_blueprint/overview.md @@ -0,0 +1,51 @@ +# Архитектурный обзор проекта ETPGRF Site + +## 1. Назначение проекта +**ETPGRF Site** — веб-сервис и интерфейс для онлайн-типографирования текстов на базе библиотеки `etpgrf`, а также контентная платформа (блог, справочные и статические страницы, статистика использования). + +## 2. Технологический стек +- **Backend:** Python 3.13+, Django 6.0+, Poetry. +- **База данных:** SQLite 3 (файл `data/db-etpgrf.sqlite3` с увеличенным таймаутом блокировки). +- **Frontend:** + - Bootstrap 5 (CSS, сетка, компоненты, иконки bootstrap-icons). + - Alpine.js (декларативное состояние на клиенте). + - HTMX (динамическая подгрузка фрагментов, отправка форм типографирования, статистика). + - CodeMirror 6 (продвинутый редактор текста с подсветкой спецсимволов/сущностей). + - Сборщик фронтенда: `esbuild` в каталоге `frontend-assembly/`. +- **Инфраструктура & Деплой:** + - Docker & Docker Compose (`docker-compose.yml` для разработки, `docker-compose.prod.yml` для продакшена). + - Nginx (раздача статики `/static/` и медиа `/media/`, SSL-терминация, обратное проксирование к Gunicorn). + - Gunicorn (WSGI-сервер Django). + - CI/CD: Gitea Actions (автосборка Docker-образов по тегам `v*` и деплой). + +## 3. Структура директорий +``` +2026-etpgrf-site/ +├── .github/ # Инструкции для AI и CI +│ └── copilot-instructions.md +├── _prj_blueprint/ # Быстрый контекст и документация архитектуры +├── config/ # Конфигурационные файлы Nginx +│ └── nginx/ +├── data/ # Хранилище базы данных SQLite (db-etpgrf.sqlite3) +├── etpgrf_site/ # Исходный код Django +│ ├── manage.py +│ ├── etpgrf_site/ # Корневой модуль конфигурации (settings, urls, wsgi) +│ ├── typograph/ # Приложение типографа (обработка, DailyStat, UI) +│ └── blog/ # Приложение блога и статических страниц +├── frontend-assembly/ # Node.js окружение сборки CodeMirror 6 (esbuild) +├── media/ # Загружаемые медиа-файлы (обложки постов) +├── public/ # Статика проекта +│ ├── static/ # Исходная статика (css, js, img, svg, codemirror) +│ └── static_collected/ # Собранная статика collectstatic +├── Dockerfile # Сборка продакшн-образа +├── docker-compose.yml # Dev-окружение +├── docker-compose.prod.yml # Prod-окружение +├── pyproject.toml # Poetry зависимости и метаданные +├── NOTE.md # Инструкции по релизам и версионированию +└── CHANGELOG.md # История версий +``` + +## 4. Ссылки на детальные описания +- [Бэкенд и логика приложений](backend.md) +- [Фронтенд и сборка](frontend.md) +- [Деплой, окружение и релизный процесс](deployment.md) diff --git a/ci-cd.md b/ci-cd.md new file mode 100644 index 0000000..deef0c8 --- /dev/null +++ b/ci-cd.md @@ -0,0 +1,57 @@ +# CI/CD с Gitea Runner + +Gitea Runner — это инструмент для выполнения CI/CD задач, интегрированный с Gitea. Он позволяет автоматизировать +процессы сборки, тестирования и развертывания приложений. + +В нашем репозии входим в "Настройки" -> "Действия" -> "Ранеры" и создаем новый Runner. Для это получим регистрационный +токен. + +## Настройка Gitea Runner на macOS + +```shell +docker run -d --restart always \ [±main ●] + -v /var/run/docker.sock:/var/run/docker.sock \ + -e GITEA_INSTANCE_URL=https://git.cube2.ru \ + -e GITEA_RUNNER_REGISTRATION_TOKEN=здест_полученный_токен \ + -e GITEA_RUNNER_REGISTRATION_TOKEN=здесь_вставляем_полученный_токен \ + -e GITEA_RUNNER_NAME=mac-mini-runner \ + --name gitea-runner \ + gitea/act_runner:latest +``` + + Увидим: + ```txt + Unable to find image 'gitea/act_runner:latest' locally +latest: Pulling from gitea/act_runner +6e174226ea69: Pull complete +adcf2c0b73c2: Pull complete +e0c151a1a72f: Pull complete +3333c50851c8: Pull complete +Digest: sha256:0000000000000000000000000000000000000000000000000000000000000000 +Status: Downloaded newer image for gitea/act_runner:latest +f000000000000000000000000000000000000000000000000000000000000000 +``` + +## Обновление в продакшен + +Наш `.gitea/workflows/docker-publish.yaml` настроен на публикацию Docker образа при создании тега, который начинается +с `v`. Образ собирается на компьютпере разработчика (см. главу Настройка Gitea Runner на macOS) и пакет загружается +в Gitea. + +На хостинге работает Docker Stack с нашим проектом. Кроме `etpgrf-site-etpgrf-backend` и `etpgrf-site-etpgrf-nginx` +в нем работает `etpgrf-site-watchtower`, который следит за обновлениями образов на Gitea и если находит обновление, то +получает новый образ и перезапускает контейнер с новым образом. + +Т.о. если мы хотим обновить продакшен, нам нужно просто создать новый тег в репозитории: + +```shell +git tag v0.1.x +git push origin v0.1.x +``` + +sudo docker exec -it etpgrf-site-etpgrf-backend-1 python etpgrf_site/manage.py createsuperuser + + + +e-serg +f0b01jLq$eRyID \ No newline at end of file