Entries in the Category “programming”

One vim server per desktop

written by nicoe, on Jan 27, 2011 9:14:00 PM.

I usually organize my desktop 'semantically'. The first desktop is where I do my main development, the second one is where I test those developments, the third one is used for my tests in bpython or when I need to write some little examples. The last desktops is where I have my luakit windows and the next to last one is where I have my gajim, xchat and mutt windows. The five other desktops are usually empty but are there in case of need.

And here is what my typical desktop looks like:

/static/nicoe/thumb_desktop_20110127.png

One thing that annoy the hell out of me is the fact that I cannot open a specific file in my already running vim from one of the command line. So today, I finally stop complaining about that and I read about the remote option of vim.

So here is my script that will create a server per desktop and if a server is already running on this desktop than it will connect to it and open the file into it.

#!/bin/sh
if test -n "$DISPLAY"; then
    desktop="SERVER$(wmctrl -d | grep '\*' | cut -f 1 -d ' ')"
    vim --serverlist | grep $desktop
    if [ $? -eq 1 ]
    then
        urxvtcd +sb -geometry 80x57 -e vim --servername $desktop $* >> /dev/null &
    else
        vim --servername $desktop --remote $*
    fi
else
    vim $*
fi

The trickier part was finding the wmctrl tool which is a nice utility to interact through the command line with EWMH/NetWM compatible X Window managers (and thus with my the greatest WM of all time : openbox ;)).

Using distant OpenERP objects pythonically

written by nicoe, on May 19, 2010 10:03:00 PM.

At work we have a project to realize a pygtk POS interface for OpenERP. It is getting closer and closer everyday and after much hagglings to create the right UI, I had to connect it to the underlying server. Using the so called netrpc protocol out of the box is not really the most pythonic you can get.

So I came up with those classes that made me fells just like home when I needed to work with the OpenERP objects.

class MetaOEObject(type):

  def __init__(cls, name, bases, dict):
      super(MetaOEObject, cls).__init__(name, bases, dict)
      cls.proxy = Config.client.create_proxy(Config.database,
                                             dict['dotted_name'])
      cls.fields = cls.proxy.fields_get()
      OEObject.proxies[dict['dotted_name']] = cls


class OEObject(object):

  proxies = {}

  def __init__(self, id=None):
      self.id = id
      if id is not None:
          self.value = self.proxy.read(id)

  @classmethod
  def select(cls, condition):
      ids = cls.proxy.search(condition)
      return [cls(id) for id in ids]

  def __getattr__(self, name):
      if name not in self.fields:
          raise AttributeError
      elif self.fields[name]['type'] == 'many2one':
          oeobj = OEObject.proxies[self.fields[name]['relation']]
          if self.value[name]:
              return oeobj(self.value[name][0])
          else:
              return None
      elif self.fields[name]['type'] == 'one2many':
          oeobj = OEObject.proxies[self.fields[name]['relation']]
          return [oeobj(id) for ids in self.value[name]]
      elif self.fields[name]['type'] == 'binary':
          if not self.value[name]:
              return None
          filename = os.tempnam()
          fd = open(filename, 'w')
          fd.write(base64.b64decode(self.value[name]))
          fd.flush()
          return filename
      return self.value[name]

  def __str__(self):
      print self.dotted_name, self.id
      return '<%s (%d)>' % (self.dotted_name, self.id)


class Category(OEObject):
  __metaclass__ = MetaOEObject
  dotted_name = 'product.category'


class Product(OEObject):
  __metaclass__ = MetaOEObject
  dotted_name = 'product.product'

Those kind of classes makes use of metaclasses so that proxy and fields are class-attributes which seems nicer to me. It allows me write pieces of code like this

for category in Category.select([('parent_id', '=', None)]):
    page = self.create_category_page(category, notebook)
    for product in Product.select([('categ_id', '=', category.id)]):
        page.add_product(product)

Which populates a GtkIconView into a notebook used to display products sorted by categories.

relatorio 0.5 is released

written by nicoe, on Jan 23, 2009 1:23:00 PM.

I'm quite happy to announce the new release of relatorio. Thanks to the sponsoring of b2ck, we added some nice features such as looping on columns in OOTemplates and the improvements in the closing/opening tag detection algorithm, many thanks to them !

Here is the full changelog:

  • Added Text and XML Template to the TemplateLoader
  • Splitted mimetypes and ids in the ReportRepository
  • RelatorioStream now has a __str__ method
  • OOTemplate: ChartTemplate can be included
  • OOTemplate: Correctly handle content type in the table cells
  • OOTemplate: Better closing/opening tag detection algorithm
  • OOTemplate: Looping on columns now work in OOTemplates
  • OOTemplate: Using compression

And here is a screenshot of the looping feature:

Loops on columns work now !

Well the colours are not great but I'm not the one to blame !