martes, 30 de agosto de 2011

Google Summer of Code 2011

Once again, this year I participated in the Google Summer of Code as a mentor for Gentoo. The project was called Autodep and its aim was to produce a tool to check the DEPEND and RDEPEND of ebuilds automatically, featuring things like blocking access to non-dependancy files from packages.

It turned out quite well and the student, Alexander Bersenev, worked really hard to finish the project. He is also using one of the clusters he has access to in his university to check the whole portage tree for packages missing dependencies. Quite cool, isn't it?.

You can find the project code Here and the documentation Here

BTW, to create the GuideXML document for this project, I wrote a plugin for Sphinx that throws formatted GuideXML document from the docs. You can find it in my GitHub

Django Dia exporter

Today, I adapted an old piece of code I had laying around in my personal GIT. I wrote this code some time ago when I needed to transform an UML diagram I designed, using the awesome DIA, into a Django models file.

All you need to do is take this code and put it somewhere in ${DIA_SHARE_FOLDER}/python/codegen.py (where DIA_SHARE_FOLDER is generally /usr/share/dia), add an import re at the beginning of that file and this:

dia.register_export ("PyDia Code Generation (Django)", 
"py", DjangoRenderer()) 

at the very end (together with the other generators).

The code is:

class DjangoRenderer(ObjRenderer) :
   
    mapp = {"Datetime" : "DateTime"}

    def __init__(self) :

        ObjRenderer.__init__(self)
        self.processed_kls = set([])

    def end_render(self) :
        re_foreign = re.compile(r"[cC]lass\s*(.*).*")
        field_str = "\t%s = models.%sField(%s) %s\n"
        foreign_str = "\t%s = models.ForeignKey('%s'%s) %s\n"

        f = open(self.filename, "w")
        f.write("from django.db import models %s" % ("\n" * 3))
        for sk in self.klasses.keys() :
            parents = self.klasses[sk].parents + self.klasses[sk].templates
            f.write ("class %s (models.Model):\n" % (sk,))
            
            kls_attributes = dict(self.klasses[sk].attributes)
            attributes = kls_attributes.keys()

            if attributes.__len__() == 0:
                f.write("\tpass\n\n")
            else:
                for sa in attributes :

                    comments = ""

                    attr = kls_attributes[sa]
                    value = attr[2] == "" and "None" or attr[2]
                    comments = attr[3]

                    if attr[3]:
                        comments = "#%s" % attr[3].replace('\n', ' ')
                    try:
                        ty, parms = [x.strip() for x in attr[0].split("|")]
                    except ValueError:
                        ty, parms = (attr[0], "")

                    mobj = re_foreign.match(ty)

                    if mobj:
                        foreign_obj = mobj.groups()[0]
                        f.write(foreign_str % (sa, foreign_obj, 
parms, comments))
                    else:
                        ty = ty.capitalize()
                        ty = self.mapp.get(ty, ty)
                        f.write(field_str % (sa, ty, parms, comments))
                else:
                    f.write("\n" * 2)
        f.close()
        ObjRenderer.end_render(self)


Now. The only thing to take into consideration is, when designing in DIA, you have to be a bit more specific in the Type of properties of your classes.

For instance. If you want a property to be of type string, you should specify it as:

Char | max_length=200, null=True.

This tells the exporter that it should construct a

models.CharField(max_length=200, null=True)

If you want to specify a ForeignKey, the type should be:
Class SomeClass
or if you have options (like related_name), this should be:
Class SomeClass | related_name=some.

Hope this serves you somehow.