Canon CanoScan LiDE 210 auch für Linux

Der erste Scanner, ein Canon CanoScan 9900F, war ein mächtiges Trumm; mächtig schwer, mächtig laut und ständig zickende Treiber, zumindest unter Windows XP Prof. 32 bit. Allerdings bedeutete »schwer« nicht gleichzeitig solide, da nach nur zwei Jahren trotz permanenter Unterforderung bereits der Ein-/Ausschalter seinen Dienst versagte.

Mit dem CanoScan LiDE 210 ist alles ganz anders. Er ist nicht größer als nötig, bezieht seine Energie aus dem USB-Kabel, und er ist sehr leise und leicht, fast schon zerbrechlich. In der Kategorie Haptik unterläge er, wegen seines rachitischen Auftritts, sogar einem leeren Joghurtbecher. Dennoch ist er aufgrund seiner Praktikabilität ein ganz Großer. Wenn man wöchentlich nur ein paar Seiten einzuscannen hat ist er die Lösung. In der anderen Zeit verschwindet er platzsparend im Schrank. Die Scans selbst sind von hervorragender Qualität, ob Brief oder Bild.

Windows 7 Prof. 64 bit

Eines hat sich in den letzten zehn Jahren bei Canon offensichtlich nicht geändert: Die problematische Software/Treiber. Um es an dieser Stelle abzukürzen, die CD läßt man besser im Karton und lädt sich den Treiber und die Scanner-Applikation direkt von den Canon-Seiten. Dann funktioniert auch alles auf Anhieb. Bei der Software selbst (Navigator) hat Canon den Fokus nicht auf die Usability sondern auf ein Gummibärchen-Design gelegt. Aber das ist Geschmackssache.

Linux Ubuntu 12.04 64 bit

Was soll man groß sagen? Sony Vaio (Z-Serie) hochgefahren, Terminalfenster geöffnet, Scanner mit USB verbunden, Programm scanimage aufgerufen und der Scanner summt, einfach so, out-of-the-box. Wer mag kann sich alternativ auch xscanimage und/oder xsane herunterladen. Das läuft dann ebenso unkompliziert. Etwas genauer: scanimage und anschließend convert (ImageMagick) wurde so aufgerufen:

$ scanimage --format=tiff    \
            --mode Color     \
            --depth 8        \
            --resolution 300 \
            --icc-profile /usr/share/color/icc/RGB/AdobeRGB1998.icc \
             -l 1mm          \
             -t 1mm          \
             -x 208mm        \
             -y 295mm        \
             -v              \
             > canoscan_${tmstmp}.tif

$ convert -quality 85 \
          -gamma 1.4  \
          -brightness-contrast 10x40 \
          -comment "Quelle: Canon, CanoScan LiDE 210" \
           canoscan_${tmstmp}.tif \
           canoscan_${tmstmp}.jpg

Hinweis: tmstmp ist hier $(date +"%F_%H-%M-%S")

Wer es noch bequemer mag, kann sich das alles in mehrere Scripts mit entsprechenden Parametern für Briefe, Bilder, etc. einpacken. Die Umwandlung mehrerer JPGs in ein PDF-Dokument erfolgt übrigens so: $ convert *.jpg doku.pdf
rh2012-12-001

iPad 3: Mophie Powerstand

Mophies Powerstand
Mophies Powerstand sorgt für Helligkeit
Die Handhabung des iPad, dies ist hier im wörtlichen Sinne gemeint, ist – je nach Einsatzzweck – nicht unproblematisch. Entweder man hält das iPad fest in beiden Händen, dann kann man nicht mehr Schreiben oder es liegt auf dem Tisch, dann fällt auf Dauer das Lesen schwer. Das haben offensichtlich auch viele Hersteller aus dem Zubehörbereich festgestellt und bieten für das iPad entsprechende Lösungen, sog. Stands, an. Häufig sind diese Teile aus Kunststoffen gefertigt, die keinen Eindruck von Solidität hinterlassen. In manchen dieser Stands sind zudem noch Lärmbalken integriert, die wohl der stereophonen Musikwiedergabe dienen sollen. Für diejenigen, die mehr Stabilität erwarten oder auf zusätzliche Audiounterstützung verzichten können, für die wird die Auswahl schon schwerer. Dabei bietet Apple in seinem Online Store im Bereich iPad Zubehör eine Lösung an: Der Mophie Powerstand. Dieses Apple Zukaufteil der kalifornischen Firma Mophie, die in China fertigen läßt, verdient durchaus das Prädikat German Steelwork.

Der Powerstand ist scheinbar aus dem vollen Aluminium gefräst und steht solide und wackelfrei auf dem Schreibtisch. Das iPad gleitet langsam aber präzise in den Stand und rastet unten vernehmlich in den Dock Connector ein. So ausgestattet kann man das iPad-Powerstand Duo problemlos und sicher von Büro zu Büro, von Zimmer zu Zimmer tragen ohne befürchten zu müssen, daß das iPad aus dem Stand herausfällt. Genau dieser Vorteil könnte sich, je nach Nutzungsart, allerdings schnell auch als Nachteil erweisen. Wer häufig, also mehrmals täglich, das iPad ohne die Halterung benutzen möchte, wird mit einem Problem konfrontiert. Es erfordert einige Zeit und Sorgfalt das iPad verkantungsfrei in den Stand einzuführen, die Entnahme ebenso. Wer zwar Geduld aber keine Zeit hat, möchte das höchstens einmal täglich praktizieren.

Ein zweiter Kritikpunkt an dem Powerstand ergibt sich gleich in der ersten Nacht. Das iPad wird im Powerstand über ein USB-Kabel (A an B) und ein Netzteil geladen. Dies geschieht leider nicht ohne eine Illumination des Stands aus der hinteren Querachse heraus. Aus zwei etwa 2 Euro Münzen großen Achsenenden brüllt grellweißes LED-Licht heraus und stellt damit die Leistung so mancher Taschenlampe sprichwörtlich in den Schatten. Die zweiteilige Fragestellung an Mophie »was soll das« und »wie kann man das abstellen« beantwortet Staci vom Customer Advocate wie folgt:

»Unfortunately there is no way to deactivate the lights.«

Liebe Staci, das war zwar nicht die erhoffte Antwort, aber danke für eine Antwort.

Die tägliche Arbeit mit dem iPad und dem Mophie Powerstand ist wirklich angenehm. Von den Kritikpunkten, die ja beide keine k.o.-Punkte sind, müßte sich das Dauer-Flutlicht eigentlich unkompliziert und ohne konstruktiven Mehraufwand beheben lassen. Dann wäre der Mophie Powerstand auch uneingeschränkt empfehlenswert.
rh2012-10-001

WordPress: Sync Comment Count

Synchronteile
Synchronisierung der Kommentare
Den Kommentarzähler unterhalb eines Artikels speist WordPress, vielleicht aus Gründen der Geschwindigkeit, aus der Datenbank-Tabelle wp_posts.comment_count. Aufgrund von mißlungenen manuellen Eingriffen, Unfällen oder sonstigen Mißgeschicken kann dieser Soll-Zähler schon einmal von der tatsächlichen Anzahl der vorliegenden Kommentare (Ist) abweichen. Technisch gesehen stellt das wohl kein Problem dar, aber es sieht unvorteilhaft aus, wenn fünf Kommentare angekündigt, aber nach einem Klick lediglich drei davon abgebildet werden.

Die wirkliche Anzahl der Kommentare je Post läßt sich allerdings sehr leicht aus der Tabelle wp_comments durch einfaches Zählen ermitteln und das Ergebnis in die Tabelle wp_posts übertragen. Wenn das ganze jetzt noch als sogenannte stored procedure angelegt wird, steht die Routine jederzeit zur Verfügung. In PhpMyAdmin könnte man im SQL-Editor dazu folgendes eingeben:

DROP PROCEDURE if exists proc_posts_commentcount_update //
CREATE DEFINER = WP_DB_User@localhost
  PROCEDURE proc_posts_commentcount_update()
  COMMENT 'fuehrt einen Soll-Ist-Abgleich der Kommentare durch'
  BEGIN
    update WP_Database.wp_posts as po
    left join (select comment_post_ID, count(*) as 'cnt'
    from WP_Database.wp_comments
    where comment_approved = '1'
    group by comment_post_ID) as co
    on co.comment_post_ID = po.ID
    set po.comment_count = coalesce(co.cnt, 0)
    where po.post_status = 'publish' and po.post_type = 'post';
  END //

Hinweis: Kommentare (Comment) dürfen bei einigen MySQL-Versionen scheinbar eine Länge von 64 Zeichen nicht übersteigen.

Zu jedem echten Post in der Tabelle wp_posts (Status = publish und Typ = post) werden die Vorkommen der freigegebenen Kommentare (Approved = 1) in der Tabelle wp_comments gezählt und die Anzahl in das Datenfeld wp_posts.comment_count eingetragen. Liegen keine Kommentare zu einem Post vor, so soll dies der Wert »0« und nicht »NULL« sein (Coalesce). Damit hat ein vollständiger Soll/Ist-Abgleich der Kommentare stattgefunden. Gespeicherte Prozeduren können jederzeit über das Call-Statement aufgerufen und ausgeführt werden.
rh2012-08-002

WordPress: Trash last Comments

Es ist schon etwas ernüchternd, wenn man morgens den ersten Blick in die E-Mail Konten wirft und anhand der WordPress Benachrichtigungsmails feststellen muß, daß sich wieder einmal an die hundert Spam- oder Unsinn-Kommentare in WordPress angesammelt haben. Schon an den Absenderdaten erkennt man meist überschlägig: Alles Schrott, vieles kann weg. Spätestens hier entsteht dann der Wunsch den gesamten Müll jederzeit und von überall mit einem Knopfdruck, entfernen zu können.

Vorausgesetzt wird, daß keine WordPress Plugins im Hintergrund wirken, denen man mit den nächsten Schritten ins Handwerk pfuscht. Außerdem wird angenommen, daß eingehende Kommentare per Voreinstellung als sofort freigegeben gelten. Desweiteren muß darauf hingewiesen werden, daß manuelle Eingriffe in die WordPress-Datenbankstrukturen grundsätzlich Probleme verursachen können.

Neue Kommentare werden, ergänzt mit Verwaltungsinformationen, in der Tabelle wp_comments abgelegt. Das Datenfeld wp_comments.comment_approved ist zum Beispiel mit dem Wert »1« belegt, wenn der Kommentar freigegeben wurde oder mit dem Wert »trash« belegt, wenn der Kommentar für die Löschung/Leerung des Papierkorbs vorgesehen ist. Erlaubt WordPress geschachtelte Kommentare, enthält wp_comments.comment_parent des Child-Kommentars die ID des bezogenen Parent-Kommentars, andernfalls steht hier einfach eine »0«. Innerhalb dieser Hierarchie werden die Kommentare nach Datum aufsteigend sortiert dargestellt. Die zu den Kommentaren in Bezug stehende Tabelle wp_commentmeta wurde damit bisher noch nicht berührt. Das ändert sich erst, wenn über das Web-Interface von WordPress ein Kommentar gelöscht, genauer gesagt zunächst in den Papierkorb verschoben wird. Dann laufen diese vier Dinge ab:

  • in der Tabelle wp_comments wird das Feld comment_approved von »1« auf »trash« gesetzt
  • die Tabelle wp_commentmeta erhält einen neuen Datensatz mit der ID des gelöschten Kommentars wp_comments.comment_ID, dem Schlüssel _wp_trash_meta_status und dem Wert des Datenfelds wp_comments.comment_approved vor dem Löschen, hier also eine »1«
  • die Tabelle wp_commentmeta erhält noch einen weiteren Datensatz, ebenfalls mit der ID des gelöschten Kommentars, dem Schlüssel _wp_trash_meta_time und dem Unix-Timestamp des Löschzeitpunkts
  • besonders problematisch: obwohl es sich um eine berechenbare Größe handelt ist das Datenfeld wp_posts.comment_count mit der Anzahl der zugehörigen Kommentare vorbesetzt und wird mit jedem Löschvorgang um eins dekrementiert.

Wird über die WordPress-Verwaltung in einem weiteren Schritt jetzt auch noch der Papierkorb geleert, werden alle drei betroffenen Datensätze (2 × wp_commentmeta und 1 × wp_comments) aus den beiden Tabellen gelöscht. Wenn übrigens ein Parent-Kommentar gelöscht wird, nicht aber seine Child-Kommentare, erhalten diese Child-Kommentare im Datenfeld wp_comments.comment_parent den Eintrag »0«, werden also nachträglich quasi selbst zu Parent-Kommentaren. Ihre Einsortierung in der Kommentarhierarchie erfolgt dann wiederum nach Datum. Dieses WordPress Verhalten ist überdenkenswert.

Aufgabe

Benötigt wird jetzt eine praktische Möglichkeit Kommentare eines beliebigen Zeitraums ohne Zuhilfenahme des WordPress Web-Interface zu löschen. Genauer gesagt, zunächst sollen die betreffenden Kommentare in den WP-Papierkorb verschoben werden aus dem eine Rettung vor der nächsten Leerung jederzeit wieder möglich ist. Zum Einsatz soll eine MySQL-Prozedur (stored procedure) in der WordPress Umgebung und ein kleines Skript auf dem PC oder Notebook kommen, das die entfernte Prozedur anstößt. Hier sei nochmals der Hinweis erlaubt: Keine Eingriffe in Produktionssysteme ohne Datensicherung und dann auch nur mit dem Verständnis dafür, was man da eigentlich macht.

Prozedur

Die MySQL-Prozedur kann sehr bequem über den SQL-Editor von phpMyAdmin erfaßt und abgespeichert werden:

DROP PROCEDURE IF EXISTS proc_comments_new_delete //
CREATE DEFINER = 'WP_DB_User'@'localhost'
  PROCEDURE proc_comments_new_delete()
  BEGIN

    drop temporary table if exists WP_Database.tmp;

    create temporary table WP_Database.tmp (
    ID bigint(20) unsigned not null auto_increment,
    c_ID bigint(20) unsigned not null default '0',
    cp_ID bigint(20) unsigned not null default '0',
    primary key(ID)) engine = memory;

    insert into WP_Database.tmp
    select NULL, co.comment_ID, co.comment_post_ID
    from wp_comments as co
    where date(co.comment_date) >= date_sub(current_date(),
      INTERVAL 1 DAY)
    and co.comment_approved = '1';

    insert into WP_Database.wp_commentmeta
    select NULL, tmp.c_ID, '_wp_trash_meta_status',
      co.comment_approved
    from tmp, wp_comments as co
    where tmp.c_ID > 0 and tmp.c_ID = co.comment_ID;

    insert into WP_Database.wp_commentmeta
    select NULL, tmp.c_ID, '_wp_trash_meta_time',
      unix_timestamp(current_timestamp())
    from tmp, wp_comments as co
    where tmp.c_ID > 0 and tmp.c_ID = co.comment_ID;

    update WP_Database.wp_comments as co, tmp
    set co.comment_approved = 'trash'
    where co.comment_ID = tmp.c_ID;

    call proc_posts_commentcount_update();

    drop temporary table if exists WP_Database.tmp;

  END //

Hinweise: Das Update der Kommentarzähler erfolgt hier in einer eigenen Prozedur, da diese Routine auch eigenständig sinnvoll eingesetzt werden kann. Die Beschreibung hierzu erfolgt im nächsten Post. Der Begrenzer/Delimiter »//« muß im SQL-Editor bekannt gemacht werden, damit der Editor die Verwaltung von der Nutzdaten zwischen Begin und End richtig trennen kann. Diese Schritte werden dabei durchlaufen:

  1. alte Prozedur gleichen Namens ggf. löschen
  2. neue Prozedur erstellen
  3. temporäre Tabelle tmp löschen
  4. temporäre Tabelle tmp mit drei Datenfeldern zur Aufnahme der IDs erstellen
  5. temporäre Tabelle mit den IDs der Kommentare füllen, die von heute oder gestern sind und den comment_approved Status »1« tragen
  6. Tabelle wp_commentmeta gemäß den IDs aus der Tabelle tmp mit den Einträgen ID, _wp_trash_meta_status und dem comment_approved Status aus der Tabelle wp_comments beschicken
  7. Tabelle wp_commentmeta desweiteren mit den Einträgen zu ID, _wp_trash_meta_time und dem Unix-Timestamp des Löschdatums beschicken
  8. in der Tabelle wp_comments das Datenfeld comment_approved von »1« auf »trash« setzen
  9. update des Kommentarzählers wp_posts.comment_count für alle Kommentare/Posts durchführen
  10. temporäre Tabelle tmp löschen

Der unter Punkt 5. genannte Zeitraum (gestern/heute) ist natürlich nur ein Beispiel und sollte dem Bedarf angepaßt werden. Alternativ könnte auch ein konkreter Zeitraum, zum Beispiel die letzten 24 Stunden, vorgegeben werden:

select comment_post_ID as PostID, comment_author as Autor,
  comment_date as DatumZeit, comment_author_email as EMail,
  comment_content as Inhalt
from WP_Database.wp_comments as co
where (unix_timestamp() - unix_timestamp(co.comment_date))
  between 0 and 86400 and
  co.comment_approved = '1'
order by co.comment_date;

Hinweis: Die »magic number« 86400 setzt sich natürlich zusammen aus 60 Sekunden × 60 Minuten × 24 Stunden.

Skript

Schließlich wird noch ein kleines Skript benötigt, das man per »rechte Maustaste | Öffnen | Klick« den eigentlichen Job machen läßt. Mehr sollte nicht notwendig sein:

@echo off
set Nachricht=alle neuen Kommentare geloescht
::
echo.Kommentare von heute und vom Vortag suchen ...
::
set sql=
set sql=%sql% call proc_comments_new_delete()
::
c:\"program files (x86)"\putty\plink -ssh -P 22 ^
  -l ssh-user -pw user-password ^
  hostname-oder-ip ^
  /usr/bin/mysql -u mysql-user –pmysql-password wordpress-database ^
  --execute=\"%sql%\"
::
if %ERRORLEVEL% gtr 0 (
  set Nachricht=Fehler beim Loeschen neuer Kommentare ^
  & goto batchend)
::
:batchend
echo.%Nachricht%

Zusammenfassung

Während dieser Artikel entstand sind 27 Spam-/Unsinn-Kommentare eingetroffen und komfortabel wieder entsorgt worden. Natürlich ist das Löschen ganzer Kommentargruppen gestern/heute oder 24 Stunden nicht der Weisheit letzter Schluß. Aber es ist möglicherweise eine Vorstufe zu einer zentralen, transparenten, nicht WordPress-Plugin gestützten Spam-Kontrolle. Abschließend sei nochmals angemerkt, daß Manipulationen an der WordPress Datenbank, vorbei an der WP-Datenbankverwaltung, fatale Folgen für den gesamten Blog haben kann. Desweiteren ist das Versenden von Paßwörtern und sonstigen Verbindungsdaten über unverschlüsselte Leitungen, wie hier im Skript gezeigt, sehr schlechter Stil. Es ist halt nur bequem.
rh2012-08-001