diff --git a/README.md b/README.md index e598fb4..309d491 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,32 @@ c.create_post('тест1') # создание постов # итд ``` +### SSE - прослушивание уведомлений в реальном времени + +```python +from itd import ITDClient, StreamConnect, StreamNotification + +# Используйте cookies для автоматического обновления токена +c = ITDClient(cookies='refresh_token=...; __ddg1_=...; is_auth=1') + +for event in c.stream_notifications(): + if isinstance(event, StreamConnect): + print(f'! Подключено к SSE: {event.user_id}') + elif isinstance(event, StreamNotification): + print(f'-- {event.type.value}: {event.actor.display_name} (@{event.actor.username})') +``` + +> [!NOTE] +> SSE автоматически переподключается при истечении токена + +Типы уведомлений: +- `like` - лайк на пост +- `follow` - новый подписчик +- `wall_post` - пост на вашей стене +- `comment` - комментарий к посту +- `reply` - ответ на комментарий +- `repost` - репост вашего поста + ### Кастомные запросы ```python diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..870e87e --- /dev/null +++ b/examples/README.md @@ -0,0 +1,73 @@ +# Примеры использования ITD SDK + +Эта папка содержит примеры использования ITD SDK для различных сценариев. + +## Структура + +``` +examples/ +├── README.md # Этот файл +└── stream/ # Примеры работы с SSE потоком уведомлений + ├── basic_stream.py + ├── stop_stream.py + ├── filter_notifications.py + └── notification_logger.py +``` + +## Подготовка + +Перед запуском примеров установите зависимости: + +```bash +pip install -r ../requirements.txt +``` + +## Получение cookies + +Все примеры требуют cookies с `refresh_token`. Как их получить: + +1. Откройте [итд.com](https://xn--d1ah4a.com) в браузере +2. Откройте DevTools (F12) +3. Перейдите на вкладку **Network** +4. Найдите запрос к `/auth/refresh` +5. Скопируйте значение **Cookie** из Request Headers +6. Формат: `refresh_token=...; __ddg1_=...; is_auth=1` + +См. `cookie-screen.png` в корне проекта для примера. + +--- + +## Stream - Прослушивание уведомлений + +Примеры работы с SSE потоком уведомлений в реальном времени. + +📁 **Папка:** `stream/` +📖 **Документация:** [stream/README.md](stream/README.md) + +**Примеры:** +- `basic_stream.py` - Базовое прослушивание всех уведомлений +- `stop_stream.py` - Программная остановка потока +- `filter_notifications.py` - Фильтрация по типу уведомлений +- `notification_logger.py` - Логирование в JSON файл + +**Быстрый старт:** +```bash +cd stream +python basic_stream.py +``` + +--- + +## Дополнительная информация + +- [Основной README](../README.md) - Документация по всему SDK +- Каждая папка с примерами содержит свой README с подробностями + +## Помощь + +Если примеры не работают: + +1. Проверьте, что cookies актуальные (не истекли) +2. Убедитесь, что установлены все зависимости +3. Проверьте формат cookies (должен содержать `refresh_token=`) +4. Используйте Python 3.13+ (для поддержки `deprecated`) diff --git a/examples/stream/README.md b/examples/stream/README.md new file mode 100644 index 0000000..99a7d41 --- /dev/null +++ b/examples/stream/README.md @@ -0,0 +1,75 @@ +# Stream - Прослушивание уведомлений + +Примеры работы с SSE (Server-Sent Events) потоком уведомлений в реальном времени. + +## Подготовка + +1. Установите зависимости: +```bash +pip install -r ../../requirements.txt +``` + +2. Получите cookies с `refresh_token` (см. [главный README](../README.md)) + +3. Запускайте примеры из корня проекта или из папки `examples/stream/` + +## Примеры + +### basic_stream.py +Базовое прослушивание всех уведомлений. + +```bash +python basic_stream.py +``` + +Показывает все входящие уведомления в реальном времени. + +### stop_stream.py +Программная остановка потока через `client.stop_stream()`. + +```bash +python stop_stream.py +``` + +Полезно для интеграции в многопоточные приложения. + +### filter_notifications.py +Фильтрация уведомлений по типу. + +```bash +python filter_notifications.py +``` + +Показывает только выбранные типы (like, follow, comment). Настраивается через `SHOW_TYPES`. + +### notification_logger.py +Логирование всех уведомлений в JSON файл. + +```bash +python notification_logger.py +``` + +Создает файл `notifications_YYYYMMDD_HHMMSS.log` с полной историей событий. + +## Типы уведомлений + +- **like** - Лайк на пост +- **follow** - Новый подписчик +- **wall_post** - Пост на вашей стене +- **comment** - Комментарий к посту +- **reply** - Ответ на комментарий +- **repost** - Репост вашего поста + +## Особенности + +- ✅ Автоматическое переподключение при разрыве +- ✅ Автоматическое обновление токена (при использовании cookies) +- ✅ Обработка всех типов уведомлений +- ✅ Graceful shutdown по Ctrl+C + +## API Reference + +Подробная документация по методам и моделям: +- [Основной README](../../README.md) - Общая информация об SDK +- [itd/client.py](../../itd/client.py) - Метод `stream_notifications()` +- [itd/models/event.py](../../itd/models/event.py) - Модели `StreamConnect` и `StreamNotification` diff --git a/examples/stream/basic_stream.py b/examples/stream/basic_stream.py new file mode 100644 index 0000000..6928ea1 --- /dev/null +++ b/examples/stream/basic_stream.py @@ -0,0 +1,37 @@ +""" +Базовый пример прослушивания SSE потока уведомлений +""" +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).parent.parent.parent)) + +from itd import ITDClient, StreamConnect, StreamNotification + +def main(): + cookies = 'YOUR_COOKIES_HERE' + + if cookies == 'YOUR_COOKIES_HERE': + print('! Укажите cookies в переменной cookies') + print(' См. examples/README.md для инструкций') + return + + client = ITDClient(cookies=cookies) + + print('-- Подключение к SSE...') + + try: + for event in client.stream_notifications(): + if isinstance(event, StreamConnect): + print(f'-- Подключено! User ID: {event.user_id}') + print('-- Ожидание уведомлений...\n') + else: + print(f'* {event.type.value}: {event.actor.username}') + if event.preview: + preview = event.preview[:50] + '...' if len(event.preview) > 50 else event.preview + print(f' {preview}') + + except KeyboardInterrupt: + print(f'\n! Отключение...') + +if __name__ == '__main__': + main() diff --git a/examples/stream/filter_notifications.py b/examples/stream/filter_notifications.py new file mode 100644 index 0000000..f26063e --- /dev/null +++ b/examples/stream/filter_notifications.py @@ -0,0 +1,54 @@ +""" +Пример фильтрации уведомлений по типу +""" +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).parent.parent.parent)) + +from itd import ITDClient, StreamConnect, StreamNotification +from itd.enums import NotificationType + +def main(): + cookies = 'YOUR_COOKIES_HERE' + + if cookies == 'YOUR_COOKIES_HERE': + print('! Укажите cookies в переменной cookies') + print(' См. examples/README.md для инструкций') + return + + client = ITDClient(cookies=cookies) + + # Настройка: какие типы уведомлений показывать + SHOW_TYPES = { + NotificationType.LIKE, + NotificationType.FOLLOW, + NotificationType.COMMENT, + } + + print('-- Подключение к SSE...') + print(f'-- Фильтр: {", ".join(t.value for t in SHOW_TYPES)}\n') + + try: + for event in client.stream_notifications(): + if isinstance(event, StreamConnect): + print(f'✅ Подключено! User ID: {event.user_id}\n') + continue + + if event.type not in SHOW_TYPES: + continue + + # Обработка разных типов + if event.type == NotificationType.LIKE: + print(f'❤️ {event.actor.display_name} лайкнул ваш пост') + + elif event.type == NotificationType.FOLLOW: + print(f'👤 {event.actor.display_name} подписался на вас') + + elif event.type == NotificationType.COMMENT: + print(f'💬 {event.actor.display_name}: {event.preview}') + + except KeyboardInterrupt: + print(f'\n! Отключение...') + +if __name__ == '__main__': + main() diff --git a/examples/stream/notification_logger.py b/examples/stream/notification_logger.py new file mode 100644 index 0000000..fb758b0 --- /dev/null +++ b/examples/stream/notification_logger.py @@ -0,0 +1,60 @@ +""" +Пример логирования уведомлений в файл +""" +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).parent.parent.parent)) + +from itd import ITDClient, StreamConnect, StreamNotification +from datetime import datetime +import json + +def main(): + cookies = 'YOUR_COOKIES_HERE' + + if cookies == 'YOUR_COOKIES_HERE': + print('! Укажите cookies в переменной cookies') + print(' См. examples/README.md для инструкций') + return + + client = ITDClient(cookies=cookies) + log_file = f'notifications_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log' + + print(f'-- Подключение к SSE...') + print(f'-- Логирование в: {log_file}\n') + + try: + with open(log_file, 'w', encoding='utf-8') as f: + for event in client.stream_notifications(): + timestamp = datetime.now().isoformat() + + if isinstance(event, StreamConnect): + log_entry = { + 'timestamp': timestamp, + 'type': 'connect', + 'user_id': str(event.user_id) + } + print(f'-- Подключено! User ID: {event.user_id}') + else: + log_entry = { + 'timestamp': timestamp, + 'type': event.type.value, + 'id': str(event.id), + 'actor': { + 'username': event.actor.username, + 'display_name': event.actor.display_name + }, + 'preview': event.preview, + 'target_type': event.target_type.value if event.target_type else None, + 'target_id': str(event.target_id) if event.target_id else None + } + print(f'* {event.type.value}: {event.actor.username}') + + f.write(json.dumps(log_entry, ensure_ascii=False) + '\n') + f.flush() + + except KeyboardInterrupt: + print(f'\n! Отключение... Лог сохранен в {log_file}') + +if __name__ == '__main__': + main() diff --git a/examples/stream/stop_stream.py b/examples/stream/stop_stream.py new file mode 100644 index 0000000..ef46cf2 --- /dev/null +++ b/examples/stream/stop_stream.py @@ -0,0 +1,47 @@ +""" +Пример остановки SSE потока из кода +""" +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).parent.parent.parent)) + +import threading +import time +from itd import ITDClient, StreamConnect, StreamNotification + +def main(): + cookies = 'YOUR_COOKIES_HERE' + + if cookies == 'YOUR_COOKIES_HERE': + print('! Укажите cookies в переменной cookies') + return + + client = ITDClient(cookies=cookies) + + # Функция для прослушивания в отдельном потоке + def listen(): + print('! Начинаем прослушивание...') + try: + for event in client.stream_notifications(): + if isinstance(event, StreamConnect): + print(f'-- Подключено! User ID: {event.user_id}') + else: + print(f'🔔 {event.type.value}: {event.actor.username}') + except Exception as e: + print(f'! Ошибка: {e}') + + # В отдельном потоке + thread = threading.Thread(target=listen, daemon=True) + thread.start() + + print('Прослушивание запущено. Нажмите Enter для остановки...') + input() + + print('!! Останавливаем прослушивание...') + client.stop_stream() + + thread.join(timeout=5) + print('! Остановлено') + +if __name__ == '__main__': + main()