- Added sudo using database
NOTE: redeploy recommended to generating database, or you can go to your herokuapp > resources > add-ons > then serach Heroku Postgres > hit Submit Order Form, then copy your database url from DATABASE_URL > Heroku config vars
- mirror: Fix for uploading telegram file_name of None type
- gdriveTools: Fix infinite loop when hitting rate limits

Co-authored-by: Sreeraj V R <SVR666@users.noreply.github.com>
Co-authored-by: Gautam Kumar <gautamajay52@gmail.com>
Co-authored-by: KenHV <yo@kenharris.xyz>
This commit is contained in:
Hafitz Setya 2021-05-17 15:36:46 +07:00 committed by GitHub
parent 9d969f3ab6
commit 6df4486ca5
Signed by untrusted user: GitHub
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 359 additions and 79 deletions

View File

@ -7,11 +7,11 @@ This is a Telegram bot writen in Python for mirroring files on the Internet to o
## Additional Features
- Mirroring Uptobox.com links to Google Drive (Uptobox account must be premium)
- Sudo support (DWYOR, Sudo User can restart your bot and delete your Drive file)
- Get detailed info about replied media
- Nyaa.si and Sukebei Torrent search
- Speedtest with picture results
- Limiting Torrent size support
- Sudo with database support
- Check Heroku dynos stats
- Custom image support
- Racaty.net support
@ -63,11 +63,56 @@ Install Docker by following the [official Docker docs](https://docs.docker.com/e
```
sudo pacman -S docker python
```
- Install dependencies for running setup scripts:
```
pip3 install -r requirements-cli.txt
```
## Generate Database
<details>
<summary><b>Click here for more details</b></summary>
**1. The easy way**
- Make new Heroku blank app
- Go to your Heroku blank app
- Go to resources
- In Add-ons search **Heroku Postgres**
- Hit **Submit Order Form**
- Copy your Database URL from Heroku Config Vars > **DATABASE_URL**
**2. The hard way**
- Install Postgresql:
```
sudo apt-get update && sudo apt-get install postgresql
```
- Change to the Postgres user:
```
sudo su - postgres
```
- Create a new database user (change YOUR_USER appropriately):
```
createuser -P -s -e YOUR_USER
```
This will be followed by you needing to input your password.
- Create a new database table:
```
createdb -O YOUR_USER YOUR_DB_NAME
```
Change YOUR_USER and YOUR_DB_NAME appropriately.
- Finally:
```
psql YOUR_DB_NAME -h YOUR_HOST YOUR_USER
```
This will allow you to connect to your database via your terminal. By default, YOUR_HOST should be 0.0.0.0:5432.
You should now be able to build your database URL. This will be:
```
sqldbtype://username:pw@hostname:port/db_name
```
Replace sqldbtype with whichever db youre using (eg postgres, mysql, sqllite, etc) repeat for your username, password, hostname (localhost?), port (5432?), and db name.
**NOTE**: If you deploying on Heroku, no need to generate database manually, because it will automatic generate database
</details>
## Setting up config file
<details>
@ -86,8 +131,8 @@ Fill up rest of the fields. Meaning of each fields are discussed below:
- **DOWNLOAD_DIR**: The path to the local folder where the downloads should be downloaded to
- **DOWNLOAD_STATUS_UPDATE_INTERVAL**: A short interval of time in seconds after which the Mirror progress message is updated. (I recommend to keep it `5` seconds at least)
- **OWNER_ID**: The Telegram user ID (not username) of the Owner of the bot
- **SUDO_USER**: (Optional field) Multiple Telegram user ID (not username) separate by space.
- **AUTHORIZED_CHATS**: Fill user_id and chat_id of you want to authorize.
- **DATABASE_URL**: Your Database URL. See [Generate Database](https://github.com/breakdowns/slam-mirrorbot/tree/master#generate-database) to generate database. (**NOTE**: If you deploying on Heroku, no need to generate database manually, because it will automatic generate database)
- **AUTO_DELETE_MESSAGE_DURATION**: Interval of time (in seconds), after which the bot deletes it's message (and command message) which is expected to be viewed instantly. (**Note**: Set to `-1` to never automatically delete messages)
- **IS_TEAM_DRIVE**: (Optional field) Set to `True` if `GDRIVE_FOLDER_ID` is from a Team Drive else `False` or Leave it empty.
- **USE_SERVICE_ACCOUNTS**: (Optional field) (Leave empty if unsure) Whether to use Service Accounts or not. For this to work see [Using service accounts](https://github.com/breakdowns/slam-mirrorbot#generate-service-accounts-what-is-service-account) section below.

View File

@ -38,10 +38,6 @@
"description": "The Telegram User ID of the Owner of the Bot. Get it by using /info in @MissRose_bot.",
"required": true
},
"SUDO_USER": {
"description": "Multiple Telegram user ID (not username) separate by space.",
"required": false
},
"AUTO_DELETE_MESSAGE_DURATION": {
"description": "Interval of time (in seconds), after which the bot deletes it's message (and command message) which is expected to be viewed instantly. Note: Set to -1 to never automatically delete messages.",
"required": true
@ -153,5 +149,10 @@
"description": "Fill your URL if you are using extra buttons.",
"required": false
}
},
"addons": [
{
"plan": "heroku-postgresql"
}
]
}

View File

@ -11,6 +11,9 @@ from dotenv import load_dotenv
from pyrogram import Client
from telegraph import Telegraph
import psycopg2
from psycopg2 import Error
import socket
import faulthandler
faulthandler.enable()
@ -26,6 +29,8 @@ logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s
handlers=[logging.FileHandler('log.txt'), logging.StreamHandler()],
level=logging.INFO)
LOGGER = logging.getLogger(__name__)
load_dotenv('config.env')
Interval = []
@ -34,8 +39,17 @@ Interval = []
def getConfig(name: str):
return os.environ[name]
LOGGER = logging.getLogger(__name__)
def mktable():
try:
conn = psycopg2.connect(DB_URI)
cur = conn.cursor()
sql = "CREATE TABLE users (uid bigint, sudo boolean DEFAULT FALSE);"
cur.execute(sql)
conn.commit()
LOGGER.info("Table Created!")
except Error as e:
LOGGER.error(e)
exit(1)
try:
if bool(getConfig('_____REMOVE_THIS_LINE_____')):
@ -65,12 +79,7 @@ status_reply_dict = {}
download_dict = {}
# Stores list of users and chats the bot is authorized to use in
AUTHORIZED_CHATS = set()
if os.path.exists('authorized_chats.txt'):
with open('authorized_chats.txt', 'r+') as f:
lines = f.readlines()
for line in lines:
# LOGGER.info(line.split())
AUTHORIZED_CHATS.add(int(line.split()[0]))
SUDO_USERS = set()
try:
achats = getConfig('AUTHORIZED_CHATS')
achats = achats.split(" ")
@ -81,13 +90,13 @@ except:
try:
BOT_TOKEN = getConfig('BOT_TOKEN')
DB_URI = getConfig('DATABASE_URL')
parent_id = getConfig('GDRIVE_FOLDER_ID')
DOWNLOAD_DIR = getConfig('DOWNLOAD_DIR')
if DOWNLOAD_DIR[-1] != '/' or DOWNLOAD_DIR[-1] != '\\':
DOWNLOAD_DIR = DOWNLOAD_DIR + '/'
DOWNLOAD_STATUS_UPDATE_INTERVAL = int(getConfig('DOWNLOAD_STATUS_UPDATE_INTERVAL'))
OWNER_ID = int(getConfig('OWNER_ID'))
SUDO_USER = tuple(filter(lambda x: x, map(int, os.environ.get("SUDO_USER", "").split())))
AUTO_DELETE_MESSAGE_DURATION = int(getConfig('AUTO_DELETE_MESSAGE_DURATION'))
TELEGRAM_API = getConfig('TELEGRAM_API')
TELEGRAM_HASH = getConfig('TELEGRAM_HASH')
@ -95,6 +104,26 @@ except KeyError as e:
LOGGER.error("One or more env variables missing! Exiting now")
exit(1)
try:
conn = psycopg2.connect(DB_URI)
cur = conn.cursor()
sql = "SELECT * from users;"
cur.execute(sql)
rows = cur.fetchall() #returns a list ==> (uid, sudo)
for row in rows:
AUTHORIZED_CHATS.add(row[0])
if row[1]:
SUDO_USERS.add(row[0])
except Error as e:
if 'relation "users" does not exist' in str(e):
mktable()
else:
LOGGER.error(e)
exit(1)
finally:
cur.close()
conn.close()
LOGGER.info("Generating USER_SESSION_STRING")
with Client(':memory:', api_id=int(TELEGRAM_API), api_hash=TELEGRAM_HASH, bot_token=BOT_TOKEN) as app:
USER_SESSION_STRING = app.export_session_string()

View File

@ -10,7 +10,7 @@ import pytz
import time
from telegram import ParseMode, BotCommand, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import CommandHandler, run_async
from bot import dispatcher, updater, botStartTime, AUTHORIZED_CHATS, SUDO_USER, IMAGE_URL
from bot import dispatcher, updater, botStartTime, IMAGE_URL
from bot.helper.ext_utils import fs_utils
from bot.helper.telegram_helper.bot_commands import BotCommands
from bot.helper.telegram_helper.message_utils import *
@ -56,14 +56,6 @@ Type /{BotCommands.HelpCommand} to get a list of available commands
update.effective_message.reply_photo(IMAGE_URL, start_string, parse_mode=ParseMode.MARKDOWN)
@run_async
def chat_list(update, context):
chat_list = sudo = ''
chat_list += '\n'.join(str(id) for id in AUTHORIZED_CHATS)
sudo += '\n'.join(str(id) for id in SUDO_USER)
sendMessage(f'<b><u>Authorized Chats</u></b>\n{chat_list}\n<b><u>Sudo Users</u></b>\n{sudo}', context.bot, update)
@run_async
def repo(update, context):
button = [
@ -99,10 +91,10 @@ def log(update, context):
@run_async
def bot_help(update, context):
help_string = f'''
help_string_adm = f'''
/{BotCommands.HelpCommand}: To get this message
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to Google Drive
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to Google Drive.
/{BotCommands.UnzipMirrorCommand} [download_url][magnet_link]: Starts mirroring and if downloaded file is any archive, extracts it to Google Drive
@ -110,6 +102,8 @@ def bot_help(update, context):
/{BotCommands.CloneCommand}: Copy file/folder to Google Drive
/{BotCommands.DeleteCommand} [link]: Delete file from Google Drive (Only Owner & Sudo)
/{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl. Click /{BotCommands.WatchCommand} for more help.
/{BotCommands.TarWatchCommand} [youtube-dl supported link]: Mirror through youtube-dl and tar before uploading
@ -124,7 +118,13 @@ def bot_help(update, context):
/{BotCommands.AuthorizeCommand}: Authorize a chat or a user to use the bot (Can only be invoked by Owner & Sudo of the bot)
/{BotCommands.AuthListCommand}: See Authorized list & Sudo User (Can only be invoked by Owner & Sudo of the bot)
/{BotCommands.UnAuthorizeCommand}: Unauthorize a chat or a user to use the bot (Can only be invoked by Owner & Sudo of the bot)
/{BotCommands.AuthorizedUsersCommand}: Show authorized users (Only Owner & Sudo)
/{BotCommands.AddSudoCommand}: Add sudo user (Only Owner)
/{BotCommands.RmSudoCommand}: Remove sudo users (Only Owner)
/{BotCommands.LogCommand}: Get a log file of the bot. Handy for getting crash reports
@ -144,6 +144,46 @@ def bot_help(update, context):
/stickerhelp: Get help for Stickers module.
'''
help_string = f'''
/{BotCommands.HelpCommand}: To get this message
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to Google Drive.
/{BotCommands.UnzipMirrorCommand} [download_url][magnet_link]: Starts mirroring and if downloaded file is any archive, extracts it to Google Drive
/{BotCommands.TarMirrorCommand} [download_url][magnet_link]: Start mirroring and upload the archived (.tar) version of the download
/{BotCommands.CloneCommand}: Copy file/folder to Google Drive
/{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl. Click /{BotCommands.WatchCommand} for more help.
/{BotCommands.TarWatchCommand} [youtube-dl supported link]: Mirror through youtube-dl and tar before uploading
/{BotCommands.CancelMirror}: Reply to the message by which the download was initiated and that download will be cancelled
/{BotCommands.StatusCommand}: Shows a status of all the downloads
/{BotCommands.ListCommand} [search term]: Searches the search term in the Google Drive, if found replies with the link
/{BotCommands.StatsCommand}: Show Stats of the machine the bot is hosted on
/{BotCommands.SpeedCommand}: Check Internet Speed of the Host
/{BotCommands.RepoCommand}: Get the bot repo.
/mediainfo: Get detailed info about replied media.
/tshelp: Get help for Torrent search module.
/weebhelp: Get help for Anime, Manga, and Character module.
/stickerhelp: Get help for Stickers module.
'''
if CustomFilters.sudo_user(update) or CustomFilters.owner_filter(update):
sendMessage(help_string_adm, context.bot, update)
else:
sendMessage(help_string, context.bot, update)
@ -183,15 +223,14 @@ def main():
ping_handler = CommandHandler(BotCommands.PingCommand, ping,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
restart_handler = CommandHandler(BotCommands.RestartCommand, restart,
filters=CustomFilters.owner_filter)
filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
help_handler = CommandHandler(BotCommands.HelpCommand,
bot_help, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
stats_handler = CommandHandler(BotCommands.StatsCommand,
stats, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
log_handler = CommandHandler(BotCommands.LogCommand, log, filters=CustomFilters.owner_filter)
log_handler = CommandHandler(BotCommands.LogCommand, log, filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
repo_handler = CommandHandler(BotCommands.RepoCommand, repo,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
authlist_handler = CommandHandler(BotCommands.AuthListCommand, chat_list, filters=CustomFilters.owner_filter)
dispatcher.add_handler(start_handler)
dispatcher.add_handler(ping_handler)
dispatcher.add_handler(restart_handler)
@ -199,7 +238,6 @@ def main():
dispatcher.add_handler(stats_handler)
dispatcher.add_handler(log_handler)
dispatcher.add_handler(repo_handler)
dispatcher.add_handler(authlist_handler)
updater.start_polling()
LOGGER.info("Bot Started!")
signal.signal(signal.SIGINT, fs_utils.exit_clean_up)

View File

@ -0,0 +1,78 @@
import psycopg2
from psycopg2 import Error
from bot import AUTHORIZED_CHATS, SUDO_USERS, DB_URI, LOGGER
class DbManger:
def __init__(self):
self.err = False
def connect(self):
try:
self.conn = psycopg2.connect(DB_URI)
self.cur = self.conn.cursor()
except psycopg2.DatabaseError as error :
LOGGER.error("Error in dbMang : ", error)
self.err = True
def disconnect(self):
self.cur.close()
self.conn.close()
def db_auth(self,chat_id: int):
self.connect()
if self.err :
return "There's some error check log for details"
else:
sql = 'INSERT INTO users VALUES ({});'.format(chat_id)
self.cur.execute(sql)
self.conn.commit()
self.disconnect()
AUTHORIZED_CHATS.add(chat_id)
return 'Authorized successfully'
def db_unauth(self,chat_id: int):
self.connect()
if self.err :
return "There's some error check log for details"
else:
sql = 'DELETE from users where uid = {};'.format(chat_id)
self.cur.execute(sql)
self.conn.commit()
self.disconnect()
AUTHORIZED_CHATS.remove(chat_id)
if chat_id in SUDO_USERS:
SUDO_USERS.remove(chat_id)
return 'Unauthorized successfully'
def db_addsudo(self,chat_id: int):
self.connect()
if self.err :
return "There's some error check log for details"
else:
if chat_id in AUTHORIZED_CHATS:
sql = 'UPDATE users SET sudo = TRUE where uid = {};'.format(chat_id)
self.cur.execute(sql)
self.conn.commit()
self.disconnect()
SUDO_USERS.add(chat_id)
return 'Successfully promoted as sudo'
else:
sql = 'INSERT INTO users VALUES ({},TRUE);'.format(chat_id)
self.cur.execute(sql)
self.conn.commit()
self.disconnect()
AUTHORIZED_CHATS.add(chat_id)
SUDO_USERS.add(chat_id)
return 'Successfully Authorized and promoted as sudo'
def db_rmsudo(self,chat_id: int):
self.connect()
if self.err :
return "There's some error check log for details"
else:
sql = 'UPDATE users SET sudo = FALSE where uid = {};'.format(chat_id)
self.cur.execute(sql)
self.conn.commit()
self.disconnect()
SUDO_USERS.remove(chat_id)
return 'Successfully removed from Sudo'

View File

@ -128,10 +128,11 @@ class GoogleDriveHelper:
global SERVICE_ACCOUNT_INDEX
service_account_count = len(os.listdir("accounts"))
if SERVICE_ACCOUNT_INDEX == service_account_count - 1:
SERVICE_ACCOUNT_INDEX = 0
return False
SERVICE_ACCOUNT_INDEX += 1
LOGGER.info(f"Switching to {SERVICE_ACCOUNT_INDEX}.json service account")
self.__service = self.authorize()
return True
@retry(wait=wait_exponential(multiplier=2, min=3, max=6), stop=stop_after_attempt(5),
retry=retry_if_exception_type(HttpError), before=before_log(LOGGER, logging.DEBUG))
@ -189,7 +190,8 @@ class GoogleDriveHelper:
reason = json.loads(err.content).get('error').get('errors')[0].get('reason')
if reason == 'userRateLimitExceeded' or reason == 'dailyLimitExceeded':
if USE_SERVICE_ACCOUNTS:
self.switchServiceAccount()
if not self.switchServiceAccount():
return None
LOGGER.info(f"Got: {reason}, Trying Again.")
return self.upload_file(file_path, file_name, mime_type, parent_id)
else:
@ -270,7 +272,8 @@ class GoogleDriveHelper:
reason = json.loads(err.content).get('error').get('errors')[0].get('reason')
if reason == 'userRateLimitExceeded' or reason == 'dailyLimitExceeded':
if USE_SERVICE_ACCOUNTS:
self.switchServiceAccount()
if not self.switchServiceAccount():
raise err
LOGGER.info(f"Got: {reason}, Trying Again.")
return self.copyFile(file_id,dest_id)
else:
@ -569,7 +572,7 @@ class GoogleDriveHelper:
if self.num_of_path > 1:
self.edit_telegraph()
msg = f"<b>🔎 Search Results For <i>{fileName}</i></b> \n<b>📚 Found {len(response['files'])} results</b>"
msg = f"<b>🔎 Found {len(response['files'])} results for <i>{fileName}</i></b>"
buttons = button_build.ButtonMaker()
buttons.buildbutton("HERE", f"https://telegra.ph/{self.path[0]}")

View File

@ -8,9 +8,11 @@ class _BotCommands:
self.CancelAllCommand = 'cancelall'
self.ListCommand = 'list'
self.StatusCommand = 'status'
self.AuthorizedUsersCommand = 'users'
self.AuthorizeCommand = 'authorize'
self.UnAuthorizeCommand = 'unauthorize'
self.AuthListCommand = 'authlist'
self.AddSudoCommand = 'addsudo'
self.RmSudoCommand = 'rmsudo'
self.PingCommand = 'ping'
self.RestartCommand = 'restart'
self.StatsCommand = 'stats'

View File

@ -1,20 +1,19 @@
from telegram.ext import BaseFilter
from telegram import Message
from bot import AUTHORIZED_CHATS, OWNER_ID, SUDO_USER, download_dict, download_dict_lock
from bot import AUTHORIZED_CHATS, SUDO_USERS, OWNER_ID, download_dict, download_dict_lock
class CustomFilters:
class _OwnerFilter(BaseFilter):
def filter(self, message):
id = message.from_user.id
return bool(message.from_user.id == OWNER_ID or id in SUDO_USER)
return bool(message.from_user.id == OWNER_ID)
owner_filter = _OwnerFilter()
class _AuthorizedUserFilter(BaseFilter):
def filter(self, message):
id = message.from_user.id
return bool(id in AUTHORIZED_CHATS or id == OWNER_ID or id in SUDO_USER)
return bool(id in AUTHORIZED_CHATS or id == OWNER_ID)
authorized_user = _AuthorizedUserFilter()
@ -24,10 +23,16 @@ class CustomFilters:
authorized_chat = _AuthorizedChat()
class _SudoUser(BaseFilter):
def filter(self,message):
return bool(message.from_user.id in SUDO_USERS)
sudo_user = _SudoUser()
class _MirrorOwner(BaseFilter):
def filter(self, message: Message):
user_id = message.from_user.id
if user_id in SUDO_USER:
if user_id == OWNER_ID:
return True
args = str(message.text).split(' ')
if len(args) > 1:

View File

@ -1,69 +1,145 @@
from bot.helper.telegram_helper.message_utils import sendMessage
from telegram.ext import run_async
from bot import AUTHORIZED_CHATS, dispatcher
from bot import AUTHORIZED_CHATS, SUDO_USERS, dispatcher
from telegram.ext import CommandHandler
from bot.helper.telegram_helper.filters import CustomFilters
from telegram.ext import Filters
from telegram import Update
from bot.helper.telegram_helper.bot_commands import BotCommands
from bot.helper.ext_utils.db_handler import DbManger
@run_async
def authorize(update,context):
reply_message = None
message_ = None
reply_message = update.message.reply_to_message
msg = ''
with open('authorized_chats.txt', 'a') as file:
message_ = update.message.text.split(' ')
if len(message_) == 2:
chat_id = int(message_[1])
if chat_id not in AUTHORIZED_CHATS:
msg = DbManger().db_auth(chat_id)
else:
msg = 'User already authorized'
else:
if reply_message is None:
# Trying to authorize a chat
chat_id = update.effective_chat.id
if chat_id not in AUTHORIZED_CHATS:
file.write(f'{chat_id}\n')
AUTHORIZED_CHATS.add(chat_id)
msg = 'Chat authorized'
msg = DbManger().db_auth(chat_id)
else:
msg = 'Already authorized chat'
else:
# Trying to authorize someone in specific
user_id = reply_message.from_user.id
if user_id not in AUTHORIZED_CHATS:
file.write(f'{user_id}\n')
AUTHORIZED_CHATS.add(user_id)
msg = 'Person Authorized to use the bot!'
msg = DbManger().db_auth(user_id)
else:
msg = 'Person already authorized'
msg = 'User already authorized'
sendMessage(msg, context.bot, update)
@run_async
def unauthorize(update,context):
reply_message = None
message_ = None
reply_message = update.message.reply_to_message
message_ = update.message.text.split(' ')
if len(message_) == 2:
chat_id = int(message_[1])
if chat_id in AUTHORIZED_CHATS:
msg = DbManger().db_unauth(chat_id)
else:
msg = 'User already unauthorized'
else:
if reply_message is None:
# Trying to unauthorize a chat
chat_id = update.effective_chat.id
if chat_id in AUTHORIZED_CHATS:
AUTHORIZED_CHATS.remove(chat_id)
msg = 'Chat unauthorized'
msg = DbManger().db_unauth(chat_id)
else:
msg = 'Already unauthorized chat'
else:
# Trying to authorize someone in specific
user_id = reply_message.from_user.id
if user_id in AUTHORIZED_CHATS:
AUTHORIZED_CHATS.remove(user_id)
msg = 'Person unauthorized to use the bot!'
msg = DbManger().db_unauth(user_id)
else:
msg = 'Person already unauthorized!'
with open('authorized_chats.txt', 'a') as file:
file.truncate(0)
for i in AUTHORIZED_CHATS:
file.write(f'{i}\n')
msg = 'User already unauthorized'
sendMessage(msg, context.bot, update)
@run_async
def addSudo(update,context):
reply_message = None
message_ = None
reply_message = update.message.reply_to_message
message_ = update.message.text.split(' ')
if len(message_) == 2:
chat_id = int(message_[1])
if chat_id not in SUDO_USERS:
msg = DbManger().db_addsudo(chat_id)
else:
msg = 'Already Sudo'
else:
if reply_message is None:
msg = "Give ID or Reply To message of whom you want to Promote"
else:
# Trying to authorize someone in specific
user_id = reply_message.from_user.id
if user_id not in SUDO_USERS:
msg = DbManger().db_addsudo(user_id)
else:
msg = 'Already Sudo'
sendMessage(msg, context.bot, update)
@run_async
def removeSudo(update,context):
reply_message = None
message_ = None
reply_message = update.message.reply_to_message
message_ = update.message.text.split(' ')
if len(message_) == 2:
chat_id = int(message_[1])
if chat_id in SUDO_USERS:
msg = DbManger().db_rmsudo(chat_id)
else:
msg = 'Not a Sudo'
else:
if reply_message is None:
msg = "Give ID or Reply To message of whom you want to remove from Sudo"
else:
user_id = reply_message.from_user.id
if user_id in SUDO_USERS:
msg = DbManger().db_rmsudo(user_id)
else:
msg = 'Not a Sudo'
sendMessage(msg, context.bot, update)
@run_async
def sendAuthChats(update,context):
user = sudo = ''
user += '\n'.join(str(id) for id in AUTHORIZED_CHATS)
sudo += '\n'.join(str(id) for id in SUDO_USERS)
sendMessage(f'<b><u>Authorized Chats</u></b>\n{user}\n<b><u>Sudo Users</u></b>\n{sudo}', context.bot, update)
send_auth_handler = CommandHandler(command=BotCommands.AuthorizedUsersCommand, callback=sendAuthChats,
filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
authorize_handler = CommandHandler(command=BotCommands.AuthorizeCommand, callback=authorize,
filters=CustomFilters.owner_filter & Filters.group)
filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
unauthorize_handler = CommandHandler(command=BotCommands.UnAuthorizeCommand, callback=unauthorize,
filters=CustomFilters.owner_filter & Filters.group)
filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
addsudo_handler = CommandHandler(command=BotCommands.AddSudoCommand, callback=addSudo,
filters=CustomFilters.owner_filter)
removesudo_handler = CommandHandler(command=BotCommands.RmSudoCommand, callback=removeSudo,
filters=CustomFilters.owner_filter)
dispatcher.add_handler(send_auth_handler)
dispatcher.add_handler(authorize_handler)
dispatcher.add_handler(unauthorize_handler)
dispatcher.add_handler(addsudo_handler)
dispatcher.add_handler(removesudo_handler)

View File

@ -25,5 +25,5 @@ def deletefile(update, context):
threading.Thread(target=auto_delete_message, args=(context.bot, update.message, reply_message)).start()
delete_handler = CommandHandler(command=BotCommands.DeleteCommand, callback=deletefile, filters=CustomFilters.owner_filter)
delete_handler = CommandHandler(command=BotCommands.DeleteCommand, callback=deletefile, filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
dispatcher.add_handler(delete_handler)

View File

@ -59,7 +59,9 @@ class MirrorListener(listeners.MirrorListeners):
download = download_dict[self.uid]
name = download.name()
size = download.size_raw()
m_path = f'{DOWNLOAD_DIR}{self.uid}/{download.name()}'
if name is None: # when pyrogram's media.file_name is of NoneType
name = os.listdir(f'{DOWNLOAD_DIR}{self.uid}')[0]
m_path = f'{DOWNLOAD_DIR}{self.uid}/{name}'
if self.isTar:
download.is_archiving = True
try:

View File

@ -77,6 +77,6 @@ def dyno_usage(update, context):
dyno_usage_handler = CommandHandler(command=BotCommands.UsageCommand, callback=dyno_usage,
filters=CustomFilters.owner_filter)
filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
dispatcher.add_handler(dyno_usage_handler)

View File

@ -11,9 +11,9 @@ AUTO_DELETE_MESSAGE_DURATION = 20
IS_TEAM_DRIVE = ""
TELEGRAM_API =
TELEGRAM_HASH = ""
DATABASE_URL =
# Optional config
AUTHORIZED_CHATS = ""
SUDO_USER =
USE_SERVICE_ACCOUNTS = ""
INDEX_URL = ""
UPTOBOX_TOKEN = ""

View File

@ -25,3 +25,4 @@ lxml
telegraph
pytz
html-telegraph-poster>=0.2.31
psycopg2-binary