archiver / utils /progress_formatter.py
KHALED-ALIM
โšก ุชุณุฑูŠุน ูƒู„ ุงู„ุนู…ู„ูŠุงุช + ุชุทูˆูŠุฑ ุดุงู…ู„ ู„ู„ุฑุณุงุฆู„ ูˆุงู„ุฃุฒุฑุงุฑ
bf1c6f2
Raw
History Blame Contribute Delete
7.22 kB
"""Build detailed progress messages shown to the admin in Telegram โ€” per-stage."""
from __future__ import annotations
from models.schemas import DownloadProgress
from utils.file_utils import format_size as _fmt_size
_PROGRESS_BAR_LENGTH = 20
def _bar(percent: float) -> str:
filled = int(percent / 100 * _PROGRESS_BAR_LENGTH)
empty = _PROGRESS_BAR_LENGTH - filled
return "โ–ˆ" * filled + "โ–‘" * empty
def _eta(seconds: float) -> str:
m, s = divmod(int(seconds), 60)
h, m = divmod(m, 60)
if h:
return f"{h}h {m}m"
if m:
return f"{m}m {s}s"
return f"{s}s"
def _speed_line(bps: float) -> str:
mb_s = bps / 1_048_576
return f"{mb_s:.1f} MB/s ({mb_s * 8:.1f} Mbps)"
def _header(status: str) -> str:
headers = {
"downloading": "โฌ‡๏ธ **ุชุญู…ูŠู„ ุงู„ู…ู„ู ู…ู† ุชู„ุบุฑุงู…**",
"processing": "๐Ÿ”„ **ู…ุนุงู„ุฌุฉ ุงู„ููŠุฏูŠูˆ (FFmpeg)**",
"uploading": "โ˜๏ธ **ุฑูุน ุงู„ู…ู„ู ุฅู„ู‰ StreamTape**",
"telegram_upload": "๐Ÿ“ค **ุฑูุน ู†ุณุฎ ุงุญุชูŠุงุทูŠุฉ ุฅู„ู‰ ุชู„ุบุฑุงู…**",
"archiving": "๐Ÿ—„๏ธ **ุฃุฑุดูุฉ ููŠ ู‚ุงุนุฏุฉ ุงู„ุจูŠุงู†ุงุช**",
"done": "โœ… **ุงูƒุชู…ู„ ุจู†ุฌุงุญ! ๐ŸŽ‰**",
"error": "โŒ **ุญุฏุซ ุฎุทุฃ!**",
}
return headers.get(status, "โณ **ุฌุงุฑูŠ ุงู„ุนู…ู„...**")
def format_progress_message(p: DownloadProgress) -> str:
title = _header(p.status)
lines: list[str] = [
"โ”" * 28,
title,
"โ”" * 28,
]
# โ”€โ”€ downloading โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
if p.status == "downloading":
lines.append("")
lines.append(f"๐Ÿ“ฆ **ุงู„ุญุฌู… ุงู„ูƒู„ูŠ:** `{_fmt_size(p.total)}`")
if p.downloaded > 0:
lines.append(f"โฌ‡๏ธ **ุชู… ุงู„ุชุญู…ูŠู„:** `{_fmt_size(p.downloaded)}` ู…ู† `{_fmt_size(p.total)}`")
if p.total > 0:
lines.append(f"\n๐Ÿ“Š `{_bar(p.percent)}` `{p.percent:.1f}%`")
if p.speed > 0:
lines.append(f"๐Ÿš€ **ุงู„ุณุฑุนุฉ:** `{_speed_line(p.speed)}`")
lines.append(f"โฑ๏ธ **ุงู„ูˆู‚ุช ุงู„ู…ุชุจู‚ูŠ:** ~`{_eta(p.eta_seconds)}`")
if p.elapsed > 0:
lines.append(f"โฑ๏ธ **ุงู„ูˆู‚ุช ุงู„ู…ู†ู‚ุถูŠ:** `{_eta(p.elapsed)}`")
if p.bandwidth_total > 0:
lines.append("")
lines.append("โ”€" * 28)
lines.append(f"๐ŸŒ **ุฅุฌู…ุงู„ูŠ ุงู„ุจุงู†ุฏูˆูŠุซ:** `{_fmt_size(p.bandwidth_total)}`")
# โ”€โ”€ processing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
elif p.status == "processing":
lines.append("")
lines.append(f"๐Ÿ“ฆ **ุงู„ุญุฌู… ุงู„ูƒู„ูŠ:** `{_fmt_size(p.total)}`")
if p.stage_detail:
lines.append(f"๐Ÿ”ง **ู…ุฑุญู„ุฉ FFmpeg:** `{p.stage_detail}`")
if p.sub_stage:
lines.append(f"โš™๏ธ **ุงู„ุนู…ู„ูŠุฉ:** `{p.sub_stage}`")
if p.total > 0:
lines.append(f"\n๐Ÿ“Š `{_bar(p.percent)}` `{p.percent:.1f}%`")
if p.elapsed > 0:
lines.append(f"โฑ๏ธ **ุงู„ูˆู‚ุช ุงู„ู…ู†ู‚ุถูŠ:** `{_eta(p.elapsed)}`")
# โ”€โ”€ uploading (StreamTape) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
elif p.status == "uploading":
lines.append("")
lines.append(f"๐Ÿ“ฆ **ุงู„ุญุฌู… ุงู„ูƒู„ูŠ:** `{_fmt_size(p.total)}`")
if p.stage_detail:
lines.append(f"๐Ÿ‘ค **ุงู„ุญุณุงุจ:** `{p.stage_detail}`")
if p.sub_stage:
lines.append(f"โš™๏ธ **ุงู„ู…ุฑุญู„ุฉ ุงู„ูุฑุนูŠุฉ:** `{p.sub_stage}`")
if p.total_items > 0:
cur = p.current_item
tot = p.total_items
lines.append(f"๐Ÿ“Œ **ุชู‚ุฏู… ุงู„ุญุณุงุจุงุช:** `{cur}` ู…ู† `{tot}`")
pct = cur / tot * 100
lines.append(f"\n๐Ÿ“Š `{_bar(pct)}` `{pct:.1f}%`")
if p.elapsed > 0:
lines.append(f"โฑ๏ธ **ุงู„ูˆู‚ุช ุงู„ู…ู†ู‚ุถูŠ:** `{_eta(p.elapsed)}`")
# โ”€โ”€ telegram_upload โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
elif p.status == "telegram_upload":
lines.append("")
lines.append(f"๐Ÿ“ฆ **ุงู„ุญุฌู… ุงู„ูƒู„ูŠ:** `{_fmt_size(p.total)}`")
if p.total_items > 0:
cur = p.current_item
tot = p.total_items
lines.append(f"๐Ÿ“ค **ุงู„ู†ุณุฎุฉ:** `{cur}/{tot}`")
pct = cur / tot * 100
lines.append(f"\n๐Ÿ“Š `{_bar(pct)}` `{pct:.1f}%`")
if p.elapsed > 0:
lines.append(f"โฑ๏ธ **ุงู„ูˆู‚ุช ุงู„ู…ู†ู‚ุถูŠ:** `{_eta(p.elapsed)}`")
# โ”€โ”€ archiving โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
elif p.status == "archiving":
lines.append("")
if p.stage_detail:
lines.append(f"๐Ÿ—„๏ธ **ุงู„ุฌุฏูˆู„:** `{p.stage_detail}`")
if p.sub_stage:
lines.append(f"โœ… **ุงู„ุญุงู„ุฉ:** `{p.sub_stage}`")
if p.total_items > 0:
lines.append(f"๐Ÿ“Œ **ุงู„ุชู‚ุฏู…:** `{p.current_item}` ู…ู† `{p.total_items}`")
lines.append("")
lines.append("โœ… **ุชู…ุช ุงู„ุฃุฑุดูุฉ ุจู†ุฌุงุญ!**")
lines.append("")
lines.append("โ”" * 28)
lines.append("โœ… **ุชู…ุช ุงู„ุนู…ู„ูŠุฉ ุจู†ุฌุงุญ!**")
return "\n".join(lines)
# โ”€โ”€ done โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
elif p.status == "done":
lines.append("")
lines.append("๐ŸŽ‰ **๐ŸŽŠ ุชู… ุจู†ุฌุงุญ! ๐ŸŽŠ**")
lines.append("")
lines.append(f"๐Ÿ“ฆ **ุงู„ุญุฌู… ุงู„ูƒู„ูŠ:** `{_fmt_size(p.total)}`")
if p.elapsed > 0:
lines.append(f"โฑ๏ธ **ุงู„ูˆู‚ุช ุงู„ู…ุณุชุบุฑู‚:** `{_eta(p.elapsed)}`")
if p.bandwidth_total > 0:
lines.append(f"๐ŸŒ **ุฅุฌู…ุงู„ูŠ ุงู„ุจุงู†ุฏูˆูŠุซ:** `{_fmt_size(p.bandwidth_total)}`")
lines.append("")
lines.append("โ”" * 28)
lines.append("โœ… **ุชู…ุช ุงู„ุนู…ู„ูŠุฉ ุจู†ุฌุงุญ!**")
return "\n".join(lines)
# โ”€โ”€ error โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
elif p.status == "error":
lines.append("")
if p.stage_detail:
lines.append(f"โš ๏ธ **ุงู„ู…ุฑุญู„ุฉ:** `{p.stage_detail}`")
if p.sub_stage:
lines.append(f"๐Ÿ”ด **ุงู„ุฎุทุฃ:** `{p.sub_stage}`")
lines.append("")
lines.append("โ”" * 28)
lines.append("โŒ **ูุดู„ุช ุงู„ุนู…ู„ูŠุฉ!**")
return "\n".join(lines)
lines.append("")
lines.append("โ”" * 28)
lines.append("โณ **ูŠุฑุฌู‰ ุงู„ุงู†ุชุธุงุฑ...**")
return "\n".join(lines)