diff --git a/.env.sample b/.env.sample index fb49d134fb..79d989c855 100644 --- a/.env.sample +++ b/.env.sample @@ -4,4 +4,9 @@ API_ID= API_HASH= SESSION= REDIS_URI= -REDIS_PASSWORD= \ No newline at end of file +REDIS_PASSWORD= + +# [OPTIONAL] + +LOG_CHANNEL= +BOT_TOKEN= diff --git a/.github/ISSUE_TEMPLATE/bug-reports.yml b/.github/ISSUE_TEMPLATE/bug-reports.yml index 206fe047a2..e2ca5a92d0 100644 --- a/.github/ISSUE_TEMPLATE/bug-reports.yml +++ b/.github/ISSUE_TEMPLATE/bug-reports.yml @@ -1,6 +1,6 @@ name: Bug Report description: File a bug report -title: "[BUG REPORT]: " +title: "[BUG REPORT]" labels: [bug] assignees: - xditya diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 0000000000..a917e2c942 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,16 @@ +name: Greetings + +on: [pull_request, issues] + +jobs: + greeting: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: 'Thanks for Opening This Issue, we will look into it soon!' + pr-message: 'Thanks for Your Contribution. It will be reviewed soon, Useless Prs are Closed Immediately' diff --git a/.gitignore b/.gitignore index 485b60338d..7b7616df13 100644 --- a/.gitignore +++ b/.gitignore @@ -13,12 +13,29 @@ build *.log target/npmlist.json package-lock.json + # Directories addons/ +pyUltroid/ __pycache__/ venv/ node_modules/ glitch_me/ +src/glitch-me .idea/ .vscode/ -temp/ \ No newline at end of file +temp/ +bin-debug/ +bin-release/ +[Oo]bj/ +[Bb]in/ +.settings/ +*.swf +*.air +*.ipa +*.apk + +# temporary files +*.raw +tplugins +tassistant diff --git a/Dockerfile b/Dockerfile index b50b71da31..d271e38f13 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in . -FROM programmingerror/ultroid:b0.1 +FROM theteamultroid/ultroid:main # set timezone ENV TZ=Asia/Kolkata @@ -14,12 +14,8 @@ RUN git clone https://github.com/TeamUltroid/Ultroid.git /root/TeamUltroid/ WORKDIR /root/TeamUltroid/ # install main requirements. -COPY requirements.txt /deploy/ -RUN pip3 install --no-cache-dir -r /deploy/requirements.txt - -# install addons requirements -RUN wget -O /deploy/addons.txt https://git.io/JWdOk -RUN pip3 install --no-cache-dir -r /deploy/addons.txt +RUN pip3 install --no-cache-dir -r requirements.txt +RUN pip3 uninstall av -y && pip3 install av --no-binary av # start the bot CMD ["bash", "resources/startup/startup.sh"] diff --git a/README.md b/README.md index 3ddfbcdebb..4eb03b7f2e 100644 --- a/README.md +++ b/README.md @@ -5,20 +5,20 @@ Ultroid - UserBot -A stable pluggable Telegram userbot + vc music bot, based on Telethon. +A stable pluggable Telegram userbot + Voice & Video Call music bot, based on Telethon. [![Stars](https://img.shields.io/github/stars/TeamUltroid/Ultroid?style=flat-square&color=yellow)](https://github.com/TeamUltroid/Ultroid/stargazers) [![Forks](https://img.shields.io/github/forks/TeamUltroid/Ultroid?style=flat-square&color=orange)](https://github.com/TeamUltroid/Ultroid/fork) [![Size](https://img.shields.io/github/repo-size/TeamUltroid/Ultroid?style=flat-square&color=green)](https://github.com/TeamUltroid/Ultroid/) -[![Python](https://img.shields.io/badge/Python-v3.9-blue)](https://www.python.org/) +[![Python](https://img.shields.io/badge/Python-v3.9.7-blue)](https://www.python.org/) +[![CodeFactor](https://www.codefactor.io/repository/github/teamultroid/ultroid/badge/main)](https://www.codefactor.io/repository/github/teamultroid/ultroid/overview/main) [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/TeamUltroid/Ultroid/graphs/commit-activity) -[![Docker Pulls](https://img.shields.io/docker/pulls/programmingerror/ultroid?style=flat-square)](https://img.shields.io/docker/pulls/programmingerror/ultroid?style=flat-square) +[![Docker Pulls](https://img.shields.io/docker/pulls/theteamultroid/ultroid?style=flat-square)](https://img.shields.io/docker/pulls/theteamultroid/ultroid?style=flat-square) [![Open Source Love svg2](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/TeamUltroid/Ultroid) [![Contributors](https://img.shields.io/github/contributors/TeamUltroid/Ultroid?style=flat-square&color=green)](https://github.com/TeamUltroid/Ultroid/graphs/contributors) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com) [![License](https://img.shields.io/badge/License-AGPL-blue)](https://github.com/TeamUltroid/Ultroid/blob/main/LICENSE) [![Sparkline](https://stars.medv.io/Teamultroid/Ultroid.svg)](https://stars.medv.io/TeamUltroid/Ultroid) - ---- # Deploy @@ -53,10 +53,10 @@ Get the [Necessary Variables](#Necessary-Variables) and then click the button be ### Local Deploy - Latest Method This is the latest and most fastest method currently.
-First, goto [This Project](https://github.com/BLUE-DEVIL1134/UltroidCli) and install the latest release from the Github Releases.
-Then, do as its given in the `README.md` to add the executable to your system path. +First, go to [This Project](https://github.com/BLUE-DEVIL1134/UltroidCli) and install the latest release from the Github Releases.
+Then, do as it's given in the `README.md` to add the executable to your system path. -Further, take a look at the [`docs`](https://blue-devil1134.github.io/UltroidCli/) to get more information on this. +Further, take a look at the [`docs`](https://blue-devil1134.github.io/UltroidCli/) to get more information. ### Local Deploy - Easy Method @@ -93,8 +93,6 @@ Further, take a look at the [`docs`](https://blue-devil1134.github.io/UltroidCli `python(3) -m pyUltroid` ## Necessary Variables -- `API_ID` - Your API_ID from [my.telegram.org](https://my.telegram.org/) -- `API_HASH` - Your API_HASH from [my.telegram.org](https://my.telegram.org/) - `SESSION` - SessionString for your accounts login session. Get it from [here](#Session-String) - `REDIS_URI` - Redis endpoint URL, from [redislabs](http://redislabs.com/), tutorial [here.](./resources/extras/redistut.md) - `REDIS_PASSWORD ` - Redis endpoint Password, from [redislabs](http://redislabs.com/), tutorial [here.](./resources/extras/redistut.md) @@ -117,6 +115,5 @@ Ultroid is licensed under [GNU Affero General Public License](https://www.gnu.or # Credits * [![TeamUltroid-Devs](https://img.shields.io/static/v1?label=Teamultroid&message=devs&color=critical)](https://t.me/UltroidDevs) * [Lonami](https://github.com/LonamiWebs/) for [Telethon.](https://github.com/LonamiWebs/Telethon) -* [Dan](https://github.com/delivrance) for [Pyrogram.](https://github.com/pyrogram/pyrogram) -* [Pytgcalls](https://github.com/pytgcalls) for [PyTgCalls.](https://github.com/pytgcalls/pytgcalls) +* [MarshalX](https://github.com/MarshalX) for [PyTgCalls.](https://github.com/MarshalX/tgcalls) diff --git a/app.json b/app.json index 5e6e0f4b9b..885b2c6e67 100644 --- a/app.json +++ b/app.json @@ -37,12 +37,12 @@ "value": "" }, "HEROKU_API": { - "description": "Heroku API token. Needed if deploying on heroku ONLY.", + "description": "Heroku API token. Mandatory for Heroku Deploy...", "value": "", "required": false }, "HEROKU_APP_NAME": { - "description": "Name of your heroku app, given in the first blank on this page. To be added if deploying to heroku ONLY.", + "description": "Name of your Heroku app, given in the first blank on this page. To be added if deploying to heroku ONLY.", "value": "", "required": false } diff --git a/assistant/__init__.py b/assistant/__init__.py index 9ff002d22a..a869538655 100644 --- a/assistant/__init__.py +++ b/assistant/__init__.py @@ -24,5 +24,4 @@ async def setit(event, name, value): def get_back_button(name): - button = [Button.inline("« Bᴀᴄᴋ", data=f"{name}")] - return button + return [Button.inline("« Bᴀᴄᴋ", data=f"{name}")] diff --git a/assistant/api_setter.py b/assistant/api_setter.py index e745ae4bf7..b4e649b34a 100644 --- a/assistant/api_setter.py +++ b/assistant/api_setter.py @@ -41,12 +41,11 @@ async def rmbgapi(event): "Cancelled!!", buttons=get_back_button("apiset"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("apiset"), - ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("apiset"), + ) @callback("dapi") @@ -66,12 +65,11 @@ async def rmbgapi(event): "Cancelled!!", buttons=get_back_button("apiset"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("apiset"), - ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("apiset"), + ) @callback("oapi") @@ -91,9 +89,8 @@ async def rmbgapi(event): "Cancelled!!", buttons=get_back_button("apiset"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("apiset"), - ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("apiset"), + ) diff --git a/assistant/callbackstuffs.py b/assistant/callbackstuffs.py index ec340683cd..d623de9948 100644 --- a/assistant/callbackstuffs.py +++ b/assistant/callbackstuffs.py @@ -6,10 +6,8 @@ # . import re -import urllib -from glob import glob -from os import remove -from random import choices +import sys +from os import execl, remove from telegraph import Telegraph from telegraph import upload_file as upl @@ -26,90 +24,63 @@ TOKEN_FILE = "resources/auths/auth_token.txt" -@callback( - re.compile( - "ebk_(.*)", - ), -) -async def eupload(event): - match = event.pattern_match.group(1).decode("utf-8") - await event.answer("Uploading..") - try: - await event.edit( - file=f"https://www.gutenberg.org/files/{match}/{match}-pdf.pdf" - ) - except BaseException: - book = "Ultroid-Book.epub" - urllib.request.urlretrieve( - "https://www.gutenberg.org/ebooks/132.epub.images", book - ) - fn, media, _ = await asst._file_to_media( - book, thumb="resources/extras/ultroid.jpg" - ) - await event.edit(file=media) - remove(book) - - @callback( re.compile( "sndplug_(.*)", ), ) +@owner async def send(eve): name = (eve.data_match.group(1)).decode("UTF-8") - thumb = "" - for m in choices(sorted(glob("resources/extras/*.jpg"))): - thumb += m + thumb = "resources/extras/inline.jpg" + await eve.answer("■ Sending ■") if name.startswith("def"): - plug_name = name.replace(f"def_plugin_", "") + plug_name = name.replace("def_plugin_", "") plugin = f"plugins/{plug_name}.py" - buttons = [ - [ - Button.inline( - "« Pᴀsᴛᴇ »", - data=f"pasta-{plugin}", - ) - ], - [ - Button.inline("« Bᴀᴄᴋ", data="back"), - Button.inline("••Cʟᴏꜱᴇ••", data="close"), - ], - ] - else: - plug_name = name.replace(f"add_plugin_", "") + data = "back" + elif name.startswith("add"): + plug_name = name.replace("add_plugin_", "") plugin = f"addons/{plug_name}.py" - buttons = [ - [ - Button.inline( - "« Pᴀsᴛᴇ »", - data=f"pasta-{plugin}", - ) - ], - [ - Button.inline("« Bᴀᴄᴋ", data="buck"), - Button.inline("••Cʟᴏꜱᴇ••", data="close"), - ], - ] + data = "buck" + else: + plug_name = name.replace("vc_plugin_", "") + plugin = f"vcbot/{plug_name}.py" + data = "vc_helper" + buttons = [ + [ + Button.inline( + "« Pᴀsᴛᴇ »", + data=f"pasta-{plugin}", + ) + ], + [ + Button.inline("« Bᴀᴄᴋ", data=data), + Button.inline("••Cʟᴏꜱᴇ••", data="close"), + ], + ] await eve.edit(file=plugin, thumb=thumb, buttons=buttons) +heroku_api, app_name = Var.HEROKU_API, Var.HEROKU_APP_NAME + + @callback("updatenow") @owner async def update(eve): repo = Repo() ac_br = repo.active_branch ups_rem = repo.remote("upstream") - if Var.HEROKU_API: + if heroku_api: import heroku3 try: - heroku = heroku3.from_key(Var.HEROKU_API) + heroku = heroku3.from_key(heroku_api) heroku_app = None heroku_applications = heroku.apps() except BaseException: return await eve.edit("`Wrong HEROKU_API.`") for app in heroku_applications: - if app.name == Var.HEROKU_APP_NAME: + if app.name == app_name: heroku_app = app if not heroku_app: await eve.edit("`Wrong HEROKU_APP_NAME.`") @@ -121,7 +92,7 @@ async def update(eve): ups_rem.fetch(ac_br) repo.git.reset("--hard", "FETCH_HEAD") heroku_git_url = heroku_app.git_url.replace( - "https://", "https://api:" + Var.HEROKU_API + "@" + "https://", "https://api:" + heroku_api + "@" ) if "heroku" in repo.remotes: remote = repo.remote("heroku") @@ -139,42 +110,36 @@ async def update(eve): await eve.edit( "`Userbot dyno build in progress, please wait for it to complete.`" ) - try: - ups_rem.pull(ac_br) - except GitCommandError: - repo.git.reset("--hard", "FETCH_HEAD") - await updateme_requirements() - await eve.edit( - "`Successfully Updated!\nBot is restarting... Wait for a second!`" - ) + call_back() + await bash("git pull && pip3 install -r requirements.txt") execl(sys.executable, sys.executable, "-m", "pyUltroid") @callback("changes") @owner async def changes(okk): + await okk.answer("■ Generating Changelogs...") repo = Repo.init() ac_br = repo.active_branch - changelog, tl_chnglog = await gen_chlog(repo, f"HEAD..upstream/{ac_br}") - changelog_str = changelog + f"\n\nClick the below button to update!" + changelog, tl_chnglog = gen_chlog(repo, f"HEAD..upstream/{ac_br}") + changelog_str = changelog + "\n\nClick the below button to update!" if len(changelog_str) > 1024: await okk.edit(get_string("upd_4")) await asyncio.sleep(2) - with open(f"ultroid_updates.txt", "w+") as file: + with open("ultroid_updates.txt", "w+") as file: file.write(tl_chnglog) await okk.edit( get_string("upd_5"), file="ultroid_updates.txt", buttons=Button.inline("Update Now", data="updatenow"), ) - remove(f"ultroid_updates.txt") + remove("ultroid_updates.txt") return - else: - await okk.edit( - changelog_str, - buttons=Button.inline("Update Now", data="updatenow"), - parse_mode="html", - ) + await okk.edit( + changelog_str, + buttons=Button.inline("Update Now", data="updatenow"), + parse_mode="html", + ) @callback( @@ -186,25 +151,20 @@ async def changes(okk): async def _(e): ok = (e.data_match.group(1)).decode("UTF-8") with open(ok, "r") as hmm: - _, key = get_paste(hmm.read()) - if _ == "dog": - link = "https://del.dog/" + key - raw = "https://del.dog/raw/" + key - else: - link = "https://nekobin.com/" + key - raw = "https://nekobin.com/raw/" + key + _, key = await get_paste(hmm.read()) + link = "https://spaceb.in/" + key + raw = f"https://spaceb.in/api/v1/documents/{key}/raw" + if not _: + return await e.answer(key[:30], alert=True) + data = "buck" if ok.startswith("plugins"): - buttons = [ - Button.inline("« Bᴀᴄᴋ", data="back"), - Button.inline("••Cʟᴏꜱᴇ••", data="close"), - ] - else: - buttons = [ - Button.inline("« Bᴀᴄᴋ", data="buck"), - Button.inline("••Cʟᴏꜱᴇ••", data="close"), - ] + data = "back" + buttons = [ + Button.inline("« Bᴀᴄᴋ", data=data), + Button.inline("••Cʟᴏꜱᴇ••", data="close"), + ] await e.edit( - f"Pasted\n 👉[Link]\n 👉[Raw Link]", + f"Pasted\n👉 [Link]\n👉 [Raw Link]", buttons=buttons, link_preview=False, parse_mode="html", @@ -334,12 +294,77 @@ async def otvaar(event): Button.inline("Eᴍᴏᴊɪ ɪɴ Hᴇʟᴘ", data="emoj"), Button.inline("Sᴇᴛ ɢDʀɪᴠᴇ", data="gdrive"), ], - [Button.inline("Inline Pic", data="inli_pic")], + [ + Button.inline("Iɴʟɪɴᴇ Pɪᴄ", data="inli_pic"), + Button.inline("Sᴜᴅᴏ HNDLR", data="shndlr"), + ], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ", "oofdm")], [Button.inline("« Bᴀᴄᴋ", data="setter")], ], ) +@callback("oofdm") +@owner +async def euwhe(event): + BT = [ + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oɴ", "dmof")], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Oғғ", "dmof")], + [Button.inline("Dᴜᴀʟ Mᴏᴅᴇ Hɴᴅʟʀ", "dmhn")], + ] + await event.edit( + "About [Dual Mode](https://t.me/UltroidUpdates/18)", + buttons=BT, + link_preview=False, + ) + + +@callback("dmof") +@owner +async def rhwhe(e): + if udB.get("DUAL_MODE"): + udB.delete("DUAL_MODE") + key = "Off" + else: + udB.set("DUAL_MODE", "True") + key = "On" + Msg = "Dual Mode : " + key + await e.edit(Msg, buttons=get_back_button("otvars")) + + +@callback("dmhn") +@owner +async def hndlrr(event): + await event.delete() + pru = event.sender_id + var = "DUAL_HNDLR" + name = "Dual Handler" + CH = udB.get(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("otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("otvars"), + ) + + @callback("emoj") @owner async def emoji(event): @@ -353,12 +378,12 @@ async def emoji(event): response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message( + await conv.send_message( "Cancelled!!", buttons=get_back_button("otvars"), ) elif themssg.startswith(("/", HNDLR)): - return await conv.send_message( + await conv.send_message( "Incorrect Emoji", buttons=get_back_button("otvars"), ) @@ -385,12 +410,12 @@ async def pluginch(event): response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message( + await conv.send_message( "Cancelled!!", buttons=get_back_button("otvars"), ) elif themssg.startswith(("/", HNDLR)): - return await conv.send_message( + await conv.send_message( "Incorrect channel", buttons=get_back_button("otvars"), ) @@ -420,17 +445,55 @@ async def hndlrr(event): response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message( + await conv.send_message( "Cancelled!!", buttons=get_back_button("otvars"), ) elif len(themssg) > 1: - return await conv.send_message( + await conv.send_message( "Incorrect Handler", buttons=get_back_button("otvars"), ) elif themssg.startswith(("/", "#", "@")): - return await conv.send_message( + await conv.send_message( + "This cannot be used as handler", + buttons=get_back_button("otvars"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("otvars"), + ) + + +@callback("shndlr") +@owner +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("otvars"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("otvars"), + ) + elif themssg.startswith(("/", "#", "@")): + await conv.send_message( "This cannot be used as handler", buttons=get_back_button("otvars"), ) @@ -445,13 +508,13 @@ async def hndlrr(event): @callback("taglog") @owner async def tagloggrr(e): + if not udB.get("TAG_LOG"): + BUTTON = [Button.inline("SET TAG LOG", data="settag")] + else: + BUTTON = [Button.inline("DELETE TAG LOG", data="deltag")] await e.edit( "Choose Options", - buttons=[ - [Button.inline("SET TAG LOG", data="settag")], - [Button.inline("DELETE TAG LOG", data="deltag")], - [Button.inline("« Bᴀᴄᴋ", data="otvars")], - ], + buttons=[BUTTON, [Button.inline("« Bᴀᴄᴋ", data="otvars")]], ) @@ -481,22 +544,24 @@ async def taglogerr(event): "Cancelled!!", buttons=get_back_button("taglog"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("taglog"), - ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("taglog"), + ) @callback("eaddon") @owner async def pmset(event): + if not udB.get("ADDONS"): + BT = [Button.inline("Aᴅᴅᴏɴs Oɴ", data="edon")] + else: + BT = [Button.inline("Aᴅᴅᴏɴs Oғғ", data="edof")] await event.edit( "ADDONS~ Extra Plugins:", buttons=[ - [Button.inline("Aᴅᴅᴏɴs Oɴ", data="edon")], - [Button.inline("Aᴅᴅᴏɴs Oғғ", data="edof")], + BT, [Button.inline("« Bᴀᴄᴋ", data="otvars")], ], ) @@ -516,8 +581,7 @@ async def eddon(event): @callback("edof") @owner async def eddof(event): - var = "ADDONS" - await setit(event, var, "False") + udB.set("ADDONS", "False") await event.edit( "Done! ADDONS has been turned off!! After Setting All Things Do Restart", buttons=get_back_button("eaddon"), @@ -527,11 +591,14 @@ async def eddof(event): @callback("sudo") @owner async def pmset(event): + if not udB.get("SUDO"): + BT = [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oɴ", data="onsudo")] + else: + BT = [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oғғ", data="ofsudo")] await event.edit( f"SUDO MODE ~ Some peoples can use ur Bot which u selected. To know More use `{HNDLR}help sudo`", buttons=[ - [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oɴ", data="onsudo")], - [Button.inline("Sᴜᴅᴏ Mᴏᴅᴇ Oғғ", data="ofsudo")], + BT, [Button.inline("« Bᴀᴄᴋ", data="otvars")], ], ) @@ -591,12 +658,11 @@ async def sfgrp(event): "Cancelled!!", buttons=get_back_button("sfban"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("sfban"), - ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("sfban"), + ) @callback("sfexf") @@ -608,8 +674,9 @@ async def sfexf(event): pru = event.sender_id async with asst.conversation(pru) as conv: await conv.send_message( - f"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.", + "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." ) + response = conv.wait_event(events.NewMessage(chats=pru)) response = await response themssg = response.message.message @@ -618,12 +685,11 @@ async def sfexf(event): "Cancelled!!", buttons=get_back_button("sfban"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}", - buttons=get_back_button("sfban"), - ) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("sfban"), + ) @callback("alvcstm") @@ -659,15 +725,14 @@ async def name(event): "Cancelled!!", buttons=get_back_button("alvcstm"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - "{} changed to {}\n\nAfter Setting All Things Do restart".format( - name, - themssg, - ), - buttons=get_back_button("alvcstm"), - ) + await setit(event, var, themssg) + await conv.send_message( + "{} changed to {}\n\nAfter Setting All Things Do restart".format( + name, + themssg, + ), + buttons=get_back_button("alvcstm"), + ) @callback("alvmed") @@ -679,7 +744,7 @@ async def media(event): name = "Alive Media" async with event.client.conversation(pru) as conv: await conv.send_message( - "**Alive Media**\nSend me a pic/gif/bot api id of sticker to set as alive media.\n\nUse /cancel to terminate the operation.", + "**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: @@ -694,10 +759,12 @@ async def media(event): media = await event.client.download_media(response, "alvpc") if ( not (response.text).startswith("/") - and not response.text == "" + and response.text != "" and not response.media ): url = response.text + elif response.sticker: + url = response.file.id else: try: x = upl(media) @@ -771,7 +838,7 @@ async def inl_on(event): var = "INLINE_PM" await setit(event, var, "True") await event.edit( - f"Done!! PMPermit type has been set to inline!", + "Done!! PMPermit type has been set to inline!", buttons=[[Button.inline("« Bᴀᴄᴋ", data="pmtype")]], ) @@ -782,7 +849,7 @@ async def inl_on(event): var = "INLINE_PM" await setit(event, var, "False") await event.edit( - f"Done!! PMPermit type has been set to normal!", + "Done!! PMPermit type has been set to normal!", buttons=[[Button.inline("« Bᴀᴄᴋ", data="pmtype")]], ) @@ -806,20 +873,19 @@ async def name(event): "Cancelled!!", buttons=get_back_button("pmcstm"), ) - else: - if len(themssg) > 4090: - return await conv.send_message( - "Message too long!\nGive a shorter message please!!", - buttons=get_back_button("pmcstm"), - ) - await setit(event, var, themssg) - await conv.send_message( - "{} changed to {}\n\nAfter Setting All Things Do restart".format( - name, - themssg, - ), + if len(themssg) > 4090: + return await conv.send_message( + "Message too long!\nGive a shorter message please!!", buttons=get_back_button("pmcstm"), ) + await setit(event, var, themssg) + await conv.send_message( + "{} changed to {}\n\nAfter Setting All Things Do restart".format( + name, + themssg, + ), + buttons=get_back_button("pmcstm"), + ) @callback("swarn") @@ -861,7 +927,7 @@ async def media(event): name = "PM Media" async with event.client.conversation(pru) as conv: await conv.send_message( - "**PM Media**\nSend me a pic/gif/ or link to set as pmpermit media.\n\nUse /cancel to terminate the operation.", + "**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: @@ -876,10 +942,12 @@ async def media(event): media = await event.client.download_media(response, "pmpc") if ( not (response.text).startswith("/") - and not response.text == "" + and response.text != "" and not response.media ): url = response.text + elif response.sticker: + url = response.file.id else: try: x = upl(media) @@ -929,7 +997,7 @@ async def apon(event): var = "AUTOAPPROVE" await setit(event, var, "True") await event.edit( - f"Done!! AUTOAPPROVE Started!!", + "Done!! AUTOAPPROVE Started!!", buttons=[[Button.inline("« Bᴀᴄᴋ", data="apauto")]], ) @@ -953,23 +1021,59 @@ async def apof(event): @callback("pml") @owner async def alvcs(event): + if not udB.get("PMLOG"): + BT = [Button.inline("PMLOGGER ON", data="pmlog")] + else: + BT = [Button.inline("PMLOGGER OFF", data="pmlogof")] await event.edit( "PMLOGGER This Will Forward Ur Pm to Ur Private Group -", buttons=[ - [Button.inline("PMLOGGER ON", data="pmlog")], - [Button.inline("PMLOGGER OFF", data="pmlogof")], + BT, + [Button.inline("PᴍLᴏɢɢᴇʀ Gʀᴏᴜᴘ", "pmlgg")], [Button.inline("« Bᴀᴄᴋ", data="pmcstm")], ], ) +@callback("pmlgg") +@owner +async def disus(event): + await event.delete() + pru = event.sender_id + var = "PMLOGGROUP" + name = "Pm Logger Group" + async with event.client.conversation(pru) as conv: + await conv.send_message( + f"Send The Symbol Which u want as your {name}\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("pml"), + ) + elif len(themssg) > 1: + await conv.send_message( + "Incorrect Value", + buttons=get_back_button("pml"), + ) + else: + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to `{themssg}`", + buttons=get_back_button("pml"), + ) + + @callback("pmlog") @owner async def pmlog(event): var = "PMLOG" await setit(event, var, "True") await event.edit( - f"Done!! PMLOGGER Started!!", + "Done!! PMLOGGER Started!!", buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], ) @@ -1010,7 +1114,7 @@ async def pmonn(event): var = "PMSETTING" await setit(event, var, "True") await event.edit( - f"Done! PMPermit has been turned on!!", + "Done! PMPermit has been turned on!!", buttons=[[Button.inline("« Bᴀᴄᴋ", data="ppmset")]], ) @@ -1021,7 +1125,7 @@ async def pmofff(event): var = "PMSETTING" await setit(event, var, "False") await event.edit( - f"Done! PMPermit has been turned off!!", + "Done! PMPermit has been turned off!!", buttons=[[Button.inline("« Bᴀᴄᴋ", data="ppmset")]], ) @@ -1030,7 +1134,7 @@ async def pmofff(event): @owner async def chbot(event): await event.edit( - f"From This Feature U can chat with ppls Via ur Assistant Bot.\n[More info](https://t.me/UltroidUpdates/2)", + "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")], @@ -1060,15 +1164,14 @@ async def name(event): "Cancelled!!", buttons=get_back_button("chatbot"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - "{} changed to {}".format( - name, - themssg, - ), - buttons=get_back_button("chatbot"), - ) + await setit(event, var, themssg) + await conv.send_message( + "{} changed to {}".format( + name, + themssg, + ), + buttons=get_back_button("chatbot"), + ) @callback("onchbot") @@ -1097,7 +1200,7 @@ async def chon(event): @owner async def vcb(event): await event.edit( - f"From This Feature U can play songs in group voice chat\n\n[moreinfo](https://t.me/UltroidUpdates/4)", + "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="vcs")], [Button.inline("« Bᴀᴄᴋ", data="setter")], @@ -1125,15 +1228,14 @@ async def name(event): "Cancelled!!", buttons=get_back_button("vcb"), ) - else: - await setit(event, var, themssg) - await conv.send_message( - "{} changed to {}\n\nAfter Setting All Things Do restart".format( - name, - themssg, - ), - buttons=get_back_button("vcb"), - ) + await setit(event, var, themssg) + await conv.send_message( + "{} changed to {}\n\nAfter Setting All Things Do restart".format( + name, + themssg, + ), + buttons=get_back_button("vcb"), + ) @callback("inli_pic") @@ -1160,7 +1262,7 @@ async def media(event): media = await event.client.download_media(response, "inlpic") if ( not (response.text).startswith("/") - and not response.text == "" + and response.text != "" and not response.media ): url = response.text diff --git a/assistant/initial.py b/assistant/initial.py new file mode 100644 index 0000000000..186ae48a34 --- /dev/null +++ b/assistant/initial.py @@ -0,0 +1,79 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +import re + +from . import * + +STRINGS = { + 1: """🎇 **Thanks for Deploying Ultroid Userbot!** + +• Here, are the Some Basic stuff from, where you can Know, about its Usage.""", + 2: """🎉** About Ultroid** + +🧿 Ultroid is Pluggable and powerful Telethon Userbot, made in Python from Scratch. It is Aimed to Increase Security along with Addition of Other Useful Features. + +❣ Made by **@TeamUltroid**""", + 3: """**💡• FAQs •** + +-> [Setting up TimeZone](https://t.me/UltroidUpdates/22) +-> [About Inline PmPermit](https://t.me/UltroidUpdates/21) +-> [About Dual Mode](https://t.me/UltroidUpdates/18) +-> [Custom Thumbnail](https://t.me/UltroidUpdates/13) +-> [About FullSudo](https://t.me/UltroidUpdates/11) +-> [Setting Up PmBot](https://t.me/UltroidUpdates/2) +-> [Also Check](https://t.me/UltroidUpdates/14) + +**• To Know About Updates** + - Join @TheUltroid.""", + 4: f"""• `To Know All Available Commands` + + - `{HNDLR}help` + - `{HNDLR}cmds`""", + 5: """• **For Any Other Query or Suggestion** + - Move to **@UltroidSupport**. + +• Thanks for Reaching till END.""", +} + + +@callback(re.compile("initft_(\\d+)")) +async def init_depl(e): + CURRENT = int(e.data_match.group(1)) + if CURRENT == 5: + return await e.edit( + STRINGS[5], + buttons=Button.inline("<< Back", "initbk_" + str(4)), + link_preview=False, + ) + await e.edit( + STRINGS[CURRENT], + buttons=[ + Button.inline("<<", "initbk_" + str(CURRENT - 1)), + Button.inline(">>", "initft_" + str(CURRENT + 1)), + ], + link_preview=False, + ) + + +@callback(re.compile("initbk_(\\d+)")) +async def ineiq(e): + CURRENT = int(e.data_match.group(1)) + if CURRENT == 1: + return await e.edit( + STRINGS[1], + buttons=Button.inline("Start Back >>", "initft_" + str(2)), + link_preview=False, + ) + await e.edit( + STRINGS[CURRENT], + buttons=[ + Button.inline("<<", "initbk_" + str(CURRENT - 1)), + Button.inline(">>", "initft_" + str(CURRENT + 1)), + ], + link_preview=False, + ) diff --git a/assistant/inlinestuff.py b/assistant/inlinestuff.py index 7088780be7..bff8aec1df 100644 --- a/assistant/inlinestuff.py +++ b/assistant/inlinestuff.py @@ -6,13 +6,13 @@ # . import base64 +from datetime import datetime from random import choice from re import compile as re_compile from re import findall import requests -from bs4 import BeautifulSoup -from orangefoxapi import OrangeFoxAPI +from bs4 import BeautifulSoup as bs from play_scraper import search from search_engine_parser import GoogleSearch, YahooSearch from telethon import Button @@ -21,16 +21,12 @@ from plugins._inline import SUP_BUTTONS from . import * -from . import humanbytes as hb ofox = "https://telegra.ph/file/231f0049fcd722824f13b.jpg" gugirl = "https://telegra.ph/file/0df54ae4541abca96aa11.jpg" yeah = "https://telegra.ph/file/e3c67885e16a194937516.jpg" -ps = "https://telegra.ph/file/de0b8d9c858c62fae3b6e.jpg" ultpic = "https://telegra.ph/file/4136aa1650bc9d4109cc5.jpg" -ofox_api = OrangeFoxAPI() - api1 = base64.b64decode("QUl6YVN5QXlEQnNZM1dSdEI1WVBDNmFCX3c4SkF5NlpkWE5jNkZV").decode( "ascii" ) @@ -45,6 +41,7 @@ @in_pattern("ofox") @in_owner async def _(e): + match = None try: match = e.text.split(" ", maxsplit=1)[1] except IndexError: @@ -54,39 +51,43 @@ async def _(e): text="**OFᴏx🦊Rᴇᴄᴏᴠᴇʀʏ**\n\nYou didn't search anything", buttons=Button.switch_inline("Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="ofox ", same_peer=True), ) - await e.answer([kkkk]) - a = ofox_api.releases(codename=match) - c = ofox_api.devices(codename=match) - if len(a.data) > 0: + return await e.answer([kkkk]) + device, releases = await get_ofox(match) + if device.get("detail") is None: fox = [] - for b in a.data: - ver = b.version - release = b.type - size = hb(b.size) - for z in c.data: - fullname = z.full_name - code = z.codename - link = f"https://orangefox.download/device/{code}" - text = f"**••OʀᴀɴɢᴇFᴏx Rᴇᴄᴏᴠᴇʀʏ Fᴏʀ•[•]({ofox})** {fullname}\n" - text += f"**••Cᴏᴅᴇɴᴀᴍᴇ••** {code}\n" - text += f"**••Bᴜɪʟᴅ Tʏᴘᴇ••** {release}\n" - text += f"**••Vᴇʀsɪᴏɴ••** {ver}\n" - text += f"**••Sɪᴢᴇ••** {size}\n" - fox.append( - await e.builder.article( - title=f"{fullname}", - description=f"{ver}\n{release}", - text=text, - thumb=wb(ofox, 0, "image/jpeg", []), - link_preview=True, - buttons=[ - Button.url("Dᴏᴡɴʟᴏᴀᴅ", url=f"{link}"), - Button.switch_inline( - "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="ofox ", same_peer=True - ), - ], - ) + fullname = device["full_name"] + codename = device["codename"] + str(device["supported"]) + maintainer = device["maintainer"]["name"] + link = f"https://orangefox.download/device/{codename}" + for data in releases["data"]: + release = data["type"] + version = data["version"] + size = humanbytes(data["size"]) + release_date = datetime.utcfromtimestamp(data["date"]).strftime("%Y-%m-%d") + text = f"[\xad]({ofox})**OʀᴀɴɢᴇFᴏx Rᴇᴄᴏᴠᴇʀʏ Fᴏʀ**\n\n" + text += f"` Fᴜʟʟ Nᴀᴍᴇ: {fullname}`\n" + text += f"` Cᴏᴅᴇɴᴀᴍᴇ: {codename}`\n" + text += f"` Mᴀɪɴᴛᴀɪɴᴇʀ: {maintainer}`\n" + text += f"` Bᴜɪʟᴅ Tʏᴘᴇ: {release}`\n" + text += f"` Vᴇʀsɪᴏɴ: {version}`\n" + text += f"` Sɪᴢᴇ: {size}`\n" + text += f"` Bᴜɪʟᴅ Dᴀᴛᴇ: {release_date}`" + fox.append( + await e.builder.article( + title=f"{fullname}", + description=f"{version}\n{release_date}", + text=text, + thumb=wb(ofox, 0, "image/jpeg", []), + link_preview=True, + buttons=[ + Button.url("Dᴏᴡɴʟᴏᴀᴅ", url=f"{link}"), + Button.switch_inline( + "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="ofox ", same_peer=True + ), + ], ) + ) await e.answer( fox, switch_pm="OrangeFox Recovery Search.", switch_pm_param="start" ) @@ -301,7 +302,7 @@ async def _(e): await e.builder.article( title=name, description=ids, - thumb=wb(ps, 0, "image/jpeg", []), + thumb=wb(icon, 0, "image/jpeg", []), text=text, link_preview=True, buttons=[ @@ -373,60 +374,39 @@ async def _(e): await e.answer(modss, switch_pm="Search Mod Applications.", switch_pm_param="start") -@in_pattern("ebooks") +# Inspired by @FindXDaBot + + +@in_pattern("xda") @in_owner -async def clip(e): +async def xda_dev(event): + QUERY = event.text.split(" ", maxsplit=1) try: - quer = e.text.split(" ", maxsplit=1)[1] + query = QUERY[1] except IndexError: - await e.answer( - [], switch_pm="Enter Query to Look for EBook", switch_pm_param="start" - ) - return - quer = quer.replace(" ", "+") - sear = f"http://www.gutenberg.org/ebooks/search/?query={quer}&submit_search=Go%21" - magma = requests.get(sear).content - bs = BeautifulSoup(magma, "html.parser", from_encoding="utf-8") - out = bs.find_all("img") - Alink = bs.find_all("a", "link") - if len(out) == 0: - return await e.answer( - [], switch_pm="No Results Found !", switch_pm_param="start" + return await event.answer( + [], switch_pm="Enter Query to Search", switch_pm_param="start" ) - buil = e.builder - dont_take = [ - "Authors", - "Did you mean", - "Sort Alpha", - "Sort by", - "Subjects", - "Bookshelves", - ] - hm = [] - titles = [] - for num in Alink: - try: - rt = num.find("span", "title").text - if not rt.startswith(tuple(dont_take)): - titles.append(rt) - except BaseException: - pass - for rs in range(len(out)): - if "/cache/epub" in out[rs]["src"]: - link = out[rs]["src"] - num = link.split("/")[3] - link = "https://gutenberg.org" + link.replace("small", "medium") - file = wb(link, 0, "image/jpeg", []) - hm.append( - buil.article( - title=titles[rs], - type="photo", - description="GutenBerg Search", - thumb=file, - content=file, - include_media=True, - text=f"**• Ebook Search**\n\n->> `{titles[rs]}`", - buttons=Button.inline("Get as Doc", data=f"ebk_{num}"), - ) + le = "https://www.xda-developers.com/search/" + query.replace(" ", "+") + ct = requests.get(le).content + ml = bs(ct, "html.parser", from_encoding="utf-8") + ml = ml.find_all("div", re_compile("layout_post_"), id=re_compile("post-")) + out = [] + builder = event.builder + for on in ml: + data = on.find_all("img", "xda_image")[0] + title = data["alt"] + thumb = data["src"] + hre = on.find_all("div", "item_content")[0].find("h4").find("a")["href"] + desc = on.find_all("div", "item_meta clearfix")[0].text + thumb = wb(thumb, 0, "image/jpeg", []) + text = f"[{title}]({hre})" + out.append( + await builder.article( + title=title, description=desc, url=hre, thumb=thumb, text=text ) - await e.answer(hm, switch_pm="Ebooks Search", switch_pm_param="start") + ) + uppar = "|| XDA Search Results ||" + if len(out) == 0: + uppar = "No Results Found :(" + await event.answer(out, switch_pm=uppar, switch_pm_param="start") diff --git a/assistant/manager/__init__.py b/assistant/manager/__init__.py index fc68000831..33d345d698 100644 --- a/assistant/manager/__init__.py +++ b/assistant/manager/__init__.py @@ -7,5 +7,3 @@ from plugins import * - -asst = asst diff --git a/assistant/manager/_help.py b/assistant/manager/_help.py new file mode 100644 index 0000000000..3aa06c0c77 --- /dev/null +++ b/assistant/manager/_help.py @@ -0,0 +1,130 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import * + +START = """ +🪅 **Help Menu** 🪅 + +✘ /start : Check I am Alive or not. +✘ /help : Get This Message. +✘ /repo : Get Bot's Repo.. + +🧑‍💻 Join **@TheUltroid** +""" + +ADMINTOOLS = """✘ **AdminTools** ✘ + +• /pin : Pins the Replied Message +• /pinned : Get Pinned message in chat. +• /unpin : Unpin the Replied message +• /unpin all : Unpin all Pinned Messages. + +• /ban (username/id/reply) : Ban the User +• /unban (username/id/reply) : UnBan the User. + +• /mute (username/id/reply) : Mute the User. +• /unmute (username/id/reply) : Unmute the User. + +• /tban (username/id/reply) (time) : Temporary ban a user +• /tmute (username/id/reply) (time) : temporary Mutes a User. + +• /purge (purge messages) + +• /setgpic (reply photo) : keep Chat Photo of Group. +• /delgpic : remove current chat Photo.""" + +UTILITIES = """ +✘ ** Utilities ** ✘ + +• /info (reply/username/id) : get detailed info of user. +• /id : get chat/user id. +• /tr : Translate Languages.. + +• /paste (reply file/text) : paste content on Spaceb.in +• /meaning (text) : Get Meaning of that Word. +• /google (query) : Search Something on Google.. + +• /suggest (query/reply) : Creates a Yes / No Poll. +""" + +LOCKS = """ +✘ ** Locks ** ✘ + +• /lock (query) : lock particular content in chat. +• /unlock (query) : Unlock some content. + +• All Queries +- `msgs` : for messages. +- `inlines` : for inline queries. +- `media` : for all medias. +- `games` : for games. +- `sticker` : for stickers. +- `polls` : for polls. +- `gif` : for gifs. +- `pin` : for pins. +- `changeinfo` : for change info right. +""" + +MISC = """ +✘ **Misc** ✘ + +• /joke : Get Random Jokes. +""" + +STRINGS = {"Admintools": ADMINTOOLS, "locks": LOCKS, "Utils": UTILITIES, "Misc": MISC} + +MNGE = udB.get("MNGR_EMOJI") or "•" + + +def get_buttons(): + BTTS = [] + keys = STRINGS.copy() + while keys: + BT = [] + for i in list(keys)[:2]: + text = MNGE + " " + i + " " + MNGE + BT.append(Button.inline(text, "hlp_" + i)) + del keys[i] + BTTS.append(BT) + url = "https://t.me/" + asst.me.username + "?startgroup=true" + BTTS.append([Button.url("Add me to Group", url)]) + return BTTS + + +@asst_cmd("help") +async def helpish(event): + if not event.is_private: + url = "https://t.me/" + asst.me.username + "?start=start" + return await event.reply( + "Contact me in PM for help!", buttons=Button.url("Click me for Help", url) + ) + if str(event.sender_id) in owner_and_sudos() and ( + udB.get("DUAL_MODE") and (udB.get("DUAL_HNDLR") == "/") + ): + return + BTTS = get_buttons() + await event.reply(START, buttons=BTTS) + + +@callback("mngbtn") +@owner +async def ehwhshd(e): + buttons = get_buttons() + buttons[-1].append(Button.inline("<< Back", "open")) + await e.edit(buttons=buttons) + + +@callback("mnghome") +async def home_aja(e): + await e.edit(START, buttons=get_buttons()) + + +@callback(re.compile("hlp_(.*)")) +async def do_something(event): + match = event.pattern_match.group(1).decode("utf-8") + await event.edit(STRINGS[match], buttons=Button.inline("<< Back", "mnghome")) diff --git a/assistant/manager/_on_adds.py b/assistant/manager/_on_adds.py new file mode 100644 index 0000000000..8c2aefd8f3 --- /dev/null +++ b/assistant/manager/_on_adds.py @@ -0,0 +1,23 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import * + + +@asst.on(events.ChatAction()) +async def dueha(e): + if not e.user_added: + return + user = await e.get_user() + if not user.is_self: + return + sm = udB.get("ON_MNGR_ADD") + if sm == "OFF": + return + if not sm: + sm = "Thanks for Adding me :)" + await e.reply(sm, link_preview=False) diff --git a/assistant/manager/admins.py b/assistant/manager/admins.py new file mode 100644 index 0000000000..35b9245186 --- /dev/null +++ b/assistant/manager/admins.py @@ -0,0 +1,38 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from . import * + + +@ultroid_cmd(pattern="dkick", type=["manager", "official"]) +async def dowj(e): + replied = await e.get_reply_message() + if replied: + user = replied.sender_id + else: + return await eor(e, "Reply to a message...") + try: + await replied.delete() + await e.client.kick_participant(e.chat_id, user) + await eor(e, "Kicked Successfully!") + except Exception as E: + await eor(e, str(E)) + + +@ultroid_cmd(pattern="dban", type=["manager", "official"]) +async def dowj(e): + replied = await e.get_reply_message() + if replied: + user = replied.sender_id + else: + return await eor(e, "Reply to a message...") + try: + await replied.delete() + await e.client.edit_permissions(e.chat_id, user, view_messages=False) + await eor(e, "Banned Successfully!") + except Exception as E: + await eor(e, str(E)) diff --git a/assistant/manager/misc.py b/assistant/manager/misc.py new file mode 100644 index 0000000000..7e1e975705 --- /dev/null +++ b/assistant/manager/misc.py @@ -0,0 +1,46 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + +import aiohttp + +from . import * + + +@ultroid_cmd(pattern="echo ?(.*)", type=["manager"]) +async def oqha(e): + match = e.pattern_match.group(1) + if match: + text = match + reply_to = e + elif e.is_reply: + text = (await e.get_reply_message()).text + reply_to = e.reply_to_msg_id + else: + return await eor(e, "What to Echo?", time=5) + await e.client.send_message(e.chat_id, text, reply_to=reply_to) + + +@ultroid_cmd(pattern="kickme$", type=["manager"], allow_all=True) +async def doit(e): + if e.sender_id in DEVLIST: + return await eod(e, "`I will Not Kick You, my Developer..`") + try: + await e.client.kick_participant(e.chat_id, e.sender_id) + except Exception as Fe: + return await eor(e, str(Fe), time=5) + await eor(e, "Yes, You are right, get out.", time=5) + + +@ultroid_cmd(pattern="joke$", type=["manager"]) +async def do_joke(e): + e = await e.get_reply_message() if e.is_reply else e + link = "https://v2.jokeapi.dev/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&type=single" + async with aiohttp.ClientSession() as ses: + async with ses.get(link) as out: + out = await out.json() + await e.reply(out["joke"]) diff --git a/assistant/ping.py b/assistant/ping.py index 1c75b1b5c3..74b527456b 100644 --- a/assistant/ping.py +++ b/assistant/ping.py @@ -12,9 +12,7 @@ @owner async def _(event): start = datetime.now() + msg = await event.reply("Pong!") end = datetime.now() ms = (end - start).microseconds / 1000 - await asst.send_message( - event.chat_id, - f"**Pong!!**\n `{ms} milliseconds`", - ) + await msg.edit(f"**Pong!!**\n `{ms} ms`") diff --git a/assistant/piston.py b/assistant/piston.py new file mode 100644 index 0000000000..019361e0d9 --- /dev/null +++ b/assistant/piston.py @@ -0,0 +1,45 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +from pistonapi import PistonAPI + +from . import * + + +@in_pattern("run") +async def piston_run(event): + piston = PistonAPI() + version = None + try: + lang = event.text.split()[1] + code = event.text.split(maxsplit=2)[2] + except IndexError: + result = await event.builder.article( + title="Bad Query", + description="Usage: [Language] [code]", + text=f'**Inline Usage**\n\n`@{asst.me.username} run python print("hello world")`\n\n[Language List](https://telegra.ph/Ultroid-09-01-6)', + ) + return await event.answer([result]) + if lang in piston.languages.keys(): + version = piston.languages[lang]["version"] + if not version: + result = await event.builder.article( + title="Unsupported Language", + description="Usage: [Language] [code]", + text=f'**Inline Usage**\n\n`@{asst.me.username} run python print("hello world")`\n\n[Language List](https://telegra.ph/Ultroid-09-01-6)', + ) + return await event.answer([result]) + output = piston.execute(language=lang, version=version, code=code) or "Success" + if len(output) > 3000: + output = output[:3000] + "..." + result = await event.builder.article( + title="Result", + description=output, + text=f"• **Language:**\n`{lang}`\n\n• **Code:**\n`{code}`\n\n• **Result:**\n`{output}`", + buttons=Button.switch_inline("Fork", query=event.text, same_peer=True), + ) + await event.answer([result], switch_pm="• Piston •", switch_pm_param="start") diff --git a/assistant/pmbot/banuser.py b/assistant/pmbot/banuser.py index 987d2928a2..ca1b02230c 100644 --- a/assistant/pmbot/banuser.py +++ b/assistant/pmbot/banuser.py @@ -17,15 +17,15 @@ async def banhammer(event): if x is None: return await event.edit("Please reply to someone to ban him.") target = get_who(x.id) - if not is_blacklisted(target): - blacklist_user(target) - await asst.send_message(event.chat_id, f"#BAN\nUser - {target}") - await asst.send_message( - target, - "`GoodBye! You have been banned.`\n**Further messages you send will not be forwarded.**", - ) - else: - return await asst.send_message(event.chat_id, f"User is already banned!") + if is_blacklisted(target): + return await asst.send_message(event.chat_id, "User is already banned!") + + blacklist_user(target) + await asst.send_message(event.chat_id, f"#BAN\nUser - {target}") + await asst.send_message( + target, + "`GoodBye! You have been banned.`\n**Further messages you send will not be forwarded.**", + ) @asst_cmd("unban") @@ -37,9 +37,9 @@ async def banhammer(event): if x is None: return await event.edit("Please reply to someone to ban him.") target = get_who(x.id) - if is_blacklisted(target): - rem_blacklist(target) - await asst.send_message(event.chat_id, f"#UNBAN\nUser - {target}") - await asst.send_message(target, "`Congrats! You have been unbanned.`") - else: - return await asst.send_message(event.chat_id, f"User was never banned!") + if not is_blacklisted(target): + return await asst.send_message(event.chat_id, "User was never banned!") + + rem_blacklist(target) + await asst.send_message(event.chat_id, f"#UNBAN\nUser - {target}") + await asst.send_message(target, "`Congrats! You have been unbanned.`") diff --git a/assistant/pmbot/incoming.py b/assistant/pmbot/incoming.py index 157a3163ee..aab122ab04 100644 --- a/assistant/pmbot/incoming.py +++ b/assistant/pmbot/incoming.py @@ -19,15 +19,11 @@ @asst.on(events.NewMessage(incoming=True, func=lambda e: e.is_private)) async def on_new_mssg(event): - incoming = event.raw_text who = event.sender_id if is_blacklisted(who): return # doesn't reply to that user anymore - if incoming.startswith("/"): - pass - elif who == OWNER_ID: + if event.text.startswith("/") or who == OWNER_ID: return - else: - xx = await event.forward_to(OWNER_ID) - add_stuff(xx.id, who) + xx = await event.forward_to(OWNER_ID) + add_stuff(xx.id, who) diff --git a/assistant/pmbot/outgoing.py b/assistant/pmbot/outgoing.py index 0a28b7b425..5bd25553ef 100644 --- a/assistant/pmbot/outgoing.py +++ b/assistant/pmbot/outgoing.py @@ -17,23 +17,18 @@ @asst.on(events.NewMessage(incoming=True, func=lambda e: e.is_private)) async def on_out_mssg(event): x = await event.get_reply_message() - if x is None: + if not x: return who = event.sender_id if who == OWNER_ID: to_user = get_who(x.id) if event.text.startswith("/who"): try: - k = await asst.get_entity(int(to_user)) + k = await asst.get_entity(to_user) return await event.reply(f"[{k.first_name}](tg://user?id={k.id})") except BaseException: return elif event.text.startswith("/"): return - if event.media: - if event.text: - await asst.send_file(int(to_user), event.media, caption=event.text) - else: - await asst.send_file(int(to_user), event.media) - else: - await asst.send_message(int(to_user), event.text) + if to_user: + await asst.send_message(to_user, event.message) diff --git a/assistant/start.py b/assistant/start.py index c02b6ac1eb..a95e748c03 100644 --- a/assistant/start.py +++ b/assistant/start.py @@ -19,11 +19,11 @@ Owner_info_msg = f""" Owner - {OWNER_NAME} -OwnerID - {OWNER_ID} +OwnerID - {OWNER_ID} Message Forwards - {udB.get("PMBOT")} -Ultroid [v{ultroid_version}], powered by @TeamUltroid +Ultroid [v{ultroid_version}], powered by @TeamUltroid """ _settings = [ @@ -35,8 +35,10 @@ Button.inline("Aʟɪᴠᴇ", data="alvcstm"), Button.inline("PᴍPᴇʀᴍɪᴛ", data="ppmset"), ], - [Button.inline("Fᴇᴀᴛᴜʀᴇs", data="otvars")], - [Button.inline("VC Sᴏɴɢ Bᴏᴛ", data="vcb")], + [ + Button.inline("Fᴇᴀᴛᴜʀᴇs", data="otvars"), + Button.inline("VC Sᴏɴɢ Bᴏᴛ", data="vcb"), + ], [Button.inline("« Bᴀᴄᴋ", data="mainmenu")], ] @@ -57,7 +59,7 @@ async def own(event): await event.edit( Owner_info_msg, - buttons=[Button.inline("Close", data=f"closeit")], + buttons=[Button.inline("Close", data="closeit")], link_preview=False, parse_mode="html", ) @@ -72,41 +74,37 @@ async def closet(lol): async def ultroid(event): if event.is_group: return + if not is_added(event.sender_id) and str(event.sender_id) not in owner_and_sudos(): + add_user(event.sender_id) + if str(event.sender_id) not in owner_and_sudos(): + ok = "" + u = await event.client.get_entity(event.chat_id) + if not udB.get("STARTMSG"): + if udB.get("PMBOT") == "True": + ok = "You can contact my master using this bot!!\n\nSend your Message, I will Deliver it To Master." + await event.reply( + f"Hey there [{get_display_name(u)}](tg://user?id={u.id}), this is Ultroid Assistant of [{ultroid_bot.me.first_name}](tg://user?id={ultroid_bot.uid})!\n\n{ok}", + buttons=[Button.inline("Info.", data="ownerinfo")], + ) + else: + me = f"[{ultroid_bot.me.first_name}](tg://user?id={ultroid_bot.uid})" + mention = f"[{get_display_name(u)}](tg://user?id={u.id})" + await event.reply( + Redis("STARTMSG").format(me=me, mention=mention), + buttons=[Button.inline("Info.", data="ownerinfo")], + ) else: - if ( - not is_added(event.sender_id) - and str(event.sender_id) not in owner_and_sudos() - ): - add_user(event.sender_id) - if str(event.sender_id) not in owner_and_sudos(): - ok = "" - u = await event.client.get_entity(event.chat_id) - if not udB.get("STARTMSG"): - if udB.get("PMBOT") == "True": - ok = "You can contact my master using this bot!!\n\nSend your Message, I will Deliver it To Master." - await event.reply( - f"Hey there [{get_display_name(u)}](tg://user?id={u.id}), this is Ultroid Assistant of [{ultroid_bot.me.first_name}](tg://user?id={ultroid_bot.uid})!\n\n{ok}", - buttons=[Button.inline("Info.", data="ownerinfo")], - ) - else: - me = f"[{ultroid_bot.me.first_name}](tg://user?id={ultroid_bot.uid})" - mention = f"[{get_display_name(u)}](tg://user?id={u.id})" - await event.reply( - Redis("STARTMSG").format(me=me, mention=mention), - buttons=[Button.inline("Info.", data="ownerinfo")], - ) + name = get_display_name(event.sender_id) + if event.pattern_match.group(1) == "set": + await event.reply( + "Choose from the below options -", + buttons=_settings, + ) else: - name = get_display_name(event.sender_id) - if event.pattern_match.group(1) == "set": - await event.reply( - "Choose from the below options -", - buttons=_settings, - ) - else: - await event.reply( - get_string("ast_3").format(name), - buttons=_start, - ) + await event.reply( + get_string("ast_3").format(name), + buttons=_start, + ) @callback("mainmenu") @@ -145,26 +143,25 @@ async def bdcast(event): themssg = response.message.message if themssg == "/cancel": return await conv.send_message("Cancelled!!") - else: - success = 0 - fail = 0 - await conv.send_message(f"Starting a broadcast to {len(ok)} users...") - start = datetime.now() - for i in ok: - try: - await asst.send_message(int(i), f"{themssg}") - success += 1 - except BaseException: - fail += 1 - end = datetime.now() - time_taken = (end - start).seconds - await conv.send_message( - f""" + success = 0 + fail = 0 + await conv.send_message(f"Starting a broadcast to {len(ok)} users...") + start = datetime.now() + for i in ok: + try: + await asst.send_message(int(i), f"{themssg}") + success += 1 + except BaseException: + fail += 1 + end = datetime.now() + time_taken = (end - start).seconds + await conv.send_message( + f""" Broadcast completed in {time_taken} seconds. Total Users in Bot - {len(ok)} Sent to {success} users. Failed for {fail} user(s).""", - ) + ) @callback("setter") @@ -195,16 +192,15 @@ async def timezone_(event): "Cancelled!!", buttons=get_back_button("mainmenu"), ) - else: - try: - tz(themssg) - await setit(event, var, themssg) - await conv.send_message( - f"{name} changed to {themssg}\n", - buttons=get_back_button("mainmenu"), - ) - except BaseException: - await conv.send_message( - "Wrong TimeZone, Try again", - buttons=get_back_button("mainmenu"), - ) + try: + tz(themssg) + await setit(event, var, themssg) + await conv.send_message( + f"{name} changed to {themssg}\n", + buttons=get_back_button("mainmenu"), + ) + except BaseException: + await conv.send_message( + "Wrong TimeZone, Try again", + buttons=get_back_button("mainmenu"), + ) diff --git a/assistant/ytdl.py b/assistant/ytdl.py index 2f90b70512..0047dd79b6 100644 --- a/assistant/ytdl.py +++ b/assistant/ytdl.py @@ -9,14 +9,12 @@ import os import re import time -from urllib.request import urlretrieve from numerize import numerize from pyUltroid.functions.all import * from telethon import Button from telethon.tl.types import DocumentAttributeAudio, DocumentAttributeVideo from telethon.tl.types import InputWebDocument as wb -from youtube_dl import YoutubeDL from youtubesearchpython import VideosSearch ytt = "https://telegra.ph/file/afd04510c13914a06dd03.jpg" @@ -24,6 +22,7 @@ @in_pattern("yt") +@in_owner async def _(event): try: string = event.text.split(" ", maxsplit=1)[1] @@ -128,12 +127,18 @@ async def _(event): "quiet": True, "logtostderr": False, } - ytdl_data = await dler(event, link) - YoutubeDL(opts).download([link]) + ytdl_data = await dler(event, link, opts, True) title = ytdl_data["title"] - artist = ytdl_data["uploader"] + if ytdl_data.get("artist"): + artist = ytdl_data["artist"] + elif ytdl_data.get("creator"): + artist = ytdl_data["creator"] + elif ytdl_data.get("channel"): + artist = ytdl_data["channel"] views = numerize.numerize(ytdl_data["view_count"]) - urlretrieve(f"https://i.ytimg.com/vi/{vid_id}/hqdefault.jpg", f"{title}.jpg") + await download_file( + f"https://i.ytimg.com/vi/{vid_id}/hqdefault.jpg", f"{title}.jpg" + ) thumb = f"{title}.jpg" duration = ytdl_data["duration"] os.rename(f"{ytdl_data['id']}.mp3", f"{title}.mp3") @@ -159,13 +164,19 @@ async def _(event): "logtostderr": False, "quiet": True, } - ytdl_data = await dler(event, link) - YoutubeDL(opts).download([link]) + ytdl_data = await dler(event, link, opts, True) title = ytdl_data["title"] - artist = ytdl_data["uploader"] + if ytdl_data.get("artist"): + artist = ytdl_data["artist"] + elif ytdl_data.get("creator"): + artist = ytdl_data["creator"] + elif ytdl_data.get("channel"): + artist = ytdl_data["channel"] views = numerize.numerize(ytdl_data["view_count"]) - urlretrieve(f"https://i.ytimg.com/vi/{vid_id}/hqdefault.jpg", f"{title}.jpg") - thumb = f"{title}.jpg" + thumb = await fast_download( + f"https://i.ytimg.com/vi/{vid_id}/hqdefault.jpg", filename=f"{title}.jpg" + ) + hi, wi = ytdl_data["height"], ytdl_data["width"] duration = ytdl_data["duration"] try: os.rename(f"{ytdl_data['id']}.mp4", f"{title}.mp4") @@ -173,11 +184,9 @@ async def _(event): try: os.rename(f"{ytdl_data['id']}.mkv", f"{title}.mp4") except FileNotFoundError: - os.rename(f"{ytdl_data['id']}.webm", f"{title}.mp4") + os.rename(f"{ytdl_data['id']}.mp4.webm", f"{title}.mp4") except Exception as ex: return await event.edit(str(ex)) - wi, _ = await bash(f'mediainfo "{title}.mp4" | grep "Width"') - hi, _ = await bash(f'mediainfo "{title}.mp4" | grep "Height"') c_time = time.time() file = await uploader( f"{title}.mp4", f"{title}.mp4", c_time, event, "Uploading " + title + "..." @@ -185,8 +194,8 @@ async def _(event): attributes = [ DocumentAttributeVideo( duration=int(duration), - w=int(wi.split(":")[1].split()[0]), - h=int(hi.split(":")[1].split()[0]), + w=wi, + h=hi, supports_streaming=True, ), ] @@ -201,4 +210,4 @@ async def _(event): attributes=attributes, thumb=thumb, ) - os.system(f'rm "{title}"*') + await bash(f'rm "{title}"*') diff --git a/plugins/_ChatActions.py b/plugins/_ChatActions.py index eabeac3bad..17e89c3f37 100644 --- a/plugins/_ChatActions.py +++ b/plugins/_ChatActions.py @@ -1,9 +1,18 @@ +# Ultroid - UserBot +# Copyright (C) 2021 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + + from pyUltroid.functions.all import get_chatbot_reply from pyUltroid.functions.chatBot_db import chatbot_stats from pyUltroid.functions.clean_db import * from pyUltroid.functions.forcesub_db import * from pyUltroid.functions.gban_mute_db import * from pyUltroid.functions.greetings_db import * +from pyUltroid.functions.username_db import * from telethon.errors.rpcerrorlist import UserNotParticipantError from telethon.tl.functions.channels import GetParticipantRequest from telethon.utils import get_display_name @@ -48,21 +57,20 @@ async def ChatActionsHandler(ult): # sourcery no-metrics await res[0].click(ult.chat_id, reply_to=ult.action_message.id) # gban checks - if ult.user_joined and ult.added_by: + if ult.user_joined or ult.added_by: user = await ult.get_user() chat = await ult.get_chat() - if is_gbanned(str(user.id)) and chat.admin_rights: + reason = is_gbanned(user.id) + if reason and chat.admin_rights: try: await ultroid_bot.edit_permissions( chat.id, user.id, view_messages=False, ) - reason = get_gban_reason(user.id) gban_watch = f"#GBanned_User Joined.\n\n**User** - [{user.first_name}](tg://user?id={user.id})\n" - if reason is not None: - gban_watch += f"**Reason**: {reason}\n\n" - gban_watch += f"`User Banned.`" + gban_watch += f"**Reason**: {reason}\n\n" + gban_watch += "`User Banned.`" await ult.reply(gban_watch) except BaseException: pass @@ -80,6 +88,7 @@ async def ChatActionsHandler(ult): # sourcery no-metrics fullname = f"{name} {last}" if last else name uu = user.username username = f"@{uu}" if uu else mention + wel = get_welcome(ult.chat_id) msgg = wel["welcome"] med = wel["media"] userid = user.id @@ -98,7 +107,7 @@ async def ChatActionsHandler(ult): # sourcery no-metrics ) await asyncio.sleep(150) await send.delete() - elif not is_gbanned(str(user.id)): + elif not is_gbanned(user.id): await ult.reply(file=med) if (ult.user_left or ult.user_kicked) and get_goodbye(ult.chat_id): user = await ult.get_user() @@ -112,6 +121,7 @@ async def ChatActionsHandler(ult): # sourcery no-metrics fullname = f"{name} {last}" if last else name uu = user.username username = f"@{uu}" if uu else mention + wel = get_goodbye(ult.chat_id) msgg = wel["goodbye"] med = wel["media"] userid = user.id @@ -135,8 +145,47 @@ async def ChatActionsHandler(ult): # sourcery no-metrics @ultroid_bot.on(events.NewMessage(incoming=True)) -async def chatBot_replies(event): - if event.sender_id and chatbot_stats(event.chat_id, event.sender_id) and not event.media: - msg = get_chatbot_reply(event, event.text) +async def chatBot_replies(e): + sender = await e.get_sender() + if not isinstance(sender, types.User): + return + if e.text and chatbot_stats(e.chat_id, e.sender_id): + msg = get_chatbot_reply(e, e.message.message) if msg: - await event.reply(msg) + await e.reply(msg) + chat = await e.get_chat() + if e.is_group and not sender.bot: + if sender.username: + await uname_stuff(e.sender_id, sender.username, sender.first_name) + elif e.is_private and not sender.bot: + if chat.username: + await uname_stuff(e.sender_id, chat.username, chat.first_name) + + +@ultroid_bot.on(events.Raw(types.UpdateUserName)) +async def uname_change(e): + await uname_stuff(e.user_id, e.username, e.first_name) + + +async def uname_stuff(id, uname, name): + if udB.get("USERNAME_LOG") == "True": + old = get_username(id) + # Ignore Name Logs + if old and old == uname: + return + if old and uname: + await asst.send_message( + LOG_CHANNEL, + f"∆ #UsernameUpdate\n\n@{old} changed username to @{uname}", + ) + elif old and not uname: + await asst.send_message( + LOG_CHANNEL, + f"∆ #UsernameUpdate\n\n[{name}](tg://user?id={id}) removed its username. (@{old})", + ) + elif not old and uname: + await asst.send_message( + LOG_CHANNEL, + f"∆ #UsernameUpdate\n\n[{name}](tg://user?id={id})'s new username --> @{uname}", + ) + update_username(id, uname) diff --git a/plugins/__init__.py b/plugins/__init__.py index 0a68f2cc98..3bb9fbe8d8 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -6,6 +6,7 @@ # . import asyncio +import os import time from pyUltroid import * @@ -15,6 +16,7 @@ from pyUltroid.version import ultroid_version from telethon import Button from telethon.tl import functions, types +from telethon.utils import get_display_name from strings import get_string @@ -30,16 +32,22 @@ OWNER_NAME = ultroid_bot.me.first_name OWNER_ID = ultroid_bot.me.id +LOG_CHANNEL = int(udB.get("LOG_CHANNEL")) List = [] Dict = {} N = 0 +# Chats, which needs to be ignore for some cases +# Considerably, there can be many +# Feel Free to Add Any other... + NOSPAM_CHAT = [ - -1001387666944, # @PyrogramChat - -1001109500936, # @TelethonChat - -1001050982793, # @Python - -1001256902287, # @DurovsChat + -1001327032795, # UltroidSupport + -1001387666944, # PyrogramChat + -1001109500936, # TelethonChat + -1001050982793, # Python + -1001256902287, # DurovsChat ] KANGING_STR = [ diff --git a/plugins/_help.py b/plugins/_help.py index d2f300718f..bebbe1988e 100644 --- a/plugins/_help.py +++ b/plugins/_help.py @@ -12,6 +12,25 @@ from . import * +C_PIC = udB.get("INLINE_PIC") +_file_to_replace = C_PIC or "resources/extras/inline.jpg" + +_main_help_menu = [ + [ + Button.inline("• Plugins", data="hrrrr"), + Button.inline("• Addons", data="frrr"), + ], + [ + Button.inline("••Voice Chat", data="vc_helper"), + Button.inline("Inline Plugins••", data="inlone"), + ], + [ + Button.inline("⚙️ Owner Tools", data="ownr"), + Button.url("Settings ⚙️", url=f"https://t.me/{asst.me.username}?start=set"), + ], + [Button.inline("••Cʟᴏꜱᴇ••", data="close")], +] + @ultroid_cmd(pattern="help ?(.*)") async def _help(ult): @@ -37,7 +56,7 @@ async def _help(ult): x += "\n© @TeamUltroid" await eor(ult, x) except BaseException: - await eod(ult, get_string("help_1").format(plug), time=5) + await eor(ult, get_string("help_1").format(plug), time=5) except BaseException: await eor(ult, "Error 🤔 occured.") else: @@ -50,30 +69,17 @@ async def _help(ult): for y in x: z.append(y) cmd = len(z) + 10 - return await ult.client.send_message( - ult.chat_id, + if udB.get("MANAGER") and udB.get("DUAL_HNDLR") == "/": + _main_help_menu[2:3] = [[Button.inline("• Manager Help •", "mngbtn")]] + return await ult.reply( get_string("inline_4").format( OWNER_NAME, len(PLUGINS) - 5, len(ADDONS), cmd, ), - buttons=[ - [ - Button.inline("• Pʟᴜɢɪɴs", data="hrrrr"), - Button.inline("• Aᴅᴅᴏɴs", data="frrr"), - ], - [ - Button.inline("Oᴡɴᴇʀ•ᴛᴏᴏʟꜱ", data="ownr"), - Button.inline("Iɴʟɪɴᴇ•Pʟᴜɢɪɴs", data="inlone"), - ], - [ - Button.url( - "⚙️Sᴇᴛᴛɪɴɢs⚙️", url=f"https://t.me/{tgbot}?start=set" - ), - ], - [Button.inline("••Cʟᴏꜱᴇ••", data="close")], - ], + file=_file_to_replace, + buttons=_main_help_menu, ) except rep: return await eor( diff --git a/plugins/_inline.py b/plugins/_inline.py index 46bc9ff3af..768695e912 100644 --- a/plugins/_inline.py +++ b/plugins/_inline.py @@ -18,6 +18,7 @@ from telethon.tl.types import InputBotInlineResult, InputWebDocument from . import * +from ._help import _main_help_menu # ================================================# notmine = f"This bot is for {OWNER_NAME}" @@ -38,32 +39,18 @@ TLINK = C_PIC else: _file_to_replace = "resources/extras/inline.jpg" + +upage = 0 # ============================================# # --------------------BUTTONS--------------------# -_main_help_menu = [ - [ - Button.inline("• Pʟᴜɢɪɴs", data="hrrrr"), - Button.inline("• Aᴅᴅᴏɴs", data="frrr"), - ], - [ - Button.inline("Oᴡɴᴇʀ•ᴛᴏᴏʟꜱ", data="ownr"), - Button.inline("Iɴʟɪɴᴇ•Pʟᴜɢɪɴs", data="inlone"), - ], - [ - Button.url("⚙️Sᴇᴛᴛɪɴɢs⚙️", url=f"https://t.me/{asst.me.username}?start=set"), - ], - [Button.inline("••Cʟᴏꜱᴇ••", data="close")], -] - SUP_BUTTONS = [ [ - Button.url("Repo", url="https://github.com/TeamUltroid/Ultroid"), - Button.url("Addons", url="https://github.com/TeamUltroid/UltroidAddons"), + Button.url("• Repo •", url="https://github.com/TeamUltroid/Ultroid"), + Button.url("• Support •", url="t.me/UltroidSupport"), ], - [Button.url("Support", url="t.me/UltroidSupport")], ] # --------------------BUTTONS--------------------# @@ -75,9 +62,6 @@ async def inline_alive(o): if len(o.text) == 0: b = o.builder MSG = "• **Ultroid Userbot •**" - uptime = time_formatter((time.time() - start_time) * 1000) - MSG += f"\n\n• **Uptime** - `{uptime}`\n" - MSG += f"• **OWNER** - `{OWNER_NAME}`" WEB0 = InputWebDocument( "https://telegra.ph/file/55dd0f381c70e72557cb1.jpg", 0, "image/jpg", [] ) @@ -97,7 +81,7 @@ async def inline_alive(o): content=InputWebDocument(TLINK, 0, "image/jpg", []), ) ] - await o.answer(RES, switch_pm=f"👥 ULTROID PORTAL", switch_pm_param="start") + await o.answer(RES, switch_pm="👥 ULTROID PORTAL", switch_pm_param="start") @in_pattern("ultd") @@ -121,18 +105,19 @@ async def inline_handler(event): await event.answer([result], gallery=True) -@in_pattern("haste") +@in_pattern("pasta") @in_owner async def _(event): - ok = event.text.split(" ")[1] - link = "https://hastebin.com/" - result = event.builder.article( + ok = event.text.split("-")[1] + link = "https://spaceb.in/" + ok + raw = f"https://spaceb.in/api/v1/documents/{ok}/raw" + result = await event.builder.article( title="Paste", - text="Pᴀsᴛᴇᴅ Tᴏ Hᴀsᴛᴇʙɪɴ!", + text="Pasted to Spacebin 🌌", buttons=[ [ - Button.url("HasteBin", url=f"{link}{ok}"), - Button.url("Raw", url=f"{link}raw/{ok}"), + Button.url("SpaceBin", url=link), + Button.url("Raw", url=raw), ], ], ) @@ -170,23 +155,32 @@ async def setting(event): ) +@callback("vc_helper") +@owner +async def on_vc_callback_query_handler(event): + xhelps = "**Voice Chat Help Menu for {}**\n**Available Commands:** `{}`\n\n@TeamUltroid".format( + OWNER_NAME, len(VC_HELP) + ) + buttons = page_num(0, VC_HELP, "vchelp", "vc") + await event.edit(f"{xhelps}", buttons=buttons, link_preview=False) + + @callback("doupdate") @owner async def _(event): - check = await updater() + check = updater() if not check: return await event.answer( "You Are Already On Latest Version", cache_time=0, alert=True ) repo = Repo.init() ac_br = repo.active_branch - changelog, tl_chnglog = await gen_chlog(repo, f"HEAD..upstream/{ac_br}") - changelog_str = changelog + f"\n\nClick the below button to update!" + changelog, tl_chnglog = gen_chlog(repo, f"HEAD..upstream/{ac_br}") + changelog_str = changelog + "\n\nClick the below button to update!" if len(changelog_str) > 1024: await event.edit(get_string("upd_4")) - file = open(f"ultroid_updates.txt", "w+") - file.write(tl_chnglog) - file.close() + with open("ultroid_updates.txt", "w+") as file: + file.write(tl_chnglog) await event.edit( get_string("upd_5"), file="ultroid_updates.txt", @@ -195,8 +189,7 @@ async def _(event): [Button.inline("« Bᴀᴄᴋ", data="ownr")], ], ) - remove(f"ultroid_updates.txt") - return + remove("ultroid_updates.txt") else: await event.edit( changelog_str, @@ -266,8 +259,8 @@ async def _(e): ], [ Button.switch_inline( - "EBᴏᴏᴋs Uᴘʟᴏᴀᴅᴇʀ", - query="ebooks India", + "Piston Eval", + query="run javascript console.log('Hello Ultroid')", same_peer=True, ), Button.switch_inline( @@ -276,6 +269,7 @@ async def _(e): same_peer=True, ), ], + [Button.switch_inline("xda Search", query="xda telegram", same_peer=True)], [ Button.inline( "« Bᴀᴄᴋ", @@ -339,6 +333,30 @@ async def on_plug_in_callback_query_handler(event): await event.edit(buttons=buttons, link_preview=False) +@callback( + re.compile( + rb"vchelp_next\((.+?)\)", + ), +) +@owner +async def on_vc_callback_query_handler(event): + current_page_number = int(event.data_match.group(1).decode("UTF-8")) + buttons = page_num(current_page_number + 1, VC_HELP, "vchelp", "vc") + await event.edit(buttons=buttons, link_preview=False) + + +@callback( + re.compile( + rb"vchelp_prev\((.+?)\)", + ), +) +@owner +async def on_vc_callback_query_handler(event): + current_page_number = int(event.data_match.group(1).decode("UTF-8")) + buttons = page_num(current_page_number - 1, VC_HELP, "vchelp", "vc") + await event.edit(buttons=buttons, link_preview=False) + + @callback( re.compile( rb"addon_next\((.+?)\)", @@ -391,6 +409,22 @@ async def backr(event): ) +@callback("bvck") +@owner +async def bvckr(event): + xhelps = "**Voice Chat Help Menu for {}**\n**Available Commands:** `{}`\n\n@TeamUltroid".format( + OWNER_NAME, len(VC_HELP) + ) + current_page_number = int(upage) + buttons = page_num(current_page_number, VC_HELP, "vchelp", "vc") + await event.edit( + f"{xhelps}", + file=_file_to_replace, + buttons=buttons, + link_preview=False, + ) + + @callback("open") @owner async def opner(event): @@ -465,6 +499,51 @@ async def on_plug_in_callback_query_handler(event): await event.edit(halps, buttons=buttons) +@callback( + re.compile( + b"vc_plugin_(.*)", + ), +) +@owner +async def on_vc_plg_callback_query_handler(event): + plugin_name = event.data_match.group(1).decode("UTF-8") + help_string = f"Plugin Name - `{plugin_name}`\n" + try: + for i in VC_HELP[plugin_name]: + help_string += i + except BaseException: + pass + if help_string == "**Commands Available:**\n\n": + reply_pop_up_alert = f"{plugin_name} has no detailed help..." + else: + reply_pop_up_alert = help_string + reply_pop_up_alert += "\n© @TeamUltroid" + buttons = [ + [ + Button.inline( + "« Sᴇɴᴅ Pʟᴜɢɪɴ »", + data=f"sndplug_{(event.data).decode('UTF-8')}", + ) + ], + [ + Button.inline("« Bᴀᴄᴋ", data="bvck"), + Button.inline("••Cʟᴏꜱᴇ••", data="close"), + ], + ] + try: + if str(event.query.user_id) in owner_and_sudos(): + await event.edit( + reply_pop_up_alert, + buttons=buttons, + ) + else: + reply_pop_up_alert = notmine + await event.answer(reply_pop_up_alert, cache_time=0) + except BaseException: + halps = f"Do .help {plugin_name} to get the list of commands." + await event.edit(halps, buttons=buttons) + + @callback( re.compile( b"add_plugin_(.*)", @@ -524,19 +603,14 @@ async def on_plug_in_callback_query_handler(event): await event.edit(halps, buttons=buttons) -def page_num(page_number, loaded_plugins, prefix, type): +def page_num(page_number, loaded_plugins, prefix, type_): number_of_rows = 5 number_of_cols = 2 emoji = Redis("EMOJI_IN_HELP") - if emoji: - multi = emoji - else: - multi = "✘" - helpable_plugins = [] + multi = emoji or "✘" global upage upage = page_number - for p in loaded_plugins: - helpable_plugins.append(p) + helpable_plugins = [p for p in loaded_plugins] helpable_plugins = sorted(helpable_plugins) modules = [ Button.inline( @@ -545,7 +619,7 @@ def page_num(page_number, loaded_plugins, prefix, type): x, multi, ), - data=f"{type}_plugin_{x}", + data=f"{type_}_plugin_{x}", ) for x in helpable_plugins ] diff --git a/plugins/_ultroid.py b/plugins/_ultroid.py index 7c9c4a2aa3..7da74fc7e6 100644 --- a/plugins/_ultroid.py +++ b/plugins/_ultroid.py @@ -4,8 +4,12 @@ # This file is a part of < https://github.com/TeamUltroid/Ultroid/ > # PLease read the GNU Affero General Public License in # . -from telethon.errors import ChatSendInlineForbiddenError -from telethon.errors.rpcerrorlist import BotMethodInvalidError as bmi + +from telethon.errors import ( + BotMethodInvalidError, + ChatSendInlineForbiddenError, + ChatSendMediaForbiddenError, +) from . import * @@ -16,13 +20,46 @@ • Support - @UltroidSupport """ +RP_BUTTONS = [ + [ + Button.url("Repo", "https://github.com/TeamUltroid/Ultroid"), + Button.url("Addons", "https://github.com/TeamUltroid/UltroidAddons"), + ], + [Button.url("Support Group", "t.me/ultroidsupport")], +] + +ULTSTRING = """🎇 **Thanks for Deploying Ultroid Userbot!** + +• Here, are the Some Basic stuff from, where you can Know, about its Usage.""" -@ultroid_cmd(pattern="repo$", type=["official", "manager"], ignore_dualmode=True) + +@ultroid_cmd( + pattern="repo$", + type=["official", "manager"], +) async def repify(e): try: - q = await e.client.inline_query(asst.me.username, "repo") + q = await e.client.inline_query(asst.me.username, "") await q[0].click(e.chat_id) - if e.out: - await e.delete() - except (ChatSendInlineForbiddenError, bmi): - await eor(e, REPOMSG) + return await e.delete() + except ( + ChatSendInlineForbiddenError, + ChatSendMediaForbiddenError, + BotMethodInvalidError, + ): + pass + except Exception as er: + LOGS.info("Error while repo command : " + str(er)) + await eor(e, REPOMSG) + + +@ultroid_cmd(pattern="ultroid") +async def useUltroid(rs): + button = Button.inline("Start >>", "initft_2") + msg = await asst.send_message( + LOG_CHANNEL, + ULTSTRING, + file="https://telegra.ph/file/54a917cc9dbb94733ea5f.jpg", + buttons=button, + ) + await eor(rs, f"**[Click Here]({msg.message_link})**") diff --git a/plugins/_userlogs.py b/plugins/_userlogs.py index 46f02cae21..35198b3798 100644 --- a/plugins/_userlogs.py +++ b/plugins/_userlogs.py @@ -5,18 +5,21 @@ # PLease read the GNU Affero General Public License in # . +import os import re +from pyUltroid.functions.botchat_db import tag_add, who_tag from telethon.errors.rpcerrorlist import ( ChatWriteForbiddenError, MediaEmptyError, PeerIdInvalidError, + UserNotParticipantError, ) from telethon.utils import get_display_name from . import * -# taglogger +CACHE_SPAM = {} @ultroid_bot.on( @@ -32,65 +35,78 @@ async def all_messages_catcher(e): NEEDTOLOG = int(udB.get("TAG_LOG")) except Exception: return LOGS.info("you given Wrong Grp/Channel ID in TAG_LOG.") - x = e.sender - if x.bot or x.verified: + x = await e.get_sender() + if isinstance(x, types.User) and (x.bot or x.verified): return y = e.chat where_n = get_display_name(y) who_n = get_display_name(x) - where_l = f"https://t.me/c/{y.id}/{e.id}" - send = await ultroid_bot.get_messages(e.chat_id, ids=e.id) + where_l = e.message.message_link + buttons = [[Button.url(where_n, where_l)]] + if x.username: + who_l = f"https://t.me/{x.username}" + buttons.append([Button.url(who_n, who_l)]) + else: + buttons.append([Button.inline(who_n, data=f"who{x.id}")]) try: - if x.username: - who_l = f"https://t.me/{x.username}" - await asst.send_message( - NEEDTOLOG, - send, - buttons=[ - [Button.url(who_n, who_l)], - [Button.url(where_n, where_l)], - ], - ) - else: - await asst.send_message( - NEEDTOLOG, - send, - buttons=[ - [Button.inline(who_n, data=f"who{x.id}")], - [Button.url(where_n, where_l)], - ], - ) + sent = await asst.send_message(NEEDTOLOG, e.message, buttons=buttons) + tag_add(sent.id, e.chat_id, e.id) except MediaEmptyError: - if x.username: - who_l = f"https://t.me/{x.username}" - await asst.send_message( - NEEDTOLOG, - "`Unsupported Media`", - buttons=[ - [Button.url(who_n, who_l)], - [Button.url(where_n, where_l)], - ], - ) - else: - await asst.send_message( - NEEDTOLOG, - "`Unsupported Media`", - buttons=[ - [Button.inline(who_n, data=f"who{x.id}")], - [Button.url(where_n, where_l)], - ], - ) - except PeerIdInvalidError: - await ultroid_bot.send_message( + try: + msg = await asst.get_messages(e.chat_id, ids=e.id) + sent = await asst.send_message(NEEDTOLOG, msg, buttons=buttons) + tag_add(sent.id, e.chat_id, e.id) + except Exception as me: + LOGS.info(me) + if e.photo or e.sticker or e.gif: + try: + media = await e.download_media() + await asst.send_message( + NEEDTOLOG, e.message.text, file=media, buttons=buttons + ) + return os.remove(media) + except Exception as er: + LOGS.info(er) + await asst.send_message(NEEDTOLOG, "`Unsupported Media`", buttons=buttons) + except (PeerIdInvalidError, ValueError): + await asst.send_message( int(udB.get("LOG_CHANNEL")), "The Chat Id You Set In Tag Logger Is Wrong , Please Correct It", ) except ChatWriteForbiddenError: - await ultroid_bot.send_message(NEEDTOLOG, "Please Give Your Assistant Bot") + try: + await asst.get_permissions(NEEDTOLOG, "me") + MSG = "Your Asst Cant Send Messages in Tag Log Chat." + MSG += "\n\nPlease Review the case or you can off" + MSG += "Your TagLogger, if you dont want to use it" + except UserNotParticipantError: + MSG = "Add me to Your Tag Logger Chat to Log Tags" + try: + CACHE_SPAM[NEEDTOLOG] + except KeyError: + await asst.send_message(LOG_CHANNEL, MSG) + CACHE_SPAM.update({NEEDTOLOG: True}) except Exception as er: LOGS.info(str(er)) +if udB.get("TAG_LOG"): + + @ultroid_bot.on( + events.NewMessage( + outgoing=True, chats=[int(udB["TAG_LOG"])], func=lambda e: e.reply_to + ) + ) + async def idk(e): + id = e.reply_to_msg_id + chat, msg = who_tag(id) + if chat and msg: + try: + await ultroid_bot.send_message(chat, e.message, reply_to=msg) + except BaseException: + pass + + @callback(re.compile("who(.*)")) async def _(e): wah = e.pattern_match.group(1).decode("UTF-8") @@ -112,7 +128,7 @@ async def when_asst_added_to_chat(event): chat = f"[{chat.title}](https://t.me/{chat.username}/{event.action_message.id})" else: chat = f"[{chat.title}](https://t.me/c/{chat.id}/{event.action_message.id})" - if user.is_self: + if user and user.is_self: tmp = event.added_by buttons = Button.inline("Leave Chat", data=f"leave_ch_{event.chat_id}|bot") return await asst.send_message( @@ -127,35 +143,23 @@ async def when_asst_added_to_chat(event): @ultroid.on(events.ChatAction) async def when_ultd_added_to_chat(event): + user = await event.get_user() + chat = await event.get_chat() + if not (user and user.is_self): + return + if chat.username: + chat = f"[{chat.title}](https://t.me/{chat.username}/{event.action_message.id})" + else: + chat = f"[{chat.title}](https://t.me/c/{chat.id}/{event.action_message.id})" + buttons = Button.inline("Leave Chat", data=f"leave_ch_{event.chat_id}|user") if event.user_added: - user = await event.get_user() - chat = await event.get_chat() - if hasattr(chat, "username") and chat.username: - chat = f"[{chat.title}](https://t.me/{chat.username}/{event.action_message.id})" - else: - chat = f"[{chat.title}](https://t.me/c/{chat.id}/{event.action_message.id})" - if user.is_self: - tmp = event.added_by - buttons = Button.inline("Leave Chat", data=f"leave_ch_{event.chat_id}|user") - return await asst.send_message( - int(udB.get("LOG_CHANNEL")), - f"#ADD_LOG\n\n{inline_mention(tmp)} just added {inline_mention(user)} to {chat}.", - buttons=buttons, - ) + tmp = event.added_by + text = f"#ADD_LOG\n\n{inline_mention(tmp)} just added {inline_mention(user)} to {chat}." elif event.user_joined: - user = await event.get_user() - chat = await event.get_chat() - if hasattr(chat, "username") and chat.username: - chat = f"[{chat.title}](https://t.me/{chat.username}/{event.action_message.id})" - else: - chat = f"[{chat.title}](https://t.me/c/{chat.id}/{event.action_message.id})" - if user.is_self: - buttons = Button.inline("Leave Chat", data=f"leave_ch_{event.chat_id}|user") - return await asst.send_message( - int(udB.get("LOG_CHANNEL")), - f"#JOIN_LOG\n\n[{user.first_name}](tg://user?id={user.id}) just joined {chat}.", - buttons=buttons, - ) + text = f"#JOIN_LOG\n\n[{user.first_name}](tg://user?id={user.id}) just joined {chat}." + else: + return + await asst.send_message(int(udB["LOG_CHANNEL"]), text, buttons=buttons) @callback( diff --git a/plugins/_wspr.py b/plugins/_wspr.py index 73e685ebbc..b515704952 100644 --- a/plugins/_wspr.py +++ b/plugins/_wspr.py @@ -142,8 +142,7 @@ async def _(e): snap.update({e.id: desc}) except ValueError: sur = e.builder.article( - title="Type ur msg", - text=f"You Didn't Type Your Msg", + title="Type ur msg", text="You Didn't Type Your Msg" ) await e.answer([sur]) diff --git a/plugins/admintools.py b/plugins/admintools.py index c23d588c72..1faad5e67f 100644 --- a/plugins/admintools.py +++ b/plugins/admintools.py @@ -18,6 +18,11 @@ • `{i}kick ` Kick the user from the chat. +• `{i}tban