diff --git a/live-updates/opt/tuxflotte/scripts/atspi_click.py b/live-updates/opt/tuxflotte/scripts/atspi_click.py index 36c0ed6..1a1877b 100755 --- a/live-updates/opt/tuxflotte/scripts/atspi_click.py +++ b/live-updates/opt/tuxflotte/scripts/atspi_click.py @@ -30,10 +30,29 @@ Sprache ist durch "debian-installer/language=de" im Kexec-Append-Preseed grundsaetzlich auf de_DE gesetzt (siehe backend.sh), s.o. aber nicht verlaesslich fuer jede einzelne Seite. +NACHTRAG (real beim Testen entdeckt, 29.08.2026): auf der manuellen +Partitionierungsseite ("Etwas Anderes") lief der Klick auf "Jetzt +installieren" nachweislich zuverlaessig (AT-SPI meldete jedes Mal Erfolg), +aber die Seite kam nie voran - stattdessen loeste jeder Klick erneut die +Debconf-Frage "ubiquity/partman-rebuild-cache" aus +(/lib/partman/update.d/99signal_ubiquity), was ubi-partman.py zurueck auf +dieselbe Seite wirft (siehe ADR-0023-Nachtrag). Ein gezielter Fix am +Partitionsrezept (kein zusaetzliches $bootable{ } auf der Root-Partition +unter UEFI) aenderte NICHTS - das deutet auf einen zeitlichen statt +strukturellen Fehler hin: die Seite zeigt waehrend dieser Phase ein +Status-Panel "Konfiguration der Installation wird ueberprueft ..." - klickt +der Autoklicker WAEHREND dieser Hintergrundpruefung noch laeuft, koennte +er sie unterbrechen/neu anstossen, statt ihr Zeit zum Abschliessen zu +geben. Dieses Skript wartet deshalb jetzt aktiv, solange dieser Text +sichtbar ist (siehe VALIDATION_TEXT_MARKERS/find_showing_text()), und +klickt erst, wenn er verschwunden ist. + Exit-Codes: 0 = ein Button wurde gefunden und geklickt, 1 = kein eindeutiger Button gefunden (z.B. Seite im Ladezustand, oder echte Mehrdeutigkeit - dann bewusst NICHT geklickt, siehe select_target()), -2 = pyatspi/AT-SPI-Bus nicht erreichbar (Bruecke evtl. nicht aktiv). +2 = pyatspi/AT-SPI-Bus nicht erreichbar (Bruecke evtl. nicht aktiv), +3 = Ubiquitys eigene Hintergrundpruefung laeuft noch sichtbar - bewusst +nicht geklickt, siehe Nachtrag oben. """ import sys @@ -88,6 +107,52 @@ PREFER_LABELS = { MAX_DEPTH = 40 +# Zweisprachig vorsichtshalber (siehe Multimedia-Codecs-Erfahrung oben), +# auch wenn dieser konkrete Text bisher immer deutsch beobachtet wurde. +VALIDATION_TEXT_MARKERS = ( + "wird überprüft", + "wird ueberprueft", + "being checked", + "checking the install", +) + + +def find_showing_text(node, needle, depth=0): + """Sucht ein sichtbares Accessible, dessen Name ODER Beschreibung den + Suchtext enthaelt - unabhaengig von seiner Rolle (Label/Expander/...), + da Ubiquitys Status-Panel-Text nicht zuverlaessig unter derselben Rolle + exponiert sein muss. Bei Unsicherheit ueber den Sichtbarkeitsstatus + bewusst konservativ (lieber einen Zyklus zu viel warten als einen + Klick mitten in die Pruefung setzen).""" + if node is None or depth > MAX_DEPTH: + return False + try: + name = (node.name or "").strip().lower() + except Exception: + name = "" + try: + desc = (node.description or "").strip().lower() + except Exception: + desc = "" + if needle in name or needle in desc: + try: + state = node.getState() + return state.contains(pyatspi.STATE_SHOWING) + except Exception: + return True + try: + count = node.childCount + except Exception: + return False + for i in range(count): + try: + child = node.getChildAtIndex(i) + except Exception: + continue + if find_showing_text(child, needle, depth + 1): + return True + return False + def collect_buttons(node, depth=0, acc=None): """Alle sichtbaren+aktivierten Push-Buttons im Baum einsammeln (Rolle, @@ -171,14 +236,26 @@ def main(): print(f"AT-SPI-Desktop nicht erreichbar: {exc}", file=sys.stderr) return 2 - all_buttons = [] + apps = [] for i in range(desktop.childCount): try: app = desktop.getChildAtIndex(i) except Exception: continue - if app is None: - continue + if app is not None: + apps.append(app) + + for marker in VALIDATION_TEXT_MARKERS: + for app in apps: + if find_showing_text(app, marker): + print( + f"Hintergrundpruefung noch sichtbar ('{marker}'), warte statt zu klicken.", + file=sys.stderr, + ) + return 3 + + all_buttons = [] + for app in apps: collect_buttons(app, 0, all_buttons) target = select_target(all_buttons) diff --git a/live-updates/opt/tuxflotte/scripts/autoclicker.sh b/live-updates/opt/tuxflotte/scripts/autoclicker.sh index a667acd..857e5e2 100755 --- a/live-updates/opt/tuxflotte/scripts/autoclicker.sh +++ b/live-updates/opt/tuxflotte/scripts/autoclicker.sh @@ -97,6 +97,13 @@ while [ "${SECONDS}" -lt "${end}" ]; do elif [ "${rc}" -eq 2 ]; then log "AT-SPI-Bus nicht erreichbar, breche ab: ${out}" break + elif [ "${rc}" -eq 3 ]; then + # Ubiquitys eigene Hintergrundpruefung laeuft noch sichtbar (siehe + # atspi_click.py-Nachtrag) - bewusst NICHT als Fehlversuch zaehlen, + # nur abwarten. Real beim Testen entdeckt: ein Klick auf "Jetzt + # installieren" WAEHREND dieser Pruefung fuehrte wiederholt in die + # partman-rebuild-cache-Schleife statt zum eigentlichen Commit. + log "wartet auf Hintergrundpruefung: ${out}" else misses=$((misses + 1)) log "kein Treffer (${misses}): ${out}"