MrBlog

Apr 11

Played a little with the gource log visualizer today. It is typically used to visualize committed revisions in a revision control system, although any system that logs events of some kind could be made to work with it I suppose.

I happen to have a repository of xaraya going back to 2002 in git, so I thought I’d give it a shot.

…more time passes than originally planned…

Result

8 years of commit history in 10 minutes of video. Produced with gource from a git repository of Xaraya. The video traces the 2.x main branch back to its origin, repository wise. The start is the import of the CVS postnuke repository into Bitkeeper. Since then xaraya has switched to monotone.

Gource settings used:
gource --stop-position 1.0 \
       --camera-mode overview \
       --bloom-intensity 0.18 \
       --user-image-dir .git/avatar \
       --highlight-all-users \
       --output-framerate 60 \
       -s 0.5 \
       -720x576 \
       -a 0.3 \
       --hide filenames \
       --user-scale 1.4 \
       --date-format %Y-%m-%d \
       --disable-progress \
       --output-ppm-stream - \
| ffmpeg -y -b 3000K -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -vpre default gource.mp4

This produced a video of 11 min. 35 seconds. To bring it back to 10 minutes the framerate was increased until the total time fell just below 10 minutes.

I specifically wanted the whole history to be in one video of 10 minutes (the Youtube maximum) which means compromising a bit on the quality. If there are things I can do within these assumptions to improve the video, I’d like to hear them.

Cobra build blog

Nov 17

Before I used an Apple machine with OSX, XEmacs was my editor of choice. Recently I saw Emacs 23 being released with native OSX support in the main repository (well, NextStep support formally, but with Cocoa bindings, which makes it OSX native I guess).

That alone was enough to revisit the old friend. With caution, because I still feel the pain somewhat of switching to TextMate from Xemacs. Another reason is that I sort of lost patience lately with proprietary applications. (TextMate in this case). I’m finding it less doable to have to wait for another developer to be able to find the time to fix issues or provide upgrades within reasonable intervals.

I’ve had a similar experience with Ecto not that long ago. You’d think I’d have learned by now…

Using Emacs again instead of TextMate was actually quite easy. My fingers still ‘remembered’ the keys to press apparently. However, the learning curve to use the editor effectively is still steep. It’s still, and now more than it was with the native build, a joy to work with though.

What keeps (re-)surprising me about Emacs is that there’s apparently a mode or package for anything you want to do to get you 80% of the way and, thanks to the strong customization, the other 20% is around the corner.

I switched last week and since then I’ve discovered a mode that lets me view PDF-files (docview), a mode that connects to my microblog (identica-mode), spent quite a few hours in org-mode organizing my notes and task-lists (including syncing them to my iPhone), editting XML files in nxml-mode and blogging right now with the weblogger package.

I seriously think you can take a bare iron machine, install a minimal linux kernel on it, configure Emacs as the ‘sole interactive application’ on it and still end up with a useful machine, not missing out on any task you’d want to perform.

Sep 29

As a side-effect of Migrating to Claws I lost my OSX addressbook usage, at least for mail. In my company we use OpenERP for CRM, invoicing and other business needs. This means that the majority, if not all the email-addresses I need are in our OpenERP database.

So, it made sense to finish an effort I started earlier, which is to link OpenERP to our LDAP server and thus be able to query information from the OpenERP database through an LDAP interface and have every address available in the Claws addressbook (and the OSX addressbook too for that matter).

In an earlier version of OpenERP we used a specific module for this, which basically published an LDAP entry whenever we changed data in the OpenERP database. This worked, but was a less than ideal solution, not to mention it stopped working on an OpenERP upgrade. The solution I wanted was to have the data available in LDAP immediately. This meant making the LDAP server a “client” of the OpenERP database or, said another way, making the OpenERP database function as an SQL backend to the LDAP server.

Defining an SQL backend for LDAP

Creating an SQL backend for slapd is, albeit terse, documented. I mainly used the information at the OpenLDAP FAQ. The basic idea is that the LDAP-server connects through ODBC to the database, the OpenERP database in our case, and translates information found in relational tables to a subtree of the LDAP hierarchy.

To model this information, you have to create at least 3 tables in the database:

  1. ldap_oc_mappings: which objectClass of LDAP is stored in what table;
  2. ldap_attr_mappings: how attributeTypes of an objectClass are resolved from RDBMS data;
  3. ldap_entries: what’s the DN of an entry, and how the entry relates to its objectClass mapping and to its parent DN;

The FAQ mentions two other tables, which we do not need. The idea is to specify in these three tables how the LDAP server gets to the entries and what they mean. For addressbook-like entries for mail, the defacto objectClass to use for this is something referred to an ‘inetOrgPerson’. The collection of these objects will be below an objectClass ‘organizationalUnit’, giving the simplest ‘tree-relation’ we can think of.

Making the SQL backend use OpenERP

The table ldap_oc-mappings is queried by the LDAP server to map these object classes to tables, so the server knows in which tables to look for the attributes of these two classes. The next two statements insert two rows in that table, one for each object Class, mapping them to the tables ldap_inetOrgPerson and ldap_organizationalUnit, expecting a column id to contain the primary key for the objects.

INSERT INTO ldap_oc_mappings(name,keytbl,keycol) 
    VALUES('inetOrgPerson','ldap_inetOrgPerson','id');
INSERT INTO ldap_oc_mappings(name,keytbl,keycol) 
    VALUES('organizationalUnit','ldap_ organizationalUnit','id');

The ldap_inetOrgPerson is actually a view over the res_partner_address table in OpenERP, so it uses the data directly.

CREATE OR REPLACE VIEW ldap_inetorgperson AS 
  SELECT 
    a.id, 
    btrim((COALESCE(a.firstname,'')||' ') || a.lastname) AS cn, 
    btrim((COALESCE(a.firstname,'')||' ') || a.lastname) AS displayname, 
    a.phone AS telephonenumber, 
    a.lastname AS sn, 
    a.firstname AS givenname, 
    a.fax AS facsimiletelephonenumber, 
    a.mobile, 
    a.private_phone AS homephone, 
    lower(a.email) AS mail, 
    a.street, 
    a.zip AS postalcode
  FROM res_partner_address a
  WHERE 
    a.email  ''  AND 
    a.email  '"' AND 
    a.type  =  'contact';

This gives a dataset of all people who actually have an email-address registered in the OpenERP database. The column aliases are not needed as such, but make the construction of the ldap_attr_mappings table a bit easier. The second objectClass we registered in ldap_oc_mappings, organizationalUnit can be modelled with one simple row in the table ldap_organizationalUnit:

INSERT INTO ldap_organizationalUnit(name) VALUES ('addressbook');

With that row, we basically define one organizational unit in our simple tree named addressbook under which all our objects of type inetOrgPerson will be placed.

So, at this point we have 2 objectClasses registered, we have created the raw data for them. What’s left? Two things, first, we need to define how the attributes of the raw data relate to the object attributes. For this, the table ldap_attr_mappings contains a row for each attribute. For the telephoneNumber attribute, the data row is as follows:

INSERT INTO ldap_attr_mappings(
        oc_map_id,name,sel_expr,from_tbls,join_where
    ) 
VALUES(
    1,'telephoneNumber','telephoneNumber',ldap_inetOrgPerson,'1=1'
);

This says basically to the ldap server that in order to get to the telephoneNumber attribute for inetOrgPerson (oc_map_id 1 refers to the first row in the ldap_oc_mappings table), it needs to look in the table ldap_inetOrgPerson, use the same attribute name for the column and apply no special where clause. It is basically a recipe for the server to translate an LDAP request into an SQL query.

For each of the columns in the ldap_inetOrgPerson view, such a row needs to be present in the ldap_attr_mappings table.

Still here? The final step is to create the third meta table ldap_entries. This table is basically the lookup table to map ldap-index values to rdbms-index values. I have defined ldap_entries as a view on the raw data as follows:

 CREATE OR REPLACE VIEW ldap_entries AS 
   SELECT 
     0 AS id, 
     'ou=addressbook,dc=hsdev,dc=com' AS dn, 
     2 AS oc_map_id, 
     0 AS parent, 
     0 AS keyval
    UNION 
   SELECT 
     ldap_inetorgperson.id, 
     ('cn=' || ldap_inetorgperson.cn) || 
     ',ou=addressbook,dc=hsdev,dc=com' AS dn, 
     1 AS oc_map_id, 
     0 AS parent, 
     ldap_inetorgperson.id AS keyval
   FROM ldap_inetorgperson;

This does 2 things, it refers the ldap addres ou=addressbook,dc=hsdev,dc=com as the organizational unit (oc_map_id = 2) and assigns that ID 0. The second part of the UNION then formats each of the inetOrgPerson addresses as an LDAP address in the constructed tree (mine would be: cn=Marcel van der Boom,ou=addressbook,dc=hsdev,dc=com) and maps it to the ID in the raw data table (keyval) and puts the organizational unit as its parent.

With the above a minimal proof of concept can be constructed so that each partner address which has an email-address shows up in LDAP. After this, it’s a matter of configuring the email-client using the ou=addressbook,dc=hsdev,dc=com as a search base.

Here’s a picture of my record in the claws address book:

screen_011.png

The same concept can be applied to other data in OpenERP (the partner records themselves come to mind or user accounts). It would not be that hard to wrap the above into an OpenERP module to manage this. Once the LDAP server has a configuration to use an SQL backend, all configuration can be done in OpenERP itself, modelling access using the meta tables. Perhaps I’ll do that at some point, if some of my customers would benefit from this too.

Sep 18

After installing Snow Leopard I was left with a page of programs and plugins that needed attention because of the upgrade. Most of these were little nuisances and just needed a little reconfiguration. There were a couple of things where Apple decided to rename an app or hide it otherwise from view (Kerberos Ticket manager [...]

Read…
Aug 24

The number of accounts I have on useful networks, social or otherwise, has been on an increasing trend-line for a while. In the beginning, things were simple, but it gets messy pretty quick. One feature which these networks share in some form or another are “status notices”. Starting with the ‘chat status’ in the Instant [...]

Read…
Aug 05

Last Monday was my 40th birthday. I’m kind of used to having a quiet birthday; most of the people are always on holidays during this time of year. My girlfriend had organised a two day trip, she usually does something like that for my birthday, to an unknown destination to do something unknown. We were [...]

Read…
Jun 22

Today, I have been fighting playing the html code in templates of WordPress and the CSS of the site. I wanted to display the posts of the Cobra blog a bit more visible than an RSS feed, but not (like it was) importing every entry into this blog, so I came up with a block [...]

Read…
Jun 19

After quite a long period of using ecto, I have switched to using Marsedit. Ecto got sold beginning last year by Adriaan to Illuminix. There has been no update of ecto since and I’m seeing no signs of improvement either. Does this mean ecto as a product is bad? No. I still love the idea [...]

Read…
Apr 03

While looking for a solution to a LaTeX path search problem I ran into…

Read…
Feb 19

As of last thursday, I’ve started to migrate everything in our network to use GSSAPI or Kerberos authentication. The amount of passwords and accounts grew over our heads and the inevitable “I’ll use the same everywhere” started to be apparent. The actual preparation for this already started more than a year ago. We are in [...]

Read…