# altrepo

Асинхронный Python-клиент для работы с сервисами репозитория ALT Linux. Библиотека предоставляет удобный интерфейс для доступа к данным о пакетах, задачах, мейнтейнерах и другой информации из экосистемы ALT Linux.

## Возможности

- **REST API** — полный клиент для [rdb.altlinux.org/api](https://rdb.altlinux.org/api): информация о пакетах, поиск, задачи, мейнтейнеры, баги, ACL, зависимости, эрраты, лицензии и многое другое
- **Парсер новостей** — получение и разбор новостей из рассылки [sisyphus-cybertalk](https://lists.altlinux.org/pipermail/sisyphus-cybertalk/): добавленные, обновлённые и удалённые пакеты, баги
- **Watch** — отслеживание устаревших пакетов через [watch.altlinux.org](https://watch.altlinux.org), как по отдельному мейнтейнеру, так и по всему репозиторию целиком
- **FTBFS** — список пакетов с ошибками пересборки
- **AppStream** — загрузка, кеширование и поиск по AppStream-метаданным пакетов

## Установка

```bash
pip3 install altrepo
```

## Быстрый старт

Минимальный пример для начала работы с библиотекой. Создаём клиент, инициализируем сессию и делаем запрос:

```python
import asyncio
from altrepo import ALTRepo

async def main():
    client = ALTRepo()
    await client.init()

    result = await client.api.package.package_info("vim", branch="sisyphus")
    pkg = result.packages[0]
    print(f"{pkg.name} {pkg.version}-{pkg.release}")

    await client.close()

asyncio.run(main())
```

## Примеры использования

### Работа с API пакетов

Получение подробной информации о пакете и поиск по имени:

```python
# Информация о конкретном пакете
result = await client.api.package.package_info("firefox", branch="sisyphus")
pkg = result.packages[0]
print(f"{pkg.name} {pkg.version}-{pkg.release} ({pkg.summary})")

# Поиск пакетов по подстроке в имени
result = await client.api.package.package_search("python3-module", branch="sisyphus")
for pkg in result.packages[:10]:
    print(f"  {pkg.name}: {pkg.summary}")
```

### Задачи и мейнтейнеры

Поиск задач по мейнтейнеру или по имени пакета:

```python
# Задачи мейнтейнера
result = await client.api.task.find_tasks(
    input=["fiersik"], branch="sisyphus", by_package=False
)
for task in result.tasks[:5]:
    print(f"  #{task.task_id} [{task.state}] {task.owner}")

# Баги мейнтейнера из Bugzilla
bugs = await client.api.bug.bugzilla_by_maintainer("fiersik")
if bugs:
    for bug in bugs.bugs[:5]:
        print(f"  #{bug.bug_id} {bug.status}: {bug.summary}")
```

### Отслеживание устаревших пакетов

Библиотека поддерживает два режима работы с watch.altlinux.org:

```python
# Устаревшие пакеты конкретного мейнтейнера
watch = await client.parser.packages.watch_by_maintainer("fiersik", "by-acl")
for pkg in watch[:5]:
    print(f"  {pkg.pkg_name}: {pkg.old_version} -> {pkg.new_version}")

# Полный список устаревших пакетов по всему репозиторию
# Каждая запись содержит имя мейнтейнера (или группы с префиксом @)
total = await client.parser.packages.watch_total()
print(f"Всего устаревших пакетов: {len(total)}")
```

### Новости репозитория

Получение свежих новостей о пакетах из рассылки sisyphus-cybertalk:

```python
# Свежие новости Sisyphus за сегодня
news = await client.parser.news.sisyphus()
if news:
    print(f"Добавлено: {len(news.added or [])}")
    print(f"Обновлено: {len(news.updated or [])}")
    print(f"Удалено: {len(news.removed or [])}")

# Агрегированные новости за произвольный период
from datetime import date
news = await client.parser.news.packages_by_range(
    date(2026, 3, 1), date(2026, 3, 10)
)
```

### FTBFS — ошибки пересборки

```python
ftbfs = await client.parser.packages.ftbfs()
print(f"Пакетов с ошибками пересборки: {len(ftbfs)}")
for pkg in ftbfs[:5]:
    print(f"  {pkg.name} {pkg.version} ({pkg.ftbfs_weeks} нед.)")
```

## Конфигурация

Все URL-ы и настройки имеют разумные значения по умолчанию, поэтому для стандартного использования никакая дополнительная конфигурация не требуется. При необходимости любой параметр можно переопределить через `ALTRepoConfig`:

```python
from altrepo import ALTRepo, ALTRepoConfig

config = ALTRepoConfig(
    api_base_url="https://rdb.altlinux.org/api",
    appstream_dir="/tmp/appstream",
    appstream_branches=["sisyphus", "p11", "p10"],
)
client = ALTRepo(config=config)
```

Если в вашем приложении уже есть `aiohttp.ClientSession`, её можно передать при инициализации, чтобы не создавать лишних соединений:

```python
import aiohttp

session = aiohttp.ClientSession()
client = ALTRepo()
await client.init(session=session)
```

## Лицензия

AGPL-3.0-or-later
