From edc36ebad5e17fdf517cbe23da0732f6d9987100 Mon Sep 17 00:00:00 2001 From: Daniel Jeller Date: Tue, 14 Mar 2023 09:32:25 +0100 Subject: [PATCH 1/6] Change file encoding after moving to linux --- .gitignore | 0 LICENSE | 0 README.md | 0 conftest.py | 0 pytest_helpers.py | 0 requirements.txt | 0 setup.py | 0 test/test_charter.py | 0 test/test_charter_group.py | 0 test/test_helpers.py | 0 test/test_seal.py | 0 test/test_validator.py | 0 to_cei/charter.py | 0 to_cei/charter_group.py | 0 to_cei/config.py | 0 to_cei/filecache.py | 0 to_cei/helpers.py | 0 to_cei/seal.py | 0 to_cei/validator.py | 0 to_cei/xml_assembler.py | 0 20 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md mode change 100644 => 100755 conftest.py mode change 100644 => 100755 pytest_helpers.py mode change 100644 => 100755 requirements.txt mode change 100644 => 100755 setup.py mode change 100644 => 100755 test/test_charter.py mode change 100644 => 100755 test/test_charter_group.py mode change 100644 => 100755 test/test_helpers.py mode change 100644 => 100755 test/test_seal.py mode change 100644 => 100755 test/test_validator.py mode change 100644 => 100755 to_cei/charter.py mode change 100644 => 100755 to_cei/charter_group.py mode change 100644 => 100755 to_cei/config.py mode change 100644 => 100755 to_cei/filecache.py mode change 100644 => 100755 to_cei/helpers.py mode change 100644 => 100755 to_cei/seal.py mode change 100644 => 100755 to_cei/validator.py mode change 100644 => 100755 to_cei/xml_assembler.py diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/conftest.py b/conftest.py old mode 100644 new mode 100755 diff --git a/pytest_helpers.py b/pytest_helpers.py old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 diff --git a/test/test_charter.py b/test/test_charter.py old mode 100644 new mode 100755 diff --git a/test/test_charter_group.py b/test/test_charter_group.py old mode 100644 new mode 100755 diff --git a/test/test_helpers.py b/test/test_helpers.py old mode 100644 new mode 100755 diff --git a/test/test_seal.py b/test/test_seal.py old mode 100644 new mode 100755 diff --git a/test/test_validator.py b/test/test_validator.py old mode 100644 new mode 100755 diff --git a/to_cei/charter.py b/to_cei/charter.py old mode 100644 new mode 100755 diff --git a/to_cei/charter_group.py b/to_cei/charter_group.py old mode 100644 new mode 100755 diff --git a/to_cei/config.py b/to_cei/config.py old mode 100644 new mode 100755 diff --git a/to_cei/filecache.py b/to_cei/filecache.py old mode 100644 new mode 100755 diff --git a/to_cei/helpers.py b/to_cei/helpers.py old mode 100644 new mode 100755 diff --git a/to_cei/seal.py b/to_cei/seal.py old mode 100644 new mode 100755 diff --git a/to_cei/validator.py b/to_cei/validator.py old mode 100644 new mode 100755 diff --git a/to_cei/xml_assembler.py b/to_cei/xml_assembler.py old mode 100644 new mode 100755 From 435a394d7b54af34d3e34611f2157795b6f5fde1 Mon Sep 17 00:00:00 2001 From: Daniel Jeller Date: Tue, 14 Mar 2023 09:34:29 +0100 Subject: [PATCH 2/6] Change the raw github file url for validation with the official one --- to_cei/validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/to_cei/validator.py b/to_cei/validator.py index 1c0468c..bfb5d03 100755 --- a/to_cei/validator.py +++ b/to_cei/validator.py @@ -8,7 +8,7 @@ class Schema(str, Enum): - CEI = "https://raw.githubusercontent.com/icaruseu/mom-ca/master/my/XRX/src/mom/app/cei/xsd/cei.xsd" + CEI = "http://www.monasterium.net/NS/cei" class Validator: From 87865079bb790f91d8ddec56353f8229d37f5b53 Mon Sep 17 00:00:00 2001 From: Daniel Jeller Date: Wed, 15 Mar 2023 09:51:36 +0100 Subject: [PATCH 3/6] Add CEI schema location to generated elements and xml declaration --- to_cei/charter.py | 3 ++- to_cei/charter_group.py | 3 ++- to_cei/config.py | 13 ++++++++++++- to_cei/validator.py | 2 +- to_cei/xml_assembler.py | 10 +++++++++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/to_cei/charter.py b/to_cei/charter.py index 3ef78d7..47c6d16 100755 --- a/to_cei/charter.py +++ b/to_cei/charter.py @@ -6,7 +6,7 @@ from astropy.time import Time from lxml import etree -from to_cei.config import CEI +from to_cei.config import CEI, CEI_SCHEMA_LOCATION_ATTRIBUTE from to_cei.helpers import (get_str, get_str_list, get_str_or_element, get_str_or_element_list, join) from to_cei.seal import Seal @@ -969,6 +969,7 @@ def _create_cei_tenor(self) -> Optional[etree._Element]: def _create_cei_text(self) -> etree._Element: return CEI.text( + CEI_SCHEMA_LOCATION_ATTRIBUTE, self._create_cei_front(), self._create_cei_body(), self._create_cei_back(), diff --git a/to_cei/charter_group.py b/to_cei/charter_group.py index b5fcf8c..cad76d1 100755 --- a/to_cei/charter_group.py +++ b/to_cei/charter_group.py @@ -3,7 +3,7 @@ from lxml import etree from to_cei.charter import Charter -from to_cei.config import CEI +from to_cei.config import CEI, CEI_SCHEMA_LOCATION_ATTRIBUTE from to_cei.xml_assembler import XmlAssembler @@ -41,6 +41,7 @@ def name(self, value: str): def to_xml(self) -> etree._Element: xml = CEI.cei( + CEI_SCHEMA_LOCATION_ATTRIBUTE, CEI.teiHeader(CEI.fileDesc(CEI.titleStmt(CEI.title(self.name)))), CEI.text(CEI.group(*[charter.to_xml() for charter in self.charters])), ) diff --git a/to_cei/config.py b/to_cei/config.py index 51660db..f674033 100755 --- a/to_cei/config.py +++ b/to_cei/config.py @@ -1,3 +1,4 @@ +from lxml import etree from lxml.builder import ElementMaker # type: ignore from to_cei import filecache @@ -8,6 +9,16 @@ CEI_PREFIX: str = "cei" -CHARTER_NSS = {CEI_PREFIX: CEI_NS} +CHARTER_NSS = { + CEI_PREFIX: CEI_NS, + "xsi": "http://www.w3.org/2001/XMLSchema-instance", +} + +CEI_SCHEMA_LOCATION_ATTRIBUTE = { + etree.QName( + "http://www.w3.org/2001/XMLSchema-instance", "schemaLocation" + ): f"{CEI_NS} {CEI_NS}" +} + CEI = ElementMaker(namespace=CEI_NS, nsmap=CHARTER_NSS) diff --git a/to_cei/validator.py b/to_cei/validator.py index bfb5d03..324d3d9 100755 --- a/to_cei/validator.py +++ b/to_cei/validator.py @@ -8,7 +8,7 @@ class Schema(str, Enum): - CEI = "http://www.monasterium.net/NS/cei" + CEI = config.CEI_NS class Validator: diff --git a/to_cei/xml_assembler.py b/to_cei/xml_assembler.py index d489d40..9adb8f1 100755 --- a/to_cei/xml_assembler.py +++ b/to_cei/xml_assembler.py @@ -18,7 +18,13 @@ def to_string(self) -> str: return ( "" if xml is None - else str(etree.tostring(xml, encoding="unicode", pretty_print=True)) + else str( + etree.tostring( + xml, + encoding="unicode", + pretty_print=True, + ) + ) ) def to_file( @@ -45,4 +51,6 @@ def to_file( encoding="UTF-8", pretty_print=True, inclusive_ns_prefixes=[CEI_PREFIX] + inclusive_ns_prefixes, + xml_declaration=True, + standalone=False, ) From a150fd2d08f15f9b7e1730263682a545230f93ae Mon Sep 17 00:00:00 2001 From: Daniel Jeller Date: Wed, 15 Mar 2023 09:53:53 +0100 Subject: [PATCH 4/6] Bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e7e8f1b..0f695a0 100755 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ # This call to setup() does all the work setup( name="to_cei", - version="0.1.5", + version="0.1.6", description="to-CEI", long_description=long_description, long_description_content_type="text/markdown", From 773887fc57a92bcf75e6a3f490f0db3dc556460d Mon Sep 17 00:00:00 2001 From: Daniel Jeller Date: Wed, 15 Mar 2023 11:13:08 +0100 Subject: [PATCH 5/6] Add add_schema_location parameter to serialization methods --- test/test_charter.py | 12 +++++++++++- test/test_charter_group.py | 10 ++++++++++ to_cei/charter.py | 20 +++++++++++++------- to_cei/charter_group.py | 15 +++++++++------ to_cei/config.py | 15 +++++++++------ to_cei/xml_assembler.py | 9 +++++---- 6 files changed, 57 insertions(+), 24 deletions(-) diff --git a/test/test_charter.py b/test/test_charter.py index d073dfd..023d507 100755 --- a/test/test_charter.py +++ b/test/test_charter.py @@ -8,7 +8,8 @@ from pytest_helpers import xp, xps from to_cei.charter import NO_DATE_TEXT, NO_DATE_VALUE, Charter -from to_cei.config import CEI, CHARTER_NSS +from to_cei.config import (CEI, CHARTER_NSS, SCHEMA_LOCATION, + SCHEMA_LOCATION_QNAME) from to_cei.helpers import ln from to_cei.seal import Seal from to_cei.validator import Validator @@ -88,6 +89,15 @@ def test_writes_correct_file(tmp_path): Validator().validate_cei(written.getroot()) +def test_add_schema_location_is_respected(): + charter = Charter("1A") + assert ( + charter.to_xml(add_schema_location=True).get(SCHEMA_LOCATION_QNAME) + == SCHEMA_LOCATION + ) + assert charter.to_xml(add_schema_location=False).get(SCHEMA_LOCATION_QNAME) == None + + # --------------------------------------------------------------------# # Charter abstract # # --------------------------------------------------------------------# diff --git a/test/test_charter_group.py b/test/test_charter_group.py index 1ad4d4f..6ed4fbd 100755 --- a/test/test_charter_group.py +++ b/test/test_charter_group.py @@ -5,6 +5,7 @@ from to_cei.charter import Charter from to_cei.charter_group import CharterGroup +from to_cei.config import SCHEMA_LOCATION, SCHEMA_LOCATION_QNAME from to_cei.validator import Validator @@ -23,6 +24,15 @@ def test_writes_correct_file(tmp_path): Validator().validate_cei(written.getroot()) +def test_add_schema_location_is_respected(): + group = CharterGroup("Charter group", [Charter("1A"), Charter("1b")]) + assert ( + group.to_xml(add_schema_location=True).get(SCHEMA_LOCATION_QNAME) + == SCHEMA_LOCATION + ) + assert group.to_xml(add_schema_location=False).get(SCHEMA_LOCATION_QNAME) == None + + def test_raises_exception_for_empty_name(): with pytest.raises(ValueError): CharterGroup("") diff --git a/to_cei/charter.py b/to_cei/charter.py index 47c6d16..52bf5c4 100755 --- a/to_cei/charter.py +++ b/to_cei/charter.py @@ -967,14 +967,16 @@ def _create_cei_tenor(self) -> Optional[etree._Element]: else CEI.tenor(self.transcription) ) - def _create_cei_text(self) -> etree._Element: - return CEI.text( - CEI_SCHEMA_LOCATION_ATTRIBUTE, + def _create_cei_text(self, add_schema_location: bool = False) -> etree._Element: + text = CEI.text( self._create_cei_front(), self._create_cei_body(), self._create_cei_back(), type="charter", ) + if add_schema_location: + text.attrib.update(CEI_SCHEMA_LOCATION_ATTRIBUTE) + return text def _create_cei_traditio_form(self) -> Optional[etree._Element]: return None if not self._tradition else CEI.traditioForm(self._tradition) @@ -994,13 +996,17 @@ def _create_cei_witness_orig(self) -> Optional[etree._Element]: # Public methods # # --------------------------------------------------------------------# - def to_xml(self) -> etree._Element: - return self._create_cei_text() + def to_xml(self, add_schema_location: bool = False) -> etree._Element: + return self._create_cei_text(add_schema_location) - def to_file(self, folder: Optional[str] = None): + def to_file(self, folder: Optional[str] = None, add_schema_location: bool = False): """Writes the xml representation of the charter to a file. The filename is generated from the normalized charter id. Args: folder (str): The folder to write the file to. If this is ommitted, the file is written to the place where the script is """ - return super(Charter, self).to_file(self.id_norm + ".cei", folder=folder) + return super(Charter, self).to_file( + self.id_norm + ".cei", + folder=folder, + add_schema_location=add_schema_location, + ) diff --git a/to_cei/charter_group.py b/to_cei/charter_group.py index cad76d1..8498cfb 100755 --- a/to_cei/charter_group.py +++ b/to_cei/charter_group.py @@ -39,15 +39,18 @@ def name(self, value: str): raise ValueError("Group name cannot be empty") self._name = value - def to_xml(self) -> etree._Element: - xml = CEI.cei( - CEI_SCHEMA_LOCATION_ATTRIBUTE, + def to_xml(self, add_schema_location: bool = False) -> etree._Element: + cei = CEI.cei( CEI.teiHeader(CEI.fileDesc(CEI.titleStmt(CEI.title(self.name)))), CEI.text(CEI.group(*[charter.to_xml() for charter in self.charters])), ) - return xml + if add_schema_location: + cei.attrib.update(CEI_SCHEMA_LOCATION_ATTRIBUTE) + return cei - def to_file(self, folder: Optional[str] = None): + def to_file(self, folder: Optional[str] = None, add_schema_location: bool = False): return super(CharterGroup, self).to_file( - self.name.lower().replace(" ", "_") + ".cei.group", folder=folder + self.name.lower().replace(" ", "_") + ".cei.group", + folder=folder, + add_schema_location=add_schema_location, ) diff --git a/to_cei/config.py b/to_cei/config.py index f674033..e54c5c6 100755 --- a/to_cei/config.py +++ b/to_cei/config.py @@ -11,14 +11,17 @@ CHARTER_NSS = { CEI_PREFIX: CEI_NS, - "xsi": "http://www.w3.org/2001/XMLSchema-instance", } -CEI_SCHEMA_LOCATION_ATTRIBUTE = { - etree.QName( - "http://www.w3.org/2001/XMLSchema-instance", "schemaLocation" - ): f"{CEI_NS} {CEI_NS}" -} +SCHEMA_LOCATION_QNAME = etree.QName( + "http://www.w3.org/2001/XMLSchema-instance", "schemaLocation" +) + +SCHEMA_LOCATION = f"{CEI_NS} {CEI_NS}" + +CEI_SCHEMA_LOCATION_ATTRIBUTE = {SCHEMA_LOCATION_QNAME: SCHEMA_LOCATION} + +XSI_NS = "http://www.w3.org/2001/XMLSchema-instance" CEI = ElementMaker(namespace=CEI_NS, nsmap=CHARTER_NSS) diff --git a/to_cei/xml_assembler.py b/to_cei/xml_assembler.py index 9adb8f1..acd473a 100755 --- a/to_cei/xml_assembler.py +++ b/to_cei/xml_assembler.py @@ -10,11 +10,11 @@ class XmlAssembler(ABC): @abstractmethod - def to_xml(self) -> Optional[etree._Element]: + def to_xml(self, add_schema_location: bool = False) -> Optional[etree._Element]: pass - def to_string(self) -> str: - xml = self.to_xml() + def to_string(self, add_schema_location: bool = False) -> str: + xml = self.to_xml(add_schema_location) return ( "" if xml is None @@ -32,8 +32,9 @@ def to_file( name: str, folder: Optional[str | Path] = None, inclusive_ns_prefixes: List[str] = [], + add_schema_location: bool = False, ): - xml = self.to_xml() + xml = self.to_xml(add_schema_location) if xml is None: raise Exception("Failed to read xml") folder = ( From aff391ad1a5884a0d9797aa06d2a9639df37617b Mon Sep 17 00:00:00 2001 From: Daniel Jeller Date: Wed, 15 Mar 2023 11:22:05 +0100 Subject: [PATCH 6/6] Add comments to the public methods --- to_cei/charter.py | 11 ++++++++++- to_cei/charter_group.py | 14 ++++++++++++++ to_cei/xml_assembler.py | 8 ++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/to_cei/charter.py b/to_cei/charter.py index 52bf5c4..726e0fa 100755 --- a/to_cei/charter.py +++ b/to_cei/charter.py @@ -997,13 +997,22 @@ def _create_cei_witness_orig(self) -> Optional[etree._Element]: # --------------------------------------------------------------------# def to_xml(self, add_schema_location: bool = False) -> etree._Element: + """Creates an xml representation of the charter. + + Args: + add_schema_location: If True, the CEI schema location is added to the root element. + + Returns: + An etree Element object representing the charter. + """ return self._create_cei_text(add_schema_location) def to_file(self, folder: Optional[str] = None, add_schema_location: bool = False): """Writes the xml representation of the charter to a file. The filename is generated from the normalized charter id. Args: - folder (str): The folder to write the file to. If this is ommitted, the file is written to the place where the script is + folder (str): The folder to write the file to. If this is ommitted, the file is written to the place where the script is executed from. + add_schema_location (bool): If True, the CEI schema location is added to the root element. Defaults to False. """ return super(Charter, self).to_file( self.id_norm + ".cei", diff --git a/to_cei/charter_group.py b/to_cei/charter_group.py index 8498cfb..7dffc4d 100755 --- a/to_cei/charter_group.py +++ b/to_cei/charter_group.py @@ -40,6 +40,14 @@ def name(self, value: str): self._name = value def to_xml(self, add_schema_location: bool = False) -> etree._Element: + """Creates an xml representation of the charter group. + + Args: + add_schema_location: If True, the CEI schema location is added to the root element. + + Returns: + An etree Element object representing the charter group. + """ cei = CEI.cei( CEI.teiHeader(CEI.fileDesc(CEI.titleStmt(CEI.title(self.name)))), CEI.text(CEI.group(*[charter.to_xml() for charter in self.charters])), @@ -49,6 +57,12 @@ def to_xml(self, add_schema_location: bool = False) -> etree._Element: return cei def to_file(self, folder: Optional[str] = None, add_schema_location: bool = False): + """Writes the xml representation of the charter group to a file. The filename is generated from a normalization of the group name. + + Args: + folder (str): The folder to write the file to. If this is ommitted, the file is written to the place where the script is executed from. + add_schema_location (bool): If True, the CEI schema location is added to the root element. Defaults to False. + """ return super(CharterGroup, self).to_file( self.name.lower().replace(" ", "_") + ".cei.group", folder=folder, diff --git a/to_cei/xml_assembler.py b/to_cei/xml_assembler.py index acd473a..7fc76b9 100755 --- a/to_cei/xml_assembler.py +++ b/to_cei/xml_assembler.py @@ -14,6 +14,14 @@ def to_xml(self, add_schema_location: bool = False) -> Optional[etree._Element]: pass def to_string(self, add_schema_location: bool = False) -> str: + """Serializes the xml representation of the object to a string. + + Args: + add_schema_location: If True, the CEI schema location is added to the root element. + + Returns: + A string representation of the object. + """ xml = self.to_xml(add_schema_location) return ( ""