"""PiCopy – Kopierstatus, Verlauf, add_log.""" import json import threading from datetime import datetime from pathlib import Path from picopy.config import ( STATE_FILE, HISTORY_FILE, MAX_HISTORY, _atomic_write, log ) copy_state = { 'running': False, 'progress': 0, 'total': 0, 'done': 0, 'current': '', 'error': None, 'last_copy': None, 'logs': [], 'bytes_total': 0, 'bytes_done': 0, 'start_ts': None, 'eta_sec': None, 'speed_bps': 0, 'phase': 'idle', 'space_warning': False, 'space_needed': 0, 'space_free': 0, 'last_success_file': '', } copy_lock = threading.Lock() def load_state(): global copy_state try: if STATE_FILE.exists(): saved = json.loads(STATE_FILE.read_text(encoding='utf-8')) saved['running'] = False saved['current'] = '' copy_state.update(saved) except (json.JSONDecodeError, ValueError) as e: log.warning(f'state.json korrupt ({e}), starte mit leerem Zustand') try: STATE_FILE.rename(STATE_FILE.with_suffix('.corrupt')) except Exception: pass except Exception as e: log.warning(f'state.json nicht lesbar: {e}') def save_state(): try: with copy_lock: data = dict(copy_state) _atomic_write(STATE_FILE, json.dumps(data)) except Exception: pass def load_history() -> list: try: if HISTORY_FILE.exists(): return json.loads(HISTORY_FILE.read_text(encoding='utf-8')) except Exception: pass return [] def append_history(entry: dict): h = load_history() h.insert(0, entry) try: _atomic_write(HISTORY_FILE, json.dumps(h[:MAX_HISTORY])) except Exception as e: log.warning(f'Verlauf speichern fehlgeschlagen: {e}') def add_log(msg): log.info(msg) with copy_lock: copy_state['logs'].append({'t': datetime.now().strftime('%H:%M:%S'), 'm': msg}) copy_state['logs'] = copy_state['logs'][-200:]