Jun 12

Komisch das ich da noch nie draufgestossen bin (passiert wahrscheinlich erst, wenn man mehr als einen Submit-Button hat – kommt ja idR selten vor). Trotzdem, zum merken und mitschreiben:


Der Internet Explorer (getestet bis Version 6.0) verhält sich bei dieser Art Button leider falsch. Er sendet die Buttonbeschriftung, nicht den Inhalt des value-Attributes. Existieren mehrere Absende-Buttons, werden die Beschriftungen aller Buttons gesendet, nicht nur die des geklickten. Deshalb muss man dem IE leider attestieren, dass er dieses Feature derzeit noch nicht korrekt unterstützt.

via selftml

Tagged with:
Mai 29

Das Perl-Modul WWW::Shorten::Bitly als solches bietet die Moeglichkeit URLs, die zuvor mit bit.ly verkuerzt worden sind, wieder zu “expanden” und auch diverse Clickstatistiken auf diese URLs zu fahren.

Leider hat das Modul ein paar Schoenheitsfehler:

  1. Beim “Expanden” meint das Modul die Methode “GET” nutzen zu wollen. Die API von bit.ly schreibt hier aber ein “POST” vor. Das ist recht zuegig gefixed. Einfach in der Zeile 257 (Methode “expand” der Version 1.14) aus dem get ein post machen -> Fertig :-)
  2. Beim Aufruf der Methode “clicks” auf URLs mit vielen Statistik-Daten (Referrers, etc.) versagt der SAX-Parser auf ganzer Linie. Er quittiert das Parsen mit einer Fehlermeldung a’la: End tag mismatch (nodeKey != nodeValue) [Ln: x, Col: yyyyy]Das Problem laesst sich dadurch loesen, dass man dem XML::Simple Modul sagt, es soll gefaelligst einen Ordentlichen parser benutzen. z.B. den XML::Parser (der zuvor via cpan installiert werden muss (setzt libexpat1-dev vorraus !)). Wir teilen dies dem Bitly Modul nach dem Einbinden von XML::Simple ueber folgenden String mit: $XML::Simple::PREFERRED_PARSER = 'XML::Parser'; … und oh Wunder: Alles funktioniert

In diffs ausgedrueckt sind folgende Aenderungen an WWW::Shorten::Bitly Version 1.14 notwendig:

22a23,24
> $XML::Simple::PREFERRED_PARSER = 'XML::Parser';
>
257c259
< $self->{response} = $self->{browser}->get($self->{BASE} . '/expand', [
---
> $self->{response} = $self->{browser}->post($self->{BASE} . '/expand', [

Ab nun klappt auch das Auslesen mit dem Modul.

Tagged with:
Apr 30

Kurzer Test/Kompatibilitaetsbericht:

- Originalheadset vom Blackberry 8900: Miese Qualitaet, fiel schon nach 3 Tagen auseinander

- Originalheadset vom Blackberry 9000: Dank In-Ear werden die Umgebungsgeraeusche zwar isoliert, aber man hoert auch jede Bewegung des Headsets

- iPhone 3GS Headset am Blackberry 8900: Prima. Annehmen funktioniert / lauter & leiser leider nicht

- iPhone Classic Headset am Blackberry 8900: Prima. Annehmen funktioniert.

- iPhone 3GS Headset am Blackberry 9000: Funktioniert ueberhaupt nicht (kein Ton, wird nicht als Headset erkannt)

- iPhone Classic Headset am Blackberry 9000: Prima. Annehmen funktioniert.

Fazit: iPhone Classic-Headset (Das bei dem man eh nicht lauter & leiser einstellen kann) mit BB ist eine recht gute Kombination.

Tagged with:
Feb 17

Gegeben sei folgende Tabelle:

Wert Orderer
A 10
B 20
C 30
D 40
E 50
F 60
G 70
H 80
I 90

Nun mal angenommen folgendes möchten wir irgendwie aus der DB bekommen (Um eine 3 spaltige Tabelle mit tr,td aufzubauen:

Wert Wert Wert
A D G
B E H
C F I

Dann benötigen wir die Daten ja in folgender Reihenfolge:

A,D,G,B,E,H,C,F,I

Nach langem herumprobieren habe ich alle Versuche über Bord geworfen, und bin zu folgendem, suboptimalen (aufgrund der Subselects), Ergebnis gekommen:


SELECT wert
FROM (SELECT wert,
x,
ROW_NUMBER () OVER (PARTITION BY x ORDER BY orderer) AS y
FROM (SELECT wert,
orderer,
NTILE (:3) OVER (ORDER BY orderer) AS x
FROM tabelle))
ORDER BY y, x

Hat jemand einen besseren Vorschlag… Ich meine: Funktionieren tut das ganze (In BIND-Variable 3 wird die Anzahl der Spalten übergeben). Aber Sexy geht irgendwie anders…

Tagged with:
Jan 09

Args !

Die Thickbox Library als solches ist ganz nett. Mit Hilfe des Frameworks, welches auf jquery aufsetzt, kann man wunderbare Layer-PopUps basteln (Ja, die braucht man auch schonmal ausserhalb der Werbebanner-Welt). Das Ding ist ziemlich ausgereift, und beisst sich auch nicht mit meinem CGI::Ajax Modul. Einzig der Superbrowser aus Redmond in der Version 6 (InternetEplorer 6 / IE6) macht, wie könnte es anders sein, Probleme !

Das Handling von Seitenbreite und Seitenhöhe dieser Browserwurst kommt nämlich bei dynamisch nachgeladenen Bildchen durcheinander. Soll heissen: Ist die Seite nach dem Laden eines img’s Breiter als vorher, dann behält der Internet Exploder 6 stur die alte Seitenbreite. Da nun Thickbox die PopUps aber immer mittig platzieren will (Mitte = Seitenbreite / 2) passt hier nun garnichts mehr.

Wenn man in der Thickbox.js die Funktion tb_position durch folgendes, mühsam erarbeitetes, Stückchen Kot ersetzt, dann klappts auch mit dem Internet Exploiter…


function tb_position() {
var scrolledX = $(document).scrollLeft()
if ( !(jQuery.browser.msie6)) { // take away IE6
$("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
$("#TB_window").css({marginLeft: '-' + parseInt(( (TB_WIDTH) / 2),10) + 'px', width: TB_WIDTH + 'px'});
} else { // Krankheit aus Redmond !!! Friss dieses:
$("#TB_window").css({marginLeft: parseInt(( (-1)*(TB_WIDTH) / 2)+scrolledX,10) + 'px', width: TB_WIDTH + 'px'});
}
}

Tagged with:
Jan 07

Da ich gerade mal wieder mit den Eigenarten des Internetexploders am kämpfen bin, ist dieses Dokument recht interessant. Erschreckend, dass kein einziger (!) Browser die Content-Disposition – Typen korrekt nach RFC interpretiert.

Jeder, der schonmal fluchenderweise versucht hat Anhänge, via Webserver, mit selbstgebautem Header auszuliefern, weiss worum es hier geht.

Interessant wäre doch ein derartiger Test auch mal mit “CacheControl”, “Cache-Control”, und wer weiss wieviel Varianten es davon noch gibt…

Tagged with:
Jan 05

… schonmal versucht Abhängigkeiten grafisch darzustellen ? Am besten noch aus Datenbankcontent ?

Klar, man könnte zu irgendwelchen proprietären MindMap-Tools oder gar zu M$-Visio (oh grauss !) greifen. Dabei geht es mit graphviz in Verbindung mit “dot” soooo einfach. Das Ding ist ehrlich einen Blick wert. Zusammen mit der “Connect by Prior” Clause in Oracle ist das Teil der Knaller schlechthin.

Ein wenig Doku dazu (die original-Doku ist recht schwere Kost) gibt es z.B.

Das allerbeste ist, dass MediaWiki das Ding von Haus aus unterstützt, und man derartige Graphen direkt per Wiki-Editor in die Artikel einbetten kann…

Tagged with:
Jan 03

Ha, da habe ich doch schon ewig nach gesucht (und bin immer wieder auf “Chicken of the VNC”, “Jolly VNC” oder andere Spaesse ausgewichen).

Gesucht war eine Tastenkombination mit der man beim Verbinden auf Windooze Kisten ein “CTRL-ALT-DEL” senden kann. Alle Standardkombinationen sind fehlgeschlagen. Jetzt weiss ich wie es geht. Man drücke nach dem Verbinden via “Command-K” und “vnc://ip.ad.dre.sse” einfach CTRL-ALT-COMMAND-DELETE.

Das Command war das fehlenden Glied :-)

Fuer alle “alten” Mac-User: COMMAND = “Apfeltaste” :-)

Tagged with:
Dez 28

Wer nicht unbedingt mit Kanonen auf Spatzen schiessen will, und sich Adobes Creative Suite zulegen moechte, ist mit PAINT.NET bestens bedient. Das gute Stueck punktet mit Layern, einer Menge Effekten und dem Fakt, dass es frei ist.

Wenn es jetzt noch sowas aehnliches fuer den MAC gaebe, waere ich gluecklich. Und jetzt komm mir bitte keiner mit The Gimp . Das Ding ist zwar ebenfalls nett, aber solange es nur unter “X” schnurrt, leider keine echte alternative.

Tagged with:
Okt 07

Auch nett…

wer weiss wofuer man es mal gebrauchen kann.

Gegeben sei folgende Tabelle:

SQL> SELECT deptno, ename FROM emp ORDER BY deptno, ename;

DEPTNO ENAME
------ ----------
    10 CLARK
    10 KING
    10 MILLER
    20 ADAMS
    20 FORD
    20 JONES
    20 SCOTT
    20 SMITH
    30 ALLEN
    30 BLAKE
    30 JAMES
    30 MARTIN
    30 TURNER
    30 WARD

14 rows selected.

Wir moechten jetzt die Employees zu einem department aber in je einer Zeile haben. Man nehme: wm.concat aus wmsys

SELECT deptno,wmsys.wm_concat(dname) departments FROM dept group by deptno;

    DEPTNO CONCATENATED
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
...

Ist doch schick, oder ?

Jan 10

Wer soetwas in seinen Access Logs als Refrerrer sieht kann sich wundern, muss er aber nicht :-)

http://127.0.0.1:4664/preview?event...

Der Referrer kommt naemlich von der Google-Desktop Suche. Also: Wieder schlauer geworden :-)

Nov 22

Man kennt das. Gerade frisch einen Postfix aufgesetzt, eine Testmail losgelassen und Zaaack! – das Ding will nicht rausgehen. Jetzt dümpelt die Mail bis zum Timeout in der Queue herum. Abhilfe habe ich früher geschaffen in dem ich mir via mailq die Mail-ID herausgekramt habe und dann mühsam durch die spool Directories gegangen bin um ein File nach dem anderen zu löschen. Es geht eleganter:

mailq aufrufen um die Mail-ID zu bekommen

und anschliessend nur noch “postsuper -d <mail-id>” aufrufen um die Mail zu töten. Fertig….

Ja, die meisten werden es kennen. Nur so vergesse ICH das garantiert nicht mehr :-)

Sep 17

Probleme bei der Ausgabe von Texten in UTF8 unter Perl ? So für Schnittstellen, und ähnliches ?

Kein Problem:

Nach öffnen des Ausgabestreams (File, oder ähnliches) einfach ein simples binmode FILEHANDLE,":utf8"; implementieren, und schon klappt es mit dem Charset. Wieso das auf einigen Systemen (z.B. Solaris) auch ohne Binmode geht (das setzen der Environment-Variable “LANG” auf de_DE.UTF half hier), weiss ich nicht. Aber so funktioniert es in jedem Falle !

Sep 03

Ein Update des DBD::Oracle Treibers von 1.16 auf 1.21 klingt zunaechst unspektakulaer. Aber wie so oft steckt der Teufel im Detail. Benutzt man nämlich persistente Verbindungen unter mod_perl mit dem Modul Apache::DBI, ändert sich das Verhalten beim disconnecten von der DB. In der Regel cached das mod_perl die Verbindungen ja, daran hat sich auch nichts geaendert.

Bei der 1.16er Version jedoch impliziert das disconnect ein commit. Das hängt laut Modul-Doku von gutdünken des (Modul-)Entwicklers ab. Hat man seine Applikation jetzt darauf ausgerichtet, dann macht man nie ein Commit (sollte man nicht tun !). Dumm nur, dass dieses Verhalten bei der 1.21er geändert wurde. Nun impliziert das Modul beim disconnecten nämlich ein Rollback. Und das macht es selbst dann, wenn ein commit vorrausgeht.

Im ersten Ansatz ist das verschmerzbar. Wenn die DB allerdings, selbst bei Skripten die nur SELECTen, jedesmal mit einem Rollback belaestigt wird, kommt da schon einiges zusammen. Das Verhalten lässt sich mit folgendem “Workaround” aendern:

Aus einem $dbh->disconnect() wird ab sofort ein

$dbh->{AutoCommit}=1;
$dbh->disconnect();

Das AutoCommit wird also kurz vorm disconnecten gesetzt, und beeinflusst das sonstige Rollback/Commit-Verhalten im gesamten Skript ueberhaupt nicht. Sobald ein neues Connect (auch in einer persistenten mod_perl Umgebung) kommt, werden (auch bei gecachter DB-Verbindung) die Parameter AutoCommit, etc., eh neu gesetzt. Damit verhält sich alles wieder wie vorher.

Aug 28

Schon mal versucht einen Aggregations-SQL nach anderen Werten als den Format-Strings die mit to_date, to_char benutzt werden duerfen zu bauen ?

Ist garnicht so simpel. Ein

select count(*),attribut,to_char(creationdate,'DD.MM.YYYY')
 from tabelle
 group by attribut,trunc(creationdate,'DD.MM.YYYY')

ist noch fuer jedermann verstaendlich. Auch wenn man nach Stunden gruppieren will, geht das noch schmerzfrei (‘HH’). Was aber wenn man auf 15Minuten Ebene Aggregieren soll ? Ohne Kunstgriff geht es nicht. Hier der to_date String:

 to_date(to_char(sysdate,'DD.MM.YYYY') ||
         ' ' ||
         trunc(to_number(to_char(sysdate,'SSSSS'))/900)*900,
         'DD.MM.YYYY SSSSS')

Was passiert hier ?

Zunächst wird die aktuelle Zeit (im Select ist es natuerlich das zu gruppierende Feld) in Sekunden nach Mitternacht umgewandelt. Nun dividieren wir das Ergebniss durch 900 (15 Minuten = 900 Sekunden) und schnibbeln die Nachkommastellen ab. Anschliessend das ganze wieder mit 900 Multiplizieren, und wir haben jede Erdenkliche Uhrzeit auf die letzte Viertelstunde (ab-)gerundet. (Schlaue Menschen koennten jetzt sagen, Mensch Joerch, nimm doch DIV, MOD gibts unter Oracle schliesslich auch -> DIV gibts leider NICHT). So, jetzt packen wir noch das Datum wieder davor (ist ja durch die Umwandlung in Sek. nach Mitternacht verloren gegangen) und konvertieren das ganze wieder in ein Datum. Fertig ist der Viertelstundenaggregator :-) Bezogen auf das obige Beispiel lautet unserer (zugegebenermassen unlesbarerer Spruch) wie folgt:


select count(*),attribut,
 to_date(to_char(creationdate,'DD.MM.YYYY') ||
         ' ' ||
         trunc(to_number(to_char(creationdate,'SSSSS'))/900)*900,
         'DD.MM.YYYY SSSSS')
 from tabelle
 group by attribut,
 to_date(to_char(creationdate,'DD.MM.YYYY') ||
         ' ' ||
         trunc(to_number(to_char(creationdate,'SSSSS'))/900)*900,
         'DD.MM.YYYY SSSSS')
preload preload preload