refactor
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
[](https://makeapullrequest.com)
|
||||
</p>
|
||||
|
||||
#### _A Simple, Fast, Customizable Userbot for Telegram._
|
||||
#### _A Simple, Fast, Customizable Userbot for Telegram made after Dragon-Userbot abandoned._
|
||||
|
||||
|
||||
<h1>Installation</h1>
|
||||
|
||||
107
install.py
107
install.py
@@ -1,18 +1,18 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it is under the terms of the GNU 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 free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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.
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
@@ -21,51 +21,46 @@ from pyrogram import Client
|
||||
from utils import config
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Client(
|
||||
"my_account",
|
||||
api_id = config.api_id,
|
||||
api_hash = config.api_hash,
|
||||
hide_password = True,
|
||||
test_mode = config.test_server,
|
||||
)
|
||||
app = Client(
|
||||
"my_account",
|
||||
api_id=config.api_id,
|
||||
api_hash=config.api_hash,
|
||||
hide_password=True,
|
||||
test_mode=config.test_server,
|
||||
)
|
||||
|
||||
if config.db_type in ["mongo", "mongodb"]:
|
||||
from pymongo import MongoClient, errors
|
||||
if config.db_type in ["mongo", "mongodb"]:
|
||||
from pymongo import MongoClient, errors
|
||||
|
||||
db = MongoClient(config.db_url)
|
||||
try:
|
||||
db.server_info()
|
||||
except errors.ConnectionFailure as e:
|
||||
raise RuntimeError(
|
||||
"MongoDB server isn't available! "
|
||||
f"Provided url: {
|
||||
config.db_url
|
||||
}. "
|
||||
"Enter valid URL and restart installation"
|
||||
) from e
|
||||
db = MongoClient(config.db_url)
|
||||
try:
|
||||
db.server_info()
|
||||
except errors.ConnectionFailure as e:
|
||||
raise RuntimeError(
|
||||
"MongoDB server isn't available! "
|
||||
f"Provided url: {config.db_url}. "
|
||||
"Enter valid URL and restart installation"
|
||||
) from e
|
||||
|
||||
install_type = sys.argv[1] if len(sys.argv) > 1 else "3"
|
||||
if install_type == "1":
|
||||
restart = "pm2 restart Moon"
|
||||
elif install_type == "2":
|
||||
restart = "sudo systemctl restart Moon"
|
||||
else :
|
||||
restart = "cd Moon-Userbot/ && python main.py"
|
||||
install_type = sys.argv[1] if len(sys.argv) > 1 else "3"
|
||||
if install_type == "1":
|
||||
restart = "pm2 restart Moon"
|
||||
elif install_type == "2":
|
||||
restart = "sudo systemctl restart Moon"
|
||||
else:
|
||||
restart = "cd Moon-Userbot/ && python main.py"
|
||||
|
||||
app.start()
|
||||
try:
|
||||
app.send_message(
|
||||
"me",
|
||||
f"<b>[ {
|
||||
datetime.datetime.now()}] Moon-Userbot launched! \n"
|
||||
"Channel: @moonuserbot\n"
|
||||
"Custom modules: @moonub_modules\n"
|
||||
"Chat [RU]: @moonub_chat\n"
|
||||
f"For restart, enter:</b>\n"
|
||||
f"<code> {
|
||||
restart
|
||||
}</code>",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
app.stop()
|
||||
app.start()
|
||||
try:
|
||||
app.send_message(
|
||||
"me",
|
||||
f"<b>[{datetime.datetime.now()}] Moon-Userbot launched! \n"
|
||||
"Channel: @moonuserbot\n"
|
||||
"Custom modules: @moonub_modules\n"
|
||||
"Chat [RU]: @moonub_chat\n"
|
||||
f"For restart, enter:</b>\n"
|
||||
f"<code>{restart}</code>",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
app.stop()
|
||||
|
||||
265
install.sh
265
install.sh
@@ -1,159 +1,164 @@
|
||||
#!/bin/bash
|
||||
if command -v termux-setup-storage; then
|
||||
echo For termux, please use https://raw.githubusercontent.com/The-MoonTg-project/Moon-Userbot/main/termux-install.sh
|
||||
exit 1
|
||||
echo For termux, please use https://raw.githubusercontent.com/The-MoonTg-project/Moon-Userbot/main/termux-install.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[$UID != 0]]; then
|
||||
echo Please run this script as root
|
||||
exit 1
|
||||
if [[ $UID != 0 ]]; then
|
||||
echo Please run this script as root
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apt update -y
|
||||
apt install python3 python3-pip git ffmpeg wget gnupg -y || exit 2
|
||||
|
||||
su -c "python3 -m pip install -U pip" $SUDO_USER
|
||||
su -c "python3 -m pip install -U wheel pillow" $SUDO_USER
|
||||
su -c "python3 -m pip install -U pip" $SUDO_USER
|
||||
su -c "python3 -m pip install -U wheel pillow" $SUDO_USER
|
||||
|
||||
if [[-d "Moon-Userbot"]]; then
|
||||
cd Moon-Userbot
|
||||
elif [[-f ".env.dist"]] && [[-f "main.py"]] && [[-d "modules"]]; then
|
||||
:
|
||||
if [[ -d "Moon-Userbot" ]]; then
|
||||
cd Moon-Userbot
|
||||
elif [[ -f ".env.dist" ]] && [[ -f "main.py" ]] && [[ -d "modules" ]]; then
|
||||
:
|
||||
else
|
||||
git clone https://github.com/The-MoonTg-project/Moon-Userbot || exit 2
|
||||
cd Moon-Userbot || exit 2
|
||||
git clone https://github.com/The-MoonTg-project/Moon-Userbot || exit 2
|
||||
cd Moon-Userbot || exit 2
|
||||
fi
|
||||
|
||||
if [[-f ".env"]] && [[-f "my_account.session"]]; then
|
||||
echo "It seems that Moon-Userbot is already installed. Exiting..."
|
||||
exit
|
||||
if [[ -f ".env" ]] && [[ -f "my_account.session" ]]; then
|
||||
echo "It seems that Moon-Userbot is already installed. Exiting..."
|
||||
exit
|
||||
fi
|
||||
|
||||
su -c "python3 -m pip install -U -r requirements.txt" $SUDO_USER || exit 2
|
||||
su -c "python3 -m pip install -U -r requirements.txt" $SUDO_USER || exit 2
|
||||
|
||||
echo
|
||||
echo "Enter API_ID and API_HASH"
|
||||
echo "You can get it here -> https://my.telegram.org/apps"
|
||||
echo "Leave empty to use defaults (please note that default keys significantly increases your ban chances)"
|
||||
read -r -p "API_ID > " api_id
|
||||
echo "Enter API_ID and API_HASH"
|
||||
echo "You can get it here -> https://my.telegram.org/"
|
||||
echo "Leave empty to use defaults (please note that default keys significantly increases your ban chances)"
|
||||
read -r -p "API_ID > " api_id
|
||||
|
||||
if [[$api_id = ""]]; then
|
||||
api_id = "2040"
|
||||
api_hash = "b18441a1ff607e10a989891a5462e627"
|
||||
if [[ $api_id = "" ]]; then
|
||||
api_id="2040"
|
||||
api_hash="b18441a1ff607e10a989891a5462e627"
|
||||
else
|
||||
read -r -p "API_HASH > " api_hash
|
||||
read -r -p "API_HASH > " api_hash
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Choose database type:"
|
||||
echo "[1] MongoDB db_url"
|
||||
echo "[2] MongoDB localhost"
|
||||
echo "[3] Sqlite (default)"
|
||||
read -r -p "> " db_type
|
||||
echo "Choose database type:"
|
||||
echo "[1] MongoDB db_url"
|
||||
echo "[2] MongoDB localhost"
|
||||
echo "[3] Sqlite (default)"
|
||||
read -r -p "> " db_type
|
||||
|
||||
echo
|
||||
case $db_type in
|
||||
1)
|
||||
echo "Please enter db_url"
|
||||
echo "You can get it here -> "
|
||||
read -r -p "> " db_url
|
||||
db_name = Moon_Userbot
|
||||
db_type = mongodb
|
||||
;;
|
||||
2)
|
||||
if systemctl status mongodb; then
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add -
|
||||
source /etc/os-release
|
||||
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $ {
|
||||
UBUNTU_CODENAME
|
||||
}/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list
|
||||
apt update
|
||||
apt install mongodb -y
|
||||
systemctl daemon-reload
|
||||
systemctl enable mongodb
|
||||
fi
|
||||
systemctl start mongodb
|
||||
1)
|
||||
echo "Please enter db_url"
|
||||
echo "You can get it here -> https://mongodb.com/atlas"
|
||||
read -r -p "> " db_url
|
||||
db_name=Moon_Userbot
|
||||
db_type=mongodb
|
||||
;;
|
||||
2)
|
||||
if systemctl status mongodb; then
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add -
|
||||
source /etc/os-release
|
||||
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${UBUNTU_CODENAME}/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list
|
||||
apt update
|
||||
apt install mongodb -y
|
||||
systemctl daemon-reload
|
||||
systemctl enable mongodb
|
||||
fi
|
||||
systemctl start mongodb
|
||||
|
||||
db_url = mongodb://localhost:27017
|
||||
db_name = Moon_Userbot
|
||||
db_type = mongodb
|
||||
;;
|
||||
*)
|
||||
db_name = db.sqlite3
|
||||
db_type = sqlite3
|
||||
;;
|
||||
db_url=mongodb://localhost:27017
|
||||
db_name=Moon_Userbot
|
||||
db_type=mongodb
|
||||
;;
|
||||
*)
|
||||
db_name=db.sqlite3
|
||||
db_type=sqlite3
|
||||
;;
|
||||
esac
|
||||
|
||||
cat > .env << EOL
|
||||
API_ID=${api_id}
|
||||
API_HASH=${api_hash}
|
||||
# sqlite/sqlite3 or mongo/mongodb
|
||||
DATABASE_TYPE=${db_type}
|
||||
# file name for sqlite3, database name for mongodb
|
||||
DATABASE_NAME=${db_name}
|
||||
# only for mongodb
|
||||
DATABASE_URL=${db_url}
|
||||
EOL
|
||||
chown -R $SUDO_USER:$SUDO_USER .
|
||||
echo
|
||||
echo "Choose installation type:"
|
||||
echo "[1] PM2"
|
||||
echo "[2] Systemd service"
|
||||
echo "[3] Custom (default)"
|
||||
read -r -p "> " install_type
|
||||
su -c "python3 install.py ${install_type}" $SUDO_USER || exit 3
|
||||
case $install_type in
|
||||
1)
|
||||
if ! command -v pm2; then
|
||||
curl -fsSL https://deb.nodesource.com/setup_17.x | bash
|
||||
apt install nodejs -y
|
||||
npm install pm2 -g
|
||||
su -c "pm2 startup" $SUDO_USER
|
||||
env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u $SUDO_USER --hp /home/$SUDO_USER
|
||||
fi
|
||||
su -c "pm2 start main.py --name Moon --interpreter python3" $SUDO_USER
|
||||
su -c "pm2 save" $SUDO_USER
|
||||
echo
|
||||
echo "============================"
|
||||
echo "Great! Moon-Userbot installed successfully and running now!"
|
||||
echo "Installation type: PM2"
|
||||
echo "Start with: \"pm2 start Moon\""
|
||||
echo "Stop with: \"pm2 stop Moon\""
|
||||
echo "Process name: Moon"
|
||||
echo "============================"
|
||||
;;
|
||||
2)
|
||||
cat > /etc/systemd/system/Moon.service << EOL
|
||||
[Unit]
|
||||
Description=Service for Moon Userbot
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=$(which python3) ${PWD}/main.py
|
||||
WorkingDirectory=${PWD}
|
||||
Restart=always
|
||||
User=${SUDO_USER}
|
||||
Group=${SUDO_USER}
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
systemctl daemon-reload
|
||||
systemctl start Moon
|
||||
systemctl enable Moon
|
||||
echo
|
||||
echo "============================"
|
||||
echo "Great! Moon-Userbot installed successfully and running now!"
|
||||
echo "Installation type: Systemd service"
|
||||
echo "Start with: \"sudo systemctl start Moon\""
|
||||
echo "Stop with: \"sudo systemctl stop Moon\""
|
||||
echo "============================"
|
||||
;;
|
||||
*)
|
||||
echo
|
||||
echo "============================"
|
||||
echo "Great! Moon-Userbot installed successfully!"
|
||||
echo "Installation type: Custom"
|
||||
echo "Start with: \"python3 main.py\""
|
||||
echo "============================"
|
||||
;;
|
||||
esac
|
||||
chown -R $SUDO_USER:$SUDO_USER .
|
||||
API_ID=${api_id}
|
||||
API_HASH=${api_hash}
|
||||
# sqlite/sqlite3 or mongo/mongodb
|
||||
DATABASE_TYPE=${db_type}
|
||||
# file name for sqlite3, database name for mongodb
|
||||
DATABASE_NAME=${db_name}
|
||||
# only for mongodb
|
||||
DATABASE_URL=${db_url}
|
||||
EOL
|
||||
|
||||
chown -R $SUDO_USER:$SUDO_USER .
|
||||
|
||||
echo
|
||||
echo "Choose installation type:"
|
||||
echo "[1] PM2"
|
||||
echo "[2] Systemd service"
|
||||
echo "[3] Custom (default)"
|
||||
read -r -p "> " install_type
|
||||
|
||||
su -c "python3 install.py ${install_type}" $SUDO_USER || exit 3
|
||||
|
||||
case $install_type in
|
||||
1)
|
||||
if ! command -v pm2; then
|
||||
curl -fsSL https://deb.nodesource.com/setup_17.x | bash
|
||||
apt install nodejs -y
|
||||
npm install pm2 -g
|
||||
su -c "pm2 startup" $SUDO_USER
|
||||
env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u $SUDO_USER --hp /home/$SUDO_USER
|
||||
fi
|
||||
su -c "pm2 start main.py --name Moon --interpreter python3" $SUDO_USER
|
||||
su -c "pm2 save" $SUDO_USER
|
||||
|
||||
echo
|
||||
echo "============================"
|
||||
echo "Great! Moon-Userbot installed successfully and running now!"
|
||||
echo "Installation type: PM2"
|
||||
echo "Start with: \"pm2 start Moon\""
|
||||
echo "Stop with: \"pm2 stop Moon\""
|
||||
echo "Process name: Moon"
|
||||
echo "============================"
|
||||
;;
|
||||
2)
|
||||
cat > /etc/systemd/system/Moon.service << EOL
|
||||
[Unit]
|
||||
Description=Service for Moon Userbot
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=$(which python3) ${PWD}/main.py
|
||||
WorkingDirectory=${PWD}
|
||||
Restart=always
|
||||
User=${SUDO_USER}
|
||||
Group=${SUDO_USER}
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
systemctl daemon-reload
|
||||
systemctl start Moon
|
||||
systemctl enable Moon
|
||||
|
||||
echo
|
||||
echo "============================"
|
||||
echo "Great! Moon-Userbot installed successfully and running now!"
|
||||
echo "Installation type: Systemd service"
|
||||
echo "Start with: \"sudo systemctl start Moon\""
|
||||
echo "Stop with: \"sudo systemctl stop Moon\""
|
||||
echo "============================"
|
||||
;;
|
||||
*)
|
||||
echo
|
||||
echo "============================"
|
||||
echo "Great! Moon-Userbot installed successfully!"
|
||||
echo "Installation type: Custom"
|
||||
echo "Start with: \"python3 main.py\""
|
||||
echo "============================"
|
||||
;;
|
||||
esac
|
||||
|
||||
chown -R $SUDO_USER:$SUDO_USER .
|
||||
273
main.py
273
main.py
@@ -1,18 +1,18 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it is under the terms of the GNU 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 free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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.
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import sqlite3
|
||||
import subprocess
|
||||
@@ -25,162 +25,135 @@ from importlib import import_module
|
||||
import logging
|
||||
import platform
|
||||
|
||||
logging.basicConfig(level = logging.INFO)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
DeleteAccount.__new__ = None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
script_path = os.path.dirname(os.path.realpath(__file__))
|
||||
if script_path != os.getcwd():
|
||||
os.chdir(script_path)
|
||||
script_path = os.path.dirname(os.path.realpath(__file__))
|
||||
if script_path != os.getcwd():
|
||||
os.chdir(script_path)
|
||||
|
||||
if os.path.exists("./config.ini.old") and not os.path.exists("./.env"):
|
||||
logging.warning("Old config.ini file detected! Converting to .env...")
|
||||
import configparser
|
||||
if os.path.exists("./config.ini.old") and not os.path.exists("./.env"):
|
||||
logging.warning("Old config.ini file detected! Converting to .env...")
|
||||
import configparser
|
||||
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read("./config.ini.old")
|
||||
db_url = parser.get("pyrogram", "db_url")
|
||||
db_name = parser.get("db", "db_name")
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read("./config.ini.old")
|
||||
db_url = parser.get("pyrogram", "db_url")
|
||||
db_name = parser.get("db", "db_name")
|
||||
|
||||
with open(".env.dist") as f:
|
||||
env_text = f.read().format(
|
||||
db_url = db_url,
|
||||
db_name = db_name,
|
||||
db_type = "mongodb",
|
||||
)
|
||||
with open(".env.dist") as f:
|
||||
env_text = f.read().format(
|
||||
db_url=db_url,
|
||||
db_name=db_name,
|
||||
db_type="mongodb",
|
||||
)
|
||||
|
||||
with open(".env", "w") as f:
|
||||
f.write(env_text)
|
||||
with open(".env", "w") as f:
|
||||
f.write(env_text)
|
||||
|
||||
os.remove("./config.ini.old")
|
||||
os.remove("./config.ini.old")
|
||||
|
||||
logging.warning("Old config file has been successfully converted")
|
||||
logging.warning("Old config file has been successfully converted")
|
||||
|
||||
from utils.db import db
|
||||
from utils.misc import gitrepo, userbot_version
|
||||
from utils.scripts import restart
|
||||
from utils import config
|
||||
from utils.db import db
|
||||
from utils.misc import gitrepo, userbot_version
|
||||
from utils.scripts import restart
|
||||
from utils import config
|
||||
|
||||
app = Client(
|
||||
"my_account",
|
||||
api_id = config.api_id,
|
||||
api_hash = config.api_hash,
|
||||
hide_password = True,
|
||||
workdir = script_path,
|
||||
app_version = userbot_version,
|
||||
device_model = f"Moon-Userbot @ {
|
||||
gitrepo.head.commit.hexsha[:7]}",
|
||||
system_version = platform.version() + " " + platform.machine(),
|
||||
sleep_threshold = 30,
|
||||
test_mode = config.test_server,
|
||||
parse_mode = "html",
|
||||
)
|
||||
app = Client(
|
||||
"my_account",
|
||||
api_id=config.api_id,
|
||||
api_hash=config.api_hash,
|
||||
hide_password=True,
|
||||
workdir=script_path,
|
||||
app_version=userbot_version,
|
||||
device_model=f"Moon-Userbot @ {gitrepo.head.commit.hexsha[:7]}",
|
||||
system_version=platform.version() + " " + platform.machine(),
|
||||
sleep_threshold=30,
|
||||
test_mode=config.test_server,
|
||||
parse_mode="html",
|
||||
)
|
||||
|
||||
try:
|
||||
app.start()
|
||||
except sqlite3.OperationalError as e:
|
||||
if str(e) == "database is locked" and os.name == "posix":
|
||||
logging.warning(
|
||||
"Session file is locked. Trying to kill blocking process..."
|
||||
)
|
||||
subprocess.run(["fuser", "-k", "my_account.session"])
|
||||
restart()
|
||||
raise
|
||||
except (errors.NotAcceptable, errors.Unauthorized) as e:
|
||||
logging.error(
|
||||
f" {
|
||||
e.__class__.__name__
|
||||
}: {
|
||||
e
|
||||
}\n"
|
||||
f"Moving session file to my_account.session-old..."
|
||||
)
|
||||
os.rename("./my_account.session", "./my_account.session-old")
|
||||
restart()
|
||||
try:
|
||||
app.start()
|
||||
except sqlite3.OperationalError as e:
|
||||
if str(e) == "database is locked" and os.name == "posix":
|
||||
logging.warning(
|
||||
"Session file is locked. Trying to kill blocking process..."
|
||||
)
|
||||
subprocess.run(["fuser", "-k", "my_account.session"])
|
||||
restart()
|
||||
raise
|
||||
except (errors.NotAcceptable, errors.Unauthorized) as e:
|
||||
logging.error(
|
||||
f"{e.__class__.__name__}: {e}\n"
|
||||
f"Moving session file to my_account.session-old..."
|
||||
)
|
||||
os.rename("./my_account.session", "./my_account.session-old")
|
||||
restart()
|
||||
|
||||
success_handlers = 0
|
||||
failed_handlers = 0
|
||||
success_modules = 0
|
||||
failed_modules = 0
|
||||
success_handlers = 0
|
||||
failed_handlers = 0
|
||||
success_modules = 0
|
||||
failed_modules = 0
|
||||
|
||||
for path in sorted((Path("modules")).rglob("*.py")):
|
||||
module_path = ".".join(path.parent.parts + (path.stem,))
|
||||
try:
|
||||
module = import_module(module_path)
|
||||
for name, obj in vars(module).items():
|
||||
# defaulting to [] if obj isn't a function-handler
|
||||
for handler, group in getattr(obj, "handlers", []):
|
||||
try:
|
||||
app.add_handler(handler, group)
|
||||
success_handlers += 1
|
||||
except Exception as e:
|
||||
failed_handlers += 1
|
||||
logging.warning(
|
||||
f"Can't add {
|
||||
module_path
|
||||
}. {
|
||||
name
|
||||
}. {
|
||||
handler.__name__
|
||||
}: {
|
||||
e.__class__.__name__
|
||||
}: {
|
||||
e
|
||||
}"
|
||||
)
|
||||
except Exception as e:
|
||||
logging.warning(
|
||||
f"Can't import module {
|
||||
module_path
|
||||
}: {
|
||||
e.__class__.__name__
|
||||
}: {
|
||||
e
|
||||
}"
|
||||
)
|
||||
failed_modules += 1
|
||||
else :
|
||||
success_modules += 1
|
||||
for path in sorted((Path("modules")).rglob("*.py")):
|
||||
module_path = ".".join(path.parent.parts + (path.stem,))
|
||||
try:
|
||||
module = import_module(module_path)
|
||||
for name, obj in vars(module).items():
|
||||
# defaulting to [] if obj isn't a function-handler
|
||||
for handler, group in getattr(obj, "handlers", []):
|
||||
try:
|
||||
app.add_handler(handler, group)
|
||||
success_handlers += 1
|
||||
except Exception as e:
|
||||
failed_handlers += 1
|
||||
logging.warning(
|
||||
f"Can't add {module_path}.{name}.{handler.__name__}: {e.__class__.__name__}: {e}"
|
||||
)
|
||||
except Exception as e:
|
||||
logging.warning(
|
||||
f"Can't import module {module_path}: {e.__class__.__name__}: {e}"
|
||||
)
|
||||
failed_modules += 1
|
||||
else:
|
||||
success_modules += 1
|
||||
|
||||
logging.info(
|
||||
f"Imported {
|
||||
success_handlers
|
||||
} handlers from {
|
||||
success_modules
|
||||
} modules."
|
||||
)
|
||||
if failed_modules:
|
||||
logging.warning(f"Failed to import {
|
||||
failed_modules
|
||||
} modules")
|
||||
if failed_handlers:
|
||||
logging.warning(f"Failed to add {
|
||||
failed_handlers
|
||||
} to handlers")
|
||||
logging.info(
|
||||
f"Imported {success_handlers} handlers from {success_modules} modules."
|
||||
)
|
||||
if failed_modules:
|
||||
logging.warning(f"Failed to import {failed_modules} modules")
|
||||
if failed_handlers:
|
||||
logging.warning(f"Failed to add {failed_handlers} to handlers")
|
||||
|
||||
if len(sys.argv) == 4:
|
||||
restart_type = sys.argv[3]
|
||||
if restart_type == "1":
|
||||
text = "<b>Update process completed!</b>"
|
||||
else :
|
||||
text = "<b>Restart completed!</b>"
|
||||
try:
|
||||
app.send_message(
|
||||
chat_id = sys.argv[1], text = text, reply_to_message_id = int(sys.argv[2])
|
||||
)
|
||||
except errors.RPCError:
|
||||
app.send_message(chat_id = sys.argv[1], text = text)
|
||||
if len(sys.argv) == 4:
|
||||
restart_type = sys.argv[3]
|
||||
if restart_type == "1":
|
||||
text = "<b>Update process completed!</b>"
|
||||
else:
|
||||
text = "<b>Restart completed!</b>"
|
||||
try:
|
||||
app.send_message(
|
||||
chat_id=sys.argv[1], text=text, reply_to_message_id=int(
|
||||
sys.argv[2])
|
||||
)
|
||||
except errors.RPCError:
|
||||
app.send_message(chat_id=sys.argv[1], text=text)
|
||||
|
||||
# required for sessionkiller module
|
||||
if db.get("core.sessionkiller", "enabled", False):
|
||||
db.set(
|
||||
"core.sessionkiller",
|
||||
"auths_hashes",
|
||||
[auth.hash for auth in app.send(GetAuthorizations()).authorizations],
|
||||
)
|
||||
# required for sessionkiller module
|
||||
if db.get("core.sessionkiller", "enabled", False):
|
||||
db.set(
|
||||
"core.sessionkiller",
|
||||
"auths_hashes",
|
||||
[auth.hash for auth in app.send(
|
||||
GetAuthorizations()).authorizations],
|
||||
)
|
||||
|
||||
logging.info("Moon-Userbot started!")
|
||||
logging.info("Moon-Userbot started!")
|
||||
|
||||
idle()
|
||||
idle()
|
||||
|
||||
2523
modules/admintool.py
2523
modules/admintool.py
File diff suppressed because it is too large
Load Diff
@@ -1,129 +1,129 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
from html import escape as t
|
||||
from time import perf_counter
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.errors.exceptions.flood_420 import FloodWait
|
||||
from pyrogram.raw.functions.messages.get_all_chats import GetAllChats
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
from utils.scripts import format_exc
|
||||
|
||||
|
||||
@Client.on_message(filters.command("admcount", prefix) & filters.me)
|
||||
async def admcount(client: Client, message: Message):
|
||||
await message.edit("<b>Retrieving information... (it'll take some time)</b>")
|
||||
|
||||
start = perf_counter()
|
||||
try:
|
||||
response = await client.send(GetAllChats(except_ids=[]))
|
||||
chats = response["chats"]
|
||||
|
||||
adminned_chats = 0
|
||||
owned_chats = 0
|
||||
owned_usernamed_chats = 0
|
||||
|
||||
for chat in chats:
|
||||
if getattr(chat, "migrated_to", None):
|
||||
continue
|
||||
if chat.creator and getattr(chat, "username", None):
|
||||
owned_usernamed_chats += 1
|
||||
elif chat.creator:
|
||||
owned_chats += 1
|
||||
elif getattr(chat, "admin_rights", None):
|
||||
adminned_chats += 1
|
||||
except Exception as e:
|
||||
await message.edit(format_exc(e))
|
||||
return
|
||||
|
||||
stop = perf_counter()
|
||||
|
||||
await message.edit(
|
||||
f"<b><u>Total:</u></b> {adminned_chats + owned_chats + owned_usernamed_chats}"
|
||||
f"\n<b><u>Adminned chats:</u></b> {adminned_chats}\n"
|
||||
f"<b><u>Owned chats:</u></b> {owned_chats}\n"
|
||||
f"<b><u>Owned chats with username:</u></b> {owned_usernamed_chats}\n\n"
|
||||
f"Done at {round(stop - start, 3)} seconds.\n\n"
|
||||
f"<b>Get full list: </b><code>{prefix}admlist</code>"
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command("admlist", prefix) & filters.me)
|
||||
async def admlist(client: Client, message: Message):
|
||||
await message.edit("<b>Retrieving information... (it'll take some time)</b>")
|
||||
|
||||
start = perf_counter()
|
||||
try:
|
||||
response = await client.send(GetAllChats(except_ids=[]))
|
||||
chats = response["chats"]
|
||||
|
||||
adminned_chats = []
|
||||
owned_chats = []
|
||||
owned_usernamed_chats = []
|
||||
|
||||
for chat in chats:
|
||||
if getattr(chat, "migrated_to", None) is not None:
|
||||
continue
|
||||
if chat.creator and getattr(chat, "username", None):
|
||||
owned_usernamed_chats.append(chat)
|
||||
elif chat.creator:
|
||||
owned_chats.append(chat)
|
||||
elif getattr(chat, "admin_rights", None):
|
||||
adminned_chats.append(chat)
|
||||
|
||||
text = "<b>Adminned chats:</b>\n"
|
||||
for index, chat in enumerate(adminned_chats):
|
||||
text += (
|
||||
f"{index + 1}. <a href=https://t.me/c/{chat.id}/1>{chat.title}</a>\n"
|
||||
)
|
||||
|
||||
text += "\n<b>Owned chats:</b>\n"
|
||||
for index, chat in enumerate(owned_chats):
|
||||
text += (
|
||||
f"{index + 1}. <a href=https://t.me/c/{chat.id}/1>{chat.title}</a>\n"
|
||||
)
|
||||
|
||||
text += "\n<b>Owned chats with username:</b>\n"
|
||||
for index, chat in enumerate(owned_usernamed_chats):
|
||||
text += (
|
||||
f"{index + 1}. <a href=https://t.me/{chat.username}>{chat.title}</a>\n"
|
||||
)
|
||||
|
||||
stop = perf_counter()
|
||||
total_count = (
|
||||
len(adminned_chats) + len(owned_chats) + len(owned_usernamed_chats)
|
||||
)
|
||||
await message.edit(
|
||||
text + "\n"
|
||||
f"<b><u>Total:</u></b> {total_count}"
|
||||
f"\n<b><u>Adminned chats:</u></b> {len(adminned_chats)}\n"
|
||||
f"<b><u>Owned chats:</u></b> {len(owned_chats)}\n"
|
||||
f"<b><u>Owned chats with username:</u></b> {len(owned_usernamed_chats)}\n\n"
|
||||
f"Done at {round(stop - start, 3)} seconds."
|
||||
)
|
||||
except Exception as e:
|
||||
await message.edit(format_exc(e))
|
||||
return
|
||||
|
||||
|
||||
modules_help["admlist"] = {
|
||||
"admcount": "Get count of adminned and owned chats",
|
||||
"admlist": "Get list of adminned and owned chats",
|
||||
}
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
from html import escape as t
|
||||
from time import perf_counter
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.errors.exceptions.flood_420 import FloodWait
|
||||
from pyrogram.raw.functions.messages.get_all_chats import GetAllChats
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
from utils.scripts import format_exc
|
||||
|
||||
|
||||
@Client.on_message(filters.command("admcount", prefix) & filters.me)
|
||||
async def admcount(client: Client, message: Message):
|
||||
await message.edit("<b>Retrieving information... (it'll take some time)</b>")
|
||||
|
||||
start = perf_counter()
|
||||
try:
|
||||
response = await client.send(GetAllChats(except_ids=[]))
|
||||
chats = response["chats"]
|
||||
|
||||
adminned_chats = 0
|
||||
owned_chats = 0
|
||||
owned_usernamed_chats = 0
|
||||
|
||||
for chat in chats:
|
||||
if getattr(chat, "migrated_to", None):
|
||||
continue
|
||||
if chat.creator and getattr(chat, "username", None):
|
||||
owned_usernamed_chats += 1
|
||||
elif chat.creator:
|
||||
owned_chats += 1
|
||||
elif getattr(chat, "admin_rights", None):
|
||||
adminned_chats += 1
|
||||
except Exception as e:
|
||||
await message.edit(format_exc(e))
|
||||
return
|
||||
|
||||
stop = perf_counter()
|
||||
|
||||
await message.edit(
|
||||
f"<b><u>Total:</u></b> {adminned_chats + owned_chats + owned_usernamed_chats}"
|
||||
f"\n<b><u>Adminned chats:</u></b> {adminned_chats}\n"
|
||||
f"<b><u>Owned chats:</u></b> {owned_chats}\n"
|
||||
f"<b><u>Owned chats with username:</u></b> {owned_usernamed_chats}\n\n"
|
||||
f"Done at {round(stop - start, 3)} seconds.\n\n"
|
||||
f"<b>Get full list: </b><code>{prefix}admlist</code>"
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command("admlist", prefix) & filters.me)
|
||||
async def admlist(client: Client, message: Message):
|
||||
await message.edit("<b>Retrieving information... (it'll take some time)</b>")
|
||||
|
||||
start = perf_counter()
|
||||
try:
|
||||
response = await client.send(GetAllChats(except_ids=[]))
|
||||
chats = response["chats"]
|
||||
|
||||
adminned_chats = []
|
||||
owned_chats = []
|
||||
owned_usernamed_chats = []
|
||||
|
||||
for chat in chats:
|
||||
if getattr(chat, "migrated_to", None) is not None:
|
||||
continue
|
||||
if chat.creator and getattr(chat, "username", None):
|
||||
owned_usernamed_chats.append(chat)
|
||||
elif chat.creator:
|
||||
owned_chats.append(chat)
|
||||
elif getattr(chat, "admin_rights", None):
|
||||
adminned_chats.append(chat)
|
||||
|
||||
text = "<b>Adminned chats:</b>\n"
|
||||
for index, chat in enumerate(adminned_chats):
|
||||
text += (
|
||||
f"{index + 1}. <a href=https://t.me/c/{chat.id}/1>{chat.title}</a>\n"
|
||||
)
|
||||
|
||||
text += "\n<b>Owned chats:</b>\n"
|
||||
for index, chat in enumerate(owned_chats):
|
||||
text += (
|
||||
f"{index + 1}. <a href=https://t.me/c/{chat.id}/1>{chat.title}</a>\n"
|
||||
)
|
||||
|
||||
text += "\n<b>Owned chats with username:</b>\n"
|
||||
for index, chat in enumerate(owned_usernamed_chats):
|
||||
text += (
|
||||
f"{index + 1}. <a href=https://t.me/{chat.username}>{chat.title}</a>\n"
|
||||
)
|
||||
|
||||
stop = perf_counter()
|
||||
total_count = (
|
||||
len(adminned_chats) + len(owned_chats) + len(owned_usernamed_chats)
|
||||
)
|
||||
await message.edit(
|
||||
text + "\n"
|
||||
f"<b><u>Total:</u></b> {total_count}"
|
||||
f"\n<b><u>Adminned chats:</u></b> {len(adminned_chats)}\n"
|
||||
f"<b><u>Owned chats:</u></b> {len(owned_chats)}\n"
|
||||
f"<b><u>Owned chats with username:</u></b> {len(owned_usernamed_chats)}\n\n"
|
||||
f"Done at {round(stop - start, 3)} seconds."
|
||||
)
|
||||
except Exception as e:
|
||||
await message.edit(format_exc(e))
|
||||
return
|
||||
|
||||
|
||||
modules_help["admlist"] = {
|
||||
"admcount": "Get count of adminned and owned chats",
|
||||
"admlist": "Get list of adminned and owned chats",
|
||||
}
|
||||
|
||||
171
modules/afk.py
171
modules/afk.py
@@ -1,85 +1,86 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
|
||||
from pyrogram import Client, filters, types
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
from utils.db import db
|
||||
|
||||
|
||||
# avoid using global variables
|
||||
afk_info = db.get(
|
||||
"core.afk",
|
||||
"afk_info",
|
||||
{
|
||||
"start": 0,
|
||||
"is_afk": False,
|
||||
"reason": "",
|
||||
},
|
||||
)
|
||||
|
||||
is_afk = filters.create(lambda _, __, ___: afk_info["is_afk"])
|
||||
|
||||
|
||||
@Client.on_message(
|
||||
is_afk
|
||||
& (filters.private | filters.mentioned)
|
||||
& ~filters.channel
|
||||
& ~filters.me
|
||||
& ~filters.bot
|
||||
)
|
||||
async def afk_handler(_, message: types.Message):
|
||||
start = datetime.datetime.fromtimestamp(afk_info["start"])
|
||||
end = datetime.datetime.now().replace(microsecond=0)
|
||||
afk_time = end - start
|
||||
await message.reply(
|
||||
f"<b>I'm AFK {afk_time}\n" f"Reason:</b> <i>{afk_info['reason']}</i>"
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command("afk", prefix) & filters.me)
|
||||
async def afk(_, message):
|
||||
if len(message.text.split()) >= 2:
|
||||
reason = message.text.split(" ", maxsplit=1)[1]
|
||||
else:
|
||||
reason = "None"
|
||||
|
||||
afk_info["start"] = int(datetime.datetime.now().timestamp())
|
||||
afk_info["is_afk"] = True
|
||||
afk_info["reason"] = reason
|
||||
|
||||
await message.edit(f"<b>I'm going AFK.\n" f"Reason:</b> <i>{reason}</i>")
|
||||
|
||||
db.set("core.afk", "afk_info", afk_info)
|
||||
|
||||
|
||||
@Client.on_message(filters.command("unafk", prefix) & filters.me)
|
||||
async def unafk(_, message):
|
||||
if afk_info["is_afk"]:
|
||||
start = datetime.datetime.fromtimestamp(afk_info["start"])
|
||||
end = datetime.datetime.now().replace(microsecond=0)
|
||||
afk_time = end - start
|
||||
await message.edit(f"<b>I'm not AFK anymore.\n" f"I was afk {afk_time}</b>")
|
||||
afk_info["is_afk"] = False
|
||||
else:
|
||||
await message.edit("<b>You weren't afk</b>")
|
||||
|
||||
db.set("core.afk", "afk_info", afk_info)
|
||||
|
||||
|
||||
modules_help["afk"] = {"afk [reason]": "Go to afk", "unafk": "Get out of AFK"}
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
|
||||
from pyrogram import Client, filters, types
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
from utils.db import db
|
||||
|
||||
|
||||
# avoid using global variables
|
||||
afk_info = db.get(
|
||||
"core.afk",
|
||||
"afk_info",
|
||||
{
|
||||
"start": 0,
|
||||
"is_afk": False,
|
||||
"reason": "",
|
||||
},
|
||||
)
|
||||
|
||||
is_afk = filters.create(lambda _, __, ___: afk_info["is_afk"])
|
||||
|
||||
|
||||
@Client.on_message(
|
||||
is_afk
|
||||
& (filters.private | filters.mentioned)
|
||||
& ~filters.channel
|
||||
& ~filters.me
|
||||
& ~filters.bot
|
||||
)
|
||||
async def afk_handler(_, message: types.Message):
|
||||
start = datetime.datetime.fromtimestamp(afk_info["start"])
|
||||
end = datetime.datetime.now().replace(microsecond=0)
|
||||
afk_time = end - start
|
||||
await message.reply(
|
||||
f"<b>I'm AFK {afk_time}\n" f"Reason:</b> <i>{afk_info['reason']}</i>"
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command("afk", prefix) & filters.me)
|
||||
async def afk(_, message):
|
||||
if len(message.text.split()) >= 2:
|
||||
reason = message.text.split(" ", maxsplit=1)[1]
|
||||
else:
|
||||
reason = "None"
|
||||
|
||||
afk_info["start"] = int(datetime.datetime.now().timestamp())
|
||||
afk_info["is_afk"] = True
|
||||
afk_info["reason"] = reason
|
||||
|
||||
await message.edit(f"<b>I'm going AFK.\n" f"Reason:</b> <i>{reason}</i>")
|
||||
|
||||
db.set("core.afk", "afk_info", afk_info)
|
||||
|
||||
|
||||
@Client.on_message(filters.command("unafk", prefix) & filters.me)
|
||||
async def unafk(_, message):
|
||||
if afk_info["is_afk"]:
|
||||
start = datetime.datetime.fromtimestamp(afk_info["start"])
|
||||
end = datetime.datetime.now().replace(microsecond=0)
|
||||
afk_time = end - start
|
||||
await message.edit(f"<b>I'm not AFK anymore.\n" f"I was afk {afk_time}</b>")
|
||||
afk_info["is_afk"] = False
|
||||
else:
|
||||
await message.edit("<b>You weren't afk</b>")
|
||||
|
||||
db.set("core.afk", "afk_info", afk_info)
|
||||
|
||||
|
||||
modules_help["afk"] = {
|
||||
"afk [reason]": "Go to afk(note that afk module is not fully completed yet so to unafk it's unable tp detect user messages and disable automatically so you'll have to manually use .unafk command for a while ASAP )", "unafk": "Get out of AFK"}
|
||||
|
||||
@@ -1,125 +1,126 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.raw import functions
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.db import db
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
anti_pm_enabled = filters.create(
|
||||
lambda _, __, ___: db.get("core.antipm", "status", False)
|
||||
)
|
||||
|
||||
in_contact_list = filters.create(lambda _, __, message: message.from_user.is_contact)
|
||||
|
||||
is_support = filters.create(lambda _, __, message: message.chat.is_support)
|
||||
|
||||
|
||||
@Client.on_message(
|
||||
filters.private
|
||||
& ~filters.me
|
||||
& ~filters.bot
|
||||
& ~in_contact_list
|
||||
& ~is_support
|
||||
& anti_pm_enabled
|
||||
)
|
||||
async def anti_pm_handler(client: Client, message: Message):
|
||||
user_info = await client.resolve_peer(message.chat.id)
|
||||
if db.get("core.antipm", "spamrep", False):
|
||||
await client.send(functions.messages.ReportSpam(peer=user_info))
|
||||
if db.get("core.antipm", "block", False):
|
||||
await client.send(functions.contacts.Block(id=user_info))
|
||||
await client.send(
|
||||
functions.messages.DeleteHistory(peer=user_info, max_id=0, revoke=True)
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["antipm", "anti_pm"], prefix) & filters.me)
|
||||
async def anti_pm(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
if db.get("core.antipm", "status", False):
|
||||
await message.edit(
|
||||
"<b>Anti-PM status: enabled\n"
|
||||
f"Disable with: </b><code>{prefix}antipm disable</code>"
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Anti-PM status: disabled\n"
|
||||
f"Enable with: </b><code>{prefix}antipm enable</code>"
|
||||
)
|
||||
elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
|
||||
db.set("core.antipm", "status", True)
|
||||
await message.edit("<b>Anti-PM enabled!</b>")
|
||||
elif message.command[1] in ["disable", "off", "0", "no", "false"]:
|
||||
db.set("core.antipm", "status", False)
|
||||
await message.edit("<b>Anti-PM disabled!</b>")
|
||||
else:
|
||||
await message.edit(f"<b>Usage: {prefix}antipm [enable|disable]</b>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["antipm_report"], prefix) & filters.me)
|
||||
async def antipm_report(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
if db.get("core.antipm", "spamrep", False):
|
||||
await message.edit(
|
||||
"<b>Spam-reporting enabled.\n"
|
||||
f"Disable with: </b><code>{prefix}antipm_report disable</code>"
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Spam-reporting disabled.\n"
|
||||
f"Enable with: </b><code>{prefix}antipm_report enable</code>"
|
||||
)
|
||||
elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
|
||||
db.set("core.antipm", "spamrep", True)
|
||||
await message.edit("<b>Spam-reporting enabled!</b>")
|
||||
elif message.command[1] in ["disable", "off", "0", "no", "false"]:
|
||||
db.set("core.antipm", "spamrep", False)
|
||||
await message.edit("<b>Spam-reporting disabled!</b>")
|
||||
else:
|
||||
await message.edit(f"<b>Usage: {prefix}antipm_report [enable|disable]</b>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["antipm_block"], prefix) & filters.me)
|
||||
async def antipm_block(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
if db.get("core.antipm", "block", False):
|
||||
await message.edit(
|
||||
"<b>Blocking users enabled.\n"
|
||||
f"Disable with: </b><code>{prefix}antipm_block disable</code>"
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Blocking users disabled.\n"
|
||||
f"Enable with: </b><code>{prefix}antipm_block enable</code>"
|
||||
)
|
||||
elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
|
||||
db.set("core.antipm", "block", True)
|
||||
await message.edit("<b>Blocking users enabled!</b>")
|
||||
elif message.command[1] in ["disable", "off", "0", "no", "false"]:
|
||||
db.set("core.antipm", "block", False)
|
||||
await message.edit("<b>Blocking users disabled!</b>")
|
||||
else:
|
||||
await message.edit(f"<b>Usage: {prefix}antipm_block [enable|disable]</b>")
|
||||
|
||||
|
||||
modules_help["antipm"] = {
|
||||
"antipm [enable|disable]*": "When enabled, deletes all messages from users who are not in the contact book",
|
||||
"antipm_report [enable|disable]*": "Enable spam reporting",
|
||||
"antipm_block [enable|disable]*": "Enable user blocking",
|
||||
}
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.raw import functions
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.db import db
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
anti_pm_enabled = filters.create(
|
||||
lambda _, __, ___: db.get("core.antipm", "status", False)
|
||||
)
|
||||
|
||||
in_contact_list = filters.create(
|
||||
lambda _, __, message: message.from_user.is_contact)
|
||||
|
||||
is_support = filters.create(lambda _, __, message: message.chat.is_support)
|
||||
|
||||
|
||||
@Client.on_message(
|
||||
filters.private
|
||||
& ~filters.me
|
||||
& ~filters.bot
|
||||
& ~in_contact_list
|
||||
& ~is_support
|
||||
& anti_pm_enabled
|
||||
)
|
||||
async def anti_pm_handler(client: Client, message: Message):
|
||||
user_info = await client.resolve_peer(message.chat.id)
|
||||
if db.get("core.antipm", "spamrep", False):
|
||||
await client.send(functions.messages.ReportSpam(peer=user_info))
|
||||
if db.get("core.antipm", "block", False):
|
||||
await client.send(functions.contacts.Block(id=user_info))
|
||||
await client.send(
|
||||
functions.messages.DeleteHistory(peer=user_info, max_id=0, revoke=True)
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["antipm", "anti_pm"], prefix) & filters.me)
|
||||
async def anti_pm(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
if db.get("core.antipm", "status", False):
|
||||
await message.edit(
|
||||
"<b>Anti-PM status: enabled\n"
|
||||
f"Disable with: </b><code>{prefix}antipm disable</code>"
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Anti-PM status: disabled\n"
|
||||
f"Enable with: </b><code>{prefix}antipm enable</code>"
|
||||
)
|
||||
elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
|
||||
db.set("core.antipm", "status", True)
|
||||
await message.edit("<b>Anti-PM enabled!</b>")
|
||||
elif message.command[1] in ["disable", "off", "0", "no", "false"]:
|
||||
db.set("core.antipm", "status", False)
|
||||
await message.edit("<b>Anti-PM disabled!</b>")
|
||||
else:
|
||||
await message.edit(f"<b>Usage: {prefix}antipm [enable|disable]</b>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["antipm_report"], prefix) & filters.me)
|
||||
async def antipm_report(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
if db.get("core.antipm", "spamrep", False):
|
||||
await message.edit(
|
||||
"<b>Spam-reporting enabled.\n"
|
||||
f"Disable with: </b><code>{prefix}antipm_report disable</code>"
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Spam-reporting disabled.\n"
|
||||
f"Enable with: </b><code>{prefix}antipm_report enable</code>"
|
||||
)
|
||||
elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
|
||||
db.set("core.antipm", "spamrep", True)
|
||||
await message.edit("<b>Spam-reporting enabled!</b>")
|
||||
elif message.command[1] in ["disable", "off", "0", "no", "false"]:
|
||||
db.set("core.antipm", "spamrep", False)
|
||||
await message.edit("<b>Spam-reporting disabled!</b>")
|
||||
else:
|
||||
await message.edit(f"<b>Usage: {prefix}antipm_report [enable|disable]</b>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["antipm_block"], prefix) & filters.me)
|
||||
async def antipm_block(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
if db.get("core.antipm", "block", False):
|
||||
await message.edit(
|
||||
"<b>Blocking users enabled.\n"
|
||||
f"Disable with: </b><code>{prefix}antipm_block disable</code>"
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Blocking users disabled.\n"
|
||||
f"Enable with: </b><code>{prefix}antipm_block enable</code>"
|
||||
)
|
||||
elif message.command[1] in ["enable", "on", "1", "yes", "true"]:
|
||||
db.set("core.antipm", "block", True)
|
||||
await message.edit("<b>Blocking users enabled!</b>")
|
||||
elif message.command[1] in ["disable", "off", "0", "no", "false"]:
|
||||
db.set("core.antipm", "block", False)
|
||||
await message.edit("<b>Blocking users disabled!</b>")
|
||||
else:
|
||||
await message.edit(f"<b>Usage: {prefix}antipm_block [enable|disable]</b>")
|
||||
|
||||
|
||||
modules_help["antipm"] = {
|
||||
"antipm [enable|disable]*": "When enabled, deletes all messages from users who are not in the contact book",
|
||||
"antipm_report [enable|disable]*": "Enable spam reporting",
|
||||
"antipm_block [enable|disable]*": "Enable user blocking",
|
||||
}
|
||||
|
||||
@@ -1,72 +1,88 @@
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.errors import FloodWait
|
||||
from pyrogram.raw import functions, types
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_@"], prefix) & filters.me)
|
||||
async def solo_mention_clear(client: Client, message: Message):
|
||||
await message.delete()
|
||||
peer = await client.resolve_peer(message.chat.id)
|
||||
request = functions.messages.ReadMentions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_all_@"], prefix) & filters.me)
|
||||
async def global_mention_clear(client: Client, message: Message):
|
||||
request = functions.messages.GetAllChats(except_ids=[])
|
||||
try:
|
||||
result = await client.send(request)
|
||||
except FloodWait as e:
|
||||
await message.edit_text(
|
||||
f"<code>FloodWait received. Wait {e.x} seconds before trying again</code>"
|
||||
)
|
||||
return
|
||||
await message.delete()
|
||||
for chat in result.chats:
|
||||
if type(chat) is types.Chat:
|
||||
peer_id = -chat.id
|
||||
elif type(chat) is types.Channel:
|
||||
peer_id = int(f"-100{chat.id}")
|
||||
peer = await client.resolve_peer(peer_id)
|
||||
request = functions.messages.ReadMentions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_reacts"], prefix) & filters.me)
|
||||
async def solo_reaction_clear(client: Client, message: Message):
|
||||
await message.delete()
|
||||
peer = await client.resolve_peer(message.chat.id)
|
||||
request = functions.messages.ReadReactions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_all_reacts"], prefix) & filters.me)
|
||||
async def global_reaction_clear(client: Client, message: Message):
|
||||
request = functions.messages.GetAllChats(except_ids=[])
|
||||
try:
|
||||
result = await client.send(request)
|
||||
except FloodWait as e:
|
||||
await message.edit_text(
|
||||
f"<code>FloodWait received. Wait {e.x} seconds before trying again</code>"
|
||||
)
|
||||
return
|
||||
await message.delete()
|
||||
for chat in result.chats:
|
||||
if type(chat) is types.Chat:
|
||||
peer_id = -chat.id
|
||||
elif type(chat) is types.Channel:
|
||||
peer_id = int(f"-100{chat.id}")
|
||||
peer = await client.resolve_peer(peer_id)
|
||||
request = functions.messages.ReadReactions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
modules_help["clear_notifs"] = {
|
||||
"clear_@": "clear all mentions in this chat",
|
||||
"clear_all_@": "clear all mentions in all chats",
|
||||
"clear_reacts": "clear all reactions in this chat",
|
||||
"clear_all_reacts": "clear all reactions in all chats (except private chats)",
|
||||
}
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.errors import FloodWait
|
||||
from pyrogram.raw import functions, types
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_@"], prefix) & filters.me)
|
||||
async def solo_mention_clear(client: Client, message: Message):
|
||||
await message.delete()
|
||||
peer = await client.resolve_peer(message.chat.id)
|
||||
request = functions.messages.ReadMentions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_all_@"], prefix) & filters.me)
|
||||
async def global_mention_clear(client: Client, message: Message):
|
||||
request = functions.messages.GetAllChats(except_ids=[])
|
||||
try:
|
||||
result = await client.send(request)
|
||||
except FloodWait as e:
|
||||
await message.edit_text(
|
||||
f"<code>FloodWait received. Wait {e.x} seconds before trying again</code>"
|
||||
)
|
||||
return
|
||||
await message.delete()
|
||||
for chat in result.chats:
|
||||
if type(chat) is types.Chat:
|
||||
peer_id = -chat.id
|
||||
elif type(chat) is types.Channel:
|
||||
peer_id = int(f"-100{chat.id}")
|
||||
peer = await client.resolve_peer(peer_id)
|
||||
request = functions.messages.ReadMentions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_reacts"], prefix) & filters.me)
|
||||
async def solo_reaction_clear(client: Client, message: Message):
|
||||
await message.delete()
|
||||
peer = await client.resolve_peer(message.chat.id)
|
||||
request = functions.messages.ReadReactions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["clear_all_reacts"], prefix) & filters.me)
|
||||
async def global_reaction_clear(client: Client, message: Message):
|
||||
request = functions.messages.GetAllChats(except_ids=[])
|
||||
try:
|
||||
result = await client.send(request)
|
||||
except FloodWait as e:
|
||||
await message.edit_text(
|
||||
f"<code>FloodWait received. Wait {e.x} seconds before trying again</code>"
|
||||
)
|
||||
return
|
||||
await message.delete()
|
||||
for chat in result.chats:
|
||||
if type(chat) is types.Chat:
|
||||
peer_id = -chat.id
|
||||
elif type(chat) is types.Channel:
|
||||
peer_id = int(f"-100{chat.id}")
|
||||
peer = await client.resolve_peer(peer_id)
|
||||
request = functions.messages.ReadReactions(peer=peer)
|
||||
await client.send(request)
|
||||
|
||||
|
||||
modules_help["clear_notifs"] = {
|
||||
"clear_@": "clear all mentions in this chat",
|
||||
"clear_all_@": "clear all mentions in all chats",
|
||||
"clear_reacts": "clear all reactions in this chat",
|
||||
"clear_all_reacts": "clear all reactions in all chats (except private chats)",
|
||||
}
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
|
||||
# if your module has packages from PyPi
|
||||
|
||||
# from utils.scripts import import_library
|
||||
# example_1 = import_library("example_1")
|
||||
# example_2 = import_library("example_2")
|
||||
|
||||
# import_library() will automatically install required library
|
||||
# if it isn't installed
|
||||
|
||||
|
||||
@Client.on_message(filters.command("example_edit", prefix) & filters.me)
|
||||
async def example_edit(client: Client, message: Message):
|
||||
await message.edit("<code>This is an example module</code>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command("example_send", prefix) & filters.me)
|
||||
async def example_send(client: Client, message: Message):
|
||||
await client.send_message(message.chat.id, "<b>This is an example module</b>")
|
||||
|
||||
|
||||
# This adds instructions for your module
|
||||
modules_help["example"] = {
|
||||
"example_send": "example send",
|
||||
"example_edit": "example edit",
|
||||
}
|
||||
|
||||
# modules_help["example"] = { "example_send [text]": "example send" }
|
||||
# | | | |
|
||||
# | | | └─ command description
|
||||
# module_name command_name └─ optional command arguments
|
||||
# (only snake_case) (only snake_case too)
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
|
||||
# if your module has packages from PyPi
|
||||
|
||||
# from utils.scripts import import_library
|
||||
# example_1 = import_library("example_1")
|
||||
# example_2 = import_library("example_2")
|
||||
|
||||
# import_library() will automatically install required library
|
||||
# if it isn't installed
|
||||
|
||||
|
||||
@Client.on_message(filters.command("example_edit", prefix) & filters.me)
|
||||
async def example_edit(client: Client, message: Message):
|
||||
await message.edit("<code>This is an example module</code>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command("example_send", prefix) & filters.me)
|
||||
async def example_send(client: Client, message: Message):
|
||||
await client.send_message(message.chat.id, "<b>This is an example module</b>")
|
||||
|
||||
|
||||
# This adds instructions for your module
|
||||
modules_help["example"] = {
|
||||
"example_send": "example send",
|
||||
"example_edit": "example edit",
|
||||
}
|
||||
|
||||
# modules_help["example"] = { "example_send [text]": "example send" }
|
||||
# | | | |
|
||||
# | | | └─ command description
|
||||
# module_name command_name └─ optional command arguments
|
||||
# (only snake_case) (only snake_case too)
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters, ContinuePropagation, errors
|
||||
from pyrogram.types import (
|
||||
Message,
|
||||
@@ -7,282 +23,256 @@ from pyrogram.types import (
|
||||
InputMediaAudio,
|
||||
)
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
# noinspection PyUnresolvedReferences
|
||||
from utils.misc import modules_help, prefix
|
||||
from utils.scripts import format_exc
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
# noinspection PyUnresolvedReferences
|
||||
from utils.db import db
|
||||
|
||||
|
||||
def get_filters_chat(chat_id):
|
||||
return db.get("core.filters", f" {
|
||||
chat_id
|
||||
}", {})
|
||||
return db.get("core.filters", f"{chat_id}", {})
|
||||
|
||||
|
||||
def set_filters_chat(chat_id, filters_):
|
||||
return db.set("core.filters", f" {
|
||||
chat_id
|
||||
}", filters_)
|
||||
return db.set("core.filters", f"{chat_id}", filters_)
|
||||
|
||||
|
||||
async def contains_filter(_, __, m):
|
||||
return m.text and m.text.lower() in get_filters_chat(m.chat.id).keys()
|
||||
return m.text and m.text.lower() in get_filters_chat(m.chat.id).keys()
|
||||
|
||||
|
||||
contains = filters.create(contains_filter)
|
||||
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
# noinspection PyTypeChecker
|
||||
@Client.on_message(contains)
|
||||
async def filters_main_handler(client: Client, message: Message):
|
||||
value = get_filters_chat(message.chat.id)[message.text.lower()]
|
||||
try:
|
||||
await client.get_messages(int(value["CHAT_ID"]), int(value["MESSAGE_ID"]))
|
||||
except errors.RPCError:
|
||||
raise ContinuePropagation
|
||||
value = get_filters_chat(message.chat.id)[message.text.lower()]
|
||||
try:
|
||||
await client.get_messages(int(value["CHAT_ID"]), int(value["MESSAGE_ID"]))
|
||||
except errors.RPCError:
|
||||
raise ContinuePropagation
|
||||
|
||||
if value.get("MEDIA_GROUP"):
|
||||
messages_grouped = await client.get_media_group(
|
||||
int(value["CHAT_ID"]), int(value["MESSAGE_ID"])
|
||||
)
|
||||
media_grouped_list = []
|
||||
for _ in messages_grouped:
|
||||
if _.photo:
|
||||
if _.caption:
|
||||
media_grouped_list.append(
|
||||
InputMediaPhoto(_.photo.file_id, _.caption.markdown)
|
||||
)
|
||||
else :
|
||||
media_grouped_list.append(InputMediaPhoto(_.photo.file_id))
|
||||
elif _.video:
|
||||
if _.caption:
|
||||
if _.video.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaVideo(
|
||||
_.video.file_id,
|
||||
_.video.thumbs[0].file_id,
|
||||
_.caption.markdown,
|
||||
)
|
||||
)
|
||||
else :
|
||||
media_grouped_list.append(
|
||||
InputMediaVideo(_.video.file_id, _.caption.markdown)
|
||||
)
|
||||
elif _.video.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaVideo(_.video.file_id, _.video.thumbs[0].file_id)
|
||||
)
|
||||
else :
|
||||
media_grouped_list.append(InputMediaVideo(_.video.file_id))
|
||||
elif _.audio:
|
||||
if _.caption:
|
||||
media_grouped_list.append(
|
||||
InputMediaAudio(_.audio.file_id, _.caption.markdown)
|
||||
)
|
||||
else :
|
||||
media_grouped_list.append(InputMediaAudio(_.audio.file_id))
|
||||
elif _.document:
|
||||
if _.caption:
|
||||
if _.document.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(
|
||||
_.document.file_id,
|
||||
_.document.thumbs[0].file_id,
|
||||
_.caption.markdown,
|
||||
)
|
||||
)
|
||||
else :
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(_.document.file_id, _.caption.markdown)
|
||||
)
|
||||
elif _.document.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(
|
||||
_.document.file_id, _.document.thumbs[0].file_id
|
||||
)
|
||||
)
|
||||
else :
|
||||
media_grouped_list.append(InputMediaDocument(_.document.file_id))
|
||||
await client.send_media_group(
|
||||
message.chat.id,
|
||||
media_grouped_list,
|
||||
reply_to_message_id = message.message_id,
|
||||
)
|
||||
else :
|
||||
await client.copy_message(
|
||||
message.chat.id,
|
||||
int(value["CHAT_ID"]),
|
||||
int(value["MESSAGE_ID"]),
|
||||
reply_to_message_id = message.message_id,
|
||||
)
|
||||
raise ContinuePropagation
|
||||
if value.get("MEDIA_GROUP"):
|
||||
messages_grouped = await client.get_media_group(
|
||||
int(value["CHAT_ID"]), int(value["MESSAGE_ID"])
|
||||
)
|
||||
media_grouped_list = []
|
||||
for _ in messages_grouped:
|
||||
if _.photo:
|
||||
if _.caption:
|
||||
media_grouped_list.append(
|
||||
InputMediaPhoto(_.photo.file_id, _.caption.markdown)
|
||||
)
|
||||
else:
|
||||
media_grouped_list.append(InputMediaPhoto(_.photo.file_id))
|
||||
elif _.video:
|
||||
if _.caption:
|
||||
if _.video.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaVideo(
|
||||
_.video.file_id,
|
||||
_.video.thumbs[0].file_id,
|
||||
_.caption.markdown,
|
||||
)
|
||||
)
|
||||
else:
|
||||
media_grouped_list.append(
|
||||
InputMediaVideo(_.video.file_id,
|
||||
_.caption.markdown)
|
||||
)
|
||||
elif _.video.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaVideo(_.video.file_id,
|
||||
_.video.thumbs[0].file_id)
|
||||
)
|
||||
else:
|
||||
media_grouped_list.append(InputMediaVideo(_.video.file_id))
|
||||
elif _.audio:
|
||||
if _.caption:
|
||||
media_grouped_list.append(
|
||||
InputMediaAudio(_.audio.file_id, _.caption.markdown)
|
||||
)
|
||||
else:
|
||||
media_grouped_list.append(InputMediaAudio(_.audio.file_id))
|
||||
elif _.document:
|
||||
if _.caption:
|
||||
if _.document.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(
|
||||
_.document.file_id,
|
||||
_.document.thumbs[0].file_id,
|
||||
_.caption.markdown,
|
||||
)
|
||||
)
|
||||
else:
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(
|
||||
_.document.file_id, _.caption.markdown)
|
||||
)
|
||||
elif _.document.thumbs:
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(
|
||||
_.document.file_id, _.document.thumbs[0].file_id
|
||||
)
|
||||
)
|
||||
else:
|
||||
media_grouped_list.append(
|
||||
InputMediaDocument(_.document.file_id))
|
||||
await client.send_media_group(
|
||||
message.chat.id,
|
||||
media_grouped_list,
|
||||
reply_to_message_id=message.message_id,
|
||||
)
|
||||
else:
|
||||
await client.copy_message(
|
||||
message.chat.id,
|
||||
int(value["CHAT_ID"]),
|
||||
int(value["MESSAGE_ID"]),
|
||||
reply_to_message_id=message.message_id,
|
||||
)
|
||||
raise ContinuePropagation
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["filter"], prefix) & filters.me)
|
||||
async def filter_handler(client: Client, message: Message):
|
||||
try:
|
||||
if len(message.text.split()) < 2:
|
||||
return await message.edit(
|
||||
f"<b>Usage</b>: <code> {
|
||||
prefix
|
||||
}filter [name] (Reply required)</code>"
|
||||
)
|
||||
name = message.text.split(maxsplit = 1)[1].lower()
|
||||
chat_filters = get_filters_chat(message.chat.id)
|
||||
if name in chat_filters.keys():
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code> {
|
||||
name
|
||||
}</code> already exists."
|
||||
)
|
||||
if not message.reply_to_message:
|
||||
return await message.edit("<b>Reply to message</b> please.")
|
||||
try:
|
||||
if len(message.text.split()) < 2:
|
||||
return await message.edit(
|
||||
f"<b>Usage</b>: <code>{prefix}filter [name] (Reply required)</code>"
|
||||
)
|
||||
name = message.text.split(maxsplit=1)[1].lower()
|
||||
chat_filters = get_filters_chat(message.chat.id)
|
||||
if name in chat_filters.keys():
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code>{name}</code> already exists."
|
||||
)
|
||||
if not message.reply_to_message:
|
||||
return await message.edit("<b>Reply to message</b> please.")
|
||||
|
||||
try:
|
||||
chat = await client.get_chat(db.get("core.notes", "chat_id", 0))
|
||||
except (errors.RPCError, ValueError, KeyError):
|
||||
# group is not accessible or isn't created
|
||||
chat = await client.create_supergroup(
|
||||
"Moon_Userbot_Notes_Filters", "Don't touch this group, please"
|
||||
)
|
||||
db.set("core.notes", "chat_id", chat.id)
|
||||
try:
|
||||
chat = await client.get_chat(db.get("core.notes", "chat_id", 0))
|
||||
except (errors.RPCError, ValueError, KeyError):
|
||||
# group is not accessible or isn't created
|
||||
chat = await client.create_supergroup(
|
||||
"Moon_Userbot_Notes_Filters", "Don't touch this group, please"
|
||||
)
|
||||
db.set("core.notes", "chat_id", chat.id)
|
||||
|
||||
chat_id = chat.id
|
||||
chat_id = chat.id
|
||||
|
||||
if message.reply_to_message.media_group_id:
|
||||
get_media_group = [
|
||||
_.message_id
|
||||
for _ in await client.get_media_group(
|
||||
message.chat.id, message.reply_to_message.message_id
|
||||
)
|
||||
]
|
||||
try:
|
||||
message_id = await client.forward_messages(
|
||||
chat_id, message.chat.id, get_media_group
|
||||
)
|
||||
except errors.ChatForwardsRestricted:
|
||||
await message.edit(
|
||||
"<b>Forwarding messages is restricted by chat admins</b>"
|
||||
)
|
||||
return
|
||||
filter_ = {
|
||||
"MESSAGE_ID": str(message_id[1].message_id),
|
||||
"MEDIA_GROUP": True,
|
||||
"CHAT_ID": str(chat_id),
|
||||
} else :
|
||||
try:
|
||||
message_id = await message.reply_to_message.forward(chat_id)
|
||||
except errors.ChatForwardsRestricted:
|
||||
if message.reply_to_message.text:
|
||||
# manual copy
|
||||
message_id = await client.send_message(
|
||||
chat_id, message.reply_to_message.text
|
||||
)
|
||||
else :
|
||||
await message.edit(
|
||||
"<b>Forwarding messages is restricted by chat admins</b>"
|
||||
)
|
||||
return
|
||||
filter_ = {
|
||||
"MEDIA_GROUP": False,
|
||||
"MESSAGE_ID": str(message_id.message_id),
|
||||
"CHAT_ID": str(chat_id),
|
||||
}
|
||||
if message.reply_to_message.media_group_id:
|
||||
get_media_group = [
|
||||
_.message_id
|
||||
for _ in await client.get_media_group(
|
||||
message.chat.id, message.reply_to_message.message_id
|
||||
)
|
||||
]
|
||||
try:
|
||||
message_id = await client.forward_messages(
|
||||
chat_id, message.chat.id, get_media_group
|
||||
)
|
||||
except errors.ChatForwardsRestricted:
|
||||
await message.edit(
|
||||
"<b>Forwarding messages is restricted by chat admins</b>"
|
||||
)
|
||||
return
|
||||
filter_ = {
|
||||
"MESSAGE_ID": str(message_id[1].message_id),
|
||||
"MEDIA_GROUP": True,
|
||||
"CHAT_ID": str(chat_id),
|
||||
}
|
||||
else:
|
||||
try:
|
||||
message_id = await message.reply_to_message.forward(chat_id)
|
||||
except errors.ChatForwardsRestricted:
|
||||
if message.reply_to_message.text:
|
||||
# manual copy
|
||||
message_id = await client.send_message(
|
||||
chat_id, message.reply_to_message.text
|
||||
)
|
||||
else:
|
||||
await message.edit(
|
||||
"<b>Forwarding messages is restricted by chat admins</b>"
|
||||
)
|
||||
return
|
||||
filter_ = {
|
||||
"MEDIA_GROUP": False,
|
||||
"MESSAGE_ID": str(message_id.message_id),
|
||||
"CHAT_ID": str(chat_id),
|
||||
}
|
||||
|
||||
chat_filters.update({
|
||||
name: filter_
|
||||
})
|
||||
chat_filters.update({name: filter_})
|
||||
|
||||
set_filters_chat(message.chat.id, chat_filters)
|
||||
return await message.edit(f"<b>Filter</b> <code> {
|
||||
name
|
||||
}</code> has been added.")
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
set_filters_chat(message.chat.id, chat_filters)
|
||||
return await message.edit(f"<b>Filter</b> <code>{name}</code> has been added.")
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["filters"], prefix) & filters.me)
|
||||
async def filters_handler(client: Client, message: Message):
|
||||
try:
|
||||
text = ""
|
||||
for index, a in enumerate(get_filters_chat(message.chat.id).items(), start = 1):
|
||||
key, item = a
|
||||
key = key.replace("<", "").replace(">", "")
|
||||
text += f" {
|
||||
index
|
||||
}. <code> {
|
||||
key
|
||||
}</code>\n"
|
||||
text = f"<b>Your filters in current chat</b>:\n\n" f" {
|
||||
text
|
||||
}"
|
||||
text = text[:4096]
|
||||
return await message.edit(text)
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
try:
|
||||
text = ""
|
||||
for index, a in enumerate(get_filters_chat(message.chat.id).items(), start=1):
|
||||
key, item = a
|
||||
key = key.replace("<", "").replace(">", "")
|
||||
text += f"{index}. <code>{key}</code>\n"
|
||||
text = f"<b>Your filters in current chat</b>:\n\n" f"{text}"
|
||||
text = text[:4096]
|
||||
return await message.edit(text)
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
|
||||
|
||||
@Client.on_message(
|
||||
filters.command(["delfilter", "filterdel", "fdel"], prefix) & filters.me
|
||||
)
|
||||
async def filter_del_handler(client: Client, message: Message):
|
||||
try:
|
||||
if len(message.text.split()) < 2:
|
||||
return await message.edit(f"<b>Usage</b>: <code> {
|
||||
prefix
|
||||
}fdel [name]</code>")
|
||||
name = message.text.split(maxsplit = 1)[1].lower()
|
||||
chat_filters = get_filters_chat(message.chat.id)
|
||||
if name not in chat_filters.keys():
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code> {
|
||||
name
|
||||
}</code> doesn't exists."
|
||||
)
|
||||
del chat_filters[name]
|
||||
set_filters_chat(message.chat.id, chat_filters)
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code> {
|
||||
name
|
||||
}</code> has been deleted."
|
||||
)
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
try:
|
||||
if len(message.text.split()) < 2:
|
||||
return await message.edit(f"<b>Usage</b>: <code>{prefix}fdel [name]</code>")
|
||||
name = message.text.split(maxsplit=1)[1].lower()
|
||||
chat_filters = get_filters_chat(message.chat.id)
|
||||
if name not in chat_filters.keys():
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code>{name}</code> doesn't exists."
|
||||
)
|
||||
del chat_filters[name]
|
||||
set_filters_chat(message.chat.id, chat_filters)
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code>{name}</code> has been deleted."
|
||||
)
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["fsearch"], prefix) & filters.me)
|
||||
async def filter_search_handler(client: Client, message: Message):
|
||||
try:
|
||||
if len(message.text.split()) < 2:
|
||||
return await message.edit(
|
||||
f"<b>Usage</b>: <code> {
|
||||
prefix
|
||||
}fsearch [name]</code>"
|
||||
)
|
||||
name = message.text.split(maxsplit = 1)[1].lower()
|
||||
chat_filters = get_filters_chat(message.chat.id)
|
||||
if name not in chat_filters.keys():
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code> {
|
||||
name
|
||||
}</code> doesn't exists."
|
||||
)
|
||||
return await message.edit(
|
||||
f"<b>Trigger</b>:\n<code> {
|
||||
name
|
||||
}</code"
|
||||
f">\n<b>Answer</b>:\n {
|
||||
chat_filters[name]}"
|
||||
)
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
try:
|
||||
if len(message.text.split()) < 2:
|
||||
return await message.edit(
|
||||
f"<b>Usage</b>: <code>{prefix}fsearch [name]</code>"
|
||||
)
|
||||
name = message.text.split(maxsplit=1)[1].lower()
|
||||
chat_filters = get_filters_chat(message.chat.id)
|
||||
if name not in chat_filters.keys():
|
||||
return await message.edit(
|
||||
f"<b>Filter</b> <code>{name}</code> doesn't exists."
|
||||
)
|
||||
return await message.edit(
|
||||
f"<b>Trigger</b>:\n<code>{name}</code"
|
||||
f">\n<b>Answer</b>:\n{chat_filters[name]}"
|
||||
)
|
||||
except Exception as e:
|
||||
return await message.edit(format_exc(e))
|
||||
|
||||
|
||||
modules_help["filters"] = {
|
||||
"filter [name]": "Create filter (Reply required)",
|
||||
"filters": "List of all triggers",
|
||||
"fdel [name]": "Delete filter by name",
|
||||
"fsearch [name]": "Info filter by name",
|
||||
}
|
||||
"filter [name]": "Create filter (Reply required)",
|
||||
"filters": "List of all triggers",
|
||||
"fdel [name]": "Delete filter by name",
|
||||
"fsearch [name]": "Info filter by name",
|
||||
}
|
||||
|
||||
147
modules/help.py
147
modules/help.py
@@ -1,18 +1,18 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# 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
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.types import Message
|
||||
@@ -23,83 +23,58 @@ from utils.scripts import format_module_help
|
||||
|
||||
@Client.on_message(filters.command(["help", "h"], prefix) & filters.me)
|
||||
async def help_cmd(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
msg_edited = False
|
||||
text = (
|
||||
"<b>Help for <a href=https://t.me/Moonub_chat>Moon-Userbot</a>\n"
|
||||
f"For more help on how to use a command, type <code> {
|
||||
prefix
|
||||
}help [module]</code>\n\n"
|
||||
"Available Modules:\n"
|
||||
)
|
||||
if len(message.command) == 1:
|
||||
msg_edited = False
|
||||
text = (
|
||||
"<b>Help for <a href=https://t.me/Moonub_chat>Moon-Userbot</a>\n"
|
||||
f"For more help on how to use a command, type <code>{prefix}help [module]</code>\n\n"
|
||||
"Available Modules:\n"
|
||||
)
|
||||
|
||||
for module_name, module_commands in modules_help.items():
|
||||
text += "• {}: {}\n".format(
|
||||
module_name.title(),
|
||||
" ".join(
|
||||
[
|
||||
f"<code> {
|
||||
prefix + cmd_name.split()[0]}</code>"
|
||||
for cmd_name in module_commands.keys()
|
||||
]
|
||||
),
|
||||
)
|
||||
if len(text) >= 2048:
|
||||
text += "</b>"
|
||||
if msg_edited:
|
||||
await message.reply(text, disable_web_page_preview = True)
|
||||
else :
|
||||
await message.edit(text, disable_web_page_preview = True)
|
||||
msg_edited = True
|
||||
text = "<b>"
|
||||
for module_name, module_commands in modules_help.items():
|
||||
text += "• {}: {}\n".format(
|
||||
module_name.title(),
|
||||
" ".join(
|
||||
[
|
||||
f"<code>{prefix + cmd_name.split()[0]}</code>"
|
||||
for cmd_name in module_commands.keys()
|
||||
]
|
||||
),
|
||||
)
|
||||
if len(text) >= 2048:
|
||||
text += "</b>"
|
||||
if msg_edited:
|
||||
await message.reply(text, disable_web_page_preview=True)
|
||||
else:
|
||||
await message.edit(text, disable_web_page_preview=True)
|
||||
msg_edited = True
|
||||
text = "<b>"
|
||||
|
||||
text += f"\nThe number of modules in the userbot: {
|
||||
len(modules_help) / 1
|
||||
}</b>"
|
||||
text += f"\nThe number of modules in the userbot: {len(modules_help) / 1}</b>"
|
||||
|
||||
if msg_edited:
|
||||
await message.reply(text, disable_web_page_preview = True)
|
||||
else :
|
||||
await message.edit(text, disable_web_page_preview = True)
|
||||
elif message.command[1].lower() in modules_help:
|
||||
await message.edit(format_module_help(message.command[1].lower()))
|
||||
else :
|
||||
# TODO: refactor this cringe
|
||||
command_name = message.command[1].lower()
|
||||
for name, commands in modules_help.items():
|
||||
for command in commands.keys():
|
||||
if command.split()[0] == command_name:
|
||||
cmd = command.split(maxsplit = 1)
|
||||
cmd_desc = commands[command]
|
||||
return await message.edit(
|
||||
f"<b>Help for command <code> {
|
||||
prefix
|
||||
} {
|
||||
command_name
|
||||
}</code>\n"
|
||||
f"Module: {
|
||||
name
|
||||
} (<code> {
|
||||
prefix
|
||||
}help {
|
||||
name
|
||||
}</code>)</b>\n\n"
|
||||
f"<code> {
|
||||
prefix
|
||||
} {
|
||||
cmd[0]}</code>"
|
||||
f" {
|
||||
' <code>' + cmd[1] + '</code>' if len(cmd) > 1 else ''
|
||||
}"
|
||||
f" — <i> {
|
||||
cmd_desc
|
||||
}</i>"
|
||||
)
|
||||
await message.edit(f"<b>Module {
|
||||
command_name
|
||||
} not found</b>")
|
||||
if msg_edited:
|
||||
await message.reply(text, disable_web_page_preview=True)
|
||||
else:
|
||||
await message.edit(text, disable_web_page_preview=True)
|
||||
elif message.command[1].lower() in modules_help:
|
||||
await message.edit(format_module_help(message.command[1].lower()))
|
||||
else:
|
||||
# TODO: refactor this cringe
|
||||
command_name = message.command[1].lower()
|
||||
for name, commands in modules_help.items():
|
||||
for command in commands.keys():
|
||||
if command.split()[0] == command_name:
|
||||
cmd = command.split(maxsplit=1)
|
||||
cmd_desc = commands[command]
|
||||
return await message.edit(
|
||||
f"<b>Help for command <code>{prefix}{command_name}</code>\n"
|
||||
f"Module: {name} (<code>{prefix}help {name}</code>)</b>\n\n"
|
||||
f"<code>{prefix}{cmd[0]}</code>"
|
||||
f"{' <code>' + cmd[1] + '</code>' if len(cmd) > 1 else ''}"
|
||||
f" — <i>{cmd_desc}</i>"
|
||||
)
|
||||
await message.edit(f"<b>Module {command_name} not found</b>")
|
||||
|
||||
|
||||
modules_help["help"] = {
|
||||
"help [module/command name]": "Get common/module/command help"
|
||||
}
|
||||
"help [module/command name]": "Get common/module/command help"}
|
||||
|
||||
@@ -1,225 +1,225 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
import requests
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.scripts import restart
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
|
||||
BASE_PATH = os.path.abspath(os.getcwd())
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["modhash", "mh"], prefix) & filters.me)
|
||||
async def get_mod_hash(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
return
|
||||
url = message.command[1].lower()
|
||||
resp = requests.get(url)
|
||||
if not resp.ok:
|
||||
await message.edit(
|
||||
f"<b>Troubleshooting with downloading module <code>{url}</code></b>"
|
||||
)
|
||||
return
|
||||
|
||||
await message.edit(
|
||||
f"<b>Module hash: <code>{hashlib.sha256(resp.content).hexdigest()}</code>\n"
|
||||
f"Link: <code>{url}</code>\nFile: <code>{url.split('/')[-1]}</code></b>"
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["loadmod", "lm"], prefix) & filters.me)
|
||||
async def loadmod(_, message: Message):
|
||||
if (
|
||||
not (
|
||||
message.reply_to_message
|
||||
and message.reply_to_message.document
|
||||
and message.reply_to_message.document.file_name.endswith(".py")
|
||||
)
|
||||
and len(message.command) == 1
|
||||
):
|
||||
await message.edit("<b>Specify module to download</b>")
|
||||
return
|
||||
|
||||
if len(message.command) > 1:
|
||||
url = message.command[1].lower()
|
||||
|
||||
if url.startswith(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
|
||||
):
|
||||
module_name = url.split("/")[-1].split(".")[0]
|
||||
elif "/" not in url and "." not in url:
|
||||
module_name = url.lower()
|
||||
url = f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}.py"
|
||||
else:
|
||||
modules_hashes = requests.get(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
|
||||
).text
|
||||
resp = requests.get(url)
|
||||
|
||||
if not resp.ok:
|
||||
await message.edit(
|
||||
f"<b>Troubleshooting with downloading module <code>{url}</code></b>"
|
||||
)
|
||||
return
|
||||
|
||||
if hashlib.sha256(resp.content).hexdigest() not in modules_hashes:
|
||||
return await message.edit(
|
||||
"<b>Only <a href=https://github.com/The-MoonTg-project/custom_modules/tree/main/modules_hashes.txt>"
|
||||
"verified</a> modules or from the official "
|
||||
"<a href=https://github.com/The-MoonTg-project/custom_modules>"
|
||||
"custom_modules</a> repository are supported!</b>",
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
module_name = url.split("/")[-1].split(".")[0]
|
||||
|
||||
resp = requests.get(url)
|
||||
if not resp.ok:
|
||||
await message.edit(f"<b>Module <code>{module_name}</code> is not found</b>")
|
||||
return
|
||||
|
||||
if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
|
||||
os.mkdir(f"{BASE_PATH}/modules/custom_modules")
|
||||
|
||||
with open(f"./modules/custom_modules/{module_name}.py", "wb") as f:
|
||||
f.write(resp.content)
|
||||
else:
|
||||
file_name = await message.reply_to_message.download()
|
||||
module_name = message.reply_to_message.document.file_name[:-3]
|
||||
|
||||
with open(file_name, "rb") as f:
|
||||
content = f.read()
|
||||
|
||||
modules_hashes = requests.get(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
|
||||
).text
|
||||
|
||||
if hashlib.sha256(content).hexdigest() not in modules_hashes:
|
||||
os.remove(file_name)
|
||||
return await message.edit(
|
||||
"<b>Only <a href=https://github.com/The-MoonTg-project/custom_modules/tree/main/modules_hashes.txt>"
|
||||
"verified</a> modules or from the official "
|
||||
"<a href=https://github.com/The-MoonTg-project/custom_modules>"
|
||||
"custom_modules</a> repository are supported!</b>",
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
else:
|
||||
os.rename(file_name, f"./modules/custom_modules/{module_name}.py")
|
||||
|
||||
await message.edit(f"<b>The module <code>{module_name}</code> is loaded!</b>")
|
||||
restart()
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["unloadmod", "ulm"], prefix) & filters.me)
|
||||
async def unload_mods(_, message: Message):
|
||||
if len(message.command) <= 1:
|
||||
return
|
||||
|
||||
module_name = message.command[1].lower()
|
||||
|
||||
if module_name.startswith(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
|
||||
):
|
||||
module_name = module_name.split("/")[-1].split(".")[0]
|
||||
|
||||
if os.path.exists(f"{BASE_PATH}/modules/custom_modules/{module_name}.py"):
|
||||
os.remove(f"{BASE_PATH}/modules/custom_modules/{module_name}.py")
|
||||
await message.edit(f"<b>The module <code>{module_name}</code> removed!</b>")
|
||||
restart()
|
||||
elif os.path.exists(f"{BASE_PATH}/modules/{module_name}.py"):
|
||||
await message.edit(
|
||||
"<b>It is forbidden to remove built-in modules, it will disrupt the updater</b>"
|
||||
)
|
||||
else:
|
||||
await message.edit(f"<b>Module <code>{module_name}</code> is not found</b>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["loadallmods"], prefix) & filters.me)
|
||||
async def load_all_mods(_, message: Message):
|
||||
await message.edit("<b>Fetching info...</b>")
|
||||
|
||||
if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
|
||||
os.mkdir(f"{BASE_PATH}/modules/custom_modules")
|
||||
|
||||
modules_list = requests.get(
|
||||
"https://api.github.com/repos/The-MoonTg-project/custom_modules/contents/"
|
||||
).json()
|
||||
|
||||
new_modules = {}
|
||||
for module_info in modules_list:
|
||||
if not module_info["name"].endswith(".py"):
|
||||
continue
|
||||
if os.path.exists(f'{BASE_PATH}/modules/custom_modules/{module_info["name"]}'):
|
||||
continue
|
||||
new_modules[module_info["name"][:-3]] = module_info["download_url"]
|
||||
if not new_modules:
|
||||
return await message.edit("<b>All modules already loaded</b>")
|
||||
|
||||
await message.edit(f'<b>Loading new modules: {" ".join(new_modules.keys())}</b>')
|
||||
for name, url in new_modules.items():
|
||||
with open(f"./modules/custom_modules/{name}.py", "wb") as f:
|
||||
f.write(requests.get(url).content)
|
||||
|
||||
await message.edit(
|
||||
f'<b>Successfully loaded new modules: {" ".join(new_modules.keys())}</b>'
|
||||
)
|
||||
restart()
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["updateallmods"], prefix) & filters.me)
|
||||
async def updateallmods(_, message: Message):
|
||||
await message.edit("<b>Updating modules...</b>")
|
||||
|
||||
if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
|
||||
os.mkdir(f"{BASE_PATH}/modules/custom_modules")
|
||||
|
||||
modules_installed = list(os.walk("modules/custom_modules"))[0][2]
|
||||
|
||||
if not modules_installed:
|
||||
return await message.edit("<b>You don't have any modules installed</b>")
|
||||
|
||||
for module_name in modules_installed:
|
||||
if not module_name.endswith(".py"):
|
||||
continue
|
||||
|
||||
resp = requests.get(
|
||||
f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}"
|
||||
)
|
||||
if not resp.ok:
|
||||
modules_installed.remove(module_name)
|
||||
continue
|
||||
|
||||
with open(f"./modules/custom_modules/{module_name}", "wb") as f:
|
||||
f.write(resp.content)
|
||||
|
||||
await message.edit(f"<b>Successfully updated {len(modules_installed)} modules</b>")
|
||||
|
||||
|
||||
modules_help["loader"] = {
|
||||
"loadmod [module_name]*": "Download module.\n"
|
||||
"Only modules from the official custom_modules repository and proven "
|
||||
"modules whose hashes are in modules_hashes.txt are supported",
|
||||
"unloadmod [module_name]*": "Delete module",
|
||||
"modhash [link]*": "Get module hash by link",
|
||||
"loadallmods": "Load all custom modules (use it at your own risk)",
|
||||
"updateallmods": "Update all custom modules",
|
||||
}
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
import requests
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.types import Message
|
||||
|
||||
from utils.scripts import restart
|
||||
from utils.misc import modules_help, prefix
|
||||
|
||||
|
||||
BASE_PATH = os.path.abspath(os.getcwd())
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["modhash", "mh"], prefix) & filters.me)
|
||||
async def get_mod_hash(_, message: Message):
|
||||
if len(message.command) == 1:
|
||||
return
|
||||
url = message.command[1].lower()
|
||||
resp = requests.get(url)
|
||||
if not resp.ok:
|
||||
await message.edit(
|
||||
f"<b>Troubleshooting with downloading module <code>{url}</code></b>"
|
||||
)
|
||||
return
|
||||
|
||||
await message.edit(
|
||||
f"<b>Module hash: <code>{hashlib.sha256(resp.content).hexdigest()}</code>\n"
|
||||
f"Link: <code>{url}</code>\nFile: <code>{url.split('/')[-1]}</code></b>"
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["loadmod", "lm"], prefix) & filters.me)
|
||||
async def loadmod(_, message: Message):
|
||||
if (
|
||||
not (
|
||||
message.reply_to_message
|
||||
and message.reply_to_message.document
|
||||
and message.reply_to_message.document.file_name.endswith(".py")
|
||||
)
|
||||
and len(message.command) == 1
|
||||
):
|
||||
await message.edit("<b>Specify module to download</b>")
|
||||
return
|
||||
|
||||
if len(message.command) > 1:
|
||||
url = message.command[1].lower()
|
||||
|
||||
if url.startswith(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
|
||||
):
|
||||
module_name = url.split("/")[-1].split(".")[0]
|
||||
elif "/" not in url and "." not in url:
|
||||
module_name = url.lower()
|
||||
url = f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}.py"
|
||||
else:
|
||||
modules_hashes = requests.get(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
|
||||
).text
|
||||
resp = requests.get(url)
|
||||
|
||||
if not resp.ok:
|
||||
await message.edit(
|
||||
f"<b>Troubleshooting with downloading module <code>{url}</code></b>"
|
||||
)
|
||||
return
|
||||
|
||||
if hashlib.sha256(resp.content).hexdigest() not in modules_hashes:
|
||||
return await message.edit(
|
||||
"<b>Only <a href=https://github.com/The-MoonTg-project/custom_modules/tree/main/modules_hashes.txt>"
|
||||
"verified</a> modules or from the official "
|
||||
"<a href=https://github.com/The-MoonTg-project/custom_modules>"
|
||||
"custom_modules</a> repository are supported!</b>",
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
module_name = url.split("/")[-1].split(".")[0]
|
||||
|
||||
resp = requests.get(url)
|
||||
if not resp.ok:
|
||||
await message.edit(f"<b>Module <code>{module_name}</code> is not found</b>")
|
||||
return
|
||||
|
||||
if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
|
||||
os.mkdir(f"{BASE_PATH}/modules/custom_modules")
|
||||
|
||||
with open(f"./modules/custom_modules/{module_name}.py", "wb") as f:
|
||||
f.write(resp.content)
|
||||
else:
|
||||
file_name = await message.reply_to_message.download()
|
||||
module_name = message.reply_to_message.document.file_name[:-3]
|
||||
|
||||
with open(file_name, "rb") as f:
|
||||
content = f.read()
|
||||
|
||||
modules_hashes = requests.get(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/modules_hashes.txt"
|
||||
).text
|
||||
|
||||
if hashlib.sha256(content).hexdigest() not in modules_hashes:
|
||||
os.remove(file_name)
|
||||
return await message.edit(
|
||||
"<b>Only <a href=https://github.com/The-MoonTg-project/custom_modules/tree/main/modules_hashes.txt>"
|
||||
"verified</a> modules or from the official "
|
||||
"<a href=https://github.com/The-MoonTg-project/custom_modules>"
|
||||
"custom_modules</a> repository are supported!</b>",
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
else:
|
||||
os.rename(file_name, f"./modules/custom_modules/{module_name}.py")
|
||||
|
||||
await message.edit(f"<b>The module <code>{module_name}</code> is loaded!</b>")
|
||||
restart()
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["unloadmod", "ulm"], prefix) & filters.me)
|
||||
async def unload_mods(_, message: Message):
|
||||
if len(message.command) <= 1:
|
||||
return
|
||||
|
||||
module_name = message.command[1].lower()
|
||||
|
||||
if module_name.startswith(
|
||||
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/"
|
||||
):
|
||||
module_name = module_name.split("/")[-1].split(".")[0]
|
||||
|
||||
if os.path.exists(f"{BASE_PATH}/modules/custom_modules/{module_name}.py"):
|
||||
os.remove(f"{BASE_PATH}/modules/custom_modules/{module_name}.py")
|
||||
await message.edit(f"<b>The module <code>{module_name}</code> removed!</b>")
|
||||
restart()
|
||||
elif os.path.exists(f"{BASE_PATH}/modules/{module_name}.py"):
|
||||
await message.edit(
|
||||
"<b>It is forbidden to remove built-in modules, it will disrupt the updater</b>"
|
||||
)
|
||||
else:
|
||||
await message.edit(f"<b>Module <code>{module_name}</code> is not found</b>")
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["loadallmods"], prefix) & filters.me)
|
||||
async def load_all_mods(_, message: Message):
|
||||
await message.edit("<b>Fetching info...</b>")
|
||||
|
||||
if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
|
||||
os.mkdir(f"{BASE_PATH}/modules/custom_modules")
|
||||
|
||||
modules_list = requests.get(
|
||||
"https://api.github.com/repos/The-MoonTg-project/custom_modules/contents/"
|
||||
).json()
|
||||
|
||||
new_modules = {}
|
||||
for module_info in modules_list:
|
||||
if not module_info["name"].endswith(".py"):
|
||||
continue
|
||||
if os.path.exists(f'{BASE_PATH}/modules/custom_modules/{module_info["name"]}'):
|
||||
continue
|
||||
new_modules[module_info["name"][:-3]] = module_info["download_url"]
|
||||
if not new_modules:
|
||||
return await message.edit("<b>All modules already loaded</b>")
|
||||
|
||||
await message.edit(f'<b>Loading new modules: {" ".join(new_modules.keys())}</b>')
|
||||
for name, url in new_modules.items():
|
||||
with open(f"./modules/custom_modules/{name}.py", "wb") as f:
|
||||
f.write(requests.get(url).content)
|
||||
|
||||
await message.edit(
|
||||
f'<b>Successfully loaded new modules: {" ".join(new_modules.keys())}</b>'
|
||||
)
|
||||
restart()
|
||||
|
||||
|
||||
@Client.on_message(filters.command(["updateallmods"], prefix) & filters.me)
|
||||
async def updateallmods(_, message: Message):
|
||||
await message.edit("<b>Updating modules...</b>")
|
||||
|
||||
if not os.path.exists(f"{BASE_PATH}/modules/custom_modules"):
|
||||
os.mkdir(f"{BASE_PATH}/modules/custom_modules")
|
||||
|
||||
modules_installed = list(os.walk("modules/custom_modules"))[0][2]
|
||||
|
||||
if not modules_installed:
|
||||
return await message.edit("<b>You don't have any modules installed</b>")
|
||||
|
||||
for module_name in modules_installed:
|
||||
if not module_name.endswith(".py"):
|
||||
continue
|
||||
|
||||
resp = requests.get(
|
||||
f"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/{module_name}"
|
||||
)
|
||||
if not resp.ok:
|
||||
modules_installed.remove(module_name)
|
||||
continue
|
||||
|
||||
with open(f"./modules/custom_modules/{module_name}", "wb") as f:
|
||||
f.write(resp.content)
|
||||
|
||||
await message.edit(f"<b>Successfully updated {len(modules_installed)} modules</b>")
|
||||
|
||||
|
||||
modules_help["loader"] = {
|
||||
"loadmod [module_name]*": "Download module.\n"
|
||||
"Only modules from the official custom_modules repository and proven "
|
||||
"modules whose hashes are in modules_hashes.txt are supported",
|
||||
"unloadmod [module_name]*": "Delete module",
|
||||
"modhash [link]*": "Get module hash by link",
|
||||
"loadallmods": "Load all custom modules (use it at your own risk)",
|
||||
"updateallmods": "Update all custom modules",
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ if ! command -v termux-setup-storage; then
|
||||
|
||||
echo
|
||||
echo "Enter API_ID and API_HASH"
|
||||
echo "You can get it here -> https://my.telegram.org/apps"
|
||||
echo "You can get it here -> https://my.telegram.org/"
|
||||
echo "Leave empty to use defaults (please note that default keys significantly increases your ban chances)"
|
||||
read -r -p "API_ID > " api_id
|
||||
|
||||
|
||||
340
utils/db.py
340
utils/db.py
@@ -1,170 +1,170 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
import threading
|
||||
import dns.resolver
|
||||
import pymongo
|
||||
import sqlite3
|
||||
from utils import config
|
||||
|
||||
dns.resolver.default_resolver = dns.resolver.Resolver(configure=False)
|
||||
dns.resolver.default_resolver.nameservers = ["8.8.8.8"]
|
||||
|
||||
|
||||
class Database:
|
||||
def get(self, module: str, variable: str, default=None):
|
||||
"""Get value from database"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set(self, module: str, variable: str, value):
|
||||
"""Set key in database"""
|
||||
raise NotImplementedError
|
||||
|
||||
def remove(self, module: str, variable: str):
|
||||
"""Remove key from database"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_collection(self, module: str) -> dict:
|
||||
"""Get database for selected module"""
|
||||
raise NotImplementedError
|
||||
|
||||
def close(self):
|
||||
"""Close the database"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class MongoDatabase(Database):
|
||||
def __init__(self, url, name):
|
||||
self._client = pymongo.MongoClient(url)
|
||||
self._database = self._client[name]
|
||||
|
||||
def set(self, module: str, variable: str, value):
|
||||
self._database[module].replace_one(
|
||||
{"var": variable}, {"var": variable, "val": value}, upsert=True
|
||||
)
|
||||
|
||||
def get(self, module: str, variable: str, expected_value=None):
|
||||
doc = self._database[module].find_one({"var": variable})
|
||||
return expected_value if doc is None else doc["val"]
|
||||
|
||||
def get_collection(self, module: str):
|
||||
return {item["var"]: item["val"] for item in self._database[module].find()}
|
||||
|
||||
def remove(self, module: str, variable: str):
|
||||
self._database[module].delete_one({"var": variable})
|
||||
|
||||
def close(self):
|
||||
self._client.close()
|
||||
|
||||
|
||||
class SqliteDatabase(Database):
|
||||
def __init__(self, file):
|
||||
self._conn = sqlite3.connect(file, check_same_thread=False)
|
||||
self._conn.row_factory = sqlite3.Row
|
||||
self._cursor = self._conn.cursor()
|
||||
self._lock = threading.Lock()
|
||||
|
||||
@staticmethod
|
||||
def _parse_row(row: sqlite3.Row):
|
||||
if row["type"] == "bool":
|
||||
return row["val"] == "1"
|
||||
elif row["type"] == "int":
|
||||
return int(row["val"])
|
||||
elif row["type"] == "str":
|
||||
return row["val"]
|
||||
else:
|
||||
return json.loads(row["val"])
|
||||
|
||||
def _execute(self, module: str, *args, **kwargs) -> sqlite3.Cursor:
|
||||
self._lock.acquire()
|
||||
try:
|
||||
return self._cursor.execute(*args, **kwargs)
|
||||
except sqlite3.OperationalError as e:
|
||||
if str(e).startswith("no such table"):
|
||||
sql = f"""
|
||||
CREATE TABLE IF NOT EXISTS '{module}' (
|
||||
var TEXT UNIQUE NOT NULL,
|
||||
val TEXT NOT NULL,
|
||||
type TEXT NOT NULL
|
||||
)
|
||||
"""
|
||||
self._cursor.execute(sql)
|
||||
self._conn.commit()
|
||||
return self._cursor.execute(*args, **kwargs)
|
||||
raise e from None
|
||||
finally:
|
||||
self._lock.release()
|
||||
|
||||
def get(self, module: str, variable: str, default=None):
|
||||
sql = f"SELECT * FROM '{module}' WHERE var=:var"
|
||||
cur = self._execute(module, sql, {"tabl": module, "var": variable})
|
||||
|
||||
row = cur.fetchone()
|
||||
if row is None:
|
||||
return default
|
||||
else:
|
||||
return self._parse_row(row)
|
||||
|
||||
def set(self, module: str, variable: str, value) -> bool:
|
||||
sql = f"""
|
||||
INSERT INTO '{module}' VALUES ( :var, :val, :type )
|
||||
ON CONFLICT (var) DO
|
||||
UPDATE SET val=:val, type=:type WHERE var=:var
|
||||
"""
|
||||
|
||||
if isinstance(value, bool):
|
||||
val = "1" if value else "0"
|
||||
typ = "bool"
|
||||
elif isinstance(value, str):
|
||||
val = value
|
||||
typ = "str"
|
||||
elif isinstance(value, int):
|
||||
val = str(value)
|
||||
typ = "int"
|
||||
else:
|
||||
val = json.dumps(value)
|
||||
typ = "json"
|
||||
|
||||
self._execute(module, sql, {"var": variable, "val": val, "type": typ})
|
||||
self._conn.commit()
|
||||
|
||||
return True
|
||||
|
||||
def remove(self, module: str, variable: str):
|
||||
sql = f"DELETE FROM '{module}' WHERE var=:var"
|
||||
self._execute(module, sql, {"var": variable})
|
||||
self._conn.commit()
|
||||
|
||||
def get_collection(self, module: str) -> dict:
|
||||
sql = f"SELECT * FROM '{module}'"
|
||||
cur = self._execute(module, sql)
|
||||
|
||||
collection = {}
|
||||
for row in cur:
|
||||
collection[row["var"]] = self._parse_row(row)
|
||||
|
||||
return collection
|
||||
|
||||
def close(self):
|
||||
self._conn.commit()
|
||||
self._conn.close()
|
||||
|
||||
|
||||
if config.db_type in ["mongo", "mongodb"]:
|
||||
db = MongoDatabase(config.db_url, config.db_name)
|
||||
else:
|
||||
db = SqliteDatabase(config.db_name)
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
import threading
|
||||
import dns.resolver
|
||||
import pymongo
|
||||
import sqlite3
|
||||
from utils import config
|
||||
|
||||
dns.resolver.default_resolver = dns.resolver.Resolver(configure=False)
|
||||
dns.resolver.default_resolver.nameservers = ["8.8.8.8"]
|
||||
|
||||
|
||||
class Database:
|
||||
def get(self, module: str, variable: str, default=None):
|
||||
"""Get value from database"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set(self, module: str, variable: str, value):
|
||||
"""Set key in database"""
|
||||
raise NotImplementedError
|
||||
|
||||
def remove(self, module: str, variable: str):
|
||||
"""Remove key from database"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_collection(self, module: str) -> dict:
|
||||
"""Get database for selected module"""
|
||||
raise NotImplementedError
|
||||
|
||||
def close(self):
|
||||
"""Close the database"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class MongoDatabase(Database):
|
||||
def __init__(self, url, name):
|
||||
self._client = pymongo.MongoClient(url)
|
||||
self._database = self._client[name]
|
||||
|
||||
def set(self, module: str, variable: str, value):
|
||||
self._database[module].replace_one(
|
||||
{"var": variable}, {"var": variable, "val": value}, upsert=True
|
||||
)
|
||||
|
||||
def get(self, module: str, variable: str, expected_value=None):
|
||||
doc = self._database[module].find_one({"var": variable})
|
||||
return expected_value if doc is None else doc["val"]
|
||||
|
||||
def get_collection(self, module: str):
|
||||
return {item["var"]: item["val"] for item in self._database[module].find()}
|
||||
|
||||
def remove(self, module: str, variable: str):
|
||||
self._database[module].delete_one({"var": variable})
|
||||
|
||||
def close(self):
|
||||
self._client.close()
|
||||
|
||||
|
||||
class SqliteDatabase(Database):
|
||||
def __init__(self, file):
|
||||
self._conn = sqlite3.connect(file, check_same_thread=False)
|
||||
self._conn.row_factory = sqlite3.Row
|
||||
self._cursor = self._conn.cursor()
|
||||
self._lock = threading.Lock()
|
||||
|
||||
@staticmethod
|
||||
def _parse_row(row: sqlite3.Row):
|
||||
if row["type"] == "bool":
|
||||
return row["val"] == "1"
|
||||
elif row["type"] == "int":
|
||||
return int(row["val"])
|
||||
elif row["type"] == "str":
|
||||
return row["val"]
|
||||
else:
|
||||
return json.loads(row["val"])
|
||||
|
||||
def _execute(self, module: str, *args, **kwargs) -> sqlite3.Cursor:
|
||||
self._lock.acquire()
|
||||
try:
|
||||
return self._cursor.execute(*args, **kwargs)
|
||||
except sqlite3.OperationalError as e:
|
||||
if str(e).startswith("no such table"):
|
||||
sql = f"""
|
||||
CREATE TABLE IF NOT EXISTS '{module}' (
|
||||
var TEXT UNIQUE NOT NULL,
|
||||
val TEXT NOT NULL,
|
||||
type TEXT NOT NULL
|
||||
)
|
||||
"""
|
||||
self._cursor.execute(sql)
|
||||
self._conn.commit()
|
||||
return self._cursor.execute(*args, **kwargs)
|
||||
raise e from None
|
||||
finally:
|
||||
self._lock.release()
|
||||
|
||||
def get(self, module: str, variable: str, default=None):
|
||||
sql = f"SELECT * FROM '{module}' WHERE var=:var"
|
||||
cur = self._execute(module, sql, {"tabl": module, "var": variable})
|
||||
|
||||
row = cur.fetchone()
|
||||
if row is None:
|
||||
return default
|
||||
else:
|
||||
return self._parse_row(row)
|
||||
|
||||
def set(self, module: str, variable: str, value) -> bool:
|
||||
sql = f"""
|
||||
INSERT INTO '{module}' VALUES ( :var, :val, :type )
|
||||
ON CONFLICT (var) DO
|
||||
UPDATE SET val=:val, type=:type WHERE var=:var
|
||||
"""
|
||||
|
||||
if isinstance(value, bool):
|
||||
val = "1" if value else "0"
|
||||
typ = "bool"
|
||||
elif isinstance(value, str):
|
||||
val = value
|
||||
typ = "str"
|
||||
elif isinstance(value, int):
|
||||
val = str(value)
|
||||
typ = "int"
|
||||
else:
|
||||
val = json.dumps(value)
|
||||
typ = "json"
|
||||
|
||||
self._execute(module, sql, {"var": variable, "val": val, "type": typ})
|
||||
self._conn.commit()
|
||||
|
||||
return True
|
||||
|
||||
def remove(self, module: str, variable: str):
|
||||
sql = f"DELETE FROM '{module}' WHERE var=:var"
|
||||
self._execute(module, sql, {"var": variable})
|
||||
self._conn.commit()
|
||||
|
||||
def get_collection(self, module: str) -> dict:
|
||||
sql = f"SELECT * FROM '{module}'"
|
||||
cur = self._execute(module, sql)
|
||||
|
||||
collection = {}
|
||||
for row in cur:
|
||||
collection[row["var"]] = self._parse_row(row)
|
||||
|
||||
return collection
|
||||
|
||||
def close(self):
|
||||
self._conn.commit()
|
||||
self._conn.close()
|
||||
|
||||
|
||||
if config.db_type in ["mongo", "mongodb"]:
|
||||
db = MongoDatabase(config.db_url, config.db_name)
|
||||
else:
|
||||
db = SqliteDatabase(config.db_name)
|
||||
|
||||
@@ -1,44 +1,45 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from sys import version_info
|
||||
from .db import db
|
||||
from git import Repo
|
||||
|
||||
|
||||
class ModulesHelpDict(dict):
|
||||
def append(self, obj: dict):
|
||||
# convert help from old to new type
|
||||
module_name = list(obj.keys())[0]
|
||||
cmds = obj[module_name]
|
||||
commands = {}
|
||||
for cmd in cmds:
|
||||
cmd_name = list(cmd.keys())[0]
|
||||
cmd_desc = cmd[cmd_name]
|
||||
commands[cmd_name] = cmd_desc
|
||||
self[module_name] = commands
|
||||
|
||||
|
||||
modules_help = ModulesHelpDict()
|
||||
requirements_list = []
|
||||
|
||||
python_version = f"{version_info[0]}.{version_info[1]}.{version_info[2]}"
|
||||
|
||||
prefix = db.get("core.main", "prefix", ".")
|
||||
|
||||
gitrepo = Repo(".")
|
||||
commits_since_tag = list(gitrepo.iter_commits(f"{gitrepo.tags[-1].name}..HEAD"))
|
||||
userbot_version = f"3.1.{len(commits_since_tag)}"
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from sys import version_info
|
||||
from .db import db
|
||||
from git import Repo
|
||||
|
||||
|
||||
class ModulesHelpDict(dict):
|
||||
def append(self, obj: dict):
|
||||
# convert help from old to new type
|
||||
module_name = list(obj.keys())[0]
|
||||
cmds = obj[module_name]
|
||||
commands = {}
|
||||
for cmd in cmds:
|
||||
cmd_name = list(cmd.keys())[0]
|
||||
cmd_desc = cmd[cmd_name]
|
||||
commands[cmd_name] = cmd_desc
|
||||
self[module_name] = commands
|
||||
|
||||
|
||||
modules_help = ModulesHelpDict()
|
||||
requirements_list = []
|
||||
|
||||
python_version = f"{version_info[0]}.{version_info[1]}.{version_info[2]}"
|
||||
|
||||
prefix = db.get("core.main", "prefix", ".")
|
||||
|
||||
gitrepo = Repo(".")
|
||||
commits_since_tag = list(gitrepo.iter_commits(
|
||||
f"{gitrepo.tags[-1].name}..HEAD"))
|
||||
userbot_version = f"3.1.{len(commits_since_tag)}"
|
||||
|
||||
246
utils/scripts.py
246
utils/scripts.py
@@ -1,18 +1,18 @@
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
# Moon-Userbot - telegram userbot
|
||||
# Copyright (C) 2020-present Moon Userbot Organization
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# 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
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
@@ -28,173 +28,137 @@ from .misc import modules_help, prefix, requirements_list
|
||||
|
||||
|
||||
def text(message: types.Message):
|
||||
return message.text if message.text else message.caption
|
||||
return message.text if message.text else message.caption
|
||||
|
||||
|
||||
def restart():
|
||||
os.execvp(sys.executable, [sys.executable, "main.py"])
|
||||
os.execvp(sys.executable, [sys.executable, "main.py"])
|
||||
|
||||
|
||||
def format_exc(e: Exception, hint: str = None):
|
||||
traceback.print_exc()
|
||||
if isinstance(e, errors.RPCError):
|
||||
return (
|
||||
f"<b>Telegram API error!</b>\n"
|
||||
f"<code>[ {
|
||||
e.CODE
|
||||
} {
|
||||
e.ID or e.NAME
|
||||
}] - {
|
||||
e.MESSAGE
|
||||
}</code>"
|
||||
)
|
||||
else :
|
||||
if hint:
|
||||
hint_text = f"\n\n<b>Hint: {
|
||||
hint
|
||||
}</b>"
|
||||
else :
|
||||
hint_text = ""
|
||||
return (
|
||||
f"<b>Error!</b>\n" f"<code> {
|
||||
e.__class__.__name__
|
||||
}: {
|
||||
e
|
||||
}</code>" + hint_text
|
||||
)
|
||||
traceback.print_exc()
|
||||
if isinstance(e, errors.RPCError):
|
||||
return (
|
||||
f"<b>Telegram API error!</b>\n"
|
||||
f"<code>[{e.CODE} {e.ID or e.NAME}] - {e.MESSAGE}</code>"
|
||||
)
|
||||
else:
|
||||
if hint:
|
||||
hint_text = f"\n\n<b>Hint: {hint}</b>"
|
||||
else:
|
||||
hint_text = ""
|
||||
return (
|
||||
f"<b>Error!</b>\n" f"<code>{e.__class__.__name__}: {e}</code>" + hint_text
|
||||
)
|
||||
|
||||
|
||||
def with_reply(func):
|
||||
async def wrapped(client: Client, message: types.Message):
|
||||
if not message.reply_to_message:
|
||||
await message.edit("<b>Reply to message is required</b>")
|
||||
else :
|
||||
return await func(client, message)
|
||||
async def wrapped(client: Client, message: types.Message):
|
||||
if not message.reply_to_message:
|
||||
await message.edit("<b>Reply to message is required</b>")
|
||||
else:
|
||||
return await func(client, message)
|
||||
|
||||
return wrapped
|
||||
return wrapped
|
||||
|
||||
|
||||
async def interact_with(message: types.Message) -> types.Message:
|
||||
"""
|
||||
Check history with bot and return bot's response
|
||||
Example:
|
||||
.. code-block:: python
|
||||
bot_msg = await interact_with(await bot.send_message("@BotFather", "/start"))
|
||||
:param message: already sent message to bot
|
||||
:return: bot's response
|
||||
"""
|
||||
"""
|
||||
Check history with bot and return bot's response
|
||||
Example:
|
||||
.. code-block:: python
|
||||
bot_msg = await interact_with(await bot.send_message("@BotFather", "/start"))
|
||||
:param message: already sent message to bot
|
||||
:return: bot's response
|
||||
"""
|
||||
|
||||
await asyncio.sleep(1)
|
||||
# noinspection PyProtectedMember
|
||||
response = await message._client.get_history(message.chat.id, limit = 1)
|
||||
seconds_waiting = 0
|
||||
await asyncio.sleep(1)
|
||||
# noinspection PyProtectedMember
|
||||
response = await message._client.get_history(message.chat.id, limit=1)
|
||||
seconds_waiting = 0
|
||||
|
||||
while response[0].from_user.is_self:
|
||||
seconds_waiting += 1
|
||||
if seconds_waiting >= 5:
|
||||
raise RuntimeError("bot didn't answer in 5 seconds")
|
||||
while response[0].from_user.is_self:
|
||||
seconds_waiting += 1
|
||||
if seconds_waiting >= 5:
|
||||
raise RuntimeError("bot didn't answer in 5 seconds")
|
||||
|
||||
await asyncio.sleep(1)
|
||||
# noinspection PyProtectedMember
|
||||
response = await message._client.get_history(message.chat.id, limit = 1)
|
||||
await asyncio.sleep(1)
|
||||
# noinspection PyProtectedMember
|
||||
response = await message._client.get_history(message.chat.id, limit=1)
|
||||
|
||||
interact_with_to_delete.append(message.message_id)
|
||||
interact_with_to_delete.append(response[0].message_id)
|
||||
interact_with_to_delete.append(message.message_id)
|
||||
interact_with_to_delete.append(response[0].message_id)
|
||||
|
||||
return response[0]
|
||||
return response[0]
|
||||
|
||||
|
||||
interact_with_to_delete = []
|
||||
|
||||
|
||||
def format_module_help(module_name: str):
|
||||
commands = modules_help[module_name]
|
||||
commands = modules_help[module_name]
|
||||
|
||||
help_text = f"<b>Help for | {
|
||||
module_name
|
||||
}|\n\nUsage:</b>\n"
|
||||
help_text = f"<b>Help for |{module_name}|\n\nUsage:</b>\n"
|
||||
|
||||
for command, desc in commands.items():
|
||||
cmd = command.split(maxsplit = 1)
|
||||
args = " <code>" + cmd[1] + "</code>" if len(cmd) > 1 else ""
|
||||
help_text += f"<code> {
|
||||
prefix
|
||||
} {
|
||||
cmd[0]}</code> {
|
||||
args
|
||||
} — <i> {
|
||||
desc
|
||||
}</i>\n"
|
||||
for command, desc in commands.items():
|
||||
cmd = command.split(maxsplit=1)
|
||||
args = " <code>" + cmd[1] + "</code>" if len(cmd) > 1 else ""
|
||||
help_text += f"<code>{prefix}{cmd[0]}</code>{args} — <i>{desc}</i>\n"
|
||||
|
||||
return help_text
|
||||
return help_text
|
||||
|
||||
|
||||
def format_small_module_help(module_name: str):
|
||||
commands = modules_help[module_name]
|
||||
commands = modules_help[module_name]
|
||||
|
||||
help_text = f"<b>Help for | {
|
||||
module_name
|
||||
}|\n\nCommands list:\n"
|
||||
for command, desc in commands.items():
|
||||
cmd = command.split(maxsplit = 1)
|
||||
args = " <code>" + cmd[1] + "</code>" if len(cmd) > 1 else ""
|
||||
help_text += f"<code> {
|
||||
prefix
|
||||
} {
|
||||
cmd[0]}</code> {
|
||||
args
|
||||
}\n"
|
||||
help_text += f"\nGet full usage: <code> {
|
||||
prefix
|
||||
}help {
|
||||
module_name
|
||||
}</code></b>"
|
||||
help_text = f"<b>Help for |{module_name}|\n\nCommands list:\n"
|
||||
for command, desc in commands.items():
|
||||
cmd = command.split(maxsplit=1)
|
||||
args = " <code>" + cmd[1] + "</code>" if len(cmd) > 1 else ""
|
||||
help_text += f"<code>{prefix}{cmd[0]}</code>{args}\n"
|
||||
help_text += f"\nGet full usage: <code>{prefix}help {module_name}</code></b>"
|
||||
|
||||
return help_text
|
||||
return help_text
|
||||
|
||||
|
||||
def import_library(library_name: str, package_name: str = None):
|
||||
"""
|
||||
Loads a library, or installs it in ImportError case
|
||||
:param library_name: library name (import example...)
|
||||
:param package_name: package name in PyPi (pip install example)
|
||||
:return: loaded module
|
||||
"""
|
||||
if package_name is None:
|
||||
package_name = library_name
|
||||
requirements_list.append(package_name)
|
||||
"""
|
||||
Loads a library, or installs it in ImportError case
|
||||
:param library_name: library name (import example...)
|
||||
:param package_name: package name in PyPi (pip install example)
|
||||
:return: loaded module
|
||||
"""
|
||||
if package_name is None:
|
||||
package_name = library_name
|
||||
requirements_list.append(package_name)
|
||||
|
||||
try:
|
||||
return importlib.import_module(library_name)
|
||||
except ImportError:
|
||||
completed = subprocess.run(["python3", "-m", "pip", "install", package_name])
|
||||
if completed.returncode != 0:
|
||||
raise AssertionError(
|
||||
f"Failed to install library {
|
||||
package_name
|
||||
} (pip exited with code {
|
||||
completed.returncode
|
||||
})"
|
||||
)
|
||||
return importlib.import_module(library_name)
|
||||
try:
|
||||
return importlib.import_module(library_name)
|
||||
except ImportError:
|
||||
completed = subprocess.run(
|
||||
["python3", "-m", "pip", "install", package_name])
|
||||
if completed.returncode != 0:
|
||||
raise AssertionError(
|
||||
f"Failed to install library {package_name} (pip exited with code {completed.returncode})"
|
||||
)
|
||||
return importlib.import_module(library_name)
|
||||
|
||||
|
||||
def resize_image(input_img, output = None, img_type = "PNG"):
|
||||
if output is None:
|
||||
output = BytesIO()
|
||||
output.name = f"sticker. {
|
||||
img_type.lower()}"
|
||||
def resize_image(input_img, output=None, img_type="PNG"):
|
||||
if output is None:
|
||||
output = BytesIO()
|
||||
output.name = f"sticker.{img_type.lower()}"
|
||||
|
||||
with Image.open(input_img) as img:
|
||||
# We used to use thumbnail(size) here, but it returns with a *max* dimension of 512,512
|
||||
# rather than making one side exactly 512 so we have to calculate dimensions manually :(
|
||||
if img.width == img.height:
|
||||
size = (512, 512)
|
||||
elif img.width < img.height:
|
||||
size = (max(512 * img.width // img.height, 1), 512)
|
||||
else :
|
||||
size = (512, max(512 * img.height // img.width, 1))
|
||||
with Image.open(input_img) as img:
|
||||
# We used to use thumbnail(size) here, but it returns with a *max* dimension of 512,512
|
||||
# rather than making one side exactly 512 so we have to calculate dimensions manually :(
|
||||
if img.width == img.height:
|
||||
size = (512, 512)
|
||||
elif img.width < img.height:
|
||||
size = (max(512 * img.width // img.height, 1), 512)
|
||||
else:
|
||||
size = (512, max(512 * img.height // img.width, 1))
|
||||
|
||||
img.resize(size).save(output, img_type)
|
||||
img.resize(size).save(output, img_type)
|
||||
|
||||
return output
|
||||
return output
|
||||
|
||||
Reference in New Issue
Block a user