""" Сервис генерации гипнотических названий для картин галереи. Включает: - Локальный генератор псевдослучайных гипно-заголовков (в стиле Гипножабы, психоделики и мемов). - Закладку (интерфейс и спецификацию) для будущей интеграции с OpenRouter API (мультимодальные VLM). """ import random from typing import Optional # Словари для локального генератора гипно-тайтлов HYPNO_ADJECTIVES = [ "мерцающий", "астральный", "гипнотический", "вульгарный", "сюрреалистический", "абсурдный", "психоделический", "пульсирующий", "неоновый", "трансцендентный", "мозговой", "ментальный", "бессознательный", "космический", "галлюциногенный", "фрактальный", " отрешённый", "синестетический", "параллельный", "иллюзорный", "эфемерный", "гипножабий", "проводящий", "тошнотворный", "завораживающий", "магнетический", "беспечный", "сновидческий", "психотропный", "мистический", "потусторонний", "беспечный", "сновидческий", "психотропный", "мистический", "потусторонний", "спиральный", "зыбкий", "пахучий", "скользкий", "туманный", "онейрический", "эфирный", "трансовый", "квантовый", "сочный", "гипно-абсурдный", "психоактивный", "сюрреалистичный", "магический", "синтетический", "хроматический", "перцептивный", "психоделичный", "галлюцинаторный", "трансцендентальный", "перфорированный", ] HYPNO_NOUNS = [ "транс", "пульсар", "взгляд", "слизень", "вихрь", "портал", "путь", "фрактал", "сигнал", "спектр", "резонанс", "морок", "оазис", "омут", "лабиринт", "импульс", "монолит", "оракул", "вектор", "сгусток", "каскад", "горизонт", "мухомор", "паттерн", "контур", "фантом", "всплеск", "мираж", "транквилизатор", "взмах", "взгляд", "морок", "туман", "свет", "кристалл", "поток", "сингулятор", "снег", "пульс", "глюк", "качан", "сигнал", "поток", "свет", "синтез", "рык", "трепет", "плюх", "Му", "бip-бip", "карачун", "фронтир", "сторож", "привратник", "шёпот", "шлепок по жопе", "гриб", "плевок", "червяк", "пузырь", "психо-паук", ] HYPNO_GENITIVES = [ "сознания", "Гипножабы", "бессознательного", "пустоты", "матрицы", "психо-паутины", "слизня", "ноосферы", "нео-модерна", "транса", "глубины", "эфира", "плесени", "измерения", "пуантилизма", "субстанции", "неопределенности", "континуума", "кислоты", "сына подруги твоей мамы" ] HYPNO_POSTFIXES = [ "#42", "v3.14", "(Ultra)", "(Фаза 7)", "(Альфа)", "(Омега)", "(Протокол 09)", "(Ревизия 14)", "(Экстракт)", "(Слой 9)", "(Палата №6)", "(Ангар 18)", "(Неоконченное произведение)", "(Секретный проект)", ] def generate_hypno_title(seed: Optional[int] = None) -> str: """ Генерирует сочное гипнотическое название для картины на основе словарей. Примеры: - «Мерцающий Транс сознания #42» - «Гипножабий Пульсар психо-паутины» - «Астральный Взгляд v3.14» """ rng = random.Random(seed) adj = rng.choice(HYPNO_ADJECTIVES) noun = rng.choice(HYPNO_NOUNS) pattern_type = rng.randint(1, 3) if pattern_type == 1: genitive = rng.choice(HYPNO_GENITIVES) postfix = rng.choice(HYPNO_POSTFIXES) return f"{adj} {noun} {genitive} {postfix}" elif pattern_type == 2: genitive = rng.choice(HYPNO_GENITIVES) return f"{adj} {noun} {genitive}" else: postfix = rng.choice(HYPNO_POSTFIXES) return f"{adj} {noun} {postfix}" # ===================================================================== # ЗАКЛАДКА: OpenRouter VLM API Integration (Post-MVP / AI Title) # ===================================================================== def generate_title_openrouter( image_bytes: bytes, *, api_key: Optional[str] = None, model: str = "google/gemini-2.5-flash", system_prompt: str = ( "Ты — глашатай всемогущей Гипножабы. Придумай короткое (2-4 слова), " "яркое, иронично-абсурдное и гипнотическое название на русском языке " "для полутоновой SVG-картины, изображенной на миниатюре. " "Отвечай ТОЛЬКО названием, без кавычек и вводных слов." ), timeout: int = 5, ) -> Optional[str]: """ [ЗАКЛАДКА ПОД OPENROUTER API] Спецификация интеграции: 1. Исходное растровое изображение сжимается до thumbnail 256x256 WebP/JPEG. 2. Кодируется в Base64 (data:image/jpeg;base64,...). 3. Отправляется POST-запрос на https://openrouter.ai/api/v1/chat/completions: Payload: { "model": model, "messages": [ {"role": "system", "content": system_prompt}, { "role": "user", "content": [ {"type": "text", "text": "Дай гипнотическое название для этой картины:"}, {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64_data}"}} ] } ], "max_tokens": 50, "temperature": 0.9 } 4. При ошибке таймаута, отсутствии OPENROUTER_API_KEY в .env или сбое сети функция возвращает None, вызывая локальный fallback (generate_hypno_title). """ # TODO: Интегрировать requests / httpx при добавлении OPENROUTER_API_KEY в settings.py if not api_key: return None # Заглушка: при отсутствии реального сетевого коннектора возвращаем None для fallback return None