8537: Gedcom import crashes; kulath patch
This commit is contained in:
parent
de7430eeb8
commit
26723c1b60
@ -1917,6 +1917,7 @@ class GedcomParser(UpdateCallback):
|
|||||||
self.default_tag = None
|
self.default_tag = None
|
||||||
self.dir_path = os.path.dirname(filename)
|
self.dir_path = os.path.dirname(filename)
|
||||||
self.is_ftw = False
|
self.is_ftw = False
|
||||||
|
self.addr_is_detail = False
|
||||||
self.groups = None
|
self.groups = None
|
||||||
self.want_parse_warnings = True
|
self.want_parse_warnings = True
|
||||||
|
|
||||||
@ -2931,23 +2932,32 @@ class GedcomParser(UpdateCallback):
|
|||||||
return place
|
return place
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __create_place(self, title, location):
|
def __add_place(self, event, sub_state):
|
||||||
"""
|
"""
|
||||||
Create a new place based on the title and primary location.
|
Add a new place to an event if not already present, or update a
|
||||||
|
place.
|
||||||
|
|
||||||
@param title: The place title
|
@param event: The event
|
||||||
@type title: string
|
@type event: gen.lib.Event
|
||||||
@param location: The current location
|
@param substate: The sub-state for PLAC or ADDR elements (i.e. parsed by
|
||||||
@type location: gen.lib.Location
|
event_parse_tbl)
|
||||||
@return gen.lib.Place
|
@type sub_state: CurrentState
|
||||||
"""
|
"""
|
||||||
place = Place()
|
if sub_state.place:
|
||||||
place.set_title(title)
|
# see whether this place already exists
|
||||||
if location:
|
place = self.__find_place(sub_state.place.get_title(),
|
||||||
place.add_alternate_locations(location)
|
self.__get_first_loc(sub_state.place))
|
||||||
|
if place is None:
|
||||||
|
place = sub_state.place
|
||||||
self.dbase.add_place(place, self.trans)
|
self.dbase.add_place(place, self.trans)
|
||||||
self.place_names[title].append(place.get_handle())
|
self.place_names[place.get_title()].append(place.get_handle())
|
||||||
return place
|
event.set_place_handle(place.get_handle())
|
||||||
|
else:
|
||||||
|
place.merge(sub_state.place)
|
||||||
|
self.dbase.commit_place(place, self.trans)
|
||||||
|
event.set_place_handle(place.get_handle())
|
||||||
|
place_title = place_displayer.display(self.dbase, place)
|
||||||
|
sub_state.pf.load_place(self.place_import, place, place_title)
|
||||||
|
|
||||||
def __find_file(self, fullname, altpath):
|
def __find_file(self, fullname, altpath):
|
||||||
tries = []
|
tries = []
|
||||||
@ -3862,10 +3872,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
sub_state.level = state.level+1
|
sub_state.level = state.level+1
|
||||||
sub_state.event = event
|
sub_state.event = event
|
||||||
sub_state.event_ref = event_ref
|
sub_state.event_ref = event_ref
|
||||||
|
sub_state.pf = self.place_parser
|
||||||
|
|
||||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
|
self.__add_place(event, sub_state)
|
||||||
|
|
||||||
self.dbase.commit_event(event, self.trans)
|
self.dbase.commit_event(event, self.trans)
|
||||||
event_ref.ref = event.handle
|
event_ref.ref = event.handle
|
||||||
state.person.add_event_ref(event_ref)
|
state.person.add_event_ref(event_ref)
|
||||||
@ -4067,10 +4080,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
sub_state.level = state.level+1
|
sub_state.level = state.level+1
|
||||||
sub_state.event = event
|
sub_state.event = event
|
||||||
sub_state.event_ref = event_ref
|
sub_state.event_ref = event_ref
|
||||||
|
sub_state.pf = self.place_parser
|
||||||
|
|
||||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
|
self.__add_place(event, sub_state)
|
||||||
|
|
||||||
self.dbase.add_event(event, self.trans)
|
self.dbase.add_event(event, self.trans)
|
||||||
event_ref.ref = event.handle
|
event_ref.ref = event.handle
|
||||||
state.person.add_event_ref(event_ref)
|
state.person.add_event_ref(event_ref)
|
||||||
@ -4519,11 +4535,14 @@ class GedcomParser(UpdateCallback):
|
|||||||
try:
|
try:
|
||||||
title = line.data
|
title = line.data
|
||||||
place = self.__find_place(title, None)
|
place = self.__find_place(title, None)
|
||||||
if place:
|
if place is None:
|
||||||
state.place = place
|
place = Place()
|
||||||
|
place.set_title(title)
|
||||||
|
self.dbase.add_place(place, self.trans)
|
||||||
|
self.place_names[place.get_title()].append(place.get_handle())
|
||||||
else:
|
else:
|
||||||
state.place = self.__create_place(title, None)
|
pass
|
||||||
state.lds_ord.set_place_handle(state.place.handle)
|
state.lds_ord.set_place_handle(place.handle)
|
||||||
except NameError:
|
except NameError:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -4887,10 +4906,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
sub_state.level = state.level+1
|
sub_state.level = state.level+1
|
||||||
sub_state.event = event
|
sub_state.event = event
|
||||||
sub_state.event_ref = event_ref
|
sub_state.event_ref = event_ref
|
||||||
|
sub_state.pf = self.place_parser
|
||||||
|
|
||||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
|
self.__add_place(event, sub_state)
|
||||||
|
|
||||||
if event.type == EventType.MARRIAGE:
|
if event.type == EventType.MARRIAGE:
|
||||||
descr = event.get_description()
|
descr = event.get_description()
|
||||||
if descr == "Civil Union":
|
if descr == "Civil Union":
|
||||||
@ -4930,10 +4952,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
sub_state.level = state.level+1
|
sub_state.level = state.level+1
|
||||||
sub_state.event = event
|
sub_state.event = event
|
||||||
sub_state.event_ref = event_ref
|
sub_state.event_ref = event_ref
|
||||||
|
sub_state.pf = self.place_parser
|
||||||
|
|
||||||
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
|
self.__add_place(event, sub_state)
|
||||||
|
|
||||||
self.dbase.commit_event(event, self.trans)
|
self.dbase.commit_event(event, self.trans)
|
||||||
event_ref.ref = event.handle
|
event_ref.ref = event.handle
|
||||||
state.family.add_event_ref(event_ref)
|
state.family.add_event_ref(event_ref)
|
||||||
@ -5361,65 +5386,30 @@ class GedcomParser(UpdateCallback):
|
|||||||
state.event.set_description(line.data)
|
state.event.set_description(line.data)
|
||||||
else:
|
else:
|
||||||
title = line.data
|
title = line.data
|
||||||
place_handle = state.event.get_place_handle()
|
place = state.place
|
||||||
if place_handle:
|
if place:
|
||||||
# We encounter a PLAC, having previously encountered an ADDR
|
# We encounter a PLAC, having previously encountered an ADDR
|
||||||
old_place = self.dbase.get_place_from_handle(place_handle)
|
if place.get_title() and place.get_title() != "":
|
||||||
old_title = old_place.get_title()
|
|
||||||
location = self.__get_first_loc(old_place)
|
|
||||||
if old_title != "":
|
|
||||||
# We have previously found a PLAC
|
# We have previously found a PLAC
|
||||||
self.__add_msg(_("A second PLAC ignored"), line, state)
|
self.__add_msg(_("A second PLAC ignored"), line, state)
|
||||||
# ignore this second PLAC, and use the old one
|
# ignore this second PLAC, and use the old one
|
||||||
title = old_title
|
|
||||||
place = old_place
|
|
||||||
else:
|
else:
|
||||||
# This is the first PLAC
|
# This is the first PLAC
|
||||||
refs = list(self.dbase.find_backlink_handles(place_handle))
|
place.set_title(line.data)
|
||||||
# We haven't commited the event yet, so the place will not
|
|
||||||
# be linked to it. If there are any refs they will be from
|
|
||||||
# other events (etc)
|
|
||||||
if len(refs) == 0:
|
|
||||||
place = self.__find_place(title, location)
|
|
||||||
if place is None:
|
|
||||||
place = old_place
|
|
||||||
place.set_title(title)
|
|
||||||
self.place_names[old_title].remove(place_handle)
|
|
||||||
self.place_names[title].append(place_handle)
|
|
||||||
else:
|
|
||||||
place.merge(old_place)
|
|
||||||
self.place_import.remove_location(old_place.handle)
|
|
||||||
self.dbase.remove_place(place_handle, self.trans)
|
|
||||||
self.place_names[old_title].remove(place_handle)
|
|
||||||
else:
|
|
||||||
place = self.__find_place(title, location)
|
|
||||||
if place is None:
|
|
||||||
place = self.__create_place(title, location)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
# The first thing we encounter is PLAC
|
# The first thing we encounter is PLAC
|
||||||
location = None
|
state.place = Place()
|
||||||
place = self.__find_place(title, location)
|
place = state.place
|
||||||
if place is None:
|
place.set_title(line.data)
|
||||||
place = self.__create_place(title, location)
|
|
||||||
|
|
||||||
state.event.set_place_handle(place.handle)
|
|
||||||
|
|
||||||
sub_state = CurrentState()
|
sub_state = CurrentState()
|
||||||
sub_state.place = place
|
sub_state.place = place
|
||||||
sub_state.level = state.level+1
|
sub_state.level = state.level+1
|
||||||
sub_state.pf = self.place_parser
|
|
||||||
|
|
||||||
self.__parse_level(sub_state, self.event_place_map,
|
self.__parse_level(sub_state, self.event_place_map,
|
||||||
self.__undefined)
|
self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
place_title = place_displayer.display(self.dbase, place)
|
|
||||||
sub_state.pf.load_place(self.place_import, place, place_title)
|
|
||||||
|
|
||||||
self.dbase.commit_place(place, self.trans)
|
|
||||||
|
|
||||||
def __event_place_note(self, line, state):
|
def __event_place_note(self, line, state):
|
||||||
"""
|
"""
|
||||||
@param line: The current line in GedLine format
|
@param line: The current line in GedLine format
|
||||||
@ -5528,55 +5518,53 @@ class GedcomParser(UpdateCallback):
|
|||||||
self.__merge_address(free_form, sub_state.location, line, state)
|
self.__merge_address(free_form, sub_state.location, line, state)
|
||||||
|
|
||||||
location = sub_state.location
|
location = sub_state.location
|
||||||
place_handle = state.event.get_place_handle()
|
|
||||||
if place_handle:
|
if self.addr_is_detail and state.place:
|
||||||
|
# Commit the enclosing place
|
||||||
|
place = self.__find_place(state.place.get_title(), None)
|
||||||
|
if place is None:
|
||||||
|
place = state.place
|
||||||
|
self.dbase.add_place(place, self.trans)
|
||||||
|
self.place_names[place.get_title()].append(place.get_handle())
|
||||||
|
else:
|
||||||
|
place.merge(state.place)
|
||||||
|
self.dbase.commit_place(place, self.trans)
|
||||||
|
place_title = place_displayer.display(self.dbase, place)
|
||||||
|
state.pf.load_place(self.place_import, place, place_title)
|
||||||
|
|
||||||
|
# Create the Place Details (it is committed with the event)
|
||||||
|
place_detail = Place()
|
||||||
|
place_detail.set_name(location.get_street())
|
||||||
|
place_detail.set_title(location.get_street())
|
||||||
|
# For RootsMagic etc. Place Details e.g. address, hospital, cemetary
|
||||||
|
place_detail.set_type((PlaceType.CUSTOM, _("Detail")))
|
||||||
|
placeref = PlaceRef()
|
||||||
|
placeref.ref = place.get_handle()
|
||||||
|
place_detail.set_placeref_list([placeref])
|
||||||
|
state.place = place_detail
|
||||||
|
else:
|
||||||
|
place = state.place
|
||||||
|
if place:
|
||||||
# We encounter an ADDR having previously encountered a PLAC
|
# We encounter an ADDR having previously encountered a PLAC
|
||||||
old_place = self.dbase.get_place_from_handle(place_handle)
|
if len(place.get_alternate_locations()) != 0 and \
|
||||||
title = old_place.get_title()
|
not self.__get_first_loc(place).is_empty():
|
||||||
if len(old_place.get_alternate_locations()) != 0 and \
|
|
||||||
not self.__get_first_loc(old_place).is_empty():
|
|
||||||
# We have perviously found an ADDR, or have populated location
|
# We have perviously found an ADDR, or have populated location
|
||||||
# from PLAC title
|
# from PLAC title
|
||||||
self.__add_msg(_("Location already populated; ADDR ignored"),
|
self.__add_msg(_("Location already populated; ADDR ignored"),
|
||||||
line, state)
|
line, state)
|
||||||
# ignore this second ADDR, and use the old one
|
# ignore this second ADDR, and use the old one
|
||||||
location = self.__get_first_loc(old_place)
|
|
||||||
place = old_place
|
|
||||||
else:
|
else:
|
||||||
# This is the first ADDR
|
# This is the first ADDR
|
||||||
refs = list(self.dbase.find_backlink_handles(place_handle))
|
place.add_alternate_locations(location)
|
||||||
# We haven't commited the event yet, so the place will not be
|
|
||||||
# linked to it. If there are any refs they will be from other
|
|
||||||
# events (etc)
|
|
||||||
if len(refs) == 0:
|
|
||||||
place = self.__find_place(title, location)
|
|
||||||
if place is None:
|
|
||||||
place = old_place
|
|
||||||
self.__add_location(place, location)
|
|
||||||
else:
|
|
||||||
place.merge(old_place)
|
|
||||||
self.place_import.remove_location(old_place.handle)
|
|
||||||
self.dbase.remove_place(place_handle, self.trans)
|
|
||||||
self.place_names[title].remove(place_handle)
|
|
||||||
else:
|
|
||||||
place = self.__find_place(title, location)
|
|
||||||
if place is None:
|
|
||||||
place = self.__create_place(title, location)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
# The first thing we encounter is ADDR
|
# The first thing we encounter is ADDR
|
||||||
title = ""
|
state.place = Place()
|
||||||
place = self.__find_place(title, location)
|
place = state.place
|
||||||
if place is None:
|
place.add_alternate_locations(location)
|
||||||
place = self.__create_place(title, location)
|
|
||||||
|
|
||||||
# merge notes etc into place
|
# merge notes etc into place
|
||||||
place.merge(sub_state.place)
|
place.merge(sub_state.place)
|
||||||
|
|
||||||
state.event.set_place_handle(place.get_handle())
|
|
||||||
self.dbase.commit_place(place, self.trans)
|
|
||||||
|
|
||||||
def __add_location(self, place, location):
|
def __add_location(self, place, location):
|
||||||
"""
|
"""
|
||||||
@param place: A place object we have found or created
|
@param place: A place object we have found or created
|
||||||
@ -5608,12 +5596,10 @@ class GedcomParser(UpdateCallback):
|
|||||||
@param state: The current state
|
@param state: The current state
|
||||||
@type state: CurrentState
|
@type state: CurrentState
|
||||||
"""
|
"""
|
||||||
place_handle = state.event.get_place_handle()
|
place = state.place
|
||||||
if place_handle:
|
if place:
|
||||||
place = self.dbase.get_place_from_handle(place_handle)
|
|
||||||
codes = [place.get_code(), line.data]
|
codes = [place.get_code(), line.data]
|
||||||
place.set_code(' '.join(code for code in codes if code))
|
place.set_code(' '.join(code for code in codes if code))
|
||||||
self.dbase.commit_place(place, self.trans)
|
|
||||||
|
|
||||||
def __event_privacy(self, line, state):
|
def __event_privacy(self, line, state):
|
||||||
"""
|
"""
|
||||||
@ -6925,6 +6911,11 @@ class GedcomParser(UpdateCallback):
|
|||||||
self.gedsource = self.gedmap.get_from_source_tag(line.data)
|
self.gedsource = self.gedmap.get_from_source_tag(line.data)
|
||||||
if line.data.strip() in ["FTW", "FTM"]:
|
if line.data.strip() in ["FTW", "FTM"]:
|
||||||
self.is_ftw = True
|
self.is_ftw = True
|
||||||
|
# Some software (e.g. RootsMagic (http://files.rootsmagic.com/PAF-
|
||||||
|
# Book/RootsMagic-for-PAF-Users-Printable.pdf) use the Addr fields for
|
||||||
|
# 'Place Details (address, hospital, cemetary)'
|
||||||
|
if line.data.strip().lower() in ['rootsmagic']:
|
||||||
|
self.addr_is_detail = True
|
||||||
# We will use the approved system ID as the name of the generating
|
# We will use the approved system ID as the name of the generating
|
||||||
# software, in case we do not get the name in the proper place
|
# software, in case we do not get the name in the proper place
|
||||||
self.genby = line.data
|
self.genby = line.data
|
||||||
@ -7576,9 +7567,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
sub_state.event_ref = event_ref
|
sub_state.event_ref = event_ref
|
||||||
sub_state.event = event
|
sub_state.event = event
|
||||||
sub_state.person = state.person
|
sub_state.person = state.person
|
||||||
|
sub_state.pf = self.place_parser
|
||||||
|
|
||||||
self.__parse_level(sub_state, event_map, self.__undefined)
|
self.__parse_level(sub_state, event_map, self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
|
self.__add_place(event, sub_state)
|
||||||
|
|
||||||
self.dbase.commit_event(event, self.trans)
|
self.dbase.commit_event(event, self.trans)
|
||||||
|
|
||||||
event_ref.set_reference_handle(event.handle)
|
event_ref.set_reference_handle(event.handle)
|
||||||
@ -7600,10 +7595,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
sub_state.level = state.level+1
|
sub_state.level = state.level+1
|
||||||
sub_state.event = event
|
sub_state.event = event
|
||||||
sub_state.event_ref = event_ref
|
sub_state.event_ref = event_ref
|
||||||
|
sub_state.pf = self.place_parser
|
||||||
|
|
||||||
self.__parse_level(sub_state, event_map, self.__undefined)
|
self.__parse_level(sub_state, event_map, self.__undefined)
|
||||||
state.msg += sub_state.msg
|
state.msg += sub_state.msg
|
||||||
|
|
||||||
|
self.__add_place(event, sub_state)
|
||||||
|
|
||||||
self.dbase.commit_event(event, self.trans)
|
self.dbase.commit_event(event, self.trans)
|
||||||
event_ref.set_reference_handle(event.handle)
|
event_ref.set_reference_handle(event.handle)
|
||||||
return event_ref
|
return event_ref
|
||||||
|
Loading…
Reference in New Issue
Block a user