2007-02-14 05:30:31 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
|
|
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
|
|
|
#
|
|
|
|
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
"""
|
|
|
|
Support classes to simplify GEDCOM importing
|
|
|
|
"""
|
2007-02-16 05:37:24 +05:30
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
import re
|
2007-10-08 22:11:39 +05:30
|
|
|
import gen.lib
|
2007-02-14 05:30:31 +05:30
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
NAME_RE = re.compile(r"/?([^/]*)(/([^/]*)(/([^/]*))?)?")
|
|
|
|
SURNAME_RE = re.compile(r"/([^/]*)/([^/]*)")
|
|
|
|
|
2007-02-16 11:26:51 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# CurrentState
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class CurrentState:
|
|
|
|
"""
|
2008-02-21 06:04:04 +05:30
|
|
|
Keep track of the current state variables.
|
2007-02-16 11:26:51 +05:30
|
|
|
"""
|
|
|
|
def __init__(self, person=None, level=0, event=None, event_ref=None):
|
|
|
|
"""
|
2008-02-21 06:04:04 +05:30
|
|
|
Initialize the object.
|
2007-02-16 11:26:51 +05:30
|
|
|
"""
|
|
|
|
self.name_cnt = 0
|
|
|
|
self.person = person
|
|
|
|
self.level = level
|
|
|
|
self.event = event
|
|
|
|
self.event_ref = event_ref
|
|
|
|
self.source_ref = None
|
|
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Return the value associated with the specified attribute.
|
2007-02-16 11:26:51 +05:30
|
|
|
"""
|
|
|
|
return self.__dict__.get(name)
|
|
|
|
|
|
|
|
def __setattr__(self, name, value):
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Set the value associated with the specified attribute.
|
2007-02-16 11:26:51 +05:30
|
|
|
"""
|
|
|
|
self.__dict__[name] = value
|
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# PlaceParser
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2007-02-14 05:30:31 +05:30
|
|
|
class PlaceParser:
|
2007-09-08 02:54:01 +05:30
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Provide the ability to parse GEDCOM FORM statements for places, and
|
2007-09-08 02:54:01 +05:30
|
|
|
the parse the line of text, mapping the text components to Location
|
|
|
|
values based of the FORM statement.
|
|
|
|
"""
|
2007-02-14 05:30:31 +05:30
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
__field_map = {
|
2007-10-08 22:11:39 +05:30
|
|
|
'addr' : gen.lib.Location.set_street,
|
|
|
|
'subdivision' : gen.lib.Location.set_street,
|
|
|
|
'addr1' : gen.lib.Location.set_street,
|
|
|
|
'adr1' : gen.lib.Location.set_street,
|
|
|
|
'city' : gen.lib.Location.set_city,
|
|
|
|
'town' : gen.lib.Location.set_city,
|
|
|
|
'village' : gen.lib.Location.set_city,
|
|
|
|
'county' : gen.lib.Location.set_county,
|
|
|
|
'country' : gen.lib.Location.set_country,
|
|
|
|
'state' : gen.lib.Location.set_state,
|
|
|
|
'state/province': gen.lib.Location.set_state,
|
|
|
|
'region' : gen.lib.Location.set_state,
|
|
|
|
'province' : gen.lib.Location.set_state,
|
|
|
|
'area code' : gen.lib.Location.set_postal_code,
|
2007-02-14 05:30:31 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
def __init__(self, line=None):
|
2007-09-08 02:54:01 +05:30
|
|
|
self.parse_function = []
|
2008-01-06 01:40:26 +05:30
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
if line:
|
|
|
|
self.parse_form(line)
|
2007-02-14 05:30:31 +05:30
|
|
|
|
|
|
|
def parse_form(self, line):
|
2007-09-08 02:54:01 +05:30
|
|
|
"""
|
|
|
|
Parses the GEDCOM PLAC.FORM into a list of function
|
|
|
|
pointers (if possible). It does this my mapping the text strings
|
2007-10-08 22:11:39 +05:30
|
|
|
(separated by commas) to the corresponding gen.lib.Location
|
2007-09-08 02:54:01 +05:30
|
|
|
method via the __field_map variable
|
|
|
|
"""
|
2007-02-14 05:30:31 +05:30
|
|
|
for item in line.data.split(','):
|
|
|
|
item = item.lower().strip()
|
2007-09-08 02:54:01 +05:30
|
|
|
fcn = self.__field_map.get(item, lambda x, y: None)
|
|
|
|
self.parse_function.append(fcn)
|
2007-02-14 05:30:31 +05:30
|
|
|
|
|
|
|
def load_place(self, place, text):
|
2007-09-08 02:54:01 +05:30
|
|
|
"""
|
|
|
|
Takes the text string representing a place, splits it into
|
|
|
|
its subcomponents (comma separated), and calls the approriate
|
|
|
|
function based of its position, depending on the parsed value
|
|
|
|
from the FORM statement.
|
|
|
|
"""
|
|
|
|
items = [item.strip() for item in text.split(',')]
|
|
|
|
if len(items) != len(self.parse_function):
|
|
|
|
return
|
|
|
|
loc = place.get_main_location()
|
|
|
|
index = 0
|
|
|
|
for item in items:
|
|
|
|
self.parse_function[index](loc, item)
|
|
|
|
index += 1
|
2007-02-14 05:30:31 +05:30
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IdFinder
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2007-02-14 05:30:31 +05:30
|
|
|
class IdFinder:
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Provide method of finding the next available ID.
|
2007-02-14 05:30:31 +05:30
|
|
|
"""
|
|
|
|
def __init__(self, keys, prefix):
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Initialize the object.
|
2007-02-14 05:30:31 +05:30
|
|
|
"""
|
|
|
|
self.ids = set(keys)
|
|
|
|
self.index = 0
|
|
|
|
self.prefix = prefix
|
|
|
|
|
|
|
|
def find_next(self):
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Return the next available GRAMPS' ID for a Event object based
|
2007-02-14 05:30:31 +05:30
|
|
|
off the person ID prefix.
|
|
|
|
|
|
|
|
@return: Returns the next available index
|
|
|
|
@rtype: str
|
|
|
|
"""
|
|
|
|
index = self.prefix % self.index
|
|
|
|
while str(index) in self.ids:
|
|
|
|
self.index += 1
|
|
|
|
index = self.prefix % self.index
|
|
|
|
self.ids.add(index)
|
|
|
|
self.index += 1
|
|
|
|
return index
|
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IdMapper
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2007-02-19 10:52:29 +05:30
|
|
|
class IdMapper:
|
|
|
|
|
|
|
|
def __init__(self, trans, find_next, translate):
|
|
|
|
if translate:
|
|
|
|
self.__getitem__ = self.get_translate
|
|
|
|
else:
|
|
|
|
self.__getitem__ = self.no_translate
|
|
|
|
self.trans = trans
|
|
|
|
self.find_next = find_next
|
|
|
|
self.swap = {}
|
|
|
|
|
|
|
|
def clean(self, gid):
|
|
|
|
temp = gid.strip()
|
2007-02-25 20:37:24 +05:30
|
|
|
if len(temp) > 1 and temp[0] == '@' and temp[-1] == '@':
|
2007-02-19 10:52:29 +05:30
|
|
|
temp = temp[1:-1]
|
|
|
|
return temp
|
|
|
|
|
|
|
|
def no_translate(self, gid):
|
|
|
|
return self.clean(gid)
|
|
|
|
|
2007-02-24 04:26:41 +05:30
|
|
|
def get_translate(self, gid):
|
2007-02-19 10:52:29 +05:30
|
|
|
gid = self.clean(gid)
|
2008-07-17 23:40:32 +05:30
|
|
|
if gid in self.swap:
|
2008-02-21 06:04:04 +05:30
|
|
|
return self.swap[gid]
|
2007-02-19 10:52:29 +05:30
|
|
|
else:
|
|
|
|
if self.trans.get(str(gid)):
|
|
|
|
new_val = self.find_next()
|
|
|
|
else:
|
|
|
|
new_val = gid
|
|
|
|
self.swap[gid] = new_val
|
|
|
|
return new_val
|
|
|
|
|
2007-02-16 05:37:24 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Support functions
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2007-02-16 11:26:51 +05:30
|
|
|
def parse_name_personal(text):
|
2007-09-08 02:54:01 +05:30
|
|
|
"""
|
|
|
|
Parses a GEDCOM NAME value into an Name structure
|
|
|
|
"""
|
2007-10-08 22:11:39 +05:30
|
|
|
name = gen.lib.Name()
|
2007-02-14 05:30:31 +05:30
|
|
|
|
2007-09-08 02:54:01 +05:30
|
|
|
match = SURNAME_RE.match(text)
|
|
|
|
if match:
|
|
|
|
names = match.groups()
|
2007-02-16 05:37:24 +05:30
|
|
|
name.set_first_name(names[1].strip())
|
|
|
|
name.set_surname(names[0].strip())
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
names = NAME_RE.match(text).groups()
|
|
|
|
name.set_first_name(names[0].strip())
|
|
|
|
name.set_surname(names[2].strip())
|
|
|
|
name.set_suffix(names[4].strip())
|
|
|
|
except:
|
|
|
|
name.set_first_name(text.strip())
|
|
|
|
return name
|
|
|
|
|
2007-02-16 11:26:51 +05:30
|
|
|
def extract_id(value):
|
2007-02-16 05:37:24 +05:30
|
|
|
"""
|
|
|
|
Extracts a value to use for the GRAMPS ID value from the GEDCOM
|
2007-09-08 02:54:01 +05:30
|
|
|
reference token. The value should be in the form of @XYZ@, and the
|
|
|
|
returned value will be XYZ
|
2007-02-16 05:37:24 +05:30
|
|
|
"""
|
|
|
|
return value.strip()[1:-1]
|