67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
# core/commands/put.py
|
|
import os
|
|
import zlib
|
|
import glob
|
|
from core.connection import BuzzerError
|
|
|
|
def get_file_crc32(filepath: str) -> int:
|
|
"""Berechnet die IEEE CRC32-Prüfsumme einer Datei in Chunks."""
|
|
crc = 0
|
|
with open(filepath, 'rb') as f:
|
|
while chunk := f.read(4096):
|
|
crc = zlib.crc32(chunk, crc)
|
|
return crc & 0xFFFFFFFF
|
|
|
|
def execute(conn, sources: list, target: str):
|
|
"""
|
|
Lädt Dateien auf den Mikrocontroller hoch.
|
|
"""
|
|
# 1. Globbing auflösen (Notwendig für Windows, da die CMD Wildcards nicht auflöst)
|
|
resolved_files = []
|
|
for src in sources:
|
|
matches = glob.glob(src)
|
|
if matches:
|
|
resolved_files.extend(matches)
|
|
else:
|
|
print(f"Warnung: Datei '{src}' nicht gefunden.")
|
|
|
|
if not resolved_files:
|
|
print("Keine gültigen Dateien zum Übertragen gefunden.")
|
|
return
|
|
|
|
is_target_dir = target.endswith('/')
|
|
|
|
# Wenn mehrere Dateien angegeben sind, muss das Ziel zwingend ein Verzeichnis sein
|
|
if len(resolved_files) > 1 and not is_target_dir:
|
|
print("Fehler: Bei mehreren Quelldateien muss das Ziel ein Verzeichnis sein (mit '/' enden).")
|
|
return
|
|
|
|
# 2. Transfer-Schleife
|
|
for filepath in resolved_files:
|
|
if not os.path.isfile(filepath):
|
|
print(f"Überspringe '{filepath}' (ist keine Datei)")
|
|
continue
|
|
|
|
filename = os.path.basename(filepath)
|
|
filesize = os.path.getsize(filepath)
|
|
crc32 = get_file_crc32(filepath)
|
|
|
|
dest_path = f"{target}{filename}" if is_target_dir else target
|
|
|
|
size_kb = filesize / 1024
|
|
print(f"Sende 📄 {filename} \033[90m({size_kb:.1f} KB)\033[0m nach {dest_path} ... ", end="", flush=True)
|
|
|
|
try:
|
|
# PUT-Befehl ohne Warten auf 'OK' senden
|
|
cmd = f"put {dest_path};{filesize};{crc32}\n"
|
|
conn.serial.write(cmd.encode('utf-8'))
|
|
conn.serial.flush()
|
|
|
|
# Warten auf READY, Binärdaten senden und auf abschließendes OK warten
|
|
conn.send_binary(filepath)
|
|
|
|
print("\033[32mErfolgreich\033[0m")
|
|
except BuzzerError as e:
|
|
print(f"\n ❌ \033[31mFehler vom Controller: {e}\033[0m")
|
|
except Exception as e:
|
|
print(f"\n ❌ \033[31mÜbertragungsfehler: {e}\033[0m") |