Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit 6df4486

Browse files
breakdownsSVR666gautamajay52KenHV
authored
v4.7.5 (#94)
- 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 <[email protected]> Co-authored-by: Gautam Kumar <[email protected]> Co-authored-by: KenHV <[email protected]>
1 parent 9d969f3 commit 6df4486

File tree

14 files changed

+359
-79
lines changed

14 files changed

+359
-79
lines changed

README.md

+48-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ This is a Telegram bot writen in Python for mirroring files on the Internet to o
77

88
## Additional Features
99
- Mirroring Uptobox.com links to Google Drive (Uptobox account must be premium)
10-
- Sudo support (DWYOR, Sudo User can restart your bot and delete your Drive file)
1110
- Get detailed info about replied media
1211
- Nyaa.si and Sukebei Torrent search
1312
- Speedtest with picture results
1413
- Limiting Torrent size support
14+
- Sudo with database support
1515
- Check Heroku dynos stats
1616
- Custom image support
1717
- Racaty.net support
@@ -63,11 +63,56 @@ Install Docker by following the [official Docker docs](https://docs.docker.com/e
6363
```
6464
sudo pacman -S docker python
6565
```
66-
6766
- Install dependencies for running setup scripts:
6867
```
6968
pip3 install -r requirements-cli.txt
7069
```
70+
## Generate Database
71+
<details>
72+
<summary><b>Click here for more details</b></summary>
73+
74+
**1. The easy way**
75+
- Make new Heroku blank app
76+
- Go to your Heroku blank app
77+
- Go to resources
78+
- In Add-ons search **Heroku Postgres**
79+
- Hit **Submit Order Form**
80+
- Copy your Database URL from Heroku Config Vars > **DATABASE_URL**
81+
82+
**2. The hard way**
83+
- Install Postgresql:
84+
```
85+
sudo apt-get update && sudo apt-get install postgresql
86+
```
87+
- Change to the Postgres user:
88+
```
89+
sudo su - postgres
90+
```
91+
- Create a new database user (change YOUR_USER appropriately):
92+
```
93+
createuser -P -s -e YOUR_USER
94+
```
95+
This will be followed by you needing to input your password.
96+
- Create a new database table:
97+
```
98+
createdb -O YOUR_USER YOUR_DB_NAME
99+
```
100+
Change YOUR_USER and YOUR_DB_NAME appropriately.
101+
- Finally:
102+
```
103+
psql YOUR_DB_NAME -h YOUR_HOST YOUR_USER
104+
```
105+
This will allow you to connect to your database via your terminal. By default, YOUR_HOST should be 0.0.0.0:5432.
106+
107+
You should now be able to build your database URL. This will be:
108+
```
109+
sqldbtype://username:pw@hostname:port/db_name
110+
```
111+
Replace sqldbtype with whichever db youre using (eg postgres, mysql, sqllite, etc) repeat for your username, password, hostname (localhost?), port (5432?), and db name.
112+
113+
**NOTE**: If you deploying on Heroku, no need to generate database manually, because it will automatic generate database
114+
115+
</details>
71116

72117
## Setting up config file
73118
<details>
@@ -86,8 +131,8 @@ Fill up rest of the fields. Meaning of each fields are discussed below:
86131
- **DOWNLOAD_DIR**: The path to the local folder where the downloads should be downloaded to
87132
- **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)
88133
- **OWNER_ID**: The Telegram user ID (not username) of the Owner of the bot
89-
- **SUDO_USER**: (Optional field) Multiple Telegram user ID (not username) separate by space.
90134
- **AUTHORIZED_CHATS**: Fill user_id and chat_id of you want to authorize.
135+
- **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)
91136
- **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)
92137
- **IS_TEAM_DRIVE**: (Optional field) Set to `True` if `GDRIVE_FOLDER_ID` is from a Team Drive else `False` or Leave it empty.
93138
- **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.

app.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@
3838
"description": "The Telegram User ID of the Owner of the Bot. Get it by using /info in @MissRose_bot.",
3939
"required": true
4040
},
41-
"SUDO_USER": {
42-
"description": "Multiple Telegram user ID (not username) separate by space.",
43-
"required": false
44-
},
4541
"AUTO_DELETE_MESSAGE_DURATION": {
4642
"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.",
4743
"required": true
@@ -153,5 +149,10 @@
153149
"description": "Fill your URL if you are using extra buttons.",
154150
"required": false
155151
}
156-
}
152+
},
153+
"addons": [
154+
{
155+
"plan": "heroku-postgresql"
156+
}
157+
]
157158
}

bot/__init__.py

+38-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
from pyrogram import Client
1212
from telegraph import Telegraph
1313

14+
import psycopg2
15+
from psycopg2 import Error
16+
1417
import socket
1518
import faulthandler
1619
faulthandler.enable()
@@ -26,6 +29,8 @@
2629
handlers=[logging.FileHandler('log.txt'), logging.StreamHandler()],
2730
level=logging.INFO)
2831

32+
LOGGER = logging.getLogger(__name__)
33+
2934
load_dotenv('config.env')
3035

3136
Interval = []
@@ -34,8 +39,17 @@
3439
def getConfig(name: str):
3540
return os.environ[name]
3641

37-
38-
LOGGER = logging.getLogger(__name__)
42+
def mktable():
43+
try:
44+
conn = psycopg2.connect(DB_URI)
45+
cur = conn.cursor()
46+
sql = "CREATE TABLE users (uid bigint, sudo boolean DEFAULT FALSE);"
47+
cur.execute(sql)
48+
conn.commit()
49+
LOGGER.info("Table Created!")
50+
except Error as e:
51+
LOGGER.error(e)
52+
exit(1)
3953

4054
try:
4155
if bool(getConfig('_____REMOVE_THIS_LINE_____')):
@@ -65,12 +79,7 @@ def getConfig(name: str):
6579
download_dict = {}
6680
# Stores list of users and chats the bot is authorized to use in
6781
AUTHORIZED_CHATS = set()
68-
if os.path.exists('authorized_chats.txt'):
69-
with open('authorized_chats.txt', 'r+') as f:
70-
lines = f.readlines()
71-
for line in lines:
72-
# LOGGER.info(line.split())
73-
AUTHORIZED_CHATS.add(int(line.split()[0]))
82+
SUDO_USERS = set()
7483
try:
7584
achats = getConfig('AUTHORIZED_CHATS')
7685
achats = achats.split(" ")
@@ -81,20 +90,40 @@ def getConfig(name: str):
8190

8291
try:
8392
BOT_TOKEN = getConfig('BOT_TOKEN')
93+
DB_URI = getConfig('DATABASE_URL')
8494
parent_id = getConfig('GDRIVE_FOLDER_ID')
8595
DOWNLOAD_DIR = getConfig('DOWNLOAD_DIR')
8696
if DOWNLOAD_DIR[-1] != '/' or DOWNLOAD_DIR[-1] != '\\':
8797
DOWNLOAD_DIR = DOWNLOAD_DIR + '/'
8898
DOWNLOAD_STATUS_UPDATE_INTERVAL = int(getConfig('DOWNLOAD_STATUS_UPDATE_INTERVAL'))
8999
OWNER_ID = int(getConfig('OWNER_ID'))
90-
SUDO_USER = tuple(filter(lambda x: x, map(int, os.environ.get("SUDO_USER", "").split())))
91100
AUTO_DELETE_MESSAGE_DURATION = int(getConfig('AUTO_DELETE_MESSAGE_DURATION'))
92101
TELEGRAM_API = getConfig('TELEGRAM_API')
93102
TELEGRAM_HASH = getConfig('TELEGRAM_HASH')
94103
except KeyError as e:
95104
LOGGER.error("One or more env variables missing! Exiting now")
96105
exit(1)
97106

107+
try:
108+
conn = psycopg2.connect(DB_URI)
109+
cur = conn.cursor()
110+
sql = "SELECT * from users;"
111+
cur.execute(sql)
112+
rows = cur.fetchall() #returns a list ==> (uid, sudo)
113+
for row in rows:
114+
AUTHORIZED_CHATS.add(row[0])
115+
if row[1]:
116+
SUDO_USERS.add(row[0])
117+
except Error as e:
118+
if 'relation "users" does not exist' in str(e):
119+
mktable()
120+
else:
121+
LOGGER.error(e)
122+
exit(1)
123+
finally:
124+
cur.close()
125+
conn.close()
126+
98127
LOGGER.info("Generating USER_SESSION_STRING")
99128
with Client(':memory:', api_id=int(TELEGRAM_API), api_hash=TELEGRAM_HASH, bot_token=BOT_TOKEN) as app:
100129
USER_SESSION_STRING = app.export_session_string()

bot/__main__.py

+55-17
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import time
1111
from telegram import ParseMode, BotCommand, InlineKeyboardMarkup, InlineKeyboardButton
1212
from telegram.ext import CommandHandler, run_async
13-
from bot import dispatcher, updater, botStartTime, AUTHORIZED_CHATS, SUDO_USER, IMAGE_URL
13+
from bot import dispatcher, updater, botStartTime, IMAGE_URL
1414
from bot.helper.ext_utils import fs_utils
1515
from bot.helper.telegram_helper.bot_commands import BotCommands
1616
from bot.helper.telegram_helper.message_utils import *
@@ -56,14 +56,6 @@ def start(update, context):
5656
update.effective_message.reply_photo(IMAGE_URL, start_string, parse_mode=ParseMode.MARKDOWN)
5757

5858

59-
@run_async
60-
def chat_list(update, context):
61-
chat_list = sudo = ''
62-
chat_list += '\n'.join(str(id) for id in AUTHORIZED_CHATS)
63-
sudo += '\n'.join(str(id) for id in SUDO_USER)
64-
sendMessage(f'<b><u>Authorized Chats</u></b>\n{chat_list}\n<b><u>Sudo Users</u></b>\n{sudo}', context.bot, update)
65-
66-
6759
@run_async
6860
def repo(update, context):
6961
button = [
@@ -99,17 +91,19 @@ def log(update, context):
9991

10092
@run_async
10193
def bot_help(update, context):
102-
help_string = f'''
94+
help_string_adm = f'''
10395
/{BotCommands.HelpCommand}: To get this message
10496
105-
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to Google Drive
97+
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to Google Drive.
10698
10799
/{BotCommands.UnzipMirrorCommand} [download_url][magnet_link]: Starts mirroring and if downloaded file is any archive, extracts it to Google Drive
108100
109101
/{BotCommands.TarMirrorCommand} [download_url][magnet_link]: Start mirroring and upload the archived (.tar) version of the download
110102
111103
/{BotCommands.CloneCommand}: Copy file/folder to Google Drive
112104
105+
/{BotCommands.DeleteCommand} [link]: Delete file from Google Drive (Only Owner & Sudo)
106+
113107
/{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl. Click /{BotCommands.WatchCommand} for more help.
114108
115109
/{BotCommands.TarWatchCommand} [youtube-dl supported link]: Mirror through youtube-dl and tar before uploading
@@ -124,7 +118,13 @@ def bot_help(update, context):
124118
125119
/{BotCommands.AuthorizeCommand}: Authorize a chat or a user to use the bot (Can only be invoked by Owner & Sudo of the bot)
126120
127-
/{BotCommands.AuthListCommand}: See Authorized list & Sudo User (Can only be invoked by Owner & Sudo of the bot)
121+
/{BotCommands.UnAuthorizeCommand}: Unauthorize a chat or a user to use the bot (Can only be invoked by Owner & Sudo of the bot)
122+
123+
/{BotCommands.AuthorizedUsersCommand}: Show authorized users (Only Owner & Sudo)
124+
125+
/{BotCommands.AddSudoCommand}: Add sudo user (Only Owner)
126+
127+
/{BotCommands.RmSudoCommand}: Remove sudo users (Only Owner)
128128
129129
/{BotCommands.LogCommand}: Get a log file of the bot. Handy for getting crash reports
130130
@@ -144,7 +144,47 @@ def bot_help(update, context):
144144
145145
/stickerhelp: Get help for Stickers module.
146146
'''
147-
sendMessage(help_string, context.bot, update)
147+
148+
help_string = f'''
149+
/{BotCommands.HelpCommand}: To get this message
150+
151+
/{BotCommands.MirrorCommand} [download_url][magnet_link]: Start mirroring the link to Google Drive.
152+
153+
/{BotCommands.UnzipMirrorCommand} [download_url][magnet_link]: Starts mirroring and if downloaded file is any archive, extracts it to Google Drive
154+
155+
/{BotCommands.TarMirrorCommand} [download_url][magnet_link]: Start mirroring and upload the archived (.tar) version of the download
156+
157+
/{BotCommands.CloneCommand}: Copy file/folder to Google Drive
158+
159+
/{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl. Click /{BotCommands.WatchCommand} for more help.
160+
161+
/{BotCommands.TarWatchCommand} [youtube-dl supported link]: Mirror through youtube-dl and tar before uploading
162+
163+
/{BotCommands.CancelMirror}: Reply to the message by which the download was initiated and that download will be cancelled
164+
165+
/{BotCommands.StatusCommand}: Shows a status of all the downloads
166+
167+
/{BotCommands.ListCommand} [search term]: Searches the search term in the Google Drive, if found replies with the link
168+
169+
/{BotCommands.StatsCommand}: Show Stats of the machine the bot is hosted on
170+
171+
/{BotCommands.SpeedCommand}: Check Internet Speed of the Host
172+
173+
/{BotCommands.RepoCommand}: Get the bot repo.
174+
175+
/mediainfo: Get detailed info about replied media.
176+
177+
/tshelp: Get help for Torrent search module.
178+
179+
/weebhelp: Get help for Anime, Manga, and Character module.
180+
181+
/stickerhelp: Get help for Stickers module.
182+
'''
183+
184+
if CustomFilters.sudo_user(update) or CustomFilters.owner_filter(update):
185+
sendMessage(help_string_adm, context.bot, update)
186+
else:
187+
sendMessage(help_string, context.bot, update)
148188

149189

150190
botcmds = [
@@ -183,23 +223,21 @@ def main():
183223
ping_handler = CommandHandler(BotCommands.PingCommand, ping,
184224
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
185225
restart_handler = CommandHandler(BotCommands.RestartCommand, restart,
186-
filters=CustomFilters.owner_filter)
226+
filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
187227
help_handler = CommandHandler(BotCommands.HelpCommand,
188228
bot_help, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
189229
stats_handler = CommandHandler(BotCommands.StatsCommand,
190230
stats, filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
191-
log_handler = CommandHandler(BotCommands.LogCommand, log, filters=CustomFilters.owner_filter)
231+
log_handler = CommandHandler(BotCommands.LogCommand, log, filters=CustomFilters.owner_filter | CustomFilters.sudo_user)
192232
repo_handler = CommandHandler(BotCommands.RepoCommand, repo,
193233
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
194-
authlist_handler = CommandHandler(BotCommands.AuthListCommand, chat_list, filters=CustomFilters.owner_filter)
195234
dispatcher.add_handler(start_handler)
196235
dispatcher.add_handler(ping_handler)
197236
dispatcher.add_handler(restart_handler)
198237
dispatcher.add_handler(help_handler)
199238
dispatcher.add_handler(stats_handler)
200239
dispatcher.add_handler(log_handler)
201240
dispatcher.add_handler(repo_handler)
202-
dispatcher.add_handler(authlist_handler)
203241
updater.start_polling()
204242
LOGGER.info("Bot Started!")
205243
signal.signal(signal.SIGINT, fs_utils.exit_clean_up)

0 commit comments

Comments
 (0)