Skip to content

Commit

Permalink
Improve help module
Browse files Browse the repository at this point in the history
- Add docker-compose.yml file
- Fix bugs
- Tidy up
  • Loading branch information
l3v11 authored May 23, 2022
1 parent ad413c9 commit c866569
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 106 deletions.
122 changes: 73 additions & 49 deletions bot/__main__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import time

from psutil import cpu_percent, cpu_count, disk_usage, virtual_memory
from telegram import InlineKeyboardMarkup
from telegram.ext import CommandHandler

from bot import LOGGER, botStartTime, AUTHORIZED_CHATS, dispatcher, updater
from bot import LOGGER, botStartTime, AUTHORIZED_CHATS, telegraph, dispatcher, updater
from bot.modules import auth, cancel, clone, count, delete, eval, list, permission, shell, status
from bot.helper.ext_utils.bot_utils import get_readable_file_size, get_readable_time
from bot.helper.telegram_helper.bot_commands import BotCommands
from bot.helper.telegram_helper.button_builder import ButtonMaker
from bot.helper.telegram_helper.filters import CustomFilters
from bot.helper.telegram_helper.message_utils import *
from bot.helper.telegram_helper.message_utils import sendMessage, sendMarkup, editMessage, sendLogFile

def start(update, context):
if CustomFilters.authorized_user(update) or CustomFilters.authorized_chat(update):
Expand Down Expand Up @@ -45,72 +47,94 @@ def stats(update, context):
f"\n<b>DISK:</b> {disk}% | <b>Uptime:</b> {uptime}"
sendMessage(stats, context.bot, update.message)

def bot_help(update, context):
help_string = f'''
<u><i><b>Usage:</b></i></u>
For <i>folder</i> results only:
<code>/{BotCommands.ListCommand} -d &lt;query&gt;</code>
For <i>file</i> results only:
<code>/{BotCommands.ListCommand} -f &lt;query&gt;</code>
<u><i><b>Commands:</b></i></u>
/{BotCommands.StartCommand}: Start the bot
/{BotCommands.ListCommand} [query]: Search data on Drives
/{BotCommands.CloneCommand} [url]: Copy data from Drive / AppDrive / DriveApp / GDToT to Drive
/{BotCommands.CountCommand} [drive_url]: Count data of Drive
/{BotCommands.CancelCommand} [gid]: Cancel a task
/{BotCommands.StatusCommand}: Get a status of all tasks
/{BotCommands.PermissionCommand} [drive_url] [email]: Set data permission of Drive (Email optional & Only owner)
/{BotCommands.DeleteCommand} [drive_url]: Delete data from Drive (Only owner)
/{BotCommands.AuthorizeCommand}: Authorize an user or a chat for using the bot (Only owner)
/{BotCommands.UnauthorizeCommand}: Unauthorize an user or a chat for using the bot (Only owner)
/{BotCommands.UsersCommand}: View authorized chats (Only owner)
/{BotCommands.ShellCommand} [cmd]: Run commands in terminal (Only owner)
/{BotCommands.ExecHelpCommand}: Get help for executor (Only owner)
def log(update, context):
sendLogFile(context.bot, update.message)

/{BotCommands.PingCommand}: Ping the bot
help_string = '''
<b><a href='https://github.com/l3v11/SearchX'>SearchX</a></b> - The Ultimate Telegram Bot for Google Drive
/{BotCommands.StatsCommand}: Get the system stats
Choose a help category:
'''

/{BotCommands.LogCommand}: Get the log file (Only owner)
help_string_user = f'''
<u><b>User Commands</b></u>
<br><br>
• <b>/{BotCommands.StartCommand}</b>: Start the bot
<br><br>
• <b>/{BotCommands.ListCommand}</b> &lt;query&gt;: Search data on Drives
<br><br>
• <b>/{BotCommands.ListCommand} -d</b> &lt;query&gt;: Search folders on Drives
<br><br>
• <b>/{BotCommands.ListCommand} -f</b> &lt;query&gt;: Search files on Drives
<br><br>
• <b>/{BotCommands.CloneCommand}</b> &lt;url&gt;: Copy data from Drive / AppDrive / DriveApp / GDToT to Drive
<br><br>
• <b>/{BotCommands.CountCommand}</b> &lt;drive_url&gt;: Count data of Drive
<br><br>
• <b>/{BotCommands.CancelCommand}</b> &lt;gid&gt;: Cancel a task
<br><br>
• <b>/{BotCommands.StatusCommand}</b>: Get a status of all tasks
<br><br>
• <b>/{BotCommands.PingCommand}</b>: Ping the bot
<br><br>
• <b>/{BotCommands.StatsCommand}</b>: Get the system stats
<br><br>
• <b>/{BotCommands.HelpCommand}</b>: Get this message
'''

/{BotCommands.HelpCommand}: Get this message
help_user = telegraph[0].create_page(
title='SearchX Help',
author_name='Levi',
author_url='https://t.me/l3v11',
html_content=help_string_user)['url']

help_string_admin = f'''
<u><b>Admin Commands</b></u>
<br><br>
• <b>/{BotCommands.PermissionCommand}</b> &lt;drive_url&gt; &lt;email&gt;: Set data permission of Drive (Email optional)
<br><br>
• <b>/{BotCommands.DeleteCommand}</b> &lt;drive_url&gt;: Delete data from Drive
<br><br>
• <b>/{BotCommands.AuthorizeCommand}</b>: Authorize an user or a chat for using the bot
<br><br>
• <b>/{BotCommands.UnauthorizeCommand}</b>: Unauthorize an user or a chat for using the bot
<br><br>
• <b>/{BotCommands.UsersCommand}</b>: View authorized chats
<br><br>
• <b>/{BotCommands.ShellCommand}</b> &lt;cmd&gt;: Run commands in terminal
<br><br>
• <b>/{BotCommands.ExecHelpCommand}</b>: Get help about executor
<br><br>
• <b>/{BotCommands.LogCommand}</b>: Get the log file
'''
sendMessage(help_string, context.bot, update.message)

def log(update, context):
sendLogFile(context.bot, update.message)
help_admin = telegraph[0].create_page(
title='SearchX Help',
author_name='Levi',
author_url='https://t.me/l3v11',
html_content=help_string_admin)['url']

def bot_help(update, context):
button = ButtonMaker()
button.build_button("User", f"{help_user}")
button.build_button("Admin", f"{help_admin}")
sendMarkup(help_string, context.bot, update.message, InlineKeyboardMarkup(button.build_menu(2)))

def main():
start_handler = CommandHandler(BotCommands.StartCommand, start, run_async=True)
ping_handler = CommandHandler(BotCommands.PingCommand, ping,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
stats_handler = CommandHandler(BotCommands.StatsCommand, stats,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
help_handler = CommandHandler(BotCommands.HelpCommand, bot_help,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
log_handler = CommandHandler(BotCommands.LogCommand, log,
filters=CustomFilters.owner_filter, run_async=True)
help_handler = CommandHandler(BotCommands.HelpCommand, bot_help,
filters=CustomFilters.authorized_chat | CustomFilters.authorized_user, run_async=True)
dispatcher.add_handler(start_handler)
dispatcher.add_handler(ping_handler)
dispatcher.add_handler(stats_handler)
dispatcher.add_handler(help_handler)
dispatcher.add_handler(log_handler)
dispatcher.add_handler(help_handler)
updater.start_polling()
LOGGER.info("Bot started")
updater.idle()
Expand Down
42 changes: 18 additions & 24 deletions bot/helper/drive_utils/gdriveTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import urllib.parse as urlparse
from urllib.parse import parse_qs
from random import randrange
from tenacity import retry, wait_exponential, stop_after_attempt, \
retry_if_exception_type, before_log, RetryError
from timeit import default_timer as timer

from telegram import InlineKeyboardMarkup
Expand All @@ -18,7 +20,6 @@
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from tenacity import *

from bot import LOGGER, DRIVE_NAMES, DRIVE_IDS, INDEX_URLS, parent_id, \
IS_TEAM_DRIVE, telegraph, USE_SERVICE_ACCOUNTS, INDEX_URL
Expand All @@ -34,7 +35,6 @@

class GoogleDriveHelper:
def __init__(self, name=None):
self.__G_DRIVE_TOKEN_FILE = "token.json"
# Check https://developers.google.com/drive/scopes for all available scopes
self.__OAUTH_SCOPE = ['https://www.googleapis.com/auth/drive']
self.__G_DRIVE_DIR_MIME_TYPE = "application/vnd.google-apps.folder"
Expand All @@ -61,31 +61,26 @@ def cspeed(self):
return 0

def authorize(self):
# Get credentials
credentials = None
creds = None
if not USE_SERVICE_ACCOUNTS:
if os.path.exists(self.__G_DRIVE_TOKEN_FILE):
credentials = Credentials.from_authorized_user_file(self.__G_DRIVE_TOKEN_FILE, self.__OAUTH_SCOPE)
if credentials is None or not credentials.valid:
if credentials and credentials.expired and credentials.refresh_token:
credentials.refresh(Request())
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', self.__OAUTH_SCOPE)
else:
LOGGER.error("token.json file is missing")
else:
LOGGER.info(f"Authorizing with {SERVICE_ACCOUNT_INDEX}.json file")
credentials = service_account.Credentials.from_service_account_file(
creds = service_account.Credentials.from_service_account_file(
f'accounts/{SERVICE_ACCOUNT_INDEX}.json', scopes=self.__OAUTH_SCOPE)
return build('drive', 'v3', credentials=credentials, cache_discovery=False)
return build('drive', 'v3', credentials=creds, cache_discovery=False)

def alt_authorize(self):
credentials = None
creds = None
if USE_SERVICE_ACCOUNTS and not self.alt_auth:
self.alt_auth = True
if os.path.exists(self.__G_DRIVE_TOKEN_FILE):
if os.path.exists('token.json'):
LOGGER.info("Authorizing with token.json file")
credentials = Credentials.from_authorized_user_file(self.__G_DRIVE_TOKEN_FILE, self.__OAUTH_SCOPE)
if credentials is None or not credentials.valid:
if credentials and credentials.expired and credentials.refresh_token:
credentials.refresh(Request())
return build('drive', 'v3', credentials=credentials, cache_discovery=False)
creds = Credentials.from_authorized_user_file('token.json', self.__OAUTH_SCOPE)
return build('drive', 'v3', credentials=creds, cache_discovery=False)
return None

@staticmethod
Expand Down Expand Up @@ -162,7 +157,7 @@ def setPerm(self, link, access):
try:
if access != "anyone":
self.__set_permission_email(file_id, access)
msg += "Added <code>{access}</code> as viewer"
msg += f"Added <code>{access}</code> as viewer"
else:
self.__set_permission_public(file_id)
msg += "Set permission to <code>Anyone with the link</code>"
Expand Down Expand Up @@ -263,23 +258,23 @@ def clone(self, link):
msg += f'\n<b>Type:</b> Folder'
msg += f'\n<b>SubFolders:</b> {self.total_folders}'
msg += f'\n<b>Files:</b> {self.total_files}'
msg += f'\n\n<a href="{self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id)}"><b>Drive Link</b></a>'
msg += f'\n\n<b><a href="{self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id)}">Drive Link</a></b>'
if INDEX_URL is not None:
url_path = requests.utils.quote(f'{meta.get("name")}', safe='')
url = f'{INDEX_URL}/{url_path}/'
msg += f' | <a href="{url}"><b>Index Link</b></a>'
msg += f'<b> | <a href="{url}">Index Link</a></b>'
else:
file = self.copyFile(meta.get('id'), parent_id)
msg += f'<b>Name:</b> <code>{file.get("name")}</code>'
if mime_type is None:
mime_type = 'File'
msg += f'\n<b>Size:</b> {get_readable_file_size(int(meta.get("size", 0)))}'
msg += f'\n<b>Type:</b> {mime_type}'
msg += f'\n\n<a href="{self.__G_DRIVE_BASE_DOWNLOAD_URL.format(file.get("id"))}"><b>Drive Link</b></a>'
msg += f'\n\n<b><a href="{self.__G_DRIVE_BASE_DOWNLOAD_URL.format(file.get("id"))}">Drive Link</a></b>'
if INDEX_URL is not None:
url_path = requests.utils.quote(f'{file.get("name")}', safe='')
url = f'{INDEX_URL}/{url_path}'
msg += f' | <a href="{url}"><b>Index Link</b></a>'
msg += f'<b> | <a href="{url}">Index Link</a></b>'
except Exception as err:
if isinstance(err, RetryError):
LOGGER.info(f"Total attempts: {err.last_attempt.attempt_number}")
Expand All @@ -296,7 +291,6 @@ def clone(self, link):
else:
msg = str(err)
LOGGER.error(msg)
return msg
return msg

def cloneFolder(self, name, local_path, folder_id, parent_id):
Expand Down
3 changes: 3 additions & 0 deletions bot/helper/telegram_helper/bot_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ def __init__(self):
self.UnauthorizeCommand = 'unauthorize'
self.UsersCommand = 'users'
self.ShellCommand = 'shell'
self.EvalCommand = 'eval'
self.ExecCommand = 'exec'
self.ClearLocalsCommand = 'clearlocals'
self.ExecHelpCommand = 'exechelp'
self.PingCommand = 'ping'
self.StatsCommand = 'stats'
Expand Down
14 changes: 7 additions & 7 deletions bot/modules/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,19 @@ def clear(update, context):
send("Cleared locals", bot, update)

def exechelp(update, context):
help_string = '''
help_string = f'''
<u><b>Executor</b></u>
• /eval: Run code in Python
• /exec: Run commands in Exec
• /clearlocals: Clear locals
• /{BotCommands.EvalCommand}: Run code in Python
• /{BotCommands.ExecCommand}: Run commands in Exec
• /{BotCommands.ClearLocalsCommand}: Clear locals
'''
sendMessage(help_string, context.bot, update.message)

eval_handler = CommandHandler('eval', evaluate,
eval_handler = CommandHandler(BotCommands.EvalCommand, evaluate,
filters=CustomFilters.owner_filter, run_async=True)
exec_handler = CommandHandler('exec', execute,
exec_handler = CommandHandler(BotCommands.ExecCommand, execute,
filters=CustomFilters.owner_filter, run_async=True)
clear_handler = CommandHandler('clearlocals', clear,
clear_handler = CommandHandler(BotCommands.ClearLocalsCommand, clear,
filters=CustomFilters.owner_filter, run_async=True)
exechelp_handler = CommandHandler(BotCommands.ExecHelpCommand, exechelp,
filters=CustomFilters.owner_filter, run_async=True)
Expand Down
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: "3.3"

services:
app:
build: .
command: bash start.sh
restart: on-failure
26 changes: 0 additions & 26 deletions dtoken.py

This file was deleted.

File renamed without changes.
28 changes: 28 additions & 0 deletions gen_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

# If modifying these scopes, delete the file token.json.
SCOPES = ["https://www.googleapis.com/auth/drive"]

creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
print("\n\033[1;96mtoken.json\033[m file exists")
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
print("\nGenerated \033[1;96mtoken.json\033[m file")

0 comments on commit c866569

Please sign in to comment.