Blinking Eva

Since it’s suddenly, out of nowhere, christmas time again, and since christmas is traditionally the time to build blinking somethings, i decided to publish this. Long ago – well, actually last year – this as a christmas present for my girlfriend Eva.

What does it do? Nothing useful. You plug it in, and the various LEDs blink wildly, one letter at a time, two letters at a time, all on, all off.

Posted in Electronics | Tagged , | Leave a comment

GPS Mouse in Python

Some months ago I aquired a cheap gps mouse (Royaltek RGM-2000, really cheap, 2 € + shipping) at ebay. My plans to use it in combination with an microcontroller and a display haven’t worked out, it is a lot of work and the garmin units do that job fine.
However, playing around with it in python lead to better results. Getting the data to google earth works nicely, and at least qlandkarte can read the generated gpx tracks.

Posted in Computers | Tagged , | 2 Comments


This device connects to a computer’s usb port and controls two small electric motors using the L293D. The atmega microcontroller uses the firmware-only USB driver from objective development.

Device description

The usbmot device controls up to two small motors, 600 mA current each, 1.2 A peak each, with an atmel atmega microcontroller connected to some host device via USB. The speed of the motors can be controlled with PWM.


Both firmware and host software are in the software package at the end of this page. In order to recompile the firmware, you will need an avr build chain (for example avr-gcc and avrdude), which you probably have if you found this page. To compile the host software, you will need a c++-compiler and the qt development package.

Posted in Electronics | Tagged , , | 13 Comments

kernel config based on lsmod output

Update (October 7th, 2011): Kernels from 2.6.32 onwards should have the option to “make localmodconfig” and “make localyesconfig”. This post describes a dirty hack to get a result similar to “make localyesconfig”. If possible, use the official way instead of my python script.

After reading about the amazing 5-seconds bootup I decided to once again compile a kernel myself. Compiling a kernel is almost trivial these days, but customizing the configuration can still be quite confusing. For example, the names of the modules in lsmod aren’t the ones you select as config options. To map them, I found some scripts in the LQWiki, but they weren’t that easily to use, and also programming in bash is just painful.

Posted in Computers | Tagged , , | 10 Comments

World of Overkill

Think about an ordinary man on an ordinary day. He drives to work using 1.5 tons of steel, with an engine strong enough to carry two cows to the slaughterhouse, does some work in some office, using some 3 GHz machine to answer some emails and print some forms. Later that day he goes home, where roughly 400 cubic meters of air and some more of wood and concrete are heated to comfortable 23 degrees Celsius, to provide a comfortable evening for 0.1 cubic meters of person.

Posted in Musings | Tagged | 1 Comment

Feeding a screensaver from the digikam database

After several months of living without any screensaver, I decided it just would be nice to once again have something nice to watch and show while idling. I really like the photo slideshow that ships with windows vista, but as my laptop runs linux only that was not possible. The next best thing i found was glslideshow from the xscreensaver compilation. Like most slideshow programs, glslideshow will look into a given directory, and show files out of it in random order. However, there are downsides to that simple approach: My photo folder contains some private pictures, and also some pictures that are just ugly. So i decided to connect it to my digikam database, which was surprisingly simple.

Posted in Computers, Photography | Tagged , , , | 6 Comments

KFile, a simple download-link generator for WordPress

After finally finding a nice CMS to use for my homepage, I was searching for a simple plugin that lets me

  • upload files manually using scp or other means from the command line
  • display a nice link to the file, stating name, size etc. after adding a text like [file=foo.tar.bz2]

All I found were quite large plugins using databases, using quite elaborate administration front ends. So I started writing one myself.


  • Install and activate the plugin.
  • Create a directory wordpressurl/download (alternatively, change the constant in kfile.php)
  • Upload files there
Posted in Internet | Tagged , | 2 Comments

Synchronizing Digikam and NGG

This little script automatically generates the gallery on this site from the local digikam(kde 3) database. To accomplish that task, it looks for files tagged public, and uploads them if they aren’t already uploaded. It completely rewrites the ngg database, so don’t use this if yo have put effort into creating a database with the ngg frontend.
Pictures are resized locally using imagemagick, so it avoids problems with low memory on some shared servers.

Script to export Photos from Digikam to NGG
Copyright (C) 2008  Andreas Goelzer

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <>.

This program exports pictures from your 
DigiKam ( database to a
NGG ( database.
It is at the moment highly experimental and in a works-for-me-right-now
Be really really careful if trying to use it, it will
- determine which photos are tagged "public"
- upload them to a dir, kill everything in the target dir not tagged public
- rewrite the remote database
- automatically create thumbnails along the way
I don't know much about databases, so this code is quite inefficient. It
doesn't pose a big problem for my ~5k local, 100 remote photos, though

Once again, it *will* erase the remote directory, and possibly more. 
see for updates.
import sqlite3;
import os;
import sys;
import re;

print "Calculating new remote DB"

con = sqlite3.connect("digikam3.db")
target = ""
targetdir = "subdir"	
openmysql = "mysql -h rdbms -u username --password=pw database"

def mymask(obj):
	if type(obj) in (str, unicode):
		return "\'" + obj.replace('"', '\\"').replace("'", "\\'").replace("\n","\\n") + "\'"
		return repr(obj)
def myrepr(obj):
	if type(obj) in (tuple, list):
		for elem in obj:
			str += mymask(elem) + ",";
		return "(" + str[:-1] + ")"
		return repr(obj)

def joinselect(con, query):
	return ",".join(list(myrepr(row) for row in con.execute(query)))
def remoteexec(cmd):
	os.system("ssh " + target + " \"" + cmd + "\"")

def copyremote(file,tsubdir):
	os.system("scp -p " + file + " " + target + ":" + re.escape(targetdir + tsubdir));

dbprefix = "wp_ngg_"
chooseidsstring = "(SELECT DISTINCT imageid FROM imagetags WHERE tagid = (SELECT id FROM tags WHERE name = \"public\"))"
sqlcommands  = "DELETE FROM " + dbprefix + "pic2tags;\n";
sqlcommands += "DELETE FROM " + dbprefix + "tags;\n";
sqlcommands += "DELETE FROM " + dbprefix + "pictures;\n";
sqlcommands += "DELETE FROM " + dbprefix + "gallery;\n";
sqlcommands += "DELETE FROM " + dbprefix + "album;\n";

sqlcommands += "INSERT INTO " + dbprefix + "pic2tags(picid,tagid) VALUES " + joinselect(con, "SELECT  imageid, tagid FROM imagetags  WHERE imageid IN  " + chooseidsstring) + ";\n"

sqlcommands += "INSERT INTO " + dbprefix + "tags(id, name, slug) VALUES " + joinselect(con, "SELECT  id,name,name FROM tags WHERE id IN (SELECT DISTINCT tagid FROM imagetags   WHERE imageid IN    " + chooseidsstring + ")") + ";\n"

sqlcommands += "INSERT INTO " + dbprefix + "pictures(pid, galleryid, filename, description) VALUES " + joinselect(con, "SELECT  id,dirid,name,caption FROM images   WHERE id IN "  + chooseidsstring ) + ";\n"

sqlcommands += "INSERT INTO " + dbprefix + "gallery(gid, name, path, title,previewpic) VALUES "

for row in con.execute("SELECT id,url,icon FROM albums WHERE id IN (SELECT DISTINCT dirid FROM images WHERE id IN " + chooseidsstring + ") ORDER BY url"):
	allalbums += "i:" + str(j) + ";i:" + str(row[0]) + ";"
	j += 1
	#if(row[2] == None): icon = "NULL"
	#check whether icon is public
	icon = str(row[2])
	if(row[2] == None or con.execute(chooseidsstring[1:-1] + " AND imageid = " + icon).fetchone() == None):
		nrow = con.execute("SELECT id FROM images WHERE id IN " + chooseidsstring + " AND dirid = " + str(row[0])).fetchone()
	sqlcommands += "(" + str(row[0]) + ", \"" + os.path.basename(row[1]) + "\" , \"photos" + row[1] + "\", \""+ os.path.basename(row[1]).replace("_"," ") + "\"," + icon + "),"	
sqlcommands = sqlcommands[:-1] + ";\n"
allalbums = "a:" + str(j) + ":{" + allalbums + "}"

sqlcommands += "INSERT INTO "+ dbprefix + "album(id, name, sortorder) VALUES (1, 'Main Gallery', '" + allalbums + "');\n"

#print s
f = open('remotedb.sql','w')

remoteexec(openmysql + '<' + targetdir + '/' + 'remotedb.sql')

print "creating remote directories"
#remotely create dirs
con2 = sqlite3.connect(":memory:")

con2.execute("CREATE TABLE remotedirs (file varchar(255), PRIMARY KEY (file))")
a = os.popen("ssh " + target + " find " + re.escape(targetdir) + " -type d").readlines();

for elem in a:
	if(elem != ''): con2.execute("INSERT INTO remotedirs VALUES (\"" + elem[len(targetdir):-1] + "\")");
con2.execute("CREATE TABLE localdirs (file varchar(255))")

for row in  con.execute("SELECT DISTINCT albums.url from images INNER JOIN albums ON images.dirid = WHERE IN " + chooseidsstring):
	for dirss in dirs[1:]:
		dire += "/" + dirss
		con2.execute("INSERT INTO localdirs VALUES (\"" + dire + "\")");
	con2.execute("INSERT INTO localdirs VALUES (\"" + row[0]+"/thumbs\")");
#delete dirs
for row in con2.execute("SELECT file FROM remotedirs WHERE file NOT IN (SELECT DISTINCT file FROM localdirs) ORDER BY length(file) DESC"):
	print "deleting " + row[0]; 
	remoteexec("rmdir " + re.escape(targetdir + row[0]));

#create dirs
for row in con2.execute("SELECT file FROM localdirs WHERE file NOT IN (SELECT file FROM remotedirs)"):
	print "creating " + row[0]; 
	remoteexec("mkdir " + re.escape(targetdir + row[0]));

#handle files
a = os.popen("ssh " + target + " find " + re.escape(targetdir) + " -type f").readlines();
con2.execute("CREATE TABLE remote (file varchar(255), PRIMARY KEY (file))")
for elem in a:
	if(elem != ''): con2.execute("INSERT INTO remote VALUES (\"" + elem[len(targetdir):-1] + "\")");
con2.execute("CREATE TABLE local (file varchar(255), isthumb bool , PRIMARY KEY (file))")

for row in  con.execute("SELECT albums.url, from images INNER JOIN albums ON images.dirid = WHERE IN " + chooseidsstring):
	con2.execute("INSERT INTO local VALUES (\"" + row[0]+"/"+row[1] + "\", 0)");
	con2.execute("INSERT INTO local VALUES (\"" + row[0]+"/thumbs/thumbs_"+row[1] + "\", 1)");

print "Deleting leftover files"
#delete files no longer in the db
for row in con2.execute("SELECT file FROM remote WHERE file NOT IN (SELECT file FROM local)"):
	print "deleting " + row[0]; 
	remoteexec("rm " +  re.escape(targetdir + row[0]));

print "Uploading files"
#upload files
for row in con2.execute("SELECT file,isthumb FROM local WHERE file NOT IN (SELECT file FROM remote)"):
		print "creating and uploading thumbnail: " + row[0]; 
		os.system("convert \"." + row[0].replace("thumbs/thumbs_","") + "\" -thumbnail 100x75 thumb.jpg")
		copyremote("thumb.jpg", re.escape(row[0]))
		print "resizing and uploading image:     " + row[0]; 
		os.system("convert \"." + row[0] + "\" -resize \"1024x768>\" small.jpg")
		copyremote("small.jpg", re.escape(row[0]))

filetype (7.25 kiB, 2008-10-06)

Posted in Internet, Photography | Tagged , | Leave a comment

Deleting multiple tables with a common prefix

//Connect to the database server and select our database
$link = mysql_connect('', 'UXXXX', 'epsilon eridani') 
	or die('Could not connect: ' . mysql_error());
mysql_select_db('DBXXXX') or die('Could not select database');
//get table list
$result = mysql_query("SHOW TABLES") or die(mysql_error());
//kill tables
$tokillprefix = "jos_";
 	if(substr($row[0],0,strlen($tokillprefix)) == $tokillprefix){
	 	echo "killing $row[0] <br>\n";
		mysql_query("DROP TABLE $row[0]") or die(mysql_error());
Posted in Computers | Tagged , , | Leave a comment

Debian Sarge GNU/Linux on a Fujitsu-Siemens Amilo M7425 Laptop


This is my Guide to a working Installation of Debian Sarge GNU/Linux on the Amilo M7425. It may be useful for other distributions too, i used a 2.6.10 kernel. I’m not yet finished, but it runs well enough. If you are using Suse, check out the Lugoland Amilo M7425 manual. Since I don’t use debian any more, this page wo’t be updated again.

Some notes to Ubuntu

I recently switched to ubuntu. I was impressed how fine this machine works with ubuntu, no need for a selfcompiled kernel, WLan works during the installation process. All I had to do was adding "ac", "battery", "speedstep_centrino" and "cpufreq_ondemand" to /etc/modules and activate my little speedstep script ("update-rc.d speedstep defaults").

Posted in Computers | Tagged | 2 Comments