Minor Changes

Signed-off-by: anasty17 <e.anastayyar@gmail.com>
This commit is contained in:
anasty17 2024-01-12 17:23:06 +02:00
parent 59cc026843
commit 023c595469
10 changed files with 80 additions and 77 deletions

View File

@ -184,7 +184,6 @@ Fill up rest of the fields. Meaning of each field is discussed below. **NOTE**:
- `SUDO_USERS`: Fill user_id of users whom you want to give sudo permission. Separate them by space. `Int`
- `DEFAULT_UPLOAD`: Whether `rc` to upload to `RCLONE_PATH` or `gd` to upload to `GDRIVE_ID`. Default is `gd`. Read More [HERE](https://github.com/anasty17/mirror-leech-telegram-bot/tree/master#upload).`Str`
- `STATUS_UPDATE_INTERVAL`: Time in seconds after which the progress/status message will be updated. Recommended `10` seconds at least. `Int`
- `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 disable auto message deletion. `Int`
- `STATUS_LIMIT`: Limit the no. of tasks shown in status message with buttons. Default is `10`. **NOTE**: Recommended limit is `4` tasks. `Int`
- `EXTENSION_FILTER`: File extensions that won't upload/clone. Separate them by space. `Str`
- `INCOMPLETE_TASK_NOTIFIER`: Get incomplete task messages after restart. Require database and superGroup. Default is `False`. `Bool`

View File

@ -263,12 +263,6 @@ if len(STATUS_UPDATE_INTERVAL) == 0:
else:
STATUS_UPDATE_INTERVAL = int(STATUS_UPDATE_INTERVAL)
AUTO_DELETE_MESSAGE_DURATION = environ.get("AUTO_DELETE_MESSAGE_DURATION", "")
if len(AUTO_DELETE_MESSAGE_DURATION) == 0:
AUTO_DELETE_MESSAGE_DURATION = 30
else:
AUTO_DELETE_MESSAGE_DURATION = int(AUTO_DELETE_MESSAGE_DURATION)
YT_DLP_OPTIONS = environ.get("YT_DLP_OPTIONS", "")
if len(YT_DLP_OPTIONS) == 0:
YT_DLP_OPTIONS = ""
@ -367,7 +361,6 @@ if len(RCLONE_SERVE_PASS) == 0:
config_dict = {
"AS_DOCUMENT": AS_DOCUMENT,
"AUTHORIZED_CHATS": AUTHORIZED_CHATS,
"AUTO_DELETE_MESSAGE_DURATION": AUTO_DELETE_MESSAGE_DURATION,
"BASE_URL": BASE_URL,
"BASE_URL_PORT": BASE_URL_PORT,
"BOT_TOKEN": BOT_TOKEN,

View File

@ -15,12 +15,15 @@ def _get_combined_info(result, start_time):
hosts = result[0].get("hosts")
bytesLoaded = 0
bytesTotal = 0
status = ""
for res in result:
st = res.get("status", "").lower()
if st and st != "finished":
status = st
bytesLoaded += res.get("bytesLoaded", 0)
bytesTotal += res.get("bytesTotal", 0)
if not status:
status = "UnknownError"
try:
speed = bytesLoaded / (time() - start_time)
eta = (bytesTotal - bytesLoaded) / speed

View File

@ -92,12 +92,11 @@ async def deleteMessage(message):
async def auto_delete_message(cmd_message=None, bot_message=None):
if config_dict["AUTO_DELETE_MESSAGE_DURATION"] != -1:
await sleep(config_dict["AUTO_DELETE_MESSAGE_DURATION"])
if cmd_message is not None:
await deleteMessage(cmd_message)
if bot_message is not None:
await deleteMessage(bot_message)
await sleep(60)
if cmd_message is not None:
await deleteMessage(cmd_message)
if bot_message is not None:
await deleteMessage(bot_message)
async def delete_status():

View File

@ -56,7 +56,6 @@ START = 0
STATE = "view"
handler_dict = {}
default_values = {
"AUTO_DELETE_MESSAGE_DURATION": 30,
"DOWNLOAD_DIR": "/usr/src/app/downloads/",
"LEECH_SPLIT_SIZE": MAX_SPLIT_SIZE,
"RSS_DELAY": 600,
@ -176,9 +175,6 @@ async def edit_variable(_, message, pre_message, key):
value = False
if key == "INCOMPLETE_TASK_NOTIFIER" and DATABASE_URL:
await DbManger().trunc_table("tasks")
elif key == "RSS_DELAY":
value = int(value)
addJob(value)
elif key == "DOWNLOAD_DIR":
if not value.endswith("/"):
value += "/"
@ -253,6 +249,8 @@ async def edit_variable(_, message, pre_message, key):
await rclone_serve_booter()
elif key in ["JD_EMAIL", "JD_PASS"]:
jdownloader.initiate()
elif key == "RSS_DELAY":
addJob()
async def edit_aria(_, message, pre_message, key):
@ -774,12 +772,6 @@ async def load_config():
STATUS_UPDATE_INTERVAL, update_status_message, key
)
AUTO_DELETE_MESSAGE_DURATION = environ.get("AUTO_DELETE_MESSAGE_DURATION", "")
if len(AUTO_DELETE_MESSAGE_DURATION) == 0:
AUTO_DELETE_MESSAGE_DURATION = 30
else:
AUTO_DELETE_MESSAGE_DURATION = int(AUTO_DELETE_MESSAGE_DURATION)
YT_DLP_OPTIONS = environ.get("YT_DLP_OPTIONS", "")
if len(YT_DLP_OPTIONS) == 0:
YT_DLP_OPTIONS = ""
@ -938,7 +930,6 @@ async def load_config():
{
"AS_DOCUMENT": AS_DOCUMENT,
"AUTHORIZED_CHATS": AUTHORIZED_CHATS,
"AUTO_DELETE_MESSAGE_DURATION": AUTO_DELETE_MESSAGE_DURATION,
"BASE_URL": BASE_URL,
"BASE_URL_PORT": BASE_URL_PORT,
"BOT_TOKEN": BOT_TOKEN,
@ -995,6 +986,7 @@ async def load_config():
if DATABASE_URL:
await DbManger().update_config(config_dict)
await gather(initiate_search_tools(), start_from_queued(), rclone_serve_booter())
addJob()
bot.add_handler(

View File

@ -9,6 +9,7 @@ from bot.helper.telegram_helper.message_utils import (
sendMessage,
auto_delete_message,
deleteMessage,
editMessage,
)
from bot.helper.ext_utils.status_utils import getTaskByGid, getAllTasks, MirrorStatus
from bot.helper.ext_utils.bot_utils import new_task
@ -79,26 +80,30 @@ async def cancel_all(status):
return True
def create_cancel_buttons():
buttons = button_build.ButtonMaker()
buttons.ibutton("Downloading", f"canall ms {MirrorStatus.STATUS_DOWNLOADING}")
buttons.ibutton("Uploading", f"canall ms {MirrorStatus.STATUS_UPLOADING}")
buttons.ibutton("Seeding", f"canall ms {MirrorStatus.STATUS_SEEDING}")
buttons.ibutton("Spltting", f"canall ms {MirrorStatus.STATUS_SPLITTING}")
buttons.ibutton("Cloning", f"canall ms {MirrorStatus.STATUS_CLONING}")
buttons.ibutton("Extracting", f"canall ms {MirrorStatus.STATUS_EXTRACTING}")
buttons.ibutton("Archiving", f"canall ms {MirrorStatus.STATUS_ARCHIVING}")
buttons.ibutton("QueuedDl", f"canall ms {MirrorStatus.STATUS_QUEUEDL}")
buttons.ibutton("QueuedUp", f"canall ms {MirrorStatus.STATUS_QUEUEUP}")
buttons.ibutton("Paused", f"canall ms {MirrorStatus.STATUS_PAUSED}")
buttons.ibutton("All", "canall ms all")
buttons.ibutton("Close", "canall close")
return buttons.build_menu(2)
async def cancell_all_buttons(_, message):
async with task_dict_lock:
count = len(task_dict)
if count == 0:
await sendMessage(message, "No active tasks!")
return
buttons = button_build.ButtonMaker()
buttons.ibutton("Downloading", f"canall {MirrorStatus.STATUS_DOWNLOADING}")
buttons.ibutton("Uploading", f"canall {MirrorStatus.STATUS_UPLOADING}")
buttons.ibutton("Seeding", f"canall {MirrorStatus.STATUS_SEEDING}")
buttons.ibutton("Spltting", f"canall {MirrorStatus.STATUS_SPLITTING}")
buttons.ibutton("Cloning", f"canall {MirrorStatus.STATUS_CLONING}")
buttons.ibutton("Extracting", f"canall {MirrorStatus.STATUS_EXTRACTING}")
buttons.ibutton("Archiving", f"canall {MirrorStatus.STATUS_ARCHIVING}")
buttons.ibutton("QueuedDl", f"canall {MirrorStatus.STATUS_QUEUEDL}")
buttons.ibutton("QueuedUp", f"canall {MirrorStatus.STATUS_QUEUEUP}")
buttons.ibutton("Paused", f"canall {MirrorStatus.STATUS_PAUSED}")
buttons.ibutton("All", "canall all")
buttons.ibutton("Close", "canall close")
button = buttons.build_menu(2)
button = create_cancel_buttons()
can_msg = await sendMessage(message, "Choose tasks to cancel.", button)
await auto_delete_message(message, can_msg)
@ -112,6 +117,18 @@ async def cancel_all_update(_, query):
if data[1] == "close":
await deleteMessage(reply_to)
await deleteMessage(message)
elif data[1] == "back":
button = create_cancel_buttons()
await editMessage(message, "Choose tasks to cancel.", button)
elif data[1] == "ms":
buttons = button_build.ButtonMaker()
buttons.ibutton("Yes!", f"canall {data[2]}")
buttons.ibutton("Back", "canall back all")
buttons.ibutton("Close", "canall close")
button = buttons.build_menu(2)
await editMessage(
message, f"Are you sure you want to cancel all {data[2]} tasks", button
)
else:
res = await cancel_all(data[1])
if not res:

View File

@ -182,7 +182,7 @@ async def rssSub(_, message, pre_event):
if scheduler.state == 2:
scheduler.resume()
elif is_sudo and not scheduler.running:
addJob(config_dict["RSS_DELAY"])
addJob()
scheduler.start()
@ -229,7 +229,7 @@ async def rssUpdate(_, message, pre_event, state):
if scheduler.state == 2:
scheduler.resume()
elif is_sudo and not scheduler.running:
addJob(config_dict["RSS_DELAY"])
addJob()
scheduler.start()
if is_sudo and DATABASE_URL and user_id != message.from_user.id:
await DbManger().rss_update(user_id)
@ -578,7 +578,7 @@ Timeout: 60 sec. Argument -c for command and options
if scheduler.state == 2:
scheduler.resume()
elif not scheduler.running:
addJob(config_dict["RSS_DELAY"])
addJob()
scheduler.start()
if DATABASE_URL:
await DbManger().rss_update_all()
@ -613,7 +613,7 @@ Timeout: 60 sec. Argument -c for command and options
elif data[1] == "start":
if not scheduler.running:
await query.answer()
addJob(config_dict["RSS_DELAY"])
addJob()
scheduler.start()
await updateRssMenu(query)
else:
@ -712,10 +712,10 @@ async def rssMonitor():
scheduler.pause()
def addJob(delay):
def addJob():
scheduler.add_job(
rssMonitor,
trigger=IntervalTrigger(seconds=delay),
trigger=IntervalTrigger(seconds=config_dict["RSS_DELAY"]),
id="0",
name="RSS",
misfire_grace_time=15,
@ -725,7 +725,7 @@ def addJob(delay):
)
addJob(config_dict["RSS_DELAY"])
addJob()
scheduler.start()
bot.add_handler(
MessageHandler(

View File

@ -37,7 +37,7 @@ async def mirror_status(_, message):
if count == 0:
currentTime = get_readable_time(time() - botStartTime)
free = get_readable_file_size(disk_usage(DOWNLOAD_DIR).free)
msg = f"No Active Tasks!\nEach user can get status for his tasks by me or user_id after cmd: /{BotCommands.StatusCommand} me"
msg = f"No Active Tasks!\nEach user can get status for his tasks by adding me or user_id after cmd: /{BotCommands.StatusCommand} me"
msg += (
f"\n<b>CPU:</b> {cpu_percent()}% | <b>FREE:</b> {free}"
f"\n<b>RAM:</b> {virtual_memory().percent}% | <b>UPTIME:</b> {currentTime}"

View File

@ -15,7 +15,6 @@ SUDO_USERS = "" # Require restart after changing it
STATUS_LIMIT = "10"
DEFAULT_UPLOAD = "gd"
STATUS_UPDATE_INTERVAL = "10"
AUTO_DELETE_MESSAGE_DURATION = "30"
FILELION_API = ""
STREAMWISH_API = ""
EXTENSION_FILTER = ""

View File

@ -1,11 +1,12 @@
# -*- encoding: utf-8 -*-
import hashlib
import hmac
import json
import time
from hashlib import sha256
from hmac import new
from json import dumps, loads, JSONDecodeError
from time import time
from urllib.parse import quote
import base64
import requests
from base64 import b64encode, b64decode
from requests import get, post
from requests.exceptions import RequestException
from Crypto.Cipher import AES
from .exception import (
@ -850,7 +851,7 @@ class Jddevice:
if (
self.__direct_connection_enabled
and self.__direct_connection_info is not None
and time.time() >= self.__direct_connection_cooldown
and time() >= self.__direct_connection_cooldown
):
return self.__direct_connect(path, http_action, params, action_url)
response = self.myjd.request_api(path, http_action, params, action_url)
@ -858,14 +859,14 @@ class Jddevice:
raise (MYJDConnectionException("No connection established\n"))
if (
self.__direct_connection_enabled
and time.time() >= self.__direct_connection_cooldown
and time() >= self.__direct_connection_cooldown
):
self.__refresh_direct_connections()
return response["data"]
def __direct_connect(self, path, http_action, params, action_url):
for conn in self.__direct_connection_info:
if time.time() > conn["cooldown"]:
if time() > conn["cooldown"]:
connection = conn["conn"]
api = "http://" + connection["ip"] + ":" + str(connection["port"])
response = self.myjd.request_api(
@ -877,9 +878,9 @@ class Jddevice:
self.__direct_connection_consecutive_failures = 0
return response["data"]
else:
conn["cooldown"] = time.time() + 60
conn["cooldown"] = time() + 60
self.__direct_connection_consecutive_failures += 1
self.__direct_connection_cooldown = time.time() + (
self.__direct_connection_cooldown = time() + (
60 * self.__direct_connection_consecutive_failures
)
response = self.myjd.request_api(path, http_action, params, action_url)
@ -903,7 +904,7 @@ class Myjdapi:
This functions initializates the myjdapi object.
"""
self.__request_id = int(time.time() * 1000)
self.__request_id = int(time() * 1000)
self.__api_url = "https://api.jdownloader.org"
self.__app_key = "http://git.io/vmcsk"
self.__api_version = 1
@ -941,7 +942,7 @@ class Myjdapi:
:return: secret hash
"""
secret_hash = hashlib.sha256()
secret_hash = sha256()
secret_hash.update(
email.lower().encode("utf-8")
+ password.encode("utf-8")
@ -958,10 +959,10 @@ class Myjdapi:
old_token = self.__login_secret
else:
old_token = self.__server_encryption_token
new_token = hashlib.sha256()
new_token = sha256()
new_token.update(old_token + bytearray.fromhex(self.__session_token))
self.__server_encryption_token = new_token.digest()
new_token = hashlib.sha256()
new_token = sha256()
new_token.update(self.__device_secret + bytearray.fromhex(self.__session_token))
self.__device_encryption_token = new_token.digest()
@ -972,7 +973,7 @@ class Myjdapi:
:param key:
:param data:
"""
signature = hmac.new(key, data.encode("utf-8"), hashlib.sha256)
signature = new(key, data.encode("utf-8"), sha256)
return signature.hexdigest()
def __decrypt(self, secret_token, data):
@ -985,7 +986,7 @@ class Myjdapi:
init_vector = secret_token[: len(secret_token) // 2]
key = secret_token[len(secret_token) // 2 :]
decryptor = AES.new(key, AES.MODE_CBC, init_vector)
return UNPAD(decryptor.decrypt(base64.b64decode(data)))
return UNPAD(decryptor.decrypt(b64decode(data)))
def __encrypt(self, secret_token, data):
"""
@ -998,14 +999,14 @@ class Myjdapi:
init_vector = secret_token[: len(secret_token) // 2]
key = secret_token[len(secret_token) // 2 :]
encryptor = AES.new(key, AES.MODE_CBC, init_vector)
encrypted_data = base64.b64encode(encryptor.encrypt(data))
encrypted_data = b64encode(encryptor.encrypt(data))
return encrypted_data.decode("utf-8")
def update_request_id(self):
"""
Updates Request_Id
"""
self.__request_id = int(time.time())
self.__request_id = int(time())
def connect(self, email, password):
"""Establish connection to api
@ -1163,7 +1164,7 @@ class Myjdapi:
)
]
query = query[0] + "&".join(query[1:])
encrypted_response = requests.get(api + query, timeout=3, verify=False)
encrypted_response = get(api + query, timeout=3, verify=False)
else:
params_request = []
if params is not None:
@ -1171,7 +1172,7 @@ class Myjdapi:
if isinstance(param, (str, list)):
params_request += [param]
elif isinstance(param, (dict, bool)):
params_request += [json.dumps(param)]
params_request += [dumps(param)]
else:
params_request += [str(param)]
params_request = {
@ -1180,33 +1181,33 @@ class Myjdapi:
"params": params_request,
"rid": self.__request_id,
}
data = json.dumps(params_request)
data = dumps(params_request)
# Removing quotes around null elements.
data = data.replace('"null"', "null")
data = data.replace("'null'", "null")
encrypted_data = self.__encrypt(self.__device_encryption_token, data)
request_url = api + action + path if action is not None else api + path
try:
encrypted_response = requests.post(
encrypted_response = post(
request_url,
headers={"Content-Type": "application/aesjson-jd; charset=utf-8"},
data=encrypted_data,
timeout=3,
verify=False,
)
except requests.exceptions.RequestException as e:
except RequestException as e:
return None
if encrypted_response.status_code != 200:
try:
error_msg = json.loads(encrypted_response.text)
except json.JSONDecodeError:
error_msg = loads(encrypted_response.text)
except JSONDecodeError:
try:
error_msg = json.loads(
error_msg = loads(
self.__decrypt(
self.__device_encryption_token, encrypted_response.text
)
)
except json.JSONDecodeError as exc:
except JSONDecodeError as exc:
raise MYJDDecodeException(
"Failed to decode response: {}", encrypted_response.text
) from exc
@ -1238,7 +1239,7 @@ class Myjdapi:
response = self.__decrypt(
self.__device_encryption_token, encrypted_response.text
)
jsondata = json.loads(response.decode("utf-8"))
jsondata = loads(response.decode("utf-8"))
if jsondata["rid"] != self.__request_id:
self.update_request_id()
return None