Playing with Google Maps API

  • Post author:
  • Post category:Uncategorized

I finally got round to playing with the Google Maps API, and the results can be seen here. I took data from the GnomeWorldWide wiki page and merged in some information from the Planet Gnome FOAF file (which now includes the nicknames and hackergotchis). The code is available here (a BZR branch, but you can easily download the latest versions of the files directly). The code works roughly as follows: Convert the locations info GnomeWorldWide page into an XML file, adding information from the Planet Gnome FOAF file using the makexml.py script. When the main page loads, it requests the XML file previously generated. For each person element in the XML file, a marker is created on the map. When a marker is clicked, an info window is displayed, which is the result of applying an XSLT transformation to the XML node.

Python class advisors

  • Post author:
  • Post category:Uncategorized

Anyone who has played with Zope 3 has probably seen the syntax used to declare what interfaces a particular class implements. It looks something like this: class Foo: implements(IFoo, IBar) ... This leads to the following question: how can a function call inside a class definition's scope affect the resulting class? To understand how this works, a little knowledge of Python metaclasses is needed. Metaclasses In Python, classes are instances of metaclasses. For new-style classes, the default metaclass is type (which happens to be its own metaclass). When you create a new class or subclass, you are creating a new instance of the metaclass. The constructor for a metaclass takes three arguments: the class's name, a tuple of the base classes and a dictionary attributes and methods. So the following two definitions of the class C are equivalent: class C(object): a = 42 C = type('C', (object,), {'a': 42}) The metaclass for a particular class can be picked in a number of ways: A __metaclass__ variable at module or class scope. Use the same metaclass as the base class. If no metaclass is specified through either of these means, an "old style" class is created. I won't cover old style classes here. Now in Python calling a function and creating a new instance look pretty similar. In fact the metaclass machinary doesn't really care. The following two class definitions are also equivalent: class C: __metaclass__ = type def not_the_metaclass(name, bases, attrs): return type(name, bases, attrs) class C: __metaclass__ = not_the_metaclass So using a function or other callable object as the metaclass allows you to hook into the class creation without affecting the type of the resulting class. Class Advisors The tricks performed by the Zope implements() function are wrapped up in the zope.interface.advice module. It does so by making use of the fact that Python programs can inspect their execution stack at runtime. Walk up the stack to where the scope of the class being defined. Check to see if a "__metaclass__" variable has been set, which would indicate the that a metaclass has been specified for this particular class already. Check the module scope for a "__metaclass__" variable. Define a function advise(name, bases, cdict) that does the following: Deduce the metaclass (either what __metaclass__ was set to in the class scope, the module scope, or check base classes). Call the metaclass to create the new class. Do something to the new class (in the case of Zope, it sets what interfaces the class implements). Set the "__metaclass__" variable in the class scope to this function. The actual implementation is a little more complicated to handle the case of registering multiple class advisors for a single class. The actual interface provided is quite simple though: from zope.interface.advice import addClassAdvisor def setA(): def advisor(cls): cls.a = 42 return cls addClassAdvisor(advisor) class C: setA() This simply sets the attribute 'a' on the class after it has been created. Also, since method decorators are implemented as a single function call, they can add…

Pemberton

One of the nice things about living in Perth is the forrests down south. Below is one of the photos I took over the weekend down in Pemberton: The Karri forrest on the other side of Big Brook Dam, Pemberton

Comparison of Configs/Aliases in Bazaar, CVS and Subversion

When a project grows to a certain size, it will probably need a way to share code between multiple software packages they release. In the context of Gnome, one example is the sharing of the libbackground code between Nautilus and gnome-control-center. The simplest way to do this is to just copy over the files in question and manually synchronise them. This is a pain to do, and can lead to problems if changes are made to both copies, so you'd want to avoid it if possible. So most version control systems provide some way to share code in this way. As with the previous articles, I'll focus on Bazaar, CVS and Subversion Unlike the common operations each system implements this feature in a different way, so I'll go over each one in turn and then compare them. CVS When you run the "cvs checkout module" command, CVS will look in the CVSROOT/modules file for the repository. For example, the file might contain the following: module foobar This would tell CVS to check out the foobar directory from the repository into a directory named module when the user asks for module. If no entry is found for a particular name, the directory by that name is checked out from the repository. To compose multiple modules into a single working copy, the ampersand syntax can be used: module foo &bar &baz bar othermodule/bar With this modules file, "cvs checkout module" would give the following working copy: Working Copy Repository module foo module/bar othermodule/bar module/baz baz Operations like tag, commit, update, etc will descend into included modules, so for the most part a user can treat the resulting working copy as a single tree. If a particular branch tag exists on all the included modules, you can even check out a branch of the combined working copy. There are some problems with the support though: While "cvs update" will update the working copy, it won't take into account any changes in CVSROOT/modules. If you've only got write access to part of the repository, and can't write to CVSROOT/modules, then you can't change configurations. While CVS lets you check out old versions of code, you still use the latest version of CVSROOT/modules. This can make it difficult to check out historical versions of the tree. Since "cvs tag" descends into included modules, you can end up with many branch tags on some modules. For instance, the gnome-common/macros directory in Gnome CVS has 282 branch tags, which makes it almost impossible to feed fixes to all those branches. Subversion Rather than a single repository-wide file describing the module configuration for checkouts, Subversion makes use of the svn:externals property on directories. Any directory can have such a property attached. Each line in the property is of the form: subdir [-rrevnum] absolute-uri-of-tree-to-include This will check out each the given tree at the given sub dir when ever "svn checkout" or "svn update" are used. However unlike CVS, "svn commit" will not descend into the included modules. Some…

End Of Fashion

I went to see End of Fashion upstairs at 78s today for their in-store appearance. The tickets were included with the band's single which was pretty nice. They played for about 40 minutes, starting off with some of their well known songs, and then mixed in a few of the new ones off the album. Towards the end, they did a cover of The Red Sun Band's "Devil Song". After the set the band were doing autographs, so I got the liner notes from my copy of the new album signed by all the band members. I like what I've listened to on the album so far.