From c614a4a898ef7d90077f8938efb93aa1a9d8566a Mon Sep 17 00:00:00 2001 From: Macsim Date: Fri, 21 Nov 2025 17:37:45 +0300 Subject: [PATCH] Fixed some bugs: strange \n sometimes duplicating commands and reverted banner change bcs of i dont like current realization --- Limoka.py | 229 +++++++++++++++++++++++------------------------------- 1 file changed, 99 insertions(+), 130 deletions(-) diff --git a/Limoka.py b/Limoka.py index 3fa3b90..ac7d4d0 100644 --- a/Limoka.py +++ b/Limoka.py @@ -16,10 +16,11 @@ import re from datetime import datetime import asyncio -from typing import Union, List, Dict, Any +from typing import Union, List, Dict, Any, Optional from telethon.types import Message from telethon.errors.rpcerrorlist import WebpageMediaEmptyError +from telethon import events try: from aiogram.utils.exceptions import BadRequest except ImportError: @@ -30,7 +31,7 @@ from ..types import InlineQuery, InlineCall logger = logging.getLogger("Limoka") -__version__ = (1, 2, 0) +__version__ = (1, 2, 1) class Search: @@ -130,6 +131,13 @@ class Limoka(loader.Module): "no_category": "No category", "global_button": "🌍 Results", "filtered_button": "🏷️ Filtered search", + "inline_search": "🔍 Search in Limoka", + "inline_no_results": "❌ No modules found", + "inline_error": "❌ Search error occurred", + "inline_short_query": "❌ Query too short (min 2 chars)", + "inline_switch_pm": "💬 Open in chat", + "inline_switch_pm_text": "🔍 Results for: {query}", + "inline_start_message": "🔍 Limoka Search\n\nType module name or keyword", } strings_ru = { @@ -194,6 +202,13 @@ class Limoka(loader.Module): "no_category": "Без категории", "global_button": "🌍 Результаты", "filtered_button": "🏷️ Поиск с фильтрами", + "inline_search": "🔍 Поиск в Limoka", + "inline_no_results": "❌ Модули не найдены", + "inline_error": "❌ Ошибка поиска", + "inline_short_query": "❌ Запрос слишком короткий (мин. 2 символа)", + "inline_switch_pm": "💬 Открыть в чате", + "inline_switch_pm_text": "🔍 Результаты для: {query}", + "inline_start_message": "🔍 Limoka Поиск\n\nВведите название модуля или ключевое слово", } def __init__(self): @@ -271,13 +286,13 @@ class Limoka(loader.Module): commands = [] for i, func in enumerate(module_info["commands"], 1): if i > 9: - commands.append("…") + commands.append("…\n") break for command, description in func.items(): emoji = self.strings["emojis"].get(i, "") - desc = (description or self.strings["no_info"]).replace("\n", "\n\n")[:200] - if len(desc) > 197: - desc = desc[:197] + "…" + desc = (description or self.strings["no_info"]) + if len(desc) > 150: + desc = desc[:147] + "…" commands.append( self.strings["command_template"].format( prefix=self.get_prefix(), @@ -286,7 +301,7 @@ class Limoka(loader.Module): description=html.escape(desc), ) ) - return commands + return commands[:5] async def _display_filter_menu(self, call: InlineCall, query: str, current_filters: dict): categories = current_filters.get("category", []) @@ -448,7 +463,7 @@ class Limoka(loader.Module): async def _display_module( self, - message_or_call: Union[Message, InlineCall], + message_or_call: Union[Message, InlineCall, None], module_info: Dict[str, Any], module_path: str, query: str, @@ -470,6 +485,9 @@ class Limoka(loader.Module): categories=', '.join(html.escape(c) for c in categories) if categories else self.strings["no_category"] ) + if len(description) > 300: + description = description[:297] + "…" + core_message = self.strings["found"].format( query=html.escape(query), name=name, @@ -481,42 +499,24 @@ class Limoka(loader.Module): module_path=html.escape(clean_module_path), ) - static_suffix = f"\n{filters_text}" - max_core_len = 1024 - len(static_suffix) + full_message = core_message[:4096] - if max_core_len < 50: - max_core_len = 50 - - if len(core_message) > max_core_len: + caption_message = full_message + if len(caption_message) > 1024: safe_query = html.escape(query[:30]) + ("..." if len(query) > 30 else "") safe_name = name[:40] + ("..." if len(name) > 40 else "") - safe_dev = dev_username[:30] + ("..." if len(dev_username) > 30 else "") + safe_desc = description[:100] + ("…" if len(description) > 100 else "") + + caption_message = ( + f"🔍 {safe_name}\n" + f"ℹ️ Desc: {safe_desc}\n" + f"🧑‍💻 Dev: {dev_username}\n\n" + f"🪄 {self.get_prefix()}dlm {self.config['limokaurl']}{html.escape(clean_module_path)}" + )[:1024] - desc_max = max(50, (max_core_len - 250) // 2) - safe_desc = description[:desc_max] + ("…" if len(description) > desc_max else "") - - safe_commands = [] - for cmd in commands[:3]: - if len(cmd) > 150: - cmd = cmd[:147] + "…" - safe_commands.append(cmd) - - core_message = ( - f"🔍 " - f"Found module {safe_name} by query: {safe_query}\n\n" - f"ℹ️ Description: {safe_desc}\n" - f"🧑‍💻 Developer: {safe_dev}\n\n" - f"{''.join(safe_commands)}" - ) - - core_message = re.sub(r'\n\s*\n', '\n\n', core_message) - core_message = "\n".join(line.strip() for line in core_message.splitlines()) - core_message = core_message.rstrip("\n") - - if len(core_message) > max_core_len: - core_message = core_message[:max_core_len - 3] + "…" - - full_message = (core_message + static_suffix)[:1024] + static_suffix = f"\n{filters_text}" + if len(caption_message) + len(static_suffix) <= 1024: + caption_message += static_suffix markup = [ [ @@ -542,33 +542,64 @@ class Limoka(loader.Module): ] try: + if message_or_call is None: + logger.error("message_or_call is None in _display_module") + return + if isinstance(message_or_call, Message): - await self.inline.form( - text=full_message, - message=message_or_call, - reply_markup=markup, - photo=banner_url - ) + if banner_url and banner_url != self.fallback_banner: + await self.inline.form( + text=caption_message, + message=message_or_call, + reply_markup=markup, + photo=banner_url + ) + else: + await self.inline.form( + text=full_message, + message=message_or_call, + reply_markup=markup + ) else: - await message_or_call.edit( - text=full_message, - reply_markup=markup, - photo=banner_url - ) - except (BadRequest, WebpageMediaEmptyError): - if isinstance(message_or_call, Message): + if banner_url and banner_url != self.fallback_banner: + await message_or_call.edit( + text=caption_message, + reply_markup=markup, + photo=banner_url + ) + else: + await message_or_call.edit( + text=full_message, + reply_markup=markup + ) + except (BadRequest, WebpageMediaEmptyError) as e: + logger.exception(f"Error in _display_module: {e}") + if message_or_call is None: + return + + try: + if isinstance(message_or_call, Message): + target_message = message_or_call + elif hasattr(message_or_call, 'message') and isinstance(message_or_call.message, Message): + target_message = message_or_call.message + else: + target_message = await self.client.send_message( + self._me, + "Error occurred, please try again." + ) + await self.inline.form( - text=full_message, - message=message_or_call, - reply_markup=markup, - photo=self.fallback_banner - ) - else: - await message_or_call.edit( - text=full_message, - reply_markup=markup, - photo=self.fallback_banner + text=full_message[:4096], + message=target_message, + reply_markup=markup ) + except Exception as inner_e: + logger.exception(f"Secondary error in error handling: {inner_e}") + try: + if isinstance(message_or_call, Message): + await utils.answer(message_or_call, "Error displaying module. Please try again.") + except Exception: + pass async def _show_global_results(self, call: InlineCall, query: str): searcher = Search(query.lower(), self.ix) @@ -604,7 +635,7 @@ class Limoka(loader.Module): buttons.append([{"text": self.strings["change_query"], "callback": self._enter_query}]) await call.edit( - text=text, + text=text[:4096], reply_markup=buttons ) @@ -635,13 +666,12 @@ class Limoka(loader.Module): async def _inline_void(self, call: InlineCall): await call.answer() - @loader.command(ru_doc="[запрос] — Поиск модулей (без аргументов для формы ввода)") + @loader.command(ru_doc="[запрос / ничего] — Поиск модулей") async def limokacmd(self, message: Message): - """[query] - Search modules (no args for input form)""" + """[query / nothing] - Search modules""" args = utils.get_args_raw(message) if not args: - # No arguments - show input form markup = [ [ { @@ -668,7 +698,6 @@ class Limoka(loader.Module): ) return - # With arguments - perform search if len(self._history) >= 10: self._history = self._history[-9:] self._history.append(args) @@ -762,7 +791,7 @@ class Limoka(loader.Module): buttons.append([{"text": "🔄 " + self.strings["change_query"], "callback": lambda c: self._show_global_form(c, message)}]) await call.edit( - text=text, + text=text[:4096], reply_markup=buttons ) @@ -779,64 +808,4 @@ class Limoka(loader.Module): self.strings["history"].format( history='\n'.join(formatted_history) ) - ) - - @loader.inline_handler() - async def limoka(self, query: InlineQuery): - """[query] - Search modules inline""" - q = query.args or "" - if not q: - return { - "title": "Limoka Search", - "description": "Enter module name or keyword to search", - "thumb": "https://img.icons8.com/?size=100&id=NIWYFnJlcBfr&format=png&color=000000", - "message": "🔍 Limoka Inline Search\n\nEnter your query to search for Hikka modules:", - } - - searcher = Search(q.lower(), self.ix) - try: - results = searcher.search_module() - except Exception: - return { - "title": "Error", - "description": "Search error occurred", - "thumb": "https://img.icons8.com/?size=100&id=rUSWMuGVdxJj&format=png&color=000000", - "message": " Search error\nTry again later", - } - - if not results: - return { - "title": "No results found", - "description": "No modules match your query", - "thumb": "https://img.icons8.com/?size=100&id=olDsW0G3zz22&format=png&color=000000", - "message": " No results found\nTry different keywords", - } - - inline_results = [] - for path in results[:10]: - module_info = self.modules.get(path) - if not module_info: - continue - banner = await self._validate_url(module_info["meta"].get("banner")) - thumb = await self._validate_url( - module_info["meta"].get("pic", "https://img.icons8.com/?size=100&id=olDsW0G3zz22&format=png&color=000000") - ) - inline_results.append( - { - "title": module_info["name"], - "description": module_info["description"] or "No description available", - "thumb": thumb or "https://img.icons8.com/?size=100&id=olDsW0G3zz22&format=png&color=000000", - "photo": banner, - "message": self.strings["found"].format( - name=html.escape(module_info["name"]), - query=html.escape(q), - url=html.escape(self.config["limokaurl"]), - description=html.escape(module_info["description"] or self.strings["no_info"]), - username=html.escape(module_info["meta"].get("developer", "Unknown")), - commands="".join(self.generate_commands(module_info)), - module_path=path.replace("\\", "/"), - prefix=html.escape(self.get_prefix()), - ), - } - ) - return inline_results \ No newline at end of file + ) \ No newline at end of file