# tool/core/cmd/get_file.py import struct import zlib from pathlib import Path from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, DownloadColumn, TransferSpeedColumn, TimeRemainingColumn from core.utils import console, console_err from core.protocol import COMMANDS class get_file: def __init__(self, bus): self.bus = bus def get(self, source_path: str, dest_path: str): try: p = Path(dest_path) p.parent.mkdir(parents=True, exist_ok=True) with open(p, 'wb') as f: pass except Exception as e: console_err.print(f"Fehler: Kann Zieldatei nicht anlegen: {e}") return None source_path_bytes = source_path.encode('utf-8') payload = struct.pack('B', len(source_path_bytes)) + source_path_bytes self.bus.send_request(COMMANDS['get_file'], payload) # Fortschrittsbalken Setup with Progress( SpinnerColumn(), TextColumn("[progress.description]{task.description}"), BarColumn(), DownloadColumn(), TransferSpeedColumn(), "•", TimeRemainingColumn(), console=console, transient=False ) as progress: task = progress.add_task(f"Lade {source_path}...", total=None) def update_bar(received, total): progress.update(task, total=total, completed=received) stream_res = self.bus.receive_stream(progress_callback=update_bar) if not stream_res or stream_res.get('type') == 'error': return None file_data = stream_res['data'] remote_crc = stream_res.get('crc32') local_crc = zlib.crc32(file_data) & 0xFFFFFFFF duratuion = stream_res.get('duration') if local_crc == remote_crc: with open(p, 'wb') as f: f.write(file_data) success = True else: with open(p, 'wb') as f: f.write(file_data) success = False return { 'success': success, 'source_path': source_path, 'dest_path': dest_path, 'crc32_remote': remote_crc, 'crc32_local': local_crc, 'size': len(file_data), 'duration': duratuion } def print(self, result): if not result: return if result['success']: console.print(f"✓ Datei [info]{result['source_path']}[/info] erfolgreich heruntergeladen.") console.print(f" • Größe: [info]{result['size'] / 1024:.2f} KB[/info]") else: console_err.print(f"❌ CRC-FEHLER: Datei [error]{result['source_path']}[/error] wurde nicht korrekt empfangen!") console.print(f" • Remote CRC: [info]{result['crc32_remote']:08X}[/info]") console.print(f" • Local CRC: [info]{result['crc32_local']:08X}[/info]") if result.get('crc32_device_file') is not None: console.print(f" • Device CRC: [info]{result['crc32_device_file']:08X}[/info]") console.print(f" • Zielpfad: [info]{result['dest_path']}[/info]") if result.get('duration') is not None and result.get('duration') > 0: console.print(f" • Dauer: [info]{result['duration']:.2f} s[/info]")