Jan
07
2011
My recent post on Flickr authorisation mentioned a problem I was having trying to upload images. I was receiving an “invalid signature” message but only when attempting to upload images. Other actions (looking for new uploads, searching for tags) were all performed without trouble.
The upload fails if you supply a non-empty list of tags to the hsflickr library. In short, uploading images works like this:
uploadPhoto filename title description tags attributes
The upload will fail if the tags argument is non-null. That is, supplying tags at the point you upload the image will result in an error. Thankfully the workaround is short:
photoID <- uploadPhoto filename title description [] attributes
addTags photoID tags
Supply an empty list of tags for the initial upload, and when that succeeds use the resulting photo ID to set the real tags afterwards.
When I work out what the underlying issue is I’ll post a patch here (and punt one upstream).
Dec
03
2010
I feel like I’m just posting stupid screenshots at the moment, but this is the second time E-ON have done this to me so there’s no mercy.

Come on, form mail isn’t difficult! Get your act together, and check the damn things before you hit send.
Nov
21
2010
It’s been a quiet week on the programming front but I’ve made steady changes to Thud since committing the initial code to BitBucket ten days ago.
I’ve added some unit tests, which was a simple thing to do but not very easy to get right. Unit tests are a bit like Cluedo, in that you have to convince yourself of something very complicated with a few well-chosen questions. And it’s easy to forget your assumptions and miss something vital.
Just today I spotted something by playing with the game. I realised it was possible to hurl or shove a piece over another to reach the enemy on the far side. The logic only checked that the target was within reach but not that it was within proper line of sight. (This goes back to the original implementation too, so it’s not just a feature of my mucking about with the code that deals with the game rules and breaking something.) The rules are silent on whether this is even allowed (I suspect not) so I’ve disallowed it for now.
This is not the kind of bug I would have caught with unit tests because it would never have occurred to me to check for it. Of course the butler didn’t commit the murder, that’s preposterous! I only spotted it during play because I was purposely lining up foes next to each other in order to manually test their capture capabilities and realised that I could hurl a dwarf further than necessary… and the game allowed it.
So I’ve been repeatedly rewriting the file that deals with game rules so that scenarios like this become more obvious. I’m getting to the point where I’m happy with this small segment so I need to push on to other things.
As I mentioned on another post it’s nice having an issue tracker for the code so I can write down any ideas that occur to me, whether they’re short-term or long-term concerns. I think it’s time to look at some of the more medium-term goals now, such as network interaction, otherwise I’ll spend the rest of my days endlessly fiddling with the game rules.
Nov
16
2010
Description of screenshot included in blog post:

Mar
17
2009
As nice a program as Banshee is, they did something really strange during development. At some point they broke everything — presumably for a rewrite — and are slowly assembling it again.
So things that were working well in the early days, like album covers, have become more of a pain with the slicker later versions. If you’re having trouble with album covers here are a few things that might help you.
- Dropping a
folder.jpg file in the album folder does work, but with a number of caveats.
Album covers are cached in ~/.cache/album-art/. And various subfolders too, for different sizes. It’s best to delete the relevant file from this cache before doing anything. Luckily the correspondence between filename and album is very simple:
$ cd ~/.cache/album-art
$ rm robertplantalisonkrauss-raisingsand.jpg
$ rm */robertplantalisonkrauss-raisingsand.jpg
It should be fairly easy to find the cached images with this naming scheme. Once the cache has been deleted Banshee will pick up the folder.jpg file you added manually to the album folder.
Album names that includes funny characters (parentheses and colons, for example) don’t parse properly. So inserting folder.jpg in the right place will have no effect.
Instead you need to copy the album cover to the cache, ignoring the dodgy characters.
$ cd .cache/album-art
$ cp ~/Music/Classic\ FM/Movies\:\ The\ Ultimate\ Collection/folder.jpg classicfm-moviestheultimatecollection.jpg
Then it’ll just magically appear in Banshee, in the right place, and all the other resized versions will be generated without problem.
I hope this helps some people out for the more complicated scenarios. Eventually this bug will be fixed and Banshee will not have these problems at all. (Also, interested parties might want to check out that bug thread to see how far down a rat hole one can get with the “simple” topic of album art.)
Jun
26
2008
Citylink are a bunch of useless amateurs that don’t have the guts to admit their uselessness when it’s pointed out to them.
I spent all day yesterday and half of this morning trying to book tickets to get to Glasgow. I was repeatedly told by the online ordering system:
Please Note: There are currently no fares available for your origin
and destination. This may be because you have selected an open
return. Please go back and plan your journey again using the
return option.
Naturally this error message appears whether you choose Single, Return or Open Return. If I was unlucky the search would fail completely because the hamsters were having their postprandial snooze.
I emailed them to let them know their site was crap (well, I was slightly more constructive than that). They replied an hour later telling me to upgrade my Java installation — they even directed me to http://www.java.com. This was all rather suspicious, because not only do I have the latest Java install, but their site doesn’t even use Java. It does use Javascript extensively, but (1) the two languages are completely unrelated and (2) Javascript cannot be updated by going to that website. This may cause some minor confusion for the layman but I would hope the person who emailed me, the System Development Assistant, would know what languages they use when developing their system! I say the site doesn’t use Java, but I mean on my computer. Their website appears to run with Java Servlets but that’s all on their computers. There’s nothing that me fiddling with my settings will do.
Just out of interest I fired up IE6 in Windows and tried again. It worked! Well, maybe there is something wrong with Firefox after all… but no, my usual system was now working fine. What had they changed?
So, do you think they told me to look for the tartan paint while they fixed everything in the background? I’m quite inclined to send them a rude email back asking them not to take the piss.
May
30
2008
Let’s start with an analogy. I’ve got the manuscript for my bestseller here and I want you to proofread it for me. My options are to email it to you or put it online somewhere for you to download. Email is an effective way of pushing it to you but it might be too large a file to attach. Alternatively I could send you a link which you can use to download from somewhere else. The advantage of this method is that it scales really well — if I want 50 friends to read my new book it’s just as quick to email them all with a link.
There is one disadvantage — if the file isn’t there then the would-be proofreader sees Error 404: File Not Found. And they give up.
Using this analogy we can look at the problem of programs moving data about in memory. There are two ways to do — copy all the data from one place to another, or just copy the location where the data is stored. This is the same idea as emailing the whole document or just emailing the link.
The disadvantages of copying all the data around should be easy to see — it’s terribly slow. All of these delays cost a lot of time because memory access is so much slower than the processor. The alternative, passing references round instead of all the data, is much faster. The only data copied is a tiny little link showing the location of the needed data.
But — and this is really important — if the link points to the wrong data then the consequences can be catastrophic. If the in-memory link (which is called a “pointer”) doesn’t point anywhere then the application (or even the whole computer) can crash. Why such a big reaction to what is essentially a 404 error?
The details to this are quite interesting. Inside your computer there is an intricate hierarchy of privileges — this prevents programs from doing things they’re not allowed to do, like reading protected files without permission. One of the ways in which these privileges work is that each program is assigned an area of memory to use. It can’t just access any old location in memory. If a program tries to access memory outside its own assigned segment it will often be killed by the operating system. (If it is not killed then the program could do something dangerous like interfering with another program or with the operating system itself.) The operating system may state that the program was killed because of a segmentation fault or similar stern warning.
One common fault in programs is trying to follow pointers that don’t point anywhere. These are often called null pointers, since they actually point to address zero in memory, which doesn’t contain anything. This memory location is specifically not owned by anyone, so there should never be any need to look there. Any program which does look there is assumed to be in error and killed by the OS.
You know how common 404 errors are when browsing the web. Null pointers are just as common in programming. They are used all the time and can be quite powerful in many situations. But they are also very dangerous and many modern programming languages do their best to provide the advantages of pointers without the dangers. Sometimes the result is like a safety razor, with most of the function and fewer dangers — and sometimes the result is just the same dangerous tool with a warning sticker.
Apr
02
2008
I’ve been fiddling with Mono lately, the free software implementation of the Microsoft .Net system. I say, fiddling, mostly just looking at. My good friend Matt wrote a network game of Thud! in C# for Windows. I was trying to get it working under Linux.
I’m happy to say that migrating a Visual Studio project with MonoDevelop worked flawlessly for me. Then I just hit Build Project and it worked. The game is human-player only, so I wanted to write a rudimentary AI to play against. (I don’t really know how to play, so I think I could beat me fairly easily.)
Then I hit this bug in the Mono system which causes complete failure whenever you try to open a network connection — but only if your machine has a dynamic IP address. Yeah, I know…
I wanted to simplify the networking protocol (currently it’s the default .Net serialisation system, which is rather opaque). That will have to wait until I can play the game without crashing it.
Feb
12
2008
You know the optical illusion type thing which has a word repeated at the end of one line and the beginning of another?
This is exactly the
the kind of thing I mean.
They’re always horribly difficult to spot. I’m pretty sure I noticed one in the blurb on the back of one of my books at some point, but I don’t know which one. I just had a quick look at some of the potential culprits — I had a feeling it was William Gibson — but couldn’t find it. But then, maybe my eye just skipped over it?
Either way, I just reported this bug in GeSHi, in the Haskell highlighter. This is taken from the middle of a long list of standard functions…
'zip3', 'zipWith', 'zipWith3', 'unzip', 'unzip3',
'unzip', 'unzip3', 'lines', 'words', 'unlines',
…and notice how unzip and unzip3 are in there twice? Well, it causes the linking tool (which creates web links to the Haskell API for these functions) to break on these two functions. It never ceases to amaze how silly some bugs can be. ;-)
Jan
20
2008
I spent last night trying to find a music player that would do what I wanted. I didn’t think I had extremely complex or demanding requirements.
- A music library that can be loaded and queried quickly.
- A music player that can cope with the standard Ogg Vorbis and MP3 files.
- An organiser to sync the library (or a subset of it) with my portable MP3 player.
It seems number one is still beyond the abilities of most people who write these programs. Banshee reportedly has O(1) library loading in an experimental branch, but the remainder offer O(n). And n doesn’t have to get very large before you notice quite a slowdown. Exaile seems the best of the ones I tested, but really it’s just the least worst.
Everything I tested managed number two pretty well. But then, they’re music players, they should at least be able to play music files.
The third feature I want was a massive failure on all fronts. They all recognise my player as an external disk, but then they want to index the damn thing which takes forever. Rhythmbox actually hangs for some five minutes on startup (no UI response at all) until it’s finished loading all the tunes from my MP3 player — something I didn’t even ask it to do.
Exaile doesn’t actually hang while it’s indexing my player’s HD but it gives no indication that anything is happening. But five minutes later it pops back with a full list of everything on the disk. It won’t really let me sync though.
Banshee seems the best for syncing audio between different places. At least it seems to have the kind of options you’d need (manual updating, full automatic syncing). Shame it crashes stupendously when you hit the sync button, eh?
So I don’t have anything better than before. I use Exaile here because its library is pretty fast. I use Rhythmbox at work because it was the only one installed by default and it doesn’t demonstrate much slow-down with only two albums in the library. I have nothing to sync the contents of my on-computer library with my portable player. There are a bunch of separate applications that do this job for iPods but not for anything else, as far as I see. Pretty disappointing.