Review copilot neuroslop and fixed bugs

This commit is contained in:
2026-05-01 15:34:45 +03:00
parent b983126e6e
commit 2d55baf3ad
4 changed files with 100 additions and 103 deletions

View File

@@ -94,8 +94,8 @@
```
**Получите:**
- 🖼️ Высокое качество обложки
- 📋 Полная информация:
- Высокое качество обложки
- Полная информация:
- Название: Steins;Gate
- Оригинальное название: シュタインズ・ゲート
- Дата выпуска: 2009-09-15
@@ -120,8 +120,8 @@
```
**Получите:**
- 👤 Аватар персонажа высокого качества
- 📋 Информация:
- Аватар персонажа высокого качества
- Информация:
- Имя и оригинальное имя
- Пол
- Группа крови
@@ -244,7 +244,7 @@
## Советы и трюки
### 💡 Совет 1: Комбинирование команд
### Совет 1: Комбинирование команд
Эффективный способ использования:
```bash
@@ -252,7 +252,7 @@
/[type]_detail [id] # Посмотрите детали
```
### 💡 Совет 2: Использование ID
### Совет 2: Использование ID
После поиска вы видите ID в скобках:
```
@@ -264,7 +264,7 @@
/vn_detail v17
```
### 💡 Совет 3: Максимум информации за раз
### Совет 3: Максимум информации за раз
Команды подробного просмотра дают максимум информации:
- Картинку (если есть)
@@ -273,7 +273,7 @@
- Связанные элементы
- Ссылку на оригинальный сайт
### 💡 Совет 4: Работа с изображениями
### Совет 4: Работа с изображениями
- **Быстрый поиск**: используйте `/search`, получите автоматические картинки
- **Качество**: используйте `/vn_detail` и т.д. для лучшего качества картинок
@@ -310,28 +310,28 @@
## Полезные команды для разных целей
### 📚 Исследование ВН
### Исследование ВН
```bash
/stats # Сколько всего ВН
/search [имя] # Найти конкретную ВН
/vn_detail [id] # Полная информация о ВН
```
### 👥 Изучение персонажей
### Изучение персонажей
```bash
/char [имя] # Найти персонажа
/char_detail [id] # Полная информация о персонаже
/trait # Посмотреть черты характера
```
### 🎬 Поиск релизов
### Поиск релизов
```bash
/release [название] # Найти релиз
/release_detail [id] # Информация о релизе
/search [ВН] # Найти ВН и её релизы
```
### 🏷️ Просмотр категорий
### Просмотр категорий
```bash
/tag # Теги и категории
/trait # Черты характера

View File

@@ -1,13 +1,13 @@
# Работа с изображениями в VNDB Telegram Bot
## 📸 Поддерживаемые изображения
## Поддерживаемые изображения
Бот может отправлять изображения для:
- 🎮 **Визуальные новеллы** - обложки и постеры
- 👤 **Персонажи** - аватары и официальные картинки
- 📦 **Релизы** - коробки и обложки физических изданий
- **Визуальные новеллы** - обложки и постеры
- **Персонажи** - аватары и официальные картинки
- **Релизы** - коробки и обложки физических изданий
## 🚀 Использование изображений
## Использование изображений
### 1. Автоматическая отправка при поиске
@@ -18,8 +18,8 @@
```
Бот вернёт:
- 📝 Текстовую информацию со списком найденных ВН
- 🖼️ Обложки первых 3 ВН
- Текстовую информацию со списком найденных ВН
- Обложки первых 3 ВН
### 2. Детальный просмотр с полной информацией
@@ -32,8 +32,8 @@
```
Отправит:
- 🎮 Обложку ВН (высокое качество)
- 📋 Полная информация:
- Обложку ВН (высокое качество)
- Полная информация:
- Название и оригинальное название
- Дата выпуска
- Рейтинг и количество голосов
@@ -49,8 +49,8 @@
```
Отправит:
- 👤 Аватар персонажа
- 📋 Информация:
- Аватар персонажа
- Информация:
- Имя и оригинальное имя
- Пол
- Группа крови
@@ -64,8 +64,8 @@
```
Отправит:
- 📦 Картинку релиза
- 📋 Информация:
- Картинку релиза
- Информация:
- Название
- Дата выпуска
- Платформа
@@ -75,7 +75,7 @@
- ВН, к которой относится
- Описание
## 🎨 Примеры
## Примеры
### Поиск и просмотр ВН
@@ -133,20 +133,20 @@
/vn_detail v17
```
## ⚠️ Обработка ошибок при изображениях
## Обработка ошибок при изображениях
Если изображение недоступно или бот не может его отправить:
- Бот вернёт текстовую информацию без изображения
- Информация будет полной и точной
- Вы по-прежнему можете посетить VNDB напрямую для просмотра изображения
## 🌐 Источник изображений
## Источник изображений
Все изображения загружаются с официального CDN VNDB:
- **URL база**: `https://t.vndb.org`
- **Качество**: Оптимальное для отображения в Telegram
## 💡 Советы
## Советы
1. **Для быстрого поиска**: используйте `/search`, `/char`, `/release`
- Автоматически получите первые изображения
@@ -165,7 +165,7 @@
# Получаете полную информацию с обложкой
```
## 📝 Примечания
## Примечания
- Не все элементы имеют изображения в VNDB
- Если изображение отсутствует, бот отправит только текстовую информацию

View File

@@ -7,16 +7,16 @@
Бот поддерживает **все методы** VNDB API v2:
### Поиск и запросы
- 🎮 **Визуальные новеллы** - полный поиск по названию, языку, платформе, тегам, рейтингу и дате выпуска
- 👥 **Персонажи** - поиск по имени, полу, роли, чертам характера
- 🎬 **Релизы** - поиск по названию, платформе, типу, дате выпуска
- 👨‍💼 **Сотрудники** - поиск сценаристов, художников, композиторов и других
- 🏢 **Продюсеры** - поиск издателей и разработчиков
- 🏷️ **Теги** - просмотр популярных тегов и категорий
- **Черты характера** - список черт персонажей
- 💬 **Цитаты** - получение случайных цитат из ВН
- **Визуальные новеллы** - полный поиск по названию, языку, платформе, тегам, рейтингу и дате выпуска
- **Персонажи** - поиск по имени, полу, роли, чертам характера
- **Релизы** - поиск по названию, платформе, типу, дате выпуска
- **Сотрудники** - поиск сценаристов, художников, композиторов и других
- **Продюсеры** - поиск издателей и разработчиков
- **Теги** - просмотр популярных тегов и категорий
- **Черты характера** - список черт персонажей
- **Цитаты** - получение случайных цитат из ВН
### Изображения 📸
### Изображения
- **Обложки ВН** - автоматическая отправка обложек при поиске визуальных новелл
- **Аватары персонажей** - картинки персонажей при поиске
- **Картинки релизов** - изображения для каждого релиза
@@ -29,9 +29,9 @@
- Управление меткамиме
### Информация
- 📊 Статистика базы данных
- 📋 Информация о схеме API
- 🔐 Информация об авторизации
- Статистика базы данных
- Информация о схеме API
- Информация об авторизации
## Установка

119
bot.py
View File

@@ -1,7 +1,3 @@
"""
VNDB Telegram Bot
Main bot implementation with command handlers
"""
import logging
from typing import Optional
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
@@ -43,7 +39,7 @@ class BotHandlers:
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Start command handler"""
welcome_text = """
🎮 **Добро пожаловать в VNDB Telegram Бот!**
**Добро пожаловать в VNDB Telegram Бот!**
Этот бот позволяет искать информацию о визуальных новеллах, персонажах, релизах и многом другом из базы данных VNDB.
@@ -60,7 +56,8 @@ class BotHandlers:
/schema - Информация о схеме API
/help - Справка по командам
*Используйте /help для получения подробной информации*
__Используйте /help для получения подробной информации__
__Также можете ознакомится с примерами команд по ссылке: https://git.kotac.ru/King-of-the-all-Cookies/ayako/src/branch/main/EXAMPLES.md__
"""
await update.message.reply_text(welcome_text, parse_mode="Markdown")
@@ -68,7 +65,7 @@ class BotHandlers:
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Help command handler"""
help_text = """
**📚 Справка по командам VNDB Бота**
**Справка по командам VNDB Бота**
**Поиск информации:**
/search <название> - Поиск визуальных новелл по названию
@@ -82,11 +79,11 @@ class BotHandlers:
**Подробный просмотр (с картинками):**
/vn_detail <ID> - Просмотр полной информации о ВН с обложкой
ример: /vn_detail v17_
_ример: /vn_detail v17__
/char_detail <ID> - Просмотр информации о персонаже с аватаром
ример: /char_detail c1_
_ример: /char_detail c1__
/release_detail <ID> - Просмотр информации о релизе с картинкой
ример: /release_detail r1_
_ример: /release_detail r1__
**Информация:**
/stats - Показать статистику базы данных VNDB
@@ -119,15 +116,15 @@ class BotHandlers:
stats = await vndb_client.get_stats()
stats_text = f"""
📊 **Статистика базы данных VNDB:**
**Статистика базы данных VNDB:**
🎮 Визуальные новеллы: {stats.get('vn', 0):,}
👥 Персонажи: {stats.get('chars', 0):,}
🎬 Релизы: {stats.get('releases', 0):,}
🏢 Продюсеры: {stats.get('producers', 0):,}
👨‍💼 Сотрудники: {stats.get('staff', 0):,}
🏷️ Теги: {stats.get('tags', 0):,}
Черты характера: {stats.get('traits', 0):,}
Визуальные новеллы: {stats.get('vn', 0):,}
Персонажи: {stats.get('chars', 0):,}
Релизы: {stats.get('releases', 0):,}
Продюсеры: {stats.get('producers', 0):,}
Сотрудники: {stats.get('staff', 0):,}
Теги: {stats.get('tags', 0):,}
Черты характера: {stats.get('traits', 0):,}
"""
await update.message.reply_text(stats_text, parse_mode="Markdown")
except Exception as e:
@@ -147,7 +144,7 @@ class BotHandlers:
schema = await vndb_client.get_schema()
# Build schema info
schema_text = "📋 **Информация о схеме VNDB API:**\n\n"
schema_text = "**Информация о схеме VNDB API:**\n\n"
# Database types
if "db_types" in schema:
@@ -163,7 +160,7 @@ class BotHandlers:
schema_text += f"{field_type}\n"
schema_text += "\n"
schema_text += "Для полного списка полей и типов посетите: https://api.vndb.org/kana"
schema_text += "**Для полного списка полей и типов посетите: https://api.vndb.org/kana**"
await update.message.reply_text(schema_text, parse_mode="Markdown")
except Exception as e:
@@ -179,12 +176,12 @@ class BotHandlers:
if not args:
await update.message.reply_text(
"Пожалуйста, укажите название для поиска\n"
"Пожалуйста, укажите название для поиска\n"
"Пример: /search Steins Gate"
)
return ConversationHandler.END
await update.message.reply_text(f"🔍 Поиск визуальных новелл: **{args}**\nЗагрузка...", parse_mode="Markdown")
await update.message.reply_text(f"Поиск визуальных новелл: **{args}**\nЗагрузка...", parse_mode="Markdown")
# Search for VN
filters = ["search", "=", args]
@@ -195,7 +192,7 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return ConversationHandler.END
# Format results
@@ -220,7 +217,7 @@ class BotHandlers:
f" Рейтинг: {rating/10:.1f}/10 ({votecount} голосов)\n\n"
)
response_text += f"\n📌 Всего найдено: {len(results['results'])} результатов"
response_text += f"\nВсего найдено: {len(results['results'])} результатов"
if results.get("more"):
response_text += " (есть еще результаты)"
@@ -236,7 +233,7 @@ class BotHandlers:
title = vn.get("title", "VN")
await update.message.reply_photo(
photo=f"https://t.vndb.org{image_url}",
caption=f"🎮 {title}",
caption=f"{title}",
parse_mode="Markdown"
)
except Exception as e:
@@ -248,7 +245,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error searching VN: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
return ConversationHandler.END
@@ -260,12 +257,12 @@ class BotHandlers:
if not args:
await update.message.reply_text(
"Пожалуйста, укажите имя персонажа\n"
"Пожалуйста, укажите имя персонажа\n"
"Пример: /char Okabe"
)
return ConversationHandler.END
await update.message.reply_text(f"🔍 Поиск персонажей: **{args}**\n⏳ Загрузка...", parse_mode="Markdown")
await update.message.reply_text(f"Поиск персонажей: **{args}**\n⏳ Загрузка...", parse_mode="Markdown")
filters = ["search", "=", args]
results = await vndb_client.query_character(
@@ -275,7 +272,7 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return ConversationHandler.END
response_text = f"**Результаты поиска персонажей: {args}**\n\n"
@@ -311,7 +308,7 @@ class BotHandlers:
name = char.get("name", "Character")
await update.message.reply_photo(
photo=f"https://t.vndb.org{image_url}",
caption=f"👤 {name}",
caption=f"{name}",
parse_mode="Markdown"
)
except Exception as e:
@@ -322,7 +319,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error searching characters: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
return ConversationHandler.END
@@ -334,12 +331,12 @@ class BotHandlers:
if not args:
await update.message.reply_text(
"Пожалуйста, укажите название для поиска\n"
"Пожалуйста, укажите название для поиска\n"
"Пример: /release Windows"
)
return ConversationHandler.END
await update.message.reply_text(f"🔍 Поиск релизов: **{args}**\nЗагрузка...", parse_mode="Markdown")
await update.message.reply_text(f"Поиск релизов: **{args}**\nЗагрузка...", parse_mode="Markdown")
filters = ["search", "=", args]
results = await vndb_client.query_release(
@@ -349,7 +346,7 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return ConversationHandler.END
response_text = f"**Результаты поиска релизов: {args}**\n\n"
@@ -386,7 +383,7 @@ class BotHandlers:
title = release.get("title", "Release")
await update.message.reply_photo(
photo=f"https://t.vndb.org{image_url}",
caption=f"🎬 {title}",
caption=f"{title}",
parse_mode="Markdown"
)
except Exception as e:
@@ -397,7 +394,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error searching releases: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
return ConversationHandler.END
@@ -409,12 +406,12 @@ class BotHandlers:
if not args:
await update.message.reply_text(
"Пожалуйста, укажите имя\n"
"Пожалуйста, укажите имя\n"
"Пример: /staff Yoko"
)
return ConversationHandler.END
await update.message.reply_text(f"🔍 Поиск сотрудников: **{args}**\nЗагрузка...", parse_mode="Markdown")
await update.message.reply_text(f"Поиск сотрудников: **{args}**\nЗагрузка...", parse_mode="Markdown")
filters = ["search", "=", args]
results = await vndb_client.query_staff(
@@ -424,7 +421,7 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return ConversationHandler.END
response_text = f"**Результаты поиска сотрудников: {args}**\n\n"
@@ -449,7 +446,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error searching staff: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
return ConversationHandler.END
@@ -461,12 +458,12 @@ class BotHandlers:
if not args:
await update.message.reply_text(
"Пожалуйста, укажите название\n"
"Пожалуйста, укажите название\n"
"Пример: /producer Key"
)
return ConversationHandler.END
await update.message.reply_text(f"🔍 Поиск продюсеров: **{args}**\n⏳ Загрузка...", parse_mode="Markdown")
await update.message.reply_text(f"Поиск продюсеров: **{args}**\n⏳ Загрузка...", parse_mode="Markdown")
filters = ["search", "=", args]
results = await vndb_client.query_producer(
@@ -476,7 +473,7 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return ConversationHandler.END
response_text = f"**Результаты поиска продюсеров: {args}**\n\n"
@@ -500,7 +497,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error searching producers: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
return ConversationHandler.END
@@ -508,7 +505,7 @@ class BotHandlers:
async def list_tags(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""List popular tags"""
try:
await update.message.reply_text("Загружаю теги...", parse_mode="Markdown")
await update.message.reply_text("Загружаю теги...", parse_mode="Markdown")
results = await vndb_client.query_tag(
fields=["name", "description"],
@@ -518,10 +515,10 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return
response_text = "**🏷️ Популярные теги VNDB:**\n\n"
response_text = "**Популярные теги VNDB:**\n\n"
for i, tag in enumerate(results["results"], 1):
tag_id = tag.get("id", "Unknown")
@@ -538,13 +535,13 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error listing tags: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
@staticmethod
async def list_traits(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""List character traits"""
try:
await update.message.reply_text("Загружаю черты характера...", parse_mode="Markdown")
await update.message.reply_text("Загружаю черты характера...", parse_mode="Markdown")
results = await vndb_client.query_trait(
fields=["name", "description"],
@@ -554,10 +551,10 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return
response_text = "**Популярные черты характера:**\n\n"
response_text = "**Популярные черты характера:**\n\n"
for i, trait in enumerate(results["results"], 1):
trait_id = trait.get("id", "Unknown")
@@ -574,7 +571,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error listing traits: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
@staticmethod
async def get_quote(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -584,7 +581,7 @@ class BotHandlers:
if context.args and context.args[0].isdigit():
count = min(int(context.args[0]), 5) # Max 5 quotes
await update.message.reply_text(f"Загружаю {count} цитат...", parse_mode="Markdown")
await update.message.reply_text(f"Загружаю {count} цитат...", parse_mode="Markdown")
results = await vndb_client.query_quote(
fields=["character", "quote"],
@@ -593,10 +590,10 @@ class BotHandlers:
)
if not results.get("results"):
await update.message.reply_text("😞 Ничего не найдено")
await update.message.reply_text("Ничего не найдено")
return
response_text = "**💬 Случайные цитаты:**\n\n"
response_text = "**Случайные цитаты:**\n\n"
for quote in results["results"]:
quote_text = quote.get("quote", "")
@@ -611,7 +608,7 @@ class BotHandlers:
except Exception as e:
logger.error(f"Error getting quotes: {e}")
error_msg = ErrorHandler.format_error(e)
await update.message.reply_text(f"{error_msg}")
await update.message.reply_text(f"{error_msg}")
@staticmethod
async def authinfo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -620,7 +617,7 @@ class BotHandlers:
token = Config.VNDB_TOKEN
if not token:
await update.message.reply_text(
"Токен VNDB не установлен\n\n"
"Токен VNDB не установлен\n\n"
"Чтобы использовать функции авторизации:\n"
"1. Посетите https://vndb.org/u/tokens\n"
"2. Создайте новый токен\n"
@@ -632,7 +629,7 @@ class BotHandlers:
auth_info = await client_with_token.get_authinfo()
response_text = f"""
**👤 Информация об авторизации:**
**Информация об авторизации:**
ID: {auth_info.get('id', 'Unknown')}
Пользователь: {auth_info.get('username', 'Unknown')}
@@ -642,12 +639,12 @@ ID: {auth_info.get('id', 'Unknown')}
permissions = auth_info.get("permissions", [])
if "listread" in permissions:
response_text += "Чтение списка (listread)\n"
response_text += "Чтение списка (listread)\n"
if "listwrite" in permissions:
response_text += "Запись в список (listwrite)\n"
response_text += "Запись в список (listwrite)\n"
if not permissions:
response_text += "Нет разрешений"
response_text += "Нет разрешений"
await update.message.reply_text(response_text, parse_mode="Markdown")