Module gedcom.element.individual

GEDCOM element consisting of tag GEDCOM_TAG_INDIVIDUAL

Expand source code
# -*- coding: utf-8 -*-

# Python GEDCOM Parser
#
# Copyright (C) 2018 Damon Brodie (damon.brodie at gmail.com)
# Copyright (C) 2018-2019 Nicklas Reincke (contact at reynke.com)
# Copyright (C) 2016 Andreas Oberritter
# Copyright (C) 2012 Madeleine Price Ball
# Copyright (C) 2005 Daniel Zappala (zappala at cs.byu.edu)
# Copyright (C) 2005 Brigham Young University
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Further information about the license: http://www.gnu.org/licenses/gpl-2.0.html

"""GEDCOM element consisting of tag `gedcom.tags.GEDCOM_TAG_INDIVIDUAL`"""

import re as regex
from gedcom.element.element import Element
from gedcom.helpers import deprecated
import gedcom.tags


class NotAnActualIndividualError(Exception):
    pass


class IndividualElement(Element):

    def get_tag(self):
        return gedcom.tags.GEDCOM_TAG_INDIVIDUAL

    def is_deceased(self):
        """Checks if this individual is deceased
        :rtype: bool
        """
        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
                return True

        return False

    def is_child(self):
        """Checks if this element is a child of a family
        :rtype: bool
        """
        found_child = False

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD:
                found_child = True

        return found_child

    def is_private(self):
        """Checks if this individual is marked private
        :rtype: bool
        """
        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE:
                private = child.get_value()
                if private == 'Y':
                    return True

        return False

    def get_name(self):
        """Returns an individual's names as a tuple: (`str` given_name, `str` surname)
        :rtype: tuple
        """
        given_name = ""
        surname = ""

        # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found.
        # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those.
        found_given_name = False
        found_surname_name = False

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME:
                # Some GEDCOM files don't use child tags but instead
                # place the name in the value of the NAME tag.
                if child.get_value() != "":
                    name = child.get_value().split('/')

                    if len(name) > 0:
                        given_name = name[0].strip()
                        if len(name) > 1:
                            surname = name[1].strip()

                    return given_name, surname

                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME:
                        given_name = childOfChild.get_value()
                        found_given_name = True

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME:
                        surname = childOfChild.get_value()
                        found_surname_name = True

                if found_given_name and found_surname_name:
                    return given_name, surname

        # If we reach here we are probably returning empty strings
        return given_name, surname

    def get_all_names(self):
        return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME]

    def surname_match(self, surname_to_match):
        """Matches a string with the surname of an individual
        :type surname_to_match: str
        :rtype: bool
        """
        (given_name, surname) = self.get_name()
        return regex.search(surname_to_match, surname, regex.IGNORECASE)

    @deprecated
    def given_match(self, name):
        """Matches a string with the given name of an individual
        ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead
        :type name: str
        :rtype: bool
        """
        return self.given_name_match(name)

    def given_name_match(self, given_name_to_match):
        """Matches a string with the given name of an individual
        :type given_name_to_match: str
        :rtype: bool
        """
        (given_name, surname) = self.get_name()
        return regex.search(given_name_to_match, given_name, regex.IGNORECASE)

    def get_gender(self):
        """Returns the gender of a person in string format
        :rtype: str
        """
        gender = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX:
                gender = child.get_value()

        return gender

    def get_birth_data(self):
        """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
        :rtype: tuple
        """
        date = ""
        place = ""
        sources = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

        return date, place, sources

    def get_birth_year(self):
        """Returns the birth year of a person in integer format
        :rtype: int
        """
        date = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date_split = childOfChild.get_value().split()
                        date = date_split[len(date_split) - 1]

        if date == "":
            return -1
        try:
            return int(date)
        except ValueError:
            return -1

    def get_death_data(self):
        """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
        :rtype: tuple
        """
        date = ""
        place = ""
        sources = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

        return date, place, sources

    def get_death_year(self):
        """Returns the death year of a person in integer format
        :rtype: int
        """
        date = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date_split = childOfChild.get_value().split()
                        date = date_split[len(date_split) - 1]

        if date == "":
            return -1
        try:
            return int(date)
        except ValueError:
            return -1

    @deprecated
    def get_burial(self):
        """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
        ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead
        :rtype: tuple
        """
        self.get_burial_data()

    def get_burial_data(self):
        """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
        :rtype: tuple
        """
        date = ""
        place = ""
        sources = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL:
                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

        return date, place, sources

    @deprecated
    def get_census(self):
        """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
        ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead
        :rtype: list of tuple
        """
        self.get_census_data()

    def get_census_data(self):
        """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
        :rtype: list of tuple
        """
        census = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS:

                date = ''
                place = ''
                sources = []

                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

                census.append((date, place, sources))

        return census

    def get_last_change_date(self):
        """Returns the date of when the person data was last changed formatted as a string
        :rtype: str
        """
        date = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

        return date

    def get_occupation(self):
        """Returns the occupation of a person
        :rtype: str
        """
        occupation = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION:
                occupation = child.get_value()

        return occupation

    def birth_year_match(self, year):
        """Returns `True` if the given year matches the birth year of this person
        :type year: int
        :rtype: bool
        """
        return self.get_birth_year() == year

    def birth_range_match(self, from_year, to_year):
        """Checks if the birth year of a person lies within the given range
        :type from_year: int
        :type to_year: int
        :rtype: bool
        """
        birth_year = self.get_birth_year()

        if from_year <= birth_year <= to_year:
            return True

        return False

    def death_year_match(self, year):
        """Returns `True` if the given year matches the death year of this person
        :type year: int
        :rtype: bool
        """
        return self.get_death_year() == year

    def death_range_match(self, from_year, to_year):
        """Checks if the death year of a person lies within the given range
        :type from_year: int
        :type to_year: int
        :rtype: bool
        """
        death_year = self.get_death_year()

        if from_year <= death_year <= to_year:
            return True

        return False

    def criteria_match(self, criteria):
        """Checks if this individual matches all of the given criteria

        `criteria` is a colon-separated list, where each item in the
        list has the form [name]=[value]. The following criteria are supported:

        surname=[name]
             Match a person with [name] in any part of the `surname`.
        given_name=[given_name]
             Match a person with [given_name] in any part of the given `given_name`.
        birth=[year]
             Match a person whose birth year is a four-digit [year].
        birth_range=[from_year-to_year]
             Match a person whose birth year is in the range of years from
             [from_year] to [to_year], including both [from_year] and [to_year].

        :type criteria: str
        :rtype: bool
        """

        # Check if criteria is a valid criteria and can be split by `:` and `=` characters
        try:
            for criterion in criteria.split(':'):
                criterion.split('=')
        except ValueError:
            return False

        match = True

        for criterion in criteria.split(':'):
            key, value = criterion.split('=')

            if key == "surname" and not self.surname_match(value):
                match = False
            elif key == "name" and not self.given_name_match(value):
                match = False
            elif key == "birth":

                try:
                    year = int(value)
                    if not self.birth_year_match(year):
                        match = False
                except ValueError:
                    match = False

            elif key == "birth_range":

                try:
                    from_year, to_year = value.split('-')
                    from_year = int(from_year)
                    to_year = int(to_year)
                    if not self.birth_range_match(from_year, to_year):
                        match = False
                except ValueError:
                    match = False

            elif key == "death":

                try:
                    year = int(value)
                    if not self.death_year_match(year):
                        match = False
                except ValueError:
                    match = False

            elif key == "death_range":

                try:
                    from_year, to_year = value.split('-')
                    from_year = int(from_year)
                    to_year = int(to_year)
                    if not self.death_range_match(from_year, to_year):
                        match = False
                except ValueError:
                    match = False

        return match

Classes

class IndividualElement (level, pointer, tag, value, crlf='\n', multi_line=True)

GEDCOM element

Each line in a GEDCOM file is an element with the format

level [pointer] tag [value]

where level and tag are required, and pointer and value are optional. Elements are arranged hierarchically according to their level, and elements with a level of zero are at the top level. Elements with a level greater than zero are children of their parent.

A pointer has the format @pname@, where pname is any sequence of characters and numbers. The pointer identifies the object being pointed to, so that any pointer included as the value of any element points back to the original object. For example, an element may have a FAMS tag whose value is @F1@, meaning that this element points to the family record in which the associated person is a spouse. Likewise, an element with a tag of FAMC has a value that points to a family record in which the associated person is a child.

See a GEDCOM file for examples of tags and their values.

Tags available to an element are seen here: gedcom.tags

Expand source code
class IndividualElement(Element):

    def get_tag(self):
        return gedcom.tags.GEDCOM_TAG_INDIVIDUAL

    def is_deceased(self):
        """Checks if this individual is deceased
        :rtype: bool
        """
        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
                return True

        return False

    def is_child(self):
        """Checks if this element is a child of a family
        :rtype: bool
        """
        found_child = False

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD:
                found_child = True

        return found_child

    def is_private(self):
        """Checks if this individual is marked private
        :rtype: bool
        """
        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE:
                private = child.get_value()
                if private == 'Y':
                    return True

        return False

    def get_name(self):
        """Returns an individual's names as a tuple: (`str` given_name, `str` surname)
        :rtype: tuple
        """
        given_name = ""
        surname = ""

        # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found.
        # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those.
        found_given_name = False
        found_surname_name = False

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME:
                # Some GEDCOM files don't use child tags but instead
                # place the name in the value of the NAME tag.
                if child.get_value() != "":
                    name = child.get_value().split('/')

                    if len(name) > 0:
                        given_name = name[0].strip()
                        if len(name) > 1:
                            surname = name[1].strip()

                    return given_name, surname

                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME:
                        given_name = childOfChild.get_value()
                        found_given_name = True

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME:
                        surname = childOfChild.get_value()
                        found_surname_name = True

                if found_given_name and found_surname_name:
                    return given_name, surname

        # If we reach here we are probably returning empty strings
        return given_name, surname

    def get_all_names(self):
        return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME]

    def surname_match(self, surname_to_match):
        """Matches a string with the surname of an individual
        :type surname_to_match: str
        :rtype: bool
        """
        (given_name, surname) = self.get_name()
        return regex.search(surname_to_match, surname, regex.IGNORECASE)

    @deprecated
    def given_match(self, name):
        """Matches a string with the given name of an individual
        ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead
        :type name: str
        :rtype: bool
        """
        return self.given_name_match(name)

    def given_name_match(self, given_name_to_match):
        """Matches a string with the given name of an individual
        :type given_name_to_match: str
        :rtype: bool
        """
        (given_name, surname) = self.get_name()
        return regex.search(given_name_to_match, given_name, regex.IGNORECASE)

    def get_gender(self):
        """Returns the gender of a person in string format
        :rtype: str
        """
        gender = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX:
                gender = child.get_value()

        return gender

    def get_birth_data(self):
        """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
        :rtype: tuple
        """
        date = ""
        place = ""
        sources = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

        return date, place, sources

    def get_birth_year(self):
        """Returns the birth year of a person in integer format
        :rtype: int
        """
        date = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date_split = childOfChild.get_value().split()
                        date = date_split[len(date_split) - 1]

        if date == "":
            return -1
        try:
            return int(date)
        except ValueError:
            return -1

    def get_death_data(self):
        """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
        :rtype: tuple
        """
        date = ""
        place = ""
        sources = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

        return date, place, sources

    def get_death_year(self):
        """Returns the death year of a person in integer format
        :rtype: int
        """
        date = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date_split = childOfChild.get_value().split()
                        date = date_split[len(date_split) - 1]

        if date == "":
            return -1
        try:
            return int(date)
        except ValueError:
            return -1

    @deprecated
    def get_burial(self):
        """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
        ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead
        :rtype: tuple
        """
        self.get_burial_data()

    def get_burial_data(self):
        """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
        :rtype: tuple
        """
        date = ""
        place = ""
        sources = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL:
                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

        return date, place, sources

    @deprecated
    def get_census(self):
        """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
        ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead
        :rtype: list of tuple
        """
        self.get_census_data()

    def get_census_data(self):
        """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
        :rtype: list of tuple
        """
        census = []

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS:

                date = ''
                place = ''
                sources = []

                for childOfChild in child.get_child_elements():

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                        place = childOfChild.get_value()

                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                        sources.append(childOfChild.get_value())

                census.append((date, place, sources))

        return census

    def get_last_change_date(self):
        """Returns the date of when the person data was last changed formatted as a string
        :rtype: str
        """
        date = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE:
                for childOfChild in child.get_child_elements():
                    if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                        date = childOfChild.get_value()

        return date

    def get_occupation(self):
        """Returns the occupation of a person
        :rtype: str
        """
        occupation = ""

        for child in self.get_child_elements():
            if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION:
                occupation = child.get_value()

        return occupation

    def birth_year_match(self, year):
        """Returns `True` if the given year matches the birth year of this person
        :type year: int
        :rtype: bool
        """
        return self.get_birth_year() == year

    def birth_range_match(self, from_year, to_year):
        """Checks if the birth year of a person lies within the given range
        :type from_year: int
        :type to_year: int
        :rtype: bool
        """
        birth_year = self.get_birth_year()

        if from_year <= birth_year <= to_year:
            return True

        return False

    def death_year_match(self, year):
        """Returns `True` if the given year matches the death year of this person
        :type year: int
        :rtype: bool
        """
        return self.get_death_year() == year

    def death_range_match(self, from_year, to_year):
        """Checks if the death year of a person lies within the given range
        :type from_year: int
        :type to_year: int
        :rtype: bool
        """
        death_year = self.get_death_year()

        if from_year <= death_year <= to_year:
            return True

        return False

    def criteria_match(self, criteria):
        """Checks if this individual matches all of the given criteria

        `criteria` is a colon-separated list, where each item in the
        list has the form [name]=[value]. The following criteria are supported:

        surname=[name]
             Match a person with [name] in any part of the `surname`.
        given_name=[given_name]
             Match a person with [given_name] in any part of the given `given_name`.
        birth=[year]
             Match a person whose birth year is a four-digit [year].
        birth_range=[from_year-to_year]
             Match a person whose birth year is in the range of years from
             [from_year] to [to_year], including both [from_year] and [to_year].

        :type criteria: str
        :rtype: bool
        """

        # Check if criteria is a valid criteria and can be split by `:` and `=` characters
        try:
            for criterion in criteria.split(':'):
                criterion.split('=')
        except ValueError:
            return False

        match = True

        for criterion in criteria.split(':'):
            key, value = criterion.split('=')

            if key == "surname" and not self.surname_match(value):
                match = False
            elif key == "name" and not self.given_name_match(value):
                match = False
            elif key == "birth":

                try:
                    year = int(value)
                    if not self.birth_year_match(year):
                        match = False
                except ValueError:
                    match = False

            elif key == "birth_range":

                try:
                    from_year, to_year = value.split('-')
                    from_year = int(from_year)
                    to_year = int(to_year)
                    if not self.birth_range_match(from_year, to_year):
                        match = False
                except ValueError:
                    match = False

            elif key == "death":

                try:
                    year = int(value)
                    if not self.death_year_match(year):
                        match = False
                except ValueError:
                    match = False

            elif key == "death_range":

                try:
                    from_year, to_year = value.split('-')
                    from_year = int(from_year)
                    to_year = int(to_year)
                    if not self.death_range_match(from_year, to_year):
                        match = False
                except ValueError:
                    match = False

        return match

Ancestors

Methods

def birth_range_match(self, from_year, to_year)

Checks if the birth year of a person lies within the given range :type from_year: int :type to_year: int :rtype: bool

Expand source code
def birth_range_match(self, from_year, to_year):
    """Checks if the birth year of a person lies within the given range
    :type from_year: int
    :type to_year: int
    :rtype: bool
    """
    birth_year = self.get_birth_year()

    if from_year <= birth_year <= to_year:
        return True

    return False
def birth_year_match(self, year)

Returns True if the given year matches the birth year of this person :type year: int :rtype: bool

Expand source code
def birth_year_match(self, year):
    """Returns `True` if the given year matches the birth year of this person
    :type year: int
    :rtype: bool
    """
    return self.get_birth_year() == year
def criteria_match(self, criteria)

Checks if this individual matches all of the given criteria

criteria is a colon-separated list, where each item in the list has the form [name]=[value]. The following criteria are supported:

surname=[name] Match a person with [name] in any part of the surname. given_name=[given_name] Match a person with [given_name] in any part of the given given_name. birth=[year] Match a person whose birth year is a four-digit [year]. birth_range=[from_year-to_year] Match a person whose birth year is in the range of years from [from_year] to [to_year], including both [from_year] and [to_year].

:type criteria: str :rtype: bool

Expand source code
def criteria_match(self, criteria):
    """Checks if this individual matches all of the given criteria

    `criteria` is a colon-separated list, where each item in the
    list has the form [name]=[value]. The following criteria are supported:

    surname=[name]
         Match a person with [name] in any part of the `surname`.
    given_name=[given_name]
         Match a person with [given_name] in any part of the given `given_name`.
    birth=[year]
         Match a person whose birth year is a four-digit [year].
    birth_range=[from_year-to_year]
         Match a person whose birth year is in the range of years from
         [from_year] to [to_year], including both [from_year] and [to_year].

    :type criteria: str
    :rtype: bool
    """

    # Check if criteria is a valid criteria and can be split by `:` and `=` characters
    try:
        for criterion in criteria.split(':'):
            criterion.split('=')
    except ValueError:
        return False

    match = True

    for criterion in criteria.split(':'):
        key, value = criterion.split('=')

        if key == "surname" and not self.surname_match(value):
            match = False
        elif key == "name" and not self.given_name_match(value):
            match = False
        elif key == "birth":

            try:
                year = int(value)
                if not self.birth_year_match(year):
                    match = False
            except ValueError:
                match = False

        elif key == "birth_range":

            try:
                from_year, to_year = value.split('-')
                from_year = int(from_year)
                to_year = int(to_year)
                if not self.birth_range_match(from_year, to_year):
                    match = False
            except ValueError:
                match = False

        elif key == "death":

            try:
                year = int(value)
                if not self.death_year_match(year):
                    match = False
            except ValueError:
                match = False

        elif key == "death_range":

            try:
                from_year, to_year = value.split('-')
                from_year = int(from_year)
                to_year = int(to_year)
                if not self.death_range_match(from_year, to_year):
                    match = False
            except ValueError:
                match = False

    return match
def death_range_match(self, from_year, to_year)

Checks if the death year of a person lies within the given range :type from_year: int :type to_year: int :rtype: bool

Expand source code
def death_range_match(self, from_year, to_year):
    """Checks if the death year of a person lies within the given range
    :type from_year: int
    :type to_year: int
    :rtype: bool
    """
    death_year = self.get_death_year()

    if from_year <= death_year <= to_year:
        return True

    return False
def death_year_match(self, year)

Returns True if the given year matches the death year of this person :type year: int :rtype: bool

Expand source code
def death_year_match(self, year):
    """Returns `True` if the given year matches the death year of this person
    :type year: int
    :rtype: bool
    """
    return self.get_death_year() == year
def get_all_names(self)
Expand source code
def get_all_names(self):
    return [a.get_value() for a in self.get_child_elements() if a.get_tag() == gedcom.tags.GEDCOM_TAG_NAME]
def get_birth_data(self)

Returns the birth data of a person formatted as a tuple: (str date, str place, list sources) :rtype: tuple

Expand source code
def get_birth_data(self):
    """Returns the birth data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
    :rtype: tuple
    """
    date = ""
    place = ""
    sources = []

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
            for childOfChild in child.get_child_elements():

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date = childOfChild.get_value()

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                    place = childOfChild.get_value()

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                    sources.append(childOfChild.get_value())

    return date, place, sources
def get_birth_year(self)

Returns the birth year of a person in integer format :rtype: int

Expand source code
def get_birth_year(self):
    """Returns the birth year of a person in integer format
    :rtype: int
    """
    date = ""

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_BIRTH:
            for childOfChild in child.get_child_elements():
                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date_split = childOfChild.get_value().split()
                    date = date_split[len(date_split) - 1]

    if date == "":
        return -1
    try:
        return int(date)
    except ValueError:
        return -1
def get_burial(self)

Returns the burial data of a person formatted as a tuple: (str date, str´ place,listsources) ::deprecated:: As of version 1.0.0 useget_burial_data()` method instead :rtype: tuple

Expand source code
@deprecated
def get_burial(self):
    """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
    ::deprecated:: As of version 1.0.0 use `get_burial_data()` method instead
    :rtype: tuple
    """
    self.get_burial_data()
def get_burial_data(self)

Returns the burial data of a person formatted as a tuple: (str date, str´ place,list` sources) :rtype: tuple

Expand source code
def get_burial_data(self):
    """Returns the burial data of a person formatted as a tuple: (`str` date, `str´ place, `list` sources)
    :rtype: tuple
    """
    date = ""
    place = ""
    sources = []

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_BURIAL:
            for childOfChild in child.get_child_elements():

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date = childOfChild.get_value()

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                    place = childOfChild.get_value()

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                    sources.append(childOfChild.get_value())

    return date, place, sources
def get_census(self)

Returns a list of censuses of an individual formatted as tuples: (str date, str´ place,listsources) ::deprecated:: As of version 1.0.0 useget_census_data()` method instead :rtype: list of tuple

Expand source code
@deprecated
def get_census(self):
    """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
    ::deprecated:: As of version 1.0.0 use `get_census_data()` method instead
    :rtype: list of tuple
    """
    self.get_census_data()
def get_census_data(self)

Returns a list of censuses of an individual formatted as tuples: (str date, str´ place,list` sources) :rtype: list of tuple

Expand source code
def get_census_data(self):
    """Returns a list of censuses of an individual formatted as tuples: (`str` date, `str´ place, `list` sources)
    :rtype: list of tuple
    """
    census = []

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_CENSUS:

            date = ''
            place = ''
            sources = []

            for childOfChild in child.get_child_elements():

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date = childOfChild.get_value()

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                    place = childOfChild.get_value()

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                    sources.append(childOfChild.get_value())

            census.append((date, place, sources))

    return census
def get_death_data(self)

Returns the death data of a person formatted as a tuple: (str date, str place, list sources) :rtype: tuple

Expand source code
def get_death_data(self):
    """Returns the death data of a person formatted as a tuple: (`str` date, `str` place, `list` sources)
    :rtype: tuple
    """
    date = ""
    place = ""
    sources = []

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
            for childOfChild in child.get_child_elements():
                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date = childOfChild.get_value()
                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_PLACE:
                    place = childOfChild.get_value()
                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SOURCE:
                    sources.append(childOfChild.get_value())

    return date, place, sources
def get_death_year(self)

Returns the death year of a person in integer format :rtype: int

Expand source code
def get_death_year(self):
    """Returns the death year of a person in integer format
    :rtype: int
    """
    date = ""

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
            for childOfChild in child.get_child_elements():
                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date_split = childOfChild.get_value().split()
                    date = date_split[len(date_split) - 1]

    if date == "":
        return -1
    try:
        return int(date)
    except ValueError:
        return -1
def get_gender(self)

Returns the gender of a person in string format :rtype: str

Expand source code
def get_gender(self):
    """Returns the gender of a person in string format
    :rtype: str
    """
    gender = ""

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_SEX:
            gender = child.get_value()

    return gender
def get_last_change_date(self)

Returns the date of when the person data was last changed formatted as a string :rtype: str

Expand source code
def get_last_change_date(self):
    """Returns the date of when the person data was last changed formatted as a string
    :rtype: str
    """
    date = ""

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_CHANGE:
            for childOfChild in child.get_child_elements():
                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_DATE:
                    date = childOfChild.get_value()

    return date
def get_name(self)

Returns an individual's names as a tuple: (str given_name, str surname) :rtype: tuple

Expand source code
def get_name(self):
    """Returns an individual's names as a tuple: (`str` given_name, `str` surname)
    :rtype: tuple
    """
    given_name = ""
    surname = ""

    # Return the first gedcom.tags.GEDCOM_TAG_NAME that is found.
    # Alternatively as soon as we have both the gedcom.tags.GEDCOM_TAG_GIVEN_NAME and _SURNAME return those.
    found_given_name = False
    found_surname_name = False

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_NAME:
            # Some GEDCOM files don't use child tags but instead
            # place the name in the value of the NAME tag.
            if child.get_value() != "":
                name = child.get_value().split('/')

                if len(name) > 0:
                    given_name = name[0].strip()
                    if len(name) > 1:
                        surname = name[1].strip()

                return given_name, surname

            for childOfChild in child.get_child_elements():

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_GIVEN_NAME:
                    given_name = childOfChild.get_value()
                    found_given_name = True

                if childOfChild.get_tag() == gedcom.tags.GEDCOM_TAG_SURNAME:
                    surname = childOfChild.get_value()
                    found_surname_name = True

            if found_given_name and found_surname_name:
                return given_name, surname

    # If we reach here we are probably returning empty strings
    return given_name, surname
def get_occupation(self)

Returns the occupation of a person :rtype: str

Expand source code
def get_occupation(self):
    """Returns the occupation of a person
    :rtype: str
    """
    occupation = ""

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_OCCUPATION:
            occupation = child.get_value()

    return occupation
def given_match(self, name)

Matches a string with the given name of an individual ::deprecated:: As of version 1.0.0 use given_name_match() method instead :type name: str :rtype: bool

Expand source code
@deprecated
def given_match(self, name):
    """Matches a string with the given name of an individual
    ::deprecated:: As of version 1.0.0 use `given_name_match()` method instead
    :type name: str
    :rtype: bool
    """
    return self.given_name_match(name)
def given_name_match(self, given_name_to_match)

Matches a string with the given name of an individual :type given_name_to_match: str :rtype: bool

Expand source code
def given_name_match(self, given_name_to_match):
    """Matches a string with the given name of an individual
    :type given_name_to_match: str
    :rtype: bool
    """
    (given_name, surname) = self.get_name()
    return regex.search(given_name_to_match, given_name, regex.IGNORECASE)
def is_child(self)

Checks if this element is a child of a family :rtype: bool

Expand source code
def is_child(self):
    """Checks if this element is a child of a family
    :rtype: bool
    """
    found_child = False

    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_FAMILY_CHILD:
            found_child = True

    return found_child
def is_deceased(self)

Checks if this individual is deceased :rtype: bool

Expand source code
def is_deceased(self):
    """Checks if this individual is deceased
    :rtype: bool
    """
    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_DEATH:
            return True

    return False
def is_private(self)

Checks if this individual is marked private :rtype: bool

Expand source code
def is_private(self):
    """Checks if this individual is marked private
    :rtype: bool
    """
    for child in self.get_child_elements():
        if child.get_tag() == gedcom.tags.GEDCOM_TAG_PRIVATE:
            private = child.get_value()
            if private == 'Y':
                return True

    return False
def surname_match(self, surname_to_match)

Matches a string with the surname of an individual :type surname_to_match: str :rtype: bool

Expand source code
def surname_match(self, surname_to_match):
    """Matches a string with the surname of an individual
    :type surname_to_match: str
    :rtype: bool
    """
    (given_name, surname) = self.get_name()
    return regex.search(surname_to_match, surname, regex.IGNORECASE)

Inherited members

class NotAnActualIndividualError (...)

Common base class for all non-exit exceptions.

Expand source code
class NotAnActualIndividualError(Exception):
    pass

Ancestors

  • builtins.Exception
  • builtins.BaseException