feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets
This commit is contained in:
Executable
+147
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
monitor_transfer.py
|
||||
===================
|
||||
Фоновый мониторинг переноса архива со смартфона.
|
||||
Каждые 3 секунды обновляет файл прогресса на Рабочем столе:
|
||||
/home/alexives/Desktop/ПРОГРЕСС_ПЕРЕНОСА.txt
|
||||
и короткую строку:
|
||||
/home/alexives/Desktop/ПРОГРЕСС_СТРОКА.txt
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
DEST_ROOT = Path("/mnt/data/архив_с_телефона")
|
||||
DESKTOP_FULL = Path("/home/alexives/Desktop/ПРОГРЕСС_ПЕРЕНОСА.txt")
|
||||
DESKTOP_LINE = Path("/home/alexives/Desktop/ПРОГРЕСС_СТРОКА.txt")
|
||||
|
||||
# Целевые объемы в байтах
|
||||
TARGET_SIZES = {
|
||||
"Download": 17 * 1024 * 1024 * 1024,
|
||||
"футажи": 2.3 * 1024 * 1024 * 1024,
|
||||
"Pictures": 1.4 * 1024 * 1024 * 1024,
|
||||
"DCIM/MyAlbums": 59 * 1024 * 1024 * 1024,
|
||||
"DCIM/Camera": 16 * 1024 * 1024 * 1024,
|
||||
}
|
||||
TOTAL_BYTES = sum(TARGET_SIZES.values())
|
||||
|
||||
def get_dir_size(path: Path) -> int:
|
||||
if not path.exists():
|
||||
return 0
|
||||
try:
|
||||
res = subprocess.run(["du", "-sb", str(path)], capture_output=True, text=True, check=True)
|
||||
return int(res.stdout.split()[0])
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
def format_size(bytes_val: int) -> str:
|
||||
gb = bytes_val / (1024 ** 3)
|
||||
if gb >= 1.0:
|
||||
return f"{gb:.2f} ГБ"
|
||||
mb = bytes_val / (1024 ** 2)
|
||||
return f"{mb:.1f} МБ"
|
||||
|
||||
def make_bar(percent: float, length: int = 25) -> str:
|
||||
filled = int(round(length * percent / 100))
|
||||
filled = max(0, min(length, filled))
|
||||
return "█" * filled + "░" * (length - filled)
|
||||
|
||||
def main():
|
||||
prev_bytes = 0
|
||||
prev_time = time.time()
|
||||
speed = 0.0
|
||||
|
||||
while True:
|
||||
current_sizes = {}
|
||||
total_copied = 0
|
||||
|
||||
for name in TARGET_SIZES:
|
||||
sz = get_dir_size(DEST_ROOT / name)
|
||||
current_sizes[name] = sz
|
||||
total_copied += sz
|
||||
|
||||
now = time.time()
|
||||
dt = now - prev_time
|
||||
if dt >= 2.0:
|
||||
if prev_bytes > 0 and total_copied >= prev_bytes:
|
||||
speed = (total_copied - prev_bytes) / dt
|
||||
prev_bytes = total_copied
|
||||
prev_time = now
|
||||
|
||||
percent = (total_copied / TOTAL_BYTES) * 100
|
||||
percent = min(100.0, percent)
|
||||
|
||||
# Определение текущей активной папки
|
||||
current_folder = "Завершено"
|
||||
for name in TARGET_SIZES:
|
||||
target = TARGET_SIZES[name]
|
||||
curr = current_sizes[name]
|
||||
if curr < target * 0.98:
|
||||
current_folder = name
|
||||
break
|
||||
|
||||
speed_mb = speed / (1024 * 1024)
|
||||
rem_bytes = max(0, TOTAL_BYTES - total_copied)
|
||||
eta_min = (rem_bytes / speed / 60) if speed > 100000 else 0
|
||||
|
||||
bar = make_bar(percent, 25)
|
||||
now_str = time.strftime("%H:%M:%S")
|
||||
|
||||
# 1. Формируем подробный отчет
|
||||
full_report = [
|
||||
"=" * 68,
|
||||
" 📱 СТАТУС ПЕРЕНОСА АРХИВА СО СМАРТФОНА",
|
||||
"=" * 68,
|
||||
f"Прогресс: [{bar}] {percent:.1f}%",
|
||||
f"Объём: {format_size(total_copied)} из ~{format_size(TOTAL_BYTES)}",
|
||||
f"Скорость: {speed_mb:.1f} МБ/сек",
|
||||
f"Осталось: ~{eta_min:.0f} мин." if eta_min > 0 else "Осталось: расчёт...",
|
||||
f"Текущая: «{current_folder}»",
|
||||
"-" * 68,
|
||||
"📂 Статус папок:",
|
||||
]
|
||||
|
||||
for name, target in TARGET_SIZES.items():
|
||||
curr = current_sizes[name]
|
||||
if curr == 0:
|
||||
st = "[В ОЧЕРЕДИ]"
|
||||
elif curr >= target * 0.98:
|
||||
st = "[ГОТОВО]"
|
||||
else:
|
||||
st = "[КОПИРУЕТСЯ...]"
|
||||
full_report.append(f" • {name:<14} {st:<16} {format_size(curr)} / {format_size(target)}")
|
||||
|
||||
full_report.append("-" * 68)
|
||||
full_report.append(" (Музыка и аудиокниги оставлены на телефоне)")
|
||||
full_report.append(f"Обновлено: {now_str}")
|
||||
full_report.append("=" * 68)
|
||||
|
||||
# 2. Формируем короткую строку состояния
|
||||
one_line = f"[{bar}] {percent:.1f}% | {format_size(total_copied)} / {format_size(TOTAL_BYTES)} | {speed_mb:.1f} МБ/с | ETA: ~{eta_min:.0f}м | Папка: {current_folder} ({now_str})\n"
|
||||
|
||||
# Запись файлов
|
||||
try:
|
||||
with open(DESKTOP_FULL, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(full_report) + "\n")
|
||||
with open(DESKTOP_LINE, "w", encoding="utf-8") as f:
|
||||
f.write(one_line)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Проверка завершения
|
||||
if percent >= 99.9:
|
||||
try:
|
||||
subprocess.run(["notify-send", "Архив с телефона", "Все файлы успешно перенесены на компьютер!"])
|
||||
except Exception:
|
||||
pass
|
||||
break
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user