
Autsch, das war ein Kampf. In der Bash mal etwas größeres Skripten kann schon weh tun, aber ich darf ja bald zurück zu Python und Ruby.
Und weiter geht's mit Programmiersprachen. Der heutige Sonntag Nachmittag ging für die Portierung nach Lua drauf. Auch wenn Lua ein paar nette Features enthält, wie z.b. eingebaute String Methoden, die genauso mächtig sind wie Reguläre Ausdrücke, so hab ich mich mit der Sprache doch etwas gequält. Vor allem solche netten Dinge wie Exception Handling, Arrays auf Elemente prüfen, etc... muss man selbst nachrüsten. Aber die Erfahrung war es trotzdem wert. Zwar kann man sich vieles einfacher machen, wie z.B. Python Listen, aber dann kann ich ja fast wieder direkt Python verwenden...
Matthias und ich haben gestern Nacht ein wenig Extreme Programming durchgeführt. Er war der Driver und hat gecodet und ich saß als Co-Pilot neben dran.
Heraus kam ein kleines Python Skript, welches einen RSS Feed für neue Python Module im Python Package Index (PyPI) erzeugt. PyPI bietet nämlich derzeit nur einen Feed an, der die letzten 40 Updates bestehender Module anzeigt. Das kann sehr viel Einträge in einem RSS Reader geben.
Das Skript geht nun in die Testphase und den erzeugten Feed findet man unter:
Den Quellcode dazu gibt es auf Launchpad:
Kürzlich hab ich einen etwas längeren Download angestoßen, der via Fire-and-Forget einfach alles gezogen hat, was er kriegen kann. Das bedeutet, dass es mit Sicherheit viele Pfade gibt, die keine Daten enthalten. Das Skript hat jedoch immer ein sogenanntes Pickle File abgelegt, das einfach nur das gerade benutzte Objekt serialisiert hat und auf Platte gespeichert. Die Ordnerstruktur sieht z.B. so aus:
|── 004ee81b2697d8c7-367448064 │ │ │ ├── 1951630894 │ │ ├── data.pickle │ │ └── Stargate Atlantis - 3x19 - Vengeance.srt │ │ │ ├── 1951630970 │ │ |__ data.pickle │ │ │ ├── 1951631043 │ │ |___ data.pickle │ │
Jetzt wollte ich einfach alle Ordner wissen, die nur dieses Pickle File enthalten, also quasi alle Ordner, die nur 1 Datei als Inhalt haben. Und wie immer gibt es da was Leckeres in Python. Das os - Modul kennt eine Methode walk() die rekursiv durch den Ordner düst und in jedem Durchgang einem den aktuellen Pfad, dessen Verzeichnisse und dessen Dateien zurückgibt in Form eines Tupels. Pythonisch wie man es halt gewohnt ist.
Hier ist das Snippet, wie ich das Verzeichnis, in dem ich mich befinde, rekursiv nach Ordnern suche, die nur eine Datei haben:
import os search_dir = "." for folder, subfolders, files in os.walk(search_dir): if not len(files) > 1: print folder
Tja, so einfach kann es sein.
Ach ja, os.walk() ist ein Generator, d.h. man muss mindestens eine For-Loop nutzen. Wenn man folgenden Fehler bekommt, benutzt man os.walk() nicht richtig:
ValueError: too many values to unpack
Viele Seiten lassen einen ja nur eine bestimmte Menge an Daten downloaden und unterbinden danach jeglichen Dateitransfer. Da ich mir heute ein Skript gebaut habe, das mindestens 8h laufen wird und ich schon recht schnell wegen einem Download-Limit gestoppt werde, musste ich mir was ausdenken.
Manuell den Router resetten um eine neue IP zu bekommen wäre Wahnsinn. Da fiel mir twill ein.
Twill ist ein Python Programm bzw. Modul. D.h. es kann interaktiv in der Shell benutzt werden oder auch als Modul um selber Aufgaben skripten zu können.
Nun, was macht twill?
twill verhält sich wie ein Browser und kann Formulareingaben machen, Buttons drücken, etc... Also alles, was ein Browser kann, kann man skripten bzw. automatisieren.
Also ran an den Speck und den Button Rebooten im Arcor Router skripten. Logindaten sind natürlich Fantasiewerte...
Inhalt der Datei reboot-router.twill
go 'http://192.168.0.254/login.stm' fv 2 user root fv 2 pws Geheim submit go 'http://192.168.0.254/cgi-bin/restart.exe'
Ausführen via twill-sh
twill-sh reboot-router.twill
import twill twill.commands.go('http://192.168.0.254/login.stm') twill.commands.fv(2, 'user', 'root') twill.commands.fv(2, 'pws', 'Geheim') twill.commands.submit() twill.commands.go('http://192.168.0.254/cgi-bin/restart.exe')