================================
20130421 (Sunday, 21 April 2013)
================================

"Upcoming" and "Missed" events
------------------------------

The `coming_reminders` and `missed_reminders`
virtual fields of :class:`lino_xl.lib.cal.Home` 
("Ausblick" und "Verpasste Termine")
showed also events of other users.

Added a new case to :ref:`welfare.specs.misc` and 
fixed the bug.

Which revealed that this bug is probably at least one release old.
The fact that nobody complained indicates that 
these two panels are obsolete and should be replaced by something 
better.


Sphinx: unsupported build info format in .buildinfo
---------------------------------------------------

I sometimes had the following Sphinx warnings::

  WARNING: unsupported build info format in u'/home/luc/hgwork/welfare/docs/.build/.buildinfo', building all
  
Which disturbed me because it stopped the build 
(because I have -W option turned on and want it to stay like this).

This invalid `.buildinfo` file contained::

    # Sphinx build info version 1
    # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
    config: 
    tags: 

It is indeed not normal to have this file exist with "empty" entries. 
Possible that this comes because I use complex configurations.
But still it was Sphinx herself who generated this file and now 
she complains about the content. That's not correct!
Here is the responsible code in `/sphinx/builders/html.py`::

    try:
        fp = open(path.join(self.outdir, '.buildinfo'))
        try:
            version = fp.readline()
            if version.rstrip() != '# Sphinx build info version 1':
                raise ValueError
            fp.readline()  # skip commentary
            cfg, old_config_hash = fp.readline().strip().split(': ')
            if cfg != 'config':
                raise ValueError
            tag, old_tags_hash = fp.readline().strip().split(': ')
            if tag != 'tags':
                raise ValueError
        finally:
            fp.close()
    except ValueError:
        self.warn('unsupported build info format in %r, building all' %
                  path.join(self.outdir, '.buildinfo'))
    except Exception:
        pass

A principal problem with this code is that it uses the 
standard exception `ValueError` to handle a custom problem.
It's a mousetrap, and my concrete case of invalid build file 
makes Sphinx step into this trap.
In fact (AFAICS) the author wants Sphinx to warn only in those 
special cases and to silently ignore (without any warning)
any "really invalid" .buildinfo file.
So I suggest to replace "ValueError" by a custom exception "InvalidInfo"::

    class InvalidInfo(Exception): 
        pass
        
    try:
        fp = open(path.join(self.outdir, '.buildinfo'))
        try:
            version = fp.readline()
            if version.rstrip() != '# Sphinx build info version 1':
                raise InvalidInfo
            fp.readline()  # skip commentary
            cfg, old_config_hash = fp.readline().strip().split(': ')
            if cfg != 'config':
                raise InvalidInfo
            tag, old_tags_hash = fp.readline().strip().split(': ')
            if tag != 'tags':
                raise InvalidInfo
        finally:
            fp.close()
    except InvalidInfo:
        self.warn('unsupported build info format in %r, building all' %
                  path.join(self.outdir, '.buildinfo'))
    except Exception:
        pass



More bugs fixed
---------------

- pcsw.Client.print_eid_content didn't work. 
- Added a test case to :ref:`welfare.specs.pcsw`.



Merging imported Partners
-------------------------

Es war ein Denkfehler, die Aktion "Fusionieren" für importierte
Partner zu verbieten. 
Zumindest im Fall "23219 nach 23624 fusionieren" ist dieses Verbot
falsch. Also raus mit folgendem Code 
(aus der :class:`lino_welfare.modlib.pcsw.models.Partner`)::

    def get_row_permission(self,ar,state,ba):
        if isinstance(ba.action,dd.MergeAction) and settings.SITE.is_imported_partner(self):
            return False
        return super(Partner,self).get_row_permission(ar,state,ba)



Oho, another surprise:
adding MergeAction in post_analyze is too late, but adding 
it in pre_analyze is too early! 
See also :blogref:`20130409`: 
MergeAction needs the info in _lino_ddh to fill keep_volatiles.
Solution: pre_analyze is now being emitted a little bit later: after 
setup_choicelists(), setup_workflows() and the loop which fills 
`_lino_ddh`.


TODO:

- File does not exist: /usr/local/django/cpas_eupen/media/eid-jslib/media

- Shouldn't we remove `allow_cascaded_delete = ['client']`  on 
  pcsw.Coaching? because it sounds more intuitive that you cannot 
  delete a Client without first manually deleting every Coaching.