Metadata-Version: 2.5
Name: anicli-multi
Version: 0.4.1
Summary: Мультиисточниковый поиск аниме, фильмов и сериалов поверх anicli-ru
Project-URL: Source, https://github.com/root3315/anicli-multi
Author: sozda
License: MIT
License-File: LICENSE
License-File: NOTICE
Keywords: anicli,anime,cli,mpv
Classifier: Environment :: Console
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.9
Requires-Dist: anicli-ru<7,>=6.1
Requires-Dist: platformdirs>=3.0
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# anicli-multi

Поиск аниме, фильмов и сериалов сразу по нескольким источникам поверх
[anicli-ru](https://github.com/vypivshiy/ani-cli-ru).

Обычный `anicli-ru` ищет в одном источнике, выбранном при запуске, и только аниме. Если
тайтла там нет, приходится выходить и перезапускаться с другим `-s`. `anicli-multi`
опрашивает несколько источников параллельно и показывает **одну строку на тайтл** с
пометкой, где он доступен.

```
~ наруто

  1  Наруто: Ураганные хроники (animego, yummy-anime, anilibria)
  2  Боруто: Новое поколение Наруто (animego, anilibria)
  3  Наруто: Последний фильм (hdrezka, yummy-anime)

~/multi 1
```

Фильмы, сериалы, мультфильмы и шоу тоже:

```
~ интерстеллар

  1  Интерстеллар [фильм] (hdrezka)
  2  Наука «Интерстеллар» [фильм] (hdrezka)

~ во все тяжкие

  1  Во все тяжкие [сериал] (hdrezka)
  2  Во все тяжкие: Медведи [мультфильм] (hdrezka)
  3  El Camino: Во все тяжкие [фильм] (hdrezka)
```

Служебные хвосты со страниц поиска — «3 сезон, 10 серия», «Завершен (все серии)»,
«Онгоинг» — из названий вырезаются.

Тип показывается бейджем у всего, что не аниме. Одноимённые аниме и игровой фильм
остаются разными строками — тип входит в ключ группировки.

Выдача упорядочена по релевантности запросу: сначала точные совпадения, затем названия,
начинающиеся с запроса, затем содержащие его. При равной релевантности выше то, что
найдено на большем числе источников. Строки, где запрос вообще не встречается в названии,
отсекаются — под таблицей пишется, сколько скрыто.

### Фильтр по типу

Достаточно дописать тип к запросу — отдельный синтаксис не нужен:

```
~ жизнь по вызову сериал

  1  Жизнь по вызову [сериал] (hdrezka)
```

Слово типа вырезается из запроса к источникам и становится фильтром. Понимает `сериал`,
`фильм`, `кино`, `аниме`, `мультфильм`, `мультик`, `шоу` и их формы множественного числа.
Срабатывает, только если слово стоит первым или последним.

Фильтр мягкий: если под тип ничего не подошло, показывается вся найденная выдача с
пометкой. Поэтому «наруто последний фильм» находит «Наруто: Последний Фильм», хотя тот
лежит в разделе аниме.

### Уточнения в запросе

Дописывать `1 сезон`, `5 серия`, `смотреть`, `онлайн`, `бесплатно`, `hd` можно — они
вырезаются перед отправкой в источники. Это не косметика: источники сами начинают отдавать
мусор, если получают такой запрос целиком.

Слова `сезон` и `серия` вырезаются только рядом с числом, поэтому «Сезон охоты» ищется как
надо.

Совпадение считается не только по фразе целиком: если все значимые слова запроса есть в
названии — пусть вразбивку и в другом порядке — строка считается релевантной. «ураганные
хроники наруто» находит «Наруто: Ураганные хроники».

## Установка

Нужен [mpv](https://mpv.io/) в PATH и Python 3.9 или новее.

На Linux, macOS и Windows одинаково:

```
pipx install anicli-multi
```

или

```
uv tool install anicli-multi
```

Установка mpv: `sudo apt install mpv` на Debian и Ubuntu, `sudo pacman -S mpv` на Arch,
`brew install mpv` на macOS, `winget install shinchiro.mpv` на Windows.

## Использование

```
ani                              запустить REPL
ani наруто                       запустить и сразу искать
ani --sources animego,hdrezka    разово переопределить набор источников
```

В REPL достаточно набрать название — слово `search` не нужно. Команды:

| Команда | Алиас | Что делает |
|---|---|---|
| `search <запрос>` | `s` | поиск по всем настроенным источникам |
| `ongoing` | `o` | текущие онгоинги |
| `history` | `h` | недавно просмотренное |
| `config` | | настройки anicli-ru |
| `help` | | справка |
| `exit` | `q` | выход |

Выбрав тайтл, доступный на нескольких источниках, вы отдельно выбираете источник —
дальше идёт штатный флоу anicli-ru: серия, озвучка, запуск в mpv.

### Навигация

Внутри поиска работают команды перемещения:

| Ввод | Что делает |
|---|---|
| `..` | шаг назад: от серий к результатам поиска, оттуда — в главное меню |
| `~` | сразу в главное меню |
| `q` / `exit` | выход из программы (из главного меню) |
| Ctrl+D | тоже выход |

Подсказка показывается под таблицей результатов, под списком серий и после
возврата из плеера — чтобы после просмотра не пришлось гадать, как выйти.

Все опции `anicli-ru cli` работают как есть: `-q 1080`, `--proxy`, `--cookies-from-browser`,
`-H`, `--timeout` и остальные.

## Конфиг

`%APPDATA%\anicli-multi\config.json` на Windows, `~/.config/anicli-multi/config.json` на Linux
и macOS:

```json
{
  "sources": ["animego", "hdrezka", "yummy-anime", "anilibria"],
  "timeout": 10.0,
  "bare_text_search": true,
  "hdrezka_categories": ["animation", "films", "series", "cartoons", "show"],
  "max_results": 30
}
```

`max_results` — сколько строк показывать. Лимит честный: скрытые строки нельзя выбрать по
номеру, потому что дальше передаётся только показанный срез.

`hdrezka_categories` задаёт, какие разделы каталога hdrezka искать. Значение
`["animation"]` возвращает прежнее поведение — только аниме.

`sources` задаёт и набор, и приоритет: название тайтла показывается в варианте от первого
источника в списке. `timeout` — предел ожидания одного источника в секундах.
`bare_text_search: false` возвращает строгий режим, где голый текст даёт «Unknown command».

Доступные источники: `animego`, `hdrezka`, `yummy-anime`, `anilibria`, `animevost`,
`dreamcast`. Источники `anilibme` и `sameband` из `anicli-api` на момент написания ничего не
отдают, поэтому в набор по умолчанию не входят.

## Ограничения

- Тайтлы склеиваются только при точном совпадении названия после нормализации. Один тайтл
  под русским и ромадзи-названием на разных источниках останется двумя строками. Это
  осознанный размен: fuzzy-матчинг склеивал бы и разные тайтлы, а это хуже лишней строки.
- Опечатка в команде (`sarch наруто`) уйдёт в поиск, а не в сообщение об ошибке. Отключается
  через `bare_text_search: false`.
- Поиск идёт не быстрее самого медленного источника, но ограничен сверху значением `timeout`.
  Источник, не уложившийся в него, выпадает из выдачи с пометкой под таблицей.
- Фильмы, сериалы, мультфильмы и шоу приходят только с `hdrezka` — остальные источники
  аниме-только. Склеивать их между источниками нечего, и если hdrezka недоступен, кино не
  найдётся вовсе.
- Расширенный поиск по hdrezka опирается на вёрстку сайта. Если она изменится, `hdrezka`
  автоматически откатится в аниме-режим с предупреждением, а не сломает инструмент.

## Разработка

```
uv venv --python 3.10
uv pip install -e ".[dev]"
python -m pytest
```

Тесты с сетью помечены маркером `network` и в обычный прогон не входят:

```
python -m pytest -m network
```

## Лицензия

MIT. См. `NOTICE` — проект построен на `anicli-ru` и `anicli-api`, обе тоже MIT.
