Howto: Mobile Webinterface

Ich schrieb ja vor kurzem darueber, dass ich eine kleine Werder Bremen Newsuebersicht erstellt habe. Als ich nun fuer ein paar Tage im Kurzurlaub war und die Seite ueber mein Handy aufrief, fiel mir auf, dass sie ein mobiles Interface gebrauchen koennte. Das Bild war zu gross, und generell haette man wohl auch was bei den Ladezeiten optimieren koennen. Wieder zurueck habe ich mich dann gleich an die Arbeit gemacht. Schnell bin ich auf zwei sehr nette Loesungen gestossen und habe kurzerhand beide miteinander Kombiniert. Die Loesungen findet Ihr auf den beiden Seiten:

Der erste Blogeintrag beschreibt, worauf man achten muss wenn man ein mobile Webseite erstellt, und beinhaltet eine Anleitung um seine eigene Seite mobil-Freundlich mit einer Subdomain zu erstellen. Der Weg ist recht simpel: Man erstellt eine Subdomain, z.B. von www.pregos.info dann mobile.pregos.info und weist der Subdomain den gleichen DocumentRoot zu. Anschliessend erstellt man zwei PHP Dateien und legt diese in den DocumentRoot. Beide PHP-Dateien werden ueber eine .htaccess vor und nach jeder HTML-Seite aufgerufen. Dabei wird ueberprueft ob die mobile.pregos.info Subdomain aufgerufen wurde, und wenn ja der HTML-Quelltext durch verschiedene Filter gejagt, die dann die Seite entsprechend anpassen.

Dieser Weg ist sehr schnell eingerichtet und funktioniert wunderbar. Ich finde ihn aber nicht schoen, denn das Szenario was mir vorschwebt ist eine mobile Seite von http://werder.pregos.info unter der gleichen Domain, da  jetzt noch ne Subdomain ranzuhaengen http://m.werder.pregos.info, nee, zuviel. Ich moechte, dass die Seite je nachdem von welchem Geraet sie aufgerufen wird, entweder als mobile Version oder als normale zu sehen ist.

Ein simpler Weg dieses zu erreichen waere z.B. mittels JavaScript festzustellen wie gross die Bildschirmaufloesung des anzeigenden Browsers ist und dementsprechend die Seite mittels CSS zu layouten. Das bedeutet aber gleichzeitig, dass ich mit JavaScript arbeiten muss und alle Browser das unterstuetzen muessen und Rechenleistung auf dem mobilen Geraet und und und… Ich will EINE Domain, EINE URL und SELBSTERKENNUNG des Servers.

Ueber WURFL (Wireless Universal Ressource File) bin ich dann irgendwie zu dem Projekt Apache Mobile Filter gestossen. Apache Mobile Filter ist eine Apache-Plugin, dass die Funktionen von WURFL direkt in Apache zur Verfuegung stellt. WURFL kennt z.B. alle UserAgents (z.Zt. 8661 verschiedene) und kann auf dieser Basis sagen, ob das gerade aufrufende Geraet ein mobiles Geraet ist oder nicht. Ueberpruefen und sehen was AMF alles so an Variablen zur Verfuegung stellt koennt Ihr unter der Adresse: http://apachemobilefilter.nogoogle.it/php_test.php

Das schoene ist, dass AMF diese Variablen in PHP unter Apache als dessen Server Enviroment Variablen zur Verfuegung stellt. Ich kann also in PHP z.B. mit der Variable $_SERVER[‚AMF_IS_WIRELESS_DEVICE‘] arbeiten. Mit dieser Loesung kann ich nun serverseitig ueberpruefen ob es sich um ein mobiles Endgeraet handelt oder nicht, und dementsprechend die mobile Version der Seite anzeigen lassen oder nicht.

Nur der Weg dahin brauchte noch etwas, der Support von Apache Mobile Filter war aber allererste Sahne, echt super, kann man nicht anders sagen, und fuer die Nachwelt hier nochmal ein Auszug aus meiner .bash_history:

mkdir foo
cd foo
wget http://downloads.sourceforge.net/project/mobilefilter/ApacheMobileFilter/2.21/Apache2-WURFLFilter-2.21.tar.gz?use_mirror=dfn
tar -xzvf Apache2-WURFLFilter-2.21.tar.gz
cd Apache2-WURFLFilter-2.21/
perl Makefile.PL
make install
aptitude install libapache2-mod-perl2 libgd-gd2-perl libgd-tools
a2enmod perl
cpan Apache2::WURFLFilter Apache2::Filter Apache2::RequestRec Apache2::RequestUtil Apache2::Connection Apache2::SubRequest Apache2::Log CGI::Cookie APR::Table CGI::Cookie LWP::Simple Image::Resize IO::Uncompress::Unzip Cache::FileBackend
mkdir /var/www/MobileFilter
chown www-data:www-data /var/www/MobileFilter

Dazu habe ich noch in die /etc/apache2/httpd.conf die folgenden Eintraege hineingeschrieben:

PerlSetEnv MOBILE_HOME /var/www/MobileFilter
PerlSetEnv CacheDirectoryStore /tmp
PerlSetEnv WurflNetDownload true
PerlSetEnv DownloadWurflURL  http://downloads.sourceforge.net/wurfl/wurfl-latest.zip
PerlSetEnv LoadWebPatch true
PerlSetEnv PatchWurflNetDownload true
PerlSetEnv PatchWurflUrl http://wurfl.sourceforge.net/web_browsers_patch.xml
PerlSetEnv CookieCacheSystem true
PerlSetEnv CapabilityList all
PerlModule Apache2::WURFLFilter
PerlTransHandler +Apache2::WURFLFilter
#PerlOutputFilterHandler Apache2::AMFDeviceMonitor

Anschliessend muss der Apache Webserver mit einem /etc/init.d/apache2 restart neu gestartet werden.

Welche Variablen euch dann zur Verfuegung stehen und ob alles funktioniert kann man mit der Test-PHP Seite ueberpruefen die ich oben bereits einmal verlinkt habe. Diese koennt Ihr euch ganz einfach auf euren eigenen Server schmeissen, gibts hier zum Download.

Wenn irgendwelche Fehler auftauchen oder (wie bei mir zu Anfang) die Variablen nicht zur Verfuegung stehen, einfach nochmal ein rm -rf /tmp/wurfl* machen und Apache neustarten.

Ach so… um die mobile Seite jetzt zu implementieren habe ich die bereits beschriebene Loesung mit den PHP-Files und der .htaccess genommen und einfach in der global_prepend.php und die Zeile:

if ($_SERVER['SERVER_NAME'] == 'mobile.myawesomeblog.com') {

ersetzt durch

 if ($_SERVER['AMF_IS_WIRELESS_DEVICE'] == 'true') {

sowie die nachfolgende Zeile mit der URL-Ersetzung von normaler zu mobile-URL einfach weggelassen.

Werder Bremen Newsübersicht

Ich hatte die Schnauze voll von dem doofen Zusammensuchen aller Werder Bremen News am Morgen und dann ueber den Tag verteilt. Mir fehlte eine zentrale Anlaufstelle dafuer. Die Werder Bremen Presseschau ist irgendwie zu klein ;-)
Deswegen habe ich angefangen und mir kurzerhand eine kleine Seite selbergeschrieben, die div. Werder Bremen spezifische RSS-Feeds abruft und die jeweils fuenf neusten Artikel anzeigt. Weiter werden alle Artikel ebenfalls als eigener neuer RSS-Feed exportiert und dank Twitterfeed wird sogar gezwitschert.

Die Seite incl. Quelltext ist unter:
http://werder.pregos.info

zu finden. Sport1 und Fussballtransfer habe ich bereits angeschrieben da deren Feeds defekt sind, einer wird nicht aktualisiert und bei einem anderen ist die Domain der Links zu den Artikeln falsch. Beim Weser-Kurier hab ich ein komisches Problem mit Simplepie, aber das bekomme ich auch noch geloest. Bis dahin hab ich erstmal eine schoene Uebersichtsseite die ich von ueberall und den ganzen Tag lang immer aufrufen kann und immer viele Werdernews im Ueberblick habe.

Statusmeldungen verbreiten

Sobald man mehr als nur ein paar Rechner betreut steht man bei Wartungsarbeiten an Servern oder der Netzinfrastruktur vor dem Problem viele Leute verlaesslich zu informieren. Seiner eigenen Informationspflicht nachkommen zu muessen, aber gleichzeitig das ganze fuer sich selber so einfach wie moeglich zu gestalten ist ein schwieriger Spagat. Ich wusste nicht, wie ich diesen loesen soll.

Ich habe mir dann einige Gedanken dazu gemacht. Am besten ist es natuerlich die Informationspflicht umzudrehen. Nicht mehr ICH muss mich darum kuemmern, dass die Leute alle die Informationen erhalten, sondern DIE LEUTE muessen sich darum kuemmern die von mir bereitgestellten Informationen immer zu erhalten. Ich glaube, dass das machbar ist. Dazu gehoert natuerlich einiges an Planung, uebergangszeit usw.
Dann habe ich mich hingesetzt und mir ueberlegt, wie ich solche Informationen gerne praesentiert haette und schnell war raus: ein RSS-Feed sollte her. Am einfachsten erschien es mir eine kleine Homepage zu haben, wo man Meldungen schreiben kann und diese dann als RSS-Feed exportiert werden. Simpel sollte es vor allem sein. Eine Netzsuche nach geeigneten Loesungen brachte mich schnell zu den bekannten Projekten: WordPress incl. Plugins, Dokuwiki + Plugins, Laconica… In meinen Augen alle oversized..

Nach kurzem ueberlegen hab ich es einfach selber geschrieben. Herausgekommen sind eine MySQL Datenbank mit einer Tabelle, einige wenige Zeilen PHP-Code und ein bisschen XHTML mit CSS. Man kann in einem passwortgeschuetzen Bereich eine neue Meldung verfassen und diese dann Abspeichern. Die Meldungen der letzten sieben Tage werden dann auf der Startseite angezeigt. Des Weiteren werden sie als RSS-Feed exportiert. Das die Ueberschriften bei Twitter gepostet werden war ein Zeitvertreib, aber die Emailverteilerfunktion bei der die Meldungen auch automatisch per Mail versendet werden an einen Verteiler, in den man sich sehr einfach ein- oder austragen kann war dann doch noch notwendig.

Hier zwei Bilder von dem System, wer interesse am Quelltext hat einfach melden.

statusseite

neuemeldung

Nagios zur Druckerueberwachung

Drucker sind mit eines der Leidwesen eines jeden Administrators. Steckengebliebene Druckauftraege kann man oft noch leicht remote aus der Queue loeschen. Aber dann wird es auch schon haerter. Sie fressen Papier das umstaendlich wieder irgendwo herausgesucht werden muss, leere Papierfaecher fuehren zu endlosen Supportanfragen, genau wie leerer Toner oder nicht ganz geschlossene Abdeckklappen. Viele User schaffen es auch nicht aus den Lampen und Symbolen auf den Druckern schlau zu werden, so dass oft nur ein Abstecher vor Ort uebrig bleibt. Wie gut ist es dann, wenn der Admin schnell und uebersichtlich einen Status des Druckers geliefert bekommt, bzw. noch viel besser bei auftretenden Problemen schon gleich frueher gewarnt wird.

Fuer alle Administratoren die Nagios als Monitoringsystem verwenden, gibt es ein wundervolles Plugin von der Firma Ciphron zur Verfuegung gestellt: check_printer, dass es erlaubt Drucker sehr gut mit Nagios zu monitoren. Das Plugin ist auf dem CIPHRONs CORPORATE BLOG genauer vorgestellt.

In Nagios ist es sehr schnell installiert und eingerichtet. Ich gehe im folgenden von einem Debian System aus.

Das Plugin herunterladen und in /usr/lib/nagios/plugins/ abspeichern. Da es in PHP geschrieben ist und SNMP braucht muessen entsprechende Pakete installiert sein, aptitude install php5-cli php5-snmp hilft bei Bedarf weiter. Dann muss ein ein checkcommand definiert werden:

define command{
     command_name    check_printer
     command_line    /usr/bin/php $USER1$/check_printer $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$
     }

und schon kann es losgehen. Wenn ein Drucker bereits als Host definiert ist, kann es losgehen mit dem definieren von entsprechenden Services. Um Tonerinformationen herauszubekommen reicht schon ein einfaches:

define service{
    use                              generic-service
    host_name                        MeinDrucker
    service_description              TONER
    contact_groups                   drucker-admins
    check_command                   check_printer!123.123.123.123!public!toner!1!0.1
    }

Die Syntax ist !IP!SNMP-Community!Welche Info!Wert!Warnlevel!. Das Beispiel gibt fuer einen Drucker MeinDrucker eine Warnung, wenn der Fuellstand des ersten Toners (meistens Schwarz) unter 10% faellt.

Das Plugin erklaert seine Funktionen selber sehr gut, schmeisst ueber fast alles Informationen aus und kann Warnungen beim Unterschreiten verschiedener Level etc. ausgeben. Echt superklasse und superpraktisch!!