-
Notifications
You must be signed in to change notification settings - Fork 24
Corrige validação para SupplementaryMaterial e testes #947
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
Merged
robertatakenaka
merged 25 commits into
scieloorg:master
from
Rossi-Luciano:fix_supplementary_material_validation
Apr 16, 2025
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
27ba169
Corrige validação para SupplementaryMaterial
Rossi-Luciano c450579
Corrige testes para a validação de SupplementaryMaterial
Rossi-Luciano 263278a
Adiciona rules
Rossi-Luciano 4f10ea2
Remove 'xml_tree' como parâmetro da classe
Rossi-Luciano e27f676
Corrige as chamadas para as validações
Rossi-Luciano 56e1a44
Remove 'validate_position' de 'SupplementaryMaterialValidation'
Rossi-Luciano e914db8
Adiciona 'validate_prohibited_inline' e 'validate_position' em 'Artic…
Rossi-Luciano bd7e054
Corrige as chamadas para as validações
Rossi-Luciano 05a46fc
Adapta os testes
Rossi-Luciano c8c2fee
Corrige o nome da classe de validação
Rossi-Luciano e8a94bd
Adapta os testes
Rossi-Luciano b522623
Merge remote-tracking branch 'origin/master' into fix_supplementary_m…
Rossi-Luciano 3b28f96
Evita erro ao atualizar dicionário com valores None em long_desc e al…
Rossi-Luciano 4b871c8
Inicializa atributos media e graphic como None para evitar referência…
Rossi-Luciano c9fc9af
Adiciona 'id' em 'data'
Rossi-Luciano 18e9cb1
Inclui busca por <supplementary-material> em front, body, back e sub-…
Rossi-Luciano 483b405
Complementa 'rules'
Rossi-Luciano 068f4de
Adiciona teste
Rossi-Luciano 62a868d
Remove dependência direta do nó XML em SupplementaryMaterialValidation
Rossi-Luciano 9a1b156
Torna lista de elementos proibidos configurável na validação de <supp…
Rossi-Luciano 57a93ad
Ignora validação de posição quando não há seção supplementary-material
Rossi-Luciano 9608bc8
Remove xml_tree da inicialização de SupplementaryMaterialValidation
Rossi-Luciano 39e2f5e
Restringe a busca por <supplementary-material> às seções <front>, <bo…
Rossi-Luciano 1b426e2
Simplifica a busca por seções de material suplementar
Rossi-Luciano cc0e20c
Adiciona 'front-stub' ao padrão de busca.
Rossi-Luciano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,178 @@ | ||
from ..models.supplementary_material import ArticleSupplementaryMaterials | ||
from ..validation.utils import format_response | ||
from lxml import etree | ||
from langdetect import detect | ||
from packtools.sps.models.supplementary_material import XmlSupplementaryMaterials | ||
from packtools.sps.models.media import XmlMedias | ||
from packtools.sps.models.graphic import Graphic, XmlGraphic | ||
from packtools.sps.validation.graphic import GraphicValidation | ||
from packtools.sps.validation.media import MediaValidation | ||
from packtools.sps.validation.utils import build_response | ||
|
||
|
||
class SupplementaryMaterialValidation: | ||
def __init__(self, xmltree): | ||
self.xmltree = xmltree | ||
self.supplementary_materials = ArticleSupplementaryMaterials(xmltree).data() | ||
|
||
def validate_supplementary_material_existence(self, error_level="WARNING"): | ||
for supp in self.supplementary_materials: | ||
yield format_response( | ||
title="validation of <supplementary-material> elements", | ||
parent=supp.get("parent"), | ||
parent_id=supp.get("parent_id"), | ||
parent_article_type=supp.get("parent_article_type"), | ||
parent_lang=supp.get("parent_lang"), | ||
item="supplementary-material", | ||
sub_item=None, | ||
validation_type="exist", | ||
is_valid=True, | ||
expected=supp.get("supplementary_material_id"), | ||
obtained=supp.get("supplementary_material_id"), | ||
advice=None, | ||
data=supp, | ||
error_level="OK", | ||
def __init__(self, data, params): | ||
""" | ||
Inicializa a validação de um material suplementar. | ||
|
||
Args: | ||
supp (dict): Dados do material suplementar extraídos do modelo | ||
""" | ||
self.data = data | ||
self.params = params | ||
|
||
def validate(self): | ||
""" | ||
Executa todas as validações definidas. | ||
""" | ||
yield from MediaValidation(self.data, self.params).validate() | ||
yield from GraphicValidation(self.data, self.params).validate() | ||
yield self.validate_sec_type() | ||
yield self.validate_label() | ||
yield self.validate_not_in_app_group() | ||
|
||
def validate_sec_type(self): | ||
""" | ||
Verifica se <supplementary-material> está inserido em <sec>, caso esteja, valida @sec-type="supplementary-material" | ||
""" | ||
if self.data.get("parent_suppl_mat") == "sec": | ||
sec_type = self.data.get("sec_type") | ||
valid = sec_type == "supplementary-material" | ||
return build_response( | ||
title="@sec-type", | ||
parent=self.data, | ||
item="sec", | ||
sub_item="supplementary-material", | ||
is_valid=valid, | ||
validation_type="match", | ||
expected="<sec sec-type='supplementary-material'>", | ||
obtained=self.data.get("parent_tag"), | ||
advice=f'In <sec sec-type="{sec_type}"><supplementary-material> replace "{sec_type}" with "supplementary-material".', | ||
error_level=self.params["sec_type_error_level"], | ||
data=self.data, | ||
) | ||
else: | ||
yield format_response( | ||
title="validation of <supplementary-material> elements", | ||
parent="article", | ||
parent_id=None, | ||
parent_article_type=self.xmltree.get("article-type"), | ||
parent_lang=self.xmltree.get( | ||
"{http://www.w3.org/XML/1998/namespace}lang" | ||
), | ||
item="supplementary-material", | ||
sub_item=None, | ||
validation_type="exist", | ||
is_valid=False, | ||
expected="<supplementary-material> element", | ||
obtained=None, | ||
advice="Consider adding a <supplementary-material> element to provide additional data or materials related to the article.", | ||
data=None, | ||
error_level=error_level, | ||
|
||
def validate_label(self): | ||
""" | ||
Verifica a presença obrigatória de <label> | ||
""" | ||
label = self.data.get("label") | ||
valid = bool(label) | ||
return build_response( | ||
title="label", | ||
parent=self.data, | ||
item="supplementary-material", | ||
sub_item="label", | ||
is_valid=valid, | ||
validation_type="exist", | ||
expected="<label> in <supplementary-material>", | ||
obtained=label, | ||
advice="Add label in <supplementary-material>: <supplementary-material><label>. Consult SPS documentation for more detail.", | ||
error_level=self.params["label_error_level"], | ||
data=self.data, | ||
) | ||
|
||
def validate_not_in_app_group(self): | ||
""" | ||
Ensures that <supplementary-material> does not occur inside <app-group> and <app>. | ||
""" | ||
valid = self.data.get("parent_suppl_mat") not in self.params["parent_suppl_mat_expected"] | ||
return build_response( | ||
title="Prohibition of <supplementary-material> inside <app-group> and <app>", | ||
parent=self.data, | ||
item="supplementary-material", | ||
sub_item="parent", | ||
is_valid=valid, | ||
validation_type="forbidden", | ||
expected="Outside <app-group> and <app>", | ||
obtained=self.data.get("parent_tag"), | ||
advice="Do not use <supplementary-material> inside <app-group> or <app>.", | ||
error_level=self.params["app_group_error_level"], | ||
data=self.data, | ||
) | ||
|
||
|
||
class XmlSupplementaryMaterialValidation: | ||
def __init__(self, xml_tree, params): | ||
self.article_supp = list(XmlSupplementaryMaterials(xml_tree).items) | ||
self.xml_tree = xml_tree | ||
self.params = params | ||
|
||
|
||
def validate_prohibited_inline(self): | ||
""" | ||
Ensures that <inline-supplementary-material> is not used. | ||
""" | ||
|
||
nodes = self.xml_tree.xpath(".//inline-supplementary-material") | ||
obtained = etree.tostring(nodes[0]) if nodes else "None" | ||
valid = not bool(nodes) | ||
|
||
return build_response( | ||
title="Prohibition of inline-supplementary-material", | ||
parent={}, | ||
item="inline-supplementary-material", | ||
sub_item=None, | ||
is_valid=valid, | ||
validation_type="forbidden", | ||
expected="No <inline-supplementary-material>", | ||
obtained=obtained, | ||
advice="The use of <inline-supplementary-material> is prohibited.", | ||
error_level=self.params["inline_error_level"], | ||
data={}, | ||
) | ||
|
||
def validate_position(self): | ||
""" | ||
Verifies if the supplementary materials section is in the last position of <body> or inside <back>. | ||
""" | ||
sections = self.xml_tree.xpath('.//sec[@sec-type="supplementary-material"]') | ||
if not sections: | ||
return | ||
|
||
article_body = self.xml_tree.find("body") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Rossi-Luciano acho que primeiro tem que saber se há pelo menos 1 material suplementar antes de seguir a validação There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, @robertatakenaka |
||
article_back = self.xml_tree.find("back") | ||
|
||
is_last_in_body = False | ||
is_in_back = False | ||
|
||
if article_body is not None: | ||
sections = article_body.findall("sec") | ||
if sections and sections[-1].get("sec-type") == "supplementary-material": | ||
is_last_in_body = True | ||
|
||
if article_back is not None: | ||
sections = article_back.findall("sec") | ||
is_in_back = any( | ||
sec.get("sec-type") == "supplementary-material" for sec in sections | ||
) | ||
|
||
valid = is_last_in_body or is_in_back | ||
|
||
if is_last_in_body: | ||
parent_tag = "body (last section)" | ||
elif is_in_back: | ||
parent_tag = "back" | ||
else: | ||
parent_tag = None | ||
|
||
return build_response( | ||
title="Position of supplementary materials", | ||
parent={}, | ||
item="supplementary-material", | ||
sub_item=None, | ||
is_valid=valid, | ||
validation_type="position", | ||
expected="Last section of <body> or inside <back>", | ||
obtained=parent_tag, | ||
advice="The supplementary materials section must be at the end of <body> or inside <back>.", | ||
error_level=self.params["position_error_level"], | ||
data={}, | ||
) | ||
|
||
def validate(self): | ||
for supp in self.article_supp: | ||
yield from SupplementaryMaterialValidation( | ||
supp, self.params | ||
).validate() | ||
|
||
yield self.validate_prohibited_inline() | ||
yield self.validate_position() |
16 changes: 16 additions & 0 deletions
16
packtools/sps/validation_rules/supplementary_material_rules.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"supplementary_material": { | ||
"sec_type_error_level": "CRITICAL", | ||
"position_error_level": "CRITICAL", | ||
"label_error_level": "CRITICAL", | ||
"app_group_error_level": "CRITICAL", | ||
"inline_error_level": "CRITICAL", | ||
"mime_correspondence": { | ||
"pdf": "application", | ||
"zip": "application", | ||
"mp4": "video", | ||
"mp3": "audio" | ||
}, | ||
"parent_suppl_mat_expected": ["app-group", "app"] | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Rossi-Luciano este método pode ser de uma classe que seja instanciada com xml_tree
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, @robertatakenaka