Login

4 jours ardents

Written on 2008-07-14 21:24.

J'ai passé un bon petit week-end musical aux ardentes, quatre jours de gadoue et de mélange de styles musicaux.

Dans les très bons moments: Camille et son incroyable human beatbox, Trentemøller qui a joué sous un déluge tout à fait en adéquation avec le ton de l'album, Apparat, Sage Francis et son hip-hop sans concessions musicales ou politiques, les Puppetmastaz, la drum'n'bass avec kiki, le Cinematic Orchestra et leurs sons jazzy, les imparables Dionysos et Monsieur Alain Bashung et sa voix incroyable.

Évidemment, en plus il y a l'ambiance et ce genre de grand regroupement est propice aux retrouvailles avec tous ces gens qu'on ne voit que trop peu : les infos/ingés, les anciens de St-Jean, les Nicolas.

Et puis il y a les inconnus sympas qui vous offrent un gateau, une chope : ça fait oublier tous les idiots qui ne sont la que pour la frime et qui parlent à longueur de concerts.

Note to myself

Written on 2008-07-09 16:42.

How to display numbers and monetary value in a locale aware way

>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
>>> locale.currency(6512.345)
'6512,35 \xe2\x82\xac'
>>> print locale.currency(6512.345)
6512,35 €
>>> print locale.currency(6512.345, grouping=True)
6.512,35 €
>>> print locale.currency(6512.345, grouping=True, international=True)
6.512,35 EUR
>>> locale.format('%#2.3f', 6512.345, True, False)
'6.512,345'

More info in the python documentation for the locale module

Announcing relatorio !

Written on 2008-07-07 10:28.

Today, I'm very proud to announce the birth of our new project : relatorio, a reporting module able to generate a whole lot of different document types from templates. relatorio is a Portuguese word that means report, I choose Portuguese because the Spanish/French words did not sound good enough.

Technically, we are using genshi and trml2pdf (the homepage does not work anymore) to create PDF and OpenOffice documents.

In this post I'll show you how easy it is to create OpenOffice documents using relatorio. First we need some objects to work on. Let's create a fake invoice object:

class Invoice(dict):
    @property
    def total(self):
        return reduce(operator.add, (l['amount'] for l in self['lines']), 0)
    @property
    def vat(self):
        return self.total * 0.21
inv = Invoice(customer={'name': 'John Bonham',
                        'address': {'street': 'Smirnov street',
                                    'zip': 1000,
                                    'city': 'Montreux'}},
              lines=[{'item': {'name': 'Vodka 70cl',
                               'reference': 'VDKA-001',
                               'price': 10.34},
                      'quantity': 7,
                      'amount': 7*10.34},
                     {'item': {'name': 'Cognac 70cl',
                               'reference': 'CGNC-067',
                               'price': 13.46},
                      'quantity': 12,
                      'amount': 12*13.46},
                     {'item': {'name': 'Sparkling water 25cl',
                               'reference': 'WATR-007',
                               'price': 0.4},
                      'quantity': 1,
                      'amount': 0.4},
                     {'item': {'name': 'Good customer rebate',
                               'reference': 'BONM-001',
                               'price': -20},
                      'quantity': 1,
                      'amount': -20},
                    ],
              id='MZY-20080703',
              status='late')

So we created an invoice for the famous Led Zeppelin's drummer and his favorite addiction.

The next thing to do is to create a template for invoices. We will use the one displayed below. To create the genshi directives, you just need to create a text-type placeholder [1] field, and fill it with the expression you want to use.

A simple invoice OpenOffice document template

You can now start to use relatorio to create John Bonham's invoice.

from relatorio.templates.odt import Template
basic = Template(source=None, filepath='basic.odt')
file('bonham_basic.odt', 'w').write(basic.generate(o=inv).getvalue())

On the first line we import the odt Template engine. This class has the same signature as the one from genshi but uses only the filepath arguments. It returns a StringIO object that can be used to write the report on the disc.

The simple template filled with Bonham's invoice

And so here is our invoice with all the fields completed according to the Invoice object we created earlier. Notice how the style we set in the template are also applied in the resulting invoice.

We made use of the py:for directive. But it is not the only genshi directive supported by the relatorio odt plugin, it also support py:if, py:choose/py:when/py:otherwise and py:with.

An example demonstrating all the genshi directives used by relatorio

We also included a simple report repository that allows you to link your reports to a class and retrieve them by the name you gave them or by the mimetype they output.

>>> import relatorio
>>> repos = relatorio.ReportRepository()
>>> repos.add_report(Invoice, 'application/vnd.oasis.opendocument.text',
...                  'basic.odt', report_name='basic')
>>> repos.add_report(Invoice, 'application/vnd.oasis.opendocument.text',
...                  'invoice.odt', report_name='complicated')
>>> repos.reports[Invoice]['basic']
('application/vnd.oasis.opendocument.text',
 <relatorio report on /home/nicoe/tmp/relatorio_demo/basic.odt>)
>>> repos.reports[Invoice]['application/vnd.oasis.opendocument.text']
[('basic',
  <relatorio report on /home/nicoe/tmp/relatorio_demo/basic.odt>),
 ('complicated',
  <relatorio report on /home/nicoe/tmp/relatorio_demo/invoice.odt>)]

Moreover, the report repository works with a TemplateLoader object that automatically reloads a template when the file used to create it has been modified.

When using the report repository, you're also working with the relatorio reports, those are proxies over a Template that enables you to pre-process data before rendering it. The default behavior is to bind your object to the template variable o and all other arguments to the variable args. Here is an example showing you how you could use it in cherrypy to make the request object available to all your reports.

class OHFactory(relatorio.DefaultFactory):
   def __call__(self, obj, **kwargs):
       data = {}
       data['o'] = obj
       data['args'] = kwargs
       data['request'] = cherrypy.request
       return data

I hope you will find this module usefull and abuse it in every way.

[1]Created using Ctrl-F2 with the standard mapping of OpenOffice.

Tasque : mon gestionnaire de tâche

Written on 2008-07-01 21:09.

Mon bureau le 01/07/2008 Voici une capture d'écran de mon bureau aujourd'hui (et comme on peut le voir il fait beau et je traine néanmoins devant mon ordi). Tout à droite se trouve Tasque, qui est mon gestionnaire de tâche. Il a la particularité d'utiliser plusieurs backends dont Remember the milk, ce qui permet d'avoir ses tâches sur son bureau et sur le net.

Ce petit programme n'a qu'un inconvénient, il est codé en C# et je me traine donc mono uniquement pour lui. Mais comme il me permet de ne presque rien oublier, on fait avec.

Sur la gauche, deux shells zsh ouverts sur des répertoires gérés via mercurial. Ces shells utilisent une configuration très fortement inspirée de celle de madduck.

Genshi is fantastic !

Written on 2008-06-25 22:55.

I did not notice it but a new release of genshi is available. The team at edgewall already famous for trac is doing a great job to ease the generation of xml templates as well as for text templates.

Lately I had to create a list of the available pages on the blog and I was wondering how to do it with a mix of <py:for> and <py:if>. But then I realized that it was easier to use the marvelous <py:choose> in this way:

<py:for each="pagenum in range(1, max_pages+1)">
  <py:choose test="">
  <li py:when="pagenum==page"><b>$pagenum</b></li>
  <li py:when="pagenum==1"><a href="/blogs${base}?page=1">1</a></li>
  <li py:when="pagenum==max_pages">
     <a href="/blogs${base}?page=$pagenum">$pagenum</a>
  </li>
  <li py:when="abs(page-pagenum)==1">
     <a href="/blogs${base}?page=$pagenum">$pagenum</a>
  </li>
  <li py:when="abs(page-pagenum)==2"><span py:strip="True">...</span></li>
  </py:choose>
</py:for>

This little piece of code will bold the current page, display a link to the first, the last, the previous and the next pages.

Musical countries meme

Written on 2008-06-18 17:00.

Take the overall top 50 artist from your last.fm account, look up their countries, display the list to the world.

us: 18
fr: 10
uk: 10
de: 3
is: 2
be: 2
br: 2
ca: 1
au: 1
ru: 1

Found through planet debian.

Tu seras un pirate mon fils

Written on 2008-06-18 14:08.

Alors que le JT de Jean-Pierre Pernaut montre avec inquiètude les jeunes en train de détruire la musique avec leurs téléchargements sur de drôles de machines, on préfèrera lire un article des écrans qui montre que les jeunes vivent la musique avec un passion intacte. Morceaux choisis ...

Ils font des recherches, explorent, découvrent, essayent, évaluent, et recommandent aux autres

Ils disent estimer juste de rendre aux autres ce qu’ils leur ont offert, et l’étude va jusqu’à leur prêter « un code moral, même s’ils agissent illégalement »

Car les vilains pirates sont prêts à payer leur musique ! 80% d’entre eux se disent intéressés par un service de partage légal, en payant à leur fournisseur d’accès une somme forfaitaire qu’ils voudraient voir reversée aux artistes. Ils posent une condition : pas d’accès en streaming, mais la possibilité de disposer de manière permanente des morceaux achetés, sans DRM.

Tu seras un pirate mon fils (heu filleul plutôt).

Pages :