示例#1
0
    def get_families(self,
                     individual,
                     family_type=gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE):
        """Return family elements listed for an individual

        family_type can be `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` (families where the individual is a spouse) or
        `gedcom.tags.GEDCOM_TAG_FAMILY_CHILD` (families where the individual is a child). If a value is not
        provided, `gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE` is default value.

        :type individual: IndividualElement
        :type family_type: str
        :rtype: list of FamilyElement
        """
        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        families = []
        element_dictionary = self.get_element_dictionary()

        for child_element in individual.get_child_elements():
            is_family = (
                child_element.get_tag() == family_type
                and child_element.get_value() in element_dictionary
                and element_dictionary[child_element.get_value()].is_family())
            if is_family:
                families.append(element_dictionary[child_element.get_value()])

        return families
示例#2
0
    def get_marriage_years(self, individual):
        """Returns a list of marriage years (as integers) for an individual
        :type individual: IndividualElement
        :rtype: list of int
        """
        dates = []

        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        # Get and analyze families where individual is spouse.
        families = self.get_families(individual,
                                     gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE)
        for family in families:
            for child in family.get_child_elements():
                if child.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE:
                    for childOfChild in child.get_child_elements():
                        if childOfChild.get_tag(
                        ) == gedcom.tags.GEDCOM_TAG_DATE:
                            date = childOfChild.get_value().split()[-1]
                            try:
                                dates.append(int(date))
                            except ValueError:
                                pass
        return dates
示例#3
0
 def get_marriages(self, individual):
     """Returns a list of marriages of an individual formatted as a tuple (`str` date, `str` place)
     :type individual: IndividualElement
     :rtype: tuple
     """
     marriages = []
     if not isinstance(individual, IndividualElement):
         raise NotAnActualIndividualError(
             "Operation only valid for elements with %s tag" %
             gedcom.tags.GEDCOM_TAG_INDIVIDUAL)
     # Get and analyze families where individual is spouse.
     families = self.get_families(individual,
                                  gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE)
     for family in families:
         for family_data in family.get_child_elements():
             if family_data.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE:
                 date = ''
                 place = ''
                 for marriage_data in family_data.get_child_elements():
                     if marriage_data.get_tag(
                     ) == gedcom.tags.GEDCOM_TAG_DATE:
                         date = marriage_data.get_value()
                     if marriage_data.get_tag(
                     ) == gedcom.tags.GEDCOM_TAG_PLACE:
                         place = marriage_data.get_value()
                 marriages.append((date, place))
     return marriages
示例#4
0
    def get_marriages(self, individual):
        """Returns a list of marriages of an individual formatted as a tuple (`str` date, `str` place)
        :type individual: IndividualElement
        :rtype: tuple
        """
        marriages = []
        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)
        # Get and analyze families where individual is spouse.
        families = self.get_families(individual,
                                     gedcom.tags.GEDCOM_TAG_FAMILY_SPOUSE)
        # TODO: Combine this code with the IndividualElement.get_fact_data method.
        for family in families:
            for family_data in family.get_child_elements():
                if family_data.get_tag() == gedcom.tags.GEDCOM_TAG_MARRIAGE:
                    spouses = self.get_family_members(
                        family, FAMILY_MEMBERS_TYPE_PARENTS)
                    spouse = [
                        spouse.get_pointer() for spouse in spouses
                        if spouse.get_pointer() != individual.get_pointer()
                    ]
                    value = spouse[0] if spouse else ''
                    date = ''
                    place = ''
                    sources = []
                    note = ''
                    for marriage_data in family_data.get_child_elements():
                        if marriage_data.get_tag(
                        ) == gedcom.tags.GEDCOM_TAG_DATE:
                            date = marriage_data.get_value()
                        if marriage_data.get_tag(
                        ) == gedcom.tags.GEDCOM_TAG_PLACE:
                            place = marriage_data.get_value()
                        if marriage_data.get_tag(
                        ) == gedcom.tags.GEDCOM_TAG_SOURCE:
                            master_source = marriage_data.get_value()
                            reference = marriage_data.get_descendant_value(
                                [gedcom.tags.GEDCOM_TAG_REFERENCE])
                            page = marriage_data.get_descendant_value(
                                [gedcom.tags.GEDCOM_TAG_PAGE])
                            data = marriage_data.get_descendant_value([
                                gedcom.tags.GEDCOM_TAG_DATA,
                                gedcom.tags.GEDCOM_TAG_TEXT
                            ])

                            sources.append({
                                'master': master_source,
                                'reference': reference,
                                'page': page,
                                'data': data
                            })
                        if marriage_data.get_tag(
                        ) == gedcom.tags.GEDCOM_TAG_NOTE:
                            note = marriage_data.get_multi_line_value()
                    marriages.append((value, date, place, sources, note))
        return marriages
示例#5
0
    def marriage_year_match(self, individual, year):
        """Checks if one of the marriage years of an individual matches the supplied year. Year is an integer.
        :type individual: IndividualElement
        :type year: int
        :rtype: bool
        """
        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        years = self.get_marriage_years(individual)
        return year in years
示例#6
0
    def marriage_range_match(self, individual, from_year, to_year):
        """Check if one of the marriage years of an individual is in a given range. Years are integers.
        :type individual: IndividualElement
        :type from_year: int
        :type to_year: int
        :rtype: bool
        """
        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        years = self.get_marriage_years(individual)
        for year in years:
            if from_year <= year <= to_year:
                return True
        return False
示例#7
0
    def get_parents(self, individual, parent_type="ALL"):
        """Return elements corresponding to parents of an individual

        Optional parent_type. Default "ALL" returns all parents. "NAT" can be
        used to specify only natural (genetic) parents.

        :type individual: IndividualElement
        :type parent_type: str
        :rtype: list of IndividualElement
        """
        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        parents = []
        families = self.get_families(individual,
                                     gedcom.tags.GEDCOM_TAG_FAMILY_CHILD)

        for family in families:
            if parent_type == "NAT":
                for family_member in family.get_child_elements():

                    if family_member.get_tag() == gedcom.tags.GEDCOM_TAG_CHILD \
                       and family_member.get_value() == individual.get_pointer():

                        for child in family_member.get_child_elements():
                            if child.get_value() == "Natural":
                                if child.get_tag(
                                ) == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_MREL:
                                    parents += self.get_family_members(
                                        family, gedcom.tags.GEDCOM_TAG_WIFE)
                                elif child.get_tag(
                                ) == gedcom.tags.GEDCOM_PROGRAM_DEFINED_TAG_FREL:
                                    parents += self.get_family_members(
                                        family, gedcom.tags.GEDCOM_TAG_HUSBAND)
            else:
                parents += self.get_family_members(family, "PARENTS")

        return parents
示例#8
0
    def get_ancestors(self, individual, ancestor_type="ALL"):
        """Return elements corresponding to ancestors of an individual

        Optional `ancestor_type`. Default "ALL" returns all ancestors, "NAT" can be
        used to specify only natural (genetic) ancestors.

        :type individual: IndividualElement
        :type ancestor_type: str
        :rtype: list of Element
        """
        if not isinstance(individual, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag" %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        parents = self.get_parents(individual, ancestor_type)
        ancestors = []
        ancestors.extend(parents)

        for parent in parents:
            ancestors.extend(self.get_ancestors(parent))

        return ancestors
示例#9
0
    def find_path_to_ancestor(self, descendant, ancestor, path=None):
        """Return path from descendant to ancestor
        :rtype: object
        """
        if not isinstance(descendant, IndividualElement) and isinstance(
                ancestor, IndividualElement):
            raise NotAnActualIndividualError(
                "Operation only valid for elements with %s tag." %
                gedcom.tags.GEDCOM_TAG_INDIVIDUAL)

        if not path:
            path = [descendant]

        if path[-1].get_pointer() == ancestor.get_pointer():
            return path
        else:
            parents = self.get_parents(descendant, "NAT")
            for parent in parents:
                potential_path = self.find_path_to_ancestor(
                    parent, ancestor, path + [parent])
                if potential_path is not None:
                    return potential_path

        return None