Friday, September 28, 2018¶
Adresse Empfänger in Bescheinigungen¶
Wow, it took me some time to find the explanation for the following problem (#2554):
(melanie) Inhalt der Bescheinigungen: Adressfeld ist versetzt/verschwunden! Layout nicht ok!
Lag daran, dass etgen.html
seit Thursday, March 8, 2018 lxml-Elemente
benutzt und die Syntax class_="Recipient"
deshalb ersetzt werden
muss durch die neue Syntax **{'class':"Recipient"}
. Das heißt
auch, dass die *.odt-Dateien jetzt nicht mehr gesyncht werden
sollten, also muss ich die initdb_preview_from_prod.sh
lokal
anpassen. Das erwies sich aber als eher aufwändig, deshalb muss ich
einfach dran denken, nach dem Synch die Datei
excerpts/Default.odt
manuell anzupassen.
Ich habe das gefunden, nachdem ich den Fall in Usage of database excerpts in Lino Welfare dokumentiert hatte. Dazu habe ich dem Roten Kreuz in den Demo-Daten eine Adresse verpasst.
Formatierung Tabellen in Budgets Schuldnerberatung¶
The debts/Budget/Default.odt
template uses the story()
function to insert a stream of “story chunks” produced by methods on
the Budget
object. These
chunks are processed by story2odt
which
calls insert_table
for
each table in the stream. insert_table
dynamically creates odf tables and respects the widths it gets from
the request’s get_field_info
, which returns
col.width or col.preferred_width for each column.
I played a bit with the appy renderer in order to remind me how it all works internally. (Yes, I wrote it myself, but this was years ago.)
>>> from lino import startup
>>> startup('lino_welfare.projects.eupen.settings.doctests')
>>> from lino.api.doctest import *
>>> from etgen.html import tostring
>>> from lino_xl.lib.appypod.appy_renderer import AppyRenderer
>>> from lxml import etree
>>> ar = rt.login('robin')
>>> ctx = {}
>>> rnd = AppyRenderer(ar, "empty.odt", ctx, "out.odt")
Appy is not very testing friendly. Above line requires a file
empty.odt
just some empty but valid LO document, and every
test run will create a temporary directory.
>>> obj = debts.Budget.objects.get(pk=1)
>>> story = obj.data_story(ar)
>>> odf = rnd.insert_story(story)
>>> # print(odf)
The story contains a sequence of <header> and <table> elements, but no root element. That’s a problem for the parser. So we wrap the story for them.
>>> odf = "<foo>" + odf + "</foo>"
>>> # from io import BytesIO
>>> # stream = BytesIO(odf.encode("utf-8"))
>>> # tree = etree.parse(stream)
>>> # root = tree.getroot()
>>> root = etree.fromstring(odf)
>>> children = list(root)
>>> table = children[1]
>>> table
<Element {urn:oasis:names:tc:opendocument:xmlns:table:1.0}table at ...>
>>> columns, headers, rows = tuple(table)
>>> for col in columns:
... etree.tostring(col)
... print(col.get("table:style-name"))
>>> for child in root:
... print(child.tag)
>>> print(odf)
>>> tree = etree.fromstring(odf)
>>> tree
I finally simply added width specifiers to the column_names in the
tables that are getting printed there. Including a new constant
AMOUNT_WIDTH
in lino_welfare.modlib.debts.choicelists
.
Currently it is set to ":15"
which seems to give good results. I
also decreased the right page margin in
debts/Budget/Default.odt
from 20 to 10 mm.
Django 2 support is advancing¶
Hamza and I had a session where we fixed a failure on Travis:
2018-09-28 20:15 in book: be32b6b (fixing failures py2to3 ajax.rst django.request logger level)
Django 2 has become more eager about logging every request, including failed ones. This is of course disturbing when we want a testable doc that works for both Django 1 and 2. So in Refusing permission to an anonymous request we simply disable logging.