OOP mit JavaScript: Kurze Einführung

Ich bin gerade wieder an unserer kleinen Inhouse-Webaplikation am Arbeiten und versuche meine Ajax-Funktion zu verbessern, da das langsam aber sicher ein kleines Chaos wird. Bei Recherechen im Internet bin ich wieder auf die OOP-Möglichkeiten von JavaScript gestossen. Ob JavaScript nun wirklich Objekt-Orientiert oder nur -Basiert ist will ich hier aussen vor lassen, das tut nichts zu Sache. Ich möchte an dieser Stelle nur die wichtigsten Dinge notieren, in der Hoffnung, dass jemand anders, oder ich in einiger Zeit damit etwas weiter kommt. Möglicherweise gibts dann noch einen zweiten Teil dazu.

Ein Objekt erzeugen

Mit JavaScript hat man die Möglichkeit ein Objekt zu erstellen und diesem dann im Nachhinein Eigeschaften (Variabeln) und Methoden (Funktionen) hinzuzufügen. Dies hat aber den Nachteil, dass man die Eigenschaften/Methoden jedem Objekt hinzufügen muss. Von dem her ist das eine weniger praktikable Lösung.
// Ein Objekt erzeugen
var obj=new Object();

// Eine Eigenschaft definieren
obj.eigenschaft="Inhalt";

// Eine Methode definieren
obj.methode=function() 
{
    alert(obj.eigenschaft);
}

// Die Methode aufrufen
obj.methode();

Eine Referenz erstellen

Die bessere Lösung ist es eine Klasse zu erstellen und danach eine Referenz zu diesem Objekt zu machen. In JavaScript gibt es allerdings keine Klassen, so muss man eine Funktion nehmen. Mit new erstellt man dann die Refernz.
// Eine Funktion erstellen
function meinObjekt()
{
    ...
}

// Eine Referenz zum Objekt erstellen
var obj=new meinObjekt();

Variabeln: Privat und Public


Auch in JavaScript hat man die Möglichkeit zu definieren, ob eine Variable Public, oder Private ist. Auf Variabeln die Public sind, kann auch von ausserhalb des Objekts zugegriffen werden, auf private allerdings nicht. Um eine Variable zu erstellen die Public ist muss man this. davorstellen.
// Das Objekt (Klasse) erstellen
meinObjekt=function()
{
    // Eine "Public" Variable erstellen
    this.public="Public";
    
    // Eine Private Variable erstellen
    var privat="Privat";

    return true;
}

// Die Referenz erstellen
var klasse=new klasse();

alert(klasse.public);        // Gibt "Public" zurueck
alert(klasse.privat);        // Gibt "undefined" zurueck

Methoden: Privat und Public

Bei Methoden sieht das ganz ähnlich aus wie bei den Variabeln, auch hier kann man Methoden erstellen die Public oder eben Privat sind.
// Das Objekt (Klasse) erstellen
meinObjekt=function()
{
    // Eine "Public" Methode erstellen
    this.public=function()
    {
        alert("Public");
    }
    
    // Eine Private Methode erstellen
    privat=function()
    {
        alert("Privat");
    }

    return true;
}

// Die Referenz erstellen
var klasse=new klasse();

klasse.public();             // Gibt "Public" zurück
klasse.privat();             // Gibt nichts zurück


So, das war mal ein kleiner Exkurs in die OOP-Möglichkleiten von JavaScript. Es gibt da noch eine andere Funktionen, die ich wohl spätzer noch genauer erläutern werde.

Moblogscript in PHP

Eigentlich wollte ich ja schon seit längerem etwas über mein Moblog-Script schreiben. Eigentlich seit dem Wunsch von Znuk, aber leider ist es bisher immer beim "wollen" geblieben. Da ich nun mein Script etwas verbessert habe, greife ich die Gelegenheit gleich beim Schopf und erkläre die Funktionsweise kurz.

Funktionsweise

In der Theorie sieht das ganze sehr simpel aus. Ich mache auf meinem Handy (Samsung SGH-600E) ein Foto, und sende es per Mail an eine (geheime) Mailadresse. Auf dem Webserver wird nun alle 15 Minuten ein PHP-Script aufgerufen, welches überprüft ob in der Mailbox neue Mails sind, diese dann verarbeitet und schlussendlich einen neuen Beitrag auf meiner Homepage erstellt.

Spammails

Ein Problem an der Sache sind die Spammails. Das Problem kann man aber einfach umgehen, indem man eine Mailadresse nimmt, die nicht so schnell erraten werden kann, diese nirgens publiziert und im PHP-Script noch eine Passwortabfrage einbaut. Ich bin hier auf Nummer sicher gegangen und habe alle beiden Methoden eingesetzt, den schliesslich möchte ich keine Spammails auf meiner Homepage.

Mailaufbau

Damit das ganze mit dem Passwortschutz und der zuordnung zum richtigen Thema auch funktioniert, muss das E-Mail natürlich auch immer gleich aufgebaut werden. Bei mir sieht das nun folgendermassen aus:
passwort
Thema
Ort
Text für die Homepage
Auf der ersten Zeile steht das Passwort, welches auch als erstes geprüft wird, darauf gehe ich aber spätzer genauer ein. Darauf folgt das Thema, in welches der Aktrikel gehört. Zum Bsp. "Bike", "Diverses" usw. Da ich Moblogs ja immer von unterwegs versende ist es interessant von wo das Mail versendet wurde. Mein Handy hat noch keinen GPS Empfänger und so kann ich auch keine Koordinaten angeben, also muss ich mich auf den Ortsnamen beschränken. Aber das reicht im Normalfall bestens aus. Zum Schluss folgt der Text, welcher auf der Homepage stehen soll.
Das Problem, welches ich meistens habe, ist das Tippen auf der kleinen "Tastatur" auf dem Handy, aber für kurze Nachrichten reicht es meist und wirklich wichtig ist ja das Bild.

Das Script

Nun zum wirklich spannenden Teil dieses Beitrags. Das Script ist in PHP geschrieben und wird alle 15 Minuten aufgerufen. Wenn ein neues Mail vorhanden ist wird das Passwort geprüft und der Artikel erstellt, sofern das Passwort natürlich korrekt ist.
Die Verbindung zur Datenbank und das schreiben der Daten in die DB habe ich hier ausgelassen, da dies ja je nach Blogsoftware bzw. Tabellenstruktur variert. Das Script gibt einfach Variabeln mit dem Inhalt zurück und diese können dann nach belieben in die DB geschrieben werden.

Voraussetzungen

Damit das Script richtig funktioniert, bzw die Mails auch lesen und bearbeiten kann müssen die Imap-Funktionen von PHP Installiert sein. Sonst wird es zu kompliziert.

Ablauf

Damit man einen groben Überblick über das Script bekommt fasse ich hier den Ablauf des Scripts etwas zusammen.
  1. Überprüfen ob neue Mails vorhanden sind
  2. Passwort des Mails überprüfen
  3. Headerdaten auslesen (Betreff, Datum & Zeit)
  4. Text auslesen
  5. Attachments auslesen
  6. Text aufteilen (Thema, Ort und Text)
  7. Bilder speichern
  8. (Daten in die Datenbank schreiben)
  9. E-Mail löschen
  10. Verbindungen trennen

Code

Zuerst werden einige Konstanten definiert, die Hostname vom Mailserver, Benutzername, Passwort usw. beinhalten.
<?
// Konfiguration
define("MAIL_HOST","{mail.server.ch:143}");                // Hostname und Port vom Mailserver
define("MAIL_USER","moblog@adresse.ch");                   // Der Benutzername
define("MAIL_PASS","passwort");                            // Passwort vom Mailaccount

define("PASS","passwort");                                 // Das Passwort das im Mail stehen soll 
define("IMAGES_PATH","images/");                           // Pfad zum Bilderordner
?>



Damit die allfälligen Fehler oder Mitteilungen vom Script auch sinnvoll Protokolliert werden, habe ich eine kleine Funktion geschrieben, welche das aktuelle Datum sowie eine Fehlermeldung zurückgibt. Wenn das Script mit einem Cronjob aufgerufen wird, wird diese nachricht automatisch ins Logfile geschrieben.
<?
// kleine funktion die eine fehlermeldung mit dem aktuellen datum ausgibt
function _log($text)
{
    echo 
date("r")."    ".$text."\n";
}
?>


Nun kann auch schon die Verbindung zum Mailserver hergestellt werden. Die angaben zum Hostnamen usw, werden aus den oben definierten Konstanten gelesen. Wenn die Verbindung zum Mailserver nicht hergestellt werden kann wird eine Fehlermeldung ausgegeben und das Script abgebrochen.
<?
// verbindung zum mailserver herstellen
if(!$mail=imap_open(MAIL_HOST,MAIL_USER,MAIL_PASS))
{
    
_log("Keine Verbindung zum Mail-Server");
    exit;
}
?>


Wenn die Verbindung zum Server steht kann überprüft werden, ob neue, ungelesen Mails auf der Server sind. Ist dies nicht der Fall wird das Script abgebrochen.
<?
// ueberpruefen, ob mails vorhanden sind
$headerstrings=imap_headers($mail);
$mails=count($headerstrings);                              // Die Anzahl der neuen Mails

if($mails==0)
{
    echo 
"keine mails";
    exit;
}
_log($mails." neue E-Mails auf dem Server.");              // Nachricht ausgeben
?>


Ist bekannt ob und wieviele neue Mails vorhanden sind, gehts ans verarbeiten der Mails. Mit einer Schleife wird jedes Mail durchgegangen und überprüft.
Aus Übersichtlichkeitsgründen habe ich hier den Code in zwei Funktionen ausgelagert. Zum einen gibt es die Funktion _getData(). Diese Funktion list die Daten aus dem Mail aus und gibt sie schön sortiert in einem Array zurück. Dieser kann so aussehen:
Array
(
    [header] => Array
        (
            [date] => datum als timestamp
            [email] => mailadresse des absenders
            [name] => name des absenders
            [subject] => betreff
        )
    [text] => Inhalt des Mails (mit Passwort, Thema, Ort und Text)
    [attachment] => Array
        (
            [0] => Array
                (
                    [filename] => Dateiname des ersten Anhangs
                    [content] => Inhalt des ersten Anhangs
                )
            [1] => Array
                (
                    [filename] => Dateiname des zweiten Anhangs
                    [content] => Inhalt des zweiten Anhangs
                )
        )
)


Die zweite Funktion heisst _getMetaData() und sie unterteilt den Inhalt der Nachricht, überprüft das Passwort und gibt die verschiedenen Angaben (Thema, Ort und Text) geordnet zurück.

Nun aber erstmal der Code, der die Funktionen aufruft:
<?
// mail fuer mail durchgehen, daten auslesen, passwort check machen, daten in die db schreiben und das mail loeschen
foreach($headerstrings as $headerstring)
{
    
preg_match("/[0-9]/",$headerstring,$number);           // Numer des E-Mails auslesen

    
$mailData=_getData($headerstring,$number);             // Inhalt aus dem Mail auslesen

    
$meta=_getMetaData($mailData['text']);                 // Inhalt aufteilen

    
if($meta===FALSE)                                      // wenn $meta FALSE ist, stimmt das Passwort nicht
    
{
        
log("falsches pw");
        continue;
    }

    
$mailData['text']=$meta[0];                            // Text des E-Mails
    
$mailData['meta']=$meta[1];                            // Meta Daten des E-Mails (Thema und Ort)

    
foreach($mailData['attachment'] AS $attachment)        // alle attachments durchgehen
    
{
        
$filename=$attachment['filename'];                 // dateiname auslesen

        
$fp=fOpen(IMAGES_PATH.$filename,"w+");             // das attachment abspeichern
        
fWrite($fp,$attachment['content']);
        
fClose($fp);
    }

    
imap_delete($mail,$number[0]);                         // Mail l&ouml;schen
}
?>


Nun zu den Funktionen. Als erstes _getData(), die den Inhalt der Mails ausliest und zurückgibt. Hierzu muss ich vieleicht noch sagen, dass jedes Gerät die Mails etwas anders gestaltet und es so zu Problemen bei dieser Funktion kommen könnte. Mit meinem Handy funktioniert es wunderbar, aber bei anderen Geräten muss man vieleicht die eine oder andere Anpassung vornehmen.
<?
// liest die daten aus einem mail aus, verarbeitet sie und gibt sie als array zur&uuml;ck
function _getData($headerstring,$number)
{
    global 
$mail;
    
$mailData=array();                                     // Array, in den schlussendlich die
                                                           // Daten geschrieben werden

    
$header=imap_fetchheader($mail,$number[0]);            // mailheader auslesen

    
preg_match("/Date: (.*)?[\+|-]/",$header,$date);       // datum des mails auselesen
    
$date=htmlEntities($date[1]);
    
$mailData['header']['date']=strToTime($date);

    
$headerinfo=imap_headerinfo($mail,$number[0],256,256); // liest die headerinformationen aus

    
$mailData['header']['email']=$headerinfo->from[0]->mailbox."@".$headerinfo->from[0]->host// mailadresse des absenders auslesen

    
$decode=imap_mime_header_decode($headerinfo->from[0]->personal); // name des absenders auslesen
    
$mailData['header']['name']=$decode[0]->text;

    
$decode=imap_mime_header_decode($headerinfo->fetchsubject); // betreff auslesen
    
$mailData['header']['subject']=$decode[0]->text;


    
// inhalt der mailnachricht auslesen
    
$struct=imap_fetchstructure($mail,$number[0]);
    
    
// mails mit attachments werden immer als multipart, also mail mit verschieden teile versendet
    // sollte eine mail ohne attachment und mit nur als plaintext versendet worden sein, wird nur der text ausgelesen 
    
if(!empty($struct->parts))
    {
        
// durch alle teile gehen
        
for($i=0;$i<count($struct->parts);$i++)
        {
            
$part=$struct->parts[$i];

            
$msg=imap_fetchbody($mail,$number[0],$i+1);    // inhalt des teils

            // wenn der teil ein attachment, bild und jpg ist.
            
if ($part->disposition==ATTACHMENT OR $part->type==TYPEIMAGE OR ($part->type==TYPEAPPLICATION AND $part->subtype!="SMIL"))
            {
                if(
$part->subtype=="JPEG" OR $part->subtype=="JPG" OR $part->subtype=="OCTET-STREAM")
                {
                    
$attachment=array();

                    
// daten in einen array schreiben.
                    
$attachment['filename']=$part->dparameters[0];
                    
$attachment['filename']=$attachment['filename']->value;
                    
$attachment['content']=base64_decode($msg);

                    
$mailData['attachment'][]=$attachment;
                    unSet(
$attachment);
                }
            }

            
// wenn der teil nur text ist
            
elseif(($part->type==TYPETEXT OR $part->type==TYPEMULTIPART OR $part->disposition==INLINE))
            {
                
$mailData['text']=base64_decode($msg);
            }
        }
    }
    else
    {
        
// wenn das mail als plaintext versendet wurde
        
$mailData['text']=imap_body($mail,$number[0]);
    }

    return 
$mailData;                                      // daten zur&uuml;ckgeben
}
?>


Und nun noch zur zweiten Funktion, welche den Text der Nachricht verarbeitet und das Passwort überprüft.
<?
function _getMetaData($text)
{
    
$text=explode("\n",$text);                             // den text aufteilen

    
if(trim($text[0])!=PASS)                               // ueberprufen, ob die erste zeile dem passwort entspricht
    
{
        return 
FALSE;
    }
    unSet(
$text[0]);

    
$metaData['topic']=trim($text[1]);                     // die zweite zeile als thema (topic) abspeichern
    
unSet($text[1]);

    
$metaData['location']=trim($text[2]);                  // die dritte zeile als ort (location) abspeichern
    
unSet($text[2]);

    
$text=implode("\n",$text);                             // den rest zusammenfuegen und als text speichern

    
return array($text,$metaData);                         // den array zurueckgeben
}
?>


Zum Schluss müssen die gelöschten Mails mit imap_expunge() noch definitiv gelöscht und die Verbindung zum Server getrennt werden.
<? 
// mailbox leeren und verbindung zum server trennen
imap_expunge($mail);
imap_close($mail);
?>


Das ist auch schon der ganze Zauber. Wie schon gesagt müssen die Daten noch in die DB geschrieben werden und idealerweise generiert man für die Bilder auch noch ein Thumbnail, aber das sollte ja kein grosses Problem darstellen.
Wer sich das Script nicht aus den einzelnen Teilen zusammensetzen will, kann es sich hier herunterladen.

Dunst mit Gimp entfernen

Welcher Fotograf kennt das Problem nicht. Man will ein Foto von einem Objekt aus grosser Entfernung Fotografieren, packt dafür ein Zoomobjektiv aus. Das Resultat ist aber alles andere als gut. Flaue Farben, man kann den Dunst und den Schmutz in der Luft förmlich sehen. Dank der Digitalen Fotobearbeitung ist das heutzutage aber kein Grund mehr um das Foto zu löschen. Hier möchte cih beschreiben, wie man so ein Foto mit wenigen Schritten im Opensource Programm GIMP verbessern kann.

Ich hatte genau das Problem am letzten Montag als ich von der Hochwacht ein Foto von Eglisau und dem Viadukt gemacht habe. Mit der EOS 400D und dem 300MM Tele sah das Foto so aus:

Anklicken für grössere Ansicht


Als erstes kann man hier die Farbwerte des Bildes bearbeiten. Dazu klickt man beim Bild auf Ebene -> Farben -> Werte. Bei der unteren Grenze kann man nun den gewünschten Wert angeben. Je nach Bild kann dieser Unterschied natürlich anders sein, bei meinem Bild fand ich den Wert 60 ideal.
http://images.t-error.ch/blog/702/farbwerte.jpg


Und so sieht das Bild nach dem ersten Schritt aus.

Anklicken für grössere Ansicht


Beim nächsten Schritt wendet man den Filter unscharf Maskieren aus. Dieser ist unter [Filter -> Verbessern -> Unscharf Maskieren zu finden. Auch hier ist es am besten, wenn man an den Werten etwas herumschraubt. Ich habe hier bei Radius 60 und bei Menge 0.4 gewählt.
http://images.t-error.ch/blog/702/unscharf_maskieren.jpg


Und so sieht das Bild nach dem letzten Schritt aus. Nicht schlecht, oder?

Anklicken für grössere Ansicht


Und damit man die Verbesserung etwas besser sieht, habe ich links die originale, blasse Version und rechts die Bearbeitete. Natürlich kann man da noch viel mehr machen, aber so kann man immerhin mit wenigen Schritten ein gutes Ergebnis erzielen.

Anklicken für grössere Ansicht

Garmin Edge nach entfernen vom Strom wieder einschalten

Ich hatte ja bereits öfters darüber geschrieben, dass ich Probleme mit meinem Garmin Edge 305 hatte. Nachdem ich den Stecker vom Gerät abgezogen hatte reagierte es einfach nicht mehr. Dunkler Bildschirm und ich konnte es nicht mehr einschalten. Ich musste erst warten bis der Akku leer war und konnte es dann wieder aufladen und benutzen. Vor allem wenn man im Bikeurlaub ist und das Gerät am nächsten Tag wieder braucht ist das natürlich sehr schlecht. Bei mir so in der Lenzerheide passiert und so musste ich die Tour Alter Schyn ohne GPS fahren. Und mir als Daten-Junkie tut das natürlich weh. Letzthin hatte ich das Problem wieder und habe dann erneut im Internet nachgeforscht und bin so auf einen Eintrag in der FAQ von Garmin gestossen. Dort wird genau das Problem beschrieben und (Gott Garmin sei Dank) auch die Lösung dazu:

  • Das Edge an eine Stromquelle (USB oder 220 V Steckdose) anschliessen.
  • Reset und Mode gleichzeitig 3 Sekunden lang drücken. Nun sollte wieder "Batterie wird geladen stehen" und man sollte das Gerät auch wieder einschalten können.
  • Das Gerät nun 15-30 Minuten laden.
Zudem sollte man auch die neues Version der Firmware auf dem Gerät installieren. Dort Eintrag in der FAQ gibts hier

Bei mir hat das wunderbar geklappt und so kann ich nun auch wieder ruhig schlaffen ;)

ZKB Onlinebank Java unter Linux installieren (Howto)

http://images.t-error.ch/blog/563/zkb_logo.jpg

Vor etwas mehr als zwei Monaten habe ich bereits über die ZKB Java Onlinebank unter Linux geschrieben. Damals gab es sogar Probleme mit dem Download. Diese wurden dann aber zügig behoben, wie ich auch in den Kommentaren geschrieben habe. Danach hatte ich allerdings Probleme bei der Installation und so habe ich das ganze auch nicht mehr gross verfolgt. Unter anderem, weil ich nicht gewillt war viel Energie in etwas zu setzten, das ich ja eigentlich auch online und ohne gefrickel haben kann.

Aufgrund von Kommentaren von Cruizzer im ehemaligen Beitrag, ist die ganze Sache bei mir nun wieder ins Rollen gekommen. Spätestens seit seinem Kommentar mit der Lösung, wie man die Software nun trotzdem installieren kann.
Nun möchte ich hier eine Kurzanleitung liefern, für alle, die dasselbe Problem haben. Vielen Dank an dieser Stelle an Cruizzer, der die Lösung gefunden hatte.

Als erstes muss man die Bin Datei von der ZKB Seite herunterladen und auf dem Computer speichern. Nun kommt der Trick 77. Anstatt die Datei in der Shell einfach auszuführen, startet man die Datei mit dem Java Befehl:
java -jar setup.bin
Und schon startet die Setup Routine. Auf meinem Computer lief das ganze nicht so zügig, obwohl ich einen Pentium M 2GHz mit einem GB Ram habe. Aber möglicherweise liegt es ja auch am Compiz.
Beim ersten Schritt muss man nun den Installationspfad angeben. Ich habe die Software in mein Home, in den Unterordner .ZKBOnba installiert.
http://images.t-error.ch/blog/563/pfad.jpg


Mit einem Klick auf Weiter wird die Software in das gewünschte Verzeichnis installiert.
http://images.t-error.ch/blog/563/installation.jpg


Die Installation ist jetzt abgeschlossen. Um das Programm zu starten Navigiert man in den Installations-Ordner und führt dort das Shell-Script Start_ZKB_Onba_3.
Kurz darauf wird der Splash-Screen angezeigt und dieser bleibt dann auch ein weilchen. Auf meinem Computer dauerte das über eine Minute. Aber das kann von Computer zu Computer variieren.
http://images.t-error.ch/blog/563/splash.jpg


Nach dem Splash-Screen folgt die Loginmaske, bei welcher man die Vertragsnummer, Passwort und Sicherheitszahl eingeben kann. Wenn man diese Daten richtig eingegeben hat, ist man drin.
http://images.t-error.ch/blog/563/anmeldung.jpg


Für mich ist das aber leider keine gute Lösung, die Software ist einfach viel zu langsam. Java ist ja sowieso nicht dafür bekannt, schnell zu sein, aber die Geschwindigkeit ist nun wirklich nicht zum aushalten. Ich werde in Zukunft trotzdem die Online Version benutzen.
Es kann aber gut sein, dass die Java-Bank auf anderen Computern unter Linux gut läuft. Ich würde mich über Erfahrungsberichte freuen.

Bilder mit ImageMagick unter Linux verkleinern

Letzthin habe ich einen Beitrag über ein PHP Script geschrieben, welches automatisch Bilder verkleinert. Dank eine Hinweis von Boje bin ich dann zu diesem Artikel über Script-Fu gekommen. Eigentlich geht es dort darum, wie man Bilder automatisch im Gimp verkleinert, allerdings hat es oben ein kurzes Shellscript, welches zeigt wie man ein Bild mit dem Befehl convert verkleinert. Und das ist einiges simpler als meine PHP-Lösung. Das Script erfüllt allerdings nicht ganz meine Anforderdungen, also habe ich es noch etwas angepasst. convert ist ein Bestandteil von ImageMagick also muss man das zuerst installieren, falls das nicht nicht geschehen ist.
sudo apt-get install imagemagick

Das Script ist dann relativ schnell gemacht und es ist doch einiges simpler und kürzer als die PHP Version. Und sie funktioniert genauso gut.
#!/bin/bash

# Alle .jpg Dateien auslesen
for file in *.jpg
do
    # Thumbnail erstellen
    convert ${file} -resize x150 `basename $file .jpg`_thumb.jpg

    # Die grosse Datei verkleinern
    convert ${file} -resize x600 ${file}
done

Installation von Compiz Fusion

Wie ich schonmal beschrieben habe, bin ich ein Beryl Nutzer. Oder besser war ich. Den Beryl und Compiz haben sich zusammengeschlossen. Das bedeutet unter anderem, dass Beryl nicht mehr weiterentwickelt wird. Als Zeit sich das neue Compiz mal anzusehen. Das neue Produkt heisst nun Compiz Fusion.
Zuerst muss aber Beryl runter. Ich habe alle Beryl Pakete im Synaptic entfernt. Den Window-Decorator Emerald habe ich noch behalten, auch wenn er nicht zwingend nötig ist. Bei der Installation habe ich mich an einen Beitrag im Compiz Forum gehalten und bin so auch auf keine Probleme gestossen. Damit man die Compiz Pakete über apt installieren kann muss man zuerst die folgenden Quellen in der Datei /etc/apt/sources.list angeben.
# Treviņo's Ubuntu feisty EyeCandy Repository (GPG key: 81836EBF - DD800CD9)
# Many eyecandy 3D apps like Beryl, Compiz, Fusion and kiba-dock snapshots
# built using latest available (working) sources from git/svn/cvs...
deb http://download.tuxfamily.org/3v1deb feisty eyecandy
deb-src http://download.tuxfamily.org/3v1deb feisty eyecandy

Und damit apt die Pakete auch von diesen Quellen liest muss man den folgenden Befehl ausführen:
sudo apt-get update

Nun kann man Compiz in der Konsole über apt oder mit Synaptic installieren. Ich habe mich hier an die Anleitung gehalten und in der Konsole die folgenden Befehle ausgeführt:
sudo apt-get install compiz
sudo apt-get install compizconfig-settings-manager
sudo apt-get install compiz-fusion-*

Passiert ist bisher noch nichts. Damit Compiz auch geladen wird, muss man zuerst den X-Server neustarten. Bei nächsten Anmelden wird immer noch kein Compiz geladen. Dies macht man jetzt mit diesem Befehl:
compiz --replace

Idealerweise speichert man diesen Befehl in den Autostart (System -> Einstellungen -> Sitzung unter Gnome), dann wird Compiz automatisch geladen.

Jetzt darf man sich an das Konfigurieren machen. Und da kann man viel Zeit vertrieben. Compiz bietet so schon eine Menge von Möglichkeiten und man kann auch noch zusätzliche Plugins herunterladen. Die Konfiguration findet man unter System -> Einstellungen -> CompizConfig Settings Manager. Und das sieht etwa so aus:
http://images.t-error.ch/news/428/CompizConfig.png

Nun noch einige Screenshots und eine Demo von Youtube:
http://images.t-error.ch/news/428/cube.png
http://images.t-error.ch/news/428/expo.png
http://images.t-error.ch/news/428/skalieren.png




Bilder mit JavaScript preloaden

Ich versuche momentan eine kleine und simple Galerie zu Programmieren. Ein PHP Script soll die Bilder aus eine Verzeichnis auslesen und dann mit Lightbox anzeigen. Der Nachteil von Lightbox ist aber, dass es erst funktioniert, wenn die Seite komplett geladen ist. Und wenn es da mehrere Bilder gibt, kann das Laden der Seite auch mal länger dauern und die wenigsten Besucher wollen da warten.
Ich versuche diese Problematik nun mit einem Preloader zu umgehen. Bisher ohne grossen Erfolg. Aber immerhin weiss ich jetzt, wie man Bilder mit JavaScript "preloadet."
<script language="JavaScript" type="text/javascript">
    <!--
        if (document.images)
        {
            preload_obj=new Image();
            preload_obj.src="images/test.jpg";
        }
    //-->
</script>

Recht simpel. Es wird ein neues Objekt erstellt und danach mit src die Quelle der Datei zugewiesen. Natürlich kann man so mit PHP auch mehrere Bilder preloaden.

JavaScript Effekte mit Scriptaculous

Ich bin gerade etwas mit den Scriptaculous Libraries am Pröbeln. Eine sehr nette, und einfache Sache. Einige Teile sind sicher etwas Eyecandy, aber das kommt je länger desto mehr. Auch im Webbereich.
Mit Scriptaculous kann man "Aufklappeffekte" wie ich sie bei meiner Tourenverwaltung habe, ganz einfach und noch etwas schöner realisieren. Dazu benötigt man nur die neusten Scriptaculous (blödes Wort) Libraries. Dieso kopiert man zusammen mit der Datei prototype.js in einen Ordner. Vorzugsweise javascript/. Wie man erahnen kann, basiert Scriptaculous auf Prototype, allerdings muss Prototype nicht zusätzlich heruntergeladen werden.
Nun müssen die Libraries noch in die Seite eingebunden werden. Dies funktioniert wie bei jedem JavaScript. Bei Scriptaculous kann noch angegeben werden, welche Module geladen werden sollen. Dies macht man mit dem load Parameter. Wenn dieser Parameter nicht angegeben wird, werden alle Module geladen. Ich benötige aber nur das Effects Modul also lade ich auch nur dieses.
<script type="text/javascript" language="JavaScript" src="js/prototype.js"></script>
<script type="text/javascript" language="JavaScript" src="js/scriptaculous.js?load=effects"></script>
Auf der Scriptaculous Homepage hat es schon diverse Beispiele zu den verschiedenen Effekten. Mich interessierte der Effekt toggle mehr, da es damit möglich ist, ein Element auf und zu zu klappen. Mit einem Klick auf ein Element kann so ein anderes Element geöffnet oder geschlossen werden. Hier ein simples Codebeispiel.
<div onClick="new Effect.toggle($('element'),'blind')">click</div>
<div id="element"><div>test test test</div></div>
Damit kann man mit einem Click das Element element öffnen und wieder schliessen. Hier wird der Effekt blind verwendet. Wichtig ist, dass im zu öffnenden Element noch ein zusätzlicher Divcontaoiner ist, sonst funktionieren einige Effekte nicht korrekt. Das Beispiel sieht mit etwas zusätzlichem CSS dan so aus:
blind
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test

Oft möchte man es ja so haben, dass das Element von Anfang an geschlossen ist. Dazu kann man ganz einfach das CSS Element display mit dem Wert none benutzen. Das sieht dann so aus.
blind

Zusätzlich gibt es noch die Effekte slide und appear welche mich persönlich nicht so ansprechen. Mit gefällt blind am besten. Zum Schluss aber noch je ein Beipsiel.
slide

appear

Achtung: Lightbox2 verwendet schon Scriptaculous und Prototype. So muss man diese Libraries nicht mehr laden.

Userdirs mit Apache unter Ubuntu

Unter Linux ist es mit dem Apache Webserver möglich jedem Benutzer auf dem Server/Computer einen Platz zu bieten, welche aus dem Internet erreichbar ist. Sofern man aus dem Internet auf den Server zugreifen kann. Der Ordner /home/david/public_html/ wäre dann über die Url http://server/~david/ erreichbar. Natürlich kann man mit einem DNS Server und den richtigen Einstellungen beim Webserver diesen Ordner auch direkt unter einer Domain erreichbar machen.
Dafür, dass man den Ordner public_html über den Webserver erreichen kann, sorgt der Mod Userdir. Standardmässig ist dieser Unter Ubuntu Feisty Fawn zwar dabei aber nicht eingerichtet. Ich finde diese Modul sehr praktisch, also habe ich es noch "installiert".
Dazu öffnet man am besten ein Terminal und wechselt mit dem Befehl su den Benutzer. Nach der Eingabe des Passwortes ist man Root. Die Konfigurationsdateien des Apache Webservers sind im Ordner /etc/apache2 abgelegt. Dort gibt es auch zwei Ordner. Zum einen den Ordner mods-available und den Ordner mods-enabled. Im ersten befinden sich die Module, die verfügbar sind und im zweiten sind die Module, die am laufen sind. Damit die Module nicht doppelt gespeichert werden sind im zweiten Ordern nur symbolische Links zu den Modulen im Ordner mods-available. Im Ordner mit den verfügbaren Modulen finden wir nun auch das Modul Userdir.
root@pluto:/etc/apache2# ls -la mods-available/userdir*
-rw-r--r-- 1 root root 293 2007-01-15 19:10 mods-available/userdir.conf
-rw-r--r-- 1 root root  66 2007-01-15 19:10 mods-available/userdir.load
Zum einen haben wir hier die Konfigurationsdatei userdir.conf und die Moduldatei userdir.load. Jetzt müssen wir je eine symbolische Verknüpfung zu jeder Datei machen. Dazu wechseln wir am besten in den Ordner mods-enabled und erstellen die Verknüpfungen mit dem Befehl ln
root@pluto:/etc/apache2# cd mods-enabled/
root@pluto:/etc/apache2/mods-enabled# ln -s ../mods-available/userdir.conf 
root@pluto:/etc/apache2/mods-enabled# ln -s ../mods-available/userdir.load

Bevor das Modul nun auch geladen wird, muss man den Webserver noch neustarten
/etc/init.d/apache2 restart

Nun sind die Dateien im Ordner /home/david/public_html/ auch über http://localhost/~david/ erreichbar. Sofern man es natürlich vom Webserver aus probiert.