Recent posts

Caution with string values in choice fields in Plone forms with z3c.form

I recently noticed a very strange behaviour while setting initial data for a choice field in a z3c.form. Suppose you have a simple, static vocabulary:

num_voc = SimpleVocabulary([SimpleTerm(value=1, token='1', title='one'),
                            SimpleTerm(value=2, token='2', title='two'),
                            SimpleTerm(value=3, token='3', title='three')])

Here you might skip token, as it is then created by str(<value>) automatically. We will use it in a form by the following schema

num = schema.Choice(title='number', vocabulary=num_voc)

The return value of the forms extractData method will return the value of the dictionary. For example, in a form buttons action method, the selected "two" in the form will result in the integer value 2:

data, errors = self.extractData()
assert data['num'] == 2    # correct

However, if you set the value in the updateWidgets method when the form is opened with a get request, you need to set the widget value to a list containing the token, which happens to be a string:

self.widgets['number'].value = ['2']

The reason is, that the selected attribute of the option in the widget is set by the expression term.token in self.value. While this is natural, as choice fields might support several selected items, it becomes a trap if you use string values. Consider the following example:

title_voc = SimpleVocabulary([SimpleTerm(value='Dr.', title='one'),
                              SimpleTerm(value='Prof.', title='two'),
                              SimpleTerm(value='Prof. Dr.', title='three')])

(Note that the tokens are equal to the values here. For non-ASCII values, value.encode('ascii', 'backslashreplace') is used as of zope.schema >= 4.6.0, i.e. Plone 5.2. But this is a different story and means to need to do the same when setting the value of the widget. Or better, just do not use string values at all.)

If you now miss to set the value as a list ['Prof. Dr.'] but use the string directly, i.e. self.widgets['number'].value = 'Prof. Dr.', you will find all the three options being selected without any error, as term.token in self.value is true for all three cases. Awkward!

Plone bei der Deutschen Physikalischen Gesellschaft

Zu meinem heutigen Vortrag auf der Plonetagung 2020 in Dresden hinterlege ich hier die Präsentation als PDF Datei. Im Vortrag wird das Tool prestio (github, pypi) vorgestellt, mit dem Daten aus Plone ins Dateisystem gedumpt und wieder geladen werden können.

Sorry Apple, too late

I would have brought the new Apple 16" machine for sure, if it would have been available last fall. But Apple just did not offer any reasonable laptop. For years. Until today. I was forced to replace my previous machine by the support end of El Capitan and no newer operating system being available on this old machine. (The situation might have been different, if I could have used Sierra or even High Sierra. Technically, this might have been possible as some hacks have shown, but Apple decided to not support this.)

I finally decided to end my 15 years of Mac user life and switched (back) to Linux for my laptop. Last September I brought a Lenovo X1 carbon 6th gen. right after they announced the support of the S3 sleep mode to improve Linux compatibility. (They added a Linux BIOS option for that, awesome.) I do not regret it. I am fully aware of my rather limited use-case. Linux is not at all a reasonable replacement for many situations. Still, it also has advantages. Furthermore I admit to having used Ubuntu 19.04 initially for better compatibility with the hardware compared to Debian 9. This, again, confirms the trouble to be taken into account. But since this summer I am happy with Debian 10. Apple has lost me, and it is not clear whether I will ever come back.

Akkuwechsel bei Tolino Vision 2

Nach knapp über 3 Jahren intensiver Nutzung hat sich der Akku des Tolino Vision 2 meiner Frau verabschiedet. Zwar heißt es ja landläufig, dass die Akkus bei E-Book-Readern ewig halten, was sicher stimmt, wenn da nicht die Hintergrundbeleuchtung wäre. Wenn man diese sehr viel nutzt, ist es dann doch nichts mit wochenlanger Haltbarkeit einer Akku-Ladung. Folglich läd man den Akku öfter auf und irgendwann verabschiedet er sich dann halt.

Beim Händler nachgefragt, bei dem das Gerät gekauft wurde (Thalia), wurde ich an den Hersteller Longshine Technologie GmbH verwiesen. Dort angefragt, wurde mir mitgeteilt, dass kein Garantieanspruch mehr besteht. Davon war ja auch überhaupt keine Rede, ich wollte den Akku getauscht haben. Die Anwort darauf (wörtlich): "Eine Reparatur oder Austausch des Akku ist leider nicht möglich."

Nun, das will ich dann doch noch sehen, bevor das Gerät auf dem Müll landet, und die Aussage entpuppt sich als komplette Lüge. Der Tolino lässt sich ganz einfach aufhebeln, dazu braucht es nichts weiter als z.B. ein stumpfes Messer. Und schon hat man den Akku vor Augen, mit der Typbezeichnung PR-285083. Der Akku ist mit doppelseitigem Klebeband eingeklebt und lässt sich gut (und rückstandslos) entfernen. Anhand der Typ-Bezeichnung lässt sich zudem Ersatz beschaffen (hab ich hier gemacht: https://www.akku.net/Akku-Info/1.64.BUN.999.4,Akku-f%C3%BCr-E-Book-Reader-Barnes-&-Noble-Typ-PR-285083.html). Man braucht nicht mal den Anschlussstecker umbauen, denn auch der passt abgesehen von zwei kleinen Nasen zusätzlich bei der Barnes&Noble-Version, die man in wenigen Sekunden abschleifen kann. Mit einem neuen Stück Klebeband fixiert und das Gehäuse wieder zugeklippst, funktioniert der Tolino wieder wie am ersten Tag. Aufwand: keine 5 Minuten.

Was mich an der ganzen Sache stört, ist, dass der Hersteller keinen Austausch des Akku selbst anbietet oder über einen Dienstleister realisiert. Wie kann das sein? Ein Akku ist ein Verschleißteil. Keine Reparaturmöglichkeit anzubieten, sollte glatt verboten werden. Jemand, der sich nicht selbst helfen kann, schmeißt womöglich am Ende ein ansonsten noch total brauchbares Gerät weg.

Nachweihnachtliche Bastelei: LiPo Akku für ein Carrera RC Auto

Carrera RC Autos sind ein großer Spaß und motivieren Kinder zum draußen spielen und auch weite Strecken laufen. Allerdings braucht es dafür eine gute Stromversorgung. Die Hersteller-Lösung ohne Einzelzellen-Überwachnung beim Laden und Entladen ist gerade bei LiPos fragwürdig, da die Zellen sehr empfindlich sind. Deshalb habe ich schon beim ersten Auto eine Umrüstung auf Modellbau-Akkus gemacht und nun ein zweites Mal wiederholt. Ich hatte eigentlich vor, das bei Amazon zu posten. Dort finden sich bei den Ersatzakkus schlechte Rezensionen und ich dachte, man könnte da ja mal einen Hinweis geben, wie es besser geht. Amazon lässt mich aber nicht. In einem Fall darf ich gar keine Rezension verfassen. In einem anderen Fall (die Akkus gibt es mit verschiedenen Kapazitäten) hab ich einen post hinterlassen, aber er erscheint im Moment nicht online. Vielleicht ändert sich das noch. edit: Mittlerweile ist es auch bei Amazon online.

Bei der Umrüstung auf Modellbau-Akkus mit Balancer-Anschluss, braucht man ein geeignetes Ladegerät, z.B. dieses hier. Ich selbst hatte schon ein anderes, größeres Ladegerät, aber das spielt ja keine entscheidende Rolle.

Leider muss man im Zuge dessen auch die proprietären Akku-Stecker/Kupplungen von Carrera tauschen, denn die gibt es nicht einzeln zu kaufen.

Und dann sollte man natürlich auch beim Entladen die Zellen überwachen. Dafür gibt preisgünstig kleine LiPo Überwacher (z.B. hier), die man in den geräumigen Modellautos unterbringen kann. Die geben ein akustisches Warnsignal, wenn die Spannung einer Zelle zu gering wird. Mit ein bisschen Bastelei kann man auch die Anzeige hinter einem transparenten Plastik "nach draußen führen". Und für einen separaten Schalter zum Einschalten der Akku-Überwachung ist auch noch locker Platz. Nach so einer Umrüstung fährt ein Auto pro Akku mehrere Kilometer und über eine Stunde (natürlich abhängig von der Akku-Dimensionierung) ... vielfach getestet im "harten" Alltags-Einsatz schon seit Monaten.

Die Carrera-Autos selbst zeigen irgendwann auch Verschleiß-Erscheinungen und laden zum Instandsetzen ein, sind alles in allem aber erstaunlich robust.

MacBook Pro SE

At present I still work on a MacBook Pro 17" (early 2009), which I ordered at the day of the presentation at the MacWorld in January 2009. This is just the second Mac I own. My first Mac was a 17" Powerbook I brought in 2003. It is time for another update. Actually a new machine is due for several years already, but I struggle with the options available.

A recent visit at an Apple Store in Munich was disillusioning once again. Apple does not provide me with any upgrade I can comfort myself with. They have progressed in a direction I refuse to join. While making the machines thinner and thinner, Apple seems to have completely lost the vision for users needing a workhorse. I'm just joining the chorus: The keyboard with the new butterfly mechanism is crap. I tried it, I cannot work with it. Also I cannot make myself comfortable to the touch bar missing a proper escape key any vi user just needs to have. I'm also curious about the removal of the inverse T for the cursor keys which most manufacturers have agreed to.

In my opinion it is unquestionable for a machine labeled "pro" to allow for the hard drive being exchangeable. Soldering it to the mainboard is just irrational. Currently I have a 500GB SSD and a 750 GB HD in my machine (having removed the CD drive years ago). I exchanged and upgraded my drives multiple times already, once due to a HD crash I had a few years ago. I survive it with ease as I just went to a store, brought a new drive and restored from a time machine backup. All done within a few hours. This was just perfect and as it should be.

One more thing while I'm grumbling anyway: I'm very angry about the missing matte screen option which got lost years ago already. Still, and given the fact, that most of the time I work on an external display, I could arrange myself following the spirit of the time in all that (even the hard drive). Except for the keyboard.

I'm already close to switch to a Thinkpad but I still hope for the better: A MacBook Pro SE. While the hardware of my present machine is already discontinued, I can only hope that it won't break in the near future, before the last macOS 10.11 supported on this machine becomes unmaintained as well. Maybe, hopefully, Apple will release a MacBook Pro SE along with the Mac Pro already announced for 2018. Hope dies last.

Doppelmord Babenhausen

Auf meinem Server liegt seit kurzem das Urteil zum "Doppelmord Babenhausen" (siehe http://www.doppelmord-babenhausen.de), in welchem Andreas Darsow zu lebenslanger Haft mit besonderer Schwere der Schuld verurteilt wurde. Aufgrund aktueller Berichterstattungen gibt es momentan viele Zugriffe darauf (aktuell knapp 4000 Zugriffe innerhalb von 24 Stunden). Ich kann in den log-files auch Zugriffe sehen, dass z.B. über die Suchfunktion auf dieser Seite nach dem Urteil gesucht wird. Das hat bis zum Veröffentlichen dieses Blog-Eintrags nicht funktioniert, da das Urteil von dieser Seite aus bisher nicht verlinkt war. Vielleicht wundern sich also einige Besucher, warum dieses Urteil überhaupt unter der Domain http://www.wobsta.de abrufbar ist und ob das alles mit rechten Dingen zugeht. Ich kann Sie beruhigen. Es ist alles in Ordnung und so gewollt, denn des Rätsels Lösung ist ganz einfach. Ich bin kürzlich von einer guten Bekannten kontaktiert worden mit der Bitte um Hilfe bei der Veröffentlichung des Urteils. Aufgrund der aktuellen Berichterstattung sollte das Urteil schnellsten online gestellt werden und ich habe bei der Erstellung der Datei sowie eben auch mit Speicherplatz ausgeholfen, da es technische Schwierigkeiten bei der online-Stellung dieses großen Dokuments auf der Webseite zum "Doppelmord Babenhausen" gab.

Designerware?! – und deren Folgen

Tja, was ist Designerware? Die Standardausstattung im Sanitärbereich durch einen etablierten Bauträger hätte ich hier eher nicht vermutet, aber das ist eben wohl auch eine Frage des Standpunktes. Wenn man jedenfalls in eben diesem Fall Amaturen vorfindet, deren Perlatoren im nächsten Baumarkt komplett unbekannt sind, bin ich schon geneigt, von Designerware zu sprechen. Vor allem, wenn bei diesen Amaturen ein Design-Feature als unpraktisch im Alltag angesehen werden muss.

Was ist nun also mit den Perlatoren? Nun, diese verkalken. Und je nach Wasser bei uns nun mal eher stärker. Gut, muss man sie halt reinigen und ggf. mal Neue einsetzen. Nur wie, wenn normales Werkzeug dazu nicht taugt? Die installierten Perlatoren haben auch noch das Problem, dass sie bündig mit dem Hahn abschließen und sehr dazu geneigen, dass immer Wasser am Hahn lang läuft, mit entsprechend ständig neuen Kalkablagerungen. Am liebsten wären mir hier doch Perlatoren, die ein klein bisschen aus dem Hahn herausstehen, damit ein letzter Tropfen am Perlator hängen bleibt und nicht am Hahn langläuft. Also, Ziel ist klar, als nächstes mal im Baumarkt fragen. Leider sind die Perlatoren und das Problem anhand der Beschreibung unbekannt. Also anderntags ein zweiter Versuch: mit Foto auf dem Handy und (automatisch) bei einem anderen Kundenberater. Aber das hat nichts geholfen. Ich hab dann die Standard-Variante (M24 mit Außengewinde) mitgenommen und als nächstes daheim den Perlator mit Gewalt entfernt (und dabei natürlich komplett kaputt gemacht). Die Standard-Perlatoren passen leider nicht, aber auf dem entfernten Perlator findet sich Neoperl JR als Bezeichnung. Als nächstes sucht man im Netz und findet dann natürlich Informationen. Und leider musste ich dabei lernen, dass man keine Alternative hat, als wieder solche unsinnigen Perlatoren einzusetzen und dafür ein heiden Geld auszugeben. Außer man tauscht gleich die komplette Amatur. Super! Und bei der Gelegenheit hab ich zumindest gelernt, dass ich bin nicht der Einzige, der sich tierisch darüber aufregt: http://www.amazon.de/product-reviews/B004PQ22II.

Teutonia – nicht noch mal

Die Überschrift könnte man positiv verstehen: Teutonia – nicht noch mal. Wozu auch? Man kauft im günstigsten Fall ein Mal im Leben einen Kinderwagen. Das erfüllt Teutonia, auch wenn man den Kinderwagen beim zweiten Kind noch mal hernimmt. Gut, die Luftkammerräder, die wir haben, zeigen deutliche Verschleißerscheinungen. Man könnte da gut mal in einen neuen Satz Reifen investieren. Aber beim Gestell und allem Anderen hat man nicht das Gefühl, dass es den nächsten Winter nicht übersteht.

Trotzdem ist die Überschrift genau so negativ gemeint, wie sie klingt. Und zwar aufgrund meiner folgenden Erfahrung:

Der Kinderwagen-Aufsatz auf dem Gestell ist bei unserem Modell mit je einer Verriegelung auf jeder Seite versehen. Diese ist dummerweise so konstruiert, dass man die Arretierfunktion der Entriegelung bei Fehlbenutzung ziemlich leicht abbrechen kann (siehe Pfeil im Bild). Man könnte das sicher so konstruieren, dass in dem Fall was anderes passiert als dass diese Arretierung kaputt geht, aber sei es drum. Das Problem geht damit nämlich erst los. Wenn man das repariert haben will, geht man als nächstes zum Fachhändler, bei dem man den Wagen vor Ort gekauft hat und bittet um Hilfe. Ich hab selbst miterlebt, wie der Händler daraufhin mit Teutonia telefoniert hat. Ich hatte das defekte Teil zu dem Zeitpunkt schon selbst ausgebaut. Das Ergebnis des Telefonats war ziemlich ernüchternd. Solche Ersatzteile werden nicht zur Verfügung gestellt. Derartige Reparaturen werden nur von Teutonia selbst ausgeführt. Man müsse den Kinderwagen dazu einschicken. Mein Fachhändler bot mir an dieser Stelle einen kostenlosen Leihwagen an, aber ich fand das unsinnig, das defekte Teil wieder einzubauen, nur damit anschließend der komplette Kinderwagen einmal durch die Republik geschickt wird.

Natürlich kann Teutonia sich darauf berufen, dass das ein sicherheitsrelevantes Bauteil ist. Aber bei einem Puky-Rad kann ich auch jedes sicherheitsrelevante Bauteil nachkaufen und selbst wechseln. Das ist ein guter Service für mündige Kunden. Zumal das defekte Teil nach Lösen nur einer handvoll Schrauben zu erreichen und in wenigen Minuten ersetzbar ist. Wenn man denn so ein Ersatzteil hat, nur bei Teutonia stößt man mit dieser Bitte auf taube Ohren.

Zum Glück leben wir in einer Zeit, in der man sich so ein Ersatzteil halt notfalls individuell drucken lässt. Man muss sich das Ersatzbauteil leider erst umständlich im Rechner zeichnen. Aber es geht. Das Video zeigt das Ergebnis. Eigentlich schon cool, aber natürlich ein ganz schöner Aufwand, zu dem man hier genötigt wird.

Subversion and Trac setup with minimal privilege overlap

Over the years I developed (in discussion with a few colleagues and friends) a subversion and trac setup with a rather strong privilege separation. I've written it down for Debian wheezy, but it can be reproduced (with more or less effort) on other distributions as well. I once did it on SUSE, which was a nightmare, but this is more a judgment about the cleanness and flexibility of the distribution, not the setup described here. In addition some details will certainly need adjustments to new developments, but the basics are rather mature. Also, even when the focus of other setups vary, the whole concept is probably worth sharing. It also forced me to rewind my setup and write it down not in a bunch of snippets in a best practice folder on my machine (as I'm doing it all the time), but in a (still sparsely) documented blog post.

First of all, I will install trac from source as a regular user. As I frequently tweak details on the trac installation, I don't want to use the version that comes with the distribution. The important point here is, that trac will be installed neither as root nor as the user which runs the trac process in the end. On machines I'm managing myself (alone) I use my own user account for such installations, but you could use a specific software installation account. To make the installation process a little more universal, let us set an environment variable for this user (on a root shell we'll use in the course of this guide):

export SW=...

We install Apache, as it is still the solution of choice for serving subversion (webdav). We take subversion from the distribution as well as python and gunicorn (as a simple solution for serving trac):

apt-get install -y apache2 libapache2-svn python-virtualenv python-subversion python-dev gunicorn sudo

We don't want Apache to serve at Port 80, nor should it do anything else than subversion. As other use-cases of "specific" apache instances might come up, we disable the default configuration and setup an apache2-svn configuration. This apache instance will be run as a svn user to be created later on. The apache config is created by the following steps:

service apache2 stop
update-rc.d -f apache2 remove
echo -e '\necho "default apache disabled"\nexit' >> /etc/default/apache2
mkdir /etc/apache2-svn
cp /etc/apache2/{apache2.conf,magic} /etc/apache2-svn
sed -e 's/www-data/svn/' /etc/apache2/envvars > /etc/apache2-svn/envvars
echo "Listen 127.0.0.1:49443" > /etc/apache2-svn/ports.conf
ln -s /etc/apache2/{conf.d,mods-available} /etc/apache2-svn
mkdir /etc/apache2-svn/{mods-enabled,sites-available,sites-enabled}
APACHE_CONFDIR=/etc/apache2-svn a2enmod authz_host mime auth_basic authn_file authz_groupfile dav_fs authz_svn alias ssl
touch /etc/default/apache2-svn
sed 's/#.*apache2/&-svn/' /etc/init.d/apache2 > /etc/init.d/apache2-svn
chmod +x /etc/init.d/apache2-svn
mkdir /var/log/apache2-svn

As subversion uses more of http than simple get and post requests, it is rather hard to switch the scheme on a reverse proyx in front of the subversion server. Thus we create a private key, a signing request and self-sign it with our own private key:

openssl genrsa -out /etc/apache2-svn/server.key 2048
openssl req -new -batch -subj "/C=US/CN=localhost" -key /etc/apache2-svn/server.key -out /etc/apache2-svn/server.csr
openssl x509 -req -days 3650 -in /etc/apache2-svn/server.csr -signkey /etc/apache2-svn/server.key -out /etc/apache2-svn/server.crt

Now comes the apache configuration:

echo -e "ServerName svn\n"\
"ServerAdmin webmaster@$(hostname)\n"\
"DocumentRoot /var/www/\n"\
"CustomLog /var/log/apache2-svn/access.log combined\n"\
"SSLEngine On\n"\
"SSLCertificateFile /etc/apache2-svn/server.crt\n"\
"SSLCertificateKeyFile /etc/apache2-svn/server.key\n"\
"SSLSessionCache shmcb:/var/run/apache2-svn/ssl_scache(512000)\n"\
"SSLMutex file:/var/run/apache2-svn/ssl_mutex\n"\
"\n"\
"<Location /repos/>\n"\
"    DAV svn\n"\
"    SVNParentPath /var/lib/svn/repos\n"\
"    SVNListParentPath On\n"\
"    AuthzSVNAccessFile /etc/apache2-svn/authz\n"\
"    AuthType Basic\n"\
'    AuthName "svn repos"\n'\
"    AuthUserFile /etc/auth/htpasswd\n"\
"    Require valid-user\n"\
"</Location>\n"\
"\n"\
'RedirectMatch /repos$ /repos/' > /etc/apache2-svn/sites-available/default
APACHE_CONFDIR=/etc/apache2-svn a2ensite default

In this setup a subversion and trac user will be authenticated via a passwd file and the subversion access is configured in an authz file:

htpasswd -c /etc/$newuser/htpasswd user
echo -e "[groups]\n"\
"all=user\n"\
"\n"\
"[/]\n"\
"@all=rw" > /etc/apache2-svn/authz

Now we're all done regarding subversion except for the svn user itself:

adduser --system --home /var/lib/svn --group svn
sudo -u svn mkdir /var/lib/svn/{repos,backups,skel}
echo -e '#!/bin/bash\n'\
'/usr/bin/sudo -u trac /home/'$SW'/trac/bin/trac-admin /var/lib/trac/projects/NAME changeset added "$1" "$2" &&\n'\
'/usr/bin/svnadmin dump "$1" --revision "$2" --incremental|/bin/gzip > "/var/lib/svn/backups/NAME/dump.$(/usr/bin/printf %05d $2).gz"' > /var/lib/svn/skel/post-commit
echo -e '#!/bin/bash\n'\
'/usr/bin/sudo -u trac /home/'$SW'/trac/bin/trac-admin /var/lib/trac/projects/NAME changeset modified "$1" "$2" &&\n'\
'/usr/bin/svnadmin dump "$1" --revision "$2" --incremental|/bin/gzip > "/var/lib/svn/backups/NAME/dump.$(/usr/bin/printf %05d $2).gz"' > /var/lib/svn/skel/post-revprop-change
chown svn.svn /var/lib/svn/skel/*
chmod u+x /var/lib/svn/skel/*

Here we've included skeleton files for some hooks, which will create svn dump backups for each revision at checkin and inform trac about the changes in the repository. As trac will run as a separate trac user user, we need to add a sudoers rule:

echo "svn ALL=(trac)NOPASSWD:/home/wobsta/trac/bin/trac-admin /var/lib/trac/projects/* changeset added *,/home/wobsta/trac/bin/trac-admin /var/lib/trac/projects/* changeset modified *" > /etc/sudoers.d/trac
chmod 440 /etc/sudoers.d/trac

Ok, now let's install trac:

cd /tmp
sudo -u $SW virtualenv /home/$SW/trac
sudo -u $SW /home/$SW/trac/bin/pip install trac
sudo -u $SW mkdir /home/$SW/trac/wsgi
echo -e "#!/home/$SW/trac/bin/python\n"\
"\n"\
"import site, sys\n"\
"site.addsitedir('/home/$SW/trac/lib/python2.7/site-packages')\n"\
"from pkg_resources import working_set\n"\
"for path in sys.path:\n"\
"    working_set.add_entry(path)\n"\
"\n"\
"import os\n"\
"\n"\
"os.environ['PYTHON_EGG_CACHE'] = '/var/lib/trac/eggs'\n"\
"\n"\
"import trac.web.main\n"\
"def application(environ, start_response):\n"\
"    environ['SCRIPT_NAME'] = '/projects'\n"\
"    environ['REMOTE_USER'] = environ.get('HTTP_REMOTE_USER')\n"\
"    environ['trac.env_parent_dir'] = '/var/lib/trac/projects'\n"\
"    return trac.web.main.dispatch_request(environ, start_response)" | sudo -u $SW tee /home/$SW/trac/wsgi/projects.py > /dev/null

In the last step we've created a wsgi adapter. Due to the component architecture of trac adding the site-package path of the virtual env is not enough in this script, but package discovery requires a working_set modification as shown. In addition, we fix the SCRIPT_NAME environment variable and copy the HTTP_REMOTE_USER to the REMOTE_USER environment variable as required by trac. This setup enables us to use nginx as the front-end webserver in the end.

To complete the trac installation, we have to add the trac user to the system:

adduser --system --home /var/lib/trac --group trac
sudo -u trac mkdir /var/lib/trac/{projects,eggs}

Now we're left with starting apache2-svn and adding trac to the gunicorn configuration:

service apache2-svn start
update-rc.d apache2-svn defaults
service gunicorn stop
echo -e "CONFIG = {\n"\
"    'working_dir': '/home/$SW/trac/wsgi',\n"\
"    'environment': {\n"\
"    },\n"\
"    'user': 'trac',\n"\
"    'group': 'trac',\n"\
"    'args': (\n"\
"        '--bind=127.0.0.1:49080',\n"\
"        '--workers=3',\n"\
"        '--timeout=30',\n"\
"        'projects:application',\n"\
"    ),\n"\
"}" > /etc/gunicorn.d/trac
service gunicorn start

To create a new subversion repository and corresponding trac instance with a given name, execute:

export NAME=test
sudo -u svn svnadmin create /var/lib/svn/repos/$NAME
sudo -u svn mkdir /var/lib/svn/backups/$NAME
rm -r /var/lib/svn/repos/$NAME/hooks
cp -ra /var/lib/svn/skel /var/lib/svn/repos/$NAME/hooks
sed -i s/NAME/$NAME/ /var/lib/svn/repos/$NAME/hooks/*
sudo -u trac /home/$SW/trac/bin/trac-admin /var/lib/trac/projects/$NAME initenv

The reverse proxy configuration is straight forward and shown for as an nginx config snipped here

location /repos { proxy_pass https://127.0.0.1:49443; }

location /projects {
  rewrite ^/projects/(.*)$ /$1 break;
  proxy_pass http://127.0.0.1:49080;
}
location ~ ^/projects/[a-z]+/login {
  auth_basic "trac projects";
  auth_basic_user_file /etc/auth/htpasswd;
  proxy_set_header REMOTE_USER $remote_user;
  rewrite ^/projects/(.*)$ /$1 break;
  proxy_pass http://127.0.0.1:49080;
}

Thank's all, folks.

Netzteil Serienfehler Dell Monitor 2405FPW

Vor wenigen Tagen verabschiedete sich das Netzteil meines schon in die Jahre gekommenen, aber immer noch guten Dell Monitors 2405FPW beim Einschalten mit einem kleinen Knall. Während ich eigentlich ein Fan von integrierten Netzteilen bin, steht man in so einem Fall leider erstmal vor dem Problem, überhaupt an die Fehlerquelle ranzukommen. Zum Glück findet sich auf youtube ein Video, dass das Öffnen des Geräts zeigt.

Auf der Netzteil-Platine waren sofort zwei defekte Bauteile erkennbar: ein Widerstand und ein Kondensator. Leider ist in so einem Fall natürlich mit sehr hoher Wahrscheinlichkeit mehr kaputt, so dass ein Wechsel dieser zwei sichbar defekten Teile gar nichts bringen würde. Ein Kompletttausch des Netzteils wäre naheliegend, aber ich habe auf den ersten Anlauf keine Bezugsquelle gefunden, wo ein Ersatz lieferbar gewesen wäre. Die viel schwierigere Ersatzteilsituation ist natürlich noch mal ein klarer Nachteil von integrierten Netzteilen. Stattdessen stolperte ich aber über mehrere Berichte mit Defekten genau dieser Art. Unter anderem bietet ein Bastler namens Tom auf seiner Webseite einen Reparaturservice für die USA an. Ich habe mich an ihn per E-Mail gewandt mit der Frage, ob und zu welchen Konditionen denn eine Reparatur mit Versand von und nach Deutschland möglich wäre. Oder alternativ, was denn bei dem Defekt typischerweise kaputt geht, damit ich das evtl. doch selbst reparieren könnte.

Innerhalb weniger Stunden erhielt ich eine Antwort von Tom mit einer detaillierten Teileliste von Dingen, die typischerweise bei dem Defekt in Mitleidenschaft gezogen werden, und ein paar Reparaturhinweisen. Tom hat schon Dutzende dieser Defekte repariert und es seien nur ganz selten weitere Dinge betroffen (die er in seiner Teileliste aber auch benannt hat), so dass er mich ermuntert hat, es mit dem Wechsel dieser typischen Defekt-Teile zu probieren. Die Chancen wären sehr hoch, dass ich es damit wieder zum Laufen bekommen würde. Ich war begeistert!

Tom schlug vor, dass ich versuchen sollte, die Teile in Europa zu besorgen, da die Versandkosten eines Reparatur-Teile-Kits unklar sind und man evtl. ja auch noch Probleme mit dem Zoll bekommt. Er schlug mir stattdessen einen Distributor vor, und genau über den habe ich die Teile am Ende auch bekommen. Und was soll ich sagen: Es hat geklappt! Nach dem Tausch weiterer Teile, die typischerweise bei diesem Fehler kaputt gehen, funktioniert der Monitor wieder.

Ein ganz herzliches Dankeschön an dieser Stelle an Tom, ohne dessen Hilfe ich die Reparatur überhaupt gar nicht erst in Betracht gezogen hätte und niemals hätte durchführen können. Viele der Teile hätte ich weder identifizieren können, noch deren Funktion prüfen können. So weiss ich auch gar nicht, ob all die Teile, die ich gewechselt habe, tatsächlich kaputt sind. Aber das ist egal. Der finanzielle Aufwand für die Ersatzteile (ca. 20 Euro) ist auch bei diesem alten Monitor gering gegenüber dem Wert, den er noch hat.

Rundfunkgebühren für Computer in einem Heimbüro, Verhandlung und Entscheidung beim Bundesverwaltungsgericht

Heute war Verhandlung und Urteilsverkündung vor dem Bundesverwaltungsgericht hinsichtlich meiner Klage bezüglich Rundfunkgebühren für sogenannte neuartige Rundfunkempfangsgeräte. Das Bundesverwaltungsgericht hat die Berufung des Bayerischen Rundfunks zurückgewiesen und das bisherige Urteil bestätigt (Bericht zum bisherigen Rechtsweg und zugehörige Urteilstexte). Demnach muss ich für den Computer an meinem Heimarbeitsplatz keine zusätzlichen Rundfunkgebühren zahlen, nachdem ich bereits Rundfunkgebühren für privat genutzte Rundfunkempfangsgeräte innerhalb der selben Wohnung zahle. Die bisherige und äußerst fragwürdige Gebührenpraxis, nach der die Rundfunkanstalten für bestimmte Heimarbeitsplätze zusätzliche Rundfunkgebühren verlangen (beispielsweise bei Selbständigen), bei andere Heimarbeitsplätzen (beispielsweise von Lehrern) keine doppelte Gebührenpflicht besteht, ist im Gesetz nicht verankert. Folgerichtig wurde der Berufung des Bayerischen Rundfunks nicht stattgegeben.

Rundfunkgebühren für Computer in einem Heimbüro, zweite Instanz

Ich führe einen Rechtsstreit mit dem Bayerischen Rundfunk hinsichtlich der Zahlung von Rundfunkgebühren für sogenannte neuartige Rundfunkempfangsgeräte, zu dem ich aktuell das Urteil in zweiter Instanz erhalten habe. Aus diesem Anlass möchte ich mein Blog nun auch mal nutzen, darüber zu berichten.

Seit meinem Umzug zum 01.01.2008 befindet sich mein Bürozimmer, das ich im Rahmen einer selbständigen Tätigkeit besitze, innerhalb meiner Privatwohnung. Während ich in 2007, mit Einführung der Gebührenpflicht für neuartige Rundfunkempfangsgeräte Rundfunkgebühren für den Computer in meinem seinerzeit separat angemieteten Büro bezahlt habe, habe ich nach dem Umzug eine Klage gegen die Gebührenerhebung für mein nicht ausschließlich privat genutztes Rundfunkempfangsgerät angestrengt, da ich nunmehr in der selben Wohnung bereits Rundfunkgebühren für privat genutzte klassische Rundfunkempfangsgeräte bezahle.

In der ersten Instanz beim Verwaltungsgericht München wurde unter Aktenzeichen M 6b K 09.768 meiner Klage stattgegeben, indem die Rundfunkgebührenpflicht für neuartige Rundfunkempfangsgeräte insgesamt in Frage gestellt wurde (Urteil). Nach diesem Urteil hätte ich auch in 2007 für mein Büro keine Rundfunkgebühren zahlen müssen. Ich hatte auch tatsächlich bereits in 2007 überlegt, gegen die generelle Gebührenforderung für neuartige Rundfunkempfangsgeräte im nicht-privaten Bereich zu klagen, habe dann aber davon abgesehen. Und in der Tat wurde mittlerweile die grundsätzliche Gebührenpflicht für neuartige Rundfunkempfangsgeräte beim Bundesverwaltungsgericht bestätigt.

Der Bayerische Rundfunk hat in diesem Sinne auch ganz zu Recht Berufung gegen das erstinstanzliche Urteil eingelegt. Das Berufungsverwahren wurde beim Bayerischen Verwaltungsgerichtshof unter Aktenzeichen 7 BV 10.443 geführt (Urteil). Demnach besteht keine zweite Rundfunkgebührenpflicht für den Computer in meinem Büro. Eine Revision zum Bundesverwaltungsgericht ist zugelassen. Eine endgültige (und fallübergreifende) Bewertung dieser Situation ist leider auch nur auf diese Weise zu erreichen. Ich werde über den weiteren Fortgang im Verfahren in diesem Blog berichten.

Excel FollowHyperlink loads URL twice

I'm writing a web app which receives data from Excel 2010 on Windows 7 (64 bit). I'm using a small VBA macro for data upload and web page opening. However, when using ActiveWorkbook.FollowHyperlink in VBA the website is not opened by my default browser initially (Chrome in my example), but by some MS Office internal Internet Explorer instance. I'm redirecting from this first URL … and my real web browser is called on the redirected URL only. Got it? The header of the first access contains the following user agent:

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; ms-office)

The server response with a redirect and the other url is called by the same user agent. At the end this second url is opened with my default browser, which happens to be:

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3

Unfortunately this is not useful, as I'm setting a cookie at the first request (where the redirect occurs). I only found an ugly solution using ShellExecute (so far):

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

and then opening the website by:

ShellExecute 0, vbNullString, "http://...", vbNullString, vbNullString, vbNormalFocus

Others seem to have the same problem (http://groups.google.com/group/microsoft.public.excel.programming/browse_thread/thread/3191ab7cbebe38e8). But ShellExecute really should only be a last resort. Never mind, it's just Microsoft.

Py3k WSGI Test

I started a small project back in May where I was trying to use Python 3 for web development for the first time. While it somehow worked (with ugly hacks in the stdlib and being a memory hog), I finally decided it to be a failure. As I needed the project to get in production I switched back to Python 2 and everything worked out well. Still, I'm interested in web development on Python 3. Recently the author of the Python 3 enabled WSGI framework bottle started a new project multipart to fix the problems with cgi.FieldStorage. As the WSGI problems on Python 3 are under constant discussion I want to demonstrate the use of multipart in bottle even though multipart has not yet been integrated in bottle by the author. In my mind it can be used already (at least for development and test instances), it works well, and doesn't look ugly at all. So you are welcome to have a look at the source of my sample application and test the demo instance (edit: link to the demo instance removed, as it is not available anymore).

cgi multipart bugs in py3k

Recently I started to implement a small web app in py3k and wsgi. While none of the major python web frameworks are ready for py3k anytime soon and wsgi for py3k is still under major discussions (see for example this current post by Armin Ronacher), there are already options to actually start working on the subject.

I'm using bottle (dev tree) and the current releases of sqlalchemy, py-postgresql and jinja2 on Python 3.1.2. This actually works sort of. I will likely write some further posts about my progress. However, I quickly found a bug in the cgi multipart input handling, which actually turned out to arise from two different sources. I tried to solve it and just opened issue 8846 on the Python issue tracker showing my findings.

Lampenhalter kaputt → schlecht; unkomplizierte Hilfe der Fa. IBV Deutschland GmbH → eindeutig lobenswert

Ich hab in meiner Küche ein paar Mini-Lichtleisten installiert (um genau zu sein diese hier, gekauft bei OBI). Die sind jetzt ungefähr zweieinhalb Jahre alt. Vor einer Weile schon (schon mehr als ein Jahr her) hing eine der Lampen herunter, weil die Plastikhalter für die horizontale Befestigung abgebrochen waren. Wahrscheinlich beim Einschalten kaputt gedrückt, dachte ich mir. Mit ein paar zusätzlichen Plastikstücken und Zweikomponentenkleber ließ sich das ganz brauchbar reparieren. Nachdem die Befestigungshalter sowieso einen eher schwächlichen Eindruck machten, hab ich gleich alle Halter entsprechend verstärkt (die eingeklebten Verstärkungen kann man auf dem Foto deutlich sehen). Gut, hat erstmal geklappt.

Allerdings hing kürzlich eine andere Lampe herunter. Und dort waren die Halter direkt bei der Verschraubung an den Oberschränken gebrochen. Wie beim ersten Mal war meiner Frau und mir nicht bewusst, dass wir das beim Benutzen kaputt gedrückt haben könnten. Und beim Abschrauben bröselte mir das dann auch gleich noch in mehreren Stücken entgegen (siehe Foto). Hmmm. Eigentlich kann das ja nun wirklich nicht sein. Irgend ein Materialproblem, denke ich. Nun ja, also hab ich mal nach dem Hersteller gesucht und dort per E-Mail angefragt (zusammen mit dem Foto). Denn Wegschmeißen der völlig intakten Lampen fand ich nicht angemessen, zumal die Lampen ansonsten gut funktionieren und wir die Lampen gern und viel benutzen. Innerhalb nicht mal einer Stunde kam eine E-Mail-Antwort, dass ich kostenlos Ersatzhalter per Post geschickt bekomme, was dann auch prompt gestehen ist. Nachdem ich mich zunächst über das Problem mit den Haltern geärgert habe (und ich diese Halterung auch insgesamt für nicht so super stabil halte, aber es sind ja auch nur preiswerte Unterbauleuchten aus dem Baumarkt), finde ich das echt ein netten Zug vom Hersteller. Prima!

Alles neu macht der Mai

Nachdem meine alte Webseite jahrelang unverändert im Netz stand, nehme ich heute endlich mal eine radikale Aktualisierung online. Allerdings gibt es auf meiner eigentlichen Homepage auch nicht viel neue Inhalte und überhaupt brauche ich die Homepage auch nicht dringend, um Neuigkeiten hinsichtlich meiner Arbeit zu verbreiten. Andererseits war die alte Version in technischer Hinsicht her aus dem letzten Jahrtausend, so dass ich gar keinen Spaß hatte, darin überhaupt irgendwelche Zeit zu investieren. Was schon schade war, da ich gerade in letzter Zeit auch immer Mal über Themen gestolpert bin, bei denen ich eigentlich ganz froh gewesen wäre über eine Plattform, auf der man das auch mal dokumentieren kann. Ich denke da an meine Klage gegen den Bayerischen Rundfunk wegen doppelter Rundfunkgebühren (privat und als Selbständiger). Oder auch so ein paar nette Geschichten, die einem so als Verbraucher widerfahren. Und natürlich technische Spielereien und Tricks. Und für so etwas gibt es bekanntlich schon seit vielen Jahren Blogs.

Ich muss dazu sagen, dass ich vor einigen Jahren schon mal ein Blog angefangen hatte (nicht selbst gehostet, sondern bei einem großen Anbieter), das aber schnell eingeschlafen ist und das ich dann deshalb auch irgendwann wieder gelöscht hatte. Diesmal wird das sicher anders werden. Allein schon, weil ich eine ganze Menge Material in der Hinterhand habe und weil ich es in meinen Webauftritt integriere und selbst hoste.

Nun gut, genug der Vorrede. Dieses Blog hier wird sicher zweisprachig werden, weil technische gimmicks nunmal in Englisch disktuiert werden, andere Sachen aber nur auf Deutsch sinnvoll sind. Wer nur eine Sprache lesen will, kann ja die Kategorien deutsch und english nutzen.