Batchscript verzögern

Bei einem Logon-Script im Geschäft hatte ich das Problem, dass es ab und zu die Netzlaufwerke verbindet, bevor die Netzwerkevrbindung zum Server richtig steht. Beim Windows-Server kann man da eine Verzögerung einstellen, das es sich aber um eine VPN-Verbindung handelt, geht das da nicht.
So habe ich im Script eine Verzögerung von ca 3 Sekunden eingebaut. Da es unter Windows aber keinen "sleep" Befehl wie unter Linux gibt, musste ich da einen Workaround machen. Mit einem ping an eine unbekannte Adresse kann man etwas Zeit schinden und mit den richtigen Parametern geht das ganz gut:
ping -n 3 -w 1000 1.2.3.4>nul

Lösung von CIFS VFS: server not responding

Seitdem ich bei meinem neuen Notebook unter Ubuntu 8.10 meine SMB-Shares wieder in der fstab eingetragen hatte, kam jedes mal beim herunterfahren die folgende Fehlermeldung, welche den Computer für etwa eine Minute blockierte.
CIFS VFS: server not responding
CIFS VFS: No response for cmd 50 mid 155


Nichts wirklich tragisches, aber doch nervig genug um der Sache nachzugehen. Glücklicherweise war ich nicht der einzige mit dem Problem. Das Problem ist, dass die SMB-Shares mit dem CIFS Daemon und nicht über den Kernel gemountet werden. Beim herunterfahren wird dann zuerst der Daemon gestoppt und danach sollen die Shares getrennt werden, was dann natürlich nicht mehr funktioniert. Die Lösung ist recht simpel, ein Script, welches die Shares trennt, bevor der Daemon gestoppt wird. Im Ubuntu-Forum findet man da eine gut funktionierende Lösung. Allerdings muss man sich kurz registrieren, damit man die Datei beziehen kann. Bei mir ist die Fehlermeldung nun verschwunden.

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.

An welchem Port vom Switch hängt der Computer?

Ja nachdem wie sauber (oder eben unsauber) ein Patchpanel und ein Switch verkabelt ist kann es recht schwierig sein herauszufinden welcher Computer nun an welchem Port angeschlossen ist. Wenn man keine Lust hat jedem Kabel nachzugehen, muss man eine andere Lösung für das Problem suchen.
Eine Möglichkeit ist das blinken lassen des Lichts beim Switch. Jeder Switch zeigt an, ob er auf einem bestimmten Port eine Verbindung hat. Unter Linux kann man ganz einfach ein Script machen, welches das Interface immer wieder aus und wieder einschaltet. Wenn das Interface ausgeschaltet ist, hat der Switch kein Link, sonst schon. Das folgende kleine Script macht genau das. Es schaltet das Interface aus, wartet eine Sekunde, schaltet es wieder ein, wartet wieder eine Sekunde und so weiter. So kann man beim Switch sehr einfach sehen, an welchem Port der Computer angeschlossen ist.
#!/bin/bash

while true; do
    ifconfig  down
    sleep 1

    ifconfig  up
    sleep 1
done

Das Script funktioniert nur unter Linux und zudem sollte nicht noch zusätzlicher Datenverkehr über das Interface laufen, sonst macht das keinen Sinn.

Gravatare mit PHP cachen

In meinem Blog verwende ich schon lange den Dienst Gravatar. Dadurch wird zu den Kommentaren ein Bild (Avatar) vom Kommentator angezeigt. Vorausgesetzt, eine Mailadresse wird angegeben und ein Avatar ist bei Gravatar auf diese Adresse registriert. Beim Aufruf meiner Seite wir dieser Avatar von der Gravatarseite geholt und angezeigt.

Für den Benutzer hat das den Vorteil, dass er sich nur an einem Ort registrieren muss und dann auf allen Seiten die Gravatar unterstützen einen Avatar hat. Die Mailadresse bleibt dabei immer geschützt, da sie vor der Übertragung in einen MD5 String umgewandelt wird.

Auch für den Webseitenbetreiber hat Gravatar einige Vorteile. So muss man kein eigenes Avatarsystem zusammenbauen und kann einfach Gravatar nutzen. Das ganze ist sehr einfach zu realisieren. Für Wordpress gibt es ja auch Plugins.

Der Nachteil ist allerdings, dass Gravatar halt auf einer anderen Seite läuft. Sollte diese Seite mal Trafficprobleme haben, oder gar ganz down sein, so wir die eigene Seite auch langsam, da die Bilder nicht geladen werden können. Dieses Problem kann man umgehen, indem man die Bilder in einem Cache abspeichert. Ich habe ein PHP Script geschrieben, welches diese Bilder in einen Cache speichert.

Der Ablauf sieht so aus. Zuerst überprüft das Script, ob sich das Bild schon im Cache befindet. Zur Identifizierung wird die Mailadresse als MD5 String verwendet. Ist das Bild schon im Cache und nicht älter als zwei Tage wird das Bild ausgegeben.
Anders sieht es aus, wenn das Bild noch nicht im Cache, oder schon älter als zwei Tage ist. Dann wir eine Verbindung zum Gravatarserver hergestellt, das Bild heruntergeladen und im Cache gespeichert. Dann wird es auch ausgegeben.

Mir ist klar, dass es (noch) keine perfekte Lösung ist, aber es funktioniert. Natürlich kann man so auch andere Bilder (nicht von Gravatar) cachen. Man muss halt einige Angaben anpassen.

Nun müssen sich nur noch mehr Leute bei Gravatar anmelden.

Hier der Code des Scripts:
<?

// Konfiguration
define("CACHE_FOLDER","cache/");                // cache ordner
define("CACHE_DURATION",48);                    // wie lange die bilder im cache bleiben sollen (tage)
define("GRAVATAR_OPTIONS","size=64&amp;");      // optionen (bild groesse, rating usw)

// ueberprufen ob die mailadresse (als md5 string) gesetzt ist
if(!isSet($_GET['address']))
{
    die(
"no address is set");
}

// cache dauer in sekunden umrechnen
$duration_secs=CACHE_DURATION*60*60;

// adresse ueberpruefen
$address=$_GET['address'];
if(!
preg_match("/[a-z0-9]*/i",$address))
{
    die(
"wrong address");
}

define("GRAVATAR_HOST","www.gravatar.com");
define("GRAVATAR_PATH","/avatar.php?".GRAVATAR_OPTIONS."gravatar_id=".$address);
$filename=CACHE_FOLDER.$address.".jpg";

// ueberprufen, ob die datei heruntergeladen werden muss
$download=TRUE;
if(
file_exists($filename))
{
    if(
fileMTime($filename)>(time()-$duration_secs))
    {
        
$download=FALSE;
    }
}

// wenn ja
if($download)
{
    
// zum host verbinden
    
$source=@fSockOpen(GRAVATAR_HOST,80,$errno,$errstr,30);

    
// wen verbindung hergestellt
    
if($source!=FALSE)
    {
        
// zu sendende headers zusammenstellen
        
$req ="GET ".GRAVATAR_PATH." HTTP/1.0\r\n";
        
$req.="Host: ".GRAVATAR_HOST."\r\n";
        
$req.="Connection: Close\r\n\r\n";

        
// headers senden
        
fWrite($source,$req);
        
        
// headers der antwort auslesen
        
while(!fEof($source))
        {
            
$header=trim(fGets($source,1024));
            if(
$header=="")
            {
                break;
            }
        }

        
// zieldatei oeffnen
        
$dest=fOpen($filename,"w+");

        
// daten auslesen und direkt in die zieldatei schreiben
        
while(!fEof($source))
        {
            
$data=fGets($source,1024);
            
fWrite($dest,$data);
        }

        
// verbindung trennen
        
fClose($source);
        
fClose($dest);
    }
    else
    {
        
// wenn gravatar down und kein bild im cache
        // standardbild verwenden
        
$filename="gravatar.jpg";
    }
}

// Bild ausgeben.
header("Content-type: image/jpeg");
echo 
file_get_contents($filename);
?>

Trackbackspam verhindern

In letzter Zeit hatte ich, wie schonmal schonmal berichtet, vermehrt Trackbackspam. Für das Problem mit dem Kommentarspam habe ich eine gute Lösung gefunden. Seit der Einführung der Matheaufgabe, hatte ich keinen Spamkommentar mehr. Bei den Trackbacks ist das ja nicht so einfach, aber es gibt trotzdem eine recht zuverlässige Lösung.
Wenn ich von einer Seite einen Trackback erhalte, dann sollte auf dieser Seite auch ein Link auf meine Seite sein, oder sie sollte zumindest erwähnt werden. Und genau das überprüft diese Funktion.
Nun habe ich eine kleine PHP Funktiongeschrieben, welche überprüft ob auf der fremden Seite meine URL Vorkommt. So reicht eine Überprüfung des Strings t-error.ch schon. Ich muss nicht mal überprüfen, ob es ein Link ist, denn die Trackbackspammer erwähnen auf ihren Seiten meine Seite ja kaum. Die Funktion überprüft die Seite in der Variable $url und gibt die Variable $spam zurück. Relativ simpel und effektiv. Bisher wurde noch kein Trackbackspam durchgelassen.
<?
function trackbackSpamCheck($url)
{
    
// Spamvariable
    
$spam=1;

    
// die url aufsplitten
    
$parsed=parse_url(trim(addSlashes($url)));

    
// einen pfad angeben wenn noetig
    
if(!isSet($parsed['path']))
    {
        
$parsed['path']="/";
    }

    
// den querystring anfuegen wenn noetig
    
$path=$parsed['path'];
    if(isSet(
$parsed['query']))
    {
        
$path.="?".$parsed['query'];
    }

    
// zum host verbinden
    
$fp=fSockOpen($parsed['host'],80,$errno,$errstr,30);
    if(
$fp)
    {
        
// GET request senden
        
fPuts($fp,"GET ".$path." HTTP/1.0\r\n");
        
fPuts($fp,"Host: ".$parsed['host']."\r\n\r\n");

        
// Den Quelltext auslesen
        
while(!fEof($fp))
        {
            
// auf t-error.ch pruefen
            
if(eregi("t-error.ch",fgets($fp,1024)))
            {
                
// wenn vorhanden $spam auf 0 setzen und abbrechen
                
$spam=0;
                break;
            }
        }

        
// verbindung trennen
        
fclose($fp);
    }
    
    return 
$spam
}
?>

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

Linktipps von del.icio.us mit PHP erstellen

Wie man schon einmal beobachten konnte, habe ich nun auch meine delicious Links in meinem Blog. Allerdings werden die Links nur jede Woche angezeigt. Dazu habe ich selber ein kleines Script geschrieben.
Das Script wird täglich durch einen Cronjob aufgerufen und liest die Links aus dem RSS Feed von delicious und schreibt sie in eine Datenbank. Dort werden sie aufbewahrt, bis sie von einem anderen Script ausgelesen und auf die Webseite geschreiben werden. Das passiert bei mir wöchentlich.

Für die Technik-Interessierten habe ich hier die Datenbankstruktur und den Code des Scriptes, welches die Links ausliest. Das schreiben der Links in den Blog sollte ja nicht so schwierig sein.
Bei Gelegenheit werde ich die Daten nicht mehr aus dem Feed, sondern aus der API nehmen. Aber so funktionierts ja auch.
Ach ja: Das Script verwendet MagpieRSS um die RSS Datei zu parsen.

Die Tabellenstruktur
mysql> describe delicious;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| delID          | int(11)      |      | PRI | NULL    | auto_increment |
| delTitle       | varchar(200) |      |     |         |                |
| delLink        | varchar(200) |      |     |         |                |
| delTags        | varchar(200) |      |     |         |                |
| delDescription | text         |      |     |         |                |
| delLang        | char(2)      |      |     |         |                |
| delDate        | int(11)      |      |     | 0       |                |
| delActive      | tinyint(4)   |      |     | 0       |                |
+----------------+--------------+------+-----+---------+----------------+
Wenn delActive auf 1 ist, bedeutet das, dass der Link schon auf der Homepage angezeigt wird.

Der PHP Code
#!/usr/bin/php
<?
// abstand machen, damits auch schoen aussieht
function space($lenght)
{
    
$count=100-$lenght;
    for(
$i=0;$i<$count;$i++)
    {
        echo 
" ";
    }
}

// alle klassen, funktionen usw einbinden
require_once("/home/t-error/public_html/includes/_head.inc.php");

// magpie einbinden
require("magpierss/rss_fetch.inc");

// rss daten herunterladen und parsen
$data=fetch_rss("http://del.icio.us/rss/blacklord");
$data=$data->items;

// los gehts
foreach($data AS $item)
{
    
// die daten in verstaendliche variabeln schreiben
    
$title=        addSlashes($item['title']);
    
$link=         $item['link'];
    
$date=         intVal($item['date_timestamp']);
    
    
// tags als array speichern
    
$tags=         explode(" ",strToLower($item['dc']['subject']));
    
$description=  NULL;

    
// wenn eine beschreibung geschreiben worden ist
    
if(isSet($item['description']))
    {
        
$description=addSlashes($item['description']);
    }

    
// den lang: tag rausfiltern und die richtige sprache in $lang schreiben
    
$tags_arr=array();
    foreach(
$tags AS $tag)
    {
        if(
preg_match("/^lang:([a-z]{2}$)/",$tag,$result))
        {
            
$lang=$result[1];
        }
        else
        {
            
$tags_arr[]=$tag;
        }
    }

    
// tags wieder zusammensetzten
    
$tags=implode(" ",$tags_arr);

    
// ueberpruefen, ob der link schon in der datenbank ist
    
$res=$db->query("
                SELECT
                    delActive
                FROM
                    "
.TBL_PREFIX.TBL_DELICIOUS."
                WHERE
                    delDate="
.$date." AND
                    delLink='"
.$link."'");

    
// wenn nein: einfuegen. los!
    
if($db->num_rows($res)==0)
    {
        
$db->query("
                INSERT INTO
                    "
.TBL_PREFIX.TBL_DELICIOUS."
                    (
                        `delTitle`,
                        `delLink`,
                        `delDate`,
                        `delTags`,
                        `delDescription`,
                        `delLang`
                    )
                VALUES
                    (
                        '"
.$title."',
                        '"
.$link."',
                        '"
.$date."',
                        '"
.$tags."',
                        '"
.$description."',
                        '"
.$lang."'
                    )"
);
                    
        
// noch eine kleine ausgabe
        
echo $title;
        
space(strLen($title));
        echo 
"[ inserted ]\n";
    }
    
    
// wenn ja: nur aendern, man weiss ja nie
    
else
    {
        if(
$db->result($res,0,"delActive")==0)
        {
            
$db->query("
                    UPDATE
                        "
.TBL_PREFIX.TBL_DELICIOUS."
                    SET
                        `delTitle`='"
.$title."',
                        `delLink`='"
.$link."',
                        `delDate`='"
.$date."',
                        `delTags`='"
.$tags."',
                        `delDescription`='"
.$description."',
                        `delLang`='"
.$lang."'
                    WHERE
                        delDate="
.$date." AND
                        delLink='"
.$link."'");
        }
    }
}
?>

Dieses Script kann, wenn die Zugriffsrechte korrekt gesetzt sind, über die Shell aufgerufen werden.

Verbesserungsvorschläge sind gerne Willkommen

Mail -> Blog

Ich arbeite momentan an einem kleinen PHP Script, welches Mails von einem bestimmten Konto ausliest und als Artikel auf meine Homepage schreibt.
Dadurch kann ich auch unter der Woche einen kleinen Statusbericht durchgeben. Ich denke, es ist auch möglich noch eine Unterstützung für Bilder zu erstellen. Dann kann ich Bilder von meinem Handy direkt per Mail auf die Homepage stellen.

Noch genauer zur Funktion:
Zuerst schreibe ich ein Mail an eine vorher definierte E-Mail adresse.
Auf der ersten Zeile steht ein Passwort. Schliesslich soll ja nicht jeder in meinem Blog schreiben können.
Auf der zweiten Zeile ist eine Komma getrennt Liste der Topics, zu welchen der Artikel gehört.
Danach kommt der Text
Der Titel des Artikels wird aus dem Betreff gelesen

Das PHP Script wir immer wieder vom cron aufgerufen und überprüft, ob im Mailkonto neue Nachrichten vorhanden sind.
Ist dies der fall, werden die Nachrichten heruntergeladen und ausgewertet. Das heisst, auslesen und überprüfen des Passwortes, auslesen von Datum, Titel, Text und die Topics.
Nun muss der Artikel nur noch in die DB geschrieben werden. Keine wirkliche Hexerei :)

Vieleicht werde ich heute noch damit fertig. Spätestens aber nächstes Weekend. Da ist ja Ostern und ich habe viel mehr Zeit.