DoubleCommand and multiple keyboards

I love my MacBook Pro. But not everything about her.

For instance, I despise that there is no forward delete key on the inbuilt keyboard. But using DoubleCommand you can fix that. You can also make the fn key act like control (I’m always hitting fn-C instead of Ctrl-C to kill a thread, for instance), and a whole lot of other changes.

But if you remap the small enter key to forward delete (which I highly recommend), if you plug in a USB keyboard, then the keypad’s enter key will also be mapped to forward delete. Which is not cool.

The latest SVN version of DoubleCommand has the facility to fix this, but it requires a bit of terminal work to set it up.

If you haven’t got a newish version (~1.6.6), first, check out the latest code:

$ svn co https://doublecommand.svn.sourceforge.net/svnroot/doublecommand doublecommand

The code we want is in trunk/kext. Open the project inside that folder. Build the project, and then enter the following command from inside of the build/ subdirectory:

$ sudo cp -r Default/DoubleCommand.kext /Library/StartupItems/DoubleCommand/DoubleCommand.kext  

Enter your password when requested. Then change to the DoubleCommand installation directory:

$ cd /Library/StartupItems/DoubleCommand  

We need to unload and then load the kext. The easiest way is using the following commands ($ means type it in, > is the output):

$ sudo ./DoubleCommand stop  
> Unloading DoubleCommand  
> kextunload: unload kext ./DoubleCommand.kext succeeded  
$ sudo ./DoubleCommand  
> Loading DoubleCommand  
> kextload: ./DoubleCommand.kext loaded successfully  
> dc.config: 0 -> 1593344

Take a note of that last number, and then perform the two commands:

$ sudo sysctl -w dc.keyboard1=37
$ sudo sysctl -w dc.config1=<the_number_above>

Now, load up the DoubleCommand preferences pane, and disable the ‘Enter key acts as forward delete’, or whatever you had it acting as. Now, the two keyboards will appear differently in behaviour. And hopefully your life will be fuller.

Many thanks to the developer, Michael Baltaks, for his quick response and assistance in this matter.

Mac OS X hostnames

I run a DHCP/DNS server on my home network, which allocates addresses for all of my machines, and provides them with DNS when connected. Because my development machine, a MacBook Pro also sometimes has to run a web server, and provide varying responses according to the hostname by which she is currently being addressed, I set up a range of VirtualHost directives in apache, and entries in m own /etc/hosts file. This was fine as long as I was the only person accessing these sites, but I also needed to access them from a couple of other machines (including a VM running WinXP).

So, I palmed off the /etc/hosts entry to the DHCP server, a reflashed NSLU2. This machine is just the DHCP/DNS server, which is available only via ssh. But, if I connect to my home network, then the DHCP/DNS server decides to use this hostname as my hostname. I’m still tweaking to see if there is a way around it (have the correct hostname specified earlier in the file springs to mind).

It’s fairly annoying to have the wrong hostname showing in my Terminal when I open up a bash session, or look at the console.log. Something I really can’t live with.

Dictionary returns in ZSI

For my day job, I am developing a SOAP server in python. I have been using ZSI as a framework, and it is very good. It will, with mod_python, allow you to build a complete application in python (and even without mod_python you can have it as a standalone process). One of the touted features is easy return of lists and dictionaries, without having to declare ComplexTypes classes.

However, it doesn’t quite work. And the not-working-bit is really odd.

If you return a dict, such as the following:

1
  return {"uid":23,"gid":993,"cid":333}

Then ZSI creates a SOAP response like:

1
2
3
    <uid id="1234" xsi:type="xsd:int">23</uid>  
    <gid id="5678" xsi:type="xsd:int">993</gid>  
    <cid id="0987" xsi:type="xsd:int">333</cid>

But, if you return a dictionary with values that happen to be the same, as I did with my boilerplate code:

1
2
3
    return {"uid":"xsd__string",
            "gid":"xsd__string",
            "cid":"xsd__string"}

Then it fails. The second and any other instance of any dict key where the value has already been used by another key is empty, and the wrong type:

1
2
3
    <uid id="1234" xsi:type="xsd:string">xsd__string</uid>  
    <gid href="#5678"></gid>  
    <cid href="#0987"></cid>

This can be overcome with liberal use of classes (or subclasses, since most of the time I am returning dicts or lists). It is a bit of a pain in the arse, though. I’ve filed a bug report. And stopped using ZSI. If I found this bug this fast, then I don’t want to know how many more there are. It’s just easier to convert the XML to python objects and back again, and package it up to look like a SOAP request. Which is kind of what SOAP does anyway.

4 GB RAM

Well, the 4GB of PC2-5300 SO-DIMM RAM I ordered arrived today. I got it very cheap on eBay, and was pretty worried about it. But it all seems pretty stable so far - Rember tells me it is all okay, and it seems to be running smoothly.

Upgrading the RAM in a MacBook Pro is a piece of cake - took less than 5 minutes, including waiting for the machine to shut down and then start up after replacing the sticks. Had three small philips head screws to remove, after taking off the battery. Then the RAM came out fairly easy, and the new sticks were in.

I used the 2x 1G sticks from the laptop to upgrade my Media Centre - the Mac Mini (jens) seems to like the doubling of RAM she got too. Having said that, opening the case up was a bit trickier, but took less than 30 minutes anyway. The longest time was spent trying to figure out why the external HDD wouldn’t mount (because I had turned it off), then why it wouldn’t turn on (apparently it needs to be connected to a firewire port first).

The extra RAM in my laptop means I can finally run a VMWare machine without having to set aside 15 minutes for the machine to respond enough to be usable. I know this isn’t just a problem with the particular VM file, since this is a brand new VM. The old one was even worse! Having said that, I’m not about to use it all of the time. Although once it is running, it goes okay, it still consumes a fair chunk of the RAM.

Speaking of RAM use, I’m running a few Dashboard widgets, a couple of which use up 15MB of RAM each. DoBeDo and iStat widget seem to be the culprits. I think I’ll kill DoBeDo - I use Anxiety as my main ToDo viewer, which uses half of the RAM of DoBeDo. It’s just nice that whenever I go into Dashboard it’s there to remind me. I often use iStat widget just to keep a track on stuff, so that can stay too.

Back to Uni

After a nearly 10-year hiatus, I’m back at Uni. And loving it.

I’m currently sitting in the Flinders Uni “Coopers” bar, having a nice cold Pale Ale. My first day of Uni was today, and so far it’s pretty cruisy.

I actually finished the first two afternoons’ work in the first half of the first afternoon. The lectures didn’t really give me much new, it’s all just aligning what I already know about OOP with the syntax of java.

The thing that actually took me the longest today was remembering how many degrees are in the internal angles of a regular pentagon. I ended up having to fire up a python interpreter to keep a track of all of my maths. I think I would have finished in half the time it took me otherwise. That, and having to remember to declare variables…

So, Java is looking easy so far, and from what I can see the next 2.5 weeks are going to be more of the same. About time I started to get High Distinctions, I think. I’m finding plenty of time to listen to Late Night Cocoa, and learn Objective C/Cocoa while I learn Java.

Support Sux0r

I don’t like doing technical support. It is just not something that I find enjoyable at all. I don’t mind fixing the occasional computer - I had a mate’s PowerBook G4 for a few days the other day, and even got a bit miffed by how frustrating that was. Long story short - it seemed like the hard drive was buggered, but after replacing that (which was very hard), I by chance removed and reinserted the RAM, which doesn’t require a complete disassembly, and it booted fine. I then spent 40 minutes fixing my sister’s laptop’s internet. Which again I didn’t mind, as I was the one who had left it set up to use a static IP address when i was working on getting an ad-hoc WiFi network going. It took 40 mins to fix something that if I had the machine in front of me (or even VNC), I probably could have fixed in 4.

One thing I will be doing at my job is some technical support for a specialist software package. I’ve listened to my boss (still sounds weird calling him that, since he’s a mate of way back) and I really don’t think it will be fun. I can already parrot a heap of the phrases he uses several times a day, and I’ll be heading out with him to do some site visits late this week or next.

Well, I’m not the person to tell that sometimes you have to do stuff you don’t really like, just to keep the money rolling in. How many years was I a teacher for again?

•

Whilst trying to tag this post, I realised that I don’t have as much to rant and rave about since I am not a teacher. I’m not the angry young man I was. Still, this is as close to a rant as I am getting, so it’s going in that pile…

EyeTV 3

Apparently, EyeTV 3 will be released today (Tuesday). I did read somewhere that this version will be a fully-fledged media centre, but maybe that’s just rumour and innuendo.

I hope not. I’d love it to access and display data from iTunes, since I’ve painstakingly put most of my pre-EyeTV (and saved-from-EyeTV) media into iTunes.

Life as a Coder

I never thought I’d manage to find a job coding in python for a living. But that is what my full-time job is, right now, anyway.

I can’t really talk about the work I’m doing, since it is a commercial enterprise, but I can talk about what sort of things I am coding. I have spent the last couple of weeks rebuilding a server in python that uses SOAP to communicate with the outside world (well, a client application, anyway) over SSL connections. Python is used so it is easily extensible, without having to recompile. Eventually it will be dynamic, where new modules can be added to a database, and depending on the userid of a request, a different function will be called. It’s really quite exciting.

I’ve come across a couple of new software programs - one of which is NX (nomachine) Client, which is a remote tunnel for X windowing. I can remote in via this to work from home, as well as ssh or sftp. Which is fairly cool. Speedier than VNC, since I think the local X-Windowing system is responsible for some of the drawing tasks. Feels about the same over ADSL as ARD does over WLAN.

In my “free” time I’ve been doing a couple of other things, both programming tasks. The first is a web application for an art gallery to create HTML and PDF invitations and newsletters. Originally I planned to use a web app so that it could eventually be rolled out as a blog-alike - in fact originally it was just going to be a WordPress installation with some minor modifications. It turned out to be easier to rewrite it from scratch. I have learned from this process that PHP is crap: it’s never clear about the way to do stuff, and many functions have weird names. count_chars, for instance, doesn’t really count the characters, unless you decide that things like #@! aren’t characters. In which case you want strlen. Which had me tricked for some time, since I stopped looking once I had found count_chars. Python and len(anything) is much better.

Speaking of python (again), I’ve also been working on a Regular Expression helper - similar to the one that comes with Komodo IDE. I started (and pretty much finished, in a matter of hours, to the extent it solved my first use problem) this after having to load up Komodo just to get a visual representation of which bits of a text block were being matched by a regex. Still some kinks to work out - I need to figure out how to put stuff into an outline view, so I can see more than just matches, but match groups. Then it will be all good.

In the process of my work job, I downloaded SOAP Client, a freeware tool for testing SOAP packets. It was all good until I tried sending HTTPS requests, which it fails unfathomably on (cannot connect to endpoint…). I emailed the author, and he then promptly released the source code. I’ve snaffled that from Google Code, and I’ll try to hack through it a bit to implement SSL connections. Not sure how to go about it at this stage - dunno if it is with WebKit or something else I need to do. I also plan to add in the ability to edit the SOAP request manually before it is sent off to the server.

I start Uni in a couple of weeks - I’m doing an introductory Java course in intensive mode, which I expect to be fairly easy. I’m really only doing it so I can do the meatier sounding subjects, like Programming Language Concepts and Systems Programming. I really think I’m going to enjoy this course. I will be interested when I come to the Internet Computing subject, since I’ve been doing a fair bit of that in various forms over the past few years. Be interesting to see what the academics think it means.

Well, that’s been my life over the time period since coming back from the beach for a 10 day holiday over New Year. Apart from squeezing in a few games of Touch Football here and there, I’ve pretty much been chained to my laptop.

And loving it.

IMDb Data and iTunes

Using python, it’s easy to get data from IMDb into your iTunes database.

You’ll need a few tools to get this working. appscript, py-IMDb and CocoaDialog. Install each of these, and for the latter, note where you store it. I’m not going to go through the code, as it is fairly well commented. If you can’t get it to work, leave a comment and I’ll see if I can help.

IMDB2iTunes.py

Note that you will need to save the file above, and rename it so it has a .py extension.

EyeTV and two tuners

I love my Mac Mini. It does almost everything I want. With the purchase of a second tuner, EyeTV actually becomes useful. Previously, when I tried to record two programs that adjoined one another, but were on different channels, then you were likely to miss the start of the second program, and/or the end of the first program. Even if you set some padding (I use -5/+15), because there was a single time where the transfer needs to take place, chances are you miss some TV.

So, with two tuners, the system flawlessly records two programs at once. Which means the pre/post padding is respected, as long as there is no clash with other scheduled recordings. It means you then need to edit (or just skip, if you plan on watching only, not keeping), but at least you get all of the material. Oh, and it takes up a bit more disk space.

But the hassle I discovered is that the USB subsystem seems to choke under the load, if you record a program and try to watch another. The picture and sound of the program you are watching becomes jumpy and broken.

I made the program smoother by putting the record buffer into RAM. (And making it much, much smaller).

Note that this is using a USB disk as the recording location, I’m hoping to get much better performance when I move the drive to a Firewire enclosure. However, I can record two programs without jumpiness, so it may be something to do with the Live TV Buffer and how it is handled.

I don’t use live buffering much anyway, so I may just live without.