Skip to content

Commit

Permalink
Merge branch 'release/v0.2.5dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyaurel committed Dec 15, 2018
2 parents def78de + 77b2f1f commit 7fea5c5
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 531 deletions.
402 changes: 6 additions & 396 deletions .gitignore

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: python

matrix:
include:
- python: '2.7'
env: TOXENV=py27
- python: '3.4'
env: TOXENV=py34
- python: '3.5'
env: TOXENV=py35
- python: '3.6'
env: TOXENV=py36

install: pip install tox

script: tox

notifications:
email: false
11 changes: 0 additions & 11 deletions Dockerfile

This file was deleted.

File renamed without changes.
8 changes: 8 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Include the README
include *.md

# Include the license file
include LICENSE.txt

# Include the `requirements.txt` file
include requirements.txt
163 changes: 88 additions & 75 deletions README.md

Large diffs are not rendered by default.

9 changes: 0 additions & 9 deletions docker-compose.yml

This file was deleted.

66 changes: 34 additions & 32 deletions gedcom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class Gedcom:
- a dict (only elements with pointers, which are the keys)
"""

def __init__(self, file_path, use_strict = True):
def __init__(self, file_path, use_strict=True):
"""Initialize a GEDCOM data object. You must supply a GEDCOM file
:type file_path: str
"""
Expand Down Expand Up @@ -215,19 +215,19 @@ def get_root_child_elements(self):

# Private methods

def __parse(self, file_path, use_strict = True):
def __parse(self, file_path, use_strict=True):
"""Open and parse file path as GEDCOM 5.5 formatted data
:type file_path: str
"""
gedcom_file = open(file_path, 'rb')
line_number = 1
last_element = self.__root_element
for line in gedcom_file:
last_element = self.__parse_line(line_number, line.decode('utf-8-sig'), last_element, use_strict )
last_element = self.__parse_line(line_number, line.decode('utf-8-sig'), last_element, use_strict)
line_number += 1

@staticmethod
def __parse_line(line_number, line, last_element, use_strict = True):
def __parse_line(line_number, line, last_element, use_strict=True):
"""Parse a line from a GEDCOM 5.5 formatted document
Each line should have the following (bracketed items optional):
Expand Down Expand Up @@ -260,25 +260,25 @@ def __parse_line(line_number, line, last_element, use_strict = True):

if regex_match is None:
if use_strict:
error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number +
"\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf")
error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number
+ "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf")
raise SyntaxError(error_message)
else:
# Quirk check - see if this is a line without a CRLF (which could be the last line)
last_line_regex = level_regex + pointer_regex + tag_regex + value_regex
regex_match = regex.match(last_line_regex, line)
if regex_match is not None:
line_parts = regex_match.groups()

level = int(line_parts[0])
pointer = line_parts[1].rstrip(' ')
tag = line_parts[2]
value = line_parts[3][1:]
crlf = '\n'
else:
# Quirk check - Sometimes a gedcom has a text field with a CR.
# This creates a line without the standard level and pointer. If this is detected
# then turn it into a CONC or CONT
# Quirk check - Sometimes a gedcom has a text field with a CR.
# This creates a line without the standard level and pointer.
# If this is detected then turn it into a CONC or CONT.
line_regex = '([^\n\r]*|)'
cont_line_regex = line_regex + end_of_line_regex
regex_match = regex.match(cont_line_regex, line)
Expand All @@ -294,7 +294,7 @@ def __parse_line(line_number, line, last_element, use_strict = True):
tag = GEDCOM_TAG_CONCATENATION
else:
line_parts = regex_match.groups()

level = int(line_parts[0])
pointer = line_parts[1].rstrip(' ')
tag = line_parts[2]
Expand All @@ -303,9 +303,9 @@ def __parse_line(line_number, line, last_element, use_strict = True):

# Check level: should never be more than one higher than previous line.
if level > last_element.get_level() + 1:
error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number +
"\nLines must be no more than one level higher than previous line." +
"\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf")
error_message = ("Line %d of document violates GEDCOM format 5.5" % line_number
+ "\nLines must be no more than one level higher than previous line."
+ "\nSee: https://chronoplexsoftware.com/gedcomvalidator/gedcom/gedcom-5.5.pdf")
raise SyntaxError(error_message)

# Create element. Store in list and dict, create children and parents.
Expand Down Expand Up @@ -416,9 +416,9 @@ def get_families(self, individual, family_type=GEDCOM_TAG_FAMILY_SPOUSE):
families = []
element_dictionary = self.get_element_dictionary()
for child_element in individual.get_child_elements():
is_family = (child_element.get_tag() == family_type and
child_element.get_value() in element_dictionary and
element_dictionary[child_element.get_value()].is_family())
is_family = (child_element.get_tag() == family_type
and child_element.get_value() in element_dictionary
and element_dictionary[child_element.get_value()].is_family())
if is_family:
families.append(element_dictionary[child_element.get_value()])
return families
Expand Down Expand Up @@ -508,12 +508,12 @@ def get_family_members(self, family, members_type="ALL"):
element_dictionary = self.get_element_dictionary()
for child_element in family.get_child_elements():
# Default is ALL
is_family = (child_element.get_tag() == GEDCOM_TAG_HUSBAND or
child_element.get_tag() == GEDCOM_TAG_WIFE or
child_element.get_tag() == GEDCOM_TAG_CHILD)
is_family = (child_element.get_tag() == GEDCOM_TAG_HUSBAND
or child_element.get_tag() == GEDCOM_TAG_WIFE
or child_element.get_tag() == GEDCOM_TAG_CHILD)
if members_type == "PARENTS":
is_family = (child_element.get_tag() == GEDCOM_TAG_HUSBAND or
child_element.get_tag() == GEDCOM_TAG_WIFE)
is_family = (child_element.get_tag() == GEDCOM_TAG_HUSBAND
or child_element.get_tag() == GEDCOM_TAG_WIFE)
elif members_type == "HUSB":
is_family = child_element.get_tag() == GEDCOM_TAG_HUSBAND
elif members_type == "WIFE":
Expand Down Expand Up @@ -821,13 +821,15 @@ def criteria_match(self, criteria):
:rtype: bool
"""

# error checking on the criteria
# Check if criteria is a valid criteria
try:
for criterion in criteria.split(':'):
key, value = criterion.split('=')
except:
criterion.split('=')
except ValueError:
return False

match = True

for criterion in criteria.split(':'):
key, value = criterion.split('=')
if key == "surname" and not self.surname_match(value):
Expand All @@ -839,7 +841,7 @@ def criteria_match(self, criteria):
year = int(value)
if not self.birth_year_match(year):
match = False
except:
except ValueError:
match = False
elif key == "birth_range":
try:
Expand All @@ -848,14 +850,14 @@ def criteria_match(self, criteria):
to_year = int(to_year)
if not self.birth_range_match(from_year, to_year):
match = False
except:
except ValueError:
match = False
elif key == "death":
try:
year = int(value)
if not self.death_year_match(year):
match = False
except:
except ValueError:
match = False
elif key == "death_range":
try:
Expand All @@ -864,7 +866,7 @@ def criteria_match(self, criteria):
to_year = int(to_year)
if not self.death_range_match(from_year, to_year):
match = False
except:
except ValueError:
match = False

return match
Expand Down Expand Up @@ -929,7 +931,7 @@ def get_name(self):
last = ""
if not self.is_individual():
return first, last

# Return the first GEDCOM_TAG_NAME that is found. Alternatively
# as soon as we have both the GEDCOM_TAG_GIVEN_NAME and _SURNAME return those
found_given_name = False
Expand Down Expand Up @@ -1022,7 +1024,7 @@ def get_birth_year(self):
return -1
try:
return int(date)
except:
except ValueError:
return -1

def get_death_data(self):
Expand Down Expand Up @@ -1062,7 +1064,7 @@ def get_death_year(self):
return -1
try:
return int(date)
except:
except ValueError:
return -1

def get_burial(self):
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
setuptools
wheel
twine
tox
13 changes: 13 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[metadata]
# This includes the license file(s) in the wheel.
# https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file
license_files = LICENSE.txt

[bdist_wheel]
# This flag says to generate wheels that support both Python 2 and Python
# 3. If your code will not run unchanged on both Python 2 and 3, you will
# need to generate separate wheels for each Python version that you
# support. Removing this line (or setting universal to 0) will prevent
# bdist_wheel from trying to make a universal wheel. For more see:
# https://packaging.python.org/guides/distributing-packages-using-setuptools/#wheels
universal=1
48 changes: 40 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
from setuptools import setup
from setuptools import setup, find_packages
from os import path
from io import open

here = path.abspath(path.dirname(__file__))

# Get the long description from the `README.md` file
with open(path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = f.read()

setup(
name='python-gedcom',
version='0.2.4dev',
packages=['gedcom', ],
license='GPLv2',
package_dir={'': '.'},
version='0.2.5dev',
description='A Python module for parsing, analyzing, and manipulating GEDCOM files.',
long_description=open('README.md').read(),
maintainer='Nicklas Reincke',
maintainer_email='contact@reynke.com',
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/nickreynke/python-gedcom',
author='Nicklas Reincke',
author_email='contact@reynke.com',
license='GPLv2',
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Topic :: Sociology :: Genealogy',
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
keywords='python gedcom parser',
packages=find_packages(exclude=['contrib', 'docs', 'tests']),
install_requires=[],
extras_require={
'dev': ['setuptools', 'wheel', 'twine'],
'test': ['tox'],
},
package_data={},
data_files=[],
project_urls={
'Bug Reports': 'https://github.com/nickreynke/python-gedcom/issues',
'Source': 'https://github.com/nickreynke/python-gedcom',
},
)
Empty file added tests/__init__.py
Empty file.
2 changes: 2 additions & 0 deletions tests/test_simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def test_success():
assert True
27 changes: 27 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# - check-manifest
# confirm items checked into vcs are in your sdist
# - python setup.py check
# confirm required package meta-data in setup.py

[tox]
envlist = py{27,34,35,36}

[testenv]
basepython =
py27: python2.7
py34: python3.4
py35: python3.5
py36: python3.6
deps =
check-manifest
flake8
pytest
commands =
check-manifest --ignore tox.ini,tests*
python setup.py check -m -s
flake8 .
py.test tests
[flake8]
exclude = .tox,*.egg,build,data
select = E,W,F
ignore = E501,W503

0 comments on commit 7fea5c5

Please sign in to comment.