andi.jpg

Urlaub

Hallo,

jetzt ist es endlich soweit, ich fahr 2 Wochen nach Italien und Kärnten :)

Ich werde also die Tage nichts Neues veröffentlichen und wünsch euch eine schöne Zeit.

BTW. ist seit heute die Webseite unter http://codejungle.org erreichbar, Spenden willkommen.

In der Zwischenzeit kann ich auf mein anderes Projekt http://hackers.ath.cx verweisen, das zumindest täglich aktualisiert wird.

Also macht es gut!

LG

Andreas

COMMENTS (0) | Permalink


tux-bandit.jpg

Gesichtserkennung

Hallo,

ich habe am späten Abend noch etwas mit Gesichtserkennung gespielt und möchte euch die ersten Ergebnisse nicht vorenthalten.

Sie sind zwar noch nicht 100 % ausgereift, aber für low level hardware (20 euro webcam) zufriedenstellend. Aber genug der geschriebenen Worte, hier ein kleiner Screencast->

Ich werde euch natürlich auf dem laufenden halten, wenn das ganze Projekt etwas ausgereifter ist.

[UPDATE]

Nach einigen Tests ist es mir gelungen die Gesichtserkennung in realtime durchzuführen, sprich ohne das lästige Flackern. Ziel der Aktion soll sein, im Rahmen einer Kunstaktion, Menschen auf einem öffentlichen Platz zu erkennen, eine Sprechblase über Ihren Kopf zu hinterlegen (mit Texten wie Raubkopierer etc) um auf die Misstände der Vorratsdatenspeicherung aufmerksam zu machen und die Öffentlichkeit darüber zu informieren.


Zur verwendeten Software:

Ubuntu

camstream

OpenCV

Für weitere Fragen stehe ich gerne zur Verfügung.

MFG

Andreas

Quellen:

http://opencvlibrary.sourceforge.net/

http://code.google.com/p/ehci/

COMMENTS (0) | Permalink


map_radius.jpg

PLZ Umkreissuche in PHP

Hallo,

nachdem ich die letzten Tage wenig neues veröffentlicht habe, heute mal etwas interessantes für den ambitionierten PHP Programmierer.

Eine PLZ Umkreissuche in PHP, dazu benötigen wir:

  1. Eine Geo DB mit Long und LAT sowie PLZ (am besten von opengeodb auf sourceforge)
  2. Einen brauchbaren Umkreissuchen-Script
  3. Etwas Zeit

Bei meinen Versuchen hat sich herausgestellt, dass ich die meiste Zeit damit verbracht habe, eine brauchbare Datenbank zu finden und zu formatieren. Hilfe dazu weiter unten, jetzt erstmal etwas Code:

Code

<?php

// Zuerst eine Verbindung zur Datenbank aufbauen!
        
$connect=@mysql_connect("localhost""user""pass")
        or die(
"Cant connect to Database");
        @
mysql_select_db("geo_plz"$connect)or die("Cant select Database");

// die PLZ nach der wir suchen
$plz '9220';

// der Umkreis in Km
$umkreis 5;

// Erdradius (geozentrischer Mittelwert) in Km
$radius 6368;

/* -------------------------- */

$sql_rad mysql_query("SELECT lon, lat FROM `plz_at` WHERE `plz` = '$plz' ");
$erg_rad mysql_fetch_object($sql_rad);

// Umrechnung von GRAD IN RAD

$lon $erg_rad->lon 180 M_PI;
$lat $erg_rad->lat 180 M_PI;

// jetzt erfolgt die eigentliche Abfrage

$query "SELECT ort, plz, (
 "
.$radius." * SQRT(2*(1-cos(RADIANS(lat)) * 
 cos("
.$lat.") * (sin(RADIANS(lon)) *
 sin("
.$lon.") + cos(RADIANS(lon)) * 
 cos("
.$lon.")) - sin(RADIANS(lat)) * sin(".$lat.")))) AS Distance 
 FROM plz_at WHERE 
 "
.$radius." * SQRT(2*(1-cos(RADIANS(lat)) * 
 cos("
.$lat.") * (sin(RADIANS(lon)) * 
 sin("
.$lon.") + cos(RADIANS(lon)) * 
 cos("
.$lon.")) - sin(RADIANS(lat)) * sin(".$lat."))) <= ".$umkreis.
 ORDER BY Distance
"
;

// die Ausgabe (vereinfacht)

$sql mysql_query($query);
while( 
$erg mysql_fetch_object($sql) ) {

 echo 
'
<pre>'
print_r($erg), '</pre>
'
;
}

?>


Natürlich wäre es jetzt denkbar für jede gefundene PLZ im Umkreis eine Abfrage der Mitglieder oder Filialen zu machen, diesen Spass überlasse ich aber lieber euch :)

Wer die formatierte Datenbank für Deutschland, Österreich und Schweiz braucht oder eine Frage hat, einfach kurz melden.

LG

Andreas

 

Eine wichtige Adresse die beim Erstellen der Datenbank sowie der Gestaltung der Abfrage hilfreich ist lautet:

http://opengeodb.giswiki.org/wiki/OpenGeoDB_-_Umkreissuche

COMMENTS (0) | Permalink


tux-bandit.jpg

SWAP Geschwindigkeitsrausch oder RAM erweiterung via USB

Hallo,

bei meinem ersten Beitrag zum Thema Linux auf diesen Blog werde ich nur einen kleinen Artikel schreiben, der wie immer aus gegebenem Anlass endstanden ist.

Vor kurzem kam mir die Idee, einen neuen Arbeitsspeicher zu kaufen, nach dem Motto "ein bisschen mehr kann nie schaden". Stattdessen habe ich nun eine andere Lösung gefunden und meinen Swapbereich auf einen USB Stick ausgelagert.

Swap bitte was ??

Swap oder auch Swapping ist ein Bereich auf der Festplatte, der bei Linux zum Beispiel genutzt wird um die Prozessdaten auszulagern, wenn der Arbeitsspeicher voll ist. Eine Faustregel besagt, dass der Swapbereich doppelt so gross sein soll, wie der Arbeitsspeicher selber.

Ein wesentlicher Vorteil der Auslagerung des Swapbereichs auf einen USB Stick ist der Kostenfaktor. 2 GB USB Sticks bekommt man heute ja schon recht günstig, auf jeden Fall um einiges billiger als 2 GB RAM. Also wieso nicht den Swapbereich auf einen USB Stick auslagern?

Wie mach ich das ??

Zuerst sollte man wissen wo sich die Swappartition derzeit befindet, das kann man zum Beispiel mit cfdisk oder einfach swapon -s als root herausfinden.

Als nächstes hängt man seinen USB Stick an den Computer und führt folgenden Befehl aus:

mkswap /dev/< usb device >

Danach hängt man seine alte SWAP Partition mit swapoff aus. Beispiel:

swapoff /dev/< swap device >

und das neu angelegte USB Swap Device an:

swapon /dev/< usb device >


[UPDATE]

Nach einem Test mittels hdparm bin ich von der Idee nicht mehr so begeistert.

Siehe Benchmark->

/dev/sda1: (Sata - Festplatte)
 Timing cached reads:   1536 MB in  2.00 seconds = 767.41 MB/sec
 Timing buffered disk reads:  212 MB in  3.02 seconds =  70.24 MB/sec

/dev/sdb1: (USB Stick)
 Timing cached reads:   1514 MB in  2.00 seconds = 756.58 MB/sec
 Timing buffered disk reads:   36 MB in  3.04 seconds =  11.83 MB/sec

 

Was hier ersichtlich wird ist, dass der USB Stick wohl signifikant langsamer ist als die SATA Platte. Es macht also wenig Sinn den Swap auf einen USB Stick auszulagern, zumindest nicht bei den heute erhältlichen SATA Festplatten. Vielleicht wiederhole ich den Test nochmal mit einer ATA Platte... Mal sehen wie die Performance da ausschaut.

Leider ist auch die SATA Platte im Vergleich 100 bis 1000 mal langsamer als der Arbeitsspeicher, was einerseits an der Konstruktion der Speicher andererseits an der Architektur des Computers an sich liegt. Um die Geschwindigkeit des Swapspeichers zu tweeken gäbe es noch die Möglichkeit mit hdparm die Geschwindigkeit der Festplatte zu erhöhen. Dies birgt aber auch das Risiko die Festplatte zu beschädigen...

 

Ich hoffe euch hat der Artikel gefallen und würde mich über ein Kommentar sehr freuen.

Andreas


Quellen:

http://de.wikipedia.org/wiki/Swapping

http://de.wikipedia.org/wiki/Hdparm

http://www.thomashertweck.de/linuxram.html

 

COMMENTS (0) | Permalink


Freedemo-Geborgenheit.jpg

Vorratsdatenspeicherung oder das Ende der Unschuldsvermutung

Hallo,

aus gegebenem Anlass habe ich mir überlegt ein wenig über die Vorratsdatenspeicherung zu schreiben. Einerseits weil hier scheinbar noch grosser Aufklärungsbedarf herrscht und andererseits weil ich gerade von einer Versamlung aus dem Metalab komme, wo über die Vorbereitung zur Demo (am 11 Okt) und die nächsten Schritte diskutiert wurde.

Ich habe ja nichts zu verbergen?

Eigentlich kann ich diese Aussage schon nicht mehr hören, leider ist es jedoch eine Haltung, die die meisten Leute hier in Österreich vertreten. Grundsätzlich stimmt die Aussage auch, denkt man die Sache aber zu Ende sieht es schon etwas anders aus. Mit dem Umkehrsschluss kann sich wohl keiner anfreunden. Wer gibt schon gerne alles von sich Preis?

Ich selber habe generell auch nichts zu verbergen, möchte jedoch selbst entscheiden wer welche Daten bekommt und wer nicht. Zum Beispiel möchte ich nicht, dass mein potenzieller neuer Chef weiss, welchen Kontostand ich habe, oder dass meine Krankenkasse beschliesst meine Beiträge zu erhöhen, da sie über meine Kreditkarte festgestellt haben, dass ich mich zu ungesund ernähre ebenso wenig dass es möglich ist, dass Firmen ein gesamtes Profil von mir erstellen können was über die Kontaktadresse hinausgeht.

Was ist so schlimm an der Vorratsdatenspeicherung?

Ein einzelner gespeicherter Eintrag ist ja nicht schlimm, dort 'ne Adresse, da die Arztrechnung und hier die Telefonanrufe, alles nicht so tragisch. Doch die Vernetzung dieser Daten ermöglicht eine komplette Überwachung. Und gespeichert werden Daten überall, auch in Bereichen, wo man es sonst weniger vermuten würde. Das alles sind die schönen neuen Möglichkeiten der Überwachung. In der Regel sind Menschen die die Überwachung antreiben, Menschen die etwas verbergen möchten.

Daher fordere ich auf mit personenspezifischen Daten sensibler umzugehen und nicht jede neue Überwachungsaktion unter dem Deckmantel "Terrorabwehr" zu tolerieren.

Ich möchte hier ausserdem auf das nächste Treffen zum Thema im Metalab Wien hinweisen:

Mi 06.08.2008 gegen 20 Uhr

Sowie die europaweite Demonstration "Freedom Not Fear" am 11. Oktober

Ausserdem eine etwas ältere Fernsehendiskussion zum Thema:


Quelle:

http://www.vorratsdatenspeicherung.de/

http://wiki.vorratsdatenspeicherung.de/Freedom_Not_Fear_2008

COMMENTS (0) | Permalink


andi.jpg

Lastenverteilung mit MySQL und SQLrelay

Nach meinen ersten Tests mit Sqlrelay und MySQL - Proxy denke ich es ist an der Zeit davon zu berichten.

sqlrelay

Sqlrelay verspricht Datenbankanwendungen stabiler und schneller zu machen und unterstützt dabei noch eine breite Palette von Datenbanksystem.

Die Installation kann bei Debian Systemen einfach über das Paketverwaltungstool apt-get gemacht werden. Ich persönlich habe auf Debian Testing-Pakete zurückgegriffen. Die Konfiguration geschieht über eine XML Datei, die für den Anfänger vielleicht etwas zu viel des guten ist.

Es gibt drei Möglichkeiten seine PHP Applikation mit dem sqlrelay Daemon zu verbinden.

  1. Pear DB2 (hat einen sqlrelay Treiber)

  2. Mysql Drop in Replacement

  3. PHP sqlrelay api

Leider habe ich auf die neuere MDB2 api gesetzt für die es derzeit noch keinen sqlrelay Treiber gibt, weshalb für mich nur das mysql drop in replacement in Frage kam.

Nachteil von sqlrelay in meinen Augen ist, dass es nicht möglich ist eine größere Abfrage auf mehrere Nodes zu verteilen, was gleichzeitig auch der Vorteil von mysql-proxy (mit h-scale plugin) ist.

mysql-proxy

Die Installation von mysql-proxy geht ebenfalls über das Packetverwaltungstool apt-get, will man allerdings die aktuellste Version haben ist etwas Handarbeit erforderlich.

In neueren Versionen von mysql-proxy ist das read-write Splitting bereits vorhanden, was besonders bei Master/Slave Setups nützlich ist. Die Konfiguration ist für meinen Geschmack etwas einfacher als beim sqlrelay, man gibt einfach seinen Master und die Slaves an, und übergibt den Port auf dem der Mysql-Proxy laufen soll.

Seiner Applikation braucht man dann auch nur noch den Host und Port vom Proxy mitteilen, und die Lastenverteilung läuft schon, ebenso kann mysql-proxy mit ausgefallenen Nodes umgehen.

Nachteil von mysql-proxy ist evtl. das es nur MySQL ansprechen kann und nicht wie sqlrelay mit anderen DBs kommuniziert. Ausserdem ist mir beim Testen aufgefallen, dass unter starker Last der Arbeitsspeicher rauf geht, was auf einen Memoryleak schliessen lässt (evtl. in aktuellen Versionen schon behoben).

Last but not least

postgres-r

Bei meinen Recherchen bin ich noch auf postgres-r gestossen, was ein Master/Master Replicationssystem für Postgresql darstellt.

Tests sind zwar noch aus ständig, generell kann man aber sagen das postgresql eine stabile, mit vielen Funktionen bestückte Datenbank ist, die evtl mehr den fortgeschrittenen Programmierer anspricht.

 

Fazit

Für den Standard Mysql Benutzer empfehle ich mysql-proxy, das auch bald in den mysql-cluster einfließen wird. Da es einfach zu installieren ist und man wenig Änderungen am System und den Anwendungen machen muss.

Für den Produktivbetrieb empfehle ich Postgresql, da es eine robuste, mit vielen Funktionen erweiterbare, Datenbank ist.

Generell sollte man einiges beachten bevor man sich einen Datenbank Cluster zulegt. Ich habe schon viele schlecht programmierte Webanwendungen gesehen, die durch falsch gesetzte Indexe und schlecht geschriebene Abfragen mehr als 10 mal so lange brauchen und weitaus weniger Anfragen entgegen nehmen können als äquivalente Anwendungen. Außerdem sollte man beachten das nicht jede Anwendung von Haus aus Lastverteilung unterstützt, fragen die man sich dabei stellen sollte sind z.B. wo werden Sessiondaten gespeichert (default im Filesystem), wo die Benutzerdaten (Bilder..). Man muss sich also zumindest Gedanken machen wie man die Daten repliziert, bei Sessiondaten eignet sich z.B. ein session handler, bei den Benutzerdaten gibts viele Ansätze (siehe drbd, c oder r sync, nfs usw.).

Ein oft gemachter Fehler in Lasten verteilten Systemen ist die Sprache selber, Marketingleute verwechseln gerne Lastverteilung mit Ausfallsicherheit. Man sollte sich auch Gedanken über den Single Point of Failure machen, sowie drauf achten, das der Lastenverteiler diesen nicht selbst darstellt. In ausfallsicheren Systemen sind diese, sowie im Idealfall alle anderen Komponente, redundant (also doppelt vorhanden).

Ich hoffe ich konnte einen kleinen nicht all zu technischen Überblick über die verschiedenen Vor- und Nachteile der vorgestellten Systeme geben und wünsche im Sinne von Linux "have a lot of fun"

Andreas

 

Quellen:

sqlrelay http://sqlrelay.sourceforge.net/

mysql-proxy http://forge.mysql.com/wiki/MySQL_Proxy

hscale http://hscale.org

postgres-r http://postgres-r.org/

lvs http://www.linuxvirtualserver.org/

drbd http://www.drbd.org

rsync http://rsync.samba.org/

COMMENTS (0) | Permalink


Database Session handler for php

This are my first example for codejungle, it s  a database session handler for php.

I got this example from php.net, but there was some small bugs i.e. on the read method.

more comming soon

Code

<?php
class Session {
    
// session-lifetime
    
public $lifeTime;
    function 
__construct ($db) {
        
// get session-lifetime
        
$this->lifeTime get_cfg_var("session.gc_maxlifetime");
           
// open database-connection
        
$this->mdb2 =& MDB2::factory($db);
        if (
PEAR::isError($this->mdb2)) {
            
$php_errormsg .= $this->mdb2->getMessage();
            
$php_errormsg .= $this->mdb2->getDebugInfo();
        }
        
session_set_save_handler(array(&$this'open'),
                                array(&
$this'close'),
                                array(&
$this'read'),
                                array(&
$this'write'),
                                array(&
$this'destroy'),
                                array(&
$this'gc'));
        
register_shutdown_function('session_write_close');
        
session_start();
           return 
true;
    }
    function 
open($savePath$sessName) {
        
// get session-lifetime
        
$this->lifeTime get_cfg_var("session.gc_maxlifetime");
        return 
true;
    }
    function 
close() {
        
$this->gc(ini_get('session.gc_maxlifetime'));
        
// close database-connection
        
return $this->mdb2->disconnect();
    }
    function 
read($sessID) {
        global 
$php_errormsg;
        
// fetch session-data
        
$query "
            SELECT session_data FROM sessions
            WHERE session = '$sessID'
            AND session_expires >
        "
.time();
        
$result $this->mdb2->query($query);
        
// return data or an empty string at failure
        
if (MDB2::isError($result)) {
            
$php_errormsg .= $result->getMessage();
            
$php_errormsg .= $result->getDebugInfo ();
            return 
false;
        }
        list(
$value)=@$result->fetchrow();
        return 
$value;
    }
    function 
write($sessID,$sessData) {
        global 
$php_errormsg;
        
// new session-expire-time
        
$newExp time() + $this->lifeTime;
        
// is a session with this id in the database?
        
$query "
            SELECT * FROM sessions
            WHERE session = '$sessID'
        "
;
        
$result $this->mdb2->query($query);
        
// if yes,
          
if($result->numRows()) {
        
// ...update session-data
            
$query "
                UPDATE sessions
                SET session_expires = '$newExp',
                 session_data = '$sessData'
                WHERE session = '$sessID'
            "
;
          }
        
// if no session-data was found,
          
else {
            
// create a new row
            
$query "
                INSERT INTO sessions (
                     session,
                      session_expires,
                      session_data)
                VALUES(
                     '$sessID',
                      '$newExp',
                      '$sessData')
            "
;
          }
        
$result $this->mdb2->exec($query);
        
// if something happened, return true
        
if (MDB2::isError($result)) {
            
$php_errormsg .= $result->getMessage();
            
$php_errormsg .= $result->getDebugInfo ();
            return 
false;
        } else {
            
// ...else return true
            
return true;
        }
    }
    function 
destroy($sessID) {
        global 
$php_errormsg;
        
// delete session-data
        
$query "
            DELETE FROM sessions
            WHERE session = '$sessID'
        "
;
        
$opt_db="OPTIMIZE TABLE sessions";  
        
$result $this->mdb2->exec($query);
        
$resultopt $this->mdb2->exec($opt_db);
        
// if session was not deleted, return false,
         
if (MDB2::isError($result)) {
            
$php_errormsg .= $result->getMessage();
            
$php_errormsg .= $result->getDebugInfo ();
            return 
false;
         } else {
            
// ...else return true
            
return true;
        }
    }
    function 
gc($sessMaxLifeTime) {
        global 
$php_errormsg;
        
// delete old sessions
        
$query "
            DELETE FROM sessions
            WHERE session_expires <
        "
.time();
        
$result $this->mdb2->exec($query);
        
// return affected rows
        
if (MDB2::isError($result)) {
            
$php_errormsg .= $result->getMessage();
            
$php_errormsg .= $result->getDebugInfo ();
        }
        return 
$result;
    }
}
?>

 

If you have question pls just ask

 

COMMENTS (1) | Permalink


bandits3-0.gif

Projektstatus von CMS-Bandits

Eines von meinen aktivsten Projekten ist CMS-Bandits an dem ich die letzten Monate die meisten Änderungen gemacht habe. Zu den größeren Änderungen gehört der Datenbank Abstractionslayer und das neue Sessionhandling. Sowie viele kleine Änderungen wie das Revisionslog, die Übersetzungsfunktion und den komplett überarbeiteten RSS Feed.

Ausserdem habe ich eine 100 Mbit Anbindung spendiert bekommen (danke Istvan). Dennoch ist es nicht leicht ein OpenSource Projekt ohne Sponsoren oder sonstige Einnahmen am Leben zu erhalten. Derzeit konzentriere ich mich auf neue Projekte die auch etwas Geld einbringen, werde aber das CMS noch weiterentwickeln.

BTW bassiert diese Webseite auch auf einer Entwicklerversion von meinem CMS, welches ihr hier gratis downloaden könnt.

Jetzt etwas technisches zu den neuen Funktionen:

Der Datenbank Abstraktionslayer MDB2 ermöglicht den Betrieb auf nahezu jeder Datenbank. Das neue Sessionhandling ist besonders dann interessant, wenn man das CMS auf einer Clusterfarm betreiben will, ausserdem hat man auch einen kleinen Performancegewinn auf normalen Maschinen da die Sessiondaten von MySQL nach Möglichkeit im Arbeitsspeicher gehalten wird, was 100-1000 fach schneller ist als das Dateisystem.

Der neue Revisionslog ermöglicht es bei Änderungen Schritte wieder zurück zu gehen, es macht also nichts wenn man mal einen Artikel versehentlich gelöscht hat. Der neu geschriebene RSS Feed kann jetzt auch von allen RSS-Readern gelesen werden.

Ich würde mich natürlich freuen, wenn jemand mein CMS unterstützen möchte, sei es finanziell oder einfach nur durch Verbesserungsvorschläge (in Form von Code am liebsten).

 

Ich wünsche euch noch eine schöne Woche

Andreas

 

COMMENTS (0) | Permalink



[«] « prev 1 2 next » [»]