Beispiel eines Idle-Skripts

Nachdem wir gesehen haben, wie eingehende Anrufe behandelt werden, folgt nun eine sehr kurze Einführung, wie ausgehende Anrufe mit Hilfe des Idle-Skripts initiiert werden.

Wie bereits erwähnt, wird das Idle-Skript in regelmäßigen Abständen von CapiSuite aufgerufen, um irgendwo nach gespeicherten Aufträgen zu suchen und diese dann zu verschicken.

Das hier vorgestellte Beispiel sucht nach einer Datei job-XXXX.sff im Beispiel-Verzeichnis, das wir im letzten Abschnitt erzeugt haben. Diese Datei wird an das durch XXXX angegebene Ziel gefaxt. Wenn Sie kein gültiges Ziel haben, an das Sie zum Testen Faxe schicken können, warum nehmen Sie nicht einfach CapiSuite als Absender und Emfänger gleichzeitig? Ersetzten Sie in diesem Fall XXXX durch die Nummer, die Ihr Incoming-Skript behandelt. Dies funktioniert nich, wenn Ihre ISDN-Karte nicht zwei Fax-übertragungen parallel durchführen kann (einige alte AVM-B1-Karten haben z.B. diese Beschränkung).

Wir brauchen jetzt für unsere Tests ein oder mehrere Fax-Dateien im SFF-Format. Erzeugen Sie bitte welche mit einem Namen wie der oben gezeigte. Wenn Sie nicht wissen, wie Sie dies tun sollen, schauen Sie bitte unter dem „Erzeugen eines SFF“ nach.

Wenn ich ein CapiSuite-Skript entwicklen möchte, aber nicht sicher bin, wie es geht, fange ich oft mit einem normalen Skript an, das ich ohne CapiSuite testen kann. Lassen Sie uns also zuerst ein Skript erstellen, das die Dateien durchsucht und die Empfängernummern extrahiert. Wenn das funktioniert, können wir weiter machen und die CapiSuite-spezifischen Aufrufe einfügen.

Beispiel 2.5. idle_example.py

import os,re1

my_path="/path/to/your/capisuite-examples/"

files=os.listdir(my_path)2
files=filter (lambda s: re.match("job-.*\.sff",s),files)3

for job in files:4
	destination=job[4:-3]5 # Hmmm.. Ist das richtig?
	print "found",job,"to destination",destination
1

Wir kennen das os-Modul bereits. re stellt Funktionen zum Suchen nach regulären Ausdrücken zur Verfügung. Wenn Sie nicht wissen, was reguläre Ausdrücke sind, lesen Sie bitte z.B. die Python-Dokumentation des re-Moduls oder eine andere Dokumentation dazu. Sie sind zu kompliziert, um sie hier zu erklären.

2

os.listdir gibt die Dateien eines Verzeichnisses als Liste zurück.

3

Diese Zeile ist ein bisschen trickreicher. Sie filtert alle Dateinamen aus der Liste heraus, die nicht zur Regel mit "job-" beginnen, dann eine beliebige Anzahl von Zeichen, mit ".sff" aufhören passen. Dies wird mit der filter-Funktion gemacht. Die Funktion erwartet den Namen einer Funktion, die die Regel als ersten Parameter prüft und die zu filternde Liste der Dateien als zweiten.

Wir können jetzt eine neue Funktion definieren und ihren Namen hier verwenden, aber das lambda-Schlüsselwort erlaubt eine viel elegantere Lösung: Es definiert eine "namenlose Funktion" mit dem Parameter s. Der Funktionsrumpf folgt direkt danach und besteht aus einem Aufruf von re.match, der prüft, ob der übergebene String s auf den Ausdruck passt.

4

Iterieren über alle gefundenen Dateinamen.

5

Das Ziel wird aus dem gegebenen Dateinamen mit Hilfe von String-Indizes extrahiert.

Speichern Sie das Skript jetzt als idle_example.py in unserem Beispielverzeichnis und lassen Sie es laufen, indem Sie python idle_example.py aufrufen.

Wenn Sie SFF-Dateien mit den richtigen Namen angelegt haben, sollten Sie nun Zeile für Zeile angezeigt werden. Aber... Offensichtlich funktioniert irgendetwas hier nicht richtig. Das Ziel enthält den ".". Ich habe tatsächlich einen Fehler beim indizieren des Strings gemacht. Es sollte destination=job[4:-4] anstatt [4:-3] heißen. ändern wir das also und probieren es nochmal. Es sollte jetzt funktionieren. Das ist der Grund, warum ich solche Skripte lieber zuerst außerhalb von CapiSuite schreibe. Das Debuggen geht so viel schneller...

Da wir jetzt wissen, dass die grundlegenden Teile funktionieren, können wir die richtigen Kommunikationsfunktionen hinzufügen.

Speichern Sie dieses Beispiel bitte wieder als idle_example.py in Ihrem Beispielverzeichnis.

Beispiel 2.6. idle_example.py, Version für CapiSuite

import os,re,capisuite

my_path="/path/to/your/capisuite-examples/"
my_number="678"1
my_stationID="+49 123 45678"
my_headline="example headline"

def idle(capi):2
	files=os.listdir(my_path)
	files=filter (lambda s: re.match("job-.*\.sff",s),files)

	for job in files:
		destination=job[4:-4]
		capisuite.log("sending "+job+" to destination "+destination,1)3
		try:
			(call,result)=capisuite.call_faxG3(capi,1,my_number,destination,
			  60,my_stationID,my_headline)4
			if (result!=0):5
				capisuite.log("job "+job+" failed at call setup with reason "
				  +str(hex(result)),1)
				os.rename(my_path+job,my_path+"failed-"+job)6
				return7
			capisuite.fax_send(call,my_path+job)8
			(result,resultB3)=capisuite.disconnect(call)9
		except capisuite.CallGoneError:
			(result,resultB3)=capisuite.disconnect(call)
			
		if (result in (0,0x3400,0x3480,0x3490) and resultB3==0):10
			capisuite.log("job "+job+" was successful",1)
			os.rename(my_path+job,my_path+"done-"+job)
			return
		else:
			capisuite.log("job "+job+" failed during send with reasons "
			  +str(hex(result))+","+str(hex(resultB3)),1)
			os.rename(my_path+job,my_path+"failed-"+job)
1

Einige Parameter für das Senden des Faxes werden hier gesetzt. my_number ist Ihre eigene Nummer, die zum Senden des Faxes verwendet wird. my_stationID ist die Fax-Gerätekennung, die an die Gegenstelle übermittelt und auf der gesendeten Fax-Seite angezeigt wird. Es sind nur Ziffern und das "+" erlaubt. Sie können außerdem in fax_headline einen kurzen Text definieren, der in der Fax-Kopfzeile angezeigt wird.

2

Wie im „Das Idle-Skript“ erklärt, müssen Sie eine Funktion namens idle definieren, die dann in regelmäßigen Abständen von CapiSuite ausgeführt wird. Deshalb wurde aller Code in diese Funktion verschoben.

3

Wir können keine Meldungen nach stdout ausgeben, da das Skript im Kontext eines Daemons läuft. Deshalb stellt CapiSuite Funktionen bereit, um Einträge in den CapiSuite-Log-Dateien zu erzeugen. log erwartet mindestens zwei Parameter: die Meldung und einen Log-Level. Dieser Level entspricht der Log-Level-Einstellung in der globalen CapiSuite-Konfiguration (siehe „Konfiguration von CapiSuite“). Wenn der Level der Meldung kleiner oder gleich verglichen mit dem Level in der Konfiguration ist, wird sie in die Logs geschrieben. Sie können also Meldungen zu Debug-Zwecken einfügen, die im Normalbetrieb nicht in die Logs geschrieben werden, indem Sie Level größer als 1 verwenden.

4

Diese Funktion initiiert einen ausgehenden Anruf, bei dem der Fax-Service verwendet wird. Die Parameter sind:

  • Referenz auf das von CapiSuite erhaltene CAPI-Objekt (Parameter für idle).

  • Die Nummer des Controllers, der für ausgehende Anrufe verwendet wird. Der erste Controller hat immer die Nummer "1".

  • Die eigene Nummer, die für ausgehende Anrufe verwendet wird

  • Die Empfängernummer des Anrufs

  • Maximale Zeit in Sekunden, die auf einen erfolgreichen Verbindungsaufbau gewartet werden soll

  • Die Fax-Gerätekennung

  • Die Fax-Kopfzeile

Die Funktion gibt ein Tuple zurück, das eine Referenz auf den erzeugten Anruf und einen Fehler-Code enthält.

5

Dieser Block prüft, ob der Verbindungsaufbau erfolgreich war. Eine detaillierte Beschreibung der möglichen Fehler-Codes finden Sie im „CapiSuite-Befehlsreferenz“. 0 bedeutet "alles war OK, die Verbindung wurde aufgebaut".

6

Wenn der Anruf nicht erfolgreich war, wird die Fax-Datei umbenannt, um zu verhinden, dass die selbe Datei immer wieder verschickt wird.

7

Vergessen Sie nicht, die idle-Funktion zu verlassen, wenn die Verbindung nicht aufgebaut werden konnte!

8

Ein weiteres sehr einfaches CapiSuite-Kommando: verschickt die gegebene Datei als Fax-Dokument.

9

Wir haben bislang die Gründe, warum eine Verbindung beendet wurde, ignoriert. Jetzt müssen wir sie analysieren, weil wir wissen müssen, ob die Datei erfolgreich übertragen wurde. Deshalb gibt disconnect ein Tuple zurück, das den physikalischen und logischen Fehler-Code enthält. Jede ISDN-Verbindung enthält eine physikalische und (mindestens) eine logische Verbindung. Man kann sich die physikalische Verbindung als "den Draht" vorstellen, der uns mit dem Empfänger verbindet, während sich die logische Verbindung auf das Fax-Protokoll bezieht, das diesen "Draht" verwendet. Sie müssen sich beide Werte ansehen, um entscheiden zu können, ob alles OK war.

10

Erlaubte Werte für den physikalischen Verbindungsabbau sind 0,0x3400,0x3480 und 0x3490. Diese bedeuten alle "kein Fehler aufgetreten, Verbindung wurde normal beendet". Der logische Wert darf nur 0 sein, wenn alles OK ist. Weitere Informationen zu den Fehler-Codes finden Sie im „CapiSuite-Befehlsreferenz“.

Nachdem Sie die Datei gespeichert und die Standard-Werte an Ihre eigene Konfiguration angepasst haben, ändern Sie bitte den Wert von idle_script in der CapiSuite-Konfiguration, damit er auf dieses Skript verweist (wie im „Konfiguration von CapiSuite“ beschrieben).

Starten Sie CapiSuite neu und beobachten Sie die Logs. Einige Minuten später sollten die Dateien job-XXX.sff verschickt worden und entweder in done-job-XXX.sff oder failed-job-XXX.sff umbenannt worden sein. Wenn der Auftrag fehlgeschlagen ist, schauen Sie bitte in das Error-Log und prüfen die Fehler-Codes, die im „CapiSuite-Befehlsreferenz“ und Anhang B, CAPI 2.0 Fehler-Codes beschrieben sind.

Hoffentlich hat Ihnen dieses Tutorial geholfen zu verstehen, wie Sie Ihre eigenen Skripte schreiben können. Machen Sie bitte weiter, indem Sie die Beispiele oder die Dateien, die mit CapiSuite geliefert werden, modifizieren (lesen Sie den „Struktureller überblick über die Standard-Skripte“ zuvor). Sie finden eine komplette Referenz der verfügbaren Kommandos im „CapiSuite-Befehlsreferenz“.

Wenn Sie Schwierigkeiten haben, Ihre eigenen Skripte zum Laufen zu bringe, nutzen Sie bitte die CapiSuite-Mailingliste. Und vergessen Sie nicht, Spaß dabei zu haben. ;-)