diff --git a/.env.sample b/.env.sample index 72c86eae46c9c983e469e4ef4f0378fede958b0c..9d792fb3608a8e7e4a8ef41682520443e59df17e 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ -# Don't use quotes( " and ' ) +# Don't use quotes( " and ' ) API_ID= API_HASH= @@ -7,5 +7,4 @@ BOT_USERNAME= BOT_TOKEN= REDIS_URI= REDIS_PASSWORD= -HEROKU_API= -HEROKU_APP_NAME= \ No newline at end of file +LOG_CHANNEL= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 959f179a80cfe5509d1c84ba969bd523d937ac64..34d5effca737d47bd76235419ef5a13e993a37e1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,9 @@ logs-ultroid.txt ultroid-log.txt /*.jpg /*.png -/*.mp4 \ No newline at end of file +/*.mp4 +addons/ +ultroid.log +target/npmlist.json +node_modules +glitch_me/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 10e6ddf86e305184f700a19c5735b6d58a462be5..bacc3107620f84a12ff22882a3288c2b34368d17 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,17 @@ # PLease read the GNU Affero General Public License in . FROM ultroidteam/ultroid:0.0.3 +RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \ + dpkg -i ./google-chrome-stable_current_amd64.deb; apt -fqqy install && \ + rm ./google-chrome-stable_current_amd64.deb +RUN wget -O chromedriver.zip http://chromedriver.storage.googleapis.com/$(curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE)/chromedriver_linux64.zip && \ + unzip chromedriver.zip chromedriver -d /usr/bin/ && \ + rm chromedriver.zip +RUN curl --silent --location https://deb.nodesource.com/setup_15.x | bash - +RUN apt-get install -y nodejs sudo RUN git clone https://github.com/TeamUltroid/Ultroid.git /root/TeamUltroid/ WORKDIR /root/TeamUltroid/ +RUN git clone https://github.com/1Danish-00/glitch_me.git && pip install -e ./glitch_me RUN pip install -r requirements.txt -CMD ["bash", "resources/startup/startup.sh"] +RUN npm install -g npm@7.7.0 && npm install +RUN npm run build diff --git a/LICENSE b/LICENSE index f288702d2fa16d3cdf0035b15a9fcbc552cd88e7..be3f7b28e564e7dd05eaf59d64adba1a4065ac0e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies @@ -7,17 +7,15 @@ Preamble - The GNU General Public License is a free, copyleft license for -software and other kinds of works. + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to +our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. +software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you @@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. The precise terms and conditions for copying, distribution and modification follow. @@ -72,7 +60,7 @@ modification follow. 0. Definitions. - "This License" refers to version 3 of the GNU General Public License. + "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. @@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - 13. Use with the GNU Affero General Public License. + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single +under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General +Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published +GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's +versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. @@ -635,40 +633,29 @@ the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by + it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + GNU Affero General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see +For more information on this, and how to apply and follow the GNU AGPL, see . - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..40d1685b214a468b95b78f2f6c61ad48f004d87b --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +test: + @pre-commit run --all-files + +install: + @pip3 install --upgrade pip setuptools wheel + @pip3 install --upgrade -r requirements.txt + + +dev-install: + @pip3 install --upgrade pip setuptools wheel + @pip3 install --upgrade -r requirements-dev.txt + @sleep 5 + @pre-commit + @pre-commit install + +update: + @git pull + @pip3 install --upgrade pip setuptools wheel + @pip3 install --upgrade -r requirements.txt + +ci: + @pip3 install --upgrade pip setuptools wheel + @pip3 install --upgrade -r requirements-dev.txt + @pre-commit diff --git a/README.md b/README.md index 930a3beaffe5e2b9f0c5064f0ff0caeb0800359a..6fc40dd28dc71ff8be382d8ddeb77206c04d0377 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,106 @@ -# Ultroid - UserBot -A stable pluggable Telegram userbot, based on Telethon. -

- TeamUltroid + TeamUltroid Logo

+

+ Ultroid - UserBot +

+ +A stable pluggable Telegram userbot + vc music bot, based on Telethon. -[![Stars](https://img.shields.io/github/stars/TeamUltroid/Ultroid?style=flat-square&color=green)](https://github.com/TeamUltroid/Ultroid/stargazers) -[![Forks](https://img.shields.io/github/forks/TeamUltroid/Ultroid?style=flat-square&color=green)](https://github.com/TeamUltroid/Ultroid/fork) -[![Python Version](https://img.shields.io/badge/Python-v3.9-blue)](https://www.python.org/) +[![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/) +[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/TeamUltroid/Ultroid/graphs/commit-activity) +[![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) -[![License](https://img.shields.io/badge/License-AGPL-blue)](https://github.com/TeamUltroid/Ultroid/blob/main/LICENSE) -[![Size](https://img.shields.io/github/repo-size/TeamUltroid/Ultroid?style=flat-square&color=green)](https://github.com/TeamUltroid/Ultroid/) +[![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) +[![HitCount](http://hits.dwyl.com/Teamultroid/Teamultroid/Ultroid.svg)](http://hits.dwyl.com/Teamultroid/Teamultroid/Ultroid) +[![Sparkline](https://stars.medv.io/Teamultroid/Ultroid.svg)](https://stars.medv.io/TeamUltroid/Ultroid) + +---- -
-More Info -
- Documentation - ultroid.tech
-
+# Deploy +- [Heroku](#Deploy-to-Heroku) +- [Local Machine](#Deploy-Locally) -# Deploy -- [Heroku](https://github.com/TeamUltroid/Ultroid#Deploy-to-Heroku) -- [Local Machine](https://github.com/TeamUltroid/Ultroid#Deploy-Locally) +# Documentation +[![Document](https://img.shields.io/badge/Documentation-Ultroid-blue)](http://ultroid.tech/) + +# Tutorial +- Full Tutorial - [![Full Tutorial](https://img.shields.io/badge/Watch%20Now-blue)](https://www.youtube.com/watch?v=9wF7k9qA0Q4) + +- Tutorial to get Redis URL and password - [here.](./resources/extras/redistut.md) +--- ## Deploy to Heroku -- Get your `API_ID` and `API_HASH` from [here](https://my.telegram.org/) -- Get your `SESSION` from [here](https://repl.it/@TeamUltroid/UltroidStringSession#main.py). -and click the below button!
+Get the [Necessary Variables](#Necessary-Variables) and then click the button below! [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) ## Deploy Locally -- Get your `API_ID` and `API_HASH` from [here](https://my.telegram.org/) -- Get your `REDIS_URI` and `REDIS_PASSWORD` from [here](https://redislabs.com), tutorial [here](./resources/extras/redistut.md). +- [Traditional Method](#local-deploy---traditional-method) +- [Easy Method](#local-deploy---easy-method) + +### Local Deploy - Easy Method +- Linux - `bash -c "$(curl -fsSL https://git.io/JY9UM)"` +- Windows - `cd desktop ; wget https://del.dog/raw/ultroid-termux -o locals.py ; python locals.py` +- Termux - `sh -c "$(curl -fsSL https://del.dog/raw/ultroid-termux)"` + +### Local Deploy - Traditional Method +- Get your [Necessary Variables](#Necessary-Variables) - Clone the repository:
`git clone https://github.com/TeamUltroid/Ultroid.git` - Go to the cloned folder:
`cd Ultroid` - Create a virtual env:
-`virtualenv -p /usr/bin/python3 venv` +`virtualenv -p /usr/bin/python3 venv` `. ./venv/bin/activate` - Install the requirements:
-`pip install -r requirements.txt` -- Generate your `SESSION`: -`bash sessiongen` -or -`bash -c "$(curl -fsSL https://del.dog/ultroid)"` -- Fill your details in a `.env` file, as given in [`.env.sample`](https://github.com/TeamUltroid/Ultroid/blob/main/.env.sample). -(You can either edit and rename the file or make a new file.) -- Run the bot: -`bash resources/startup/startup.sh` +`pip(3) install -U -r requirements.txt` +- Generate your `SESSION`: + - For Linux users: + `bash sessiongen` + or + `bash -c "$(curl -fsSL https://del.dog/ultroid)"` + - For Termux users: + `sh -c "$(curl -fsSL https://da.gd/termux-tel)"` + - For Windows Users: + `cd desktop ; wget https://del.dog/ultroid -o ultroid.py ; python ultroid.py` +- Fill your details in a `.env` file, as given in [`.env.sample`](https://github.com/TeamUltroid/Ultroid/blob/main/.env.sample). +(You can either edit and rename the file or make a new file named `.env`.) +- Run the bot: + - Linux Users: + `bash resources/startup/startup.sh` + - Windows Users: + `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) +- `BOT_TOKEN` - The token of your bot from [@BotFather](https://t.me/BotFather) +- `BOT_USERNAME` - The username of your bot from [@BotFather](https://t.me/BotFather) +- `LOG_CHANNEL` - A private group/channel id. +- `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) + +## Session String +Different ways to get your `SESSION`: +* [![Run on Repl.it](https://replit.com/badge/github/TeamUltroid/Ultroid)](https://replit.com/@TeamUltroid/UltroidStringSession) +* Linux : `bash -c "$(curl -fsSL https://del.dog/ultroid)"` +* PowerShell : `cd desktop ; wget https://git.io/JY9JI ; python ultroid.py` +* Termux : `sh -c "$(curl -fsSL https://da.gd/termux-tel)"` Made with 💕 by [@TeamUltroid](https://t.me/TeamUltroid).
-# Credits -* [Lonami](https://github.com/LonamiWebs/) for [Telethon](https://github.com/LonamiWebs/Telethon) +# License +Ultroid is licensed under [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) v3 or later. + +[![License](https://www.gnu.org/graphics/agplv3-155x51.png)](LICENSE) +# 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) +* [AndrewLaneX](https://github.com/AndrewLaneX) for [tgcalls.](http://github.com/tgcallsjs/tgcalls) diff --git a/app.json b/app.json index c85c8ffde31bb358ac9a5cb6cacdf2c0a37d0342..b83cbd2623ada9e490778a89f2732a76c3c7a2fa 100644 --- a/app.json +++ b/app.json @@ -1,10 +1,16 @@ { "name": "Ultroid UserBot", "description": "Pluggable telegram userbot, made in python using Telethon.", - "logo": "https://telegra.ph/file/1518e15421d21c5afd9af.jpg", - "keywords": ["Telethon", "telegram", "userbot", "python"], + "logo": "https://telegra.ph/file/031957757a4f6a5191040.jpg", + "keywords": [ + "Telethon", + "telegram", + "userbot", + "python", + "ultroid" + ], "repository": "https://github.com/TeamUltroid/Ultroid", - "website": "https://ultroid.netlify.app/", + "website": "https://ultroid.tech", "success_url": "https://t.me/TheUltroid", "stack": "container", "env": { @@ -43,11 +49,12 @@ }, "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.", - "value": "" + "value": "", + "required": false }, "LOG_CHANNEL": { "description": "Create a private group. Add @missrose_bot and your BOT_USERNAME bot. Do /id. Paste that here", - "value": "" + "value": "" } } -} +} \ No newline at end of file diff --git a/assistant/__init__.py b/assistant/__init__.py index 919cdcfa7bca8d82e3de95b9707b15866f94ebae..84b95991783ac8e3f82ff8b8af0ac12fba4554cc 100644 --- a/assistant/__init__.py +++ b/assistant/__init__.py @@ -21,3 +21,8 @@ async def setit(event, name, value): udB.set(name, value) except BaseException: return await event.edit("`Something Went Wrong`") + + +def get_back_button(name): + button = [Button.inline("« Bᴀᴄᴋ", data=f"{name}")] + return button diff --git a/assistant/api_setter.py b/assistant/api_setter.py index cb746e42ec42be66df43ca5c81b42f1abf5ffc2a..81e0cecf32bc437c1bc56f51b37eb172ce5fbefb 100644 --- a/assistant/api_setter.py +++ b/assistant/api_setter.py @@ -17,7 +17,7 @@ async def apiset(event): get_string("ast_1"), buttons=[ [Button.inline("Remove.bg", data="rmbg")], - [custom.Button.inline("« Back", data="setter")], + [Button.inline("« Back", data="setter")], ], ) @@ -38,7 +38,13 @@ async def rmbgapi(event): response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message("Cancelled!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("apiset"), + ) else: await setit(event, var, themssg) - await conv.send_message("{} changed to {}".format(name, themssg)) + await conv.send_message( + f"{name} changed to {themssg}", + buttons=get_back_button("apiset"), + ) diff --git a/assistant/inlinestuff.py b/assistant/inlinestuff.py index eb2438819676b5025f9de4f1463937d856cc560d..fd60bcfa6f8304c9bccfca9a8ae079973aa4dabd 100644 --- a/assistant/inlinestuff.py +++ b/assistant/inlinestuff.py @@ -5,25 +5,95 @@ # PLease read the GNU Affero General Public License in # . -import random -import re +from random import randrange +from re import compile as re_compile +from re import findall from urllib.request import urlopen -import play_scraper import requests from bs4 import BeautifulSoup -from pyUltroid.functions.parser import GoogleSearch, YahooSearch +from orangefoxapi import OrangeFoxAPI +from play_scraper import search from rextester_py import rexec_aio from rextester_py.rextester_aio import UnknownLanguage +from search_engine_parser import GoogleSearch, YahooSearch from telethon import Button from telethon.tl.types import InputWebDocument as wb 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" +rex_langs = """ada, bash, brainfuck, c (clang), c, c (vc), +c#, c++ (clang), c++, c++ (vc++), d, elixir, +erlang, f#, fortran, go, haskell, java, js, +kotlin, lisp, lua, mysql, nasm, node, +objective-c, ocaml, octave, oracle, pascal, +perl, php, postgresql, prolog, python, +python3, r, ruby, scala, scheme, sql server, +swift, tcl, vb.net""" + +ofox_api = OrangeFoxAPI() + + +@in_pattern("ofox") +@in_owner +async def _(e): + try: + match = e.text.split(" ", maxsplit=1)[1] + except IndexError: + kkkk = e.builder.article( + title="Enter Device Codename", + thumb=wb(ofox, 0, "image/jpeg", []), + 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: + 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 + ), + ], + ) + ) + await e.answer(fox) + else: + sed = e.builder.article( + title="Not Found", + description="Wrong Codename", + text="OʀᴀɴɢFᴏx Rᴇᴄᴏᴠᴇʀʏ Fᴏʀ Yᴏᴜʀ Pʜᴏɴᴇ Is Eɪᴛʜᴇʀ Nᴏᴛ Oғғɪᴄɪᴀʟʟʏ Bᴜɪʟᴛ Oʀ Yᴏᴜ Hᴀᴠᴇ Eɴᴛᴇʀᴇᴅ Wʀᴏɴɢ Cᴏᴅᴇɴᴀᴍᴇ", + buttons=Button.switch_inline("Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="ofox ", same_peer=True), + ) + await e.answer([sed]) @in_pattern("fl2lnk ?(.*)") @@ -60,7 +130,7 @@ async def _(e): @callback( - re.compile( + re_compile( "fl(.*)", ), ) @@ -88,7 +158,7 @@ async def repo(e): [Button.url("Repo", url="https://github.com/TeamUltroid/Ultroid")], [Button.url("Support", url="t.me/UltroidSupport")], ], - ) + ), ] await e.answer(res) @@ -107,7 +177,7 @@ async def gsearch(q_event): ) await q_event.answer([kkkk]) searcher = [] - page = re.findall(r"page=\d+", match) + page = findall(r"page=\d+", match) cache = False try: page = page[0] @@ -136,14 +206,18 @@ async def gsearch(q_event): [Button.url("Lɪɴᴋ", url=f"{link}")], [ Button.switch_inline( - "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="go ", same_peer=True + "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", + query="go ", + same_peer=True, ), Button.switch_inline( - "Sʜᴀʀᴇ", query=f"go {match}", same_peer=False + "Sʜᴀʀᴇ", + query=f"go {match}", + same_peer=False, ), ], ], - ) + ), ) except IndexError: break @@ -158,10 +232,14 @@ async def rextester(event): omk = event.text.split(" ", maxsplit=1)[1] if omk is not None: if "|" in omk: - lang, code = omk.split("|") + lang, codee = omk.split("|") + else: + lang = "python3" + codee = omk + if lang == "php": + code = f"" else: - lang = "python 3" - code = omk + code = codee output = await rexec_aio(lang, code) stats = output.stats if output.errors is not None: @@ -183,7 +261,7 @@ async def rextester(event): resultm = builder.article( title="Error", # By @ProgrammingError description="Invalid language choosen", - text="The list of valid languages are\n\nc#, vb.net, f#, java, python, c (gcc), \nc++ (gcc), php, pascal, objective-c, haskell, \nruby, perl, lua, nasm, sql server, javascript, lisp, prolog, go, scala, \nscheme, node.js, python 3, octave, c (clang), \nc++ (clang), c++ (vc++), c (vc), d, r, tcl, mysql, postgresql, oracle, swift, \nbash, ada, erlang, elixir, ocaml, \nkotlin, brainfuck, fortran\n\n\n Format to use Rextester is `@Yourassistantusername rex langcode|code`", + text=f"The list of valid languages are\n\n{rex_langs}\n\n\nFormat to use Rextester is `@Yourassistantusername rex langcode|code`", ) await event.answer([resultm]) @@ -199,12 +277,14 @@ async def gsearch(q_event): thumb=wb(yeah, 0, "image/jpeg", []), text="**Yᴀʜᴏᴏ Sᴇᴀʀᴄʜ**\n\nYou didn't search anything", buttons=Button.switch_inline( - "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="yahoo ", same_peer=True + "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", + query="yahoo ", + same_peer=True, ), ) await q_event.answer([kkkk]) searcher = [] - page = re.findall(r"page=\d+", match) + page = findall(r"page=\d+", match) cache = False try: page = page[0] @@ -233,14 +313,18 @@ async def gsearch(q_event): [Button.url("Lɪɴᴋ", url=f"{link}")], [ Button.switch_inline( - "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="yahoo ", same_peer=True + "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", + query="yahoo ", + same_peer=True, ), Button.switch_inline( - "Sʜᴀʀᴇ", query=f"yahoo {match}", same_peer=False + "Sʜᴀʀᴇ", + query=f"yahoo {match}", + same_peer=False, ), ], ], - ) + ), ) except IndexError: break @@ -261,7 +345,7 @@ async def _(e): ) await e.answer([kkkk]) foles = [] - aap = play_scraper.search(f) + aap = search(f) for z in aap: name = z["title"] desc = z["description"] @@ -315,7 +399,7 @@ async def _(e): await e.answer([kkkk]) page = 1 start = (page - 1) * 3 + 1 - urd = random.randrange(1, 3) + urd = randrange(1, 3) if urd == 1: da = "AIzaSyAyDBsY3WRtB5YPC6aB_w8JAy6ZdXNc6FU" if urd == 2: @@ -325,7 +409,7 @@ async def _(e): url = f"https://www.googleapis.com/customsearch/v1?key={da}&cx=25b3b50edb928435b&q={quer}&start={start}" data = requests.get(url).json() search_items = data.get("items") - play_scraper.search(quer) + search(quer) modss = [] for a in search_items: title = a.get("title") @@ -343,14 +427,18 @@ async def _(e): [Button.url("Dᴏᴡɴʟᴏᴀᴅ", url=f"{link}")], [ Button.switch_inline( - "Mᴏʀᴇ Mᴏᴅs", query="mods ", same_peer=True + "Mᴏʀᴇ Mᴏᴅs", + query="mods ", + same_peer=True, ), Button.switch_inline( - "Sʜᴀʀᴇ", query=f"mods {quer}", same_peer=False + "Sʜᴀʀᴇ", + query=f"mods {quer}", + same_peer=False, ), ], ], - ) + ), ) await e.answer(modss) @@ -365,7 +453,9 @@ async def clip(e): title="Search Something", text="**Cʟɪᴘᴀʀᴛ Sᴇᴀʀᴄʜ**\n\nYou didn't search anything", buttons=Button.switch_inline( - "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="clipart ", same_peer=True + "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", + query="clipart ", + same_peer=True, ), ) await e.answer([kkkk]) diff --git a/assistant/localization.py b/assistant/localization.py index cad971c688b8f3a604f83d4f6c53fab1f8517457..720f64a0cde139a2a6e393aff77e8fc080304894 100644 --- a/assistant/localization.py +++ b/assistant/localization.py @@ -16,7 +16,8 @@ async def setlang(event): languages = get_languages() tultd = [ Button.inline( - f"{languages[ult]['natively']} [{ult.lower()}]", data=f"set_{ult}" + f"{languages[ult]['natively']} [{ult.lower()}]", + data=f"set_{ult}", ) for ult in languages ] @@ -34,5 +35,5 @@ async def settt(event): languages = get_languages() udB.set("language", f"{lang}") await event.edit( - f"Your language has been set to {languages[lang]['natively']} [{lang}]." + f"Your language has been set to {languages[lang]['natively']} [{lang}].", ) diff --git a/assistant/othervars.py b/assistant/othervars.py index 7a5a7ba36434f5aa29c5f1bb5f235e4c74a69a88..8df87a1427d95313a4b9d1daedc6872c4081ce87 100644 --- a/assistant/othervars.py +++ b/assistant/othervars.py @@ -5,8 +5,20 @@ # PLease read the GNU Affero General Public License in # . +import os + +from telegraph import Telegraph +from telegraph import upload_file as upl + from . import * +# --------------------------------------------------------------------# +telegraph = Telegraph() +r = telegraph.create_account(short_name="Ultroid") +auth_url = r["auth_url"] +# --------------------------------------------------------------------# + + TOKEN_FILE = "resources/auths/auth_token.txt" @@ -22,7 +34,7 @@ async def _(e): ) storage = await create_token_file(TOKEN_FILE, e) authorize(TOKEN_FILE, storage) - f = open(TOKEN_FILE, "r") + f = open(TOKEN_FILE) token_file_data = f.read() udB.set("GDRIVE_TOKEN", token_file_data) await e.reply( @@ -43,7 +55,7 @@ async def _(e): + "2. Create Folder.\n" + "3. Make that folder public.\n" + "4. Copy link of that folder." - + "5. Send all characters which is after id= ." + + "5. Send all characters which is after id= .", ) async with ultroid_bot.asst.conversation(e.sender_id) as conv: reply = conv.wait_event(events.NewMessage(from_users=e.sender_id)) @@ -51,7 +63,7 @@ async def _(e): udB.set("GDRIVE_FOLDER_ID", repl.text) await repl.reply( "Success Now You Can Authorise.", - buttons=Button.inline("« Back", data="gdrive"), + buttons=get_back_button("gdrive"), ) @@ -67,7 +79,7 @@ async def _(e): udB.set("GDRIVE_CLIENT_SECRET", repl.text) await repl.reply( "Success!\nNow You Can Authorise or add FOLDER ID.", - buttons=Button.inline("« Back", data="gdrive"), + buttons=get_back_button("gdrive"), ) @@ -85,7 +97,7 @@ async def _(e): udB.set("GDRIVE_CLIENT_ID", repl.text) await repl.reply( "Success now set CLIENT SECRET", - buttons=Button.inline("« Back", data="gdrive"), + buttons=get_back_button("gdrive"), ) @@ -151,14 +163,20 @@ async def emoji(event): response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message("Cancelled!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("otvars"), + ) elif themssg.startswith(("/", HNDLR)): - return await conv.send_message("Incorrect Emoji") + return await conv.send_message( + "Incorrect Emoji", + buttons=get_back_button("otvars"), + ) else: await setit(event, var, themssg) await conv.send_message( - "{} changed to {}\n".format(name, themssg), - buttons=[Button.inline("« Bᴀᴄᴋ", data="otvars")], + f"{name} changed to {themssg}\n", + buttons=get_back_button("otvars"), ) @@ -171,22 +189,29 @@ async def pluginch(event): 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." + "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": - return await conv.send_message("Cancelled!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("otvars"), + ) elif themssg.startswith(("/", HNDLR)): - return await conv.send_message("Incorrect channel") + return await conv.send_message( + "Incorrect channel", + buttons=get_back_button("otvars"), + ) else: await setit(event, var, themssg) await conv.send_message( "{} changed to {}\n After Setting All Things Do Restart".format( - name, themssg + name, + themssg, ), - buttons=[Button.inline("« Bᴀᴄᴋ", data="otvars")], + buttons=get_back_button("otvars"), ) @@ -199,22 +224,31 @@ async def hndlrr(event): 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." + 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": - return await conv.send_message("Cancelled!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("otvars"), + ) elif len(themssg) > 1: - return await conv.send_message("Incorrect Handler") + return await conv.send_message( + "Incorrect Handler", + buttons=get_back_button("otvars"), + ) elif themssg.startswith(("/", "#", "@")): - return await conv.send_message("Incorrect Handler") + return 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( - "{} changed to {}".format(name, themssg), - buttons=[Button.inline("« Bᴀᴄᴋ", data="otvars")], + f"{name} changed to {themssg}", + buttons=get_back_button("otvars"), ) @@ -227,18 +261,21 @@ async def tagloggerr(event): name = "Tag Log Group" async with event.client.conversation(pru) as conv: await conv.send_message( - 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." + 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.", ) response = conv.wait_event(events.NewMessage(chats=pru)) response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message("Cancelled!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("otvars"), + ) else: await setit(event, var, themssg) await conv.send_message( - "{} changed to {}".format(name, themssg), - buttons=[Button.inline("« Bᴀᴄᴋ", data="otvars")], + f"{name} changed to {themssg}", + buttons=get_back_button("otvars"), ) @@ -262,7 +299,7 @@ async def eddon(event): await setit(event, var, "True") await event.edit( "Done! ADDONS has been turned on!!\n\n After Setting All Things Do Restart", - buttons=[Button.inline("« Bᴀᴄᴋ", data="eaddon")], + buttons=get_back_button("eaddon"), ) @@ -273,7 +310,7 @@ async def eddof(event): await setit(event, var, "False") await event.edit( "Done! ADDONS has been turned off!! After Setting All Things Do Restart", - buttons=[Button.inline("« Bᴀᴄᴋ", data="eaddon")], + buttons=get_back_button("eaddon"), ) @@ -297,7 +334,7 @@ async def eddon(event): await setit(event, var, "True") await event.edit( "Done! SUDO MODE has been turned on!!\n\n After Setting All Things Do Restart", - buttons=[Button.inline("« Bᴀᴄᴋ", data="sudo")], + buttons=get_back_button("sudo"), ) @@ -308,7 +345,7 @@ async def eddof(event): await setit(event, var, "False") await event.edit( "Done! SUDO MODE has been turned off!! After Setting All Things Do Restart", - buttons=[Button.inline("« Bᴀᴄᴋ", data="sudo")], + buttons=get_back_button("sudo"), ) @@ -334,18 +371,21 @@ async def sfgrp(event): 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." + 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!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("sfban"), + ) else: await setit(event, var, themssg) await conv.send_message( - "{} changed to {}".format(name, themssg), - buttons=[Button.inline("« Bᴀᴄᴋ", data="sfban")], + f"{name} changed to {themssg}", + buttons=get_back_button("sfban"), ) @@ -358,46 +398,29 @@ 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." + 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.", ) response = conv.wait_event(events.NewMessage(chats=pru)) response = await response themssg = response.message.message if themssg == "/cancel": - return await conv.send_message("Cancelled!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("sfban"), + ) else: await setit(event, var, themssg) await conv.send_message( - "{} changed to {}".format(name, themssg), - buttons=[Button.inline("« Bᴀᴄᴋ", data="sfban")], + f"{name} changed to {themssg}", + buttons=get_back_button("sfban"), ) -# Ultroid - UserBot -# Copyright (C) 2020 TeamUltroid -# -# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > -# PLease read the GNU Affero General Public License in -# . - -import os - -from telegraph import Telegraph -from telegraph import upload_file as upl - -from . import * - -# --------------------------------------------------------------------# -telegraph = Telegraph() -r = telegraph.create_account(short_name="Ultroid") -auth_url = r["auth_url"] -# --------------------------------------------------------------------# - @callback("alvcstm") @owner async def alvcs(event): await event.edit( - "Customise your {}alive. Choose from the below options -".format(HNDLR), + f"Customise your {HNDLR}alive. Choose from the below options -", buttons=[ [Button.inline("Aʟɪᴠᴇ Tᴇxᴛ", data="alvtx")], [Button.inline("Aʟɪᴠᴇ ᴍᴇᴅɪᴀ", data="alvmed")], @@ -416,19 +439,24 @@ async def name(event): name = "Alive Text" async with event.client.conversation(pru) as conv: await conv.send_message( - "**Alive Text**\nEnter the new alive text.\n\nUse /cancel to terminate the operation." + "**Alive Text**\nEnter the new alive text.\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!!") + return await conv.send_message( + "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 - ) + name, + themssg, + ), + buttons=get_back_button("alvcstm"), ) @@ -441,13 +469,16 @@ 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/bot api id of sticker to set as alive media.\n\nUse /cancel to terminate the operation.", ) response = await conv.get_response() try: themssg = response.message.message if themssg == "/cancel": - return await conv.send_message("Operation cancelled!!") + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("alvcstm"), + ) except BaseException: pass media = await event.client.download_media(response, "alvpc") @@ -463,9 +494,15 @@ async def media(event): url = f"https://telegra.ph/{x[0]}" os.remove(media) except BaseException: - return await conv.send_message("Terminated.") + return await conv.send_message( + "Terminated.", + buttons=get_back_button("alvcstm"), + ) await setit(event, var, url) - await conv.send_message("{} has been set.".format(name)) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("alvcstm"), + ) @callback("delmed") @@ -473,9 +510,12 @@ async def media(event): async def dell(event): try: udB.delete("ALIVE_PIC") - return await event.edit("Done!") + return await event.edit("Done!", buttons=get_back_button("alvcstm")) except BaseException: - return await event.edit("Something went wrong...") + return await event.edit( + "Something went wrong...", + buttons=get_back_button("alvcstm"), + ) @callback("pmcstm") @@ -496,7 +536,7 @@ async def alvcs(event): Button.inline("Sᴇᴛ Wᴀʀɴs", data="swarn"), Button.inline("Dᴇʟᴇᴛᴇ Pᴍ Mᴇᴅɪᴀ", data="delpmmed"), ], - [Button.inline("« Bᴀᴄᴋ", data="pmset")], + [Button.inline("« Bᴀᴄᴋ", data="ppmset")], ], ) @@ -510,19 +550,24 @@ async def name(event): 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." + "**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!!") + return await conv.send_message( + "Cancelled!!", + buttons=get_back_button("pmcstm"), + ) else: await setit(event, var, themssg) await conv.send_message( "{} changed to {}\n\nAfter Setting All Things Do restart".format( - name, themssg - ) + name, + themssg, + ), + buttons=get_back_button("pmcstm"), ) @@ -546,10 +591,14 @@ async def set_wrns(event): dn = udB.set("PMWARNS", value) if dn: await event.edit( - f"PM Warns Set to {value}.\nNew users will have {value} chances in PMs before getting banned." + f"PM Warns Set to {value}.\nNew users will have {value} chances in PMs before getting banned.", + buttons=get_back_button("pmcstm"), ) else: - await event.edit(f"Something went wrong, please check your {hndlr}logs!") + await event.edit( + f"Something went wrong, please check your {hndlr}logs!", + buttons=get_back_button("pmcstm"), + ) @callback("pmmed") @@ -561,13 +610,16 @@ 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/bot api id of sticker to set as pmpermit media.\n\nUse /cancel to terminate the operation." + "**PM Media**\nSend me a pic/gif/ or link to set as pmpermit media.\n\nUse /cancel to terminate the operation.", ) response = await conv.get_response() try: themssg = response.message.message if themssg == "/cancel": - return await conv.send_message("Operation cancelled!!") + return await conv.send_message( + "Operation cancelled!!", + buttons=get_back_button("pmcstm"), + ) except BaseException: pass media = await event.client.download_media(response, "pmpc") @@ -583,9 +635,15 @@ async def media(event): url = f"https://telegra.ph/{x[0]}" os.remove(media) except BaseException: - return await conv.send_message("Terminated.") + return await conv.send_message( + "Terminated.", + buttons=get_back_button("pmcstm"), + ) await setit(event, var, url) - await conv.send_message("{} has been set.".format(name)) + await conv.send_message( + f"{name} has been set.", + buttons=get_back_button("pmcstm"), + ) @callback("delpmmed") @@ -593,9 +651,12 @@ async def media(event): async def dell(event): try: udB.delete("PMPIC") - return await event.edit("Done!") + return await event.edit("Done!", buttons=get_back_button("pmcstm")) except BaseException: - return await event.edit("Something went wrong...") + return await event.edit( + "Something went wrong...", + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) @callback("apauto") @@ -616,7 +677,10 @@ async def apauto(event): async def apon(event): var = "AUTOAPPROVE" await setit(event, var, "True") - await event.edit(f"Done!! AUTOAPPROVE Started!!") + await event.edit( + f"Done!! AUTOAPPROVE Started!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="apauto")]], + ) @callback("apof") @@ -624,9 +688,15 @@ async def apon(event): async def apof(event): try: udB.delete("AUTOAPPROVE") - return await event.edit("Done! AUTOAPPROVE Stopped!!") + return await event.edit( + "Done! AUTOAPPROVE Stopped!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="apauto")]], + ) except BaseException: - return await event.edit("Something went wrong...") + return await event.edit( + "Something went wrong...", + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) @callback("pml") @@ -647,7 +717,10 @@ async def alvcs(event): async def pmlog(event): var = "PMLOG" await setit(event, var, "True") - await event.edit(f"Done!! PMLOGGER Started!!") + await event.edit( + f"Done!! PMLOGGER Started!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], + ) @callback("pmlogof") @@ -655,16 +728,23 @@ async def pmlog(event): async def pmlogof(event): try: udB.delete("PMLOG") - return await event.edit("Done! PMLOGGER Stopped!!") + return await event.edit( + "Done! PMLOGGER Stopped!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="pml")]], + ) except BaseException: - return await event.edit("Something went wrong...") + return await event.edit( + "Something went wrong...", + buttons=[[Button.inline("« Sᴇᴛᴛɪɴɢs", data="setter")]], + ) @callback("ppmset") @owner async def pmset(event): - await event.edit("PMPermit Settings:", - buttons=[ + await event.edit( + "PMPermit Settings:", + buttons=[ [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oɴ", data="pmon")], [Button.inline("Tᴜʀɴ PMPᴇʀᴍɪᴛ Oғғ", data="pmoff")], [Button.inline("Cᴜsᴛᴏᴍɪᴢᴇ PMPᴇʀᴍɪᴛ", data="pmcstm")], @@ -678,7 +758,10 @@ async def pmset(event): async def pmonn(event): var = "PMSETTING" await setit(event, var, "True") - await event.edit(f"Done! PMPermit has been turned on!!") + await event.edit( + f"Done! PMPermit has been turned on!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="ppmset")]], + ) @callback("pmoff") @@ -686,4 +769,117 @@ async def pmonn(event): async def pmofff(event): var = "PMSETTING" await setit(event, var, "False") - await event.edit(f"Done! PMPermit has been turned off!!") + await event.edit( + f"Done! PMPermit has been turned off!!", + buttons=[[Button.inline("« Bᴀᴄᴋ", data="ppmset")]], + ) + + +@callback("chatbot") +@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)", + buttons=[ + [Button.inline("Cʜᴀᴛ Bᴏᴛ Oɴ", data="onchbot")], + [Button.inline("Cʜᴀᴛ Bᴏᴛ Oғғ", data="ofchbot")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + link_preview=False, + ) + + +@callback("onchbot") +@owner +async def chon(event): + var = "PMBOT" + await setit(event, var, "True") + await event.edit( + "Done! Now u Can Chat With People Via This Bot", + buttons=[Button.inline("« Bᴀᴄᴋ", data="chatbot")], + ) + + +@callback("ofchbot") +@owner +async def chon(event): + var = "PMBOT" + await setit(event, var, "False") + await event.edit( + "Done! Chat People Via This Bot Stopped.", + buttons=[Button.inline("« Bᴀᴄᴋ", data="chatbot")], + ) + + +@callback("vcb") +@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)", + buttons=[ + [Button.inline("VC Sᴇssɪᴏɴ", data="vcs")], + [Button.inline("WEBSOCKET", data="vcw")], + [Button.inline("« Bᴀᴄᴋ", data="setter")], + ], + link_preview=False, + ) + + +@callback("vcs") +@owner +async def name(event): + await event.delete() + pru = event.sender_id + var = "VC_SESSION" + name = "VC SESSION" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**Vc session**\nEnter the New session u generated for vc bot.\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("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"), + ) + + +@callback("vcw") +@owner +async def name(event): + await event.delete() + pru = event.sender_id + var = "WEBSOCKET_URL" + name = "WEBSOCKET URL" + async with event.client.conversation(pru) as conv: + await conv.send_message( + "**WEBSOCKET URL**\nEnter your websocket url means\n`https://{HEROKU_APP_NAME}.herokuapp.com`\nIn place of HEROKU_APP_NAME put ur heroku app name\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("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"), + ) diff --git a/assistant/pmbot/banuser.py b/assistant/pmbot/banuser.py index b77cc83721185a03b80995602c5ba367c6777896..4fd8f6ad0e29bc2d4cf6a67eba6b222169ef3e9d 100644 --- a/assistant/pmbot/banuser.py +++ b/assistant/pmbot/banuser.py @@ -6,11 +6,7 @@ async def banhammer(event): x = await event.get_reply_message() if x is None: return await event.edit("Please reply to someone to ban him.") - if x.fwd_from: - target = x.fwd_from.from_id.user_id - else: - # this is a weird way of doing it - return + target = int(udB.get(str(x.id))) if not is_blacklisted(target): blacklist_user(target) await asst.send_message(event.chat_id, f"#BAN\nUser - {target}") @@ -27,11 +23,7 @@ async def banhammer(event): x = await event.get_reply_message() if x is None: return await event.edit("Please reply to someone to ban him.") - if x.fwd_from: - target = x.fwd_from.from_id.user_id - else: - # this is a weird way of doing it - return + target = int(udB.get(str(x.id))) if is_blacklisted(target): rem_blacklist(target) await asst.send_message(event.chat_id, f"#UNBAN\nUser - {target}") diff --git a/assistant/pmbot/incoming.py b/assistant/pmbot/incoming.py index fa94ff21dac6197226493c18e5e2c753de6fcd2b..48d9b7f8f60264a17f8cb229185a2b6b5329aa14 100644 --- a/assistant/pmbot/incoming.py +++ b/assistant/pmbot/incoming.py @@ -29,4 +29,5 @@ async def on_new_mssg(event): elif who == OWNER_ID: return else: - await event.forward_to(OWNER_ID) + xx = await event.forward_to(OWNER_ID) + udB.set(str(xx.id), str(who)) diff --git a/assistant/pmbot/outgoing.py b/assistant/pmbot/outgoing.py index 9a2c5f2d8141c0aa70529a550c5fca260398e9ba..252dd2ce3486d8f5dcb7a31b3fd64c7c983d7bee 100644 --- a/assistant/pmbot/outgoing.py +++ b/assistant/pmbot/outgoing.py @@ -8,7 +8,6 @@ # https://github.com/xditya/TeleBot/blob/master/telebot/plugins/mybot/pmbot/outgoing.py from telethon import events -from telethon.utils import pack_bot_file_id from . import * @@ -20,24 +19,15 @@ async def on_out_mssg(event): x = await event.get_reply_message() if x is None: return - to_send = event.raw_text who = event.sender_id - if x.fwd_from: - to_user = x.fwd_from.sender_id.user_id - else: - # this is a weird way of doing it - return if who == OWNER_ID: - if to_send.startswith("/"): + if event.text.startswith("/"): return - if event.text is not None and event.media: - # if sending media - bot_api_file_id = pack_bot_file_id(event.media) - await asst.send_file( - to_user, - file=bot_api_file_id, - caption=event.text, - reply_to=x.reply_to_msg_id, - ) + to_user = udB.get(str(x.id)) + 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(to_user, to_send, reply_to=x.reply_to_msg_id) + await asst.send_message(int(to_user), event.text) diff --git a/assistant/start.py b/assistant/start.py index b69c62e7ac40695c0b419c5683bd067564a4d5aa..1d0c38b79187e2dbba84d095ae00492c94219c1d 100644 --- a/assistant/start.py +++ b/assistant/start.py @@ -8,7 +8,8 @@ from datetime import datetime from pyUltroid.functions.asst_fns import * -from telethon import Button, custom, events +from pyUltroid.misc._decorators import sed +from telethon import Button, events from plugins import * @@ -18,17 +19,17 @@ from . import * @asst_cmd("start") async def assistant(event): if event.is_group and event.sender_id in sed: - return await eor(event, "`I dont work in groups`") + bnn = (await asst.get_me()).username + return await event.reply( + "`I dont work in groups`", + buttons=[Button.url("⚙️Sᴛᴀʀᴛ⚙️", url=f"https://t.me/{bnn}?start=set")], + ) else: if not is_added(event.sender_id) and event.sender_id not in sed: add_user(event.sender_id) - await asst.send_message( - OWNER_ID, - f"Bot started by [{event.sender_id}](tg://user?id={event.sender_id})", - ) ok = "" - if udB.get("MSG_FRWD") == True: - ok = "You can contact me using this bot!!" + if udB.get("PMBOT") == "True": + ok = "You can contact my master using this bot!!\n\nSend your Message, I will Deliver it To Master." if event.is_private and event.sender_id in sed: return await event.reply( @@ -37,9 +38,11 @@ async def assistant(event): ) -@asst_cmd("start") +@asst_cmd("start ?(.*)") @owner async def ultroid(event): + if event.pattern_match.group(1): + return if event.is_group: return name = event.sender.first_name @@ -88,7 +91,7 @@ async def botstat(event): ok = len(get_all_users()) msg = """Ultroid Assistant - Stats Total Users - {}""".format( - ok + ok, ) await event.answer(msg, cache_time=0, alert=True) @@ -100,7 +103,7 @@ async def bdcast(event): await event.edit(f"Broadcast to {len(ok)} users.") async with event.client.conversation(OWNER_ID) as conv: await conv.send_message( - "Enter your broadcast message.\nUse /cancel to stop the broadcast." + "Enter your broadcast message.\nUse /cancel to stop the broadcast.", ) response = conv.wait_event(events.NewMessage(chats=OWNER_ID)) response = await response @@ -125,7 +128,7 @@ async def bdcast(event): Broadcast completed in {time_taken} seconds. Total Users in Bot - {len(ok)} Sent to {success} users. -Failed for {fail} user(s).""" +Failed for {fail} user(s).""", ) @@ -135,12 +138,37 @@ async def setting(event): await event.edit( "Choose from the below options -", buttons=[ - [Button.inline("API Kᴇʏs", data="apiset")], + [ + Button.inline("API Kᴇʏs", data="apiset"), + Button.inline("Pᴍ Bᴏᴛ", data="chatbot"), + ], + [ + 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("« Bᴀᴄᴋ", data="mainmenu")], + ], + ) + + +@asst_cmd("start set") +@owner +async def set(event): + await event.reply( + "Choose from the below options -", + buttons=[ + [ + Button.inline("API Kᴇʏs", data="apiset"), + Button.inline("Pᴍ Bᴏᴛ", data="chatbot"), + ], [ 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("« Bᴀᴄᴋ", data="mainmenu")], ], ) diff --git a/assistant/ytdl.py b/assistant/ytdl.py index aa8a766cc28cad656da842a74ebf863ea62d697d..2bc87e73f13208133d6fdd48555250c37ddcfa6b 100644 --- a/assistant/ytdl.py +++ b/assistant/ytdl.py @@ -13,9 +13,9 @@ import time from pyUltroid.functions.all import * from telethon import Button +from telethon.errors import UserNotParticipantError from telethon.tl.types import DocumentAttributeAudio from telethon.tl.types import InputWebDocument as wb -from youtube_dl import YoutubeDL from youtubesearchpython import VideosSearch ytt = "https://telegra.ph/file/afd04510c13914a06dd03.jpg" @@ -65,14 +65,18 @@ async def _(event): ], [ Button.switch_inline( - "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", query="yt ", same_peer=True + "Sᴇᴀʀᴄʜ Aɢᴀɪɴ", + query="yt ", + same_peer=True, ), Button.switch_inline( - "Sʜᴀʀᴇ", query=f"yt {string}", same_peer=False + "Sʜᴀʀᴇ", + query=f"yt {string}", + same_peer=False, ), ], ], - ) + ), ) await event.answer(results) @@ -81,7 +85,7 @@ async def _(event): @owner async def _(sur): url = sur.pattern_match.group(1).decode("UTF-8") - getter = sur.sender_id + sur.sender_id opts = { "format": "bestaudio", "addmetadata": True, @@ -95,17 +99,14 @@ async def _(sur): "key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "320", - } + }, ], "outtmpl": "%(id)s.mp3", "quiet": True, "logtostderr": False, } song = True - await dler(sur) - with YoutubeDL(opts) as ytdl: - ytdl_data = ytdl.extract_info(url) - + ytdl_data = await dler(sur, opts, url) jpg = f"{ytdl_data['id']}.mp3.jpg" png = f"{ytdl_data['id']}.mp3.png" webp = f"{ytdl_data['id']}.mp3.webp" @@ -125,28 +126,58 @@ async def _(sur): await sur.edit( f"`Preparing to upload song:`\ \n**{ytdl_data['title']}**\ - \nby *{ytdl_data['uploader']}*" - ) - await asst.send_file( - getter, - f"{ytdl_data['id']}.mp3", - thumb=thumb, - caption=f"**{ytdl_data['title']}\n{time_formatter((ytdl_data['duration'])*1000)}\n{ytdl_data['uploader']}**", - supports_streaming=True, - attributes=[ - DocumentAttributeAudio( - duration=int(ytdl_data["duration"]), - title=str(ytdl_data["title"]), - performer=str(ytdl_data["uploader"]), - ) - ], - progress_callback=lambda d, t: asyncio.get_event_loop().create_task( - progress(d, t, sur, c_time, "Uploading..", f"{ytdl_data['title']}.mp3") - ), + \nby *{ytdl_data['uploader']}*", ) + MSG = f"**{ytdl_data['title']}** Uploaded Successfully !" + chat = sur.chat_id + whome = ultroid_bot + if sur.is_private and sur.sender_id != ultroid_bot.uid: + chat = sur.sender_id + whome = asst + MSG += f"\nGet at {Var.BOT_USERNAME}" + try: + await whome.send_file( + chat, + f"{ytdl_data['id']}.mp3", + thumb=thumb, + caption=f"**{ytdl_data['title']}\n{time_formatter((ytdl_data['duration'])*1000)}\n{ytdl_data['uploader']}**", + supports_streaming=True, + attributes=[ + DocumentAttributeAudio( + duration=int(ytdl_data["duration"]), + title=str(ytdl_data["title"]), + performer=str(ytdl_data["uploader"]), + ), + ], + progress_callback=lambda d, t: asyncio.get_event_loop().create_task( + progress( + d, + t, + sur, + c_time, + "Uploading..", + f"{ytdl_data['title']}.mp3", + ), + ), + ) + except UserNotParticipantError: + await asst.send_file( + sur.sender_id, + f"{ytdl_data['id']}.mp3", + thumb=thumb, + caption=f"**{ytdl_data['title']}\n{time_formatter((ytdl_data['duration'])*1000)}\n{ytdl_data['uploader']}**", + supports_streaming=True, + attributes=[ + DocumentAttributeAudio( + duration=int(ytdl_data["duration"]), + title=str(ytdl_data["title"]), + performer=str(ytdl_data["uploader"]), + ), + ], + ) os.system(f"rm {ytdl_data['id']}.mp*") await sur.edit( - f"Get Your requested file **{ytdl_data['title']}** from here {Var.BOT_USERNAME} ", + MSG, buttons=Button.switch_inline("Search More", query="yt ", same_peer=True), ) @@ -155,7 +186,8 @@ async def _(sur): @owner async def _(fuk): url = fuk.pattern_match.group(1).decode("UTF-8") - getter = fuk.sender_id + fuk.sender_id + event = fuk opts = { "format": "best", "addmetadata": True, @@ -170,29 +202,60 @@ async def _(fuk): "quiet": True, } video = True - await dler(fuk) - with YoutubeDL(opts) as ytdl: - ytdl_data = ytdl.extract_info(url) + ytdl_data = await dler(fuk, opts, url) c_time = time.time() if video: await fuk.edit( f"`Preparing to upload video:`\ \n**{ytdl_data['title']}**\ - \nby *{ytdl_data['uploader']}*" - ) - await asst.send_file( - getter, - f"{ytdl_data['id']}.mp4", - thumb=f"./resources/extras/ultroid.jpg", - caption=f"**{ytdl_data['title']}\n{time_formatter((ytdl_data['duration'])*1000)}\n{ytdl_data['uploader']}**", - supports_streaming=True, - progress_callback=lambda d, t: asyncio.get_event_loop().create_task( - progress(d, t, fuk, c_time, "Uploading..", f"{ytdl_data['title']}.mp4") - ), + \nby *{ytdl_data['uploader']}*", ) + MSG = f"**{ytdl_data['title']}** Uploaded Successfully !" + chat = fuk.chat_id + whome = ultroid_bot + if event.is_private and event.sender_id != ultroid_bot.uid: + chat = fuk.sender_id + whome = asst + MSG += f"\nGet at {Var.BOT_USERNAME}" + try: + await whome.send_file( + chat, + f"{ytdl_data['id']}.mp4", + thumb=f"./resources/extras/ultroid.jpg", + caption=f"**{ytdl_data['title']}\n{time_formatter((ytdl_data['duration'])*1000)}\n{ytdl_data['uploader']}**", + supports_streaming=True, + progress_callback=lambda d, t: asyncio.get_event_loop().create_task( + progress( + d, + t, + fuk, + c_time, + "Uploading..", + f"{ytdl_data['title']}.mp4", + ), + ), + ) + except UserNotParticipantError: + await asst.send_file( + chat, + f"{ytdl_data['id']}.mp4", + thumb=f"./resources/extras/ultroid.jpg", + caption=f"**{ytdl_data['title']}\n{time_formatter((ytdl_data['duration'])*1000)}\n{ytdl_data['uploader']}**", + supports_streaming=True, + progress_callback=lambda d, t: asyncio.get_event_loop().create_task( + progress( + d, + t, + fuk, + c_time, + "Uploading..", + f"{ytdl_data['title']}.mp4", + ), + ), + ) os.remove(f"{ytdl_data['id']}.mp4") await fuk.edit( - f"Get Your requested file **{ytdl_data['title']}** from here {Var.BOT_USERNAME} ", + MSG, buttons=Button.switch_inline("Search More", query="yt ", same_peer=True), ) diff --git a/commit b/commit new file mode 100644 index 0000000000000000000000000000000000000000..71d19aafa2b19ad23e6a4e1ffca9e8cd485a56e5 --- /dev/null +++ b/commit @@ -0,0 +1,2 @@ +Spam +dd diff --git a/heroku.yml b/heroku.yml index 09b09fc7936196c12850c07549f1decc84321cd9..2c9bc4b30092226ffbf8753e714f6833b516713f 100644 --- a/heroku.yml +++ b/heroku.yml @@ -1,3 +1,7 @@ -build: +build: docker: worker: Dockerfile + web: Dockerfile +run: + worker: bash resources/startup/startup.sh + web: python vcstarter.py diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..284722f0a48c8ea7a9d0a909e23214a9d7eeefb9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1816 @@ +{ + "name": "ultroid-vcbot", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@mapbox/node-pre-gyp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.1.tgz", + "integrity": "sha512-CUBdThIZMoLEQQxACwhLsPg/puxBca0abTH3ixuvBQkhjJ80Hdp99jmVjxFCOa52/tZqN9d70IbGUf+OuKDHGA==", + "requires": { + "detect-libc": "^1.0.3", + "http-proxy-agent": "^4.0.1", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@types/node": { + "version": "14.14.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz", + "integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==", + "dev": true + }, + "@types/redis": { + "version": "2.8.28", + "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.28.tgz", + "integrity": "sha512-8l2gr2OQ969ypa7hFOeKqtFoY70XkHxISV0pAwmQ2nm6CSPb1brmTmqJCGGrekCo+pAZyWlNXr+Kvo6L/1wijA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/ws": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@youtwitface/escape-html": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@youtwitface/escape-html/-/escape-html-1.1.3.tgz", + "integrity": "sha512-ZTE6NDvovm1S9jtzITZJvTiq4At09bDQjH4M/MNiZJq78LehIltGodCBZA5RROIE3bkQGJa9EwN37d5qgSFCfg==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "denque": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", + "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "optional": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "envalid": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/envalid/-/envalid-7.1.0.tgz", + "integrity": "sha512-C5rtCxfj+ozW5q79fBYKcBEf0KSNklKwZudjCzXy9ANT8Pz1MKxPBn6unZnYXXy6e+cqVgnEURQeXmdueG9/kA==" + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dev": true, + "requires": { + "ini": "1.3.7" + }, + "dependencies": { + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + } + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "nodemon": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", + "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-timeout": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", + "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==" + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "redis": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz", + "integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==", + "requires": { + "denque": "^1.4.1", + "redis-commands": "^1.5.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0" + } + }, + "redis-commands": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", + "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "requires": { + "redis-errors": "^1.0.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-compare": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-compare/-/safe-compare-1.1.4.tgz", + "integrity": "sha512-b9wZ986HHCo/HbKrRpBJb2kqXMK9CEWIE1egeEvZsYn69ay3kdfl9nG3RyOcR+jInTDf7a86WQ1d4VJX7goSSQ==", + "requires": { + "buffer-alloc": "^1.2.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sandwich-stream": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz", + "integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "telegraf": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.3.0.tgz", + "integrity": "sha512-MuDUtSMipzMzQp8fXbQx76jp4ZD70KREdnpH1idUzN9Zlgm6EzatBQFU4Ps0ipxtEmnBBdghBMumQwrjRe3eqg==", + "requires": { + "abort-controller": "^3.0.0", + "debug": "^4.3.1", + "minimist": "^1.2.5", + "module-alias": "^2.2.2", + "node-fetch": "^2.6.1", + "p-timeout": "^4.1.0", + "safe-compare": "^1.1.4", + "sandwich-stream": "^2.0.2", + "typegram": "^3.2.0" + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, + "tgcalls": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tgcalls/-/tgcalls-0.1.2.tgz", + "integrity": "sha512-b4hGcMPtTWn3pNY3GhgSh+fWHRO4seeoGBuTfg5CBQkD5LlSRYYqwjpAptaYzBJDgU4pDnwp8N+sBs05PwzuSw==", + "requires": { + "wrtc": "^0.4.7" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typegram": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/typegram/-/typegram-3.2.3.tgz", + "integrity": "sha512-zlkY7vNTLcwQhLUyYXAUzRelzH752LBFl8m4u04d5g5P7lM9bGegeIRwzd3mVCHJH6R3s48pKeFTVSdVlN+omg==" + }, + "typescript": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", + "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", + "dev": true + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "wrtc": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/wrtc/-/wrtc-0.4.7.tgz", + "integrity": "sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g==", + "requires": { + "domexception": "^1.0.1", + "node-pre-gyp": "^0.13.0" + }, + "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } + }, + "ws": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", + "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==" + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000000000000000000000000000000000..1fd21e963e1ed734fd71e4058af169a2fe852a10 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "ultroid-vcbot", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "node build/index.js", + "build": "tsc", + "test": "tsc --noEmit", + "dev": "nodemon src/index.ts" + }, + "author": "TeamUltroid ", + "license": "AGPL-3.0", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "@youtwitface/escape-html": "^1.0.0", + "dotenv": "^8.2.0", + "envalid": "^7.0.0", + "redis": "^3.0.2", + "telegraf": "^4.0.2", + "tgcalls": "^0.1.2", + "ws": "^7.4.3" + }, + "devDependencies": { + "@types/node": "^14.14.25", + "@types/redis": "^2.8.28", + "@types/ws": "^7.4.0", + "nodemon": "^2.0.7", + "ts-node": "^9.1.1", + "typegram": "^3.1.9", + "typescript": "^4.1.3" + } +} diff --git a/plugins/__init__.py b/plugins/__init__.py index 52cc236f8952ab813809eb7b245410cdb723363c..f8aff2750b6aec937368dd23d240d759a04671ff 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -14,14 +14,23 @@ from pyUltroid.functions import * from pyUltroid.functions.all import * from pyUltroid.functions.broadcast_db import * from pyUltroid.functions.gban_mute_db import * +from pyUltroid.functions.goodbye_db import * from pyUltroid.functions.google_image import googleimagesdownload from pyUltroid.functions.sudos import * +from pyUltroid.functions.welcome_db import * from pyUltroid.utils import * from strings import get_string +try: + import glitch_me +except ModuleNotFoundError: + os.system( + "git clone https://github.com/1Danish-00/glitch_me.git && pip install -e ./glitch_me" + ) + start_time = time.time() -ultroid_version = "v0.0.4" +ultroid_version = "v0.0.5" OWNER_NAME = ultroid_bot.me.first_name OWNER_ID = ultroid_bot.me.id diff --git a/plugins/_help.py b/plugins/_help.py index 684a92047b1185f3b91ef4cd59c1fd38b4dce585..801fdefbec9caa835cf99fcc4e96361d5a1eacbf 100644 --- a/plugins/_help.py +++ b/plugins/_help.py @@ -23,7 +23,7 @@ async def ult(ult): if plug: try: if plug in HELP: - output = "**Plugin** - `{}`\n".format(plug) + output = f"**Plugin** - `{plug}`\n" for i in HELP[plug]: output += i output += "\n© @TheUltroid" diff --git a/plugins/_inline.py b/plugins/_inline.py index a1abd8f2de250c671bf2b8a8f6e0b770a41ad96f..c067a98a90d02a65839c1c1a7e9d00c039a53ab6 100644 --- a/plugins/_inline.py +++ b/plugins/_inline.py @@ -13,6 +13,7 @@ from math import ceil from platform import python_version as pyver from git import Repo +from pyUltroid import __version__ as UltVer from support import * from telethon import Button, __version__ from telethon.tl.types import InputWebDocument @@ -20,8 +21,8 @@ from telethon.tl.types import InputWebDocument from . import * # ================================================# -notmine = "This bot is for {}".format(OWNER_NAME) -ULTROID_PIC = "https://telegra.ph/file/11245cacbffe92e5d5b14.jpg" +notmine = f"This bot is for {OWNER_NAME}" +ULTROID_PIC = "https://telegra.ph/file/031957757a4f6a5191040.jpg" helps = get_string("inline_1") add_ons = udB.get("ADDONS") @@ -37,17 +38,20 @@ else: async def e(o): if len(o.text) == 0: b = o.builder - uptime = grt((time.time() - start_time)) + uptime = grt(time.time() - start_time) + header = udB.get("ALIVE_TEXT") if udB.get("ALIVE_TEXT") else "Hey, I am alive." ALIVEMSG = get_string("alive_1").format( + header, OWNER_NAME, ultroid_version, + UltVer, uptime, pyver(), __version__, Repo().active_branch, ) res = [ - await b.article( + await b.article( title="Ultroid Userbot", url="https://t.me/TeamUltroid", description="Userbot | Telethon ", @@ -57,11 +61,12 @@ async def e(o): [Button.url(text="Support Group", url="t.me/UltroidSupport")], [ Button.url( - text="Repo", url="https://github.com/Teamultroid/Ultroid" - ) + text="Repo", + url="https://github.com/Teamultroid/Ultroid", + ), ], ], - ) + ), ] await o.answer(res, switch_pm=f"👥 ULTROID PORTAL", switch_pm_param="start") @@ -91,7 +96,10 @@ if Var.BOT_USERNAME is not None and asst is not None: url="https://t.me/TheUltroid", thumb=InputWebDocument(ULTROID_PIC, 0, "image/jpeg", []), text=get_string("inline_4").format( - OWNER_NAME, len(PLUGINS) - 5, len(ADDONS), cmd + OWNER_NAME, + len(PLUGINS) - 5, + len(ADDONS), + cmd, ), buttons=[ [ @@ -105,8 +113,8 @@ if Var.BOT_USERNAME is not None and asst is not None: [ Button.url( "⚙️Sᴇᴛᴛɪɴɢs⚙️", - url=f"https://t.me/{bnn}?start={ultroid_bot.me.id}", - ) + url=f"https://t.me/{bnn}?start=set", + ), ], [Button.inline("••Cʟᴏꜱᴇ••", data="close")], ], @@ -123,7 +131,7 @@ if Var.BOT_USERNAME is not None and asst is not None: [ Button.url("NekoBin", url=f"{link}"), Button.url("Raw", url=f"{link_raw}"), - ] + ], ], ) await event.answer([result] if result else None) @@ -154,7 +162,7 @@ if Var.BOT_USERNAME is not None and asst is not None: @callback("upp") async def _(event): - uptime = grt((time.time() - start_time)) + uptime = grt(time.time() - start_time) pin = f"🙋Uᴘᴛɪᴍᴇ = {uptime}" await event.answer(pin, cache_time=0, alert=True) @@ -167,7 +175,7 @@ if Var.BOT_USERNAME is not None and asst is not None: "Sᴇɴᴅ Oғғɪᴄɪᴀʟ Pʟᴜɢɪɴs", query="send", same_peer=True, - ) + ), ], [ Button.switch_inline( @@ -198,7 +206,7 @@ if Var.BOT_USERNAME is not None and asst is not None: "YᴏᴜTᴜʙᴇ Dᴏᴡɴʟᴏᴀᴅᴇʀ", query="yt Ed Sheeran Perfect", same_peer=True, - ) + ), ], [ Button.switch_inline( @@ -212,11 +220,18 @@ if Var.BOT_USERNAME is not None and asst is not None: same_peer=True, ), ], + [ + Button.switch_inline( + "OʀᴀɴɢᴇFᴏx🦊Rᴇᴄᴏᴠᴇʀʏ", + query="ofox beryllium", + same_peer=True, + ), + ], [ Button.inline( "<- Bᴀᴄᴋ", data="open", - ) + ), ], ] await e.edit(buttons=button, link_preview=False) @@ -326,8 +341,9 @@ if Var.BOT_USERNAME is not None and asst is not None: ], [ Button.url( - "⚙️Sᴇᴛᴛɪɴɢs⚙️", url=f"https://t.me/{bnn}?start={ultroid_bot.me.id}" - ) + "⚙️Sᴇᴛᴛɪɴɢs⚙️", + url=f"https://t.me/{bnn}?start={ultroid_bot.me.id}", + ), ], [Button.inline("••Cʟᴏꜱᴇ••", data="close")], ] @@ -338,7 +354,10 @@ if Var.BOT_USERNAME is not None and asst is not None: cmd = len(z) + 10 await event.edit( get_string("inline_4").format( - OWNER_NAME, len(PLUGINS) - 5, len(ADDONS), cmd + OWNER_NAME, + len(PLUGINS) - 5, + len(ADDONS), + cmd, ), buttons=buttons, link_preview=False, @@ -367,10 +386,10 @@ if Var.BOT_USERNAME is not None and asst is not None: except BaseException: pass if help_string == "": - reply_pop_up_alert = "{} has no detailed help...".format(plugin_name) + reply_pop_up_alert = f"{plugin_name} has no detailed help..." else: reply_pop_up_alert = help_string - reply_pop_up_alert += "\n© @TheUltroid" + reply_pop_up_alert += "\n© @TeamUltroid" try: if event.query.user_id in sed: await event.edit( @@ -384,7 +403,7 @@ if Var.BOT_USERNAME is not None and asst is not None: reply_pop_up_alert = notmine await event.answer(reply_pop_up_alert, cache_time=0) except BaseException: - halps = "Do .help {} to get the list of commands.".format(plugin_name) + halps = f"Do .help {plugin_name} to get the list of commands." await event.edit(halps) @callback( @@ -418,10 +437,10 @@ if Var.BOT_USERNAME is not None and asst is not None: except BaseException: pass if help_string == "": - reply_pop_up_alert = "{} has no detailed help...".format(plugin_name) + reply_pop_up_alert = f"{plugin_name} has no detailed help..." else: reply_pop_up_alert = help_string - reply_pop_up_alert += "\n© @TheUltroid" + reply_pop_up_alert += "\n© @TeamUltroid" try: if event.query.user_id in sed: await event.edit( @@ -435,7 +454,7 @@ if Var.BOT_USERNAME is not None and asst is not None: reply_pop_up_alert = notmine await event.answer(reply_pop_up_alert, cache_time=0) except BaseException: - halps = "Do .help {} to get the list of commands.".format(plugin_name) + halps = f"Do .help {plugin_name} to get the list of commands." await event.edit(halps) @@ -457,9 +476,11 @@ def paginate_help(page_number, loaded_plugins, prefix): modules = [ Button.inline( "{} {} {}".format( - random.choice(list(multi)), x, random.choice(list(mult2i)) + random.choice(list(multi)), + x, + random.choice(list(mult2i)), ), - data="us_plugin_{}".format(x), + data=f"us_plugin_{x}", ) for x in helpable_plugins ] @@ -474,13 +495,15 @@ def paginate_help(page_number, loaded_plugins, prefix): ] + [ ( Button.inline( - "<- Pʀᴇᴠɪᴏᴜs", data="{}_prev({})".format(prefix, modulo_page) + "<- Pʀᴇᴠɪᴏᴜs", + data=f"{prefix}_prev({modulo_page})", ), Button.inline("-Bᴀᴄᴋ-", data="open"), Button.inline( - "Nᴇxᴛ ->", data="{}_next({})".format(prefix, modulo_page) + "Nᴇxᴛ ->", + data=f"{prefix}_next({modulo_page})", ), - ) + ), ] else: pairs = pairs[ @@ -507,9 +530,11 @@ def paginate_addon(page_number, loaded_plugins, prefix): modules = [ Button.inline( "{} {} {}".format( - random.choice(list(multi)), x, random.choice(list(mult2i)) + random.choice(list(multi)), + x, + random.choice(list(mult2i)), ), - data="add_plugin_{}".format(x), + data=f"add_plugin_{x}", ) for x in helpable_plugins ] @@ -524,13 +549,15 @@ def paginate_addon(page_number, loaded_plugins, prefix): ] + [ ( Button.inline( - "<- Pʀᴇᴠɪᴏᴜs", data="{}_prev({})".format(prefix, modulo_page) + "<- Pʀᴇᴠɪᴏᴜs", + data=f"{prefix}_prev({modulo_page})", ), Button.inline("-Bᴀᴄᴋ-", data="open"), Button.inline( - "Nᴇxᴛ ->", data="{}_next({})".format(prefix, modulo_page) + "Nᴇxᴛ ->", + data=f"{prefix}_next({modulo_page})", ), - ) + ), ] else: pairs = pairs[ diff --git a/plugins/_tagnotifs.py b/plugins/_tagnotifs.py index b800d37b274b1d4fc7704264872727b0231573ed..ed1e7b2b4f8eb650b3f526c4b5e97df69300d672 100644 --- a/plugins/_tagnotifs.py +++ b/plugins/_tagnotifs.py @@ -15,24 +15,33 @@ from . import * events.NewMessage( incoming=True, func=lambda e: (e.mentioned), - ) + ), ) async def all_messages_catcher(e): if udB.get("TAG_LOG") is not None: NEEDTOLOG = int(udB.get("TAG_LOG")) x = await ultroid_bot.get_entity(e.sender_id) - if x.bot: + if x.bot or x.verified: return y = await ultroid_bot.get_entity(e.chat_id) + if y.username: + yy = f"[{get_display_name(y)}](https://t.me/{y.username})" + else: + yy = f"[{get_display_name(y)}](https://t.me/c/{y.id}/{e.id})" xx = f"[{get_display_name(x)}](tg://user?id={x.id})" - yy = f"[{get_display_name(y)}](https://t.me/c/{y.id})" msg = f"https://t.me/c/{y.id}/{e.id}" if e.text: cap = f"{xx} tagged you in {yy}\n\n```{e.text}```\nㅤ" else: cap = f"{xx} tagged you in {yy}" + btx = "📨 View Message" + try: + if e.text: + cap = get_string("tagnot_1").format(xx, yy, e.text, msg) + else: + cap = get_string("tagnot_2").format(xx, yy, msg) await asst.send_message( NEEDTOLOG, cap, diff --git a/plugins/_wspr.py b/plugins/_wspr.py index 4562241c8712c048d0f4b4d3e3b6d22989dc23cf..07febd5363bf0361fda251a76515cbc67fe1ddc0 100644 --- a/plugins/_wspr.py +++ b/plugins/_wspr.py @@ -18,6 +18,7 @@ from telethon.tl.types import UserStatusLastWeek as lw from telethon.tl.types import UserStatusOffline as off from telethon.tl.types import UserStatusOnline as on from telethon.tl.types import UserStatusRecently as rec + from . import * snap = {} @@ -98,7 +99,9 @@ async def _(e): button = [ Button.url("Private", url=f"t.me/{username}"), Button.switch_inline( - "Secret msg", query=f"msg {query} wspr ", same_peer=True + "Secret msg", + query=f"msg {query} wspr ", + same_peer=True, ), ] sur = e.builder.article( @@ -132,7 +135,8 @@ async def _(e): snap.update({logi.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=f"You Didn't Type Your Msg", ) await e.answer([sur]) diff --git a/plugins/admintools.py b/plugins/admintools.py index 9f40be2da15e2fd433e49f070f3bdad59adfccae..964d9a377e968a3aa889019d5acf43783e4458c7 100644 --- a/plugins/admintools.py +++ b/plugins/admintools.py @@ -50,8 +50,8 @@ import asyncio from telethon.errors import BadRequestError from telethon.errors.rpcerrorlist import UserIdInvalidError -from telethon.tl.functions.channels import EditAdminRequest, EditBannedRequest -from telethon.tl.types import ChatAdminRights, ChatBannedRights +from telethon.tl.functions.channels import EditAdminRequest +from telethon.tl.types import ChatAdminRights from . import * @@ -59,15 +59,11 @@ from . import * @ultroid_cmd( pattern="promote ?(.*)", groups_only=True, + admins_only=True, ) async def prmte(ult): xx = await eor(ult, get_string("com_1")) - chat = await ult.get_chat() - isAdmin = chat.admin_rights - isCreator = chat.creator - if not isAdmin and not isCreator: - return await xx.edit("`Hmm, I'm not an admin here...`") - await xx.edit("`Promoting...`") + await ult.get_chat() user, rank = await get_user_info(ult) if not rank: rank = "Admin" @@ -87,10 +83,10 @@ async def prmte(ult): pin_messages=True, ), rank, - ) + ), ) await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) `is now an admin in {ult.chat.title} with title {rank}.`" + f"[{user.first_name}](tg://user?id={user.id}) `is now an admin in {ult.chat.title} with title {rank}.`", ) except BadRequestError: return await xx.edit("`I don't have the right to promote you.`") @@ -101,15 +97,11 @@ async def prmte(ult): @ultroid_cmd( pattern="demote ?(.*)", groups_only=True, + admins_only=True, ) async def dmote(ult): xx = await eor(ult, get_string("com_1")) - chat = await ult.get_chat() - isAdmin = chat.admin_rights - isCreator = chat.creator - if not isAdmin and not isCreator: - return await xx.edit("`Hmm, I'm not an admin here...`") - await xx.edit("`Demoting...`") + await ult.get_chat() user, rank = await get_user_info(ult) if not rank: rank = "Not Admin" @@ -129,10 +121,10 @@ async def dmote(ult): pin_messages=None, ), rank, - ) + ), ) await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) `is no longer an admin in {ult.chat.title}`" + f"[{user.first_name}](tg://user?id={user.id}) `is no longer an admin in {ult.chat.title}`", ) except BadRequestError: return await xx.edit("`I don't have the right to demote you.`") @@ -143,31 +135,18 @@ async def dmote(ult): @ultroid_cmd( pattern="ban ?(.*)", groups_only=True, + admins_only=True, ) async def bban(ult): xx = await eor(ult, get_string("com_1")) - chat = await ult.get_chat() - isAdmin = chat.admin_rights - isCreator = chat.creator - if not isAdmin and not isCreator: - return await xx.edit("`Hmm, I'm not an admin here...`") + await ult.get_chat() user, reason = await get_user_info(ult) if not user: return await xx.edit("`Reply to a user or give username to ban him!`") if str(user.id) in DEVLIST: return await xx.edit(" `LoL, I can't Ban my Developer 😂`") - await xx.edit("`Getting user info...`") try: - await ultroid_bot( - EditBannedRequest( - ult.chat_id, - user.id, - ChatBannedRights( - until_date=None, - view_messages=True, - ), - ) - ) + await ultroid_bot.edit_permissions(ult.chat_id, user.id, view_messages=False) except BadRequestError: return await xx.edit("`I don't have the right to ban a user.`") except UserIdInvalidError: @@ -178,82 +157,62 @@ async def bban(ult): await reply.delete() except BadRequestError: return await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) **was banned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`\n**Reason**: `{reason}`\n**Messages Deleted**: `False`" + f"[{user.first_name}](tg://user?id={user.id}) **was banned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`\n**Reason**: `{reason}`\n**Messages Deleted**: `False`", ) if reason: await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) **was banned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`\n**Reason**: `{reason}`" + f"[{user.first_name}](tg://user?id={user.id}) **was banned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`\n**Reason**: `{reason}`", ) else: await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) **was banned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`" + f"[{user.first_name}](tg://user?id={user.id}) **was banned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`", ) @ultroid_cmd( pattern="unban ?(.*)", groups_only=True, + admins_only=True, ) async def uunban(ult): xx = await eor(ult, get_string("com_1")) - chat = await ult.get_chat() - isAdmin = chat.admin_rights - isCreator = chat.creator - if not isAdmin and not isCreator: - return await xx.edit("`Hmm, I'm not an admin here...`") + await ult.get_chat() user, reason = await get_user_info(ult) if not user: return await xx.edit("`Reply to a user or give username to unban him!`") - await xx.edit("`Getting user info...`") try: - await ultroid_bot( - EditBannedRequest( - ult.chat_id, - user.id, - ChatBannedRights( - until_date=None, - view_messages=None, - ), - ) - ) + await ultroid_bot.edit_permissions(ult.chat_id, user.id, view_messages=True) except BadRequestError: return await xx.edit("`I don't have the right to unban a user.`") except UserIdInvalidError: await xx.edit("`I couldn't get who he is!`") if reason: await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) **was unbanned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`\n**Reason**: `{reason}`" + f"[{user.first_name}](tg://user?id={user.id}) **was unbanned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`\n**Reason**: `{reason}`", ) else: await xx.edit( - f"[{user.first_name}](tg://user?id={user.id}) **was unbanned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`" + f"[{user.first_name}](tg://user?id={user.id}) **was unbanned by** [{OWNER_NAME}](tg://user?id={OWNER_ID}) **in** `{ult.chat.title}`", ) @ultroid_cmd( pattern="kick ?(.*)", groups_only=True, + admins_only=True, ) async def kck(ult): - tt = ult.text - try: - tx = tt[5] - if tx: - return - except BaseException: - pass + if ult.text == f"{HNDLR}kickme": + return xx = await eor(ult, get_string("com_1")) - chat = await ult.get_chat() - isAdmin = chat.admin_rights - isCreator = chat.creator - if not isAdmin and not isCreator: - return await xx.edit("`Hmm, I'm not an admin here...`") + await ult.get_chat() user, reason = await get_user_info(ult) if not user: return await xx.edit("`Kick? Whom? I couldn't get his info...`") if str(user.id) in DEVLIST: return await xx.edit(" `Lol, I can't Kick my Developer`😂") - await xx.edit("`Kicking...`") + if user.id == ultroid_bot.uid: + return await xx.edit("`You Can't kick urself`") try: await ultroid_bot.kick_participant(ult.chat_id, user.id) await asyncio.sleep(0.5) @@ -261,15 +220,15 @@ async def kck(ult): return await xx.edit("`I don't have the right to kick a user.`") except Exception as e: return await xx.edit( - f"`I don't have the right to kick a user.`\n\n**ERROR**:\n`{str(e)}`" + f"`I don't have the right to kick a user.`\n\n**ERROR**:\n`{str(e)}`", ) if reason: await xx.edit( - f"[{user.first_name}](tg://user?id={user.id})` was kicked by` [{OWNER_NAME}](tg://user?id={OWNER_ID}) `in {ult.chat.title}`\n**Reason**: `{reason}`" + f"[{user.first_name}](tg://user?id={user.id})` was kicked by` [{OWNER_NAME}](tg://user?id={OWNER_ID}) `in {ult.chat.title}`\n**Reason**: `{reason}`", ) else: await xx.edit( - f"[{user.first_name}](tg://user?id={user.id})` was kicked by` [{OWNER_NAME}](tg://user?id={OWNER_ID}) `in {ult.chat.title}`" + f"[{user.first_name}](tg://user?id={user.id})` was kicked by` [{OWNER_NAME}](tg://user?id={OWNER_ID}) `in {ult.chat.title}`", ) @@ -367,7 +326,11 @@ async def fastpurger(purg): await ultroid_bot.delete_messages(chat, msgs) done = await ultroid_bot.send_message( purg.chat_id, - "__Fast purge complete!__\n**Purged** `" + str(count) + "` **messages.**", + "__Fast purge complete!__\n**Purged** `" + + str(len(msgs)) + + "` **of** `" + + str(count) + + "` **messages.**", ) await asyncio.sleep(5) await done.delete() @@ -383,7 +346,9 @@ async def fastpurgerme(purg): if not purg.reply_to_msg_id: return await eod(purg, "`Reply to a message to purge from.`", time=10) async for msg in ultroid_bot.iter_messages( - chat, from_user="me", min_id=purg.reply_to_msg_id + chat, + from_user="me", + min_id=purg.reply_to_msg_id, ): msgs.append(msg) count = count + 1 @@ -409,14 +374,14 @@ async def _(e): xx = await eor(e, get_string("com_1")) if e.reply_to_msg_id: input = (await e.get_reply_message()).sender_id - (await e.client.get_entity(input)).first_name + name = (await e.client.get_entity(input)).first_name try: nos = 0 async for x in e.client.iter_messages(e.chat_id, from_user=input): await e.client.delete_messages(e.chat_id, x) nos += 1 await xx.edit( - f"**Purged **`{nos}`** msgs of **[{input}](tg://user?id={input})" + f"**Purged **`{nos}`** msgs of **[{name}](tg://user?id={input})", ) except ValueError: return await eod(xx, str(er), time=5) diff --git a/plugins/afk.py b/plugins/afk.py index 0c1ffcf3c84433171d068dde9d6c049be69ad85f..e7599ae5bd604f8f5b6157f65389f4f638a276d1 100644 --- a/plugins/afk.py +++ b/plugins/afk.py @@ -18,6 +18,7 @@ import asyncio from datetime import datetime +from pyUltroid.functions.pmpermit_db import * from telethon import events from telethon.tl import functions, types @@ -49,7 +50,7 @@ async def set_not_afk(event): back_alive = datetime.now() afk_end = back_alive.replace(microsecond=0) if afk_start != {}: - total_afk_time = str((afk_end - afk_start)) + total_afk_time = str(afk_end - afk_start) current_message = event.message.message if "afk" not in current_message and "yes" in USER_AFK: try: @@ -67,7 +68,8 @@ async def set_not_afk(event): ) except BaseException: shite = await ultroid_bot.send_message( - event.chat_id, get_string("afk_1").format(total_afk_time) + event.chat_id, + get_string("afk_1").format(total_afk_time), ) try: try: @@ -101,11 +103,14 @@ async def set_not_afk(event): @ultroid_bot.on( - events.NewMessage(incoming=True, func=lambda e: bool(e.mentioned or e.is_private)) + events.NewMessage(incoming=True, func=lambda e: bool(e.mentioned or e.is_private)), ) async def on_afk(event): if event.fwd_from: return + if event.is_private: + if not is_approved(event.chat_id): + return global USER_AFK global afk_time global last_afk_message @@ -114,11 +119,12 @@ async def on_afk(event): back_alivee = datetime.now() afk_end = back_alivee.replace(microsecond=0) if afk_start != {}: - total_afk_time = str((afk_end - afk_start)) + total_afk_time = str(afk_end - afk_start) current_message_text = event.message.message.lower() if "afk" in current_message_text: return False - if USER_AFK and not (await event.get_sender()).bot: + sender = await event.get_sender() + if USER_AFK and not (sender.bot or sender.verified): msg = None if reason: message_to_reply = get_string("afk_3").format(total_afk_time, reason) @@ -175,7 +181,7 @@ async def _(event): pic = None if not USER_AFK: last_seen_status = await ultroid_bot( - functions.account.GetPrivacyRequest(types.InputPrivacyKeyStatusTimestamp()) + functions.account.GetPrivacyRequest(types.InputPrivacyKeyStatusTimestamp()), ) if isinstance(last_seen_status.rules, types.PrivacyValueAllowAll): afk_time = datetime.datetime.now() @@ -185,15 +191,19 @@ async def _(event): if pic.endswith((".tgs", ".webp")): await ultroid_bot.send_message(event.chat_id, file=pic) await ultroid_bot.send_message( - event.chat_id, get_string("afk_5").format(reason) + event.chat_id, + get_string("afk_5").format(reason), ) else: await ultroid_bot.send_message( - event.chat_id, get_string("afk_5").format(reason), file=pic + event.chat_id, + get_string("afk_5").format(reason), + file=pic, ) except BaseException: await ultroid_bot.send_message( - event.chat_id, get_string("afk_5").format(reason) + event.chat_id, + get_string("afk_5").format(reason), ) else: try: @@ -202,7 +212,9 @@ async def _(event): await ultroid_bot.send_message(event.chat_id, get_string("afk_6")) else: await ultroid_bot.send_message( - event.chat_id, get_string("afk_6"), file=pic + event.chat_id, + get_string("afk_6"), + file=pic, ) except BaseException: await ultroid_bot.send_message(event.chat_id, get_string("afk_6")) @@ -212,11 +224,14 @@ async def _(event): if pic.endswith((".tgs", ".webp")): await ultroid_bot.send_message(LOG, file=pic) await ultroid_bot.send_message( - LOG, get_string("afk_7").format(reason) + LOG, + get_string("afk_7").format(reason), ) else: await ultroid_bot.send_message( - LOG, get_string("afk_7").format(reason), file=pic + LOG, + get_string("afk_7").format(reason), + file=pic, ) elif reason: await ultroid_bot.send_message(LOG, get_string("afk_7").format(reason)) diff --git a/plugins/autocorrect.py b/plugins/autocorrect.py new file mode 100644 index 0000000000000000000000000000000000000000..089f95e72ad886f38ebba866976e4c54dba3f3ca --- /dev/null +++ b/plugins/autocorrect.py @@ -0,0 +1,53 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available + +• `{i}autocorrect` + To on/off Autocorrect Feature. + +""" + +from gingerit.gingerit import GingerIt +from googletrans import Translator +from telethon import events + +from . import * + +tr = Translator() + + +@ultroid_cmd(pattern="autocorrect") +async def acc(e): + if Redis("AUTOCORRECT") != "True": + udB.set("AUTOCORRECT", "True") + await eor(e, "AUTOCORRECT Feature On") + else: + udB.delete("AUTOCORRECT") + await eor(e, "AUTOCORRECT Feature Off") + + +@ultroid_bot.on(events.NewMessage(outgoing=True)) +async def gramme(event): + if Redis("AUTOCORRECT") != "True": + return + t = event.text + tt = tr.translate(t) + if t.startswith((HNDLR, ".", "?", "#", "_", "*", "'", "@", "[", "(", "+")): + return + if t.endswith(".."): + return + if tt.src != "en": + return + xx = GingerIt() + x = xx.parse(t) + res = x["result"] + await event.edit(res) + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/autopic.py b/plugins/autopic.py index 8246e45879f1f2d8d6188bdbeedc96d8b8abfade..2058110d913510cccd980126707ef152392d527e 100644 --- a/plugins/autopic.py +++ b/plugins/autopic.py @@ -28,17 +28,17 @@ from . import * async def autopic(e): search = e.pattern_match.group(1) if not search: - return await eor(get_string("autopic_1")) + return await eor(e, get_string("autopic_1")) clls = returnpage(search) if len(clls) == 0: - return await eor(get_string("autopic_2").format(search)) + return await eor(e, get_string("autopic_2").format(search)) if not len(clls) == 1: num = random.randrange(0, len(clls) - 1) else: num = 0 page = clls[num] title = page["title"] - await eor(get_string("autopic_3").format(title)) + await eor(e, get_string("autopic_3").format(title)) udB.set("AUTOPIC", "True") while True: ge = udB.get("AUTOPIC") diff --git a/plugins/blacklist.py b/plugins/blacklist.py new file mode 100644 index 0000000000000000000000000000000000000000..ee902416ecf9f64bbb6348dc0c444199de1f10e8 --- /dev/null +++ b/plugins/blacklist.py @@ -0,0 +1,104 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +• `{i}blacklist ` + blacklist the choosen word in that chat. + +• `{i}remblacklist ` + Remove the word from blacklist.. + +• `{i}listblacklist` + list all blacklisted words. + + 'if a person uses blacklist Word his/her msg will be deleted' + 'And u Must be Admin in that Chat' +""" + +import re + +from pyUltroid.functions.blacklist_db import * +from telethon.tl.types import ChannelParticipantsAdmins + +from . import * + + +@ultroid_cmd(pattern="blacklist ?(.*)") +async def af(e): + if e.is_group: + if not e._chat.admin_rights: + return await eod(e, "`You are Not Admin Here`") + wrd = e.pattern_match.group(1) + chat = e.chat_id + if not (wrd): + return await eod(e, "`Give the word to blacklist..`") + wrd = e.text[10:] + add_blacklist(int(chat), wrd) + await eor(e, f"Done : `{wrd}` Blacklisted here.") + + +@ultroid_cmd(pattern="remblacklist ?(.*)") +async def rf(e): + if e.is_group: + if not e._chat.admin_rights: + return await eod(e, "`You are Not Admin Here`") + wrd = e.pattern_match.group(1) + chat = e.chat_id + if not wrd: + return await eod(e, "`Give the word to remove from blacklist..`") + rem_blacklist(int(chat), wrd) + await eor(e, f"Done : `{wrd}` Removed from Blacklist.") + + +@ultroid_cmd(pattern="listblacklist") +async def lsnote(e): + if e.is_group: + if not e._chat.admin_rights: + return await eod(e, "`You are Not Admin Here`") + x = list_blacklist(e.chat_id) + if x: + sd = "Blacklist Found In This Chats Are\n\n" + await eor(e, sd + x) + else: + await eor(e, "No Blacklist word Found Here") + + +@ultroid_bot.on(events.NewMessage(incoming=True)) +async def bl(e): + if e.is_group: + if not e._chat.admin_rights: + return + xx = e.text + chat = e.chat_id + x = get_blacklist(int(chat)) + if x and xx: + if " " in xx: + xx = xx.split(" ") + kk = "" + for c in xx: + kk = re.search(str(c), str(x), flags=re.IGNORECASE) + if kk: + async for l in ultroid_bot.iter_participants( + e.chat_id, filter=ChannelParticipantsAdmins + ): + if l.id == e.sender_id: + return + await e.delete() + else: + k = re.search(xx, x, flags=re.IGNORECASE) + if k: + async for l in ultroid_bot.iter_participants( + e.chat_id, filter=ChannelParticipantsAdmins + ): + if l.id == e.sender_id: + return + await e.delete() + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/bot.py b/plugins/bot.py index 4faab45606bf4b0f1a5ae4d1f9abc4c9d8c9ee76..c81504374ba37f554d95f528cdac87cb876177bf 100644 --- a/plugins/bot.py +++ b/plugins/bot.py @@ -18,6 +18,7 @@ View all plugin names. • `{i}restart` + s - soft restart To restart your bot. • `{i}logs` @@ -30,9 +31,7 @@ Turn off your bot. """ -import asyncio import math -import os import shutil import time from datetime import datetime as dt @@ -42,7 +41,10 @@ import heroku3 import psutil import requests from git import Repo +from pyUltroid import __version__ as UltVer +from search_engine_parser.core.utils import get_rand_user_agent as grua from telethon import __version__ +from telethon.errors.rpcerrorlist import ChatSendMediaForbiddenError from . import * @@ -66,26 +68,37 @@ except BaseException: ) async def lol(ult): pic = udB.get("ALIVE_PIC") - uptime = grt((time.time() - start_time)) + uptime = grt(time.time() - start_time) header = udB.get("ALIVE_TEXT") if udB.get("ALIVE_TEXT") else "Hey, I am alive." + y = Repo().active_branch + xx = Repo().remotes[0].config_reader.get("url") + rep = xx.replace(".git", f"/tree/{y}") + kk = f" `[{y}]({rep})` " als = (get_string("alive_1")).format( header, OWNER_NAME, ultroid_version, + UltVer, uptime, pyver(), __version__, - Repo().active_branch, + kk, ) if pic is None: - await ult.edit(als) + return await eor(ult, als) elif pic is not None and "telegra" in pic: - await ult.delete() - await ult.reply(als, file=pic) + try: + await ult.reply(als, file=pic) + await ult.delete() + except ChatSendMediaForbiddenError: + await eor(ult, als) else: - await ult.delete() - await ultroid_bot.send_message(ult.chat_id, file=pic) - await ultroid_bot.send_message(ult.chat_id, als) + try: + await ultroid_bot.send_message(ult.chat_id, file=pic) + await ultroid_bot.send_message(ult.chat_id, als) + await ult.delete() + except ChatSendMediaForbiddenError: + await eor(ult, als) @ultroid_cmd( @@ -94,11 +107,9 @@ async def lol(ult): async def _(event): start = dt.now() x = await eor(event, "`Pong !`") - if event.fwd_from: - return end = dt.now() ms = (end - start).microseconds / 1000 - uptime = grt((time.time() - start_time)) + uptime = grt(time.time() - start_time) await x.edit(get_string("ping").format(ms, uptime)) @@ -121,41 +132,32 @@ async def restartbt(ult): ) async def _(ult): xx = await eor(ult, "`Processing...`") - if HEROKU_API is None and HEROKU_APP_NAME is None: - return await xx.edit("Please set `HEROKU_APP_NAME` and `HEROKU_API` in vars.") - await xx.edit("`Downloading Logs...`") - with open("logs-ultroid.txt", "w") as log: - log.write(app.get_log()) - ok = app.get_log() + with open("ultroid.log") as f: + k = f.read() key = ( - requests.post("https://nekobin.com/api/documents", json={"content": ok}) + requests.post("https://nekobin.com/api/documents", json={"content": k}) .json() .get("result") .get("key") ) url = f"https://nekobin.com/{key}" - await ult.client.send_file( + await ultroid.send_file( ult.chat_id, - "logs-ultroid.txt", - reply_to=ult.id, - caption=get_string("log").format(url), + file="ultroid.log", + caption=f"**Ultroid Logs.**\nPasted [here](https://nekobin.com/{key}) too!", ) - await xx.edit("`Uploading...`") - await asyncio.sleep(1) + await xx.edit("Done") await xx.delete() - return os.remove("logs-ultroid.txt") @ultroid_cmd( pattern="usage$", ) async def dyno_usage(dyno): + if not HEROKU_API and HEROKU_APP_NAME: + return dyn = await eor(dyno, "`Processing...`") - useragent = ( - "Mozilla/5.0 (Linux; Android 10; SM-G975F) " - "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/80.0.3987.149 Mobile Safari/537.36" - ) + useragent = grua() user_id = Heroku.account().id headers = { "User-Agent": useragent, @@ -166,7 +168,7 @@ async def dyno_usage(dyno): r = requests.get(heroku_api + path, headers=headers) if r.status_code != 200: return await dyno.edit( - "`Error: something bad happened`\n\n" f">.`{r.reason}`\n" + "`Error: something bad happened`\n\n" f">.`{r.reason}`\n", ) result = r.json() quota = result["account_quota"] diff --git a/plugins/broadcast.py b/plugins/broadcast.py index 9394a6b35d06453ec2c213611becddddd68888c7..c75ae9c138b3582253019d14befd4026cb0dc269 100644 --- a/plugins/broadcast.py +++ b/plugins/broadcast.py @@ -23,6 +23,7 @@ • `{i}listchannels` To get list of all added chats. """ + import asyncio import io @@ -31,7 +32,7 @@ from . import * @ultroid_cmd(pattern="add ?(.*)", allow_sudo=False) async def broadcast_adder(event): - if "addsudo" in event.text: # weird fix + if not event.text[4] == " ": # weird fix return msgg = event.pattern_match.group(1) x = await eor(event, get_string("bd_1")) @@ -92,6 +93,8 @@ async def broadcast_adder(event): @ultroid_cmd(pattern="rem ?(.*)", allow_sudo=False) async def broadcast_remover(event): + if not event.text[4] == " ": # weird fix + return chat_id = event.pattern_match.group(1) x = await eor(event, get_string("com_1")) if chat_id == "all": @@ -150,8 +153,6 @@ async def list_all(event): @ultroid_cmd(pattern="forward ?(.*)", allow_sudo=False) async def forw(event): - if event.fwd_from: - return if not event.is_reply: await eor(event, "Reply to a message to broadcast.") return @@ -163,8 +164,6 @@ async def forw(event): sent_count = 0 if event.reply_to_msg_id: previous_message = await event.get_reply_message() - previous_message.message - previous_message.raw_text error_count = 0 for channel in channels: try: @@ -173,16 +172,12 @@ async def forw(event): await x.edit( f"Sent : {sent_count}\nError : {error_count}\nTotal : {len(channels)}", ) - except Exception as error: + except Exception: try: await ultroid_bot.send_message( - Var.LOG_CHANNEL, f"Error in sending at {channel}." + Var.LOG_CHANNEL, + f"Error in sending at {channel}.", ) - await ultroid_bot.send_message(Var.LOG_CHANNEL, "Error! " + str(error)) - if error == "The message cannot be empty unless a file is provided": - return await x.edit( - "For sending files, upload in Saved Messages and reply .forward to it." - ) except BaseException: pass error_count += 1 @@ -248,17 +243,19 @@ async def sending(event): except Exception as error: try: await ultroid_bot.send_message( - Var.LOG_CHANNEL, f"Error in sending at {channel}." + Var.LOG_CHANNEL, + f"Error in sending at {channel}.", ) await ultroid_bot.send_message( - Var.LOG_CHANNEL, "Error! " + str(error) + Var.LOG_CHANNEL, + "Error! " + str(error), ) if ( error == "The message cannot be empty unless a file is provided" ): return await x.edit( - f"For sending files, upload in Saved Messages and reply {hndlr}forward to in." + f"For sending files, upload in Saved Messages and reply {hndlr}forward to in.", ) except BaseException: pass @@ -270,7 +267,8 @@ async def sending(event): if error_count > 0: try: await ultroid_bot.send_message( - Var.LOG_CHANNEL, f"{error_count} Errors" + Var.LOG_CHANNEL, + f"{error_count} Errors", ) except BaseException: pass @@ -279,7 +277,9 @@ async def sending(event): for channel in channels: try: await ultroid_bot.send_message( - int(channel), raw_text, link_preview=False + int(channel), + raw_text, + link_preview=False, ) sent_count += 1 await x.edit( @@ -288,17 +288,19 @@ async def sending(event): except Exception as error: try: await ultroid_bot.send_message( - Var.LOG_CHANNEL, f"Error in sending at {channel}." + Var.LOG_CHANNEL, + f"Error in sending at {channel}.", ) await ultroid_bot.send_message( - Var.LOG_CHANNEL, "Error! " + str(error) + Var.LOG_CHANNEL, + "Error! " + str(error), ) if ( error == "The message cannot be empty unless a file is provided" ): return await x.edit( - f"For sending files, upload in Saved Messages and reply {hndlr}forward to in." + f"For sending files, upload in Saved Messages and reply {hndlr}forward to in.", ) except BaseException: pass @@ -310,7 +312,8 @@ async def sending(event): if error_count > 0: try: await ultroid_bot.send_message( - Var.LOG_CHANNEL, f"{error_count} Errors" + Var.LOG_CHANNEL, + f"{error_count} Errors", ) except BaseException: await x.edit("Set up log channel for checking errors.") diff --git a/plugins/carbon.py b/plugins/carbon.py index 31f0eabb39fbeca56227fa38ace26ac95081cf50..49a8e0bd5619bd31214623394d9b430daaa11249 100644 --- a/plugins/carbon.py +++ b/plugins/carbon.py @@ -182,7 +182,7 @@ async def crbn(event): temp = await event.get_reply_message() if temp.media: b = await ultroid_bot.download_media(temp) - a = open(b, "r") + a = open(b) code = a.read() a.close() os.remove(b) @@ -211,7 +211,7 @@ async def crbn(event): temp = await event.get_reply_message() if temp.media: b = await ultroid_bot.download_media(temp) - a = open(b, "r") + a = open(b) code = a.read() a.close() os.remove(b) diff --git a/plugins/channelhacks.py b/plugins/channelhacks.py new file mode 100644 index 0000000000000000000000000000000000000000..7aa8931952ac004a9bc66a9f411e489f4573b4e1 --- /dev/null +++ b/plugins/channelhacks.py @@ -0,0 +1,266 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available + + +🔹 `{i}shift | ` + This will transfer all old post from channel A to channel B. + (u can use username or id of channel too) + example : `{i}shift @abc | @xyz` + [note - this (" | ") sign is nessesary] + +🔹 For auto-posting/forwarding all new message from any source channel to any destination channel. + + * `asource ` + This add source channel to database + * `dsource ` + This remove source channels from database + * `listsource ` + Show list of source channels + + + * `{i}adest ` + This add Ur channels to database + * `{i}ddest ` + This Remove Ur channels from database + * `{i}listdest ` + Show List of Ur channels + + 'you can set many channels in database' + 'For activating auto-post use `{i}setredis AUTOPOST True` ' +""" + +import asyncio + +from pyUltroid.functions.ch_db import * + +from . import * + + +@ultroid_bot.on(events.NewMessage()) +async def _(e): + if not udB.get("AUTOPOST") == "True": + return + x = get_source_channels() + th = await e.get_chat() + for xs in x: + if str(th.id) not in str(xs): + return + y = get_destinations() + for ys in y: + try: + if e.text and not e.media: + await ultroid_bot.send_message(int(ys), e.text) + elif e.media and e.text: + await ultroid_bot.send_file(int(ys), e.media, caption=e.text) + else: + await ultroid_bot.send_file(int(ys), e.media) + except Exception as e: + await ultroid_bot.send_message(bot.me.id, str(e)) + + +@ultroid_cmd(pattern="shift (.*)") +async def _(e): + x = e.pattern_match.group(1) + z = await eor(e, "`processing..`") + a, b = x.split("|") + try: + c = int(a) + except Exception: + try: + c = (await ultroid_bot.get_entity(a)).id + except Exception: + await z.edit("invalid Channel given") + return + try: + d = int(b) + except Exception: + try: + d = (await ultroid_bot.get_entity(b)).id + except Exception: + await z.edit("invalid Channel given") + return + async for msg in ultroid_bot.iter_messages(int(c), reverse=True): + try: + await asyncio.sleep(0.5) + await ultroid_bot.send_message(int(d), msg) + except: + pass + await z.edit("Done") + + +@ultroid_cmd(pattern="asource (.*)") +async def source(e): + x = e.pattern_match.group(1) + try: + y = int(x) + except Exception: + try: + y = int((await bot.get_entity(x)).id) + except Exception as es: + print(es) + return + if not is_source_channel_added(y): + add_source_channel(y) + await eor(e, "Source added succesfully") + elif is_source_channel_added(y): + await eor(e, "Source channel already added") + + +@ultroid_cmd(pattern="dsource ?(.*)") +async def dd(event): + chat_id = event.pattern_match.group(1) + x = await eor(event, "processing") + if chat_id == "all": + await x.edit("`Removing...`") + udB.delete("CH_SOURCE") + await x.edit("Source database cleared.") + return + try: + y = int(chat_id) + except Exception: + try: + y = int((await bot.get_entity(chat_id)).id) + except Exception as es: + print(es) + return + if is_source_channel_added(y): + rem_source_channel(y) + await x.edit("Source removed from database") + await asyncio.sleep(3) + await x.delete() + elif is_source_channel_added(y): + rem_source_channel(y) + await x.edit("Source removed from database") + await asyncio.sleep(3) + await x.delete() + elif not is_source_channel_added(y): + await x.edit("Source channel is already removed from database. ") + await asyncio.sleep(3) + await x.delete() + + +@ultroid_cmd(pattern="listsource") +async def list_all(event): + x = await eor(event, "`Calculating...`") + channels = get_source_channels() + num = get_no_source_channels() + if num == 0: + return await eod(x, "No chats were added.", time=5) + msg = "Source channels in database:\n" + for channel in channels: + name = "" + try: + name = (await ultroid.get_entity(int(channel))).title + except: + name = "" + msg += f"=> **{name}** [`{channel}`]\n" + msg += f"\nTotal {get_no_source_channels()} channels." + if len(msg) > 4096: + MSG = msg.replace("*", "").replace("`", "") + with io.BytesIO(str.encode(MSG)) as out_file: + out_file.name = "channels.txt" + await ultroid_bot.send_file( + event.chat_id, + out_file, + force_document=True, + allow_cache=False, + caption="Channels in database", + reply_to=event, + ) + await x.delete() + else: + await x.edit(msg) + + +@ultroid_cmd(pattern="adest (.*)") +async def destination(e): + x = e.pattern_match.group(1) + try: + y = int(x) + except Exception: + try: + y = int((await bot.get_entity(x)).id) + except Exception as es: + print(es) + return + if not is_destination_added(y): + add_destination(y) + await eor(e, "Destination added succesfully") + elif is_destination_added(y): + await eor(e, "Destination channel already added") + + +@ultroid_cmd(pattern="ddest ?(.*)") +async def dd(event): + chat_id = event.pattern_match.group(1) + x = await eor(event, "processing") + if chat_id == "all": + await x.edit("`Removing...`") + udB.delete("CH_DESTINATION") + await x.edit("Destinations database cleared.") + return + try: + y = int(chat_id) + except Exception: + try: + y = int((await bot.get_entity(chat_id)).id) + except Exception as es: + print(es) + return + if is_destination_added(y): + rem_destination(y) + await x.edit("Destination removed from database") + await asyncio.sleep(3) + await x.delete() + elif is_destination_added(y): + rem_destination(y) + await x.edit("Destination removed from database") + await asyncio.sleep(3) + await x.delete() + elif not is_destination_added(y): + await x.edit("Destination channel is already removed from database. ") + await asyncio.sleep(3) + await x.delete() + + +@ultroid_cmd(pattern="listdest") +async def list_all(event): + x = await eor(event, "`Calculating...`") + channels = get_destinations() + num = get_no_destinations() + if num == 0: + return await eod(x, "No chats were added.", time=5) + msg = "Destination channels in database:\n" + for channel in channels: + name = "" + try: + name = (await ultroid.get_entity(int(channel))).title + except: + name = "" + msg += f"=> **{name}** [`{channel}`]\n" + msg += f"\nTotal {get_no_destinations()} channels." + if len(msg) > 4096: + MSG = msg.replace("*", "").replace("`", "") + with io.BytesIO(str.encode(MSG)) as out_file: + out_file.name = "channels.txt" + await ultroid_bot.send_file( + event.chat_id, + out_file, + force_document=True, + allow_cache=False, + caption="Destination channels in database", + reply_to=event, + ) + await x.delete() + else: + await x.edit(msg) + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/chats.py b/plugins/chats.py index a9805f035a6249722189231e6d250dbcaa05d3df..fa26ae3688fbfa222cb9715717482a14ea6caed5 100644 --- a/plugins/chats.py +++ b/plugins/chats.py @@ -71,19 +71,19 @@ async def _(e): functions.messages.CreateChatRequest( users=["@missrose_bot"], title=group_name, - ) + ), ) created_chat_id = r.chats[0].id await e.client( functions.messages.DeleteChatUserRequest( chat_id=created_chat_id, user_id="@missrose_bot", - ) + ), ) result = await e.client( functions.messages.ExportChatInviteRequest( peer=created_chat_id, - ) + ), ) await xx.edit( f"Your [{group_name}]({result.link}) Group Made Boss!", @@ -98,13 +98,13 @@ async def _(e): title=group_name, about="Join @TeamUltroid", megagroup=False if type_of_group == "c" else True, - ) + ), ) created_chat_id = r.chats[0].id result = await e.client( functions.messages.ExportChatInviteRequest( peer=created_chat_id, - ) + ), ) await xx.edit( f"Your [{group_name}]({result.link}) Group/Channel Has been made Boss!", diff --git a/plugins/converter.py b/plugins/converter.py index 9a7f9b2826d207e3ed5268b47fa02593cdb5a719..fa6c9563a2c57a5746c254aa658763ea500ec72b 100644 --- a/plugins/converter.py +++ b/plugins/converter.py @@ -8,23 +8,35 @@ """ ✘ Commands Available - -• `{i}rename ` - rename the file - + • `{i}mtoi ` media to image conversion • `{i}mtos ` convert media to sticker. + +• `{i}doc ` + Reply to a text msg to save it in a file. + +• `{i}open` + Reply to a file to reveal it's text. + +• `{i}rename ` + rename the file + """ +import asyncio import os import cv2 +import requests from PIL import Image from . import * +opn = [] + @ultroid_cmd(pattern="rename ?(.*)") async def imak(event): @@ -88,4 +100,59 @@ async def smak(event): os.remove(image) +@ultroid_cmd( + pattern="doc", +) +async def _(event): + input_str = event.text[5:] + xx = await eor(event, get_string("com_1")) + if event.reply_to_msg_id: + a = await event.get_reply_message() + if not a.message: + return await xx.edit("`Reply to a message`") + else: + b = open(input_str, "w") + b.write(str(a.message)) + b.close() + await xx.edit(f"**Packing into** `{input_str}`") + await asyncio.sleep(2) + await xx.edit(f"**Uploading** `{input_str}`") + await asyncio.sleep(2) + await event.client.send_file(event.chat_id, input_str) + await xx.delete() + os.remove(input_str) + + +@ultroid_cmd( + pattern="open$", +) +async def _(event): + xx = await eor(event, get_string("com_1")) + if event.reply_to_msg_id: + a = await event.get_reply_message() + if a.media: + b = await a.download_media() + c = open(b) + d = c.read() + c.close() + try: + await xx.edit(f"```{d}```") + except BaseException: + key = ( + requests.post( + "https://nekobin.com/api/documents", json={"content": d} + ) + .json() + .get("result") + .get("key") + ) + await xx.edit( + f"**MESSAGE EXCEEDS TELEGRAM LIMITS**\n\nSo Pasted It On [NEKOBIN](https://nekobin.com/{key})" + ) + else: + return await eod(xx, "`Reply to a readable file`", time=5) + else: + return await eod(xx, "`Reply to a readable file`", time=5) + + HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/core.py b/plugins/core.py index 4e5e9ef8ea3dedcd48bce4258f299b2040d032fc..be0bf0dede575e3ae32bdd18d787ec1afd753b1d 100644 --- a/plugins/core.py +++ b/plugins/core.py @@ -54,11 +54,13 @@ async def inline_handler(event): buttons=[ [ Button.switch_inline( - "Search Again..?", query="send ", same_peer=True - ) - ] + "Search Again..?", + query="send ", + same_peer=True, + ), + ], ], - ) + ), ) except BaseException: pass @@ -73,9 +75,11 @@ async def inline_handler(event): buttons=[ [ Button.switch_inline( - "Search Again..?", query="send ", same_peer=True - ) - ] + "Search Again..?", + query="send ", + same_peer=True, + ), + ], ], ) await event.answer([ultroid]) @@ -88,9 +92,11 @@ async def inline_handler(event): buttons=[ [ Button.switch_inline( - "Search Again", query="send ", same_peer=True - ) - ] + "Search Again", + query="send ", + same_peer=True, + ), + ], ], ) await event.answer([ultroidcode]) diff --git a/plugins/dm.py b/plugins/dm.py new file mode 100644 index 0000000000000000000000000000000000000000..49a9168aa540ead0599ff3fc162cce73ff0600a7 --- /dev/null +++ b/plugins/dm.py @@ -0,0 +1,45 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . +""" +✘ Commands Available - + +• `{i}dm ` + Direct Message the User. +""" + +from . import * + + +@ultroid_cmd(pattern="dm ?(.*)") +async def dm(e): + d = e.pattern_match.group(1) + c = d.split(" ") + try: + chat_id = await get_user_id(c[0]) + except Exception as ex: + return await eod(e, "`" + str(ex) + "`", time=5) + msg = "" + masg = await e.get_reply_message() + if e.reply_to_msg_id: + await ultroid_bot.send_message(chat_id, masg) + await eod(e, "`⚜️Message Delivered!`", time=4) + for i in c[1:]: + msg += i + " " + if msg == "": + return + try: + await ultroid_bot.send_message(chat_id, msg) + await eod(e, "`⚜️Message Delivered!⚜️`", time=4) + except BaseException: + await eod( + e, + "`{i}help dm`", + time=4, + ) + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/uploads_files.py b/plugins/download_upload.py similarity index 60% rename from plugins/uploads_files.py rename to plugins/download_upload.py index 22b28ddd1e4f0a9909c72277803649971e0d2e2a..189c7cef57ebc5f3bedd6df29659418bd5d12969 100644 --- a/plugins/uploads_files.py +++ b/plugins/download_upload.py @@ -14,27 +14,21 @@ • `{i}dl ` Reply to file to download. -• `{i}save ` - Reply to a text msg to save it in a file. - -• `{i}open` - Reply to a file to reveal it's text. """ import asyncio -import os import time from datetime import datetime as dt from . import * -opn = [] - @ultroid_cmd( pattern="dl ?(.*)", ) async def download(event): + if not event.is_reply: + return await eor(event, "`Reply to a Media Message`") xx = await eor(event, get_string("com_1")) kk = event.pattern_match.group(1) s = dt.now() @@ -56,7 +50,7 @@ async def download(event): xx, k, "Downloading...", - ) + ), ), ) else: @@ -72,12 +66,15 @@ async def download(event): k, "Downloading...", file_name=d, - ) + ), ), ) e = datetime.now() t = time_formatter(((e - s).seconds) * 1000) - await eod(xx, get_string("udl_2").format(o, t)) + if t: + await eod(xx, get_string("udl_2").format(o, t)) + else: + await eod(xx, f"Downloaded `{o}` in `0 second(s)`") @ultroid_cmd( @@ -96,6 +93,8 @@ async def download(event): event.chat_id, kk, caption=kk, + force_document=True, + thumb="resources/extras/logo_rdm.png", progress_callback=lambda d, t: asyncio.get_event_loop().create_task( progress( d, @@ -104,72 +103,27 @@ async def download(event): tt, "Uploading...", file_name=kk, - ) + ), ), ) except ValueError as ve: return await eod(xx, str(ve)) + except BaseException: + try: + await ultroid_bot.send_message(event.chat_id, kk) + return await kk.delete() + except BaseException: + pass e = datetime.now() t = time_formatter(((e - s).seconds) * 1000) try: await x.edit(f"`{kk}`\nTime Taken: `{t}`") except BaseException: pass - await eod(xx, f"Uploaded `{kk}` in `{t}`", time=5) - - -@ultroid_cmd( - pattern="save", -) -async def _(event): - input_str = event.text[6:] - xx = await eor(event, get_string("com_1")) - if event.reply_to_msg_id: - a = await event.get_reply_message() - if not a.message: - return await xx.edit("`Reply to a message`") - else: - b = open(input_str, "w") - b.write(str(a.message)) - b.close() - await xx.edit(f"**Packing into** `{input_str}`") - await asyncio.sleep(2) - await xx.edit(f"**Uploading** `{input_str}`") - await asyncio.sleep(2) - await event.client.send_file(event.chat_id, input_str) - await xx.delete() - os.remove(input_str) - - -@ultroid_cmd( - pattern="open$", -) -async def _(event): - xx = await eor(event, get_string("com_1")) - if event.reply_to_msg_id: - a = await event.get_reply_message() - if a.media: - b = await a.download_media() - c = open(b, "r") - d = c.read() - c.close() - n = 4096 - for bkl in range(0, len(d), n): - opn.append(d[bkl : bkl + n]) - for bc in opn: - await event.client.send_message( - event.chat_id, - f"```{bc}```", - reply_to=event.reply_to_msg_id, - ) - await event.delete() - opn.clear() - os.remove(b) - await xx.delete() - else: - return await eod(xx, "`Reply to a readable file`", time=10) + if t: + await eod(xx, f"Uploaded `{kk}` in `{t}`", time=5) else: - return await eod(xx, "`Reply to a readable file`", time=10) + await eod(xx, f"Uploaded `{kk}` in `0 second(s)`") HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/fedutils.py b/plugins/fedutils.py index 805902690760c67d9855fbe0e45fbef87d4c7fda..8f12ca71faa2121ecd73742e1c6cdc01b149d80f 100644 --- a/plugins/fedutils.py +++ b/plugins/fedutils.py @@ -41,7 +41,8 @@ async def _(event): previous_message = await event.get_reply_message() if previous_message.media: downloaded_file_name = await ultroid_bot.download_media( - previous_message, "fedlist" + previous_message, + "fedlist", ) file = open(downloaded_file_name, encoding="utf8") lines = file.readlines() @@ -111,7 +112,7 @@ async def _(event): response = await bot_conv.get_response() except asyncio.exceptions.TimeoutError: return await msg.edit( - "`Seems like rose isn't responding, or, the plugin is misbehaving`" + "`Seems like rose isn't responding, or, the plugin is misbehaving`", ) await asyncio.sleep(3) if "make a file" in response.text or "Looks like" in response.text: @@ -121,10 +122,11 @@ async def _(event): await asyncio.sleep(3) if fedfile.media: downloaded_file_name = await ultroid_bot.download_media( - fedfile, "fedlist" + fedfile, + "fedlist", ) await asyncio.sleep(6) - file = open(downloaded_file_name, "r", errors="ignore") + file = open(downloaded_file_name, errors="ignore") lines = file.readlines() for line in lines: try: @@ -138,7 +140,7 @@ async def _(event): return if len(fedList) == 0: await msg.edit( - f"Unable to collect FedAdminList. Retrying ({a+1}/3)..." + f"Unable to collect FedAdminList. Retrying ({a+1}/3)...", ) else: break @@ -185,7 +187,7 @@ async def _(event): except Exception as e: print(f"Error in removing FedAdmin file.\n{str(e)}") await msg.edit( - f"SuperFBan Completed.\nTotal Feds - {len(fedlist)}.\nExcluded - {exCount}.\n Affected {len(fedList) - exCount} feds.\n#TB" + f"SuperFBan Completed.\nTotal Feds - {len(fedlist)}.\nExcluded - {exCount}.\n Affected {len(fedList) - exCount} feds.\n#TB", ) @@ -197,7 +199,8 @@ async def _(event): previous_message = await event.get_reply_message() if previous_message.media: downloaded_file_name = await ultroid_bot.download_media( - previous_message, "fedlist" + previous_message, + "fedlist", ) file = open(downloaded_file_name, encoding="utf8") lines = file.readlines() @@ -257,7 +260,7 @@ async def _(event): response = await bot_conv.get_response() except asyncio.exceptions.TimeoutError: return await msg.edit( - "`Seems like rose isn't responding, or, the plugin is misbehaving`" + "`Seems like rose isn't responding, or, the plugin is misbehaving`", ) await asyncio.sleep(3) if "make a file" in response.text or "Looks like" in response.text: @@ -267,10 +270,11 @@ async def _(event): await asyncio.sleep(3) if fedfile.media: downloaded_file_name = await ultroid_bot.download_media( - fedfile, "fedlist" + fedfile, + "fedlist", ) await asyncio.sleep(6) - file = open(downloaded_file_name, "r", errors="ignore") + file = open(downloaded_file_name, errors="ignore") lines = file.readlines() for line in lines: try: @@ -284,7 +288,7 @@ async def _(event): return if len(fedList) == 0: await msg.edit( - f"Unable to collect FedAdminList. Retrying ({a+1}/3)..." + f"Unable to collect FedAdminList. Retrying ({a+1}/3)...", ) else: break @@ -331,13 +335,13 @@ async def _(event): except Exception as e: print(f"Error in removing FedAdmin file.\n{str(e)}") await msg.edit( - f"SuperUnFBan Completed.\nTotal Feds - {len(fedlist)}.\nExcluded - {exCount}.\n Affected {len(fedList) - exCount} feds.\n#TB" + f"SuperUnFBan Completed.\nTotal Feds - {len(fedlist)}.\nExcluded - {exCount}.\n Affected {len(fedList) - exCount} feds.\n#TB", ) @ultroid_cmd(pattern="fstat ?(.*)") async def _(event): - ok = await event.edit("`Checking...`") + ok = await eor(event, "`Checking...`") if event.reply_to_msg_id: previous_message = await event.get_reply_message() sysarg = str(previous_message.sender_id) @@ -349,7 +353,7 @@ async def _(event): user = sysarg if sysarg == "": await ok.edit( - "`Give me someones id, or reply to somones message to check his/her fedstat.`" + "`Give me someones id, or reply to somones message to check his/her fedstat.`", ) return else: @@ -359,7 +363,11 @@ async def _(event): await conv.get_response() await conv.send_message("/fedstat " + sysarg) audio = await conv.get_response() - if "Looks like" in audio.text: + if audio.message.startswith("This command can only be used once"): + return await ok.edit( + "Oops, you can use this command only once every minute!", + ) + elif "Looks like" in audio.text: await audio.click(0) await asyncio.sleep(2) audio = await conv.get_response() @@ -369,10 +377,11 @@ async def _(event): caption=f"List of feds {user} has been banned in.\n\nCollected using Ultroid.", link_preview=False, ) + await ok.delete() else: - await ultroid.send_message(event.chat_id, audio.text) + okk = await conv.get_edit() + await ok.edit(okk.message) await ultroid.send_read_acknowledge(bot) - await event.delete() except YouBlockedUserError: await ok.edit("**Error**\n `Unblock` @MissRose_Bot `and try again!") diff --git a/plugins/filter.py b/plugins/filter.py new file mode 100644 index 0000000000000000000000000000000000000000..a2415aff036027ff0c6c2e6ea17914886b6c8558 --- /dev/null +++ b/plugins/filter.py @@ -0,0 +1,113 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +• `{i}addfilter ` + add the used word as filter relating to replied message. + +• `{i}remfilter ` + Remove the filtered user.. + +• `{i}listfilters` + list all filters. +""" + +import os + +from pyUltroid.functions.filter_db import * +from telegraph import upload_file as uf +from telethon.utils import pack_bot_file_id + +from . import * + + +@ultroid_cmd(pattern="addfilter ?(.*)") +async def af(e): + wrd = e.pattern_match.group(1) + wt = await e.get_reply_message() + chat = e.chat_id + if not (wt and wrd): + return await eor(e, "`Use this command word to set as filter and reply...`") + try: + rem_filter(int(chat), wrd) + except: + pass + if wt and wt.media: + wut = mediainfo(wt.media) + if wut.startswith(("pic", "gif")): + dl = await bot.download_media(wt.media) + variable = uf(dl) + m = "https://telegra.ph" + variable[0] + elif wut == "video": + if wt.media.document.size > 8 * 1000 * 1000: + return await eod(x, "`Unsupported Media`") + else: + dl = await bot.download_media(wt.media) + variable = uf(dl) + os.remove(dl) + m = "https://telegra.ph" + variable[0] + else: + m = pack_bot_file_id(wt.media) + if wt.text: + add_filter(int(chat), wrd, wt.text, m) + else: + add_filter(int(chat), wrd, None, m) + else: + add_filter(int(chat), wrd, wt.text, None) + await eor(e, f"Done : Filter `{wrd}` Saved.") + + +@ultroid_cmd(pattern="remfilter ?(.*)") +async def rf(e): + wrd = e.pattern_match.group(1) + chat = e.chat_id + if not wrd: + return await eor(e, "`Give the filter to remove..`") + rem_filter(int(chat), wrd) + await eor(e, f"Done : Filter `{wrd}` Removed.") + + +@ultroid_cmd(pattern="listfilter$") +async def lsnote(e): + x = list_filter(e.chat_id) + if x: + sd = "Filters Found In This Chats Are\n\n" + await eor(e, sd + x) + else: + await eor(e, "No Filters Found Here") + + +@ultroid_bot.on(events.NewMessage()) +async def fl(e): + xx = e.text + chat = e.chat_id + x = get_filter(int(chat)) + if x: + if " " in xx: + xx = xx.split(" ") + kk = "" + for c in xx: + if c in x: + k = get_reply(int(chat), c) + if k: + kk = k + if kk: + msg = k["msg"] + media = k["media"] + await e.reply(msg, file=media) + + else: + k = get_reply(chat, xx) + if k: + msg = k["msg"] + media = k["media"] + await e.reply(msg, file=media) + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/gadgets.py b/plugins/gadgets.py new file mode 100644 index 0000000000000000000000000000000000000000..e98b19e007f936da18538925a591b37705e819ee --- /dev/null +++ b/plugins/gadgets.py @@ -0,0 +1,55 @@ +# +# Ultroid - UserBot +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +• `{i}gadget ` + Gadget Search from Telegram. + +""" + +import requests +from bs4 import BeautifulSoup as bs + +from . import * + + +@ultroid_cmd(pattern="gadget ?(.*)") +async def mobs(e): + mat = e.pattern_match.group(1) + if not mat: + await eor(e, "Please Give a Mobile Name to look for.") + query = mat.replace(" ", "%20") + jwala = f"https://gadgets.ndtv.com/search?searchtext={query}" + c = requests.get(jwala).content + b = bs(c, "html.parser", from_encoding="utf-8") + bt = await eor(e, "`Processing...`") + try: + out = "**📱 Mobile / Gadgets Search**\n\n" + re = b.find_all("div", "rvw-imgbox") + li = re[0].findNext()["href"] + mg = re[0].findNext().findNext().findNext() + tit = mg["title"] + cont = requests.get(li).content + nu = bs(cont, "html.parser", from_encoding="utf-8") + req = nu.find_all("div", "_pdsd") + imu = nu.find_all("source", type="image/webp")[0]["srcset"].split("?")[0] + out += f"☑️ **[{tit}]({li})**\n\n" + for fp in req: + ty = fp.findNext() + out += f"- **{ty.text}** - `{ty.findNext().text}`\n" + out += "_" + await ultroid_bot.send_file(e.chat_id, file=imu, caption=out) + if e.sender_id == ultroid_bot.uid: + await bt.delete() + except Exception as a: + print(a) + await eor(e, "No Results Found") + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/gdrive.py b/plugins/gdrive.py index 723d9cd67116ed55ce62379e42eb058d0dd0e67a..67a140a03cd8827bffe9c0ceeb6dd4aa94f520e3 100644 --- a/plugins/gdrive.py +++ b/plugins/gdrive.py @@ -19,6 +19,9 @@ • `{i}udir ` Upload a directory on Google Drive. +• `{i}listdrive` + List all GDrive files. + • `{i}gfolder` Link to your Google Drive Folder. If added then all uploaded files will be placed here. @@ -30,13 +33,21 @@ import os import time from datetime import datetime -from telethon import events - from . import * TOKEN_FILE = "resources/auths/auth_token.txt" +@ultroid_cmd( + pattern="listdrive$", +) +async def files(event): + if not os.path.exists(TOKEN_FILE): + return await eod(event, get_string("gdrive_6").format(Var.BOT_USERNAME)) + http = authorize(TOKEN_FILE, None) + await eor(event, list_files(http)) + + @ultroid_cmd( pattern="ugdrive ?(.*)", ) @@ -70,7 +81,7 @@ async def _(event): ms = (end - start).seconds required_file_name = downloaded_file_name await mone.edit( - "Downloaded to `{}` in {} seconds.".format(downloaded_file_name, ms) + f"Downloaded to `{downloaded_file_name}` in {ms} seconds.", ) elif input_str: input_str = input_str.strip() @@ -78,10 +89,12 @@ async def _(event): end = datetime.now() ms = (end - start).seconds required_file_name = input_str - await mone.edit("Found `{}` in {} seconds.".format(input_str, ms)) + await mone.edit(f"Found `{input_str}` in {ms} seconds.") else: return await eod( - mone, "File Not found in local server. Give me a file path :((", time=5 + mone, + "File Not found in local server. Give me a file path :((", + time=5, ) if required_file_name: http = authorize(TOKEN_FILE, None) @@ -110,13 +123,14 @@ async def sch(event): return await eod(event, get_string("gdrive_6").format(Var.BOT_USERNAME)) http = authorize(TOKEN_FILE, None) input_str = event.pattern_match.group(1).strip() - a = await eor(event, "Searching for {} in G-Drive.".format(input_str)) + a = await eor(event, f"Searching for {input_str} in G-Drive.") if Redis("GDRIVE_FOLDER_ID") is not None: query = "'{}' in parents and (title contains '{}')".format( - Redis("GDRIVE_FOLDER_ID"), input_str + Redis("GDRIVE_FOLDER_ID"), + input_str, ) else: - query = "title contains '{}'".format(input_str) + query = f"title contains '{input_str}'" try: msg = await gsearch(http, query, input_str) return await a.edit(str(msg)) @@ -133,14 +147,14 @@ async def _(event): input_str = event.pattern_match.group(1) if os.path.isdir(input_str): http = authorize(TOKEN_FILE, None) - a = await eor(event, "Uploading `{}` to G-Drive...".format(input_str)) + a = await eor(event, f"Uploading `{input_str}` to G-Drive...") dir_id = await create_directory( http, os.path.basename(os.path.abspath(input_str)), Redis("GDRIVE_FOLDER_ID"), ) await DoTeskWithDir(http, input_str, event, dir_id) - dir_link = "https://drive.google.com/folderview?id={}".format(dir_id) + dir_link = f"https://drive.google.com/folderview?id={dir_id}" await eod(a, get_string("gdrive_7").format(input_str, dir_link)) else: return await eod(event, f"Directory {input_str} does not seem to exist", time=5) @@ -152,7 +166,7 @@ async def _(event): async def _(event): if Redis("GDRIVE_FOLDER_ID"): folder_link = "https://drive.google.com/folderview?id=" + Redis( - "GDRIVE_FOLDER_ID" + "GDRIVE_FOLDER_ID", ) await eod(event, "`Here is Your G-Drive Folder link : `\n" + folder_link) else: diff --git a/plugins/get_addons.py b/plugins/get_addons.py new file mode 100644 index 0000000000000000000000000000000000000000..83746c603f87f7929417554c4d2a26f18ef6f652 --- /dev/null +++ b/plugins/get_addons.py @@ -0,0 +1,51 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +• `{i}getaddons ` + Load Plugins from the given raw link. +""" +import requests + +from . import * + + +@ultroid_cmd(pattern="getaddons ?(.*)") +async def get_the_addons_lol(event): + thelink = event.pattern_match.group(1) + xx = await eor(event, get_string("com_1")) + fool = "Please provide a raw link!" + if thelink is None: + return await eod(xx, fool, time=10) + split_thelink = thelink.split("/") + if "raw" in split_thelink or "raw.githubusercontent.com" in split_thelink: + pass + else: + return await eod(xx, fool, time=10) + name_of_it = split_thelink[(len(split_thelink) - 1)] + plug = requests.get(thelink).text + fil = f"addons/{name_of_it}" + await xx.edit("Packing the codes...") + uult = open(fil, "w", encoding="utf-8") + uult.write(plug) + uult.close + await xx.edit("Packed. Now loading the plugin..") + shortname = name_of_it.split(".")[0] + try: + load_addons(shortname) + await eod(xx, f"**Sᴜᴄᴄᴇssғᴜʟʟʏ Lᴏᴀᴅᴇᴅ** `{shortname}`", time=3) + except Exception as e: + await eod( + xx, + f"**Could not load** `{shortname}` **because of the following error.**\n`{str(e)}`", + time=3, + ) + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/glitch.py b/plugins/glitch.py new file mode 100644 index 0000000000000000000000000000000000000000..f006b7ee2192c5ecba053da5d0492bd09f2434ae --- /dev/null +++ b/plugins/glitch.py @@ -0,0 +1,39 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" + +✘ Commands Available - + +•`{i}glitch ` + gives a glitchy gif. + +""" + +import os + +from . import * + + +@ultroid_cmd(pattern="glitch$") +async def _(e): + reply = await e.get_reply_message() + if not reply.media: + return await eor(e, "reply to any media") + xx = await eor(e, "`Gliching...`") + ok = await bot.download_media(reply.media) + cmd = f"glitch_me gif --line_count 200 -f 10 -d 50 '{ok}' ult.gif" + stdout, stderr = await bash(cmd) + await ultroid_bot.send_file( + e.chat_id, "ult.gif", force_document=False, reply_to=reply + ) + await xx.delete() + os.remove(ok) + os.remove("ult.gif") + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"}) diff --git a/plugins/globaltools.py b/plugins/globaltools.py index a5038cf1856f0b3f434f10d72331345c369eb26b..d8bce794086d7566555f235307cac65f8716a603 100644 --- a/plugins/globaltools.py +++ b/plugins/globaltools.py @@ -25,11 +25,12 @@ • `{i}gcast ` Globally Send that msg in all grps. + +• `{i}gucast ` + Globally Send that msg in all Ur Chat Users. """ from telethon import events -from telethon.tl.functions.channels import EditBannedRequest -from telethon.tl.types import ChatBannedRights from . import * @@ -69,7 +70,7 @@ async def _(e): pass ungban(userid) await xx.edit( - f"`Ungbanned` [{name}](tg://user?id={userid}) `in {chats} chats.\nRemoved from gbanwatch.`" + f"`Ungbanned` [{name}](tg://user?id={userid}) `in {chats} chats.\nRemoved from gbanwatch.`", ) @@ -103,7 +104,9 @@ async def _(e): return await eod(xx, "`I can't gban my Developers.`", time=3) if is_gbanned(userid): return await eod( - xx, "`User is already gbanned and added to gbanwatch.`", time=4 + xx, + "`User is already gbanned and added to gbanwatch.`", + time=4, ) async for ggban in e.client.iter_dialogs(): if ggban.is_group or ggban.is_channel: @@ -114,7 +117,7 @@ async def _(e): pass gban(userid) await xx.edit( - f"`Gbanned` [{name}](tg://user?id={userid}) `in {chats} chats.\nAdded to gbanwatch.`" + f"`Gbanned` [{name}](tg://user?id={userid}) `in {chats} chats.\nAdded to gbanwatch.`", ) @@ -141,6 +144,29 @@ async def gcast(event): await kk.edit(f"Done in {done} chats, error in {er} chat(s)") +@ultroid_cmd( + pattern="gucast ?(.*)", +) +async def gucast(event): + xx = event.pattern_match.group(1) + if not xx: + return eor(event, "`Give some text to Globally Broadcast`") + tt = event.text + msg = tt[7:] + kk = await eor(event, "`Globally Broadcasting Msg...`") + er = 0 + done = 0 + async for x in ultroid_bot.iter_dialogs(): + if x.is_user and not x.entity.bot: + chat = x.id + try: + done += 1 + await ultroid_bot.send_message(chat, msg) + except: + er += 1 + await kk.edit(f"Done in {done} chats, error in {er} chat(s)") + + @ultroid_cmd( pattern="gkick ?(.*)", ) @@ -266,7 +292,9 @@ async def _(e): if chat.admin_rights: try: await e.client.edit_permissions( - chat.id, user.id, view_messages=False + chat.id, + user.id, + view_messages=False, ) gban_watch = f"`Gbanned User` [{user.first_name}](tg://user?id={user.id}) `Spotted\n" gban_watch += f"Banned Successfully`" diff --git a/plugins/google.py b/plugins/google.py index caabe3fa15665c0f67ffbd45b3929b7016190de9..ff3f4ed7b21b9abfe693519df20f7d8fe6e33c22 100644 --- a/plugins/google.py +++ b/plugins/google.py @@ -24,7 +24,7 @@ from shutil import rmtree import requests from bs4 import BeautifulSoup as bs from PIL import Image -from pyUltroid.functions.parser import GoogleSearch +from search_engine_parser import GoogleSearch from strings import get_string @@ -45,9 +45,14 @@ async def google(event): url = res["links"][i] des = res["descriptions"][i] out += f" 👉🏻 [{text}]({url})\n`{des}`\n\n" - await x.edit( - f"**Google Search Query:**\n`{inp}`\n\n**Results:**\n{out}", link_preview=False - ) + omk = f"**Google Search Query:**\n`{inp}`\n\n**Results:**\n{out}" + opn = [] + for bkl in range(0, len(omk), 4095): + opn.append(omk[bkl : bkl + 4095]) + for bc in opn: + await ultroid_bot.send_message(event.chat_id, bc, link_preview=False) + await x.delete() + opn.clear() @ultroid_cmd(pattern="img ?(.*)") @@ -88,17 +93,19 @@ async def reverse(event): x, y = img.size file = {"encoded_image": (dl, open(dl, "rb"))} grs = requests.post( - "https://www.google.com/searchbyimage/upload", files=file, allow_redirects=False + "https://www.google.com/searchbyimage/upload", + files=file, + allow_redirects=False, ) loc = grs.headers.get("Location") response = requests.get( loc, headers={ - "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0" + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0", }, ) xx = bs(response.text, "html.parser") - div = xx.find("div", {"class": "r5a77d"}) + div = xx.find_all("div", {"class": "r5a77d"})[0] alls = div.find("a") link = alls["href"] text = alls.text @@ -113,7 +120,10 @@ async def reverse(event): pth = gi.download(args) ok = pth[0][text] await event.client.send_file( - event.chat_id, ok, album=True, caption="Similar Images Realted to Search" + event.chat_id, + ok, + album=True, + caption="Similar Images Realted to Search", ) rmtree(f"./resources/downloads/{text}/") os.remove(dl) diff --git a/plugins/greetings.py b/plugins/greetings.py new file mode 100644 index 0000000000000000000000000000000000000000..2c7b990ab1fb33b7d8302f81fe92e42768f198ca --- /dev/null +++ b/plugins/greetings.py @@ -0,0 +1,229 @@ +# Ultroid - UserBot +# Copyright (C) 2020 TeamUltroid +# +# This file is a part of < https://github.com/TeamUltroid/Ultroid/ > +# PLease read the GNU Affero General Public License in +# . + +""" +✘ Commands Available - + +---- Welcomes ---- +• `{i}setwelcome ` + Set welcome message in the current chat. + +• `{i}clearwelcome` + Delete the welcome in the current chat. + +• `{i}getwelcome` + Get the welcome message in the current chat. + +---- GoodByes ---- +• `{i}setgoodbye ` + Set goodbye message in the current chat. + +• `{i}cleargoodbye` + Delete the goodbye in the current chat. + +• `{i}getgoodbye` + Get the goodbye message in the current chat. + +""" +Note = "\n\nNote: `{mention}`, `{group}`, `{count}`, `{name}`, `{fullname}`, `{username}`, `{userid}` can be used as formatting parameters.\n\n" + + +import os + +from telegraph import upload_file as uf +from telethon.utils import get_display_name, pack_bot_file_id + +from . import * + + +@ultroid_cmd(pattern="setwelcome") +async def setwel(event): + x = await eor(event, get_string("com_1")) + r = await event.get_reply_message() + if event.is_private: + return await eod(x, "Please use this in a group and not PMs!", time=10) + if r and r.media: + wut = mediainfo(r.media) + if wut.startswith(("pic", "gif")): + dl = await bot.download_media(r.media) + variable = uf(dl) + os.remove(dl) + m = "https://telegra.ph" + variable[0] + elif wut == "video": + if r.media.document.size > 8 * 1000 * 1000: + return await eod(x, "`Unsupported Media`") + else: + dl = await bot.download_media(r.media) + variable = uf(dl) + os.remove(dl) + m = "https://telegra.ph" + variable[0] + else: + m = pack_bot_file_id(r.media) + if r.text: + add_welcome(event.chat_id, r.message, m) + else: + add_welcome(event.chat_id, None, m) + await eor(x, "`Welcome note saved`") + elif r.text: + add_welcome(event.chat_id, r.message, None) + await eor(x, "`Welcome note saved`") + else: + await eod(x, "`Reply to message which u want to set as welcome`") + + +@ultroid_cmd(pattern="clearwelcome$") +async def clearwel(event): + if not get_welcome(event.chat_id): + await eod(event, "`No welcome was set!`", time=5) + delete_welcome(event.chat_id) + await eod(event, "`Welcome Note Deleted`") + + +@ultroid_cmd(pattern="getwelcome$") +async def listwel(event): + wel = get_welcome(event.chat_id) + if not wel: + await eod(event, "`No welcome was set!`", time=5) + msgg = wel["welcome"] + med = wel["media"] + await event.reply(f"**Welcome Note in this chat**\n\n`{msgg}`", file=med) + await event.delete() + + +@ultroid_bot.on(events.ChatAction()) +async def _(event): + wel = get_welcome(event.chat_id) + if wel: + if event.user_joined or event.user_added: + user = await event.get_user() + chat = await event.get_chat() + title = chat.title if chat.title else "this chat" + pp = await event.client.get_participants(chat) + count = len(pp) + mention = f"[{get_display_name(user)}](tg://user?id={user.id})" + name = user.first_name + last = user.last_name + if last: + fullname = f"{name} {last}" + else: + fullname = name + uu = user.username + if uu: + username = f"@{uu}" + else: + username = mention + msgg = wel["welcome"] + med = wel["media"] + userid = user.id + await event.reply( + msgg.format( + mention=mention, + group=title, + count=count, + name=name, + fullname=fullname, + username=username, + userid=userid, + ), + file=med, + ) + + +@ultroid_cmd(pattern="setgoodbye") +async def setgb(event): + x = await eor(event, get_string("com_1")) + r = await event.get_reply_message() + if event.is_private: + return await eod(x, "Please use this in a group and not PMs!", time=10) + if r and r.media: + wut = mediainfo(r.media) + if wut.startswith(("pic", "gif")): + dl = await bot.download_media(r.media) + variable = uf(dl) + os.remove(dl) + m = "https://telegra.ph" + variable[0] + elif wut == "video": + if r.media.document.size > 8 * 1000 * 1000: + return await eod(x, "`Unsupported Media`") + else: + dl = await bot.download_media(r.media) + variable = uf(dl) + os.remove(dl) + m = "https://telegra.ph" + variable[0] + else: + m = pack_bot_file_id(r.media) + if r.text: + add_goodbye(event.chat_id, r.message, m) + else: + add_goodbye(event.chat_id, None, m) + await eor(x, "`Goodbye note saved`") + elif r.text: + add_goodbye(event.chat_id, r.message, None) + await eor(x, "`Goddbye note saved`") + else: + await eod(x, "`Reply to message which u want to set as goodbye`") + + +@ultroid_cmd(pattern="cleargoodbye$") +async def clearwgb(event): + if not get_goodbye(event.chat_id): + await eod(event, "`No goodbye was set!`", time=5) + delete_goodbye(event.chat_id) + await eod(event, "`Goodbye Note Deleted`") + + +@ultroid_cmd(pattern="getgoodbye$") +async def listgd(event): + wel = get_goodbye(event.chat_id) + if not wel: + await eod(event, "`No goodbye was set!`", time=5) + msgg = wel["goodbye"] + med = wel["media"] + await event.reply(f"**Goodbye Note in this chat**\n\n`{msgg}`", file=med) + await event.delete() + + +@ultroid_bot.on(events.ChatAction()) +async def _(event): + wel = get_goodbye(event.chat_id) + if wel: + if event.user_left or event.user_kicked: + user = await event.get_user() + chat = await event.get_chat() + title = chat.title if chat.title else "this chat" + pp = await event.client.get_participants(chat) + count = len(pp) + mention = f"[{get_display_name(user)}](tg://user?id={user.id})" + name = user.first_name + last = user.last_name + if last: + fullname = f"{name} {last}" + else: + fullname = name + uu = user.username + if uu: + username = f"@{uu}" + else: + username = mention + msgg = wel["goodbye"] + med = wel["media"] + userid = user.id + await event.reply( + msgg.format( + mention=mention, + group=title, + count=count, + name=name, + fullname=fullname, + username=username, + userid=userid, + ), + file=med, + ) + + +HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}" + Note}) diff --git a/plugins/groups.py b/plugins/groups.py index c8237ac07ff193b9134b7f71e499eeb1f63cb7c3..83015909a438fd691f20b3febd6650cf9507c8d5 100644 --- a/plugins/groups.py +++ b/plugins/groups.py @@ -16,8 +16,7 @@ """ -from telethon import events -from telethon.tl import functions, types +from telethon.tl import functions from telethon.tl.types import (ChannelParticipantsKicked, ChatBannedRights, UserStatusEmpty, UserStatusLastMonth, UserStatusLastWeek, UserStatusOffline, @@ -35,7 +34,9 @@ async def _(event): p = 0 (await event.get_chat()).title async for i in event.client.iter_participants( - event.chat_id, filter=ChannelParticipantsKicked, aggressive=True + event.chat_id, + filter=ChannelParticipantsKicked, + aggressive=True, ): try: await event.client.edit_permissions(event.chat_id, i, view_messages=True) @@ -78,7 +79,7 @@ async def _(event): if "empty" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 y -= 1 @@ -89,7 +90,7 @@ async def _(event): if "month" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 m -= 1 @@ -100,7 +101,7 @@ async def _(event): if "week" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 w -= 1 @@ -111,7 +112,7 @@ async def _(event): if "offline" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 o -= 1 @@ -122,7 +123,7 @@ async def _(event): if "online" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 q -= 1 @@ -133,7 +134,7 @@ async def _(event): if "recently" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 r -= 1 @@ -144,7 +145,7 @@ async def _(event): if "bot" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 b -= 1 @@ -155,7 +156,7 @@ async def _(event): if "deleted" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 d -= 1 @@ -166,7 +167,7 @@ async def _(event): if "none" in input_str: try: await event.client( - functions.channels.EditBannedRequest(event.chat_id, i, rights) + functions.channels.EditBannedRequest(event.chat_id, i, rights), ) c += 1 n -= 1 diff --git a/plugins/imagetools.py b/plugins/imagetools.py index 3aa1827a991e402096ccd74b4d828f86610b30df..ff3f816a22259d2d8fe60a2c09cfc4df2ac32b80 100644 --- a/plugins/imagetools.py +++ b/plugins/imagetools.py @@ -8,15 +8,18 @@ """ ✘ Commands Available - +• `{i}grey ` + To make it black nd white. + +• `{i}color ` + To make it Colorfull. + • `{i}toon ` To make it toon. • `{i}danger ` To make it look Danger. -• `{i}grey ` - To make it black nd white. - • `{i}negative ` To make negative image. @@ -66,7 +69,9 @@ async def sketch(e): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -90,6 +95,36 @@ async def sketch(e): os.remove("ultroid.png") +@ultroid_cmd(pattern="color$") +async def _(event): + reply = await event.get_reply_message() + if not reply.media: + return await eor(event, "`Reply To a Black nd White Image`") + xx = await eor(event, "`Coloring image 🎨🖌️...`") + image = await ultroid_bot.download_media(reply.media) + img = cv2.VideoCapture(image) + ret, frame = img.read() + cv2.imwrite("ult.jpg", frame) + if udB.get("DEEP_API"): + key = Redis("DEEP_API") + else: + key = "quickstart-QUdJIGlzIGNvbWluZy4uLi4K" + r = requests.post( + "https://api.deepai.org/api/colorizer", + files={"image": open("ult.jpg", "rb")}, + headers={"api-key": key}, + ) + os.remove("ult.jpg") + os.remove(image) + if "status" in r.json(): + return await event.edit( + r.json()["status"] + "\nGet api nd set `{i}setredis DEEP_API key`" + ) + r_json = r.json()["output_url"] + await ultroid_bot.send_file(event.chat_id, r_json, reply_to=reply) + await xx.delete() + + @ultroid_cmd( pattern="grey$", ) @@ -104,7 +139,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -119,7 +156,10 @@ async def ultd(event): ultroid = cv2.cvtColor(ult, cv2.COLOR_BGR2GRAY) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -141,7 +181,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -156,7 +198,10 @@ async def ultd(event): ultroid = cv2.GaussianBlur(ult, (35, 35), 0) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -179,7 +224,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -194,7 +241,10 @@ async def ultd(event): ultroid = cv2.bitwise_not(ult) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -217,7 +267,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -233,7 +285,10 @@ async def ultd(event): ultroid = cv2.hconcat([ult, ish]) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -256,7 +311,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -273,7 +330,10 @@ async def ultd(event): ultroid = cv2.vconcat([ult, ish]) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -296,7 +356,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -315,7 +377,10 @@ async def ultd(event): ultroid = cv2.vconcat([mici, trn]) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -338,7 +403,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -367,10 +434,13 @@ async def ultd(event): ) centers = np.uint8(centers) ish = centers[labels.flatten()] - ultroid = ish.reshape((ult.shape)) + ultroid = ish.reshape(ult.shape) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -393,7 +463,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -409,7 +481,10 @@ async def ultd(event): ultroid = cv2.cvtColor(dan, cv2.COLOR_HSV2BGR) cv2.imwrite("ult.jpg", ultroid) await event.client.send_file( - event.chat_id, "ult.jpg", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.jpg", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") @@ -432,7 +507,9 @@ async def ultd(event): cmd = ["lottie_convert.py", ultt, "ult.png"] file = "ult.png" process = await asyncio.create_subprocess_exec( - *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await process.communicate() stderr.decode().strip() @@ -446,7 +523,7 @@ async def ultd(event): got = upf(file) lnk = f"https://telegra.ph{got[0]}" r = requests.get( - f"https://nekobot.xyz/api/imagegen?type=blurpify&image={lnk}" + f"https://nekobot.xyz/api/imagegen?type=blurpify&image={lnk}", ).json() ms = r.get("message") utd = url(ms) @@ -457,7 +534,10 @@ async def ultd(event): img = Image.open("ult.png").convert("RGB") img.save("ult.webp", "webp") await event.client.send_file( - event.chat_id, "ult.webp", force_document=False, reply_to=event.reply_to_msg_id + event.chat_id, + "ult.webp", + force_document=False, + reply_to=event.reply_to_msg_id, ) await xx.delete() os.remove("ult.png") diff --git a/plugins/mute.py b/plugins/mute.py index e1fc7b5cbd73888ee2dcab875aef96db0afe2ad3..1ae42ee543248de7ae66a480c4e5edeb7223629c 100644 --- a/plugins/mute.py +++ b/plugins/mute.py @@ -10,16 +10,16 @@ • `{i}mute ` Mute user in current chat. - + • `{i}unmute ` Unmute user in current chat. - + • `{i}dmute ` Mute user in current chat by deleting msgs. - + • `{i}undmute ` Unmute dmuted user in current chat. - + • `{i}tmute