Artikel im RSS Feeder verzögern

Welcher Blogger kennt das Problem nicht: man scheibt einen neuen Artikel, liest ihn vor dem veröffentlichen nochmals genau durch beseitigt alle Fehler, und stellt den Artikel danach ins Internet. Auf dem Blog noch kurzen eine Kontrolle, ob alles passt und Prompt findet man noch einen Fehler. Soweit so schlecht, den Fehler noch schnell beseitigen bevor es jemand sieht, das Internet ist ja Realtime. Fast; auf der Seite wird der Fehler nicht mehr angezeigt, dafür haben sich die Feedreader schon die alte und fehlerhafte Version gespeichert.
Dieses Problem kann man ganz einfach beheben. Entweder man machte keine Fehler mehr, oder man zeigt die neuen Artikel erst eine gewisse Zeit (zum Bsp 5 Min) später im RSS-Feed an. Dadurch hat man Zeit um die Fehler zu beheben, bevor die Feedreader überhaupt merken, dass es etwas neues gibt. In meinem Fall war das eine kleine Anpassung in der mySQL Abfrage.

Vorher:
<? mysql_query("... articleDate<".time()." ..."); ?>

Nachher:
<? mysql_query("... articleDate<".(time()-(5*60))." ..."); ?>


Nun hoffe, ich dass die Artikel in den Feedreader (und auch im Blog) etwas weniger Fehler haben.

Backup einer mySQL Datenbank erstellen

Wenn man eine Sicherung von einer mySQL Datenbank machen will kann man das natürlich auf auf mehrere Arten machen. Zum einen kann man das ganze über das beliebte phpMyAdmin machen. Oder, wenn man Zugriff auf die Shell vom Server hat, mit mysqldump oder cp. So kann man relativ simpel ein Cronjob einrichten, welcher Täglich oder Wöchentlich eine Sicherung der Datenbank macht.

Die Variante mit mysqldump ist recht simpel und funktioniert, ohne dass man den mySQL Server stoppen muss. mysqldump erstellt wie phpMyAdmin eine SQL Datei mit den create table und insert Anweisungen. In diesem keinen Beispiel wir die Datenbank "datenbank" exportiert und gleich noch mit gzip etwas komprimiert.
mysqldump -ubenutzer -p datenbank | gzip -c > file.sql.gz


Die andere Möglichkeit ist das kopieren der Dateien in der mySQL die Daten ablegt. In Ubuntu liegen diese Daten im Ordner /var/lib/mysql/. Dazu muss aber der mySQL Server gestoppt werden, dafür hat man aber eine etwas sauberere Sicherung. Bei Migrationen auf andere Server ist diese Variante wohl etwas besser. Hier ein kleines Beispiel, dass den mySQL Server stoppt, alle Datenbanken in den Ordner /home/backup/mysql/ kopiert und den Server dann wieder startet.
#!/bin/bash

mysqldir="/var/lib/mysql";

# stop mysql
/etc/init.d/mysql stop

date=`date +%d%m%Y`

mkdir /home/backup/mysql/$29.04.08 07:54/

cp -R $mysqldir/* /home/backup/mysql/$29.04.08 07:54/

# start mysql
/etc/init.d/mysql start

Tourenverwaltungstool lanciert

Trotz dem nicht gerade umwerfenden Feedback zum Tourenverwaltungstool habe ich mich nun doch entschieden, das ganze zu machen. Zum einen für mich, mein jetziges funktioniert zwar sehr gut, aber das neue Tool könnte mir die Verwaltung noch etwas vereinfachen. Ich habe mir nun auch schon einige Gedanken dazu gemacht. Zum einen natürlich welche Daten man abspeichern kann und zum anderen auch, welche Zusatzfunktionen noch verfügbar sein sollen.
Momentan sieht es so aus:

Daten:
  • Name der Tour
  • Beschreibung / Route
  • Distanz
  • Höhenmeter
  • Durchschnittsgeschwindigkeit
  • Fahrzeit
  • Höchstgeschwindigkeit
  • Durchschnittlicher Puls
  • Temperatur
  • Datum / Zeit
Die Zusatzfunktionen habe ich im ersten Beitrag ja schon beschrieben.

Nun ist es aber nicht so, dass das Tool schon bald fertig ist. Im Geschäft habe ich momentan sehr viel zu tun und dementsprechend habe ich am Abend auch kein Lust um noch stundenlang zu Programmieren. Allerdings würde es mich interessieren, ob jemand noch Ergänzungen hat. Gibt es Dinge, die für euch wichtig wären, Dinge, die ihr gerne in so einem Tool hättet?

Tourenverwaltungstool für Biker

Ich verwende wie einigen ja sicher schon bekannt seit anfangs Jahr eine selbstgestrickte PHP Applikation um meine Biketouren zu verwalten. Ich bin damit sehr zufrieden, auch wenn es sicher viele Dinge gibt, die man verbessern könnte.
Nun spiele ich mit dem Gedanken, diese Applikation auszubauen und zum Download zur Verfügung zu stellen. Das heisst, wer will, kann die Applikation herunterladen und auf dem eigenen Webserver installieren. Vorausgesetzt, der Webserver unterstützt PHP und mySQL.
Meine Frage nun an meine treuen Leser und Bikefreunde. Wer hätte Interesse an so einer Applikation? Wenn wirklich Interesse bestehen würde, könnte ich die Applikation auch so einrichten, dass sie bei mir gehostet wird und man sich mit einem Benutzer einloggen kann. Denn nicht jeder hat einen Webserver mit PHP und mySQL zur Verfügung.

Einige Gedanken habe ich mir dazu schon gemacht. Ich habe zwei Listen mit Funktionen gemacht. Erstere beinhaltet Funktionen, die beim ersten Release schon dabei wären. Also das nötigste, so dass man Touren bequem und übersichtlich verwalten könnte. Letztere beinhaltet Funktionen, die das ganze dann noch bequemer machen würden, aber nicht wirklich nötig sind. Zum Beispiel der Import von einer GPX Datei.

Basisfunktionen
  • Angabe der wichtigsten Daten wie Distanz, Höhenmeter, Geschwindigkeit
  • Verwaltung von mehreren Bikes
  • Upload von Fotos zu den jeweiligen Touren
  • Ein Kalender der anzeigt, wann eine Tour gefahren wurde
  • Administrationsoberfläche zur Verwaltung und Erfassung der Touren.
  • Einfache Installation durch ein Script
  • Design mit Templates anpassbar
  • Die Möglichkeit nur Touren von einem Monat, oder mit einem bestimmten Bike anzusehen
  • Graphen mit Distanz pro Monat usw.

Erweiterte Funktionen
  • Wasserzeichen auf Fotos
  • Auslesen der Daten aus einer GPX Datei (Export von SportTracks oder ähnlichem)
  • Automatische Erstellung einer Google Earth Datei, falls GPX Datei vorhanden.
  • Darstellung der Tour mit Google Maps, falls GPX Datei vorhanden.
  • Höhenprofil von der GPX Datei

Das Tool soll keine Konkurrenz zu SportTracks oder ähnlichen Programmen sein, schliesslich ist es damit auch nicht möglich Daten aus dem GPS herunter zu laden, allerdings könnte man damit die gefahrenen Touren im Internet präsentieren und man hat auch immer den Überblick wieviele Kilometer man dieses Jahr oder diesen Monat schon gemacht hat. Für Statistikfans auf jeden Fall eine schöne Sache.

Ich würde mich über Feedback freuen. Wenn einige Leute interesse hätten würde ich mich an die Arbeit machen. Verbesserungsvorschläge sind natürlich auch willkommen.

mySQL Passwort ändern

Wie man einen mySQL Server unter Ubuntu Linux installiert habe ich ja schon beschrieben. Der erste Schritt, den man nach der Installation machen sollte ist das ändern des Passwortes. Denn sonst kann man ohne Passwort auf den mySQL Server zugreifen. Wenn auch nur vom localhost.
Mit den folgenden Befehlen kann man das root Passwort ändern.
mysql -u root -p
Enter password:
mysql> set password=password("neues passwort");
Wenn man sich nun wieder bei mySQL einloggt, muss man das neue Passwort eingeben.

Installation von Apache, PHP und mySQL unter Ubuntu 6.06

Das Installieren von Programmen in Ubuntu ist nicht wirklich schwierig. Mit den Programm apt kann man ganzen einfach Programme installieren, wenn man weiss wie sie heissen. Und vor allem zu Apache, PHP und mySQL findet man im Internet Dokumentationen bis zum abwinken.
Hier eine kleine Anleitung zur Installation (nicht Konfiguration) von Apache2, PHP5 und mySQL5. Meistens heisst das Packet so wie das Programm, aber es gibt halt auch ausnahmen.
apt-get install apache2
apt-get install php5
apt-get install mysql-server
apt-get install php5-mysql


Die Programmen sind nun installiert. Die Konfigurationsdateien sind an den folgenden Orten abgelegt.
Apache 2: /etc/apache2/apache2.conf
PHP5: /etc/php5/apache2/php.ini
mySQL 5: /etc/mysql/my.ini

Nach der Installation sollte man sicher das Passwort für den mySQL Zugriff ändern, da sonst jeder darauf Zugriff hat.

Ubuntu

http://images.t-error.ch/news/311/ubuntulogo.pngNach meiner langen Linux-Abstinenz wage ich mich nun wieder mal an ein Linux. Seit meiner Leere Lehre bald zwei Jahren hatte ich relativ wenig mit Linux zu tun. Nun gehts aber wieder los. Und zwar gleich mit zwei Projekten.

Zum einen gibt es im Geschäft einen neuen Server. Er wird hauptsächlich benutzt um Bilder von Hotels und Feriendestinationen zu speichern. Und zusätzlich soll er noch meine Flugliste hosten. Das ganze lässt sich gut mit Linux realisieren. Ein Samba Fileserver für die Bilder und ein Apache mit PHP und mySQL für die Flugliste. Nichts aussergewöhnliches, aber mal wieder etwas spannendes mit Linux.
Als Distribution habe ich die Server Edition von Ubuntu gewählt. Version 6.06 mit LTS. Ich habe den Server nun schon aufgesetzt. Schwierigkeiten hatte ich nur beim erstellen des Raid 1 mit zwei 250 GB Platten. Aber lange hielt mich das auch nicht auf. Nun bin ich am konfigurieren der Kiste und werde hier wohl so ab und zu wieder einige Dinge dazu schreiben.

Zum andern Plane ich auch meinem privaten Notebook auch Linux zu Installieren. Geplant ist auch ein Ubuntu, allerdings in der neueren Version und natürlich die Desktop Edition. Momentan benutze ich zuhause noch Windows XP, es könnte also noch spannend werden bei der Umstellung. Einige Dinge sind mir bekannt, die Probleme bereiten könnten/werden:
  • Garmin Edge Software. Soviel ich weiss gibt es da keine Linux Lösung
  • Dual Screen. Mit Windows XP kein Problem. Mit Linux sollte es ja auch möglich sein, aber wohl nicht nur mit einem Klick.
  • Und dann gibt es sicher noch einige andere Dinge, die sich dann spontan melden werden.

Nun warte ich noch auf eine neue Festplatte, da die 60 GB Platte, die momentan eingebaut ist, einwenig zu klein ist.

Dateien mit PHP in mySQL DB speichern

Hier schreibe ich, wie man eine Datei in einer mySQL Datenbank speichert. Dafür sollte man sich etwas mit PHP und mySQL auskennen. Ich schreibe hier nicht, wie man Dateien auf den Webspace hochlädt. Zudem gehe ich davon aus, dass die Datei schon auf dem Webspace liegt.

Vorbereitungen

Also los. Zuerst zur Datenbank. Prädestiniert für Binärdateien sind die Blobs (Binary Large Objects). Zudem sollte man den Mimetype in der Datenbank speichern, falls der schon, zum Beispiel durch einen Upload bekannt ist. Also sieht die Tabelle zum Beispiel so aus:
mysql> describe files;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| fileID   | int(11)      |      | PRI | NULL    | auto_increment |
| fileType | varchar(200) |      |     |         |                |
| fileData | blob         |      |     |         |                |
+----------+--------------+------+-----+---------+----------------+

Daten schreiben

Um die Daten in die DB zu schreiben, muss zuerst den Inhalt der Datei auslesen. Die macht man so:
<?
// die datei, die in die db geschrieben wird
$file="bild.jpg";

// datei oeffnen
// das r steht fuer read und das b fuer binary
$fp=@fOpen($file,"rb")or die("konnte die datei nicht oeffnen");

// daten auslesen
$content=fRead($fp,fileSize($file));

// datei schliessen
fClose($fp);
?>
Nun ist der Inhalt der Datei in der Variable $content gespeichert.
Jetzt muss der Inhalt der Datei noch in die Datenbank geschrieben werden. Da die Datei in diesem Beispiel ein JPG ist nehme ich ich den Mimetype image/jpeg. Sollte dieser Typ nicht bekannt sein, muss auf die Datei mime.types zurückgegriffen werden. Dieser Mimetype ist wichtig, da er nachher als Content-type an den Browser gesendet wird.
Nun zur mySQL Query:
<?
mysql_query
("
    INSERT INTO
        files
        (
            `fileType`,
            `fileData`
        )
    VALUES
        (
            'image/jpeg',
            '"
.addSlashes($content)."'
        )"
);
?>
Die Funktion addSlashes() ist wichtig, da es sonst zu mySQL Fehler kommt, da das Zeichen ' im Dateiinhalt sein könnte.

Daten auslesen


<?
// id setzen. kann auch per $_GET bzw. $_POST geschehen
$id=1;

// daten auslesen
$result=$db->query("
                SELECT
                    fileType,
                    fileData
                FROM
                    files
                WHERE
                    fileID="
.$id);

$type=mysql_result($result,0,"fileType");
$data=mysql_result($result,0,"fileData");

// headers
// den content-type (mimetype) senden. aus der db
header("Content-type: ".$type);

// die groesse des inhalts anzeigen. damit der browser die verbleibende zeit berechnen kann.
header("Content-Length: ".strLen($data));

// die anzeige und der filename der datei.
// content-disposition: attachment oeffnet einen speichern unter dialog
// content-disposition: inline oeffnet das file im browser falls moeglich (pdf)
header("Content-Disposition: attachment; filename=bild.jpg");

echo 
$data;
?>


Keine grosse Kunst, allerdings gibt es doch einige Dinge, die man beachten sollte.

Kommentarfunktion funktioniert wieder

Ich habe heute bemerkt, dass ich einen kleinen Fehler in der Kommentarfunktion hatte. Wegen diesem Fehler wurde der Kommentar nicht in die Datenbank eingetragen, zudem wurde auch keine Fehlermeldung ausgegeben. Das ganze war auf einen Fehler in der SQL-Query zurückzuführen und ist nun gefixt.
Falls also jemand einen Kommentar hatte schreiben wollen, so kann er/sie dies gerne nachführen.

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