In der Softwareentwicklung sind zehn Jahre eine lange, sehr lange Zeit! Zahllose neue Technologien, Compilerversionen, Bibliotheken, APIs, Webservices, etc. werden freigegeben und müssen vom Entwickler, der sie nutzt, verstanden und umgesetzt werden. Andererseits sind zehn Jahre auch eine recht kurze Zeit, denn ein Computerprogramm ist gerade dann durchdacht und übersichtlich aufgebaut, wenn es sich auch über mehrere Jahre leicht warten lässt. Dazu gehören nicht einfach nur aussagekräftige Kommentare an der richtigen Stelle. Niklaus Wirth und viele andere Pioniere der Softwareentwicklung haben darauf hingewiesen, wie wichtig es ist, Software zu strukturieren. Komplexe Aufgaben werden gelöst, indem sie in ihre Teilprobleme zerlegt werden, was wiederum voraussetzt, dass man sich über die Datenstrukturen und Prozesse eines Programmes Gedanken macht. Der Programmierer kommt schneller zum Ziel, wenn er von den zu verarbeitenden Datenstrukturen ein genaues Bild hat.
In der letzten Dekade habe ich viele Programme geschrieben, die meisten davon in meinem Lieblingsformalismus Perl, aber auch in PHP, C und C# («C-Sharp»). Warum gerade Perl? Weil es ein fantastisches Werkzeug ist, um Daten verschiedenster Art einfach und schnell zu manipulieren: dies beginnt bei eher langweiligen Textdateien, führt dann weiter über Excel-Tabellen und OpenOffice-Dokumente, macht auch vor komplexen Webservices und seriellen Schnittstellen nicht halt und findet seinen Höhepunkt beim Zugriff auf faktische alle existierenden Datenbanksysteme! Zu kaum einer anderen Programmiersprache gibt es so viele Bibliotheken wie Perl! Das vom Linguisten Larry Wall, nicht streng-formalistische Perl-System wird so zum Alleskönner. «Alleskönner» das klingt verdächtig, denn allzugerne wird oberflächlich, wer alles können will. Perl macht hier eine erfreuliche Ausnahme. Die verfügbaren Bibliotheken, entwickelt von mehreren tausend Programmierern, sind ausgereift, einheitlich dokumentiert und über eine zentrale Anlaufstelle erreichbar: CPAN (Comprehensive Perl Archive Network).
Man merkt es sicher, ich bin Perl-Fan. Bevor ich noch mehr ins Schwärmen gerate, möchte ich im folgenden kurz Rechenschaft darüber ablegen, was ich in den letzten Jahren gemacht habe. Eigentlich lässt es sich in einem einzigen Wort zusammenfassen: Prozessautomation. Das Problem ist gut bekannt: die tägliche Arbeit besteht stets zu einem Teil aus Routinearbeiten, Aufgaben also, die sich wiederholen und immer nach dem mehr oder weniger gleichen Schema abgearbeitet werden müssen. Bei einem ISP ist das zum Beispiel das Handling von DSL-Bestellungen, Kündigungen und Umzügen, das Prüfen offener Tickets oder das Konfigurieren von Modems und Routern. Und genau hier bietet sich in einem Informatik-Unternehmen die Chance, einige dieser Prozesse zu automatisieren. Genau dazu sind Computer schliesslich da und jede Prozessautomation legt Ressourcen frei, spart wertvolle Zeit. Ich beschreibe im Folenden einige Beispiele, solcher Prozesse, die helfen, Routinearbeiten zu erleichtern.
SPAM Clearing Center: Bei einem Internet Provider sammeln sich nicht hunderte von unerwünschten Werbemails (SPAM) an, es sind tausende – jeden Tag. Bis zu zehn Mailserver sind zu 98% ausschliesslich mit dem SPAM-Handling beschäftigt. Filter helfen mit, diese Flut einzudämmen, damit sie aber effizient wirken, müssen sie «trainiert» werden. Dem Filter muss mitgeteilt werden, was SPAM ist – und was nicht! Kunden können SPAM’s melden, die unerwünschten Mails landen damit in einem Ordner, den wir für das Training der Filter auswerten müssen. Damit dies etwas leichter geht, haben wir ein SPAM Clearing Center entwickelt. Dieses listet alle SPAM’s auf, auf Knopfdruck können nun die mehreren Hundert Einträge pro Woche (!) klassifiziert werden. Ist eine Zusendung kein SPAM, dann kann der Kunde darüber informiert werden und wer 100 oder mehr erfolgreiche Zusendungen gemacht hat, erhält automatisch per E-Mail eine Verdankung.
SPAM Clearing Center
Geplante Ausfälle: Wenn Swisscom Leitungen und Zentralen ausbaut, dann kommt es zu geplanten Unterbrüchen bei den Breitband- und Telefonverbindungen der angeschlossenen Haushalte in diesem Gebiet. Swisscom liefert den Providern eine Liste der geplanten Ausfälle, damit diese ihre Kunden rechtzeitig über den Ausfall informieren können. Erfreulicherweise ist dieser Dienst auch als Webservice verfügbar. Also holen wir diese Liste regelmässig via Perl Script ab, speichern die Ausfälle in einer Tabelle und generieren mit LaTeX Briefe, die nur noch verpackt und versandt werden müssen. Gerade dies ist ein gutes Beispiel, wie ein Script auf ganz verschiedene Datenbestände und Prozesse zugreift, um eine sonst eintönige Aufgabe zu automatisieren. Für den SOAP-Zugriff beim Dienstanbieter gibt es eine ausgereifte CPAN-Bibliothek, das Erzeugen der Briefe erfolgt mit vorgefertigten Textvorlagen und das Ergebnis wird – je nach Einstellung – auf dem Drucker ausgegeben oder per Mailanhang versandt.
ADSL Modems provisionieren: Dies habe ich in einem früheren Artikel bereits erläutert, wir haben selbst in Perl einen ACS Server entwickelt, der ein Modem automatisch konfiguriert, sobald der Kunde es angeschlossen hat. Diese Technik funktioniert natürlich nicht nur bei ADSL Routern, sie kommt auch bei beliebigen anderen Endgeräten (Telefone, Firewalls, etc.) zum Einsatz.
WORD Formulare: Es ist auch heute noch so, es gibt Dienste, die manuell mit ausgefüllten Formularen bestellt werden müssen. Auch bei SolNet gibt es Microsot Word-Dokumente, die abgetippt und dann versandt werden müssen, entweder als Mailanhang oder als Postbrief. Diese Aufgabe wird spätestens dann fehleranfällig und zeitaufwendig, wenn sie sich mehrmals pro Woche wiederholt. Um die Sache einfacher zu machen, holen wir die Daten direkt aus dem Kundenstamm und ergänzen sie – wo erforderlich – mit den Werten, die zuvor mit einem Web-Formular und gespeichert worden sind. Dies hat den grossen Vorteil, dass das Formular später beliebig ergänzt, korrigiert und kopiert werden kann. Wie aber kommen diese Daten aus der Postgres-Datenbank in das Word-Formular? Wir nutzen einmal mehr Perl! Mit der Bibliothek ODF::lpOD können wir das Formular, das wir zuvor in das OpenDocument Format konvertiert haben, per Script verändern. lPOD stellt dazu eine einfache, aber sehr effiziente Funktion zum Suchen und Ersetzen zur Verfügung. Das ganze Programmgerüst ist nur wenige Zeilen lang:
use ODF::lpOD:
my $doc = odf_document->get(„formular.odt“);
…
my $paragraph = $context->get_paragraph(content => „#NAME#“);
if ($p) {
$count = $p->replace(‚#NAME#‘, $r->{’name‘});
}
Nachdem das OpenOffice Dokument erfolgreich geöffnet wurde, wird ein Parapgraph ermittelt, in dem sich ein Feld befindet, das durch einen Text aus der Datanbank ersetzt werden soll. Ich habe eine simple Tag-Notation verwendet, mit der die zu verändernden Passagen im Dokument deutlich markiert und dann verarbeitet werden können. Die replace Funktion setzt dann den mit SELECT ermittelten Text an dieser Stelle ein. Dies entspricht zuemlich genau der Suchen/Ersetzen Funktion der Textverarbeitung! Sind alle Aenderungen gemacht, kann das Dokument gespeichert und seiner Bestimmung zugeführt werden.
Stopp! Es muss ja im Word-Format vorliegen. Man könnte das erzeugte Formualar nun «händisch» mit OpenOffice öffnen und dann im DOC-Format speichern. Erfreulicherweise gibt es unoconv, ein in Python entwickeltes Tool, das im Batchbetrieb genau diese Aufgabe für uns erledigen kann.
Wann ist eigentlich Ostern? Mit einem Programm lässt sich dies errechnen, bei Perl gibt es auch dazu eine CPAN-Library, die mittels einer einzigen Zeile das Osterdatum für ein gegebenes Jahr errechnet. Was kann man damit machen? Hier wieder ein Beispiel. Zu Beginn haben wir auf unserer Telefonzentrale die Feiertage manuell eingestellt, also Karfreitag, Ostern, Ostermontag, etc. Und dann vergassen wir diese Konfiguration wieder! Die Folge: im kommenden Jahr war Ostern früher und die Support-Mitarbeiter freuten sich an einem Freitag über die Stille im Büro (die hilfesuchenden Kunden waren weniger begeistert)… Heute erledigt ein Script das Einstellen dieder Feiertage und sendet Mails an die Mitarbeiter, um auf die bevorstehenden Feiertage hinzuweisen. Die dazu verwendete Perl Libraray: Date::Calc. Hier noch einige, an das Osterdatum gebundene Feiertage und die Offsets in Tagen:
my @F = (
[‚Karfreitag‘, -2],
[‚Ostermontag‘, 1],
[‚Himmelfahrt‘, 39],
[‚Pfingstmontag‘, 50]
);
Tickets: Apropos Support. Der Kundendienst erhält täglich Anfragen, per Telefon, Kontaktformular, Mail oder – ganz traditionell – per Fax. So wie bei den meisten Dienstleistern werden alle diese Anfragen in einem Ticketing-System gesammelt und bearbeitet. Auch hier gibt es kein geringes Automatisierungs-Potential. Sobald eine Anfrage per Mail oder Online-Formular eintrifft, wird versucht, diese dem richtigen Kundendossier zuzuweisen. Dies geschieht zum Beispiel mittels der verwendeten E-Mail Adresse. War eine Zuweisung möglich, wird im Vertrag ein History Eintrag erstellt, der direkt zum Ticket führt. Auf diese Weise können wir auch steuern, welchem Team ein Ticket zugewiesen wird, welche Priorität es hat, wer intern informiert wird, und so weiter. Und, falls das E-Mail einen Anhang hat: dieser geht automatisch in das Dokumentenarchiv!
In allen Beiträgen dieser Rubrik, habe ich geschrieben, dass es Spass macht, bei SolNet zu arbeiten. Daran hat sich in all den Jahren nichts geändert. Die Arbeit ist jeden Moment spannend und abwechslungsreich. Und wenn mir Gesundheit geschenkt bleibt, mache ich gerne weiter. Gewiss, diese zehn Jahre sind an mir nicht spurlos vorbeigegangen, als ich hier begann, hätte ich nicht gedacht, dass einmal Magnesiumtabletten und magenschonender Getreidekaffee auf meinem Arbeitstisch stehen… Anderes hat sich aber überhaupt nicht verändert: allem voran die Freude am Programmieren. Apropos: hier zum Schluss noch ein Foto von einem Screenshot eines Programmes aus dem Jahre 1983. Es zeigt den Ausschnitt eines Commodore 64 BASIC-Programmes zum Erstellen einer Rangliste:
Programmieren war damals ziemlich (!) anders. Nicht nur, dass das damalige BASIC langsam und eingeschränkt war. Auch mit den Ressourcen musste sparsam umgegangen werden, standen doch für Programm und Daten nur rund 38 KB RAM zur Verfügung. Aber eines ist gleich geblieben: mit Fleiss, Fachwissen und Geduld konnten damit fantastische Programme entwickelt werden.