diff --git a/app.py b/app.py index 566ab93..40b600f 100644 --- a/app.py +++ b/app.py @@ -76,6 +76,7 @@ copy_state = { 'phase': 'idle', } copy_lock = threading.Lock() +_copy_thread: threading.Thread | None = None def load_state(): global copy_state @@ -922,16 +923,20 @@ def r_status(): @app.route('/api/copy/start', methods=['POST']) def r_start(): + global _copy_thread with copy_lock: if copy_state['running']: return jsonify(error='Bereits aktiv'), 400 + if _copy_thread is not None and _copy_thread.is_alive(): + return jsonify(error='Abbruch läuft noch, bitte einen Moment warten'), 400 cfg = load_cfg() devs = usb_devices() src = next((d for d in devs if d['usb_port'] == cfg.get('source_port')), None) dst = next((d for d in devs if d['usb_port'] == cfg.get('dest_port')), None) if not src: return jsonify(error='Quellgerät nicht gefunden'), 400 if not dst: return jsonify(error='Zielgerät nicht gefunden'), 400 - threading.Thread(target=do_copy, args=(src, dst, cfg), daemon=True).start() + _copy_thread = threading.Thread(target=do_copy, args=(src, dst, cfg), daemon=True) + _copy_thread.start() return jsonify(ok=True) @app.route('/api/copy/cancel', methods=['POST']) @@ -2306,7 +2311,7 @@ async function poll(){ } sum.textContent=''; bS.style.display='none'; bC.style.display=''; time.textContent=''; }else{ - bS.style.display=''; bC.style.display=''; cf.textContent=''; + bS.style.display=''; bC.style.display='none'; cf.textContent=''; eta.style.display='none'; spd.style.display='none'; pfiles.style.display='none'; pbytes.style.display='none'; pp.style.display='none'; if(c.error){ tx.className='st-headline st-err'; tx.textContent='Fehler: '+c.error;