Files
999/scripts/monitor_transfer.py
T

148 lines
5.2 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()