Home Fiffi GEMScript FAQ

Dieser Beitrag wurde in der Revolution 9 veröffentlicht.

Ferngesteuert im Netz

CAB, Fiffi und der MagiC Scripter

Viele Aufgaben lassen sich mit dem WWW-Browser CAB und dem FTP-Client Fiffi gut lösen. Es gibt jedoch wiederkehrende Vorgänge und Routinetätigkeiten, die mit den bordeigenen Mitteln der beiden Internet-Anwendungen nur manuell bearbeitet werden können. Dank der GEMScript-Fähigkeit dieser beiden kann zur Automatisierung aber der MagiC Scripter eingesetzt werden.

Wie in [1] ausführlich erläutert ist GEMScript ein Protokoll, daß die Kommunikation von GEM-Anwendungen beschreibt. Das GEMScript-Protokoll behandelt allerdings nicht den Inhalt der Kommunikation, sondern beinahe ausschließlich die Form der Kommunikation. Beinahe ausschließlich deshalb, weil in der GEMScript-Dokumentation (http://www.uni-karlsruhe.de/~Thomas.Much/GEMScript) einige Standard-Kommandos festgelegt sind, die von den meisten Anwendungen sowieso zur Verfügung gestellt werden (z.B. das Öffnen und Schließen eines Fensters).

Das GEMScript-Protokoll wird zur Zeit hauptsächlich dazu genutzt, eine GEM-Applikation durch eine andere fernzusteuern. So kann man beispielsweise jinnee mittels GEMScript anweisen, einen Notizzettel mit einen bestimmten Inhalt auf das Desktop abzulegen oder Verzeichnisfenster und Icons manipulieren.

Aber erst mit dem MagiC Scripter wird GEMScript so richtig interessant. MagiC Scripter ist zunächst eine Skriptsprache mit einer C-ähnlichem Syntax. Im Gegensatz zur Programmiersprache C gibt es aber Laufzeitprüfungen und - besonders wichtig für unkompliziertes programmieren - ein automatisches Speichermanagment. Durch die Kommunikation über GEMScript wird der Sprachumfang des MagiC Scripter um die Kommandos der betreffenden GEM-Applikation erweitert.

In diesem Beitrag will ich Sie in das 'Fernsteuern' von GEM-Applikation mit dem MagiC Scripter einführen und an einigen Skripts zeigen, wie sich wiederkehrende Vorgänge mit CAB, Fiffi und dem MagiC Scripter automatisieren lassen.

Fernsteuerung

MagiC Scripter kennt drei Möglichkeiten mit GEMScript-fähigen Anwendungen zu kommunizieren: Externe Variablen, Festlegung einer Applikation mittels address() und Funktionsaufrufe der Form appname.funktionsname(<parameter>). Für diesen Beitrag wird nur die letzte Form genutzt. Sowohl der funktionsname als auch die Anzahl der Parameter hängen nur von der angesprochenen Applikation ab und können von MagiC Scripter nicht überprüft werden. Lediglich ein Scheitern der Verbindungsaufnahme zu einer Applikation und die Verwendung einer der jeweiligen Anwendung unbekannten Funktion können zu Laufzeitfehlern führen.

Will man CAB aus einem Skript heraus anweisen, die Homepage der Revolution-Redaktion anzuzeigen, so kann dies wie folgt aussehen:

  CAB.open( "http://www.deltalabs.com" );

Wenn in CAB ab V2.7 dann unter Optionen/Allgemein noch 'automatisch Verbinden' aktiviert ist, wird automatisch mit IConnect eine Verbindung ins Internet aufgebaut und die Homepage geladen.

Automatischer Web-Zugriff und mehr

Im Gegensatz zu anderen Internet-Client benötigt ein WWW-Browser in beinahe allen Situationen die Interaktion mit dem Anwender. Es ist also es durchaus verständlich, daß die GEMScript-Kommandos von CAB größtenteils das Browser-Fenster beeinflussen. So öffnet CAB.open() ein Fenster mit einer bestimmten URL, CAB.print() druckt das dargestellte Dokument und CAB.save() speichert es schließlich ab.

Das Öffnen eines Dokuments via MagiC Scripter bietet sich an, falls Sie eine WWW-Seite lesen, die sich täglich ändert (z.B. die Milan Homepage mit CAB.open( "http://www.milan-computer.de" )). Ist dann noch das Verfallsdatum Serverseitig sinnvoll gesetzt ist, entscheidet CAB ob die Seite aus dem Cache geladen wird oder ob sie neu angefordert werden müssen. Da CAB via GEMScript geladene Dokumente nicht unter einem frei wählbaren Namen abspeichert - bisher muß man den Dateinamen noch manuell über die Dateiauswahlbox festlegen - sind die Verwendungsmöglichkeiten natürlich eingeschränkt.

Weitaus interessanter für die Verwendung mit MagiC Scripter dürften daher zur Zeit die beiden Kommandos CAB.bookmarknewtopic() und CAB.bookmarknewentry() sein. Ersteres erweitert die Hotlist um eine neue Rubrik, zweiteres fügt in diese einen Eintrag ein. Das Skript L2H.sic benutzt diese beiden Kommandos, um Links der Form '<a href="Url">Name</a>' aus übergebenden (HTML-) Datei in die Hotlist von CAB einzutragen. Als Rubrik-Name wird dabei der jeweilige Dateiname benutzt.

Ferngesteuerter Dateitansfer

Ein FTP-Programm eignet sich weit aus mehr zur Fernsteuerung von außen. Über GEMScript kann Fiffi eine FTP-Sitzung einrichten und alle möglichen Dateioperationen, die auch manuell möglich sind, ausführen (z.B. Dateien vom FTP-Server laden oder ablegen und Verzeichnisse erzeugen oder löschen). Im MagiC Scripter muß Fiffi dazu zunächst mit Fiffi.open() der Name des Servers und optional der Name des Accounts, das Paßwort und ein Verzeichnis übergeben werden. Kann Fiffi die Sitzung einrichten (unter Optionen/Internet 'IConnect starten' und 'Verbindung aufbauen' aktivieren) ist der Rückgabewert größer als null und gleichzeitig das Handle für alle weiteren Kommandos, die sich auf diese Sitzung beziehen - die GEMScript-Kommunikation mit Fiffi ist im Gegensatz zu CAB also verbindungsorientiert. Ist die Rückgabe dagegen kleiner null, konnte die Sitzung nicht eingerichtet werden und das Skript kann am Rückgabewert die mögliche Fehlerursache erkennen (s. Dokumentation zu Fiffi).

Angenommen Sie müßen regelmäßig verschiedene Dateien auf einem FTP-Server in ein bestimmtes Verzeichnis legen. Diese sich wiederholende Tätigkeit läßt sich leicht durch ein Skript erledigen. Das Skript Upload.sic richtet eine FTP-Sitzung ein. Danach werden alle per Kommandozeile übergebenen Dateien zu dem FTP-Server transferiert. Das Verzeichnis, in das die Dateien gelangen, wird gleich beim Einrichten der Sitzung mit Fiffi.open() festgelegt. Eine andere Möglichkeit wäre, das Verzeichnis mit Fiffi.cd() erst nach dem Einrichten der Sitzung zu setzen.

Das Skript kann sogar für etwas ausgefallenere Anwendungen wie etwa die Bereitstellung aktueller Grafiken auf einer Homepage oder eine WebCam genutzt werden. Eine WebCam stellt regelmäßig ein von einer Digitalkamera aufgenommenes Bild einer bestimmten Situation auf einem WWW-Server zur Verfügung. Regelmäßig kann für beide Anwendungen alle zwei Sekunden (bei einem Intranet) oder auch nur alle sechs Stunden (Einwahl bei einem Provider) bedeuten. Dazu wird das Skript zu bestimmten Zeiten gestartet - beispielsweise mit 'Start Me Up!' (http://thmuch.home.pages.de) - und bekommt als Parameter die zu übertragene Datei übergeben.

Abgleich einer Homepage

Eine eigene Homepage ist auch für einen Atari-Anwender in diesen Tagen nichts besonderes mehr. Üblicherweise befindet sich eine Kopie der Homepage auf dem heimischen Rechner, um sie dort offline mit dem Duo qed/CAB oder auch mit dem Dokumentationsgenie UDO überarbeiten und erweitern zu können. So ein Dokument umfaßt mit den HTML-Files und Grafiken bisweilen einige zig Dateien, die sich oftmals der Hierarchie wegen in verschiedenen Verzeichnissen befinden. Die Dateien einer Homepage werden dann vom lokalen Rechner mittels FTP (File Transfer Protocol), also beispielsweise mit Fiffi, auf den WWW-Server übertragen. Nun ist es ziemlich mühsam, eine umfangreichere Homepage nach geänderten oder neuen Dateien zu durchsuchen und diese Dateien manuell mit Fiffi in die verschiedenen Verzeichnisse auf dem WWW-Server abzulegen. Mit einem geeigneten Skript kann man diese Arbeit getrost dem MagiC Scripter und Fiffi im Hintergrund erledigen lassen.

Das Skript UMHP.sic sucht beim Start im Verzeichnis der Homepage auf dem lokalen Rechner die Datei Last.Update. Wird diese gefunden, wird daraus der Zeitpunkt des letzten Abgleichs der Homepage gelesen; wird sie nicht gefunden, geht das Skript davon aus, daß alle Dateien auf dem WWW-Server abgelegt werden sollen. Anschließend durchsucht das Skript rekursiv die Verzeichnisse der Homepage auf dem lokalen Rechner nach Dateien und Verzeichnisse, die jüngeren Datums sind und merkt sich diese. Nun wird Fiffi gestartet, eine FTP-Sitzung gemäß obigen Ausführungen geöffnet und die geänderten oder neuen Dateien im Verzeichnis der Homepage abgelegt. Zum Schluß wird noch die Datei Last.Update mit der aktuellen Systemzeit geschrieben.

Dateien, die für die Homepage nicht mehr benötigt werden, also in der lokalen Kopie nicht mehr vorhanden sind, werden von dem Skript auf dem Server nicht gelöscht. Eine mögliche Erweiterungen könnte daher nach dem Ablegen der Dateien mit Fiffi.ls() eine Liste der Dateien und Verzeichnisse der Homepage auf dem Server erstellen und anschließend mit einem Vergleich der lokalen Daten überflüssige Einträge mit Fiffi.rm() und Fiffi.rmdir() löschen.

Fazit

Ich hoffe, die hier gezeigten Beispiele haben Ihnen Appetit auf mehr (eigene) Skripts für die beiden Internet-Clients gemacht. Dank der GEMScript-Unterstütung lassen sich beliebig viele Funktionen nachrüsten, ohne den Programmierer des jeweiligen Clients erstmal von seinen Vorstellungen überzeugen zu müssen. Ich - und viele Anwender - würden sich freuen, wenn Sie selbst geschriebene Skripts der Öffentlichkeit zur Verfügung stellen.

Bei all der schönen neuen Funktionalität sollte Sie aber immer bedenken, daß das Einrichten der Verbindung und vorallem deren Abbau nicht immer reibungslos verläuft. Daher gilt die Warnung: Wer Internet-Zugriffe automatisiert, riskiert Telefon-Gebühren in ungeahnten Höhen!

Jürgen Koneczny

[1] GEMScript - Die ferngesteuerte Geisterhand, Revolution Januar/Februar 1998

GEMScript-Kommandos CAB

bookmarknewentry Fügt eine neue Rubrik in die Hotlist ein.
bookmarknewtopic Fügt einen neuen Eintrag in eine Rubrik ein.
close Schließt das Fenster mit der angegebenen URL oder das Oberste.
new Öffnet ein neues Fenster mit der URL des obersten Fenster von CAB.
open Öffnet ein neues Fenster mit einer angegebenen URL.
print Druckt das Fenster mit der angegebenen URL oder das Oberste.
quit Beendet CAB.
save Speichert das Fenster mit der angegebenen URL oder das Oberste.
sendmail Versendet eine EMail.
tofront Bringt das Fenster mit der angegebenen URL nach oben.

GEMScript-Kommandos Fiffi

cd Wechselt in der Sitzung in das angegebene Verzeichnis.
close Schließt die angegebene Sitzung oder die Oberste.
get Lädt die angegebene Datei vom Server auf den lokalen Rechner.
getfront Gibt den Namen des Host des obersten Fensters zurück.
lcd Setzt das Verzeichnis, in das Fiffi empfangene Dateien speichert.
ls Liefert den Inhalt des angegebenen bzw. aktuellen Verzeichnisses.
mkdir Erzeugt das angegebene Verzeichnis auf dem Server.
open Öffnet eine FTP-Sitzung.
put Speichert die angegebene Datei auf dem Server.
pwd Gibt das aktuelle Verzeichnis des Servers zurück.
quit Beendet Fiffi.
rm Löscht die angegebene Datei auf dem Server.
rmdir Löscht das angegebene Verzeichnis auf dem Server.
tofront Bringt das Verzeichnisfenster, das zur angegebenen Sitzung gehört, nach vorne.
type Stellt den Transfertyp für die angegebene Sitzung ein.
/**********************************************************************
  Name: L2H.sic (Link to Hotlist)

  Autor: Jürgen Koneczny

  Beschreibung: Dieses Skript durchsucht die übergebenden Dateien nach
      Links der Form '<a href="Url">Name</a>' und trägt diese in die 
      Hotlist von CAB ein.
***********************************************************************/

// *** Anfang der Konfiguration ***

// Zugriffspfad Fiffi und CAB
const CabPath = "C:\\Gem\\CAB\\CAB.app";

// *** Ende der Konfiguration ***


const Title = "Link 2 Hotlist";

proc  main( ... )
  local   i, Line;
{
  if( argc > 0 )
  {
      progstart( CabPath, "" );
      for( i = 0; i < argc; i++ )
      {
          Line = ReadFile( argv[i] );
          if( Line.length )
          {
              CAB.bookmarknewtopic( "L2H: " + basename( argv[i] ));
              GetLinks( "L2H: " + basename( argv[i] ), Line );
          }
      }
  }
  else
      dialog.note( Title, "Eine HTML-Datei auf L2H ziehen!", "-bAbbruch" );
}

proc  ReadFile( File )
  local   i, Line;
{
  if( fopen( File, "r" ))
  {
      while( getline( File, Line[i++] ));
      fclose( File );
      return( Line );
  }
  return( 0 );
}

proc  GetLinks( Topic, Line )
  local   i, j, Name, Tmp, Url;
{
  for( i = 0; i < Line.length; i++ )
  {
      if( match( Line[i], "<a href=\"*\">*</a>" ))
      {
          Tmp = substr( Line[i], index( Line[i], "<a href=\"" ) + 9 );
          strncpy( Url, Tmp, index( Tmp, "\">" ));
          Tmp = substr( Tmp, index( Tmp, "\">" ) + 2 );
          strncpy( Name, Tmp, index( Tmp, "</a>" ));
          CAB.bookmarknewentry( Topic, Url, Name );
      }
  }
}
/**********************************************************************
  Name: Upload.sic

  Autor: Jürgen Koneczny

  Beschreibung: Dieses Skript legt alle per Kommandozeile übergeben
      Dateien mittels Fiffi auf einen FTP-Server.
      Fiffi sollte so konfiguriert sein, daß die Internet-Verbindung
      automatisch aufgebaut wird (Optionen/Internet).
***********************************************************************/

// *** Anfang der Konfiguration ***

// Server-Daten
const Server = "ftp.camelot.de";
const User = "zulu";
const Password = "****";

// Zugriffspfad der Homepage auf dem Server
const Dest = "/home/zulu/";

// Zugriffspfad Fiffi und CAB
const FiffiPath = "C:\\Gem\\Fiffi\\Fiffi.app";

// *** Ende der Konfiguration ***

const Title = "Upload";

proc  main( ... )
  local i;
{
  if( argc > 0 )
  {
      progstart( FiffiPath, "" );
      wait( 400 );

      if(( Session = Fiffi.open( Server, User, Password, Dest )) > 0 )
      {
          for( i = 0; i < argc; i++ )
          {
              if( Fiffi.put( Session, argv[i] ) != 0 )
              {
                  dialog.note( Title, "Fehler bei", argv[i], "-bAbbruch" );
                  break;
              }
          }
          Fiffi.close( Session );
      }
      else
          dialog.note( Title, "Fehler beim Einrichten der Sitzung", "-bAbbruch" );    
  }
  else
      dialog.note( Title, "", "Mindestens ein Argument übergeben", "-bAbbruch" );
}

/**********************************************************************
  Name: UMHP.sic (Upload My Homepage)

  Autor: Jürgen Koneczny

  Beschreibung: Dieses Skript lädt einen Verzeichnisbaum mittels Fiffi
      auf einen FTP-Server. Es werden nur Dateien und Verzeichnisse 
      beachtet, die jüngeren Datums sind, als der letzte Upload auf
      diesen Server. Das Script eignet sich daher insbesondere zum Ab-
      gleich einer Homepage auf einem WWW-Server.
      Fiffi sollte so konfiguriert sein, daß die Internet-Verbindung
      automatisch aufgebaut wird (Optionen/Internet).
***********************************************************************/

// *** Anfang der Konfiguration ***

// Server-Daten
const Server = "ftp.camelot.de";
const User = "zulu";
const Password = "******";

// Zugriffspfad der Homepage auf dem Server
const Dest = "/home/zulu/.html-data";

// Zugriffspfad der Homepage auf dem lokalen Rechner
const CODE = "C:\\Daten\\Prog\\Homepage";

// Zugriffspfad Fiffi und CAB
const FiffiPath = "C:\\Gem\\Fiffi\\Fiffi.app";
const CabPath = "C:\\Gem\\CAB\\CAB.app";

// *** Ende der Konfiguration ***


const Title = "Update My Homepage";

proc  main()
  local   DateFile, i, Ret, Session, Success;
{
  DateFile = CODE + "\\Last.Update";

  if( fopen( DateFile, "r" ))
  {
      getline( DateFile, Date );
      fclose( DateFile );
      files.rm( DateFile );
  }
  else
      Date = 0;

  GetFiles( CODE, Dest );

  if( Files.length > 0 )
  {
      progstart( FiffiPath, "" );
      wait( 400 );

      if(( Session = Fiffi.open( Server, User, Password, Dest )) > 0 )
      {
          Success = 1;
          for( i = 0; i < Files.length; i++ )
          {
              if( Files[i, 2] & 16 )
                  Ret = Fiffi.mkdir( Session, Files[i, 1] );
              else
                  Ret = Fiffi.put( Session, Files[i, 0], Files[i, 1] );
              if( Ret != 0 && Ret != 553 )    // 553 ist die Antwort des Servers, 
                                          // falls das Verzeichnis bereits existiert
              {
                  dialog.note( Title, "Fehler bei", Files[i, 0], "-bAbbruch" );
                  Success = 0;
                  break;
              }
          }
          Fiffi.close( Session );
      }
      else
          dialog.note( Title, "Fehler beim Einrichten der Sitzung", "-bAbbruch" );    
  }

  if( fopen( DateFile, "w" ))
  {
      if( Success )
          putline( DateFile, time());
      else
          putline( DateFile, Date );
      fclose( DateFile );
  }
}


proc  GetFiles( LocalDir, ServerDir )
  local   Anz, i, j, List;
{
  Anz = filelist( List, LocalDir );
  for( i = 0; i < Anz; i++ )
  {
      if( List[i, 2] > Date )
      {
          j = Files.length;
          Files[j, 0] = LocalDir + "\\" + List[i, 0];
          Files[j, 1] = ServerDir + "/" + List[i, 0];
          Files[j, 2] = List[i, 3];
      }
      if( List[i, 3] & 16 )
          GetFiles( LocalDir + "\\" + List[i, 0], ServerDir + "/" + List[i, 0] );
  }
}

Copyright © by Jürgen Koneczny
Letzte Änderung: 23. Februar 1999