From 148a0e8c2e54e9975407ea1eec6ffdf187184938 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 15 Sep 2024 19:11:06 -0300 Subject: [PATCH 01/13] Adiciona atributos ausentes em 'corresp' e 'fn' --- packtools/sps/models/v2/notes.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packtools/sps/models/v2/notes.py b/packtools/sps/models/v2/notes.py index 48ed2d1b3..4f313fd8d 100644 --- a/packtools/sps/models/v2/notes.py +++ b/packtools/sps/models/v2/notes.py @@ -22,13 +22,14 @@ def data(self): class BaseNoteGroups: def __init__(self, article_or_sub_article_node, fn_parent_tag_name, NoteGroupClass): - self.article_or_sub_article_node = article_or_sub_article_node self.fn_parent_tag_name = fn_parent_tag_name self.parent = article_or_sub_article_node.tag self.parent_id = article_or_sub_article_node.get("id") self.parent_lang = article_or_sub_article_node.get("{http://www.w3.org/XML/1998/namespace}lang") self.parent_article_type = article_or_sub_article_node.get("article-type") self.NoteGroupClass = NoteGroupClass + self.article_or_sub_article_node = article_or_sub_article_node \ + if self.parent == "sub-article" else article_or_sub_article_node.find("./") @property def items(self): @@ -45,6 +46,7 @@ def __init__(self, node): self.label = self.node.findtext("label") self.text = process_subtags(self.node) self.bold = self.node.findtext("bold") + self.title = self.node.findtext("title") @property def data(self): @@ -53,7 +55,8 @@ def data(self): "fn_type": self.type, "fn_label": self.label, "fn_text": self.text, - "fn_bold": self.bold + "fn_bold": self.bold, + "fn_title": self.title } @@ -91,13 +94,23 @@ def corresp(self): def corresp_label(self): return process_subtags(self.fn_parent_node.find("corresp/label")) + @property + def corresp_title(self): + return process_subtags(self.fn_parent_node.find("corresp/title")) + + @property + def corresp_bold(self): + return process_subtags(self.fn_parent_node.find("corresp/bold")) + @property def data(self): return { **super().data, "corresp": self.corresp, - "corresp_label": self.corresp_label - } + "corresp_label": self.corresp_label, + "corresp_title": self.corresp_title, + "corresp_bold": self.corresp_bold + } class AuthorNotes(BaseNoteGroups): From 279726c867909ce84be63a549d78737268a050fa Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 15 Sep 2024 19:11:41 -0300 Subject: [PATCH 02/13] Adequa os testes --- tests/sps/models/v2/test_notes.py | 191 +++++++++++++++++------------- 1 file changed, 108 insertions(+), 83 deletions(-) diff --git a/tests/sps/models/v2/test_notes.py b/tests/sps/models/v2/test_notes.py index aaed22123..af75b42bd 100644 --- a/tests/sps/models/v2/test_notes.py +++ b/tests/sps/models/v2/test_notes.py @@ -54,7 +54,8 @@ def test_fn_data(self): "fn_type": "conflict", "fn_label": "1", "fn_text": "*1Os autores declaram não haver conflito de interesses.", - "fn_bold": "*" + "fn_bold": "*", + 'fn_title': None, } ) @@ -91,7 +92,8 @@ def test_fn_group(self): 'fn_label': None, 'fn_type': 'other', 'fn_parent': 'fn-group', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, }, { 'fn_id': 'fn3', @@ -100,7 +102,8 @@ def test_fn_group(self): 'fn_label': None, 'fn_type': 'other', 'fn_parent': 'fn-group', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, }, { 'fn_id': 'fn4', @@ -109,7 +112,8 @@ def test_fn_group(self): 'fn_label': None, 'fn_type': 'other', 'fn_parent': 'fn-group', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, } ] for i, item in enumerate(obtained): @@ -158,7 +162,8 @@ def test_fn_groups(self): 'fn_label': None, 'fn_type': 'other', 'fn_parent': 'fn-group', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, }, { 'fn_id': 'fn3', @@ -167,7 +172,8 @@ def test_fn_groups(self): 'fn_label': None, 'fn_type': 'other', 'fn_parent': 'fn-group', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, }, { 'fn_id': 'fn4', @@ -176,7 +182,8 @@ def test_fn_groups(self): 'fn_label': None, 'fn_type': 'other', 'fn_parent': 'fn-group', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, } ] } @@ -219,7 +226,8 @@ def test_author_note(self): 'fn_parent': 'author-notes', 'fn_text': '1Os autores declaram não haver conflito de interesses.', 'fn_type': 'conflict', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, } ] for i, item in enumerate(obtained): @@ -278,6 +286,8 @@ def test_author_notes(self): 'Recanto Real Rua 4, 440 15021-450 São José do Rio Preto, SP, ' 'Brasil E-mail: roseanap@gmail.com', 'corresp_label': 'Correspondência', + "corresp_title": None, + "corresp_bold": None, 'fns': [ { 'fn_id': 'fn_01', @@ -285,7 +295,8 @@ def test_author_notes(self): 'fn_parent': 'author-notes', 'fn_text': '1Os autores declaram não haver conflito de interesses.', 'fn_type': 'conflict', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, }, ] }, @@ -297,6 +308,8 @@ def test_author_notes(self): 'corresp': '*Correspondence: Dr. Edmundo Figueira Departamento de ' 'Fisioterapia,Universidade FISP - Hogwarts,', 'corresp_label': '*', + "corresp_title": None, + "corresp_bold": 'Correspondence', 'fns': [ { 'fn_id': None, @@ -304,7 +317,8 @@ def test_author_notes(self): 'fn_parent': 'author-notes', 'fn_text': 'Não há conflito de interesse entre os autores do artigo.', 'fn_type': 'coi-statement', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, }, { 'fn_id': None, @@ -312,7 +326,8 @@ def test_author_notes(self): 'fn_parent': 'author-notes', 'fn_text': 'Todos os autores tiveram contribuição igualitária na criação do artigo.', 'fn_type': 'equal', - 'fn_bold': None + 'fn_bold': None, + 'fn_title': None, } ] } @@ -370,6 +385,20 @@ def setUp(self): '' '' '' + '' + '' + '' + '' + ': John Doe, Example Institution, 123 Example Street, Example City, Country.' + 'Email: johndoe@example.com' + '' + '' + '' + '

The authors declare there is no conflict of interest.

' + '
' + '
' + '
' + '
' '' ) self.xml_tree = etree.fromstring(xml) @@ -379,90 +408,86 @@ def test_all_notes(self): obtained = list(ArticleNotes(self.xml_tree).all_notes()) expected = [ { - 'parent': 'article', - 'parent_article_type': 'research-article', - 'parent_id': None, - 'parent_lang': 'pt', - 'label': None, - 'title': 'Highlights: ', - 'fns': [ + "corresp": "Correspondência: Roseana Mara Aredes Priuli Av. Juscelino " + "Kubistcheck de Oliveira, 1220, Jardim Panorama, Condomínio " + "Recanto Real Rua 4, 440 15021-450 São José do Rio Preto, SP, " + "Brasil E-mail: roseanap@gmail.com", + "corresp_label": "Correspondência", + "corresp_title": None, + "corresp_bold": None, + "fns": [ { - 'fn_id': 'fn2', - 'fn_text': 'A)Study presents design and production of an LED lamp for photovoltaic light traps.', - 'fn_label': None, - 'fn_type': 'other', - 'fn_parent': 'fn-group', - 'fn_bold': "A)" - }, - { - 'fn_id': 'fn3', - 'fn_text': 'The LED lamp switches on and off automatically, controls the battery charge and indicates ' - 'the operating status of the system.', - 'fn_label': None, - 'fn_type': 'other', - 'fn_parent': 'fn-group', - 'fn_bold': None - }, - { - 'fn_id': 'fn4', - 'fn_text': 'The LED lamp is a superior substitute for the standard fluorescent lamps used in ' - 'conventional light traps.', - 'fn_label': None, - 'fn_type': 'other', - 'fn_parent': 'fn-group', - 'fn_bold': None + "fn_bold": None, + "fn_id": "fn_01", + "fn_label": "1", + "fn_parent": "author-notes", + "fn_text": "1Os autores declaram não haver conflito de interesses.", + "fn_type": "conflict", + 'fn_title': None, } - ] + ], + "parent": "article", + "parent_article_type": "research-article", + "parent_id": None, + "parent_lang": "pt", }, { - 'parent': 'article', - 'parent_article_type': 'research-article', - 'parent_id': None, - 'parent_lang': 'pt', - 'corresp': 'Correspondência: Roseana Mara Aredes Priuli Av. Juscelino ' - 'Kubistcheck de Oliveira, 1220, Jardim Panorama, Condomínio ' - 'Recanto Real Rua 4, 440 15021-450 São José do Rio Preto, SP, ' - 'Brasil E-mail: roseanap@gmail.com', - 'corresp_label': 'Correspondência', - 'fns': [ + "corresp": "*Correspondence: Dr. Edmundo Figueira Departamento de " + "Fisioterapia,Universidade FISP - Hogwarts,", + "corresp_label": "*", + "corresp_title": None, + "corresp_bold": "Correspondence", + "fns": [ { - 'fn_id': 'fn_01', - 'fn_label': '1', - 'fn_parent': 'author-notes', - 'fn_text': '1Os autores declaram não haver conflito de interesses.', - 'fn_type': 'conflict', - 'fn_bold': None + "fn_bold": None, + "fn_id": None, + "fn_label": None, + "fn_parent": "author-notes", + "fn_text": "Não há conflito de interesse entre os autores do artigo.", + "fn_type": "coi-statement", + 'fn_title': None, }, - ] - }, - { - 'parent': 'article', - 'parent_article_type': 'research-article', - 'parent_id': None, - 'parent_lang': 'pt', - 'corresp': '*Correspondence: Dr. Edmundo Figueira Departamento de ' - 'Fisioterapia,Universidade FISP - Hogwarts,', - 'corresp_label': '*', - 'fns': [ { - 'fn_id': None, - 'fn_label': None, - 'fn_parent': 'author-notes', - 'fn_text': 'Não há conflito de interesse entre os autores do artigo.', - 'fn_type': 'coi-statement', - 'fn_bold': None + "fn_bold": None, + "fn_id": None, + "fn_label": None, + "fn_parent": "author-notes", + "fn_text": "Todos os autores tiveram contribuição igualitária na " + "criação do artigo.", + "fn_type": "equal", + 'fn_title': None, }, + ], + "parent": "article", + "parent_article_type": "research-article", + "parent_id": None, + "parent_lang": "pt", + }, + { + "corresp": "Correspondence: John Doe, Example Institution, 123 Example " + "Street, Example City, Country.Email: johndoe@example.com", + "corresp_label": "Correspondence", + "corresp_title": None, + "corresp_bold": None, + "fns": [ { - 'fn_id': None, - 'fn_label': None, - 'fn_parent': 'author-notes', - 'fn_text': 'Todos os autores tiveram contribuição igualitária na criação do artigo.', - 'fn_type': 'equal', - 'fn_bold': None + "fn_bold": None, + "fn_id": None, + "fn_label": "2", + "fn_parent": "author-notes", + "fn_text": "2The authors declare there is no conflict of interest.", + "fn_type": "conflict", + 'fn_title': None, } - ] + ], + "parent": "sub-article", + "parent_article_type": "translation", + "parent_id": "TRen", + "parent_lang": "en", } + ] + self.assertEqual(len(obtained), 3) for i, item in enumerate(obtained): with self.subTest(i): self.assertDictEqual(item, expected[i]) From 60968c78b3c7a72da2c12638b5749bca73f252d6 Mon Sep 17 00:00:00 2001 From: Luciano Rossi Date: Sun, 15 Sep 2024 19:12:30 -0300 Subject: [PATCH 03/13] =?UTF-8?q?Adiciona=20valida=C3=A7=C3=A3o=20para=20'?= =?UTF-8?q?label',=20'title'=20e=20'bold'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packtools/sps/validation/footnotes.py | 237 +++++++++++++++++++------- 1 file changed, 171 insertions(+), 66 deletions(-) diff --git a/packtools/sps/validation/footnotes.py b/packtools/sps/validation/footnotes.py index f1f674c82..ed49a0c74 100644 --- a/packtools/sps/validation/footnotes.py +++ b/packtools/sps/validation/footnotes.py @@ -1,19 +1,20 @@ -from packtools.sps.models.footnotes import ArticleFootnotes +from packtools.sps.models.v2.notes import ArticleNotes from packtools.sps.models.article_and_subarticles import ArticleAndSubArticles from packtools.sps.validation.utils import format_response from packtools.sps.validation.exceptions import ValidationFootnotes class FootnoteValidation: - def __init__(self, xmltree): - self.xmltree = xmltree + def __init__(self, xml_tree, fns_dict): + self.xml_tree = xml_tree + self.fns_dict = fns_dict @property def dtd_version(self): - article = ArticleAndSubArticles(self.xmltree) + article = ArticleAndSubArticles(self.xml_tree) return article.main_dtd_version - def fn_validation(self): + def coi_statement_vs_conflict_by_dtd_validation(self, error_level="ERROR"): """ Checks if fn-type is coi-statement for dtd-version >= 1.3 @@ -80,67 +81,171 @@ def fn_validation(self): if not dtd: return - fns = ArticleFootnotes(self.xmltree) - for fn in fns.article_footnotes: + for fn in self.fns_dict.get("fns"): fn_type = fn.get("fn_type") - parent = fn.get("parent") - parent_id = fn.get("parent_id") - parent_article_type = fn.get("parent_article_type") - parent_lang = fn.get("parent_lang") - fn_parent = fn.get("fn_parent") - if dtd >= 1.3 and fn_type == "conflict": - yield self._generate_response(fn, parent, parent_id, parent_article_type, parent_lang, fn_parent, "coi-statement", "conflict") + yield format_response( + title="Footnotes validation", + parent=self.fns_dict.get("parent"), + parent_id=self.fns_dict.get("parent_id"), + parent_article_type=self.fns_dict.get("parent_article_type"), + parent_lang=self.fns_dict.get("parent_lang"), + item=fn.get("fn_parent"), + sub_item="fn", + validation_type="match", + is_valid=False, + expected='', + obtained='', + advice="replace conflict with coi-statement", + data=self.fns_dict, + error_level=error_level + ) elif dtd < 1.3 and fn_type == "coi-statement": - yield self._generate_response(fn, parent, parent_id, parent_article_type, parent_lang, fn_parent, "conflict", "coi-statement") - - def _generate_response(self, fn, parent, parent_id, parent_article_type, parent_lang, fn_parent, expected, obtained): - """ - Helper method to generate the response dictionary for validation. - - Params - ------ - fn : dict - The footnote dictionary. - - parent : str - The parent element. - - parent_id : str or None - The parent ID if available. - - parent_article_type : str - The type of the parent article. - - parent_lang : str - The language of the parent article. - - fn_parent : str - The footnote parent element. - - expected : str - The expected value. - - obtained : str - The obtained value. - - Returns - ------- - dict - The formatted response dictionary. - """ - return format_response( - title="Footnotes validation", - parent=parent, - parent_id=parent_id, - parent_article_type=parent_article_type, - parent_lang=parent_lang, - item=fn_parent, - sub_item="fn", - validation_type="match", - is_valid=False, - expected=f'', - obtained=f'', - advice=f"replace {obtained} with {expected}", - data=fn - ) + yield format_response( + title="Footnotes validation", + parent=self.fns_dict.get("parent"), + parent_id=self.fns_dict.get("parent_id"), + parent_article_type=self.fns_dict.get("parent_article_type"), + parent_lang=self.fns_dict.get("parent_lang"), + item=fn.get("fn_parent"), + sub_item="fn", + validation_type="match", + is_valid=False, + expected='', + obtained='', + advice="replace coi-statement with conflict", + data=self.fns_dict, + error_level=error_level + ) + + def missing_corresp_label_validation(self, error_level="WARNING"): + if bool(self.fns_dict.get("corresp")) and not bool(self.fns_dict.get("corresp_label")): + yield format_response( + title="Missing corresp label validation", + parent=self.fns_dict.get("parent"), + parent_id=self.fns_dict.get("parent_id"), + parent_article_type=self.fns_dict.get("parent_article_type"), + parent_lang=self.fns_dict.get("parent_lang"), + item="corresp", + sub_item="label", + validation_type="exist", + is_valid=False, + expected="