Sunday, June 30, 2013

Hodor qualification

In the world of creative programming jargon, we already knew about Yoda conditions (“if three the size is”):

if (3 == size) {
  ...
}

And about Pokémon exception handling (“gotta catch 'em all!”):

try {
  ...
}
catch (Exception ex) {
  ...
}

Now I recently ran into a new antipattern, and decided to name it Hodor qualification after the character from Game of Thrones who can only say his own name.

Hodor qualification is to needlessly prefix calls to static methods by their class name, even from within the same class:

class Hodor {

  private static int foo(int x) { ... }

  private static void bar() {
    return Hodor.foo(1) + Hodor.foo(2) + Hodor.foo(3);
  }

}

Hodor!

Tuesday, February 19, 2013

Uninstalling old kernels in Ubuntu

One would think that Ubuntu would be smart enough to remove obsolete kernel packages by itself. One would be wrong.

I think the Computer Janitor can clean them up but you still have to run that manually. So I prefer the following command:

uname -r; sudo apt-get remove $(dpkg --get-selections 'linux-image-*' | grep '\binstall' | head -n-3 | cut -f1)

This removes all kernels except the latest two. It prints the currently running kernel version so you can easily check that it's not removing that one.

Sunday, October 21, 2012

Turning off the screen saver in Ubuntu

TL;DR: xset s off

“That's easy,” I could hear you think when you read the title. Well, it took me hours to figure it out. It drove me crazy that I'd have to get up and move the mouse every 10 minutes while watching a movie¹, and I couldn't figure out how to disable this behaviour. And when something takes that much effort, I blog about it so that other people might find the solution more easily.

Of course you can easily disable the screen saver through the control panel thing. But I'm not using the Gnome panel, so I never know how to get to that GUI in the first place. Also, you may find, like me, that it just does not work and your screen will still turn black after 10 minutes.

From the console, you can disable the screen saver with:

$ gsettings set org.gnome.desktop.screensaver idle-activation-enabled false

This probably does the same thing as the check box in the GUI. But for me, it wasn't enough: the screen would still blank after 10 minutes!

As it turns out, this is a default built into Xorg itself. Try this:

$ xset q
...
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  600    cycle:  600
...

Yep, that's the problem. Once you've found it, the solution is simple:

$ xset s off
$ xset q
...
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  0    cycle:  600
...

This only works until the X server is restarted; put xset s off in your .xsession file to make this change permanent.


¹ At least for some movies. mplayer disables the screensaver automatically, but Flash doesn't.

Sunday, July 15, 2012

Switching default PulseAudio device when USB microphone is plugged in

I have a PlayStation Eye for a USB webcam and microphone, which is supposed to be supported by Linux. Unfortunately the microphone won't work until I unplug it and plug it in again after boot.

But the unplugging causes PulseAudio to change its default device back to my on-board sound card, which doesn't have a microphone plugged into it. It won't change the default back to the Eye on its own. Here's a workaround, which took me several hours to develop, and isn't for the faint of heart. But it works now, dammit.

All we need to do is nudge PulseAudio a little via a udev event. First, install the daemon package:

sudo apt-get install daemon

Then create a new file /etc/udev/rules.d/99-pseye.rules with the following content (all on one line!):

SUBSYSTEMS=="usb", ATTR{idVendor}=="1415", ATTR{idProduct}=="2000", RUN+="/usr/bin/daemon -- /bin/su thomas -c 'sleep 1 && /usr/bin/pacmd set-default-source alsa_input.usb-OmniVision_Technologies__Inc._USB_Camera-B4.04.27.1-01-CameraB404271.input-4-channels'"

OmniVision is apparently the manufacturer of this camera. Reports around the internet have slightly different version numbers; type pacmd list-sources and use the name of your particular device (which shows up as name: <...>). You also want to replace thomas by your own username; this is used to find the running pulseaudio daemon.

There shouldn't be any need to restart the udev daemon, but if you find otherwise, do sudo restart udev.

The daemon command is needed because we need to delay the pacmd command a bit; if we run it right away, PulseAudio hasn't picked up the new device yet. The trouble is that udev tries very hard to wait for completion of all child processes of the RUN command before firing its events into userland, so PulseAudio will always get its event only after our script has already finished and failed. Even various combinations of & and nohup wouldn't convince udev not to wait, but daemon does the trick.

If this doesn't work, here are some debugging methods that I used. Try adding -o/tmp/daemon.log after /usr/bin/daemon and inspect the output. To watch udev events happen in real time, use udevadm monitor. Another good source of information is /var/log/syslog; do tail -f /var/log/syslog | grep pacmd to filter it. Also check the output of pacmd dump to see whether the set-default-source command has taken hold.

Oh, and the upstream PulseAudio people in all their wisdom decided (bug report) that 4-channel microphones like this one don't deserve to have a default profile, resulting in the message Failed to find a working profile in /var/log/syslog. The result is that PulseAudio will retry loading, and retry, and retry … causing brief and hard to debug system freezes once every minute or so. To make the microphone work at all in Ubuntu 12.04 (bug report), you also have to add the following at the end of /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf:

[Mapping input-4-channels]
device-strings = hw:%f
channel-map = front-left,front-right,rear-left,rear-right
description = 4 Channels Input
direction = input
priority = 5

[Profile input:mic-array]
description = Microphone Array
input-mappings = input-4-channels
priority = 2
skip-probe = yes

Then type pulseaudio -k to reload the daemon (it will be restarted on demand). Yes, this will be overwritten on upgrades. I've found no way to work around that yet.

Sunday, August 14, 2011

Heathrow runway alternation in Google Calendar

I moved to London recently, and unfortunately I found out too late that my new flat is right in the flight path of Heathrow's northern runway, causing quite a bit of overhead noise. However, I noticed that some periods were very quiet (including when I was viewing the flat). Was there some method to this madness?

Turns out, there is. The Heathrow runway alternation schedule is nicely documented on the Heathrow website. Basically: one week has noisy mornings, the next week has noisy afternoons/evenings.

But it's a PDF file, which is only useful for printing and sticking on walls, which is sooooo 2010. So I turned it into a public Google Calendar, for use by myself and anyone else who might be interested. But alas, Google removed the ability to search for public calendars back in 2009, which forces me to post about it here to make it findable.

Here's the ID of this calendar:
r1846kc94hj3ekk24ueb69151g@group.calendar.google.com 
Copy this, head over to Google Calendar, and paste it into the box labelled “Add a friend’s calendar”. Simple as that.

That's only for the northern runway, known as 27R (when landing/departing towards the west) or 09L (when landing/departing towards the east). Since landing and departing probably make the same amount of noise, I lumped them all together. If anyone would like a similar thing for the southern runway, let me know and I'll put one together.

Friday, February 18, 2011

Exporting slices from Inkscape, part 2

I previously wrote about how to export slices from an Inkscape file, using a bash script. Here's a better script, using Python, which doesn't require you to give your slices any special label.

The new process is as follows:

  • First, draw your image as usual.
  • Then, add a layer that will hold the slices; name it slices (this is important). Set the layer's opacity to about 50% to be able to see what you're doing. Enable the grid, and make sure it is set to pixels: you want your slices to align with pixel boundaries.
  • Draw your slice rectangles onto the slices layer, aligned to the grid. Ensure that the rectangles have no border; the fill is irrelevant (I use red).
  • Right-click a slice, and choose Object Properties. Change Id field to the name of the eventual PNG file, without the extension. The area defined by a rectangle named foo will be saved to foo.png. Repeat this for all slices.
  • Hide the slices layer. If you forget this, the script will print a warning.
  • Save your image. Let's say you called it layout.svg.
  • Run the script as follows:
    ./export.py layout.svg
    You should see each of your slices being exported to a PNG file in the same directory.

Here's the code for the script. Save this to a file export.py and make it executable.

#!/usr/bin/env python

import sys
import os
from xml.dom import minidom

if len(sys.argv) < 2:
    print 'Usage:  %s filename.svg' % sys.argv[0]
    sys.exit(0)
input_file = sys.argv[1]

dom = minidom.parse(input_file)
groups = dom.getElementsByTagName('g')
for group in groups:
    if group.getAttribute('inkscape:groupmode') == 'layer' and group.getAttribute('inkscape:label') == 'slices':
        if 'display:none' not in group.getAttribute('style'):
            print 'Warning: slices layer might still be visible'
        for element in group.getElementsByTagName('rect'):
            export_id = element.getAttribute('id')
            filename = '%s.png' % export_id
            print 'Exporting %s...' % filename
            os.system('inkscape --export-id="%s" --export-png="%s" --file="%s"' % (export_id, filename, input_file))
        break
else:
    print 'No layer named "slices" found; not exporting anything'
    sys.exit(1)

Wednesday, February 2, 2011

Editor's Prick?

Some time ago, I received an e-mail concerning my little open source program Taekwindow:

Monday, Jan 17, 2011, 10:27
From: F.R.
To: me

My name is F., Customer Manager of WareSeeker.com, a professional software directory. I would like to propose a solution to promote your software on our site.

We would like to take this opportunity to introduce ourselves. Wareseeker is one of top 5 professional software directories in the world and currently serving about 2 million page views per day. Many renowned software publishers rely on us as their primary media of promoting their products, thus increasing the sales or download dramatically.

We have tested thoroughly and guarantee that Taekwindow 0.3.1 is 100% SAFE TO INSTALL, which means it does not contain any form of malware: spyware, viruses, trojans and dialers.

Taekwindow 0.3.1 has been received Editor’s Pick Award from us.

We hope that you will gain more benefit through this Award. Moreover, we would like to request you add our link and Editor's Pick icon on your Awards category at http://taekwindow.sourceforge.net/download.html

It's not the first time Taekwindow receives such an award, and they generally don't mean very much. But still, it's a nice gesture, and I've done other download sites the same favour, so I replied in the positive.

Since the Taekwindow site is largely built by an automated build system that only runs on Windows, and I am spending all my time in Linux lately, I did not make any promises when I would get round to it. It would probably have been later that week.

Two days later, I received two e-mails in quick succession.

Wed, Jan 19, 2011, 02:40
From: F.R.
To: me

How about our request of our link and Editor's Pick icon at http://taekwindow.sourceforge.net/download.html

You will do that, ok? but when

Keep contact me

Wed, Jan 19, 2011, 09:46
From: F.R.
To: me

How long you got message of mine? I will remind you in final time for our link and Editor's Pick icon on your site.

Give me the respond when you reached this email

Okay, so he expects me to answer to e-mail within 7 hours and 6 minutes, while I'm asleep. And he's getting pushy. But at least I could tell him that I received his mails.

Wed, Jan 19, 2011, 12:04
From: me
To: F.R.

I got your messages alright. I'm a busy person, and I do not appreciate your impatience about me doing you a favour. Please stop pushing me. I'll get to it as soon as I have time.

I might still have done it later that week, but I didn't get round to it. Today, another e-mail appeared.

Tue, Jan 25, 2011, 02:42
From: F.R.
To: me

I don't know how are you busy, I'm also a busy man with a huge business volume each day but I still spend some minutes to write for me to remind you about our request.

Today If you don't reply my mail, I will remove our award for your product on my site. Contact me immediately when you reached this mail

Is that how you treat people when you want them to do you a favour? Not appreciated.

Tue, Jan 25, 2011, 11:45
From: me
To: F.R.

Dear Mr. R.,

The usual nature of awards is that they are given without requesting anything in return. In spite of that, I graciously agreed to return the favour, although due to other obligations I couldn't say when. After a few days, a gentle reminder might certainly have been appropriate. However, two reminders within eight hours (during which I was asleep, I might add), of an increasingly unfriendly nature, did not increase the likelihood that I would answer to your request. Your further pushy behaviour did not improve the situation, and now you request has turned into a demand, with a corresponding punishment should I not comply.

I noticed that Taekwindow has received 13 downloads through your site, and this number has not changed in the last few days. Compared to 149 downloads at Softoxi and 1121 downloads at Softpedia, I doubt there is much value for Taekwindow to be hosted on your site. Given the apparent attitude of the site's employees, it might even do more harm than good.

If it must be like this, I would prefer not to have anything to do with you or your site anymore. I have removed the staged modifications to the Taekwindow website. I will now proceed to write a post about our exchange on my blog, which receives a moderate amount of traffic. Good luck with your future endeavours.

Sincerely,

Thomas

P.S. Incidentally, the download page for Taekwindow on WareSeeker reads: "Software piracy is theft, Using crack, password, serial numbers, registration codes, key generators, cd key, hacks is illegal and prevent future development of Taekwindow 0.3.1 Edition." None of these statements are true. Software piracy may be considered a crime in most countries, but it is distinct from theft. The use of password[s], serial numbers, registration codes and/or cd keys is often a part of software installation required by the software's manufacturer, without which the software will not function, so this can hardly be considered illegal. Finally, the use of any of these will not impact the future development of Taekwindow 0.3.1 in the slightest.

Here's that blog post. See? I do keep my promises — mostly.