0006061: GEDCOM import: link from FAM to child but missing link from child to FAM causes inconsistent displays. Fixed in GEDCOM import, importxml and Check and repair. (Also minor fixes for improved diagnostics when importxml just completely fails and for exportxml illegal characters in mime_type).

svn: r20438
This commit is contained in:
Tim G L Lyons 2012-09-23 22:28:34 +00:00
parent 7e32fa416f
commit 82bfe43483
4 changed files with 106 additions and 5 deletions

View File

@ -1208,7 +1208,8 @@ class GrampsXmlWriter(UpdateCallback):
# from Windows to Linux of gpkg's path to images does not work. # from Windows to Linux of gpkg's path to images does not work.
path = path.replace('\\','/') path = path.replace('\\','/')
self.g.write('%s<file src="%s" mime="%s"%s/>\n' self.g.write('%s<file src="%s" mime="%s"%s/>\n'
% (" "*(index+1), self.fix(path), mime_type, desc_text)) % (" "*(index+1), self.fix(path), self.fix(mime_type),
desc_text))
self.write_attribute_list(obj.get_attribute_list()) self.write_attribute_list(obj.get_attribute_list())
self.write_note_list(obj.get_note_list(), index+1) self.write_note_list(obj.get_note_list(), index+1)
dval = obj.get_date_object() dval = obj.get_date_object()

View File

@ -137,6 +137,7 @@ def importData(database, filename, callback=None):
return return
except ExpatError, msg: except ExpatError, msg:
ErrorDialog(_("Error reading %s") % filename, ErrorDialog(_("Error reading %s") % filename,
str(msg) + "\n" +
_("The file is probably either corrupt or not a " _("The file is probably either corrupt or not a "
"valid Gramps database.")) "valid Gramps database."))
return return
@ -220,6 +221,7 @@ class ImportInfo(object):
self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}] self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
self.data_newobject = [0] * 10 self.data_newobject = [0] * 10
self.data_unknownobject = [0] * 10 self.data_unknownobject = [0] * 10
self.data_families = ''
self.expl_note = '' self.expl_note = ''
self.data_relpath = False self.data_relpath = False
@ -237,6 +239,11 @@ class ImportInfo(object):
self.data_unknownobject[self.key2data[key]] += 1 self.data_unknownobject[self.key2data[key]] += 1
elif category == 'relative-path': elif category == 'relative-path':
self.data_relpath = True self.data_relpath = True
elif category == 'unlinked-family':
# This is a bit ugly because it isn't using key in the same way as
# the rest of the categories, but it is only the calling routine
# that really knows what the error message should be.
self.data_families += key + "\n"
def _extract_mergeinfo(self, key, obj, sec_obj): def _extract_mergeinfo(self, key, obj, sec_obj):
""" """
@ -325,6 +332,11 @@ class ImportInfo(object):
datakey = self.key2data[key] datakey = self.key2data[key]
for handle in self.data_mergecandidate[datakey].keys(): for handle in self.data_mergecandidate[datakey].keys():
txt += self.data_mergecandidate[datakey][handle] txt += self.data_mergecandidate[datakey][handle]
if self.data_families:
txt += "\n\n"
txt += self.data_families
return txt return txt
class LineParser(object): class LineParser(object):
@ -903,6 +915,7 @@ class GrampsParser(UpdateCallback):
) % self.mediapath ) ) % self.mediapath )
self.fix_not_instantiated() self.fix_not_instantiated()
self.fix_families()
for key in self.func_map.keys(): for key in self.func_map.keys():
del self.func_map[key] del self.func_map[key]
del self.func_map del self.func_map
@ -2962,6 +2975,72 @@ class GrampsParser(UpdateCallback):
key = CLASS_TO_KEY_MAP[obj.__class__.__name__] key = CLASS_TO_KEY_MAP[obj.__class__.__name__]
self.info.add('unknown-object', key, obj) self.info.add('unknown-object', key, obj)
def fix_families(self):
# Fix any imported families where there is a link from the family to an
# individual, but no corresponding link from the individual to the
# family.
for orig_handle in self.import_handles.keys():
for target in self.import_handles[orig_handle].keys():
if target == 'family':
family_handle = self.import_handles[orig_handle][target][HANDLE]
family = self.db.get_family_from_handle(family_handle)
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
if father_handle:
father = self.db.get_person_from_handle(father_handle)
if father and \
family_handle not in father.get_family_handle_list():
father.add_family_handle(family_handle)
self.db.commit_person(father, self.trans)
txt = _("Error: family '%(family)s'"
" father '%(father)s'"
" does not refer"
" back to the family."
" Reference added." %
{'family' : family.gramps_id,
'father' : father.gramps_id})
self.info.add('unlinked-family', txt, None)
LOG.warn(txt)
if mother_handle:
mother = self.db.get_person_from_handle(mother_handle)
if mother and \
family_handle not in mother.get_family_handle_list():
mother.add_family_handle(family_handle)
self.db.commit_person(mother, self.trans)
txt = _("Error: family '%(family)s'"
" mother '%(mother)s'"
" does not refer"
" back to the family."
" Reference added." %
{'family' : family.gramps_id,
'mother' : mother.gramps_id})
self.info.add('unlinked-family', txt, None)
LOG.warn(txt)
for child_ref in family.get_child_ref_list():
child_handle = child_ref.ref
child = self.db.get_person_from_handle(child_handle)
if child:
if family_handle not in \
child.get_parent_family_handle_list():
# The referenced child has no reference to the
# family. There was a link from the FAM record
# to the child, but no FAMC link from the child
# to the FAM.
child.add_parent_family_handle(family_handle)
self.db.commit_person(child, self.trans)
txt = _("Error: family '%(family)s'"
" child '%(child)s'"
" does not "
"refer back to the family. "
"Reference added." %
{'family' : family.gramps_id,
'child' : child.gramps_id})
self.info.add('unlinked-family', txt, None)
LOG.warn(txt)
def append_value(orig, val): def append_value(orig, val):
if orig: if orig:
return "%s, %s" % (orig, val) return "%s, %s" % (orig, val)

View File

@ -3028,6 +3028,28 @@ class GedcomParser(UpdateCallback):
'orig_mother' : 'orig_mother' :
__input_pid(mother.gramps_id)}) __input_pid(mother.gramps_id)})
for child_ref in family.get_child_ref_list():
child_handle = child_ref.ref
child = self.dbase.get_person_from_handle(child_handle)
if child:
if family_handle not in \
child.get_parent_family_handle_list():
# The referenced child has no reference to the family.
# There was a link from the FAM record to the child, but
# no FAMC link from the child to the FAM.
child.add_parent_family_handle(family_handle)
self.dbase.commit_person(child, self.trans)
self.__add_msg("Error: family '%(family)s' (input as"
" @%(orig_family)s@) child '%(child)s'"
" (input as '%(orig_child)s') does not "
"refer back to the family. "
"Reference added." %
{'family' : family.gramps_id,
'orig_family' : input_id,
'child' : child.gramps_id,
'orig_child' :
__input_pid(child.gramps_id)})
if self.missing_references: if self.missing_references:
self.dbase.commit_note(self.explanation, self.trans, time.time()) self.dbase.commit_note(self.explanation, self.trans, time.time())
txt = _("\nThe imported file was not self-contained.\n" txt = _("\nThe imported file was not self-contained.\n"

View File

@ -481,12 +481,11 @@ class CheckIntegrity(object):
# is "Broken8" # is "Broken8"
logging.warning(" FAIL: family '%(fam_gid)s' " logging.warning(" FAIL: family '%(fam_gid)s' "
"child '%(child_gid)s' has no reference" "child '%(child_gid)s' has no reference"
" to the family" % " to the family. Reference added" %
{'fam_gid' : family.gramps_id, {'fam_gid' : family.gramps_id,
'child_gid' : child.gramps_id}) 'child_gid' : child.gramps_id})
family.remove_child_ref(child_ref) child.add_parent_family_handle(family_handle)
self.db.commit_family(family, self.trans) self.db.commit_person(child, self.trans)
self.broken_links.append((child_handle, family_handle))
else: else:
# The person referenced by the child handle # The person referenced by the child handle
# does not exist in the database # does not exist in the database