Verbessere die Mount-Überprüfung und Fehlerbehandlung für USB-Geräte
This commit is contained in:
47
app.py
47
app.py
@@ -568,13 +568,43 @@ def r_wifi_status():
|
||||
|
||||
_browse_mounts = {} # usb_port -> mount_point
|
||||
|
||||
|
||||
def _mp_is_alive(mp):
|
||||
"""Prüft ob ein Mount-Punkt wirklich aktiv und lesbar ist."""
|
||||
try:
|
||||
with open('/proc/mounts') as f:
|
||||
mounted = any(mp in line.split() for line in f)
|
||||
if not mounted:
|
||||
return False
|
||||
os.listdir(mp) # I/O-Test: schlägt fehl wenn Gerät entfernt wurde
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def _drop_browse_mount(port):
|
||||
"""Veralteten Mount bereinigen."""
|
||||
mp = _browse_mounts.pop(port, None)
|
||||
if mp:
|
||||
subprocess.run(['umount', '-l', mp], capture_output=True)
|
||||
log.info(f'Browse-Mount bereinigt: {mp}')
|
||||
|
||||
|
||||
def get_browse_mp(dev):
|
||||
port = dev.get('usb_port', '')
|
||||
if dev.get('mount'):
|
||||
|
||||
# Auto-mount vom System bevorzugen
|
||||
if dev.get('mount') and _mp_is_alive(dev['mount']):
|
||||
return dev['mount']
|
||||
|
||||
# Gecachten Mount prüfen
|
||||
mp = _browse_mounts.get(port)
|
||||
if mp and Path(mp).is_dir():
|
||||
if mp:
|
||||
if _mp_is_alive(mp):
|
||||
return mp
|
||||
_drop_browse_mount(port) # veraltet → aufräumen
|
||||
|
||||
# Frisch mounten
|
||||
mp = f'/mnt/picopy_br_{port}'
|
||||
os.makedirs(mp, exist_ok=True)
|
||||
r = subprocess.run(['mount', dev['device'], mp], capture_output=True)
|
||||
@@ -592,11 +622,11 @@ def r_browse():
|
||||
devs = usb_devices()
|
||||
dev = next((d for d in devs if d['usb_port'] == port), None)
|
||||
if not dev:
|
||||
return jsonify(error='Gerät nicht verbunden'), 404
|
||||
return jsonify(error='Gerät nicht verbunden – bitte neu einstecken'), 404
|
||||
|
||||
mp = get_browse_mp(dev)
|
||||
if not mp:
|
||||
return jsonify(error='Gerät nicht mountbar'), 500
|
||||
return jsonify(error='Gerät nicht lesbar – bitte neu einstecken'), 500
|
||||
|
||||
try:
|
||||
base = Path(mp).resolve()
|
||||
@@ -618,12 +648,19 @@ def r_browse():
|
||||
'size': s.st_size if item.is_file() else None,
|
||||
'mtime': datetime.fromtimestamp(s.st_mtime).strftime('%d.%m.%y %H:%M'),
|
||||
})
|
||||
except Exception:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
rel = str(target.relative_to(base))
|
||||
return jsonify(path='' if rel == '.' else rel, entries=entries)
|
||||
|
||||
except OSError as e:
|
||||
import errno as _errno
|
||||
if e.errno == _errno.EIO:
|
||||
# I/O-Fehler = Gerät abgezogen, Mount bereinigen
|
||||
_drop_browse_mount(port)
|
||||
return jsonify(error='Gerät nicht mehr erreichbar – bitte neu einstecken'), 503
|
||||
return jsonify(error=str(e)), 500
|
||||
except Exception as e:
|
||||
return jsonify(error=str(e)), 500
|
||||
|
||||
|
||||
Reference in New Issue
Block a user