Skip to content

Commit

Permalink
v2.5 (breakdowns#10)
Browse files Browse the repository at this point in the history
- /list command now results will be uploaded to telegra.ph
- Auto generate Telegraph Token
- Added Inline Buttons
- Update /stats command
  • Loading branch information
breakdowns authored Mar 3, 2021
1 parent 01bfc52 commit 35ad3e5
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 56 deletions.
7 changes: 7 additions & 0 deletions bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import telegram.ext as tg
from dotenv import load_dotenv
from pyrogram import Client
from telegraph import Telegraph
import socket

socket.setdefaulttimeout(600)
Expand Down Expand Up @@ -105,6 +106,12 @@ def getConfig(name: str):
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()
#Generate Telegraph Token
LOGGER.info("Generating Telegraph Token")
telegraph = Telegraph()
telegraph.create_account(short_name="mirror_bot")
telegraph_token = telegraph.get_access_token()

try:
INDEX_URL = getConfig('INDEX_URL')
if len(INDEX_URL) == 0:
Expand Down
24 changes: 16 additions & 8 deletions bot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ def stats(update, context):
total = get_readable_file_size(total)
used = get_readable_file_size(used)
free = get_readable_file_size(free)
sent = get_readable_file_size(psutil.net_io_counters().bytes_sent)
recv = get_readable_file_size(psutil.net_io_counters().bytes_recv)
cpuUsage = psutil.cpu_percent(interval=0.5)
memory = psutil.virtual_memory().percent
stats = f'Bot Uptime: {currentTime}\n' \
f'Total disk space: {total}\n' \
f'Used: {used}\n' \
f'Free: {free}\n' \
f'CPU: {cpuUsage}%\n' \
f'RAM: {memory}%'
disk = psutil.disk_usage('/').percent
stats = f'<b>Bot Uptime:</b> {currentTime}\n' \
f'<b>Total disk space:</b> {total}\n' \
f'<b>Used:</b> {used} ' \
f'<b>Free:</b> {free}\n\n' \
f'📊Data Usage📊\n<b>Upload:</b> {sent}\n' \
f'<b>Down:</b> {recv}\n\n' \
f'<b>CPU:</b> {cpuUsage}%\n' \
f'<b>RAM:</b> {memory}%\n' \
f'<b>Disk:</b> {disk}%'
sendMessage(stats, context.bot, update)


Expand Down Expand Up @@ -74,9 +80,11 @@ def bot_help(update, context):
/{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.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.TarMirrorCommand} [download_url][magnet_link]: Start mirroring and upload the archived (.tar) version of the download
/{BotCommands.WatchCommand} [youtube-dl supported link]: Mirror through youtube-dl
Expand Down
113 changes: 87 additions & 26 deletions bot/helper/mirror_utils/upload_utils/gdriveTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@
from googleapiclient.http import MediaFileUpload
from tenacity import *

from telegram import InlineKeyboardMarkup
from bot.helper.telegram_helper import button_build
from telegraph import Telegraph
from bot import parent_id, DOWNLOAD_DIR, IS_TEAM_DRIVE, INDEX_URL, \
USE_SERVICE_ACCOUNTS, download_dict
USE_SERVICE_ACCOUNTS, download_dict, telegraph_token
from bot.helper.ext_utils.bot_utils import *
from bot.helper.ext_utils.fs_utils import get_mime_type

LOGGER = logging.getLogger(__name__)
logging.getLogger('googleapiclient.discovery').setLevel(logging.ERROR)
SERVICE_ACCOUNT_INDEX = 0

TELEGRAPHLIMIT = 95

class GoogleDriveHelper:
def __init__(self, name=None, listener=None):
Expand All @@ -51,6 +54,8 @@ def __init__(self, name=None, listener=None):
self.updater = None
self.name = name
self.update_interval = 3
self.telegraph_content = []
self.path = []

def cancel(self):
self.is_cancelled = True
Expand Down Expand Up @@ -311,29 +316,32 @@ def clone(self, link):
if meta.get("mimeType") == self.__G_DRIVE_DIR_MIME_TYPE:
dir_id = self.create_directory(meta.get('name'), parent_id)
result = self.cloneFolder(meta.get('name'), meta.get('name'), meta.get('id'), dir_id)
msg += f'<a href="{self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id)}">{meta.get("name")}</a>' \
f' ({get_readable_file_size(self.transferred_size)})'
msg += f'<b>Filename : </b><code>{meta.get("name")}</code>\n<b>Size : </b>{get_readable_file_size(self.transferred_size)}'
buttons = button_build.ButtonMaker()
buttons.buildbutton("✨Drive Link✨", self.__G_DRIVE_DIR_BASE_DOWNLOAD_URL.format(dir_id))
if INDEX_URL is not None:
url = requests.utils.requote_uri(f'{INDEX_URL}/{meta.get("name")}/')
msg += f' | <a href="{url}"> Index URL</a>'
buttons.buildbutton("⚡Index Link⚡", url)
else:
file = self.copyFile(meta.get('id'), parent_id)
msg += f'<a href="{self.__G_DRIVE_BASE_DOWNLOAD_URL.format(file.get("id"))}">{file.get("name")}</a>'
msg += f'<b>Filename : </b><code>{file.get("name")}</code>'
buttons = button_build.ButtonMaker()
buttons.buildbutton("✨Drive Link✨", self.__G_DRIVE_BASE_DOWNLOAD_URL.format(file.get("id")))
try:
msg += f' ({get_readable_file_size(int(meta.get("size")))}) '
msg += f'\n<b>Size : </b><code>{get_readable_file_size(int(meta.get("size")))}</code>'
except TypeError:
pass
if INDEX_URL is not None:
url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}')
msg += f' | <a href="{url}"> Index URL</a>'
buttons.buildbutton("⚡Index Link⚡", url)
except Exception as err:
if isinstance(err, RetryError):
LOGGER.info(f"Total Attempts: {err.last_attempt.attempt_number}")
err = err.last_attempt.exception()
err = str(err).replace('>', '').replace('<', '')
LOGGER.error(err)
return err
return msg
return msg, InlineKeyboardMarkup(buttons.build_menu(2))

def cloneFolder(self, name, local_path, folder_id, parent_id):
LOGGER.info(f"Syncing: {local_path}")
Expand Down Expand Up @@ -424,6 +432,26 @@ def authorize(self):
f'accounts/{SERVICE_ACCOUNT_INDEX}.json',
scopes=self.__OAUTH_SCOPE)
return build('drive', 'v3', credentials=credentials, cache_discovery=False)
def edit_telegraph(self):
nxt_page = 1
prev_page = 0
for content in self.telegraph_content :
if nxt_page == 1 :
content += f'<b><a href="https://telegra.ph/{self.path[nxt_page]}">Next</a></b>'
nxt_page += 1
else :
if prev_page <= self.num_of_path:
content += f'<b><a href="https://telegra.ph/{self.path[prev_page]}">Prev</a></b>'
prev_page += 1
if nxt_page < self.num_of_path:
content += f'<b> | <a href="https://telegra.ph/{self.path[nxt_page]}">Next</a></b>'
nxt_page += 1
Telegraph(access_token=telegraph_token).edit_page(path = self.path[prev_page],
title = 'Mirror Bot Search',
author_name='Mirror Bot',
author_url='https://github.com/magneto261290/magneto-python-ariap',
html_content=content)
return

def escapes(self, str):
chars = ['\\', "'", '"', r'\a', r'\b', r'\f', r'\n', r'\r', r'\t']
Expand All @@ -440,22 +468,55 @@ def drive_list(self, fileName):
includeTeamDriveItems=True,
q=query,
spaces='drive',
pageSize=20,
pageSize=200,
fields='files(id, name, mimeType, size)',
orderBy='modifiedTime desc').execute()
for file in response.get('files', []):
if file.get(
'mimeType') == "application/vnd.google-apps.folder": # Detect Whether Current Entity is a Folder or File.
msg += f"⁍ <a href='https://drive.google.com/drive/folders/{file.get('id')}'>{file.get('name')}" \
f"</a> (folder)"
if INDEX_URL is not None:
url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}/')
msg += f' | <a href="{url}"> Index URL</a>'
else:
msg += f"⁍ <a href='https://drive.google.com/uc?id={file.get('id')}" \
f"&export=download'>{file.get('name')}</a> ({get_readable_file_size(int(file.get('size')))})"
if INDEX_URL is not None:
url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}')
msg += f' | <a href="{url}"> Index URL</a>'
msg += '\n'
return msg
content_count = 0
if response["files"]:
msg += f'<h4>Results : {fileName}</h4><br><br>'
for file in response.get('files', []):
if file.get('mimeType') == "application/vnd.google-apps.folder": # Detect Whether Current Entity is a Folder or File.
msg += f"⁍<code>{file.get('name')}<br>(folder📁)</code><br>" \
f"<b><a href='https://drive.google.com/drive/folders/{file.get('id')}'>Drive Link</a></b>"
if INDEX_URL is not None:
url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}/')
msg += f' <b>| <a href="{url}">Index Link</a></b>'
else:
msg += f"⁍<code>{file.get('name')}<br>({get_readable_file_size(int(file.get('size')))})📄</code><br>" \
f"<b><a href='https://drive.google.com/uc?id={file.get('id')}&export=download'>Drive Link</a></b>"
if INDEX_URL is not None:
url = requests.utils.requote_uri(f'{INDEX_URL}/{file.get("name")}')
msg += f' <b>| <a href="{url}">Index Link</a></b>'
msg += '<br><br>'
content_count += 1
if content_count == TELEGRAPHLIMIT :
self.telegraph_content.append(msg)
msg = ""
content_count = 0

if msg != '':
self.telegraph_content.append(msg)

if len(self.telegraph_content) == 0:
return "No Result Found :(", None

for content in self.telegraph_content :
self.path.append(Telegraph(access_token=telegraph_token).create_page(
title = 'Slam Mirror Bot Search',
author_name='Slam Mirror Bot',
author_url='https://github.com/breakdowns/slam-mirrorbot',
html_content=content
)['path'])

self.num_of_path = len(self.path)
if self.num_of_path > 1:
self.edit_telegraph()

msg = f"<b>Search Results For {fileName} 👇</b>"
buttons = button_build.ButtonMaker()
buttons.buildbutton("HERE", f"https://telegra.ph/{self.path[0]}")

return msg, InlineKeyboardMarkup(buttons.build_menu(1))

else :
return '', ''
16 changes: 16 additions & 0 deletions bot/helper/telegram_helper/button_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from telegram import InlineKeyboardButton

class ButtonMaker:
def __init__(self):
self.button = []

def buildbutton(self, key, link):
self.button.append(InlineKeyboardButton(text = key, url = link))

def build_menu(self, n_cols, footer_buttons=None, header_buttons=None):
menu = [self.button[i:i + n_cols] for i in range(0, len(self.button), n_cols)]
if header_buttons:
menu.insert(0, header_buttons)
if footer_buttons:
menu.append(footer_buttons)
return menu
10 changes: 7 additions & 3 deletions bot/helper/telegram_helper/message_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from telegram import InlineKeyboardMarkup
from telegram.message import Message
from telegram.update import Update
import time
Expand All @@ -15,12 +16,15 @@ def sendMessage(text: str, bot, update: Update):
text=text, parse_mode='HTMl')
except Exception as e:
LOGGER.error(str(e))
def sendMarkup(text: str, bot, update: Update, reply_markup: InlineKeyboardMarkup):
return bot.send_message(update.message.chat_id,
reply_to_message_id=update.message.message_id,
text=text, reply_markup=reply_markup, parse_mode='HTMl')


def editMessage(text: str, message: Message):
def editMessage(text: str, message: Message, reply_markup=None):
try:
bot.edit_message_text(text=text, message_id=message.message_id,
chat_id=message.chat.id,
chat_id=message.chat.id,reply_markup=reply_markup,
parse_mode='HTMl')
except Exception as e:
LOGGER.error(str(e))
Expand Down
4 changes: 2 additions & 2 deletions bot/modules/clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def cloneNode(update,context):
link = args[1]
msg = sendMessage(f"Cloning: <code>{link}</code>",context.bot,update)
gd = GoogleDriveHelper()
result = gd.clone(link)
result, button = gd.clone(link)
deleteMessage(context.bot,msg)
sendMessage(result,context.bot,update)
sendMarkup(result,context.bot,update,button)
else:
sendMessage("Provide G-Drive Shareable Link to Clone.",context.bot,update)

Expand Down
27 changes: 14 additions & 13 deletions bot/modules/list.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
from telegram.ext import CommandHandler, run_async
from bot.helper.mirror_utils.upload_utils.gdriveTools import GoogleDriveHelper
from bot import LOGGER, dispatcher
from bot.helper.telegram_helper.message_utils import auto_delete_message, sendMessage
from bot.helper.telegram_helper.message_utils import sendMessage, sendMarkup, editMessage
from bot.helper.telegram_helper.filters import CustomFilters
import threading
from bot.helper.telegram_helper.bot_commands import BotCommands

@run_async
def list_drive(update,context):
if update.message.text == f'/{BotCommands.ListCommand}':
sendMessage(f'Send a search key along with {BotCommands.ListCommand} command', context.bot, update)
message = update.message.text
search = message.split(' ',maxsplit=1)[1]
LOGGER.info(f"Searching: {search}")
gdrive = GoogleDriveHelper(None)
msg = gdrive.drive_list(search)
if msg:
reply_message = sendMessage(msg, context.bot, update)
else:
reply_message = sendMessage('No result found', context.bot, update)
try:
search = update.message.text.split(' ',maxsplit=1)[1]
LOGGER.info(f"Searching: {search}")
reply = sendMessage('Searching..... Please wait!', context.bot, update)
gdrive = GoogleDriveHelper(None)
msg, button = gdrive.drive_list(search)

threading.Thread(target=auto_delete_message, args=(context.bot, update.message, reply_message)).start()
if button:
editMessage(msg, reply, button)
else:
editMessage('No result found', reply, button)

except IndexError:
sendMessage('Send a search key along with command', context.bot, update)


list_handler = CommandHandler(BotCommands.ListCommand, list_drive,filters=CustomFilters.authorized_chat | CustomFilters.authorized_user)
Expand Down
12 changes: 8 additions & 4 deletions bot/modules/mirror.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import requests
from telegram.ext import CommandHandler, run_async
from telegram import InlineKeyboardMarkup

from bot import Interval, INDEX_URL, BLOCK_MEGA_LINKS
from bot import dispatcher, DOWNLOAD_DIR, DOWNLOAD_STATUS_UPDATE_INTERVAL, download_dict, download_dict_lock
Expand All @@ -18,6 +19,7 @@
from bot.helper.telegram_helper.bot_commands import BotCommands
from bot.helper.telegram_helper.filters import CustomFilters
from bot.helper.telegram_helper.message_utils import *
from bot.helper.telegram_helper import button_build
import pathlib
import os
import subprocess
Expand Down Expand Up @@ -137,26 +139,28 @@ def onUploadProgress(self):

def onUploadComplete(self, link: str):
with download_dict_lock:
msg = f'<a href="{link}">{download_dict[self.uid].name()}</a> ({download_dict[self.uid].size()})'
msg = f'<b>Filename : </b><code>{download_dict[self.uid].name()}</code>\n<b>Size : </b><code>{download_dict[self.uid].size()}</code>'
buttons = button_build.ButtonMaker()
buttons.buildbutton("✨Drive Link✨", link)
LOGGER.info(f'Done Uploading {download_dict[self.uid].name()}')
if INDEX_URL is not None:
share_url = requests.utils.requote_uri(f'{INDEX_URL}/{download_dict[self.uid].name()}')
if os.path.isdir(f'{DOWNLOAD_DIR}/{self.uid}/{download_dict[self.uid].name()}'):
share_url += '/'
msg += f'\n\nShareable link: <a href="{share_url}">here</a>'
buttons.buildbutton("⚡Index Link⚡", share_url)
if self.message.from_user.username:
uname = f"@{self.message.from_user.username}"
else:
uname = f'<a href="tg://user?id={self.message.from_user.id}">{self.message.from_user.first_name}</a>'
if uname is not None:
msg += f'\ncc : {uname}'
msg += f'\n\ncc : {uname}'
try:
fs_utils.clean_download(download_dict[self.uid].path())
except FileNotFoundError:
pass
del download_dict[self.uid]
count = len(download_dict)
sendMessage(msg, self.bot, self.update)
sendMarkup(msg, self.bot, self.update, InlineKeyboardMarkup(buttons.build_menu(2)))
if count == 0:
self.clean()
else:
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ natsort
aiohttp
speedtest-cli>=2.1.2
messages
lxml
telegraph

0 comments on commit 35ad3e5

Please sign in to comment.