Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
anasty17
GitHub Repository: anasty17/mirror-leech-telegram-bot
Path: blob/master/bot/helper/ext_utils/status_utils.py
1630 views
1
from html import escape
2
from psutil import virtual_memory, cpu_percent, disk_usage
3
from time import time
4
from asyncio import iscoroutinefunction, gather
5
6
from ... import task_dict, task_dict_lock, bot_start_time, status_dict, DOWNLOAD_DIR
7
from ...core.config_manager import Config
8
from ..telegram_helper.button_build import ButtonMaker
9
from ..telegram_helper.bot_commands import BotCommands
10
11
SIZE_UNITS = ["B", "KB", "MB", "GB", "TB", "PB"]
12
13
14
class MirrorStatus:
15
STATUS_UPLOAD = "Upload"
16
STATUS_DOWNLOAD = "Download"
17
STATUS_CLONE = "Clone"
18
STATUS_QUEUEDL = "QueueDl"
19
STATUS_QUEUEUP = "QueueUp"
20
STATUS_PAUSED = "Pause"
21
STATUS_ARCHIVE = "Archive"
22
STATUS_EXTRACT = "Extract"
23
STATUS_SPLIT = "Split"
24
STATUS_CHECK = "CheckUp"
25
STATUS_SEED = "Seed"
26
STATUS_SAMVID = "SamVid"
27
STATUS_CONVERT = "Convert"
28
STATUS_FFMPEG = "FFmpeg"
29
30
31
STATUSES = {
32
"ALL": "All",
33
"DL": MirrorStatus.STATUS_DOWNLOAD,
34
"UP": MirrorStatus.STATUS_UPLOAD,
35
"QD": MirrorStatus.STATUS_QUEUEDL,
36
"QU": MirrorStatus.STATUS_QUEUEUP,
37
"AR": MirrorStatus.STATUS_ARCHIVE,
38
"EX": MirrorStatus.STATUS_EXTRACT,
39
"SD": MirrorStatus.STATUS_SEED,
40
"CL": MirrorStatus.STATUS_CLONE,
41
"CM": MirrorStatus.STATUS_CONVERT,
42
"SP": MirrorStatus.STATUS_SPLIT,
43
"SV": MirrorStatus.STATUS_SAMVID,
44
"FF": MirrorStatus.STATUS_FFMPEG,
45
"PA": MirrorStatus.STATUS_PAUSED,
46
"CK": MirrorStatus.STATUS_CHECK,
47
}
48
49
50
async def get_task_by_gid(gid: str):
51
async with task_dict_lock:
52
for tk in task_dict.values():
53
if hasattr(tk, "seeding"):
54
await tk.update()
55
if tk.gid() == gid:
56
return tk
57
return None
58
59
60
async def get_specific_tasks(status, user_id):
61
if status == "All":
62
if user_id:
63
return [tk for tk in task_dict.values() if tk.listener.user_id == user_id]
64
else:
65
return list(task_dict.values())
66
tasks_to_check = (
67
[tk for tk in task_dict.values() if tk.listener.user_id == user_id]
68
if user_id
69
else list(task_dict.values())
70
)
71
coro_tasks = []
72
coro_tasks.extend(tk for tk in tasks_to_check if iscoroutinefunction(tk.status))
73
coro_statuses = await gather(*[tk.status() for tk in coro_tasks])
74
result = []
75
coro_index = 0
76
for tk in tasks_to_check:
77
if tk in coro_tasks:
78
st = coro_statuses[coro_index]
79
coro_index += 1
80
else:
81
st = tk.status()
82
if (st == status) or (
83
status == MirrorStatus.STATUS_DOWNLOAD and st not in STATUSES.values()
84
):
85
result.append(tk)
86
return result
87
88
89
async def get_all_tasks(req_status: str, user_id):
90
async with task_dict_lock:
91
return await get_specific_tasks(req_status, user_id)
92
93
94
def get_readable_file_size(size_in_bytes):
95
if not size_in_bytes:
96
return "0B"
97
98
index = 0
99
while size_in_bytes >= 1024 and index < len(SIZE_UNITS) - 1:
100
size_in_bytes /= 1024
101
index += 1
102
103
return f"{size_in_bytes:.2f}{SIZE_UNITS[index]}"
104
105
106
def get_readable_time(seconds: int):
107
periods = [("d", 86400), ("h", 3600), ("m", 60), ("s", 1)]
108
result = ""
109
for period_name, period_seconds in periods:
110
if seconds >= period_seconds:
111
period_value, seconds = divmod(seconds, period_seconds)
112
result += f"{int(period_value)}{period_name}"
113
return result
114
115
116
def time_to_seconds(time_duration):
117
try:
118
parts = time_duration.split(":")
119
if len(parts) == 3:
120
hours, minutes, seconds = map(float, parts)
121
elif len(parts) == 2:
122
hours = 0
123
minutes, seconds = map(float, parts)
124
elif len(parts) == 1:
125
hours = 0
126
minutes = 0
127
seconds = float(parts[0])
128
else:
129
return 0
130
return hours * 3600 + minutes * 60 + seconds
131
except:
132
return 0
133
134
135
def speed_string_to_bytes(size_text: str):
136
size = 0
137
size_text = size_text.lower()
138
if "k" in size_text:
139
size += float(size_text.split("k")[0]) * 1024
140
elif "m" in size_text:
141
size += float(size_text.split("m")[0]) * 1048576
142
elif "g" in size_text:
143
size += float(size_text.split("g")[0]) * 1073741824
144
elif "t" in size_text:
145
size += float(size_text.split("t")[0]) * 1099511627776
146
elif "b" in size_text:
147
size += float(size_text.split("b")[0])
148
return size
149
150
151
def get_progress_bar_string(pct):
152
pct = float(pct.strip("%"))
153
p = min(max(pct, 0), 100)
154
cFull = int(p // 8)
155
p_str = "■" * cFull
156
p_str += "□" * (12 - cFull)
157
return f"[{p_str}]"
158
159
160
async def get_readable_message(sid, is_user, page_no=1, status="All", page_step=1):
161
msg = ""
162
button = None
163
164
tasks = await get_specific_tasks(status, sid if is_user else None)
165
166
STATUS_LIMIT = Config.STATUS_LIMIT
167
tasks_no = len(tasks)
168
pages = (max(tasks_no, 1) + STATUS_LIMIT - 1) // STATUS_LIMIT
169
if page_no > pages:
170
page_no = (page_no - 1) % pages + 1
171
status_dict[sid]["page_no"] = page_no
172
elif page_no < 1:
173
page_no = pages - (abs(page_no) % pages)
174
status_dict[sid]["page_no"] = page_no
175
start_position = (page_no - 1) * STATUS_LIMIT
176
177
for index, task in enumerate(
178
tasks[start_position : STATUS_LIMIT + start_position], start=1
179
):
180
if status != "All":
181
tstatus = status
182
elif iscoroutinefunction(task.status):
183
tstatus = await task.status()
184
else:
185
tstatus = task.status()
186
if task.listener.is_super_chat:
187
msg += f"<b>{index + start_position}.<a href='{task.listener.message.link}'>{tstatus}</a>: </b>"
188
else:
189
msg += f"<b>{index + start_position}.{tstatus}: </b>"
190
msg += f"<code>{escape(f'{task.name()}')}</code>"
191
if task.listener.subname:
192
msg += f"\n<i>{task.listener.subname}</i>"
193
if (
194
tstatus not in [MirrorStatus.STATUS_SEED, MirrorStatus.STATUS_QUEUEUP]
195
and task.listener.progress
196
):
197
progress = task.progress()
198
msg += f"\n{get_progress_bar_string(progress)} {progress}"
199
if task.listener.subname:
200
subsize = f"/{get_readable_file_size(task.listener.subsize)}"
201
ac = len(task.listener.files_to_proceed)
202
count = f"{task.listener.proceed_count}/{ac or '?'}"
203
else:
204
subsize = ""
205
count = ""
206
msg += f"\n<b>Processed:</b> {task.processed_bytes()}{subsize}"
207
if count:
208
msg += f"\n<b>Count:</b> {count}"
209
msg += f"\n<b>Size:</b> {task.size()}"
210
msg += f"\n<b>Speed:</b> {task.speed()}"
211
msg += f"\n<b>ETA:</b> {task.eta()}"
212
if (
213
tstatus == MirrorStatus.STATUS_DOWNLOAD
214
and task.listener.is_torrent
215
or task.listener.is_qbit
216
):
217
try:
218
msg += f"\n<b>Seeders:</b> {task.seeders_num()} | <b>Leechers:</b> {task.leechers_num()}"
219
except:
220
pass
221
elif tstatus == MirrorStatus.STATUS_SEED:
222
msg += f"\n<b>Size: </b>{task.size()}"
223
msg += f"\n<b>Speed: </b>{task.seed_speed()}"
224
msg += f"\n<b>Uploaded: </b>{task.uploaded_bytes()}"
225
msg += f"\n<b>Ratio: </b>{task.ratio()}"
226
msg += f" | <b>Time: </b>{task.seeding_time()}"
227
else:
228
msg += f"\n<b>Size: </b>{task.size()}"
229
msg += f"\n<code>/{BotCommands.CancelTaskCommand[1]} {task.gid()}</code>\n\n"
230
231
if len(msg) == 0:
232
if status == "All":
233
return None, None
234
else:
235
msg = f"No Active {status} Tasks!\n\n"
236
buttons = ButtonMaker()
237
if not is_user:
238
buttons.data_button("📜", f"status {sid} ov", position="header")
239
if len(tasks) > STATUS_LIMIT:
240
msg += f"<b>Page:</b> {page_no}/{pages} | <b>Tasks:</b> {tasks_no} | <b>Step:</b> {page_step}\n"
241
buttons.data_button("<<", f"status {sid} pre", position="header")
242
buttons.data_button(">>", f"status {sid} nex", position="header")
243
if tasks_no > 30:
244
for i in [1, 2, 4, 6, 8, 10, 15]:
245
buttons.data_button(i, f"status {sid} ps {i}", position="footer")
246
if status != "All" or tasks_no > 20:
247
for label, status_value in list(STATUSES.items()):
248
if status_value != status:
249
buttons.data_button(label, f"status {sid} st {status_value}")
250
buttons.data_button("♻️", f"status {sid} ref", position="header")
251
button = buttons.build_menu(8)
252
msg += f"<b>CPU:</b> {cpu_percent()}% | <b>FREE:</b> {get_readable_file_size(disk_usage(DOWNLOAD_DIR).free)}"
253
msg += f"\n<b>RAM:</b> {virtual_memory().percent}% | <b>UPTIME:</b> {get_readable_time(time() - bot_start_time)}"
254
return msg, button
255
256