Files
buzzer/tool/core/cmd/get_file.py
2026-03-07 08:51:50 +01:00

89 lines
3.3 KiB
Python

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