20130826 (Monday, 26 August 2013)

Lino’s current default template for writing sales invoices isn’t really beautiful. I started to work on a new one.

The new Invoice.odt is based on the existing Letter.odt for lino_welfare.

First I renamed get_letter_margin_html get_letter_margin_bottom_html and added a new method get_letter_margin_top_html

Already the first line arises questions: where and how to specify the date of a letter.

Specifying the city in the date of a letter

It seems that at least in Europe it is common to add the sending place to the sending date:

  • de: “Eupen, den 26. August 2013” or “Eupen, 26. August 2013”
  • fr: Eupen, le 26 août 2013
  • en_US: Eupen, August 26, 2013
  • en_BR: Eupen, 26 August 2013

So in Invoice.odt I specify:

[sc.site_company.city.name], [tr("",de="den",fr="le")] [dtos(self.date)]

Which required a new optional positional argument for north.dbutils.babelitem() to specify a default value which doesn’t depend on the database’s default language.

But oops, in Spanish they say “En Madrid, a 21 de enero de 2010” (found here). It seems that python-babel doesn’t worry about the problem.

More research:

Shortcut functions for date formatting

Until now I used the following short-named functions when inserting dates into document templates:

dtos   26.08.2013
dtosl  Montag, 26.08.2013
dtomy  August 2013

Where “l” stands for “long”.

But python-babel differentiates between “long” and “full”, and my “long” corresponds to their “full”.

To solve these naming clashes and still remain backwards compatible, I declare these functions obsolete and define a new series of short-named date formatting functions:

fds(d) --> 26.08.2013
fdm(d) --> 26. Aug 2013
fdl(d) --> 26. August 2013
fdf(d) --> Montag, 26. August 2013

Missing commas in linoweb.js

Bug fixed: IE doesn’t like Javascript expressions containing uselessly trailing commas (as e.g. in var obj = { a:1, }). This kind of typo in JS generated by Lino often passes undiscovered because I don’t use that browser. But Joe’s users now noted such a comma and he fixed it and sent me a patch:

Following is small fix, that fixes compatibility with IE10
(otherwise compatibility mode is required and there are some UI glitches
in compat mode)

--- a/lino/extjs/linoweb.js     Sat Aug 24 03:43:43 2013 +0300
+++ b/lino/extjs/linoweb.js     Mon Aug 26 01:54:17 2013 +0200
@@ -1160,7 +1160,7 @@
   });
 Lino.DateTimeField = Ext.extend(Ext.ux.form.DateTime,{
   dateFormat: '{{settings.SITE.date_format_extjs}}',
-  timeFormat: '{{settings.SITE.time_format_extjs}}',
+  timeFormat: '{{settings.SITE.time_format_extjs}}'
   //~ hiddenFormat: '{{settings.SITE.date_format_extjs}} {{settings.SITE.time_format_extjs}}'
   });
 Lino.URLField = Ext.extend(Ext.form.TriggerField,{

Thank you, Joe. I applied your fix to trunk.

Yes, when there will be more contributors, then Lino will definitively need a code repository with pull requests for this kind of contribution.

‘ExtUI’ object has no attribute ‘build_site_cache’

Bug fixed: The modlib.system.models.BuildSiteCache action didn’t work. It caused a server exception ‘ExtUI’ object has no attribute ‘build_site_cache’.

Github or Gitorious?

Today I discovered the Why is Github more popular than Gitorious? question on stackoverflow which has been “closed as not constructive”. I didn’t read half of the comments, especially also because it is probably obsolete.

But yes… the decision “Github or Gitorious?” seems to depend on the religious question about whether software should be free (of commercial interest) or not. If I had do decide right now, than I’d probably toss a coin…

Formatting None values

The format_value method of lino.ui.store.StoreField.RequestStoreField failed on None value. That’s another complex question: who should handle None values`, the formatter (i.e. format_value) or the callers (i.e. row2list & Co?). Let’s leave this job to the formatters because it is easier to implement.

The dump2py management command

Until now there was at least one limit for north: it had to fail on huge databases. We didn’t yet reach that limit, but Murphy’s law states that it will happen one day.

This limit exists “by nature”, because Django’s serializer concept means that a dump creates exactly one file, and because Python must load a module into memory before compiling and executing it.

The good news is: it took only a few hours to remove that limit. I wrote a management command north.management.commands.dump2py and I split the north.dpy.Deserializer into a “Loader”.

The bad news is: I’ll need to update quite some documentation. But in summary:

To make a python dump (be it for daily backup or before a migration) we no longer recommend to say:

$ python manage.py dumpdata --format py > mydump.py

It is now better to say:

$ python manage.py mydump

This will create a python dump of your database to the directory mydump. The directory will contain one file main.py and a lot of other .py files (currently one for every model) which are being execfile()d from that main.py.

To restore such a dump to your database, simply issue:

$ python mydump/main.py