diff --git a/CHANGELOG b/CHANGELOG index 813dea62..291ff6de 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ Changelog 2.0.1 (current dev) ------------------- +Supported GEO-Link API versions: v1.0.0, v1.1.0, v1.1.1, v1.2.0, v1.2.1, v1.2.2 (default) + +- Add support for GEO-Link API version 1.2.2 (new attribute "index") - Dependency updates 2.0.0 diff --git a/geolink_formatter/entity.py b/geolink_formatter/entity.py index b45294be..db6dc59f 100644 --- a/geolink_formatter/entity.py +++ b/geolink_formatter/entity.py @@ -12,7 +12,7 @@ class Document(object): def __init__(self, files, id=None, category=None, doctype=None, federal_level=None, authority=None, authority_url=None, title=None, number=None, abbreviation=None, instance=None, type=None, subtype=None, decree_date=None, enactment_date=None, abrogation_date=None, cycle=None, - municipality=None): + municipality=None, index=None): """Creates a new document instance. Args: @@ -34,6 +34,7 @@ def __init__(self, files, id=None, category=None, doctype=None, federal_level=No abrogation_date (datetime.date): The date of abrogation. cycle (str): The document cycle. municipality (str): The municipality concerned by this document. + index (int): The document's index for sorting. Raises: TypeError: Raised on missing argument or invalid argument type. @@ -87,6 +88,7 @@ def __init__(self, files, id=None, category=None, doctype=None, federal_level=No self._abrogation_date = abrogation_date self._cycle = cycle self._municipality = municipality + self._index = None if index is None else int(index) @property def files(self): @@ -178,6 +180,11 @@ def municipality(self): """str: The municipality concerned by this document (since v1.2.1).""" return self._municipality + @property + def index(self): + """int: The document's index for sorting (since v1.2.2).""" + return self._index + class File(object): def __init__(self, category=None, href=None, title=None, description=None): diff --git a/geolink_formatter/parser.py b/geolink_formatter/parser.py index 23094797..73449d81 100644 --- a/geolink_formatter/parser.py +++ b/geolink_formatter/parser.py @@ -3,7 +3,6 @@ import pkg_resources import requests -import sys from lxml.etree import XMLSchema, DTD, DocumentInvalid from defusedxml.lxml import fromstring from geolink_formatter.entity import Document, File @@ -27,13 +26,16 @@ class SCHEMA(object): V1_2_1 = '1.2.1' """str: geoLink schema version 1.2.1""" + V1_2_2 = '1.2.2' + """str: geoLink schema version 1.2.2""" + class XML(object): _date_format = '%Y-%m-%d' """str: Format of date values in XML.""" - def __init__(self, host_url=None, version='1.2.1', dtd_validation=False, xsd_validation=True): + def __init__(self, host_url=None, version='1.2.2', dtd_validation=False, xsd_validation=True): """Create a new XML parser instance containing the geoLink XSD for validation. Args: @@ -52,12 +54,8 @@ def __init__(self, host_url=None, version='1.2.1', dtd_validation=False, xsd_val self._xsd_validation = xsd_validation xsd = pkg_resources.resource_filename('geolink_formatter', 'schema/v{0}.xsd'.format(version)) if self._xsd_validation: - if sys.version_info.major > 2: - with open(xsd, encoding='utf-8') as f: - self._schema = XMLSchema(fromstring(f.read())) - else: - with open(xsd) as f: - self._schema = XMLSchema(fromstring(f.read())) + with open(xsd, encoding='utf-8') as f: + self._schema = XMLSchema(fromstring(f.read())) @property def host_url(self): @@ -156,7 +154,8 @@ def from_string(self, xml): enactment_date=enactment_date, abrogation_date=abrogation_date, cycle=document_el.attrib.get('cycle'), - municipality=document_el.attrib.get('municipality') + municipality=document_el.attrib.get('municipality'), + index=document_el.attrib.get('index') )) return documents diff --git a/geolink_formatter/schema/v1.2.2.xsd b/geolink_formatter/schema/v1.2.2.xsd new file mode 100644 index 00000000..0e194588 --- /dev/null +++ b/geolink_formatter/schema/v1.2.2.xsd @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/resources/geolink_v1.2.2.xml b/tests/resources/geolink_v1.2.2.xml new file mode 100644 index 00000000..084666a3 --- /dev/null +++ b/tests/resources/geolink_v1.2.2.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_entity.py b/tests/test_entity.py index 78238d84..1b39f092 100644 --- a/tests/test_entity.py +++ b/tests/test_entity.py @@ -31,7 +31,7 @@ def test_document(): enactment_date=date, federal_level='testlevel', authority='Authority', authority_url='http://my.link.to/authority', type='testtype', subtype='testsubtype', decree_date=date, instance='INST', number='123', abbreviation='abbr', abrogation_date=date, - cycle='cycle') + cycle='cycle', municipality='Test Municipality', index=1) assert isinstance(d, Document) assert d.id == '1' assert d.title == 'Test' @@ -50,6 +50,8 @@ def test_document(): assert d.abbreviation == 'abbr' assert d.abrogation_date == date assert d.cycle == 'cycle' + assert d.municipality == 'Test Municipality' + assert d.index == 1 def test_document_empty(): @@ -72,6 +74,8 @@ def test_document_empty(): assert d.abbreviation is None assert d.abrogation_date is None assert d.cycle is None + assert d.municipality is None + assert d.index is None def test_document_invalid_decree_date(): diff --git a/tests/test_parser.py b/tests/test_parser.py index c031370d..bd3f9d82 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -218,6 +218,18 @@ def test_schema_version_1_2_1(): assert documents[1].municipality is None +def test_schema_version_1_2_2(): + with requests_mock.mock() as m: + with open('tests/resources/geolink_v1.2.2.xml', 'rb') as f: + m.get('http://oereblex.test.com/api/geolinks/1500.xml', content=f.read()) + documents = XML(version=SCHEMA.V1_2_2).from_url('http://oereblex.test.com/api/geolinks/1500.xml') + assert len(documents) == 5 + assert documents[0].index is None + assert documents[-3].index == 1 + assert documents[-2].index == 2 + assert documents[-1].index == 3 + + def test_default_version_with_locale(): with requests_mock.mock() as m: with open('tests/resources/geolink_v1.2.1.xml', 'rb') as f: