fíam

(rhymes with liam)

  • Blango, django-geonames, oauthsp and wapi hosted at GitHub

    Feb. 17, 2009 at 01:22:19 CET

    I've finished moving some of my git repos to GitHub. You can now check Blango, django-geonames, oauthsp and wapi from there. Those are, from now on, the official repos. The old ones at byNotes have already been closed.

  • Leaving byNotes

    Feb. 15, 2009 at 23:18:54 CET

    Well, let me start by explaining all those mails about byNotes I haven't answered in the last few months. Around mid November I got contacted by the recruiting staff of a social network. At that time, I was still working in the project for my degree (computer science students in Spain are required to write a project for the university in order to get the degree) and I wanted to concentrate on it, but I decided to just take the interviews just in case. They finally told me they wanted me to join them and we agreed to continue the negotiations once I had finished my project.

    Fast forward to January, my project is done and christmas holidays are gone, time to reestablish negotiations. Salary is good, schedule is very good (telecommuting 99% of the time) but there's something bad: I must leave byNotes, since management considers it's competing with them.

    It wasn't an easy decision, but it was the best option. byNotes has been very fun, but also such a time drain to me, and I haven't got any single eurocent from it. Plus, I'm a coder, not a designer nor a business guy, and I don't have too much money to spend on it. So I really don't think I could make it profitable.

    As of today, I've been already working for my new employer for some weeks. My name still figures as the domain holder for bynotes.com and in some about pages, but that should change soon. I'm sure the new maintainers will do a good job at keeping the project alive.

    And now comes the interesting part for you, developers. What happens with my free software projects? Well, I'm keeping all of them, but I won't be able to spend some much time working on them. Since I won't be owning byNotes anymore, I'm moving them to GitHub and using LightHouse for ticket tracking. The following is the list of projects I'll be moving to GitHub in the next few days:

    • Django projects

      • Blango
      • wapi
      • django-bundles
      • django-geonames
      • django-geocoding
      • django-storage
      • django-mediafiles
      • django-oauthsp
    • Python projects

      • ffmpeg bindings
    • Cocoa projects

      • My fork of OAuthConsumer (fixing some bugs, implementing some goodies)
      • BNMaps (map framework)
  • Using a metaclass for registering template tags

    Jan. 8, 2009 at 17:59:45 CET

    Writing your template tags requires too much boilerplate code. Period. I think we all agree on that. Let's see how we can improve it.

    A lot of times I find myself writing code like this (error handling omitted for clarity):

    @register.tag
    def my_menu(parser, token):
        tag_name, argument1, argument2 = token.split_contents()
    
        return MyMenuNode(argument1, argument2)
    
    class MyMenuNode(template.Node):
        def __init__(self, argument1, argument2):
             ...
    

    We are specifying the argument count and the template tag name twice, not exactly DRY friendly ;). After evaluating the solutions coming to my mind, I decided to go with a metaclass based approach, keeping the magic to a minimum.

    import inspect
    from django import template
    
    register = template.Library()
    
    class NodeType(type):
        def __init__(mcs, name, bases, dct):
            super(NodeType, mcs).__init__(name, bases, dct) 
            if not mcs.is_node(name, dct):
                tag_name = ''.join(char if char.islower() else '_%s' % char.lower() for char in name)[1:-5]
                init = mcs.get_init(bases, dct)
                (args, varargs, varkw, defaults) = inspect.getargspec(init)
                arg_count = len(args) # not exactly arg count, but this way we avoid adding one in tag_function
                def tag_function(parser, token):
                    arguments = token.split_contents()
                    if len(arguments) != arg_count:
                        raise template.TemplateSyntaxError('%s tag requires %d arguments' % (arguments[0], arg_count - 1)) 
                    return mcs(*arguments[1:])
    
                register.tag(name=tag_name, compile_function=tag_function)
    
        def is_node(mcs, name, dct):
            return name == 'Node' and dct['__module__'] == __name__
    
        def get_init(mcs, bases, dct):
            if '__init__' in dct:
                return dct['__init__']
    
            for base in bases:
                init = mcs.get_bases(base.__bases__, base.__dict__)
                if init:
                    return init
    
    
    class Node(template.Node):
        __metaclass__ = NodeType
    

    Inheriting from Node, we can now define a new tag just by creating a new class, which gets automatically registered:

    class MyMenuNode(Node):
        def __init__(self, request):
            self.request = template.Variable(request)
    
        def render(self, context):
            # do something with self.request
            return 'my menu markup'
    

    As soon as we load the file containing this code, we'll have a tag named my_menu defined, which takes the current request as its only argument.

    How do you deal with template tags? Do you copy and paste your boilerplate code or have you found a better solution than this one?

  • Intrepid Ibex will break your VirtualHost

    Oct. 31, 2008 at 13:56:49 CET

    After upgrading the server hosting this blog to Intepid Ibex, I discovered all my VirtualHost weren't working. Since I couldn't find any solution searching in Google, my next approach was downloading the older apache2 package and doing a diff between the supplied configurations.

    It seems Debian developers decided to change this line in ports.conf:

    NameVirtualHost *
    

    To this:

    NameVirtualHost *:80
    

    This means your VirtualHosts declared with <VirtualHost *> (or <VirtualHost x.y.z.t>) will no longer work. For restoring them, change the following:

    <VirtualHost *>
    

    To:

     <VirtualHost *:80>
    

    Or, alternativelly, cd to /etc/apache2/sites-available/ and execute the following command:

    sudo perl -pi -e 's/\<VirtualHost([^\:]+)\>/\<VirtualHost $1:80\>/' *
    
  • Blango now hosted at byNotes repository

    Oct. 31, 2008 at 10:38:49 CET

    Blango is now hosted at the byNotes source code repository and I'll start doing proper releases soon.

    However, I feel like Blango has all I need and I don't see any new features I could add (you can check the current features at the project page. How would you enhance it? Leave a comment with your cool idea!