"""Пулы фраз, которыми бот обозначает ход долгой операции. Фразы показываются в живом драфте (``sendMessageDraft``) в приватном чате и сменяют друг друга случайным образом через случайные промежутки времени, пока операция не завершилась. Ни одна фраза не обещает конкретного результата — это только обозначение процесса. """ from __future__ import annotations import os import random GENERATION_PHRASES: tuple[str, ...] = ( "⏳ Разбираю запрос и подбираю формулировки…", "⏳ Собираю фактуру из того, что ты прислал…", "⏳ Придумываю три разных захода к теме…", "⏳ Проверяю, что не придумываю лишних фактов…", "⏳ Подбираю более точное начало поста…", "⏳ Слежу за длиной и читаемостью каждого варианта…", "⏳ Убираю канцелярит и лишние вводные…", "⏳ Собираю три варианта и проверяю орфографию…", ) TRAINING_PHRASES: tuple[str, ...] = ( "⏳ Читаю присланные материалы…", "⏳ Выделяю особенности твоей подачи…", "⏳ Сопоставляю новые примеры с прежним профилем…", "⏳ Уточняю портрет аудитории…", "⏳ Отмечаю типичные темы и повороты…", "⏳ Собираю обновлённый профиль аккаунта…", "⏳ Проверяю, что ничего не потерялось…", "⏳ Упаковываю вывод в компактный профиль…", ) IMAGES_PHRASES: tuple[str, ...] = ( "⏳ Скачиваю изображения…", "⏳ Распознаю тексты на скриншотах…", "⏳ Отделяю заголовки от основного текста…", "⏳ Сверяю извлечённые посты между собой…", "⏳ Ищу повторяющиеся приёмы в текстах…", "⏳ Проверяю, что тексты прочитаны полностью…", "⏳ Готовлю варианты поста по увиденному…", ) VOICE_PHRASES: tuple[str, ...] = ( "⏳ Скачиваю аудиосообщение…", "⏳ Перевожу речь в текст…", "⏳ Расставляю знаки препинания в расшифровке…", "⏳ Уточняю границы фраз…", "⏳ Проверяю расшифровку на слух…", "⏳ Разбираю, что именно ты просишь…", ) IDEAS_PHRASES: tuple[str, ...] = ( "⏳ Ищу свежий угол для темы…", "⏳ Проверяю, что идея не повторяет прошлые…", "⏳ Подбираю формулировку заголовка…", "⏳ Оцениваю пользу идеи для твоей аудитории…", "⏳ Формулирую, зачем эта тема аккаунту…", "⏳ Отбираю самый сильный вариант…", ) DEFAULT_PHRASES: tuple[str, ...] = ( "⏳ Работаю над запросом…", "⏳ Привожу результат к нужному виду…", "⏳ Почти готова, проверяю детали…", ) ACTIVITY_PHRASES: dict[str, tuple[str, ...]] = { "generation": GENERATION_PHRASES, "training": TRAINING_PHRASES, "images": IMAGES_PHRASES, "voice": VOICE_PHRASES, "ideas": IDEAS_PHRASES, } def _positive_float(name: str, default: float) -> float: raw = os.getenv(name, "").strip() if not raw: return default try: value = float(raw) except ValueError: return default return value if value > 0 else default def _positive_int(name: str, default: int) -> int: raw = os.getenv(name, "").strip() if not raw: return default try: value = int(raw) except ValueError: return default return value if value > 0 else default ACTIVITY_MIN_SECONDS = _positive_float("ACTIVITY_MIN_SECONDS", 3.0) ACTIVITY_MAX_SECONDS = _positive_float("ACTIVITY_MAX_SECONDS", 8.0) if ACTIVITY_MIN_SECONDS > ACTIVITY_MAX_SECONDS: ACTIVITY_MIN_SECONDS, ACTIVITY_MAX_SECONDS = ACTIVITY_MAX_SECONDS, ACTIVITY_MIN_SECONDS # Предохранитель: если операция зависла и finish() не вызвался, ротация # всё равно прекратится и не будет бесконечно долбить драфт. ACTIVITY_MAX_ROTATIONS = _positive_int("ACTIVITY_MAX_ROTATIONS", 12) def random_interval() -> float: """Случайная пауза между сменами фраз, в секундах.""" return random.uniform(ACTIVITY_MIN_SECONDS, ACTIVITY_MAX_SECONDS) def next_phrase(kind: str | None = None, exclude: str | None = None) -> str: """Случайная фраза из пула операции, не повторяющая только что показанную.""" pool = ACTIVITY_PHRASES.get(kind or "", DEFAULT_PHRASES) if exclude is None or len(pool) < 2: return random.choice(pool) variants = tuple(phrase for phrase in pool if phrase != exclude) return random.choice(variants)