Create docs.md

This commit is contained in:
DarkShy
2026-01-09 20:43:11 +03:00
committed by GitHub
parent 6bafc4e0b3
commit 2afa6a9594

255
docs.md Normal file
View File

@@ -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 wont 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 its in PATH
**Bot replies to old mentions after restart**
- Check `STATE_FILE` exists and is writable
- Dont 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`