Excuses aan Frank

Gisteren was Frank Vander linden in De Ideale Wereld. Mijn Kosovaarse vriendin vroeg me wie die interessante kale vent op de TV was. Ik antwoordde haar: “oh ik denk een drummer van De Kreuners of zo”.

Dat was onvergefelijk fout, natuurlijk. Als boetedoening speel ik vandaag alle nummers van De Mens af hier in de huiskamer. Zodat ze een beetje onze Vlaamse muziekcultuur kan waarnemen.

Bij deze ook mijn uitgebreide excuses in deze open brief aan de Frank: sorry dat ik mij totaal vergist heb. Ik heb er heel de nacht over wakker gelegen. Hoe kon zoiets toch gebeuren?

Eikels verbranden

Normaal gesproken

Normaal gaan we in Vlaanderen niet al te extreem doen met onze houtkachel. Per slot van rekening hebben we allemaal wel of gas, elektriciteit of een warmtepomp of nog iets anders om onze woning te verwarmen.

De houtkachel werd of wordt meestal gebruikt om gezelligheid te bereiken.

Maar dit jaar hebben we een redelijk zware energiecrisis. Die zorgt ervoor dat ons gas heel erg duur is. Daarom gaan we een aantal alternatieven uitproberen.

Wat ik in mijn tuin zoal vond waren de eikels van een eikenboom. Enkele problemen met het verbranden van eikels:

  • Je moet de eikels verzamelen
  • De eikels zijn (vaak te) vochtig
  • De (verzamelde) eikels zijn gemengd met bladeren
  • Je moet de eikels snel in de kachel krijgen

De eikels verzamelen

Dit doe ik met een grashark. Ik geef voorkeur aan eikels die op verharde grond liggen. We moeten niet autistisch doen en proberen alle eikels te verzamelen. Meestal zijn er voldoende eikels die op de verharde grond liggen. Bovendien gebruik ik de hark om de bladeren te scheiden van de eikels (we zitten hier op aarde niet in een vacuüm en dus vallen de eikels sneller dan de bladeren. Je bent een ingenieur? Dan kan je die kennis gebruiken).

De eikels zijn te vochtig

Ik verzamel de eikels wanneer het droog weer is. Bovendien houd ik de eikels een paar dagen (zelfs weken) bij in een (open) emmer of container alvorens ik ze in de kachel gebruik. Hoe langer je ze kan drogen, hoe beter.

De eikels zijn (nog steeds) gemengd met bladeren

Die bladeren zijn vaak vuil en vochtig, wat rook veroorzaakt wanneer we de verzameling verbranden. Daarom heb ik een ijzeren raster op de emmers waarin ik de eikels laat vallen gelegd. Zo kunnen de bladeren eenvoudig gefilterd worden.

Je moet de eikels snel in de kachel krijgen.

Hoe langer het deurtje van de kachel open is, hoe meer rook er ontsnapt. Dat is niet goed want ongezond voor de mensbeesten die zich in de buurt van de kachel bevinden. Daarom heb ik geïnvesteerd in een ijzeren blik om de eikels uit een grotere emmer te kunnen scheppen in voldoende hoeveelheid per keer. Ik leg de eikels ook rondom het brandende vuur in plaats van in het vuur. Zodat pas later, wanneer de deur van de kachel reeds gesloten is (en er geen rook in de leefruimte meer kan ontsnappen), de eikels zullen verbranden.

Tot slot

Tot slot heb ik een luchtzuiveraar in de leefruimte staan. Iedere ochtend open ik ook alle ramen (d.i. vrij belangrijk). Tijdens de avond zijn er vaak ook twee ramen die in een lijn van West naar Oost liggen open. De wind in Vlaanderen waait meestal van West naar Oost. Geloof je me niet? Kijk maar eens hoe de landingsbanen van de luchthaven van Zaventem liggen. En zoek op waarom dat zo is. Je wil dat de wind snel door je leefruimte waait, zodat het zoveel mogelijk fijnstof meeneemt.

Uiteraard verlies je door de raam open te zetten wat van de door de kachel gegenereerde warmte. Maar als je daar dan weer een beetje over nadenkt, dan doet dat er niet zoveel toe: je hebt die warmte gratis vergekregen door gebruik te maken van eikels. Of niet?

Of is het beter dat je longen gevuld worden met fijnstof?

Je kan ook even na de kacheldeur gesloten is die ramen weer sluiten. Uit een goede kachel die goed geïnstalleerd is ontsnapt letterlijk niets van rook naar de leefruimte. Als vanzelfsprekend wil je dit enkel met een goede kachel doen.

Natuurlijk

Is dit allemaal goed voor de luchtkwaliteit van Vlaanderen? Vast niet.

Mijn kachel is een erg moderne DDG kachel die m.a.w. een zogenaamde volledige verbranding doet (en ook aangesloten is op de centrale verwarming). Maar dit is uiteraard niet goed voor de luchtkwaliteit van het land.

Ik ben er niet zeker van of men momenteel veel betere alternatieven heeft: Russisch gas verbranden aan meer dan duizend euro per maand is ook niet echt een goede optie. Elektriciteit is onwaarschijnlijk duur. Dus ja.

De wet

Je mag niets anders dan onbewerkt hout verbranden. De eikels zijn volgens mij onbewerkt hout. Maarja. Het hangt vast van een interpretatie af.

OCR for your old scanner/printer’s E-mails

Yesterday I explained how to make a scrap computer do OCR on your scanner/printer’s scanned PDFs in case you have a SMB file share (a Windows file share) where the printer will write to.

I also promised I would make the E-Mail feature of the printer send E-mails with the PDFs in that E-mail being OCR scanned.

I had earlier explained how you can make your old scanner/printer support modern SMTP servers that have TLS, by introducing a scrap computer running Postfix to forward the E-mails for you. This article depends on that, of course. As we will let the scrap computer now do the OCR part. If you have not yet done that, first do it before continuing here.

I looked at Xavier Merten‘s CockooMX, and decided to massacre it until it would do what I want it to do. Namely call ocrmypdf on the application/pdf attachments and then add the resulting PDF/A (which will have OCR text) to the E-mail.

First install some extra software: apt-get install libmime-tools-perl . It will provide you with MIME::Tools, we will use MIME::Parser and MIME::Entity.

Create a Perl script called /usr/local/bin/ocrpdf.pl (chmod 755 it) that looks like this (which is Xavier’s CockooMX massacred and reduced to what I need – Sorry Xavier. Maybe we could try to make CockooMX have a plugin like infrastructure? But writing what looks suspicious to a database ain’t what I’m aiming for here):


#!/usr/bin/perl

# Copyright note

use Digest::MD5;
use File::Path qw(make_path remove_tree);
use File::Temp;
use MIME::Parser;
use Sys::Syslog;
use strict;
use warnings;

use constant EX_TEMPFAIL => 75; # Mail sent to the deferred queue (retry)
use constant EX_UNAVAILABLE => 69; # Mail bounced to the sender (undeliverable)

my $syslogProgram	= "ocrpdf";
my $sendmailPath	= "/usr/sbin/sendmail";
my $syslogFacility	= "mail";
my $outputDir		= "/var/ocrpdf";
my $ocrmypdf		= "/usr/bin/ocrmypdf";

# Create our working directory
$outputDir = $outputDir . '/' . $$;
if (! -d $outputDir && !make_path("$outputDir", { mode => 0700 })) {
  syslogOutput("mkdir($outputDir) failed: $!");
  exit EX_TEMPFAIL;
}

# Save the mail from STDIN
if (!open(OUT, ">$outputDir/content.tmp")) {
  syslogOutput("Write to \"$outputDir/content.tmp\" failed: $!");
  exit EX_TEMPFAIL;
}
while() {
  print OUT $_;
}
close(OUT);

# Save the sender & recipients passed by Postfix
if (!open(OUT, ">$outputDir/args.tmp")) {
  syslogOutput("Write to \"$outputDir/args.tmp\" failed: $!");
  exit EX_TEMPFAIL;
}
foreach my $arg (@ARGV) {
  print OUT $arg . " ";
}
close(OUT);

# Extract MIME types from the message
my $parser = new MIME::Parser;
$parser->output_dir($outputDir);
my $entity = $parser->parse_open("$outputDir/content.tmp");

# Extract sender and recipient(s)
my $headers = $entity->head;
my $from = $headers->get('From');
my $to = $headers->get('To');
my $subject = $headers->get('Subject');
chomp($from);
chomp($subject);

syslogOutput("Processing mail from: $from ($subject)");

processMIMEParts($entity);
deliverMail($entity);
remove_tree($outputDir) or syslogOuput("Cannot delete \"$outputDir\": $!");

exit 0;

sub processMIMEParts
{
  my $entity = shift || return;
  for my $part ($entity->parts) {
    if($part->mime_type eq 'multipart/alternative' ||
       $part->mime_type eq 'multipart/related' ||
       $part->mime_type eq 'multipart/mixed' ||
       $part->mime_type eq 'multipart/signed' ||
       $part->mime_type eq 'multipart/report' ||
       $part->mime_type eq 'message/rfc822' ) {
         # Recursively process the message
         processMIMEParts($part);
     } else {
       if( $part->mime_type eq 'application/pdf' ) {
         my $type = lc  $part->mime_type;
         my $bh = $part->bodyhandle;
         syslogOutput("OCR for: \"" . $bh->{MB_Path} . "\" (" . $type . ") to \"" . $bh->{MB_Path} . ".ocr.pdf" . "\"" );
         # Perform the OCR scan, output to a new file
         system($ocrmypdf, $bh->{MB_Path}, $bh->{MB_Path} . ".ocr.pdf");
         # Add the new file as attachment
         $entity->attach(Path   => $bh->{MB_Path} . ".ocr.pdf",
                         Type   => "application/pdf",
                         Encoding => "base64");
      }
     }
   }
   return;
}

#
# deliverMail - Send the mail back
#
sub deliverMail {
  my $entity = shift || return;

  # Write the changed entity to a temporary file
  if (! open(FH, '>', "$outputDir/outfile.tmp")) {
    syslogOutput("deliverMail: cannot write $outputDir/outfile.tmp: $!");
    exit EX_UNAVAILABLE;
  }
  $entity->print(\*FH);
  close(FH);

  # Read saved arguments
  if (! open(IN, "<$outputDir/args.tmp")) {
    syslogOutput("deliverMail: Cannot read $outputDir/args.tmp: $!");
    exit EX_TEMPFAIL;
  }
  my $sendmailArgs = ;
  close(IN);
	
  # Read mail content from temporary file of changed entity
  if (! open(IN, "<$outputDir/outfile.tmp")) {
    syslogOutput("deliverMail: Cannot read $outputDir/content.txt: $!");
    exit EX_UNAVAILABLE;
  }
	
  # Spawn a sendmail process
  syslogOutput("Spawn=$sendmailPath -G -i $sendmailArgs");
  if (! open(SENDMAIL, "|$sendmailPath -G -i $sendmailArgs")) {
    syslogOutput("deliverMail: Cannot spawn: $sendmailPath $sendmailArgs: $!");
    exit EX_TEMPFAIL;
  }
  while() {
    print SENDMAIL $_;
  }
  close(IN);
  close(SENDMAIL);
}

#
# Send Syslog message using the defined facility
#
sub syslogOutput {
  my $msg = shift or return(0);
  openlog($syslogProgram, 'pid', $syslogFacility);
  syslog('info', '%s', $msg);
  closelog();
}

Now we just do what Xavier’s CockooMX documentation also tells you to do: add it to master.cf:

Create a UNIX user: adduser ocrpdf

Change the smtp service:

smtp      inet  n       -       -       -       -       smtpd
-o content_filter=ocrpdf

Create a new service

ocrpdf  unix  -       n       n       -       -       pipe
user=ocrpdf argv=/usr/local/bin/ocrpdf.pl -f ${sender} ${recipient}

OCR for your old printer/scanner

Modern printers can do OCR on your scans. But as we talked about last time, aren’t all printers or scanners modern.

We have a scrap computer that is (already) catching all E-mails on a badly configured local SMTP server, to then forward it to a well configured SMTP server that has TLS. Now we also want to do OCR on the scanned PDFs.

My printer has a so called Network Scan function that scans to a SMB file share (that’s a Windows share). The scrap computer is configured to share /var/scan using Samba as ‘share’, of course. The printer is configured to use that share. Note that you might need in smb.conf this for very old printers:

client min protocol = LANMAN1
server min protocol = LANMAN1
client lanman auth = yes
client ntlmv2 auth = no
client plaintext auth = yes
ntlm auth = yes
security = share

And of course also something like this:

[scan]
path = /var/scan
writable = yes
browsable = yes
guest ok = yes
public = yes
create mask = 0777

First install software: apt-get install ocrmypdf inotify-tools screen bash

We need a script to perform OCR scan on a PDF. We’ll here use it in another script that monitors /var/scan for changes. Later in another post I’ll explain how to use it from Postfix’s master.cf on the attachments of an E-mail. Here is /usr/local/bin/fixpdf.sh:

! /bin/sh
a=$1
TMP=`mktemp -d -t XXXXX`
DIR=/var/scan
mkdir -p $DIR/ocr
cd $DIR
TIMESTAMP=`stat -c %Y "$a"`
ocrmypdf --force-ocr "$a" "$TMP/OCR-$a"
mv -f "$TMP/OCR-$a" "$DIR/ocr/$TIMESTAMP-$a"
chmod 777 "$DIR/ocr/$TIMESTAMP-$a"
cd /tmp
rm -rf $TMP

Note that I prepend the filename with a timestamp. That’s because my printer has no way to give the scanned files a good filename that I can use for my archiving purposes. You can of course do this different.

Now we want a script that monitors /var/scan and launches that fixpdf.sh script in the background each time a file is created.

My Xerox WorkCentre 7232 uses a directory called SCANFILE.LCK/ for its own file locking. When it is finished with a SCANFILE.PDF it deletes that LCK directory.

Being bad software developers the Xerox people didn’t use a POSIX rename for SCANFILE.PDF to do an atomic write operation at the end.

It looks like this:

inotifywait -r -m  /var/scan | 
while read file_path file_event file_name; do
echo ${file_path}${file_name} event: ${file_event}
done
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/XEROXSCAN003.LCK event: CREATE,ISDIR
/var/scan/XEROXSCAN003.LCK event: OPEN,ISDIR
/var/scan/XEROXSCAN003.LCK event: ACCESS,ISDIR
/var/scan/XEROXSCAN003.LCK event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/XEROXSCAN003.PDF event: CREATE
/var/scan/XEROXSCAN003.PDF event: OPEN
/var/scan/XEROXSCAN003.PDF event: MODIFY
/var/scan/XEROXSCAN003.PDF event: MODIFY
...
/var/scan/XEROXSCAN003.PDF event: MODIFY
/var/scan/XEROXSCAN003.PDF event: MODIFY
/var/scan/XEROXSCAN003.PDF event: CLOSE_WRITE,CLOSE
/var/scan/XEROXSCAN003.PDF event: ATTRIB
/var/scan/XEROXSCAN003.LCK event: OPEN,ISDIR
/var/scan/XEROXSCAN003.LCK/ event: OPEN,ISDIR
/var/scan/XEROXSCAN003.LCK event: ACCESS,ISDIR
/var/scan/XEROXSCAN003.LCK/ event: ACCESS,ISDIR
/var/scan/XEROXSCAN003.LCK event: ACCESS,ISDIR
/var/scan/XEROXSCAN003.LCK/ event: ACCESS,ISDIR
/var/scan/XEROXSCAN003.LCK event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/XEROXSCAN003.LCK/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/XEROXSCAN003.LCK/ event: DELETE_SELF
/var/scan/XEROXSCAN003.LCK event: DELETE,ISDIR

The printer deleting that SCANFILE.LCK/ directory is a good moment to start our OCR script (call it for example /usr/local/bin/monitorscan.sh):

! /bin/bash
inotifywait -r -m -e DELETE,ISDIR /var/scan |
while read file_path file_event file_name; do
if [ ${file_event} = "DELETE,ISDIR" ]; then
if [[ ${file_name} == *"LCK" ]]; then
suffix=".LCK"
filename=`echo ${file_name} | sed -e "s/$suffix$//"`.PDF
/usr/local/bin/fixpdf.sh $filename &
fi
fi
done

Give both scripts 755 permissions with chmod and now you just run screen /usr/local/bin/monitorscan.sh

When your printer was written by good software developers, it will do POSIX rename. That looks like this (yes, also when done over a SMB network share):

inotifywait -r -m  /var/scan | 
while read file_path file_event file_name; do
echo ${file_path}${file_name} event: ${file_event}
done
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/ event: OPEN,ISDIR
/var/scan/ event: ACCESS,ISDIR
/var/scan/ event: CLOSE_NOWRITE,CLOSE,ISDIR
/var/scan/.tmp123.GOODBRANDSCAN-123.PDF event: CREATE
/var/scan/.tmp123.GOODBRANDSCAN-123.PDF event: OPEN
/var/scan/.tmp123.GOODBRANDSCAN-123.PDF event: MODIFY
...
/var/scan/.tmp123.GOODBRANDSCAN-123.PDF event: MOVED_FROM
/var/scan/GOODBRANDSCAN-123.PDF event: MOVED_TO

That means that your parameters for inotifywait could be -r -m -e MOVED_TO and in ${file_name} you’ll have that GOODBRANDSCAN-123.PDF. This is of course better than Xerox’s way with their not invented here LCK things that probably also wouldn’t be necessary with a POSIX rename call.

I will document how to do this to the E-mail feature of the printer with Postfix later.

I first need a moment in my life where I actually need this hard enough that I will start figuring out how to extract certain attachment MIME parts from an E-mail with Posix’s master.cf. I guess I will have to look into CockooMX by Xavier Mertens for that. Update: that article is available now.

.

De dienstplicht opnieuw invoeren, voor iedereen

Dat vind ik een goed idee. Maar dan wel wanneer ook vrouwen moeten gaan.

Sterven voor je land is geen zwaar werk. Vrouwen zijn daar net zo geschikt voor als mannen. Het enige wat je moet doen is in een zelfgegraven put of in de loopgraven (die tegenwoordig door graafmachines, wat een luxe, voor je gemaakt zijn) rustig te wachten tot de artillerie van de tegenstander de benen en armen van je lijf kapotbombarderen. Gedurende dat spektakel zie je meestal eerst een aantal keer hetzelfde gebeuren bij je vriendinnen in het putteke een beetje verderop.

Tijdens dat wachten heb je diarree en ben je daardoor constant uitgedroogd, komen de ratten aan je tenen knauwen, worden je strijdende vriendinnen geweldadig zot (want ze hebben hun vriendinnen aan gort geschoten zien worden), is er de hele nacht constant bombardement waarbij iedere knal een knal op jouw putteke had kunnen zijn, zie je mensen levend verbrand worden door fosfor-regen en krijg je continu idiote opdrachten van de leidinggevende commandanten (die, trouwens, vrouwen kunnen zijn: geen probleem he, dat kan ook. Dat kan ook).

Dat gaat van een zomer of lente-situatie uit. Want in de winter is het ook nog eens negatief een paar graden gedurende de hele nacht dat jij daar zit. Teminste als je hier bij ons gestationeerd bent, en niet dichter bij Rusland. Waar het min 20 en min 30 is en je gewoonweg doodvriest. Terwijl de ratten aan je tenen knauwen en je diarree hebt. Just in case you forgot about that.

Om op dat moment getrained te worden is iets dat geheel ‘equal’ hoort te zijn. Zoals de toiletten moeten we unisex-loopgraven hebben. Zoals de huidige generatie het wil moeten we dus ook unisex-legerdienst hebben.

Ik ben helemaal voorstander. Zolang de vrouwtjes ook moeten gaan. We moeten allemaal ons steentje bijdragen. Niet waar?

Wrong SMTP config so that your old scanner/printer can send mails

This is a warning: only do this at home, instead of don’t do this at home. On your local home network that is behind a firewall and/or gateway.

Edit: Philip Paeps sent me a few suggestions to restrict things even more. I have adapted this blog item to mention all of them.

Unfortunately there are companies that make and made printers and then don’t provide firmware upgrades for it.

You end up with a scanner/printer that works perfectly fine. Except you can’t find any SMTP servers without TLS anymore. Because rightfully so has more or less every E-mail provider turned off plain text SMTP.

Now your printer cannot send the scanned documents over E-mail anymore. Firmware upgrade of your scanner/printer? What if there is none?

What to do? Run a unencrypted postfix smtpd on some scrap computer on your local network, that relays your mails with its smtp client to a TLS enabled SMTP server.

apt-get install postfix # and select Internet site

I didn’t want fake security by having authentication on the smtpd side, as there will be no encryption between printer and our local postfix. When somebody listens on your local network they would not only have the PDFs that you scanned with your scanner/printer, they will also have those authentication tokens.

I suppose you can add authentication, but then at least don’t be silly and use usernames and passwords that you use somewhere else. Note that some really old scanners/printers also can’t do SMTP with authentication.

I used these relay_restrictions for smtpd. We will place the printer’s IP address in/within mynetworks, so we will relay for it through permit_mynetworks.

smtpd_relay_restrictions = permit_mynetworks reject_unauth_destination

The mydestination should be as restricted as possible so we’ll just empty it (no local delivery at all):

mydestination =
local_recipient_maps =
local_transport = error:local delivery is disabled

You can now also remove the local delivery agent from master.cf if you want. We restrict the mynetworks of course too. The scanner/printer is with DHCP on 192.168.0.0/24, so add that:

mydestination =
mynetworks = 127.0.0.0/8 192.168.0.0/24

Even better is to have your scanner/printer on a fixed IP address and then use that one IP address:

mynetworks = 127.0.0.0/8 192.168.0.11

In fact, when the scrap computer has a fixed IP address then you can further restrict things by using inet_interfaces of course:

inet_interfaces = 192.168.0.14, 127.0.0.1

And now we configure the relayhost, we will relay to our TLS enabled SMTP(s) server:

relayhost = [smtps.server.org]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
header_size_limit = 4096000
message_size_limit = 524288000

Now make a file /etc/postfix/sasl_passwd to add the username / password. After that of course run postmap /etc/postfix/sasl_passwd

[smtps.server.org]:587 username:password

We now on the printer configure the scrap computer’s local network IP address or DHCP hostname as SMTP server.

Other security considerations that are possible is to place printer and scrap computer on a VLAN or let there be a crossed UTP cable between them. But if you are going to do those things then you also know how to do it yourself. Such things do make sense: your easily hackable LED lamps and even more easily hackable Smart TV don’t need to talk to your printer nor this scrap computer. VLAN everything!

Aankondigingspolitiek en dan daarna

Na meer dan een half jaar geshockeerd toe te kijken hoe onze Europese leiders de éne na de andere aankondigingspolitiek deden zonder wat dan ook substantiëels te doen, lijkt de politieke klasse in de Europese wijk in Brussel eindelijk te zijn wakker geschoten.

Dat Rusland tegensancties zou doen nadat wij letterlijk hun nationale reserves afnamen, was verdomd voorspelbaar en kei hard al vanaf half februari een gegeven dat zeker was.

Dat het Russisch gas uiteindelijk zou afgesloten worden was klaar en duidelijk. Hoeveel gas het was was klaar en duidelijk. Dat de godganse Europese economie dan op haar gat zou gaan, was klaar en duidelijk.

We vinden het allemaal heel erg prettig om nu een beetje met Duitsland te staan lachen. Maar heel erg binnenkort zal jouw baan, die afhankelijk is van de Duitse industrie (denk er maar eens twee keer over na), verdwijnen. Het zal gedaan zijn met lachen terwijl je gigantisch hoge energiefacturen mag betalen.

Allemaal klaar en duidelijk. Crystal helder.

Maar wat deden de jongens en meisjes in de Europese wijk te Brussel daar aan? Helemaal niets.

Aankondigingspolitiek. Populistisch zijn. Dissidenten verketteren: was je tegen sancties, dan was je voor Putin. Alsof dit enkel Putin is en niet de gehele elite in Het Kremlin. Enkelen werden zelfs afgedreigd. Ja toch wel ja. WIJ zijn aan het afglijden naar fascisme en censuur. Heel erg duidelijk.

Maar als je je economie in oorlog zet tegen Rusland, dan hoor je ook voorbereid te zijn. Dat zijn en dat waren wij niet. Totaal niet.

De populistische aankondigingspolitiek van het afgelopen jaar zal er voor zorgen dat onze Europese economie gewoon de grond ingeboord zal worden.

We hadden intelligente sancties kunnen bedenken. Maar dat was niet straf genoeg. We hadden kunnen gaan onderhandelen met Rusland. Maar dan werd je verketterd.

Of is dat niet waar? Zie dan naar Macron die probeerde en telkens door de roeptoeters verketterd werd.

Maar zie hoe Erdogan het wel doet en daarmee zijn Turkije helemaal op de kaart heeft gezet. Hoe de hele West-Europese wereld in het conflict van Oekraïne er letterlijk gewoon niet toe doet. Maar Turkije helemaal wel.

Onze Westerse leiders zijn een bende populistische Twitter-accounts maar dan zonder eigen leger. Ze zijn dus niets. Niets dat er toe doet.

Wij hebben géén strategie. Dat zijn wij helemaal verleerd. We schipperen rond op populisme en het om ter hardst roepen. Ik bedoel, tweeten.

En dat, dat werkt niet in oorlogstijden.

Belgian blue stone with white stains.

Here’s a scenario: ten years ago, you renovated your bathroom. As a shower, you chose a walk-in shower with a Belgian blue stone which is porous and is a limestone.

That’s why you have to be careful with products like Antikal. Because they will react with the lime in your limestone. In other words, you have to rinse away the excess Antikal quickly.

But you’re a computer geek and because you have a piece of software that you programmed and are already thinking about, you sometimes forget this.

Thus, a drop of Antikal remains on your blue stone.

A few hours later, that drop became a white stain. Which now really seems to be inside your stone.

Unfortunately, it really is. No matter what you try, it cannot be scrubbed off. Unless you let a professional come and polish a layer off of your stone (which costs about 800 euros, by the way).

Unfortunately, not much later the stains come back. Because the stains are deep in your stone and the reaction ‘continues’. That was 800 euros for a few weeks’ peace of mind.

Now what?

Of course you buy a whole gang of HG products such as HG blauwesteen reiniger, HG grafsteenreiniger and HG natuursteen kleurvlekkenverwijderaar.

You spray it on, let it soak in for half an hour; a little of the stains are now indeed better. But not really.

What actually worked better was the Mr. Proper Magic sponge. That sanded the top layer of that white stain away a bit.

But what worked best after that was a coat of Moeller Stone Care HMK P333 Hardsteenolie.

Your Belgian Blue stone will become a Belgian dark blue stone. But the stains (which I had first rubbed out with the Mr. Proper Magic sponge) are less visible and seem to belong to the stone’s natural life.

Then, after two full days letting the stuff get impregnated, a sticky top layer appeared. I had probably used a little too much of that stuff.

But another heavy treatment with the whole gang of HG products, such as HG blauwesteen reiniger, HG grafsteenreiniger and HG natuursteen kleurvlekkenverwijderaar (all at the same time and soak for half an hour) followed by rubbing hard with an iron sponge, and the sticky top layer is gone.

The stone is actually quite beautiful now. Dark blue.

De helaasheid der dingen

Zoals altijd zijn we als EU of Europa achtergesteld omdat we geen enkel militair antwoord hebben op de zaken die geostrategisch gaande zijn.

Voor Ukraine kunnen we weinig tot niets doen omdat we geen enkel antwoord hebben op de vraag ‘vanwaar komt het gas dan wel?’

Deze vraag is te belachelijk simpel en toch kan geen enkel EU politicus ze beantwoorden.

Nochtans was het antwoord hierop haalbaar: men had werk kunnen maken van alternatieve energiebronnen. Maar dat vonden de heren en dames EU-politici niet nodig. Overbodig. En zo verder.

M.a.w. zijn ze volstrekt incompetent. Ik schrijf ze effectief volledig af. Want ze hadden daar wel een antwoord op moeten kunnen formuleren. De idioten die er nu nog zitten kunnen dat niet. Daarom zijn het losers en daarom horen we ze te ontslaan uit hun functie. Helaas zijn het ook populisten en daarom zal hun ontslag vele jaren duren (zie Brexit).

Richting Taiwan doen de EU politici alweer hun belachelijke best om wat dan ook te betekenen. Maar iets betekenen doen ze helemaal niet. Ze doen niets dat er toe doet.

Omdat ze collectief besloten hebben geen EU-leger te hebben.

Daarom zijn ze onbelangrijk. Insignificant. Incompetent. Onbelangrijk.

We moeten

Een eigen Europees leger starten. Waarbij ieder Europees land haar eigen expertise in de groep werpt.

Afspraken maken met Rusland over de energievoorziening van Europa.

Een nieuw veiligheidspakt met Rusland maken opdat er zo weinig mogelijk conflicten in Europa zullen zijn.

Machtsprojectie doen vanuit Europa, met het Europees leger. We moeten opnieuw leren wat het is om aan geostrategie te doen. We moeten dat Europees leger durven inzetten om onze strategische doelen te behalen. We moeten niet verlegen zijn om de wereld duidelijk te maken dat wij zulke strategische doelen hebben.

Het conflict in Oekraïne beïndigen. Want het dient ons (Europeanen) en Russen niet. We zijn beiden benadeeld door dit conflict. We hebben er beiden baad bij om dit te beïndigen.

Durven praten over Europa en niet enkel over de Europese Unie.

Kosovo in de EU

De bedoeling van Finland en Zweden die lid worden van het huidige NATO mag niet zijn dat we meer NATO krijgen. Maar wel dat we een groter EU leger verkrijgen.

Alleen een goed EU leger zal in de toekomst een buurland zoals Rusland koest en kalm houden. De NATO zal dat niet doen. In tegendeel, het zal Rusland onrustig maken. Want dat speelt in NATO’s kaarten: een grootschalig conflict op het grondgebied van de EU met Rusland is in het grootste belang van de NATO om te blijven bestaan als organisatie.

M.a.w. moeten wij Europeanen heel erg veel investeren in onze eigen defensie. We moeten dit niet meer overlaten aan de VS. We moeten dit financieel én operationeel in eigen handel nemen.

We moeten bereid zijn en klaar staat om agressie van bijvoorbeeld Rusland te kunnen afslaan. Zelfs te bestraffen. Dat wil dus zeggen dat ook wij nucleaire wapens nodig hebben. In EU handen. Inzetbaar. Met een strategisch EU commando dat het middel ook effectief kan en vooral zal inzetten in geval van bepaalde scenarios.

Maar vooral moeten we investeren in diplomatie en realisme, realpolitik, met Rusland. Aan de hand van hun bezorgdheden, en die van ons.

Oekraïne was een bufferstaat. Dat werkte goed. Ik zou graag willen dat het dat zou blijven en zou zijn. Terwijl het graan produceert. Terwijl het groeit. Terwijl het eventueel over een paar decennium onderdeel van de EU wordt.

Maar zouden we niet eerst de Balkan eens eindelijk na zo’n godverdomme 20 jaar lid maken van de EU?! Kosovaren bijvoorbeeld kunnen nog steeds niet zonder reis visum naar de EU komen. Hoewel we daar de grootste NAVO-basis van West-Europa hebben (KFOR) staan. We praten hier nu over Oekraïne dat morgen lid van de EU zou kunnen worden. Terwijl de gehele Balkan-regio na haar oorlogen van de jaren negentig nog steeds, in 2022, niet geïntegreerd is.

Going around media bans

For the people who want to know how to get around the ongoing media bans:

Do a Google search and type in ‘free ssh country‘. Use as ‘country‘ the country where the media is that you want to reach. Take the first hit. Create the SSH tunnel account that is freely available.

In a console (if you don’t have SSH, you can install it with for example Git Bash, Cygwin, etc on Windows. You can also use Putty of course – make a SOCKS tunnel). Note that the username and hostname will be different (the website will tell you).

ssh -D 1337 -q -C -N user-vpnthathost.com@countryNr.thathost.com

For Firefox: Settings->Network Settings [Settings]->Manual Proxy configuration. Type next to SOCKS Host: localhost, and next to Port: 1337. Next check ‘Proxy DNS when using SOCKS v5’. You have equivalent settings in Chrome and Chromium among other browsers.

There are many options as VPN service. You can also search with Tor-browser if you think the secret services want to kill you or something. It’s not very likely, though. But if you are paranoid, then I guess sure.

Tor-browser itself might by the way also work just fine.

How to make a movie from the history of wikipedia images

Install some software

apt-get install imagej wget imagemagick bash

Get a JSON with all the versions of a image on Wikipedia

Let’s assume you want to watch how the invasion in Ukraine took place. That’s this one:

https://en.wikipedia.org/w/api.php?action=query&titles=File%3A2022_Russian_invasion_of_Ukraine.svg&prop=imageinfo&iilimit=999&iiprop=%7Curl&format=json

We only need the URL, so iiprop=|url. If you need the timestamp (when was the image file made) then use iiprop=|url|timestamp. A list of them you can find here.

You can use wget or in your browser just do save file as (use RAW data at the top then, for example in Firefox).

Fetch the images

#! /bin/bash

mkdir svg
cd svg
ITEMS=`cat api-result.json | jq '.query.pages."-1".imageinfo | .[] | .url'`
for a in $ITEMS
do
wget "$a"
sleep 1
done

Convert them to PNGs:

Normally they are already in the right order. So no renaming should be needed. Else you have to add to the iiprop of the query ‘timestamp’ and then with jg you extract that from the JSON to for example add it somehow to the filenames.

Or just use touch to change the file’s last modification date after wget fetched it and then here you use UNIX find to loop in the right order, and write PNG files like 0001.png, 0002.png, etc.

#! /bin/bash
cd ..
mkdir png
for a in svg/*
do
# You can come up with a better translation for the filename
b=`echo $a | sed s/svg//g`
convert -density 250 -size 1546x1038 $a png/$b.png
done

Convert PNGs to a movie

  • Start imagej
  • File > Import > Image Sequence
  • Select the png directory where the images where converted to
  • File -> Save As -> AVI -> fill in 2 frames per second -> movie.avi

Convert into fake-news, propaganda, etc

  • Use another software to insert dramatic background music
  • Upload to youtube for fame and fortune or whatever
  • Buy likes, become a hipster, convert from hipster to influencer

Nobody moves, nobody gets hurt

Maar toch. Start dat EU-leger nu maar.

Het volgende conflict, in Oekraïne, staat voor de deur. De West-Europese landen gaan zich weer volstrekt belachelijk maken, en hebben zich reeds volstrekt belachelijk gemaakt.

Het is tijd dat we stoppen met de schoothond van de VS en NAVO te zijn, en dat we als de EU een eigen leger hebben dat deel uit maakt van NAVO en dat op termijn de noodzaak van het bestaan van NAVO opheft.

Jeff Hoeyberghs liet een scheet

Het land in crisis: alle hoofdredacteuren van het land schrijven opiniestukken! Duizenden vrouwen gingen naar de rechtbank.

Meanwhile: Op 31 maart 2020 werd België in de zaak Jeanty door het Europees Mensenrechtenhof veroordeeld voor de inhumane behandeling van een gedetineerde met psychische problemen. Artikel 3 EVRM wordt geschonden geacht omdat de man in voorlopige hechtenis niet de vereiste medische zorg had verkregen (link).

Nobody cares.

Ik verwijs naar een blog-post van me uit 2008: Moral indulgence.

Improving Qt

We are a few years further. A few years in which we all tried to make a difference.

I’m incredibly proud of my achievement of QTBUG-61928. At the time I thought I could never convince the Qt development team of changing their APIs. They did and today in Qt6 it’s all very much part of the package.

I want to thank Thiago and others. But I also think it’s a team effort. It might not be because of just me. But I still feel a little bit proud of having pushed this team just enough to make the changes.

I am now at a new Qt bug report. This time it’s about int64_t. I think that QModelIndex should be completely supporting it. Again, I think a lot. And I have a lot of opinions. But I anyway filed QTBUG-99312 for this.

Laster en eerroof naar correctionele

Ik vind dat het verhuizen van welke rechtbank laster een eerroof behandelt naar de correctionele rechtbanken te laten gaan, een goede zaak is.

Ik begrijp het, dat het feit dat, assisen de rechtbank was die hierover ging, als een soort van buffer speelde om de vrijheid van meningsuiting te vrijwaren. De comma’s staan er omdat het momenten om over na te denken zijn.

Maar dat is en was eigenlijk een misbruik van een soort van overheidsincompentie (of eigenlijk rechtbankenincompetentie). Namelijk dat er bij Assisen te weinig capaciteit was om dit soort misdaden te beoordelen en wanneer (en slechts enkel wanneer) het over de schreef ging, te veroordelen.

In de praktijk betekende het dat eigenlijk bijna alles kon. Terwijl dat nu geen goed idee meer is. Niet alles kan. Je vrijheid om bv. een leugen te spreken is begrenst daar waar die vrijheid schade berokkent. En dat is zo zelfs wanneer wat jij zegt geen leugen is, en voornamelijk wanneer dat wat gezegd wordt geen maatschappelijke meerwaarde heeft.

Het is dus aan een rechter om je dan te stoppen. Wij leven hier in België onder het Belgische recht. Niet onder jouw absolute vrijheid. Want onze geringe vrijheid is afhankelijk van ons Belgische recht. M.a.w. is, hoe controversieel ook (en laat ik duidelijk zijn dat ik duidelijk weet dat het controversieel is), jouw ingebeelde recht om een ander te schaden, niet altijd gelijk aan jouw recht om het ook te uiten. Niet hier in België. Niet altijd. Bijna altijd wel, maar niet altijd.

Context doet er toe (dus, de humor kan terecht zeer ver gaan). Maar niet altijd.

Ik ben wel erg bezorgd hierover. Maar dat maakt niet dat dit niet mag of kan behandeld worden. Het slaat stevig in op de verlichtingsfilosofie. Die zegt dat bijna alles moet kunnen gezegd worden. Maar om alles te kunnen zeggen moeten we ook, zeker met de opkomst van nieuwe media, akkoord gaan dat een overvloed van leugens ook de reputatie van eerbare mensen onherstelbaar zal schaden. Dus was de verlichting als filosofie soms naïef (hoewel ze stelde dat dit normaalgesproken zichelf corrigeert).

De grond van de vrije meningsuiting mogen we toch niet vergeten. Vind ik.

RE: Dat er geen gevaar is, lozh

Ik heb gelogen. In ieder geval ben ik een belofte niet nagekomen: ik beloofde een tiental blogpost die als ondertoon zouden hebben dat er geen gevaar is.

De enige twee die daar aan zouden kunnen voldoen waren mijn blog items over dat onze aarde een rechthoekige blok is en die waar ik oproep om te stoppen met NAVO.

Want nu dat onze aarde rechthoekig is, vallen we er aan onze kant toch al niet meer af. En ook wanneer we zouden stoppen met NAVO, dan vernietigen we onze rechthoekige blok ‘de aarde’ toch al niet meer met onze eigen nucleaire wapens!

Dus, moest de mensheid deze twee blog-items volgen en geloven, dan zou ongeveer 99,98% van alle gevaar voor de mensheid verdwijnen.

Maar de toekomst brengt een nieuwe belofte: Lozh en Vranyo. Want nu gaan we eindelijk eens die sociale media aanpakken. We hebben alvast Trump overal verbannen.

Vranyo!

Avast, Qt6 announcing new QPromise and QFuture APIs

Qt published its New_Features in Qt 6.0.

Some noteworthy items in their list:

  • QPromise allows setting values, progress and exceptions to QFuture
  • QFuture supports attaching continuations

I like to think I had my pirate-hook in it at least a little bit with QTBUG-61928.

I need to print this out and put it above my bed:

Thiago Macieira added a comment – 
You’re right
Philip Van Hoof added a comment – 
Damn, and I was worried the entire morning that I had been ranting again.
Thiago Macieira added a comment – 
oh, you were ranting. Doesn’t mean you’re wrong.

Thanks for prioritizing this Thiago.