# 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")