Thursday, October 4, 2018

I started working for #2495.

  • In lino_xl.lib.cal.GuestStates. They asked to change the text for guest state “absent” from “Abwesend” (absent) to “Fehlt” (missing). I thought that this is a good vocabulary change and renamed “absent” to “missing” for the voga workflow in general. Which means also for Lino Voga and Lino Tera. But not for Lino Welfare who use the feedback workflow. This is confirmed by what we have in Lino Tera where I changed:

    EntryStates.missed.guest_state = GuestStates.absent
    

    to:

    EntryStates.missed.guest_state = GuestStates.missing
    

I updated Calendar functions in Lino Avanti while working. I wrote a new function lino.api.doctest.show_workflow().

Test failures in Welfare

I saw some failures in Welfare but don’t see why they are there. I opened a separate ticket #2565 for this. Looks as if there’s one calendar more, and pcsw.Client has a changed content type id. I don’t remember any code change that might have caused these. Aha, I then saw that in Python 3 it is the opposite. The number of calendars changes when migrating from Python 2 to 3 (or from Django 1 to 2). Maybe the loading order of plugins is changed.

Hamza had observed that the difference comes because Django 2 for some reason creates content types in a different order than Django 1. So the ContentType.id of a given table varies depending on whether inv prep has been run under Py3 or Py2. Resolution –> use ellipsis in these doctests for the contenttype id.

Importing invoices for Lino Tera

I started spzloader3.py and tl3.py.

MyCoachedEnrolments for Avanti

How to do a gfklookup for remote fields:

flt = {'event__'+k: v
       for k, v in gfk2lookup(Event.owner, self).items()}

Changes in action API

The new action lino_avanti.lib.courses.Course.update_missing_rates() triggered me to start reviewing this part of the action API. At some moment I had this code:

class UpdateMissingRates(dd.Action):
   ...
   def run_from_ui(self, ar, ...):
       for obj in ar.selected_rows:
           obj.run_update_missing_rates(ar)

class Course(Course):
    update_missing_rates = UpdateMissingRates()

    def run_update_missing_rates(self, ar):
        ... do the actual thing

@dd.schedule_daily()
def update_missing_rates():
    for obj in ...:
       obj.run_update_missing_rates()

These were too many names for the same thing. For simple actions without custom permission handling there should be no need to create a class. The action on the model should be callable more naturally from code. Do we need all these methods run_from_code, run_from_ui and run_from_session?

Here is what I changed: when calling an InstanceAction directly (i.e. using its __call__() method), you may no longer specify an action request as first argument (if you want to do that, you call run_from_ui or run_from_session).

These action methods run_from_code, run_from_ui and run_from_session are still there but they now have a docstring. And because an instance action is callable, I can now write above code more concisely:

class Course(Course):
    update_missing_rates = UpdateMissingRates()

    @dd.action(...)
    def update_missing_rates(self, ar):
        ... do the actual thing

@dd.schedule_daily()
def update_missing_rates():
    for obj in ...:
       obj.update_missing_rates()

En passant an internal optimization: dd.action no longer is a function in lino.core.actions but a shortcut to the lino.core.actions.Action.decorator() class method. This might be useful of somebody wants to have an action class and still use the decorated model method:

class MyAction(dd.Action):
    ...

class MyModel(dd.Model):
    ...
    @MyAction.decorate()
    def update_missing_rates(self, ar):
        ... do the actual thing

Help texts from Sphinx

I had some fun because I wanted the help_text for our new action to show up.

I noticed that the help_texts.py files had not been updated for some time. I think I fixed it but don’t understand all the details. It seems that Sphinx now stores its pickles (.doctrees) in the source directory, as a sibling of the output path (.build). And because of this inv clean did not delete them. So Sphinx did not process all documents after a clean. And that’s why help_text_extractor never generated any help_texts.py files.

‘Course’ object has no attribute ‘get_date_formatter’

Occured during lino_xl.lib.cal.EventGenerator.update_all_guests(), which is not covered by the test suite.