Tovruna

← Лента

Asakura @asakura · 58 минут назад
📄 Tovruna Forum журнал проекта, состояние и инструкция для продолжения.md

Tovruna Forum: журнал проекта, состояние и инструкция для продолжения

Дата: 27 октября 2026 (время сервера, Ташкент). Владелец: Luka. Язык общения: русский, ответы краткие и прямые. Если данные расходятся с более старыми документами («передача в новый чат», «что сделано и что дальше», «итоги сессии 27 октября»), верить этому документу.

1. Цель и первоначальный план

Компактный, быстрый и безопасный форум на собственном Fedora-ноутбуке, домен tovruna.uz. Дизайн в стиле Telegram, тёмная тема по умолчанию. Все повседневные действия (разделы, пользователи, роли, жалобы, реклама, настройки) должны выполняться через браузерную админ-панель без правки кода.

Первоначальные этапы и их состояние:

Этап Содержание Состояние
0 Аудит Завершён
1 Минимальный сайт по домену (Caddy, HTTPS) Завершён
2 База данных и миграции Завершён
3 Авторизация: регистрация, вход, роли Завершён
4 Основной форум: темы, сообщения, поиск, профили, медиа Завершён, переделан в «группы» (см. разделы 5 и 6)
5 Админ-панель /panel/ Впереди
6 Модерация: жалобы, блокировки, журнал действий Впереди
7 Реклама и объявления Впереди
8 Безопасность и производительность Частично (антифлуд, проверка загрузок), основное впереди
9 Публичное развёртывание (HSTS, firewall) Сайт уже открыт по HTTPS, остальное впереди
10 Обслуживание, чистка резервных копий Впереди

В ходе работы владелец добавил: группы как в Telegram с боковой панелью, публичные и приватные адреса, личные сообщения с «прочитано», кастомизацию ников и текстов, ленту рекомендаций на главной.

2. Инфраструктура (подтверждено)

  • Ноутбук Fedora 44 KDE, пользователь luka, работает постоянно, сон отключён. Intel i5-1135G7, около 15 ГБ RAM, диск btrfs 58 ГБ, свободно около 41 ГБ. Wi-Fi 192.168.1.36 (закреплён в роутере), проброшены внешние TCP 80 и 443.
  • Внешний IPv4 91.229.162.31 (может измениться). Домен tovruna.uz у регистратора aHOST, DNS на Cloudflare, A-запись в режиме DNS only.
  • SSH: внешний порт 2222 → 22. Вход по паролю пока включён (долг).
  • Стек: Python 3.14.6, Django 6.1.2, Gunicorn 26.2.0 (2 воркера, 127.0.0.1:8000, лимит памяти 512 МБ) как пользовательская служба tovruna.service (Linger включён). Перед ним Caddy 2.10.2: сайт описан в /etc/caddy/Caddyfile.d/tovruna.caddyfile, сертификат Let’s Encrypt, редирект с http на https.
  • БД: SQLite в режиме WAL, каталог ~/tovruna/data/ (права 700). Секреты в ~/tovruna/.env (права 600), не показывать.
  • Время: chronyd. Если часы убегают, sudo chronyc makestep, проверка chronyc tracking.
  • Firewall: открыты http, https, ssh, а также весь диапазон 1025-65535 (слишком широко, долг).
  • Minecraft (порт 25565) сейчас не запущен, форум ему не мешает.

3. Структура проекта (~/tovruna)

  • config/: settings.py (часовой пояс Asia/Tashkent, язык ru, core.context.sidebar в контекстных процессорах, core.middleware.LastSeenMiddleware после AuthenticationMiddleware), urls.py (порядок: admin, accounts, forum, core).
  • core/: context.py (список групп пользователя для боковой панели), middleware.py (в файле есть старый код и класс LastSeenMiddleware), шаблоны base.html (весь CSS, шапка, боковая панель, меню аватара) и welcome.html (для гостей).
  • accounts/: свой User (роль, display_name, bio, avatar_path, banner_path, last_seen), ProfilePhoto (история фото), profile_media.py (save_profile_photo, save_group_image), вход, регистрация, профиль.
  • forum/: models.py, views.py, forms.py, urls.py, access.py (visible_topics), media.py (проверка и перекодирование загрузок), шаблоны feed.html, topic.html, _post.html, group_form.html, new_group.html.
  • data/ (база), каталог с загруженными файлами (MEDIA_ROOT).

4. Модель данных

  • Topic = группа (как чат в Telegram). Поля: section, author, title, description, handle (адрес, уникальный, хранится строчными), is_private, invite_code, avatar_path, banner_path, is_pinned, is_closed, last_activity_at. Свойства avatar_url, banner_url, метод get_absolute_url() (/<handle>/ либо /t/<id>/).
  • Membership: участники группы (topic, user, уникальная пара). Писать в группу может только участник.
  • Section: теперь только скрытый контейнер (обязателен для темы). Единственный раздел «Болталка» (pk=1) нигде не показывается, новые группы создаются в первом разделе.
  • Post: topic, author, body, edited_at, is_deleted (мягкое удаление), reply_to. Attachment: файлы сообщений и фото профилей и групп.
  • Применённые миграции: accounts.0004, accounts.0005_last_seen, forum.0005_post_reply_to, forum.0006_groups, forum.0007_group_profile. makemigrations --check даёт No changes detected.

5. Решения владельца

  • Админку Django /admin/ в интернет не открываем, управление через собственную /panel/. Живое обновление опросом (раз в 5 секунд), не WebSocket.
  • Группы вместо «форума и разделов». Главная для вошедших: лента карточек групп (рекомендации автоматически: больше сообщений за 7 дней, потом свежесть). Слева боковая панель со списком своих групп (на телефоне выезжает по ☰).
  • Публичная группа: адрес tovruna.uz/имя, 3-32 символа (латиница, цифры, _, .), первой буква, без точки в конце и без двух точек подряд, без учёта регистра. Читать может любой вошедший, писать только после вступления.
  • Приватная группа: адрес tovruna.uz/+код (случайный код), не видна в ленте, панели и поиске чужим, вход по ссылке-приглашению.
  • Группа имеет фото, шапку, описание, число участников и «в сети» (заходил за последние 5 минут). Лимит: не более 5 новых групп в час на человека.
  • Профиль: аватар и шапка (фото или GIF), история фото, видео в профиле нет. Лимиты: фото 5 МБ, GIF 8 МБ, видео 30 МБ, квота 200 МБ. Имя пользователя 5-32 символа.
  • В группе нет номеров страниц, лента как в мессенджере. Ответ на сообщение: двойной клик или «↩». Правка и удаление: автор своё, суперадмин любое, удаление мягкое.
  • Личные сообщения отдельным разделом, отметка «прочитано» только там. Кастомизация: владелец просил подборку вариантов (список ниже).

6. Что сделано в этой сессии

Подтверждено выводом или словами владельца:

  • Боковая панель слева (на телефоне открывается и закрывается), главная-лента вместо «Общее / Болталка», подпись «© Tovruna» убрана.
  • Миграции групп и last_seen применены, копии data/ сделаны.
  • Тест с откатом (все 10 строк совпали): создание группы с фото, шапкой и описанием; «Участников: 1», «в сети: 1» в шапке; не участник не может писать (403); вступление; участник пишет; чужой не открывает настройки (403); владелец открывает и сохраняет настройки; откат без остатка.
  • Исправлены две моих ошибки: LastSeenMiddleware не создавался, потому что файл уже был (сайт падал при старте), и type(u) на SimpleLazyObject (ошибка для вошедших). Обе исправлены, сайт отвечает 200.

Выдано, но в браузере или выводом не подтверждено:

  1. Внешний вид шапки группы, формы «Создать группу» с предпросмотром фото и шапки, фото групп в панели и ленте (владелец ещё не прислал скриншоты).
  2. Приватные группы: тест (чужой не видит по адресу и номеру, вход по /+код) выдавался, вывода нет.
  3. Скрипт, выдавший участие всем, кто писал в старых группах (участников всего: N): вывода нет.
  4. Из прошлых документов: GIF-аватар и анимированная шапка, отказ на поддельном файле, профиль на телефоне и в светлой теме, видео HEVC с телефона, поведение при нехватке памяти (journalctl --user -u tovruna -n 30), перезагрузка ноутбука (должны подняться tovruna.service и Caddy), метки времени «из будущего» у старых тестовых сообщений (до 02:40 27 октября).

7. План дальше (по порядку)

  1. Подтвердить пункты 1-3 раздела 6 (скриншоты формы и шапки группы, создание группы через меню аватара, тест приватной группы).
  2. Починить new_topic (адрес /s/<slug>/new/): он создаёт тему без Membership автора. Либо добавить участие, либо убрать старые маршруты разделов (/s/<slug>/, шаблоны index.html, section.html).
  3. Правка и удаление сообщений: меню «⋯», права (автор, role=admin, суперпользователь), отметка «изменено» (edited_at), мягкое удаление, как удалённое исчезает у других в живой ленте, запись в ActionLog.
  4. Личные сообщения с «прочитано»: новые модели и миграция (перед ней остановить службу и скопировать data/), галочки как в Telegram, опрос, блок про ЛС на приветственной странице.
  5. Кастомизация (владелец выбирает номера): (1) Discord: акцентный цвет, плотность, размер шрифта, пузыри или строки; (2) Telegram: обои чата, форма пузырей, цвет своих сообщений; (3) Reddit и X: светлая, тёмная и чёрная (OLED) темы, цвет ссылок, режим чтения; (4) Steam: фон профиля, рамка аватара, цвет имени; (5) Tumblr и VK: свой фон и цвета профиля; (6) Twitch: цвет ника в чате, значки рядом с именем; (7) Notion: выбор и порядок блоков ленты. Отдельно владелец просил кастомизацию текстов и ников.
  6. Просмотр фото и видео (сетка, полноэкранный просмотр, свайп), без внешних библиотек.
  7. Предпросмотр ссылок (защита от SSRF, кэш в базе, картинки через Pillow).
  8. Редизайн остальных страниц: reply.html (ошибки ответа), результаты поиска, форма редактирования профиля, список групп в профиле (сейчас там «Последние темы»).
  9. Этап 5: админ-панель /panel/ (путь не начинать с /admin): Dashboard, группы, пользователи с блокировкой и ролями, настройки, ActionLog. Этапы 6-10: модерация, реклама, безопасность и производительность, публичное развёртывание, обслуживание.

8. Открытые вопросы и технический долг

  • В config/urls.py всё ещё подключён admin/, хотя решено не открывать админку в интернет: закрыть в Caddy или убрать.
  • SSH по паролю включён: перейти на ключи с запасной сессией. Узнать, статический ли внешний IP, нужен ли Cloudflare proxy, перейти с Wi-Fi на кабель.
  • Ограничение частоты для поиска, загрузок и эндпоинтов опроса и подгрузки /t/<id>/new/ и /t/<id>/older/ (доступны без входа): Этап 8. Приватные группы по этим адресам защищены правами, но лимитов запросов нет.
  • Новые служебные адреса из одного сегмента (/что-то/) должны добавляться в RESERVED_HANDLES в forum/forms.py, иначе имя группы перехватит страницу.
  • Очистка файлов-сирот (Этап 10): не удалять вложения с profile_photo, а также файлы, на которые ссылаются avatar_path и banner_path групп и пользователей. Мониторинг свободного места.
  • Видео HEVC отклоняются: решить, нужна ли перекодировка. HSTS включать после стабильной работы HTTPS. Аппаратные часы (RTC) хранятся в местном времени из-за Windows, пока не трогали.

9. Резервные копии (почистить на Этапе 10)

  • Базы в ~/tovruna: data.bak-avatars, data.bak-reply, data.bak-groups, data.bak-groups2.
  • Файлы кода рядом с изменёнными: суффиксы .bak-sb, .bak-sb2, .bak-sb3, .bak-feed, .bak-groups, .bak-g2 ... .bak-g8 и более старые .bak*. Список: find . -name '*.bak*' -not -path './.venv/*'.

10. Правила работы с ассистентом и уроки

Русский язык, кратко. Один шаг за раз: действие, проверка, следующий шаг. У каждой команды указано, где выполнять и нужен ли sudo. Перед правкой файла копия .bakN, перед миграциями остановить службу (systemctl --user stop tovruna) и скопировать data/ (cp -a data data.bak-имя). Не утверждать, что что-то прошло, пока нет вывода. Проверки через python manage.py shell внутри transaction.atomic() с transaction.set_rollback(True). Правки скриптами с assert, чтобы повтор был безопасным. Секреты из .env не показывать. Новые пакеты только с согласия.

Уроки:

  • После systemctl --user restart tovruna перед curl ставить sleep 4. Код 000 без ошибок в журнале значит, что служба ещё стартует.
  • Не писать test ! -e файл && cat > файл: если файл уже есть, запись молча пропускается (так сломался LastSeenMiddleware). Сначала проверять наличие файла, а нужный код дописывать скриптом.
  • Перед перезапуском проверять загрузку всех прослоек: python -c "import os, django; os.environ['DJANGO_SETTINGS_MODULE']='config.settings'; django.setup(); from django.utils.module_loading import import_string as i; [i(m) for m in django.conf.settings.MIDDLEWARE]; print('ok')".
  • request.user в Django обёрнут в SimpleLazyObject: модель брать через get_user_model(), а не type(request.user).
  • Тесты ходят через Client(HTTP_HOST="127.0.0.1") и force_login. Проверять сайт не только curl без входа, но и под вошедшим пользователем.
  • Длинные файлы через cat > ... <<'EOF' давать частями и проверять wc -l и ast.parse. Если нужен код файла, просить cat, владелец присылает вывод.
  • Полезные команды: systemctl --user status tovruna, journalctl --user -u tovruna -n 30 --no-pager, python manage.py check, python manage.py makemigrations --check.

11. Стартовое сообщение для нового чата

Загрузите в новый чат этот документ (скачайте его как Markdown через меню документа) и, при желании, старые файлы «Tovruna_Forum_передача_в_новый_чат.md» и «Tovruna_Forum_что_сделано_и_что_дальше.md». Затем вставьте:

Продолжаем разработку форума Tovruna (tovruna.uz) на моём Fedora-ноутбуке. Во вложении журнал проекта с актуальными статусами. Прочитай целиком и работай по правилам из раздела «Правила работы с ассистентом и уроки». Начни с раздела 7, пункт 1 (подтвердить шапку группы и форму создания, тест приватных групп), затем пункт 2 (new_topic без Membership) и далее по плану. Если нужен код файла, попроси cat, я пришлю вывод.

Ответы: 1

Asakura @asakura · 57 минут назад

Tovruna Forum: журнал проекта v2, состояние и инструкция для продолжения

Дата: 27 октября 2026 (время сервера, Ташкент). Владелец: Luka. Язык: русский, ответы краткие и прямые. Если данные расходятся с более старыми документами («журнал проекта», «передача в новый чат», «что сделано и что дальше»), верить этому документу.

1. Где мы сейчас

Форум работает на tovruna.uz (HTTPS, Caddy → Gunicorn → Django + SQLite). За эту сессию сделано: группы с окном информации, правка и удаление сообщений, служебные строки «вступил(а)», просмотр фото профиля, личные сообщения с галочками. Последний выданный шаг (медиа в личных сообщениях) не подтверждён выводом: с проверки его состояния и начинаем.

2. Первым делом в новом чате

Выполнить в ~/tovruna (sudo не нужен) и прислать вывод:

systemctl --user status tovruna --no-pager | head -5
ls dm/migrations/
grep -c MessageAttachment dm/models.py dm/views.py
python manage.py showmigrations dm forum | tail -12
python manage.py makemigrations --check
ls -d data.bak-*

Войдите, чтобы отвечать и ставить лайки.