From 9a9bb940b99a0491c14977c7dc4e571668cbe584 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Mon, 29 May 2023 16:25:21 +0530 Subject: [PATCH 01/74] https://t.me/UltroidDevChat/4810 --- modules/assistant/start.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/assistant/start.py b/modules/assistant/start.py index cffe0ad676..fcbe82cd00 100644 --- a/modules/assistant/start.py +++ b/modules/assistant/start.py @@ -177,7 +177,7 @@ async def ekekdhdb(e): @callback("mainmenu", owner=True, func=lambda x: not x.is_group) async def ultroid(event): await event.edit( - get_string("ast_3").format(ultroid_bot.full_name), + get_string("ast_3").format(get_display_name(event.sender)), buttons=_start, ) From 1371b506850326413dd672b81b7974ed0f7e85c7 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Fri, 16 Jun 2023 10:58:40 +0530 Subject: [PATCH 02/74] Commit at right repo --- core/__main__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/__main__.py b/core/__main__.py index 07f4570007..557067fcd9 100644 --- a/core/__main__.py +++ b/core/__main__.py @@ -14,7 +14,7 @@ from utilities.helper import bash, time_formatter, check_update from .utils.funcs import process_main, load_plugins - +from telethon.errors import SessionRevokedError # Option to Auto Update On Restarts.. # TODO: UPDATE_ON_RESTART @@ -50,5 +50,10 @@ ---------------------------------------------------------------------- """ ) +try: + asst.run() +except SessionRevokedError: + LOGS.info(f"Assistant [@{asst.me.username}]'s session was revoked!") -asst.run() + # shift loop to bot + ultroid_bot.run() From 1f009eb34c21043b3a70315bb87c9d65d30fe9f1 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Sun, 18 Jun 2023 13:58:31 +0530 Subject: [PATCH 03/74] hmm --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index e399829178..6b7da0bf3d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ # Important Requirements here. requests -# https://github.com/TeamUltroid/Telethon/archive/ultroid.zip -telethon +https://github.com/TeamUltroid/Telethon/archive/ultroid.zip +# telethon python-decouple telethon-patch tgcrypto From fd912ed4c35bba0a097e7eb706cea57e36e3eb95 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Sun, 18 Jun 2023 15:07:19 +0530 Subject: [PATCH 04/74] Add file which I hate most --- core/__init__.py | 1 - core/utils/__init__.py | 6 +- core/utils/funcs.py | 19 +- modules/__init__.py | 1 + modules/assistant/callbacks.py | 1277 ++++++++++++++++++++++++++++++++ modules/basic/_help.py | 13 +- modules/basic/database.py | 6 +- utilities/admins.py | 15 +- utilities/helper.py | 2 +- 9 files changed, 1308 insertions(+), 32 deletions(-) create mode 100644 modules/assistant/callbacks.py diff --git a/core/__init__.py b/core/__init__.py index b60edc729d..c5c8b891e4 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -8,7 +8,6 @@ import sys import telethonpatch # pylint: disable=unused-import - import time from .config import Var from .setup import * diff --git a/core/utils/__init__.py b/core/utils/__init__.py index 7ee05d276d..5aacaecfc8 100644 --- a/core/utils/__init__.py +++ b/core/utils/__init__.py @@ -5,12 +5,14 @@ def isMultiClient(): if getArg := list(filter(re.compile("--run=(.*)").match, sys.argv)): runCode = getArg[0].split("=")[-1] else: - return + return startMultiClient() _session = getattr(Config, f"SESSION{runCode}") _db = _get_db(runCode) + _botToken = getattr(Config, f"BOT_TOKEN{runCode}") + if not (_db and _session): return - return runCode, _session + return runCode, _session, _botToken def _get_db(count): diff --git a/core/utils/funcs.py b/core/utils/funcs.py index 031a80a848..81372d7fac 100644 --- a/core/utils/funcs.py +++ b/core/utils/funcs.py @@ -1,5 +1,5 @@ import asyncio -import os +import os, sys import time from core import LOGS, asst, udB, ultroid_bot @@ -99,6 +99,11 @@ def setup_addons(): async def load_plugins(): + # TODO: REMOVE + if "no-addons" in sys.argv: + load(path=["modules/basic"]) + return + # GET: Addons plugins plugins = None @@ -142,12 +147,12 @@ async def fetch_all(end="getallplugins", folder="addons", **kwargs): with rm.get("pmbot", helper=True, dispose=True): LOGS.info("Loaded PMBOT.") - if udB.get_config("VCBOT"): - try: - with rm.get("setup_vcbot", helper=True, dispose=True) as mod: - await mod.setup() - except Exception as er: - LOGS.exception(er) + # if udB.get_config("VCBOT"): + # try: + # with rm.get("setup_vcbot", helper=True, dispose=True) as mod: + # await mod.setup() + # except Exception as er: + # LOGS.exception(er) if not udB.get_key("INIT_DEPLOY"): udB.set_key("INIT_DEPLOY", True) diff --git a/modules/__init__.py b/modules/__init__.py index f3e03674d8..756b10397f 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -30,6 +30,7 @@ def inline_pic(get=False): return INLINE_PIC # is False, return None +udB.on("LOAD_ALL", "delete", lambda: os.rmdir("modules/addons")) List = [] Dict = {} diff --git a/modules/assistant/callbacks.py b/modules/assistant/callbacks.py new file mode 100644 index 0000000000..e73f3de1d0 --- /dev/null +++ b/modules/assistant/callbacks.py @@ -0,0 +1,1277 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +import ast +import asyncio +import re +import sys, os +import time +from asyncio.exceptions import TimeoutError as AsyncTimeOut +from os import execl, remove +from random import choice + +from bs4 import BeautifulSoup as bs +from core import HNDLR, udB, LOGS, Var +from database.helpers import get_random_color +# try: +# from pyUltroid.fns.gDrive import GDriveManager +# except ImportError: +# GDriveManager = None +from telegraph import upload_file as upl +from telethon import Button, events +from telethon.tl.types import MessageMediaWebPage +from telethon.utils import get_peer_id +from localization import get_string + +from utilities.helper import fast_download, progress +from utilities.tools import Carbon, async_searcher #, get_paste, telegraph_client +#from pyUltroid.startup.loader import Loader +from telethon.tl import types +from . import callback, get_back_button, asst + +# --------------------------------------------------------------------# +# telegraph = telegraph_client() +# GDrive = GDriveManager() if GDriveManager else None +# --------------------------------------------------------------------# + +async def setit(_, key, value): + udB.set_key(key, value) + +def text_to_url(event): + """function to get media url (with|without) Webpage""" + if isinstance(event.media, MessageMediaWebPage): + webpage = event.media.webpage + if not isinstance(webpage, types.WebPageEmpty) and webpage.type in ["photo"]: + return webpage.display_url + return event.text + + +# --------------------------------------------------------------------# + +_buttons = { + "otvars": { + "text": "Other Variables to set for @TeamUltroid:", + "buttons": [ + [ + Button.inline("Tᴀɢ Lᴏɢɢᴇʀ", data="taglog"), + Button.inline("SᴜᴘᴇʀFʙᴀɴ", data="cbs_sfban"), + ], + [ + Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ", data="sudo"), + Button.inline("Hᴀɴᴅʟᴇʀ", data="hhndlr"), + ], + [ + Button.inline("Exᴛʀᴀ Pʟᴜɢɪɴs", data="plg"), + Button.inline("Aᴅᴅᴏɴs", data="eaddon"), + ], + [ + Button.inline("Eᴍᴏᴊɪ ɪɴ Hᴇʟᴘ", data="emoj"), + Button.inline("Sᴇᴛ ɢDʀɪᴠᴇ", data="gdrive"), + ], + [ + Button.inline("Iɴʟɪɴᴇ Pɪᴄ", data="inli_pic"), + Button.inline("Sᴜᴅᴏ HNDLR", data="shndlr"), + ], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ", "cbs_oofdm")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "sfban": { + "text": "SuperFban Settings:", + "buttons": [ + [Button.inline("FBᴀɴ Gʀᴏᴜᴘ", data="sfgrp")], + [Button.inline("Exᴄʟᴜᴅᴇ Fᴇᴅs", data="abs_sfexf")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], + ], + }, + "apauto": { + "text": "This'll auto approve on outgoing messages", + "buttons": [ + [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ ON", data="apon")], + [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ OFF", data="apof")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], + ], + }, + "alvcstm": { + "text": f"Customise your {HNDLR}alive. Choose from the below options -", + "buttons": [ + [Button.inline("Aʟɪᴠᴇ Tᴇxᴛ", data="abs_alvtx")], + [Button.inline("Aʟɪᴠᴇ ᴍᴇᴅɪᴀ", data="alvmed")], + [Button.inline("Dᴇʟᴇᴛᴇ Aʟɪᴠᴇ Mᴇᴅɪᴀ", data="delmed")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "pmcstm": { + "text": "Customise your PMPERMIT Settings -", + "buttons": [ + [ + Button.inline("Pᴍ Tᴇxᴛ", data="pmtxt"), + Button.inline("Pᴍ Mᴇᴅɪᴀ", data="pmmed"), + ], + [ + Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ", data="cbs_apauto"), + Button.inline("PMLOGGER", data="pml"), + ], + [ + Button.inline("Sᴇᴛ Wᴀʀɴs", data="swarn"), + Button.inline("Dᴇʟᴇᴛᴇ Pᴍ Mᴇᴅɪᴀ", data="delpmmed"), + ], + [Button.inline("PMPermit Type", data="cbs_pmtype")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")], + ], + }, + "pmtype": { + "text": "Select the type of PMPermit needed.", + "buttons": [ + [Button.inline("Inline", data="inpm_in")], + [Button.inline("Normal", data="inpm_no")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], + ], + }, + "ppmset": { + "text": "PMPermit Settings:", + "buttons": [ + [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oɴ", data="pmon")], + [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oғғ", data="pmoff")], + [Button.inline("Cᴜsᴛᴏᴍɪᴢᴇ PMPᴇʀᴍɪᴛ", data="cbs_pmcstm")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "chatbot": { + "text": "From This Feature U can chat with ppls Via ur Assistant Bot.\n[More info](https://t.me/UltroidUpdates/2)", + "buttons": [ + [ + Button.inline("Cʜᴀᴛ Bᴏᴛ Oɴ", data="onchbot"), + Button.inline("Cʜᴀᴛ Bᴏᴛ Oғғ", data="ofchbot"), + ], + [ + Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ", data="bwel"), + Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ Mᴇᴅɪᴀ", data="botmew"), + ], + [Button.inline("Bᴏᴛ Iɴғᴏ Tᴇxᴛ", data="botinfe")], + [Button.inline("Fᴏʀᴄᴇ Sᴜʙsᴄʀɪʙᴇ", data="pmfs")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "vcb": { + "text": "From This Feature U can play songs in group voice chat\n\n[moreinfo](https://t.me/UltroidUpdates/4)", + "buttons": [ + [Button.inline("VC Sᴇssɪᴏɴ", data="abs_vcs")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "oofdm": { + "text": "About [Dual Mode](https://t.me/UltroidUpdates/18)", + "buttons": [ + [ + Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oɴ", "dmof"), + Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oғғ", "dmof"), + ], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Hɴᴅʟʀ", "dmhn")], + [Button.inline("« Back", data="cbs_otvars")], + ], + }, + "apiset": { + "text": get_string("ast_1"), + "buttons": [ + [Button.inline("Remove.bg API", data="abs_rmbg")], + [Button.inline("DEEP API", data="abs_dapi")], + [Button.inline("OCR API", data="abs_oapi")], + [Button.inline("« Back", data="setter")], + ], + }, +} + +_convo = { + "rmbg": { + "var": "RMBG_API", + "name": "Remove.bg API Key", + "text": get_string("ast_2"), + "back": "cbs_apiset", + }, + "dapi": { + "var": "DEEP_AI", + "name": "Deep AI Api Key", + "text": "Get Your Deep Api from deepai.org and send here.", + "back": "cbs_apiset", + }, + "oapi": { + "var": "OCR_API", + "name": "Ocr Api Key", + "text": "Get Your OCR api from ocr.space and send that Here.", + "back": "cbs_apiset", + }, + "pmlgg": { + "var": "PMLOGGROUP", + "name": "Pm Log Group", + "text": "Send chat id of chat which you want to save as Pm log Group.", + "back": "pml", + }, + "vcs": { + "var": "VC_SESSION", + "name": "Vc Session", + "text": "**Vc session**\nEnter the New session u generated for vc bot.\n\nUse /cancel to terminate the operation.", + "back": "cbs_vcb", + }, + "settag": { + "var": "TAG_LOG", + "name": "Tag Log Group", + "text": f"Make a group, add your assistant and make it admin.\nGet the `{HNDLR}id` of that group and send it here for tag logs.\n\nUse /cancel to cancel.", + "back": "taglog", + }, + "alvtx": { + "var": "ALIVE_TEXT", + "name": "Alive Text", + "text": "**Alive Text**\nEnter the new alive text.\n\nUse /cancel to terminate the operation.", + "back": "cbs_alvcstm", + }, + "sfexf": { + "var": "EXCLUDE_FED", + "name": "Excluded Fed", + "text": "Send the Fed IDs you want to exclude in the ban. Split by a space.\neg`id1 id2 id3`\nSet is as `None` if you dont want any.\nUse /cancel to go back.", + "back": "cbs_sfban", + }, +} + + +TOKEN_FILE = "resources/auths/auth_token.txt" + + +@callback( + re.compile( + "sndplug_(.*)", + ), + owner=True, +) +async def send(eve): + key, name = (eve.data_match.group(1)).decode("UTF-8").split("_") + thumb = "resources/extras/inline.jpg" + await eve.answer("■ Sending ■") + data = f"uh_{key}_" + index = None + if "|" in name: + name, index = name.split("|") + key = "plugins" if key == "Official" else key.lower() + plugin = f"{key}/{name}.py" + _ = f"pasta-{plugin}" + if index is not None: + data += f"|{index}" + _ += f"|{index}" + buttons = [ + [ + Button.inline( + "« Pᴀsᴛᴇ »", + data=_, + ) + ], + [ + Button.inline("« Bᴀᴄᴋ", data=data), + ], + ] + try: + await eve.edit(file=plugin, thumb=thumb, buttons=buttons) + except Exception as er: + await eve.answer(str(er), alert=True) + + +heroku_api, app_name = Var.HEROKU_API, Var.HEROKU_APP_NAME + + +@callback("updatenow", owner=True) +async def update(eve): + repo = Repo() + ac_br = repo.active_branch + ups_rem = repo.remote("upstream") + if heroku_api: + import heroku3 + + try: + heroku = heroku3.from_key(heroku_api) + heroku_app = None + heroku_applications = heroku.apps() + except BaseException as er: + LOGS.exception(er) + return await eve.edit("`Wrong HEROKU_API.`") + for app in heroku_applications: + if app.name == app_name: + heroku_app = app + if not heroku_app: + await eve.edit("`Wrong HEROKU_APP_NAME.`") + repo.__del__() + return + await eve.edit(get_string("clst_1")) + ups_rem.fetch(ac_br) + repo.git.reset("--hard", "FETCH_HEAD") + heroku_git_url = heroku_app.git_url.replace( + "https://", f"https://api:{heroku_api}@" + ) + + if "heroku" in repo.remotes: + remote = repo.remote("heroku") + remote.set_url(heroku_git_url) + else: + remote = repo.create_remote("heroku", heroku_git_url) + try: + remote.push(refspec=f"HEAD:refs/heads/{ac_br}", force=True) + except GitCommandError as error: + await eve.edit(f"`Here is the error log:\n{error}`") + repo.__del__() + return + await eve.edit("`Successfully Updated!\nRestarting, please wait...`") + else: + await eve.edit(get_string("clst_1")) + call_back() + await bash("git pull && pip3 install -r requirements.txt") + execl(sys.executable, sys.executable, "-m", "pyUltroid") + + + + +@callback( + re.compile( + "pasta-(.*)", + ), + owner=True, +) +async def _(e): + ok = (e.data_match.group(1)).decode("UTF-8") + index = None + 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 _: + return await e.answer(key[:30], alert=True) + if ok.startswith("addons"): + key = "Addons" + elif ok.startswith("vcbot"): + key = "VCBot" + else: + key = "Official" + data = f"uh_{key}_" + if index is not None: + data += f"|{index}" + await e.edit( + "", + buttons=[ + [Button.url("Lɪɴᴋ", link), Button.url("Rᴀᴡ", raw)], + [Button.inline("« Bᴀᴄᴋ", data=data)], + ], + ) + + +@callback(re.compile("cbs_(.*)"), owner=True) +async def _edit_to(event): + match = event.data_match.group(1).decode("utf-8") + data = _buttons.get(match) + if not data: + return + await event.edit(data["text"], buttons=data["buttons"], link_preview=False) + + +@callback(re.compile("abs_(.*)"), owner=True) +async def convo_handler(event: events.CallbackQuery): + match = event.data_match.group(1).decode("utf-8") + if not _convo.get(match): + return + await event.delete() + get_ = _convo[match] + back = get_["back"] + async with event.client.conversation(event.sender_id) as conv: + await conv.send_message(get_["text"]) + response = await conv.get_response() + themssg = response.message + try: + themssg = ast.literal_eval(themssg) + except Exception: + pass + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button(back), + ) + await setit(event, get_["var"], themssg) + await conv.send_message( + f"{get_['name']} changed to `{themssg}`", + buttons=get_back_button(back), + ) + + +@callback("authorise", owner=True) +async def _(e): + if not e.is_private: + return + url = GDrive._create_token_file() + await e.edit("Go to the below link and send the code!") + async with asst.conversation(e.sender_id) as conv: + await conv.send_message(url) + code = await conv.get_response() + if GDrive._create_token_file(code=code.text): + await conv.send_message( + "`Success!\nYou are all set to use Google Drive with Ultroid Userbot.`", + buttons=Button.inline("Main Menu", data="setter"), + ) + else: + await conv.send_message("Wrong code! Click authorise again.") + + +@callback("folderid", owner=True, func=lambda x: x.is_private) +async def _(e): + if not e.is_private: + return + msg = ( + "Send your FOLDER ID\n\n" + + "For FOLDER ID:\n" + + "1. Open Google Drive App.\n" + + "2. Create Folder.\n" + + "3. Make that folder public.\n" + + "4. Send link of that folder." + ) + await e.delete() + async with asst.conversation(e.sender_id, timeout=150) as conv: + await conv.send_message(msg) + repl = await conv.get_response() + id = repl.text + if id.startswith("https"): + id = id.split("?id=")[-1] + udB.set_key("GDRIVE_FOLDER_ID", id) + await repl.reply( + "`Success.`", + buttons=get_back_button("gdrive"), + ) + + +@callback("gdrive", owner=True) +async def _(e): + if not e.is_private: + return + await e.edit( + "Click Authorise and send the code.\n\nYou can use your own CLIENT ID and SECRET by [this](https://t.me/UltroidUpdates/37)", + buttons=[ + [ + Button.inline("Folder ID", data="folderid"), + Button.inline("Authorise", data="authorise"), + ], + [Button.inline("« Back", data="cbs_otvars")], + ], + link_preview=False, + ) + + +@callback("dmof", owner=True) +async def rhwhe(e): + if udB.get_key("DUAL_MODE"): + udB.del_key("DUAL_MODE") + key = "Off" + else: + udB.set_key("DUAL_MODE", "True") + key = "On" + Msg = f"Dual Mode : {key}" + await e.edit(Msg, buttons=get_back_button("cbs_otvars")) + + +@callback("dmhn", owner=True) +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "DUAL_HNDLR" + name = "Dual Handler" + CH = udB.get_key(var) or "/" + async with event.client.conversation(pru) as conv: + await conv.send_message( + f"Send The Symbol Which u want as Handler/Trigger to use your Assistant bot\nUr Current Handler is [ `{CH}` ]\n\n use /cancel to cancel.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("emoj", owner=True) +async def emoji(event): + await event.delete() + pru = event.sender_id + var = "EMOJI_IN_HELP" + name = f"Emoji in `{HNDLR}help` menu" + async with event.client.conversation(pru) as conv: + await conv.send_message("Send emoji u want to set 🙃.\n\nUse /cancel to cancel.") + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", HNDLR)): + await conv.send_message( + "Incorrect Emoji", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("plg", owner=True) +async def pluginch(event): + await event.delete() + pru = event.sender_id + var = "PLUGIN_CHANNEL" + name = "Plugin Channel" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "Send id or username of a channel from where u want to install all plugins\n\nOur Channel~ @ultroidplugins\n\nUse /cancel to cancel.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", HNDLR)): + await conv.send_message( + "Incorrect channel", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n After Setting All Things Do Restart", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("hhndlr", owner=True) +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "HNDLR" + name = "Handler/ Trigger" + async with event.client.conversation(pru) as conv: + await conv.send_message( + f"Send The Symbol Which u want as Handler/Trigger to use bot\nUr Current Handler is [ `{HNDLR}` ]\n\n use /cancel to cancel.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", "#", "@")): + await conv.send_message( + "This cannot be used as handler", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("shndlr", owner=True) +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "SUDO_HNDLR" + name = "Sudo Handler" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "Send The Symbol Which u want as Sudo Handler/Trigger to use bot\n\n use /cancel to cancel." + ) + + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", "#", "@")): + await conv.send_message( + "This cannot be used as handler", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("taglog", owner=True) +async def tagloggrr(e): + BUTTON = [ + [Button.inline("SET TAG LOG", data="abs_settag")], + [Button.inline("DELETE TAG LOG", data="deltag")], + get_back_button("cbs_otvars"), + ] + await e.edit( + "Choose Options", + buttons=BUTTON, + ) + + +@callback("deltag", owner=True) +async def _(e): + udB.del_key("TAG_LOG") + await e.answer("Done!!! Tag Logger has been turned Off") + + +@callback("eaddon", owner=True) +async def pmset(event): + BT = ( + [Button.inline("Aᴅᴅᴏɴs Oғғ", data="edof")] + if udB.get_key("ADDONS") + else [Button.inline("Aᴅᴅᴏɴs Oɴ", data="edon")] + ) + + await event.edit( + "ADDONS~ Extra Plugins:", + buttons=[ + BT, + [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], + ], + ) + + +@callback("edon", owner=True) +async def eddon(event): + var = "ADDONS" + await setit(event, var, "True") + await event.edit( + "Done! ADDONS has been turned on!!\n\n After Setting All Things Do Restart", + buttons=get_back_button("eaddon"), + ) + + +@callback("edof", owner=True) +async def eddof(event): + udB.set_key("ADDONS", "False") + await event.edit( + "Done! ADDONS has been turned off!! After Setting All Things Do Restart", + buttons=get_back_button("eaddon"), + ) + + +@callback("sudo", owner=True) +async def pmset(event): + BT = ( + [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oғғ", data="ofsudo")] + if udB.get_key("SUDO") + else [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oɴ", data="onsudo")] + ) + + await event.edit( + f"SUDO MODE ~ Some peoples can use ur Bot which u selected. To know More use `{HNDLR}help sudo`", + buttons=[ + BT, + [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], + ], + ) + + +@callback("onsudo", owner=True) +async def eddon(event): + var = "SUDO" + await setit(event, var, "True") + await event.edit( + "Done! SUDO MODE has been turned on!!\n\n After Setting All Things Do Restart", + buttons=get_back_button("sudo"), + ) + + +@callback("ofsudo", owner=True) +async def eddof(event): + var = "SUDO" + await setit(event, var, "False") + await event.edit( + "Done! SUDO MODE has been turned off!! After Setting All Things Do Restart", + buttons=get_back_button("sudo"), + ) + + +@callback("sfgrp", owner=True) +async def sfgrp(event): + await event.delete() + name = "FBan Group ID" + var = "FBAN_GROUP_ID" + pru = event.sender_id + async with asst.conversation(pru) as conv: + await conv.send_message( + f"Make a group, add @MissRose_Bot, send `{HNDLR}id`, copy that and send it here.\nUse /cancel to go back.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_sfban"), + ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_sfban"), + ) + + +@callback("alvmed", owner=True) +async def media(event): + await event.delete() + pru = event.sender_id + var = "ALIVE_PIC" + name = "Alive Media" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**Alive Media**\nSend me a pic/gif/media to set as alive media.\n\nUse /cancel to terminate the operation.", + ) + response = await conv.get_response() + try: + themssg = response.message + if themssg == "/cancel": + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("cbs_alvcstm"), + ) + except BaseException as er: + LOGS.exception(er) + if ( + not (response.text).startswith("/") + and response.text != "" + and (not response.media or isinstance(response.media, MessageMediaWebPage)) + ): + url = text_to_url(response) + elif response.sticker: + url = response.file.id + else: + media = await event.client.download_media(response, "alvpc") + try: + x = upl(media) + url = f"https://graph.org/{x[0]}" + remove(media) + except BaseException as er: + LOGS.exception(er) + return await conv.send_message( + "Terminated.", + buttons=get_back_button("cbs_alvcstm"), + ) + await setit(event, var, url) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("cbs_alvcstm"), + ) + + +@callback("delmed", owner=True) +async def dell(event): + try: + udB.del_key("ALIVE_PIC") + return await event.edit( + get_string("clst_5"), buttons=get_back_button("cbs_alabs_vcstm") + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=get_back_button("cbs_alabs_vcstm"), + ) + + +@callback("inpm_in", owner=True) +async def inl_on(event): + var = "INLINE_PM" + await setit(event, var, "True") + await event.edit( + "Done!! PMPermit type has been set to inline!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]], + ) + + +@callback("inpm_no", owner=True) +async def inl_on(event): + var = "INLINE_PM" + await setit(event, var, "False") + await event.edit( + "Done!! PMPermit type has been set to normal!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]], + ) + + +@callback("pmtxt", owner=True) +async def name(event): + await event.delete() + pru = event.sender_id + var = "PM_TEXT" + name = "PM Text" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**PM Text**\nEnter the new Pmpermit text.\n\nu can use `{name}` `{fullname}` `{count}` `{mention}` `{username}` to get this from user Too\n\nUse /cancel to terminate the operation.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_pmcstm"), + ) + if len(themssg) > 4090: + return await conv.send_message( + "Message too long!\nGive a shorter message please!!", + buttons=get_back_button("cbs_pmcstm"), + ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n\nAfter Setting All Things Do restart", + buttons=get_back_button("cbs_pmcstm"), + ) + + +@callback("swarn", owner=True) +async def name(event): + m = range(1, 10) + tultd = [Button.inline(f"{x}", data=f"wrns_{x}") for x in m] + lst = list(zip(tultd[::3], tultd[1::3], tultd[2::3])) + lst.append([Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")]) + await event.edit( + "Select the number of warnings for a user before getting blocked in PMs.", + buttons=lst, + ) + + +@callback(re.compile(b"wrns_(.*)"), owner=True) +async def set_wrns(event): + value = int(event.data_match.group(1).decode("UTF-8")) + if dn := udB.set_key("PMWARNS", value): + await event.edit( + f"PM Warns Set to {value}.\nNew users will have {value} chances in PMs before getting banned.", + buttons=get_back_button("cbs_pmcstm"), + ) + else: + await event.edit( + f"Something went wrong, please check your {HNDLR}logs!", + buttons=get_back_button("cbs_pmcstm"), + ) + + +@callback("pmmed", owner=True) +async def media(event): + await event.delete() + pru = event.sender_id + var = "PMPIC" + name = "PM Media" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**PM Media**\nSend me a pic/gif/sticker/link to set as pmpermit media.\n\nUse /cancel to terminate the operation.", + ) + response = await conv.get_response() + try: + themssg = response.message + if themssg == "/cancel": + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("cbs_pmcstm"), + ) + except BaseException as er: + LOGS.exception(er) + media = await event.client.download_media(response, "pmpc") + if ( + not (response.text).startswith("/") + and response.text != "" + and (not response.media or isinstance(response.media, MessageMediaWebPage)) + ): + url = text_to_url(response) + elif response.sticker: + url = response.file.id + else: + try: + x = upl(media) + url = f"https://graph.org/{x[0]}" + remove(media) + except BaseException as er: + LOGS.exception(er) + return await conv.send_message( + "Terminated.", + buttons=get_back_button("cbs_pmcstm"), + ) + await setit(event, var, url) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("cbs_pmcstm"), + ) + + +@callback("delpmmed", owner=True) +async def dell(event): + try: + udB.del_key("PMPIC") + return await event.edit( + get_string("clst_5"), buttons=get_back_button("cbs_pmcstm") + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) + + +@callback("apon", owner=True) +async def apon(event): + var = "AUTOAPPROVE" + await setit(event, var, "True") + await event.edit( + "Done!! AUTOAPPROVE Started!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]], + ) + + +@callback("apof", owner=True) +async def apof(event): + try: + udB.set_key("AUTOAPPROVE", "False") + return await event.edit( + "Done! AUTOAPPROVE Stopped!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]], + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) + + +@callback("pml", owner=True) +async def l_vcs(event): + BT = ( + [Button.inline("PMLOGGER OFF", data="pmlogof")] + if udB.get_key("PMLOG") + else [Button.inline("PMLOGGER ON", data="pmlog")] + ) + + await event.edit( + "PMLOGGER This Will Forward Ur Pm to Ur Private Group -", + buttons=[ + BT, + [Button.inline("PᴍLᴏɢɢᴇʀ Gʀᴏᴜᴘ", "abs_pmlgg")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], + ], + ) + + +@callback("pmlog", owner=True) +async def pmlog(event): + await setit(event, "PMLOG", "True") + await event.edit( + "Done!! PMLOGGER Started!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], + ) + + +@callback("pmlogof", owner=True) +async def pmlogof(event): + try: + udB.del_key("PMLOG") + return await event.edit( + "Done! PMLOGGER Stopped!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) + + +@callback("pmon", owner=True) +async def pmonn(event): + var = "PMSETTING" + await setit(event, var, "True") + await event.edit( + "Done! PMPermit has been turned on!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]], + ) + + +@callback("pmoff", owner=True) +async def pmofff(event): + var = "PMSETTING" + await setit(event, var, "False") + await event.edit( + "Done! PMPermit has been turned off!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]], + ) + + +@callback("botmew", owner=True) +async def hhh(e): + async with e.client.conversation(e.chat_id) as conv: + await conv.send_message("Send Any Media to keep at your Bot's welcome ") + msg = await conv.get_response() + if not msg.media or msg.text.startswith("/"): + return await conv.send_message( + "Terminated!", buttons=get_back_button("cbs_chatbot") + ) + udB.set_key("STARTMEDIA", msg.file.id) + await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot")) + + +@callback("botinfe", owner=True) +async def hhh(e): + async with e.client.conversation(e.chat_id) as conv: + await conv.send_message( + "Send message to set to Display, when user Press Info button in Bot Welcome!\n\nsend `False` to completely remove that button.." + ) + msg = await conv.get_response() + if msg.media or msg.text.startswith("/"): + return await conv.send_message( + "Terminated!", buttons=get_back_button("cbs_chatbot") + ) + udB.set_key("BOT_INFO_START", msg.text) + await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot")) + + +@callback("pmfs", owner=True) +async def heheh(event): + Ll = [] + err = "" + async with event.client.conversation(event.chat_id) as conv: + await conv.send_message( + "• Send The Chat Id(s), which you want user to Join Before using Chat/Pm Bot\n\n• Send /clear to disable PmBot Force sub..\n• • Send /cancel to stop this process.." + ) + await conv.send_message( + "Example : \n`-1001234567\n-100778888`\n\nFor Multiple Chat(s)." + ) + try: + msg = await conv.get_response() + except AsyncTimeOut: + return await conv.send_message("**• TimeUp!**\nStart from /start back.") + if not msg.text or msg.text.startswith("/"): + timyork = "Cancelled!" + if msg.text == "/clear": + udB.del_key("PMBOT_FSUB") + timyork = "Done! Force Subscribe Stopped\nRestart your Bot!" + return await conv.send_message( + "Cancelled!", buttons=get_back_button("cbs_chatbot") + ) + for chat in msg.message.split("\n"): + if chat.startswith("-") or chat.isdigit(): + chat = int(chat) + try: + CHSJSHS = await event.client.get_entity(chat) + Ll.append(get_peer_id(CHSJSHS)) + except Exception as er: + err += f"**{chat}** : {er}\n" + if err: + return await conv.send_message(err) + udB.set_key("PMBOT_FSUB", str(Ll)) + await conv.send_message( + "Done!\nRestart Your Bot.", buttons=get_back_button("cbs_chatbot") + ) + + +@callback("bwel", owner=True) +async def name(event): + await event.delete() + pru = event.sender_id + var = "STARTMSG" + name = "Bot Welcome Message:" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**BOT WELCOME MSG**\nEnter the msg which u want to show when someone start your assistant Bot.\nYou Can use `{me}` , `{mention}` Parameters Too\nUse /cancel to terminate the operation.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_chatbot"), + ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_chatbot"), + ) + + +@callback("onchbot", owner=True) +async def chon(event): + var = "PMBOT" + await setit(event, var, "True") + Loader(path="assistant/pmbot.py", key="PM Bot").load() + if AST_PLUGINS.get("pmbot"): + for i, e in AST_PLUGINS["pmbot"]: + event.client.remove_event_handler(i) + for i, e in AST_PLUGINS["pmbot"]: + event.client.add_event_handler(i, events.NewMessage(**e)) + await event.edit( + "Done! Now u Can Chat With People Via This Bot", + buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")], + ) + + +@callback("ofchbot", owner=True) +async def chon(event): + var = "PMBOT" + await setit(event, var, "False") + if AST_PLUGINS.get("pmbot"): + for i, e in AST_PLUGINS["pmbot"]: + event.client.remove_event_handler(i) + await event.edit( + "Done! Chat People Via This Bot Stopped.", + buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")], + ) + + +@callback("inli_pic", owner=True) +async def media(event): + await event.delete() + pru = event.sender_id + var = "INLINE_PIC" + name = "Inline Media" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**Inline Media**\nSend me a pic/gif/ or link to set as inline media.\n\nUse /cancel to terminate the operation.", + ) + response = await conv.get_response() + try: + themssg = response.message + if themssg == "/cancel": + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("setter"), + ) + except BaseException as er: + LOGS.exception(er) + media = await event.client.download_media(response, "inlpic") + if ( + not (response.text).startswith("/") + and response.text != "" + and (not response.media or isinstance(response.media, MessageMediaWebPage)) + ): + url = text_to_url(response) + else: + try: + x = upl(media) + url = f"https://graph.org/{x[0]}" + remove(media) + except BaseException as er: + LOGS.exception(er) + return await conv.send_message( + "Terminated.", + buttons=get_back_button("setter"), + ) + await setit(event, var, url) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("setter"), + ) + + +FD_MEDIA = {} + + +@callback(re.compile("fd(.*)"), owner=True) +async def fdroid_dler(event): + uri = event.data_match.group(1).decode("utf-8") + if FD_MEDIA.get(uri): + return await event.edit(file=FD_MEDIA[uri]) + await event.answer("• Starting Download •", alert=True) + await event.edit("• Downloading.. •") + URL = f"https://f-droid.org/packages/{uri}" + conte = await async_searcher(URL, re_content=True) + BSC = bs(conte, "html.parser", from_encoding="utf-8") + dl_ = BSC.find("p", "package-version-download").find("a")["href"] + title = BSC.find("h3", "package-name").text.strip() + thumb = BSC.find("img", "package-icon")["src"] + if thumb.startswith("/"): + thumb = f"https://f-droid.org{thumb}" + thumb, _ = await fast_download(thumb, filename=f"{uri}.png") + s_time = time.time() + file, _ = await fast_download( + dl_, + filename=f"{title}.apk", + progress_callback=lambda d, t: asyncio.get_event_loop().create_task( + progress( + d, + t, + event, + s_time, + "Downloading...", + ) + ), + ) + + time.time() + n_file = await event.client.fast_uploader( + file, show_progress=True, event=event, message="Uploading...", to_delete=True + ) + buttons = Button.switch_inline("Search Back", query="fdroid", same_peer=True) + try: + msg = await event.edit( + f"**• [{title}]({URL}) •**", file=n_file, thumb=thumb, buttons=buttons + ) + except Exception as er: + LOGS.exception(er) + try: + msg = await event.client.edit_message( + await event.get_input_chat(), + event.message_id, + f"**• [{title}]({URL}) •**", + buttons=buttons, + thumb=thumb, + file=n_file, + ) + except Exception as er: + os.remove(thumb) + LOGS.exception(er) + return await event.edit(f"**ERROR**: `{er}`", buttons=buttons) + if msg and hasattr(msg, "media"): + FD_MEDIA.update({uri: msg.media}) + os.remove(thumb) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 2565fdfa82..25b24d89f7 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -24,7 +24,7 @@ def split_list(List, index): def get_help_buttons(): row_1 = [Button.inline(get_string("help_4"), data="uh_basic_")] - if udB.get_config("ADDONS") or udB.get_key("LOAD_ALL"): + if filter_modules("addons"): # (udB.get_config("ADDONS") or udB.get_key("LOAD_ALL")) row_1.append(Button.inline(get_string("help_5"), data="uh_addons_")) row_2 = [] if udB.get_config("VCBOT"): @@ -259,9 +259,7 @@ def page_num(index, key): if index == 0 and len(fl_) == 1: new_.append([Button.inline("« Bᴀᴄᴋ »", data="open")]) else: - more = len(fl_) > 3 - - nrow = [ + new_.append([ Button.inline( "« Pʀᴇᴠɪᴏᴜs", data=f"uh_{key}_{index-1}", @@ -271,13 +269,8 @@ def page_num(index, key): "Nᴇxᴛ »", data=f"uh_{key}_{index+1}", ), - ] + ]) - if more: - - nrow.insert(0, Button.inline("«", f"uh_{key}_{index-2}")) - nrow.append(Button.inline("»", f"uh_{key}_{index+2}")) - new_.append(nrow) return new_ diff --git a/modules/basic/database.py b/modules/basic/database.py index 02b871682a..5415abd997 100644 --- a/modules/basic/database.py +++ b/modules/basic/database.py @@ -31,10 +31,10 @@ async def _get_cmd(x, varname): - val = udB.get(varname) + val = udB.get_key(varname) if val is not None: - return await x.edit(f"**Key** - `{varname}`\n**Value**: `{val}`") - await eor(x, "No such key!", time=5) + return await x.eor(f"**Key** - `{varname}`\n**Value**: `{val}`") + await x.eor( "No such key!", time=5) @ultroid_cmd(pattern="setdb( (.*)|$)", fullsudo=True) diff --git a/utilities/admins.py b/utilities/admins.py index b56b414d13..34cb14060f 100644 --- a/utilities/admins.py +++ b/utilities/admins.py @@ -13,7 +13,8 @@ from telethon.errors.rpcerrorlist import UserNotParticipantError from telethon.tl import functions, types -from core.decorators import get_sudos,owner_and_sudos +from core.decorators import get_sudos, owner_and_sudos + try: from core import _ult_cache except ImportError: @@ -28,16 +29,15 @@ def ban_time(time_str): time_int = time_str[:-1] if not time_int.isdigit(): raise Exception("Invalid time amount specified.") - to_return = 0 if unit == "s": - to_return = int(time.time() + int(time_int)) + return int(time.time() + int(time_int)) elif unit == "m": - to_return = int(time.time() + int(time_int) * 60) + return int(time.time() + int(time_int) * 60) elif unit == "h": - to_return = int(time.time() + int(time_int) * 60 * 60) + return int(time.time() + int(time_int) * 60 * 60) elif unit == "d": - to_return = int(time.time() + int(time_int) * 24 * 60 * 60) - return to_return + return int(time.time() + int(time_int) * 24 * 60 * 60) + return 0 # ------------------Admin Check--------------- # @@ -124,4 +124,3 @@ async def admin_check(event, require=None, silent: bool = False): await event.eor(f"You are missing the right of `{require}`", time=8) return False return True - diff --git a/utilities/helper.py b/utilities/helper.py index a31340745b..bb4d817c76 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -63,7 +63,7 @@ async def wrapper(*args, **kwargs): def fetch_sync(url, re_json=False, evaluate=None, method="GET", *args, **kwargs): methods = {"POST": requests.post, "HEAD": requests.head, "GET": requests.get} - print("fetching", url) +# print("fetching", url) output = methods.get(method, requests.get)(url, *args, **kwargs) if callable(evaluate): From 13647f7ed03a40fb9b663c08a79e94b972758329 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Sun, 18 Jun 2023 21:34:42 +0530 Subject: [PATCH 05/74] Update tools.py --- utilities/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/tools.py b/utilities/tools.py index 59286a9780..6a82f10446 100644 --- a/utilities/tools.py +++ b/utilities/tools.py @@ -9,7 +9,7 @@ import json import math import os -import random +import random, html import re import secrets import ssl @@ -519,7 +519,7 @@ def translate(text, target="en", detect=False): if not x: return None res = x[0] - text = res["translatedText"].replace("\ N", "\n").replace("\\n", "\n").replace("
", "\n") + text = html.unescape(res["translatedText"].replace("\ N", "\n").replace("\\n", "\n").replace("
", "\n")) return (text, res["detectedSourceLanguage"]) if detect else text atranslate = run_async(translate) From 467847715a19c6dbb55a58ca96d47afa0b94076d Mon Sep 17 00:00:00 2001 From: lanowde <117498666+lanowde@users.noreply.github.com> Date: Mon, 19 Jun 2023 09:00:53 +0530 Subject: [PATCH 06/74] fix for restart and mediainfo. (#415) * fix restart * fix mediainfo AttributeError: 'MessageMediaPhoto' object has no attribute 'audio' --- modules/basic/bot.py | 2 +- utilities/helper.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/basic/bot.py b/modules/basic/bot.py index f034cf593f..e6766777ef 100644 --- a/modules/basic/bot.py +++ b/modules/basic/bot.py @@ -72,7 +72,7 @@ async def restart_func(event): """Restart the bot.""" event = await event.eor("Restarting...") self_ = "bot" if event.client.me.bot else "user" - udB.set_key("_RESTART", [event.chat.username or event.chat_id, event.id, self_]) + udB.set_key("_RESTART", [event.chat_id, event.id, self_]) if HOSTED_ON == "heroku": from core.heroku import restart diff --git a/utilities/helper.py b/utilities/helper.py index bb4d817c76..1b79a635a9 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -236,7 +236,7 @@ def mediainfo(message: Message) -> str: "voice", "document", ]: - if getattr(message, _): + if getattr(message, _, None): if _ == "document": attributes = { DocumentAttributeSticker: "sticker", From e721aa7fcf3ee962d0802bbe262c9769c1071a00 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Mon, 19 Jun 2023 09:04:51 +0530 Subject: [PATCH 07/74] Update mediainfo.py --- modules/basic/mediainfo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/basic/mediainfo.py b/modules/basic/mediainfo.py index 7941140536..e630a62bc5 100644 --- a/modules/basic/mediainfo.py +++ b/modules/basic/mediainfo.py @@ -24,7 +24,7 @@ async def mediainfo_cmd(event): dl = await event.client.fast_downloader( r.document, show_progress=True, - event=e, + event=event, message=f"{extra}`Loading More...`", ) @@ -67,7 +67,7 @@ async def mediainfo_cmd(event): except Exception: LOGS.exception(er) return - await e.edit(f"{extra}[{get_string('mdi_1')}]({urll})", link_preview=False) + await event.eor(f"{extra}[{get_string('mdi_1')}]({urll})", link_preview=False) if not match: os.remove(naam) if thumb and thumb != naam: From a6ee48d67f197c2babb85b7519420f79f275525f Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Tue, 20 Jun 2023 05:20:30 +0530 Subject: [PATCH 08/74] oops --- utilities/helper.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/helper.py b/utilities/helper.py index 1b79a635a9..d4bdf7a090 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -187,11 +187,11 @@ def check_update() -> bool: async def download_file(link, name, validate=False): """for files, without progress callback with aiohttp""" - async def _download(content): - if validate and "application/json" in content.headers.get("Content-Type"): - return None, await content.json() + def _download(response): + if validate and "application/json" in response.headers.get("Content-Type"): + return None, response.json() with open(name, "wb") as file: - file.write(await content.read()) + file.write(response.content) return name, "" return await async_searcher(link, evaluate=_download) From 4af772e32217a36bf48b12db4076647e0cb9f875 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Tue, 20 Jun 2023 16:15:35 +0530 Subject: [PATCH 09/74] update vctools --- .gitignore | 3 +++ modules/basic/vctools.py | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index df891092d5..b2f5a9dc07 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,9 @@ temp/ *.swf *.air *.apk +*.webp +*.cpp + .vs env # temporary files diff --git a/modules/basic/vctools.py b/modules/basic/vctools.py index 5413d7f711..d57221550b 100644 --- a/modules/basic/vctools.py +++ b/modules/basic/vctools.py @@ -31,13 +31,14 @@ from telethon.tl.functions.phone import GetGroupCallRequest as getvc from telethon.tl.functions.phone import InviteToGroupCallRequest as invitetovc -from .. import get_string, ultroid_cmd +from .. import get_string, ultroid_cmd, LOGS async def get_call(event): mm = await event.client(getchat(event.chat_id)) - xx = await event.client(getvc(mm.full_chat.call, limit=1)) - return xx.call + if mm.full_chat.call: + xx = await event.client(getvc(mm.full_chat.call, limit=1)) + return xx.call def user_list(l, n): @@ -52,9 +53,12 @@ def user_list(l, n): ) async def _(e): try: - await e.client(stopvc(await get_call(e))) - await e.eor(get_string("vct_4")) + if call := await get_call(e): + await e.client(stopvc(call)) + return await e.eor(get_string("vct_4")) + await e.eor("`Voice call is not active.`") except Exception as ex: + LOGS.exception(ex) await e.eor(f"`{ex}`") @@ -70,9 +74,12 @@ async def _(e): if not x.bot: users.append(x.id) hmm = list(user_list(users, 6)) + call = await get_call(e) + if not call: + return await e.eor("`Voice Call is not active.`") for p in hmm: with contextlib.suppress(BaseException): - await e.client(invitetovc(call=await get_call(e), users=p)) + await e.client(invitetovc(call=call, users=p)) z += len(p) await ok.edit(get_string("vct_5").format(z)) @@ -87,6 +94,7 @@ async def _(e): await e.client(startvc(e.chat_id)) await e.eor(get_string("vct_1")) except Exception as ex: + LOGS.exception(ex) await e.eor(f"`{ex}`") @@ -99,8 +107,11 @@ async def _(e): title = e.pattern_match.group(1).strip() if not title: return await e.eor(get_string("vct_6"), time=5) + call = await get_call(e) + if not call: + return await e.eor("`Voice Call is not active.`") try: - await e.client(settitle(call=await get_call(e), title=title.strip())) + await e.client(settitle(call=call, title=title.strip())) await e.eor(get_string("vct_2").format(title)) except Exception as ex: await e.eor(f"`{ex}`") From adb4e1a8094dd89f77e6c064c52088fd705c6778 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Tue, 20 Jun 2023 18:53:24 +0530 Subject: [PATCH 10/74] add docstrings --- modules/basic/admins.py | 3 +++ modules/basic/bot.py | 7 +++++++ modules/basic/chats.py | 15 +++++++++------ modules/basic/devtools.py | 4 ++++ modules/basic/mediainfo.py | 10 +++++++++- modules/basic/tools.py | 21 ++++++++++++++++----- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/modules/basic/admins.py b/modules/basic/admins.py index 1b13c876cb..7a685f8c1e 100644 --- a/modules/basic/admins.py +++ b/modules/basic/admins.py @@ -5,6 +5,9 @@ # PLease read the GNU Affero General Public License in # . +from localization import get_help + +__doc__ = get_help(__name__) from telethon.errors import BadRequestError from telethon.errors.rpcerrorlist import UserIdInvalidError diff --git a/modules/basic/bot.py b/modules/basic/bot.py index e6766777ef..1f35652be6 100644 --- a/modules/basic/bot.py +++ b/modules/basic/bot.py @@ -1,3 +1,10 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + import os import sys import time diff --git a/modules/basic/chats.py b/modules/basic/chats.py index 8e042310af..1f4ed4ae7c 100644 --- a/modules/basic/chats.py +++ b/modules/basic/chats.py @@ -5,6 +5,9 @@ # PLease read the GNU Affero General Public License in # . +from localization import get_help + +__doc__ = get_help(__name__) import contextlib from telethon.errors import ChatAdminRequiredError as no_admin @@ -201,12 +204,12 @@ async def _(ult): else: return await ult.eor("Reply to a Photo or Video..") mediain = mediainfo(reply.media) - if "animated" in mediain: - replfile = await con.convert(replfile, convert_to="mp4") - else: - replfile = await con.convert( - replfile, outname="chatphoto", allowed_formats=["jpg", "png", "mp4"] - ) +# if "animated" in mediain: + # replfile = await con.convert(replfile, convert_to="mp4") + # else: + # replfile = await con.convert( + # replfile, outname="chatphoto", allowed_formats=["jpg", "png", "mp4"] + # ) file = await ult.client.upload_file(replfile) try: if "pic" not in mediain: diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 811be9c7c2..cbd4a7d816 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -5,6 +5,10 @@ # Please read the GNU Affero General Public License in # . +from localization import get_help + +__doc__ = get_help(__name__) + import contextlib import inspect import sys diff --git a/modules/basic/mediainfo.py b/modules/basic/mediainfo.py index e630a62bc5..a5be66378b 100644 --- a/modules/basic/mediainfo.py +++ b/modules/basic/mediainfo.py @@ -1,3 +1,10 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + import contextlib import os, json @@ -8,7 +15,8 @@ @ultroid_cmd(pattern="mediainfo( (.*)|$)") -async def mediainfo_cmd(event): +async def mediainfo_func(event): + """mediainfo url/file_path/reply media- generate media info""" r = await event.get_reply_message() match = event.pattern_match.group(1).strip() extra = "" diff --git a/modules/basic/tools.py b/modules/basic/tools.py index 1d4ab647a9..76c166cdab 100644 --- a/modules/basic/tools.py +++ b/modules/basic/tools.py @@ -1,3 +1,14 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from localization import get_help + +__doc__ = get_help(__name__) + import contextlib import os from glob import glob @@ -15,7 +26,7 @@ @ultroid_cmd(pattern="tr( (.*)|$)", manager=True) -async def _(event): +async def tr_func(event): input_ = event.pattern_match.group(1).strip().split(maxsplit=1) txt = input_[1] if len(input_) > 1 else None if input_: @@ -43,7 +54,7 @@ async def _(event): pattern="id( (.*)|$)", manager=True, ) -async def _(event): +async def id_func(event): if match := event.pattern_match.group(1).strip(): try: ids = await event.client.parse_id(match) @@ -110,7 +121,7 @@ async def _(event): @ultroid_cmd( pattern="ls($| ?(.*))", ) -async def ls_cmd(e): +async def ls_func(e): """list files in a directory""" files = e.pattern_match.group(1).strip() if not files: @@ -230,7 +241,7 @@ async def ls_cmd(e): @ultroid_cmd( pattern="graph( ?(.*)|$)", ) -async def graph_cmd(event): +async def graph_func(event): """ `graph` `graph list`""" @@ -279,7 +290,7 @@ async def graph_cmd(event): @ultroid_cmd(pattern="q( (.*)|$)", manager=True, allow_pm=True) -async def q_cmd(event): +async def q_func(event): match = event.pattern_match.group(1).strip() if not event.is_reply: return await event.eor("`Reply to Message..`") From 7b521b022a672e3393cfcf4a1c0d747bcdb9f0c5 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Tue, 20 Jun 2023 19:05:19 +0530 Subject: [PATCH 11/74] add help string --- modules/basic/admins.py | 2 +- modules/basic/chats.py | 2 +- modules/basic/devtools.py | 2 +- modules/basic/dlul.py | 2 +- modules/basic/mediainfo.py | 8 +++++++- modules/basic/stickers.py | 3 +++ modules/basic/tools.py | 2 +- 7 files changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/basic/admins.py b/modules/basic/admins.py index 7a685f8c1e..a06aa8ad76 100644 --- a/modules/basic/admins.py +++ b/modules/basic/admins.py @@ -7,7 +7,7 @@ from localization import get_help -__doc__ = get_help(__name__) +__doc__ = get_help("admins") from telethon.errors import BadRequestError from telethon.errors.rpcerrorlist import UserIdInvalidError diff --git a/modules/basic/chats.py b/modules/basic/chats.py index 1f4ed4ae7c..01f2d969e5 100644 --- a/modules/basic/chats.py +++ b/modules/basic/chats.py @@ -7,7 +7,7 @@ from localization import get_help -__doc__ = get_help(__name__) +__doc__ = get_help("chats") import contextlib from telethon.errors import ChatAdminRequiredError as no_admin diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index cbd4a7d816..70155b3065 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -7,7 +7,7 @@ from localization import get_help -__doc__ = get_help(__name__) +__doc__ = get_help("devtools") import contextlib import inspect diff --git a/modules/basic/dlul.py b/modules/basic/dlul.py index a017e861f3..244ef4dc7a 100644 --- a/modules/basic/dlul.py +++ b/modules/basic/dlul.py @@ -155,7 +155,7 @@ async def _upload_file( @ultroid_cmd( pattern="ul( (.*)|$)", ) -async def _(event): +async def ul_func(event): msg = await event.eor(get_string("com_1")) query = event.pattern_match.group(1).strip() if not query: diff --git a/modules/basic/mediainfo.py b/modules/basic/mediainfo.py index a5be66378b..7dbac29285 100644 --- a/modules/basic/mediainfo.py +++ b/modules/basic/mediainfo.py @@ -5,6 +5,13 @@ # PLease read the GNU Affero General Public License in # . +""" +✘ Commands Available - + +• `{i}mediainfo reply-media/file-path/url` + Get mediainfo of file +""" + import contextlib import os, json @@ -16,7 +23,6 @@ @ultroid_cmd(pattern="mediainfo( (.*)|$)") async def mediainfo_func(event): - """mediainfo url/file_path/reply media- generate media info""" r = await event.get_reply_message() match = event.pattern_match.group(1).strip() extra = "" diff --git a/modules/basic/stickers.py b/modules/basic/stickers.py index be65614a20..f4816b95a4 100644 --- a/modules/basic/stickers.py +++ b/modules/basic/stickers.py @@ -73,6 +73,8 @@ async def AddToNewPack(packType, file, emoji, sender_id, title: str): @ultroid_cmd(pattern="kang", manager=True) async def kang_func(ult): + """(reply message) + Create sticker and add to pack""" sender = await ult.get_sender() if not isinstance(sender, User): return @@ -161,6 +163,7 @@ async def kang_func(ult): @ultroid_cmd(pattern="listpack", manager=True) async def do_magic(ult): + """Get list of sticker packs.""" ko = udB.get_key("STICKERS") or {} if not ko.get(ult.sender_id): return await ult.reply("No Sticker Pack Found!") diff --git a/modules/basic/tools.py b/modules/basic/tools.py index 76c166cdab..5de86bf7e2 100644 --- a/modules/basic/tools.py +++ b/modules/basic/tools.py @@ -7,7 +7,7 @@ from localization import get_help -__doc__ = get_help(__name__) +__doc__ = get_help("devtools") import contextlib import os From d31e81dcaa914e606b53cd439ef80ddf62820b0d Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Tue, 20 Jun 2023 23:21:12 +0530 Subject: [PATCH 12/74] fix help back indexing logic is out of the brain but works --- core/remote.py | 13 +++++++++---- modules/basic/_help.py | 22 ++++++++++++++-------- requirements.txt | 1 + 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/core/remote.py b/core/remote.py index e1f81c5cb8..a782c857ec 100644 --- a/core/remote.py +++ b/core/remote.py @@ -15,6 +15,7 @@ class Remote: REMOTE_URL = Var.REMOTE_URI or "https://plugins.xditya.me" MAX_HR = 1 + DEF_CONFIG = {"plugins": {}, "helpers": {}, "manager": {}} def __init__(self) -> None: self._modules = {} @@ -23,9 +24,13 @@ def __init__(self) -> None: if os.path.exists(LOCK_PATH): with open(LOCK_PATH, "r") as file: - self.RemoteConfig: dict = json.load(file) + try: + self.RemoteConfig: dict = json.load(file) + except json.decoder.JSONDecodeError: + Logger.error(f"Failed to decode ultroid lock file, creating new...") + self.RemoteConfig = self.DEF_CONFIG else: - self.RemoteConfig = {"plugins": {}, "helpers": {}, "manager": {}} + self.RemoteConfig = self.DEF_CONFIG def _http_import(self, path: str, save_as=None, helper=False, manager=False): if not save_as: @@ -126,8 +131,8 @@ def __install_deps(self, deps: list): self._deps.append(dep) for prc in proc: prc.wait(timeout=10000) - if prc.stderr: - Logger.error(prc.stderr) + if err:= prc.stderr.read(): + Logger.error(err) async def get_all_plugins(self, end): return await fetch(f"{self.REMOTE_URL}/{end}", re_json=True) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 25b24d89f7..aad3c3c058 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -235,16 +235,22 @@ def _get_buttons(key, index): cols = udB.get_key("HELP_COLUMNS") or 2 emoji = udB.get_key("EMOJI_IN_HELP") or "✘" loaded = filter_modules(key) - List = [ - Button.inline(f"{emoji} {x} {emoji}", data=f"uplugin_{key}_{x}|{index}") - for x in loaded - ] - all_ = split_list(List, cols) - fl_ = split_list(all_, rows) + cindex = 0 + NList = [] + tl = rows * cols + while loaded: + plugs = loaded[:tl] + loaded = loaded[tl:] + MList = [] + for ps in split_list(plugs, rows): + for p in ps: + MList.append(Button.inline(f"{emoji} {p} {emoji}", data=f"uplugin_{key}_{p}|{cindex}")) + NList.append(split_list(MList, cols)) + cindex += 1 if _cache.get("help") is None: _cache["help"] = {} - _cache["help"][key] = fl_ - return fl_ + _cache["help"][key] = NList + return NList def page_num(index, key): diff --git a/requirements.txt b/requirements.txt index 6b7da0bf3d..69224660df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ python-decouple telethon-patch tgcrypto enhancer +lottie \ No newline at end of file From 137794696599e27d2ff195a74547cdda35c340b7 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Wed, 21 Jun 2023 11:12:07 +0530 Subject: [PATCH 13/74] there is no place for owner tools --- modules/basic/_help.py | 45 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index aad3c3c058..8d3bec8028 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -24,7 +24,9 @@ def split_list(List, index): def get_help_buttons(): row_1 = [Button.inline(get_string("help_4"), data="uh_basic_")] - if filter_modules("addons"): # (udB.get_config("ADDONS") or udB.get_key("LOAD_ALL")) + if filter_modules( + "addons" + ): # (udB.get_config("ADDONS") or udB.get_key("LOAD_ALL")) row_1.append(Button.inline(get_string("help_5"), data="uh_addons_")) row_2 = [] if udB.get_config("VCBOT"): @@ -45,17 +47,16 @@ def get_help_buttons(): row_2.insert(0, button) else: Markup.append([button]) - Markup.extend( - [ - [ - Button.inline(get_string("help_8"), data="ownr"), - Button.url( - get_string("help_9"), - url=f"https://t.me/{asst.me.username}?start=set", - ), - ], - [Button.inline(get_string("help_10"), data="close")], - ] + settingButton = Button.url( + get_string("help_9"), + url=f"https://t.me/{asst.me.username}?start=set", + ) + if len(row_2) == 1: + row_2.append(settingButton) + else: + Markup.append([settingButton]) + Markup.append( + [Button.inline(get_string("help_10"), data="close")], ) if row_2 and row_2 not in Markup: Markup.insert(1, row_2) @@ -238,13 +239,15 @@ def _get_buttons(key, index): cindex = 0 NList = [] tl = rows * cols - while loaded: - plugs = loaded[:tl] - loaded = loaded[tl:] + for plugs in split_list(loaded, tl): MList = [] - for ps in split_list(plugs, rows): + for ps in split_list(plugs, rows): for p in ps: - MList.append(Button.inline(f"{emoji} {p} {emoji}", data=f"uplugin_{key}_{p}|{cindex}")) + MList.append( + Button.inline( + f"{emoji} {p} {emoji}", data=f"uplugin_{key}_{p}|{cindex}" + ) + ) NList.append(split_list(MList, cols)) cindex += 1 if _cache.get("help") is None: @@ -265,7 +268,8 @@ def page_num(index, key): if index == 0 and len(fl_) == 1: new_.append([Button.inline("« Bᴀᴄᴋ »", data="open")]) else: - new_.append([ + new_.append( + [ Button.inline( "« Pʀᴇᴠɪᴏᴜs", data=f"uh_{key}_{index-1}", @@ -275,8 +279,9 @@ def page_num(index, key): "Nᴇxᴛ »", data=f"uh_{key}_{index+1}", ), - ]) - + ] + ) + return new_ From 5a3157390397ee21c459d860ed12b47873594fa8 Mon Sep 17 00:00:00 2001 From: New-dev0 Date: Wed, 21 Jun 2023 11:13:21 +0530 Subject: [PATCH 14/74] fix strings --- modules/basic/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/tools.py b/modules/basic/tools.py index 5de86bf7e2..8af5775835 100644 --- a/modules/basic/tools.py +++ b/modules/basic/tools.py @@ -7,7 +7,7 @@ from localization import get_help -__doc__ = get_help("devtools") +__doc__ = get_help("tools") import contextlib import os From ee25255be8fa5a19707c7e9f54d9b3050601c210 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Thu, 22 Jun 2023 19:12:09 +0530 Subject: [PATCH 15/74] Update --- utilities/converter.py | 61 +++++++++++++++++++++++++++--------------- utilities/helper.py | 3 ++- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/utilities/converter.py b/utilities/converter.py index 623bb63d09..0ef8d58743 100644 --- a/utilities/converter.py +++ b/utilities/converter.py @@ -1,26 +1,45 @@ -import math +import math, os from PIL import Image +from .tools import metadata, bash 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 - else: - scale = 512 / size2 - size1new = size1 * scale - size2new = 512 - size1new = math.floor(size1new) - size2new = math.floor(size2new) - sizenew = (size1new, size2new) - image = image.resize(sizenew) + """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 else: - maxsize = (512, 512) - image.thumbnail(maxsize) - return image \ No newline at end of file + 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 + + +async def create_webm(file, name="video", remove=False): + _ = await metadata(file) + name += ".webm" + h, w = _["height"], _["width"] + if h == w != 512: + h, w = 512, 512 + elif h > w: + h, w = 512, -1 + else: + 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 diff --git a/utilities/helper.py b/utilities/helper.py index d4bdf7a090..0456011a96 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -255,6 +255,7 @@ def mediainfo(message: Message) -> str: for k in message.document.attributes ): _i = "sticker" + return _i + " as document" return _ return "" @@ -321,7 +322,7 @@ def humanbytes(size): def numerize(number): if not number: - return None + return unit = "" for unit in ["", "K", "M", "B", "T"]: if number < 1000: From 8da9e39494baad1be100a2aba1575d126c94c32a Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Thu, 22 Jun 2023 19:37:23 +0530 Subject: [PATCH 16/74] few more --- core/loader.py | 2 -- modules/basic/chats.py | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/loader.py b/core/loader.py index a62af12cba..da80faa8d5 100644 --- a/core/loader.py +++ b/core/loader.py @@ -22,8 +22,6 @@ def __load(func, plugin, key, single): try: modl = func(plugin) except ModuleNotFoundError as er: - import traceback - LOGS.info(traceback.format_exc()) LOGS.error(f"{plugin}: '{er.name}' not installed!") return except Exception as exc: diff --git a/modules/basic/chats.py b/modules/basic/chats.py index 01f2d969e5..21dffdec6c 100644 --- a/modules/basic/chats.py +++ b/modules/basic/chats.py @@ -212,11 +212,12 @@ async def _(ult): # ) file = await ult.client.upload_file(replfile) try: - if "pic" not in mediain: + if "photo" not in mediain: file = types.InputChatUploadedPhoto(video=file) await ult.client(EditPhotoRequest(chat, file)) await ult.eor("`Group Photo has Successfully Changed !`", time=5) except Exception as ex: + LOGS.exception(ex) await ult.eor(f"Error occured.\n`{str(ex)}`", time=5) os.remove(replfile) From 2baae3af9b9579756d023c171e9d0d40e21b0434 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Thu, 22 Jun 2023 20:12:23 +0530 Subject: [PATCH 17/74] on the go --- core/decorators/__init__.py | 13 +------------ core/decorators/_decorators.py | 11 ++++++++--- utilities/converter.py | 16 +++++++++++++++- utilities/helper.py | 13 +++++++------ utilities/tools.py | 2 +- 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/core/decorators/__init__.py b/core/decorators/__init__.py index eb6d474db9..e41c19e34c 100644 --- a/core/decorators/__init__.py +++ b/core/decorators/__init__.py @@ -46,15 +46,4 @@ def fullsudos(): fullsudos.append(owner) return list(map(_parse, filter(lambda id: id, fullsudos))) - -# ------------------------------------------------ # - - -# TODO: What does this do?: -def append_or_update(load, func, name, arggs): - if isinstance(load, list): - return load.append(func) - if isinstance(load, dict): - if load.get(name): - return load[name].append((func, arggs)) - return load.update({name: [(func, arggs)]}) +# ------------------------------------------------ # \ No newline at end of file diff --git a/core/decorators/_decorators.py b/core/decorators/_decorators.py index 5fdf324bbe..226b145efa 100644 --- a/core/decorators/_decorators.py +++ b/core/decorators/_decorators.py @@ -76,7 +76,7 @@ def ultroid_cmd(pattern=None, manager=False, asst=asst, **kwargs): admins_only = kwargs.get("admins_only", False) fullsudo = kwargs.get("fullsudo", False) only_devs = kwargs.get("only_devs", False) -# cmd_key = kwargs.get("cmds_key") + # cmd_key = kwargs.get("cmds_key") func = kwargs.get("func", lambda e: not e.via_bot_id) def decor(dec): @@ -216,7 +216,8 @@ async def wrapp(ult: Message): parse_mode="html", ) await ultr.edit( - f"[An error occurred]", parse_mode="html" + f"[An error occurred]", + parse_mode="html", ) except Exception as er: LOGS.error(f"Error while pasting exception on graph: {er}") @@ -259,7 +260,11 @@ async def wrapp(ult: Message): if TAKE_EDITS: def func_(x): - return (x.out or x.sender_id == ultroid_bot.me.id) and not x.via_bot_id and not (x.is_channel and x.chat.broadcast) + return ( + (x.out or x.sender_id == ultroid_bot.me.id) + and not x.via_bot_id + and not (x.is_channel and x.chat.broadcast) + ) ultroid_bot.add_handler( wrapp, diff --git a/utilities/converter.py b/utilities/converter.py index 0ef8d58743..95d95385e5 100644 --- a/utilities/converter.py +++ b/utilities/converter.py @@ -1,7 +1,8 @@ import math, os from PIL import Image from .tools import metadata, bash - +from .tools import _unquote_text +from telethon.utils import get_extension def resize_photo_sticker(photo): """Resize the given photo to 512x512 (for creating telegram sticker).""" @@ -43,3 +44,16 @@ async def create_webm(file, name="video", remove=False): if remove: os.remove(file) return name + + +async def convert_ffmpeg(input_, output): + if output.endswith(".gif"): + await bash(f"ffmpeg -i '{input_}' -an -sn -c:v copy '{output}.mp4' -y") + else: + await bash(f"ffmpeg -i '{input_}' '{output}' -y") + return output + + +async def lottie_to_gif(file, output): + await bash(f"lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(output)}'") + return output diff --git a/utilities/helper.py b/utilities/helper.py index 0456011a96..004950d1eb 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -42,9 +42,6 @@ from core.git import repo from core.config import HOSTED_ON -# TODO: Mess with this later -# from database._core import ADDONS, HELP, LIST, LOADED - from core.version import version from .FastTelethon import download_file as downloadable from .FastTelethon import upload_file as uploadable @@ -237,7 +234,12 @@ def mediainfo(message: Message) -> str: "document", ]: if getattr(message, _, None): - if _ == "document": + if _ == "sticker": + stickerType = {"video/webm": "video_sticker", + "image/webp": "static_sticker", + "application/x-tgsticker": "animated_sticker"} + return stickerType[message.document.mime_type] + elif _ == "document": attributes = { DocumentAttributeSticker: "sticker", DocumentAttributeAnimated: "gif", @@ -245,8 +247,7 @@ def mediainfo(message: Message) -> str: types.DocumentAttributeCustomEmoji: "custom emoji", DocumentAttributeVideo: "video", DocumentAttributeImageSize: "photo", - DocumentAttributeFilename: "file", - } + } for __ in message.document.attributes: if type(__) in attributes: _i = attributes[type(__)] diff --git a/utilities/tools.py b/utilities/tools.py index 6a82f10446..75c4656db4 100644 --- a/utilities/tools.py +++ b/utilities/tools.py @@ -52,7 +52,7 @@ async def get_ofox(codename): ofox_baseurl = "https://api.orangefox.download/v3/" releases = await async_searcher( - ofox_baseurl + "releases?codename=" + codename, re_json=True + f"{ofox_baseurl}releases?codename={codename}", re_json=True ) device = await async_searcher( ofox_baseurl + "devices/get?codename=" + codename, re_json=True From 4441779ff55bcc9d23d57f84941ae4402a5062bd Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Fri, 23 Jun 2023 09:36:46 +0530 Subject: [PATCH 18/74] .. --- database/helpers/botchat_db.py | 29 ---------------- database/initialize/base_db.py | 4 ++- modules/basic/tools.py | 62 ++++++++++++++++++++++++++++------ 3 files changed, 55 insertions(+), 40 deletions(-) delete mode 100644 database/helpers/botchat_db.py diff --git a/database/helpers/botchat_db.py b/database/helpers/botchat_db.py deleted file mode 100644 index 71d6a6ec51..0000000000 --- a/database/helpers/botchat_db.py +++ /dev/null @@ -1,29 +0,0 @@ -# Ultroid - UserBot -# Copyright (C) 2020-2023 TeamUltroid -# -# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > -# PLease read the GNU Affero General Public License in -# . - - -from core import udB - - -def get_stuff(): - return udB.get_key("BOTCHAT") or {} - - -def tag_add(msg, chat, user): - ok = get_stuff() - if not ok.get("TAG"): - ok.update({"TAG": {msg: [chat, user]}}) - else: - ok["TAG"].update({msg: [chat, user]}) - return udB.set_key("BOTCHAT", ok) - - -def who_tag(msg): - ok = get_stuff() - if ok.get("TAG") and ok["TAG"].get(msg): - return ok["TAG"][msg] - return False, False diff --git a/database/initialize/base_db.py b/database/initialize/base_db.py index d99970a5c7..f73b2ff8a6 100644 --- a/database/initialize/base_db.py +++ b/database/initialize/base_db.py @@ -67,12 +67,14 @@ def on(self, key, method, handler, *args, **kwargs): self._handlers[key] = {} self._handlers[key][method] = (handler, args, kwargs) - def set_key(self, key, value): + def set_key(self, key, value, only_cache=False): value = self._get_data(data=value) self._cache[key] = value with suppress(KeyError): handler, arg, kwargs = self._handlers[key]["change"] handler(key, value, self.get_key(key), *arg, **kwargs) + if only_cache: + return return self.set(str(key), str(value)) def rename(self, key1, key2): diff --git a/modules/basic/tools.py b/modules/basic/tools.py index 8af5775835..b0a07191c1 100644 --- a/modules/basic/tools.py +++ b/modules/basic/tools.py @@ -18,6 +18,10 @@ from telethon.errors import MessageTooLongError from telethon.tl import TLObject +from telethon.tl.functions.channels import InviteToChannelRequest +from telethon.tl.functions.messages import AddChatUserRequest +from telethon.errors import UserBotError + from core import HNDLR from core.remote import rm from utilities.tools import atranslate, json_parser @@ -259,23 +263,20 @@ async def graph_func(event): amsg = f"Uploaded to [Telegraph]({nn}) !" except Exception as e: amsg = f"Error - {e}" - await xx.edit(amsg) + return await xx.edit(amsg) elif getmsg.document: getit = await getmsg.download_media() with open(getit, "r") as ab: cd = ab.read() - tcom = input_str or "Ultroid" - makeit = client.create_page(title=tcom, content=[f"{cd}"]) - war = makeit["url"] os.remove(getit) - await xx.edit(f"Pasted to Telegraph : [Telegraph]({war})") elif getmsg.text: - tcom = input_str or "Ultroid" - makeit = client.create_page(title=tcom, content=[getmsg.text]) - war = makeit["url"] - await xx.edit(f"Pasted to Telegraph : [Telegraph]({war})") + cd = getmsg.text else: - await xx.edit("Reply to a Media or Text !") + return await xx.edit("Reply to a Media or Text !") + tcom = input_str or "Ultroid" + makeit = client.create_page(title=tcom, content=[cd]) + war = makeit["url"] + await xx.edit(f"Pasted to Telegraph : [Telegraph]({war})") return elif input_str == "list": res = client.get_page_list() @@ -351,3 +352,44 @@ async def q_func(event): os.remove(file) await msg.delete() return message + + +@ultroid_cmd( + pattern="invite( (.*)|$)", + groups_only=True, +) +async def _(ult): + xx = await ult.eor(get_string("com_1")) + to_add_users = ult.pattern_match.group(1).strip() + add_chat_user = not ult.is_channel and ult.is_group + request = AddChatUserRequest if add_chat_user else InviteToChannelRequest + users = to_add_users.split() + single = len(users) == 1 + + for user_id in users: + try: + if add_chat_user: + kwargs = { + "chat_id": ult.chat_id, + "user_id": await ult.client.parse_id(user_id), + "fwd_limit": 1000000, + } + else: + kwargs = { + "channel": ult.chat_id, + "users": [await ult.client.parse_id(user_id)], + } + await ult.client(request(**kwargs)) + await xx.edit(f"Successfully invited `{user_id}` to `{ult.chat_id}`") + except UserBotError as er: + if single: + await xx.edit( + f"Bots can only be added as Admins in Channel.\nBetter Use `{HNDLR}promote {user_id}`" + ) + continue + LOGS.exception(er) + except Exception as er: + if single: + await xx.edit(str(er)) + continue + LOGS.exception(er) From 4000eb4422ebbcf2eb6567ae24254b7fdf0b8bd0 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Fri, 23 Jun 2023 10:07:02 +0530 Subject: [PATCH 19/74] ... --- core/decorators/_supporter.py | 6 +- core/utils/funcs.py | 4 + modules/assistant/callbacks.py | 1277 -------------------------------- modules/assistant/start.py | 41 +- modules/basic/bot.py | 7 +- 5 files changed, 30 insertions(+), 1305 deletions(-) delete mode 100644 modules/assistant/callbacks.py diff --git a/core/decorators/_supporter.py b/core/decorators/_supporter.py index 2b86d1238a..e296c30066 100644 --- a/core/decorators/_supporter.py +++ b/core/decorators/_supporter.py @@ -28,7 +28,7 @@ bot = borg = catub = friday = ultroid_bot -catub.cat_cmd = ultroid_cmd +catub.cat_cmd = ultroid_cmd # type: ignore black_list_chats = udB.get_key("BLACKLIST_CHATS") @@ -49,9 +49,7 @@ def admin_cmd(pattern=None, func=None, **args): friday_on_cmd = admin_cmd -command = ultroid_cmd -register = ultroid_cmd - +register = command = ultroid_cmd def sudo_cmd(allow_sudo=True, pattern=None, func=None, **args): args["func"] = lambda e: not e.via_bot_id and e.sender_id in get_sudos() and func diff --git a/core/utils/funcs.py b/core/utils/funcs.py index 81372d7fac..7c8ed5db12 100644 --- a/core/utils/funcs.py +++ b/core/utils/funcs.py @@ -22,6 +22,10 @@ async def onNewPlugin(ult): PluginChannel[ult.chat_id][ult.id] = file LOGS.debug(f"Loaded new plugin {file} from {ult.chat_id}") + from modules.basic._help import _cache + if _cache.get("addons"): + del _cache["addons"] + async def onPluginDel(ult): chat = ult.chat_id diff --git a/modules/assistant/callbacks.py b/modules/assistant/callbacks.py deleted file mode 100644 index e73f3de1d0..0000000000 --- a/modules/assistant/callbacks.py +++ /dev/null @@ -1,1277 +0,0 @@ -# Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid -# -# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > -# PLease read the GNU Affero General Public License in -# . - -import ast -import asyncio -import re -import sys, os -import time -from asyncio.exceptions import TimeoutError as AsyncTimeOut -from os import execl, remove -from random import choice - -from bs4 import BeautifulSoup as bs -from core import HNDLR, udB, LOGS, Var -from database.helpers import get_random_color -# try: -# from pyUltroid.fns.gDrive import GDriveManager -# except ImportError: -# GDriveManager = None -from telegraph import upload_file as upl -from telethon import Button, events -from telethon.tl.types import MessageMediaWebPage -from telethon.utils import get_peer_id -from localization import get_string - -from utilities.helper import fast_download, progress -from utilities.tools import Carbon, async_searcher #, get_paste, telegraph_client -#from pyUltroid.startup.loader import Loader -from telethon.tl import types -from . import callback, get_back_button, asst - -# --------------------------------------------------------------------# -# telegraph = telegraph_client() -# GDrive = GDriveManager() if GDriveManager else None -# --------------------------------------------------------------------# - -async def setit(_, key, value): - udB.set_key(key, value) - -def text_to_url(event): - """function to get media url (with|without) Webpage""" - if isinstance(event.media, MessageMediaWebPage): - webpage = event.media.webpage - if not isinstance(webpage, types.WebPageEmpty) and webpage.type in ["photo"]: - return webpage.display_url - return event.text - - -# --------------------------------------------------------------------# - -_buttons = { - "otvars": { - "text": "Other Variables to set for @TeamUltroid:", - "buttons": [ - [ - Button.inline("Tᴀɢ Lᴏɢɢᴇʀ", data="taglog"), - Button.inline("SᴜᴘᴇʀFʙᴀɴ", data="cbs_sfban"), - ], - [ - Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ", data="sudo"), - Button.inline("Hᴀɴᴅʟᴇʀ", data="hhndlr"), - ], - [ - Button.inline("Exᴛʀᴀ Pʟᴜɢɪɴs", data="plg"), - Button.inline("Aᴅᴅᴏɴs", data="eaddon"), - ], - [ - Button.inline("Eᴍᴏᴊɪ ɪɴ Hᴇʟᴘ", data="emoj"), - Button.inline("Sᴇᴛ ɢDʀɪᴠᴇ", data="gdrive"), - ], - [ - Button.inline("Iɴʟɪɴᴇ Pɪᴄ", data="inli_pic"), - Button.inline("Sᴜᴅᴏ HNDLR", data="shndlr"), - ], - [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ", "cbs_oofdm")], - [Button.inline("« Bᴀᴄᴋ", data="setter")], - ], - }, - "sfban": { - "text": "SuperFban Settings:", - "buttons": [ - [Button.inline("FBᴀɴ Gʀᴏᴜᴘ", data="sfgrp")], - [Button.inline("Exᴄʟᴜᴅᴇ Fᴇᴅs", data="abs_sfexf")], - [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], - ], - }, - "apauto": { - "text": "This'll auto approve on outgoing messages", - "buttons": [ - [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ ON", data="apon")], - [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ OFF", data="apof")], - [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], - ], - }, - "alvcstm": { - "text": f"Customise your {HNDLR}alive. Choose from the below options -", - "buttons": [ - [Button.inline("Aʟɪᴠᴇ Tᴇxᴛ", data="abs_alvtx")], - [Button.inline("Aʟɪᴠᴇ ᴍᴇᴅɪᴀ", data="alvmed")], - [Button.inline("Dᴇʟᴇᴛᴇ Aʟɪᴠᴇ Mᴇᴅɪᴀ", data="delmed")], - [Button.inline("« Bᴀᴄᴋ", data="setter")], - ], - }, - "pmcstm": { - "text": "Customise your PMPERMIT Settings -", - "buttons": [ - [ - Button.inline("Pᴍ Tᴇxᴛ", data="pmtxt"), - Button.inline("Pᴍ Mᴇᴅɪᴀ", data="pmmed"), - ], - [ - Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ", data="cbs_apauto"), - Button.inline("PMLOGGER", data="pml"), - ], - [ - Button.inline("Sᴇᴛ Wᴀʀɴs", data="swarn"), - Button.inline("Dᴇʟᴇᴛᴇ Pᴍ Mᴇᴅɪᴀ", data="delpmmed"), - ], - [Button.inline("PMPermit Type", data="cbs_pmtype")], - [Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")], - ], - }, - "pmtype": { - "text": "Select the type of PMPermit needed.", - "buttons": [ - [Button.inline("Inline", data="inpm_in")], - [Button.inline("Normal", data="inpm_no")], - [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], - ], - }, - "ppmset": { - "text": "PMPermit Settings:", - "buttons": [ - [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oɴ", data="pmon")], - [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oғғ", data="pmoff")], - [Button.inline("Cᴜsᴛᴏᴍɪᴢᴇ PMPᴇʀᴍɪᴛ", data="cbs_pmcstm")], - [Button.inline("« Bᴀᴄᴋ", data="setter")], - ], - }, - "chatbot": { - "text": "From This Feature U can chat with ppls Via ur Assistant Bot.\n[More info](https://t.me/UltroidUpdates/2)", - "buttons": [ - [ - Button.inline("Cʜᴀᴛ Bᴏᴛ Oɴ", data="onchbot"), - Button.inline("Cʜᴀᴛ Bᴏᴛ Oғғ", data="ofchbot"), - ], - [ - Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ", data="bwel"), - Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ Mᴇᴅɪᴀ", data="botmew"), - ], - [Button.inline("Bᴏᴛ Iɴғᴏ Tᴇxᴛ", data="botinfe")], - [Button.inline("Fᴏʀᴄᴇ Sᴜʙsᴄʀɪʙᴇ", data="pmfs")], - [Button.inline("« Bᴀᴄᴋ", data="setter")], - ], - }, - "vcb": { - "text": "From This Feature U can play songs in group voice chat\n\n[moreinfo](https://t.me/UltroidUpdates/4)", - "buttons": [ - [Button.inline("VC Sᴇssɪᴏɴ", data="abs_vcs")], - [Button.inline("« Bᴀᴄᴋ", data="setter")], - ], - }, - "oofdm": { - "text": "About [Dual Mode](https://t.me/UltroidUpdates/18)", - "buttons": [ - [ - Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oɴ", "dmof"), - Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oғғ", "dmof"), - ], - [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Hɴᴅʟʀ", "dmhn")], - [Button.inline("« Back", data="cbs_otvars")], - ], - }, - "apiset": { - "text": get_string("ast_1"), - "buttons": [ - [Button.inline("Remove.bg API", data="abs_rmbg")], - [Button.inline("DEEP API", data="abs_dapi")], - [Button.inline("OCR API", data="abs_oapi")], - [Button.inline("« Back", data="setter")], - ], - }, -} - -_convo = { - "rmbg": { - "var": "RMBG_API", - "name": "Remove.bg API Key", - "text": get_string("ast_2"), - "back": "cbs_apiset", - }, - "dapi": { - "var": "DEEP_AI", - "name": "Deep AI Api Key", - "text": "Get Your Deep Api from deepai.org and send here.", - "back": "cbs_apiset", - }, - "oapi": { - "var": "OCR_API", - "name": "Ocr Api Key", - "text": "Get Your OCR api from ocr.space and send that Here.", - "back": "cbs_apiset", - }, - "pmlgg": { - "var": "PMLOGGROUP", - "name": "Pm Log Group", - "text": "Send chat id of chat which you want to save as Pm log Group.", - "back": "pml", - }, - "vcs": { - "var": "VC_SESSION", - "name": "Vc Session", - "text": "**Vc session**\nEnter the New session u generated for vc bot.\n\nUse /cancel to terminate the operation.", - "back": "cbs_vcb", - }, - "settag": { - "var": "TAG_LOG", - "name": "Tag Log Group", - "text": f"Make a group, add your assistant and make it admin.\nGet the `{HNDLR}id` of that group and send it here for tag logs.\n\nUse /cancel to cancel.", - "back": "taglog", - }, - "alvtx": { - "var": "ALIVE_TEXT", - "name": "Alive Text", - "text": "**Alive Text**\nEnter the new alive text.\n\nUse /cancel to terminate the operation.", - "back": "cbs_alvcstm", - }, - "sfexf": { - "var": "EXCLUDE_FED", - "name": "Excluded Fed", - "text": "Send the Fed IDs you want to exclude in the ban. Split by a space.\neg`id1 id2 id3`\nSet is as `None` if you dont want any.\nUse /cancel to go back.", - "back": "cbs_sfban", - }, -} - - -TOKEN_FILE = "resources/auths/auth_token.txt" - - -@callback( - re.compile( - "sndplug_(.*)", - ), - owner=True, -) -async def send(eve): - key, name = (eve.data_match.group(1)).decode("UTF-8").split("_") - thumb = "resources/extras/inline.jpg" - await eve.answer("■ Sending ■") - data = f"uh_{key}_" - index = None - if "|" in name: - name, index = name.split("|") - key = "plugins" if key == "Official" else key.lower() - plugin = f"{key}/{name}.py" - _ = f"pasta-{plugin}" - if index is not None: - data += f"|{index}" - _ += f"|{index}" - buttons = [ - [ - Button.inline( - "« Pᴀsᴛᴇ »", - data=_, - ) - ], - [ - Button.inline("« Bᴀᴄᴋ", data=data), - ], - ] - try: - await eve.edit(file=plugin, thumb=thumb, buttons=buttons) - except Exception as er: - await eve.answer(str(er), alert=True) - - -heroku_api, app_name = Var.HEROKU_API, Var.HEROKU_APP_NAME - - -@callback("updatenow", owner=True) -async def update(eve): - repo = Repo() - ac_br = repo.active_branch - ups_rem = repo.remote("upstream") - if heroku_api: - import heroku3 - - try: - heroku = heroku3.from_key(heroku_api) - heroku_app = None - heroku_applications = heroku.apps() - except BaseException as er: - LOGS.exception(er) - return await eve.edit("`Wrong HEROKU_API.`") - for app in heroku_applications: - if app.name == app_name: - heroku_app = app - if not heroku_app: - await eve.edit("`Wrong HEROKU_APP_NAME.`") - repo.__del__() - return - await eve.edit(get_string("clst_1")) - ups_rem.fetch(ac_br) - repo.git.reset("--hard", "FETCH_HEAD") - heroku_git_url = heroku_app.git_url.replace( - "https://", f"https://api:{heroku_api}@" - ) - - if "heroku" in repo.remotes: - remote = repo.remote("heroku") - remote.set_url(heroku_git_url) - else: - remote = repo.create_remote("heroku", heroku_git_url) - try: - remote.push(refspec=f"HEAD:refs/heads/{ac_br}", force=True) - except GitCommandError as error: - await eve.edit(f"`Here is the error log:\n{error}`") - repo.__del__() - return - await eve.edit("`Successfully Updated!\nRestarting, please wait...`") - else: - await eve.edit(get_string("clst_1")) - call_back() - await bash("git pull && pip3 install -r requirements.txt") - execl(sys.executable, sys.executable, "-m", "pyUltroid") - - - - -@callback( - re.compile( - "pasta-(.*)", - ), - owner=True, -) -async def _(e): - ok = (e.data_match.group(1)).decode("UTF-8") - index = None - 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 _: - return await e.answer(key[:30], alert=True) - if ok.startswith("addons"): - key = "Addons" - elif ok.startswith("vcbot"): - key = "VCBot" - else: - key = "Official" - data = f"uh_{key}_" - if index is not None: - data += f"|{index}" - await e.edit( - "", - buttons=[ - [Button.url("Lɪɴᴋ", link), Button.url("Rᴀᴡ", raw)], - [Button.inline("« Bᴀᴄᴋ", data=data)], - ], - ) - - -@callback(re.compile("cbs_(.*)"), owner=True) -async def _edit_to(event): - match = event.data_match.group(1).decode("utf-8") - data = _buttons.get(match) - if not data: - return - await event.edit(data["text"], buttons=data["buttons"], link_preview=False) - - -@callback(re.compile("abs_(.*)"), owner=True) -async def convo_handler(event: events.CallbackQuery): - match = event.data_match.group(1).decode("utf-8") - if not _convo.get(match): - return - await event.delete() - get_ = _convo[match] - back = get_["back"] - async with event.client.conversation(event.sender_id) as conv: - await conv.send_message(get_["text"]) - response = await conv.get_response() - themssg = response.message - try: - themssg = ast.literal_eval(themssg) - except Exception: - pass - if themssg == "/cancel": - return await conv.send_message( - "Cancelled!!", - buttons=get_back_button(back), - ) - await setit(event, get_["var"], themssg) - await conv.send_message( - f"{get_['name']} changed to `{themssg}`", - buttons=get_back_button(back), - ) - - -@callback("authorise", owner=True) -async def _(e): - if not e.is_private: - return - url = GDrive._create_token_file() - await e.edit("Go to the below link and send the code!") - async with asst.conversation(e.sender_id) as conv: - await conv.send_message(url) - code = await conv.get_response() - if GDrive._create_token_file(code=code.text): - await conv.send_message( - "`Success!\nYou are all set to use Google Drive with Ultroid Userbot.`", - buttons=Button.inline("Main Menu", data="setter"), - ) - else: - await conv.send_message("Wrong code! Click authorise again.") - - -@callback("folderid", owner=True, func=lambda x: x.is_private) -async def _(e): - if not e.is_private: - return - msg = ( - "Send your FOLDER ID\n\n" - + "For FOLDER ID:\n" - + "1. Open Google Drive App.\n" - + "2. Create Folder.\n" - + "3. Make that folder public.\n" - + "4. Send link of that folder." - ) - await e.delete() - async with asst.conversation(e.sender_id, timeout=150) as conv: - await conv.send_message(msg) - repl = await conv.get_response() - id = repl.text - if id.startswith("https"): - id = id.split("?id=")[-1] - udB.set_key("GDRIVE_FOLDER_ID", id) - await repl.reply( - "`Success.`", - buttons=get_back_button("gdrive"), - ) - - -@callback("gdrive", owner=True) -async def _(e): - if not e.is_private: - return - await e.edit( - "Click Authorise and send the code.\n\nYou can use your own CLIENT ID and SECRET by [this](https://t.me/UltroidUpdates/37)", - buttons=[ - [ - Button.inline("Folder ID", data="folderid"), - Button.inline("Authorise", data="authorise"), - ], - [Button.inline("« Back", data="cbs_otvars")], - ], - link_preview=False, - ) - - -@callback("dmof", owner=True) -async def rhwhe(e): - if udB.get_key("DUAL_MODE"): - udB.del_key("DUAL_MODE") - key = "Off" - else: - udB.set_key("DUAL_MODE", "True") - key = "On" - Msg = f"Dual Mode : {key}" - await e.edit(Msg, buttons=get_back_button("cbs_otvars")) - - -@callback("dmhn", owner=True) -async def hndlrr(event): - await event.delete() - pru = event.sender_id - var = "DUAL_HNDLR" - name = "Dual Handler" - CH = udB.get_key(var) or "/" - async with event.client.conversation(pru) as conv: - await conv.send_message( - f"Send The Symbol Which u want as Handler/Trigger to use your Assistant bot\nUr Current Handler is [ `{CH}` ]\n\n use /cancel to cancel.", - ) - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_otvars"), - ) - elif len(themssg) > 1: - await conv.send_message( - "Incorrect Handler", - buttons=get_back_button("cbs_otvars"), - ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("cbs_otvars"), - ) - - -@callback("emoj", owner=True) -async def emoji(event): - await event.delete() - pru = event.sender_id - var = "EMOJI_IN_HELP" - name = f"Emoji in `{HNDLR}help` menu" - async with event.client.conversation(pru) as conv: - await conv.send_message("Send emoji u want to set 🙃.\n\nUse /cancel to cancel.") - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_otvars"), - ) - elif themssg.startswith(("/", HNDLR)): - await conv.send_message( - "Incorrect Emoji", - buttons=get_back_button("cbs_otvars"), - ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}\n", - buttons=get_back_button("cbs_otvars"), - ) - - -@callback("plg", owner=True) -async def pluginch(event): - await event.delete() - pru = event.sender_id - var = "PLUGIN_CHANNEL" - name = "Plugin Channel" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "Send id or username of a channel from where u want to install all plugins\n\nOur Channel~ @ultroidplugins\n\nUse /cancel to cancel.", - ) - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_otvars"), - ) - elif themssg.startswith(("/", HNDLR)): - await conv.send_message( - "Incorrect channel", - buttons=get_back_button("cbs_otvars"), - ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}\n After Setting All Things Do Restart", - buttons=get_back_button("cbs_otvars"), - ) - - -@callback("hhndlr", owner=True) -async def hndlrr(event): - await event.delete() - pru = event.sender_id - var = "HNDLR" - name = "Handler/ Trigger" - async with event.client.conversation(pru) as conv: - await conv.send_message( - f"Send The Symbol Which u want as Handler/Trigger to use bot\nUr Current Handler is [ `{HNDLR}` ]\n\n use /cancel to cancel.", - ) - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_otvars"), - ) - elif len(themssg) > 1: - await conv.send_message( - "Incorrect Handler", - buttons=get_back_button("cbs_otvars"), - ) - elif themssg.startswith(("/", "#", "@")): - await conv.send_message( - "This cannot be used as handler", - buttons=get_back_button("cbs_otvars"), - ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("cbs_otvars"), - ) - - -@callback("shndlr", owner=True) -async def hndlrr(event): - await event.delete() - pru = event.sender_id - var = "SUDO_HNDLR" - name = "Sudo Handler" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "Send The Symbol Which u want as Sudo Handler/Trigger to use bot\n\n use /cancel to cancel." - ) - - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_otvars"), - ) - elif len(themssg) > 1: - await conv.send_message( - "Incorrect Handler", - buttons=get_back_button("cbs_otvars"), - ) - elif themssg.startswith(("/", "#", "@")): - await conv.send_message( - "This cannot be used as handler", - buttons=get_back_button("cbs_otvars"), - ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("cbs_otvars"), - ) - - -@callback("taglog", owner=True) -async def tagloggrr(e): - BUTTON = [ - [Button.inline("SET TAG LOG", data="abs_settag")], - [Button.inline("DELETE TAG LOG", data="deltag")], - get_back_button("cbs_otvars"), - ] - await e.edit( - "Choose Options", - buttons=BUTTON, - ) - - -@callback("deltag", owner=True) -async def _(e): - udB.del_key("TAG_LOG") - await e.answer("Done!!! Tag Logger has been turned Off") - - -@callback("eaddon", owner=True) -async def pmset(event): - BT = ( - [Button.inline("Aᴅᴅᴏɴs Oғғ", data="edof")] - if udB.get_key("ADDONS") - else [Button.inline("Aᴅᴅᴏɴs Oɴ", data="edon")] - ) - - await event.edit( - "ADDONS~ Extra Plugins:", - buttons=[ - BT, - [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], - ], - ) - - -@callback("edon", owner=True) -async def eddon(event): - var = "ADDONS" - await setit(event, var, "True") - await event.edit( - "Done! ADDONS has been turned on!!\n\n After Setting All Things Do Restart", - buttons=get_back_button("eaddon"), - ) - - -@callback("edof", owner=True) -async def eddof(event): - udB.set_key("ADDONS", "False") - await event.edit( - "Done! ADDONS has been turned off!! After Setting All Things Do Restart", - buttons=get_back_button("eaddon"), - ) - - -@callback("sudo", owner=True) -async def pmset(event): - BT = ( - [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oғғ", data="ofsudo")] - if udB.get_key("SUDO") - else [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oɴ", data="onsudo")] - ) - - await event.edit( - f"SUDO MODE ~ Some peoples can use ur Bot which u selected. To know More use `{HNDLR}help sudo`", - buttons=[ - BT, - [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], - ], - ) - - -@callback("onsudo", owner=True) -async def eddon(event): - var = "SUDO" - await setit(event, var, "True") - await event.edit( - "Done! SUDO MODE has been turned on!!\n\n After Setting All Things Do Restart", - buttons=get_back_button("sudo"), - ) - - -@callback("ofsudo", owner=True) -async def eddof(event): - var = "SUDO" - await setit(event, var, "False") - await event.edit( - "Done! SUDO MODE has been turned off!! After Setting All Things Do Restart", - buttons=get_back_button("sudo"), - ) - - -@callback("sfgrp", owner=True) -async def sfgrp(event): - await event.delete() - name = "FBan Group ID" - var = "FBAN_GROUP_ID" - pru = event.sender_id - async with asst.conversation(pru) as conv: - await conv.send_message( - f"Make a group, add @MissRose_Bot, send `{HNDLR}id`, copy that and send it here.\nUse /cancel to go back.", - ) - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - return await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_sfban"), - ) - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("cbs_sfban"), - ) - - -@callback("alvmed", owner=True) -async def media(event): - await event.delete() - pru = event.sender_id - var = "ALIVE_PIC" - name = "Alive Media" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "**Alive Media**\nSend me a pic/gif/media to set as alive media.\n\nUse /cancel to terminate the operation.", - ) - response = await conv.get_response() - try: - themssg = response.message - if themssg == "/cancel": - return await conv.send_message( - "Operation cancelled!!", - buttons=get_back_button("cbs_alvcstm"), - ) - except BaseException as er: - LOGS.exception(er) - if ( - not (response.text).startswith("/") - and response.text != "" - and (not response.media or isinstance(response.media, MessageMediaWebPage)) - ): - url = text_to_url(response) - elif response.sticker: - url = response.file.id - else: - media = await event.client.download_media(response, "alvpc") - try: - x = upl(media) - url = f"https://graph.org/{x[0]}" - remove(media) - except BaseException as er: - LOGS.exception(er) - return await conv.send_message( - "Terminated.", - buttons=get_back_button("cbs_alvcstm"), - ) - await setit(event, var, url) - await conv.send_message( - f"{name} has been set.", - buttons=get_back_button("cbs_alvcstm"), - ) - - -@callback("delmed", owner=True) -async def dell(event): - try: - udB.del_key("ALIVE_PIC") - return await event.edit( - get_string("clst_5"), buttons=get_back_button("cbs_alabs_vcstm") - ) - except BaseException as er: - LOGS.exception(er) - return await event.edit( - get_string("clst_4"), - buttons=get_back_button("cbs_alabs_vcstm"), - ) - - -@callback("inpm_in", owner=True) -async def inl_on(event): - var = "INLINE_PM" - await setit(event, var, "True") - await event.edit( - "Done!! PMPermit type has been set to inline!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]], - ) - - -@callback("inpm_no", owner=True) -async def inl_on(event): - var = "INLINE_PM" - await setit(event, var, "False") - await event.edit( - "Done!! PMPermit type has been set to normal!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]], - ) - - -@callback("pmtxt", owner=True) -async def name(event): - await event.delete() - pru = event.sender_id - var = "PM_TEXT" - name = "PM Text" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "**PM Text**\nEnter the new Pmpermit text.\n\nu can use `{name}` `{fullname}` `{count}` `{mention}` `{username}` to get this from user Too\n\nUse /cancel to terminate the operation.", - ) - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - return await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_pmcstm"), - ) - if len(themssg) > 4090: - return await conv.send_message( - "Message too long!\nGive a shorter message please!!", - buttons=get_back_button("cbs_pmcstm"), - ) - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}\n\nAfter Setting All Things Do restart", - buttons=get_back_button("cbs_pmcstm"), - ) - - -@callback("swarn", owner=True) -async def name(event): - m = range(1, 10) - tultd = [Button.inline(f"{x}", data=f"wrns_{x}") for x in m] - lst = list(zip(tultd[::3], tultd[1::3], tultd[2::3])) - lst.append([Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")]) - await event.edit( - "Select the number of warnings for a user before getting blocked in PMs.", - buttons=lst, - ) - - -@callback(re.compile(b"wrns_(.*)"), owner=True) -async def set_wrns(event): - value = int(event.data_match.group(1).decode("UTF-8")) - if dn := udB.set_key("PMWARNS", value): - await event.edit( - f"PM Warns Set to {value}.\nNew users will have {value} chances in PMs before getting banned.", - buttons=get_back_button("cbs_pmcstm"), - ) - else: - await event.edit( - f"Something went wrong, please check your {HNDLR}logs!", - buttons=get_back_button("cbs_pmcstm"), - ) - - -@callback("pmmed", owner=True) -async def media(event): - await event.delete() - pru = event.sender_id - var = "PMPIC" - name = "PM Media" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "**PM Media**\nSend me a pic/gif/sticker/link to set as pmpermit media.\n\nUse /cancel to terminate the operation.", - ) - response = await conv.get_response() - try: - themssg = response.message - if themssg == "/cancel": - return await conv.send_message( - "Operation cancelled!!", - buttons=get_back_button("cbs_pmcstm"), - ) - except BaseException as er: - LOGS.exception(er) - media = await event.client.download_media(response, "pmpc") - if ( - not (response.text).startswith("/") - and response.text != "" - and (not response.media or isinstance(response.media, MessageMediaWebPage)) - ): - url = text_to_url(response) - elif response.sticker: - url = response.file.id - else: - try: - x = upl(media) - url = f"https://graph.org/{x[0]}" - remove(media) - except BaseException as er: - LOGS.exception(er) - return await conv.send_message( - "Terminated.", - buttons=get_back_button("cbs_pmcstm"), - ) - await setit(event, var, url) - await conv.send_message( - f"{name} has been set.", - buttons=get_back_button("cbs_pmcstm"), - ) - - -@callback("delpmmed", owner=True) -async def dell(event): - try: - udB.del_key("PMPIC") - return await event.edit( - get_string("clst_5"), buttons=get_back_button("cbs_pmcstm") - ) - except BaseException as er: - LOGS.exception(er) - return await event.edit( - get_string("clst_4"), - buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], - ) - - -@callback("apon", owner=True) -async def apon(event): - var = "AUTOAPPROVE" - await setit(event, var, "True") - await event.edit( - "Done!! AUTOAPPROVE Started!!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]], - ) - - -@callback("apof", owner=True) -async def apof(event): - try: - udB.set_key("AUTOAPPROVE", "False") - return await event.edit( - "Done! AUTOAPPROVE Stopped!!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]], - ) - except BaseException as er: - LOGS.exception(er) - return await event.edit( - get_string("clst_4"), - buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], - ) - - -@callback("pml", owner=True) -async def l_vcs(event): - BT = ( - [Button.inline("PMLOGGER OFF", data="pmlogof")] - if udB.get_key("PMLOG") - else [Button.inline("PMLOGGER ON", data="pmlog")] - ) - - await event.edit( - "PMLOGGER This Will Forward Ur Pm to Ur Private Group -", - buttons=[ - BT, - [Button.inline("PᴍLᴏɢɢᴇʀ Gʀᴏᴜᴘ", "abs_pmlgg")], - [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], - ], - ) - - -@callback("pmlog", owner=True) -async def pmlog(event): - await setit(event, "PMLOG", "True") - await event.edit( - "Done!! PMLOGGER Started!!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], - ) - - -@callback("pmlogof", owner=True) -async def pmlogof(event): - try: - udB.del_key("PMLOG") - return await event.edit( - "Done! PMLOGGER Stopped!!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], - ) - except BaseException as er: - LOGS.exception(er) - return await event.edit( - get_string("clst_4"), - buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], - ) - - -@callback("pmon", owner=True) -async def pmonn(event): - var = "PMSETTING" - await setit(event, var, "True") - await event.edit( - "Done! PMPermit has been turned on!!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]], - ) - - -@callback("pmoff", owner=True) -async def pmofff(event): - var = "PMSETTING" - await setit(event, var, "False") - await event.edit( - "Done! PMPermit has been turned off!!", - buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]], - ) - - -@callback("botmew", owner=True) -async def hhh(e): - async with e.client.conversation(e.chat_id) as conv: - await conv.send_message("Send Any Media to keep at your Bot's welcome ") - msg = await conv.get_response() - if not msg.media or msg.text.startswith("/"): - return await conv.send_message( - "Terminated!", buttons=get_back_button("cbs_chatbot") - ) - udB.set_key("STARTMEDIA", msg.file.id) - await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot")) - - -@callback("botinfe", owner=True) -async def hhh(e): - async with e.client.conversation(e.chat_id) as conv: - await conv.send_message( - "Send message to set to Display, when user Press Info button in Bot Welcome!\n\nsend `False` to completely remove that button.." - ) - msg = await conv.get_response() - if msg.media or msg.text.startswith("/"): - return await conv.send_message( - "Terminated!", buttons=get_back_button("cbs_chatbot") - ) - udB.set_key("BOT_INFO_START", msg.text) - await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot")) - - -@callback("pmfs", owner=True) -async def heheh(event): - Ll = [] - err = "" - async with event.client.conversation(event.chat_id) as conv: - await conv.send_message( - "• Send The Chat Id(s), which you want user to Join Before using Chat/Pm Bot\n\n• Send /clear to disable PmBot Force sub..\n• • Send /cancel to stop this process.." - ) - await conv.send_message( - "Example : \n`-1001234567\n-100778888`\n\nFor Multiple Chat(s)." - ) - try: - msg = await conv.get_response() - except AsyncTimeOut: - return await conv.send_message("**• TimeUp!**\nStart from /start back.") - if not msg.text or msg.text.startswith("/"): - timyork = "Cancelled!" - if msg.text == "/clear": - udB.del_key("PMBOT_FSUB") - timyork = "Done! Force Subscribe Stopped\nRestart your Bot!" - return await conv.send_message( - "Cancelled!", buttons=get_back_button("cbs_chatbot") - ) - for chat in msg.message.split("\n"): - if chat.startswith("-") or chat.isdigit(): - chat = int(chat) - try: - CHSJSHS = await event.client.get_entity(chat) - Ll.append(get_peer_id(CHSJSHS)) - except Exception as er: - err += f"**{chat}** : {er}\n" - if err: - return await conv.send_message(err) - udB.set_key("PMBOT_FSUB", str(Ll)) - await conv.send_message( - "Done!\nRestart Your Bot.", buttons=get_back_button("cbs_chatbot") - ) - - -@callback("bwel", owner=True) -async def name(event): - await event.delete() - pru = event.sender_id - var = "STARTMSG" - name = "Bot Welcome Message:" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "**BOT WELCOME MSG**\nEnter the msg which u want to show when someone start your assistant Bot.\nYou Can use `{me}` , `{mention}` Parameters Too\nUse /cancel to terminate the operation.", - ) - response = conv.wait_event(events.NewMessage(chats=pru)) - response = await response - themssg = response.message.message - if themssg == "/cancel": - return await conv.send_message( - "Cancelled!!", - buttons=get_back_button("cbs_chatbot"), - ) - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("cbs_chatbot"), - ) - - -@callback("onchbot", owner=True) -async def chon(event): - var = "PMBOT" - await setit(event, var, "True") - Loader(path="assistant/pmbot.py", key="PM Bot").load() - if AST_PLUGINS.get("pmbot"): - for i, e in AST_PLUGINS["pmbot"]: - event.client.remove_event_handler(i) - for i, e in AST_PLUGINS["pmbot"]: - event.client.add_event_handler(i, events.NewMessage(**e)) - await event.edit( - "Done! Now u Can Chat With People Via This Bot", - buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")], - ) - - -@callback("ofchbot", owner=True) -async def chon(event): - var = "PMBOT" - await setit(event, var, "False") - if AST_PLUGINS.get("pmbot"): - for i, e in AST_PLUGINS["pmbot"]: - event.client.remove_event_handler(i) - await event.edit( - "Done! Chat People Via This Bot Stopped.", - buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")], - ) - - -@callback("inli_pic", owner=True) -async def media(event): - await event.delete() - pru = event.sender_id - var = "INLINE_PIC" - name = "Inline Media" - async with event.client.conversation(pru) as conv: - await conv.send_message( - "**Inline Media**\nSend me a pic/gif/ or link to set as inline media.\n\nUse /cancel to terminate the operation.", - ) - response = await conv.get_response() - try: - themssg = response.message - if themssg == "/cancel": - return await conv.send_message( - "Operation cancelled!!", - buttons=get_back_button("setter"), - ) - except BaseException as er: - LOGS.exception(er) - media = await event.client.download_media(response, "inlpic") - if ( - not (response.text).startswith("/") - and response.text != "" - and (not response.media or isinstance(response.media, MessageMediaWebPage)) - ): - url = text_to_url(response) - else: - try: - x = upl(media) - url = f"https://graph.org/{x[0]}" - remove(media) - except BaseException as er: - LOGS.exception(er) - return await conv.send_message( - "Terminated.", - buttons=get_back_button("setter"), - ) - await setit(event, var, url) - await conv.send_message( - f"{name} has been set.", - buttons=get_back_button("setter"), - ) - - -FD_MEDIA = {} - - -@callback(re.compile("fd(.*)"), owner=True) -async def fdroid_dler(event): - uri = event.data_match.group(1).decode("utf-8") - if FD_MEDIA.get(uri): - return await event.edit(file=FD_MEDIA[uri]) - await event.answer("• Starting Download •", alert=True) - await event.edit("• Downloading.. •") - URL = f"https://f-droid.org/packages/{uri}" - conte = await async_searcher(URL, re_content=True) - BSC = bs(conte, "html.parser", from_encoding="utf-8") - dl_ = BSC.find("p", "package-version-download").find("a")["href"] - title = BSC.find("h3", "package-name").text.strip() - thumb = BSC.find("img", "package-icon")["src"] - if thumb.startswith("/"): - thumb = f"https://f-droid.org{thumb}" - thumb, _ = await fast_download(thumb, filename=f"{uri}.png") - s_time = time.time() - file, _ = await fast_download( - dl_, - filename=f"{title}.apk", - progress_callback=lambda d, t: asyncio.get_event_loop().create_task( - progress( - d, - t, - event, - s_time, - "Downloading...", - ) - ), - ) - - time.time() - n_file = await event.client.fast_uploader( - file, show_progress=True, event=event, message="Uploading...", to_delete=True - ) - buttons = Button.switch_inline("Search Back", query="fdroid", same_peer=True) - try: - msg = await event.edit( - f"**• [{title}]({URL}) •**", file=n_file, thumb=thumb, buttons=buttons - ) - except Exception as er: - LOGS.exception(er) - try: - msg = await event.client.edit_message( - await event.get_input_chat(), - event.message_id, - f"**• [{title}]({URL}) •**", - buttons=buttons, - thumb=thumb, - file=n_file, - ) - except Exception as er: - os.remove(thumb) - LOGS.exception(er) - return await event.edit(f"**ERROR**: `{er}`", buttons=buttons) - if msg and hasattr(msg, "media"): - FD_MEDIA.update({uri: msg.media}) - os.remove(thumb) diff --git a/modules/assistant/start.py b/modules/assistant/start.py index fcbe82cd00..cf04de9742 100644 --- a/modules/assistant/start.py +++ b/modules/assistant/start.py @@ -56,26 +56,10 @@ def get_start_message(): return Owner_info_msg, _custom -_settings = [ - [ - Button.inline("API Kᴇʏs", data="cbs_apiset"), - Button.inline("Pᴍ Bᴏᴛ", data="cbs_chatbot"), - ], - [ - Button.inline("Aʟɪᴠᴇ", data="cbs_alvcstm"), - Button.inline("PᴍPᴇʀᴍɪᴛ", data="cbs_ppmset"), - ], - [ - Button.inline("Fᴇᴀᴛᴜʀᴇs", data="cbs_otvars"), - Button.inline("VC Sᴏɴɢ Bᴏᴛ", data="cbs_vcb"), - ], - [Button.inline("« Bᴀᴄᴋ", data="mainmenu")], -] - _start = [ [ Button.inline("Lᴀɴɢᴜᴀɢᴇ 🌐", data="lang"), - Button.inline("Sᴇᴛᴛɪɴɢs ⚙️", data="setter"), +# Button.inline("Sᴇᴛᴛɪɴɢs ⚙️", data="setter"), ], [ Button.inline("Sᴛᴀᴛs ✨", data="stat"), @@ -149,10 +133,12 @@ async def ultroid_handler(event): else: name = get_display_name(event.sender) if args == "set": + """ await event.reply( "Choose from the below options -", buttons=_settings, ) + """ return elif args == "_manager": with contextlib.suppress(ImportError): @@ -225,13 +211,32 @@ async def bdcast(event): ) +""" + +_settings = [ + [ + Button.inline("API Kᴇʏs", data="cbs_apiset"), + Button.inline("Pᴍ Bᴏᴛ", data="cbs_chatbot"), + ], + [ + Button.inline("Aʟɪᴠᴇ", data="cbs_alvcstm"), + Button.inline("PᴍPᴇʀᴍɪᴛ", data="cbs_ppmset"), + ], + [ + Button.inline("Fᴇᴀᴛᴜʀᴇs", data="cbs_otvars"), + Button.inline("VC Sᴏɴɢ Bᴏᴛ", data="cbs_vcb"), + ], + [Button.inline("« Bᴀᴄᴋ", data="mainmenu")], +] + + @callback("setter", owner=True) async def setting(event): await event.edit( "Choose from the below options -", buttons=_settings, ) - +""" @callback("tz", owner=True) async def timezone_(event): diff --git a/modules/basic/bot.py b/modules/basic/bot.py index 1f35652be6..566ed73b13 100644 --- a/modules/basic/bot.py +++ b/modules/basic/bot.py @@ -8,7 +8,6 @@ import os import sys import time - from core import start_time from core.remote import rm from core.git import repo @@ -65,11 +64,7 @@ async def logs_func(event): client = mod.get_client() with open(file_path, "r") as file: title = "Ultroid Logs" - if pat := udB.get_key("_TG_LOG"): - page = client.edit_page(pat, title, content=[file.read()]) - else: - page = client.create_page(title=title, content=[file.read()]) - udB.set_key("_TG_LOG", page["path"]) + page = client.create_page(title=title, content=[file.read()]) return await event.eor(f'[Ultroid Logs]({page["url"]})', link_preview=True) await event.eor(file=file_path) From 776cf6709dda20f960ed1f8aed0e113822ea4be8 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Sat, 24 Jun 2023 23:28:14 +0530 Subject: [PATCH 20/74] minor fix --- callbacks.py | 1277 +++++++++++++++++++++++++++++++++++++ modules/basic/devtools.py | 6 +- 2 files changed, 1280 insertions(+), 3 deletions(-) create mode 100644 callbacks.py diff --git a/callbacks.py b/callbacks.py new file mode 100644 index 0000000000..e73f3de1d0 --- /dev/null +++ b/callbacks.py @@ -0,0 +1,1277 @@ +# Ultroid - UserBot +# Copyright (C) 2021-2022 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +import ast +import asyncio +import re +import sys, os +import time +from asyncio.exceptions import TimeoutError as AsyncTimeOut +from os import execl, remove +from random import choice + +from bs4 import BeautifulSoup as bs +from core import HNDLR, udB, LOGS, Var +from database.helpers import get_random_color +# try: +# from pyUltroid.fns.gDrive import GDriveManager +# except ImportError: +# GDriveManager = None +from telegraph import upload_file as upl +from telethon import Button, events +from telethon.tl.types import MessageMediaWebPage +from telethon.utils import get_peer_id +from localization import get_string + +from utilities.helper import fast_download, progress +from utilities.tools import Carbon, async_searcher #, get_paste, telegraph_client +#from pyUltroid.startup.loader import Loader +from telethon.tl import types +from . import callback, get_back_button, asst + +# --------------------------------------------------------------------# +# telegraph = telegraph_client() +# GDrive = GDriveManager() if GDriveManager else None +# --------------------------------------------------------------------# + +async def setit(_, key, value): + udB.set_key(key, value) + +def text_to_url(event): + """function to get media url (with|without) Webpage""" + if isinstance(event.media, MessageMediaWebPage): + webpage = event.media.webpage + if not isinstance(webpage, types.WebPageEmpty) and webpage.type in ["photo"]: + return webpage.display_url + return event.text + + +# --------------------------------------------------------------------# + +_buttons = { + "otvars": { + "text": "Other Variables to set for @TeamUltroid:", + "buttons": [ + [ + Button.inline("Tᴀɢ Lᴏɢɢᴇʀ", data="taglog"), + Button.inline("SᴜᴘᴇʀFʙᴀɴ", data="cbs_sfban"), + ], + [ + Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ", data="sudo"), + Button.inline("Hᴀɴᴅʟᴇʀ", data="hhndlr"), + ], + [ + Button.inline("Exᴛʀᴀ Pʟᴜɢɪɴs", data="plg"), + Button.inline("Aᴅᴅᴏɴs", data="eaddon"), + ], + [ + Button.inline("Eᴍᴏᴊɪ ɪɴ Hᴇʟᴘ", data="emoj"), + Button.inline("Sᴇᴛ ɢDʀɪᴠᴇ", data="gdrive"), + ], + [ + Button.inline("Iɴʟɪɴᴇ Pɪᴄ", data="inli_pic"), + Button.inline("Sᴜᴅᴏ HNDLR", data="shndlr"), + ], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ", "cbs_oofdm")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "sfban": { + "text": "SuperFban Settings:", + "buttons": [ + [Button.inline("FBᴀɴ Gʀᴏᴜᴘ", data="sfgrp")], + [Button.inline("Exᴄʟᴜᴅᴇ Fᴇᴅs", data="abs_sfexf")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], + ], + }, + "apauto": { + "text": "This'll auto approve on outgoing messages", + "buttons": [ + [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ ON", data="apon")], + [Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ OFF", data="apof")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], + ], + }, + "alvcstm": { + "text": f"Customise your {HNDLR}alive. Choose from the below options -", + "buttons": [ + [Button.inline("Aʟɪᴠᴇ Tᴇxᴛ", data="abs_alvtx")], + [Button.inline("Aʟɪᴠᴇ ᴍᴇᴅɪᴀ", data="alvmed")], + [Button.inline("Dᴇʟᴇᴛᴇ Aʟɪᴠᴇ Mᴇᴅɪᴀ", data="delmed")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "pmcstm": { + "text": "Customise your PMPERMIT Settings -", + "buttons": [ + [ + Button.inline("Pᴍ Tᴇxᴛ", data="pmtxt"), + Button.inline("Pᴍ Mᴇᴅɪᴀ", data="pmmed"), + ], + [ + Button.inline("Aᴜᴛᴏ Aᴘᴘʀᴏᴠᴇ", data="cbs_apauto"), + Button.inline("PMLOGGER", data="pml"), + ], + [ + Button.inline("Sᴇᴛ Wᴀʀɴs", data="swarn"), + Button.inline("Dᴇʟᴇᴛᴇ Pᴍ Mᴇᴅɪᴀ", data="delpmmed"), + ], + [Button.inline("PMPermit Type", data="cbs_pmtype")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")], + ], + }, + "pmtype": { + "text": "Select the type of PMPermit needed.", + "buttons": [ + [Button.inline("Inline", data="inpm_in")], + [Button.inline("Normal", data="inpm_no")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], + ], + }, + "ppmset": { + "text": "PMPermit Settings:", + "buttons": [ + [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oɴ", data="pmon")], + [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oғғ", data="pmoff")], + [Button.inline("Cᴜsᴛᴏᴍɪᴢᴇ PMPᴇʀᴍɪᴛ", data="cbs_pmcstm")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "chatbot": { + "text": "From This Feature U can chat with ppls Via ur Assistant Bot.\n[More info](https://t.me/UltroidUpdates/2)", + "buttons": [ + [ + Button.inline("Cʜᴀᴛ Bᴏᴛ Oɴ", data="onchbot"), + Button.inline("Cʜᴀᴛ Bᴏᴛ Oғғ", data="ofchbot"), + ], + [ + Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ", data="bwel"), + Button.inline("Bᴏᴛ Wᴇʟᴄᴏᴍᴇ Mᴇᴅɪᴀ", data="botmew"), + ], + [Button.inline("Bᴏᴛ Iɴғᴏ Tᴇxᴛ", data="botinfe")], + [Button.inline("Fᴏʀᴄᴇ Sᴜʙsᴄʀɪʙᴇ", data="pmfs")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "vcb": { + "text": "From This Feature U can play songs in group voice chat\n\n[moreinfo](https://t.me/UltroidUpdates/4)", + "buttons": [ + [Button.inline("VC Sᴇssɪᴏɴ", data="abs_vcs")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + }, + "oofdm": { + "text": "About [Dual Mode](https://t.me/UltroidUpdates/18)", + "buttons": [ + [ + Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oɴ", "dmof"), + Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oғғ", "dmof"), + ], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Hɴᴅʟʀ", "dmhn")], + [Button.inline("« Back", data="cbs_otvars")], + ], + }, + "apiset": { + "text": get_string("ast_1"), + "buttons": [ + [Button.inline("Remove.bg API", data="abs_rmbg")], + [Button.inline("DEEP API", data="abs_dapi")], + [Button.inline("OCR API", data="abs_oapi")], + [Button.inline("« Back", data="setter")], + ], + }, +} + +_convo = { + "rmbg": { + "var": "RMBG_API", + "name": "Remove.bg API Key", + "text": get_string("ast_2"), + "back": "cbs_apiset", + }, + "dapi": { + "var": "DEEP_AI", + "name": "Deep AI Api Key", + "text": "Get Your Deep Api from deepai.org and send here.", + "back": "cbs_apiset", + }, + "oapi": { + "var": "OCR_API", + "name": "Ocr Api Key", + "text": "Get Your OCR api from ocr.space and send that Here.", + "back": "cbs_apiset", + }, + "pmlgg": { + "var": "PMLOGGROUP", + "name": "Pm Log Group", + "text": "Send chat id of chat which you want to save as Pm log Group.", + "back": "pml", + }, + "vcs": { + "var": "VC_SESSION", + "name": "Vc Session", + "text": "**Vc session**\nEnter the New session u generated for vc bot.\n\nUse /cancel to terminate the operation.", + "back": "cbs_vcb", + }, + "settag": { + "var": "TAG_LOG", + "name": "Tag Log Group", + "text": f"Make a group, add your assistant and make it admin.\nGet the `{HNDLR}id` of that group and send it here for tag logs.\n\nUse /cancel to cancel.", + "back": "taglog", + }, + "alvtx": { + "var": "ALIVE_TEXT", + "name": "Alive Text", + "text": "**Alive Text**\nEnter the new alive text.\n\nUse /cancel to terminate the operation.", + "back": "cbs_alvcstm", + }, + "sfexf": { + "var": "EXCLUDE_FED", + "name": "Excluded Fed", + "text": "Send the Fed IDs you want to exclude in the ban. Split by a space.\neg`id1 id2 id3`\nSet is as `None` if you dont want any.\nUse /cancel to go back.", + "back": "cbs_sfban", + }, +} + + +TOKEN_FILE = "resources/auths/auth_token.txt" + + +@callback( + re.compile( + "sndplug_(.*)", + ), + owner=True, +) +async def send(eve): + key, name = (eve.data_match.group(1)).decode("UTF-8").split("_") + thumb = "resources/extras/inline.jpg" + await eve.answer("■ Sending ■") + data = f"uh_{key}_" + index = None + if "|" in name: + name, index = name.split("|") + key = "plugins" if key == "Official" else key.lower() + plugin = f"{key}/{name}.py" + _ = f"pasta-{plugin}" + if index is not None: + data += f"|{index}" + _ += f"|{index}" + buttons = [ + [ + Button.inline( + "« Pᴀsᴛᴇ »", + data=_, + ) + ], + [ + Button.inline("« Bᴀᴄᴋ", data=data), + ], + ] + try: + await eve.edit(file=plugin, thumb=thumb, buttons=buttons) + except Exception as er: + await eve.answer(str(er), alert=True) + + +heroku_api, app_name = Var.HEROKU_API, Var.HEROKU_APP_NAME + + +@callback("updatenow", owner=True) +async def update(eve): + repo = Repo() + ac_br = repo.active_branch + ups_rem = repo.remote("upstream") + if heroku_api: + import heroku3 + + try: + heroku = heroku3.from_key(heroku_api) + heroku_app = None + heroku_applications = heroku.apps() + except BaseException as er: + LOGS.exception(er) + return await eve.edit("`Wrong HEROKU_API.`") + for app in heroku_applications: + if app.name == app_name: + heroku_app = app + if not heroku_app: + await eve.edit("`Wrong HEROKU_APP_NAME.`") + repo.__del__() + return + await eve.edit(get_string("clst_1")) + ups_rem.fetch(ac_br) + repo.git.reset("--hard", "FETCH_HEAD") + heroku_git_url = heroku_app.git_url.replace( + "https://", f"https://api:{heroku_api}@" + ) + + if "heroku" in repo.remotes: + remote = repo.remote("heroku") + remote.set_url(heroku_git_url) + else: + remote = repo.create_remote("heroku", heroku_git_url) + try: + remote.push(refspec=f"HEAD:refs/heads/{ac_br}", force=True) + except GitCommandError as error: + await eve.edit(f"`Here is the error log:\n{error}`") + repo.__del__() + return + await eve.edit("`Successfully Updated!\nRestarting, please wait...`") + else: + await eve.edit(get_string("clst_1")) + call_back() + await bash("git pull && pip3 install -r requirements.txt") + execl(sys.executable, sys.executable, "-m", "pyUltroid") + + + + +@callback( + re.compile( + "pasta-(.*)", + ), + owner=True, +) +async def _(e): + ok = (e.data_match.group(1)).decode("UTF-8") + index = None + 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 _: + return await e.answer(key[:30], alert=True) + if ok.startswith("addons"): + key = "Addons" + elif ok.startswith("vcbot"): + key = "VCBot" + else: + key = "Official" + data = f"uh_{key}_" + if index is not None: + data += f"|{index}" + await e.edit( + "", + buttons=[ + [Button.url("Lɪɴᴋ", link), Button.url("Rᴀᴡ", raw)], + [Button.inline("« Bᴀᴄᴋ", data=data)], + ], + ) + + +@callback(re.compile("cbs_(.*)"), owner=True) +async def _edit_to(event): + match = event.data_match.group(1).decode("utf-8") + data = _buttons.get(match) + if not data: + return + await event.edit(data["text"], buttons=data["buttons"], link_preview=False) + + +@callback(re.compile("abs_(.*)"), owner=True) +async def convo_handler(event: events.CallbackQuery): + match = event.data_match.group(1).decode("utf-8") + if not _convo.get(match): + return + await event.delete() + get_ = _convo[match] + back = get_["back"] + async with event.client.conversation(event.sender_id) as conv: + await conv.send_message(get_["text"]) + response = await conv.get_response() + themssg = response.message + try: + themssg = ast.literal_eval(themssg) + except Exception: + pass + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button(back), + ) + await setit(event, get_["var"], themssg) + await conv.send_message( + f"{get_['name']} changed to `{themssg}`", + buttons=get_back_button(back), + ) + + +@callback("authorise", owner=True) +async def _(e): + if not e.is_private: + return + url = GDrive._create_token_file() + await e.edit("Go to the below link and send the code!") + async with asst.conversation(e.sender_id) as conv: + await conv.send_message(url) + code = await conv.get_response() + if GDrive._create_token_file(code=code.text): + await conv.send_message( + "`Success!\nYou are all set to use Google Drive with Ultroid Userbot.`", + buttons=Button.inline("Main Menu", data="setter"), + ) + else: + await conv.send_message("Wrong code! Click authorise again.") + + +@callback("folderid", owner=True, func=lambda x: x.is_private) +async def _(e): + if not e.is_private: + return + msg = ( + "Send your FOLDER ID\n\n" + + "For FOLDER ID:\n" + + "1. Open Google Drive App.\n" + + "2. Create Folder.\n" + + "3. Make that folder public.\n" + + "4. Send link of that folder." + ) + await e.delete() + async with asst.conversation(e.sender_id, timeout=150) as conv: + await conv.send_message(msg) + repl = await conv.get_response() + id = repl.text + if id.startswith("https"): + id = id.split("?id=")[-1] + udB.set_key("GDRIVE_FOLDER_ID", id) + await repl.reply( + "`Success.`", + buttons=get_back_button("gdrive"), + ) + + +@callback("gdrive", owner=True) +async def _(e): + if not e.is_private: + return + await e.edit( + "Click Authorise and send the code.\n\nYou can use your own CLIENT ID and SECRET by [this](https://t.me/UltroidUpdates/37)", + buttons=[ + [ + Button.inline("Folder ID", data="folderid"), + Button.inline("Authorise", data="authorise"), + ], + [Button.inline("« Back", data="cbs_otvars")], + ], + link_preview=False, + ) + + +@callback("dmof", owner=True) +async def rhwhe(e): + if udB.get_key("DUAL_MODE"): + udB.del_key("DUAL_MODE") + key = "Off" + else: + udB.set_key("DUAL_MODE", "True") + key = "On" + Msg = f"Dual Mode : {key}" + await e.edit(Msg, buttons=get_back_button("cbs_otvars")) + + +@callback("dmhn", owner=True) +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "DUAL_HNDLR" + name = "Dual Handler" + CH = udB.get_key(var) or "/" + async with event.client.conversation(pru) as conv: + await conv.send_message( + f"Send The Symbol Which u want as Handler/Trigger to use your Assistant bot\nUr Current Handler is [ `{CH}` ]\n\n use /cancel to cancel.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("emoj", owner=True) +async def emoji(event): + await event.delete() + pru = event.sender_id + var = "EMOJI_IN_HELP" + name = f"Emoji in `{HNDLR}help` menu" + async with event.client.conversation(pru) as conv: + await conv.send_message("Send emoji u want to set 🙃.\n\nUse /cancel to cancel.") + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", HNDLR)): + await conv.send_message( + "Incorrect Emoji", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("plg", owner=True) +async def pluginch(event): + await event.delete() + pru = event.sender_id + var = "PLUGIN_CHANNEL" + name = "Plugin Channel" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "Send id or username of a channel from where u want to install all plugins\n\nOur Channel~ @ultroidplugins\n\nUse /cancel to cancel.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", HNDLR)): + await conv.send_message( + "Incorrect channel", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n After Setting All Things Do Restart", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("hhndlr", owner=True) +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "HNDLR" + name = "Handler/ Trigger" + async with event.client.conversation(pru) as conv: + await conv.send_message( + f"Send The Symbol Which u want as Handler/Trigger to use bot\nUr Current Handler is [ `{HNDLR}` ]\n\n use /cancel to cancel.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", "#", "@")): + await conv.send_message( + "This cannot be used as handler", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("shndlr", owner=True) +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "SUDO_HNDLR" + name = "Sudo Handler" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "Send The Symbol Which u want as Sudo Handler/Trigger to use bot\n\n use /cancel to cancel." + ) + + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("cbs_otvars"), + ) + elif themssg.startswith(("/", "#", "@")): + await conv.send_message( + "This cannot be used as handler", + buttons=get_back_button("cbs_otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_otvars"), + ) + + +@callback("taglog", owner=True) +async def tagloggrr(e): + BUTTON = [ + [Button.inline("SET TAG LOG", data="abs_settag")], + [Button.inline("DELETE TAG LOG", data="deltag")], + get_back_button("cbs_otvars"), + ] + await e.edit( + "Choose Options", + buttons=BUTTON, + ) + + +@callback("deltag", owner=True) +async def _(e): + udB.del_key("TAG_LOG") + await e.answer("Done!!! Tag Logger has been turned Off") + + +@callback("eaddon", owner=True) +async def pmset(event): + BT = ( + [Button.inline("Aᴅᴅᴏɴs Oғғ", data="edof")] + if udB.get_key("ADDONS") + else [Button.inline("Aᴅᴅᴏɴs Oɴ", data="edon")] + ) + + await event.edit( + "ADDONS~ Extra Plugins:", + buttons=[ + BT, + [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], + ], + ) + + +@callback("edon", owner=True) +async def eddon(event): + var = "ADDONS" + await setit(event, var, "True") + await event.edit( + "Done! ADDONS has been turned on!!\n\n After Setting All Things Do Restart", + buttons=get_back_button("eaddon"), + ) + + +@callback("edof", owner=True) +async def eddof(event): + udB.set_key("ADDONS", "False") + await event.edit( + "Done! ADDONS has been turned off!! After Setting All Things Do Restart", + buttons=get_back_button("eaddon"), + ) + + +@callback("sudo", owner=True) +async def pmset(event): + BT = ( + [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oғғ", data="ofsudo")] + if udB.get_key("SUDO") + else [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oɴ", data="onsudo")] + ) + + await event.edit( + f"SUDO MODE ~ Some peoples can use ur Bot which u selected. To know More use `{HNDLR}help sudo`", + buttons=[ + BT, + [Button.inline("« Bᴀᴄᴋ", data="cbs_otvars")], + ], + ) + + +@callback("onsudo", owner=True) +async def eddon(event): + var = "SUDO" + await setit(event, var, "True") + await event.edit( + "Done! SUDO MODE has been turned on!!\n\n After Setting All Things Do Restart", + buttons=get_back_button("sudo"), + ) + + +@callback("ofsudo", owner=True) +async def eddof(event): + var = "SUDO" + await setit(event, var, "False") + await event.edit( + "Done! SUDO MODE has been turned off!! After Setting All Things Do Restart", + buttons=get_back_button("sudo"), + ) + + +@callback("sfgrp", owner=True) +async def sfgrp(event): + await event.delete() + name = "FBan Group ID" + var = "FBAN_GROUP_ID" + pru = event.sender_id + async with asst.conversation(pru) as conv: + await conv.send_message( + f"Make a group, add @MissRose_Bot, send `{HNDLR}id`, copy that and send it here.\nUse /cancel to go back.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_sfban"), + ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_sfban"), + ) + + +@callback("alvmed", owner=True) +async def media(event): + await event.delete() + pru = event.sender_id + var = "ALIVE_PIC" + name = "Alive Media" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**Alive Media**\nSend me a pic/gif/media to set as alive media.\n\nUse /cancel to terminate the operation.", + ) + response = await conv.get_response() + try: + themssg = response.message + if themssg == "/cancel": + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("cbs_alvcstm"), + ) + except BaseException as er: + LOGS.exception(er) + if ( + not (response.text).startswith("/") + and response.text != "" + and (not response.media or isinstance(response.media, MessageMediaWebPage)) + ): + url = text_to_url(response) + elif response.sticker: + url = response.file.id + else: + media = await event.client.download_media(response, "alvpc") + try: + x = upl(media) + url = f"https://graph.org/{x[0]}" + remove(media) + except BaseException as er: + LOGS.exception(er) + return await conv.send_message( + "Terminated.", + buttons=get_back_button("cbs_alvcstm"), + ) + await setit(event, var, url) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("cbs_alvcstm"), + ) + + +@callback("delmed", owner=True) +async def dell(event): + try: + udB.del_key("ALIVE_PIC") + return await event.edit( + get_string("clst_5"), buttons=get_back_button("cbs_alabs_vcstm") + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=get_back_button("cbs_alabs_vcstm"), + ) + + +@callback("inpm_in", owner=True) +async def inl_on(event): + var = "INLINE_PM" + await setit(event, var, "True") + await event.edit( + "Done!! PMPermit type has been set to inline!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]], + ) + + +@callback("inpm_no", owner=True) +async def inl_on(event): + var = "INLINE_PM" + await setit(event, var, "False") + await event.edit( + "Done!! PMPermit type has been set to normal!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_pmtype")]], + ) + + +@callback("pmtxt", owner=True) +async def name(event): + await event.delete() + pru = event.sender_id + var = "PM_TEXT" + name = "PM Text" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**PM Text**\nEnter the new Pmpermit text.\n\nu can use `{name}` `{fullname}` `{count}` `{mention}` `{username}` to get this from user Too\n\nUse /cancel to terminate the operation.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_pmcstm"), + ) + if len(themssg) > 4090: + return await conv.send_message( + "Message too long!\nGive a shorter message please!!", + buttons=get_back_button("cbs_pmcstm"), + ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n\nAfter Setting All Things Do restart", + buttons=get_back_button("cbs_pmcstm"), + ) + + +@callback("swarn", owner=True) +async def name(event): + m = range(1, 10) + tultd = [Button.inline(f"{x}", data=f"wrns_{x}") for x in m] + lst = list(zip(tultd[::3], tultd[1::3], tultd[2::3])) + lst.append([Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")]) + await event.edit( + "Select the number of warnings for a user before getting blocked in PMs.", + buttons=lst, + ) + + +@callback(re.compile(b"wrns_(.*)"), owner=True) +async def set_wrns(event): + value = int(event.data_match.group(1).decode("UTF-8")) + if dn := udB.set_key("PMWARNS", value): + await event.edit( + f"PM Warns Set to {value}.\nNew users will have {value} chances in PMs before getting banned.", + buttons=get_back_button("cbs_pmcstm"), + ) + else: + await event.edit( + f"Something went wrong, please check your {HNDLR}logs!", + buttons=get_back_button("cbs_pmcstm"), + ) + + +@callback("pmmed", owner=True) +async def media(event): + await event.delete() + pru = event.sender_id + var = "PMPIC" + name = "PM Media" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**PM Media**\nSend me a pic/gif/sticker/link to set as pmpermit media.\n\nUse /cancel to terminate the operation.", + ) + response = await conv.get_response() + try: + themssg = response.message + if themssg == "/cancel": + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("cbs_pmcstm"), + ) + except BaseException as er: + LOGS.exception(er) + media = await event.client.download_media(response, "pmpc") + if ( + not (response.text).startswith("/") + and response.text != "" + and (not response.media or isinstance(response.media, MessageMediaWebPage)) + ): + url = text_to_url(response) + elif response.sticker: + url = response.file.id + else: + try: + x = upl(media) + url = f"https://graph.org/{x[0]}" + remove(media) + except BaseException as er: + LOGS.exception(er) + return await conv.send_message( + "Terminated.", + buttons=get_back_button("cbs_pmcstm"), + ) + await setit(event, var, url) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("cbs_pmcstm"), + ) + + +@callback("delpmmed", owner=True) +async def dell(event): + try: + udB.del_key("PMPIC") + return await event.edit( + get_string("clst_5"), buttons=get_back_button("cbs_pmcstm") + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) + + +@callback("apon", owner=True) +async def apon(event): + var = "AUTOAPPROVE" + await setit(event, var, "True") + await event.edit( + "Done!! AUTOAPPROVE Started!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]], + ) + + +@callback("apof", owner=True) +async def apof(event): + try: + udB.set_key("AUTOAPPROVE", "False") + return await event.edit( + "Done! AUTOAPPROVE Stopped!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_apauto")]], + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) + + +@callback("pml", owner=True) +async def l_vcs(event): + BT = ( + [Button.inline("PMLOGGER OFF", data="pmlogof")] + if udB.get_key("PMLOG") + else [Button.inline("PMLOGGER ON", data="pmlog")] + ) + + await event.edit( + "PMLOGGER This Will Forward Ur Pm to Ur Private Group -", + buttons=[ + BT, + [Button.inline("PᴍLᴏɢɢᴇʀ Gʀᴏᴜᴘ", "abs_pmlgg")], + [Button.inline("« Bᴀᴄᴋ", data="cbs_pmcstm")], + ], + ) + + +@callback("pmlog", owner=True) +async def pmlog(event): + await setit(event, "PMLOG", "True") + await event.edit( + "Done!! PMLOGGER Started!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], + ) + + +@callback("pmlogof", owner=True) +async def pmlogof(event): + try: + udB.del_key("PMLOG") + return await event.edit( + "Done! PMLOGGER Stopped!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], + ) + except BaseException as er: + LOGS.exception(er) + return await event.edit( + get_string("clst_4"), + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) + + +@callback("pmon", owner=True) +async def pmonn(event): + var = "PMSETTING" + await setit(event, var, "True") + await event.edit( + "Done! PMPermit has been turned on!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]], + ) + + +@callback("pmoff", owner=True) +async def pmofff(event): + var = "PMSETTING" + await setit(event, var, "False") + await event.edit( + "Done! PMPermit has been turned off!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="cbs_ppmset")]], + ) + + +@callback("botmew", owner=True) +async def hhh(e): + async with e.client.conversation(e.chat_id) as conv: + await conv.send_message("Send Any Media to keep at your Bot's welcome ") + msg = await conv.get_response() + if not msg.media or msg.text.startswith("/"): + return await conv.send_message( + "Terminated!", buttons=get_back_button("cbs_chatbot") + ) + udB.set_key("STARTMEDIA", msg.file.id) + await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot")) + + +@callback("botinfe", owner=True) +async def hhh(e): + async with e.client.conversation(e.chat_id) as conv: + await conv.send_message( + "Send message to set to Display, when user Press Info button in Bot Welcome!\n\nsend `False` to completely remove that button.." + ) + msg = await conv.get_response() + if msg.media or msg.text.startswith("/"): + return await conv.send_message( + "Terminated!", buttons=get_back_button("cbs_chatbot") + ) + udB.set_key("BOT_INFO_START", msg.text) + await conv.send_message("Done!", buttons=get_back_button("cbs_chatbot")) + + +@callback("pmfs", owner=True) +async def heheh(event): + Ll = [] + err = "" + async with event.client.conversation(event.chat_id) as conv: + await conv.send_message( + "• Send The Chat Id(s), which you want user to Join Before using Chat/Pm Bot\n\n• Send /clear to disable PmBot Force sub..\n• • Send /cancel to stop this process.." + ) + await conv.send_message( + "Example : \n`-1001234567\n-100778888`\n\nFor Multiple Chat(s)." + ) + try: + msg = await conv.get_response() + except AsyncTimeOut: + return await conv.send_message("**• TimeUp!**\nStart from /start back.") + if not msg.text or msg.text.startswith("/"): + timyork = "Cancelled!" + if msg.text == "/clear": + udB.del_key("PMBOT_FSUB") + timyork = "Done! Force Subscribe Stopped\nRestart your Bot!" + return await conv.send_message( + "Cancelled!", buttons=get_back_button("cbs_chatbot") + ) + for chat in msg.message.split("\n"): + if chat.startswith("-") or chat.isdigit(): + chat = int(chat) + try: + CHSJSHS = await event.client.get_entity(chat) + Ll.append(get_peer_id(CHSJSHS)) + except Exception as er: + err += f"**{chat}** : {er}\n" + if err: + return await conv.send_message(err) + udB.set_key("PMBOT_FSUB", str(Ll)) + await conv.send_message( + "Done!\nRestart Your Bot.", buttons=get_back_button("cbs_chatbot") + ) + + +@callback("bwel", owner=True) +async def name(event): + await event.delete() + pru = event.sender_id + var = "STARTMSG" + name = "Bot Welcome Message:" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**BOT WELCOME MSG**\nEnter the msg which u want to show when someone start your assistant Bot.\nYou Can use `{me}` , `{mention}` Parameters Too\nUse /cancel to terminate the operation.", + ) + response = conv.wait_event(events.NewMessage(chats=pru)) + response = await response + themssg = response.message.message + if themssg == "/cancel": + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("cbs_chatbot"), + ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("cbs_chatbot"), + ) + + +@callback("onchbot", owner=True) +async def chon(event): + var = "PMBOT" + await setit(event, var, "True") + Loader(path="assistant/pmbot.py", key="PM Bot").load() + if AST_PLUGINS.get("pmbot"): + for i, e in AST_PLUGINS["pmbot"]: + event.client.remove_event_handler(i) + for i, e in AST_PLUGINS["pmbot"]: + event.client.add_event_handler(i, events.NewMessage(**e)) + await event.edit( + "Done! Now u Can Chat With People Via This Bot", + buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")], + ) + + +@callback("ofchbot", owner=True) +async def chon(event): + var = "PMBOT" + await setit(event, var, "False") + if AST_PLUGINS.get("pmbot"): + for i, e in AST_PLUGINS["pmbot"]: + event.client.remove_event_handler(i) + await event.edit( + "Done! Chat People Via This Bot Stopped.", + buttons=[Button.inline("« Bᴀᴄᴋ", data="cbs_chatbot")], + ) + + +@callback("inli_pic", owner=True) +async def media(event): + await event.delete() + pru = event.sender_id + var = "INLINE_PIC" + name = "Inline Media" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**Inline Media**\nSend me a pic/gif/ or link to set as inline media.\n\nUse /cancel to terminate the operation.", + ) + response = await conv.get_response() + try: + themssg = response.message + if themssg == "/cancel": + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("setter"), + ) + except BaseException as er: + LOGS.exception(er) + media = await event.client.download_media(response, "inlpic") + if ( + not (response.text).startswith("/") + and response.text != "" + and (not response.media or isinstance(response.media, MessageMediaWebPage)) + ): + url = text_to_url(response) + else: + try: + x = upl(media) + url = f"https://graph.org/{x[0]}" + remove(media) + except BaseException as er: + LOGS.exception(er) + return await conv.send_message( + "Terminated.", + buttons=get_back_button("setter"), + ) + await setit(event, var, url) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("setter"), + ) + + +FD_MEDIA = {} + + +@callback(re.compile("fd(.*)"), owner=True) +async def fdroid_dler(event): + uri = event.data_match.group(1).decode("utf-8") + if FD_MEDIA.get(uri): + return await event.edit(file=FD_MEDIA[uri]) + await event.answer("• Starting Download •", alert=True) + await event.edit("• Downloading.. •") + URL = f"https://f-droid.org/packages/{uri}" + conte = await async_searcher(URL, re_content=True) + BSC = bs(conte, "html.parser", from_encoding="utf-8") + dl_ = BSC.find("p", "package-version-download").find("a")["href"] + title = BSC.find("h3", "package-name").text.strip() + thumb = BSC.find("img", "package-icon")["src"] + if thumb.startswith("/"): + thumb = f"https://f-droid.org{thumb}" + thumb, _ = await fast_download(thumb, filename=f"{uri}.png") + s_time = time.time() + file, _ = await fast_download( + dl_, + filename=f"{title}.apk", + progress_callback=lambda d, t: asyncio.get_event_loop().create_task( + progress( + d, + t, + event, + s_time, + "Downloading...", + ) + ), + ) + + time.time() + n_file = await event.client.fast_uploader( + file, show_progress=True, event=event, message="Uploading...", to_delete=True + ) + buttons = Button.switch_inline("Search Back", query="fdroid", same_peer=True) + try: + msg = await event.edit( + f"**• [{title}]({URL}) •**", file=n_file, thumb=thumb, buttons=buttons + ) + except Exception as er: + LOGS.exception(er) + try: + msg = await event.client.edit_message( + await event.get_input_chat(), + event.message_id, + f"**• [{title}]({URL}) •**", + buttons=buttons, + thumb=thumb, + file=n_file, + ) + except Exception as er: + os.remove(thumb) + LOGS.exception(er) + return await event.edit(f"**ERROR**: `{er}`", buttons=buttons) + if msg and hasattr(msg, "media"): + FD_MEDIA.update({uri: msg.media}) + os.remove(thumb) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 70155b3065..8b7298f692 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -257,13 +257,13 @@ async def get_(): if value: try: if mode == "gsource": - exc = inspect.getsource(value) + stdout = inspect.getsource(value) elif mode == "g-args": args = inspect.signature(value).parameters.values() name = "" if hasattr(value, "__name__"): name = value.__name__ - exc = f"**{name}**\n\n" + "\n ".join([str(arg) for arg in args]) + stdout = f"**{name}**\n\n" + "\n ".join([str(arg) for arg in args]) except Exception: exc = traceback.format_exc() err = exc or stderr @@ -299,8 +299,8 @@ async def get_(): evaluation = get_string("instu_4") if evaluation: final_output += f"\n\n __►__ **OUTPUT**: \n{evaluation}" + final_output = str(evaluation) if len(final_output) > 4096: - final_output = str(evaluation) with BytesIO(final_output.encode()) as out_file: out_file.name = "eval.txt" await event.client.send_file( From 9c909fd5b750ea62b5c0a8078d8eca0cfcf8bc33 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Sun, 25 Jun 2023 10:41:12 +0530 Subject: [PATCH 21/74] Update devtools.py --- modules/basic/devtools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 8b7298f692..c2dbf26142 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -299,8 +299,8 @@ async def get_(): evaluation = get_string("instu_4") if evaluation: final_output += f"\n\n __►__ **OUTPUT**: \n{evaluation}" - final_output = str(evaluation) if len(final_output) > 4096: + final_output = str(evaluation) with BytesIO(final_output.encode()) as out_file: out_file.name = "eval.txt" await event.client.send_file( From 9e63b837c82429e521b464653c823d6de35bbebf Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Mon, 26 Jun 2023 11:36:42 +0530 Subject: [PATCH 22/74] sometimes clear answer doesnt exists --- modules/basic/stickers.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/modules/basic/stickers.py b/modules/basic/stickers.py index f4816b95a4..7b91f8a111 100644 --- a/modules/basic/stickers.py +++ b/modules/basic/stickers.py @@ -20,7 +20,7 @@ InputPeerSelf, InputStickerSetEmpty, ) -from telethon.errors import StickersetInvalidError +from telethon.errors import StickersetInvalidError, PackShortNameInvalidError from telethon.tl.types import InputStickerSetItem as SetItem from telethon.tl.types import InputStickerSetShortName, User from telethon.utils import get_display_name, get_extension, get_input_document @@ -57,18 +57,23 @@ def getName(sender, packType: str): async def AddToNewPack(packType, file, emoji, sender_id, title: str): - sn = await GetUniquePackName() - return await asst( - CreateStickerSetRequest( - user_id=sender_id, - title=title, - short_name=sn, - stickers=[SetItem(file, emoji=emoji)], - videos=packType == "video", - animated=packType == "animated", - software="@TeamUltroid", - ) - ) + for _ in range(5): + sn = await GetUniquePackName() + try: + return await asst( + CreateStickerSetRequest( + user_id=sender_id, + title=title, + short_name=sn, + stickers=[SetItem(file, emoji=emoji)], + videos=packType == "video", + animated=packType == "animated", + software="@TeamUltroid", + ) + ) + except PackShortNameInvalidError as er: + LOGS.error(er) + LOGS.info(f"retrying, {_}") @ultroid_cmd(pattern="kang", manager=True) From a3463c846b5adaffa82821c58271d6d58c0b3781 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Mon, 26 Jun 2023 11:41:35 +0530 Subject: [PATCH 23/74] or answer exists --- modules/basic/stickers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/basic/stickers.py b/modules/basic/stickers.py index 7b91f8a111..a58226a4fc 100644 --- a/modules/basic/stickers.py +++ b/modules/basic/stickers.py @@ -7,7 +7,7 @@ import contextlib import random -from secrets import token_urlsafe +from secrets import token_hex from telethon import errors from telethon.errors.rpcerrorlist import StickersetInvalidError @@ -42,7 +42,7 @@ async def packExists(packId): async def GetUniquePackName(): - packName = f"{token_urlsafe(random.randint(4, 6))}_by_{asst.me.username}" + packName = f"{token_hex(random.randint(4, 8))}_by_{asst.me.username}" return await GetUniquePackName() if await packExists(packName) else packName From 7831f5b6a1bedd21325817a210486c602b658046 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Mon, 26 Jun 2023 11:45:53 +0530 Subject: [PATCH 24/74] fix pack names --- modules/basic/stickers.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/modules/basic/stickers.py b/modules/basic/stickers.py index a58226a4fc..244337f0f2 100644 --- a/modules/basic/stickers.py +++ b/modules/basic/stickers.py @@ -6,7 +6,7 @@ # . import contextlib -import random +import random, string from secrets import token_hex from telethon import errors @@ -42,7 +42,7 @@ async def packExists(packId): async def GetUniquePackName(): - packName = f"{token_hex(random.randint(4, 8))}_by_{asst.me.username}" + packName = f"{random.choice(string.ascii_lowercase)}{token_hex(random.randint(4, 8))}_by_{asst.me.username}" return await GetUniquePackName() if await packExists(packName) else packName @@ -57,23 +57,18 @@ def getName(sender, packType: str): async def AddToNewPack(packType, file, emoji, sender_id, title: str): - for _ in range(5): - sn = await GetUniquePackName() - try: - return await asst( - CreateStickerSetRequest( - user_id=sender_id, - title=title, - short_name=sn, - stickers=[SetItem(file, emoji=emoji)], - videos=packType == "video", - animated=packType == "animated", - software="@TeamUltroid", - ) - ) - except PackShortNameInvalidError as er: - LOGS.error(er) - LOGS.info(f"retrying, {_}") + sn = await GetUniquePackName() + return await asst( + CreateStickerSetRequest( + user_id=sender_id, + title=title, + short_name=sn, + stickers=[SetItem(file, emoji=emoji)], + videos=packType == "video", + animated=packType == "animated", + software="@TeamUltroid", + ) + ) @ultroid_cmd(pattern="kang", manager=True) From afb7f788f2a5aadb97391f6c3948a0f1ca7b9538 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Tue, 27 Jun 2023 19:25:00 +0530 Subject: [PATCH 25/74] Rpcerrors are beautiful when short --- modules/basic/devtools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index c2dbf26142..76f1889916 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -35,7 +35,7 @@ from database.helpers import get_random_color from utilities.misc import json_parser from utilities.tools import Carbon, safe_load - +from telethon.errors import RPCError from .. import * Tasks = {} @@ -246,6 +246,9 @@ async def get_(): # task_id = str(task_id) # Tasks[task_id] = task # task.add_done_callback(lambda _: Tasks.pop(task_id)) + except RPCError as er: + value = None + exc = str(er) except Exception: value = None exc = traceback.format_exc() From 6b412091dbecb73f13da405a98485a2b62659525 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Tue, 27 Jun 2023 19:29:22 +0530 Subject: [PATCH 26/74] Update devtools.py --- modules/basic/devtools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 76f1889916..bbd68650b1 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -248,7 +248,7 @@ async def get_(): # task.add_done_callback(lambda _: Tasks.pop(task_id)) except RPCError as er: value = None - exc = str(er) + exc = f"{er.__class__.__name__}: {er}" except Exception: value = None exc = traceback.format_exc() From 667b952ca2480c91d896a5a6cca1835c1f043bfa Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Tue, 27 Jun 2023 20:27:41 +0530 Subject: [PATCH 27/74] Update devtools.py --- modules/basic/devtools.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index bbd68650b1..0022a43b4c 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -238,14 +238,16 @@ async def get_(): stdout, stderr, exc = None, None, None tima = time.time() try: - value = await aexec(cmd, event) + # value = await aexec(cmd, event) # TODO: Eval can be cancelled - # task = asyncio.create_task(aexec(cmd, event)) - # task_id = int(list(Tasks.keys())[0]) - # task_id += 1 - # task_id = str(task_id) - # Tasks[task_id] = task - # task.add_done_callback(lambda _: Tasks.pop(task_id)) + task = asyncio.create_task(aexec(cmd, event)) + task_id = int(list(Tasks.keys())[0]) + task_id += 1 + task_id = str(task_id) + Tasks[task_id] = task + task.add_done_callback(lambda _: Tasks.pop(task_id)) + await asyncio.wait([task]) + value = task.result() except RPCError as er: value = None exc = f"{er.__class__.__name__}: {er}" From a722ddbfc0151fa745f0218d167d1973cae943c4 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Tue, 27 Jun 2023 20:29:53 +0530 Subject: [PATCH 28/74] Update devtools.py --- modules/basic/devtools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 0022a43b4c..2b229fc76b 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -241,7 +241,10 @@ async def get_(): # value = await aexec(cmd, event) # TODO: Eval can be cancelled task = asyncio.create_task(aexec(cmd, event)) - task_id = int(list(Tasks.keys())[0]) + try: + task_id = int(list(Tasks.keys())[0]) + except IndexError: + task_id = 0 task_id += 1 task_id = str(task_id) Tasks[task_id] = task From 700aa88bbf542b6630508bfd567a74eb8073b434 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Tue, 27 Jun 2023 22:41:39 +0530 Subject: [PATCH 29/74] Eat food either way it will go to stomach --- modules/basic/devtools.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 2b229fc76b..31c9f65717 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -240,7 +240,8 @@ async def get_(): try: # value = await aexec(cmd, event) # TODO: Eval can be cancelled - task = asyncio.create_task(aexec(cmd, event)) + # task = asyncio.create_task(aexec(cmd, event)) + task = asyncio.current_task() try: task_id = int(list(Tasks.keys())[0]) except IndexError: @@ -249,8 +250,9 @@ async def get_(): task_id = str(task_id) Tasks[task_id] = task task.add_done_callback(lambda _: Tasks.pop(task_id)) - await asyncio.wait([task]) - value = task.result() + # await asyncio.wait([task]) + # value = task.result() + value = await aexec(cmd, event) except RPCError as er: value = None exc = f"{er.__class__.__name__}: {er}" From d5cc7f5bf287ae3f3fb7df4c648f776f74ead734 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Wed, 28 Jun 2023 17:35:21 +0530 Subject: [PATCH 30/74] lang --- core/remote.py | 3 +++ modules/assistant/start.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/core/remote.py b/core/remote.py index a782c857ec..6fe7750692 100644 --- a/core/remote.py +++ b/core/remote.py @@ -179,6 +179,9 @@ def evaluate(req): return fetch_sync( f"{self.REMOTE_URL}/getlanguage/{langCode}", evaluate=evaluate ) + + async def getLanguages(self): + return await fetch(f"{self.REMOTE_URL}/getlanguage", re_json=True) def save(self): with open(LOCK_PATH, "w") as file: diff --git a/modules/assistant/start.py b/modules/assistant/start.py index cf04de9742..fce880df95 100644 --- a/modules/assistant/start.py +++ b/modules/assistant/start.py @@ -5,14 +5,14 @@ # PLease read the GNU Affero General Public License in # . -import contextlib +import contextlib, re from datetime import datetime from telethon import Button, events from telethon.errors.rpcerrorlist import MessageDeleteForbiddenError from telethon.utils import get_display_name -from core import LOGS, ultroid_bot, HNDLR +from core import LOGS, ultroid_bot, HNDLR, rm from core.decorators import fullsudos, owner_and_sudos from core.version import version from database import udB @@ -238,6 +238,34 @@ async def setting(event): ) """ +@callback("lang", owner=True) +async def setlang(event): + languages = await rm.getLanguages() + tultd = [ + Button.inline( + f"{languages[ult]['name']} [{ult.lower()}]", + data=f"set_{ult}", + ) + for ult in languages + ] + buttons = list(zip(tultd[::2], tultd[1::2])) + if len(tultd) % 2 == 1: + buttons.append((tultd[-1],)) + buttons.append([Button.inline("« Back", data="mainmenu")]) + await event.edit(get_string("ast_4"), buttons=buttons) + + +@callback(re.compile(b"set_(.*)"), owner=True) +async def settt(event): + lang = event.data_match.group(1).decode("UTF-8") + languages = await rm.getLanguages() + udB.del_key("language") if lang == "en" else udB.set_key("language", lang) + await event.edit( + f"Your language has been set to {languages[lang]['natively']} [{lang}].", + buttons=get_back_button("lang"), + ) + + @callback("tz", owner=True) async def timezone_(event): from pytz import timezone From 8ffc09fd98725869e5fb4dbf17e252e49f166092 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Wed, 28 Jun 2023 18:39:14 +0530 Subject: [PATCH 31/74] update converters --- core/client/BaseClient.py | 2 +- core/remote.py | 2 +- heroku.yml | 3 --- modules/__init__.py | 3 ++- modules/assistant/start.py | 3 ++- modules/basic/chats.py | 38 ++++++++++++++++++++------------------ utilities/converter.py | 26 +++++++++++++++++++++++--- utilities/helper.py | 2 ++ 8 files changed, 51 insertions(+), 28 deletions(-) delete mode 100644 heroku.yml diff --git a/core/client/BaseClient.py b/core/client/BaseClient.py index dccece56a8..e2be906fd6 100644 --- a/core/client/BaseClient.py +++ b/core/client/BaseClient.py @@ -168,7 +168,7 @@ async def fast_uploader(self, file, **kwargs): async def fast_downloader(self, file, **kwargs): """Download files in a faster way""" # Set to True and pass event to show progress bar. - filename = kwargs.get("filename") + filename = kwargs.get("filename", file.file.name) show_progress = kwargs.get("show_progress", False) if show_progress: event = kwargs["event"] diff --git a/core/remote.py b/core/remote.py index 6fe7750692..cc760868c0 100644 --- a/core/remote.py +++ b/core/remote.py @@ -27,7 +27,7 @@ def __init__(self) -> None: try: self.RemoteConfig: dict = json.load(file) except json.decoder.JSONDecodeError: - Logger.error(f"Failed to decode ultroid lock file, creating new...") + Logger.error("Failed to decode ultroid lock file, creating new...") self.RemoteConfig = self.DEF_CONFIG else: self.RemoteConfig = self.DEF_CONFIG diff --git a/heroku.yml b/heroku.yml deleted file mode 100644 index 06f0fb7467..0000000000 --- a/heroku.yml +++ /dev/null @@ -1,3 +0,0 @@ -build: - docker: - ultroid: Dockerfile diff --git a/modules/__init__.py b/modules/__init__.py index 756b10397f..5c9382ac17 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -5,6 +5,7 @@ # PLease read the GNU Affero General Public License in # . +import shutil from random import choice from telethon import Button, events @@ -30,7 +31,7 @@ def inline_pic(get=False): return INLINE_PIC # is False, return None -udB.on("LOAD_ALL", "delete", lambda: os.rmdir("modules/addons")) +udB.on("LOAD_ALL", "delete", lambda: shutil.rmtree("modules/addons")) List = [] Dict = {} diff --git a/modules/assistant/start.py b/modules/assistant/start.py index fce880df95..b1672230ba 100644 --- a/modules/assistant/start.py +++ b/modules/assistant/start.py @@ -261,7 +261,7 @@ async def settt(event): languages = await rm.getLanguages() udB.del_key("language") if lang == "en" else udB.set_key("language", lang) await event.edit( - f"Your language has been set to {languages[lang]['natively']} [{lang}].", + f"Your language has been set to {languages[lang]['name']} [{lang}].", buttons=get_back_button("lang"), ) @@ -270,6 +270,7 @@ async def settt(event): async def timezone_(event): from pytz import timezone await event.delete() + pru = event.sender_id var = "TIMEZONE" name = "Timezone" diff --git a/modules/basic/chats.py b/modules/basic/chats.py index 21dffdec6c..542ab0d131 100644 --- a/modules/basic/chats.py +++ b/modules/basic/chats.py @@ -18,6 +18,7 @@ GetFullChannelRequest, UpdateUsernameRequest, ) +from utilities.converter import create_chat_photo from telethon.tl.functions.messages import ( CreateChatRequest, ExportChatInviteRequest, @@ -204,22 +205,20 @@ async def _(ult): else: return await ult.eor("Reply to a Photo or Video..") mediain = mediainfo(reply.media) -# if "animated" in mediain: - # replfile = await con.convert(replfile, convert_to="mp4") - # else: - # replfile = await con.convert( - # replfile, outname="chatphoto", allowed_formats=["jpg", "png", "mp4"] - # ) - file = await ult.client.upload_file(replfile) + cnfile = await create_chat_photo(replfile) + + file = await ult.client.upload_file(cnfile) try: - if "photo" not in mediain: - file = types.InputChatUploadedPhoto(video=file) + isPhoto = cnfile.endswith(("jpg", "png")) + file = types.InputChatUploadedPhoto(file=file if isPhoto else None, video=None if isPhoto else file) await ult.client(EditPhotoRequest(chat, file)) await ult.eor("`Group Photo has Successfully Changed !`", time=5) except Exception as ex: LOGS.exception(ex) await ult.eor(f"Error occured.\n`{str(ex)}`", time=5) os.remove(replfile) + with contextlib.suppress(FileNotFoundError): + os.remove(cnfile) @ultroid_cmd( @@ -263,71 +262,74 @@ async def _(event): fullsudo=True, ) async def rmusers_cmd(event): + # TODO: Simplify and UPDATE xx = await event.eor(get_string("com_1")) input_str = event.pattern_match.group(1).strip() p, b, c, d, m, n, y, w, o, q, r = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, async for i in event.client.iter_participants(event.chat_id): + kick_req = event.client.kick_participant(event.chat_id, i) + p += 1 # Total Count if isinstance(i.status, UserStatusEmpty): if "empty" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: y += 1 elif isinstance(i.status, UserStatusLastMonth): if "month" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: m += 1 elif isinstance(i.status, UserStatusLastWeek): if "week" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: w += 1 elif isinstance(i.status, UserStatusOffline): if "offline" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: o += 1 elif isinstance(i.status, UserStatusOnline): if "online" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: q += 1 elif isinstance(i.status, UserStatusRecently): if "recently" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: r += 1 if i.bot: if "bot" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: b += 1 elif i.deleted: if "deleted" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: d += 1 elif i.status is None: if "none" in input_str: with contextlib.suppress(BaseException): - await event.client.kick_participant(event.chat_id, i) + await kick_req c += 1 else: n += 1 diff --git a/utilities/converter.py b/utilities/converter.py index 95d95385e5..e0b1de97a5 100644 --- a/utilities/converter.py +++ b/utilities/converter.py @@ -1,7 +1,7 @@ -import math, os +import math, os, io from PIL import Image from .tools import metadata, bash -from .tools import _unquote_text +from .tools import _unquote_text, check_filename from telethon.utils import get_extension def resize_photo_sticker(photo): @@ -55,5 +55,25 @@ async def convert_ffmpeg(input_, output): async def lottie_to_gif(file, output): - await bash(f"lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(output)}'") + await bash(f"{} -m lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(output)}'") return output + + +async def create_chat_photo(file): + extension = file.split(".")[-1] + if extension == "webp": + with Image.open(file) as img: + filename = check_filename("tmp.png") + img.save(check_filename("tmp.png"), "PNG") + return filename + elif extension == "tgs": + return await lottie_to_gif(file, check_filename("tmp.mp4")) + elif extension == "webm": + extension = "mp4" + file = await convert_ffmpeg(file, check_filename("tmp.mp4")) + if extension in ("mp4", "gif"): + filename = check_filename('out.mp4') + await bash(f'ffmpeg -i "{_unquote_text(file)}" -vf scale=500:500 "{filename}" -y') + + return filename + return file diff --git a/utilities/helper.py b/utilities/helper.py index 004950d1eb..5ba38f86e6 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -141,6 +141,8 @@ async def updateme_requirements(): # --------------------------------------------------------------------- # +class BashError(Exception): + ... async def bash(cmd, run_code=0): """ From 31ce70f386e37423aae53973c1889c72e1ad99fc Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Wed, 28 Jun 2023 18:41:58 +0530 Subject: [PATCH 32/74] recover file --- heroku.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 heroku.yml diff --git a/heroku.yml b/heroku.yml new file mode 100644 index 0000000000..06f0fb7467 --- /dev/null +++ b/heroku.yml @@ -0,0 +1,3 @@ +build: + docker: + ultroid: Dockerfile From d50a859784040cc94c6ff7e64e02b5e4c93e3fe5 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Wed, 28 Jun 2023 19:09:27 +0530 Subject: [PATCH 33/74] #todo: fix lottie on windows --- heroku.yml | 2 +- utilities/converter.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/heroku.yml b/heroku.yml index 06f0fb7467..5c4139b20e 100644 --- a/heroku.yml +++ b/heroku.yml @@ -1,3 +1,3 @@ build: docker: - ultroid: Dockerfile + ultroid: Dockerfile \ No newline at end of file diff --git a/utilities/converter.py b/utilities/converter.py index e0b1de97a5..f32154261f 100644 --- a/utilities/converter.py +++ b/utilities/converter.py @@ -55,7 +55,7 @@ async def convert_ffmpeg(input_, output): async def lottie_to_gif(file, output): - await bash(f"{} -m lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(output)}'") + await bash(f"lottie_convert.py '{_unquote_text(file)}' '{_unquote_text(output)}'") return output From d38284995ca5b48f8000033377c0a76f963b63bc Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 29 Jun 2023 21:43:36 +0530 Subject: [PATCH 34/74] Update BaseClient.py --- core/client/BaseClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/client/BaseClient.py b/core/client/BaseClient.py index e2be906fd6..34064b7fda 100644 --- a/core/client/BaseClient.py +++ b/core/client/BaseClient.py @@ -168,7 +168,7 @@ async def fast_uploader(self, file, **kwargs): async def fast_downloader(self, file, **kwargs): """Download files in a faster way""" # Set to True and pass event to show progress bar. - filename = kwargs.get("filename", file.file.name) + filename = kwargs.get("filename", file.name) show_progress = kwargs.get("show_progress", False) if show_progress: event = kwargs["event"] From ff2cf9b93b035f2e8bcfec92aa954cdcfec28fb4 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 29 Jun 2023 21:52:33 +0530 Subject: [PATCH 35/74] Update BaseClient.py --- core/client/BaseClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/client/BaseClient.py b/core/client/BaseClient.py index 34064b7fda..dccece56a8 100644 --- a/core/client/BaseClient.py +++ b/core/client/BaseClient.py @@ -168,7 +168,7 @@ async def fast_uploader(self, file, **kwargs): async def fast_downloader(self, file, **kwargs): """Download files in a faster way""" # Set to True and pass event to show progress bar. - filename = kwargs.get("filename", file.name) + filename = kwargs.get("filename") show_progress = kwargs.get("show_progress", False) if show_progress: event = kwargs["event"] From 7e89a1f841c81da1cdd732b67926985b80793561 Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Thu, 29 Jun 2023 21:59:02 +0530 Subject: [PATCH 36/74] Update mediainfo.py --- modules/basic/mediainfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/basic/mediainfo.py b/modules/basic/mediainfo.py index 7dbac29285..16d8da455b 100644 --- a/modules/basic/mediainfo.py +++ b/modules/basic/mediainfo.py @@ -37,6 +37,7 @@ async def mediainfo_func(event): if hasattr(r.media, "document"): dl = await event.client.fast_downloader( r.document, + filename=r.file.name, show_progress=True, event=event, message=f"{extra}`Loading More...`", From 3c1071137b40b0605fa06ec51d89f8e42465a36d Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Thu, 29 Jun 2023 22:29:57 +0530 Subject: [PATCH 37/74] nothing to say --- core/client/BaseClient.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/client/BaseClient.py b/core/client/BaseClient.py index dccece56a8..859e67171d 100644 --- a/core/client/BaseClient.py +++ b/core/client/BaseClient.py @@ -188,7 +188,8 @@ async def fast_downloader(self, file, **kwargs): try: if isinstance(file.attributes[-1], DocumentAttributeFilename): filename = file.attributes[-1].file_name - except IndexError: + assert filename != None + except (IndexError, AssertionError): mimetype = file.mime_type filename = ( mimetype.split("/")[0] From 3653f8b4ce0e99531977350a2ab6a8dcd1342ba5 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 29 Jun 2023 23:55:34 +0530 Subject: [PATCH 38/74] Update _decorators.py --- core/decorators/_decorators.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/decorators/_decorators.py b/core/decorators/_decorators.py index 226b145efa..fb3dea4a9a 100644 --- a/core/decorators/_decorators.py +++ b/core/decorators/_decorators.py @@ -115,6 +115,8 @@ async def wrapp(ult: Message): get_string("py_d4").format(HNDLR), time=10, ) + if ult and ult.text and ult.media: + return try: await dec(ult) except FloodWaitError as fwerr: From 57df77a392effd8826cf9d3f3b9228f8e5e7512f Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Fri, 30 Jun 2023 23:42:26 +0530 Subject: [PATCH 39/74] Update tools.py --- modules/basic/tools.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/basic/tools.py b/modules/basic/tools.py index b0a07191c1..c7f64f043e 100644 --- a/modules/basic/tools.py +++ b/modules/basic/tools.py @@ -88,8 +88,11 @@ async def _(event): else: msg = event reply_to_id = event.message.id - if match and hasattr(msg, match.split()[0]): - msg = getattr(msg, match.split()[0]) + if match and hasattr(msg, match.split()[0].split(".")[0]): + for attr in match.split()[0].split("."): + msg = getattr(msg, attr, None) + if not msg: + break with contextlib.suppress(Exception): if hasattr(msg, "to_json"): msg = msg.to_json(ensure_ascii=False, indent=1) From 8cb6dc165c5b3e56fed5ed3b0043fd552bfb4cea Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 20 Jul 2023 11:30:24 +0530 Subject: [PATCH 40/74] Why do you exist --- core/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/__init__.py b/core/__init__.py index c5c8b891e4..9ba45b40e4 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -6,7 +6,6 @@ # . import sys -import telethonpatch # pylint: disable=unused-import import time from .config import Var @@ -58,4 +57,4 @@ SUDO_HNDLR = udB.get_key("SUDO_HNDLR") or HNDLR for _ in ["HNDLR", "DUAL_HNDLR"]: - udB.on(_, "change", update_handlers) \ No newline at end of file + udB.on(_, "change", update_handlers) From cba26f80310fbe9782adf61abcd833820cba1f23 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 20 Jul 2023 12:57:51 +0530 Subject: [PATCH 41/74] Let it handle --- modules/basic/dlul.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/basic/dlul.py b/modules/basic/dlul.py index 244ef4dc7a..332784edb2 100644 --- a/modules/basic/dlul.py +++ b/modules/basic/dlul.py @@ -89,17 +89,9 @@ async def dl_cmd(event): k = time.time() if hasattr(ok.media, "document"): file = ok.media.document - filename = ok.file.name or query - if not filename: - mime_type = file.mime_type - if "audio" in mime_type: - filename = "audio_" + dt.now().isoformat("_", "seconds") + ".ogg" - elif "video" in mime_type: - filename = "video_" + dt.now().isoformat("_", "seconds") + ".mp4" try: result = await event.client.fast_downloader( file, - filename=f"resources/downloads/{filename}", show_progress=not silent, event=xx, ) From f1c60db4e37544e5336fa483ed0e7c8aa98d7c3b Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 20 Jul 2023 13:07:07 +0530 Subject: [PATCH 42/74] Update BaseClient.py --- core/client/BaseClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/client/BaseClient.py b/core/client/BaseClient.py index 859e67171d..a1d18e6ab8 100644 --- a/core/client/BaseClient.py +++ b/core/client/BaseClient.py @@ -199,7 +199,7 @@ async def fast_downloader(self, file, **kwargs): ) message = kwargs.get("message", f"Downloading {filename}...") dirname = os.path.dirname(filename) - if not os.path.exists(dirname): + if dirname and not os.path.exists(dirname): os.mkdir(dirname) raw_file = None while not raw_file: From 30570f61e92651371cf95a1124d7102cb203e450 Mon Sep 17 00:00:00 2001 From: Aditya Date: Mon, 14 Aug 2023 12:18:37 +0530 Subject: [PATCH 43/74] chore: update license year --- modules/assistant/start.py | 2 +- modules/basic/admins.py | 2 +- modules/basic/chats.py | 2 +- modules/basic/database.py | 2 +- modules/basic/devtools.py | 2 +- modules/basic/dlul.py | 2 +- modules/basic/stickers.py | 2 +- modules/basic/sudo.py | 2 +- modules/basic/vctools.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/assistant/start.py b/modules/assistant/start.py index fcbe82cd00..99a777df0c 100644 --- a/modules/assistant/start.py +++ b/modules/assistant/start.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/admins.py b/modules/basic/admins.py index 1b13c876cb..f34a9b5547 100644 --- a/modules/basic/admins.py +++ b/modules/basic/admins.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/chats.py b/modules/basic/chats.py index 8e042310af..1d3dbc64b8 100644 --- a/modules/basic/chats.py +++ b/modules/basic/chats.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/database.py b/modules/basic/database.py index 02b871682a..e0c6a8a75d 100644 --- a/modules/basic/database.py +++ b/modules/basic/database.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index 811be9c7c2..08c7a76255 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # Please read the GNU Affero General Public License in diff --git a/modules/basic/dlul.py b/modules/basic/dlul.py index a017e861f3..11a91b1067 100644 --- a/modules/basic/dlul.py +++ b/modules/basic/dlul.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/stickers.py b/modules/basic/stickers.py index be65614a20..84419ad3bc 100644 --- a/modules/basic/stickers.py +++ b/modules/basic/stickers.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/sudo.py b/modules/basic/sudo.py index 6e56745d63..e9e8519eeb 100644 --- a/modules/basic/sudo.py +++ b/modules/basic/sudo.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in diff --git a/modules/basic/vctools.py b/modules/basic/vctools.py index 5413d7f711..ec52999536 100644 --- a/modules/basic/vctools.py +++ b/modules/basic/vctools.py @@ -1,5 +1,5 @@ # Ultroid - UserBot -# Copyright (C) 2021-2022 TeamUltroid +# Copyright (C) 2021-2023 TeamUltroid # # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in From b4376d98ab34fd2346dfa0236938685a8335553e Mon Sep 17 00:00:00 2001 From: TechiError Date: Mon, 14 Aug 2023 15:37:14 +0530 Subject: [PATCH 44/74] Introduce `creds` --- modules/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/__init__.py b/modules/__init__.py index 5c9382ac17..b0c4b6344e 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -35,6 +35,8 @@ def inline_pic(get=False): List = [] Dict = {} +# Credentials variable for saving login credentials(Like Gdrive,OneDrive,etc. login credentials) in local +creds = {} # Chats, which needs to be ignore for some cases # Considerably, there can be many From f74995ff9dfccb20f571b589dcc76642473b55ed Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Tue, 15 Aug 2023 11:18:36 +0530 Subject: [PATCH 45/74] `AttributeError: 'PhotoSize' object has no attribute 'location' --- modules/basic/tools.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/modules/basic/tools.py b/modules/basic/tools.py index c7f64f043e..4d681516a4 100644 --- a/modules/basic/tools.py +++ b/modules/basic/tools.py @@ -59,27 +59,26 @@ async def tr_func(event): manager=True, ) async def id_func(event): + text = f"`Sender ID`: `{event.sender_id}`\n" if match := event.pattern_match.group(1).strip(): try: ids = await event.client.parse_id(match) except Exception as er: return await event.eor(str(er)) - return await event.eor( - f"**Chat ID:** `{event.chat_id}`\n**User ID:** `{ids}`" - ) - ult = event - data = f"**Current Chat ID:** `{event.chat_id}`" - if event.reply_to_msg_id: - event = await event.get_reply_message() - data += f"\n**From User ID:** `{event.sender_id}`" - if event.media: - data += f"\n**Bot API File ID:** `{event.file.id}`" - data += f"\n**Msg ID:** `{event.id}`" - await ult.eor(data) + if str(ids).startswith("-"): + text += f"`Requested Chat ID`: " + else: + text += f"`Requested User ID`: " + text += f"`{ids}`\n" + if reply := (await event.get_reply_message()): + text += f"`Replied to message ID`: `{reply.id}`\n" + text += f"`Replied to User ID`: `{reply.sender_id}`\n" + text += f"`Current Chat ID`: `{event.chat_id}`" + await event.eor(text) @ultroid_cmd(pattern="json( (.*)|$)") -async def _(event): +async def json_func(event): reply_to_id = None match = event.pattern_match.group(1).strip() if event.reply_to_msg_id: @@ -361,7 +360,7 @@ async def q_func(event): pattern="invite( (.*)|$)", groups_only=True, ) -async def _(ult): +async def invite_func(ult): xx = await ult.eor(get_string("com_1")) to_add_users = ult.pattern_match.group(1).strip() add_chat_user = not ult.is_channel and ult.is_group From 954594cea8848d766ff956461c068f958fad41ad Mon Sep 17 00:00:00 2001 From: Devesh Pal Date: Fri, 18 Aug 2023 20:24:52 +0530 Subject: [PATCH 46/74] Revert In the recent days I have learnt Reverting is the quickest fix --- modules/basic/devtools.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/basic/devtools.py b/modules/basic/devtools.py index eb41569643..f2d8e96120 100644 --- a/modules/basic/devtools.py +++ b/modules/basic/devtools.py @@ -241,15 +241,15 @@ async def get_(): # value = await aexec(cmd, event) # TODO: Eval can be cancelled # task = asyncio.create_task(aexec(cmd, event)) - task = asyncio.current_task() - try: - task_id = int(list(Tasks.keys())[0]) - except IndexError: - task_id = 0 - task_id += 1 - task_id = str(task_id) - Tasks[task_id] = task - task.add_done_callback(lambda _: Tasks.pop(task_id)) + # task = asyncio.current_task() + # try: +# task_id = int(list(Tasks.keys())[0]) + # except IndexError: + # task_id = 0 + #task_id += 1 + # task_id = str(task_id) + # Tasks[task_id] = task + # task.add_done_callback(lambda _: Tasks.pop(task_id)) # await asyncio.wait([task]) # value = task.result() value = await aexec(cmd, event) From 9b4a63cfa0e87f3925e2e92cda236490426c1e55 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 18 Aug 2023 21:04:35 +0530 Subject: [PATCH 47/74] Update _decorators.py --- core/decorators/_decorators.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/decorators/_decorators.py b/core/decorators/_decorators.py index fb3dea4a9a..226b145efa 100644 --- a/core/decorators/_decorators.py +++ b/core/decorators/_decorators.py @@ -115,8 +115,6 @@ async def wrapp(ult: Message): get_string("py_d4").format(HNDLR), time=10, ) - if ult and ult.text and ult.media: - return try: await dec(ult) except FloodWaitError as fwerr: From ba9741d7e6db9440ec3d278fa00482eef57ffae9 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 18 Aug 2023 21:59:17 +0530 Subject: [PATCH 48/74] Add files via upload --- utilities/gdrive.py | 281 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 utilities/gdrive.py diff --git a/utilities/gdrive.py b/utilities/gdrive.py new file mode 100644 index 0000000000..cd29c1ff56 --- /dev/null +++ b/utilities/gdrive.py @@ -0,0 +1,281 @@ +# Ultroid - UserBot +# Copyright (C) 2020-2023 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +import base64 +import json +import logging +import os +import time +# from io import FileIO +from mimetypes import guess_type +from urllib.parse import parse_qs, urlencode + +from aiohttp import ClientSession +from aiohttp.client_exceptions import ContentTypeError + +from database import udB + +from .helper import humanbytes, time_formatter + +try: + from Crypto.Hash import SHA256 + from Crypto.PublicKey import RSA + from Crypto.Signature import pkcs1_15 +except BaseException: + pass + +# for log in [LOGGER, logger, _logger]: +# log.setLevel(WARNING) + +log = logging.getLogger("GDrive") + +# Assuming it works without any error + + +class GDrive: + def __init__(self): + self._session = ClientSession() + self.base_url = "https://www.googleapis.com/drive/v3" + self.client_id = udB.get_key("GDRIVE_CLIENT_ID") + self.client_secret = udB.get_key("GDRIVE_CLIENT_SECRET") + self.folder_id = udB.get_key("GDRIVE_FOLDER_ID") or "root" + self.scope = "https://www.googleapis.com/auth/drive" + self.creds = udB.get_key("GDRIVE_AUTH_TOKEN") or {} + self.service_account = udB.get_key("GDRIVE_SERVICE_KEY") + + def get_oauth2_url(self): + return "https://accounts.google.com/o/oauth2/v2/auth?" + urlencode({ + "client_id": self.client_id, + "redirect_uri": "http://plugins.xditya.me/auth", + "response_type": "code", + "scope": self.scope, + "access_type": "offline", + }) + + async def get_access_token(self, code=None) -> dict: + if self.service_account: + header = { + "alg": "RS256", + "typ": "JWT" + } + payload = { + "iss": self.service_account["client_email"], + "scope": self.scope, + "aud": "https://oauth2.googleapis.com/token", + "exp": int(time.time()) + 3590, + "iat": int(time.time()) + } + total_params = str( + base64.urlsafe_b64encode( + json.dumps(header).encode('ascii')).decode('utf-8').replace( + '=', '')) + "." + str( + base64.urlsafe_b64encode( + json.dumps(payload).encode('ascii')).decode('utf-8').replace( + '=', '')) + private_key = RSA.import_key( + bytes(self.service_account["private_key"], "utf-8")) + signature = pkcs1_15.new(private_key).sign( + SHA256.new(total_params.encode('utf-8'))) + token = total_params + "." + \ + str(base64.urlsafe_b64encode(signature).decode( + 'utf-8').replace('=', '')) + resp = await self._session.post("https://oauth2.googleapis.com/token", data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": token}) + self.creds = await resp.json() + self.creds["expires_in"] = time.time() + 3590 + udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) + return self.creds + if code.startswith("http://localhost"): + # get all url arguments + code = parse_qs(code.split("?")[1]).get("code")[0] + resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "http://localhost", "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"}) + self.creds = await resp.json() + self.creds["expires_in"] = time.time() + 3590 + udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) + return self.creds + + async def refresh_access_token(self) -> None: + if self.service_account: + header = { + "alg": "RS256", + "typ": "JWT" + } + payload = { + "iss": self.service_account["client_email"], + "scope": self.scope, + "aud": "https://oauth2.googleapis.com/token", + "exp": int(time.time()) + 3600, + "iat": int(time.time()) + } + total_params = str( + base64.urlsafe_b64encode( + json.dumps(header).encode('ascii')).decode('utf-8').replace( + '=', '')) + "." + str( + base64.urlsafe_b64encode( + json.dumps(payload).encode('ascii')).decode('utf-8').replace( + '=', '')) + private_key = RSA.import_key( + bytes(self.service_account["private_key"], "utf-8")) + signature = pkcs1_15.new(private_key).sign( + SHA256.new(total_params.encode('utf-8'))) + token = total_params + "." + \ + str(base64.urlsafe_b64encode(signature).decode( + 'utf-8').replace('=', '')) + resp = await self._session.post("https://oauth2.googleapis.com/token", data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": token}) + self.creds = await resp.json() + self.creds["expires_in"] = time.time() + 3590 + udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) + return + resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "grant_type": "refresh_token", "refresh_token": self.creds.get("refresh_token")}, headers={"Content-Type": "application/x-www-form-urlencoded"}) + creds = await resp.json() + if "error" in creds: + return creds + self.creds["access_token"] = creds["access_token"] + self.creds["expires_in"] = time.time() + 3590 + udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) + + async def get_size_status(self) -> dict: + await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + return await (await self._session.get( + self.base_url + "about", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + params={"fields": "storageQuota"}, + )).json() + + async def set_permissions(self, fileid: str, role: str = "reader", type: str = "anyone"): + # set permissions to anyone with link can view + await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + return await (await self._session.post( + self.base_url + f"/files/{fileid}/permissions", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + json={ + "role": role, + "type": type, + }, + )).json() + + async def list_files(self) -> dict: + await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + return await (await self._session.get( + self.base_url + "/files", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + )).json() + + async def delete(self, fileId: str) -> dict: + await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + r = await self._session.delete( + self.base_url + f"/files/{fileId}", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + ) + try: + return await r.json() + except ContentTypeError: + return {"status": "success"} + + async def copy_file(self, fileId: str, filename: str, folder_id: str, move: bool = False): + await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + headers = { + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + } + params = { + "name": filename, + "mimeType": "application/octet-stream", + "fields": "id, name, webContentLink", + "supportsAllDrives": "true", + } + file_metadata = { + "name": filename, + "fileId": fileId, + } + if folder_id: + file_metadata["parents"] = [folder_id] + elif self.folder_id: + file_metadata["parents"] = [self.folder_id] + params["addParents"] = folder_id if folder_id else self.folder_id + params["removeParents"] = "root" if move else None + r = await self._session.patch( + self.base_url + f"/files/{fileId}", + headers=headers, + data=json.dumps(file_metadata), + params=params, + ) + r = await r.json() + if r.get("error") and r["error"]["code"] == 401: + await self.refresh_access_token() + return await self.copy_file(fileId, filename, folder_id, move) + return r + + async def upload_file(self, event, path: str, filename: str = None, folder_id: str = None): + await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + last_txt = "" + filename = filename if filename else path.split("/")[-1] + mime_type = guess_type(path)[0] or "application/octet-stream" + # upload with progress bar + filesize = os.path.getsize(path) + # await self.get_size_status() + chunksize = 104857600 # 100MB + # 1. Retrieve session for resumable upload. + headers = {"Authorization": "Bearer " + + self.creds.get("access_token"), "Content-Type": "application/json"} + params = { + "name": filename, + "mimeType": mime_type, + "fields": "id, name, webContentLink", + "parents": [folder_id] if folder_id else [self.folder_id], + } + r = await self._session.post( + "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable", + headers=headers, + data=json.dumps(params), + params={"fields": "id, name, webContentLink"}, + ) + if r.status == 401: + await self.refresh_access_token() + return await self.upload_file(event, path, filename, folder_id) + elif r.status == 403: + # upload to root and move + r = await self.upload_file(event, path, filename, "root") + return await self.copy_file(r["id"], filename, folder_id, move=True) + upload_url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" + \ + r.headers.get("X-GUploader-UploadID") + + with open(path, "rb") as f: + uploaded = 0 + start = time.time() + resp = None + while filesize != uploaded: + chunk_data = f.read(chunksize) + headers = {"Content-Length": str(len(chunk_data)), + "Content-Range": "bytes " + str(uploaded) + "-" + str(uploaded + len(chunk_data) - 1) + "/" + str(filesize)} + uploaded += len(chunk_data) + resp = await self._session.put(upload_url, data=chunk_data, headers=headers) + diff = time.time() - start + percentage = round((uploaded / filesize) * 100, 2) + speed = round(uploaded / diff, 2) + eta = round((filesize - uploaded) / speed, 2) * 1000 + crnt_txt = ( + f"`Uploading {filename} to GDrive...\n\n" + + f"Status: {humanbytes(uploaded)}/{humanbytes(filesize)} »» {percentage}%\n" + + f"Speed: {humanbytes(speed)}/s\n" + + f"ETA: {time_formatter(eta)}`" + ) + if round((diff % 10.00) == 0) or last_txt != crnt_txt: + await event.edit(crnt_txt) + last_txt = crnt_txt + return await resp.json() From a4719ef9b9f74a2cc777925fc06031e9114ff264 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 18 Aug 2023 22:54:06 +0530 Subject: [PATCH 49/74] Update gdrive.py --- utilities/gdrive.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index cd29c1ff56..7279e7ee91 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -50,7 +50,7 @@ def __init__(self): def get_oauth2_url(self): return "https://accounts.google.com/o/oauth2/v2/auth?" + urlencode({ "client_id": self.client_id, - "redirect_uri": "http://plugins.xditya.me/auth", + "redirect_uri": "https://plugins.xditya.me/auth", "response_type": "code", "scope": self.scope, "access_type": "offline", @@ -88,9 +88,6 @@ async def get_access_token(self, code=None) -> dict: self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return self.creds - if code.startswith("http://localhost"): - # get all url arguments - code = parse_qs(code.split("?")[1]).get("code")[0] resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "http://localhost", "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"}) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 From 539432434d356867ca2298f6cf0d8f9de9da2ac5 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 18 Aug 2023 23:21:05 +0530 Subject: [PATCH 50/74] Update gdrive.py --- utilities/gdrive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 7279e7ee91..058a8bfc24 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -88,7 +88,7 @@ async def get_access_token(self, code=None) -> dict: self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return self.creds - resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "http://localhost", "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"}) + resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "https://plugins.xditya.me/auth", "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"}) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) From 6e46764b1251bf597b5466fa9bcd57269ee19eee Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 18 Aug 2023 23:31:28 +0530 Subject: [PATCH 51/74] Highness at it's peak --- utilities/gdrive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 058a8bfc24..f3d76f4bde 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -137,7 +137,7 @@ async def refresh_access_token(self) -> None: async def get_size_status(self) -> dict: await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None return await (await self._session.get( - self.base_url + "about", + self.base_url + "/about", headers={ "Authorization": "Bearer " + self.creds.get("access_token"), "Content-Type": "application/json", From 64c707118aabd8ec71007c277a5ab15960c09378 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 18 Aug 2023 23:40:36 +0530 Subject: [PATCH 52/74] Update helper.py --- utilities/helper.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utilities/helper.py b/utilities/helper.py index 5ba38f86e6..eafa689e24 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -308,7 +308,8 @@ def time_formatter(milliseconds, fixed_format=False): return tmp[:1] if tmp.endswith(":") else tmp -def humanbytes(size): +def humanbytes(size: int) -> str: + size = int(size) if not size: return "0B" unit = "" @@ -323,9 +324,10 @@ def humanbytes(size): return size -def numerize(number): +def numerize(number: int) -> str: + number = int(number) if not number: - return + return "" unit = "" for unit in ["", "K", "M", "B", "T"]: if number < 1000: From 0cd52e9fd85d7afacfb723f7950e82334e8711f5 Mon Sep 17 00:00:00 2001 From: TechiError Date: Sat, 19 Aug 2023 18:15:49 +0530 Subject: [PATCH 53/74] parse creds as dict not string --- utilities/gdrive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index f3d76f4bde..adabad6802 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -44,7 +44,7 @@ def __init__(self): self.client_secret = udB.get_key("GDRIVE_CLIENT_SECRET") self.folder_id = udB.get_key("GDRIVE_FOLDER_ID") or "root" self.scope = "https://www.googleapis.com/auth/drive" - self.creds = udB.get_key("GDRIVE_AUTH_TOKEN") or {} + self.creds = json.loads(udB.get_key("GDRIVE_AUTH_TOKEN")) or {} self.service_account = udB.get_key("GDRIVE_SERVICE_KEY") def get_oauth2_url(self): From fe25ece1bcfa616859fcf4e814074ae11117f527 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 12:13:18 +0530 Subject: [PATCH 54/74] Gdrive files list --- utilities/gdrive.py | 90 ++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index adabad6802..7474a163d3 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -10,7 +10,7 @@ import logging import os import time -# from io import FileIO + from mimetypes import guess_type from urllib.parse import parse_qs, urlencode @@ -28,8 +28,6 @@ except BaseException: pass -# for log in [LOGGER, logger, _logger]: -# log.setLevel(WARNING) log = logging.getLogger("GDrive") @@ -39,24 +37,35 @@ class GDrive: def __init__(self): self._session = ClientSession() - self.base_url = "https://www.googleapis.com/drive/v3" - self.client_id = udB.get_key("GDRIVE_CLIENT_ID") - self.client_secret = udB.get_key("GDRIVE_CLIENT_SECRET") - self.folder_id = udB.get_key("GDRIVE_FOLDER_ID") or "root" - self.scope = "https://www.googleapis.com/auth/drive" - self.creds = json.loads(udB.get_key("GDRIVE_AUTH_TOKEN")) or {} - self.service_account = udB.get_key("GDRIVE_SERVICE_KEY") + self.base_url: str = "https://www.googleapis.com/drive/v3" + self.client_id: str = udB.get_key("GDRIVE_CLIENT_ID") + self.client_secret: str = udB.get_key("GDRIVE_CLIENT_SECRET") + self.folder_id: str = udB.get_key("GDRIVE_FOLDER_ID") or "root" + self.redirect_uri: str = udB.get_key("GDRIVE_REDIRECT_URI") or "http://localhost" + self.scope: str = "https://www.googleapis.com/auth/drive" + self.creds: dict = udB.get_key("GDRIVE_AUTH_TOKEN") or {} + self.service_account: dict = udB.get_key("GDRIVE_SERVICE_KEY") + self.folder_mime: str = "application/vnd.google-apps.folder" + + @staticmethod + def _create_download_link(file_id: str) -> str: + return f"https://drive.google.com/uc?id={fileId}&export=download" + + @staticmethod + def _create_folder_link(folder_id: str) -> str: + return f"https://drive.google.com/folderview?id={folderId" - def get_oauth2_url(self): + @property + def get_oauth2_url(self) -> str: return "https://accounts.google.com/o/oauth2/v2/auth?" + urlencode({ "client_id": self.client_id, - "redirect_uri": "https://plugins.xditya.me/auth", + "redirect_uri": self.redirect_uri, "response_type": "code", "scope": self.scope, "access_type": "offline", }) - async def get_access_token(self, code=None) -> dict: + async def get_access_token(self, code: str = None) -> dict: if self.service_account: header = { "alg": "RS256", @@ -88,13 +97,17 @@ async def get_access_token(self, code=None) -> dict: self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return self.creds - resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "https://plugins.xditya.me/auth", "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"}) + resp = await self._session.post( + "https://oauth2.googleapis.com/token", + data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": self.redirect_uri, "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"} + ) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return self.creds - async def refresh_access_token(self) -> None: + @property + async def _refresh_access_token(self) -> None: if self.service_account: header = { "alg": "RS256", @@ -134,8 +147,9 @@ async def refresh_access_token(self) -> None: self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) + @property async def get_size_status(self) -> dict: - await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None return await (await self._session.get( self.base_url + "/about", headers={ @@ -147,7 +161,7 @@ async def get_size_status(self) -> dict: async def set_permissions(self, fileid: str, role: str = "reader", type: str = "anyone"): # set permissions to anyone with link can view - await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None return await (await self._session.post( self.base_url + f"/files/{fileid}/permissions", headers={ @@ -160,18 +174,36 @@ async def set_permissions(self, fileid: str, role: str = "reader", type: str = " }, )).json() - async def list_files(self) -> dict: - await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None - return await (await self._session.get( - self.base_url + "/files", - headers={ - "Authorization": "Bearer " + self.creds.get("access_token"), - "Content-Type": "application/json", - }, - )).json() + async def list_files(self, title: str = None) -> list: + await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None + params = {"includeItemsFromAllDrives": "true", "fields": "nextPageToken, items(id, title, mimeType, webContentLink)", "nextPageToken": None} + if title: + params["q"] = f"title contains '{title}'" + if self.folder_id: + params["q"] = f"'{self.folder_id}' in parents and (title contains '{title}')" + files = [] + while True: + resp = await (await self._session.get( + self.base_url + "/files", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + params=params, + )).json() + for file in resp.get("files", []): + if file["mimeType"] == self.folder_mime: + file["url"] = self._create_folder_link(file["id"]) + else: + file["url"] = self._create_download_link(file["id"]) + files.append(file) + params["nextPageToken"] = resp.get("nextPageToken") + if params["nextPageToken"]: + break + retutn files async def delete(self, fileId: str) -> dict: - await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None r = await self._session.delete( self.base_url + f"/files/{fileId}", headers={ @@ -185,7 +217,7 @@ async def delete(self, fileId: str) -> dict: return {"status": "success"} async def copy_file(self, fileId: str, filename: str, folder_id: str, move: bool = False): - await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None headers = { "Authorization": "Bearer " + self.creds.get("access_token"), "Content-Type": "application/json", @@ -219,7 +251,7 @@ async def copy_file(self, fileId: str, filename: str, folder_id: str, move: bool return r async def upload_file(self, event, path: str, filename: str = None, folder_id: str = None): - await self.refresh_access_token() if time.time() > self.creds.get("expires_in") else None + await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None last_txt = "" filename = filename if filename else path.split("/")[-1] mime_type = guess_type(path)[0] or "application/octet-stream" From fb8b07e30370edc2fcc72a5d7962453d58cbb191 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 12:17:04 +0530 Subject: [PATCH 55/74] Gdrive files list --- utilities/gdrive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 7474a163d3..11a8219fb1 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -49,11 +49,11 @@ def __init__(self): @staticmethod def _create_download_link(file_id: str) -> str: - return f"https://drive.google.com/uc?id={fileId}&export=download" + return f"https://drive.google.com/uc?id={file_id}&export=download" @staticmethod def _create_folder_link(folder_id: str) -> str: - return f"https://drive.google.com/folderview?id={folderId" + return f"https://drive.google.com/folderview?id={folder_id}" @property def get_oauth2_url(self) -> str: From 1ebdc8fc0ae23e7311d697c6cfd8d991a361d1f7 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 12:20:44 +0530 Subject: [PATCH 56/74] Gdrive files list --- utilities/gdrive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 11a8219fb1..3db7d46540 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -200,7 +200,7 @@ async def list_files(self, title: str = None) -> list: params["nextPageToken"] = resp.get("nextPageToken") if params["nextPageToken"]: break - retutn files + return files async def delete(self, fileId: str) -> dict: await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None From f748436b94e5a8af6b40d7960b92cdb3c57a1b4c Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 12:24:33 +0530 Subject: [PATCH 57/74] Gdrive files list --- utilities/gdrive.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 3db7d46540..570374255b 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -55,7 +55,6 @@ def _create_download_link(file_id: str) -> str: def _create_folder_link(folder_id: str) -> str: return f"https://drive.google.com/folderview?id={folder_id}" - @property def get_oauth2_url(self) -> str: return "https://accounts.google.com/o/oauth2/v2/auth?" + urlencode({ "client_id": self.client_id, @@ -106,7 +105,6 @@ async def get_access_token(self, code: str = None) -> dict: udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return self.creds - @property async def _refresh_access_token(self) -> None: if self.service_account: header = { @@ -147,7 +145,6 @@ async def _refresh_access_token(self) -> None: self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) - @property async def get_size_status(self) -> dict: await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None return await (await self._session.get( From 616d046503b89ede409c67f840b6ec26821fa980 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 12:31:07 +0530 Subject: [PATCH 58/74] Gdrive files list --- utilities/gdrive.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 570374255b..20489f6484 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -173,12 +173,13 @@ async def set_permissions(self, fileid: str, role: str = "reader", type: str = " async def list_files(self, title: str = None) -> list: await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None - params = {"includeItemsFromAllDrives": "true", "fields": "nextPageToken, items(id, title, mimeType, webContentLink)", "nextPageToken": None} + params = {"includeItemsFromAllDrives": "true", "fields": "nextPageToken, items(id, title, mimeType, webContentLink)",} if title: params["q"] = f"title contains '{title}'" if self.folder_id: params["q"] = f"'{self.folder_id}' in parents and (title contains '{title}')" files = [] + page_token = None while True: resp = await (await self._session.get( self.base_url + "/files", @@ -194,8 +195,10 @@ async def list_files(self, title: str = None) -> list: else: file["url"] = self._create_download_link(file["id"]) files.append(file) - params["nextPageToken"] = resp.get("nextPageToken") - if params["nextPageToken"]: + page_token = resp.get("nextPageToken", None) + if page_token: + params["nextPageToken"] = page_token + if page_token is None: break return files From 48a150dc6eee2136c06781f50bcb3c44f570fb64 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 12:52:06 +0530 Subject: [PATCH 59/74] Gdrive files list --- utilities/gdrive.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 20489f6484..b096be2dee 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -171,15 +171,11 @@ async def set_permissions(self, fileid: str, role: str = "reader", type: str = " }, )).json() - async def list_files(self, title: str = None) -> list: + async def list_files(self) -> list: await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None - params = {"includeItemsFromAllDrives": "true", "fields": "nextPageToken, items(id, title, mimeType, webContentLink)",} - if title: - params["q"] = f"title contains '{title}'" - if self.folder_id: - params["q"] = f"'{self.folder_id}' in parents and (title contains '{title}')" files = [] page_token = None + params = {"supportAllDrives": "true"} while True: resp = await (await self._session.get( self.base_url + "/files", @@ -196,10 +192,10 @@ async def list_files(self, title: str = None) -> list: file["url"] = self._create_download_link(file["id"]) files.append(file) page_token = resp.get("nextPageToken", None) - if page_token: - params["nextPageToken"] = page_token if page_token is None: break + else: + params["pageToken"] = page_token return files async def delete(self, fileId: str) -> dict: From 24babae1a880b1f7175dcf3f84a118056c58b3c0 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 13:02:07 +0530 Subject: [PATCH 60/74] Wake bot after floodwait --- core/decorators/_decorators.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/decorators/_decorators.py b/core/decorators/_decorators.py index 226b145efa..752e01077b 100644 --- a/core/decorators/_decorators.py +++ b/core/decorators/_decorators.py @@ -122,8 +122,7 @@ async def wrapp(ult: Message): udB.get_config("LOG_CHANNEL"), f"`FloodWaitError:\n{str(fwerr)}\n\nSleeping for {tf((fwerr.seconds + 10)*1000)}`", ) - await ultroid_bot.disconnect() - await asyncio.sleep(fwerr.seconds + 10) + time.sleep(fwerr.seconds + 10) await ultroid_bot.connect() await asst.send_message( udB.get_config("LOG_CHANNEL"), From 138edcc52f2d3b8fec0eef9e78f888809cb15e9b Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 13:45:38 +0530 Subject: [PATCH 61/74] Fix help --- modules/basic/_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 8d3bec8028..4096d79813 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -107,7 +107,7 @@ def get_from_funcs(mod, name): return False msg = f"Command available in `{name}`-\n" for cmd in funcs: - msg += f"\n• `{HNDLR}{cmd[0][:-5]}`\n - {cmd[1].__doc__}\n" + msg += f"\n• {cmd[1].__doc__.format(HNDLR)}\n" msg += "\n ©️ @TeamUltroid" return msg From a714f1cecbf0babdcccc84d5e7f84ad8cef88815 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 14:05:07 +0530 Subject: [PATCH 62/74] Fix help --- modules/basic/_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 4096d79813..c802978313 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -107,7 +107,7 @@ def get_from_funcs(mod, name): return False msg = f"Command available in `{name}`-\n" for cmd in funcs: - msg += f"\n• {cmd[1].__doc__.format(HNDLR)}\n" + msg += cmd[1].__doc__.format(i=HNDLR) msg += "\n ©️ @TeamUltroid" return msg From 24847d392c34276bfedd5dbcef7480a0ce913f7a Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 14:08:26 +0530 Subject: [PATCH 63/74] Fix help --- modules/basic/_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index c802978313..1732dbf704 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -107,7 +107,7 @@ def get_from_funcs(mod, name): return False msg = f"Command available in `{name}`-\n" for cmd in funcs: - msg += cmd[1].__doc__.format(i=HNDLR) + msg += f"• {cmd[1].__doc__.format(i=HNDLR)}\n" msg += "\n ©️ @TeamUltroid" return msg From e872ae65398e2cc6d14a17d4b1b2d11d5273fcb7 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 14:23:08 +0530 Subject: [PATCH 64/74] Fix help --- modules/basic/_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 1732dbf704..3bedc6f76a 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -107,7 +107,7 @@ def get_from_funcs(mod, name): return False msg = f"Command available in `{name}`-\n" for cmd in funcs: - msg += f"• {cmd[1].__doc__.format(i=HNDLR)}\n" + msg += f"• {cmd[1].__doc__.format(*list(HNDLR*len(funcs))}\n" msg += "\n ©️ @TeamUltroid" return msg From d1515ec958476e11dd3490353fa566af438097a4 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 20 Aug 2023 14:25:44 +0530 Subject: [PATCH 65/74] Fix help --- modules/basic/_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 3bedc6f76a..3893966ca2 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -107,7 +107,7 @@ def get_from_funcs(mod, name): return False msg = f"Command available in `{name}`-\n" for cmd in funcs: - msg += f"• {cmd[1].__doc__.format(*list(HNDLR*len(funcs))}\n" + msg += f"• {cmd[1].__doc__.format(*list(HNDLR*len(funcs)))}\n" msg += "\n ©️ @TeamUltroid" return msg From ecd31c8d28bc09102e2203184f95b5ba54215277 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Sun, 20 Aug 2023 14:29:57 +0530 Subject: [PATCH 66/74] Update _help.py --- modules/basic/_help.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/basic/_help.py b/modules/basic/_help.py index 3893966ca2..496edc5117 100644 --- a/modules/basic/_help.py +++ b/modules/basic/_help.py @@ -87,7 +87,7 @@ def get_doc_from_module(name, type=""): if mod := _get_module(name, type): if not mod.__doc__: return get_from_funcs(mod, name) - msg = f"Commands available in `{name}`-\n" + msg = f"Commands available in `{name}`-\n\n" msg += mod.__doc__.format(i=HNDLR) msg += "\n ©️ @TeamUltroid" return msg @@ -105,9 +105,9 @@ def get_from_funcs(mod, name): ) if not funcs: return False - msg = f"Command available in `{name}`-\n" + msg = f"Command available in `{name}` -" for cmd in funcs: - msg += f"• {cmd[1].__doc__.format(*list(HNDLR*len(funcs)))}\n" + msg += f"\n\n• {cmd[1].__doc__.format(*list(HNDLR*len(funcs)))}" msg += "\n ©️ @TeamUltroid" return msg From 9fba7b2165ad13bb9376093f1d0b7369f7ad5ad7 Mon Sep 17 00:00:00 2001 From: TechiError Date: Sun, 27 Aug 2023 11:03:28 +0530 Subject: [PATCH 67/74] gDrive: cleanup service account auth --- utilities/gdrive.py | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index b096be2dee..990d9024da 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -22,9 +22,7 @@ from .helper import humanbytes, time_formatter try: - from Crypto.Hash import SHA256 - from Crypto.PublicKey import RSA - from Crypto.Signature import pkcs1_15 + import jwt except BaseException: pass @@ -77,20 +75,7 @@ async def get_access_token(self, code: str = None) -> dict: "exp": int(time.time()) + 3590, "iat": int(time.time()) } - total_params = str( - base64.urlsafe_b64encode( - json.dumps(header).encode('ascii')).decode('utf-8').replace( - '=', '')) + "." + str( - base64.urlsafe_b64encode( - json.dumps(payload).encode('ascii')).decode('utf-8').replace( - '=', '')) - private_key = RSA.import_key( - bytes(self.service_account["private_key"], "utf-8")) - signature = pkcs1_15.new(private_key).sign( - SHA256.new(total_params.encode('utf-8'))) - token = total_params + "." + \ - str(base64.urlsafe_b64encode(signature).decode( - 'utf-8').replace('=', '')) + token = jwt.encode(payload, self.service_account.get("private_key"), algorithm="RS256", headers=header) resp = await self._session.post("https://oauth2.googleapis.com/token", data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": token}) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 @@ -118,20 +103,7 @@ async def _refresh_access_token(self) -> None: "exp": int(time.time()) + 3600, "iat": int(time.time()) } - total_params = str( - base64.urlsafe_b64encode( - json.dumps(header).encode('ascii')).decode('utf-8').replace( - '=', '')) + "." + str( - base64.urlsafe_b64encode( - json.dumps(payload).encode('ascii')).decode('utf-8').replace( - '=', '')) - private_key = RSA.import_key( - bytes(self.service_account["private_key"], "utf-8")) - signature = pkcs1_15.new(private_key).sign( - SHA256.new(total_params.encode('utf-8'))) - token = total_params + "." + \ - str(base64.urlsafe_b64encode(signature).decode( - 'utf-8').replace('=', '')) + token = jwt.encode(payload, self.service_account.get("private_key"), algorithm="RS256", headers=header) resp = await self._session.post("https://oauth2.googleapis.com/token", data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": token}) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 From 2c819eb57516ff39d6eaa13e2e182b9b5c852bd9 Mon Sep 17 00:00:00 2001 From: TechiError Date: Sun, 27 Aug 2023 11:04:43 +0530 Subject: [PATCH 68/74] Fix jwt RS256 not found --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 69224660df..8dab6974db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ python-decouple telethon-patch tgcrypto enhancer -lottie \ No newline at end of file +lottie +cryptography==3.4.8 From 655fda9fe32dc64f91fb5c5f1c506d7745041c0b Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Tue, 29 Aug 2023 23:46:18 +0530 Subject: [PATCH 69/74] Waah --- utilities/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/helper.py b/utilities/helper.py index eafa689e24..d86b697a6f 100644 --- a/utilities/helper.py +++ b/utilities/helper.py @@ -305,7 +305,7 @@ def time_formatter(milliseconds, fixed_format=False): ) if not tmp: return "0s" - return tmp[:1] if tmp.endswith(":") else tmp + return tmp[:-1] if tmp.endswith(":") else tmp def humanbytes(size: int) -> str: From e154d11c63b779291552da877f5e897ae110caf1 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Fri, 1 Sep 2023 19:21:30 +0530 Subject: [PATCH 70/74] Update gdrive.py --- utilities/gdrive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 990d9024da..75d40b18f3 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -243,7 +243,7 @@ async def upload_file(self, event, path: str, filename: str = None, folder_id: s params={"fields": "id, name, webContentLink"}, ) if r.status == 401: - await self.refresh_access_token() + await self._refresh_access_token() return await self.upload_file(event, path, filename, folder_id) elif r.status == 403: # upload to root and move From 67b9cfa9afcc63e8b3c4f69b34804d090f1f6962 Mon Sep 17 00:00:00 2001 From: buddhhu Date: Sun, 17 Sep 2023 14:36:45 +0530 Subject: [PATCH 71/74] Imports --- modules/basic/vctools.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/basic/vctools.py b/modules/basic/vctools.py index a0d6825a53..1852d0433a 100644 --- a/modules/basic/vctools.py +++ b/modules/basic/vctools.py @@ -24,20 +24,20 @@ import contextlib -from telethon.tl.functions.channels import GetFullChannelRequest as getchat -from telethon.tl.functions.phone import CreateGroupCallRequest as startvc -from telethon.tl.functions.phone import DiscardGroupCallRequest as stopvc -from telethon.tl.functions.phone import EditGroupCallTitleRequest as settitle -from telethon.tl.functions.phone import GetGroupCallRequest as getvc -from telethon.tl.functions.phone import InviteToGroupCallRequest as invitetovc +from telethon.tl.functions.channels import GetFullChannelRequest +from telethon.tl.functions.phone import CreateGroupCallRequest +from telethon.tl.functions.phone import DiscardGroupCallRequest +from telethon.tl.functions.phone import EditGroupCallTitleRequest +from telethon.tl.functions.phone import GetGroupCallRequest +from telethon.tl.functions.phone import InviteToGroupCallRequest from .. import get_string, ultroid_cmd, LOGS async def get_call(event): - mm = await event.client(getchat(event.chat_id)) + mm = await event.client(GetFullChannelRequest(event.chat_id)) if mm.full_chat.call: - xx = await event.client(getvc(mm.full_chat.call, limit=1)) + xx = await event.client(GetGroupCallRequest(mm.full_chat.call, limit=1)) return xx.call @@ -54,7 +54,7 @@ def user_list(l, n): async def _(e): try: if call := await get_call(e): - await e.client(stopvc(call)) + await e.client(DiscardGroupCallRequest(call)) return await e.eor(get_string("vct_4")) await e.eor("`Voice call is not active.`") except Exception as ex: @@ -79,7 +79,7 @@ async def _(e): return await e.eor("`Voice Call is not active.`") for p in hmm: with contextlib.suppress(BaseException): - await e.client(invitetovc(call=call, users=p)) + await e.client(InviteToGroupCallRequest(call=call, users=p)) z += len(p) await ok.edit(get_string("vct_5").format(z)) @@ -91,7 +91,7 @@ async def _(e): ) async def _(e): try: - await e.client(startvc(e.chat_id)) + await e.client(CreateGroupCallRequest(e.chat_id)) await e.eor(get_string("vct_1")) except Exception as ex: LOGS.exception(ex) @@ -111,7 +111,7 @@ async def _(e): if not call: return await e.eor("`Voice Call is not active.`") try: - await e.client(settitle(call=call, title=title.strip())) + await e.client(EditGroupCallTitleRequest(call=call, title=title.strip())) await e.eor(get_string("vct_2").format(title)) except Exception as ex: await e.eor(f"`{ex}`") From e1e65f4a39286a3e3c8eeabe5ccc36485e4117ce Mon Sep 17 00:00:00 2001 From: buddhhu Date: Tue, 19 Sep 2023 21:46:16 +0530 Subject: [PATCH 72/74] Search files/folder in drive --- utilities/gdrive.py | 221 ++++++++++++++++++++++++++++++-------------- 1 file changed, 152 insertions(+), 69 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 75d40b18f3..36dc5d9a42 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -39,7 +39,9 @@ def __init__(self): self.client_id: str = udB.get_key("GDRIVE_CLIENT_ID") self.client_secret: str = udB.get_key("GDRIVE_CLIENT_SECRET") self.folder_id: str = udB.get_key("GDRIVE_FOLDER_ID") or "root" - self.redirect_uri: str = udB.get_key("GDRIVE_REDIRECT_URI") or "http://localhost" + self.redirect_uri: str = ( + udB.get_key("GDRIVE_REDIRECT_URI") or "http://localhost" + ) self.scope: str = "https://www.googleapis.com/auth/drive" self.creds: dict = udB.get_key("GDRIVE_AUTH_TOKEN") or {} self.service_account: dict = udB.get_key("GDRIVE_SERVICE_KEY") @@ -54,36 +56,53 @@ def _create_folder_link(folder_id: str) -> str: return f"https://drive.google.com/folderview?id={folder_id}" def get_oauth2_url(self) -> str: - return "https://accounts.google.com/o/oauth2/v2/auth?" + urlencode({ - "client_id": self.client_id, - "redirect_uri": self.redirect_uri, - "response_type": "code", - "scope": self.scope, - "access_type": "offline", - }) + return "https://accounts.google.com/o/oauth2/v2/auth?" + urlencode( + { + "client_id": self.client_id, + "redirect_uri": self.redirect_uri, + "response_type": "code", + "scope": self.scope, + "access_type": "offline", + } + ) async def get_access_token(self, code: str = None) -> dict: if self.service_account: - header = { - "alg": "RS256", - "typ": "JWT" - } + header = {"alg": "RS256", "typ": "JWT"} payload = { "iss": self.service_account["client_email"], "scope": self.scope, "aud": "https://oauth2.googleapis.com/token", "exp": int(time.time()) + 3590, - "iat": int(time.time()) + "iat": int(time.time()), } - token = jwt.encode(payload, self.service_account.get("private_key"), algorithm="RS256", headers=header) - resp = await self._session.post("https://oauth2.googleapis.com/token", data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": token}) + token = jwt.encode( + payload, + self.service_account.get("private_key"), + algorithm="RS256", + headers=header, + ) + resp = await self._session.post( + "https://oauth2.googleapis.com/token", + data={ + "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", + "assertion": token, + }, + ) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return self.creds resp = await self._session.post( "https://oauth2.googleapis.com/token", - data={"client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": self.redirect_uri, "grant_type": "authorization_code", "code": code}, headers={"Content-Type": "application/x-www-form-urlencoded"} + data={ + "client_id": self.client_id, + "client_secret": self.client_secret, + "redirect_uri": self.redirect_uri, + "grant_type": "authorization_code", + "code": code, + }, + headers={"Content-Type": "application/x-www-form-urlencoded"}, ) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 @@ -92,24 +111,41 @@ async def get_access_token(self, code: str = None) -> dict: async def _refresh_access_token(self) -> None: if self.service_account: - header = { - "alg": "RS256", - "typ": "JWT" - } + header = {"alg": "RS256", "typ": "JWT"} payload = { "iss": self.service_account["client_email"], "scope": self.scope, "aud": "https://oauth2.googleapis.com/token", "exp": int(time.time()) + 3600, - "iat": int(time.time()) + "iat": int(time.time()), } - token = jwt.encode(payload, self.service_account.get("private_key"), algorithm="RS256", headers=header) - resp = await self._session.post("https://oauth2.googleapis.com/token", data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": token}) + token = jwt.encode( + payload, + self.service_account.get("private_key"), + algorithm="RS256", + headers=header, + ) + resp = await self._session.post( + "https://oauth2.googleapis.com/token", + data={ + "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", + "assertion": token, + }, + ) self.creds = await resp.json() self.creds["expires_in"] = time.time() + 3590 udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) return - resp = await self._session.post("https://oauth2.googleapis.com/token", data={"client_id": self.client_id, "client_secret": self.client_secret, "grant_type": "refresh_token", "refresh_token": self.creds.get("refresh_token")}, headers={"Content-Type": "application/x-www-form-urlencoded"}) + resp = await self._session.post( + "https://oauth2.googleapis.com/token", + data={ + "client_id": self.client_id, + "client_secret": self.client_secret, + "grant_type": "refresh_token", + "refresh_token": self.creds.get("refresh_token"), + }, + headers={"Content-Type": "application/x-www-form-urlencoded"}, + ) creds = await resp.json() if "error" in creds: return creds @@ -118,45 +154,68 @@ async def _refresh_access_token(self) -> None: udB.set_key("GDRIVE_AUTH_TOKEN", self.creds) async def get_size_status(self) -> dict: - await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None - return await (await self._session.get( - self.base_url + "/about", - headers={ - "Authorization": "Bearer " + self.creds.get("access_token"), - "Content-Type": "application/json", - }, - params={"fields": "storageQuota"}, - )).json() + await self._refresh_access_token() if time.time() > self.creds.get( + "expires_in" + ) else None + return await ( + await self._session.get( + self.base_url + "/about", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + params={"fields": "storageQuota"}, + ) + ).json() - async def set_permissions(self, fileid: str, role: str = "reader", type: str = "anyone"): + async def set_permissions( + self, fileid: str, role: str = "reader", type: str = "anyone" + ): # set permissions to anyone with link can view - await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None - return await (await self._session.post( - self.base_url + f"/files/{fileid}/permissions", - headers={ - "Authorization": "Bearer " + self.creds.get("access_token"), - "Content-Type": "application/json", - }, - json={ - "role": role, - "type": type, - }, - )).json() + await self._refresh_access_token() if time.time() > self.creds.get( + "expires_in" + ) else None + return await ( + await self._session.post( + self.base_url + f"/files/{fileid}/permissions", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + json={ + "role": role, + "type": type, + }, + ) + ).json() - async def list_files(self) -> list: - await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None + async def list_files(self, query: str = None) -> list: + await self._refresh_access_token() if time.time() > self.creds.get( + "expires_in" + ) else None files = [] page_token = None - params = {"supportAllDrives": "true"} + params = { + "fields": "files(id, name, mimeType, parents, webContentLink, webViewLink, size)", + "supportsAllDrives": "true", + "includeItemsFromAllDrives": "true", + } + if query: + params["q"] = f"name contains '{query}'" + params["q"] += ( + f" and '{self.folder_id}' in parents" if self.folder_id else "" + ) while True: - resp = await (await self._session.get( - self.base_url + "/files", - headers={ - "Authorization": "Bearer " + self.creds.get("access_token"), - "Content-Type": "application/json", - }, - params=params, - )).json() + resp = await ( + await self._session.get( + self.base_url + "/files", + headers={ + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + }, + params=params, + ) + ).json() for file in resp.get("files", []): if file["mimeType"] == self.folder_mime: file["url"] = self._create_folder_link(file["id"]) @@ -171,7 +230,9 @@ async def list_files(self) -> list: return files async def delete(self, fileId: str) -> dict: - await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None + await self._refresh_access_token() if time.time() > self.creds.get( + "expires_in" + ) else None r = await self._session.delete( self.base_url + f"/files/{fileId}", headers={ @@ -184,8 +245,12 @@ async def delete(self, fileId: str) -> dict: except ContentTypeError: return {"status": "success"} - async def copy_file(self, fileId: str, filename: str, folder_id: str, move: bool = False): - await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None + async def copy_file( + self, fileId: str, filename: str, folder_id: str, move: bool = False + ): + await self._refresh_access_token() if time.time() > self.creds.get( + "expires_in" + ) else None headers = { "Authorization": "Bearer " + self.creds.get("access_token"), "Content-Type": "application/json", @@ -195,6 +260,7 @@ async def copy_file(self, fileId: str, filename: str, folder_id: str, move: bool "mimeType": "application/octet-stream", "fields": "id, name, webContentLink", "supportsAllDrives": "true", + "includeItemsFromAllDrives": "true", } file_metadata = { "name": filename, @@ -218,8 +284,12 @@ async def copy_file(self, fileId: str, filename: str, folder_id: str, move: bool return await self.copy_file(fileId, filename, folder_id, move) return r - async def upload_file(self, event, path: str, filename: str = None, folder_id: str = None): - await self._refresh_access_token() if time.time() > self.creds.get("expires_in") else None + async def upload_file( + self, event, path: str, filename: str = None, folder_id: str = None + ): + await self._refresh_access_token() if time.time() > self.creds.get( + "expires_in" + ) else None last_txt = "" filename = filename if filename else path.split("/")[-1] mime_type = guess_type(path)[0] or "application/octet-stream" @@ -228,8 +298,10 @@ async def upload_file(self, event, path: str, filename: str = None, folder_id: s # await self.get_size_status() chunksize = 104857600 # 100MB # 1. Retrieve session for resumable upload. - headers = {"Authorization": "Bearer " + - self.creds.get("access_token"), "Content-Type": "application/json"} + headers = { + "Authorization": "Bearer " + self.creds.get("access_token"), + "Content-Type": "application/json", + } params = { "name": filename, "mimeType": mime_type, @@ -249,8 +321,10 @@ async def upload_file(self, event, path: str, filename: str = None, folder_id: s # upload to root and move r = await self.upload_file(event, path, filename, "root") return await self.copy_file(r["id"], filename, folder_id, move=True) - upload_url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" + \ - r.headers.get("X-GUploader-UploadID") + upload_url = ( + "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" + + r.headers.get("X-GUploader-UploadID") + ) with open(path, "rb") as f: uploaded = 0 @@ -258,10 +332,19 @@ async def upload_file(self, event, path: str, filename: str = None, folder_id: s resp = None while filesize != uploaded: chunk_data = f.read(chunksize) - headers = {"Content-Length": str(len(chunk_data)), - "Content-Range": "bytes " + str(uploaded) + "-" + str(uploaded + len(chunk_data) - 1) + "/" + str(filesize)} + headers = { + "Content-Length": str(len(chunk_data)), + "Content-Range": "bytes " + + str(uploaded) + + "-" + + str(uploaded + len(chunk_data) - 1) + + "/" + + str(filesize), + } uploaded += len(chunk_data) - resp = await self._session.put(upload_url, data=chunk_data, headers=headers) + resp = await self._session.put( + upload_url, data=chunk_data, headers=headers + ) diff = time.time() - start percentage = round((uploaded / filesize) * 100, 2) speed = round(uploaded / diff, 2) From 627a0b192692e57d60c3a6ef53063cd2eb5f92bd Mon Sep 17 00:00:00 2001 From: buddhhu Date: Tue, 19 Sep 2023 22:33:40 +0530 Subject: [PATCH 73/74] return on error --- utilities/gdrive.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 36dc5d9a42..367bc4bc9b 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -216,7 +216,9 @@ async def list_files(self, query: str = None) -> list: params=params, ) ).json() - for file in resp.get("files", []): + if "error" in resp: + return resp + for file in resp.get("files"): if file["mimeType"] == self.folder_mime: file["url"] = self._create_folder_link(file["id"]) else: @@ -314,10 +316,7 @@ async def upload_file( data=json.dumps(params), params={"fields": "id, name, webContentLink"}, ) - if r.status == 401: - await self._refresh_access_token() - return await self.upload_file(event, path, filename, folder_id) - elif r.status == 403: + if r.status == 403: # upload to root and move r = await self.upload_file(event, path, filename, "root") return await self.copy_file(r["id"], filename, folder_id, move=True) From 934f883dd31479625ac265d608df3109b84c2ce7 Mon Sep 17 00:00:00 2001 From: Amit Sharma Date: Thu, 21 Sep 2023 12:32:18 +0530 Subject: [PATCH 74/74] Get files from every page --- utilities/gdrive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/gdrive.py b/utilities/gdrive.py index 367bc4bc9b..5e52f851ca 100644 --- a/utilities/gdrive.py +++ b/utilities/gdrive.py @@ -196,7 +196,7 @@ async def list_files(self, query: str = None) -> list: files = [] page_token = None params = { - "fields": "files(id, name, mimeType, parents, webContentLink, webViewLink, size)", + "fields": "nextPageToken, files(id, name, mimeType, parents, webContentLink, webViewLink, size)", "supportsAllDrives": "true", "includeItemsFromAllDrives": "true", }