From af366e70a2f043f8845d905be6dee4d25797edd3 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Wed, 19 Feb 2025 18:38:36 +0530 Subject: [PATCH 1/5] Ultroid 2025 --- .gitignore | 1 + Dockerfile | 2 +- assistant/__init__.py | 2 +- assistant/callbackstuffs.py | 2 +- assistant/games.py | 3 +- assistant/initial.py | 2 +- assistant/inlinestuff.py | 2 +- assistant/localization.py | 2 +- assistant/manager/__init__.py | 2 +- assistant/manager/_help.py | 2 +- assistant/manager/_on_adds.py | 2 +- assistant/manager/admins.py | 2 +- assistant/manager/afk.py | 2 +- assistant/manager/misc.py | 2 +- assistant/manager/stickermanager.py | 2 +- assistant/pmbot.py | 2 +- assistant/start.py | 2 +- assistant/ytdl.py | 2 +- install-termux | 2 +- plugins/__init__.py | 2 +- plugins/_chatactions.py | 2 +- plugins/_help.py | 2 +- plugins/_inline.py | 2 +- plugins/_ultroid.py | 2 +- plugins/_userlogs.py | 2 +- plugins/_wspr.py | 2 +- plugins/admintools.py | 2 +- plugins/afk.py | 2 +- plugins/aiwrapper.py | 396 ++++++++++++++++++++++++++++ plugins/antiflood.py | 2 +- plugins/asstcmd.py | 2 +- plugins/audiotools.py | 2 +- plugins/autoban.py | 2 +- plugins/autopic.py | 2 +- plugins/beautify.py | 2 +- plugins/blacklist.py | 2 +- plugins/bot.py | 2 +- plugins/broadcast.py | 2 +- plugins/button.py | 2 +- plugins/calculator.py | 2 +- plugins/channelhacks.py | 2 +- plugins/chatbot.py | 2 +- plugins/chats.py | 2 +- plugins/cleanaction.py | 2 +- plugins/compressor.py | 2 +- plugins/converter.py | 2 +- plugins/core.py | 2 +- plugins/database.py | 2 +- plugins/devtools.py | 2 +- plugins/downloadupload.py | 2 +- plugins/echo.py | 2 +- plugins/extra.py | 2 +- plugins/fakeaction.py | 2 +- plugins/fileshare.py | 2 +- plugins/filter.py | 2 +- plugins/fontgen.py | 2 +- plugins/forcesubscribe.py | 2 +- plugins/gdrive.py | 2 +- plugins/giftools.py | 2 +- plugins/glitch.py | 2 +- plugins/globaltools.py | 2 +- plugins/greetings.py | 2 +- plugins/imagetools.py | 2 +- plugins/locks.py | 2 +- plugins/logo.py | 2 +- plugins/mediatools.py | 2 +- plugins/mute.py | 2 +- plugins/nightmode.py | 2 +- plugins/notes.py | 2 +- plugins/nsfwfilter.py | 2 +- plugins/other.py | 2 +- plugins/pdftools.py | 2 +- plugins/pmpermit.py | 2 +- plugins/polls.py | 2 +- plugins/profanityfilter.py | 2 +- plugins/profile.py | 2 +- plugins/qrcode.py | 2 +- plugins/resize.py | 2 +- plugins/schedulemsg.py | 2 +- plugins/search.py | 2 +- plugins/snips.py | 2 +- plugins/specialtools.py | 2 +- plugins/stickertools.py | 2 +- plugins/sudo.py | 2 +- plugins/tag.py | 2 +- plugins/tools.py | 28 +- plugins/twitter.py | 203 ++++++++++++++ plugins/unsplash.py | 2 +- plugins/usage.py | 2 +- plugins/utilities.py | 2 +- plugins/variables.py | 4 +- plugins/vctools.py | 2 +- plugins/videotools.py | 2 +- plugins/warn.py | 2 +- plugins/webupload.py | 2 +- plugins/words.py | 2 +- plugins/writer.py | 2 +- plugins/youtube.py | 2 +- plugins/ziptools.py | 2 +- pyUltroid/__init__.py | 2 +- pyUltroid/__main__.py | 2 +- pyUltroid/_misc/__init__.py | 2 +- pyUltroid/_misc/_assistant.py | 2 +- pyUltroid/_misc/_decorators.py | 2 +- pyUltroid/_misc/_supporter.py | 2 +- pyUltroid/_misc/_wrappers.py | 2 +- pyUltroid/configs.py | 2 +- pyUltroid/dB/_core.py | 2 +- pyUltroid/dB/afk_db.py | 2 +- pyUltroid/dB/antiflood_db.py | 2 +- pyUltroid/dB/asstcmd_db.py | 2 +- pyUltroid/dB/blacklist_db.py | 2 +- pyUltroid/dB/botchat_db.py | 2 +- pyUltroid/dB/echo_db.py | 2 +- pyUltroid/dB/filestore_db.py | 2 +- pyUltroid/dB/filter_db.py | 2 +- pyUltroid/dB/forcesub_db.py | 2 +- pyUltroid/dB/gban_mute_db.py | 2 +- pyUltroid/dB/greetings_db.py | 2 +- pyUltroid/dB/mute_db.py | 2 +- pyUltroid/dB/notes_db.py | 2 +- pyUltroid/dB/nsfw_db.py | 2 +- pyUltroid/dB/snips_db.py | 2 +- pyUltroid/dB/vc_sudos.py | 2 +- pyUltroid/dB/warn_db.py | 2 +- pyUltroid/exceptions.py | 2 +- pyUltroid/fns/FastTelethon.py | 2 +- pyUltroid/fns/__init__.py | 2 +- pyUltroid/fns/admins.py | 2 +- pyUltroid/fns/gDrive.py | 2 +- pyUltroid/fns/helper.py | 2 +- pyUltroid/fns/info.py | 2 +- pyUltroid/fns/misc.py | 2 +- pyUltroid/fns/tools.py | 2 +- pyUltroid/fns/ytdl.py | 2 +- pyUltroid/loader.py | 2 +- pyUltroid/startup/BaseClient.py | 2 +- pyUltroid/startup/__init__.py | 2 +- pyUltroid/startup/_database.py | 2 +- pyUltroid/startup/_extra.py | 2 +- pyUltroid/startup/connections.py | 2 +- pyUltroid/startup/funcs.py | 2 +- pyUltroid/startup/loader.py | 2 +- pyUltroid/startup/utils.py | 2 +- pyUltroid/version.py | 4 +- resources/session/session.sh | 2 +- resources/session/ssgen.py | 2 +- resources/startup/_termux.py | 2 +- resources/startup/locals.py | 2 +- sessiongen | 2 +- startup | 2 +- strings/strings/jp.yml | 2 +- 152 files changed, 752 insertions(+), 177 deletions(-) create mode 100644 plugins/aiwrapper.py create mode 100644 plugins/twitter.py diff --git a/.gitignore b/.gitignore index 794eba8b5a..ce5d8ae1e0 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ target/npmlist.json package-lock.json ultroid.json resources/extras/thumbnail.jpg +resources/auth/ # Directories addons/ diff --git a/Dockerfile b/Dockerfile index ada30cbf09..813c1cb202 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in . diff --git a/assistant/__init__.py b/assistant/__init__.py index cba67e1dc9..2a2a775b4d 100644 --- a/assistant/__init__.py +++ b/assistant/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/callbackstuffs.py b/assistant/callbackstuffs.py index 3cdd332044..0495c8246b 100644 --- a/assistant/callbackstuffs.py +++ b/assistant/callbackstuffs.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/games.py b/assistant/games.py index 85ea88ebf6..fef75c0cba 100644 --- a/assistant/games.py +++ b/assistant/games.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2024 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in @@ -15,6 +15,7 @@ import asyncio import re +from random import choice, shuffle from akipy.async_akipy import Akinator, akipyLOGS from telethon.errors.rpcerrorlist import BotMethodInvalidError diff --git a/assistant/initial.py b/assistant/initial.py index eb57a0308c..c126bbcf19 100644 --- a/assistant/initial.py +++ b/assistant/initial.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/inlinestuff.py b/assistant/inlinestuff.py index 16a45f522b..ae097f119a 100644 --- a/assistant/inlinestuff.py +++ b/assistant/inlinestuff.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/localization.py b/assistant/localization.py index 0fc8538cdb..9f1c18ab5b 100644 --- a/assistant/localization.py +++ b/assistant/localization.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/__init__.py b/assistant/manager/__init__.py index 69b49061e9..ca0dfd62ba 100644 --- a/assistant/manager/__init__.py +++ b/assistant/manager/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/_help.py b/assistant/manager/_help.py index f071301e91..bd3fe06d7d 100644 --- a/assistant/manager/_help.py +++ b/assistant/manager/_help.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/_on_adds.py b/assistant/manager/_on_adds.py index c54cf14442..d788f37ae9 100644 --- a/assistant/manager/_on_adds.py +++ b/assistant/manager/_on_adds.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/admins.py b/assistant/manager/admins.py index 168e14e680..d8b896543c 100644 --- a/assistant/manager/admins.py +++ b/assistant/manager/admins.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/afk.py b/assistant/manager/afk.py index ceb45a3fd2..505a81d958 100644 --- a/assistant/manager/afk.py +++ b/assistant/manager/afk.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/misc.py b/assistant/manager/misc.py index 093c9c7438..0133df8bfd 100644 --- a/assistant/manager/misc.py +++ b/assistant/manager/misc.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/manager/stickermanager.py b/assistant/manager/stickermanager.py index 18529bb34d..1d8e5fe26a 100644 --- a/assistant/manager/stickermanager.py +++ b/assistant/manager/stickermanager.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/pmbot.py b/assistant/pmbot.py index 316f8eae6d..961c2956ec 100644 --- a/assistant/pmbot.py +++ b/assistant/pmbot.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/start.py b/assistant/start.py index c8dcb3c700..3dd246dc35 100644 --- a/assistant/start.py +++ b/assistant/start.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/assistant/ytdl.py b/assistant/ytdl.py index 9a65b37679..1099690996 100644 --- a/assistant/ytdl.py +++ b/assistant/ytdl.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/install-termux b/install-termux index 7817ddc69e..ee02e5b295 100644 --- a/install-termux +++ b/install-termux @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in . diff --git a/plugins/__init__.py b/plugins/__init__.py index 9b98484c1e..173db5398a 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/_chatactions.py b/plugins/_chatactions.py index 8f1a9d3baa..3ae1c90111 100644 --- a/plugins/_chatactions.py +++ b/plugins/_chatactions.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/_help.py b/plugins/_help.py index b36101e7f5..1f7d4e6e52 100644 --- a/plugins/_help.py +++ b/plugins/_help.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/_inline.py b/plugins/_inline.py index 99e9aefd42..93cc81e4a7 100644 --- a/plugins/_inline.py +++ b/plugins/_inline.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/_ultroid.py b/plugins/_ultroid.py index b2a3e2a6fb..3d7261a3e7 100644 --- a/plugins/_ultroid.py +++ b/plugins/_ultroid.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/_userlogs.py b/plugins/_userlogs.py index 0696ce5b2e..bea7c63426 100644 --- a/plugins/_userlogs.py +++ b/plugins/_userlogs.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/_wspr.py b/plugins/_wspr.py index f46def7dad..462a34e696 100644 --- a/plugins/_wspr.py +++ b/plugins/_wspr.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/admintools.py b/plugins/admintools.py index 0d402ff2d6..557597377f 100644 --- a/plugins/admintools.py +++ b/plugins/admintools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/afk.py b/plugins/afk.py index 830136a449..67f5d08ede 100644 --- a/plugins/afk.py +++ b/plugins/afk.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/aiwrapper.py b/plugins/aiwrapper.py new file mode 100644 index 0000000000..c5fa34cf76 --- /dev/null +++ b/plugins/aiwrapper.py @@ -0,0 +1,396 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +• `{i}gemini ` + Get response from Google Gemini. + +• `{i}antr ` + Get response from Anthropic Claude. + +• `{i}gpt ` + Get response from OpenAI GPT. + +• `{i}deepseek ` + Get response from DeepSeek AI. + +Set custom models using: + • OPENAI_MODEL + • ANTHROPIC_MODEL + • GEMINI_MODEL + • DEEPSEEK_MODEL +""" + +import json +from . import LOGS, eor, get_string, udB, ultroid_cmd, async_searcher +import aiohttp +import asyncio + + +ENDPOINTS = { + "gpt": "https://api.openai.com/v1/chat/completions", + "antr": "https://api.anthropic.com/v1/messages", + "gemini": "https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent", + "deepseek": "https://api.deepseek.com/chat/completions" +} + +DEFAULT_MODELS = { + "gpt": "gpt-3.5-turbo", + "antr": "claude-3-opus-20240229", + "gemini": "gemini-pro", + "deepseek": "deepseek-chat" +} + + +def get_model(provider): + """Get model name from database or use default""" + model_keys = { + "gpt": "OPENAI_MODEL", + "antr": "ANTHROPIC_MODEL", + "gemini": "GEMINI_MODEL", + "deepseek": "DEEPSEEK_MODEL" + } + return udB.get_key(model_keys[provider]) or DEFAULT_MODELS[provider] + + +async def stream_response(msg, text): + """Stream response by editing message""" + current = "" + # Split into chunks of ~100 characters at word boundaries + words = text.split() + chunks = [] + current_chunk = [] + + for word in words: + current_chunk.append(word) + if len(" ".join(current_chunk)) > 100: + chunks.append(" ".join(current_chunk[:-1])) + current_chunk = [word] + if current_chunk: + chunks.append(" ".join(current_chunk)) + + for chunk in chunks: + current += chunk + " " + try: + await msg.edit(current) + except Exception: + pass + await asyncio.sleep(0.5) + return current + + +async def get_ai_response(provider, prompt, api_key, stream=False): + """Get response from AI provider""" + try: + headers = {"Content-Type": "application/json"} + model = get_model(provider) + + if provider == "gpt": + headers["Authorization"] = f"Bearer {api_key}" + data = { + "model": model, + "messages": [{"role": "user", "content": prompt}], + "stream": stream + } + if not stream: + response = await async_searcher( + ENDPOINTS[provider], + headers=headers, + post=True, + json=data, + re_json=True + ) + yield response["choices"][0]["message"]["content"] + return + + async with aiohttp.ClientSession() as session: + async with session.post( + ENDPOINTS[provider], + headers=headers, + json=data + ) as resp: + async for line in resp.content: + if line: + try: + json_line = json.loads(line.decode('utf-8').strip().strip('data:').strip()) + if 'choices' in json_line and json_line['choices']: + content = json_line['choices'][0].get('delta', {}).get('content', '') + if content: + yield content + except Exception: + continue + + elif provider == "antr": + headers["x-api-key"] = api_key + headers["anthropic-version"] = "2023-06-01" + data = { + "model": model, + "messages": [{"role": "user", "content": prompt}], + "stream": stream + } + if not stream: + response = await async_searcher( + ENDPOINTS[provider], + headers=headers, + post=True, + json=data, + re_json=True + ) + yield response["content"][0]["text"] + return + + async with aiohttp.ClientSession() as session: + async with session.post( + ENDPOINTS[provider], + headers=headers, + json=data + ) as resp: + async for line in resp.content: + if line: + try: + json_line = json.loads(line.decode('utf-8').strip()) + if 'content' in json_line: + content = json_line['content'][0]['text'] + if content: + yield content + except Exception: + continue + + elif provider == "gemini": + params = {"key": api_key} + data = { + "contents": [{ + "parts": [{"text": prompt}] + }] + } + response = await async_searcher( + ENDPOINTS[provider], + params=params, + headers=headers, + post=True, + json=data, + re_json=True + ) + text = response["candidates"][0]["content"]["parts"][0]["text"] + if not stream: + yield text + return + + # Simulate streaming by yielding chunks + words = text.split() + buffer = [] + for word in words: + buffer.append(word) + if len(' '.join(buffer)) > 20: # Adjust chunk size as needed + yield ' '.join(buffer) + ' ' + buffer = [] + if buffer: + yield ' '.join(buffer) + + elif provider == "deepseek": + headers["Authorization"] = f"Bearer {api_key}" + data = { + "model": model, + "messages": [{"role": "user", "content": prompt}], + "stream": stream + } + if not stream: + response = await async_searcher( + ENDPOINTS[provider], + headers=headers, + post=True, + json=data, + re_json=True + ) + yield response["choices"][0]["message"]["content"] + return + + async with aiohttp.ClientSession() as session: + async with session.post( + ENDPOINTS[provider], + headers=headers, + json=data + ) as resp: + async for line in resp.content: + if line: + try: + json_line = json.loads(line.decode('utf-8').strip()) + if 'choices' in json_line and json_line['choices']: + content = json_line['choices'][0].get('delta', {}).get('content', '') + if content: + yield content + except Exception: + continue + + except Exception as e: + LOGS.exception(e) + yield f"Error: {str(e)}" + + +@ultroid_cmd(pattern="gemini( (.*)|$)") +async def gemini_ai(event): + """Use Google Gemini""" + prompt = event.pattern_match.group(1).strip() + if not prompt: + return await event.eor("❌ Please provide a prompt!") + + api_key = udB.get_key("GEMINI_API_KEY") + if not api_key: + return await event.eor("⚠️ Please set Gemini API key using `setdb GEMINI_API_KEY your_api_key`") + + msg = await event.eor("🤔 Thinking...") + model = get_model("gemini") + + header = ( + "🤖 **Google Gemini**\n" + f"**Model:** `{model}`\n" + "➖➖➖➖➖➖➖➖➖➖\n\n" + f"**🔍 Prompt:**\n{prompt}\n\n" + "**💡 Response:**\n" + ) + + if event.client.me.bot: + await msg.edit(header) + response = "" + async for chunk in get_ai_response("gemini", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(header + response) + except Exception: + pass + else: + response = "" + async for chunk in get_ai_response("gemini", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(header + response) + except Exception: + pass + +@ultroid_cmd(pattern="antr( (.*)|$)") +async def anthropic_ai(event): + """Use Anthropic Claude""" + prompt = event.pattern_match.group(1).strip() + if not prompt: + return await event.eor("❌ Please provide a prompt!") + + api_key = udB.get_key("ANTHROPIC_KEY") + if not api_key: + return await event.eor("⚠️ Please set Anthropic API key using `setdb ANTHROPIC_KEY your_api_key`") + + msg = await event.eor("🤔 Thinking...") + model = get_model("antr") + + formatted_response = ( + "🧠 **Anthropic Claude**\n" + f"**Model:** `{model}`\n" + "➖➖➖➖➖➖➖➖➖➖\n\n" + f"**🔍 Prompt:**\n{prompt}\n\n" + f"**💡 Response:**\n" + ) + + if event.client.me.bot: + await msg.edit(formatted_response) + response = "" + async for chunk in get_ai_response("antr", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(formatted_response + response) + except Exception: + pass + else: + response = "" + async for chunk in get_ai_response("antr", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(formatted_response + response) + except Exception: + pass + +@ultroid_cmd(pattern="gpt( (.*)|$)") +async def openai_ai(event): + """Use OpenAI GPT""" + prompt = event.pattern_match.group(1).strip() + if not prompt: + return await event.eor("❌ Please provide a prompt!") + + api_key = udB.get_key("OPENAI_API_KEY") + if not api_key: + return await event.eor("⚠️ Please set GPT API key using `setdb OPENAI_API_KEY your_api_key`") + + msg = await event.eor("🤔 Thinking...") + model = get_model("gpt") + + header = ( + "🌟 **OpenAI GPT**\n" + f"**Model:** `{model}`\n" + "➖➖➖➖➖➖➖➖➖➖\n\n" + f"**🔍 Prompt:**\n{prompt}\n\n" + "**💡 Response:**\n" + ) + + if event.client.me.bot: + await msg.edit(header) + response = "" + async for chunk in get_ai_response("gpt", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(header + response) + except Exception: + pass + else: + response ="" + async for chunk in get_ai_response("gpt", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(header + response) + except Exception: + pass + +@ultroid_cmd(pattern="deepseek( (.*)|$)") +async def deepseek_ai(event): + """Use DeepSeek AI""" + prompt = event.pattern_match.group(1).strip() + if not prompt: + return await event.eor("❌ Please provide a prompt!") + + api_key = udB.get_key("DEEPSEEK_API_KEY") + if not api_key: + return await event.eor("⚠️ Please set DeepSeek API key using `setdb DEEPSEEK_API_KEY your_api_key`") + + msg = await event.eor("🤔 Thinking...") + model = get_model("deepseek") + + formatted_response = ( + "🤖 **DeepSeek AI**\n" + f"**Model:** `{model}`\n" + "➖➖➖➖➖➖➖➖➖➖\n\n" + f"**🔍 Prompt:**\n{prompt}\n\n" + f"**💡 Response:**\n" + ) + + if event.client.me.bot: + await msg.edit(formatted_response) + response = "" + async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True): + response += chunk + try: + await msg.edit(formatted_response + response) + except Exception: + pass + else: + response = "" + async for chunk in get_ai_response("deepseek", prompt, api_key, stream=True): + response += chunk + + try: + await msg.edit(formatted_response + response) + except Exception: + pass + diff --git a/plugins/antiflood.py b/plugins/antiflood.py index 82225c1695..3eb9d19dc0 100644 --- a/plugins/antiflood.py +++ b/plugins/antiflood.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/asstcmd.py b/plugins/asstcmd.py index b88446ef7d..b84c717bc9 100644 --- a/plugins/asstcmd.py +++ b/plugins/asstcmd.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/audiotools.py b/plugins/audiotools.py index f8c0b52558..2ae4e99212 100644 --- a/plugins/audiotools.py +++ b/plugins/audiotools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/autoban.py b/plugins/autoban.py index 597323213b..ab002ba64a 100644 --- a/plugins/autoban.py +++ b/plugins/autoban.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/autopic.py b/plugins/autopic.py index f6e5127662..e206a98094 100644 --- a/plugins/autopic.py +++ b/plugins/autopic.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/beautify.py b/plugins/beautify.py index 903ab13197..3ee92ff2c4 100644 --- a/plugins/beautify.py +++ b/plugins/beautify.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/blacklist.py b/plugins/blacklist.py index 78f2d42afe..e621a37e8f 100644 --- a/plugins/blacklist.py +++ b/plugins/blacklist.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/bot.py b/plugins/bot.py index f8d5367e08..bd3146d289 100644 --- a/plugins/bot.py +++ b/plugins/bot.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/broadcast.py b/plugins/broadcast.py index f8aedf2f08..4eb1d36721 100644 --- a/plugins/broadcast.py +++ b/plugins/broadcast.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/button.py b/plugins/button.py index b3d616d709..ef61d2990f 100644 --- a/plugins/button.py +++ b/plugins/button.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/calculator.py b/plugins/calculator.py index 28f2bae144..3514c2963e 100644 --- a/plugins/calculator.py +++ b/plugins/calculator.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/channelhacks.py b/plugins/channelhacks.py index d333249a0f..561517a435 100644 --- a/plugins/channelhacks.py +++ b/plugins/channelhacks.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/chatbot.py b/plugins/chatbot.py index f050be1955..00c96e03e5 100644 --- a/plugins/chatbot.py +++ b/plugins/chatbot.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/chats.py b/plugins/chats.py index 2ef171b1de..0651cd7d72 100644 --- a/plugins/chats.py +++ b/plugins/chats.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/cleanaction.py b/plugins/cleanaction.py index ebc65752f3..361e094762 100644 --- a/plugins/cleanaction.py +++ b/plugins/cleanaction.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/compressor.py b/plugins/compressor.py index 4161a9f4fa..abd6d157e3 100644 --- a/plugins/compressor.py +++ b/plugins/compressor.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/converter.py b/plugins/converter.py index 0ed3e36037..b68dd27361 100644 --- a/plugins/converter.py +++ b/plugins/converter.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/core.py b/plugins/core.py index 6664fa5800..b93f659a2f 100644 --- a/plugins/core.py +++ b/plugins/core.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/database.py b/plugins/database.py index 8c50ea2a3a..0e6c79e33a 100644 --- a/plugins/database.py +++ b/plugins/database.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/devtools.py b/plugins/devtools.py index bc44b10cfe..fb3f72b4bc 100644 --- a/plugins/devtools.py +++ b/plugins/devtools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/downloadupload.py b/plugins/downloadupload.py index 003da9fad7..d5f5e304f8 100644 --- a/plugins/downloadupload.py +++ b/plugins/downloadupload.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/echo.py b/plugins/echo.py index 03c4d0e860..bda8fff45e 100644 --- a/plugins/echo.py +++ b/plugins/echo.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/extra.py b/plugins/extra.py index f9abda572a..7fa9ac8177 100644 --- a/plugins/extra.py +++ b/plugins/extra.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/fakeaction.py b/plugins/fakeaction.py index 0f4b25492e..7e88941959 100644 --- a/plugins/fakeaction.py +++ b/plugins/fakeaction.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/fileshare.py b/plugins/fileshare.py index 430e8cd5be..62497d5813 100644 --- a/plugins/fileshare.py +++ b/plugins/fileshare.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/filter.py b/plugins/filter.py index 84ab5931ef..95294b01ad 100644 --- a/plugins/filter.py +++ b/plugins/filter.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/fontgen.py b/plugins/fontgen.py index 1cce172bef..d686c75f1f 100644 --- a/plugins/fontgen.py +++ b/plugins/fontgen.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/forcesubscribe.py b/plugins/forcesubscribe.py index 9804b28687..bc0a01f85f 100644 --- a/plugins/forcesubscribe.py +++ b/plugins/forcesubscribe.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/gdrive.py b/plugins/gdrive.py index fbadce6768..bafffbd293 100644 --- a/plugins/gdrive.py +++ b/plugins/gdrive.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/giftools.py b/plugins/giftools.py index 38fdb1f79e..5c8d0d2283 100644 --- a/plugins/giftools.py +++ b/plugins/giftools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/glitch.py b/plugins/glitch.py index a612e959e5..e4ee4df41b 100644 --- a/plugins/glitch.py +++ b/plugins/glitch.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/globaltools.py b/plugins/globaltools.py index 087db364c4..a81744abd9 100644 --- a/plugins/globaltools.py +++ b/plugins/globaltools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/greetings.py b/plugins/greetings.py index 6254a6be53..7f126e1a51 100644 --- a/plugins/greetings.py +++ b/plugins/greetings.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/imagetools.py b/plugins/imagetools.py index ef633427e4..a0757bcff7 100644 --- a/plugins/imagetools.py +++ b/plugins/imagetools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/locks.py b/plugins/locks.py index 849c242164..edbdc6b48d 100644 --- a/plugins/locks.py +++ b/plugins/locks.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/logo.py b/plugins/logo.py index 92531bb1bf..551104f6d5 100644 --- a/plugins/logo.py +++ b/plugins/logo.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/mediatools.py b/plugins/mediatools.py index 91773026da..fd0ab43b48 100644 --- a/plugins/mediatools.py +++ b/plugins/mediatools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/mute.py b/plugins/mute.py index 2939908fa0..cb7c3d6937 100644 --- a/plugins/mute.py +++ b/plugins/mute.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/nightmode.py b/plugins/nightmode.py index 5719cd7dc1..4a0edd9a8f 100644 --- a/plugins/nightmode.py +++ b/plugins/nightmode.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/notes.py b/plugins/notes.py index 38f353fe83..5553782f76 100644 --- a/plugins/notes.py +++ b/plugins/notes.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/nsfwfilter.py b/plugins/nsfwfilter.py index 3bfe62494c..ae40d5113e 100644 --- a/plugins/nsfwfilter.py +++ b/plugins/nsfwfilter.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/other.py b/plugins/other.py index b781162941..affa75b67c 100644 --- a/plugins/other.py +++ b/plugins/other.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/pdftools.py b/plugins/pdftools.py index e19cbc7a17..6be4c3319d 100644 --- a/plugins/pdftools.py +++ b/plugins/pdftools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/pmpermit.py b/plugins/pmpermit.py index caed12a934..0d0cbf7a61 100644 --- a/plugins/pmpermit.py +++ b/plugins/pmpermit.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/polls.py b/plugins/polls.py index 2b875329b5..2fb71e5dc8 100644 --- a/plugins/polls.py +++ b/plugins/polls.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/profanityfilter.py b/plugins/profanityfilter.py index d7562a0ebc..ccc96bbf56 100644 --- a/plugins/profanityfilter.py +++ b/plugins/profanityfilter.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/profile.py b/plugins/profile.py index 90b85e5e8b..32f9207023 100644 --- a/plugins/profile.py +++ b/plugins/profile.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/qrcode.py b/plugins/qrcode.py index 2e7d64ba90..f31b337744 100644 --- a/plugins/qrcode.py +++ b/plugins/qrcode.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/resize.py b/plugins/resize.py index f70fe31001..e346a75b69 100644 --- a/plugins/resize.py +++ b/plugins/resize.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/schedulemsg.py b/plugins/schedulemsg.py index b531f02db8..5a6f0dde22 100644 --- a/plugins/schedulemsg.py +++ b/plugins/schedulemsg.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/search.py b/plugins/search.py index 3224f9271c..b80e34f044 100644 --- a/plugins/search.py +++ b/plugins/search.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/snips.py b/plugins/snips.py index eba0d2df8f..6b11f27ec1 100644 --- a/plugins/snips.py +++ b/plugins/snips.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/specialtools.py b/plugins/specialtools.py index 45bd03bb94..6971c58fff 100644 --- a/plugins/specialtools.py +++ b/plugins/specialtools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/stickertools.py b/plugins/stickertools.py index 9191aa90e6..96e92c670f 100644 --- a/plugins/stickertools.py +++ b/plugins/stickertools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/sudo.py b/plugins/sudo.py index 523bbb9884..6d092e318c 100644 --- a/plugins/sudo.py +++ b/plugins/sudo.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/tag.py b/plugins/tag.py index 8d1c9eba79..141e5feac1 100644 --- a/plugins/tag.py +++ b/plugins/tag.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/tools.py b/plugins/tools.py index a1f3628236..7da413a66f 100644 --- a/plugins/tools.py +++ b/plugins/tools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in @@ -32,9 +32,6 @@ • `{i}webshot ` Get a screenshot of the webpage. - -• `{i}shorturl ` - shorten any url... """ import glob import io @@ -436,26 +433,3 @@ async def webss(event): os.remove(pic) await xx.delete() - -@ultroid_cmd(pattern="shorturl") -async def magic(event): - try: - match = event.text.split(maxsplit=1)[1].strip() - except IndexError: - return await event.eor("`Provide url to turn into tiny...`") - data = { - "url": match.split()[0], - "id": match[1] if len(match) > 1 else secrets.token_urlsafe(6), - } - data = await async_searcher( - "https://tiny.ultroid.tech/api/new", - data=data, - post=True, - re_json=True, - ) - response = data.get("response", {}) - if not response.get("status"): - return await event.eor(f'**ERROR :** `{response["message"]}`') - await event.eor( - f"• **Ultroid Tiny**\n• Given Url : {url}\n• Shorten Url : {data['response']['tinyUrl']}" - ) diff --git a/plugins/twitter.py b/plugins/twitter.py new file mode 100644 index 0000000000..81dbe534a4 --- /dev/null +++ b/plugins/twitter.py @@ -0,0 +1,203 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2025 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +• `{i}tw ` + Tweet the text. + +• `{i}twr ` + Get tweet details with reply/quote/comment count. + +• `{i}twuser ` + Get user details of the Twitter account. + +• `{i}twl ` + Upload the tweet media to telegram. + +""" + +import os +from twikit import Client +from . import LOGS, eor, get_string, udB, ultroid_cmd + +# Store client globally +twitter_client = None + +# Get path to cookies file +COOKIES_FILE = "resources/auth/twitter_cookies.json" + +async def get_client(): + global twitter_client + if twitter_client: + return twitter_client + + if not all(udB.get_key(key) for key in ["TWITTER_USERNAME", "TWITTER_EMAIL", "TWITTER_PASSWORD"]): + raise Exception("Set TWITTER_USERNAME, TWITTER_EMAIL and TWITTER_PASSWORD in vars first!") + + # Create auth directory if it doesn't exist + os.makedirs(os.path.dirname(COOKIES_FILE), exist_ok=True) + + client = Client() + await client.login( + auth_info_1=udB.get_key("TWITTER_USERNAME"), + auth_info_2=udB.get_key("TWITTER_EMAIL"), + password=udB.get_key("TWITTER_PASSWORD"), + cookies_file=COOKIES_FILE + ) + twitter_client = client + return client + + + +@ultroid_cmd(pattern="tw( (.*)|$)") +async def tweet_cmd(event): + """Post a tweet""" + text = event.pattern_match.group(1).strip() + if not text: + return await event.eor("🚫 `Give some text to tweet!`") + + msg = await event.eor("🕊 `Tweeting...`") + try: + client = await get_client() + tweet = await client.create_tweet(text=text) + await msg.edit(f"✨ **Successfully Posted!**\n\n🔗 https://x.com/{tweet.user.screen_name}/status/{tweet.id}") + except Exception as e: + await msg.edit(f"❌ **Error:**\n`{str(e)}`") + + +@ultroid_cmd(pattern="twdetail( (.*)|$)") +async def twitter_details(event): + """Get tweet details""" + match = event.pattern_match.group(1).strip() + if not match: + return await event.eor("🚫 `Give tweet ID/link to get details!`") + + msg = await event.eor("🔍 `Getting tweet details...`") + try: + client = await get_client() + if "twitter.com" in match or "x.com" in match: + tweet_id = match.split("/")[-1].split("?")[0] + else: + tweet_id = match + + tweet = await client.get_tweet_by_id(tweet_id) + text = "🐦 **Tweet Details**\n\n" + text += f"📝 **Content:** `{tweet.text}`\n\n" + if hasattr(tweet, "metrics"): + text += f"❤️ **Likes:** `{tweet.metrics.likes}`\n" + text += f"🔄 **Retweets:** `{tweet.metrics.retweets}`\n" + text += f"💬 **Replies:** `{tweet.metrics.replies}`\n" + text += f"👁 **Views:** `{tweet.metrics.views}`\n" + + await msg.edit(text) + except Exception as e: + await msg.edit(f"❌ **Error:**\n`{str(e)}`") + + +@ultroid_cmd(pattern="twuser( (.*)|$)") +async def twitter_user(event): + """Get user details""" + match = event.pattern_match.group(1).strip() + if not match: + return await event.eor("🚫 `Give username to get details!`") + + msg = await event.eor("🔍 `Getting user details...`") + try: + client = await get_client() + user = await client.get_user_by_screen_name(match) + text = "👤 **Twitter User Details**\n\n" + text += f"📛 **Name:** `{user.name}`\n" + text += f"🔖 **Username:** `@{user.screen_name}`\n" + text += f"📝 **Bio:** `{user.description}`\n\n" + text += f"👥 **Followers:** `{user.followers_count}`\n" + text += f"👣 **Following:** `{user.following_count}`\n" + text += f"🐦 **Total Tweets:** `{user.statuses_count}`\n" + text += f"📍 **Location:** `{user.location or 'Not Set'}`\n" + text += f"✅ **Verified:** `{user.verified}`\n" + + if user.profile_image_url: + image_url = user.profile_image_url.replace("_normal.", ".") + await event.client.send_file( + event.chat_id, + file=image_url, + caption=text, + force_document=False + ) + await msg.delete() + else: + await msg.edit(text) + + except Exception as e: + await msg.edit(f"❌ **Error:**\n`{str(e)}`") + + +@ultroid_cmd(pattern="twl( (.*)|$)") +async def twitter_media(event): + """Download tweet media""" + match = event.pattern_match.group(1).strip() + if not match: + return await event.eor("🚫 `Give tweet link to download media!`") + + msg = await event.eor("📥 `Downloading media...`") + try: + client = await get_client() + if "twitter.com" in match or "x.com" in match: + tweet_id = match.split("/")[-1].split("?")[0] + else: + tweet_id = match + + tweet = await client.get_tweet_by_id(tweet_id) + + if not hasattr(tweet, "media"): + return await msg.edit("😕 `No media found in tweet!`") + + # Prepare caption with tweet text + caption = f"🐦 **Tweet by @{tweet.user.screen_name}**\n\n" + caption += f"{tweet.text}\n\n" + if hasattr(tweet, "metrics"): + caption += f"❤️ `{tweet.metrics.likes}` 🔄 `{tweet.metrics.retweets}` 💬 `{tweet.metrics.replies}`" + + media_count = 0 + for media in tweet.media: + if media.type == "photo": + await event.client.send_file( + event.chat_id, + media.url, + caption=caption if media_count == 0 else None # Only add caption to first media + ) + media_count += 1 + elif media.type == "video": + if hasattr(media, "video_info") and isinstance(media.video_info, dict): + variants = media.video_info.get("variants", []) + mp4_variants = [ + v for v in variants + if v.get("content_type") == "video/mp4" and "bitrate" in v + ] + if mp4_variants: + best_video = max(mp4_variants, key=lambda x: x["bitrate"]) + video_caption = caption if media_count == 0 else "" # Only add tweet text to first media + if video_caption: + video_caption += f"\n🎥 Video Quality: {best_video['bitrate']/1000:.0f}kbps" + else: + video_caption = f"🎥 Video Quality: {best_video['bitrate']/1000:.0f}kbps" + + await event.client.send_file( + event.chat_id, + best_video["url"], + caption=video_caption + ) + media_count += 1 + + if media_count > 0: + await msg.edit(f"✅ Successfully downloaded {media_count} media items!") + await msg.delete() + else: + await msg.edit("😕 `No media could be downloaded!`") + except Exception as e: + await msg.edit(f"❌ **Error:**\n`{str(e)}`") diff --git a/plugins/unsplash.py b/plugins/unsplash.py index b3974965cc..4393009fe7 100644 --- a/plugins/unsplash.py +++ b/plugins/unsplash.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/usage.py b/plugins/usage.py index 86a5eac162..32d6a0445d 100644 --- a/plugins/usage.py +++ b/plugins/usage.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/utilities.py b/plugins/utilities.py index fd26be0ca8..4d34ebc5d7 100644 --- a/plugins/utilities.py +++ b/plugins/utilities.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/variables.py b/plugins/variables.py index 79d79ea0f6..5c4bb79090 100644 --- a/plugins/variables.py +++ b/plugins/variables.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in @@ -22,7 +22,7 @@ import os -from . import eor, get_string, udB, ultroid_cmd +from . import eor, get_string, udB, ultroid_cmd, HNDLR @ultroid_cmd(pattern="get($| (.*))", fullsudo=True) diff --git a/plugins/vctools.py b/plugins/vctools.py index 432af0bb0c..f7bd69d482 100644 --- a/plugins/vctools.py +++ b/plugins/vctools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/videotools.py b/plugins/videotools.py index 508a141a08..b25081bd88 100644 --- a/plugins/videotools.py +++ b/plugins/videotools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/warn.py b/plugins/warn.py index b6ffcc108f..dd50014171 100644 --- a/plugins/warn.py +++ b/plugins/warn.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/webupload.py b/plugins/webupload.py index 2a6c5f57ee..cfb040d1ae 100644 --- a/plugins/webupload.py +++ b/plugins/webupload.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/words.py b/plugins/words.py index 66f680d7d6..22e5f8d73f 100644 --- a/plugins/words.py +++ b/plugins/words.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/writer.py b/plugins/writer.py index e5da48d884..4e9f812ffd 100644 --- a/plugins/writer.py +++ b/plugins/writer.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/youtube.py b/plugins/youtube.py index c0eb34f796..fc129c0d48 100644 --- a/plugins/youtube.py +++ b/plugins/youtube.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/plugins/ziptools.py b/plugins/ziptools.py index 95e400170a..c7006dad7f 100644 --- a/plugins/ziptools.py +++ b/plugins/ziptools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/__init__.py b/pyUltroid/__init__.py index 36c727889a..c20629b7f1 100644 --- a/pyUltroid/__init__.py +++ b/pyUltroid/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/__main__.py b/pyUltroid/__main__.py index 70100e01d0..c4d4375cad 100644 --- a/pyUltroid/__main__.py +++ b/pyUltroid/__main__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/_misc/__init__.py b/pyUltroid/_misc/__init__.py index 0efdf629cc..e144459931 100644 --- a/pyUltroid/_misc/__init__.py +++ b/pyUltroid/_misc/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/_misc/_assistant.py b/pyUltroid/_misc/_assistant.py index 1ec817671f..bdc02b21f9 100644 --- a/pyUltroid/_misc/_assistant.py +++ b/pyUltroid/_misc/_assistant.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/_misc/_decorators.py b/pyUltroid/_misc/_decorators.py index 4422097d47..94cea82976 100644 --- a/pyUltroid/_misc/_decorators.py +++ b/pyUltroid/_misc/_decorators.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/_misc/_supporter.py b/pyUltroid/_misc/_supporter.py index f098d76dc5..1be92f7f29 100644 --- a/pyUltroid/_misc/_supporter.py +++ b/pyUltroid/_misc/_supporter.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/_misc/_wrappers.py b/pyUltroid/_misc/_wrappers.py index a1475fdf71..6625ec4d84 100644 --- a/pyUltroid/_misc/_wrappers.py +++ b/pyUltroid/_misc/_wrappers.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/configs.py b/pyUltroid/configs.py index 6ecf115606..ddf6f05a71 100644 --- a/pyUltroid/configs.py +++ b/pyUltroid/configs.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/_core.py b/pyUltroid/dB/_core.py index e330e6e3f8..de1c3cdfc2 100644 --- a/pyUltroid/dB/_core.py +++ b/pyUltroid/dB/_core.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/afk_db.py b/pyUltroid/dB/afk_db.py index 54c9c67242..e6da109fd9 100644 --- a/pyUltroid/dB/afk_db.py +++ b/pyUltroid/dB/afk_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/antiflood_db.py b/pyUltroid/dB/antiflood_db.py index 5cdc7ee112..7c68d25f2a 100644 --- a/pyUltroid/dB/antiflood_db.py +++ b/pyUltroid/dB/antiflood_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/asstcmd_db.py b/pyUltroid/dB/asstcmd_db.py index 421eac857f..9faa4f9cd2 100644 --- a/pyUltroid/dB/asstcmd_db.py +++ b/pyUltroid/dB/asstcmd_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/blacklist_db.py b/pyUltroid/dB/blacklist_db.py index c0d0e5bbdd..f7d9d24098 100644 --- a/pyUltroid/dB/blacklist_db.py +++ b/pyUltroid/dB/blacklist_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/botchat_db.py b/pyUltroid/dB/botchat_db.py index 7b70b574b6..56d7c6f367 100644 --- a/pyUltroid/dB/botchat_db.py +++ b/pyUltroid/dB/botchat_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/echo_db.py b/pyUltroid/dB/echo_db.py index e83e38c5e2..638a64ae49 100644 --- a/pyUltroid/dB/echo_db.py +++ b/pyUltroid/dB/echo_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/filestore_db.py b/pyUltroid/dB/filestore_db.py index ed3db8a46b..90ed5de099 100644 --- a/pyUltroid/dB/filestore_db.py +++ b/pyUltroid/dB/filestore_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/filter_db.py b/pyUltroid/dB/filter_db.py index a76a68ec8e..f70772affa 100644 --- a/pyUltroid/dB/filter_db.py +++ b/pyUltroid/dB/filter_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/forcesub_db.py b/pyUltroid/dB/forcesub_db.py index 650d8d3c22..10b271543d 100644 --- a/pyUltroid/dB/forcesub_db.py +++ b/pyUltroid/dB/forcesub_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/gban_mute_db.py b/pyUltroid/dB/gban_mute_db.py index 6ab7388877..0cd8a8dc99 100644 --- a/pyUltroid/dB/gban_mute_db.py +++ b/pyUltroid/dB/gban_mute_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/greetings_db.py b/pyUltroid/dB/greetings_db.py index 157d269d04..37d3bf6d45 100644 --- a/pyUltroid/dB/greetings_db.py +++ b/pyUltroid/dB/greetings_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/mute_db.py b/pyUltroid/dB/mute_db.py index f9d8e1f02b..1390d1c60c 100644 --- a/pyUltroid/dB/mute_db.py +++ b/pyUltroid/dB/mute_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/notes_db.py b/pyUltroid/dB/notes_db.py index 68c8bde6b0..a2443dbb00 100644 --- a/pyUltroid/dB/notes_db.py +++ b/pyUltroid/dB/notes_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/nsfw_db.py b/pyUltroid/dB/nsfw_db.py index eb39cf4ab4..9a157da368 100644 --- a/pyUltroid/dB/nsfw_db.py +++ b/pyUltroid/dB/nsfw_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/snips_db.py b/pyUltroid/dB/snips_db.py index 8443bd7076..1d945f72c6 100644 --- a/pyUltroid/dB/snips_db.py +++ b/pyUltroid/dB/snips_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/vc_sudos.py b/pyUltroid/dB/vc_sudos.py index 8535db5278..1eb3c8baca 100644 --- a/pyUltroid/dB/vc_sudos.py +++ b/pyUltroid/dB/vc_sudos.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/dB/warn_db.py b/pyUltroid/dB/warn_db.py index 72eae237cd..622f986435 100644 --- a/pyUltroid/dB/warn_db.py +++ b/pyUltroid/dB/warn_db.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/exceptions.py b/pyUltroid/exceptions.py index b898a4115b..bdba015f0e 100644 --- a/pyUltroid/exceptions.py +++ b/pyUltroid/exceptions.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/FastTelethon.py b/pyUltroid/fns/FastTelethon.py index 8aa001dd17..d400a20b45 100644 --- a/pyUltroid/fns/FastTelethon.py +++ b/pyUltroid/fns/FastTelethon.py @@ -1,5 +1,5 @@ # copied from https://github.com/tulir/mautrix-telegram/blob/master/mautrix_telegram/util/parallel_file_transfer.py -# Copyright (C) 2021-2023 Tulir Asokan +# Copyright (C) 2021-2025 Tulir Asokan import asyncio import hashlib diff --git a/pyUltroid/fns/__init__.py b/pyUltroid/fns/__init__.py index f352fdd397..390aec9a64 100644 --- a/pyUltroid/fns/__init__.py +++ b/pyUltroid/fns/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/admins.py b/pyUltroid/fns/admins.py index 9c26ced4ef..eb9551bae2 100644 --- a/pyUltroid/fns/admins.py +++ b/pyUltroid/fns/admins.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/gDrive.py b/pyUltroid/fns/gDrive.py index 238d3717b7..a9a6eeba17 100644 --- a/pyUltroid/fns/gDrive.py +++ b/pyUltroid/fns/gDrive.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/helper.py b/pyUltroid/fns/helper.py index 16d00ea177..105208bd13 100644 --- a/pyUltroid/fns/helper.py +++ b/pyUltroid/fns/helper.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/info.py b/pyUltroid/fns/info.py index ebb64b91dd..326f680dfb 100644 --- a/pyUltroid/fns/info.py +++ b/pyUltroid/fns/info.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/misc.py b/pyUltroid/fns/misc.py index ffaa142c20..69ce9e94a7 100644 --- a/pyUltroid/fns/misc.py +++ b/pyUltroid/fns/misc.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/tools.py b/pyUltroid/fns/tools.py index 334838b7cb..0caedad1a3 100644 --- a/pyUltroid/fns/tools.py +++ b/pyUltroid/fns/tools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/fns/ytdl.py b/pyUltroid/fns/ytdl.py index f8c05f043a..c4d97d107d 100644 --- a/pyUltroid/fns/ytdl.py +++ b/pyUltroid/fns/ytdl.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/loader.py b/pyUltroid/loader.py index a3aaa54937..a5b4c52580 100644 --- a/pyUltroid/loader.py +++ b/pyUltroid/loader.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/BaseClient.py b/pyUltroid/startup/BaseClient.py index 609e16d7a1..763159ce00 100644 --- a/pyUltroid/startup/BaseClient.py +++ b/pyUltroid/startup/BaseClient.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/__init__.py b/pyUltroid/startup/__init__.py index ff62baf3c2..8d8063a535 100644 --- a/pyUltroid/startup/__init__.py +++ b/pyUltroid/startup/__init__.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/_database.py b/pyUltroid/startup/_database.py index 782b2ea28d..f7bc274524 100644 --- a/pyUltroid/startup/_database.py +++ b/pyUltroid/startup/_database.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/_extra.py b/pyUltroid/startup/_extra.py index bb5dadd287..e71907f841 100644 --- a/pyUltroid/startup/_extra.py +++ b/pyUltroid/startup/_extra.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/connections.py b/pyUltroid/startup/connections.py index c848653e15..005f199218 100644 --- a/pyUltroid/startup/connections.py +++ b/pyUltroid/startup/connections.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/funcs.py b/pyUltroid/startup/funcs.py index 60458f9b79..593a8808e2 100644 --- a/pyUltroid/startup/funcs.py +++ b/pyUltroid/startup/funcs.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/loader.py b/pyUltroid/startup/loader.py index 03c87bb2c9..5f49114a2e 100644 --- a/pyUltroid/startup/loader.py +++ b/pyUltroid/startup/loader.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/startup/utils.py b/pyUltroid/startup/utils.py index 0472ba13db..5445dbf534 100644 --- a/pyUltroid/startup/utils.py +++ b/pyUltroid/startup/utils.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/pyUltroid/version.py b/pyUltroid/version.py index 3bf4e47bf0..2bd0e369e0 100644 --- a/pyUltroid/version.py +++ b/pyUltroid/version.py @@ -1,2 +1,2 @@ -__version__ = "2023.02.20" -ultroid_version = "0.9" +__version__ = "2025.02.19" +ultroid_version = "2.0" diff --git a/resources/session/session.sh b/resources/session/session.sh index bd09927ed9..bec7c794c5 100644 --- a/resources/session/session.sh +++ b/resources/session/session.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in . diff --git a/resources/session/ssgen.py b/resources/session/ssgen.py index f41260b921..e3522cf150 100644 --- a/resources/session/ssgen.py +++ b/resources/session/ssgen.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/resources/startup/_termux.py b/resources/startup/_termux.py index d89aee2cc5..95a6527dc6 100644 --- a/resources/startup/_termux.py +++ b/resources/startup/_termux.py @@ -1,6 +1,6 @@ # /usr/bin/python3 # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # Please read the GNU Affero General Public License in diff --git a/resources/startup/locals.py b/resources/startup/locals.py index 6d6fc55d9a..94b1f68af0 100644 --- a/resources/startup/locals.py +++ b/resources/startup/locals.py @@ -1,6 +1,6 @@ # /usr/bin/python3 # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # Please read the GNU Affero General Public License in diff --git a/sessiongen b/sessiongen index b5032ac61c..c25ce25665 100644 --- a/sessiongen +++ b/sessiongen @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in . diff --git a/startup b/startup index 2e25faa2e2..4c75a102ea 100644 --- a/startup +++ b/startup @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Ultroid - UserBot -# Copyright (C) 2021-2023 TeamUltroid +# Copyright (C) 2021-2025 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in . diff --git a/strings/strings/jp.yml b/strings/strings/jp.yml index fcd9913299..b796ae1a1c 100644 --- a/strings/strings/jp.yml +++ b/strings/strings/jp.yml @@ -232,7 +232,7 @@ cvt_8: "`読み取り可能なファイルではありません。` " # eventsofday eod_1: "🎊**今日のイベント** \n \n" -eod_2: "•** {} / 2021-2023のイベント** \n \n" +eod_2: "•** {} / 2021-2025のイベント** \n \n" # core core_1: "モジュールが見つかりました" From 90199a4a802bf9c43b218dc07cce49fa20d9aa8d Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Fri, 21 Feb 2025 23:03:57 +0530 Subject: [PATCH 2/5] Update optional-requirements.txt --- resources/startup/optional-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/startup/optional-requirements.txt b/resources/startup/optional-requirements.txt index 2876b6cee8..224c30080a 100644 --- a/resources/startup/optional-requirements.txt +++ b/resources/startup/optional-requirements.txt @@ -24,6 +24,7 @@ pypdf2>=1.26.0 pytz qrcode requests +twikit tabulate telegraph tgcrypto From 36ac5ab2c4d38f81d76e050edad2d7f69f3e7510 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Sun, 23 Feb 2025 09:10:33 +0530 Subject: [PATCH 3/5] Bug fixes --- assistant/callbackstuffs.py | 26 +- assistant/games.py | 39 +- plugins/__init__.py | 5 + plugins/_inline.py | 8 +- plugins/afk.py | 5 +- plugins/asstcmd.py | 13 +- plugins/audiotools.py | 15 +- plugins/bot.py | 2 + plugins/button.py | 8 +- plugins/compressor.py | 8 +- plugins/converter.py | 23 +- plugins/devtools.py | 10 +- plugins/filter.py | 10 +- plugins/greetings.py | 14 +- plugins/imagetools.py | 6 +- plugins/mediatools.py | 3 +- plugins/notes.py | 8 +- plugins/polls.py | 6 +- plugins/search.py | 4 +- plugins/snips.py | 8 +- plugins/specialtools.py | 78 ++- plugins/utilities.py | 19 +- plugins/writer.py | 3 +- plugins/ziptools.py | 16 +- pyUltroid/fns/misc.py | 12 +- pyUltroid/fns/tools.py | 579 ++++++++++++-------- pyUltroid/startup/BaseClient.py | 1 + pyUltroid/version.py | 2 +- requirements.txt | 7 +- resources/startup/locals.py | 1 + resources/startup/optional-requirements.txt | 2 +- 31 files changed, 561 insertions(+), 380 deletions(-) diff --git a/assistant/callbackstuffs.py b/assistant/callbackstuffs.py index 0495c8246b..15598fee2c 100644 --- a/assistant/callbackstuffs.py +++ b/assistant/callbackstuffs.py @@ -20,8 +20,8 @@ from pyUltroid.fns.gDrive import GDriveManager except ImportError: GDriveManager = None -from telegraph import upload_file as upl from telethon import Button, events +from catbox import CatboxUploader from telethon.tl.types import MessageMediaWebPage from telethon.utils import get_peer_id @@ -34,9 +34,9 @@ # --------------------------------------------------------------------# telegraph = telegraph_client() GDrive = GDriveManager() if GDriveManager else None +uploader = CatboxUploader() # --------------------------------------------------------------------# - def text_to_url(event): """function to get media url (with|without) Webpage""" if isinstance(event.media, MessageMediaWebPage): @@ -322,9 +322,9 @@ async def update(eve): await eve.edit(get_string("clst_1")) call_back() await bash("git pull && pip3 install -r requirements.txt") + await bash("pip3 install -r requirements.txt --break-system-packages") execl(sys.executable, sys.executable, "-m", "pyUltroid") - @callback(re.compile("changes(.*)"), owner=True) async def changes(okk): match = okk.data_match.group(1).decode("utf-8") @@ -384,11 +384,14 @@ async def _(e): if "|" in ok: ok, index = ok.split("|") with open(ok, "r") as hmm: - _, key = await get_paste(hmm.read()) - link = f"https://spaceb.in/{key}" - raw = f"https://spaceb.in/api/v1/documents/{key}/raw" - if not _: + _, data = await get_paste(hmm.read()) + if not data.get("link"): return await e.answer(key[:30], alert=True) + if not key.startswith("http"): + link, raw = data["link"], data["raw"] + else: + link = key + raw = f"{key}/raw" if ok.startswith("addons"): key = "Addons" elif ok.startswith("vcbot"): @@ -830,8 +833,7 @@ async def media(event): else: media = await event.client.download_media(response, "alvpc") try: - x = upl(media) - url = f"https://graph.org/{x[0]}" + url = uploader.upload_file(media) remove(media) except BaseException as er: LOGS.exception(er) @@ -969,8 +971,7 @@ async def media(event): url = response.file.id else: try: - x = upl(media) - url = f"https://graph.org/{x[0]}" + url = uploader.upload_file(media) remove(media) except BaseException as er: LOGS.exception(er) @@ -1239,8 +1240,7 @@ async def media(event): url = text_to_url(response) else: try: - x = upl(media) - url = f"https://graph.org/{x[0]}" + url = uploader.upload_file(media) remove(media) except BaseException as er: LOGS.exception(er) diff --git a/assistant/games.py b/assistant/games.py index fef75c0cba..e2b86eacca 100644 --- a/assistant/games.py +++ b/assistant/games.py @@ -14,23 +14,28 @@ """ import asyncio -import re +import re, uuid, operator from random import choice, shuffle -from akipy.async_akipy import Akinator, akipyLOGS +from akipy.async_akipy import Akinator from telethon.errors.rpcerrorlist import BotMethodInvalidError from telethon.events import Raw from telethon.tl.types import InputMediaPoll, Poll, PollAnswer, UpdateMessagePollVote from pyUltroid._misc._decorators import ultroid_cmd +from logging import getLogger +from html import unescape +from telethon.tl.types import TextWithEntities from pyUltroid.fns.helper import inline_mention from pyUltroid.fns.tools import async_searcher +from telethon.errors import ChatSendStickersForbiddenError from . import * # Ensure this import matches your project structure games = {} aki_photo = "https://graph.org/file/3cc8825c029fd0cab9edc.jpg" +akipyLOGS = getLogger("akipy") @ultroid_cmd(pattern="akinator") async def akina(e): @@ -133,11 +138,7 @@ async def eiagx(e): # ----------------------- Main Command ------------------- # -GIMAGES = [ - "https://graph.org/file/1c51015bae5205a65fd69.jpg", - "https://imgwhale.xyz/3xyr322l64j9590", -] - +GIMAGE = "https://graph.org/file/1c51015bae5205a65fd69.jpg" @asst_cmd(pattern="startgame", owner=True) async def magic(event): @@ -147,7 +148,7 @@ async def magic(event): ] await event.reply( get_string("games_1"), - file=choice(GIMAGES), + file=GIMAGE, buttons=buttons, ) @@ -243,10 +244,10 @@ async def choose_cata(event): if TRIVIA_CHATS[chat].get("cancel") is not None: break ansi = str(uuid.uuid1()).split("-")[0].encode() - opts = [PollAnswer(unescape(q["correct_answer"]), ansi)] + opts = [PollAnswer(TextWithEntities(unescape(q["correct_answer"]), entities=[]), ansi)] [ opts.append( - PollAnswer(unescape(a), str(uuid.uuid1()).split("-")[0].encode()) + PollAnswer(TextWithEntities(unescape(a), entities=[]), str(uuid.uuid1()).split("-")[0].encode()) ) for a in q["incorrect_answers"] ] @@ -254,7 +255,10 @@ async def choose_cata(event): poll = InputMediaPoll( Poll( 0, - f"[{copper+1}]. " + unescape(q["question"]), + TextWithEntities( + f"[{copper+1}]. " + unescape(q["question"]), + entities=[] + ), answers=opts, public_voters=True, quiz=True, @@ -298,13 +302,22 @@ async def choose_cata(event): @asst.on( Raw(UpdateMessagePollVote, func=lambda x: TRIVIA_CHATS and POLLS.get(x.poll_id)) ) -async def pollish(eve): +async def pollish(eve: UpdateMessagePollVote): if POLLS.get(eve.poll_id)["chat"] not in TRIVIA_CHATS.keys(): return + if not eve.options: + # Consider as correct answer if no options selected + chat = POLLS.get(eve.poll_id)["chat"] + user = eve.peer.user_id + if not TRIVIA_CHATS.get(chat, {}).get(user): + TRIVIA_CHATS[chat][user] = 1 + else: + TRIVIA_CHATS[chat][user] += 1 + return if POLLS[eve.poll_id]["answer"] != eve.options[0]: return chat = POLLS.get(eve.poll_id)["chat"] - user = eve.user_id + user = eve.peer.user_id if not TRIVIA_CHATS.get(chat, {}).get(user): TRIVIA_CHATS[chat][user] = 1 else: diff --git a/plugins/__init__.py b/plugins/__init__.py index 173db5398a..82ef3187a4 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -25,6 +25,7 @@ from pyUltroid.startup._database import _BaseDatabase as Database from pyUltroid.version import __version__, ultroid_version from strings import get_help, get_string +from catbox import CatboxUploader udB: Database @@ -50,6 +51,9 @@ def inline_pic(): Telegraph = telegraph_client() +cat_uploader = CatboxUploader() + +upload_file = cat_uploader.upload_file List = [] Dict = {} @@ -84,6 +88,7 @@ def inline_pic(): "Mr.Steal-Your-Sticker is stealing this sticker... ", ] + ATRA_COL = [ "DarkCyan", "DeepSkyBlue", diff --git a/plugins/_inline.py b/plugins/_inline.py index 93cc81e4a7..211e723ffe 100644 --- a/plugins/_inline.py +++ b/plugins/_inline.py @@ -115,8 +115,12 @@ async def inline_handler(event): @in_pattern("pasta", owner=True) async def _(event): ok = event.text.split("-")[1] - link = f"https://spaceb.in/{ok}" - raw = f"https://spaceb.in/api/v1/documents/{ok}/raw" + if not ok.startswith("http"): + link = f"https://spaceb.in/{ok}" + raw = f"https://spaceb.in/api/v1/documents/{ok}/raw" + else: + link = ok + raw = f"{ok}/raw" result = await event.builder.article( title="Paste", text="Pasted to Spacebin 🌌", diff --git a/plugins/afk.py b/plugins/afk.py index 67f5d08ede..74e06eb774 100644 --- a/plugins/afk.py +++ b/plugins/afk.py @@ -12,7 +12,6 @@ import asyncio -from telegraph import upload_file as uf from telethon import events from pyUltroid.dB.afk_db import add_afk, del_afk, is_afk @@ -28,6 +27,7 @@ udB, ultroid_bot, ultroid_cmd, + upload_file ) old_afk_msg = [] @@ -50,8 +50,7 @@ async def set_afk(event): media_type = mediainfo(reply.media) if media_type.startswith(("pic", "gif")): file = await event.client.download_media(reply.media) - iurl = uf(file) - media = f"https://graph.org{iurl[0]}" + media = upload_file(file) else: media = reply.file.id await event.eor("`Done`", time=2) diff --git a/plugins/asstcmd.py b/plugins/asstcmd.py index b84c717bc9..02a9945c1c 100644 --- a/plugins/asstcmd.py +++ b/plugins/asstcmd.py @@ -13,14 +13,9 @@ from pyUltroid.dB.asstcmd_db import add_cmd, cmd_reply, list_cmds, rem_cmd from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button - -try: - from telegraph import upload_file as uf -except ImportError: - uf = None from telethon import events, utils -from . import asst, get_string, mediainfo, udB, ultroid_cmd +from . import asst, get_string, mediainfo, udB, ultroid_cmd, upload_file @ultroid_cmd(pattern="addcmd( (.*)|$)") @@ -36,16 +31,14 @@ async def ac(e): wut = mediainfo(wt.media) if wut.startswith(("pic", "gif")): dl = await e.client.download_media(wt.media) - variable = uf(dl) + m = upload_file(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "video": if wt.media.document.size > 8 * 1000 * 1000: return await e.eor(get_string("com_4"), time=5) dl = await e.client.download_media(wt.media) - variable = uf(dl) + m = upload_file(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" else: m = utils.pack_bot_file_id(wt.media) if wt.text: diff --git a/plugins/audiotools.py b/plugins/audiotools.py index 2ae4e99212..40343bbc8c 100644 --- a/plugins/audiotools.py +++ b/plugins/audiotools.py @@ -26,8 +26,7 @@ mediainfo, stdr, time_formatter, - ultroid_cmd, - uploader, + ultroid_cmd ) __doc__ = get_help("help_audiotools") @@ -104,13 +103,15 @@ async def trim_aud(e): await bash(cmd) os.remove(file.name) f_time = time.time() - mmmm = await uploader(out, out, f_time, xxx, f"Uploading {out}...") + n_file, _ = await e.client.fast_uploader( + out, show_progress=True, event=e, message="Uploading...", to_delete=True + ) attributes = await set_attributes(out) caption = get_string("audiotools_7").format(ss, dd) await e.client.send_file( e.chat_id, - mmmm, + n_file, thumb=ULTConfig.thumb, caption=caption, attributes=attributes, @@ -147,13 +148,15 @@ async def ex_aud(e): f_time = time.time() try: - fo = await uploader(out_file, out_file, f_time, msg, f"Uploading {out_file}...") + n_file, _ = await e.client.fast_uploader( + out_file, show_progress=True, event=e, message="Uploading...", to_delete=True + ) except FileNotFoundError: return await eor(msg, get_string("audiotools_9")) await e.reply( get_string("audiotools_10"), - file=fo, + file=n_file, thumb=ULTConfig.thumb, attributes=attributes, ) diff --git a/plugins/bot.py b/plugins/bot.py index e10bd09e91..a4febdc909 100644 --- a/plugins/bot.py +++ b/plugins/bot.py @@ -211,6 +211,7 @@ async def restartbt(ult): if heroku_api: return await restart(ok) await bash("git pull && pip3 install -r requirements.txt") + await bash("pip3 install -r requirements.txt --break-system-packages") if len(sys.argv) > 1: os.execl(sys.executable, sys.executable, "main.py") else: @@ -324,6 +325,7 @@ async def _(e): or "soft" in e.pattern_match.group(1).strip() ): await bash("git pull -f && pip3 install -r requirements.txt") + await bash("pip3 install -r requirements.txt --break-system-packages") call_back() await xx.edit(get_string("upd_7")) os.execl(sys.executable, "python3", "-m", "pyUltroid") diff --git a/plugins/button.py b/plugins/button.py index ef61d2990f..ef1fbb2a84 100644 --- a/plugins/button.py +++ b/plugins/button.py @@ -11,7 +11,7 @@ import os -from telegraph import upload_file as uf +from . import upload_file as uf from telethon.utils import pack_bot_file_id from pyUltroid.fns.tools import create_tl_btn, get_msg_button @@ -31,15 +31,13 @@ async def butt(event): wut = mediainfo(wt.media) if wut and wut.startswith(("pic", "gif")): dl = await wt.download_media() - variable = uf(dl) - media = f"https://graph.org{variable[0]}" + media = uf(dl) elif wut == "video": if wt.media.document.size > 8 * 1000 * 1000: return await event.eor(get_string("com_4"), time=5) dl = await wt.download_media() - variable = uf(dl) + media = uf(dl) os.remove(dl) - media = f"https://graph.org{variable[0]}" else: media = pack_bot_file_id(wt.media) try: diff --git a/plugins/compressor.py b/plugins/compressor.py index abd6d157e3..a221d8f161 100644 --- a/plugins/compressor.py +++ b/plugins/compressor.py @@ -139,7 +139,9 @@ async def _(e): caption += f"**Compressed Size: **`{humanbytes(c_size)}`\n" caption += f"**Compression Ratio: **`{differ:.2f}%`\n" caption += f"\n**Time Taken To Compress: **`{difff}`" - mmmm = await uploader(out, out, f_time, xxx, f"Uploading {out}...") + n_file, _ = await e.client.fast_uploader( + out, show_progress=True, event=e, message="Uploading...", to_delete=True + ) if to_stream: data = await metadata(out) width = data["width"] @@ -152,7 +154,7 @@ async def _(e): ] await e.client.send_file( e.chat_id, - mmmm, + n_file, thumb=ULTConfig.thumb, caption=caption, attributes=attributes, @@ -162,7 +164,7 @@ async def _(e): else: await e.client.send_file( e.chat_id, - mmmm, + n_file, thumb=ULTConfig.thumb, caption=caption, force_document=True, diff --git a/plugins/converter.py b/plugins/converter.py index b68dd27361..201ff76b96 100644 --- a/plugins/converter.py +++ b/plugins/converter.py @@ -25,7 +25,7 @@ LOGS.info(f"{__file__}: PIL not Installed.") Image = None -from telegraph import upload_file as uf +from . import upload_file as uf from . import ( ULTConfig, @@ -53,9 +53,8 @@ async def _(e): dl = await r.download_media(thumb=-1) else: return await e.eor("`Reply to Photo or media with thumb...`") - variable = uf(dl) + nn = uf(dl) os.remove(dl) - nn = f"https://graph.org{variable[0]}" udB.set_key("CUSTOM_THUMBNAIL", str(nn)) await bash(f"wget {nn} -O resources/extras/ultroid.jpg") await e.eor(get_string("cvt_6").format(nn), link_preview=False) @@ -93,10 +92,12 @@ async def imak(event): if not os.path.exists(inp) or os.path.exists(inp) and not os.path.getsize(inp): os.rename(file, inp) k = time.time() - xxx = await uploader(inp, inp, k, xx, get_string("com_6")) + n_file, _ = await event.client.fast_uploader( + inp, show_progress=True, event=event, message="Uploading...", to_delete=True + ) await event.reply( - f"`{xxx.name}`", - file=xxx, + f"`{n_file.name}`", + file=n_file, force_document=True, thumb=ULTConfig.thumb, ) @@ -135,14 +136,18 @@ async def uconverter(event): except KeyError: return await xx.edit(get_string("sts_3").format("gif/img/sticker/webm")) file = await con.convert(b, outname="ultroid", convert_to=convert) + print(file) + if file: await event.client.send_file( event.chat_id, file, reply_to=event.reply_to_msg_id or event.id ) os.remove(file) + else: + await xx.edit("`Failed to convert`") + return await xx.delete() - @ultroid_cmd( pattern="doc( (.*)|$)", ) @@ -183,9 +188,9 @@ async def _(event): try: await xx.edit(f"```{d}```") except BaseException: - what, key = await get_paste(d) + what, data = await get_paste(d) await xx.edit( - f"**MESSAGE EXCEEDS TELEGRAM LIMITS**\n\nSo Pasted It On [SPACEBIN](https://spaceb.in/{key})" + f"**MESSAGE EXCEEDS TELEGRAM LIMITS**\n\nSo Pasted It On [SPACEBIN]({data['link']})" ) if rem: os.remove(b) diff --git a/plugins/devtools.py b/plugins/devtools.py index fb3f72b4bc..40af9a7987 100644 --- a/plugins/devtools.py +++ b/plugins/devtools.py @@ -33,10 +33,8 @@ from yaml import safe_load except ImportError: from pyUltroid.fns.tools import safe_load -try: - from telegraph import upload_file as uf -except ImportError: - uf = None + +from . import upload_file as uf from telethon.tl import functions fn = functions @@ -99,7 +97,7 @@ async def _(event): f"Unknown Response from Carbon: `{li}`\n\nstdout`:{stdout}`\nstderr: `{stderr}`" ) return - url = f"https://graph.org{uf(li)[-1]}" + url = uf(li) OUT = f"[\xad]({url}){OUT}" out = "**• OUTPUT:**" remove(li) @@ -121,7 +119,7 @@ async def _(event): f"Unknown Response from Carbon: `{li}`\n\nstdout`:{stdout}`\nstderr: `{stderr}`" ) return - url = f"https://graph.org{uf(li)[-1]}" + url = uf(li) OUT = f"[\xad]({url}){OUT}" out = "**• OUTPUT:**" remove(li) diff --git a/plugins/filter.py b/plugins/filter.py index 95294b01ad..b330769135 100644 --- a/plugins/filter.py +++ b/plugins/filter.py @@ -12,14 +12,13 @@ import os import re -from telegraph import upload_file as uf from telethon.tl.types import User from telethon.utils import pack_bot_file_id from pyUltroid.dB.filter_db import add_filter, get_filter, list_filter, rem_filter from pyUltroid.fns.tools import create_tl_btn, format_btn, get_msg_button -from . import events, get_string, mediainfo, udB, ultroid_bot, ultroid_cmd +from . import events, get_string, mediainfo, udB, ultroid_bot, ultroid_cmd, upload_file from ._inline import something @@ -35,15 +34,14 @@ async def af(e): wut = mediainfo(wt.media) if wut.startswith(("pic", "gif")): dl = await wt.download_media() - variable = uf(dl) - m = f"https://graph.org{variable[0]}" + m = upload_file(dl) + os.remove(dl) elif wut == "video": if wt.media.document.size > 8 * 1000 * 1000: return await e.eor(get_string("com_4"), time=5) dl = await wt.download_media() - variable = uf(dl) + m = upload_file(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" else: m = pack_bot_file_id(wt.media) if wt.text: diff --git a/plugins/greetings.py b/plugins/greetings.py index 7f126e1a51..27053eff30 100644 --- a/plugins/greetings.py +++ b/plugins/greetings.py @@ -32,7 +32,7 @@ """ import os -from telegraph import upload_file as uf +from . import upload_file as uf from telethon.utils import pack_bot_file_id from pyUltroid.dB.greetings_db import ( @@ -67,16 +67,14 @@ async def setwel(event): wut = mediainfo(r.media) if wut.startswith(("pic", "gif")): dl = await r.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "video": if r.media.document.size > 8 * 1000 * 1000: return await eor(x, get_string("com_4"), time=5) dl = await r.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "web": m = None else: @@ -132,16 +130,14 @@ async def setgb(event): wut = mediainfo(r.media) if wut.startswith(("pic", "gif")): dl = await r.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "video": if r.media.document.size > 8 * 1000 * 1000: return await eor(x, get_string("com_4"), time=5) dl = await r.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "web": m = None else: diff --git a/plugins/imagetools.py b/plugins/imagetools.py index a0757bcff7..22fd011823 100644 --- a/plugins/imagetools.py +++ b/plugins/imagetools.py @@ -68,7 +68,8 @@ except ImportError: Image = None LOGS.info(f"{__file__}: PIL not Installed.") -from telegraph import upload_file as upf + +from . import upload_file as upf from telethon.errors.rpcerrorlist import ( ChatSendMediaForbiddenError, MessageDeleteForbiddenError, @@ -217,8 +218,7 @@ async def ultd(event): if ultt.endswith(".tgs"): await xx.edit(get_string("sts_9")) file = await con.convert(ultt, convert_to="png", outname="ult") - got = upf(file) - lnk = f"https://graph.org{got[0]}" + lnk = upf(file) r = await async_searcher( f"https://nekobot.xyz/api/imagegen?type=blurpify&image={lnk}", re_json=True ) diff --git a/plugins/mediatools.py b/plugins/mediatools.py index fd0ab43b48..4e8667b8f5 100644 --- a/plugins/mediatools.py +++ b/plugins/mediatools.py @@ -27,6 +27,7 @@ bash, downloader, get_string, + upload_file, is_url_ok, mediainfo, ultroid_cmd, @@ -87,7 +88,7 @@ async def mi(e): makehtml = "" if naam.endswith((".jpg", ".png")): if os.path.exists(naam): - med = "https://graph.org" + Telegraph.upload_file(naam)[0]["src"] + med = upload_file(naam) else: med = match makehtml += f"
" diff --git a/plugins/notes.py b/plugins/notes.py index 5553782f76..4bceefeb67 100644 --- a/plugins/notes.py +++ b/plugins/notes.py @@ -22,7 +22,7 @@ """ import os -from telegraph import upload_file as uf +from . import upload_file as uf from telethon.utils import pack_bot_file_id from pyUltroid.dB.notes_db import add_note, get_notes, list_note, rem_note @@ -46,16 +46,14 @@ async def an(e): wut = mediainfo(wt.media) if wut.startswith(("pic", "gif")): dl = await wt.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "video": if wt.media.document.size > 8 * 1000 * 1000: return await e.eor(get_string("com_4"), time=5) dl = await wt.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" else: m = pack_bot_file_id(wt.media) if wt.text: diff --git a/plugins/polls.py b/plugins/polls.py index 2fb71e5dc8..95423a684f 100644 --- a/plugins/polls.py +++ b/plugins/polls.py @@ -18,7 +18,7 @@ Get the quiz poll where answerno is the number of option which is correct """ -from telethon.tl.types import InputMediaPoll, Poll, PollAnswer +from telethon.tl.types import InputMediaPoll, Poll, PollAnswer, TextWithEntities from . import get_string, ultroid_cmd @@ -57,10 +57,10 @@ async def uri_poll(e): if len(option) <= 1: return await e.eor("`Options Should be More than 1..`", time=5) m = await e.eor(get_string("com_1")) - OUT = [PollAnswer(option[on], str(on).encode()) for on in range(len(option))] + OUT = [PollAnswer(TextWithEntities(option[on], entities=[]), str(on).encode()) for on in range(len(option))] await e.respond( file=InputMediaPoll( - Poll(20, ques, OUT, multiple_choice=mpp, public_voters=publ, quiz=quizo), + Poll(20, TextWithEntities(ques, entities=[]), OUT, multiple_choice=mpp, public_voters=publ, quiz=quizo), correct_answers=karzo, ), ) diff --git a/plugins/search.py b/plugins/search.py index b80e34f044..020e08c02d 100644 --- a/plugins/search.py +++ b/plugins/search.py @@ -152,8 +152,10 @@ async def reverse(event): "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0", }, ) + with open("response.html", "w") as f: + f.write(response) xx = bs(response, "html.parser") - div = xx.find_all("div", {"class": "r5a77d"})[0] + div = xx.find_all("div", {"class": "kb0PBd"})[0] alls = div.find("a") link = alls["href"] text = alls.text diff --git a/plugins/snips.py b/plugins/snips.py index 6b11f27ec1..a7c7aae1f7 100644 --- a/plugins/snips.py +++ b/plugins/snips.py @@ -21,7 +21,7 @@ """ import os -from telegraph import upload_file as uf +from . import upload_file as uf from telethon.utils import pack_bot_file_id from pyUltroid._misc import sudoers @@ -45,16 +45,14 @@ async def an(e): wut = mediainfo(wt.media) if wut.startswith(("pic", "gif")): dl = await wt.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" elif wut == "video": if wt.media.document.size > 8 * 1000 * 1000: return await e.eor(get_string("com_4"), time=5) dl = await wt.download_media() - variable = uf(dl) + m = uf(dl) os.remove(dl) - m = f"https://graph.org{variable[0]}" else: m = pack_bot_file_id(wt.media) if wt.text: diff --git a/plugins/specialtools.py b/plugins/specialtools.py index 6971c58fff..52a448be76 100644 --- a/plugins/specialtools.py +++ b/plugins/specialtools.py @@ -36,10 +36,11 @@ from datetime import datetime as dt from random import choice -import pytz +import pytz, asyncio from bs4 import BeautifulSoup as bs from telethon.tl.types import DocumentAttributeVideo - +from requests import Session +from cloudscraper import create_scraper from pyUltroid.fns.tools import get_google_images, metadata from . import ( @@ -59,7 +60,7 @@ from .beautify import all_col File = [] - +scraper = create_scraper() @ultroid_cmd( pattern="getaudio$", @@ -250,6 +251,7 @@ async def hbd(event): reply_to=event.reply_to_msg_id, ) +session = Session() @ultroid_cmd(pattern="sticker( (.*)|$)") async def _(event): @@ -257,23 +259,61 @@ async def _(event): if not x: return await event.eor("`Give something to search`") uu = await event.eor(get_string("com_1")) - z = bs( - await async_searcher(f"https://combot.org/telegram/stickers?q={x}"), - "html.parser", - ) - - packs = z.find_all("div", "sticker-pack__header") - sticks = { - c.a["href"]: c.find("div", {"class": "sticker-pack__title"}).text for c in packs + + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } - - if not sticks: - return await uu.edit(get_string("spcltool_9")) - a = "SᴛɪᴄᴋEʀs Aᴠᴀɪʟᴀʙʟᴇ ~\n\n" - for _, value in sticks.items(): - a += f"{value}\n" - await uu.edit(a, parse_mode="html") - + + max_retries = 3 + retry_count = 0 + + while retry_count < max_retries: + try: + response = scraper.get( + f"https://combot.org/telegram/stickers?q={x}", + headers=headers + ).content + + # Check if response contains Cloudflare challenge + if "Just a moment..." in response.decode(): + retry_count += 1 + await asyncio.sleep(2) # Wait before retry + continue + + z = bs(response, "html.parser") + packs = z.find_all("a", {"class": "stickerset__title"}) + + if not packs: + return await uu.edit(get_string("spcltool_9")) + + break # Success - exit loop + + except Exception as er: + retry_count += 1 + await asyncio.sleep(2) + continue + + if retry_count >= max_retries: + return await uu.edit("`Failed to fetch stickers after multiple retries`") + try: + sticks = {} + for pack in packs: + href = pack.get("href") + title = pack.text.strip() + if href: + href = f"https://t.me/addstickers/{href.split('/')[-1]}" + sticks[href] = title + + if not sticks: + return await uu.edit(get_string("spcltool_9")) + + a = "SᴛɪᴄᴋEʀs Aᴠᴀɪʟᴀʙʟᴇ ~\n\n" + for href, title in sticks.items(): + a += f"{title}\n" + await uu.edit(a, parse_mode="html") + + except Exception as e: + await uu.edit(f"`Error: {str(e)}`\nTry again later.") @ultroid_cmd(pattern="wall( (.*)|$)") async def wall(event): diff --git a/plugins/utilities.py b/plugins/utilities.py index 11d8268906..f8b62f643f 100644 --- a/plugins/utilities.py +++ b/plugins/utilities.py @@ -67,10 +67,7 @@ from pyUltroid.dB.gban_mute_db import is_gbanned from pyUltroid.fns.tools import get_chat_and_msgid -try: - from telegraph import upload_file as uf -except ImportError: - uf = None +from . import upload_file as uf from telethon.errors.rpcerrorlist import ChatForwardsRestrictedError, UserBotError from telethon.errors import MessageTooLongError @@ -266,18 +263,16 @@ async def _(event): return await xx.eor( "`Reply to a Message/Document or Give me Some Text !`", time=5 ) - done, key = await get_paste(message) - if not done: - return await xx.eor(key) - link = f"https://spaceb.in/{key}" - raw = f"https://spaceb.in/api/v1/documents/{key}/raw" + done, data = await get_paste(message) + if not done and data.get("error"): + return await xx.eor(data["error"]) reply_text = ( - f"• **Pasted to SpaceBin :** [Space]({link})\n• **Raw Url :** : [Raw]({raw})" + f"• **Pasted to SpaceBin :** [Space]({data['link']})\n• **Raw Url :** : [Raw]({data['raw']})" ) try: if event.client._bot: return await xx.eor(reply_text) - ok = await event.client.inline_query(asst.me.username, f"pasta-{key}") + ok = await event.client.inline_query(asst.me.username, f"pasta-{data['link']}") await ok[0].click(event.chat_id, reply_to=event.reply_to_msg_id, hide_via=True) await xx.delete() except BaseException as e: @@ -506,7 +501,7 @@ async def telegraphcmd(event): getit = file if "document" not in dar: try: - nn = f"https://graph.org{uf(getit)[0]}" + nn = uf(getit) amsg = f"Uploaded to [Telegraph]({nn}) !" except Exception as e: amsg = f"Error : {e}" diff --git a/plugins/writer.py b/plugins/writer.py index 4e9f812ffd..9b9ea3d4e7 100644 --- a/plugins/writer.py +++ b/plugins/writer.py @@ -74,7 +74,8 @@ async def writer(e): font = ImageFont.truetype("resources/fonts/assfont.ttf", 30) x, y = 150, 140 lines = text_set(text) - line_height = font.getsize("hg")[1] + bbox = font.getbbox("hg") + line_height = bbox[3] - bbox[1] for line in lines: draw.text((x, y), line, fill=(1, 22, 55), font=font) y = y + line_height - 5 diff --git a/plugins/ziptools.py b/plugins/ziptools.py index c7006dad7f..ab2674c191 100644 --- a/plugins/ziptools.py +++ b/plugins/ziptools.py @@ -63,13 +63,15 @@ async def zipp(event): else: await bash(f"zip -r {inp} {file}") k = time.time() - xxx = await uploader(inp, inp, k, xx, get_string("com_6")) + n_file, _ = await event.client.fast_uploader( + inp, show_progress=True, event=event, message="Uploading...", to_delete=True + ) await event.client.send_file( event.chat_id, - xxx, + n_file, force_document=True, thumb=ULTConfig.thumb, - caption=f"`{xxx.name}`", + caption=f"`{n_file.name}`", reply_to=reply, ) os.remove(inp) @@ -104,13 +106,15 @@ async def unzipp(event): ok = get_all_files("unzip") for x in ok: k = time.time() - xxx = await uploader(x, x, k, xx, get_string("com_6")) + n_file, _ = await event.client.fast_uploader( + x, show_progress=True, event=event, message="Uploading...", to_delete=True + ) await event.client.send_file( event.chat_id, - xxx, + n_file, force_document=True, thumb=ULTConfig.thumb, - caption=f"`{xxx.name}`", + caption=f"`{n_file.name}`", ) await xx.delete() diff --git a/pyUltroid/fns/misc.py b/pyUltroid/fns/misc.py index 69ce9e94a7..85369b1b60 100644 --- a/pyUltroid/fns/misc.py +++ b/pyUltroid/fns/misc.py @@ -13,6 +13,7 @@ from logging import WARNING from random import choice, randrange, shuffle from traceback import format_exc +from catbox import CatboxUploader from pyUltroid.exceptions import DependencyMissingError @@ -59,6 +60,7 @@ except ImportError: BeautifulSoup = None +uploader = CatboxUploader() async def randomchannel( tochat, channel, range1, range2, caption=None, client=ultroid_bot @@ -295,15 +297,7 @@ async def _format_quote(self, event, reply=None, sender=None, type_="private"): async def telegraph(file_): file = file_ + ".png" Image.open(file_).save(file, "PNG") - files = {"file": open(file, "rb").read()} - uri = ( - "https://graph.org" - + ( - await async_searcher( - "https://graph.org/upload", post=True, data=files, re_json=True - ) - )[0]["src"] - ) + uri = uploader.upload_file(file) os.remove(file) os.remove(file_) return uri diff --git a/pyUltroid/fns/tools.py b/pyUltroid/fns/tools.py index 6785fae648..3c23f21864 100644 --- a/pyUltroid/fns/tools.py +++ b/pyUltroid/fns/tools.py @@ -9,9 +9,9 @@ import math import os import random -import re +import re, subprocess import secrets -import ssl +import ssl, html from io import BytesIO from json.decoder import JSONDecodeError from traceback import format_exc @@ -118,8 +118,12 @@ async def metadata(file): raise DependencyMissingError( f"'{_}' is not installed!\nInstall it to use this command." ) + data = {} - _info = json.loads(out)["media"]["track"] + _info = json.loads(out)["media"] + if not _info: + return {} + _info = _info["track"] info = _info[0] if info.get("Format") in ["GIF", "PNG"]: return { @@ -385,95 +389,109 @@ def make_logo(imgpath, text, funt, **args): async def get_paste(data: str, extension: str = "txt"): - ssl_context = ssl.create_default_context(cafile=certifi.where()) - json = {"content": data, "extension": extension} - key = await async_searcher( - url="https://spaceb.in/api/v1/documents/", - json=json, - ssl=ssl_context, - post=True, - re_json=True, - ) try: - return True, key["payload"]["id"] - except KeyError: - if "the length must be between 2 and 400000." in key["error"]: - return await get_paste(data[-400000:], extension=extension) - return False, key["error"] - except Exception as e: - LOGS.info(e) - return None, str(e) - + url = "https://spaceb.in/api/" + res = await async_searcher(url, json={"content": data, "extension": extension}, post=True, re_json=True) + return True, { + "link": f"https://spaceb.in/{res['payload']['id']}", + "raw": f"https://spaceb.in/{res['payload']['id']}/raw" + } + except Exception: + try: + url = "https://dpaste.org/api/" + data = { + 'format': 'json', + 'content': data.encode('utf-8'), + 'lexer': extension, + 'expires': '604800', # expire in week + } + res = await async_searcher(url, data=data, post=True, re_json=True) + return True, { + "link": res["url"], + "raw": f'{res["url"]}/raw' + } + except Exception as e: + LOGS.info(e) + return None, { + "link": None, + "raw": None, + "error": str(e) + } -# -------------------------------------- # https://stackoverflow.com/a/74563494 async def get_google_images(query): - soup = BeautifulSoup( - await async_searcher( - "https://google.com/search", - params={"q": query, "tbm": "isch"}, - headers={"User-Agent": random.choice(some_random_headers)}, - ), - "lxml", - ) - google_images = [] - all_script_tags = soup.select("script") - matched_images_data = "".join( - re.findall(r"AF_initDataCallback\(([^<]+)\);", str(all_script_tags)) - ) - matched_images_data_fix = json.dumps(matched_images_data) - matched_images_data_json = json.loads(matched_images_data_fix) - matched_google_image_data = re.findall( - r"\"b-GRID_STATE0\"(.*)sideChannel:\s?{}}", matched_images_data_json - ) - matched_google_images_thumbnails = ", ".join( - re.findall( - r"\[\"(https\:\/\/encrypted-tbn0\.gstatic\.com\/images\?.*?)\",\d+,\d+\]", - str(matched_google_image_data), - ) - ).split(", ") - thumbnails = [ - bytes(bytes(thumbnail, "ascii").decode("unicode-escape"), "ascii").decode( - "unicode-escape" - ) - for thumbnail in matched_google_images_thumbnails - ] - removed_matched_google_images_thumbnails = re.sub( - r"\[\"(https\:\/\/encrypted-tbn0\.gstatic\.com\/images\?.*?)\",\d+,\d+\]", - "", - str(matched_google_image_data), - ) - matched_google_full_resolution_images = re.findall( - r"(?:'|,),\[\"(https:|http.*?)\",\d+,\d+\]", - removed_matched_google_images_thumbnails, - ) - full_res_images = [ - bytes(bytes(img, "ascii").decode("unicode-escape"), "ascii").decode( - "unicode-escape" - ) - for img in matched_google_full_resolution_images + """Get image results from Google Custom Search API. + + Args: + query (str): Search query string + + Returns: + list: List of dicts containing image info (title, link, source, thumbnail, original) + """ + LOGS.info(f"Searching Google Images for: {query}") + + # Google Custom Search API credentials + google_keys = [ + { + "key": "AIzaSyAj75v6vHWLJdJaYcj44tLz7bdsrh2g7Y0", + "cx": "712a54749d99a449e" + }, + { + "key": "AIzaSyDFQQwPLCzcJ9FDao-B7zDusBxk8GoZ0HY", + "cx": "001bbd139705f44a6" + }, + { + "key": "AIzaSyD0sRNZUa8-0kq9LAREDAFKLNO1HPmikRU", + "cx": "4717c609c54e24250" + } ] - for index, (metadata, thumbnail, original) in enumerate( - zip(soup.select(".isv-r.PNCib.MSM1fd.BUooTd"), thumbnails, full_res_images), - start=1, - ): - google_images.append( - { - "title": metadata.select_one(".VFACy.kGQAp.sMi44c.lNHeqe.WGvvNb")[ - "title" - ], - "link": metadata.select_one(".VFACy.kGQAp.sMi44c.lNHeqe.WGvvNb")[ - "href" - ], - "source": metadata.select_one(".fxgdke").text, - "thumbnail": thumbnail, - "original": original, - } + key_index = random.randint(0, len(google_keys) - 1) + GOOGLE_API_KEY = google_keys[key_index]["key"] + GOOGLE_CX = google_keys[key_index]["cx"] + try: + # Construct API URL + url = ( + "https://www.googleapis.com/customsearch/v1" + f"?q={quote(query)}" + f"&cx={GOOGLE_CX}" + f"&key={GOOGLE_API_KEY}" + "&searchType=image" + "&num=10" # Number of results ) - random.shuffle(google_images) - return google_images + + # Make API request + response = await async_searcher(url, re_json=True) + print("response") + if not response or "items" not in response: + LOGS.error("No results from Google Custom Search API") + return [] + + # Process results + google_images = [] + for item in response["items"]: + try: + google_images.append({ + "title": item.get("title", ""), + "link": item.get("contextLink", ""), # Page containing image + "source": item.get("displayLink", ""), + "thumbnail": item.get("image", {}).get("thumbnailLink", item["link"]), + "original": item["link"] # Original image URL + }) + except Exception as e: + LOGS.warning(f"Failed to process image result: {str(e)}") + continue + + # Randomize results order + random.shuffle(google_images) + + LOGS.info(f"Found {len(google_images)} images for query: {query}") + return google_images + + except Exception as e: + LOGS.exception(f"Error in get_google_images: {str(e)}") + return [] # Thanks https://t.me/ImSafone for ChatBotApi @@ -672,7 +690,7 @@ async def get_file_link(msg): async def get_stored_file(event, hash): - from .. import udB + from .. import udB, asst msg_id = get_stored_msg(hash) if not msg_id: @@ -689,37 +707,22 @@ async def get_stored_file(event, hash): await asst.send_message(event.chat_id, msg.text, file=msg.media, reply_to=event.id) -def _package_rpc(text, lang_src="auto", lang_tgt="auto"): - GOOGLE_TTS_RPC = ["MkEWBc"] - parameter = [[text.strip(), lang_src, lang_tgt, True], [1]] - escaped_parameter = json.dumps(parameter, separators=(",", ":")) - rpc = [[[random.choice(GOOGLE_TTS_RPC), escaped_parameter, None, "generic"]]] - espaced_rpc = json.dumps(rpc, separators=(",", ":")) - freq = "f.req={}&".format(quote(espaced_rpc)) - return freq - +def translate(text, lang_tgt="en", lang_src="auto", timeout=60, detect=False): + pattern = r'(?s)class="(?:t0|result-container)">(.*?)<' + escaped_text = quote(text.encode("utf8")) + url = "https://translate.google.com/m?tl=%s&sl=%s&q=%s" % ( + lang_tgt, + lang_src, + escaped_text, + ) + response = requests.get(url, timeout=timeout).content + result = response.decode("utf8") + result = re.findall(pattern, result) + if not result: + return "" + text = html.unescape(result[0]) + return (text, None) if detect else text -def translate(*args, **kwargs): - headers = { - "Referer": "https://translate.google.co.in", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) " - "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/47.0.2526.106 Safari/537.36", - "Content-Type": "application/x-www-form-urlencoded;charset=utf-8", - } - x = requests.post( - "https://translate.google.co.in/_/TranslateWebserverUi/data/batchexecute", - headers=headers, - data=_package_rpc(*args, **kwargs), - ).text - response = "" - data = json.loads(json.loads(x[4:])[0][2])[1][0][0] - subind = data[-2] - if not subind: - subind = data[-1] - for i in subind: - response += i[0] - return response def cmd_regex_replace(cmd): @@ -751,50 +754,83 @@ class TgConverter: @staticmethod async def animated_sticker(file, out_path="sticker.tgs", throw=False, remove=False): """Convert to/from animated sticker.""" - if out_path.endswith("webp"): - er, out = await bash( - f"lottie_convert.py --webp-quality 100 --webp-skip-frames 100 '{file}' '{out_path}'" - ) - else: - er, out = await bash(f"lottie_convert.py '{file}' '{out_path}'") - if er and throw: - raise LottieException(er) - if remove: - os.remove(file) - if os.path.exists(out_path): - return out_path + LOGS.info(f"Converting animated sticker: {file} -> {out_path}") + try: + if out_path.endswith("webp"): + er, out = await bash( + f"lottie_convert.py --webp-quality 100 --webp-skip-frames 100 '{file}' '{out_path}'" + ) + else: + er, out = await bash(f"lottie_convert.py '{file}' '{out_path}'") + + if er: + LOGS.error(f"Error in animated_sticker conversion: {er}") + if throw: + raise LottieException(er) + if remove and os.path.exists(file): + os.remove(file) + LOGS.info(f"Removed original file: {file}") + if os.path.exists(out_path): + LOGS.info(f"Successfully converted to {out_path}") + return out_path + LOGS.error(f"Output file not created: {out_path}") + return None + except Exception as e: + LOGS.exception(f"Unexpected error in animated_sticker: {str(e)}") + if throw: + raise @staticmethod async def animated_to_gif(file, out_path="gif.gif"): """Convert animated sticker to gif.""" - await bash( - f"lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(out_path)}'" - ) - return out_path + LOGS.info(f"Converting to gif: {file} -> {out_path}") + try: + er, out = await bash( + f"lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(out_path)}'" + ) + if er: + LOGS.error(f"Error in animated_to_gif conversion: {er}") + if os.path.exists(out_path): + LOGS.info("Successfully converted to gif") + return out_path + LOGS.error("Gif conversion failed - output file not created") + return None + except Exception as e: + LOGS.exception(f"Unexpected error in animated_to_gif: {str(e)}") + return None @staticmethod def resize_photo_sticker(photo): """Resize the given photo to 512x512 (for creating telegram sticker).""" - image = Image.open(photo) - if (image.width and image.height) < 512: - size1 = image.width - size2 = image.height - if image.width > image.height: - scale = 512 / size1 - size1new = 512 - size2new = size2 * scale + LOGS.info(f"Resizing photo for sticker: {photo}") + try: + image = Image.open(photo) + original_size = (image.width, image.height) + + if (image.width and image.height) < 512: + size1 = image.width + size2 = image.height + if image.width > image.height: + scale = 512 / size1 + size1new = 512 + size2new = size2 * scale + else: + scale = 512 / size2 + size1new = size1 * scale + size2new = 512 + size1new = math.floor(size1new) + size2new = math.floor(size2new) + sizenew = (size1new, size2new) + image = image.resize(sizenew) else: - scale = 512 / size2 - size1new = size1 * scale - size2new = 512 - size1new = math.floor(size1new) - size2new = math.floor(size2new) - sizenew = (size1new, size2new) - image = image.resize(sizenew) - else: - maxsize = (512, 512) - image.thumbnail(maxsize) - return image + maxsize = (512, 512) + image.thumbnail(maxsize) + + LOGS.info(f"Resized image from {original_size} to {image.size}") + return image + except Exception as e: + LOGS.exception(f"Error in resize_photo_sticker: {str(e)}") + raise @staticmethod async def ffmpeg_convert(input_, output, remove=False): @@ -803,9 +839,11 @@ async def ffmpeg_convert(input_, output, remove=False): input_, name=output[:-5], remove=remove ) if output.endswith(".gif"): - await bash(f"ffmpeg -i '{input_}' -an -sn -c:v copy '{output}.mp4' -y") + out, er = await bash(f"ffmpeg -i '{input_}' -an -sn -c:v copy '{output}.mp4' -y") + LOGS.info(f"FFmpeg output: {out}, Error: {er}") else: - await bash(f"ffmpeg -i '{input_}' '{output}' -y") + out, er = await bash(f"ffmpeg -i '{input_}' '{output}' -y") + LOGS.info(f"FFmpeg output: {out}, Error: {er}") if remove: os.remove(input_) if os.path.exists(output): @@ -813,35 +851,80 @@ async def ffmpeg_convert(input_, output, remove=False): @staticmethod async def create_webm(file, name="video", remove=False): - _ = await metadata(file) - name += ".webm" - h, w = _["height"], _["width"] - if h == w and h != 512: - h, w = 512, 512 - if h != 512 or w != 512: - if h > w: - h, w = 512, -1 - if w > h: - h, w = -1, 512 - await bash( - f'ffmpeg -i "{file}" -preset fast -an -to 00:00:03 -crf 30 -bufsize 256k -b:v {_["bitrate"]} -vf "scale={w}:{h},fps=30" -c:v libvpx-vp9 "{name}" -y' - ) - if remove: - os.remove(file) - return name + LOGS.info(f"Creating webm: {file} -> {name}.webm") + try: + _ = await metadata(file) + name += ".webm" + h, w = _["height"], _["width"] + + if h == w and h != 512: + h, w = 512, 512 + if h != 512 or w != 512: + if h > w: + h, w = 512, -1 + if w > h: + h, w = -1, 512 + + await bash( + f'ffmpeg -i "{file}" -preset fast -an -to 00:00:03 -crf 30 -bufsize 256k -b:v {_["bitrate"]} -vf "scale={w}:{h},fps=30" -c:v libvpx-vp9 "{name}" -y' + ) + + if remove and os.path.exists(file): + os.remove(file) + LOGS.info(f"Removed original file: {file}") + + if os.path.exists(name): + LOGS.info(f"Successfully created webm: {name}") + return name + + LOGS.error(f"Webm creation failed - output file not created: {name}") + return None + except Exception as e: + LOGS.exception(f"Error in create_webm: {str(e)}") + return None @staticmethod def to_image(input_, name, remove=False): + """Convert video/gif to image using first frame.""" + LOGS.info(f"Converting to image: {input_} -> {name}") try: - import cv2 - except ImportError: - raise DependencyMissingError("This function needs 'cv2' to be installed.") - img = cv2.VideoCapture(input_) - ult, roid = img.read() - cv2.imwrite(name, roid) - if remove: - os.remove(input_) - return name + if not input_: + LOGS.error("Input file is None") + return None + + if not os.path.exists(input_): + LOGS.error(f"Input file does not exist: {input_}") + return None + + try: + import cv2 + except ImportError: + raise DependencyMissingError("This function needs 'cv2' to be installed.") + + img = cv2.VideoCapture(input_) + success, frame = img.read() + + if not success: + LOGS.error(f"Failed to read frame from {input_}") + return None + + cv2.imwrite(name, frame) + img.release() + + if not os.path.exists(name): + LOGS.error(f"Failed to save image: {name}") + return None + + if remove and os.path.exists(input_): + os.remove(input_) + LOGS.info(f"Removed original file: {input_}") + + LOGS.info(f"Successfully converted to image: {name}") + return name + + except Exception as e: + LOGS.exception(f"Error in to_image conversion: {str(e)}") + return None @staticmethod async def convert( @@ -851,9 +934,21 @@ async def convert( allowed_formats=[], remove_old=True, ): + """Convert between different file formats.""" + LOGS.info(f"Converting {input_file} to {convert_to or allowed_formats}") + + if not input_file: + LOGS.error("Input file is None") + return None + + if not os.path.exists(input_file): + LOGS.error(f"Input file does not exist: {input_file}") + return None + if "." in input_file: ext = input_file.split(".")[-1].lower() else: + LOGS.error("Input file has no extension") return input_file if ( @@ -866,60 +961,90 @@ async def convert( def recycle_type(exte): return convert_to == exte or exte in allowed_formats - # Sticker to Something - if ext == "tgs": - for extn in ["webp", "json", "png", "mp4", "gif"]: - if recycle_type(extn): - name = outname + "." + extn - return await TgConverter.animated_sticker( - input_file, name, remove=remove_old + try: + # Sticker to Something + if ext == "tgs": + for extn in ["webp", "json", "png", "mp4", "gif"]: + if recycle_type(extn): + name = outname + "." + extn + result = await TgConverter.animated_sticker( + input_file, name, remove=remove_old + ) + if result: + return result + if recycle_type("webm"): + gif_file = await TgConverter.convert( + input_file, convert_to="gif", remove_old=remove_old ) - if recycle_type("webm"): - input_file = await TgConverter.convert( - input_file, convert_to="gif", remove_old=remove_old - ) - return await TgConverter.create_webm(input_file, outname, remove=True) - # Json -> Tgs - elif ext == "json": - if recycle_type("tgs"): - name = outname + ".tgs" - return await TgConverter.animated_sticker( - input_file, name, remove=remove_old - ) - # Video to Something - elif ext in ["webm", "mp4", "gif"]: - for exte in ["webm", "mp4", "gif"]: - if recycle_type(exte): - name = outname + "." + exte - return await TgConverter.ffmpeg_convert( + if gif_file: + return await TgConverter.create_webm(gif_file, outname, remove=True) + + # Json -> Tgs + elif ext == "json": + if recycle_type("tgs"): + name = outname + ".tgs" + return await TgConverter.animated_sticker( input_file, name, remove=remove_old ) - for exte in ["png", "jpg", "jpeg", "webp"]: - if recycle_type(exte): - name = outname + "." + exte - return TgConverter.to_image(input_file, name, remove=remove_old) - # Image to Something - elif ext in ["jpg", "jpeg", "png", "webp"]: - for extn in ["png", "webp", "ico"]: - if recycle_type(extn): - img = Image.open(input_file) - name = outname + "." + extn - img.save(name, extn.upper()) - if remove_old: - os.remove(input_file) - return name - for extn in ["webm", "gif", "mp4"]: - if recycle_type(extn): - name = outname + "." + extn - if extn == "webm": - input_file = await TgConverter.convert( - input_file, - convert_to="png", - remove_old=remove_old, + + # Video to Something + elif ext in ["webm", "mp4", "gif"]: + for exte in ["webm", "mp4", "gif"]: + if recycle_type(exte): + name = outname + "." + exte + result = await TgConverter.ffmpeg_convert( + input_file, name, remove=remove_old ) - return await TgConverter.ffmpeg_convert( - input_file, name, remove=True if extn == "webm" else remove_old - ) + if result: + return result + + for exte in ["png", "jpg", "jpeg", "webp"]: + if recycle_type(exte): + name = outname + "." + exte + result = TgConverter.to_image(input_file, name, remove=remove_old) + if result: + return result + + # Image to Something + elif ext in ["jpg", "jpeg", "png", "webp"]: + for extn in ["png", "webp", "ico"]: + if recycle_type(extn): + try: + img = Image.open(input_file) + name = outname + "." + extn + img.save(name, extn.upper()) + if remove_old and os.path.exists(input_file): + os.remove(input_file) + LOGS.info(f"Removed original file: {input_file}") + return name + except Exception as e: + LOGS.error(f"Failed to convert image to {extn}: {str(e)}") + continue + + for extn in ["webm", "gif", "mp4"]: + if recycle_type(extn): + name = outname + "." + extn + if extn == "webm": + png_file = await TgConverter.convert( + input_file, + convert_to="png", + remove_old=remove_old, + ) + if png_file: + return await TgConverter.ffmpeg_convert( + png_file, name, remove=True + ) + else: + return await TgConverter.ffmpeg_convert( + input_file, name, remove=remove_old + ) + + LOGS.error(f"No valid conversion found for {input_file} to {convert_to or allowed_formats}") + return None + + except Exception as e: + LOGS.exception(f"Error in convert: {str(e)}") + return None def _get_value(stri): diff --git a/pyUltroid/startup/BaseClient.py b/pyUltroid/startup/BaseClient.py index 763159ce00..603121b52e 100644 --- a/pyUltroid/startup/BaseClient.py +++ b/pyUltroid/startup/BaseClient.py @@ -128,6 +128,7 @@ async def fast_uploader(self, file, **kwargs): with contextlib.suppress(FileNotFoundError): os.remove(file) return files["raw_file"], time.time() - start_time + from pyUltroid.fns.FastTelethon import upload_file from pyUltroid.fns.helper import progress diff --git a/pyUltroid/version.py b/pyUltroid/version.py index 2bd0e369e0..a74d67585c 100644 --- a/pyUltroid/version.py +++ b/pyUltroid/version.py @@ -1,2 +1,2 @@ __version__ = "2025.02.19" -ultroid_version = "2.0" +ultroid_version = "2.1" diff --git a/requirements.txt b/requirements.txt index 30d2f64832..6231f99240 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,11 @@ # Important Requirements here. telethon -# https://github.com/TeamUltroid/Telethon/archive/ultroid.zip https://github.com/New-dev0/Telethon-Patch/archive/main.zip python-decouple python-dotenv +telegraph +enhancer +requests +aiohttp +catbox-uploader +cloudscraper \ No newline at end of file diff --git a/resources/startup/locals.py b/resources/startup/locals.py index 94b1f68af0..024cef3322 100644 --- a/resources/startup/locals.py +++ b/resources/startup/locals.py @@ -76,6 +76,7 @@ def start(): print("\nCongrats. All done!\nTime to start the bot!") print("\nInstalling requirements... This might take a while...") os.system("pip3 install --no-cache-dir -r requirements.txt") + os.system("pip3 install -r requirements.txt --break-system-packages") ask = input( "Enter 'yes/y' to Install other requirements, required for local deployment." ) diff --git a/resources/startup/optional-requirements.txt b/resources/startup/optional-requirements.txt index 224c30080a..2d5fe5806a 100644 --- a/resources/startup/optional-requirements.txt +++ b/resources/startup/optional-requirements.txt @@ -1,7 +1,7 @@ # Required only for Local Deploys # ------------------------------------------------------ # -git+https://github.com/ufoptg/akipy.git +akipy apscheduler aiohttp bs4 From 750fff6de6dde88f71ab8664c20e3934ffdd9361 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Sun, 23 Feb 2025 09:13:59 +0530 Subject: [PATCH 4/5] Potential fix for code scanning alert no. 36: Incomplete URL substring sanitization Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- plugins/twitter.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/twitter.py b/plugins/twitter.py index 81dbe534a4..06613cee2c 100644 --- a/plugins/twitter.py +++ b/plugins/twitter.py @@ -81,8 +81,10 @@ async def twitter_details(event): msg = await event.eor("🔍 `Getting tweet details...`") try: client = await get_client() - if "twitter.com" in match or "x.com" in match: - tweet_id = match.split("/")[-1].split("?")[0] + from urllib.parse import urlparse + parsed_url = urlparse(match) + if parsed_url.hostname in ["twitter.com", "x.com"]: + tweet_id = parsed_url.path.split("/")[-1].split("?")[0] else: tweet_id = match From 1bcd29d78118c202cd0bf8c19f83937b93824e55 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Sun, 23 Feb 2025 09:15:54 +0530 Subject: [PATCH 5/5] Update version.py --- pyUltroid/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyUltroid/version.py b/pyUltroid/version.py index a74d67585c..791e5438e3 100644 --- a/pyUltroid/version.py +++ b/pyUltroid/version.py @@ -1,2 +1,2 @@ -__version__ = "2025.02.19" +__version__ = "2025.02.23" ultroid_version = "2.1"