First commit

This commit is contained in:
2026-05-01 15:13:02 +03:00
parent c2fcedf608
commit b983126e6e
18 changed files with 7142 additions and 147 deletions

293
detailed_handlers.py Normal file
View File

@@ -0,0 +1,293 @@
"""
Inline handlers for detailed item viewing with images
"""
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ContextTypes, CommandHandler, CallbackQueryHandler
from vndb_client import VndbClient
from utils import ImageHandler
from config import Config
import logging
logger = logging.getLogger(__name__)
vndb_client = VndbClient(use_sandbox=Config.USE_SANDBOX)
class DetailedHandlers:
"""Handlers for detailed item viewing"""
@staticmethod
async def view_vn_detail(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""View detailed VN information with image"""
try:
if not context.args:
await update.message.reply_text(
"❌ Пожалуйста, укажите ID визуальной новеллы\n"
"Пример: /vn_detail v17"
)
return
vn_id = context.args[0]
await update.message.reply_text(f"⏳ Загружаю информацию о {vn_id}...", parse_mode="Markdown")
# Get detailed VN information
filters = ["id", "=", vn_id]
results = await vndb_client.query_vn(
filters=[filters],
fields=[
"title", "original", "released", "rating", "votecount",
"description", "image{url,dims}", "length", "developer"
]
)
if not results.get("results"):
await update.message.reply_text(f"😞 ВН с ID {vn_id} не найдена")
return
vn = results["results"][0]
# Build detailed text
title = vn.get("title", "Unknown")
original = vn.get("original", "")
released = vn.get("released", "Unknown")
rating = vn.get("rating", 0)
votecount = vn.get("votecount", 0)
description = vn.get("description", "")
length = vn.get("length", "")
developer = vn.get("developer", "")
detail_text = f"""
**🎮 {title}** (`{vn_id}`)
"""
if original:
detail_text += f"Оригинал: {original}\n"
detail_text += f"""
Дата релиза: {released}
Рейтинг: {rating/10:.1f}/10 ({votecount} голосов)
"""
if length:
detail_text += f"Длительность: {length}\n"
if developer:
detail_text += f"Разработчик: {developer}\n"
if description:
# Truncate long descriptions
desc_truncated = description[:300] + "..." if len(description) > 300 else description
detail_text += f"\nОписание:\n{desc_truncated}\n"
detail_text += f"\n[Открыть на VNDB](https://vndb.org/{vn_id})"
# Send with image if available
image_data = vn.get("image")
if image_data:
image_url = ImageHandler.get_image_url(image_data)
if image_url:
try:
await update.message.reply_photo(
photo=image_url,
caption=detail_text,
parse_mode="Markdown"
)
except Exception as e:
logger.warning(f"Could not send VN image: {e}")
await update.message.reply_text(detail_text, parse_mode="Markdown")
else:
await update.message.reply_text(detail_text, parse_mode="Markdown")
else:
await update.message.reply_text(detail_text, parse_mode="Markdown")
except Exception as e:
logger.error(f"Error viewing VN detail: {e}")
await update.message.reply_text(f"❌ Ошибка при загрузке информации: {str(e)}")
@staticmethod
async def view_character_detail(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""View detailed character information with image"""
try:
if not context.args:
await update.message.reply_text(
"❌ Пожалуйста, укажите ID персонажа\n"
"Пример: /char_detail c1"
)
return
char_id = context.args[0]
await update.message.reply_text(f"⏳ Загружаю информацию о {char_id}...", parse_mode="Markdown")
# Get detailed character information
filters = ["id", "=", char_id]
results = await vndb_client.query_character(
filters=[filters],
fields=[
"name", "original", "gender", "bloodtype", "height", "weight",
"bust", "waist", "hips", "description", "image{url,dims}", "vn"
]
)
if not results.get("results"):
await update.message.reply_text(f"😞 Персонаж с ID {char_id} не найден")
return
char = results["results"][0]
# Build detailed text
name = char.get("name", "Unknown")
original = char.get("original", "")
gender = char.get("gender", "")
bloodtype = char.get("bloodtype", "")
description = char.get("description", "")
vns = char.get("vn", [])
detail_text = f"**👤 {name}** (`{char_id}`)\n"
if original:
detail_text += f"Оригинал: {original}\n"
if gender:
detail_text += f"Пол: {gender}\n"
if bloodtype:
detail_text += f"Группа крови: {bloodtype}\n"
if vns:
detail_text += f"\nПоявляется в:\n"
for vn in vns[:5]: # Show first 5 VNs
vn_id = vn.get("id", "")
if vn_id:
detail_text += f"• [{vn_id}](https://vndb.org/{vn_id})\n"
if description:
desc_truncated = description[:300] + "..." if len(description) > 300 else description
detail_text += f"\nОписание:\n{desc_truncated}\n"
detail_text += f"\n[Открыть на VNDB](https://vndb.org/{char_id})"
# Send with image if available
image_data = char.get("image")
if image_data:
image_url = ImageHandler.get_image_url(image_data)
if image_url:
try:
await update.message.reply_photo(
photo=image_url,
caption=detail_text,
parse_mode="Markdown"
)
except Exception as e:
logger.warning(f"Could not send character image: {e}")
await update.message.reply_text(detail_text, parse_mode="Markdown")
else:
await update.message.reply_text(detail_text, parse_mode="Markdown")
else:
await update.message.reply_text(detail_text, parse_mode="Markdown")
except Exception as e:
logger.error(f"Error viewing character detail: {e}")
await update.message.reply_text(f"❌ Ошибка при загрузке информации: {str(e)}")
@staticmethod
async def view_release_detail(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""View detailed release information with image"""
try:
if not context.args:
await update.message.reply_text(
"❌ Пожалуйста, укажите ID релиза\n"
"Пример: /release_detail r1"
)
return
release_id = context.args[0]
await update.message.reply_text(f"⏳ Загружаю информацию о {release_id}...", parse_mode="Markdown")
# Get detailed release information
filters = ["id", "=", release_id]
results = await vndb_client.query_release(
filters=[filters],
fields=[
"title", "original", "released", "platform", "type", "language",
"edition", "description", "image{url,dims}", "vn"
]
)
if not results.get("results"):
await update.message.reply_text(f"😞 Релиз с ID {release_id} не найден")
return
release = results["results"][0]
# Build detailed text
title = release.get("title", "Unknown")
original = release.get("original", "")
released = release.get("released", "Unknown")
platform = release.get("platform", "")
rel_type = release.get("type", "")
language = release.get("language", [])
edition = release.get("edition", "")
description = release.get("description", "")
vns = release.get("vn", [])
detail_text = f"**🎬 {title}** (`{release_id}`)\n"
if original:
detail_text += f"Оригинал: {original}\n"
detail_text += f"""
Дата выпуска: {released}
Платформа: {platform}
Тип: {rel_type}
"""
if language:
lang_str = ", ".join(language) if isinstance(language, list) else str(language)
detail_text += f"Языки: {lang_str}\n"
if edition:
detail_text += f"Издание: {edition}\n"
if vns:
detail_text += f"\nЧасть из:\n"
for vn in vns[:3]:
vn_id = vn.get("id", "")
if vn_id:
detail_text += f"• [{vn_id}](https://vndb.org/{vn_id})\n"
if description:
desc_truncated = description[:200] + "..." if len(description) > 200 else description
detail_text += f"\nОписание:\n{desc_truncated}\n"
detail_text += f"\n[Открыть на VNDB](https://vndb.org/{release_id})"
# Send with image if available
image_data = release.get("image")
if image_data:
image_url = ImageHandler.get_image_url(image_data)
if image_url:
try:
await update.message.reply_photo(
photo=image_url,
caption=detail_text,
parse_mode="Markdown"
)
except Exception as e:
logger.warning(f"Could not send release image: {e}")
await update.message.reply_text(detail_text, parse_mode="Markdown")
else:
await update.message.reply_text(detail_text, parse_mode="Markdown")
else:
await update.message.reply_text(detail_text, parse_mode="Markdown")
except Exception as e:
logger.error(f"Error viewing release detail: {e}")
await update.message.reply_text(f"❌ Ошибка при загрузке информации: {str(e)}")
def get_detail_handlers():
"""Get all detail view handlers"""
return [
CommandHandler("vn_detail", DetailedHandlers.view_vn_detail),
CommandHandler("char_detail", DetailedHandlers.view_character_detail),
CommandHandler("release_detail", DetailedHandlers.view_release_detail),
]