Coverage for lino/mixins/human.py : 46%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- # Copyright 2008-2015 Luc Saffre # License: BSD (see file COPYING for details)
See test cases and examples in :doc:`/tutorials/human/index`.
.. autosummary::
"""
'VOM', 'VON', 'OF', "DE", "DU", "EL", "AL", "DI")) "IN HET", "VON DER", "DE LA"))
"""Strip name prefix from given family name `s`.""" s = s.upper() for p in NAME_PREFIXES: if s.startswith(p): s = s[len(p):] return s
"""Separate first name from last name. Split a string that contains both last_name and first_name. The caller must indicate whether the string contains last_name first (e.g. Saffre Luc) or first_name first (e.g. Luc Saffre).
""" kw = {} a = s.split(',') if len(a) == 2: if last_name_first: return dict(last_name=a[0].strip(), first_name=a[1].strip()) a = s.strip().split() if len(a) == 0: return dict() elif len(a) == 1: return dict(last_name=a[0]) elif len(a) == 2: if last_name_first: return dict(last_name=a[0], first_name=a[1]) else: return dict(last_name=a[1], first_name=a[0]) else: # string consisting of more than 3 words if last_name_first: a01 = a[0] + ' ' + a[1] if a01.upper() in name_prefixes2: return dict( last_name=a01 + ' ' + a[2], first_name=' '.join(a[3:])) elif a[0].upper() in name_prefixes1: return dict( last_name=a[0] + ' ' + a[1], first_name=' '.join(a[2:])) else: return dict(last_name=a[0], first_name=' '.join(a[1:])) else: if len(a) >= 4: pc = a[-3] + ' ' + a[-2] # prefix2 candidate if pc.upper() in name_prefixes2: return dict( last_name=pc + ' ' + a[-1], first_name=' '.join(a[:-3])) pc = a[-2] # prefix candidate if pc.upper() in name_prefixes1: return dict( last_name=pc + ' ' + a[-1], first_name=' '.join(a[:-2])) return dict( last_name=a[-1], first_name=' '.join(a[:-1]))
return kw
if ' ' in s: return s # don't change return s[0].upper() + s[1:]
"""Parse the given `text` and return a dict of `first_name` and `last_name` value.
Extends :func:`name2kw` by raising a ValidationError if necessary.
""" kw = name2kw(text, last_name_first=False) if len(kw) != 2: raise ValidationError( _("Cannot find first and last name in \"{0}\"").format(text)) for k in ('last_name', 'first_name'): if kw[k] and not kw[k].isupper(): kw[k] = upper1(kw[k]) return kw
"""Returns "Mr" or "Mrs" or a translation thereof, depending on the gender and the current language.
Note that the English abbreviations `Mr <http://en.wikipedia.org/wiki/Mr.>`_ and `Mrs <http://en.wikipedia.org/wiki/Mrs.>`_ are written either *with* (AE) or *without* (BE) a dot.
The optional keyword argument `nominative` is used only in certain languages like German: specifying ``nominative=True`` for a male person will return the nominative or direct form "Herr" instead of the default (accusative or indirect form) "Herrn".
""" return '' return _("Mrs") return pgettext("indirect salutation", "Mr")
"""Base class for all models that represent a human.
.. attribute:: title
An optional name prefix like "Dr." or "PhD", used to specify a professional position or academic qualification.
If given, the content of this field comes always *between* salutation and name. It does not handle special cases like titles which replace the salutation ("Br.", "Sr.") or which must come at another position of the full name (e.g. "Cardinal", "Graf" before the last name).
External links: `linguee.de <http://www.linguee.de/englisch-deutsch/uebersetzung/mr.+dr..html>`__ and `wikipedia.org <https://en.wikipedia.org/wiki/Title>`__
.. attribute:: first_name
The first name, also known as given name.
.. attribute:: last_name
The last name, also known as family name.
.. attribute:: middle_name
A space-separated list of all `middle names <http://en.wikipedia.org/wiki/Middle_name>`_.
.. attribute:: gender
The sex of this person (male or female). Possible values are defined in :class:`lino.modlib.lino.choicelists.Genders`.
"""
pgettext("(of a human)", "Title"), max_length=200, blank=True, help_text=_( "Text to print between salutation and name as part " "of the first address line."))
_('First name'), max_length=200, blank=True, help_text=_("First or given name."))
_("Middle name"), max_length=200, blank=True, help_text=_("Space-separated list of all middle names."))
_('Last name'), max_length=200, blank=True, help_text=_("Last name (family name)."))
""" Taking three parameters `m`, `f` and `u` of any type, returns one of them depending on whether this Person is male, female or of unknown gender.
See :ref:`lino.tutorial.human` for some examples.
""" if self.gender is Genders.male: return m if self.gender is Genders.female: return f return u or m
#~ translation.get_language(), self.gender, **salutation_options)
self, salutation=True, upper=None, **salutation_options): """Returns a one-line string composed of salutation, :attr:`first_name` and :attr:`last_name`.
The optional keyword argument `salutation` can be set to `False` to suppress salutations.
The optional keyword argument `upper` can be specified to override the Site's default value (:attr:`lino.core.site.Site.uppercase_last_name`). `True` means to convert the last name to uppercase as is usually done in French.
Any other keyword arguments are forwarded to :func:`lino.mixins.human.get_salutation` (see there).
See :ref:`lino.tutorial.human` for some examples.
"""
words.append(self.title) words.append(self.last_name.upper()) else:
"""used in `humanlinks.LinksByHuman` and in `households.SiblingsByPerson`.
""" if other.last_name == self.last_name: text = other.first_name else: text = other.first_name + ' ' + other.last_name.upper() return ar.obj2html(other, text)
""" Abstract base class that adds a `birth_date` field and a virtual field "Age".
.. attribute:: birth_date
An :class:`IncompleteDateField <lino.core.fields.IncompleteDateField>`.
.. attribute:: age
Virtual field displaying the age in years.
"""
blank=True, verbose_name=_("Birth date"))
"""Return the age (in years) of this human. See :meth:`lino.utils.IncompleteDateField.get_age`. """ if self.birth_date: return self.birth_date.get_age(today or settings.SITE.today())
""" Return the age as a :class:`datetime.timedelta` object.
Optional keyword argument `today` should be a :class:`datetime.date` instance to replace the actual current date. This is used if you want the age at a given date in the past or the future. The default value calls :meth:`dd.Site.today`. """ # print(20160202, self.birth_date, self) if self.birth_date and self.birth_date.year: if today is None: today = settings.SITE.today() try: return today - self.birth_date.as_date() except ValueError: pass
a = self.get_exact_age(today) if a is None: return str(_('unknown')) s = _("%d years") % (old_div(a.days, 365)) if self.birth_date and self.birth_date.is_complete(): return s return u"±" + s |