"""PiCopy – Blueprint: /api/sysinfo, /api/update/*, /api/format/*, /api/system/*.""" import subprocess import threading from flask import Blueprint, jsonify, request from picopy.usb import usb_devices from picopy.state import copy_state from picopy.system import ( get_sysinfo, update_state, update_lock, format_state, FORMAT_FILESYSTEMS, check_for_updates, install_update, do_format, ) system_bp = Blueprint('system', __name__) @system_bp.route('/api/sysinfo') def r_sysinfo(): return jsonify(get_sysinfo()) @system_bp.route('/api/update/status') def r_update_status(): with update_lock: return jsonify(dict(update_state)) @system_bp.route('/api/update/check', methods=['POST']) def r_update_check(): threading.Thread(target=check_for_updates, daemon=True).start() return jsonify(ok=True) @system_bp.route('/api/update/install', methods=['POST']) def r_update_install(): from picopy.config import log try: install_update() return jsonify(ok=True) except SyntaxError as e: return jsonify(error=f'Update-Datei ungültig: {e}'), 500 except Exception as e: log.exception('Update fehlgeschlagen') return jsonify(error=str(e)), 500 @system_bp.route('/api/format/status') def r_format_status(): return jsonify(dict(format_state)) @system_bp.route('/api/format', methods=['POST']) def r_format(): if format_state['running']: return jsonify(error='Formatierung läuft bereits'), 409 if copy_state.get('running'): return jsonify(error='Kopiervorgang läuft – bitte warten'), 409 body = request.get_json(force=True) fs = body.get('fs', '').lower() name = (body.get('name') or 'PICOPY').upper() dev = body.get('device', '') if fs not in FORMAT_FILESYSTEMS: return jsonify(error=f'Unbekanntes Dateisystem: {fs}'), 400 if not dev.startswith('/dev/'): return jsonify(error='Ungültiges Gerät'), 400 # Sicherheitscheck: Gerät muss ein bekanntes USB-Gerät sein known = [d['device'] for d in usb_devices()] if dev not in known: return jsonify(error='Gerät nicht als USB-Laufwerk erkannt'), 400 threading.Thread(target=do_format, args=(fs, name, dev), daemon=True).start() return jsonify(ok=True) @system_bp.route('/api/system/reboot', methods=['POST']) def r_system_reboot(): threading.Thread(target=lambda: ( __import__('time').sleep(1), subprocess.Popen(['reboot']) ), daemon=True).start() return jsonify(ok=True)