Technik, Gothic und Anderes

Technik ist Spiel, Gothic ist ernst und Zeit hat man zuviel

Archiv

Emailadressen auf Webseiten codieren

Geschrieben von skaldrom am 5. April 2007

Spammer brauchen Emailadressen. Neue Emailadressen bekommen sie, indem sie (wie Google) mit sog. Robots von Website zu Website springen, den Inhalt herunterladen und die Emailadressen herauspfriemeln. Das heisst, man sollte seine Emailadressen im WWW verstecken, so gut dass es geht. Eine Möglichkeit ist die Benutzung von JavaScript (weil das die Addressharvester anscheinend noch nicht so beherrschen), eine Andere ist die Verwendung von Bildern (es gibt natürlich noch mehr).

Ich habe dazu ein kleines PHP Skriptchen geschrieben. Es kann eine Emailadresse alleine oder viele Emailaddressen in Text eingebettet verstecken. Im Zip hat es 3 Dateien:

  • hidemail.php: Das Hauptscript, das die Arbeit erledigt.
  • imagemke.php: Ein Script, das aus den Mailadressen Bilder erzeugt wenn das Javascript ausgeschaltet ist.
  • hmexample.php: Ein Beispiel, das die Anwendung zeigt. Es gibt auch eine online Demo.

Ich würde mich über Feedback freuen :)…. Download: hidemail PHP Skript um Mails zu hiden. Zum Gebrauch müssen einige Einstellungen (beispielsweise die URL zu imagemke.php in hidemail.php gemacht werden.

Ideen sind von:


Nachtrag Juli 2008:
Einen Interessanten Beitrag dazu gibt es beim Tillate Techblog!

Eingeordnet in Webapplikationen | 3 Komentare »

Die Spamfalle für Webmaster

Geschrieben von skaldrom am 2. April 2007

Der eine Weg, gegen Spammer vorzugehen, ist ihnen die Email-Adresse nicht zu geben. Der Andere Weg wäre es, ihnen gaaaaanz viele Adressen zu geben! Die Ursprüngliche Idee ist von Neil Gunton, hier etwas praktisch angepasst.

Die Grundidee ist folgende: Wir verbieten das Indizieren bestimmter Seiten. Liebe Roboter halten sich dran, böse nicht. Auf diesen Seiten Bieten wir ganz viele Emailadressen und weitere Links auf andere Seiten an mit noch mehr Adressen. Ich hoffe dann mal, dass sich die Datenbank des Spammers füllt, mit falschen Mailadressen…

Installation:

Das PHP-Skript kreiert verschiedene Seiten mit Fiesitäten… Weitergehende Links im Kreis, Links auf andere Spamtraps, defekte und korrekte Emailadressen, etcetc… Es sollte in ein eigenes Verzeichnis (bspw: /mails/) kopiert werden. Man kann auch ein laufendes Beispiel ansehen. Bitte bedenke: Die Seiten müssen nicht schön sein, sondern Maschinenlesbar :)…

Um die netten Roboter abzuhalten im Kreis zu indizieren, verbieten wir ihnen das ganz einfach in der Datei /robots.txt:

# robots.txt
User-agent:  *
Disallow: /mails/

Damit die Spammer das auch finden, sollte auf möglichst vielen Seiten ein versteckter Verweis angebracht werden. Zum Beispiel mit einem durchsichtigen gif, 1×1 Punkt gross:

<a href="/mails/"><img alt="" src="/images/transparent.gif" width="1" height="1" border="0"/></a>

Denkbar wäre es auch, das Ganze mit einem nofollow Link zu versehen.

Nun sollen sie sich zu Tode fressen… Hier die Dateien: Spamtrap: Skript, robots.txt und transparent.gif.

Ebenfalls eine nette Lösung ist die Spidertrap. Sie blockiert die IPs der unanständigen Roboter und schliesst sie so aus.

Eingeordnet in Webapplikationen | Keine Kommentare »

Changelogs mit SVN

Geschrieben von skaldrom am 15. March 2007

Aufgabe

Und die Aufgabe sei: Es werde ein Tool geschaffen, das jeden Tag prüft, wer an den Repositories gefrickelt hat und daraus ein Changelog generieret. Fürtherhin sei eine Liste als Index erstellt, die alle diese Repositories mit den Committern anzeiget und mit Links versehet, die zum detailierten Changelog geleiten. Auch ein RSS sei geschaffen, der abonniert werden kann.

So sei es. svn2log kann Text-Changelogs generieren. source-highlight kann daraus html-Seiten basteln. Damit svn2log auch Commits ohne Kommentar berücksichtigt, wird es gepatcht.

So sei Dir ein BASH-Script geschrieben, das durch unsere 2 Stufige Repositoryhierarchie hindurchloopt, und 4 Dinge erzeuge:

  • Text Changelog generell
  • Text Changelog der letzten 7 Tage
  • Html Changelog generell
  • Html Changelog der letzten 7 Tage

Und danach ein PHP fürwahr ein Index erstelle der eine Übersicht zeige und der auch via RSS in ein jede heimische Stube kommen kann!

Beispiel: Changelog Index

Bemerkungen

Nachtrag: Eine weitere Möglichkeit ist svn2rss. Ein etwas mächtigeres Paket, geschrieben in Ruby.

Code

Den Code gibts bei oncode.info.

Eingeordnet in Linux | Keine Kommentare »

Ein Ajax Baum der sich sein Zustand merkt

Geschrieben von skaldrom am 25. November 2006

Man gönnt sich ja sonst nichts… Ich wollte für eine mit dem Symfony Framework erstellte Webanwendung eine Baumansicht. Da leichtes implemenieren langweilig ist, musste es schon ein Ajaxbaum mit Kontextmenü und allem Schnickschnack sein. Nach längerem Suchen fiel die Wahl auf Dojo, einem Toolkit mit vielen Widgets und sonstigen Spassmachern. Der Baum besitz viele Nodes, darum sollten diese dynamisch nachgeladen werden (ok, etwas Masochismus war auch dabei). Die Anwendung besteht eigentlich aus herkömmlichen Seitenwechseln, und so musste der Baum auch seinen Zustand halten können. Nundenn, nach laaaaaanger Probierephase (die Dokumentation ist nicht gerade erschlagend) und der Hilfe vom Web wurde es dennoch Realität *freu*.

Hilfreiche Websites:

Tipps generell:

  • var djConfig = {isDebug: true }; aktiviert die Debugeingaben, dojo.debug(’Blah’); kann für Debugausgaben benutzt werden.
  • saveExpandedIndices und restoreExpandedIndices sind methoden des erweiterten tree-Controllers! Er muss also require’d und gemixint werden (siehe unten)
  • Der Baumzustand wird in einem Cookie gespeichert, damit hat man in der Applikation nichts mehr damit zu tun.

Wie das Ganze in Symfony integriert wurde kann gerne nachgefragt werden.

Nundenn, gimme Code:

<script type="text/javascript" src="/js/dojo.js"></script>
<script type="text/javascript">
var djConfig = {isDebug: true }; // Comment if debugguing
dojo.require("dojo.widget.Tree");
dojo.require("dojo.widget.TreeSelector");
dojo.require("dojo.widget.TreeNode");
dojo.require("dojo.widget.TreeContextMenu");
dojo.require("dojo.widget.TreeLoadingController");
dojo.require("dojo.widget.TreeControllerExtension");
// Do something if a node is clicked
function modulTreeSelectFired() {
    var treeSelector = dojo.widget.manager.getWidgetById('modulTreeSelector');
    var treeNode = treeSelector.selectedNode;

    < !– get a reference to the songDisplay div –>
    //var hostDiv = document.getElementById("songDisplay");

    var isFolder = treeNode['isFolder'];
    if ( !isFolder) {
       //var song = treeNode['title']
       //hostDiv.innerHTML = "You clicked on "+song;
    } else {
       //hostDiv.innerHTHML = "";
    }
    //hostDiv.style.display = "";
}

// Set up Dojo and the tree
function init() {
    var treeSelector = dojo.widget.manager.getWidgetById('modulTreeSelector');
    dojo.event.connect(treeSelector,'select','modulTreeSelectFired');

    var modulTree = dojo.widget.manager.getWidgetById('modulTree');
    dojo.event.topic.subscribe(modulTree.eventNames.collapse, "saveExpandedIndices");
    dojo.event.topic.subscribe(modulTree.eventNames.expand, "saveExpandedIndices");

    // add extensions to controller
    dojo.lang.mixin(dojo.widget.byId('modulTreeController'), dojo.widget.TreeControllerExtension.prototype);

    // Restore old state
    restoreExpandedIndices();
 }

// Save the tree state
function saveExpandedIndices() {
        // You can save this object as tree persistent state
        indices = dojo.widget.byId('modulTreeController').saveExpandedIndices(
            dojo.widget.byId('modulTree')
        );
        var flatIndices = dojo.json.serialize(indices);
        //dojo.debug(flatIndices);
        dojo.io.cookie.setCookie('modulTree/saveindices',flatIndices, 365, null, null, null);
    }

// Restore the tree state
function restoreExpandedIndices() {
        flatIndices = dojo.io.cookie.getCookie('modulTree/saveindices');
        indices = dojo.json.evalJson(flatIndices);
        //dojo.debug(flatIndices)
        if(indices) {
            dojo.widget.byId('modulTreeController').restoreExpandedIndices(dojo.widget.byId('modulTree'), indices
            );
        }
    }

// Initialize
dojo.addOnLoad(init);</script>

Der HTML-Code sollte eigentlich klar sein: Controller, Kontextmenü und Tree aufbauen (nur die erste Hierarchiestufe) und der PHP-Teil ist nach Vorgabe. Sind mehr Details gewünscht, liefere ich diese gerne nach.

Stichworte: persistent tree state, remembering tree state

Ergänzung, Juli 2008: Oky, Ihr habt recht: Gimme Code! Schwatzen kann jeder!

Hier mal den Quellcode (eher das Gerüst, bzw proof-of-concept :) ) des Moduls und den Inhalt des web/js Verzeichnisses. Hilft das was? Braucht es mehr, damit es sinnvoll ist?

Geschrieben wurde es mit Symfony 1.0 und Dojo 0.4 Rev: 6258.

In der Zwischenzeit bin ich aber von dem Dojo-Ajax Zeux wieder etwas weggekommen. Ich progge für Intra- und Extranetapplikationen, und da sind zu viele Browser mit zu vielen Konfigurationen im Einsatz. Für “öffentliche” Websites ist es sicher schön, auch wenn es (wie bei Symfony üblich) nicht voll Ajax ist, sondern halt nur Komponentenweise, was ich nicht als schön empfinde…

Ich bin zurück zum guten alten PHP-Layersmenü (Beitrag dazu folgt noch). Das fallbackt sehr schön ohne Java Script.

Eingeordnet in Theorie und Schnipsel, Webapplikationen | 6 Komentare »

Unicode-Hölle: PHP, Apache, Mysql und Symfony in UTF-8

Geschrieben von skaldrom am 20. November 2006

Ich will mein altes ASCII wieder!!! Unicode ist die Hölle. Vielleicht helfen folgende Dinge dem, der damit rumkämpfen will/muss:

  • Im ganzen Pfad muss die Codierung stimmen bzw. gezielt umgewandelt werden. In unserem Beispiel also Dateisystem, Datenbank, (PHP), Applikation und Browser.
  • Glaube nicht was Du siehst! Was angezeigt wird ist wieder aus einer Applikation die irgendwie encodiert.
  • Firefox: View -> Character Encoding ist Dein Freund. Damit sieht man, was der Browser denkt er erhalte und das Umschalten auf 8859-1 kann zeigen, dass man es noch nicht geschafft hat und immernoch das alte Encoding verwendet wird.
  • utf8_encode() und utf8_decode() sind böse! Wenn man die braucht stimmt etwas nicht.

Hier ein paar Hilfen und Tools.

Dateisystem:

locale -a zeigt die Codierungen. Auf Debian kann man mittels dpkg-reconfigure locales einiges umstellen. Hier mal Unicode zu haben schadet nicht.

Konvertierung mit recode:

Folgendes Kommando wandelt eine Datei in ISO88591 in Unicode um:

recode ISO-8859-1..UTF-8 DATEI

Mysql:
Um Daten in UTF-8 abzulegen, muss:

  • das charset stimmen
  • die Verbindung vom Client zum Server stimmen
  • die Datenbank eine Collation “utf8_unicode_ci” besitzen
  • jede Tabelle eine Collation “utf8_unicode_ci” besitzen
  • die Daten in UTF-8 abgefüllt sein

Für das Abfüllen eignet sich mysql-query-browser, da dieser schon mit utf-8 arbeiten kann, was bei der Konsole nicht immer ganz sicher ist.

  • Tools: SHOW VARIABLES LIKE ‘character%’,damit sieht man, wie man unterwegs ist
  • set names utf8 zwingt die Verbindung zu utf8
  • select _utf8′Trällöällä’ wandelt den String inUTF-8

Apache:

Irgendwo im Conf sollte AddDefaultCharset UTF-8 stehen. Das vereint das Charset über HTTP.

PHP/Browser:

Wenn der Browser kein UTF-8 anzeigen will, kann man das im php.ini umstellen: default_charset = “UTF-8″.

Links

http://www.phpwact.org/php/i18n/charsets ist eine wirklich gute, praktische Einführung in das Problem im Zusammenhang mit PHP.

Symfony/Creole:

Um da mit UTF-8 zu arbeiten muss databases.yml gefüllt werden. KEIN dsn benutzen, denn dann funzts nicht:

all:
  modul:
    class:      sfPropelDatabase
    param:
      phptype:  mysql
      username: dbuser
      password: dbuserpass
      database: modul
      host:     localhost
      encoding: utf8

Ein ähnliches, hässliches Problem bei der Datenbankmigration wird bei Orthogonal Thought beschrieben.

Eingeordnet in Theorie und Schnipsel | 4 Komentare »

MySQL Views verwenden mit Propel und Symfony

Geschrieben von skaldrom am 13. November 2006

Symfony, das PHP-Framework ist genial. Will man allerdings die Datenbank-Views verwenden, geht das nicht so direkt.

Damit die Propel orm-Klassen generiert werden, muss im config/schema.yml die Struktur so definiert werden, dass sie nicht direkt in die Datenbank abgespitzt wird:

m_my_view:
  _attributes: { phpName: ModulCompleteView, skipSql: true}
  post_id:        {type: integer}
  post_title:     {type: varchar, size: 255}
  post_content:   {type: longvarchar}
  comment_id:     {type: integer}
  comment_content:{type: longvarchar}

Damit die View bei symfony propel-insert-sql erstellt wird, sollte eine Datei im gleichen Verzeichnis erstellt werden in dem auch lib.model.schema.swl ist (normalerweise /data/sql). Wir nennen sie my-view.sql:

CREATE OR REPLACE view m_my_view as
SELECT
  post.id as post_id,
  post.title as post_title,
  post.content as post_content,
  comment.id as comment_id,
  comment.content as comment_content
FROM
  post, comment
WHERE
  comment.post_id=post.id

Und nun nur noch die Datei sqldb.map ergänzen:

my-view.sql=DB-VERBINDUNG

und nun sollts funzen.

Eingeordnet in Theorie und Schnipsel | Keine Kommentare »