Compare commits
5 Commits
docs/ai-sk
...
refactor/p
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cf6a7e940 | |||
| b8b9ec75b3 | |||
| c94131effc | |||
| d9b4f19af3 | |||
| d4ee76948f |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
72
README.md
72
README.md
@@ -1,44 +1,58 @@
|
||||
# Акылдаш — бот-секретарь
|
||||
# Акылдаш
|
||||
|
||||
Версия: `0.2.0`
|
||||
Акылдаш — проект юридической информационно-аналитической платформы. Цель —
|
||||
собирать правовые источники на законных основаниях, сохранять их происхождение
|
||||
и версии, готовить данные для поиска и RAG, а затем предоставлять результаты
|
||||
через API и пользовательский интерфейс со ссылками на первоисточники.
|
||||
|
||||
Бот сохраняет сообщения разрешённых тем Telegram в локальную SQLite-базу и
|
||||
выгружает обсуждения в Markdown. Внешние Python-зависимости не требуются.
|
||||
Telegram-бот — только часть рабочего окружения команды, а не основной продукт.
|
||||
|
||||
## Запуск
|
||||
## Текущее состояние
|
||||
|
||||
Требуется Python 3.11 или новее.
|
||||
Сейчас реализован Telegram-бот-секретарь версии `0.2.2`. Он сохраняет сообщения
|
||||
рабочих тем, формирует Markdown-экспорты и отмечает завершённые обсуждения.
|
||||
|
||||
```bash
|
||||
export TELEGRAM_BOT_TOKEN='...'
|
||||
export TELEGRAM_CHAT_ID='-1004242041275'
|
||||
export TELEGRAM_OWNER_ID='87262245'
|
||||
export TELEGRAM_REPORT_THREAD_ID='37'
|
||||
export TELEGRAM_ALLOWED_THREAD_IDS='0,2,4,6,8'
|
||||
python3 bot.py
|
||||
| Компонент | Версия | Состояние |
|
||||
|---|---:|---|
|
||||
| Telegram-бот | `0.2.2` | на Synology работает `0.2.1`; обновление после слияния |
|
||||
| Backend | — | ещё не создан |
|
||||
| Frontend | — | ещё не создан |
|
||||
| Сбор и обработка правовых данных | — | ещё не созданы |
|
||||
| RAG и база знаний | — | ещё не созданы |
|
||||
|
||||
## Структура репозитория
|
||||
|
||||
```text
|
||||
docs/ структурированная документация проекта
|
||||
decisions/ принятые архитектурные и продуктовые решения
|
||||
operations/ состояние проекта и рабочие процессы
|
||||
product/ назначение, границы и развитие продукта
|
||||
team/ материалы для команды
|
||||
tools/
|
||||
telegram-bot/ бот рабочего Telegram-пространства
|
||||
```
|
||||
|
||||
Доступные команды: `/help`, `/status`, `/export [дней]`, `/export все`.
|
||||
Экспорт доступен только пользователю с Telegram ID из `TELEGRAM_OWNER_ID`.
|
||||
Markdown публикуется в теме `TELEGRAM_REPORT_THREAD_ID`, а в исходной теме
|
||||
остаётся отсечка со ссылкой и общим хэштегом отчёта.
|
||||
Каталоги для загрузки и обработки источников, RAG, backend и frontend будут
|
||||
создаваться с первой реальной задачей в соответствующей области. Это позволит
|
||||
выбрать структуру по фактическим требованиям, а не поддерживать пустой каркас.
|
||||
|
||||
База по умолчанию хранится в `data/secretary.sqlite3`. Сообщения из других
|
||||
групп и тем не сохраняются. Полный ответ Telegram сохраняется в базе, поэтому
|
||||
метаданные вложений остаются доступными для последующего скачивания.
|
||||
Начать знакомство с проектом: [документация](docs/README.md) и
|
||||
[обзор продукта](docs/product/project-overview.md).
|
||||
|
||||
## Проверка
|
||||
## Конфиденциальные материалы
|
||||
|
||||
Секреты, персональные данные, договоры и материалы по правовой защите проекта
|
||||
не должны храниться в этом репозитории. Для них нужен отдельный закрытый
|
||||
репозиторий или защищённое хранилище с минимально необходимыми правами доступа,
|
||||
журналированием и резервным копированием. Здесь допустимы только несекретные
|
||||
правила и ссылки на такие материалы без раскрытия их содержания.
|
||||
|
||||
## Проверка Telegram-бота
|
||||
|
||||
```bash
|
||||
python3 -m unittest -v
|
||||
python3 -m unittest discover -s tools/telegram-bot -v
|
||||
```
|
||||
|
||||
## Synology
|
||||
|
||||
Контейнер `akyldash-bot` работает на образе `python:3.11-slim` с политикой
|
||||
перезапуска `unless-stopped`. Постоянные данные находятся в
|
||||
`/volume1/docker/akyldash/data`.
|
||||
|
||||
---
|
||||
|
||||
Акылдаш v0.2.0
|
||||
Акылдаш · Telegram-бот v0.2.2 · Backend — не создан · Frontend — не создан
|
||||
|
||||
27
docs/README.md
Normal file
27
docs/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Документация Акылдаш
|
||||
|
||||
## Продукт
|
||||
|
||||
- [Обзор проекта](product/project-overview.md) — назначение, основные области и
|
||||
правила работы с данными.
|
||||
|
||||
## Решения
|
||||
|
||||
- [Решение 001](decisions/001-telegram-workspace-mvp.md) — границы MVP
|
||||
Telegram-инфраструктуры.
|
||||
|
||||
## Эксплуатация и рабочий процесс
|
||||
|
||||
- [Текущий статус](operations/project-status.md) — выполненные шаги, риски и
|
||||
ближайшие действия.
|
||||
- [План Telegram-пространства](operations/telegram-workspace-plan.md) — темы,
|
||||
роли и этапы развития командного окружения.
|
||||
|
||||
## Команда
|
||||
|
||||
- [Навыки работы с ИИ](team/ai-skills-for-beginners.md) — короткие практики для
|
||||
начинающих.
|
||||
|
||||
---
|
||||
|
||||
Акылдаш · Telegram-бот v0.2.2 · Backend — не создан · Frontend — не создан
|
||||
2
docs/decisions/001-mvp-boundaries-and-rules.md → docs/decisions/001-telegram-workspace-mvp.md
Executable file → Normal file
2
docs/decisions/001-mvp-boundaries-and-rules.md → docs/decisions/001-telegram-workspace-mvp.md
Executable file → Normal file
@@ -78,4 +78,4 @@ Telegram позволяет запретить пользователям отп
|
||||
|
||||
---
|
||||
|
||||
Акылдаш v0.2.0
|
||||
Акылдаш · Telegram-бот v0.2.2
|
||||
27
docs/PROJECT_STATUS.md → docs/operations/project-status.md
Executable file → Normal file
27
docs/PROJECT_STATUS.md → docs/operations/project-status.md
Executable file → Normal file
@@ -3,11 +3,14 @@
|
||||
Последняя проверка: 2026-08-03
|
||||
Назначение документа: быстро восстановить контекст проекта для участников команды и будущих агентов.
|
||||
|
||||
Версия приложения: `0.2.0`
|
||||
- Telegram-бот: `0.2.2`
|
||||
- Telegram-бот на Synology: `0.2.1`
|
||||
- Backend: не создан
|
||||
- Frontend: не создан
|
||||
|
||||
## Краткий итог
|
||||
|
||||
Telegram-инфраструктура и первая версия бота-секретаря подготовлены. Бот сохраняет сообщения разрешённых тем в SQLite, экспортирует обсуждения в Markdown и постоянно запущен в Container Manager на Synology.
|
||||
Репозиторий переориентирован с отдельного бота на весь проект юридической информационно-аналитической платформы. Telegram-бот выделен в инструмент рабочего окружения: он сохраняет сообщения разрешённых тем в SQLite, экспортирует обсуждения в Markdown и постоянно запущен в Container Manager на Synology. Версия `0.2.2` будет развёрнута после слияния изменений; сейчас на Synology работает `0.2.1`.
|
||||
|
||||
Ближайшая цель — 2026-08-04 зафиксировать MVP с командой, настроить резервное копирование SQLite и затем проверить полный рабочий цикл на реальном обсуждении.
|
||||
|
||||
@@ -36,8 +39,9 @@ Telegram-инфраструктура и первая версия бота-се
|
||||
|
||||
### Документация и правила
|
||||
|
||||
- Подготовлен общий план реализации в `TEAM_AI_TELEGRAM_IMPLEMENTATION_PLAN.md`.
|
||||
- Зафиксированы границы MVP и правила работы с данными в `docs/decisions/001-mvp-boundaries-and-rules.md`.
|
||||
- Подготовлен общий план реализации в `docs/operations/telegram-workspace-plan.md`.
|
||||
- Зафиксированы границы MVP и правила работы с данными в `docs/decisions/001-telegram-workspace-mvp.md`.
|
||||
- Добавлены обзор всей платформы и единый индекс документации.
|
||||
- В MVP не входит автоматический вызов API языковой модели.
|
||||
- Анализ экспортов выполняется вручную в обычном ChatGPT.
|
||||
- Telegram используется как рабочий штаб, Git/Gitea — как источник утверждённых материалов.
|
||||
@@ -52,13 +56,16 @@ Telegram-инфраструктура и первая версия бота-се
|
||||
|
||||
### Репозиторий и приложение
|
||||
|
||||
- Реализован бот-секретарь версии `0.2.0` без внешних Python-зависимостей.
|
||||
- Реализован бот-секретарь версии `0.2.2` без внешних Python-зависимостей.
|
||||
- Код бота выделен из корня репозитория в `tools/telegram-bot`.
|
||||
- Сообщения и полные Telegram-метаданные сохраняются в SQLite.
|
||||
- Добавлены команды `/help`, `/status`, `/export [дней]` и `/export все`.
|
||||
- Добавлены команды `/help`, `/status` и `/export`.
|
||||
- Экспорт доступен только владельцу, указанному в `TELEGRAM_OWNER_ID`.
|
||||
- Первый `/export` охватывает всю сохранённую тему, последующие начинаются после последней успешно созданной отсечки.
|
||||
- Отчёты публикуются в закрытой теме `Отчеты` (`message_thread_id=37`).
|
||||
- Исходное обсуждение завершается заметной отсечкой со ссылкой и хэштегом отчёта.
|
||||
- Локальный Git-репозиторий восстановлен и привязан к Gitea.
|
||||
- Репозиторий организован как основа всего проекта, а не отдельного бота.
|
||||
- Бот развёрнут в Container Manager на Synology; автозапуск после перезапуска менеджера проверен.
|
||||
|
||||
### Развёртывание
|
||||
@@ -66,6 +73,7 @@ Telegram-инфраструктура и первая версия бота-се
|
||||
- Бот постоянно запущен на Synology в контейнере `akyldash-bot`.
|
||||
- Используется официальный образ `python:3.11-slim` и long polling.
|
||||
- Контейнер работает без root, с read-only root filesystem и политикой `unless-stopped`.
|
||||
- Доступ к Telegram Bot API идёт через отдельный закрытый прокси-контейнер без опубликованных наружу портов.
|
||||
- Код, закрытый env-файл и SQLite хранятся в `/volume1/docker/akyldash`.
|
||||
|
||||
## Пока не сделано
|
||||
@@ -119,6 +127,11 @@ Telegram-инфраструктура и первая версия бота-се
|
||||
|
||||
### 2026-08-03
|
||||
|
||||
- Репозиторий перестроен под весь проект юридической платформы; Telegram-бот перенесён в `tools/telegram-bot`.
|
||||
- Созданы обзор продукта и структурированный индекс документации; будущие каталоги решено создавать по фактическим задачам.
|
||||
- Закрытые юридические материалы решено хранить отдельно от основного репозитория.
|
||||
- Версия Telegram-бота обновлена до `0.2.2` из-за изменения структуры запуска.
|
||||
- Экспорт без параметров переведён с периода в семь дней на диапазон после предыдущей отсечки.
|
||||
- Бот развёрнут в Container Manager на Synology; автозапуск проверен перезапуском.
|
||||
- В теме `Работа с ИИ` опубликована первоначальная библиотека практик и отдельный материал о безопасной работе с Codex.
|
||||
- В `Общее` опубликовано и закреплено приветствие; тема закрыта для сообщений.
|
||||
@@ -149,4 +162,4 @@ Telegram-инфраструктура и первая версия бота-се
|
||||
|
||||
---
|
||||
|
||||
Акылдаш v0.2.0
|
||||
Акылдаш · Telegram-бот v0.2.2 · Backend — не создан · Frontend — не создан
|
||||
2
TEAM_AI_TELEGRAM_IMPLEMENTATION_PLAN.md → docs/operations/telegram-workspace-plan.md
Executable file → Normal file
2
TEAM_AI_TELEGRAM_IMPLEMENTATION_PLAN.md → docs/operations/telegram-workspace-plan.md
Executable file → Normal file
@@ -398,4 +398,4 @@ Git сохраняет актуальную версию
|
||||
|
||||
---
|
||||
|
||||
Акылдаш v0.2.0
|
||||
Акылдаш · Telegram-бот v0.2.2
|
||||
47
docs/product/project-overview.md
Normal file
47
docs/product/project-overview.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Обзор проекта
|
||||
|
||||
## Назначение
|
||||
|
||||
Акылдаш — юридическая информационно-аналитическая платформа. Она должна помочь
|
||||
пользователю находить применимые нормы и материалы, понимать их актуальность и
|
||||
получать ответ со ссылками на проверяемые первоисточники. Платформа не заменяет
|
||||
профессиональное юридическое заключение.
|
||||
|
||||
## Основные области
|
||||
|
||||
1. Получение открытых или лицензированных законов, актов и иных правовых
|
||||
источников.
|
||||
2. Очистка, нормализация, связывание редакций и сохранение происхождения данных.
|
||||
3. Хранение структурированных документов и поисковых индексов.
|
||||
4. Формирование базы знаний и RAG с обязательными ссылками на источники.
|
||||
5. Backend для доступа к данным и функциям платформы.
|
||||
6. Frontend для поиска, анализа и работы с результатами.
|
||||
7. Инструменты рабочего окружения команды, включая Telegram-бота.
|
||||
|
||||
Физическая структура каждой области появится вместе с её первой задачей. До
|
||||
этого список служит картой продукта, а не обещанием заранее выбранной
|
||||
архитектуры.
|
||||
|
||||
## Обязательные принципы
|
||||
|
||||
- Источник, дата получения, редакция и лицензия документа должны быть
|
||||
прослеживаемыми.
|
||||
- Ответ системы должен отделять найденный факт от вывода модели и ссылаться на
|
||||
конкретный первоисточник.
|
||||
- Актуальность правовых данных должна проверяться до использования в ответе.
|
||||
- Существенные юридические выводы проверяет человек.
|
||||
- Секреты и персональные данные не попадают в Git, логи и тестовые наборы.
|
||||
- Данные загружаются только при наличии законного основания и с соблюдением
|
||||
условий источника.
|
||||
|
||||
## Правовая защита проекта
|
||||
|
||||
Договоры, заявки, материалы об интеллектуальной собственности и другие
|
||||
закрытые юридические документы следует хранить отдельно от исходного кода: в
|
||||
закрытом репозитории или защищённом документном хранилище. Доступ выдаётся
|
||||
поимённо и только тем, кому он нужен. В основном репозитории можно хранить
|
||||
несекретный реестр документов, правила доступа и ссылки на место хранения.
|
||||
|
||||
---
|
||||
|
||||
Акылдаш · Telegram-бот v0.2.2 · Backend — не создан · Frontend — не создан
|
||||
@@ -180,4 +180,4 @@
|
||||
|
||||
---
|
||||
|
||||
Акылдаш v0.2.0
|
||||
Акылдаш · Telegram-бот v0.2.2
|
||||
|
||||
51
tools/telegram-bot/README.md
Normal file
51
tools/telegram-bot/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Telegram-бот Акылдаш
|
||||
|
||||
Версия: `0.2.2`
|
||||
|
||||
Бот сохраняет сообщения разрешённых тем Telegram в локальную SQLite-базу и
|
||||
выгружает обсуждения в Markdown. Внешние Python-зависимости не требуются.
|
||||
|
||||
## Запуск
|
||||
|
||||
Требуется Python 3.11 или новее.
|
||||
|
||||
```bash
|
||||
cd tools/telegram-bot
|
||||
export TELEGRAM_BOT_TOKEN='...'
|
||||
export TELEGRAM_CHAT_ID='-1004242041275'
|
||||
export TELEGRAM_OWNER_ID='87262245'
|
||||
export TELEGRAM_REPORT_THREAD_ID='37'
|
||||
export TELEGRAM_ALLOWED_THREAD_IDS='0,2,4,6,8'
|
||||
python3 bot.py
|
||||
```
|
||||
|
||||
Доступные команды: `/help`, `/status`, `/export`. Экспорт доступен только
|
||||
пользователю с Telegram ID из `TELEGRAM_OWNER_ID`. Первый `/export` выгружает
|
||||
всю сохранённую тему, последующие — сообщения после предыдущей успешно
|
||||
созданной отсечки.
|
||||
|
||||
Markdown публикуется в теме `TELEGRAM_REPORT_THREAD_ID`, а в исходной теме
|
||||
остаётся отсечка со ссылкой и общим хэштегом отчёта.
|
||||
|
||||
База по умолчанию хранится в `data/secretary.sqlite3`. Сообщения из других
|
||||
групп и тем не сохраняются. Полный ответ Telegram сохраняется в базе, поэтому
|
||||
метаданные вложений остаются доступными для последующего скачивания.
|
||||
|
||||
## Проверка
|
||||
|
||||
```bash
|
||||
python3 -m unittest -v
|
||||
```
|
||||
|
||||
## Synology
|
||||
|
||||
Контейнер `akyldash-bot` работает на образе `python:3.11-slim` через закрытый
|
||||
прокси-контейнер, с политикой перезапуска `unless-stopped`. Постоянные данные
|
||||
находятся в `/volume1/docker/akyldash/data`.
|
||||
|
||||
При обновлении развёртывания файл `tools/telegram-bot/bot.py` копируется в
|
||||
каталог контейнера как `bot.py`.
|
||||
|
||||
---
|
||||
|
||||
Акылдаш · Telegram-бот v0.2.2
|
||||
@@ -18,7 +18,7 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
|
||||
APP_NAME = "Акылдаш"
|
||||
APP_VERSION = "0.2.0"
|
||||
APP_VERSION = "0.2.2"
|
||||
FOOTER = f"{APP_NAME} v{APP_VERSION}"
|
||||
|
||||
|
||||
@@ -146,6 +146,29 @@ def next_update_id(connection: sqlite3.Connection) -> int:
|
||||
return int(row["value"]) if row else 0
|
||||
|
||||
|
||||
def export_checkpoint(
|
||||
connection: sqlite3.Connection, chat_id: int, thread_id: int
|
||||
) -> int:
|
||||
row = connection.execute(
|
||||
"SELECT value FROM state WHERE key = ?",
|
||||
(f"export_checkpoint:{chat_id}:{thread_id}",),
|
||||
).fetchone()
|
||||
return int(row["value"]) if row else 0
|
||||
|
||||
|
||||
def save_export_checkpoint(
|
||||
connection: sqlite3.Connection, chat_id: int, thread_id: int, message_id: int
|
||||
) -> None:
|
||||
with connection:
|
||||
connection.execute(
|
||||
"""
|
||||
INSERT INTO state (key, value) VALUES (?, ?)
|
||||
ON CONFLICT (key) DO UPDATE SET value = excluded.value
|
||||
""",
|
||||
(f"export_checkpoint:{chat_id}:{thread_id}", str(message_id)),
|
||||
)
|
||||
|
||||
|
||||
def telegram_request(
|
||||
config: Config, method: str, payload: dict, timeout: int = 65
|
||||
) -> object:
|
||||
@@ -248,10 +271,14 @@ def export_markdown(
|
||||
thread_id: int,
|
||||
days: int | None,
|
||||
now: int | None = None,
|
||||
after_message_id: int | None = None,
|
||||
) -> str:
|
||||
parameters: list[int] = [config.chat_id, thread_id]
|
||||
condition = ""
|
||||
if days is not None:
|
||||
if after_message_id is not None:
|
||||
condition = " AND message_id > ?"
|
||||
parameters.append(after_message_id)
|
||||
elif days is not None:
|
||||
condition = " AND sent_at >= ?"
|
||||
parameters.append((now or int(time.time())) - days * 86400)
|
||||
rows = connection.execute(
|
||||
@@ -263,7 +290,14 @@ def export_markdown(
|
||||
parameters,
|
||||
).fetchall()
|
||||
|
||||
period = "за всё время" if days is None else f"за последние {days} дн."
|
||||
if after_message_id is not None:
|
||||
period = (
|
||||
"с начала архива"
|
||||
if after_message_id == 0
|
||||
else "после предыдущей отсечки"
|
||||
)
|
||||
else:
|
||||
period = "за всё время" if days is None else f"за последние {days} дн."
|
||||
lines = [
|
||||
"# Обсуждение",
|
||||
"",
|
||||
@@ -328,8 +362,7 @@ def handle_command(
|
||||
message,
|
||||
"Я сохраняю обсуждения этой группы.\n"
|
||||
"/status — количество сохранённых сообщений\n"
|
||||
"/export [дней] — экспорт текущей темы за 7 дней или указанный срок\n"
|
||||
"/export все — экспорт текущей темы целиком",
|
||||
"/export — экспорт текущей темы после предыдущей отсечки",
|
||||
)
|
||||
elif command == "/status":
|
||||
topic_count = connection.execute(
|
||||
@@ -349,11 +382,22 @@ def handle_command(
|
||||
send_text(config, message, "Экспорт доступен только владельцу бота.")
|
||||
return
|
||||
try:
|
||||
days = parse_export_days(parts)
|
||||
days = parse_export_days(parts) if len(parts) > 1 else None
|
||||
except (ValueError, IndexError):
|
||||
send_text(config, message, "Использование: /export [1–3650|все]")
|
||||
return
|
||||
markdown = export_markdown(connection, config, thread_id, days)
|
||||
checkpoint = (
|
||||
None
|
||||
if len(parts) > 1
|
||||
else export_checkpoint(connection, config.chat_id, thread_id)
|
||||
)
|
||||
markdown = export_markdown(
|
||||
connection,
|
||||
config,
|
||||
thread_id,
|
||||
days,
|
||||
after_message_id=checkpoint,
|
||||
)
|
||||
stamp = datetime.now(config.timezone).strftime("%Y%m%d-%H%M")
|
||||
report_tag = f"#report_{message['message_id']}"
|
||||
report = send_document(
|
||||
@@ -373,6 +417,9 @@ def handle_command(
|
||||
f"Отчёт: {message_link(config.chat_id, report['message_id'])}\n"
|
||||
"━━━━━━━━━━━━━━━━",
|
||||
)
|
||||
save_export_checkpoint(
|
||||
connection, config.chat_id, thread_id, int(message["message_id"])
|
||||
)
|
||||
|
||||
|
||||
def run() -> None:
|
||||
@@ -153,7 +153,7 @@ class SecretaryTest(unittest.TestCase):
|
||||
"date": 1,
|
||||
"chat": {"id": config.chat_id},
|
||||
"from": {"id": config.owner_id},
|
||||
"text": "/export все",
|
||||
"text": "/export",
|
||||
}
|
||||
|
||||
with patch("bot.send_text") as send_text, patch(
|
||||
@@ -170,6 +170,69 @@ class SecretaryTest(unittest.TestCase):
|
||||
self.assertIn("#report_12", marker)
|
||||
self.assertIn("https://t.me/c/123/99", marker)
|
||||
|
||||
def test_next_export_starts_after_previous_cutoff(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
config = Config(
|
||||
token="test",
|
||||
chat_id=-100123,
|
||||
owner_id=7,
|
||||
report_thread_id=37,
|
||||
thread_ids=frozenset({2}),
|
||||
database=Path(directory) / "bot.sqlite3",
|
||||
timezone=ZoneInfo("UTC"),
|
||||
)
|
||||
connection = connect(config.database)
|
||||
|
||||
def archive(message_id, text):
|
||||
archive_update(
|
||||
connection,
|
||||
{
|
||||
"update_id": message_id,
|
||||
"message": {
|
||||
"message_id": message_id,
|
||||
"message_thread_id": 2,
|
||||
"date": message_id,
|
||||
"chat": {"id": config.chat_id},
|
||||
"from": {"id": config.owner_id},
|
||||
"text": text,
|
||||
},
|
||||
},
|
||||
config,
|
||||
)
|
||||
|
||||
archive(10, "Первое обсуждение")
|
||||
with patch("bot.send_text"), patch(
|
||||
"bot.send_document",
|
||||
side_effect=[{"message_id": 90}, {"message_id": 91}],
|
||||
) as send_document:
|
||||
handle_command(
|
||||
connection,
|
||||
config,
|
||||
{
|
||||
"message_id": 12,
|
||||
"message_thread_id": 2,
|
||||
"from": {"id": config.owner_id},
|
||||
"text": "/export",
|
||||
},
|
||||
)
|
||||
archive(13, "Второе обсуждение")
|
||||
handle_command(
|
||||
connection,
|
||||
config,
|
||||
{
|
||||
"message_id": 14,
|
||||
"message_thread_id": 2,
|
||||
"from": {"id": config.owner_id},
|
||||
"text": "/export",
|
||||
},
|
||||
)
|
||||
|
||||
first_export = send_document.call_args_list[0].args[3].decode()
|
||||
second_export = send_document.call_args_list[1].args[3].decode()
|
||||
self.assertIn("Первое обсуждение", first_export)
|
||||
self.assertNotIn("Первое обсуждение", second_export)
|
||||
self.assertIn("Второе обсуждение", second_export)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user