Author Archives


23
Jan 12

Javascript parent constructor being run when defining inheritance and a solution

When using the traditional Javascript methods to do some sort of inheritance, the constructor of the parent will always be run when trying to inherit it. This seems to be a unfortunate side effect of using new a().

The problem

Consider this code. Here b inherits from a

function a() {
    console.log("a");
}
 
function b() {
    a.call(this);
    console.log("b");
}
b.prototype = new a(); // a's constructor will be run here!
b.prototype.constructor = b;
 
new b(); // run once
new b(); // run twice

Here a’s constructor will be run 3 times.

a
a
b
a
b

The solution

There is a simple fix for this, but its only in Ecmascript 5.
Change this:

b.prototype = new a();

Into this:

b.prototype = Object.create(a.prototype);

And the constructor will only be run when actually being called:

a
b
a
b

22
Jan 12

Using hgtools with mercurial tags to automatically version packages

I liked to automate my python package versioning a bit more and did this with hgtools. With hgtools it is quite easy to store the version numbers only in your repository as tags, and not having it again in setup.py.

A minimal setup.py can look like this:

from setuptools import setup, find_packages
setup(
    name="HelloWorld",
    use_hg_version=True,
    packages=find_packages(),
    setup_requires=["hgtools"],
)

Just give a revision a tag and make an sdist, or bdist and setuptools will use the version from your tag.
Tags have to conform to strict version formatting from distutils to be used by hgtools.

Later I also made it a step in a Jenkins setup, to always build a sdist and copy it to a HTTP accessible directory so it could be installed with pip. This gave me a nice history of available release packages and also, dev versions.


5
Oct 10

Django class based views and testing them

One of the problems described well by Honza Král’s presentation on Djangocon.eu 2010, is how to test properly and make it easier. In his presentation he touches on using class based views instead of using normal functions (around 14:14 in the link video). This is not as straight forwards as it seems at first. There are some problems with thead-safety for one.

To have fast tests you should avoid hitting the database as much as you can, and after using this method I have to agree.

Making a class based view

We have this simple view:

from django.shortcuts import render_to_response, get_object_or_404
 
from mysite.polls.models import Poll
 
def simple_view(request, poll_id):
    """ A simple view, which takes an id from a url, shows it in a template. """
    poll = get_object_or_404(Poll, pk=poll_id)
    poll.access_counter += 1
    poll.save()
    return render_to_response('polls/detail.html', {'poll': poll})

And now as a Class based view:

from django.template import Context, loader
from django.http import HttpResponse
 
from mysite.polls.models import Poll
 
class simple_view(object):
    def get_objects(self, poll_id):
        """ Return poll object for given poll_id. """
        return get_object_or_404(Poll, pk=poll_id)
 
    def process(self, poll):
        """ Manipulate data and return the manipulated, unsaved object. """
        poll.access_counter += 1
        return poll
 
    def render(self, poll):
        """ Return HTML. """
        template = loader.get_template('polls/detail.html')
        context = Context({'poll': poll})
        return template.render(context)
 
    def __call__(request, poll_id):
        """ Show a Poll, increment the access_counter each time. """
        poll = self.get_objects(poll_id)
        poll = self.process(poll)
        poll.save()
 
        output = self.render(poll)
        return HttpResponse(output)

What did we do here? We separated the functionality into methods. We have four functions now:

  • get_objects which gets and returns the data, not more, not less. If you have more then one piece of data to get, return a tuple.
  • process which manipulates the data, but does not save it.
  • render transform the manipulated data into HTML.
  • __call__ the mighty function which ties it all together

Each of these functions do one thing, and try to do it well and isolated. Because this is so isolated, testing becomes quite easy since you can test the output of every step and it does not have side effects of the other parts. You still need to run __call__ at least once to check if it is all nicely tied together.

Testing

Testing a part of this view is simple:

class SimpleviewTest(TestCase):
    def test_simpleview_process_increment(self):
        view = mysite.view.simple_view()
        poll = Poll(question="sample")
 
        poll = view.process(poll)
 
        self.assertEquals(poll.access_counter, 1)

Create an instance of the view, create a poll object and feed it to the function. Check afterwards if the value has increased. This is fast, there is no database interaction!

Wiring it into urls.py

I found a little lambda helper to call the class based view:

# this wraps a class based view in a lambda, so it is thread safe (and I do not need to use __new__)
# yes this returns a lambda
class_view = lambda x: lambda *args, **kwargs: x()(*args, **kwargs)
 
urlpatterns = patterns('',
    (r'showpoll', class_view(mysite.views.simple_view)),
)

Just put the class_view function around the view reference.

This might seem quite a lot of code for this example, and it is, but this will give you some benefits when testing this way. Because this is a lot longer then before, you might not want to use it for every view, just for the more complicated ones.


13
Apr 10

Vim, python pep8 and pylint.

When you are making your Python code pep8 conformant or want to have a good pylint score and you are using vim, there are a few ways to make it easier and faster.

First you need to know a bit about the vim option -q. -q takes a filename as a argument, and vim then uses this file to jump to locations in files where the used tool has reported something. Vim expects a very simple format here.

Vim can take the output of the pep8 command:

pep8 --repeat --ignore=E501 *.py  > ~/pep.txt

Then start vim with:

vim -q ~/pepepep.txt

Vim then opens with the first reported issue, to go to the next, use :cn.
Or you can temporarily map z to that for this vim session:

:map z :cn<cr>

Like with pep8, you can do the same with pylint, but you need to use the --format parseable argument:

pylint views.py -f parseable > ~/pep.txt

Some regexps for common formatting issues

Remove trailing whitespace all over the file:
:%s/\s\+$//

Remove whitespace in front of a ,
:s/\s*,/,/

Remove whitespace in front of an equal-sign, if any, add a space.
:s/\s*=/ =/


5
May 09

Configuring the Buffalo AP’s as a Bridge

Configuring the Buffalo WHR-HP-54G as a bridge is quite easy, given that you can get Tomato firmware on there. The default Buffalo firmware doesn’t support bridging or, I couldn’t find it. only thing I found was WDS bridging which is not what I want.

Install Tomato

You need to install an alternative firmware, fortunately most WRT derivatives are compatible, most notably Tomato and openWRT. I picked Tomato because it has a nice “out of the box” experience. It has an easy to use Web interface which is easy to use. OpenWRT is more powerful in the end, but harder to set up at first. I also assume we do not need the extra features that are possible.

Get Tomato from its website, its 7zipped so you might need a more recent unarchiver.

Flashing the AP is more trail and error then science, and it did not work for me, but did work for a colleague.

Here are the Tomato install instructions

Configure a Bridge

TURN OFF IT’S DHCP SERVER

Give it an IP address in an other subnet then you main one (this is for performance reasons).

Here are the settings you need to set to be able to bridge:

Tomato WLAN settings

Tomato WLAN settings

This is a nice addition:

Bridge LED

Bridge LED

And its done.


16
Apr 09

Setting up Suse LTSP with DHCP on another server

At work, I have been tasked with setting up a Linux terminal server to lighten the load of our exsisting Windows server.

LTSP (Linux Terminal Server Project) is quite a nice piece of software. It makes good use of PXE netbooting, but it should also work with RDP.

Get Suse

Download the openSUSE-Edu-KIWI-LTSP-live-unstable.i686 iso from http://download.opensuse.org/repositories/Education/images/iso/

Why Suse? It has good support for LTSP and RDP.

Setting up RDP on Suse

Setting up RDP on Suse was very easy (compared to Ubuntu LTSP):
You can skip this if you installed from the live DVD.

zypper ar http://download.opensuse.org/repositories/home:/dreveman:/nomad/openSUSE_11.1
# nomad zypper in rdesktop xrdp xorg-x11-server-dmx xorg-x11-server-rdp

Now you need to edit /etc/sysconfig/kiwi-ltsp and add:

USE_NOMAD=”1″

Run to update the configuration:

kiwi-ltsp-setup -c

Now start the xrdp server with:

rcxrdp start

PXE booting

PXE booting is a nice feature of network cards. It allows the computer to pull the operating system over the network, and boot the pulled operating system. The user can start applications, but they are not run on the client, but on the server. This is done with several services.

DHCP to tell where to get the boot image from.
TFTP this actually delivers the boot image, based on UDP.
Xorg to display apps on the client side which are actually run on the server.
SSH to provide a secure connection between the Xorg server on the client and Xorg on the server (using option -X)

This should work out of the box when this is the only server in your network, and you do not already have a DHCP server on your network.

But we already have DHCP

LTSP assumes that you do not have an DHCP server yet and it runs one for you. This is quite bad if you already have a DHCP server running, which we have. Turning the dhcp server on Suse off is done with this:

insserv -r dhcpd && rcdhcpd stop

To turn it off forever you can remove the dhcp-server package:

rpm -e dhcp-server --nodeps

This should work until the next time you run kiwi-ltsp-setup, so I’ve been told.

You need to configure your original DHCP server (not the ltsp) , by editing the dhcpd.conf:

subnet 192.168.0.0 netmask 255.255.255.0 {
option routers 192.168.0.1;
range 192.168.0.1 192.168.0.254;
#add this and replace with your own LTSP server ip:
next-server 192.168.0.2;
filename "pxelinux.0";
}

If you try to PXE boot it now, it will fail somewhere at the startup. Press F2 to see the init messages.

You also need to edit /srv/tftpboot/pxelinux.cfg/default

The line (its under LABEL kiwi-ltsp):
append initrd=boot/initrd-ltsp vga=791 splash=silent showopts

should become:
append initrd=boot/initrd-ltsp vga=791 splash=silent showopts kiwiserver=192.168.1.231 kiwiservertype=tftp

Try booting it now, and it should work.


15
Mar 09

G1, the review after usage

So, i have been using the G1 for some time now, and thought it was time for a somewhat more in depth review. I’m writing this post on my G1 with postbot.

Lets start with the keyboard. The keyboard is quite comfortable, and I can almost type blind on it. I can feel where the keys are because they are slightly elevated and there is a small empty space in between the keys. Typing for a longer time is quite doable, but of course not as comfortable or as fast as a normal keyboard.

The available applications on the android market is filled with most of my basic needs. The most important one is the ssh client, which the app connectbot does damn well. It remapped some of the keys of the keyboard to give some easy access to the ESC or ctrl key. It also has copy support but that a bit cumbersome but it works.

The email apps are doing their work quite good too. There is the gmail app, which can only read the email from your G1 associated account. It does the usual threading just like gmail. Then there is the normal email app with support for imap and pop. I don’t use pop, but I heard it pulls in all email, like all pop clients. Pop is also the only way to have your full email available offline. Imap support is good, and also works with your second gmail account. There is a very small cache for imap, everything else gets pulled in over the air. It would have been nice to have the option to save imap and to use 2 gmail accounts in the gmail app because the email app does not do threading.

Cell reception is good, and haven’t really had problems with that. Wifi reception is decent. In Cologne there is pretty decent 3g reception, and i have to admit, I’m quite amazed by 3g speeds and latency.

Media wise i haven’t really tried too much, the mp3 player was decent but the crappy ear plugs and the lack of a mini jack let it go unused. I need to order a converter cable to use my brand new headphones.

Overall the system is quite responsive, and quite stable. Ive had two spontaneous reboots, and a few crashing apps, but that’s way less than on my p900.

The only thing i dont like about the G1 is the battery life. At tops it has lasted me around one and a half day. Which is short for me. My previous phone (se p900) got almost one week. But i wouldnt trade my g1 for a p900.


27
Jan 09

The G1 Experience

Yesterday when I got home there was a nice present waiting for me. My G1 Phone arrived! I ripped open the packaging and found a phone that was smaller than I expected from the images from the internet.

First tries

Popping in the sim card and the battery was easy, turning it on was a bit harder… I did not have much light and didn’t see the on-sign on the hangup button. After some messing around it turned on and it was booting! Next thing it asks me is to unlock the phone, “Damn!” i bought a locked phone. Luckily I knew that it could be unlocked and that it was just a matter of going to a website, entering some details and your emei code, oh and you need to pay 20 bucks too. The rest of the evening I was waiting for the unlock code to arrive. It did not arrive before I had to go to bed. Darn…

The next morning I got up on my usual time and turned on my laptop. After some morning routine stuff, I checked my email and to great satisfaction I found the unlock code! I turned on the G1 again and entered the code, and my phone was unlocked!

Sign in with your Google account please

To be able to use the phone at all you need to log in to your Google account. I tried that but of course that was not working because GPRS/UMTS was not setup for my provider, FONIC. Yet an other “Damn!”. Off to work I went and on arrival I spent some time there researching on how to set it up for FONIC, to no avail, nobody had the same problem as me it seemed. But, I knew that my provider was the cheap-ass version of o2. I found the details for that on plenty of sites, but with that information in my G1 I could also not sign in, seemingly… Back to do some work!

Later that day

A few hours later I tried signing in again, and to my amazement it worked flawlessly! Off playing with it some more! (not too much Mr. boss!). But the battery was dying.. seemingly the provided usb cable didn’t work for charging the battery, i pulled out an other usb cable and plugged it in, and charging commenced! I also moved the most important contacts from my old phone, the trusty p900, to the sim card, and mass imported them onto my phone without any problem. I hopped onto the company wifi and synchronized with my Google account so my contacts show up in gmail. This is an awesome feature, and in my opinion the killer feature. At my workplace the wifi signal was not good enough to hold a connection to the wifi network, so it switched a lot between wifi and GPRS. This has costed me a few dimes I’m afraid… I was able to call and send sms’s with ease. The search button works in a lot of the standard applications and it is a blessing.

When I arrived home serious play time commenced. I installed a few aplications from the android market. It contains tons and tons of apps, some good some bad. Locale is nice, but is lacking a lot of options that it could really improve it. And the battery wanted to be charged again… I also used the IM client, and it worked pretty damn well! So far I absolutely LOVE it. it is fast and responsive, didnt crash on me once (knock on wood) and it is easy to use after a short learning period.

I will write about my other experiences an other time.


5
Dec 08

Wichteln, aka, random christmas presents!


10
Oct 08

Why i hate the apple mighty mouse

I’ve been explaining myself a lot lately for my deep hate for the apple mighty mouse, so here is are a few points on why i hate it.

  1. Scroll wheel gets dirty and is hard to clean
    I have never had a mouse with a scrollwheel before where the wheel needed cleaning. Apple doesnt give any better solution then to hold it upside down and scroll vigorously it with a moisty wet cloth.
  2. Accidental side scrolling
    I want to scroll up and down, not sideways… this messes with Firefox when I’m holding alt or ctrl.
  3. Accidental scrolling when middle clicking
    Makes pastes go wrong. It is also the hardest middle mouse button to press on any mouse I’ve had.
  4. Left click instead of right click and vice versa
    Apple cannot make a mouse which actually registers the right side I am clicking on? I like to hold both fingers on my mouse while clicking, and the mighty mouse uses some weird way of detecting with side is pressed. I have never had this problem with ANY other mouse. How can you fuck up this most basic function?

So, kill the mighty mouse, and use a normal fine working Logitech or Microsoft mouse.