feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets

This commit is contained in:
2026-10-09 15:26:58 +05:00
parent 7f91366201
commit 0b12e4583b
244 changed files with 611461 additions and 1617 deletions
+147
View File
@@ -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()