From 3438c8973d5a2a0bb967ec6991ae16385fc981ad Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Sun, 18 Nov 2007 23:39:14 +0000 Subject: [PATCH] 2007-11-19 Benny Malengier * src/Relationship.py: many improvements and bug fixes * src/plugins/all_relations.py: bug fixes * src/plugins/RelCalc.py: use new API * src/plugins/rel_nl.py: finished, removed comment * src/plugins/rel_it.py: finished * src/plugins/rel_pl.py: move old code here away from Relationship * src/plugins/rel_pt.py: import gen.lib svn: r9367 --- ChangeLog | 9 + src/Relationship.py | 221 ++++++++++++------ src/plugins/RelCalc.py | 112 ++++----- src/plugins/all_relations.py | 8 +- src/plugins/rel_it.py | 425 ++++++++++++++++++++++++++++++----- src/plugins/rel_nl.py | 1 - src/plugins/rel_pl.py | 27 +++ src/plugins/rel_pt.py | 2 +- 8 files changed, 611 insertions(+), 194 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3c6a508f..879571d7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-11-19 Benny Malengier + * src/Relationship.py: many improvements and bug fixes + * src/plugins/all_relations.py: bug fixes + * src/plugins/RelCalc.py: use new API + * src/plugins/rel_nl.py: finished, removed comment + * src/plugins/rel_it.py: finished + * src/plugins/rel_pl.py: move old code here away from Relationship + * src/plugins/rel_pt.py: import gen.lib + 2007-11-18 Brian Matherly * src/plugins/NarrativeWeb.py: Fix 0001361: Web report: Directory name conflicts diff --git a/src/Relationship.py b/src/Relationship.py index 44ab70b71..c34eef0f1 100644 --- a/src/Relationship.py +++ b/src/Relationship.py @@ -616,32 +616,6 @@ class RelationshipCalculator: orig.get_gender(), other.get_gender()) else: return None - - def __apply_filter_old(self, db, person, rel_str, plist, pmap, depth=1): - """ DEPRECATED -- DO NOT USE - """ - if person == None or depth > MAX_DEPTH: - return - depth += 1 - plist.append(person.handle) - pmap[person.handle] = rel_str # ?? this overwrites if person is double! - - family_handle = person.get_main_parents_family_handle() - try: - if family_handle: - family = db.get_family_from_handle(family_handle) - fhandle = family.father_handle - if fhandle: - father = db.get_person_from_handle(fhandle) - self.__apply_filter_old(db, father, rel_str+'f', plist, pmap, - depth) - mhandle = family.mother_handle - if mhandle: - mother = db.get_person_from_handle(mhandle) - self.__apply_filter_old(db, mother, rel_str+'m', plist, pmap, - depth) - except: - return def get_relationship_distance(self, db, orig_person, other_person): """ @@ -759,6 +733,7 @@ class RelationshipCalculator: self.__all_families = all_families self.__all_dist = all_dist self.__only_birth = only_birth + self.__crosslinks = False # no crosslinks firstRel = -1 secondRel = -1 @@ -776,10 +751,7 @@ class RelationshipCalculator: try: self.__apply_filter(db, orig_person, '', [], firstMap) self.__apply_filter(db, other_person, '', [], secondMap, - stoprecursemap = firstMap, - store_all=False) -## print firstMap -## print secondMap + stoprecursemap = firstMap) except RuntimeError: return (-1,None,-1,[],-1,[] ) , \ [_("Relationship loop detected")] + self.__msg @@ -788,15 +760,15 @@ class RelationshipCalculator: if firstMap.has_key(person_handle) : com = [] #a common ancestor - for rel1,fam1 in zip(firstMap[person_handle][0], + for rel1, fam1 in zip(firstMap[person_handle][0], firstMap[person_handle][1]): l1 = len(rel1) - for rel2,fam2 in zip(secondMap[person_handle][0], + for rel2, fam2 in zip(secondMap[person_handle][0], secondMap[person_handle][1]): l2 = len(rel2) #collect paths to arrive at common ancestor - com.append((l1+l2,person_handle,rel1,fam1, - rel2,fam2)) + com.append((l1+l2, person_handle, rel1, fam1, + rel2, fam2)) #insert common ancestor in correct position, # if shorter links, check if not subset # if longer links, check if not superset @@ -828,7 +800,7 @@ class RelationshipCalculator: if rel1new == rel1[:len(rel1new)] and \ rel2new == rel2[:len(rel2new)] : deletelist.append(index) - index += 1 + index += 1 deletelist.reverse() for index in deletelist: del common[index] @@ -837,8 +809,6 @@ class RelationshipCalculator: self.__msg += [_('Family tree reaches back more than the maximum ' '%d generations searched.\nIt is possible that ' 'relationships have been missed') % (max_depth)] - -## print 'common list :', common if common and not self.__all_dist : rank = common[0][0] @@ -859,13 +829,18 @@ class RelationshipCalculator: return [(-1,None,'',[],'',[])], self.__msg def __apply_filter(self, db, person, rel_str, rel_fam, pmap, - depth=1, stoprecursemap=None, store_all=True): - '''We recursively add parents of person in pmap with correct rel_str, - if store_all. If store_all false, only store parents if in the - stoprecursemap. - Stop recursion if parent is in the stoprecursemap (no need to - look parents of otherpers if done so already for origpers) - store pers + depth=1, stoprecursemap=None): + '''Typically this method is called recursively in two ways: + First method is stoprecursemap= None + In this case a recursemap is builded by storing all data. + + Second method is with a stoprecursemap given + In this case parents are recursively looked up. If present in + stoprecursemap, a common ancestor is found, and the method can + stop looking further. If however self.__crosslinks == True, the data + of first contains loops, and parents + will be looked up anyway an stored if common. At end the doubles + are filtered out ''' if person == None or not person.handle : return @@ -878,14 +853,20 @@ class RelationshipCalculator: depth += 1 commonancestor = False - if stoprecursemap and stoprecursemap.has_key(person.handle) : - commonancestor = True + store = True #normally we store all parents + if stoprecursemap: + store = False #but not if a stop map given + if stoprecursemap.has_key(person.handle): + commonancestor = True + store = True #add person to the map, take into account that person can be obtained #from different sides - if pmap.has_key(person.handle) : + if pmap.has_key(person.handle): #person is already a grandparent in another branch, we already have - # had lookup of all parents + # had lookup of all parents, we call that a crosslink + if not stoprecursemap: + self.__crosslinks = True pmap[person.handle][0] += [rel_str] pmap[person.handle][1] += [rel_fam] #check if there is no loop father son of his son, ... @@ -901,29 +882,28 @@ class RelationshipCalculator: (person.get_primary_name().get_name(), rel2[len(rel1):])] return - elif store_all or commonancestor: + elif store: pmap[person.handle] = [[rel_str],[rel_fam]] #having added person to the pmap, we only look up recursively to # parents if this person is not common relative - if commonancestor : -## print 'common ancestor found' + # if however the first map has crosslinks, we need to continue reduced + if commonancestor and not self.__crosslinks : + #don't continue search, great speedup! return family_handles = [] main = person.get_main_parents_family_handle() -## print 'main',main if main : family_handles = [main] if self.__all_families : - family_handles = person.get_parent_family_handle_list() -## print 'all_families', family_handles + family_handles = person.get_parent_family_handle_list() try: parentstodo = {} fam = 0 for family_handle in family_handles : - rel_fam_new = rel_fam +[fam] + rel_fam_new = rel_fam + [fam] family = db.get_family_from_handle(family_handle) #obtain childref for this person childrel = [(ref.get_mother_relation(), @@ -982,8 +962,7 @@ class RelationshipCalculator: data = parentstodo[handle] self.__apply_filter(db, data[0], data[1], data[2], - pmap, depth, stoprecursemap, store_all) - + pmap, depth, stoprecursemap) except: import traceback print traceback.print_exc() @@ -1021,11 +1000,13 @@ class RelationshipCalculator: relfamfirst = relation[3][:] relfamsec = relation[5][:] #handle pure sibling: + rela2 = relation[2] + rela4 = relation[4] if relation[2] and relation[2][-1] == self.REL_SIBLING: #sibling will be the unique common ancestor, #change to a family with unknown handle for common ancestor - relation[2] = relation[2][:-1] + self.REL_FAM_BIRTH - relation[4] = relation[4] + self.REL_FAM_BIRTH + rela2 = relation[2][:-1] + self.REL_FAM_BIRTH + rela4 = relation[4] + self.REL_FAM_BIRTH relfamsec = relfamsec + [relfamfirst[-1]] relstrsec = relation[4][:-1] commonhandle = [] @@ -1052,7 +1033,6 @@ class RelationshipCalculator: else: familypaths.append((relstrfirst, relstrsec, relfamfirst, relfamsec)) - ##print 'resulting fam path', familypaths for familypath in familypaths: #familypath = (relstrfirst, relstrsec, relfamfirst, relfamsec) try: @@ -1062,28 +1042,58 @@ class RelationshipCalculator: #if relstr is '', the ancestor is unique, if posfam None, # first time we see this family path if (posfam is not None and relstrfirst is not None and - relstrsec is not None): + relstrsec is not None): #we already have a common ancestor of this family, just add the #other, setting correct family relation tmp = commonnew[posfam] - frstcomstr = relation[2][-1] + frstcomstr = rela2[-1] scndcomstr = tmp[2][-1] newcomstra = self.famrel_from_persrel(frstcomstr, scndcomstr) - frstcomstr = relation[4][-1] + frstcomstr = rela4[-1] scndcomstr = tmp[4][-1] newcomstrb = self.famrel_from_persrel(frstcomstr, scndcomstr) commonnew[posfam] = (tmp[0], tmp[1]+commonhandle, - relation[2][:-1]+newcomstra, - tmp[3], relation[4][:-1]+newcomstrb, + rela2[:-1]+newcomstra, + tmp[3], rela4[:-1]+newcomstrb, tmp[5]) else : existing_path.append(familypath) - commonnew.append((relation[0], commonhandle, relation[2], - relfamfirst, relation[4], relfamsec) - ) - ##print 'commonnew', commonnew - return commonnew + commonnew.append((relation[0], commonhandle, rela2, + familypath[2], rela4, familypath[3]) + ) + #we now have multiple person handles, single families, now collapse + # families again if all else equal + collapsed = commonnew[:1] + for rel in commonnew[1:]: + found = False + for newrel in collapsed: + if newrel[0:3] == rel[0:3] and newrel[4] == rel[4]: + #another familypath to arrive at same result, merge + path1 = [] + path2 = [] + for a, b in zip(newrel[3], rel[3]): + if a == b: + path1.append(a) + elif isinstance(a, list): + path1.append(a.append(b)) + else: + path1.append([a, b]) + for a, b in zip(newrel[5], rel[5]): + if a == b: + path2.append(a) + elif isinstance(a, list): + path2.append(a.append(b)) + else: + path2.append([a, b]) + newrel[3][:] = path1[:] + newrel[5][:] = path2[:] + found = True + break + if not found: + collapsed.append(rel) + + return collapsed def famrel_from_persrel(self, persrela, persrelb): """ Conversion from eg 'f' and 'm' to 'a', so relation to the two @@ -1161,8 +1171,9 @@ class RelationshipCalculator: return ('', -1, -1) else: return '' - + data = self.collapse_relations(data) + #most relevant relationship is a birth family relation of lowest rank databest = [data[0]] rankbest = data[0][0] @@ -1248,7 +1259,73 @@ class RelationshipCalculator: return (rel_str, dist_orig, dist_other) else: return rel_str + + def get_all_relationships(self, db, orig_person, other_person): + """ Returns a tuple, of which the first entry is a list with all + relationships in text, and the second a list of lists of all common + ancestors that have that text as relationship + """ + relstrings = [] + commons = {} + if orig_person == None: + return ([], []) + + if orig_person.get_handle() == other_person.get_handle(): + return ([], []) + + is_spouse = self.is_spouse(db, orig_person, other_person) + if is_spouse: + relstrings.append(is_spouse) + commons[is_spouse] = [] + data, msg = self.get_relationship_distance_new( + db, orig_person, other_person, + all_dist=True, + all_families=True, only_birth=False) + if not data[0][0] == -1: + for rel in data : + rel2 = rel[2] + rel4 = rel[4] + rel1 = rel[1] + dist_orig = len(rel[2]) + dist_other= len(rel[4]) + if rel[2] and rel[2][-1] == self.REL_SIBLING: + rel2 = rel2[:-1] + self.REL_FAM_BIRTH + dist_other += 1 + rel4 = rel4 + self.REL_FAM_BIRTH + rel1 = None + birth = self.only_birth(rel2) and self.only_birth(rel4) + if dist_orig == 1 and dist_other == 1: + rel_str = self.get_sibling_relationship_string( + self.get_sibling_type( + db, orig_person, other_person), + orig_person.get_gender(), + other_person.get_gender()) + else: + rel_str = self.get_single_relationship_string(dist_orig, + dist_other, + orig_person.get_gender(), + other_person.get_gender(), + rel2, rel4, + only_birth=birth, + in_law_a=False, + in_law_b=False) + if not rel_str in relstrings: + relstrings.append(rel_str) + if rel1: + commons[rel_str] = [rel1] + else: + #unknown parent eg + commons[rel_str] = [] + else: + if rel1: + commons[rel_str].append(rel1) + #construct the return tupply, relstrings is ordered on rank automatic + common_list = [] + for rel_str in relstrings: + common_list.append(commons[rel_str]) + return (relstrings, common_list) + def get_relationship(self, db, orig_person, other_person): """ returns a string representing the relationshp between the two people, @@ -1463,8 +1540,6 @@ class RelationshipCalculator: 2/for better determination of siblings, use if Ga=1=Gb get_sibling_relationship_string """ -## print 'Ga, Gb :', Ga, Gb - if only_birth: step = '' else: diff --git a/src/plugins/RelCalc.py b/src/plugins/RelCalc.py index 3a8594d1a..6d2582065 100644 --- a/src/plugins/RelCalc.py +++ b/src/plugins/RelCalc.py @@ -89,7 +89,7 @@ class RelCalc(Tool.Tool, ManagedWindow.ManagedWindow): self.relationship = relationship_class() base = os.path.dirname(__file__) - glade_file = "%s/relcalc.glade" % base + glade_file = base + os.sep + "relcalc.glade" self.glade = gtk.glade.XML(glade_file,"relcalc","gramps") name = name_displayer.display(self.person) @@ -144,64 +144,68 @@ class RelCalc(Tool.Tool, ManagedWindow.ManagedWindow): handle = model.get_value(node,len(PeopleModel.COLUMN_DEFS)-1) other_person = self.db.get_person_from_handle(handle) - if other_person != None: - (rel_string,common) = self.relationship.get_relationship( - self.db,self.person,other_person) - # A quick way to get unique list - common = list(set(common)) - length = len(common) - else: - length = 0 + text1 = self.glade.get_widget("text1").get_buffer() + + if other_person is None : + text1.set_text("") + return + + #now determine the relation, and print it out + rel_strings, common_an = self.relationship.get_all_relationships( + self.db, self.person, other_person) - if other_person == None: - commontext = "" - elif length == 1: - person = self.db.get_person_from_handle(common[0]) - if common[0] == other_person.handle or \ - common[0] == self.person.handle : - commontext = '' - else : - name = name_displayer.display(person) - commontext = " " + _("Their common ancestor is %s.") % name - elif length == 2: - p1 = self.db.get_person_from_handle(common[0]) - p2 = self.db.get_person_from_handle(common[1]) - p1str = name_displayer.display(p1) - p2str = name_displayer.display(p2) - commontext = " " + _("Their common ancestors are %s and %s." - ) % (p1str,p2str) - elif length > 2: - index = 0 - commontext = " " + _("Their common ancestors are: ") - for person_handle in common: - person = self.db.get_person_from_handle(person_handle) - if index != 0: - commontext = commontext + ", " - commontext = commontext + name_displayer.display(person) - index = index + 1 - commontext = commontext + "." - else: - commontext = "" + p1 = name_displayer.display(self.person) + p2 = name_displayer.display(other_person) - text1 = self.glade.get_widget("text1").get_buffer() - - if other_person: - p1 = name_displayer.display(self.person) - p2 = name_displayer.display(other_person) - - if other_person == None: - rstr = "" + text = [] + if other_person == None: + pass elif self.person.handle == other_person.handle: - rstr = _("%s and %s are the same person.") % (p1,p2) - elif rel_string == "": + rstr = _("%s and %s are the same person.") % (p1, p2) + text.append((rstr, "")) + elif len(rel_strings) == 0: rstr = _("%(person)s and %(active_person)s are not related.") % { - 'person' : p2, 'active_person' : p1 } - else: - rstr = _("%(person)s is the %(relationship)s of %(active_person)s." - ) % {'person' : p2, 'relationship' : rel_string, - 'active_person' : p1 } + 'person' : p2, 'active_person' : p1 } + text.append((rstr, "")) - text1.set_text("%s %s" % (rstr, commontext)) + for rel_string, common in zip(rel_strings, common_an): + rstr = _("%(person)s is the %(relationship)s of %(active_person)s." + ) % {'person' : p2, 'relationship' : rel_string, + 'active_person' : p1 } + length = len(common) + if length == 1: + person = self.db.get_person_from_handle(common[0]) + if common[0] == other_person.handle or \ + common[0] == self.person.handle : + commontext = '' + else : + name = name_displayer.display(person) + commontext = " " + _("Their common ancestor is %s.") % name + elif length == 2: + p1c = self.db.get_person_from_handle(common[0]) + p2c = self.db.get_person_from_handle(common[1]) + p1str = name_displayer.display(p1c) + p2str = name_displayer.display(p2c) + commontext = " " + _("Their common ancestors are %s and %s." + ) % (p1str,p2str) + elif length > 2: + index = 0 + commontext = " " + _("Their common ancestors are: ") + for person_handle in common: + person = self.db.get_person_from_handle(person_handle) + if index != 0: + commontext = commontext + ", " + commontext = commontext + name_displayer.display(person) + index = index + 1 + commontext = commontext + "." + else: + commontext = "" + text.append((rstr, commontext)) + + textval = "" + for val in text: + textval += "%s %s\n" % (val[0], val[1]) + text1.set_text(textval) #------------------------------------------------------------------------ # diff --git a/src/plugins/all_relations.py b/src/plugins/all_relations.py index 040120404..e72d378ac 100644 --- a/src/plugins/all_relations.py +++ b/src/plugins/all_relations.py @@ -97,7 +97,6 @@ class AllRelReport(): all_dist=True, only_birth=False, max_depth=20) - #all relations if (not common or common[0][0]== -1 ) and not is_spouse: rstr = _("%(person)s and %(active_person)s are not " @@ -241,7 +240,7 @@ class AllRelReport(): else: skip_list_text.append(rel_str) sdoc.paragraph(_FMT % (count-len(skip_list), rel_str)) - else : + else: sdoc.paragraph(_FMT % (count, rel_str)) count += 1 return count @@ -272,8 +271,9 @@ class AllRelReport(): sdoc.paragraph("") for relation in relations: if count in skip_list: + count += 1 continue - counter = str(count) + counter = str(count - len([x for x in range(count) if x+1 in skip_list])) name = _('Unknown') if relation[1]: name = self.sdb.name(self.database.get_person_from_handle( @@ -314,7 +314,7 @@ class AllRelReport(): famstr = '' if isinstance(fam, list): famstr = str(fam[0]+1) - for val in fam : + for val in fam[1:] : famstr = famstr + ', ' + str(val+1) else: famstr = str(fam+1) diff --git a/src/plugins/rel_it.py b/src/plugins/rel_it.py index 4f10900ca..9d2aee6a7 100644 --- a/src/plugins/rel_it.py +++ b/src/plugins/rel_it.py @@ -1,3 +1,4 @@ +# -*- python -*- # -*- coding: utf-8 -*- # # Gramps - a GTK+/GNOME based genealogy program @@ -23,6 +24,8 @@ # # Written by Lorenzo Cappelletti , 2003 +# Benny Malengier , 2007 # #------------------------------------------------------------------------- @@ -42,12 +45,77 @@ from PluginUtils import register_relcalc # #------------------------------------------------------------------------- -_level =\ - ["", "prim", "second", "terz", "quart", "quint", "sest", - "settim", "ottav", "non", "decim", "undicesim", "dodicesim", - "tredicesim", "quattordicesim", "quindicesim", "sedicesim", - "diciasettesim", "diciottesim", "diciannovesim", "ventesim"] +_level = [ + "", "prim%(gen)s", "second%(gen)s", "terz%(gen)s", "quart%(gen)s", + "quint%(gen)s", "sest%(gen)s", + "settim%(gen)s", "ottav%(gen)s", "non%(gen)s", "decim%(gen)s", + "undicesim%(gen)s", "dodicesim%(gen)s", + "tredicesim%(gen)s", "quattordicesim%(gen)s", "quindicesim%(gen)s", + "sedicesim%(gen)s", "diciasettesim%(gen)s", "diciottesim%(gen)s", + "diciannovesim%(gen)s", "ventesim%(gen)s" + ] +_level_m = [ + "", "primo", "secondo", "terzo", "quarto", + "quinto", "sesto", + "settimo", "ottavo", "nono", "decimo", + "undicesimo", "dodicesimo", + "tredicesimo", "quattordicesimo", "quindicesimo", + "sedicesimo", "diciasettesimo", "diciottesimo", + "diciannovesimo", "ventesimo" + ] + +_level_f = [ + "", "prima", "seconda", "terza", "quarta", + "quinta", "sesta", + "settima", "ottava", "nona", "decima", + "undicesima", "dodicesima", + "tredicesima", "quattordicesima", "quindicesima", + "sedicesima", "diciasettesima", "diciottesima", + "diciannovesima", "ventesima" + ] + +_father_level = [ "", + "il padre%(step)s%(inlaw)s", + "il nonno%(step)s%(inlaw)s", + "il bisnonno%(step)s%(inlaw)s", + "il trisnonno%(step)s%(inlaw)s", + ] + +_mother_level = [ "", + "la madre%(step)s%(inlaw)s", + "la nonna%(step)s%(inlaw)s", + "la bisnonna%(step)s%(inlaw)s", + "la trisnonna%(step)s%(inlaw)s", + ] + +_son_level = [ "", "il figlio%(step)s%(inlaw)s", + "il nipote%(step)s%(inlaw)s diretto", + "il pronipote%(step)s%(inlaw)s diretto" + ] + +_daughter_level = [ "", "la figlia%(step)s%(inlaw)s", + "la nipote%(step)s%(inlaw)s diretta", + "la pronipote%(step)s%(inlaw)s diretta" + ] + +_brother_level = [ "", "il fratello%(step)s%(inlaw)s", + "lo zio%(step)s%(inlaw)s", + "il prozio%(step)s%(inlaw)s", + ] + +_sister_level = [ "", "la sorella%(step)s%(inlaw)s", + "la zia%(step)s%(inlaw)s", + "la prozia%(step)s%(inlaw)s", + ] + +_nephew_level = [ "", "il nipote%(step)s%(inlaw)s", + "il pronipote%(step)s%(inlaw)s" + ] + +_niece_level = [ "", "la nipote%(step)s%(inlaw)s", + "la pronipote%(step)s%(inlaw)s" + ] #------------------------------------------------------------------------- # @@ -55,6 +123,10 @@ _level =\ # #------------------------------------------------------------------------- class RelationshipCalculator(Relationship.RelationshipCalculator): + + INLAW = ' acquisit%(gen)s' + + STEP = ' adottiv%(gen)s' def __init__(self): Relationship.RelationshipCalculator.__init__(self) @@ -68,70 +140,171 @@ class RelationshipCalculator(Relationship.RelationshipCalculator): # please, drop me an email. # #------------------------------------------------------------------------- + + def __gen_suffix(self, gender): + if gender == gen.lib.Person.MALE: + return 'o' + return 'a' + def get_parents (self,level): if level>len(_level)-1: return "remote ancestors" else: return "%si genitori" % _level[level] - def get_father (self,level, gender="o"): - if level>len(_level)-1: - return "remote ancestor" - elif level == 0: return "" - elif level == 1: return "padre" - elif level == 2: return "nonn%s" % gender - elif level == 3: return "bisnonn%s" % gender - else : return "%s%s nonn%s" % (_level[level], gender, gender) - - def get_mother (self,level): - if level == 1: return "madre" - else : return self.get_father(level, "a") - - def get_son (self, level, gender="o"): - if level>len(_level)-1: - return "remote descendant" - elif level == 0: return "" - elif level == 1: return "figli%s" % gender - elif level == 2: return "nipote" - elif level == 3: return "pronipote" - else : return "%s%s nipote" % (_level[level], gender) - - def get_daughter (self, level): - return self.get_son(level, "a") - - def get_uncle (self, level, gender="o"): - if level>len(_level)-1: - return "remote ancestor" - elif level == 0: return "" - elif level == 1: return "fratello" - elif level == 2: return "zi%s" % gender - elif level == 3: return "prozi%s" % gender - else : return "%s%s zi%s" % (_level[level], gender, gender) - - def get_aunt (self,level): - if level == 1: return "sorella" - else : return self.get_uncle(level, "a") - - def get_nephew(self,level, gender="o"): - if level>len(_level)-1: - return "remote descendant" - elif level == 0: return "" - elif level == 1: return "nipote" - elif level == 2: return "pronipote" - else : return "%s%s nipote" % (_level[level], gender) - - def get_niece(self,level): - return self.get_nephew(level, "a") - - def get_male_cousin (self,levelA, levelB, gender="o"): - if levelA+levelB>len(_level): - return "remote relative" + def get_father (self, level, step='', inlaw=''): + gen = "o" + + if level < len(_father_level): + return _father_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'il nonno%(step)s%(inlaw)s della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} else: - return "cugin%s di %so grado (%i-%i)" \ - % (gender, _level[levelA+levelB-1], levelA, levelB) + return "l'avo%(step)s%(inlaw)s (%(level)d generazioni)" % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} - def get_female_cousin (self,levelA, levelB): - return self.get_male_cousin(levelA, levelB, "a") + def get_mother (self, level, step='', inlaw=''): + gen = "a" + + if level < len(_father_level): + return _mother_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'la nonna%(step)s%(inlaw)s della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return "l'ava%(step)s%(inlaw)s (%(level)d generazioni)" % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_parent_unknown(self, level, step='', inlaw=''): + gen = "o/a" + + if level == 1: + return "uno dei genitori%(step)s%(inlaw)s" % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_father_level): + return _mother_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'nonno/a%(step)s%(inlaw)s della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return "l'ava%(step)s%(inlaw)s (%(level)d generazioni)" % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_son (self, level, step="", inlaw=""): + gen = "o" + if level < len(_son_level): + return _son_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'il nipote%(step)s%(inlaw)s diretto della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return "il discendente%(step)s%(inlaw)s diretto (%(level)d generazioni)" % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_daughter (self, level, step="", inlaw=""): + gen = "a" + if level < len(_daughter_level): + return _daughter_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'la nipote%(step)s%(inlaw)s diretta della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return "la discendente%(step)s%(inlaw)s diretta (%(level)d generazioni)" % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_uncle (self, level, step="", inlaw=""): + gen = "o" + if level < len(_brother_level): + return _brother_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'lo zio%(step)s%(inlaw)s della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return 'uno zio%(step)s%(inlaw)s lontano (%(level)d generazioni)' % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_aunt (self, level, step="", inlaw=""): + gen = "a" + if level < len(_brother_level): + return _sister_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'la zia%(step)s%(inlaw)s della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return 'una zia%(step)s%(inlaw)s lontana (%(level)d generazioni)' % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_nephew(self, level, step="", inlaw=""): + gen = "o" + if level < len(_nephew_level): + return _nephew_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'il nipote%(step)s%(inlaw)s ' \ + 'della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return 'un nipote%(step)s%(inlaw)s lontano ('\ + '%(level)d generazioni)' % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_niece(self, level, step="", inlaw=""): + gen = "a" + if level < len(_nephew_level): + return _niece_level[level] % {'step': step, 'inlaw': inlaw} \ + % {'gen': gen} + elif level < len(_level): + return 'la nipote%(step)s%(inlaw)s ' \ + 'della %(level_f)s generazione' % { + 'level_f': _level_f[level], + 'step': step, 'inlaw': inlaw} % {'gen': gen} + else: + return 'una nipote%(step)s%(inlaw)s lontana ('\ + '%(level)d generazioni)' % { + 'step': step, 'inlaw': inlaw, + 'level': level} % {'gen': gen} + + def get_male_cousin (self, levelA, levelB, step="", inlaw=""): + gen = "o" + return "il cugino%(step)s%(inlaw)s di %(level)d° grado"\ + "(%(levA)d-%(levB)d)" \ + % {'level': levelA+levelB-1, + 'step': step, 'inlaw': inlaw, + 'levA': levelA, + 'levB': levelB} % {'gen': gen} + + def get_female_cousin (self, levelA, levelB, step="", inlaw=""): + gen = "a" + return "la cugina%(step)s%(inlaw)s di %(level)d° grado"\ + "(%(levA)d-%(levB)d)" \ + % {'level': levelA+levelB-1, + 'step': step, 'inlaw': inlaw, + 'levA': levelA, + 'levB': levelB} % {'gen': gen} #------------------------------------------------------------------------- # @@ -199,6 +372,136 @@ class RelationshipCalculator(Relationship.RelationshipCalculator): else: return (self.get_female_cousin(firstRel-1, secondRel-1), common) + def get_single_relationship_string(self, Ga, Gb, gender_a, gender_b, + reltocommon_a, reltocommon_b, + only_birth=True, + in_law_a=False, in_law_b=False): + """ + See Comment in Relationship Class (Relationship.py) + """ + + if only_birth: + step = '' + else: + step = self.STEP + + if in_law_a or in_law_b : + inlaw = self.INLAW + else: + inlaw = '' + + if gender_b == gen.lib.Person.MALE: + rel_str = "un parente%s%s lontano" % (step, inlaw) % {'gen': 'o'} + elif gender_b == gen.lib.Person.FEMALE: + rel_str = "una parente%s%s lontana" % (step, inlaw) % {'gen': 'a'} + else: + rel_str = "uno dei parenti%s%s lontani" % (step, inlaw) % {'gen': 'i'} + + if Gb == 0: + if Ga == 0: + rel_str = 'la stessa persona' + elif Ga == 1 and inlaw and not step: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il suocero' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la suocera' + else: + rel_str = 'uno dei suoceri' + elif Ga == 1 and not inlaw and step: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il patrigno' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la matrigna' + else: + rel_str = 'uno dei genitori adottivi' + elif gender_b == gen.lib.Person.MALE: + rel_str = self.get_father(Ga, step, inlaw) + elif gender_b == gen.lib.Person.FEMALE: + rel_str = self.get_mother(Ga, step, inlaw) + else: + rel_str = self.get_parent_unknown(Ga, step, inlaw) + elif Ga == 0: + if Gb == 1 and inlaw and not step: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il genero' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la nuora' + else: + rel_str = 'genero/nuora' + elif gender_b == gen.lib.Person.MALE: + rel_str = self.get_son(Gb, step, inlaw) + else: + rel_str = self.get_daughter(Gb, step, inlaw) + elif Gb == 1: + if Ga == 1 and inlaw and not step: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il cognato' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la cognata' + else: + rel_str = 'il cognato/a' + if gender_b == gen.lib.Person.MALE: + rel_str = self.get_uncle(Ga, step, inlaw) + else: + rel_str = self.get_aunt(Ga, step, inlaw) + elif Ga == 1: + if gender_b == gen.lib.Person.MALE: + rel_str = self.get_nephew(Gb-1, step, inlaw) + else: + rel_str = self.get_niece(Gb-1, step, inlaw) + else: + if gender_b == gen.lib.Person.MALE: + rel_str = self.get_male_cousin(Gb-1, Ga-1, step, inlaw) + else: + rel_str = self.get_female_cousin(Gb-1, Ga-1, step, inlaw) + return rel_str + + def get_sibling_relationship_string(self, sib_type, gender_a, gender_b, + in_law_a=False, in_law_b=False): + """ Determine the string giving the relation between two siblings of + type sib_type. + Eg: b is the brother of a + Here 'brother' is the string we need to determine + For italian, we need to determine 'the brother' + This method gives more details about siblings than + get_single_relationship_string can do. + """ + if in_law_a or in_law_b : + inlaw = self.INLAW + else: + inlaw = '' + + if sib_type == self.NORM_SIB or sib_type == self.UNKNOWN_SIB: + if not inlaw: + if gender_b == gen.lib.Person.MALE: + rel_str = self.get_uncle(1, '', '') + else: + rel_str = self.get_aunt(1, '', '') + else: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il cognato' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la cognata' + else: + rel_str = 'il cognato/a' + elif sib_type == self.HALF_SIB or sib_type == self.STEP_SIB: + #Italian has no difference between half and step sibling! + if not inlaw: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il fratellastro' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la sorellastra' + else: + rel_str = 'il fratellastro/sorellastra' + else: + if gender_b == gen.lib.Person.MALE: + rel_str = 'il fratellastro acquisito' + elif gender_b == gen.lib.Person.FEMALE: + rel_str = 'la sorellastra acquisita' + else: + rel_str = 'il fratellastro/sorellastra acquisito/a' + + return rel_str #------------------------------------------------------------------------- # diff --git a/src/plugins/rel_nl.py b/src/plugins/rel_nl.py index 03eea3585..ab8524cb8 100644 --- a/src/plugins/rel_nl.py +++ b/src/plugins/rel_nl.py @@ -459,7 +459,6 @@ class RelationshipCalculator(Relationship.RelationshipCalculator): elif Ga == 0: #a is descendant if Gb == 1 and inlaw and not step: - #inlaw children only exist up to first level: if gender_b == gen.lib.Person.MALE: rel_str = 'schoonzoon' elif gender_b == gen.lib.Person.FEMALE: diff --git a/src/plugins/rel_pl.py b/src/plugins/rel_pl.py index 206ae2856..3a2d482c1 100644 --- a/src/plugins/rel_pl.py +++ b/src/plugins/rel_pl.py @@ -490,6 +490,33 @@ class RelationshipCalculator(Relationship.RelationshipCalculator): return (firstRel,secondRel,common,firstList,secondList) + def __apply_filter_old(self, db, person, rel_str, plist, pmap, depth=1): + """ DEPRECATED -- DO NOT USE + copied here from Relationship.py as no longer needed elsewhere + """ + if person == None or depth > MAX_DEPTH: + return + depth += 1 + plist.append(person.handle) + pmap[person.handle] = rel_str # ?? this overwrites if person is double! + + family_handle = person.get_main_parents_family_handle() + try: + if family_handle: + family = db.get_family_from_handle(family_handle) + fhandle = family.father_handle + if fhandle: + father = db.get_person_from_handle(fhandle) + self.__apply_filter_old(db, father, rel_str+'f', plist, pmap, + depth) + mhandle = family.mother_handle + if mhandle: + mother = db.get_person_from_handle(mhandle) + self.__apply_filter_old(db, mother, rel_str+'m', plist, pmap, + depth) + except: + return + def get_relationship(self,db,orig_person,other_person): """ Returns a string representing the relationshp between the two people, diff --git a/src/plugins/rel_pt.py b/src/plugins/rel_pt.py index 9ce6dc653..60297c352 100644 --- a/src/plugins/rel_pt.py +++ b/src/plugins/rel_pt.py @@ -30,7 +30,7 @@ # #------------------------------------------------------------------------- -import RelLib +import gen.lib import Relationship import types from gettext import gettext as _