Monday, April 25, 2016

Lino Voga

I worked on #878 and made a first release: The dates of the generated calendar events are now clickable in order to facilitate research in case of conflicting events. I changed the name of linked_date to when_html. EventsByController now uses when_html instead of when_text.

Sorting strings in Python 2 and 3

Two days ago I removed sorted(v.items()) in lino.utils.jsgen (which had been added by Hamza for #36). I did this because it caused a TypeError when the dictionary contained a mixture of str and future.types.newstr keys. This change (of course) broke the test suite. The following snippet reproduces the problem:

>>> from builtins import str
>>> d = {"foo": 1, str("bar"): 2}
>>> sorted(d.items())
[('bar', 2), ('foo', 1)]

When run with Python 2 the last line says:

>>> sorted(d.items())
Traceback (most recent call last):
TypeError: unorderable types: str() and <type 'str'>

It took me more than two hours to find out where Lino uses bytestring as keys to the dictionaries which are sent to py2js.

What is better: print (foo) or print(foo)?

I answered my own question (Tuesday, April 19, 2016) about whether or not there should be a space after print. PEP 8 recommends to avoid extraneous whitespace immediately before the open parenthesis that starts the argument list of a function call. And print is now a function (even when run under Python 2 because we did from __future__ import print_function). So I recommend to write print(foo), not print (foo).

Local customizations to the user permissions

Ticket #879. End-users ask for a “quick little” change regarding user permissions:

Wäre es möglich, den Reiter Sprachenkurs in Lino für den ganzen ASD frei zu schalten?

I did a first code change (in and answered:

Ist notiert als Ticket #879, und theoretisch ist ein erster Vorschlag bereit. Es gibt keinen Reiter “Sprachkurse”, wohl aber ein Panel “Sprachkurse” im Reiter “Sprachen”. Momentan würde durch ein Release nur dieses eine Panel für den ASD sichtbar. Soll das Panel “Sprachkenntnisse” auch sichtbar werden? Möchtet ihr eine neue Version installiert bekommen (mit den bekannten Vor- und Nachteilen)?

Gerd (understandably) asks:

Muss dafür eine neue Version her oder geht das über die Konfigurationsdateien?

I answered:

“Das kannst du über lokale Konfigurationsdateien machen, aber dann ist es halt scheiße”. Genauer gesagt hat es den Nachteil, dass diese Anwendungsintelligenz dann weder dokumentierbar noch testbar ist. Was für die Endbenutzer freilich kein Trost ist, dass sie auf ihre Lösung warten müssen. En attendant könnte ich also mal probieren, ob ich es tatsächlich mit einer lokalen Anpassung hinkriege. Vielleicht diese Nacht.

And because that might indeed be an interesting quick win, I started to think about how I would do it using a “local patch”.

Okay, here is how you can get the CourseRequestsByPerson panel visible for SocialAgent (and not only for CoursesUser).

First step is to create and activate a local roles module:

  • Create a file named next to your local with this content:

    from lino_welfare.modlib.welfare.roles import *
  • In your file, set user_types_module to the Python path of above file:

    user_types_module = 'mysite.myroles'

This first step should have no influence at all. We’ve just prepared a hook for defining local customizations (to the standard system defined by lino_welfare.modlib.welfare.roles).

Second step is to add customizations to your file. In above example we would just have to add the following lines:

from lino.api import dd, rt
t =
t.required_roles = dd.required((CoursesUser, SocialAgent))

I wrote a tutorial about this topic: lino_book.projects.myroles.

Lino Voga (continued)

I continued on #878.

Lino Care

I worked on #621 to do the list of ideas which I received last Thursday in Eupen with Johannes, Lukas, Annalisa and Carl.

The affinity of a faculty and/or competence expresses how much a given user “likes” to get assigned to a ticket of this faculty.

I updated Lino Care, a network of people who care which is now a tested document.

The username of a user is no longer mandatory.