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.
-
-
+
+
+ Ultroid - UserBot
+
+
+A stable pluggable Telegram userbot + vc music bot, based on Telethon.
-[](https://github.com/TeamUltroid/Ultroid/stargazers)
-[](https://github.com/TeamUltroid/Ultroid/fork)
-[](https://www.python.org/)
+[](https://github.com/TeamUltroid/Ultroid/stargazers)
+[](https://github.com/TeamUltroid/Ultroid/fork)
+[](https://github.com/TeamUltroid/Ultroid/)
+[](https://www.python.org/)
+[](https://github.com/TeamUltroid/Ultroid/graphs/commit-activity)
+[](https://github.com/TeamUltroid/Ultroid)
[](https://github.com/TeamUltroid/Ultroid/graphs/contributors)
-[](https://github.com/TeamUltroid/Ultroid/blob/main/LICENSE)
-[](https://github.com/TeamUltroid/Ultroid/)
+[](https://makeapullrequest.com)
+[](https://github.com/TeamUltroid/Ultroid/blob/main/LICENSE)
+[](http://hits.dwyl.com/Teamultroid/Teamultroid/Ultroid)
+[](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
+[](http://ultroid.tech/)
+
+# Tutorial
+- Full Tutorial - [](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!
[](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`:
+* [](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)
+# Credits
+* [](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 `
time - m- minutes
h- hours
@@ -31,8 +31,6 @@
from pyUltroid.functions.all import ban_time
from pyUltroid.functions.mute_db import is_muted, mute, unmute
from telethon import events
-from telethon.tl.functions.channels import EditBannedRequest
-from telethon.tl.types import ChatBannedRights
from . import *
@@ -106,7 +104,7 @@ async def endmute(event):
else:
userid = (await event.client.get_entity(input)).id
elif event.reply_to_msg_id:
- userid = reply.sender_id
+ userid = (await event.get_reply_message()).sender_id
elif private is True:
userid = event.chat_id
else:
@@ -157,7 +155,10 @@ async def _(e):
try:
bun = await ban_time(xx, tme)
await e.client.edit_permissions(
- chat.id, userid, until_date=bun, send_messages=False
+ chat.id,
+ userid,
+ until_date=bun,
+ send_messages=False,
)
await eod(
xx,
@@ -188,12 +189,15 @@ async def _(e):
return await xx.edit(str(x))
else:
userid = (await e.client.get_entity(input)).id
- name = (await event.client.get_entity(userid)).first_name
+ name = (await e.client.get_entity(userid)).first_name
else:
return await eod(xx, "`Reply to someone or use its id...`", time=3)
try:
await e.client.edit_permissions(
- chat.id, userid, until_date=None, send_messages=True
+ chat.id,
+ userid,
+ until_date=None,
+ send_messages=True,
)
await eod(
xx,
@@ -224,14 +228,17 @@ async def _(e):
return await xx.edit(str(x))
else:
userid = (await e.client.get_entity(input)).id
- name = (await event.client.get_entity(userid)).first_name
+ name = (await e.client.get_entity(userid)).first_name
else:
return await eod(xx, "`Reply to someone or use its id...`", time=3)
if userid == ultroid_bot.uid:
return await eod(xx, "`I can't mute myself.`", time=3)
try:
await e.client.edit_permissions(
- chat.id, userid, until_date=None, send_messages=False
+ chat.id,
+ userid,
+ until_date=None,
+ send_messages=False,
)
await eod(
xx,
diff --git a/plugins/notes.py b/plugins/notes.py
new file mode 100644
index 0000000000000000000000000000000000000000..b31dd40f5adf303f5fb13d9fb187b3ea520c2211
--- /dev/null
+++ b/plugins/notes.py
@@ -0,0 +1,124 @@
+# 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}addnote `
+ add note in the used chat with replied message and choosen word.
+
+• `{i}remnote `
+ Remove the note from used chat.
+
+• `{i}listnote`
+ list all notes.
+
+• Use :
+ set notes in group so all can use it.
+ type `#(Keyword of note)` to get it
+"""
+import os
+
+from pyUltroid.functions.notes_db import *
+from telegraph import upload_file as uf
+from telethon.utils import pack_bot_file_id
+
+from . import *
+
+
+@ultroid_cmd(pattern="addnote ?(.*)")
+async def an(e):
+ if e.is_group:
+ if not e._chat.admin_rights:
+ return await eod(e, "`You Are Not Admin Here.", time=5)
+ wrd = e.pattern_match.group(1)
+ wt = await e.get_reply_message()
+ chat = e.chat_id
+ if not (wt and wrd):
+ return await eod(e, "`Use this Command with Reply and word to use a note.`")
+ if "#" in wrd:
+ wrd = wrd.replace("#", "")
+ try:
+ rem_note(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)
+ os.remove(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_note(int(chat), wrd, wt.text, m)
+ else:
+ add_note(int(chat), wrd, None, m)
+ else:
+ add_note(int(chat), wrd, wt.text, None)
+ await eor(e, f"Done Note : `#{wrd}` saved.")
+
+
+@ultroid_cmd(pattern="remnote ?(.*)")
+async def rn(e):
+ if e.is_group:
+ if not e._chat.admin_rights:
+ return await eod(e, "`You Are Not Admin Here.", time=5)
+ wrd = e.pattern_match.group(1)
+ chat = e.chat_id
+ if not wrd:
+ return await eod(e, "`Give me the note handler which you want to remove.`")
+ if wrd.startswith("#"):
+ wrd = wrd.replace("#", "")
+ rem_note(int(chat), wrd)
+ await eor(e, f"Done Note: `#{wrd}` Removed.")
+
+
+@ultroid_cmd(pattern="listnote$")
+async def lsnote(e):
+ if e.is_group:
+ if not e._chat.admin_rights:
+ return await eod(e, "`You Are Not Admin Here.", time=5)
+ x = list_note(e.chat_id)
+ if x:
+ sd = "Notes Found In This Chats Are\n\n"
+ await eor(e, sd + x)
+ else:
+ await eor(e, "No Notes Found Here")
+
+
+@ultroid_bot.on(events.NewMessage())
+async def notes(e):
+ if e.is_group:
+ if not e._chat.admin_rights:
+ return
+ xx = e.text
+ if not xx.startswith("#"):
+ return
+ xx = xx.replace("#", "")
+ chat = e.chat_id
+ x = get_notes(int(chat))
+ if x:
+ if " " in xx:
+ xx = xx.split(" ")[0]
+ 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/pdftools.py b/plugins/pdftools.py
index 78b1ed29fe3dfc018cbec3d3c65b818a3025d84e..eccf34f6dcd40b0f9ac6cb94c4418c40f86c8d6a 100644
--- a/plugins/pdftools.py
+++ b/plugins/pdftools.py
@@ -83,7 +83,9 @@ async def pdfseimg(event):
pw.write(f)
os.remove(pdfp)
await event.client.send_file(
- event.chat_id, "ult.png", reply_to=event.reply_to_msg_id
+ event.chat_id,
+ "ult.png",
+ reply_to=event.reply_to_msg_id,
)
os.remove("ult.png")
await xx.delete()
@@ -107,11 +109,13 @@ async def pdfsetxt(event):
for page_num in range(pdf.numPages):
pageObj = pdf.getPage(page_num)
txt = pageObj.extractText()
- f.write("Page {0}\n".format(page_num + 1))
+ f.write("Page {}\n".format(page_num + 1))
f.write("".center(100, "-"))
f.write(txt)
await event.client.send_file(
- event.chat_id, text, reply_to=event.reply_to_msg_id
+ event.chat_id,
+ text,
+ reply_to=event.reply_to_msg_id,
)
os.remove(text)
os.remove(dl)
@@ -128,7 +132,9 @@ async def pdfsetxt(event):
with open(text, "w") as f:
f.write(str)
await event.client.send_file(
- event.chat_id, text, reply_to=event.reply_to_msg_id
+ event.chat_id,
+ text,
+ reply_to=event.reply_to_msg_id,
)
os.remove(text)
os.remove(dl)
@@ -141,7 +147,9 @@ async def pdfsetxt(event):
with open(text, "w") as f:
f.write(str)
await event.client.send_file(
- event.chat_id, text, reply_to=event.reply_to_msg_id
+ event.chat_id,
+ text,
+ reply_to=event.reply_to_msg_id,
)
os.remove(text)
os.remove(dl)
@@ -172,7 +180,9 @@ async def imgscan(event):
image_blurred = cv2.GaussianBlur(image_y, (3, 3), 0)
edges = cv2.Canny(image_blurred, 50, 200, apertureSize=3)
contours, hierarchy = cv2.findContours(
- edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
+ edges,
+ cv2.RETR_EXTERNAL,
+ cv2.CHAIN_APPROX_SIMPLE,
)
polygons = []
for cnt in contours:
@@ -183,7 +193,8 @@ async def imgscan(event):
simplified_cnt = sortedPoly[0]
if len(simplified_cnt) == 4:
cropped_image = four_point_transform(
- original_image, simplified_cnt.reshape(4, 2) * ratio
+ original_image,
+ simplified_cnt.reshape(4, 2) * ratio,
)
gray_image = cv2.cvtColor(cropped_image, cv2.COLOR_BGR2GRAY)
T = threshold_local(gray_image, 11, offset=10, method="gaussian")
@@ -209,7 +220,8 @@ async def savepdf(event):
ok = await event.get_reply_message()
if not (ok and (ok.media)):
await eor(
- event, "`Reply to Images/pdf which u want to merge as a single pdf..`"
+ event,
+ "`Reply to Images/pdf which u want to merge as a single pdf..`",
)
return
ultt = await ok.download_media()
@@ -225,20 +237,23 @@ async def savepdf(event):
image_blurred = cv2.GaussianBlur(image_y, (3, 3), 0)
edges = cv2.Canny(image_blurred, 50, 200, apertureSize=3)
contours, hierarchy = cv2.findContours(
- edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
+ edges,
+ cv2.RETR_EXTERNAL,
+ cv2.CHAIN_APPROX_SIMPLE,
)
polygons = []
for cnt in contours:
hull = cv2.convexHull(cnt)
polygons.append(
- cv2.approxPolyDP(hull, 0.01 * cv2.arcLength(hull, True), False)
+ cv2.approxPolyDP(hull, 0.01 * cv2.arcLength(hull, True), False),
)
sortedPoly = sorted(polygons, key=cv2.contourArea, reverse=True)
cv2.drawContours(image, sortedPoly[0], -1, (0, 0, 255), 5)
simplified_cnt = sortedPoly[0]
if len(simplified_cnt) == 4:
cropped_image = four_point_transform(
- original_image, simplified_cnt.reshape(4, 2) * ratio
+ original_image,
+ simplified_cnt.reshape(4, 2) * ratio,
)
gray_image = cv2.cvtColor(cropped_image, cv2.COLOR_BGR2GRAY)
T = threshold_local(gray_image, 11, offset=10, method="gaussian")
diff --git a/plugins/pmpermit.py b/plugins/pmpermit.py
index 08d7f0227d33aaf0c384c0b8f51963256b101d63..6431ad85a6f54ac5994235c645061eaa06fb042e 100644
--- a/plugins/pmpermit.py
+++ b/plugins/pmpermit.py
@@ -35,7 +35,7 @@ LASTMSG = {}
if Redis("PMPIC"):
PMPIC = Redis("PMPIC")
else:
- PMPIC = "https://telegra.ph/file/94f6a4aeb21ce2d58dd41.jpg"
+ PMPIC = "https://telegra.ph/file/031957757a4f6a5191040.jpg"
UND = get_string("pmperm_1")
@@ -85,7 +85,7 @@ PMCMDS = [
@ultroid_bot.on(events.NewMessage(incoming=True, func=lambda e: e.is_private))
async def permitpm(event):
user = await event.get_chat()
- if user.bot or user.is_self:
+ if user.bot or user.is_self or user.verified:
return
if Redis("PMLOG") == "True":
pl = udB.get("PMLOGGROUP")
@@ -133,8 +133,11 @@ if sett == "True" and sett != "False":
apprv = is_approved(user.id)
if not apprv and event.text != UND:
name = user.first_name
- fullname = (user.first_name, user.last_name)
- username = user.username
+ if user.last_name:
+ fullname = f"{name} {user.last_name}"
+ else:
+ fullname = name
+ username = f"@{user.username}"
mention = f"[{get_display_name(user)}](tg://user?id={user.id})"
count = len(get_approved())
try:
@@ -145,12 +148,14 @@ if sett == "True" and sett != "False":
prevmsg = LASTMSG[user.id]
if event.text != prevmsg:
async for message in event.client.iter_messages(
- user.id, search=UND
+ user.id,
+ search=UND,
):
await message.delete()
async for message in event.client.iter_messages(
- user.id, search=UNS
+ user.id,
+ search=UNS,
):
await message.delete()
await event.client.send_file(
@@ -170,7 +175,8 @@ if sett == "True" and sett != "False":
)
elif event.text == prevmsg:
async for message in event.client.iter_messages(
- user.id, search=UND
+ user.id,
+ search=UND,
):
await message.delete()
await event.client.send_file(
@@ -233,7 +239,7 @@ if sett == "True" and sett != "False":
name0 = str(name.first_name)
await event.client.send_message(
Var.LOG_CHANNEL,
- f"[{name0}](tg://user?id={user.id}) was blocked for spamming.",
+ f"[{name0}](tg://user?id={user.id}) was Blocked for spamming.",
)
@ultroid_cmd(pattern="(a|approve)(?: |$)")
@@ -244,7 +250,8 @@ if sett == "True" and sett != "False":
aname = replied_user.id
if str(aname) in DEVLIST:
return await eor(
- apprvpm, "Lol, He is my Developer\nHe is auto Approved"
+ apprvpm,
+ "Lol, He is my Developer\nHe is auto Approved",
)
name0 = str(replied_user.first_name)
uid = replied_user.id
@@ -262,7 +269,8 @@ if sett == "True" and sett != "False":
aname = await apprvpm.client.get_entity(user.id)
if str(user.id) in DEVLIST:
return await eor(
- apprvpm, "Lol, He is my Developer\nHe is auto Approved"
+ apprvpm,
+ "Lol, He is my Developer\nHe is auto Approved",
)
name0 = str(aname.first_name)
uid = user.id
@@ -301,19 +309,20 @@ if sett == "True" and sett != "False":
aname = replied_user.id
if str(aname) in DEVLIST:
return await eor(
- e, "`Lol, He is my Developer\nHe Can't Be DisApproved.`"
+ e,
+ "`Lol, He is my Developer\nHe Can't Be DisApproved.`",
)
name0 = str(replied_user.first_name)
if is_approved(replied_user.id):
disapprove_user(replied_user.id)
await e.edit(
- f"[{name0}](tg://user?id={replied_user.id}) `Disaproved to PM!`"
+ f"[{name0}](tg://user?id={replied_user.id}) `Disaproved to PM!`",
)
await asyncio.sleep(5)
await e.delete()
else:
await e.edit(
- f"[{name0}](tg://user?id={replied_user.id}) was never approved!"
+ f"[{name0}](tg://user?id={replied_user.id}) was never approved!",
)
await asyncio.sleep(5)
await e.delete()
@@ -322,7 +331,8 @@ if sett == "True" and sett != "False":
aname = await e.client.get_entity(bbb.id)
if str(bbb.id) in DEVLIST:
return await eor(
- e, "`Lol, He is my Developer\nHe Can't Be DisApproved.`"
+ e,
+ "`Lol, He is my Developer\nHe Can't Be DisApproved.`",
)
name0 = str(aname.first_name)
if is_approved(bbb.id):
@@ -350,7 +360,8 @@ if sett == "True" and sett != "False":
aname = replied_user.id
if str(aname) in DEVLIST:
return await eor(
- block, "`Lol, He is my Developer\nHe Can't Be Blocked`"
+ block,
+ "`Lol, He is my Developer\nHe Can't Be Blocked`",
)
name0 = str(replied_user.first_name)
await block.client(BlockRequest(replied_user.id))
@@ -360,7 +371,8 @@ if sett == "True" and sett != "False":
bbb = await block.get_chat()
if str(bbb.id) in DEVLIST:
return await eor(
- block, "`Lol, He is my Developer\nHe Can't Be Blocked`"
+ block,
+ "`Lol, He is my Developer\nHe Can't Be Blocked`",
)
await block.client(BlockRequest(bbb.id))
aname = await block.client.get_entity(bbb.id)
@@ -375,7 +387,8 @@ if sett == "True" and sett != "False":
pass
if Var.LOG_CHANNEL:
await block.client.send_message(
- Var.LOG_CHANNEL, f"#BLOCKED\nUser: [{name0}](tg://user?id={uid})"
+ Var.LOG_CHANNEL,
+ f"#BLOCKED\nUser: [{name0}](tg://user?id={uid})",
)
@ultroid_cmd(pattern="unblock$")
diff --git a/plugins/profile.py b/plugins/profile.py
index cffdaea54d6a4fa6c28569446df8e5dce9adab3e..7a6bd5be5ae23a6115ef875d89993bc2bc37c4ce 100644
--- a/plugins/profile.py
+++ b/plugins/profile.py
@@ -20,7 +20,7 @@
• `{i}delpfp (optional)`
Delete one profile pic, if no value given, else delete n number of pics.
-• `{i}gpoto `
+• `{i}poto `
Upload the photo of Chat/User if Available.
"""
@@ -47,7 +47,7 @@ async def _(ult):
set = ult.pattern_match.group(1)
try:
await ultroid_bot(functions.account.UpdateProfileRequest(about=set))
- await ok.edit("Profile bio changed to\n`{}`".format(set))
+ await ok.edit(f"Profile bio changed to\n`{set}`")
except Exception as ex:
await ok.edit("Error occured.\n`{}`".format(str(ex)))
await asyncio.sleep(10)
@@ -70,10 +70,11 @@ async def _(ult):
try:
await ultroid_bot(
functions.account.UpdateProfileRequest(
- first_name=first_name, last_name=last_name
- )
+ first_name=first_name,
+ last_name=last_name,
+ ),
)
- await ok.edit("Name changed to `{}`".format(names))
+ await ok.edit(f"Name changed to `{names}`")
except Exception as ex:
await ok.edit("Error occured.\n`{}`".format(str(ex)))
await asyncio.sleep(10)
@@ -131,7 +132,7 @@ async def remove_profilepic(delpfp):
else:
lim = 1
pfplist = await ultroid_bot(
- GetUserPhotosRequest(user_id=delpfp.from_id, offset=0, max_id=0, limit=lim)
+ GetUserPhotosRequest(user_id=delpfp.from_id, offset=0, max_id=0, limit=lim),
)
input_photos = []
for sep in pfplist.photos:
@@ -140,7 +141,7 @@ async def remove_profilepic(delpfp):
id=sep.id,
access_hash=sep.access_hash,
file_reference=sep.file_reference,
- )
+ ),
)
await ultroid_bot(DeletePhotosRequest(id=input_photos))
await ok.edit(f"`Successfully deleted {len(input_photos)} profile picture(s).`")
@@ -148,19 +149,24 @@ async def remove_profilepic(delpfp):
await ok.delete()
-@ultroid_cmd(pattern="gpoto ?(.*)")
+@ultroid_cmd(pattern="poto ?(.*)")
async def gpoto(e):
ult = e.pattern_match.group(1)
- a = await eor(e,"`Processing...`")
+ a = await eor(e, "`Processing...`")
+ if not ult and e.is_reply:
+ gs = await e.get_reply_message()
+ ult = gs.sender_id
try:
okla = await ultroid_bot.download_profile_photo(
- ult, "profile.jpg", download_big=True
+ ult,
+ "profile.jpg",
+ download_big=True,
)
await a.delete()
await ultroid_bot.send_message(e.chat_id, file=okla)
os.remove(okla)
- except Exception as e:
- await eor(e, f"ERROR - {str(e)}")
+ except Exception as er:
+ await eor(e, f"ERROR - {str(er)}")
HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/redis.py b/plugins/redis.py
index 84f9460fc2df97c0039894fe0d5562b793bf8231..a78ed21ac6091d07ac56cf5d121ff68c5e888dbb 100644
--- a/plugins/redis.py
+++ b/plugins/redis.py
@@ -49,8 +49,9 @@ async def _(ult):
redisdata = Redis(data[0])
await ok.edit(
"Redis Key Value Pair Updated\nKey : `{}`\nValue : `{}`".format(
- data[0], redisdata
- )
+ data[0],
+ redisdata,
+ ),
)
except BaseException:
await ok.edit("`Something Went Wrong`")
@@ -66,7 +67,7 @@ async def _(ult):
return await ult.edit(f"Please use `{hndlr}getkeys `")
try:
value = Redis(val)
- await ok.edit("Key: `{}`\nValue: `{}`".format(val, value))
+ await ok.edit(f"Key: `{val}`\nValue: `{value}`")
except BaseException:
await ok.edit("`Something Went Wrong`")
@@ -96,8 +97,9 @@ async def _(ult):
udB.rename(data[0], data[1])
await ok.edit(
"Redis Key Rename Successful\nOld Key : `{}`\nNew Key : `{}`".format(
- data[0], data[1]
- )
+ data[0],
+ data[1],
+ ),
)
except BaseException:
await ok.edit("Something went wrong ...")
@@ -113,8 +115,11 @@ async def _(ult):
keys = sorted(udB.keys())
msg = ""
for x in keys:
- msg += "• `{}`".format(x) + "\n"
- await ok.edit("**List of Redis Keys :**\n{}".format(msg))
+ if x.isdigit() or x.startswith("-"):
+ pass
+ else:
+ msg += f"• `{x}`" + "\n"
+ await ok.edit(f"**List of Redis Keys :**\n{msg}")
@ultroid_cmd(
diff --git a/plugins/save.py b/plugins/save.py
new file mode 100644
index 0000000000000000000000000000000000000000..e6ab3876a92c475041cc974d711236cfdaecc94d
--- /dev/null
+++ b/plugins/save.py
@@ -0,0 +1,29 @@
+# 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}save `
+ Save that replied msg to ur saved messages box.
+
+"""
+from . import *
+
+
+@ultroid_cmd(pattern="save$")
+async def saf(e):
+ x = await e.get_reply_message()
+ if not x:
+ return await eod(
+ e, "Reply to Any Message to save it to ur saved messages", time=5
+ )
+ await ultroid_bot.send_message("me", x)
+ await eod(e, "Message saved at saved messages", time=5)
+
+
+HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/snips.py b/plugins/snips.py
new file mode 100644
index 0000000000000000000000000000000000000000..a4f98e8c58edbe97016b98770ff61987e8efdf3c
--- /dev/null
+++ b/plugins/snips.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}addsnip `
+ add the used word as snip relating to replied message.
+
+• `{i}remsnip `
+ Remove the snip word..
+
+• `{i}listsnip`
+ list all snips.
+
+• Use :
+ type `$(ur snip word)` get setted reply.
+"""
+import os
+
+from pyUltroid.functions.snips_db import *
+from telegraph import upload_file as uf
+from telethon.utils import pack_bot_file_id
+
+from . import *
+
+
+@ultroid_cmd(pattern="addsnip ?(.*)")
+async def an(e):
+ wrd = e.pattern_match.group(1)
+ wt = await e.get_reply_message()
+ if not (wt and wrd):
+ return await eor(e, "Give word to set as snip and reply to a message.")
+ if "$" in wrd:
+ wrd = wrd.replace("$", "")
+ try:
+ rem_snip(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)
+ os.remove(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_snip(wrd, wt.text, m)
+ else:
+ add_snip(wrd, None, m)
+ else:
+ add_snip(wrd, wt.text, None)
+ await eor(e, f"Done : snip `${wrd}` Saved.")
+
+
+@ultroid_cmd(pattern="remsnip ?(.*)")
+async def rs(e):
+ wrd = e.pattern_match.group(1)
+ if not wrd:
+ return await eor(e, "Give the word to remove...")
+ if wrd.startswith("$"):
+ wrd = wrd.replace("$", "")
+ rem_snip(wrd)
+ await eor(e, f"Done : snip `${wrd}` Removed.")
+
+
+@ultroid_cmd(pattern="listsnip")
+async def lsnote(e):
+ x = list_snip()
+ if x:
+ sd = "SNIPS Found In This Chats Are\n\n"
+ await eor(e, sd + x)
+ else:
+ await eor(e, "No Snips Found Here")
+
+
+@ultroid_bot.on(events.NewMessage(outgoing=True))
+async def notes(e):
+ xx = e.text
+ if not xx.startswith("$"):
+ return
+ xx = xx.replace("$", "")
+ x = get_snips()
+ if x:
+ if " " in xx:
+ xx = xx.split(" ")[0]
+ k = get_reply(xx)
+ if k:
+ msg = k["msg"]
+ media = k["media"]
+ rep = await e.get_reply_message()
+ if rep:
+ await rep.reply(msg, file=media)
+ else:
+ await ultroid_bot.send_message(e.chat_id, msg, file=media)
+ await e.delete()
+
+
+HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/stickertools.py b/plugins/stickertools.py
index 2cb037144d9bec23ff22706318215678297f6881..f5114855093673f8a4300ea18afde4edbe76b3dc 100644
--- a/plugins/stickertools.py
+++ b/plugins/stickertools.py
@@ -14,7 +14,7 @@
• `{i}tiny `
To create Tiny stickers.
-• `{i}convert `
+• `{i}convert `
Reply to sticker to convert into gif or image.
• `{i}kang `
@@ -59,7 +59,7 @@ EMOJI_PATTERN = re.compile(
"\U0001FA00-\U0001FA6F" # Chess Symbols
"\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
"\U00002702-\U000027B0" # Dingbats
- "]+"
+ "]+",
)
@@ -85,7 +85,8 @@ async def waifu(animu):
finalcall = "#" + (str(random.choice(waifus)))
try:
sticcers = await ultroid_bot.inline_query(
- "stickerizerbot", f"{finalcall}{(deEmojify(text))}"
+ "stickerizerbot",
+ f"{finalcall}{(deEmojify(text))}",
)
await sticcers[0].click(
animu.chat_id,
@@ -117,10 +118,15 @@ async def uconverter(event):
elif "img" in input:
cmd = ["lottie_convert.py", b, "something.png"]
file = "something.png"
+ elif "sticker" in input:
+ cmd = ["lottie_convert.py", b, "something.webp"]
+ file = "something.webp"
else:
- return await xx.edit("**Please select from gif/img**")
+ return await xx.edit("**Please select from gif/img/sticker**")
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()
@@ -169,7 +175,8 @@ async def hehe(args):
elif "tgsticker" in message.media.document.mime_type:
await xx.edit(f"`{random.choice(KANGING_STR)}`")
await ultroid_bot.download_file(
- message.media.document, "AnimatedSticker.tgs"
+ message.media.document,
+ "AnimatedSticker.tgs",
)
attributes = message.media.document.attributes
@@ -216,7 +223,7 @@ async def hehe(args):
cmd = "/newanimated"
response = urllib.request.urlopen(
- urllib.request.Request(f"http://t.me/addstickers/{packname}")
+ urllib.request.Request(f"http://t.me/addstickers/{packname}"),
)
htmlstr = response.read().decode("utf8").split("\n")
@@ -237,7 +244,7 @@ async def hehe(args):
await xx.edit(
"`Switching to Pack "
+ str(pack)
- + " due to insufficient space`"
+ + " due to insufficient space`",
)
await conv.send_message(packname)
x = await conv.get_response()
@@ -287,7 +294,7 @@ async def hehe(args):
rsp = await conv.get_response()
if "Sorry, the file type is invalid." in rsp.text:
await xx.edit(
- "`Failed to add sticker, use` @Stickers `bot to add the sticker manually.`"
+ "`Failed to add sticker, use` @Stickers `bot to add the sticker manually.`",
)
return
await conv.send_message(emoji)
@@ -314,7 +321,7 @@ async def hehe(args):
rsp = await conv.get_response()
if "Sorry, the file type is invalid." in rsp.text:
await xx.edit(
- "`Failed to add sticker, use` @Stickers `bot to add the sticker manually.`"
+ "`Failed to add sticker, use` @Stickers `bot to add the sticker manually.`",
)
return
await conv.send_message(emoji)
@@ -361,7 +368,9 @@ async def ultdround(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()
@@ -384,7 +393,10 @@ async def ultdround(event):
npImage = np.dstack((npImage, npAlpha))
Image.fromarray(npImage).save("ult.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(file)
@@ -405,7 +417,7 @@ async def ultdestroy(event):
await event.client.download_media(ult, "ultroid.tgs")
xx = await eor(event, "`Processing...`")
os.system("lottie_convert.py ultroid.tgs json.json")
- json = open("json.json", "r")
+ json = open("json.json")
jsn = json.read()
json.close()
jsn = (
@@ -449,7 +461,7 @@ async def ultiny(event):
if ik.endswith(".tgs"):
await event.client.download_media(reply, "ult.tgs")
os.system("lottie_convert.py ult.tgs json.json")
- json = open("json.json", "r")
+ json = open("json.json")
jsn = json.read()
json.close()
jsn = jsn.replace("512", "2000")
diff --git a/plugins/sudo.py b/plugins/sudo.py
index 7c079344a34e663c357e4765a79f69b4e27d07b7..3841befee5387260e27c5e5ed09289f72819b07b 100644
--- a/plugins/sudo.py
+++ b/plugins/sudo.py
@@ -20,6 +20,7 @@
import re
+from pyUltroid.misc._decorators import sed
from telethon.tl.functions.users import GetFullUserRequest
from . import *
@@ -33,7 +34,8 @@ async def _(ult):
try:
if ult.sender_id != Var.OWNER_ID:
return await eor(
- ult, "You are sudo user, You cant add other sudo user."
+ ult,
+ "You are sudo user, You cant add other sudo user.",
)
except BaseException:
pass
@@ -50,11 +52,12 @@ async def _(ult):
return await ok.edit("You cant add yourself as Sudo User...")
elif is_sudo(id):
return await ok.edit(
- f"[{user.user.first_name}](tg://user?id={id}) `is already a SUDO User ...`"
+ f"[{user.user.first_name}](tg://user?id={id}) `is already a SUDO User ...`",
)
elif add_sudo(id):
+ udB.set("SUDO", "True")
return await ok.edit(
- f"**Added [{user.user.first_name}](tg://user?id={id}) as SUDO User**"
+ f"**Added [{user.user.first_name}](tg://user?id={id}) as SUDO User**",
)
else:
return await ok.edit("`SEEMS LIKE THIS FUNCTION CHOOSE TO BROKE ITSELF`")
@@ -97,11 +100,12 @@ async def _(ult):
return await ok.edit("`Invalid UserID`")
elif is_sudo(id):
return await ok.edit(
- f"[{user.user.first_name}](tg://user?id={id}) `is already a SUDO User ...`"
+ f"[{user.user.first_name}](tg://user?id={id}) `is already a SUDO User ...`",
)
elif add_sudo(id):
+ udB.set("SUDO", "True")
return await ok.edit(
- f"**Added [{user.user.first_name}](tg://user?id={id}) as SUDO User**"
+ f"**Added [{user.user.first_name}](tg://user?id={id}) as SUDO User**\n\nDo Restart",
)
else:
return await ok.edit(f"**Failed to add `{id}` as SUDO User ... **")
@@ -115,7 +119,8 @@ async def _(ult):
try:
if ult.sender_id != Var.OWNER_ID:
return await eor(
- ult, "You are sudo user, You cant add other sudo user."
+ ult,
+ "You are sudo user, You cant add other sudo user.",
)
except BaseException:
pass
@@ -130,11 +135,11 @@ async def _(ult):
sed.remove(id)
if not is_sudo(id):
return await ok.edit(
- f"[{user.user.first_name}](tg://user?id={id}) `wasn't a SUDO User ...`"
+ f"[{user.user.first_name}](tg://user?id={id}) `wasn't a SUDO User ...`",
)
elif del_sudo(id):
return await ok.edit(
- f"**Removed [{user.user.first_name}](tg://user?id={id}) from SUDO User(s)**"
+ f"**Removed [{user.user.first_name}](tg://user?id={id}) from SUDO User(s)**",
)
else:
return await ok.edit("`SEEMS LIKE THIS FUNCTION CHOOSE TO BREAK ITSELF`")
@@ -179,11 +184,11 @@ async def _(ult):
return await ok.edit("`Invalid UserID`")
elif not is_sudo(id):
return await ok.edit(
- f"[{user.user.first_name}](tg://user?id={id}) wasn't a SUDO user ..."
+ f"[{user.user.first_name}](tg://user?id={id}) wasn't a SUDO user ...",
)
elif del_sudo(id):
return await ok.edit(
- f"**Removed [{user.user.first_name}](tg://user?id={id}) from SUDO User**"
+ f"**Removed [{user.user.first_name}](tg://user?id={id}) from SUDO User**",
)
else:
return await ok.edit(f"**Failed to Remove `{id}` as SUDO User ... **")
@@ -208,7 +213,12 @@ async def _(ult):
msg += f"• [{user.user.first_name}](tg://user?id={i}) ( `{i}` )\n"
else:
msg += f"• `{i}` -> Invalid User\n"
- return await ok.edit(f"**List of SUDO Users :**\n{msg}")
+ m = udB.get("SUDO") if udB.get("SUDO") else "False"
+ if m == "False":
+ m = "[False](https://telegra.ph/Ultroid-04-06)"
+ return await ok.edit(
+ f"**SUDO MODE : {m}\n\nList of SUDO Users :**\n{msg}", link_preview=False
+ )
HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/tag.py b/plugins/tag.py
index 134ab9e76b2468546303ba8df2e97cb2b392db5a..748a83c17a5f7012bbe82ddbd37acdad026bd5cc 100644
--- a/plugins/tag.py
+++ b/plugins/tag.py
@@ -16,7 +16,7 @@
• `{i}tagowner`
Tag Owner of that chat
-
+
• `{i}tagbots`
Tag Bots of that chat.
diff --git a/plugins/tools.py b/plugins/tools.py
index 52d34ccbcca5b757d0e8752629b5eb5345f60222..37749a62bc5610a46022932116c74a4c8f1eee19 100644
--- a/plugins/tools.py
+++ b/plugins/tools.py
@@ -28,7 +28,7 @@
Reply a User to Get His Id
Without Replying You Will Get the Chat's Id
-• `{i}sg `
+• `{i}sg `
Get His Name History of the replied user.
• `{i}tr <(reply to) a message>`
@@ -46,7 +46,8 @@ import cv2
import emoji
from googletrans import Translator
from telethon.errors.rpcerrorlist import YouBlockedUserError
-from telethon.tl.types import ChannelParticipantAdmin, ChannelParticipantsBots
+from telethon.tl.types import (ChannelParticipantAdmin,
+ ChannelParticipantsBots, User)
from telethon.utils import pack_bot_file_id
from . import *
@@ -91,14 +92,17 @@ async def _(event):
await eor(
event,
"**Current Chat ID:** `{}`\n**From User ID:** `{}`\n**Bot API File ID:** `{}`".format(
- str(event.chat_id), str(r_msg.sender.id), bot_api_file_id
+ str(event.chat_id),
+ str(r_msg.sender.id),
+ bot_api_file_id,
),
)
else:
await eor(
event,
"**Chat ID:** `{}`\n**User ID:** `{}`".format(
- str(event.chat_id), str(r_msg.sender.id)
+ str(event.chat_id),
+ str(r_msg.sender.id),
),
)
else:
@@ -120,7 +124,7 @@ async def _(ult):
if not input_str:
chat = to_write_chat
else:
- mentions = "**Bots in **{}: \n".format(input_str)
+ mentions = f"**Bots in **{input_str}: \n"
try:
chat = await ultroid_bot.get_entity(input_str)
except Exception as e:
@@ -128,15 +132,20 @@ async def _(ult):
return None
try:
async for x in ultroid_bot.iter_participants(
- chat, filter=ChannelParticipantsBots
+ chat,
+ filter=ChannelParticipantsBots,
):
if isinstance(x.participant, ChannelParticipantAdmin):
mentions += "\n ⚜️ [{}](tg://user?id={}) `{}`".format(
- x.first_name, x.id, x.id
+ x.first_name,
+ x.id,
+ x.id,
)
else:
mentions += "\n [{}](tg://user?id={}) `{}`".format(
- x.first_name, x.id, x.id
+ x.first_name,
+ x.id,
+ x.id,
)
except Exception as e:
mentions += " " + str(e) + "\n"
@@ -174,7 +183,7 @@ async def _(e):
c = await a.download_media(
"resources/downloads/",
progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
- progress(d, t, z, toime, "Dᴏᴡɴʟᴏᴀᴅɪɴɢ...")
+ progress(d, t, z, toime, "Dᴏᴡɴʟᴏᴀᴅɪɴɢ..."),
),
)
await z.edit("**Dᴏᴡɴʟᴏᴀᴅᴇᴅ...\nNᴏᴡ Cᴏɴᴠᴇʀᴛɪɴɢ...**")
@@ -193,7 +202,9 @@ async def _(e):
"comp.mp3",
]
proess = 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 proess.communicate()
stderr.decode().strip()
@@ -210,7 +221,9 @@ async def _(e):
"circle.mp4",
]
process = await asyncio.create_subprocess_exec(
- *mcd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
+ *mcd,
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await process.communicate()
stderr.decode().strip()
@@ -223,7 +236,7 @@ async def _(e):
video_note=True,
reply_to=a,
progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
- progress(d, t, z, taime, "Uᴘʟᴏᴀᴅɪɴɢ...")
+ progress(d, t, z, taime, "Uᴘʟᴏᴀᴅɪɴɢ..."),
),
)
await z.delete()
@@ -260,30 +273,25 @@ async def _(event):
reply_to_id = event.reply_to_msg_id
time.time() + 100
process = await asyncio.create_subprocess_shell(
- cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
+ cmd,
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await process.communicate()
- OUT = f"☞ BASH\n\n• COMMAND: \n{cmd}
\n\n"
+ OUT = f"**☞ BASH\n\n• COMMAND:**\n`{cmd}` \n\n"
e = stderr.decode()
if e:
- OUT += f"• ERROR: \n{e}
\n"
+ OUT += f"**• ERROR:** \n`{e}`\n"
o = stdout.decode()
- if not o and not e:
+ if not o:
o = "Success"
- OUT += f"• OUTPUT: \n{o}"
+ OUT += f"**• OUTPUT:**\n`{o}`"
else:
_o = o.split("\n")
o = "\n".join(_o)
- OUT += f"• OUTPUT: \n{o}
"
+ OUT += f"**• OUTPUT:**\n`{o}`"
if len(OUT) > 4096:
- ultd = (
- OUT.replace("", "")
- .replace("
", "")
- .replace("", "")
- .replace(" ", "")
- .replace("", "")
- .replace(" ", "")
- )
+ ultd = OUT.replace("`", "").replace("*", "").replace("_", "")
with io.BytesIO(str.encode(ultd)) as out_file:
out_file.name = "bash.txt"
await event.client.send_file(
@@ -296,7 +304,7 @@ async def _(event):
)
await xx.delete()
else:
- await eod(xx, OUT, parse_mode="html")
+ await eod(xx, OUT)
@ultroid_cmd(
@@ -339,18 +347,14 @@ async def _(event):
evaluation = stdout
else:
evaluation = "Success"
- final_output = "► EVAL \n{}
\n\n► OUTPUT : \n{}
".format(
- cmd, evaluation
+ final_output = (
+ "__►__ **EVAL**\n```{}``` \n\n __►__ **OUTPUT**: \n```{}``` \n".format(
+ cmd,
+ evaluation,
+ )
)
if len(final_output) > 4096:
- ultd = (
- final_output.replace("", "")
- .replace("
", "")
- .replace("", "")
- .replace(" ", "")
- .replace("", "")
- .replace(" ", "")
- )
+ ultd = final_output.replace("`", "").replace("*", "").replace("_", "")
with io.BytesIO(str.encode(ultd)) as out_file:
out_file.name = "eval.txt"
await ultroid_bot.send_file(
@@ -363,7 +367,7 @@ async def _(event):
)
await xx.delete()
else:
- await eod(xx, final_output, parse_mode="html")
+ await eod(xx, final_output)
async def aexec(code, event):
@@ -372,29 +376,31 @@ async def aexec(code, event):
exec(
f"async def __aexec(e, client): "
+ "\n message = event = e"
- + "".join(f"\n {l}" for l in code.split("\n"))
+ + "".join(f"\n {l}" for l in code.split("\n")),
)
return await locals()["__aexec"](e, e.client)
@ultroid_cmd(
- pattern="sg(?: |$)(.*)",
+ pattern="sg ?(.*)",
)
async def lastname(steal):
- if steal.fwd_from:
- return
- if not steal.reply_to_msg_id:
- await steal.edit("Reply to any user message.")
+ mat = steal.pattern_match.group(1)
+ if not (steal.is_reply or mat):
+ await eor(steal, "`Use this command with reply or give Username/id...`")
return
+ if mat:
+ user_id = await get_user_id(mat)
message = await steal.get_reply_message()
+ if message:
+ user_id = message.sender.id
chat = "@SangMataInfo_bot"
- user_id = message.sender.id
id = f"/search_id {user_id}"
- if message.sender.bot:
- await steal.edit("Reply to actual users message.")
- return
- lol = await eor(steal, "Processingg !!!!!")
+ check = await ultroid_bot.get_entity(user_id)
+ if not isinstance(check, User) or check.bot:
+ return await eor(steal, "Reply to Actual User's Message !")
+ lol = await eor(steal, "`Processing !...`")
try:
async with ultroid_bot.conversation(chat) as conv:
try:
@@ -420,7 +426,8 @@ async def lastname(steal):
await lol.edit(respond.message)
await lol.reply(response.message)
await steal.client.delete_messages(
- conv.chat_id, [msg.id, responds.id, respond.id, response.id]
+ conv.chat_id,
+ [msg.id, responds.id, respond.id, response.id],
)
except TimeoutError:
return await lol.edit("Error: @SangMataInfo_bot is not responding!.")
diff --git a/plugins/updater.py b/plugins/updater.py
index e61cea59f91031d8bc4aaf7dcd7be0c6c79aacb6..be0228fd806ae93b015232065988e6c70c9c53a7 100644
--- a/plugins/updater.py
+++ b/plugins/updater.py
@@ -4,28 +4,43 @@
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
# PLease read the GNU Affero General Public License in
# .
+"""
+✘ Commands Available -
+• `{i}update`
+ See changelogs if any update is available.
+• `{i}update now`
+ (Force)Update your bots to the latest version.
+"""
import asyncio
import sys
-from os import environ, execle, path, remove
+from os import execl, path, remove
from git import Repo
from git.exc import GitCommandError, InvalidGitRepositoryError, NoSuchPathError
-from . import get_string
+from . import HELP, get_string, ultroid_version
UPSTREAM_REPO_URL = "https://github.com/TeamUltroid/Ultroid"
requirements_path = path.join(
- path.dirname(path.dirname(path.dirname(__file__))), "requirements.txt"
+ path.dirname(path.dirname(path.dirname(__file__))),
+ "requirements.txt",
)
async def gen_chlog(repo, diff):
- ch_log = ""
- d_form = "On %d/%m/%y at %H:%M:%S"
+ ac_br = repo.active_branch.name
+ ch_log = tldr_log = ""
+ ch = f"Ultroid {ultroid_version} updates for [{ac_br}] : "
+ ch_tl = f"Ultroid {ultroid_version} updates for {ac_br}:"
+ d_form = "%d/%m/%y || %H:%M"
for c in repo.iter_commits(diff):
- ch_log += f"**#{c.count()}** : {c.committed_datetime.strftime(d_form)} : [{c.summary}]({UPSTREAM_REPO_URL.rstrip('/')}/commit/{c}) by `{c.author}`\n"
- return ch_log
+ ch_log += f"\n\n💬 {c.count()} 🗓 [{c.committed_datetime.strftime(d_form)}] \n[{c.summary}] 👨💻 {c.author}
"
+ tldr_log += f"\n\n💬 {c.count()} 🗓 [{c.committed_datetime.strftime(d_form)}]\n[{c.summary}] 👨💻 {c.author}"
+ if ch_log:
+ return str(ch + ch_log), str(ch_tl + tldr_log)
+ else:
+ return ch_log, tldr_log
async def updateme_requirements():
@@ -75,41 +90,33 @@ async def upstream(ups):
repo.heads.main.set_tracking_branch(origin.refs.main)
repo.heads.main.checkout(True)
ac_br = repo.active_branch.name
- # if ac_br != "main":
- # await eod(
- # pagal,
- # f"**[UPDATER]:**` You are on ({ac_br})\n Please change to the main branch.`",
- # )
- # repo.__del__()
- # return
try:
repo.create_remote("upstream", off_repo)
except BaseException:
pass
ups_rem = repo.remote("upstream")
ups_rem.fetch(ac_br)
- changelog = await gen_chlog(repo, f"HEAD..upstream/{ac_br}")
+ changelog, tl_chnglog = await gen_chlog(repo, f"HEAD..upstream/{ac_br}")
if "now" not in conf:
if changelog:
- changelog_str = get_string("upd_3").format(
- ac_br, UPSTREAM_REPO_URL, ac_br, changelog
+ changelog_str = (
+ changelog + f"\n\nUse {hndlr}update now
to update!"
)
+ tldr_str = tl_chnglog + f"\n\nUse {hndlr}update now to update!"
if len(changelog_str) > 4096:
await eor(pagal, get_string("upd_4"))
- file = open("output.txt", "w+")
- file.write(changelog_str)
+ file = open(f"ultroid_updates.txt", "w+")
+ file.write(tldr_str)
file.close()
await ups.client.send_file(
ups.chat_id,
- "output.txt",
+ f"ultroid_updates.txt",
caption=get_string("upd_5").format(hndlr),
reply_to=ups.id,
)
- remove("output.txt")
+ remove(f"ultroid_updates.txt")
else:
- return await eod(
- pagal, get_string("upd_6").format(changelog_str, hndlr)
- )
+ return await eod(pagal, changelog_str, parse_mode="html")
else:
await eod(
pagal,
@@ -145,12 +152,14 @@ async def upstream(ups):
repo.__del__()
return
await eor(
- pagal, "`Userbot dyno build in progress, please wait for it to complete.`"
+ pagal,
+ "`Userbot dyno build in progress, please wait for it to complete.`",
)
ups_rem.fetch(ac_br)
repo.git.reset("--hard", "FETCH_HEAD")
heroku_git_url = heroku_app.git_url.replace(
- "https://", "https://api:" + Var.HEROKU_API + "@"
+ "https://",
+ "https://api:" + Var.HEROKU_API + "@",
)
if "heroku" in repo.remotes:
remote = repo.remote("heroku")
@@ -176,6 +185,8 @@ async def upstream(ups):
"`Successfully Updated!\nBot is restarting... Wait for a second!`",
)
# Spin a new instance of bot
- args = [sys.executable, "./resources/startup/deploy.sh"]
- execle(sys.executable, *args, environ)
+ execl(sys.executable, sys.executable, "-m", "pyUltroid")
return
+
+
+HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/utilities.py b/plugins/utilities.py
index 3a2d15711816f85ced579f09d004303761b97b19..1bf0764e71504fe1b65365ea6b81833afa11aff8 100644
--- a/plugins/utilities.py
+++ b/plugins/utilities.py
@@ -29,9 +29,6 @@
• `{i}paste`
Include long text / Reply to text file.
-• `{i}hastebin`
- Include long text / Reply to text file.
-
• `{i}info `
Reply to someone's msg.
@@ -49,6 +46,9 @@
• `{i}suggest `
Create a Yes/No poll for the replied suggestion.
+
+• `{i}ipinfo `
+ Get info about that IP address.
"""
import asyncio
import calendar
@@ -65,10 +65,6 @@ import requests
from telegraph import Telegraph
from telegraph import upload_file as uf
from telethon import functions
-from telethon.errors.rpcerrorlist import BotInlineDisabledError
-from telethon.errors.rpcerrorlist import BotMethodInvalidError as bmi
-from telethon.errors.rpcerrorlist import (BotResponseTimeoutError,
- ChatSendInlineForbiddenError)
from telethon.events import NewMessage
from telethon.tl.custom import Dialog
from telethon.tl.functions.channels import LeaveChannelRequest
@@ -93,9 +89,9 @@ telegraph.create_account(short_name="Ultroid")
groups_only=True,
)
async def leave(ult):
- x = ultroid_bot.me
- name = x.first_name
- await eor(ult, f"`{name} has left this group, bye!!.`")
+ if ult.sender_id != ultroid_bot.uid:
+ return
+ await eor(ult, f"`{ultroid_bot.me.first_name} has left this group, bye!!.`")
await ultroid_bot(LeaveChannelRequest(ult.chat_id))
@@ -150,7 +146,8 @@ async def _(event):
**SOLUTION**:
`{}`
""".format(
- cmd, evaluation
+ cmd,
+ evaluation,
)
await x.edit(final_output)
@@ -317,43 +314,8 @@ async def _(event):
ok = await ultroid_bot.inline_query(Var.BOT_USERNAME, q)
await ok[0].click(event.chat_id, reply_to=event.reply_to_msg_id, hide_via=True)
await xx.delete()
- except BotInlineDisabledError or BotResponseTimeoutError or ChatSendInlineForbiddenError: # handling possible exceptions
+ except BaseException:
await xx.edit(reply_text)
- except bmi:
- await xx.edit(f"**Inline Not Available as You Are in Bot Mode\n\n{reply_text}")
-
-
-@ultroid_cmd(
- pattern="hastebin ?(.*)",
-)
-async def _(event):
- input_str = event.pattern_match.group(1)
- xx = await eor(event, get_string("com_1"))
- message = "SYNTAX: `.paste `"
- if input_str:
- message = input_str
- elif event.reply_to_msg_id:
- previous_message = await event.get_reply_message()
- if previous_message.media:
- downloaded_file_name = await event.client.download_media(
- previous_message,
- "./resources/downloads",
- )
- m_list = None
- with open(downloaded_file_name, "rb") as fd:
- m_list = fd.readlines()
- message = ""
- for m in m_list:
- message += m.decode("UTF-8") + "\r\n"
- os.remove(downloaded_file_name)
- else:
- message = previous_message.message
- else:
- message = "SYNTAX: `.hastebin `"
- url = "https://hastebin.com/documents"
- r = requests.post(url, data=message).json()
- url = f"https://hastebin.com/{r['key']}"
- await xx.edit("**Pasted to Hastebin** : [Link]({})".format(url))
@ultroid_cmd(
@@ -367,8 +329,11 @@ async def _(event):
return False
replied_user_profile_photos = await event.client(
GetUserPhotosRequest(
- user_id=replied_user.user.id, offset=42, max_id=0, limit=80
- )
+ user_id=replied_user.user.id,
+ offset=42,
+ max_id=0,
+ limit=80,
+ ),
)
replied_user_profile_photos_count = "NaN"
try:
@@ -444,8 +409,10 @@ async def _(ult):
try:
await ultroid_bot(
functions.messages.AddChatUserRequest(
- chat_id=ult.chat_id, user_id=user_id, fwd_limit=1000000
- )
+ chat_id=ult.chat_id,
+ user_id=user_id,
+ fwd_limit=1000000,
+ ),
)
await xx.edit(f"Successfully invited `{user_id}` to `{ult.chat_id}`")
except Exception as e:
@@ -455,8 +422,9 @@ async def _(ult):
try:
await ultroid_bot(
functions.channels.InviteToChannelRequest(
- channel=ult.chat_id, users=[user_id]
- )
+ channel=ult.chat_id,
+ users=[user_id],
+ ),
)
await xx.edit(f"Successfully invited `{user_id}` to `{ult.chat_id}`")
except Exception as e:
@@ -475,13 +443,12 @@ async def rmbg(event):
)
if event.reply_to_msg_id:
reply = await event.get_reply_message()
- dl = await ultroid_bot.download_media(reply)
+ dl = await ultroid_bot.download_media(reply.media)
if not dl.endswith(("webp", "jpg", "png", "jpeg")):
os.remove(dl)
return await xx.edit("`Unsupported Media`")
await xx.edit("`Sending to remove.bg`")
- out = ReTrieveFile("ult.png")
- os.remove("ult.png")
+ out = ReTrieveFile(dl)
os.remove(dl)
else:
await xx.edit(f"Use `{HNDLR}rmbg` as reply to a pic to remove its background.")
@@ -496,14 +463,17 @@ async def rmbg(event):
else:
error = out.json()
await xx.edit(
- f"**Error ~** `{error['errors'][0]['title']}`,\n`{error['errors'][0]['detail']}`"
+ f"**Error ~** `{error['errors'][0]['title']}`,\n`{error['errors'][0]['detail']}`",
)
zz = Image.open(rmbgp)
if zz.mode != "RGB":
zz.convert("RGB")
zz.save("ult.webp", "webp")
await ultroid_bot.send_file(
- event.chat_id, rmbgp, force_document=True, reply_to=reply
+ event.chat_id,
+ rmbgp,
+ force_document=True,
+ reply_to=reply,
)
await ultroid_bot.send_file(event.chat_id, "ult.webp", reply_to=reply)
os.remove(rmbgp)
@@ -531,7 +501,7 @@ async def telegraphcmd(event):
await xx.edit(amsg)
elif getmsg.document:
getit = await ultroid_bot.download_media(getmsg)
- ab = open(getit, "r")
+ ab = open(getit)
cd = ab.read()
ab.close()
if input_str:
@@ -594,19 +564,71 @@ async def sugg(event):
id=12345,
question="Do you agree to the replied suggestion?",
answers=[PollAnswer("Yes", b"1"), PollAnswer("No", b"2")],
- )
+ ),
),
reply_to=msgid,
)
except Exception as e:
return await eod(
- event, f"`Oops, you can't send polls here!\n\n{str(e)}`", time=5
+ event,
+ f"`Oops, you can't send polls here!\n\n{str(e)}`",
+ time=5,
)
await event.delete()
else:
return await eod(
- event, "`Please reply to a message to make a suggestion poll!`", time=5
+ event,
+ "`Please reply to a message to make a suggestion poll!`",
+ time=5,
+ )
+
+
+@ultroid_cmd(pattern="ipinfo ?(.*)")
+async def ipinfo(event):
+ xx = await eor(event, get_string("com_1"))
+ ip = event.text.split(" ")
+ ipaddr = ""
+ try:
+ ipaddr = ip[1]
+ except:
+ return await eod(xx, "`Give me an IP address you noob!`", time=5)
+ if ipaddr == "":
+ return
+ url = f"https://ipinfo.io/{ipaddr}/geo"
+ det = requests.get(url).json()
+ try:
+ ip = det["ip"]
+ city = det["city"]
+ region = det["region"]
+ country = det["country"]
+ cord = det["loc"]
+ zipc = det["postal"]
+ tz = det["timezone"]
+ await xx.edit(
+ """
+**IP Details Fetched.**
+
+**IP:** `{}`
+**City:** `{}`
+**Region:** `{}`
+**Country:** `{}`
+**Co-ordinates:** `{}`
+**Postal Code:** `{}`
+**Time Zone:** `{}`
+""".format(
+ ip,
+ city,
+ region,
+ country,
+ cord,
+ zipc,
+ tz,
+ ),
)
+ except:
+ err = det["error"]["title"]
+ msg = det["error"]["messsage"]
+ await eod(xx, f"ERROR:\n{err}\n{msg}")
HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/vcplugin.py b/plugins/vcplugin.py
new file mode 100644
index 0000000000000000000000000000000000000000..7779801a5aa7eeb75b258060882ad2322348ac52
--- /dev/null
+++ b/plugins/vcplugin.py
@@ -0,0 +1,198 @@
+# 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}startvc`
+ Start Group Call in a group.
+
+• `{i}stopvc`
+ Stop Group Call in a group.
+
+• `{i}playvc`
+ Start Voice Chat Bot to receive Commands.
+
+• `{i}vcinvite`
+ Invite all members of group in Group Call.
+ (You must be joined)
+
+• `{i}vcaccess `
+ Give access of Voice Chat Bot.
+
+• `{i}rmvcaccess `
+ Remove access of Voice Chat Bot.
+
+• **Voice Chat Bot Commands**
+ `/play ytsearch:song name`
+ `/play youtube link`
+
+"""
+
+from pyUltroid.functions.vc_sudos import (add_vcsudo, del_vcsudo, get_vcsudos,
+ is_vcsudo)
+from telethon.tl.functions.channels import GetFullChannelRequest as getchat
+from telethon.tl.functions.phone import CreateGroupCallRequest as startvc
+from telethon.tl.functions.phone import DiscardGroupCallRequest as stopvc
+from telethon.tl.functions.phone import GetGroupCallRequest as getvc
+from telethon.tl.functions.phone import InviteToGroupCallRequest as invitetovc
+
+from . import *
+
+
+async def get_call(event):
+ mm = await event.client(getchat(event.chat_id))
+ xx = await event.client(getvc(mm.full_chat.call))
+ return xx.call
+
+
+def user_list(l, n):
+ for i in range(0, len(l), n):
+ yield l[i : i + n]
+
+
+@ultroid_cmd(
+ pattern="stopvc$",
+ admins_only=True,
+ groups_only=True,
+)
+async def _(e):
+ try:
+ await e.client(stopvc(await get_call(e)))
+ await eor(e, "`Voice Chat Stopped...`")
+ except Exception as ex:
+ await eor(e, f"`{str(ex)}`")
+
+
+@ultroid_cmd(
+ pattern="playvc$",
+)
+async def _(e):
+ await eor(e, "`VC bot started...`")
+ await bash("npm start")
+
+
+@ultroid_cmd(
+ pattern="vcinvite$",
+ groups_only=True,
+)
+async def _(e):
+ ok = await eor(e, "`Inviting Members to Voice Chat...`")
+ users = []
+ z = 0
+ async for x in e.client.iter_participants(e.chat_id):
+ if not x.bot:
+ users.append(x.id)
+ hmm = list(user_list(users, 6))
+ for p in hmm:
+ try:
+ await e.client(invitetovc(call=await get_call(e), users=p))
+ z += 6
+ except:
+ pass
+ await ok.edit(f"`Invited {z} users`")
+
+
+@ultroid_cmd(
+ pattern="startvc$",
+ admins_only=True,
+ groups_only=True,
+)
+async def _(e):
+ try:
+ await e.client(startvc(e.chat_id))
+ await eor(e, "`Voice Chat Started...`")
+ except Exception as ex:
+ await eor(e, f"`{str(ex)}`")
+
+
+@ultroid_cmd(
+ pattern="listvcaccess$",
+)
+async def _(e):
+ xx = await eor(e, "`Getting Voice Chat Bot Users List...`")
+ mm = get_vcsudos()
+ pp = f"**{len(mm)} Voice Chat Bot Approved Users**\n"
+ if len(mm) > 0:
+ for m in mm:
+ try:
+ name = (await e.client.get_entity(int(m))).first_name
+ pp += f"• [{name}](tg://user?id={int(m)})\n"
+ except ValueError:
+ pp += f"• `{int(m)} » No Info`\n"
+ await xx.edit(pp)
+
+
+@ultroid_cmd(
+ pattern="rmvcaccess ?(.*)",
+)
+async def _(e):
+ xx = await eor(e, "`Disapproving to access Voice Chat features...`")
+ input = e.pattern_match.group(1)
+ if e.reply_to_msg_id:
+ userid = (await e.get_reply_message()).sender_id
+ name = (await e.client.get_entity(userid)).first_name
+ elif input:
+ try:
+ userid = await get_user_id(input)
+ name = (await e.client.get_entity(userid)).first_name
+ except ValueError as ex:
+ return await eod(xx, f"`{str(ex)}`", time=5)
+ else:
+ return await eod(xx, "`Reply to user's msg or add it's id/username...`", time=3)
+ if not is_vcsudo(userid):
+ return await eod(
+ xx,
+ f"[{name}](tg://user?id={userid})` is not approved to use my Voice Chat Bot.`",
+ time=5,
+ )
+ try:
+ del_vcsudo(userid)
+ await eod(
+ xx,
+ f"[{name}](tg://user?id={userid})` is removed from Voice Chat Bot Users.`",
+ time=5,
+ )
+ except Exception as ex:
+ return await eod(xx, f"`{str(ex)}`", time=5)
+
+
+@ultroid_cmd(
+ pattern="vcaccess ?(.*)",
+)
+async def _(e):
+ xx = await eor(e, "`Approving to access Voice Chat features...`")
+ input = e.pattern_match.group(1)
+ if e.reply_to_msg_id:
+ userid = (await e.get_reply_message()).sender_id
+ name = (await e.client.get_entity(userid)).first_name
+ elif input:
+ try:
+ userid = await get_user_id(input)
+ name = (await e.client.get_entity(userid)).first_name
+ except ValueError as ex:
+ return await eod(xx, f"`{str(ex)}`", time=5)
+ else:
+ return await eod(xx, "`Reply to user's msg or add it's id/username...`", time=3)
+ if is_vcsudo(userid):
+ return await eod(
+ xx,
+ f"[{name}](tg://user?id={userid})` is already approved to use my Voice Chat Bot.`",
+ time=5,
+ )
+ try:
+ add_vcsudo(userid)
+ await eod(
+ xx,
+ f"[{name}](tg://user?id={userid})` is added to Voice Chat Bot Users.`",
+ time=5,
+ )
+ except Exception as ex:
+ return await eod(xx, f"`{str(ex)}`", time=5)
+
+
+HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/webshot.py b/plugins/webshot.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8d7b1fa25887ac0a79ef7ec7b9afbb58b74ac23
--- /dev/null
+++ b/plugins/webshot.py
@@ -0,0 +1,57 @@
+# 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}webshot `
+ Get a screenshot of the webpage.
+
+"""
+
+import requests
+
+from . import *
+
+
+@ultroid_cmd(pattern="webshot")
+async def webss(event):
+ xx = await eor(event, get_string("com_1"))
+ mssg = event.text.split(" ", maxsplit=2)
+ try:
+ xurl = mssg[1]
+ except IndexError:
+ return await eod(xx, "`Give a URL please!`", time=5)
+ try:
+ requests.get(xurl)
+ except requests.ConnectionError:
+ return await eod(xx, "Invalid URL!", time=5)
+ except requests.exceptions.MissingSchema:
+ try:
+ r = requests.get("https://" + xurl)
+ except requests.ConnectionError:
+ try:
+ r2 = requests.get("http://" + xurl)
+ except requests.ConnectionError:
+ return await eod(xx, "Invalid URL!", time=5)
+
+ lnk = f"https://shot.screenshotapi.net/screenshot?url={xurl}"
+ ok = requests.get(lnk).json()
+ try:
+ sshot = ok["screenshot"]
+ except:
+ return await eod(xx, "Something Went Wrong :(", time=10)
+ await xx.reply(
+ f"**WebShot Generated**\n**URL**: {xurl}",
+ file=sshot,
+ link_preview=False,
+ force_document=True,
+ )
+ await xx.delete()
+
+
+HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/plugins/webupload.py b/plugins/webupload.py
index 10f052979539cd711e5a5d8bfd0d678e4c5389d9..76e8a9a1e4fff05b5a87040aadce8a4a879d8b91 100644
--- a/plugins/webupload.py
+++ b/plugins/webupload.py
@@ -46,25 +46,27 @@ async def _(event):
xx,
ccc,
"Downloading...",
- )
+ ),
),
)
else:
return await eod(xx, "`Reply to media file`", time=5)
try:
results = await ultroid_bot.inline_query(
- Var.BOT_USERNAME, f"fl2lnk {file_name}"
+ Var.BOT_USERNAME,
+ f"fl2lnk {file_name}",
)
except rep:
return await eor(
xx,
"`The bot did not respond to the inline query.\nConsider using {}restart`".format(
- HNDLR
+ HNDLR,
),
)
except dis:
return await eor(
- xx, "`Please turn on inline mode for your bot from` @Botfather."
+ xx,
+ "`Please turn on inline mode for your bot from` @Botfather.",
)
await results[0].click(event.chat_id, reply_to=event.reply_to_msg_id, hide_via=True)
await xx.delete()
diff --git a/plugins/words.py b/plugins/words.py
index daf16772fbc11838c06debd2e5b77e72011f9ccd..403350a425f7f40aff4508c83b00fdd3da524690 100644
--- a/plugins/words.py
+++ b/plugins/words.py
@@ -136,7 +136,7 @@ async def _(event):
try:
mean = await urban.get_word(word)
await xx.edit(
- f"**Text**: `{mean.word}`\n\n**Meaning**: `{mean.definition}`\n\n**Example**: __{mean.example}__"
+ f"**Text**: `{mean.word}`\n\n**Meaning**: `{mean.definition}`\n\n**Example**: __{mean.example}__",
)
except asyncurban.WordNotFoundError:
await xx.edit(f"**No result found for** `{word}`")
diff --git a/plugins/ziptools.py b/plugins/ziptools.py
new file mode 100644
index 0000000000000000000000000000000000000000..a72cdc78bcd56f67b3fac548fb03bbf854609c75
--- /dev/null
+++ b/plugins/ziptools.py
@@ -0,0 +1,94 @@
+# 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}unzip `
+ unzip the replied file.
+"""
+
+import asyncio
+import os
+import time
+import zipfile
+
+from . import *
+
+
+@ultroid_cmd(pattern="unzip$")
+async def _(ult):
+ if not ult.is_reply:
+ return await eor(ult, "`Reply to a Zipfile..`")
+ gt = await ult.get_reply_message()
+ msg = await eor(ult, "`Processing...`")
+ if not (
+ gt.media
+ and gt.media.document
+ and gt.media.document.mime_type == "application/zip"
+ ):
+ return await msg.edit("`Reply to a Zipfile...`")
+ k = time.time()
+ d = "resources/downloads/"
+ dnl = await ultroid_bot.download_media(
+ gt,
+ d,
+ progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
+ progress(d, t, msg, k, "Downloading to my Storage..."),
+ ),
+ )
+ place = "resources/downloads/extracted/"
+ with zipfile.ZipFile(dnl, "r") as zip_ref:
+ zip_ref.extractall(place)
+ filename = sorted(get_lst_of_files(place, []))
+ await msg.edit("Unzipping now")
+ THUMB = udB.get("THUMB_URL")
+ Enum = 0
+ Elist = "**Errors Occured while Unzip**\n\n"
+ for single_file in filename:
+ if os.path.exists(single_file):
+ caption_rts = os.path.basename(single_file)
+ try:
+ await ultroid_bot.send_file(
+ ult.chat_id,
+ single_file,
+ thumb=THUMB,
+ caption=f"**File Name :** {caption_rts}",
+ force_document=True,
+ reply_to=ult.message.id,
+ )
+ except Exception as e:
+ Enum += 1
+ Elist += f"{Enum}. {caption_rts}\n- __{str(e)}__\n"
+ os.remove(single_file)
+ os.remove(dnl)
+ await msg.edit(f"**Unzipped `{len(filename)-Enum}/{len(filename)}` Files**")
+ if Enum > 0:
+ if len(Elist) < 4096:
+ await ultroid_bot.send_message(Var.LOG_CHANNEL, Elist)
+ else:
+ file = open("UnzipError.txt", "w").write(Elist)
+ file.close()
+ await ultroid_bot.send_message(
+ Var.LOG_CHANNEL,
+ "UnzipError.txt",
+ caption=f"`Error Occured on Unzip cmd",
+ )
+ os.remove("UnzipError.txt")
+
+
+def get_lst_of_files(input_directory, output_lst):
+ filesinfolder = os.listdir(input_directory)
+ for file_name in filesinfolder:
+ current_file_name = os.path.join(input_directory, file_name)
+ if os.path.isdir(current_file_name):
+ return get_lst_of_files(current_file_name, output_lst)
+ output_lst.append(current_file_name)
+ return output_lst
+
+
+HELP.update({f"{__name__.split('.')[1]}": f"{__doc__.format(i=HNDLR)}"})
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f77cacfa90ad03a327916eebfd48367a9bb5f337
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,6 @@
+-r requirements.txt
+black
+isort
+pre-commit
+pyclean
+pylint
diff --git a/requirements.txt b/requirements.txt
index 55c73d0437c9a6190c4d3140684face220daf19e..29224023bcbd1f2138fd651a9c17225c94b44890 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,6 @@
-py-Ultroid==2021.3.13
+py-Ultroid
+gingerit
+Telethon==1.21.1
+git+https://github.com/buddhhu/search-engine-parser.git
+git+https://github.com/buddhhu/ofox.git
+git+https://github.com/ProgrammingError/rextester_py.git
diff --git a/resources/session/session.sh b/resources/session/session.sh
index 0a11b48f1c1c82f9b4064504967d7f80b9db6c83..6a12414dbbd8901af69bb6eda22bba8f5543d4c7 100644
--- a/resources/session/session.sh
+++ b/resources/session/session.sh
@@ -1,4 +1,4 @@
-# !/bin/bash
+#!/usr/bin/env bash
# Ultroid - UserBot
# Copyright (C) 2020 TeamUltroid
#
diff --git a/resources/session/ssgen.py b/resources/session/ssgen.py
index e078720439b7f68c5c38d3cf2cb1fca4fc55fcde..3e3ac55ef817852342439931c59fdfdc108f2c72 100644
--- a/resources/session/ssgen.py
+++ b/resources/session/ssgen.py
@@ -6,18 +6,81 @@
# PLease read the GNU Affero General Public License in
# .
+import os
+from time import sleep
+
+# https://www.tutorialspoint.com/how-to-clear-screen-in-python#:~:text=In%20Python%20sometimes%20we%20have,screen%20by%20pressing%20Control%20%2B%20l%20.
+if os.name == "posix":
+ _ = os.system("clear")
+else:
+ # for windows platfrom
+ _ = os.system("cls")
+
+a = r"""
+ _ _ _ _ _ _
+ | | | | | | (_) | |
+ | | | | | |_ _ __ ___ _ __| |
+ | | | | | __| '__/ _ \| |/ _ |
+ | |__| | | |_| | | (_) | | (_| |
+ \____/|_|\__|_| \___/|_|\__,_|
+"""
+
+print(a)
+try:
+ print("Checking if Telethon is installed...")
+
+ for x in range(3):
+ for frame in r"-\|/-\|/":
+ print("\b", frame, sep="", end="", flush=True)
+ sleep(0.1)
+
+ x = "\bFound an existing installation of Telethon...\nSuccessfully Imported.\n\n"
+except:
+ print("Installing Telethon...")
+ os.system("pip install telethon")
+
+ x = "\bDone. Installed and imported Telethon."
+if os.name == "posix":
+ _ = os.system("clear")
+else:
+ # for windows platfrom
+ _ = os.system("cls")
+print(a)
+print(x)
+
+from telethon.errors.rpcerrorlist import (ApiIdInvalidError,
+ PhoneNumberInvalidError)
+# the imports
from telethon.sessions import StringSession
from telethon.sync import TelegramClient
-print("Please ensure that you have your API ID and API HASH.")
-print("")
+print(
+ "Get your API ID and API HASH from my.telegram.org or @ScrapperRoBot to proceed.\n\n",
+)
-API_ID = int(input("Enter API ID: "))
-API_HASH = input("Enter API HASH: ")
+try:
+ API_ID = int(input("Please enter your API ID: "))
+except ValueError:
+ print("APP ID must be an integer.\nQuitting...")
+ exit(0)
+API_HASH = input("Please enter your API HASH: ")
-with TelegramClient(StringSession(), API_ID, API_HASH) as client:
- ult = client.send_message("me",f"`{client.session.save()}`")
- ult.reply("The above is the `SESSION` for your current session.\nVisit @TheUltroid")
- print("")
- print("String Session for the current login has been generated.")
- print("Check your Telegram Saved messages for your SESSION.")
+# logging in
+try:
+ with TelegramClient(StringSession(), API_ID, API_HASH) as ultroid:
+ print("Generating a user session for Ultroid...")
+ ult = ultroid.send_message(
+ "me",
+ f"**ULTROID** `SESSION`:\n\n`{ultroid.session.save()}`\n\n**Do not share this anywhere!**",
+ )
+ print("Your SESSION has been generated. Check your telegram saved messages!")
+ exit(0)
+except ApiIdInvalidError:
+ print("Your API ID/API HASH combination is invalid. Kindly recheck.\nQuitting...")
+ exit(0)
+except ValueError:
+ print("API HASH must not be empty!\nQuitting...")
+ exit(0)
+except PhoneNumberInvalidError:
+ print("The phone number is invalid!\nQuitting...")
+ exit(0)
diff --git a/resources/startup/locals.py b/resources/startup/locals.py
new file mode 100644
index 0000000000000000000000000000000000000000..72007a5b26a8e19fef2bf701a84c97628a7c3e89
--- /dev/null
+++ b/resources/startup/locals.py
@@ -0,0 +1,140 @@
+# /usr/bin/python3
+# 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 .
+
+# Standalone file for facilitating local deploys.
+
+import os
+
+a = r"""
+ _ _ _ _ _ _
+ | | | | | | (_) | |
+ | | | | | |_ _ __ ___ _ __| |
+ | | | | | __| '__/ _ \| |/ _ |
+ | |__| | | |_| | | (_) | | (_| |
+ \____/|_|\__|_| \___/|_|\__,_|
+"""
+
+
+def start():
+
+ clear_screen()
+ check_for_py()
+
+ print(f"{a}\n\n")
+ print("Welcome to Ultroid, lets start setting up!\n\n")
+ print("Cloning the repository...\n\n")
+ try:
+ os.system("git clone https://github.com/TeamUltroid/Ultroid && cd Ultroid")
+ except Exception as e:
+ print(f"ERROR\n{str(e)}")
+ print("\n\nDone")
+ os.system("cd Ultroid")
+ clear_screen()
+ print(a)
+ print("\n\nLet's start!\n")
+
+ # generate session if needed.
+ sessionisneeded = input(
+ "Do you want to generate a new session, or have an old session string? [generate/skip]",
+ )
+ if sessionisneeded == "generate":
+ gen_session()
+ elif sessionisneeded == "skip":
+ pass
+ else:
+ print(
+ 'Please choose "generate" to generate a session string, or "skip" to pass on.\n\nPlease run the script again!',
+ )
+ exit(0)
+
+ # start bleck megik
+ print("\n\nLets start entering the variables.\n\n")
+ varrs = [
+ "API_ID",
+ "API_HASH",
+ "SESSION",
+ "BOT_USERNAME",
+ "BOT_TOKEN",
+ "REDIS_URI",
+ "REDIS_PASSWORD",
+ "LOG_CHANNEL",
+ ]
+ all_done = "# Ultroid Environment Variables.\n# Do not delete this file.\n\n"
+ for i in varrs:
+ all_done += do_input(i)
+ clear_screen()
+ print(a)
+ print("\n\nHere are the things you've entered.\nKindly check.")
+ print(all_done)
+ isitdone = input("\n\nIs it all correct? [y/n]")
+ if isitdone == "y":
+ f = open("Ultroid/.env", "w")
+ f.write(all_done)
+ f.close
+ elif isitdone == "n":
+ print("Oh, let's redo these then -_-")
+ start()
+ else:
+ f = open("Ultroid/.env", "w")
+ f.write(all_done)
+ f.close
+ clear_screen()
+ print("\nCongrats. All done!\nTime to start the bot!")
+ print("\nInstalling requirements... This might take a while...")
+ os.system("cd Ultroid")
+ os.system("pip3 install -r ./resources/extras/local-requirements.txt")
+ clear_screen()
+ print(a)
+ print("\nStarting Ultroid...")
+ os.system("python3 -m pyUltroid")
+
+
+def do_input(var):
+ val = input(f"Enter your {var}: ")
+ to_write = f"{var}={val}\n"
+ return to_write
+
+
+def clear_screen():
+ # clear screen
+ if os.name == "posix":
+ _ = os.system("clear")
+ else:
+ # for windows platfrom
+ _ = os.system("cls")
+
+
+def check_for_py():
+ print(
+ "Please make sure you have python installed. \nGet it from http://python.org/\n\n",
+ )
+ try:
+ ch = int(
+ input(
+ "Enter Choice:\n1. Continue, python is installed.\n2. Exit and install python.\n",
+ ),
+ )
+ except:
+ print("Please run the script again, and enter the choice as a number!!")
+ exit(0)
+ if ch == 1:
+ pass
+ elif ch == 2:
+ print("Please install python and continue!")
+ exit(0)
+ else:
+ print("Weren't you taught how to read? Enter a choice!!")
+ return
+
+
+def gen_session():
+ print("\nProcessing...")
+ os.system("cd Ultroid && python3 resources/session/ssgen.py")
+ return
+
+
+start()
diff --git a/resources/startup/startup.sh b/resources/startup/startup.sh
index 3d8dc18dcb68cd2d754ef080e0da0cdebf19ab6e..cf739b3d66fe12608fabfc5b0f6f1847ee9f00db 100644
--- a/resources/startup/startup.sh
+++ b/resources/startup/startup.sh
@@ -1,10 +1,11 @@
-#!/bin/bash
+#!/usr/bin/env bash
# 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 .
-
+
+
echo "
┏┳┓╋┏┓╋╋╋╋┏┓┏┓
┃┃┣┓┃┗┳┳┳━╋╋┛┃
@@ -14,5 +15,5 @@ echo "
Visit @TheUltroid for updates!!
"
-
+
python3 -m pyUltroid
diff --git a/sessiongen b/sessiongen
index 5fc90cbbac79fdb071b6ff2700fc1214347db94f..e4102fa05099b2e9fd648b02080a54a90d38d9b9 100644
--- a/sessiongen
+++ b/sessiongen
@@ -4,4 +4,4 @@
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
# PLease read the GNU Affero General Public License in .
-bash resources/session/session.sh
\ No newline at end of file
+bash resources/session/session.sh
diff --git a/src/bot.ts b/src/bot.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6eb70047e11044999529fc33b013d26a5f8f8fb4
--- /dev/null
+++ b/src/bot.ts
@@ -0,0 +1,14 @@
+/**
+* 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 { Telegraf } from 'telegraf';
+import env from './env';
+
+export const bot = new Telegraf(env.BOT_TOKEN);
+export const logger = async (msg: string, parse: 'HTML' | 'Markdown' | 'MarkdownV2' = 'HTML') => await bot.telegram.sendMessage(env.LOG_CHANNEL, msg, { parse_mode: parse });
diff --git a/src/env.ts b/src/env.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1038e55cb53a7ce854ad2f67102ac7c4a802dd21
--- /dev/null
+++ b/src/env.ts
@@ -0,0 +1,21 @@
+/**
+* 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 { cleanEnv, str } from 'envalid';
+import dotenv from 'dotenv';
+
+dotenv.config();
+
+export default cleanEnv(process.env, {
+ BOT_TOKEN: str(),
+ WEBSOCKET_URL: str(),
+ REDIS_URI: str(),
+ REDIS_PASSWORD: str(),
+ LOG_CHANNEL: str()
+});
diff --git a/src/handlers/current.ts b/src/handlers/current.ts
new file mode 100644
index 0000000000000000000000000000000000000000..491a212ac1f40deb62b2268fd5122f6687fc789a
--- /dev/null
+++ b/src/handlers/current.ts
@@ -0,0 +1,43 @@
+/**
+* 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 { Composer, Markup } from 'telegraf';
+import { getCurrentSong } from '../tgcalls';
+import { getDuration } from '../utils';
+import escapeHtml from '@youtwitface/escape-html';
+
+export const songHandler = Composer.command('current', async ctx => {
+ const { chat } = ctx.message;
+
+ if (chat.type !== 'supergroup') {
+ return;
+ }
+
+ const song = getCurrentSong(chat.id);
+
+ if (song === null) {
+ await ctx.reply('There is no song playing.');
+ return;
+ }
+
+ const { id, title, duration } = song.song;
+ const { id: from_id, f_name } = song.by;
+ return await ctx.replyWithPhoto(`https://img.youtube.com/vi/${id}/hqdefault.jpg`, {
+ caption: `Playing : ${escapeHtml(title)} \n` +
+ `Duration: ${getDuration(duration)}\n` +
+ `Requested by : ${f_name} `,
+ parse_mode: 'HTML',
+ ...Markup.inlineKeyboard([
+ [
+ Markup.button.callback('Pause', `pause:${id}`),
+ Markup.button.callback('Skip', `skip:${id}`)
+ ]
+ ])
+ })
+});
diff --git a/src/handlers/index.ts b/src/handlers/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1aae51b35465ed4bb49f6685a09d366c95ec7657
--- /dev/null
+++ b/src/handlers/index.ts
@@ -0,0 +1,25 @@
+/**
+* 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 { bot } from '../bot';
+
+import { playHandler } from './play';
+import { queueHandler } from './queue';
+import { pauseCBHandler } from './pause-resume';
+import { skipCBHandler, skipCommand } from './skip';
+import { songHandler } from './current';
+
+export const initHandlers = (): void => {
+ bot.use(playHandler);
+ bot.use(queueHandler);
+ bot.use(pauseCBHandler);
+ bot.use(skipCBHandler);
+ bot.use(skipCommand);
+ bot.use(songHandler);
+};
diff --git a/src/handlers/pause-resume.ts b/src/handlers/pause-resume.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1371a1a9e3b02bf1d427de94ea9996ef06fb464c
--- /dev/null
+++ b/src/handlers/pause-resume.ts
@@ -0,0 +1,65 @@
+/**
+* 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 { Composer, Markup } from 'telegraf';
+import { pause, getCurrentSong } from '../tgcalls';
+import { getDuration } from '../utils';
+import escapeHtml from '@youtwitface/escape-html';
+import checkExpired from '../middlewares/checkExpired';
+
+export const pauseCBHandler = Composer.action(/^pause:[a-zA-Z0-9.\-_]+$/, checkExpired, async ctx => {
+ const chat = ctx.callbackQuery.message?.chat;
+
+ let data: string = '';
+ if ('data' in ctx.callbackQuery) data = ctx.callbackQuery.data;
+
+ if (!chat) {
+ await ctx.answerCbQuery("Invalid Request");
+ return false;
+ }
+
+ const current = getCurrentSong(chat.id);
+ const paused = pause(chat.id);
+ if (!current) {
+ await ctx.answerCbQuery("There's nothing playing here.");
+ return setTimeout(async () => await ctx.deleteMessage(), 1000);
+ }
+
+ const { id, title, duration } = current.song;
+ const { id: id_by, f_name } = current.by;
+ if (paused) {
+ await ctx.editMessageCaption(`Paused : ${escapeHtml(title)} \n` +
+ `Duration : ${getDuration(duration)}\n` +
+ `Paused by : ${ctx.from?.first_name} \n` +
+ `Requested by : ${f_name} `, {
+ parse_mode: 'HTML',
+ ...Markup.inlineKeyboard([
+ [
+ Markup.button.callback('Resume', `pause:${id}`),
+ Markup.button.callback('Skip', `skip${id}`)
+ ]
+ ])
+ });
+ return await ctx.answerCbQuery("Paused ...");
+ } else {
+ await ctx.editMessageCaption(`Playing : ${escapeHtml(title)} \n` +
+ `Duration : ${getDuration(duration)}\n` +
+ `Resumed by : ${ctx.from?.first_name} \n` +
+ `Requested by : ${f_name} `, {
+ parse_mode: 'HTML',
+ ...Markup.inlineKeyboard([
+ [
+ Markup.button.callback('Pause', `pause:${id}`),
+ Markup.button.callback('Skip', `skip:${id}`)
+ ]
+ ])
+ });
+ return await ctx.answerCbQuery("Resumed ...");
+ }
+})
diff --git a/src/handlers/play.ts b/src/handlers/play.ts
new file mode 100644
index 0000000000000000000000000000000000000000..47e5d71df30d39dcf7883d8524619c62c6413a31
--- /dev/null
+++ b/src/handlers/play.ts
@@ -0,0 +1,78 @@
+/**
+* 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 { Composer, deunionize, Markup } from 'telegraf';
+import { addToQueue, getQueue } from '../tgcalls';
+import { getCurrentSong } from '../tgcalls';
+import { getDuration } from '../utils';
+import { logger as log } from '../bot';
+import escapeHtml from '@youtwitface/escape-html';
+
+export const playHandler = Composer.command('play', async ctx => {
+ const { chat } = ctx.message;
+
+ if (chat.type !== 'supergroup') {
+ await ctx.reply('I can only play in groups.');
+ return;
+ }
+
+ const [commandEntity] = ctx.message.entities!;
+ const text = ctx.message.text.slice(commandEntity.length + 1) || deunionize(ctx.message.reply_to_message)?.text;
+
+ if (!text) {
+ await ctx.reply('You need to specify a YouTube URL / Search Keyword.');
+ return;
+ }
+
+ const index = await addToQueue(chat, text, {
+ id: ctx.from.id,
+ f_name: ctx.from.first_name
+ });
+ const song = getCurrentSong(chat.id);
+
+ switch (index) {
+ case -1:
+ await ctx.reply("Failed to download song ...")
+ break;
+ case 0:
+ if (song) {
+ const { id, title, duration } = song.song;
+ ctx.replyWithPhoto(`https://img.youtube.com/vi/${id}/hqdefault.jpg`, {
+ caption: `Playing : ${escapeHtml(title)} \n` +
+ `Duration: ${getDuration(duration)}\n` +
+ `Requested by : ${song.by.f_name} `,
+ parse_mode: 'HTML',
+ ...Markup.inlineKeyboard([
+ [
+ Markup.button.callback('Pause', `pause:${id}`),
+ Markup.button.callback('Skip', `skip:${id}`)
+ ]
+ ])
+ })
+ }
+ break;
+ default:
+ const queue = getQueue(chat.id);
+ if (queue) {
+ let queueId = queue.length - 1
+ const { info, from } = queue[queueId];
+ await ctx.replyWithHTML(`Queued : ${escapeHtml(info.title)} (${getDuration(info.duration)})\n` +
+ `At position ${index}. \n` +
+ `Requested By : ${from.f_name} `, {
+ disable_web_page_preview: true,
+ // ...Markup.inlineKeyboard([
+ // [Markup.button.callback('Delete from Queue', `delq:${queueId}`)]
+ // ])
+ });
+ } else {
+ await log("Queue not found in " + chat.title)
+ }
+ }
+
+});
diff --git a/src/handlers/queue.ts b/src/handlers/queue.ts
new file mode 100644
index 0000000000000000000000000000000000000000..51088bef6ce10fc0be68a75e15bc16b4fbfb54cb
--- /dev/null
+++ b/src/handlers/queue.ts
@@ -0,0 +1,32 @@
+/**
+* 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 { Composer } from 'telegraf';
+import { getQueue } from '../tgcalls';
+import escapeHtml from '@youtwitface/escape-html';
+import { getDuration } from '../utils';
+
+export const queueHandler = Composer.command('queue', async ctx => {
+ const { chat } = ctx.message;
+
+ if (chat.type !== 'supergroup') {
+ return;
+ }
+
+ const queue = getQueue(chat.id);
+ const message =
+ queue && queue.length > 0
+ ? queue.map((data, index) => {
+ const { info, from } = data;
+ return `${index + 1} - ${escapeHtml(info.title)} (${getDuration(info.duration)})\nRequested By : ${from.f_name} `
+ }).join('\n')
+ : 'The queue is empty.';
+
+ await ctx.replyWithHTML(message, { disable_web_page_preview: true });
+});
\ No newline at end of file
diff --git a/src/handlers/skip.ts b/src/handlers/skip.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e6c94c7a7ccba9ec04cce43501fbafed557a44ad
--- /dev/null
+++ b/src/handlers/skip.ts
@@ -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
+* .
+**/
+
+import { Composer } from 'telegraf';
+import { skip } from '../tgcalls';
+import checkExpired from '../middlewares/checkExpired';
+
+export const skipCBHandler = Composer.action(/^skip:[a-zA-Z0-9.\-_]+$/, checkExpired, async ctx => {
+ const chat = ctx.callbackQuery.message?.chat;
+
+ if (!chat) {
+ await ctx.answerCbQuery("Invalid Request");
+ return
+ }
+
+ if (chat.type !== 'supergroup') {
+ return;
+ }
+
+ const skipped = skip(chat.id);
+
+ if (skipped) {
+ await ctx.answerCbQuery("Skipped ...");
+ setTimeout(async () => await ctx.deleteMessage(), 1000);
+ } else {
+ await ctx.answerCbQuery("There's no song playing..")
+ }
+})
+
+export const skipCommand = Composer.command('skip', async ctx => {
+ const { chat } = ctx.message;
+
+ if (chat.type !== 'supergroup') {
+ return;
+ }
+
+ const skipped = skip(chat.id);
+ ctx.reply(skipped ? 'Skipped.' : "There's no song playing.");
+})
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..747e9410c3a4df8a8927c7e9efd7a9cd096387d0
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,20 @@
+/**
+* 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 { bot, logger as log } from './bot';
+import { initHandlers } from './handlers';
+import { initMiddleWares } from './middlewares';
+
+(async () => {
+ initMiddleWares();
+ initHandlers();
+ await bot.telegram.deleteWebhook({ drop_pending_updates: true });
+ await bot.launch();
+ await log(`@${bot.botInfo?.username} is running...`);
+})();
diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dc1533c80e3d5b7a916a5335f842e6e4060d236b
--- /dev/null
+++ b/src/middlewares/auth.ts
@@ -0,0 +1,46 @@
+/**
+* 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 { Context, MiddlewareFn } from 'telegraf';
+import client from '../redis';
+import { promisify } from 'util';
+
+const getAsync = promisify(client.get).bind(client);
+
+const Auth: MiddlewareFn = async (ctx, next) => {
+ let sudos: string | string[] | null;
+ let vc_sudos: string | string[] | null;
+
+ sudos = await getAsync('SUDOS');
+ vc_sudos = await getAsync('VC_SUDOS');
+
+ if (sudos && (typeof (sudos) === 'string')) {
+ sudos = sudos.split(" ");
+ if (vc_sudos && (typeof (vc_sudos) === 'string')) {
+ sudos = sudos.concat(vc_sudos.split(" "))
+ }
+ }
+
+ let owner = await getAsync('OWNER_ID');
+ let id = ctx.from?.id.toString();
+
+ if ((id && sudos && (typeof (sudos) === 'object') && sudos.includes(id)) || (id === owner)) {
+ return next();
+ } else {
+ if (ctx.callbackQuery) {
+ return ctx.answerCbQuery("You aren't authorized ...", {
+ show_alert: true
+ })
+ } else {
+ return;
+ }
+ }
+}
+
+export default Auth;
diff --git a/src/middlewares/checkExpired.ts b/src/middlewares/checkExpired.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5b9456c49fa2dc689a1a57ecbb1375149f62ac1d
--- /dev/null
+++ b/src/middlewares/checkExpired.ts
@@ -0,0 +1,44 @@
+/**
+* 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 { Context, MiddlewareFn } from 'telegraf';
+import { getCurrentSong } from '../tgcalls';
+import { logger as log } from '../bot';
+import escapeHtml from '@youtwitface/escape-html';
+
+const checkExpired: MiddlewareFn = async (ctx, next) => {
+ if (ctx.callbackQuery) {
+ if ('data' in ctx.callbackQuery) {
+ let chat = ctx.callbackQuery.message?.chat;
+ if (!chat) { // USELESS CHECKING to Satisfy TS
+ return await ctx.answerCbQuery("Invalid Request");
+ }
+ let [_, id] = ctx.callbackQuery.data.split(":");
+ let current = getCurrentSong(chat.id);
+
+ if (current && (current.song.id !== id)) {
+ await ctx.answerCbQuery("This Button is Expired ...");
+ try {
+ return setTimeout(async () => await ctx.deleteMessage(), 2500);
+ } catch (err) {
+ return await log(
+ `Error in ${chat.id}
\n` +
+ `${escapeHtml(err.toString())}`
+ );
+ }
+ } else {
+ return next();
+ }
+ }
+ } else {
+ return next();
+ }
+}
+
+export default checkExpired;
\ No newline at end of file
diff --git a/src/middlewares/index.ts b/src/middlewares/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..00f728ba4e23eee253f0dbcc03dffca4566322b3
--- /dev/null
+++ b/src/middlewares/index.ts
@@ -0,0 +1,18 @@
+/**
+* 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 { bot } from '../bot';
+
+import Auth from './auth';
+import Logger from './logger';
+
+export const initMiddleWares = (): void => {
+ bot.use(Logger);
+ bot.use(Auth);
+}
\ No newline at end of file
diff --git a/src/middlewares/logger.ts b/src/middlewares/logger.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7f9f79f3b9a2bce507e78fb9abdbbae1d2f81504
--- /dev/null
+++ b/src/middlewares/logger.ts
@@ -0,0 +1,22 @@
+/**
+* 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 { Context, MiddlewareFn } from 'telegraf';
+import { logger as log } from '../bot';
+import escapeHtml from '@youtwitface/escape-html';
+
+const Logger: MiddlewareFn = async (_, next) => {
+ try {
+ await next();
+ } catch (err) {
+ await log(`Error : \n ${escapeHtml(err.toString())}
`, "HTML");
+ }
+}
+
+export default Logger;
\ No newline at end of file
diff --git a/src/redis.ts b/src/redis.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c8487fbf64dba1b7746f7f4943eaa97f76b92373
--- /dev/null
+++ b/src/redis.ts
@@ -0,0 +1,22 @@
+/**
+* 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 redis from 'redis';
+import env from './env';
+
+const host = env.REDIS_URI.split(":")[0];
+const port = Number(env.REDIS_URI.split(":")[1]);
+
+const client = redis.createClient({
+ host: host,
+ port: port,
+ password: env.REDIS_PASSWORD
+});
+
+export default client;
\ No newline at end of file
diff --git a/src/tgcalls.ts b/src/tgcalls.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8c645c79bafbe1a869b5a964a6ba7043dec2d932
--- /dev/null
+++ b/src/tgcalls.ts
@@ -0,0 +1,329 @@
+/**
+* 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 { Chat } from 'typegram';
+import { exec as _exec, spawn } from 'child_process';
+import { JoinVoiceCallResponse } from 'tgcalls/lib/types';
+import { Stream, TGCalls } from 'tgcalls';
+import env from './env';
+import WebSocket from 'ws';
+import { Readable } from 'stream';
+import { bot } from './bot';
+import { Markup } from 'telegraf';
+import { getDuration } from './utils';
+import escapeHtml from '@youtwitface/escape-html';
+
+interface DownloadedSong {
+ stream: Readable;
+ info: {
+ id: string;
+ title: string;
+ duration: number;
+ };
+}
+
+interface Queue {
+ url: string;
+ info: DownloadedSong['info'];
+ from: {
+ id: string | number;
+ f_name: string;
+ };
+}
+
+interface CurrentSong {
+ song: DownloadedSong['info'],
+ by: Queue['from']
+}
+
+interface CachedConnection {
+ connection: TGCalls<{ chat: Chat.SupergroupChat }>;
+ stream: Stream;
+ queue: Queue[];
+ currentSong: CurrentSong | null;
+ joinResolve?: (value: JoinVoiceCallResponse) => void;
+ source?: number;
+}
+
+const ws = new WebSocket(env.WEBSOCKET_URL);
+const cache = new Map();
+
+const ffmpegOptions = "-preset ultrafast -c copy -acodec pcm_s16le -f s16le -ac 1 -ar 65000 pipe:1";
+
+ws.on('message', response => {
+ const { _, data } = JSON.parse(response.toString());
+
+ switch (_) {
+ case 'get_join': {
+ const connection = cache.get(data.chat_id);
+ if (connection) {
+ connection.joinResolve?.(data);
+ }
+ break;
+ }
+ // case 'left_vc': {
+ // cache.delete(data.chat.id);
+ // break;
+ // }
+ default:
+ break;
+ }
+});
+
+const downloadSong = async (url: string): Promise => {
+ return new Promise((resolve, reject) => {
+ const ytdlChunks: string[] = [];
+ const ytdl = spawn('youtube-dl', ['-x', '--print-json', '-g', `${url}`]);
+
+ ytdl.stderr.on('data', data => console.error(data.toString()));
+
+ ytdl.stdout.on('data', data => {
+ ytdlChunks.push(data.toString());
+ });
+
+ ytdl.on('exit', code => {
+ if (code !== 0) {
+ return reject();
+ }
+
+ const ytdlData = ytdlChunks.join('');
+ const [inputUrl, _videoInfo] = ytdlData.split('\n');
+ const videoInfo = JSON.parse(_videoInfo);
+
+ const ffmpeg = spawn('ffmpeg', ['-y', '-nostdin', '-i', inputUrl, ...ffmpegOptions.split(' ')]);
+
+ resolve({
+ stream: ffmpeg.stdout,
+ info: {
+ id: videoInfo.id,
+ title: videoInfo.title,
+ duration: videoInfo.duration,
+ },
+ });
+ });
+ });
+};
+
+
+export const getSongInfo = async (url: string): Promise => {
+ return new Promise((resolve, reject) => {
+ const ytdlChunks: string[] = [];
+ const ytdl = spawn('youtube-dl', ['-x', '--print-json', '-g', `ytsearch:"${url}"`]);
+
+ ytdl.stderr.on('data', data => console.error(data.toString()));
+
+ ytdl.stdout.on('data', data => {
+ ytdlChunks.push(data.toString());
+ });
+
+ ytdl.on('exit', code => {
+ if (code !== 0) {
+ return reject();
+ }
+
+ const ytdlData = ytdlChunks.join('');
+ const [inputUrl, _videoInfo] = ytdlData.split('\n');
+ const videoInfo = JSON.parse(_videoInfo);
+
+ resolve({
+ id: videoInfo.id,
+ title: videoInfo.title,
+ duration: videoInfo.duration,
+ });
+ });
+ });
+};
+
+const createConnection = async (chat: Chat.SupergroupChat): Promise => {
+ if (cache.has(chat.id)) {
+ return;
+ }
+
+ const connection = new TGCalls({ chat });
+ const stream = new Stream();
+ const queue: {
+ url: string,
+ info: DownloadedSong['info'],
+ from: {
+ id: string | number,
+ f_name: string
+ }
+ }[] = [];
+
+ const cachedConnection: CachedConnection = {
+ connection,
+ stream,
+ queue,
+ currentSong: null,
+ };
+
+ connection.joinVoiceCall = payload => {
+ // cachedConnection.source = payload.source;
+ return new Promise(resolve => {
+ cachedConnection.joinResolve = resolve;
+
+ const data = {
+ _: 'join',
+ data: {
+ ufrag: payload.ufrag,
+ pwd: payload.pwd,
+ hash: payload.hash,
+ setup: payload.setup,
+ fingerprint: payload.fingerprint,
+ source: payload.source,
+ chat: payload.params.chat,
+ },
+ };
+ ws.send(JSON.stringify(data));
+ });
+ };
+
+ cache.set(chat.id, cachedConnection);
+ await connection.start(stream.createTrack());
+
+ stream.on('finish', async () => {
+ if (queue.length > 0) {
+ const { url, from } = queue.shift()!;
+ try {
+ const song = await downloadSong(url);
+ const { title, id, duration } = song.info
+ stream.setReadable(song.stream);
+ cachedConnection.currentSong = {
+ song: song.info,
+ by: from
+ };
+
+ await bot.telegram.sendPhoto(chat.id, `https://img.youtube.com/vi/${id}/hqdefault.jpg`, {
+ caption: `Playing : ${escapeHtml(title)} \n` +
+ `Duration : ${getDuration(duration)}\n` +
+ `Requested by : ${from.f_name} `,
+ parse_mode: 'HTML',
+ ...Markup.inlineKeyboard([
+ [
+ Markup.button.callback('Pause', `pause:${id}`),
+ Markup.button.callback('Skip', `skip:${id}`)
+ ]
+ ])
+ })
+ } catch (error) {
+ console.error(error);
+ stream.emit('finish');
+ }
+ } else {
+ // try {
+ // leaveVc(chat.id);
+ // } catch (err) {
+ // console.error(err);
+ // }
+ cachedConnection.currentSong = null;
+ }
+ });
+ // stream.on('leave', () => {
+ // const data = {
+ // _: 'leave',
+ // data: {
+ // source: cachedConnection.source,
+ // chat: chat
+ // },
+ // };
+ // ws.send(JSON.stringify(data));
+ // cachedConnection.connection.close();
+ // });
+};
+
+// export const leaveVc = (chatId: number) => {
+// if (cache.has(chatId)) {
+// const { stream } = cache.get(chatId)!;
+// stream.emit('leave');
+// cache.delete(chatId);
+// }
+// return false;
+// }
+
+export const addToQueue = async (chat: Chat.SupergroupChat, url: string, by: Queue['from']): Promise => {
+ if (!cache.has(chat.id)) {
+ await createConnection(chat);
+ return addToQueue(chat, url, by);
+ }
+
+ const connection = cache.get(chat.id)!;
+ const { stream, queue } = connection;
+
+ let songInfo: DownloadedSong['info'];
+ if (stream.finished) {
+ try {
+ const song = await downloadSong(url);
+ stream.setReadable(song.stream);
+ connection.currentSong = {
+ song: song.info,
+ by: by
+ };
+ songInfo = song.info;
+ cache.set(chat.id, connection);
+ } catch (error) {
+ console.error(error);
+ return -1;
+ }
+ return 0;
+ } else {
+ songInfo = await getSongInfo(url);
+ }
+ return queue.push({
+ url: url,
+ from: by,
+ info: songInfo
+ });
+};
+
+export const getCurrentSong = (chatId: number): CurrentSong | null => {
+ if (cache.has(chatId)) {
+ const { currentSong } = cache.get(chatId)!;
+ return currentSong;
+ }
+
+ return null;
+};
+
+export const getQueue = (chatId: number): Queue[] | null => {
+ if (cache.has(chatId)) {
+ const { queue } = cache.get(chatId)!;
+ return Array.from(queue);
+ }
+ return null;
+};
+
+export const removeQueue = (chatId: number, id: number): boolean => {
+ if (cache.has(chatId)) {
+ const { queue } = cache.get(chatId)!;
+ if (id > queue.length) return false;
+ if (queue.splice(id, 1)) return true;
+ }
+ return false;
+}
+
+export const pause = (chatId: number): boolean | null => {
+ if (cache.has(chatId)) {
+ const { stream } = cache.get(chatId)!;
+ stream.pause();
+ return stream.paused;
+ }
+
+ return null;
+};
+
+export const skip = (chatId: number): boolean => {
+ if (cache.has(chatId)) {
+ const { stream } = cache.get(chatId)!;
+ stream.finish();
+ stream.emit('finish');
+ return true;
+ }
+
+ return false;
+};
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a147c2e48c1f621b4dcca508c7535906bcbc3d6e
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,17 @@
+/**
+* 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
+* .
+**/
+
+export const getDuration = (time: string | number): string => {
+ if (typeof (time) === 'string') {
+ time = parseInt(time)
+ }
+ let min = Math.floor(time / 60);
+ let sec = time - min * 60;
+ return `${min}m ${sec}s`;
+}
\ No newline at end of file
diff --git a/strings/__init__.py b/strings/__init__.py
index 0038100d4a4aaf1f53080c9f7fa91b10115e9b8a..93196968d96eb7b4ba4c2c183178ba6d1f61495c 100644
--- a/strings/__init__.py
+++ b/strings/__init__.py
@@ -1 +1 @@
-from .strings import get_string, get_languages
\ No newline at end of file
+from .strings import get_languages, get_string
diff --git a/strings/strings.py b/strings/strings.py
index 35e418eb6ab92576b8d1f89e97d61a48ca22bd36..6ed272d951dbc5297b0c5d830b23eac24321dad4 100644
--- a/strings/strings.py
+++ b/strings/strings.py
@@ -1,10 +1,8 @@
from os import listdir, path
from typing import Any, Dict, List, Union
-from yaml import safe_load
-
from pyUltroid import udB
-
+from yaml import safe_load
languages = {}
strings_folder = path.join(path.dirname(path.realpath(__file__)), "strings")
@@ -13,7 +11,7 @@ for file in listdir(strings_folder):
if file.endswith(".yml"):
code = file[:-4]
languages[code] = safe_load(
- open(path.join(strings_folder, file), encoding="UTF-8")
+ open(path.join(strings_folder, file), encoding="UTF-8"),
)
diff --git a/strings/strings/ar.yml b/strings/strings/ar.yml
index 50612cf0af2200043d22d80492f883d265abbb12..54c1566bd054cb7fe6e37d4aa94e8ac416a99c76 100644
--- a/strings/strings/ar.yml
+++ b/strings/strings/ar.yml
@@ -7,7 +7,7 @@ authors:
# commons
com_1: "`جـاري المعالجه...`"
com_2: "`جـاري البحث...`"
-# help
+# help
help_1: "`{}` عـذرا ليس صالحآ يـوجد هنـاك خطأ!"
help_2: "عذرا لم يستجيب البوت .\nارسل امر اعاده تشغيل للأفضليه `{}restart`"
help_3: "`يرجى تشغيل وضع الاونلاين المباشر من خلال بوت فاذر` @Botfather."
@@ -102,7 +102,6 @@ chats_3: "`┇انــا لــســت مــشــرف ❗️`"
chats_4: "┇ #تــم_الحــذف\n┇تــم حــذف {}"
chats_5: " ┇تــم صــنــع مــجــمــوعــتــك ✅[{}]({}) "
chats_6: "┇إنــضــم ⚜️ @TeamUltroid"
-chats_6: "┇تــم صــنــع مــجــمــوعــتــك / قــنــاتــك ✅ [{}]({}) "
# converter
cvt_1: "┇قــم بــالــرد عــلــى أي مــيــديــا / مــلــف نــصــي ❕."
diff --git a/strings/strings/cn.yml b/strings/strings/cn.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7ce7439dc2ffcf883c865dd9e9b586c9431f3aa7
--- /dev/null
+++ b/strings/strings/cn.yml
@@ -0,0 +1,196 @@
+name: Chinese
+natively: 简体中文
+
+authors:
+ - stevenliuit
+ - junbaor
+
+# commons
+com_1: "`处理中...`"
+com_2: "`搜索中...`"
+# help
+help_1: "`{}` 不是一个有效的插件!"
+help_2: "机器人没有响应内联查询.\n考虑使用 `{}重启`"
+help_3: "`请从中为您的机器人打开内联模式` @Botfather."
+help_4: "嘿, \n你是机器人模式. \n机器人模式用户无法直接获得帮助 ... \n而不是复制粘贴在聊天下面,并点击弹出窗口 \n\n `@{} ultd`"
+
+# autopic
+autopic_1: "嘿,给我发信息 .."
+autopic_2: "找不到的结果 `{}`"
+autopic_3: "有收藏吗 `{}` 与您的搜索相关 !\n开始自选 !"
+
+# inline
+inline_1: "[Ultroid 帮助](t.me/ultroidsupport)\n\n
+**帮助菜单 {}.\n\n
+插件 ~ {}**"
+inline_2: "[Ultroid 帮助](t.me/ultroidsupport)\n\n
+**帮助菜单 {}.\n\n
+附加组件 ~ {}**"
+inline_3: "[Ultroid 帮助](t.me/ultroidsupport)\n\n
+**帮助菜单 {}.\n\n
+附加组件 ~ {}\n\n
+去添加 `附加组件` var为true的值**"
+inline_4: "**{}的机器人\n\n主菜单\n\n插件 ~ {}\n附加组件 ~ {}\n命令总数 ~ {}**"
+inline_5: "**菜单已关闭**"
+
+# tagnotif
+tagnot_1: "{} 把你带进来 {}\n\n```{}```\n\n[📨消息📨]({})"
+tagnot_2: "{} 把你带进来 {}\n\n [📨消息📨]({})"
+
+# whisper
+wspr_1: "@{} 给你的秘密信息.\n阅读后删除邮件.\n否则下一条消息将不会更新."
+wspr_2: "消息 删除"
+
+# afk
+afk_1: "`不再 AFK\n\n
+他离开了 ~ {}`"
+afk_2: "#AFK\n
+将AFK模式设置为False\n
+使用AFK是为了 {}`"
+afk_3: "我现在是 AFK.\n
+上次看到 {} 前.`\n\n
+**原因:** `{}`"
+afk_4: "`我现在是 AFK.\n\n
+上次看到 {} 前.`"
+afk_5: "`去 AFK.`\n\n
+**原因:** `{}`"
+afk_6: "我要去 AFK."
+afk_7: "目前有原因的 AFK {}"
+afk_8: "目前 AFK."
+
+# bot
+alive_1: "**Ultroid 用户机器人...**\n\n
+**{}**\n\n
+┏━━━━━━━━━━━━━━━━━━━━━\n
+┣ **所有者** - `{}`\n
+┣ **版本** - `{}`\n
+┣ **启动时间** - `{}`\n
+┣ **正常运行时间** - `{}`\n
+┣ **Python** - `{}`\n
+┣ **Telethon** - `{}`\n
+┣ **分支** - `{}`\n
+┗━━━━━━━━━━━━━━━━━━━━━"
+log: "**Heroku** Ultroid 日志.\n粘贴 [here]({}) too!"
+ping: "**Pong !!** `{}毫秒`\n**Uptime** - `{}`"
+usage: "**⚙️ Dyno 用法 ⚙️**:\n\n
+ -> `Dyno 用法 for` **{}**:\n
+ • `{}`**h** `{}`**m**
+**|** [`{}`**%**]\n\n
+ -> `本月剩余的Dyno小时配额`:\n
+ • `{}`**h** `{}`**m**
+**|** [`{}`**%**]\n\n
+**总磁盘空间: {}\n\n**
+**Used: {} Free: {}\n\n**
+**📊Data 用法\n\n上传: {}\n下载: {}\n\n**
+**CPU: {}%\nRAM: {}%\nDISK: {}%**"
+shutdown: "拜拜 {}.\n`关闭...`"
+
+# broadcast
+bd_1: "`添加到数据库...`"
+bd_2: "`尝试将所有管理频道添加到数据库...`"
+bd_3: "**完成.**\n数据库中已存在聊天记录: {}\n新增: {}"
+bd_4: "已添加频道!"
+bd_5: "`已添加到数据库!`"
+bd_6: "`频道已经在数据库!`"
+
+# carbon
+carbon_1: "处理"
+carbon_2: "Carbonised by [{}](tg://user?id={})"
+
+# chats
+chats_1: "`处理中...`"
+chats_2: "`无法删除此聊天`"
+chats_3: "`我不是管理员`"
+chats_4: "#已删除\n已删除 {}"
+chats_5: "你的 [{}]({}) 组已经成为了 Boss!"
+chats_6: "加入 @TeamUltroid"
+
+# converter
+cvt_1: "回复任一媒体或文件."
+cvt_2: "给出文件的名称和扩展名"
+cvt_3: "`处理中...`"
+cvt_4: "回复任何媒体."
+
+# core
+core_1: "发现模块"
+core_2: "{}.py 使用 .paste 粘贴在 neko 和 raw .."
+core_3: "再次搜索..?"
+core_4: "发现模块 {}"
+core_5: "{}.py 使用 .paste 粘贴在 neko 和 raw .."
+core_6: "没找到 {}.py 模块"
+core_7: "没有该模块"
+core_8: "没有发现名称是 {}.py 的模块"
+core_9: "`给出你要卸载的插件名称`"
+core_10: "**卸载** `{}` **成功.**"
+core_11: "**你不能不加载官方的插件**"
+core_12: "**无插件** `{}`"
+core_13: "`给出你要卸载的插件名称`"
+core_14: "**卸载** `{}` **成功.**"
+core_15: "**你不能卸载官方的插件**"
+core_16: "`给出你要加载的插件名称`"
+core_17: "**加载成功** `{}`"
+core_18: "**无法加载** `{}` **因为以下错误.**\n`{}`"
+
+# fedutils
+sf_1: "启动 Mass-FedBan..."
+sf_2: "`没有指定用户!`"
+sf_3: "你不能禁止我的开发,你这个笨蛋!!!"
+sf_4: "`好像是 rose 没有相应, 或者插件的行为不正常`"
+sf_5: "您只能每5分钟使用一次fed指令"
+sf_6: "5分钟后再试一次."
+sf_7: "无法收集 FedAdminList. 重试中 ({}/3)..."
+sf_8: "错误"
+sf_9: "无法收集 FedAdminList."
+sf_10: "FBaning in {} feds."
+sf_11: "指定的 FBan Group ID 不正常."
+sf_12: "{} 排除."
+sf_13: "移除 FedAdmin 文件时出错.\n{}"
+sf_14: "SuperFBan 已完成.\n总计 Feds - {}.\n不包括 - {}.\n 受影响的 {} feds.\n#TB"
+sf_15: "启动 Mass-UnFedBan..."
+sf_16: "SuperUnFBan 已完成.\n总计 Feds - {}.\n不包括 - {}.\n 受影响的 {} feds.\n#TB"
+sf_17: "`给我一个ID, 或者回复某人的信息查看他/她的 fedstat.`"
+sf_18: "列表 feds {} 已被禁止.\n\n使用Ultroid收集."
+sf_19: "**错误**\n `Unblock` @MissRose_Bot ` 再试一次!"
+sf_20: "`提取信息中...`"
+sf_21: "\n\n由Ultroid提取的FedInfo"
+
+# gdrive
+gdrive_1: "`你已经授权过 Google Drive`"
+gdrive_2: "去 [这里](https://console.developers.google.com/flows/enableapi?apiid=drive) 获取你的 `GDRIVE_CLIENT_ID` 和 `GDRIVE_CLIENT_SECRET`\n\n
+发送你的 GDRIVE_CLIENT_ID 和 GDRIVE_CLIENT_SECRET 到这里.\n`GDRIVE_CLIENT_ID GDRIVE_CLIENT_SECRET` 用空格分开."
+gdrive_3: "`错误的 Client Id`"
+gdrive_4: "`发生了一些错误! 再次发送 `/auth`.\n如果发生同样的问题请联系 `@TheUltroid"
+gdrive_5: "`成功!\n你已经在 Ultroid 用户机器人 上设置好了 Google Drive.`"
+gdrive_6: "`去 `{}` 并发送 ``/auth.`"
+gdrive_7: "**文件成功上传到 G-Drive :**\n\n[{}]({})"
+
+# pmpermit
+pmperm_1: "请等待我的回复,否则你会被屏蔽并被举报为垃圾信息!!"
+pmperm_2: "你在我主人的邮箱里乱发信息, 我不喜欢这样.\n你已经被屏蔽, 并被报告为垃圾信息, 直到进一步的通知."
+pmperm_3: "回复别人的消息或在私聊里试试这个命令."
+
+# updater
+upd_1: "`正在检查更新, 请稍等....`"
+upd_2: "`哎呀, 出现一些问题无法继续更新.`\n\n**日志跟踪:**\n"
+upd_3: "**有新的更新可用 [[{}]]({}/tree/{}):\n\n更新日志**\n\n{}"
+upd_4: "`变更日志太大,查看文件才能看到.`"
+upd_5: "使用 `{}update now` 更新."
+upd_6: "{}\n\n使用 `{}update now` 更新."
+upd_7: "\n`你的机器人是` **up-to-date** `与` **[[{}]]({}/tree/{})**\n"
+
+# upload download
+udl_1: "`回复你想下载的文件或媒体...`"
+udl_2: "下载成功..\nTo\n`{}`\nin `{}`"
+udl_3: "`给出文件的具体路径`"
+
+# words
+wrd_1: "**Word** - `{}`\n\n**含义** - \n"
+wrd_2: "**Word** - `{}`\n\n**同义词** - \n"
+wrd_3: "**Word** - `{}`\n\n**反义词** - \n"
+
+# ---------------------------------------------------#
+
+# assisant
+ast_1: "选择你要设置的 API."
+ast_2: "**remove.bg API**\n输入你的 remove.bg API key .\n\n使用 /cancel 终止操作."
+ast_3: "Hi {}. 请浏览以下选项"
diff --git a/strings/strings/en.yml b/strings/strings/en.yml
index 17c6183b17832f97cfbef3f7b59c64efcc338d25..cf7524087364e67f2476821ef4d7ade80b49d0a8 100644
--- a/strings/strings/en.yml
+++ b/strings/strings/en.yml
@@ -10,7 +10,7 @@ authors:
# commons
com_1: "`Processing...`"
com_2: "`Searching...`"
-# help
+# help
help_1: "`{}` is not a valid plugin!"
help_2: "The bot did not respond to the inline query.\nConsider using `{}restart`"
help_3: "`Please turn on inline mode for your bot from` @Botfather."
@@ -36,8 +36,8 @@ inline_4: "** Bᴏᴛ Oғ {}\n\nMᴀɪɴ Mᴇɴᴜ\n\nPʟᴜɢɪɴs ~ {}\nAᴅ
inline_5: "**Mᴇɴᴜ Hᴀs Bᴇᴇɴ Cʟᴏsᴇᴅ**"
# tagnotif
-tagnot_1: "{} tagged you in {}\n\n```{}```\n\n[📨Message📨]({})"
-tagnot_2: "{} tagged you in {}\n\n [📨Message📨]({})"
+tagnot_1: "{} tagged you in {}\n\n```{}```\n\n[📨 Message 📨]({})"
+tagnot_2: "{} tagged you in {}\n\n [📨 Message 📨]({})"
# whisper
wspr_1: "@{} secret msg for you.\nDelete your msg after reading.\nOr the next msg will not be updated."
@@ -48,8 +48,8 @@ afk_1: "`No Longer Afk\n\n
Was away for ~ {}`"
afk_2: "#AFK\n
Set AFK mode to False.\n
-Was AFK for {}`"
-afk_3: "I'm currently AFK.\n
+Was AFK for `{}`"
+afk_3: "`I'm currently AFK.\n
Last seen {} ago.`\n\n
**Reason:** `{}`"
afk_4: "`I'm currently AFK.\n\n
@@ -66,6 +66,7 @@ alive_1: "**The Ultroid Userbot...**\n\n
┏━━━━━━━━━━━━━━━━━━━━━\n
┣ **Owner** - `{}`\n
┣ **Version** - `{}`\n
+┣ **Py-Ultroid** - `{}`\n
┣ **UpTime** - `{}`\n
┣ **Python** - `{}`\n
┣ **Telethon** - `{}`\n
@@ -105,7 +106,6 @@ chats_3: "`I m not an admin`"
chats_4: "#Deleted\nDeleted {}"
chats_5: "Your [{}]({}) Group Made Boss!"
chats_6: "Join @TeamUltroid"
-chats_6: "Your [{}]({}) Group/Channel Has been made Boss!"
# converter
cvt_1: "Reply to any media/Document."
@@ -169,7 +169,7 @@ gdrive_7: "**Successfully Uploaded File on G-Drive :**\n\n[{}]({})"
# pmpermit
pmperm_1: "Please wait for me to respond or you will be blocked and reported as spam!!"
pmperm_2: "You were spamming my Master's PM, which I didn't like.\nYou have been BLOCKED and reported as SPAM, until further notice."
-pmperm_3: "Reply to someone's msg or try this commmand in private."
+pmperm_3: "Reply to someone's msg or try this command in private."
# updater
upd_1: "`Checking for updates, please wait....`"
diff --git a/strings/strings/gu.yml b/strings/strings/gu.yml
index d0937e8c42f30752a2610f3a68438b10ba4ea25b..9dd1e85e73a02319d0f4c8b7b887a514f5995b6c 100644
--- a/strings/strings/gu.yml
+++ b/strings/strings/gu.yml
@@ -3,11 +3,13 @@ natively: ગુજરાતી
authors:
- buddhhu
+ - iXD4RK
+ - Shivam_Patel
# commons
com_1: "`પ્રક્રિયા...`"
com_2: "`શોધી રહ્યું છે...`"
-# help
+# help
help_1: "`{}` માન્ય પ્લગઇન નથી!"
help_2: "`બોટે ઇનલાઇન ક્વેરીનો જવાબ આપ્યો નથી. \n``{}restart`` નો ઉપયોગ કરો`"
help_3: "`કૃપા કરીને તમારા બોટ માટે ઇનલાઇન મોડ ચાલુ કરો` @Botfather."
@@ -64,6 +66,7 @@ alive_1: "**અલ્ટ્રોઇડ યુઝરબોટ...**\n\n
┏━━━━━━━━━━━━━━━━━━━━━\n
┣ **માલિક** - `{}`\n
┣ **સંસ્કરણ** - `{}`\n
+┣ **પાઇ-અલ્ટ્રોઇડ** - `{}`\n
┣ **અપટાઇમ** - `{}`\n
┣ **પયથોન** - `{}`\n
┣ **ટેલેથોન** - `{}`\n
@@ -104,7 +107,6 @@ chats_3: "`હું એડમિન નથી`"
chats_4: "#Deleted\n{} કાઢી નાખ્યું."
chats_5: "તમારું [{}]({}) ગ્રુપ તૈયાર છે!"
chats_6: "જોડાઓ @TeamUltroid"
-chats_6: "તમારું [{}]({}) ગ્રુપ/ચેનલ તૈયાર છે!"
# converter
cvt_1: "મીડિયાને/ડોક્યુમેન્ટ જવાબ આપો."
@@ -123,11 +125,11 @@ core_7: "આવા કોઈ મોડ્યુલ નથી"
core_8: "{} નામનું કોઈ મોડ્યુલ નથી"
core_9: "`તમે અનલોડ કરવા માંગો છો તે પ્લગઇનનું નામ આપો`"
core_10: "**Uɴʟᴏᴀᴅᴇᴅ** `{}` **Sᴜᴄᴄᴇssғᴜʟʟʏ.**"
-core_11: "**Yᴏᴜ Cᴀɴ'ᴛ Uɴʟᴏᴀᴅ Oғғɪᴄɪᴀʟ Pʟᴜɢɪɴs**"
-core_12: "**Nᴏ Pʟᴜɢɪɴ Nᴀᴍᴇᴅ** `{}`"
-core_13: "`Give name of plugin which u want to uninstall`"
+core_11: "**તમે સત્તાવાર પ્લગને અનલોડ કરી શકતા નથી**"
+core_12: "**આ નામવાળી કોઈ પ્લગઇન નથી** `{}`"
+core_13: "`તમે કાઢવા કરવા માંગો છો તે પ્લગઇનનું નામ આપો`"
core_14: "**Uɴɪɴsᴛᴀʟʟᴇᴅ** `{}` **Sᴜᴄᴄᴇssғᴜʟʟʏ.**"
-core_15: "**Yᴏᴜ Cᴀɴ'ᴛ Uɴɪɴsᴛᴀʟʟ Oғғɪᴄɪᴀʟ Pʟᴜɢɪɴs**"
+core_15: "**તમે સત્તાવાર પ્લગને કાઢી કરી શકતા નથી**"
core_16: "`તમે અનલોડ કરવા માંગો છો તે પ્લગઇનનું નામ આપો`"
core_17: "**Sᴜᴄᴄᴇssғᴜʟʟʏ Lᴏᴀᴅᴇᴅ** `{}`"
core_18: "`{}` **લોડ કરી શકાયું નહીં નીચેની ભૂલને કારણે**\n`{}`"
@@ -161,28 +163,28 @@ gdrive_2: "[અહીં](https://console.developers.google.com/flows/enableapi?
GDRIVE_CLIENT_ID અને GDRIVE_CLIENT_SECRET આવી રીતે મોકલો.\n`GDRIVE_CLIENT_ID GDRIVE_CLIENT_SECRET` જગ્યા દ્વારા અલગ."
gdrive_3: "`Client ID ખોટું છે`"
gdrive_4: "`કંઈક ખોટું થયું! `/auth` ફરીથી મોકલો.\nIf same happens contact `@TheUltroid"
-gdrive_5: "`Success!\nYou are all set to use Google Drive with Ultroid Userbot.`"
+gdrive_5: "`સફળ! \ N તમે બધા અલ્ટ્રોઇડ યુઝરબotટથી ગૂગલ ડ્રાઇવનો ઉપયોગ કરવા માટે તૈયાર છો.`"
gdrive_6: "`Go to `{}` and send ``/auth.`"
-gdrive_7: "**Successfully Uploaded File on G-Drive :**\n\n[{}]({})"
+gdrive_7: "**જી ડ્રાઇવ પર સફળતાપૂર્વક ફાઇલ અપલોડ કરી :**\n\n[{}]({})"
# pmpermit
-pmperm_1: "Please wait for me to respnd or you will be blocked and reported as spam!!"
-pmperm_2: "You were spamming my Master's PM, which I didn't like."
-pmperm_3: "Reply to someone's msg or try this commmand in private."
+pmperm_1: "કૃપા કરીને મને રાહતની રાહ જુઓ અથવા તમને અવરોધિત કરવામાં આવશે અને સ્પામ તરીકે જાણ કરવામાં આવશે !! "
+pmperm_2: "તમે મારા માસ્ટરના વડા પ્રધાનને સ્પામ કરી રહ્યા હતા, જે મને ગમતું નથી. "
+pmperm_3: "કોઈના નામનો જવાબ આપો અથવા ખાનગીમાં આ કમાન્ડ અજમાવો. "
# updater
-upd_1: "`Checking for updates, please wait....`"
-upd_2: "`Oops.. Updater cannot continue due to some problems.`\n\n**LOGTRACE:**\n"
-upd_3: "**New UPDATE available for [[{}]]({}/tree/{}):\n\nCHANGELOG**\n\n{}"
-upd_4: "`Changelog is too big, view the file to see it.`"
-upd_5: "Use `{}update now` to update."
-upd_6: "{}\n\nUse `{}update now` to update."
+upd_1: "`અપડેટ્સ માટે તપાસી રહ્યું છે, કૃપા કરી પ્રતીક્ષા કરો .... `"
+upd_2: "`અરેરે .. કેટલીક સમસ્યાઓના કારણે અપડેટર ચાલુ રાખી શકશે નહીં.`\n\n**LOGTRACE:**\n"
+upd_3: "**માટે નવી નવી તારીખ ઉપલબ્ધ છે [[{}]]({}/tree/{}):\n\nચેન્જલોગ **\n\n{}"
+upd_4: "`ચેન્જલોગ ખૂબ મોટો છે, તેને જોવા માટે ફાઇલ જુઓ"
+upd_5: "Use `{}update now` અપડેટ કરવા."
+upd_6: "{}\n\nUse `{}update now` અપડેટ કરવા."
upd_7: "\n`Your BOT is` **up-to-date** `with` **[[{}]]({}/tree/{})**\n"
# upload download
-udl_1: "`Reply to the file/media you want to download...`"
-udl_2: "Download Successful..\nTo\n`{}`\nin `{}`"
-udl_3: "`Give a specific path to file`"
+udl_1: "`તમે ડાઉનલોડ કરવા માંગો છો તે ફાઇલ / મીડિયાને જવાબ આપો ...`"
+udl_2: "ડાઉનલોડ સફળ ..\nTo\n`{}`\nin `{}`"
+udl_3: "`ફાઇલ કરવા માટે એક વિશિષ્ટ પાથ આપો -"
# words
wrd_1: "**Word** - `{}`\n\n**Meanings** - \n"
@@ -192,6 +194,6 @@ wrd_3: "**Word** - `{}`\n\n**Antonyms** - \n"
# ---------------------------------------------------#
# assisant
-ast_1: "Choose which API you want to set."
-ast_2: "**remove.bg API**\nEnter your API key from remove.bg.\n\nUse /cancel to terminate the operation."
-ast_3: "Hi {}. Please browse through the options"
+ast_1: "તમે કયું API સેટ કરવા માંગો છો તે પસંદ કરો."
+ast_2: "**remove.bg API**\nથી તમારી API કી દાખલ કરો remove.bg.\n\nUse /cancel ઓપરેશન સમાપ્ત કરવા માટે."
+ast_3: "Hi {}. કૃપા કરીને વિકલ્પો દ્વારા બ્રાઉઝ કરો "
diff --git a/strings/strings/id.yml b/strings/strings/id.yml
index 3db65ad8b620797e45be05407be8d4ce9044f780..7c229240f709a8dbbe4aaead6543332bb377b273 100644
--- a/strings/strings/id.yml
+++ b/strings/strings/id.yml
@@ -7,7 +7,7 @@ authors:
# commons
com_1: "`Memproses...`"
com_2: "`Sedang Mencari...`"
-# help
+# help
help_1: "`{}` bukan plugin yang valid!"
help_2: "Bot tidak menanggapi inline kueri.\nLebih baik untuk menggunakan `{}restart`"
help_3: "`Tolong aktifkan inline mode bot Anda dari` @Botfather."
@@ -102,7 +102,6 @@ chats_3: "`Gua bukan admin`"
chats_4: "#Terhapus\nTerhapus {}"
chats_5: "Anda [{}]({}) Grup telah dibuat oleh boss!"
chats_6: "Join @TeamUltroid"
-chats_6: "Anda [{}]({}) Grup/Channel Telah dibuat oleh Bos!"
# converter
cvt_1: "Balas ke media/Dokumen apapun."
diff --git a/strings/strings/ml.yml b/strings/strings/ml.yml
index e2e0c70452b9492f24e7c70420e7a52f696b63bb..c870a22271498ccd3a1b7f78f4082304e3380a04 100644
--- a/strings/strings/ml.yml
+++ b/strings/strings/ml.yml
@@ -8,7 +8,7 @@ authors:
# commons
com_1: "`നടന്നുകൊണ്ടിരിക്കുന്നു...`"
com_2: "`അന്വേഷിക്കുന്നു...`"
-# help
+# help
help_1: "`{}` ഒരു പ്ലഗ്ഗിൻ അല്ല!"
help_2: "ഇൻലൈൻ ആയി ബോട്ട് വർക്ക് ചെയ്യുന്നതല്ല.\nഅതിനാൽ `{}restart` ചെയ്യുക"
help_3: "`ദയവായി ` @Botfather പോയി നിങ്ങളുടെ ബോട്ടിന്റെ ഇൻലൈൻ ഓപ്ഷൻ ഓണ് ആക്കുക."
@@ -103,7 +103,6 @@ chats_3: "`ഞാൻ ഇവിടെ അഡ്മിൻ അല്ല`"
chats_4: "#Deleted\nDeleted {}"
chats_5: "നിങ്ങളുടെ ഗ്രൂപ്പ് [{}]({}) വിജയകരമായി ഉണ്ടാക്കിയിരിക്കുന്നു!"
chats_6: "Join @TeamUltroid"
-chats_6: "നിങ്ങളുടെ ഗ്രൂപ്പ്/ചാനൽ [{}]({}) വിജയകരമായി ഉണ്ടാക്കിയിരിക്കുന്നു!"
# converter
cvt_1: "ഏതെങ്കിലും മീഡിയ/ഡോക്യുമെന്റ് റിപ്ലൈ ആയി കൊടുക്കുക.."
@@ -149,7 +148,7 @@ sf_14: "സൂപ്പർ ഫെഡ് ബാൻ പൂർത്തിയായ
sf_15: "മാസ്സ്-അ ൻഫെഡ് ബാൻ തുടങ്ങുന്നു..."
sf_16: "സൂപ്പർ അ ൻഫെഡ് ബാൻ പൂർത്തിയായി.\nആകെയുള്ള ഫെഡുകൾ {}.\nപൂർത്തിയായത്{}.\n ബാധിച്ചത്{} ഫെഡുകൾ.\n#TB"
sf_17: "`ആരുടെയെങ്കിലും മെസ്സേജിന് മറുപടി/റിപ്ലൈ ആയോ ആരുടെയെങ്കിലും ഐഡി വെച്ചോ ഫെഡ് സ്റ്റേറ്സ് പരിശോധിക്കാൻ കഴിയു..`"
-sf_18: " {} ഈ പറയുന്ന ഫെഡുകളിൽ ബാൻ ചെയ്യപ്പെട്ടിരിക്കുന്നു.\n\nവിവരം ശേഖരിച്ചത് Ultroid."
+sf_18: " {} ഈ പറയുന്ന ഫെഡുകളിൽ ബാൻ ചെയ്യപ്പെട്ടിരിക്കുന്നു.\n\nവിവരം ശേഖരിച്ചത് Ultroid."
sf_19: "**Error**\n `അ ൻബ്ലോക്ക് ` @MissRose_Bot `എന്നിട്ട് വീണ്ടും ശ്രമിക്കുക!"
sf_20: "`വിവരങ്ങൾ ശേഖരിക്കുന്നു...`"
sf_21: "\n\nഫെഡ് ഇൻഫോ ശേഖരിച്ചത് Ultroid"
diff --git a/strings/strings/mr.yml b/strings/strings/mr.yml
index ad575ad2e702ca84e349703964b1b06f4162c878..6c8dc90fdd0acfc74d83a1426f506e57d6eb89b6 100644
--- a/strings/strings/mr.yml
+++ b/strings/strings/mr.yml
@@ -7,7 +7,7 @@ authors:
# commons
com_1: "`प्रक्रिया करीत आहे ...`"
com_2: "`Searching...`"
-# help
+# help
help_1: "`{}` वैध प्लगइन नाही आहे!"
help_2: "`बॉटने इनलाइन क्वेरीला प्रतिसाद दिला नाही.\n{}restart वापरण्याचा विचार करा`"
help_3: "`कृपया आपल्या बोटसाठी @Botfather मधून इनलाइन मोड चालू करा`"
@@ -69,6 +69,7 @@ alive_1: "**अल्ट्राइड युजरबॉट...**\n\n
┏━━━━━━━━━━━━━━━━━━━━━\n
┣ **मालक** - `{}`\n
┣ **आवृत्ती** - `{}`\n
+┣ **पाय-उल्ट्रोइड** - `{}`\n
┣ **अपटाइम** - `{}`\n
┣ **पायथॉन** - `{}`\n
┣ **टेलिथॉन** - `{}`\n
@@ -114,7 +115,6 @@ chats_3: "`मी अद्मिण नाही आहे `"
chats_4: "#हटविले\nहटविले {}"
chats_5: "आपले [{}]({}) ग्रुप मला बॉस बनवले!"
chats_6: "@TeamUltroid ला जॉईन करा"
-chats_6: "आपले [{}]({}) ग्रुप/चॅनेल नि मला बॉस बनवले!"
# converter
cvt_1: "कोणत्याही मीडिया / दस्तऐवजाला रिप्लाय द्या."
@@ -180,7 +180,7 @@ gdrive_6: "`{}` ला जा आणि ``/auth.` पाठवा`"
gdrive_7: "**जी-ड्राइव्हवर यशस्वीरित्या अपलोड केलेली फाइल :**\n\n[{}]({})"
# pmpermit
-pmperm_1: "कृपया मला आरएसपीएनडीची वाट पाहा अन्यकरून तुम्हाला ब्लॉक केले जाईल आणि स्पॅम म्हणून रिपोर्ट केले जाईल!!"
+pmperm_1: "कृपया मला प्रतिसाद देण्याची वाट पाहा अन्यकरून तुम्हाला ब्लॉक केले जाईल आणि स्पॅम म्हणून रिपोर्ट केले जाईल!!"
pmperm_2: "तू माझ्या मास्टरचा पीएमला स्पॅम करत होतास, जे मला आवडलं नाही."
pmperm_3: "एखाद्याच्या एमएसजीला उत्तर द्या किंवा हा कॉमआण खासगीत ट्राय करा."
@@ -208,4 +208,4 @@ wrd_3: "**शब्द** - `{}`\n\n**विरुद्धार्थी** - \n
# assisant
ast_1: "तुम्हाला कोणता API सेट करायचा आहे ते निवडा."
ast_2: "**remove.bg API**\nremove.bg पासून आपले एपीआय कि प्रविष्ट करा.\n\nऑपरेशन बंद करण्यासाठी वापरा /cancel लिहा."
-ast_3: "हाय {}. कृपया पर्याय ब्राउज करा"
\ No newline at end of file
+ast_3: "हाय {}. कृपया पर्याय ब्राउज करा"
diff --git a/strings/strings/od.yml b/strings/strings/od.yml
index 3fd3490845c56c6804a97bd954cba3ddee483d78..ca260010b1ed77edd279ae125237d2ecd2d64844 100644
--- a/strings/strings/od.yml
+++ b/strings/strings/od.yml
@@ -7,7 +7,7 @@ authors:
# commons
com_1: "`ପ୍ରକ୍ରିୟାକରଣ ...`"
com_2: "`ଖୋଜୁଛି...`"
-# help
+# help
help_1: "`{}` ଗୋଟିଏ valid plugin ନୁହେଁ!"
help_2: "`ବଟ୍ ଇନଲାଇନ୍ ଜିଜ୍ଞାସାର କୌଣସି ପ୍ରତିକ୍ରିୟା ଦେଇ ନାହିଁ। \ n {} ପୁନ ଆରମ୍ଭଠାରୁ ବ୍ୟବହାର କରି ବିଚାର କରନ୍ତୁ |`"
help_3: "`ଆପଣଙ୍କ ବଟ ପାଇଁ ଦୟାକରି ଇନଲାଇନ ମୋଡ୍ ଟର୍ନ୍ ଅନ୍ କରନ୍ତୁ` @Botfather."
@@ -57,7 +57,7 @@ afk_6: "ମୁଁ ଅଫଲାଇନ୍(AFK) ଯାଉଛି |"
afk_7: "ବର୍ତ୍ତମାନ ଅଫଲାଇନ୍(AFK) ଅଛି | କାରଣ:{}"
afk_8: "ବର୍ତ୍ତମାନ ଅଫଲାଇନ୍େ(AFK) ଅଛି |"
-# alive
+# alive
alive_1: "**The Ultroid userbot...**\n\n
**{}**\n
┏━━━━━━━━━━━━━━━━━━━━━\n
@@ -103,7 +103,6 @@ chats_3: "`ମୁଁ ଏକ ଆଡମିନ ନୁହେଁ`"
chats_4: "#Deleted\nDeleted {}"
chats_5: "ଆପଣଙ୍କର ଗୋଷ୍ଠୀ [{}]({}) ସଫଳତାର ସହିତ ସୃଷ୍ଟି ହୋଇଛି!"
chats_6: "@TeamUltroid ରେ ଯୋଗ ଦିଅନ୍ତୁ"
-chats_6: "ତୁମର ଗୋଷ୍ଠୀ / ଚ୍ୟାନେଲ [{}]({}) ସଫଳତାର ସହିତ ସୃଷ୍ଟି ହୋଇଛି!"
# converter
cvt_1: "ଉତ୍ତର ଭାବରେ ଯେକୌଣସି ମିଡିଆ / ଡକ୍ୟୁମେଣ୍ଟ ଦିଅନ୍ତୁ|"
@@ -193,6 +192,3 @@ wrd_3: "**ଶବ୍ଦ** - `{}`\n\n**ବିପରୀତ ଶବ୍ଦ** - \n"
ast_1: "ଆପଣ କେଉଁ API ସେଟ୍ କରିବାକୁ ଚାହୁଁଛନ୍ତି ତାହା ବାଛନ୍ତୁ|"
ast_2: "**remove.bg API**\n remove.bg ରୁ ଆପଣଙ୍କର API କି ପ୍ରବେଶ କରନ୍|ତୁ\n\nଅପରେସନ୍ ବନ୍ଦ କରିବାକୁ ବ୍ୟବହାର /cancel କରନ୍ତୁ|"
ast_3: "ନମସ୍କାର {}| ଦୟାକରି ବିକଳ୍ପଗୁଡିକ ମଧ୍ୟରେ ବ୍ରାଉଜ୍ କରନ୍ତୁ"
-
-
-
diff --git a/strings/strings/pt-br.yml b/strings/strings/pt-br.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8a10a660c4f9960a9a350f5c5d84b0a1d3de2c9e
--- /dev/null
+++ b/strings/strings/pt-br.yml
@@ -0,0 +1,161 @@
+---
+name: Inglês
+natively: Inglês
+authors:
+ - YukkiZx
+
+#commons
+com_1: "`Em processamento...`"
+com_2: "`Procurando...`"
+
+#help
+help_1: "`{}` não é um plugin válido!"
+help_2: "`O bot não respondeu à consulta em linha.\nConsidere usar {}reiniciar`"
+help_3: "`Por favor, ative o modo inline para o seu bot de` @Botfather."
+help_4: "Ei, \nVocê está no modo Bot. \nOs usuários do modo Bot não conseguem obter ajuda diretamente ... \nEm vez disso, copie, cole o seguinte no chat e clique no pop-up \n\n `@{} ultd`"
+
+#autopic
+autopic_1: "Ei, dê-me algum texto .."
+autopic_2: "Sem resultados encontrados para `{}`"
+autopic_3: "Tenho uma coleção `{}` relacionado à sua pesquisa !\nIniciando Autopic !"
+
+#inline
+inline_1: "[Suporte Ultroid](t.me/ultroidsupport)\n\n **Menu de Ajuda {}.\n\n Plugins ~ {}**"
+inline_2: "[Suporte Ultroid](t.me/ultroidsupport)\n\n **Menu De ajuda {}.\n\n Complementos ~ {}**"
+inline_3: "[Suporte Ultroid](t.me/ultroidsupport)\n\n **Menu de ajuda {}.\n\n Complementos ~ {}\n\n Gᴏ Aɴᴅ Aᴅᴅ `ADDONS` Vᴀʀ Wɪᴛʜ Vᴀʟᴜᴇ Tʀᴜᴇ**"
+inline_4: "** Bᴏᴛ Oғ {}\n\nMᴀɪɴ Mᴇɴᴜ\n\nPʟᴜɢɪɴs ~ {}\nAᴅᴅᴏɴs ~ {}\nTᴏᴛᴀʟ Cᴏᴍᴍᴀɴᴅs ~ {}**"
+inline_5: "**O menu foi fechado**"
+
+#tagnotif
+tagnot_1: "{} marcou você em {}\n\n```{}```\n\n[📨Mensagem📨]({})"
+tagnot_2: "{} marcou você em {}\n\n [📨Mensagem📨]({})"
+
+#whisper
+wspr_1: "@{} mensagem secreta para você.\nExclua sua mensagem após ler.\nOu a próxima mensagem não será atualizada."
+wspr_2: "Mensagem apagada"
+
+#afk
+afk_1: "`Não está mais Afk\n\n Esteve fora por ~ {}`"
+afk_2: "#AFK\n Defina o modo AFK para Falso.\n Era AFK por {}`"
+afk_3: "Atualmente estou AFK.\n Visto pela última vez {} atrás.`\n\n **Razão:** `{}`"
+afk_4: "`Atualmente estou AFK.\n\n Visto pela última vez {} atrás.`"
+afk_5: "`Indo AFK.`\n\n **Razão:** `{}`"
+afk_6: "Estou ficando AFK."
+afk_7: "Está AFK pelo motivo {}"
+afk_8: "Está AFK."
+
+#bot
+alive_1: "**O Ultroid Userbot...**\n\n **{}**\n\n ┏━━━━━━━━━━━━━━━━━━━━━\n ┣ **Proprietário** - `{}`\n ┣ **Versão** - `{}`\n ┣ **Tempo de atividade** - `{}`\n ┣ **Python** - `{}`\n ┣ **Teleton** - `{}`\n ┣ **Filial** - `{}`\n ┗━━━━━━━━━━━━━━━━━━━━━"
+log: "**Heroku** Mudanças Ultroid.\nColado [aqui]({}) também!"
+ping: "**Pong !!** `{}ms`\n**Tempo de atividade** - `{}`"
+usage: "**⚙️ Uso Dyno ⚙️**:\n\n -> ` Uso Dyno for` **{}**:\n • `{}`**h** `{}`**m** **|** [`{}`**%**]\n\n -> `Dyno horas de cota restando esse mês `:\n • `{}`**h** `{}`**m** **|** [`{}`**%**]\n\n **Espaço Total em Disco: {}\n\n** **Usado: {} Livre: {}\n\n** **📊Uso De Data📊\n\nUpload: {}\nDown: {}\n\n** **CPU: {}%\nRAM: {}%\nDISK: {}%**"
+shutdown: "Adeus {}.\n`Desligando...`"
+
+#broadcast
+bd_1: "`Adicionando ao banco de dados...`"
+bd_2: "`Tentando adicionar todos os canais de administração ao banco de dados...`"
+bd_3: "**Feito.**\nBate-papos já no banco de dados: {}\nRecém-adicionado: {}"
+bd_4: "Canais adicionados!"
+bd_5: "`Adicionado ao banco de dados!`"
+bd_6: "`Canal já está no banco de dados!`"
+
+#carbon
+carbon_1: "Carregando"
+carbon_2: "Carbonizado por [{}](tg://user?id={})"
+
+#chats
+chats_1: "`Em processamento...`"
+chats_2: "`Não é possível excluir este bate-papo`"
+chats_3: "`Eu não sou um administrador`"
+chats_4: "#Excluído\nExcluído {}"
+chats_5: "Seu [{}]({}) Grupo tornou chefe!"
+chats_6: "Seu [{}]({}) Grupo/Canal tornou-se chefe!"
+
+#converter
+cvt_1: "Responder a qualquer mídia/documento."
+cvt_2: "Dê o nome e a extensão do arquivo"
+cvt_3: "`Em processamento...`"
+cvt_4: "Responda a qualquer mídia."
+
+#core
+core_1: "Módulo encontrado"
+core_2: "{}.py usar .paste colar em neko e raw.."
+core_3: "Procurar denovo..?"
+core_4: "Módulo {} encontrado"
+core_5: "{}.py usar .paste para colar em neko e raw.."
+core_6: "Módulo {}.py não encontrado"
+core_7: "Não existe tal módulo"
+core_8: "Nenhum Módulo nomeado {}.py"
+core_9: "`Dê o nome do plugin que você deseja descarregar`"
+core_10: "**Desinstalado** `{}` **Com Sucesso.**"
+core_11: "**Você não pode desinstalar plugins oficiais**"
+core_12: "**Nenhum plugin nomeado** `{}`"
+core_13: "`Dê o nome do plugin que você deseja desinstalar`"
+core_14: "**Desinstalado** `{}` **Com Sucesso.**"
+core_15: "**Você não pode Retirar Plugins Official**"
+core_16: "`Dê o nome do plugin que você deseja carregar`"
+core_17: "**Carregado Com sucesso** `{}`"
+core_18: "**Não foi possível carregar** `{}` **por causa do seguinte erro.**\n`{}`"
+
+#fedutils
+sf_1: "Iniciando um FedBan em massa..."
+sf_2: "`Nenhum usuário designado!`"
+sf_3: "Você não pode banir meu Dev, seu novato!!"
+sf_4: "`Parece que a rose não está respondendo ou o plugin está se comportando mal`"
+sf_5: "Você só pode usar comandos do fed uma vez a cada 5 minutos"
+sf_6: "Tente novamente após 5 minutos."
+sf_7: "Não foi possível coletar FedAdminList. Tentando novamente ({}/3)..."
+sf_8: "Erro"
+sf_9: "Incapaz de coletar FedAdminList."
+sf_10: "FBaning no {} feds."
+sf_11: "O ID do grupo FBan especificado está incorreto."
+sf_12: "{} Excluído."
+sf_13: "Erro ao remover arquivo FedAdmin.\n{}"
+sf_14: "SuperFBan concluído.\nFeds totais - {}.\nExcluído - {}.\n Afetado {} feds.\n#TB"
+sf_15: "Iniciando FedBan em massa..."
+sf_16: "SuperUnFBan concluído.\nFeds totais - {}.\nExcluído - {}.\n Feds {} afetados.\n#TB"
+sf_17: "`Dê-me a identidade de alguém ou responda à mensagem de alguém para verificar seu fedstat.`"
+sf_18: "Lista de feds {} foi banida em.\n\nColetados usando Ultroid."
+sf_19: "**Erro**\n `Desbloquear` @MissRose_Bot `e tente novamente!"
+sf_20: "`Extraindo informações...`"
+sf_21: "\n\nFedInfo Extraído por Ultroid"
+
+#gdrive
+gdrive_1: "`Você já autorizou com o Google Drive`"
+gdrive_2: "Ir [here](https://console.developers.google.com/flows/enableapi?apiid=drive) e pegue o seu `GDRIVE_CLIENT_ID` e `GDRIVE_CLIENT_SECRET`\n\n Mande seu GDRIVE_CLIENT_ID e GDRIVE_CLIENT_SECRET como isso.\n`GDRIVE_CLIENT_ID GDRIVE_CLIENT_SECRET` separados por espaço."
+gdrive_3: "`Id de cliente errado`"
+gdrive_4: "`Algo deu errado! Envie `/auth` novamente.\nSe o mesmo acontecer entre em contato `@TheUltroid"
+gdrive_5: "`Sucesso!\nVocê está pronto para usar o Google Drive com Ultroid Userbot.`"
+gdrive_6: "`Ir para `{}` e envia ``/auth.`"
+gdrive_7: "**O upload do Arquivo No G-Drive Foi bem sucedido :**\n\n[{}]({})"
+
+#pmpermit
+pmperm_1: "Por favor espere até eu te responder ou você será reportado e bloqueado como spam!!"
+pmperm_2: "Você Esta Spamando O Chat Privado Do meu Mestre, o que você quer."
+pmperm_3: "Responda A Mensagem de alguém ou tente esse comando no privado."
+
+#updater
+upd_1: "`Checando por Atualizações, por favor espere....`"
+upd_2: "`Oops.. O Atualizador não pode Continuar Devido A algum Problema.`\n"
+upd_3: "**Nova Atualizaçao Disponivel Para [[{}]]({}/tree/{}):\n\nCHANGELOG**\n\n{}"
+upd_4: "`Changelog é Muito grande, veja o arquivo para checar isso.`"
+upd_5: "Use `{}Atualizar Agora` para Atualizar."
+upd_6: "{}\n\nUsar `{}atualize agora` para atualizar."
+upd_7: "\n`Seu BOT é` **atualizado** `com` **[[{}]]({}/tree/{})**\n"
+
+#upload download
+udl_1: "`Responder o arquivo/mídia que você deseja baixar..`"
+udl_2: "Download bem sucedido..\nPara\n`{}`\nno `{}`"
+udl_3: "`Forneça um caminho específico para o arquivo`"
+
+#words
+wrd_1: "**Palavra** - `{}`\n\n**Significados** - \n"
+wrd_2: "**Palavra** - `{}`\n\n**Sinônimos** - \n"
+wrd_3: "**Palavra** - `{}`\n\n**Antônimos** - \n"
+
+#---------------------------------------------------#
+
+#assisant
+ast_1: "Escolha qual API você deseja definir."
+ast_2: "**remove.bg API**\nInsira sua chave de API de remove.bg.\n\nUse /cancele para encerrar a operação."
+ast_3: "Olá {}. Por favor, navegue pelas opções"
diff --git a/strings/strings/si.yml b/strings/strings/si.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6e835133488aa9f1fd61e394e06fbe053fc08938
--- /dev/null
+++ b/strings/strings/si.yml
@@ -0,0 +1,195 @@
+name: sinhala
+natively: සිංහල
+
+authors:
+ - situm Batrow // sibatrow
+
+# commons
+com_1: "`Processing...`"
+com_2: "`සොයමින්...`"
+# help
+help_1: "`{}` වලංගු plugin එකක් නෙමෙයි!"
+help_2: "bot inline query එක්ට ප්රතිචාර නොදක්වයි.\n`{}restart` කරල නැවත සලකා බලන්න"
+help_3: "`@Botfather `එකෙන් Oot ට inline mode on කරන්න."
+help_4: "Hey, \nඔයා ඉන්නෙ Bot mode එකේ. \nBot Mode Users ලට Help Directly ගන්න බෑ... \nමේ කෝඩ් එක Chat එකේ Copy Paste කරල Pop Up එක Click කරන්න \n\n `@{} ultd`"
+
+# autopic
+autopic_1: "මට මොනාහරි text එකක් දෙන්න .."
+autopic_2: "`{}` යන්නට කිසිවක් හමු නොවීය "
+autopic_3: "`{}` යන ඔබ සෙවූ දෙයට අදාලව collection එකක්ම හමු විය !\nAutopic ආරම්භ කරමින් !"
+
+# inline
+inline_1: "[Uʟᴛʀᴏɪᴅ Sᴜᴘᴘᴏʀᴛ](t.me/ultroidsupport)\n\n
+**Hᴇʟᴘ Mᴇɴᴜ Oғ {}.\n\n
+Pʟᴜɢɪɴs ~ {}**"
+inline_2: "[Uʟᴛʀᴏɪᴅ Sᴜᴘᴘᴏʀᴛ](t.me/ultroidsupport)\n\n
+**Hᴇʟᴘ Mᴇɴᴜ Oғ {}.\n\n
+Aᴅᴅᴏɴs ~ {}**"
+inline_3: "[Uʟᴛʀᴏɪᴅ Sᴜᴘᴘᴏʀᴛ](t.me/ultroidsupport)\n\n
+**Hᴇʟᴘ Mᴇɴᴜ Oғ {}.\n\n
+Aᴅᴅᴏɴs ~ {}\n\n
+Gᴏ Aɴᴅ Aᴅᴅ `ADDONS` Vᴀʀ Wɪᴛʜ Vᴀʟᴜᴇ Tʀᴜᴇ**"
+inline_4: "** Bᴏᴛ Oғ {}\n\nMᴀɪɴ Mᴇɴᴜ\n\nPʟᴜɢɪɴs ~ {}\nAᴅᴅᴏɴs ~ {}\nTᴏᴛᴀʟ Cᴏᴍᴍᴀɴᴅs ~ {}**"
+inline_5: "**Mᴇɴᴜ Hᴀs Bᴇᴇɴ Cʟᴏsᴇᴅ**"
+
+# tagnotif
+tagnot_1: "{} ඔයාව ටැග් කලා {} එකේ\n\n```{}```\n\n[📨 Message 📨]({})"
+tagnot_2: "{} ඔයාව ටැග් කලා {} එකේ\n\n [📨 Message 📨]({})"
+
+# whisper
+wspr_1: "@{} secret msg for you.\nDelete your msg after reading.\nOr the next msg will not be updated."
+wspr_2: "Message deleted"
+
+# afk
+afk_1: "`තව දුරටත් Afk නෙමෙයි\n\n
+AFK හිටියා ~ {}`"
+afk_2: "#AFK\n
+AFK mode එක False ලෙස සකසන්න.\n
+Was AFK for {}`"
+afk_3: "`මම දැන් AFK.\n
+අන්තිමට ඔන්ලයින් හිටියේ {} ට කලින්.`\n\n
+**හේතුව:** `{}`"
+afk_4: "``මම දැන් AFK.\n\n
+අන්තිමට ඔන්ලයින් හිටියේ {} ට කලින්`"
+afk_5: "`AFK යනවා.`\n\n
+**හේතුව:** `{}`"
+afk_6: "මම AFK යනවා."
+afk_7: "{} යන හේතුව නිසා මම දැන් AFK"
+afk_8: "මම දැන් AFK."
+
+# bot
+alive_1: "**The Ultroid Userbot...**\n\n
+**{}**\n\n
+┏━━━━━━━━━━━━━━━━━━━━━\n
+┣ **Owner** - `{}`\n
+┣ **Version** - `{}`\n
+┣ **Py-Ultroid** - `{}`\n
+┣ **UpTime** - `{}`\n
+┣ **Python** - `{}`\n
+┣ **Telethon** - `{}`\n
+┣ **Branch** - `{}`\n
+┗━━━━━━━━━━━━━━━━━━━━━"
+log: " Ultroid userbot ගේ **Heroku** Logs.\n[මෙතනත් ]({}) paste කර ඇත!"
+ping: "** වැඩ වැඩ මහත්තයො ** Pong !! ** `{}ms`\n**Uptime** - `{}`"
+usage: "**⚙️ Dyno භාවිතය ⚙️**:\n\n
+ -> **{}** `ගේ Dyno භාවිතය`:\n
+ • `{}`**h** `{}`**m**
+**|** [`{}`**%**]\n\n
+ -> `මේ මාසය සඳහා ඉතුරු Dyno පැය ප්රමාණය`:\n
+ • `{}`**h** `{}`**m**
+**|** [`{}`**%**]\n\n
+**සම්පූර්ණ තැටි ධාරිතාව: {}\n\n**
+**භාවිතා කල ප්රමාණය: {} ඉතිරි ප්රමාණය: {}\n\n**
+**📊 දත්ත භාවිතය 📊\n\nඋඩුගත කිරීම්: {}\nබාගත කිරීම්: {}\n\n**
+**CPU: {}%\nRAM: {}%\nDISK: {}%**"
+shutdown: "සුභ දවසක් වේවා {}.\n`වසා දමමින්...`"
+
+# broadcast
+bd_1: "`දත්ත පාදකයට ඇතුලත් කරමින්...`"
+bd_2: "`සියලු Admin chats දත්ත පාදකයට ඇතුල් කිරීමට උත්සාහ කරමින්...`"
+bd_3: "**සාර්ථකයි.**\n දත්තපාද්කය තුල දැනටමත් ඇති Chats: {}\nඅලුතින් එකතු වූ: {}"
+bd_4: " නාලිකා එකතු කරන ලදි! "
+bd_5: "` දත්ත සමුදායට එකතු කරන ලදි! `"
+bd_6: "` නාලිකාව දැනටමත් දත්ත සමුදායයි! `"
+
+# carbon
+carbon_1: "පූරණය වෙමින්..."
+carbon_2: "Carbonised කරන ලද්දේ [{}](tg://user?id={}) විසිනි"
+
+# chats
+chats_1: "`පූරණය වෙමින්...`"
+chats_2: "`මේ චැට් එක මකා දැමිය නොහැක`"
+chats_3: "`මම පරිපාලක නෙමෙයි`"
+chats_4: "#Deleted\nමකාදැමුවා {}"
+chats_5: "ඔයාගේ [{}]({}) Group එක හැඩුවා ලොක්කා..!"
+chats_6: "@TeamUltroid සමඟ එකතු වන්න"
+
+# converter
+cvt_1: "media/Document එකකට රිප්ලයි කරන්න."
+cvt_2: "ගොනුවේ නම සහ ගොනු දිගුව සඳහන් කරන්න"
+cvt_3: "`පූරණය වෙමින්...`"
+cvt_4: "මොනාහරි media එකකට රිප්ලයි කරන්න."
+
+# core
+core_1: "මොඩියුලය හමුවිය"
+core_2: "{}.py neko වල paste කිරීමට හෝ raw එක බැලීමට .paste විධානය භාවිතා කරන්න.."
+core_3: "නැවත්ත සොයනවාද..?"
+core_4: "{} මොඩියුලය හමුවුනා"
+core_5: "{}.py neko වල paste කිරීමට හෝ raw එක බැලීමට .paste විධානය භාවිතා කරන්න.."
+core_6: "{}.py මොඩියුලය හම්බුන් නෑ"
+core_7: "ඒම මොඩියුල් නෑ පුතා"
+core_8: "{}.py කියල මොඩියුල් නෑ"
+core_9: "`unload කරන්න ඕන Plugin එකේ නම කියන්න බොසා`"
+core_10: "**සාර්තකව** `{}` **Unload කරා.**"
+core_11: "**නිල Plugin Unload කිරීම කල නොහැක**"
+core_12: "`{}`**කියල Pʟᴜɢɪɴ නෑ** "
+core_13: "`Uninstall කිරීමට අවශ්ය Plugin එකේ නම ලබා දෙන්න`"
+core_14: "**සාර්තකව ** `{}` **ඉවත් කරන ලදි.**"
+core_15: "**නිල Pʟᴜɢɪɴs ඉවත් කරන්න බෑ**"
+core_16: "`Load කිරීමට අවශ්ය Plugin එකේ නම කියන්න`"
+core_17: "`{}`**සාර්තකව Lᴏᴀᴅ කරා** "
+core_18: "`{}`**Load කිරීම අසාර්තකයි** **මේ error එක ලෝඩ් කිරීමේ ක්රියාවලිය තුලදී මතු උනා.**\n`{}`"
+
+# fedutils
+sf_1: "Starting a Mass-FedBan..."
+sf_2: "`No user designated!`"
+sf_3: "You can't ban my dev you noob!!"
+sf_4: "`Seems like rose isn't responding, or, the plugin is misbehaving`"
+sf_5: "You can only use fed commands once every 5 minutes"
+sf_6: "Try again after 5 mins."
+sf_7: "Unable to collect FedAdminList. Retrying ({}/3)..."
+sf_8: "Error"
+sf_9: "Unable to collect FedAdminList."
+sf_10: "FBaning in {} feds."
+sf_11: "Specified FBan Group ID is incorrect."
+sf_12: "{} Excluded."
+sf_13: "Error in removing FedAdmin file.\n{}"
+sf_14: "SuperFBan Completed.\nTotal Feds - {}.\nExcluded - {}.\n Affected {} feds.\n#TB"
+sf_15: "Starting a Mass-UnFedBan..."
+sf_16: "SuperUnFBan Completed.\nTotal Feds - {}.\nExcluded - {}.\n Affected {} feds.\n#TB"
+sf_17: "`Give me someones id, or reply to somones message to check his/her fedstat.`"
+sf_18: "List of feds {} has been banned in.\n\nCollected using Ultroid."
+sf_19: "**Error**\n `Unblock` @MissRose_Bot `and try again!"
+sf_20: "`Extracting information...`"
+sf_21: "\n\nFedInfo Extracted by Ultroid"
+
+# gdrive
+gdrive_1: "`You have already authorised with Google Drive`"
+gdrive_2: "Go [here](https://console.developers.google.com/flows/enableapi?apiid=drive) and get your `GDRIVE_CLIENT_ID` and `GDRIVE_CLIENT_SECRET`\n\n
+Send your GDRIVE_CLIENT_ID and GDRIVE_CLIENT_SECRET as this.\n`GDRIVE_CLIENT_ID GDRIVE_CLIENT_SECRET` separated by space."
+gdrive_3: "`Wrong Client Id`"
+gdrive_4: "`Something went wrong! Send `/auth` again.\nIf same happens contact `@TheUltroid"
+gdrive_5: "`Success!\nYou are all set to use Google Drive with Ultroid Userbot.`"
+gdrive_6: "`Go to `{}` and send ``/auth.`"
+gdrive_7: "**Successfully Uploaded File on G-Drive :**\n\n[{}]({})"
+
+# pmpermit
+pmperm_1: " මගෙ master busy පොඩ්ඩක් ඉවසලා ඉන්න master ඔයාට msg එකක් දානකන්. spam ගහන්න එපා මම ඔයාව block කරනවා. ගොඩක් ස්තුතියි master ට msg කරාට. "
+pmperm_2: " ඔයා මගේ මාස්ටර් ගෙ Inbox එකට Spam ගහන්න හදපු නිසා මම ඔයාව Block කරා "
+pmperm_3: "කාගෙහරි මැසේජ් එකකට රිප්ලයි කරන්න, නෙත්තන් Privately උත්සාහ කරන්න."
+
+# updater
+upd_1: "`මඳක් රැදී සිටින්න, යාවත්කාලීන කිරීම් පිළිබඳ සොයා බලමින්....`"
+upd_2: "`Oops.. Updater එකට තවදුරටත් යා නොහැක.`\n\n**LOGTRACE:**\n"
+upd_3: "**[[{}]]({}/tree/{}) සඳහා නව යාවත්කාලීන කිරීම්:\n\nCHANGELOG**\n\n{}"
+upd_4: "`Changelog එක ගොඩක් ලොකුයි, පහත ගොනුව තුලින් එය බලා ගන්න.`"
+upd_5: "යාවත්කාලීන කිරීමට `{}update now` විධානය භාවිතා කරන්න."
+upd_6: "{}\n\nයාවත්කාලීන කිරීමට `{}update now` විධානය භාවිතා කරන්න."
+upd_7: "\n`ඔයාගෙ BOT එක` **up-to-date** **[[{}]]({}/tree/{})** එක එක්ක \n"
+
+# upload download
+udl_1: "`බාගත කිරීම සඳහා ඕනෑම file/media එකකට රිප්ලයි කරන්න...`"
+udl_2: "බාගත කිරීම සාර්ථකයි ..\nගොනුව තැම්පත් වූ ස්ථානය\n`{}`\nගතවූ කාලය `{}`"
+udl_3: "`Give a specific path to file`"
+
+# words
+wrd_1: "**වචනය** - `{}`\n\n**තේරුම්** - \n"
+wrd_2: "**වචනය** - `{}`\n\n**සමාන පද ** - \n"
+wrd_3: "**වචනය** - `{}`\n\n**විරුද්ධ පද** - \n"
+
+# ---------------------------------------------------#
+
+# assisant
+ast_1: "ඔබට සැකසිය යුතු API එක තෝරන්න."
+ast_2: "**remove.bg API**\nඔයා remove.bg එකෙන් ගනිපු API එක ඇතුල් කරන්න.\n\nමෙම ක්රියාවලිය නැවැත්වීමට /cancel විධානය භාවිතා කරන්න."
+ast_3: " ආයුබෝවන් {}. කරුණාකර පහත Options හරහා පිරික්සන්න "
diff --git a/strings/strings/ta.yml b/strings/strings/ta.yml
index 8ef527b29ed4adab700d68f6ffe0e34d50973ab6..293d051872863bc7df9af9ac939f217a66c58cc7 100644
--- a/strings/strings/ta.yml
+++ b/strings/strings/ta.yml
@@ -3,11 +3,11 @@ natively: தமிழ்
authors:
- sppidy
-
+
# commons
com_1: "`காத்திரு...`"
-# help
+# help
help_1: "`{}` சரியான Plugin அல்ல!"
help_2: "`இன்லைன் வினவலுக்கு Bot பதிலளிக்கவில்லை.\n{}restart பயன்படுத்துவதைக் கருத்தில் கொள்ளுங்கள்`"
help_3: "`உங்கள் போட் இன்லைன் பயன்முறையை` @Botfather `வழியாக இயக்கவும்`."
@@ -17,6 +17,3 @@ help_4: "தங்கள் Bot பயன்முறையில் இரு
autopic_1: "எனக்கு சில வார்த்தைகளை கொடுங்கள் .."
autopic_2: "`{}` இக்கு முடிவுகள் எதுவும் கிடைக்கவில்லை"
autopic_3: "உங்கள் தேடுளளான `{}` தோகுப்பு கிடைத்தது !\nAutopic ஆறாம்பிக்கிறது !"# inline
-
-
-
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..bb91edc9c9ff9454ad87d293348ab23b259bc58a
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "module": "CommonJS",
+ "strict": true,
+ "target": "ES2019",
+ "esModuleInterop": true,
+ "outDir": "build/"
+ },
+ "include": ["src/"]
+}
diff --git a/vcstarter.py b/vcstarter.py
new file mode 100644
index 0000000000000000000000000000000000000000..3c40ec14f4b09078a57356d41bbd013c6c133d26
--- /dev/null
+++ b/vcstarter.py
@@ -0,0 +1,164 @@
+import json
+import os
+from json.decoder import JSONDecodeError
+
+from aiohttp import web
+from aiohttp.http_websocket import WSMsgType
+from pyUltroid import Var, vcbot
+from telethon import TelegramClient
+from telethon.errors import ChannelPrivateError
+from telethon.tl.functions.channels import GetFullChannelRequest
+from telethon.tl.functions.phone import (GetGroupCallRequest,
+ JoinGroupCallRequest)
+from telethon.tl.types import DataJSON
+
+bot = TelegramClient(None, Var.API_ID, Var.API_HASH).start(bot_token=Var.BOT_TOKEN)
+
+
+if vcbot:
+
+ async def get_entity(chat):
+ try:
+ return await vcbot.get_input_entity(chat["id"])
+ except ValueError:
+ if "username" in chat:
+ return await vcbot.get_entity(chat["username"])
+ raise
+
+ async def join_call(data):
+ try:
+ chat = await get_entity(data["chat"])
+ except ValueError:
+ stree = (await vcbot.get_me()).first_name
+ return await bot.send_message(
+ data["chat"]["id"], f"`Please add {stree} in this group.`"
+ )
+ except Exception as ex:
+ return await bot.send_message(data["chat"]["id"], "`" + str(ex) + "`")
+ try:
+ full_chat = await vcbot(GetFullChannelRequest(chat))
+ except ValueError:
+ stree = (await vcbot.get_me()).first_name
+ return await bot.send_message(
+ data["chat"]["id"], f"`Please add {stree} in this group.`"
+ )
+ except Exception as ex:
+ return await bot.send_message(data["chat"]["id"], "`" + str(ex) + "`")
+ try:
+ call = await vcbot(GetGroupCallRequest(full_chat.full_chat.call))
+ except:
+ call = None
+ if not call:
+ return await bot.send_message(
+ data["chat"]["id"],
+ "`I can't access voice chat.`",
+ )
+
+ try:
+ result = await vcbot(
+ JoinGroupCallRequest(
+ call=call.call,
+ muted=False,
+ join_as="me",
+ params=DataJSON(
+ data=json.dumps(
+ {
+ "ufrag": data["ufrag"],
+ "pwd": data["pwd"],
+ "fingerprints": [
+ {
+ "hash": data["hash"],
+ "setup": data["setup"],
+ "fingerprint": data["fingerprint"],
+ },
+ ],
+ "ssrc": data["source"],
+ },
+ ),
+ ),
+ ),
+ )
+ await bot.send_message(
+ Var.LOG_CHANNEL,
+ f"`Joined Voice Chat in {(await bot.get_entity(data['chat']['id'])).title}`",
+ )
+ except Exception as ex:
+ return await bot.send_message(data["chat"]["id"], "`" + str(ex) + "`")
+
+ transport = json.loads(result.updates[0].call.params.data)["transport"]
+
+ return {
+ "_": "get_join",
+ "data": {
+ "chat_id": data["chat"]["id"],
+ "transport": {
+ "ufrag": transport["ufrag"],
+ "pwd": transport["pwd"],
+ "fingerprints": transport["fingerprints"],
+ "candidates": transport["candidates"],
+ },
+ },
+ }
+
+ # async def leave_vc(data):
+ # await bot.send_message(Var.LOG_CHANNEL, "Received Leave Request")
+ # try:
+ # await get_entity(data["chat"]["id"])
+ # except Exception as ex:
+ # return await bot.send_message(data["chat"]["id"], "`" + str(ex) + "`")
+ # try:
+ # full_chat = await vcbot(GetFullChannelRequest(chat))
+ # except Exception as ex:
+ # return await bot.send_message(data["chat"]["id"], "`" + str(ex) + "`")
+ # try:
+ # call = await vcbot(GetGroupCallRequest(full_chat.full_chat.call))
+ # except:
+ # call = None
+ #
+ # try:
+ # result = await vcbot(
+ # LeaveGroupCallRequest(
+ # call=call.call,
+ # source=data["source"],
+ # ),
+ # )
+ # await bot.send_message(
+ # Var.LOG_CHANNEL,
+ # f"`Left Voice Chat in {(await bot.get_entity(data['chat']['id'])).title}`",
+ # )
+ # except Exception as ex:
+ # return await bot.send_message(data["chat"]["id"], "`" + str(ex) + "`")
+ #
+ # return {"_": "left_vc", "data": {"chat_id": data["chat"]["id"]}}
+
+ async def websocket_handler(request):
+ ws = web.WebSocketResponse()
+ await ws.prepare(request)
+
+ async for msg in ws:
+ if msg.type == WSMsgType.TEXT:
+ try:
+ data = json.loads(msg.data)
+ except JSONDecodeError:
+ await ws.close()
+ break
+
+ response = None
+ if data["_"] == "join":
+ response = await join_call(data["data"])
+
+ # if data["_"] == "leave":
+ # response = await leave_vc(data["data"])
+
+ if response is not None:
+ await ws.send_json(response)
+
+ return ws
+
+ def main():
+ app = web.Application()
+ app.router.add_route("GET", "/", websocket_handler)
+ web.run_app(app, port=os.environ.get("PORT", 6969))
+
+ vcbot.start()
+ main()