60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
# core/commands/check.py
|
|
from core.connection import BuzzerError
|
|
|
|
def _split_parent_and_name(path: str) -> tuple[str, str]:
|
|
normalized = path.rstrip("/")
|
|
if not normalized or normalized == "/":
|
|
raise BuzzerError("Für CHECK wird ein Dateipfad benötigt.")
|
|
|
|
idx = normalized.rfind("/")
|
|
if idx <= 0:
|
|
return "/", normalized
|
|
|
|
parent = normalized[:idx]
|
|
name = normalized[idx + 1:]
|
|
if not name:
|
|
raise BuzzerError("Ungültiger Dateipfad für CHECK.")
|
|
return parent, name
|
|
|
|
|
|
def _lookup_file_size_bytes(conn, path: str) -> int | None:
|
|
parent, filename = _split_parent_and_name(path)
|
|
lines = conn.list_directory(parent)
|
|
|
|
for line in lines:
|
|
parts = line.split(",", 2)
|
|
if len(parts) != 3:
|
|
continue
|
|
|
|
entry_type, entry_size, entry_name = parts
|
|
if entry_type == "F" and entry_name == filename:
|
|
try:
|
|
return int(entry_size)
|
|
except ValueError:
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
def _estimate_crc_timeout_seconds(conn, size_bytes: int | None) -> float:
|
|
min_timeout = float(getattr(conn, "crc_timeout_min_seconds", 2.0))
|
|
ms_per_100kb = float(getattr(conn, "crc_timeout_ms_per_100kb", 1.5))
|
|
|
|
base = max(float(conn.timeout), min_timeout)
|
|
if size_bytes is None or size_bytes <= 0:
|
|
return base
|
|
|
|
blocks_100kb = size_bytes / (100.0 * 1024.0)
|
|
extra = blocks_100kb * (ms_per_100kb / 1000.0)
|
|
return base + extra
|
|
|
|
def execute(conn, path: str) -> dict:
|
|
"""Holt die CRC32 nur über Audiodaten und passt Timeout für große Dateien an."""
|
|
size_bytes = _lookup_file_size_bytes(conn, path)
|
|
timeout = _estimate_crc_timeout_seconds(conn, size_bytes)
|
|
crc32 = conn.check_file_crc(path, timeout=timeout)
|
|
|
|
return {
|
|
"crc32": crc32,
|
|
"size_bytes": size_bytes,
|
|
} |