Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Python 3.6 and different encodings #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions date.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import datetime

def splitDate(date):
"""Split the date and return the year
Add your conversion rules as needed"""
# See here for a suitable format string: https://docs.python.org/3/library/datetime.html?highlight=datetime#strftime-strptime-behavior
retdate = datetime.datetime(1,1,1)
try:
retdate = datetime.datetime.strptime(date, "%d.%m.%Y")
except ValueError:
try:
retdate = datetime.datetime.strptime(date, "%Y")
except ValueError:
pass
return retdate.year
74 changes: 40 additions & 34 deletions gedcom.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
__all__ = ["Gedcom", "Element", "GedcomParseError"]

# Global imports
import string
from date import splitDate

class Gedcom:
"""Gedcom parser
Expand All @@ -37,15 +37,15 @@ class Gedcom:

"""

def __init__(self,file):
def __init__(self,lines):
"""Initialize a Gedcom parser. You must supply a Gedcom file."""
self.__element_list = []
self.__element_dict = {}
self.__element_top = Element(-1,"","TOP","",self.__element_dict)
self.__current_level = -1
self.__current_element = self.__element_top
self.__individuals = 0
self.__parse(file)
self.__parse(lines)

def element_list(self):
"""Return a list of all the elements in the Gedcom file. The
Expand All @@ -64,12 +64,10 @@ def element_dict(self):

# Private methods

def __parse(self,file):
# open file
def __parse(self,lines):
# go through the lines
f = open(file)
number = 1
for line in f.readlines():
for line in lines:
# Skip over some junk that Rootsmagic puts in gedcom files.
if number == 1 and ord(line[0]) == 239:
line = line[3:]
Expand All @@ -80,7 +78,7 @@ def __parse(self,file):
def __parse_line(self,number,line):
# each line should have: Level SP (Pointer SP)? Tag (SP Value)? (SP)? NL
# parse the line
parts = string.split(line)
parts = str.split(line)
place = 0
l = self.__level(number,parts,place)
place += 1
Expand Down Expand Up @@ -162,24 +160,25 @@ def __value(self,number,parts,place):
while place < len(parts):
vlist.append(parts[place])
place += 1
v = string.join(vlist)
v = ' '.join(vlist)
return v

def __error(self,number,text):
error = "Gedcom format error on line " + str(number) + ': ' + text
raise GedcomParseError, error
raise GedcomParseError(error)

def __count(self):
# Count number of individuals
self.__individuals = 0
for e in self.__element_list:
if e.individual():
q = Query(e)
if q.individual():
self.__individuals += 1


def __print(self):
for e in self.element_list:
print string.join([str(e.level()),e.pointer(),e.tag(),e.value()])
print (str.join([str(e.level()),e.pointer(),e.tag(),e.value()]))


class GedcomParseError(Exception):
Expand All @@ -189,7 +188,7 @@ def __init__(self, value):
self.value = value

def __str__(self):
return `self.value`
return self.value

class Element:
"""Gedcom element
Expand Down Expand Up @@ -250,6 +249,10 @@ def value(self):
"""Return the value of this element."""
return self.__value

def dict(self):
"""Return the dictionary of this element."""
return self.__dict

def children(self):
"""Return the child elements of this element."""
return self.__children
Expand All @@ -266,9 +269,15 @@ def add_parent(self,element):
"""Add a parent element to this element."""
self.__parent = element

class Query(object):
"""Query GEDCOM Element tree"""

def __init__(self,element):
self.element = element

def individual(self):
"""Check if this element is an individual."""
return self.tag() == "INDI"
return self.element.tag() == "INDI"

# criteria matching

Expand Down Expand Up @@ -417,9 +426,9 @@ def marriage_range_match(self,year1,year2):
def families(self):
"""Return a list of all of the family elements of a person."""
results = []
for e in self.children():
for e in self.element.children():
if e.tag() == "FAMS":
f = self.__dict.get(e.value(),None)
f = e.dict().get(e.value(),None)
if f != None:
results.append(f)
return results
Expand All @@ -430,14 +439,14 @@ def name(self):
last = ""
if not self.individual():
return (first,last)
for e in self.children():
for e in self.element.children():
if e.tag() == "NAME":
# some older Gedcom files don't use child tags but instead
# place the name in the value of the NAME tag
if e.value() != "":
name = string.split(e.value(),'/')
first = string.strip(name[0])
last = string.strip(name[1])
name = str.split(e.value(),'/')
first = str.strip(name[0])
last = str.strip(name[1])
else:
for c in e.children():
if c.tag() == "GIVN":
Expand Down Expand Up @@ -466,12 +475,11 @@ def birth_year(self):
date = ""
if not self.individual():
return date
for e in self.children():
for e in self.element.children():
if e.tag() == "BIRT":
for c in e.children():
if c.tag() == "DATE":
datel = string.split(c.value())
date = datel[len(datel)-1]
date = splitDate(c.value())
if date == "":
return -1
try:
Expand Down Expand Up @@ -499,12 +507,11 @@ def death_year(self):
date = ""
if not self.individual():
return date
for e in self.children():
for e in self.element.children():
if e.tag() == "DEAT":
for c in e.children():
if c.tag() == "DATE":
datel = string.split(c.value())
date = datel[len(datel)-1]
date = splitDate(c.value())
if date == "":
return -1
try:
Expand Down Expand Up @@ -532,7 +539,7 @@ def marriage(self):
return (date,place)
for e in self.children():
if e.tag() == "FAMS":
f = self.__dict.get(e.value(),None)
f = e.dict().get(e.value(),None)
if f == None:
return (date,place)
for g in f.children():
Expand All @@ -552,17 +559,16 @@ def marriage_years(self):
dates = []
if not self.individual():
return dates
for e in self.children():
for e in self.element.children():
if e.tag() == "FAMS":
f = self.__dict.get(e.value(),None)
f = e.dict().get(e.value(),None)
if f == None:
return dates
for g in f.children():
if g.tag() == "MARR":
for h in g.children():
if h.tag() == "DATE":
datel = string.split(h.value())
date = datel[len(datel)-1]
date = splitDate(h.value())
try:
dates.append(int(date))
except:
Expand All @@ -578,10 +584,10 @@ def get_individual(self):

def get_family(self):
"""Return this element any all elements in its families."""
result = [self]
for e in self.children():
result = [self.element]
for e in self.element.children():
if e.tag() == "HUSB" or e.tag() == "WIFE" or e.tag() == "CHIL":
f = self.__dict.get(e.value())
f = e.dict().get(e.value())
if f != None:
result.append(f)
return result
Expand Down
Loading