diff --git a/CLAUDE.md b/CLAUDE.md index 08dc1a6..1e60dbd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -70,7 +70,7 @@ python3 Operations_Research_mit_Python_Version_04/veroeffentliche_04.py — **nicht** per `scp`, denn das überschreibt nur und löscht nie; eine aus dem Buch entfernte Seite bliebe sonst dauerhaft online. Vorher prüft es, ob eine Quelldatei neuer ist als die gebaute Website (die Website hing einmal wochenlang einen Bau zurück, ohne dass es auffiel), -hinterher ruft es vierzehn Adressen per HTTP ab. Bei mehr als 30 Löschungen bricht es ab — +hinterher ruft es dreizehn Adressen per HTTP ab. Bei mehr als 30 Löschungen bricht es ab — die Liste ist dann anzusehen, bevor `--loeschgrenze N` sie freigibt. Ziel in `.env` (nicht im Repository, Vorlage `.env.beispiel`); Anmeldung per SSH-Schlüssel, kein Passwort. diff --git a/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf b/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf index 24f209b..9ccab79 100644 Binary files a/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf and b/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf differ diff --git a/Operations_Research_mit_Python_Version_04.pdf b/Operations_Research_mit_Python_Version_04.pdf index 24f209b..9ccab79 100644 Binary files a/Operations_Research_mit_Python_Version_04.pdf and b/Operations_Research_mit_Python_Version_04.pdf differ diff --git a/Operations_Research_mit_Python_Version_04/veroeffentliche_04.py b/Operations_Research_mit_Python_Version_04/veroeffentliche_04.py index 1901de9..3547dbf 100755 --- a/Operations_Research_mit_Python_Version_04/veroeffentliche_04.py +++ b/Operations_Research_mit_Python_Version_04/veroeffentliche_04.py @@ -56,9 +56,15 @@ QUELLEN = [ os.path.join(BASIS, WEB_NAME), ] -# Was nach dem Hochladen erreichbar sein MUSS bzw. NICHT MEHR erreichbar sein -# darf. Die 404-Zeile ist die eigentliche Probe darauf, dass --delete gewirkt -# hat: Sie war der Anlass fuer dieses Skript. +# Was nach dem Hochladen erreichbar sein muss. +# +# Hier stand bis zur ersten Veroeffentlichung eine 404-Zeile fuer +# 'anhang-glossar-literatur.html' - die Seite, die nach dem Teilen von Anhang +# E/F verwaist auf dem Server zurueckblieb und der Anlass fuer dieses Skript +# war. Sie hat ihren Zweck erfuellt und ist wieder entfernt: Die Datei ist +# geloescht, und die Probe koennte einen Rueckschritt gar nicht mehr +# entdecken - sie bliebe auch dann 404, wenn jemand --delete aus dem +# rsync-Aufruf naehme. Was sie belegt hat, steht in PROGRESS.md. NACHPRUEFUNG = [ ("", 200), ("index.html", 200), @@ -73,7 +79,6 @@ NACHPRUEFUNG = [ ("assets/site.css", 200), ("katex/katex.min.js", 200), (PDF_DATEINAME, 200), - ("anhang-glossar-literatur.html", 404), ] LOESCHGRENZE = 30 @@ -200,10 +205,25 @@ def rsync_befehl(env: dict[str, str], probelauf: bool) -> list[str]: # auf beiden Seiten faellt dagegen nicht ins Gewicht. befehl = ["rsync", "-rltz", "--checksum", "--delete", "--chmod=D755,F644", "--skip-compress=pdf/zip/woff2/png/jpg/svg", - "--itemize-changes", "-e", ssh_optionen(env)] if probelauf: - befehl.append("--dry-run") + # Nur der Probelauf listet auf - seine Ausgabe wird gelesen und + # ausgewertet. Der echte Lauf wiederholte diese Liste sonst auf dem + # Bildschirm, obwohl schon berichtet wurde, was passieren wird: beim + # ersten Einsatz waren das 150 Zeilen, von denen 149 nur besagten, + # dass rsync einen Zeitstempel nachgezogen hat. + befehl += ["--dry-run", "--itemize-changes"] + elif sys.stdout.isatty(): + # Eine einzige, sich selbst ueberschreibende Fortschrittszeile - bei + # 23 MB ueber eine Hausleitung ist die Frage "laeuft es noch?" + # berechtigt. + # + # Nur am Terminal: progress2 ueberschreibt seine Zeile mit + # Wagenruecklauf. Laeuft die Ausgabe in eine Pipe oder Protokolldatei, + # bleibt jeder Zwischenstand als eigene Zeile stehen - gemessen + # 213 Zeilen fuer 213 Dateien, also genau das Rauschen, das hier + # abgestellt werden soll. + befehl.append("--info=progress2") ziel = env["OR_ZIEL"] befehl += [HTML_VERZ + os.sep, f'{env["OR_BENUTZER"]}@{env["OR_HOST"]}:{ziel}'] @@ -306,6 +326,13 @@ def main() -> int: help="Schritt 4 ueberspringen (kein Netz zum Server)") argumente = zerleger.parse_args() + # Sonst puffert Python seine Ausgabe blockweise, sobald sie nicht an ein + # Terminal geht (Pipe, Protokolldatei, Aufruf aus einer anderen Oberflaeche + # heraus). Die Meldungen dieses Skripts erschienen dann NACH der Ausgabe + # des rsync-Unterprozesses, der unmittelbar schreibt - der Bericht stand + # also verkehrt herum auf dem Bildschirm. + sys.stdout.reconfigure(line_buffering=True) + env = lies_env() ziel = f'{env["OR_BENUTZER"]}@{env["OR_HOST"]}:{env["OR_ZIEL"]}' print(f"Ziel: {ziel}") diff --git a/PROGRESS.md b/PROGRESS.md index 9e8c68a..25eaee4 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -2233,6 +2233,31 @@ folgt jetzt der Quelle. Damit ist jede der vier Stellen abgesichert: eine ist die Quelle, zwei werden daraus erzeugt, eine wird geprüft. +### ✅ Der Upload berichtet jetzt leserlich + +Der erste Alltagseinsatz des Skripts zeigte drei Schönheitsfehler, alle in der Ausgabe. + +**Der Bericht stand verkehrt herum.** Die `rsync`-Zeilen erschienen *vor* „Ziel:" und +„Vorprüfung bestanden". Ursache: Python puffert seine Ausgabe blockweise, sobald sie nicht +an ein Terminal geht, während der Unterprozess unmittelbar schreibt. Ein +`sys.stdout.reconfigure(line_buffering=True)` in `main()` stellt die Reihenfolge her. + +**150 Zeilen für eine übertragene Datei.** `--itemize-changes` lief auch im echten Durchgang +mit, obwohl der Probelauf längst berichtet hatte, was passieren wird. Von den 150 Zeilen +besagten 149 nur `.f..t......` — „Inhalt gleich, nur Zeitstempel nachgezogen", die +erwartbare Folge von `--checksum`. Die Auflistung bleibt jetzt dem Probelauf vorbehalten. + +**Und der Ersatz war zuerst schlimmer als das Problem.** Statt der Liste sollte +`--info=progress2` eine einzige, sich selbst überschreibende Fortschrittszeile zeigen. Am +Terminal tut es das; in einer Pipe bleibt jeder Zwischenstand als eigene Zeile stehen — +gemessen **213 Zeilen für 213 Dateien**. Die Anzeige hängt deshalb an +`sys.stdout.isatty()`. + +**Nebenbei aufgeräumt:** Die 404-Probe auf `anhang-glossar-literatur.html` ist entfernt. Sie +hat ihren Zweck erfüllt — aber einen Rückschritt könnte sie gar nicht mehr entdecken: Die +Datei ist gelöscht, die Probe bliebe auch dann grün, wenn jemand `--delete` aus dem +`rsync`-Aufruf nähme. Von den ursprünglich vierzehn Adressen bleiben dreizehn. + --- ## 8. Commit-Historie des V04-Strangs diff --git a/README.md b/README.md index d533477..2ea5f76 100644 --- a/README.md +++ b/README.md @@ -210,9 +210,8 @@ Vier Schritte, jeder mit einer eigenen Aufgabe: ist der Lauf verdächtig (falscher Zielpfad, halb gebautes Verzeichnis) und bricht ab; `--loeschgrenze N` hebt die Grenze an. 3. **Übertragung.** -4. **Nachprüfung per HTTP.** Vierzehn Adressen werden abgerufen und ihr Statuscode mit der - Erwartung verglichen — einschließlich der Probe, dass eine entfernte Seite wirklich 404 - liefert. +4. **Nachprüfung per HTTP.** Dreizehn Adressen werden abgerufen und ihr Statuscode mit der + Erwartung verglichen. `--probelauf` führt nur die Schritte 1 und 2 aus. In der `.env` steht **kein Geheimnis**: `rsync` und `scp` haben keine Passwort-Option, die Anmeldung läuft über den SSH-Schlüssel.