diff --git a/detailed_handlers.py b/detailed_handlers.py index 185aff6..eb834e7 100644 --- a/detailed_handlers.py +++ b/detailed_handlers.py @@ -1,8 +1,8 @@ """ -Inline handlers for detailed item viewing with images +Inline handlers for detailed item viewing with images (FIXED VERSION) """ -from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup -from telegram.ext import ContextTypes, CommandHandler, CallbackQueryHandler +from telegram import Update +from telegram.ext import ContextTypes, CommandHandler from vndb_client import VndbClient from utils import ImageHandler from config import Config @@ -13,281 +13,215 @@ vndb_client = VndbClient(use_sandbox=Config.USE_SANDBOX) class DetailedHandlers: - """Handlers for detailed item viewing""" - + + # ========================= + # VN DETAIL + # ========================= @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" + "❌ Укажи ID VN\nПример: /vn_detail v2002" ) 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" - ] + + vn_id = context.args[0].strip() + + await update.message.reply_text( + f"⏳ Загружаю информацию о {vn_id}..." ) - + + results = await vndb_client.query_vn( + filters=["id", "=", vn_id], + fields=[ + "id", "title", "original", "released", + "rating", "votecount", "description", + "length", "developer", "image{url,dims}" + ], + results=1 + ) + if not results.get("results"): - await update.message.reply_text(f"😞 ВН с ID {vn_id} не найдена") + await update.message.reply_text(f"😞 VN {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") - + + text = f"🎮 {vn.get('title','Unknown')} (`{vn_id}`)\n" + + if vn.get("original"): + text += f"Оригинал: {vn['original']}\n" + + text += f"Релиз: {vn.get('released','?')}\n" + text += f"Рейтинг: {vn.get('rating',0)/10:.1f} ({vn.get('votecount',0)} голосов)\n" + + if vn.get("developer"): + text += f"Разработчик: {vn['developer']}\n" + + if vn.get("description"): + desc = vn["description"][:300] + text += f"\nОписание:\n{desc}...\n" + + text += f"\nhttps://vndb.org/{vn_id}" + + img = vn.get("image") + if img: + url = ImageHandler.get_image_url(img) + if url: + await update.message.reply_photo(photo=url, caption=text) + return + + await update.message.reply_text(text) + except Exception as e: - logger.error(f"Error viewing VN detail: {e}") - await update.message.reply_text(f"❌ Ошибка при загрузке информации: {str(e)}") - + logger.error(f"VN detail error: {e}") + await update.message.reply_text(f"❌ Ошибка: {e}") + + + # ========================= + # CHARACTER DETAIL + # ========================= @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" - ) + await update.message.reply_text("❌ Пример: /char_detail c6498") 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] + + char_id = context.args[0].strip() + + await update.message.reply_text(f"⏳ Загружаю {char_id}...") + results = await vndb_client.query_character( - filters=[filters], + filters=["id", "=", char_id], fields=[ - "name", "original", "gender", "bloodtype", "height", "weight", - "bust", "waist", "hips", "description", "image{url,dims}", "vn" - ] + "id", "name", "original", + "gender", "bloodtype", + "description", "image{url,dims}", + "vn" + ], + results=1 ) - + if not results.get("results"): - await update.message.reply_text(f"😞 Персонаж с ID {char_id} не найден") + await update.message.reply_text("😞 Персонаж не найден") 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") - + + c = results["results"][0] + + text = f"👤 {c.get('name','Unknown')} (`{char_id}`)\n" + + if c.get("original"): + text += f"{c['original']}\n" + + if c.get("gender"): + text += f"Пол: {c['gender']}\n" + + if c.get("bloodtype"): + text += f"Кровь: {c['bloodtype']}\n" + + if c.get("vn"): + text += "\nVN:\n" + for vn in c["vn"][:5]: + if vn.get("id"): + text += f"• {vn['id']}\n" + + if c.get("description"): + text += f"\n{c['description'][:300]}...\n" + + text += f"\nhttps://vndb.org/{char_id}" + + img = c.get("image") + if img: + url = ImageHandler.get_image_url(img) + if url: + await update.message.reply_photo(photo=url, caption=text) + return + + await update.message.reply_text(text) + except Exception as e: - logger.error(f"Error viewing character detail: {e}") - await update.message.reply_text(f"❌ Ошибка при загрузке информации: {str(e)}") - + logger.error(f"CHAR detail error: {e}") + await update.message.reply_text(f"❌ Ошибка: {e}") + + + # ========================= + # RELEASE DETAIL + # ========================= @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" - ) + await update.message.reply_text("❌ Пример: /release_detail r3930") 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] + + release_id = context.args[0].strip() + + await update.message.reply_text(f"⏳ Загружаю {release_id}...") + results = await vndb_client.query_release( - filters=[filters], + filters=["id", "=", release_id], fields=[ - "title", "original", "released", "platform", "type", "language", - "edition", "description", "image{url,dims}", "vn" - ] + "id", "title", "original", + "released", "platform", + "type", "language", + "description", + "image{url,dims}", + "vn" + ], + results=1 ) - + if not results.get("results"): - await update.message.reply_text(f"😞 Релиз с ID {release_id} не найден") + await update.message.reply_text("😞 Релиз не найден") 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") - + + r = results["results"][0] + + text = f"🎬 {r.get('title','Unknown')} (`{release_id}`)\n" + + if r.get("original"): + text += f"{r['original']}\n" + + text += f"Дата: {r.get('released','?')}\n" + text += f"Платформа: {r.get('platform','?')}\n" + text += f"Тип: {r.get('type','?')}\n" + + if r.get("language"): + text += f"Языки: {', '.join(r['language'])}\n" + + if r.get("vn"): + text += "\nVN:\n" + for vn in r["vn"][:3]: + if vn.get("id"): + text += f"• {vn['id']}\n" + + if r.get("description"): + text += f"\n{r['description'][:200]}...\n" + + text += f"\nhttps://vndb.org/{release_id}" + + img = r.get("image") + if img: + url = ImageHandler.get_image_url(img) + if url: + await update.message.reply_photo(photo=url, caption=text) + return + + await update.message.reply_text(text) + except Exception as e: - logger.error(f"Error viewing release detail: {e}") - await update.message.reply_text(f"❌ Ошибка при загрузке информации: {str(e)}") + logger.error(f"RELEASE detail error: {e}") + await update.message.reply_text(f"❌ Ошибка: {e}") +# ========================= +# REGISTER +# ========================= 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), - ] + ] \ No newline at end of file