Volkers Homepage

<Newsserver: Hamster goes Usenet    ^Startseite    >Scoring: News filtern

Hamster mit Skripten automatisieren

Hamster-Skripte

Ich habe da vorne mal geschrieben, dass du mit Skripten deinem Hamster das Zaubern beibringst. Das stimmt tatsächlich. Du wirst staunen, was die Skriptsprache des Hamsters alles kann.

Dies ist allerdings kein ausführlicher Skriptschreiblehrgang, sondern wirklich nur eine Anregung zum Selberprobieren. Ich kann und will aus dir hier keinen Programmierer machen. Learning by doing ist angepfiffen! Die Skriptbefehle findest du alle in der Hamster-Hilfe knapp, aber gut erklärt. Und Skripte für alle Anwendungen findest du im Skriptarchiv. Lad dir einige herunter und sieh sie dir an – da kannst du eine Menge lernen.

Grundsätzliches

Da ich nicht weiß, wie viel Ahnung du vom „Programmieren“ an sich hast, möchte ich erst einmal einige Grundbegriffe klären. Fachleute mögen diese Liste nachsichtig lesen; ich nehme es mit den Begriffen nicht so genau.

  • Die meisten Hamster-Skriptbefehle sind Funktionen. Diese unterscheiden sich von einfachen „Kommandos“ dadurch, dass sie ein Ergebnis liefern, das heißt: sobald sie fertig ausgeführt sind, haben sie einen bestimmten Wert, mit dem du „weiterrechnen“ kannst. Beispiel: der Befehl, eine DFÜ-Verbindung aufzubauen, ist eine Funktion namens HamRasDial. Diese Funktion hat den Wert 0, wenn der Aufbau erfolgreich war, und einen Wert von über 0 (nämlich die Fehlermeldung), wenn es beim Verbindungsaufbau einen Fehler gab.

  • Variablen sind einfach „Zwischenspeicher“, in denen du alle möglichen Werte ablegen kannst, um sie später wieder aufzurufen. In der Hamster-Skriptsprache fangen Variablen immer mit dem Dollarzeichen $ an. Du kannst beliebig viele davon deklarieren und ihnen hinterher jeden möglichen Wert zuweisen oder sie in Rechenvorgänge, Bildschirmausgaben etc. einbauen.

  • Schleifen sind immer an irgendeine Bedingung geknüpft. Die Schleife wird so oft durchlaufen, bis (oder solange) eine Bedingung erfüllt oder nicht erfüllt ist – je nachdem.

  • Verzweigungen sind auch an Bedingungen geknüpft. Der Verzweigungsbefehl lautet

    if (Bedingung)
      <erster Zweig>
    [ else
      <zweiter Zweig> ]
    endif

    Der erste Zweig wird durchlaufen, wenn die Bedingung zutrifft, ansonsten der zweite Zweig (der auch fehlen kann, daher die eckigen Klammern). Das endif muss auf jeden Fall dahinter – da treffen sich die beiden Zweige wieder.

Eine genaue Erklärung der einzelnen Befehle findest du in der Hamster-Hilfe.

Doch genug der Theorie – ich würde jetzt vorschlagen, wir nehmen das Skript für die News-Abfrage und bauen es ein bisschen aus!

Skript-Ausschnitt
Ich empfehle dir, einen Editor mit Syntax-Highlighting zu verwenden, der die Elemente eines Skripts unterschiedlich einfärbt. Ein paar Empfehlungen findest du im Hamster-Kompendium (Link auf der Startseite).

HamRasDial ("T-Online")
print (HamRasDial ("T-Online"))

HamRasDial hat einen Rückgabewert: Die obere Zeile unternimmt einfach nur einen Anwahlversuch. Die untere macht das selbe, schreibt dir aber anschließend noch eine Null (wenn's geklappt hat) oder die Fehlernummer (wenn nicht) ins Hamster-Protokoll

Luxus Eins: Automatischer Verbindungsaufbau

(Das funktioniert nur dann, wenn du dich per Windows-DFÜ-Netzwerk ins Internet einwählst und nicht mit einer speziellen Zugangssoftware. Evtl. kann Hamster auch auf Zugangssoftware zugreifen, aber darauf kann ich hier nicht eingehen.)

Dafür brauchen wir zwei Hamster-Befehle:

  • HamRasDial ( "<Name der Verbindung>" ) baut eine DFÜ-Verbindung auf

  • HamRasHangup trennt sie wieder.

Wie du das einbaust, siehst du rechts (am Beispiel einer T-Online-Verbindung).

Das HamWaitIdle am Schluss ist wichtig, damit der Hamster die Verbindung erst dann abbaut, wenn er mit allen Jobs fertig ist!

Außerdem musst du dem Hamster spätestens jetzt die Zugangsdaten für deine DFÜ-Verbindung verraten. Dies machst du unter Einstellungen – Benutzerverwaltung... – Passworte; deine Verbindung solltest du dort ziemlich weit oben finden.

Und wenn du jetzt dein Skript anwirfst, müsste der Hamster sich eigentlich von selbst einwählen, News abgleichen und die Verbindung wieder schließen.

Die Sache hat einen Haken: Wenn schon eine Verbindung steht (z.B. du gerade am Surfen bist), dann bekommst du hier nur eine Fehlermeldung – der Hamster kann keine Verbindung aufbauen, denn es steht ja schon eine. Daher bauen wir jetzt eine Erkennung ein, ob schon eine Verbindung steht, und wenn ja, soll der Hamster sich nicht einwählen, sondern die bestehende Verbindung benutzen.

#!hs2
  
 HamRasDial ( "T-Online" )
  
 HamFetchMail ( ... )
 Sleep ( 10000 )
  
 HamSendMail ( ... )
  
 HamNewsJobsClear
 HamNewsJobsPostDef
 HamNewsJobsPullDef
 HamNewsJobsStart
  
 HamWaitIdle
 HamRasHangup
  
 quit

Skript, das sich automatisch ein- und wieder „auswählt“. Was in die Klammern gehört, weißt du ja.

Luxus Zwei: Verbindungsabfrage

Dafür gibt es die Funktion RasGetConnection. Die liefert, wenn eine DFÜ-Verbindung steht, den Namen der Verbindung. Ansonsten liefert sie eine leere Zeichenkette (Länge Null). Zeichenketten („Strings“) werden, um sie von Zahlenwerten zu unterscheiden, immer in "Anführungszeichen" gesetzt. Ein Leerstring sieht also so aus: "" – zwei Anführungszeichen mit nichts dazwischen.

Verzweigung mit if

Jetzt müssen wir eine Verzweigung einbauen, mit dem if-Befehl: Nur dann, wenn keine Verbindung steht, soll der Hamster eine aufbauen. Wie das aussehen könnte, siehst du rechts.

Damit wird T-Online nur noch dann angewählt, wenn noch keine Verbindung steht (RasGetConnection gleich Leerstring). Beachte, dass die Bedingung hinter dem if immer in Klammern stehen muss. Die Einrückung des HamRasDial um zwei Zeichen nach rechts habe ich nur zur Übersichtlichkeit gemacht, die muss nicht sein.

Die Sache hat jetzt allerdings einen ganz fürchterbaren Nachteil. Stell dir mal vor, du bist gerade am Surfen und wirfst den Hamster an. Der erkennt, dass eine Verbindung steht, übergeht den HamRasDial-Befehl ordnungsgemäß, lädt deine News runter – dann kommt er schließlich an den HamRasHangup-Befehl, legt auf, und mit dem Surfen ist Schluss!

Variablen

Wir müssen also dafür sorgen, dass der Hamster „sich merkt,“ ob er selbst eine Verbindung aufgebaut hat oder nicht. Und dafür können wir eine Variable einführen, in der wir eine entsprechende Information ablegen. Wir können die Variable nennen, wie wir wollen, nur mit $ muss sie anfangen. Meinetwegen nennen wir sie $hamsterwahl. Wir legen fest: Wenn ihr Wert 1 ist, hat der Hamster die Verbindung aufgebaut, ansonsten soll der Wert 0 sein.

Eine Variable muss deklariert werden, bevor man sie benutzt. Das macht der var-Befehl. Er sagt: „Achtung, wir werden in diesem Skript eine Variable namens $hamsterwahl verwenden“.

Im ersten Zweig wird jetzt nicht nur die DFÜ-Verbindung hergestellt, sondern auch die Variable $hamsterwahl auf den Wert 1 gesetzt.

Ich habe außerdem noch einen else-Zweig eingebaut, der dann durchlaufen wird, wenn die Bedingung nicht zutrifft (also in unserem Fall bereits eine Verbindung besteht): in diesem Fall wird die Variable auf 0 gesetzt.

Dann müssen wir noch (ebenfalls mit einer if-Verzweigung) dafür sorgen, dass der HamRasHangup-Befehl diese Variable auch wieder abfragt: Die Verbindung wird nur noch dann geschlossen, wenn die Variable $hamsterwahl auf 1 gesetzt ist – und das ist nur dann der Fall, wenn der Hamster die Verbindung selbst aufgebaut hat.

Dazwischen können beliebig viele Skriptzeilen liegen. Variablen sind sozusagen Zeilen auf Hamsters Notizblock – eine Variable behält ihren Wert, bis du ihn entweder änderst oder das Skript beendest.

Ganz schön raffiniert, gell? Aber jetzt kommt’s noch raffinierter. Denn jetzt soll uns der Hamster fragen, ob eine schon bestehende Verbindung hinterher getrennt werden soll. Zum Beispiel wenn du nach einer Surf-Sitzung noch schnell den Hamster anwirfst und dann offline gehen willst.

if ( RasGetConnection = "" )
  HamRasDial ( "T-Online" )
endif

Verbindung wird nur dann aufgebaut, wenn noch keine besteht

var ( $hamsterwahl )
  
 if ( RasGetConnection = "" )
   HamRasDial ( "T-Online" )
   $hamsterwahl = 1
 else
   $hamsterwahl = 0
 endif
  
 ##### - Hier kommen die üblichen Befehle -
  
 if ( $hamsterwahl = 1 )
   HamRasHangup
 endif

Verbindung wird nur dann beendet, wenn das Skript sie auch aufgebaut hat

Luxus Drei: Dialog mit dem Hamster

Der Hamster kann dir Fragen stellen und Antworten auswerten. Das geschieht mit der Funktion MsgBox, die wir ja auch schon verwendet haben: Die setzt ein Abfragefenster auf den Bildschirm und wartet, bis du einen Button drückst; der Rückgabewert dieser Funktion hängt davon ab, welcher Button das war. Näheres findest du in der Hilfe (im Abschnitt Hamster-Skripte – Funktionen (allgemein) – Ein- und Ausgabe).

Wir bauen jetzt ein Dialogfenster ein, das uns bei schon bestehender Verbindung fragt, ob sie hinterher getrennt werden soll oder nicht.

Weil diese Abfrage, wie gesagt, nur dann kommen soll, wenn schon eine Verbindung steht, setzen wir sie in den else-Zweig der ersten if-Verzweigung (ich hoffe, du steigst noch durch). Den kompletten if-Absatz für den Verbindungsaufbau siehst du rechts.

Ohje, das sieht ja fürchterlich aus. Ich habe in den else-Zweig der ersten Verzweigung eine zweite if-Verzweigung eingebaut! Sehen wir uns diese zweite if-Verzweigung mal genauer an:

  • Die Bedingung für diese zweite Verzweigung lautet MsgBox (...) = 6. Das bedeutet: Sobald der Hamster in der Skriptausführung an diese Stelle kommt, präsentiert er ein Fragezeichenfenster auf dem Bildschirm und wartet, bis du im Fenster einen Button drückst. Wenn du Ja drückst, bekommt die Funktion MsgBox den Wert 6, womit die if-Bedingung erfüllt wäre, bei Nein erhält MsgBox den Wert 7.

    Die Werte 6 für Ja und 7 für Nein sind fest vorgegeben, in der Hamster-Hilfe kannst du sie nachlesen.

  • Bei Ja (MsgBox...=6) ist die Bedingung erfüllt, die Variable $hamsterwahl wird auf 1 gesetzt (damit am Schluss der HamRasHangup-Befehl zuschlägt).

    Bei Nein bekommt $hamsterwahl den Wert Null.

  • Der Textinhalt der Message-Box steht direkt in der Klammer hinter der Funktion, dann die Titelzeile des Fensters, dann die Art des Fensters (hier: 0x20 für „Frage-Fenster“), und schließlich die Buttons: 0x4 heißt „Ja und Nein“.

Nur für Cracks: Die komplette zweite if-Bedingung, die wir eben eingebaut haben, könnte man auch durch folgende einzige Zeile ersetzen:

$hamsterwahl = MsgBox ( "Verbindung hinterher trennen?", _
"Hamsterskript" , 0x20|0x4 ) - 7

Das ergibt dann auch null für "Nein" bzw. eins für "Ja" (rechne nach). Aber die Lösung mit if ist für den Anfang entschieden übersichtlicher...

Man kann eine lange Zeile umbrechen, indem man an das Ende einen Leerschritt und dann einen Unterstrich eingibt – dann denkt sich Hamster die folgende Zeile noch hinten dran.

 if ( RasGetConnection = "" )
   HamRasDial ( "T-Online" )
   $hamsterwahl = 1
 else
   if ( MsgBox ( "Verbindung hinterher trennen?" , _
       "Hamsterskript" , 0x20|0x4 ) = 6 )
     $hamsterwahl = 1
   else
     $hamsterwahl = 0
   endif
 endif

Hamster stellt Fragen. – Man kann eine lange Skriptzeile umbrechen, indem man an das Ende einen Leerschritt und dann einen Unterstrich setzt.

Luxus Vier: Wiederholung des Anwahlversuches

Für die ganz Unentwegten bauen wir jetzt noch was ein, und zwar eine Wiederholung des Anwahlversuchs für den Fall, dass der DFÜ-Aufbau nicht geklappt hat. Ich habe ja schon gesagt, dass HamRasDial eine Funktion ist, deren Wert über 0 liegt, wenn’s nicht geklappt hat. Daher lässt sich das ganz einfach feststellen.

Jetzt bauen wir eine Schleife, und dafür verwenden wir den repeat ... until-Befehl. Alles, was zwischen repeat und until steht, wird so lange ausgeführt, bis die Bedingung hinter until erfüllt ist.

Nicht ärgern, wenn du nicht gleich durchsteigst...

  • Ich führe eine neue Variable $anzahl ein, die die Anwahlversuche mitzählt. Bei jedem Durchlauf der Schleife wird $anzahl mit inc (...) um 1 erhöht. Die repeat-until-Schleife wird so oft durchlaufen, bis $anzahl größer als 4 ist.

  • Nehmen wir mal an, beim ersten Versuch klappt’s nicht. Dann ist der Wert von HamRasDial, sobald der Hamster aufgibt, gößer als Null, und der if-Abschnitt wird nicht ausgeführt. Also wird $anzahl einfach mit dem Befehl inc ($anzahl) um eins erhöht – auf 2. Das until stellt fest, dass $anzahl nicht größer als 4 ist und setzt den Hamster wieder an den Anfang der Schleife, hinter das repeat. (Das wird höchstens vier Mal versucht, dann ist die Bedingung hinter dem until erfüllt, weil $anzahl ja bei jedem Durchlauf um eins erhöht wird.)

    Da $anzahl nun größer als 1 ist, trifft – im zweiten Durchlauf – das erste if zu, und der Hamster macht erstmal zehntausend Millisekunden Pause. Dann versucht er wieder, die Verbindung aufzubauen. Nehmen wir an, jetzt, beim zweiten Versuch, klappt es. Dann ist HamRasDial = 0 und der if-Abschnitt wird durchlaufen, also $hamsterwahl auf 1 und $anzahl auf 5 gesetzt. Der inc-Befehl erhöht den Wert von $anzahl nochmal, auf 6, und am until wird die Schleife verlassen – $anzahl ist ja nun größer als 4.

  • An dem Wert von $hamsterwahl kann der Hamster jetzt erkennen, ob der Verbindungsaufbau geklappt hat. Im nächsten if-Befehl wird dieser Wert abgefragt: wenn $hamsterwahl 0 ist, wird das Skript mit einer entsprechenden Meldung (print (...)) beendet (quit), ansonsten geht es weiter im Text.

var ( $hamsterwahl , $anzahl )
 
 if ( RasGetConnection = "" )
  $anzahl = 1
  $hamsterwahl = 0
 
   repeat
 
     if ( $anzahl > 1 )
      sleep ( 10000 )
    endif
 
     if ( HamRasDial ( "T-Online" ) = 0 )
      $hamsterwahl = 1
      $anzahl = 5
    endif
 
     inc ( $anzahl )
 
   until ( $anzahl > 4 )
 
   if ( $hamsterwahl = 0 )
    print ( "Aufbau fehlgeschlagen!" )
    quit
  endif
 
 else
 
   if ( MsgBox ( "Verbindung hinterher trennen?", _
      "Hamsterskript" , 0x20|0x4 ) = 6 )
    $hamsterwahl = 1
  else
    $hamsterwahl = 0
  endif
 
 endif

Anwahlprozedur mit mehreren Versuchen

Bestanden...

Das war aber schon ganz schön heftig, oder? Nun, ich will aus dir ja keinen Programmierer machen – dafür reicht der Platz hier nicht aus. Ich wollte dir ja nur mal zeigen, wie komfortabel man sich die Arbeit mit dem Hamster gestalten kann, wenn man mit Skripten arbeitet. Deshalb habe ich von Anfang an dazu geraten, dass du dich gleich dran gewöhnst.

Versuch doch als nächste Übung, das Skript automatisch alle 15 Minuten ablaufen zu lassen. Dafür könntest du das komplette Skript (nach dem #!hs2-Befehl!) in eine Schleife packen (mit until (1=2) oder einer ähnlichen nie erfüllten Schleifenbedingung) und ein entsprechend großes sleep einbauen.

Das ist die Holzhammer-Methode. Richtig komfortabel geht das mit der Scheduler-Funktion des Hamsters. Da kannst du die Zeiträume, während der ein Skript gestartet wird, genau festlegen – für jeden Wochentag einzeln.

Skripthamster
Dein Hamster und deine Skripte – ein unschlagbares Paar

<Newsserver: Hamster goes Usenet    ^Startseite    >Scoring: News filtern