Metadata-Version: 2.4
Name: oldvkapi
Version: 0.2.0
Summary: Python-клиент к API из OldVK.apk (прокси oldvk.mooo.com:8080)
Author: OldVKAPI contributors
License: MIT
Keywords: vk,vkontakte,oldvk,api,longpoll
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.0
Provides-Extra: dev
Dynamic: license-file

# OldVKAPI

Синхронный Python-клиент к API из **OldVK.apk v1.3.1** (`com.vkontakte.android`).
Протокол восстановлен дизассемблированием `classes.dex` — подробности в
`OldVK_API.md` (главы 2–10).

Коротко о протоколе: все вызовы — `POST http(s)://oldvk.mooo.com:8080/api.php`
с полями `method/v=3.0/format=json/api_id=2274003` + параметры + `sig`
(`MD5(uid + сортированные key=value + secret)`) + `sid`. Авторизация —
`auth.getTokenSecure` → `digest(MD5)` → `auth.getSessionSecure`.

## Установка

```bash
pip install requests
pip install -e .   # из каталога OldVKAPI
```

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

```python
from oldvkapi import OldVK

vk = OldVK(session_file="~/.oldvkapi/session.json",
           auto_reauth=True,      # молча обновлять сессию при error 3/4
           network_retries=2)     # повторять при обрывах сети

# Вход логином (один раз; дальше сессия берётся из JSON-файла):
vk.login("user@example.com", "password")

# или готовой сессией:
# vk = OldVK.from_session(uid=123, sid="...", secret="...")

print(vk.messages.dialogs())          # диалоги через execute-шаблон
print(vk.wall.posts(owner_id=123))    # посты стены
vk.activity.online()                  # heartbeat онлайна
```

## Разделы

Доступ — свойствами клиента, методы повторяют имена API из APK:

| Свойство | Методы (примеры) |
|---|---|
| `users` | `get_profiles(uids, fields, name_case)` |
| `friends` | `get`, `get_by_phones`, `add`, `delete`, `mutual`*, `get_requests`* |
| `groups` | `get_by_id` |
| `status` | `get`, `set` |
| `activity` | `online` |
| `messages` | `send`, `get_history`, `get_by_id`, `delete`, `mark_as_read`, `dialogs`*, `search`*, `slow_poll`* |
| `wall` | `post`, `delete`, `add_comment`, `delete_comment`, `get_comments`, `add_like`, `delete_like`, `posts`* |
| `likes` | `add`, `delete` |
| `polls` | `add_vote`, `get_by_id` |
| `photos` | `get_albums`, `get`, `get_user_photos`, `get_by_id`, `get_comments`, `get_tags`, `create_comment`, `create_album`, `edit_album`, `delete_album`, `delete`, `edit`, `comments_full`*, `info`* |
| `video` | `get`, `save`, `get_comments` |
| `audio` | `get`, `get_albums`, `search`, `add`, `delete`, `direct_url`* |
| `docs` | `get_upload_server`, `save` |
| `notes` | `get_by_id`, `get_comments` |
| `places` | `search`, `get_checkins`, `checkin`, `add`, `get_by_id`, `get_city_by_id`, `get_country_by_id` |
| `newsfeed` | `get`, `get_comments` |

\* — через `execute` (готовые шаблоны в `oldvkapi/execute.py`).

Прямой вызов любого метода: `vk.call("wall.post", owner_id=1, message="hi")`.

## Ошибки и капча

```python
from oldvkapi import CaptchaNeeded, ReauthNeeded, ApiError

try:
    vk.wall.post(owner_id=1, message="hi")
except CaptchaNeeded as cap:
    print(cap.captcha_img)          # показать картинку пользователю
    key = input("Капча: ")
    vk.call(cap.method, captcha_sid=cap.captcha_sid,
            captcha_key=key, **cap.params)
except ReauthNeeded:
    vk.reauth()                     # нужен login() с паролем в памяти
except ApiError as err:
    print(err.code, err.message)
```

Автоматический режим — без `try/except` (повтор делает сам клиент):

```python
vk = OldVK(session_file="session.json",
           captcha_handler=lambda img, sid, method, params: input(f"{img}: "))
vk.wall.post(owner_id=1, message="hi")   # re-auth и капча — автоматически
```

`error_code` 7 возвращается как `None` (как в самом приложении).

## LongPoll

```python
for update in vk.longpoll.updates():   # бесконечный генератор
    print(update)
```

`refresh()` — новый `server/key/ts`; `poll_url()` — текущий `a_check`-URL;
`slow_poll(time_offset)` — запасной опрос из приложения.

## Загрузка файлов

```python
vk.uploader.upload_wall_photo("pic.jpg", owner_id=vk.uid, message="Фото!")
vk.uploader.upload_album_photo(aid=123, file_path="pic.jpg")
vk.uploader.upload_audio("track.mp3")
vk.uploader.upload_doc("file.pdf")
vk.uploader.upload_video("Ролик", "vid.mp4", description="...")
```

## Оговорка про `digest`

Формула `digest = MD5(SECRET:nonce:login:password)` восстановлена из
байт-кода `Auth.doAuth` (порядок операндов — по append-цепочке). Если сервер
её отвергнет — используйте `oldvkapi.auth.auth_session_raw(nonce, login, digest)`
с собственной формулой.
