294 lines
12 KiB
Python
294 lines
12 KiB
Python
"""
|
||
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),
|
||
]
|