diff --git a/botdiscord/translate.py b/botdiscord/translate.py index dfd3131..532ad4d 100644 --- a/botdiscord/translate.py +++ b/botdiscord/translate.py @@ -49,28 +49,36 @@ REVERSE_MAPPING = {} FLAG_MAPPING = {} NAME_TO_CODE = {} +_translation_semaphore = asyncio.Semaphore(5) + +async def _translate_segment(session, url, segment, target_code): + if not re.search(r'[a-zA-Z0-9]', segment): + return segment + + payload = {"q": segment, "source": "auto", "target": target_code, "format": "html"} + + async with _translation_semaphore: + try: + async with session.post(url, json=payload, timeout=15) as resp: + if resp.status == 200: + data = await resp.json() + return data.get("translatedText", segment) + return segment + except Exception: + return segment + async def translate_text(text: str, target_lang: str) -> str: url = get_libretranslate_url() - if not url: - return text + if not url: return text target_code = NAME_TO_CODE.get(target_lang, target_lang) - - payload = { - "q": text, - "source": "auto", - "target": target_code, - "format": "html" - } + segments = re.split(r'([.?!]+\s*|\n+)', text) try: async with aiohttp.ClientSession() as session: - async with session.post(url, json=payload, timeout=30) as resp: - if resp.status == 200: - data = await resp.json() - return data.get("translatedText", text) - else: - return text + tasks = [_translate_segment(session, url, seg, target_code) for seg in segments] + translated_segments = await asyncio.gather(*tasks) + return "".join(translated_segments) except Exception: return text