Encodingprobleme Mac OS X

Immer wieder kommt es zu Problemen mit dem Encoding mit dem Postgres ausgegeben wird. Obwohl die Einstellungen in Postgres scheinbar richtig sind, kommen Umlaute mit dem falschen Encoding aus der DB. Außerdem konnte ich bisher keine Umlaute in Iterm eingeben. Sie wurden einfach ignoriert. Mit diesen Einstellungen habe ich dies korrigiert:

1. In der Datei ~/.inputrc folgende Zeilen eintragen und speichern:
set meta-flag on
set convert-meta off
set output-meta on

2. In der postgres-Shell das richtige Encoding setzen:
# set client_encoding to ‘latin1′;

(nochmal ansehen geht so: show client_encoding).

3. In ITerm zentral latin1 als encoding einstellen:
Bookmarks::Manage Profiles::Terminal Profiles::Encoding

Captchas mit Sinn

Leider ist der Einsatz von Captchas für den Benutzer immer eine lästige Angelegenheit: er muss sinnlose Zeichenfolgen abtippen um einem Computer zu beweisen dass er ein Mensch ist.

Das Projekt http://recaptcha.net/learnmore.html verfolgt einen neuen und recht interessanten Ansatz: Statt sinnlose Texte vom Benutzer abtippen zu lassen werden ihm Auszüge aus Büchern vorgsetzt, die von einem OCR-Programm nicht korrekt erkannt werden konnten. Dieses nicht erkannte Wort wird kombiniert mit einem dem Rechner bekannten Wort. So ist sicher gestellt das der Benutzer  keine Maschine ist und angenommen dass er den unbekannten Text richtig eingibt.

Der Nutzen für die Allgemeinheit ist, dass Texte aus alten Büchern digitalisiert werden.

Google-Maps auf der eigenen Seite einsetzen

Wer eine dynamische und sehr leistungsfähige Karte auf seiner Webseite einsetzen möchte, kann das mit Google-Maps recht schnell und problemlos erledigen. Das Angebot von Google ist kostenlos unter der Bedingung, dass die Seite, auf der die Karte eingebunden wird, kostenlos im Internet zur Verfügung steht. Weiterhin bietet Google keinen Support für Entwickler an, die die Google-Maps API verwenden möchten. Aber ein Entwickler der sein Handwerk versteht benötigt auch keinen. Es gibt eine ausführliche Beschreibung der Funktionen mit Beispielen und diese einzubinden ist recht einfach.

Möchte man Google-Maps einbinden, benötigt man zunächst einen Google-Maps API Key. Dieser wird beim Abrufen der Karten von Google übertragen und ist für die Domain auf der die Karte eingebunden wird gültig. Auf jeden Fall ist es ratsam einmal die Nutzungsbedingungen durch zu lesen.

Google stellt eine ausführliche Dokumentation der API zur Verfügung. Hier sollen nur die ersten Schritte etwas erläutert werden.

Zunächst definiert man ein DIV, in das die Karte geladen werden soll irgendwo im body-Tag der HTML-Seite:


<div style="position: absolute; top: 0px; left: 200px; width: 800px; height: 600px" id="map"></div>

Der Anzeigebereich kann man mittels dieses Divs exakt festlegen.

Im nächsten Schritt wird die Karte mittels eines Javascript-Aufrufes in dieses dif eingebunden.


<script src="http://maps.google.com/maps?file=api&v=2&key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
   if (GBrowserIsCompatible()) {
   var map = new GMap2(document.getElementById("map"));
   map.setCenter(new GLatLng(37.4419, -122.1419), 13);
   }
}

//]]>
</script>

Hierbei ist in der ersten Zeile der eigene Key, der zuvor erstellt wurde, für key=abcdefg eingesetzt werden. Die Funktion load führt dann die eigentliche Initialisierung der Karte aus. Dabei wird zunächst eine Funktion GBrowserIsCompatible() aus der Google-API augerufen, die sicher stellt, das der Browser, der die Seite anzeigt dazu geeignet ist. Danach wird ein neues Karten-Objekt erstellt. Dabei wird die ID des Divs, das die Karten enthalten soll, in diesem Fall “map”, übergeben. Der nächste Aufruf zentriert die Karte auf bestimmten Koordinaten. Der erste Parameter von setCenter ist dabei die Koordinate selbst, der zweite Parameter gibt einen Zoom-Level an. Eine genaue Dokumentation zu dem Zoom-Level wurde nicht gefunden. Je kleiner der Wert ist, desto näher wird herangezoomt. Hier muss ein wenig ausprobiert werden.

Um die Karte das erste mal ausprobieren zu können fehlt nun nur noch ein Aufruf im Body-Tag der HTML-Seite:

<body onload="load();" onunload="GUnload()">

Dadurch wird die zuvor definierte JS-Funktion load() aufgerufen sobald die Seite im Browser dargestellt wird. Der zweite Aufruf onunload=”GUnload()” sorgt dafür, das beim Verlassen der Seite der Speicher des Web-Browsers aufgeräumt wird und sollte deshalb auch unbedingt mit eingebunden werden.

Ein kleines Beispiel ist hier verfügbar.

Etoken unter Linux initialisieren

Die folgenden Schritte sind notwendig um einen Alladin-Etoken unter Linux zu initialisieren. Ein gültiger Private-Key und ein gültiges Zertifikat müssen in Form von .pem-Dateien vorliegen. Es ist zu beachten, daß der Etoken mit dieser Initialisierung nur unter Linux funktioniert, die durch diesen Prozess erstellte Struktur kann nicht von den Tools unter Windows verwendet werden.

Es ist ratsam, den Private Key nach dem Aufspielen des Etokens zu löschen oder zumindest sehr sicher aufzubewahren.
# löschen und initialisieren der Karte
pkcs15-init -EC –no-so-pin -T -l “mfrankl”

Hier ist nur die User-Pin einzugeben

# Passwoerter setzen
pkcs15-init -P -T -l “mfrankls pin” –auth-id 01

# Private Key importieren
pkcs15-init -S mfrankl-key.pem –auth-id 01

# Zertifikat importieren
pkcs15-init -X mfrankl-cert.pem –auth-id 01

Absturz von DVB-T Receiver

Hier folgt ein Auszug aus der Bedienungsanleitung eines DVB-T Receivers der Marke Skymaster. Erschreckend daran ist, daß wohl schon davon ausgegangen wird, daß der Nutzer Abstürze sowieso schon von seinem PC gewohnt ist.

“Das Gerät reagiert nicht mehr: Der Receiver muss sehr viele unterschiedliche Daten verarbeiten und reagiert deshalb manchmal wie der heimische PC: Er stürzt ab. Ein Umschalten beim Empfang von EPG-Daten oder “unverständlichen” Daten seitens des Programmanbieters können zum Absturz führen. Ziehen Sie einfach den Netzstecker und warten Sie einige Sekunden, bis Sie das Gerät wieder in Betrieb nehmen.”

Gefehlt daran hat mir nur noch dieser Absatz: “Ziehen Sie doch einfach den Stecker, wir können nichts weiter tun um dies in Zukunft zu vermeiden. Finden Sie sich einfach damit ab. Es bringt auch nichts wenn Sie uns die Fehler berichten, da wir sowieso nichts dagegen tun” :-)

Read the rest of this entry »

Online DSL-Geschwindigkeit messen

Unter der folgenden Adresse kann man schnell und einfach die Geschwindigkeit der DSL-Verbindung messen. Weitere Ergebnisse zeigen unter anderem die Netzwerkauslastung des Anbieters unter verschiedenen Gesichtspunkten auf.

http://www.wieistmeineip.de/speedtest

Erstellen von Video-DVDs aus komprimierten Videoformaten mit Linux

Dieser Eintrag beschreibt, wie aus einer komprimierten Video-Datei wie divx oder anderen unter Linux eine Video-DVD erstellt werden kann. Die einzelnen Schritte sind erstaunlich einfach und funktionieren weitestgehend automatisch. Ich persönlich fand dies einfacher als alle GUI-Tools die ich bisher gesehen habe. Natürlich gibt es keine Garantie für das Funktionieren, ich kann nur sagen daß es für mich gut funktioniert hat :-) . Die Umwandlung erfolgt in mehreren Schritten. Ausführliche Infos zu den einzelnen Schritten und weitergehenden Möglichkeiten kann aus den Quellen entnommen werden.

Schritt 1: Umwandeln des Quellvideos in ein DVD-taugliches Format:

Für diesen Schritt habe ich als erstes das Tool ffmpeg ausprobiert und war mit dem Ergebnis sehr zufrieden. Es gibt noch zahlreichen weitere Tools, die man ausprobieren könnte. Zu beachten ist, daß man für diesen Schritt schonmal eine DVD-Größe (max. 4,7GB) Plattenplatz im Verzeichnis work benötigt. Sowohl das Verzeichnis work wie auch ziel.mpg können beliebig gewählt werden. Das Verzeichnis work muss vor dem Befehl angelegt werden.


mkdir work
ffmpeg -i "quelle.avi" -target dvd work/ziel.mpg

Dieser Schritt benötigt abhängig von der Prozessorleistung einige Zeit.

Schritt 2: Erstellen der DVD-Struktur

Mit dem vorliegenden DVD-tauglichen mpg kann nun die DVD-Struktur erstellt werden. Ich habe dabei eine Struktur ohne ein Menü gewählt, das geht schnell und einfach. Zu diesem Schritt habe ich das Tool dvdauthor verwendet. Auch hier gibt es zahlreiche Alternativen, darunter auch hübsche GUI’s. Zu beachten ist, daß hier nochmals Plattenplatz in DVD-Größe benötigt wird.


cd work
dvdauthor -o dvd/ -t ziel.mpg
dvdauthor -o dvd/ -T

Der erste Befehl fügt das in Schritt 1 erstellte mpg in die Struktur ein. Sollen mehrere (kleine) Filme auf die DVD, kann der Aufruf beliebig wiederholt werden. Der zweite Schritt erstellt die endgültige DVD-Struktur. Das ganze dauert auch wieder etwas, jedoch bei weitem nicht so lange wie das Umwandeln des Videos.

Schritt 3: Prüfen des Ergebnisses

Um sicher zugehen, daß man auch das erwartete Ergebnis bekommt, kann man sich die DVD vor dem brennen schonmal vorab anschauen. Dies kann mit einem beliebigen DVD-Fähigen Media-Player wie xine oder mplayer erfolgen. Natürlich ist dieser Schritt optional.


xine dvd:"$(pwd)/dvd"

Schritt 4: Erstellen eines ISO-Images

Mit der Struktur aus Schritt 3 kann nun ein DVD-ISO Image erzeugt werden. Abhängig vom Brenn-Programm kann dieser Schritt auch übersprungen werden. K3b z.B. kann auch direkt die Dateien brennen. Da er aber auch nicht sehr zeitaufwändig ist, schadet es nicht. Dies geht mit dem folgenden Befehl:


mkisofs -dvd-video -v -o DVD.iso dvd

Schritt 5: Brennen des ISO-Images

Im letzten Schritt muss die DVD nur noch mit einem Brennprogramm der Wahl auf DVD gebrannt werden. Hier kann das KDE-Programm k3b empfohlen werden.

Quellen:

Ajax-Funktionen mit JSON und Perl

JSON als Alternative zu Nachrichtenübertragung auf XML-Basis

Eine interessante Alternative zu AJAX-Funktionen auf XML-Message-Basis bietet die JSON-Technologie an. Die Übertragung der Nachrichten vom Browser zum Server erfolgt dabei auf Basis einer einfachen Datenstruktur, die am besten beschrieben werden kann als Verschachtelung von Arrays und Hashes. In den meisten Programmiersprachen werden diese Strukuren nativ unterstützt, was die Verbreitung der Technologie extrem vereinfacht.

Der Overhead des durch die XML-Strukturen anfallenden Codes entfällt, somit wird die Übertragung und das Verarbeiten der Nachrichten vereinfacht. Weder auf der Seite des Clients noch auf der des Severs muss eine Transformation der Daten über XSLT oder aber ein Zusammensuchen der Daten durch aufwändiges Navigieren durch das DOM erfolgen. Zudem muss sich der Programmierer keine Gedanken um das Finden einer geeigneten XML-Struktur machen um die Daten hin- und her zu transportieren.

Eine Besonderheit ist dabei, daß die Daten auf der Client-Seite direkt als gültiger Javascript-Code vorliegen. Sie können direkt mit Javascript weiterverarbeitet werden.

JSON Nachrichtenstruktur

Die Strutur der zu übetragenden Nachrichten sind ausführlich auf www.json.org beschrieben.

Beispiel für eine JSON-Nachricht:

{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": [{
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef":
"A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML", "markup"]
}]
}
}
}

Implementieren auf Client-Seite

Um die AJAX-Funktionalität auf der Client-Seite zu implementieren, benötigt man eine Javascript-Library. Eine solche ist auch über die oben genannte Seite www.json.org zu beziehen, allerdings nicht besonders leicht zu finden.

Deshalb hier die direkten Links:

Weiterhin ist eine Library HTTP.Request hilfreich, mit deren Hilfe die HTTP-Übertragung selbst Browsertransparent durchgeführt werden kann. Sie kann hier bezogen werden. Allerdings ist zu beachten, daß in der aktuellen Version dieser Library zur Übertragung immer automatisch der Content-Type application/x-www-form-urlencoded verwendet wird. Dies führt z.B. bei einem Perl-Backend auf dem Server dazu, daß der Request nicht mehr korrekt ankommt sondern nur zerteilt. Zum Beheben dieses Problems sollte die folgende Zeile in Request.js geändert werden von:


this.transport.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );

in

this.transport.setRequestHeader( "Content-type", "plain/text" );

Mit diesen Vorraussetzungen kann nun der Client implementiert werden:

<script type="text/javascript" src="/global/lib/json.js"></script>
<script type="text/javascript" src="/global/lib/HTTP/Request.js"></script>
<script type="text/javascript">
var req, id = 0, since_msg = new Date();
// vor 5 Stunden
since_msg.setTime(new Date().getTime() - 1000 * 60 * 60 * 5);

function aktualisieren () {
var txt = document.getElementById('eingabe');

req = new HTTP.Request({
uri: '/test/testajax',
postbody: JSON.stringify( {
method : 'finduser',
id : id++,
params : [ txt.value, since_msg.getTime() ]
}),
onSuccess: function (trans) {
var data;
try {
var data = eval('('+trans.responseText+')'); // JSON "parsen"
} catch(e) {
alert('eval: Ungültiges JSON: ' + e);
return;
}
// hier kann ggf. noch auf data.error geprüft werden
nachrichten(data.result);
}
});
/*txt.value = ''; // Text im Eingabefeld nach Versand löschen*/
txt.focus(); // Benutzer kann weiter Text eingeben
}

function nachrichten (result) {
var ausgabe = document.getElementById('ausgabe'); // DIV fuer Text
if (result) { // Antwort auf update_box
ausgabe.innerHTML="";

for (var i = 0; i < result.length; i++) {
ausgabe.innerHTML += result[i] + "<br>\n";
}
}
}

</script>

<form action="#" onsubmit="aktualisieren();">
Ihr Text: <input type="text" id="eingabe" value="" onkeyup="aktualisieren();"/>
<input type="button" value="senden + empfangen"
onclick="aktualisieren();"/>
</form>
<div id="ausgabe"></div>

Die wichtigsten Code-Stellen:


JSON.stringify( {
method : 'finduser',
id : id++,
params : [ txt.value, since_msg.getTime() ]
}

Hier wird ein Hash der die Nachrichtenbestandteile enthält mittels JSON.stringify zu einem JSON-String umgewandelt. Die RPC-Methode, die dabei auf dem Server aufgerufen wird, nennt sich finduser. Sie bekommt die Parameter txt.value, since_msg.getTime(). id ist eine fortlaufende Nummer, die zur Identifizierung des Requests bei asynchron eintreffenden Ergebnissen dient.

Der erzeugte JSON-String zur Übertragung sieht dann so aus:

{"method":"finduser","id":0,"params":["micha",1140627355276]}

Mittels der Anweisung:

req = new HTTP.Request({
uri: '/test/testajax',
postbody: JSON.stringify( {
method : 'finduser',
id : id++,
params : [ txt.value, since_msg.getTime() ]
}),
onSuccess: function (trans) {
var data;
try {
var data = eval('('+trans.responseText+')'); // JSON "parsen"
} catch(e) {
alert('eval: Ungültiges JSON: ' + e);
return;
}
// hier kann ggf. noch auf data.error geprüft werden
nachrichten(data.result);
}
});

wird der HTTP-Request übetragen. onSuccess beinhaltet eine Funktion, die bei einem erfolgreichen Request ausgeführt wird. Hier wird die Antwort verarbeitet und dynamisch in die dargestellte Seite eingebaut.

Implementierung auf der Server-Seite

Auf der Server-Seite ist die Implementierung natürlich abhängig von der Programmiersprache der Wahl. JSON-Implementierungen sind in zahlreichen gängigen Programmiersprachen vorhanden, Links dazu sind auch über www.json.org zu finden.

Hier soll die Implementierung in Perl betrachtet werden. Wie man es von Perl gewohnt ist, steht ein fertiges CPAN-Modul JSON zur Verfügung, daß das Einbinden denkbar einfach macht. Es funktioniert (unter anderem) mit einer RPC-Schnittstelle á la SOAP. Im Idealfall muss man sich noch nicht einmal mit den JSON-Datenstrukturen beschäftigen, sondern bekommt die Parameter direkt als Funktionsparameter geliefert und gibt Perl-Datenstrukturen zurück. Die nötigen Umwandlungen passieren im Hintergrund.


package MyJSON;
use strict;
sub finduser {
my $server = shift;
my $username = shift;
my $time = shift;
#...
# return a scalar value or a hashref or an arryaref. Z.B.:
# return {'username'=>"Franz Mustermann", 'userid'=>14};
}

package main;
use strict;
use JSONRPC::Transport::HTTP;
use MyJSON;

# a la XMLRPC::Lite
JSONRPC::Transport::HTTP::CGI->dispatch_to('MyJSON')->handle();

Untersuchen der Datenübermittlung bei POST-Queries

Im Zusammenhang mit der Übertragung von XML-Queries oder Ähnlichem für AJAX ist es von Vorteil zu wissen, wie die verschiedenen Möglichkeiten zum Übertragen von Daten per POST an einen Server genau funktioniert. Einige Fehler bei der Übertragung der Daten lassen sich damit schnell verstehen.

application/x-www-form-urlencoded

Ohne irgendwelche Angaben schickt der Browser die Daten in dieser Kodierung:
Content-Type: application/x-www-form-urlencoded
Sie wird auch verwendet, wenn im Formtag dieses Attribut verwendet wird:

enctype="application/x-www-form-urlencoded"

Der Body der Nachricht sieht dann wie folgt aus:

param1=jjhkjh&param2=ghzzvfh+asd+asdas&inhalt=inhalt+der+tt%0D%0Asadasd%0D%0Asad%0D%0Aasd%0D%0A%0D%0Aas%0D%0Ada%0D%0As

Sie ist also wie der Content-Type schon sagt URL kodiert und könnte auch einfach wie sie ist in einem GET-Aufruf benutzt werden. Zu beachten ist, dass mit dieser Methode keine Dateien übertragen werden können. Hier wird lediglich der Dateiname übertragen, der eigentliche Inhalt nicht.

multipart/form-data

Die zweite Möglichkeit ist dieser Typ:
enctype="multipart/form-data"

Hierbei wird jeder einzelne Parameter in einem durch einen Boundary-abgetrennten Bereich transportiert, ähnlich wie das bei MIME-Messages geschieht. Diese Methode ist auf jeden Fall zu wählen, wenn eine oder mehrere Dateien zum Server übertragen werden sollen, im Gegensatz zur ersten Methode ist auch der Transport von Binär-Dateien möglich.

Beispiel:


POST /admin/users HTTP/1.1
Host: atlas.mf.devel
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060117 Firefox/1.0.7
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: de,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://atlas.mf.devel/admin/users?action=edit&id=51&order=ldap&sessionid=e4a6a108394d2d124b89e73d0c4ff5391&style=popup&style=popup
Cookie: sessionid=e4a6a108394d2d124b89e73d0c4ff5391
Content-Type: multipart/form-data; boundary=---------------------------12440347477298357471720878039
Content-Length: 4599
-----------------------------12440347477298357471720878039
Content-Disposition: form-data; name="atk"

74609419
-----------------------------12440347477298357471720878039
Content-Disposition: form-data; name="id"

51
-----------------------------12440347477298357471720878039
Content-Disposition: form-data; name="action"

update
-----------------------------12440347477298357471720878039
Content-Disposition: form-data; name="offset"

-----------------------------12440347477298357471720878039
Content-Disposition: form-data; name="order"

ldap
-----------------------------12440347477298357471720878039

Öffnen von lokalen Dateien über einen Link auf einer Internetseite

Hintergrund

Für ein Projekt ist es nötig auf einer Internetseite Links auf lokale Dateien anzubieten. Das Problem ist, das die Browser die aus Sicherheitsgründen blocken. Die Links sehen etwa aus, wie dieses Beispiel:

<a href="file://netshare/mountpoint/xy/datei.doc">datei.doc</a>

Browserdetails

Firefox

  • Default-Verhalten: Firefox öffnet die Links nicht. Genauer gesagt reagiert er gar nicht darauf.
  • Abhilfe: Das Blocken der file:// -Aufrufe im Firefox kann durch eine Konfigurationseinstellung beeinflusst werden. Dabei gibt vor und nach Version 1.5 von Firefox bzw. vor und nach Mozilla 1.8 unterschiedliche Konfigurationseinstellungen. Siehe dazu: Links to local pages don’t work

Konqueror (Version 3.4.1)

  • Default-Verhalten: Rückfrage ob die unsichere Aktion (Datei öffnen) durchgeführt werden soll.
  • Abhilfe: nicht nötig.

Internet Explorer IE(Version6.0)

  • Default-Verhalten: Rückfrage ob die unsichere Aktion (Datei öffnen) durchgeführt werden soll.
  • Abhilfe: nicht nötig.