Skip to content


Wii head tracking explained: how it works

I wrote about a cool Wii-mote hack yesterday, which provides a richer 3D experience, based on the movement of the head of the user. In this post (and if all goes well some following posts) I’ll try to explain some of the basics how this works. I won’t get into geometrical or mathematical details, not to bore the readers too much ;-)

I start with very basic rendering of linear distance changes.
Continued…

Posted in Virtual Reality.

Tagged with , , , , .


More Wii innovation: head tracking

Someone just sent a mail to the xorg and compiz mailing lists, pointing to this YouTube video regarding a new way of (ab)using the Nintendo Wii to control a virtual environment. If you didn’t see it yet, check it out, it’s rather impressive:

[youtube]Jd3-eiid-Uw[/youtube]

I don’t know whether this could actually be useful in a pure desktop environment, but for games (although I’m no gamer myself) I could imaging this offers a whole new spatial experience. Up to Nintendo or third-party vendors to design and commercialize the necessary gadgets or remotes.

Too bad there’s not enough empty space around our TV at home, otherwise I think I’d buy a Wii, love the tennis game ;-)

Posted in Technology.

Tagged with , , , , .


Cellphone, Bluetooth and reddit rant

Got a new cellphone today, a Nokia 6300. Pretty nice phone, except I can’t get the SyncML support to work on my Linux system… SyncML over OBEX is reported several times not to work, although the OpenSuSE wiki claims it should work… Most sources say one should use the gnokii OpenSync plugin, which does work, but has one major drawback: even when configuring the phone only to use it’s internal memory for contact list storage, the gnokii plugin will also sync the SIM content, which I copied to the phone memory. Result: duplication in my Evolution contact list. I guess I should patch libopensync-gnokii adding a configuration field providing the possibility to select only one storage container? Or try to figure out whether the Novell/SuSE guys have a patch for libsyncml?

Does anyone know whether there’s a Tango-style theme for this device? ;-)

Little unrelated rant: thanks to my blog statistics I found out my recent article on AJAX form validation with Django got featured on programming.reddit.com. I also saw some people commented on my article over there, comments on which I’ll reply later. Now I was wondering, why do people leave comments over there, and not beneath the blog entry, where everyone interested in the subject can easily find it, get into the discussion, the blog author will certainly read your comment, reply on it (as most likely he doesn’t read news-site X where user Y can post his comment, or news-site Z where Q posts his comments, etc, or he got no account on X or Z to be able to reply),… It’s as if I’d start my very own secret little webpage where I put links to all blog entries I want to comment on, and write the comment on that page, but don’t even do any trackback ping *sigh*

Oh and, those claiming AJAX form validation is bad: indeed, in some cases it is, except when you, eg, want to do “check username isn’t already registered”-style validation. If you’d have commented on the right place, we could have discussed this where it was appropriate.

Posted in Technology.

Tagged with , , , , , .


Django generic AJAX form validation

I just created a generic view for Django which allows a developer to easily add AJAX-style form validation to a newforms based form.

The system needs one server-side view, and some client-side JavaScript. You can find the view code in my Django snippets Git repository. The view only works with POST requests. It takes a standard HttpRequest and some options:

  • form_class: this parameter defines the newforms class to validate against. It can be specified in the extra args parameter of the view’s urlconf. If you don’t specify it, the ‘form_class’ POST field will be used. If this doesn’t exist either, an exception is raised. The parameter can be a newforms form instance, a string, or a class (which should be a subclass of BaseForm).
  • format: the serialization format to use. Currently only ‘json’ is supported.
  • args: extra argument list to provide to the form constructor (shouldn’t be provided in most cases)
  • kwargs: extra argument dics to provide to the form constructor (shouldn’t be provided in most cases)

Next to the server-side view you’ll need some pretty basic JavaScript code on client side. I use JQuery and the JQuery Form plugin. Here’s some sample code, assuming the form ID is ‘my_form’, and form fields are represented like this:

<p id="{{ form.field.name }}_container"><label for="{{ form.field.auto_id }}">{{ form.field.label|capfirst }}:</label>{{ form.field }}
{% if form.field.errors %}<span id="{{ form.field.name }}_error" class="error">{{ form.field.errors.0 }}</span>{% endif %}
</p>

Here’s the corresponding JavaScript code:

function do_something() {
}
function process_validation(data) {
    if(data['form_valid'] == true) {
        do_something();
        return;
    }
    for(var field in data["errors"]) {
        errors = data["errors"][field]
        if(errors.length > 0) {
            error = errors[0];
            if($("#" + field + "_error").length == 0) {
                s = $("<br /><span style=\"display: none;\" id=\"" + field + "_error\" class=\"error\">" + error + "</span>");
                $("#" + field + "_container").append(s);
            }
            $("#" + field + "_error").html(error).fadeIn("slow");
        }
    }
}
function validate_form(data) {
    data.push({name: 'form_class', value: 'project.application.forms.ApplicationForm'});
    $.post("{% url validate_form %}", data, process_validation, "json");
}
$(document).ready(function() {
    $("#my_form").submit(function() {
        data = $("#my_form").formToArray();
        $(".error").fadeOut("slow");
        validate_form(data);
        return false;
    });
});

Obviously this should be changed to suit your needs.

I hope this code can be useful for someone…

Posted in Development.

Tagged with , , , , , , , .


Filesystem issues and django-couchdb work

Last night, when shutting down my laptop (which had been up for quite a long time because of suspend/resume niceness), it crashed. I don’t know what exactly happened: pressed the GNOME’s logout button, applications were closed, until only my background was visible, then the system locked up, so I suspect my X server (some part of it, GPU driver (fglrx) might be the bad guy). I was able to sysrq s u o, so I thought everything would be relatively fine.

This morning I powered on my system, and while booting, fsck of some partitions was taking a rather long time. It’s pretty normal fsck was taking somewhat longer, but not thát long… I’m using JFS on most logical volumes.

When the consistency check of my /home partition was done, a whole load of invalid files was displayed and later on moved to lost+found: 34068 files. Once booted, I scanned my filesystems again, rebooted, logged in, started X. Everything started fine, until I launched Evolution: it presented my the ‘initial run’ wizard. Other issues (on first sight): all Firefox cookies were gone, and Pidgin’s blist.xml was corrupted. When using my old computer (which had frequent lockups on heavy IO usage) these last 2 issues happened a lot too, which is highly annoying, especially the blist.xml thing as I can’t see any reason to keep this file opened for long periods?

Luckily I was able to get my Evolution up and running again by restoring it’s GConf settings and ~/.evolution using some old backup (15/10/07). I guess I should backup more regularly… Next to this I hope I won’t find any other corrupted files, so the ones in lost+found are just Evolution email files and Firefox caches.

Anyway, here’s a screenshot displaying some of the initial and hackish work I’ve done this evening on integrating Django and CouchDB as I wrote about yesterday:

Django and CouchDB first shot

As you can see, currently I’m able to edit fields of an object. There’s one major condition: an object with the given ID should already exist in the ‘database’ which makes the current code rather useless, but hey ;-) I’ll add object creation functionality later tonight or tomorrow.

Current code is very expensive too, doing way too many queries to CouchDB, mainly in client.py. This most certainly needs work.

Upgraded my WordPress installation to the latest release, 2.3.2, in about 5 seconds. Got to love svn switch (although maybe I should start using git-svn for this installation too and git-pull the release branch in my local copy).

Posted in Development, Linux.

Tagged with , , , , , , , , , .


CouchDB with Python

Today I’ve been investigating CouchDB a little better (only heard some rumors about it before). It’s actually a pretty nice technology which can, in some places, be pretty useful… I tend to compare it to caching serialized PHP associative arrays or Python dict’s in a Memcached server using some specific prefixes, except it’s not really memory-based (it’s persistent), you get a complete query interface (views), there’s dataset versioning support (!), etc. While writing this I start to wonder what similarities I ever saw between CouchDB and a Python pickled dict in Memcached…

Anyway, one use case I saw was site user profiles: profile data is most of the time not relational at all, so why store it in a relational database, which makes it sometimes rather hard to add extra profile information fields, unless you use some dirty ‘save serialized form’ trick, which renders your data unqueryable? Storing profile information (using eg. a user’s primary email address or login name as key for the user profile document) in CouchDB allows you to extend the profile “schema” easily: just add a field to your profile editting form, make sure it’s processed server-side an stored in the profile document, and add some extra code to your profile rendering template so the extra field get displayed too. No need to alter SQL tables at all!

As in my last site project I also have some sort of user profiles, I was thinking about using CouchDB for storage of these objects. As the site is written using Django, it would be nice to be able to define a standard Django model for the profile, which would be stored in CouchDB, not insome SQL server. This way you can still enjoy newforms goodness, among others.

So I started some new project, called django-couchdb, which should in time provide a model base class (similar to django.db.models.Model), corresponding managers to query the data, and so on. I don’t know (yet) whether all this is possible to achieve, anyway, I started by creating a very basic Python class which allows you to access a CouchDB server in a very Pythonic way: using dicts. A Server is a dict consisting of Databases, a Database is a dict of Documents. All this implemented thanks to the goodness of the DictMixin base class.

The client is not finished yet, at least 3 TODO items are on my list:

  • Error/Exception handling
  • Revision handling
  • View support

Currently there is no support for any of these. Views should be easy to add, error handling a little harder. I think revision handling is the hardest part, escpecially on figuring out how to provide this functionality in a Pythonic manner.

You can find the current code in this Git repository. Patches or external branches are very welcome!

By the way: the website I referred to before has been launched. It’s only of any use (well, maybe) for dutch-speaking users though. You can visit it here. Yes, the template will change.

Posted in Development.

Tagged with , , .


First bug report ever

Yesterday I came across my (most likely, as far as I can remember) very first bug report ever, here, filed on the 16th of november 2002. A bug in Mandrake 8.2 (kernel 2.4.18, XFree86 4.2.0, KDE 3.0RC2) because of which I was unable to use my mouse in X. The machine was an Acer Pentium1 166MHz with 40MB of RAM inside and an S3Virge video adapter.

This was not my first Linux experience: my first installation ever, on the same machine, was using a SuSe sample CD my dad got at Cebit2000. This was an evaluation copy of SuSe 6.4, providing kernel 2.2.14, XFree86 3.3.6 and KDE 1.1.2 (well, I can’t remember, that’s what the web tells me now).

Compared to those days (although not that long ago) installing and (especially) using a Linux desktop nowadays could be called somewhat easier :-)

So, have you got any memories of your very first Linux install or a reference to your earliest bug report?

Posted in Linux.

Tagged with , .


Django domain redirect middleware

Most web developers know it’s possible to serve one site on several domains or subdomains, using eg. the ServerAlias Apache directive. Sometimes this behaviour is not wanted: you want your main domain to be “foo.tld”, although “www.foo.tld” should work too, and maybe even some completely different domains.

This way it’s possible to have permalinks, and you won’t get bad points from search engine spiders who don’t like the same content to be available on several URIs.

In Django there’s the PREPEND_WWW setting, which will force all requests to be redirected to www.foo.bar when coming in on foo.bar, etc. This functionality is rather limited though. As I wanted to be able to have one unique main domain in my new application, I wrote a middleware which accomplishes this in a very generic way, using the django.contrib.sites framework. You need to add this middleware before all others in your settings file, even before the CommonMiddleware.

Here’s the code:

from django.contrib.sites.models import Site
from django.http import HttpResponsePermanentRedirect
from django.core.urlresolvers import resolve
from django.core import urlresolvers
from django.utils.http import urlquote

class DomainRedirectMiddleware(object):
    def process_request(self, request):
        host = request.get_host()
        site = Site.objects.get_current()

        if host == site.domain:
            return None

        # Only redirect if the request is a valid path
        try:
            # One issue here: won't work when using django.contrib.flatpages
            # TODO: Make this work with flatpages :-) 
            resolve(request.path)
        except urlresolvers.Resolver404:
            return None

        new_uri = '%s://%s%s%s' % (
                request.is_secure() and 'https' or 'http',
                site.domain,
                urlquote(request.path),
                (request.method == 'GET' and len(request.GET) > 0) and '?%s' % request.GET.urlencode() or ''
            )

        return HttpResponsePermanentRedirect(new_uri)

Make sure you got the sites framework set up correctly when using this! As noted in the code, this doesn’t work with the Flatpages framework yet, this is TODO.

Posted in Development.

Tagged with , .


Two Django snippets

Last 2-3 days I’ve been working on this new site project. As (almost) all web projects I started last 2 years, I’m using the Django framework to develop the site, as I just love it for several reasons.

Tonight I’d like to share 2 snippets. The first one is one I use quite regularly. It’s a replacement for django.shortcuts.render_to_response, which requires one to always add a RequestContent keyword argument to be able to access MEDIA_URL etc in templates.

This replacement (which I mostly put in utils/shortcuts.py) is completely API-compatible with the default render_to_response implementation, but if you pass it a request object as first parameter (and no context_instance), it automaticly uses a RequestContext.

from django.shortcuts import render_to_response as real_render_to_response
from django.http import HttpRequest
from django.template.context import RequestContext

def render_to_response(*args, **kwargs):
    # Check old API
    if len(args) > 0 and not isinstance(args[0], HttpRequest):
        return real_render_to_response(*args, **kwargs)
    if not kwargs.get('context_instance', None):
        kwargs['context_instance'] = RequestContext(args[0])

    return real_render_to_response(*args[1:], **kwargs)

The second one is an custom form which can be used with the django-contact-form application. It automaticly uses the name and email address of the user if logged in, otherwise provides the standard text input fields.

It might be a good example of how to implement a custom widget, and how to set per-form-instance values of widgets.

Do note you will need to change some things around line 29.

class ConstOrTextInput(forms.TextInput):
    def __init__(self, *args, **kwargs):
        super(ConstOrTextInput, self).__init__(*args, **kwargs)
        self.const_value = None

    def value_from_datadict(self, *args, **kwargs):
        if not self.const_value:
            return super(forms.TextInput, self).value_from_datadict(*args, **kwargs)
        return self.const_value

        def render(self, *args, **kwargs):
            if not self.const_value:
                return super(forms.TextInput, self).render(*args, **kwargs)
            else:
                from django.utils.safestring import mark_safe
                return mark_safe(u'' % self.const_value)

class UserdataContactForm(ContactForm):
    name = forms.CharField(max_length=100,
                                           widget=ConstOrTextInput(attrs=attrs_dict),
                                           label=u'Your name')
    email = forms.EmailField(widget=ConstOrTextInput(attrs=dict(attrs_dict,
                                           maxlength=200)),
                                           label=u'Your email address')

    def __init__(self, data=None, request=None, *args, **kwargs):
        super(UserdataContactForm, self).__init__(data, request, *args, **kwargs)
        if request.user.is_authenticated():
            self.fields['name'].widget.const_value = request.user.get_profile().get_display()
            self.fields['email'].widget.const_value = request.user.email
        else:
            self.fields['name'].widget.const_value = None
            self.fields['email'].widget.const_value = None

    def from_email(self):
        if self.request and self.request.user.is_authenticated():
            return self.request.user.email
        else:
            return super(UserdataContactForm, self).from_email

I added this to the end of the forms.py from the django-contact-form application, if you place it elsewhere, some more changes might be necessary.

I hope this is useful for at least someone!

Posted in Development.

Tagged with , .


CSS preprocessor

Today I’ve been working on a little website project, just for fun. Once again, I wish there was some good CSS preprocessor available, as sometimes (especially during development, before cleaning up the CSS) you need to alter several values in several places to change one little thing.

Some examples:

  • Change some font color, which is used in several classes
  • Change size of objects (eg. if you got 3 divs, which need to span 100%, and originally they were 33% 33% 34%, and you want the first one to be 50% and split the remaining space between the other divs, you need to edit all 3 values)

This makes editting CSS files very error-prone.

A neat solution for this would be some sort of CSS preprocessor, so you could do things like this:

#define COLOR1 black
#define COLOR2 #ABABAB

.foo {
width: 40%;
color: COLOR1;
height: 10px;
}
.bar {
width: $(100% - .foo.width);
height: $(2 * .foo.height);
}

This is, obviously, just a sample of what could be possible.

Did anyone ever work on something alike, or got some other method to tackle this?

Posted in Webdesign.