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