From 2afa6a959471d8ba428b88f77f0c10463117398f Mon Sep 17 00:00:00 2001 From: DarkShy <30442729+DarkShyMW@users.noreply.github.com> Date: Fri, 9 Jan 2026 20:43:11 +0300 Subject: [PATCH] Create docs.md --- docs.md | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 docs.md diff --git a/docs.md b/docs.md new file mode 100644 index 0000000..a58e29c --- /dev/null +++ b/docs.md @@ -0,0 +1,255 @@ + +# Documentation / Документация + +## EN + +### 1) How the bot works + +1. Poll Mastodon notifications for `mention` type (`/api/v1/notifications`). +2. For each mention: + - Extract plain text from HTML content + - Remove all mentions like `@giffer` / `@giffer@domain` / `@ giffer` + - Detect `nsfw` keyword + - Parse remaining text into tags (supports quotes and `-tag`) +3. Query Furbooru (Philomena API) for GIF images: + - SFW query adds: `safe, animated, gif` + - NSFW query adds: `animated, gif` (plus `filter_id` if configured) +4. Pick a random candidate GIF result. +5. Upload media to Mastodon: + - Try GIF representations in descending size: `full → large → medium → small → thumb` + - If Mastodon rejects GIF with 422 “not supported” / size limits: + - Convert GIF → MP4 using ffmpeg + - Upload MP4 instead +6. Wait for Mastodon media processing to finish (poll `/api/v1/media/:id`): + - prevents 422 “processing not finished” when posting the status +7. Post reply status with uploaded media: + - SFW: normal reply + - NSFW: `sensitive=True` and `spoiler_text="NSFW"` (+ configurable visibility) +8. Save state: + - `last_seen_notif_id` + - list of processed `status_id` (to avoid replying twice after restarts) + +--- + +### 2) Query syntax + +The bot converts the mention text to Furbooru tags: + +- Spaces become multiple tags: + `cute fluffy tail` → `cute, fluffy, tail` +- Commas are also supported: + `cute, fluffy, tail` +- Quoted phrases stay together as one tag: + `"rainbow dash"` → `rainbow dash` +- Negative tags are supported: + `-gore` → `-gore` +- `random` / `rnd` are ignored and treated as no user tags (random result). + +NSFW mode: +- Any mention containing the word `nsfw` enables NSFW mode and removes that word from the tag list. + +--- + +### 3) Furbooru API notes + +Endpoint used: +- `GET /api/v1/json/search/images?q=...&per_page=50&page=1` + +The bot filters results: +- `format == "gif"` +- has usable `representations` URL(s) +- chooses randomly among candidates + +--- + +### 4) ALT text generation + +ALT text is generated from Furbooru tags: +- removes rating/system tags like `safe`, `nsfw`, `animated`, `gif` +- keeps up to 20 tags +- prefix: + - `Animated GIF: ...` + - `NSFW animated GIF: ...` + +--- + +### 5) Rate limiting & anti-spam + +Two layers: + +1) Per-user cooldown: +- If the same user mentions the bot again within `USER_COOLDOWN_SEC`, bot skips. + +2) Global token bucket: +- `GLOBAL_RATE_PER_SEC` tokens refill rate +- `GLOBAL_BURST` max burst +- applies to Furbooru requests + +--- + +### 6) Prevent replying twice (state) + +The bot persists state to `STATE_FILE` (default `giffer_state.json`): +- `last_seen_notif_id` (so it won’t re-fetch old notifications after restart) +- `processed_status_ids` (cache to skip duplicates even if server repeats notifications) + +If you delete the state file, the bot may reply to old mentions again. + +--- + +### 7) Windows reliability notes + +This project includes hardening for Windows: +- `socket.setdefaulttimeout(SOCKET_DEFAULT_TIMEOUT)` to prevent rare indefinite hangs +- `requests.Session` with retries +- explicit connect/read timeouts +- Mastodon API calls are wrapped with a watchdog timeout (thread executor) + +--- + +### 8) Troubleshooting + +**Bot replies “media processing not finished” / 422** +- Increase `MEDIA_PROCESS_MAX_WAIT` (e.g. 90) +- Your instance may be slow during peak hours + +**GIF rejected: “1440x1440 GIF files are not supported”** +- Expected on some instances +- Bot will fallback to smaller GIF representations +- Then fallback to MP4 conversion + +**MP4 conversion fails** +- Install bundled ffmpeg: + - `py -m pip install imageio-ffmpeg` +- Or install system ffmpeg and ensure it’s in PATH + +**Bot replies to old mentions after restart** +- Check `STATE_FILE` exists and is writable +- Don’t delete `giffer_state.json` + +--- + +## RU + +### 1) Как работает бот + +1. Опрос уведомлений Mastodon типа `mention` (`/api/v1/notifications`). +2. Для каждого упоминания: + - Достаём текст из HTML + - Удаляем любые упоминания (`@giffer`, `@giffer@домен`, `@ giffer`) + - Определяем наличие `nsfw` + - Парсим оставшееся в теги (есть кавычки и `-тег`) +3. Запрос на Furbooru (Philomena API) за GIF: + - SFW добавляет: `safe, animated, gif` + - NSFW добавляет: `animated, gif` (и `filter_id`, если задан) +4. Выбор случайного подходящего результата. +5. Загрузка медиа в Mastodon: + - Пробуем GIF (full → large → medium → small → thumb) + - Если инстанс отклоняет GIF с 422 (“not supported”/лимиты): + - Конвертим GIF → MP4 через ffmpeg + - Заливаем MP4 +6. Ждём завершения обработки медиа в Mastodon (`/api/v1/media/:id`): + - предотвращает 422 “обработка не окончена” при публикации +7. Публикуем ответ: + - SFW: обычный ответ + - NSFW: `sensitive=True` и `spoiler_text="NSFW"` (+ настраиваемая видимость) +8. Сохраняем состояние: + - `last_seen_notif_id` + - кэш `status_id` (чтобы не отвечать повторно после рестарта) + +--- + +### 2) Синтаксис запроса (теги) + +- Пробелы = несколько тегов: + `cute fluffy tail` → `cute, fluffy, tail` +- Запятые тоже можно: + `cute, fluffy, tail` +- Кавычки сохраняют фразу как один тег: + `"rainbow dash"` → `rainbow dash` +- Минус-теги работают: + `-gore` → `-gore` +- `random` / `rnd` игнорируются (рандомный результат). + +NSFW-режим: +- Если в тексте есть слово `nsfw`, включается NSFW и это слово убирается из тегов. + +--- + +### 3) Про Furbooru API + +Используем: +- `GET /api/v1/json/search/images?q=...&per_page=50&page=1` + +Фильтруем результаты: +- `format == "gif"` +- есть рабочие ссылки `representations` +- выбираем случайно + +--- + +### 4) ALT-текст + +ALT строится из тегов Furbooru: +- выкидываются системные/рейтинг-теги `safe`, `nsfw`, `animated`, `gif` +- берём до 20 тегов +- префикс: + - `Animated GIF: ...` + - `NSFW animated GIF: ...` + +--- + +### 5) Антиспам / Rate-limit + +1) Кулдаун на пользователя (`USER_COOLDOWN_SEC`) +2) Глобальный token-bucket (`GLOBAL_RATE_PER_SEC`, `GLOBAL_BURST`) + +--- + +### 6) Защита от повторных ответов (state) + +Файл `STATE_FILE` (по умолчанию `giffer_state.json`) хранит: +- `last_seen_notif_id` +- `processed_status_ids` + +Если удалить state-файл — бот может снова отвечать на старые упоминания. + +--- + +### 7) Особенности Windows + +Усиленная защита от “вечных зависаний”: +- `socket.setdefaulttimeout(...)` +- `requests.Session` с retry +- явные таймауты connect/read +- watchdog-таймаут вокруг вызовов Mastodon API + +--- + +### 8) Типовые проблемы + +**422 “обработка файлов не окончена”** +- увеличь `MEDIA_PROCESS_MAX_WAIT` (например до 90) +- инстанс может быть медленным + +**“1440x1440 GIF files are not supported”** +- ожидаемо для некоторых инстансов +- бот уйдёт на меньшие версии GIF, потом на MP4 + +**Не конвертится в MP4** +- поставь `imageio-ffmpeg`: + - `py -m pip install imageio-ffmpeg` +- или установи ffmpeg в систему и добавь в PATH + +**После рестарта отвечает на старые упоминания** +- проверь, что `giffer_state.json` не удаляется и доступен на запись + +--- + +### 9) Рекомендуемая структура репо + +- `giffer_bot.py` +- `README.md` +- `docs.md` +- `.gitignore` (исключить `config.env`, `giffer_state.json`, `*.log`) +- `LICENSE`