87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
"""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)
|