Blog: Latest Entries (15):


Filme für den IT-Nerd - Part One - Hack the Planet

Die Ganze IT-Nerd und auch Hacker-Kultur ist extrem durch Filme geprägt. Diese Tatsache sieht man nicht nur an der Guy Fawkes Maske von Anonymous die dem Film "V for Vendetta" entliehen wurde. Gerade die wenigen Filme, die sich mit Computern und dem Thema Hacken beschäftigt haben wurden von der Kultur regelrecht aufgesogen und wurden zu einen Teil davon. Teilweise lag es nicht an der Qualität oder dem Realismus sondern auch einfach an den Vorlieben von Trash und einer gehörigen Portion Selbstironie. Da durften Filme gerne auch mal schlecht und voller Fehler sein.. aber so lange sie ein gewisses Gefühl transportieren konnten wurden, waren es einfach "richtige" Hacker-Filme.

Und genau so einen Film will ich heute hier vorstellen bzw wieder ins Gedächtnis rufen. Dieser Film bringt schon mit seinem Titel genau darüber worum es geht.

Hackers




Hackers stammt aus dem Jahr 1995 und fällt damit in einer Zeit wo das Internet anfing die privaten Haushalte zu erobern. Man speicherte auf Disketten, die ersten Hacker wie Kevin Mitnick wurden berühmt und das Pfeifen der Modems gehörte noch zum altäglichen Leben. Der Film hat viele berühmte und gute Schauspieler wie Angelina Jolie + Nacktszene (viele viele Filme...), Jonny Lee Miller (Elementary), Matthew Lillard (Scooby Doo, Wing Commander) und als Antagonisten Fisher Stevens (Nummer 5 lebt) als The Plague, der eigentlich den ganzen Film irgendwie cool macht.

Am Anfang ist der Film ansatzweise so ewtas wie eine Teeny Highschool Komödie mit Hacker-Einschlag. Der als 11 jähriger verurteilter Hacker Dade "Zero Cool" darf mit 18 wieder Computer verwenden und zieht mit seiner Mutter nach New York. New York ist jetzt eigentlich weniger für seine Hacker Kultur bekannt... aber egal.. New York und Inliner sind einfach cool und irgendwie ist es auch egal wo der Film spielt.
Gleich in seiner ersten Hacker-Aktion seit Jahren trifft er auf den Hacker/die Hackerin "Acid Burn". Da Dade aber ja ein total 1337-Hacker ist, sucht er sich einen anderen Nickname um sich nicht zu verraten "Crash Override".. genau so cool wie die Namen ist dann die Szene wo beide in einem TV-Studio System mit Roboterarmen um eine Video-Kassette von "The Outer Limits" kämpfen. Er verliert.

Wie keiner erwarten würde .. nein natürlich nicht.. trifft er genau in seiner neuen Highscholl auf "Acid Burn". Nach dem er beim Wipeout Spielen ihren Highscore schlägt mag sie in natürlich noch weniger als vorher, obwohl niemand weiß, wer der andere ist. Er lernt "Cereal Killer" und noch paar andere Hacker kennen und da alle sagen "Der Gibson".. so etwas wie ein Cray.. wäre nicht zu Hacken, lässt sich der junge kleine unerfahrene aus der Gruppe dazu verleiten es doch zu tun. Damit beginnen deren Probleme. Ein Admin der nicht so gut ist, wie er tut.. FBI und am Ende die Vereinigung aller Hacker der Welt "Hack the Planet" sind keine neuen oder wirklich kreativen Ideen aber der Film hat etwas. Er geht einfach sehr unbekümmert mit dem Thema um und zeigt deutlich wie Spiel und Wettbewerb die eigentliche treibende Kraft der Hacker sind.
Eine Philosophie und der Wunsch die Welt zu verbessern, darf natürlich nicht fehlen.. aber hält sich doch dezent im Hintergrund.

Realistisch ist der Film nicht und will es auch nicht sein. Mac OS 8 auf einen P6 Prozessor der SOGAR einen PCI-Bus hat... ja..

Ein anderer Teil ist der Soundtrack des Films der die Zeit Mitte der 90er perfekt einfängt.

Man sollte sich den Film ansehen.. aber auf jeden Fall den nötigen Humor gleich mitbringen und nicht zu ernst an den Film heran gehen.

bbcode-image


Cypher - leicht und schnell - Teil 1

Die Abfragesprache für die Neo4J Graphendatenbank ist Cypher, die sich irgendwie eine Mischung aus SQL und JSON darstellt. Das Schöne an der Sprache ist, wie einfach sie zu lernen ist, weil die Struktur sehr klar ist und einfach alles so funktioniert wie man es sich denkt. Komplexe Konstrukte wie GROUP BY aus SQL gibt es nicht und die Aggregatsfunktionen fügen sich sehr viel angenehmer in alles
ein als bei SQL.

bbcode-image


Die Grundlegende Struktur einer Abfrage ist auch sehr logisch:


* MATCH
* WHERE
* RETURN
* ORDER BY
* LIMIT


Also ich sage welches Graphen-Gebilde ich such. Dann wird festgelegt welche Eigenschaften es erfüllen soll. Das geschieht anhand der Relations und Attribute der Komponenten, die man vorher fest gelegt hat (einfache statische vorgaben wie Ids kann man sogar schon vorher fest legen wie
z.B. " (e:example{id:1})").
Nun definiert man wie das ResultSet aussehen soll. Nodes, Relations, Attribute, Ergebnisse von Aggregatsfunktionen.. kann man beliebig mischen und auch eine CASE-Anweisung ist vorhanden. Dann Legt noch die Sortierung fest und möglicher Weise eine Limitierung des Resulsets.

Besonders schön sind Funktionen wie collect(), die einem Möglichkeiten bieten, die SQL einen einfach nicht nicht bieten kann.

Gehen wir mal von einer Datenbank mit Benutzern und Gruppen aus.

SQL:

SELECT g.id group_id,
u.id user_id,
u.name user_name
FROM groups g,
users u,
users_groups ug
WHERE ug.group_id = g.id
AND u.id = ug.user_id
ORDER BY g.id


Danach müssen wir durch eine Schleife laufen und immer wenn die Group-Id
sich ändert eine neue Liste für die User aufmachen und die solange füllen
bis die nächste Liste erzeugt wird. Die listen kommen dann in eine Map
wo die Group der Key für ihre Liste ist.

Jeder hat so etwas bestimmt schon mal gemacht, um keine einzelnen Queries für jede Group absetzen zu müssen. Ein großes Query ist schneller als viele kleine, weil weniger Overhead für die Connection-Verwaltung gebraucht wird und auch weniger Objekte erzeugt werden, was immer gut für die Performance
ist.

mit Neo4j geht es sehr viel einfacher.

Cypher:

MATCH (g.group)<-[m:member]-(u:user)
RETURN
g.id as group_id,
collect(u)
ORDER BY g.id


Hiermit erhält man eine Liste aller Groups mit 2 Werten. Der erste Wert ist die Id und der zweite ist die Liste der zur Group gehörigen User. Damit ist keine zusätzliche Iteration über die Ergebnismenge mehr nötig, um solch ein Konstrukt zu erzeugen.

Wenn man nun noch die Anzahl der User pro Group direkt haben möchte
muss man das Query nur minimal anpassen. Kein GROUP BY oder ähnliches.

Cypher:

MATCH (g.group)<-[m:member]-(u:user)
RETURN
g.id as group_id,
count(u) as cnt,
collect(u)
ORDER BY g.id


Komplizierter wird es mit Befehlen wie UNWIND oder FOREACH, aber im Vergleich zu entsprechenden SQL Lösungen sind diese auch noch sehr einfach und unkompliziert.

Ein Blick über den SQL-Tellerrand lohnt auf jeden Fall, wenn man Aufwand und Zeit sparen möchte bei Abfragen, die oft geschachtelte Listen nutzen und man es Leid ist, diese aus den Resultsets wieder zu rekonstruieren.

JavaFX in schön

Das man mit JavaFX schöne Anwendungen bauen kann steht außer Frage.

Hier werden einige gezeigt: https://jaxenter.de/javafx-anwendungen-aus-der-praxis-so-schoen-kann-ein-java-ui-sein-34877

Ich zweifel aber immer noch, dass der Aufwand nicht sehr viel höher ist als für eine entsprechende Webapp mit HTML5.

Aber ich habe zur Weihnachtszeit nochmal mit alten Kollegen gesprochen und es ist einfach so, dass wenn man Desktop-Anwendungen mit Java schreiben möchte, JavaFX das Beste ist was man momentan findet. SWT ist wirklich altbackend und Swing wird nicht mehr supportet. Wenn HTML5 keine Option ist ist JavaFX einfach die Zukunft für Java Anwendungen.

Remote Debugging mit PHPStorm

Heute habe ich mal wieder gelernt wie doof es ist, wenn man keine Kopie des produktiven Servers hat und die Entwicklungsumgebungen im Gegensatz zum Server immer mal wieder aktualisiert wurden. Der Server lief mit PHP 5.3 und alle anderen hatten 5.5 oder schon 5.6.

Es kam wie es kommen musste: Auf dem Server trat ein Fehler auf, der lokal bei niemanden reproduziert werden konnte. Wo der Fehler genau auftrat war unklar und nur Debuggen konnte da helfen. Zum Glück gab es einen Test-Server für die Anwender und Kunden den man verwenden konnte. Aber es man musst trotzdem Remote Debuggen.

Uns hat der Blog Post "Remote debugging with PHPStorm and Xdebug" von Marco Bunge da sehr geholfen.
Ich guck mal ob ich ähnliches auch noch mal für Eclipse mit PDT in den nächsten Wochen zu Stande bekomme.. leider sind es mal wieder zu viele Projekte gerade, wo von aber zum Glück zwei erledigt sind und ich mich ab Mitte März wieder meinen zwei Hauptprojekten widmen kann und auch wieder mehr Zeit für den Blog haben sollte.


MP4toGIF.com Filter Update

Nach dem ich den Tag mit der Sound API für Java verbracht habe, hab ich dann für heute noch mal eine Verbesserung für MP4toGIF.com in Angriff genommen. Neben den normalen Farbfiltern wird nun noch ein Vignitierungsfilter als Ergänzung zu den Farbfiltern hinzukommen.

bbcode-image


Mit dem Canvas sind solche Effekte sehr einfach umzusetzen und sind dabei noch relativ performant.


function createVignetting(ctx){
var x=Math.round(ctx.canvas.width/2);
var y=Math.round(ctx.canvas.height/2);
var grd=ctx.createRadialGradient(x,y,1,x,y,y-5);

grd.addColorStop(0,'rgba(0,0,0,0)');
grd.addColorStop(1,'rgba(0,0,0,0.8)');

ctx.fillStyle=grd;
ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);

return ctx;
}



CodeMirror für HTML-Code Liebhaber

In letzter Zeit habe ich CodeMirror lieben gelernt. Ich mag es nicht mit TinyMCE zu arbeiten und normale TextAreas sind für HTML-Coding wirklich schrecklich. Wenn man in einem System HTML-Templates bearbeitet, will man Einrückungen und Syntax-Highlighting.

Mit Code-Mirror hat man da und es ist wirklich leicht zu verwenden. Man hat eine Variable pro Editor und das einbringen von Code von Außen (z.B. das hinzufügen von Bilder-Links durch ein Klick auf ein Bild) ist sehr einfach.


//for codemirror
if(main){
main.replaceSelection(textToInsert);
}


Und es gibt sogar einen Mode für BBCode. Damit wird jetzt das Blog-Modul betrieben, wenn man sich gegen HTML mit TinyMCE entscheidet.

Wer also XML oder HTML Code in seiner Web-Anwendung bearbeiten muss oder seinen Benutzern BBCode anbietet kann das mit CodeMirror wirklich leicht und schnell einbauen.


<script src="/reachableContent/codemirror/lib/codemirror.js"></script>
<link rel="stylesheet" href="/reachableContent/codemirror/lib/codemirror.css">
<script src="/reachableContent/codemirror/mode/xml/xml.js"></script>
<script src="/reachableContent/codemirror/mode/css/css.js"></script>
<script src="/reachableContent/codemirror/mode/javascript/javascript.js"></script>
<script src="/reachableContent/codemirror/mode/htmlmixed/htmlmixed.js"></script>

...

<script type="text/javascript">
var myTextArea=document.getElementById("idTextArea");
var myCodeMirror = CodeMirror.fromTextArea(myTextArea,{tabSize: 4,
indentUnit: 4,
indentWithTabs: true,
lineNumbers: true});
</script>


bbcode-image
Auch mit BBCode

Firefox Marketplace: It has begun...

Heute kam dann auch eine Email, dass eine App von mir deaktiviert wurde. Es geht also voran den Marketplace zurück zu bauen.

Firefox OS und die OpenWebApp waren eine tolle Idee und ich habe gerne dafür entwickelt. Die Möglichkeit Web-Apps wie Desktopanwendungen zu installieren war echt super und gerade für Firmen toll, da die Mitarbeiter einfach ein Icon anklicken mussten und nicht mal merkten, dass es gerade eine Webanwendung war, die sich dann öffnete.


bbcode-image

Eine Stunde früher Aufstehen für eigene Projekte

Jeder der ein oder mehrere Projekte nebenbei laufen hat, die einem Geld bringen oder einem wichtig sind, wird das Problem kennen, dass man gerne mehr Zeit in das Projekt investieren möchte. Oft kommt so etwas in Schüben, dass man plötzlich ganz viele Ideen hat und dann gerade der Job oder das Privatleben oder meistens sogar beides einen auch mehr Zeit abverlangen, als sonst üblich. Es kommt eben immer alles auf einmal.

Wo bekommt man dann die Zeit her ohne die Zeit für das andere zu beeinträchtigen? Ich habe von John Sonmez den Tipp gelesen,
einfach eine Stunde früher aufzustehen. Klingt erst einmal gut. Man hat Ruhe weil der Rest noch schläft, opfert keine Zeit die man sonst mit anderen verbracht hätte und kann das wach zur Arbeit aufbrechen. Soweit die Theorie. Ich hab es mal versucht.. es klappt nicht und hier kommt wieder etwas in Spiel, was in der heutigen Zeit leider zu oft vergessen wird: Schlaf ist wichtig. Guter gesunder und ausreichender Schlaf.
Wenn man zu wenig schläft leidet am Ende alles mehr darunter als wenn man die zusätzliche mit mit schlafen verbracht hätte. Was bringt einen die Stunde mehr am Tag, wenn dafür die Leistungsfähig abnimmt. Es ist ja nicht nur die Stunde mehr, wo de Leistungsfähigkeit fehlt sondern den ganzen Tag über. Deswegen kann es sein, dass man durch die Stunde mehr Zeit 1-2 produktive Stunden durch den Schlafmangel wieder verliert.
Ich behaupte, mit guten Schlaf kann mit einer Stunde weniger dennoch mehr an seinem Projekt in der übrigen Zeit schafen, als wenn man diese Stunde für sein Projekt genommen hätte.

bbcode-image

Windows 10 Phone Pin,Iris jedes mal verwenden

Erstmal wundert man sich, dass man Iris verwenden kann um sein Lumia 950 zu entsperren aber auch einfach so den Lockscreen hoch schieben kann. Beim Lumia 640 mit Pin ist es das Selbe.
Unter den Einstellungen unter Konto - Anmeldeoptionen muss man die 15 Minuten auf Jedes mal stellen.

Es scheint eine Konfort-Funktion zu sein, dass man erst nach 15 Minuten Inaktivität sich wichtig anmelden muss. Wohl damit man nicht immer sich da neu identifizieren muss, bloß weil man mal kurz das Smartphone aus der Hand gelegt hat.

Macht es aber auch unsicher, weil unerlaubte Zugriffe wohl häufig schnell zwischen durch passieren und 15min schon sehr lang sind, wenn man immer mal auf sein Smartphone guckt.

Das hier hat sehr geholfen, das Problem zu lösen.

Die Iris-Funktions funktioniert erstaunlich gut und zuverlässig.Ich werde noch mal mit Foto auf einem Bildschirm testen, aber bei realen Menschen war die Funktion bis jetzt 100%ig zuverlässig.

Einarbeitung in schon bekannte Programme

Wenn man die Überschrift liest, klingt es erst einmal seltsam, da man das Programme und Anwendungen ja schon kennt. Das Problem bei komplexen Anwendungen, die in Projekten und der alltäglichen Arbeit verwendet werden, um alles zu managen, dass nicht die eine Art gibt, wie man die verwendet.

Gerade bei sehr kleinen Teams von 2-3 Personen, die eine solche Anwendung einführen und benutzen, entstehen schnell Strukturen und Abläufe, die sich stark an der Arbeitweise und dem Projekt orientieren. Wenn man nun als neue Person hinzukommt und es bekannt ist, dass man mit einer Anwendung schon gearbeitet hat, ist das Erstaunen oft groß, dass man nicht gleich zu 100% in dem System steckt und auch mal nachfragen muss, wie etwas gehandhabt wird.
Ob es nun das behanedeln voon Tickets in Youtrack oder JIRA ist oder auch das Management von Branches in GIT. Es gibt nicht die eine Art und gerade in kleinen Teams, wo es keine Schnittstellen zu anderen Teams und Einblicke in deren Arbeitweisen gibt, entwickelt sich irgendwie ganz schnell die Ansicht, dass man die richtige Arbeitweise erkannt hätte und alle anderne die produkttiv mit der Anwendung arbeiten, zur gleichen Arbeitsweisse gekommen sein müssen.

Deswegen muss man sich immer im klaren sein dass sich das Einarbeiten nie nur auf die grundlegende Bedienung von Anwendungen und dem Kennenlernen von Code beschränkt, sondern viel mehr das Verstehen der Strukuren, Workflows und Ansichten bzw Dennkweisen der Teams bezieht. Wenn man plötzlich mit einer anderen Programmiersprache arbeiten soll ist auch der Syntax das gerinigste Problem und wenn man deren Konzepte verstanden hat, kommt der Syntax fast von allein hinterher.
Man darf also nicht erwarten, dass bloss weil jemand mit einer Anwendung gearbeitet hat, auch genauso damit gearbeitet hat wie man selbst. Das bietet natürlich auch die Gelegenheit mal über den Tellerrand zu gucken und seine eigenen Abläufe noch mal neu zu überdenken und zu optimieren.

Sepia-Filter für MP4toGIF.com

Nachdem längere Zeit bei MP4toGIF.com nichts mehr passiert ist, habe ich heute mich noch mal mit neuen Filtern auseinander gesetzt und mir eine Umgebung zusammen gebaut, in der ich mit neuen Filtern experimentieren kann. Es ist schon interessant, wie man mit dem Ändern weniger Parameter sehr verschiedene Effekte erzielen kann.

bbcode-image


bbcode-image


Die Test-Umgebung findet man unter http://www.annonyme.de/js/filters/. Da kann jeder gerne mal herum experimentieren und versuchen selbst Einstellungen für einen tollen Effekt zu finden.

In den nächsten Tagen und Wochen, werden dann also wohl noch ein paar Filter mehr für MP4toGIF.com entstehen und dort integriert werden.

Die zentrale Render-Function ist sehr einfach aufgebaut:

function render(src, trg, rm, ra, gm, ga, bm, ba, useGreyScale){
var srcData=src.getImageData(0,0,src.canvas.width,src.canvas.height);
var data=srcData.data;
for(var i=0;i<data.length;i+=4){
if(useGreyScale){
var avg = (data[i+0]*rm) + (data[i+1]*gm) + (data[i+2]*bm);
data[i+0]=avg;
data[i+1]=avg;
data[i+2]=avg;
}
else{
data[i+0]=data[i+0]*rm;
data[i+1]=data[i+1]*gm;
data[i+2]=data[i+2]*bm;
}

data[i+0]=Math.abs(data[i+0]+parseInt(ra));
data[i+1]=Math.abs(data[i+1]+parseInt(ga));
data[i+2]=Math.abs(data[i+2]+parseInt(ba));
}
trg.canvas.width=src.canvas.width;
trg.canvas.height=src.canvas.height;
trg.putImageData(srcData,0,0);
}


Invertieren des Bildes ist zum Beispiel: Multiplicator auf 1 und darauf -255 addieren.

Komplexe Probleme und komplexer Code

Komplexe Probleme führen zu komplexen Code. Einfache Probleme führen zu einfachen Code. Das sind die Gesetzmässigkeiten, die immer gelten. Sollte mal ein einfaches Problem zu komplexen Code führen, muss man den einfach wegwerfen und noch mal von Vorne anfangen, weil man irgendwas falsch gemacht hat. Das passiert, aber man erkennt den Fehler schnell und kann ihn korrigieren.

Schwierig wird es wenn ein Problem ein komplex ist. Komplexität ist sowie so ein Problem für sich. Jeder der schon mal Planning Poker gespielt hat, weiß wie schlecht sich Komplexität erkennen und bewerten läßt. Ich habe für mich eine kleine Staffelung erstellt, nach der ich mich richte. Der Knackpunkt bei der Bewertung sind Schnittstellen. Egal ob es andere Systeme sind oder andere Menschen.. sobald Schnittstellen da sind hat man mehr Komplexität und Overhead. Jeder muss das Problem verstehen, seine Aufgaben ausführen und Zeiten einhalten. Wenn das nicht klappt ist es oft auch nicht mal das Problem der anderen Menschen oder Systeme. Fehlerhafte Dokumentation und unklare oder unteschiedlich verwende Begriffe sind fast immer am Anfang dabei und müssen ereinmal geklärt werden.
Deswegen ist zum Beispiel Dokumentation für mich eine hoch komplexe Sache, weil dort immer gleich 2 Schnittstellen existieren. Einmal müssen die Infos rein und dann wieder verständlich für andere raus. Jeder der mal eine 70 Seiten Dokumentation über eine System für andere Entwickler geschrieben hat, wird mir hoffetnlich beipflichten können.

Aber nun zur Tabelle:

* 0: nichts zu tun, da schon erledigt oder obsolete
* 1/2: es müssen Texte oder andere statische Werte geändert werden
* 1: es muss vorhandere Code in der Logik minimal angepasst werden (if-Bedinungen anpassen oder Try-Catch Blöcke setzen)
* 2: Es muss in einer vorhanden Struktur Code erzeugt werden (eine Methode hinzufügen oder Hilfs-Klasse erstellen)
* 3: Es werden Daten verarbeitet (Einfacher Importer oder Ein- und Ausgaben)
* 5: Daten werden um gewandelt oder einfache einfache Schnittstellen entgegen genommen oder ausgegeben (Importer wo die Daten aufbereitet werden müssen)
* 8: Es wird Logik erstelle (Berechnungen und Daten operationen, einfache Planung ohne große Konzeption)
* 13: Logik mit Schnittstellen, wo die andere Seite beeinflusst werden kann, z.B. Fehler wirft, wenn fehlerhafte Daten geliefert werden (Man muss Planen und die Konzeption muss besprochen werden)
* 20: Die Schnittstellen oder Funktionsweisen sind noch zu erarbeiten (Die Realisierung ist machbar, aber es ist noch nicht klar, wie man zum Ziel kommt)
* 40: Man weiß, was man will, aber die Realiserung benötigt Forschung (Viele Meetings und es gibt Ansätze wobei diese auch sich noch als nciht zielführend erweisen können)
* 100: Die Realiserbarkeit kann angenommen werden, aber nicht mit bekannten Mitteln (man muss also richtige Grundlagenforschung betreiben und sich viel Rat einholen)
* unendlich: Man geht von einer Realiserbarkeit aus, aber weiß, dass bis jetzt niemanden gelungen ist so etwas umzusetzen.... z.B. wenn man vorhat einen Fusionsreaktor zu bauen

Da komplexe Probleme zu komplexen Code führen und für diesen gilt, dass er schwer zu warten, lesen und zu erweitern oder ändern ist, muss man den Code vereinfachen. Wer mal versucht hat ohne Neibewertung des Problems von gleichen Ausgangslagen den Code zu verbessern wird gelernt haben, dass man nur wieder anderen komplexen Code geschrieben hat. Man kann Codenicht vereinfachen ohne die Komplexität des Problems runter zu brechen. Das sollte man tun. Probleme in kleinere und einfachere Probleme aufbrechen. Lieber eine Woche länger das Problem analysieren, als Code schreiben der andere und einen selber später noch viel mehr Zeit kosten wird.

bbcode-image


Deswegen.. nie versuchen den Code zu vereinfachen sondern immer das Problem vereinfachen und dann den Code anpassen oder besser noch einfach auch neuschreiben.

Neues Projekt mit aoop

Nach 9 Jahren geht es mit aoop doch mal los. Ein weiters Projekt mit meinem Framework startet morgen. Es basiert auf der neusten Version mit dem Blog-Modul.
Ich bin auch technischer Admin und betreue alles auf technischer Ebene. Logos und Design stammen von meiner Frau und sind wirklich toll. Wer es sich mal ansehen möchte findet es unter http://www.tentacle-news.net.
bbcode-image

Older posts:

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?