|
1 |
| -from ..models.supplementary_material import ArticleSupplementaryMaterials |
2 |
| -from ..validation.utils import format_response |
| 1 | +from lxml import etree |
| 2 | +from langdetect import detect |
| 3 | +from packtools.sps.models.supplementary_material import XmlSupplementaryMaterials |
| 4 | +from packtools.sps.models.media import XmlMedias |
| 5 | +from packtools.sps.models.graphic import Graphic, XmlGraphic |
| 6 | +from packtools.sps.validation.graphic import GraphicValidation |
| 7 | +from packtools.sps.validation.media import MediaValidation |
| 8 | +from packtools.sps.validation.utils import build_response |
3 | 9 |
|
4 | 10 |
|
5 | 11 | class SupplementaryMaterialValidation:
|
6 |
| - def __init__(self, xmltree): |
7 |
| - self.xmltree = xmltree |
8 |
| - self.supplementary_materials = ArticleSupplementaryMaterials(xmltree).data() |
9 |
| - |
10 |
| - def validate_supplementary_material_existence(self, error_level="WARNING"): |
11 |
| - for supp in self.supplementary_materials: |
12 |
| - yield format_response( |
13 |
| - title="validation of <supplementary-material> elements", |
14 |
| - parent=supp.get("parent"), |
15 |
| - parent_id=supp.get("parent_id"), |
16 |
| - parent_article_type=supp.get("parent_article_type"), |
17 |
| - parent_lang=supp.get("parent_lang"), |
18 |
| - item="supplementary-material", |
19 |
| - sub_item=None, |
20 |
| - validation_type="exist", |
21 |
| - is_valid=True, |
22 |
| - expected=supp.get("supplementary_material_id"), |
23 |
| - obtained=supp.get("supplementary_material_id"), |
24 |
| - advice=None, |
25 |
| - data=supp, |
26 |
| - error_level="OK", |
| 12 | + def __init__(self, data, params): |
| 13 | + """ |
| 14 | + Inicializa a validação de um material suplementar. |
| 15 | + |
| 16 | + Args: |
| 17 | + supp (dict): Dados do material suplementar extraídos do modelo |
| 18 | + """ |
| 19 | + self.data = data |
| 20 | + self.params = params |
| 21 | + |
| 22 | + def validate(self): |
| 23 | + """ |
| 24 | + Executa todas as validações definidas. |
| 25 | + """ |
| 26 | + yield from MediaValidation(self.data, self.params).validate() |
| 27 | + yield from GraphicValidation(self.data, self.params).validate() |
| 28 | + yield self.validate_sec_type() |
| 29 | + yield self.validate_label() |
| 30 | + yield self.validate_not_in_app_group() |
| 31 | + |
| 32 | + def validate_sec_type(self): |
| 33 | + """ |
| 34 | + Verifica se <supplementary-material> está inserido em <sec>, caso esteja, valida @sec-type="supplementary-material" |
| 35 | + """ |
| 36 | + if self.data.get("parent_suppl_mat") == "sec": |
| 37 | + sec_type = self.data.get("sec_type") |
| 38 | + valid = sec_type == "supplementary-material" |
| 39 | + return build_response( |
| 40 | + title="@sec-type", |
| 41 | + parent=self.data, |
| 42 | + item="sec", |
| 43 | + sub_item="supplementary-material", |
| 44 | + is_valid=valid, |
| 45 | + validation_type="match", |
| 46 | + expected="<sec sec-type='supplementary-material'>", |
| 47 | + obtained=self.data.get("parent_tag"), |
| 48 | + advice=f'In <sec sec-type="{sec_type}"><supplementary-material> replace "{sec_type}" with "supplementary-material".', |
| 49 | + error_level=self.params["sec_type_error_level"], |
| 50 | + data=self.data, |
27 | 51 | )
|
28 |
| - else: |
29 |
| - yield format_response( |
30 |
| - title="validation of <supplementary-material> elements", |
31 |
| - parent="article", |
32 |
| - parent_id=None, |
33 |
| - parent_article_type=self.xmltree.get("article-type"), |
34 |
| - parent_lang=self.xmltree.get( |
35 |
| - "{http://www.w3.org/XML/1998/namespace}lang" |
36 |
| - ), |
37 |
| - item="supplementary-material", |
38 |
| - sub_item=None, |
39 |
| - validation_type="exist", |
40 |
| - is_valid=False, |
41 |
| - expected="<supplementary-material> element", |
42 |
| - obtained=None, |
43 |
| - advice="Consider adding a <supplementary-material> element to provide additional data or materials related to the article.", |
44 |
| - data=None, |
45 |
| - error_level=error_level, |
| 52 | + |
| 53 | + def validate_label(self): |
| 54 | + """ |
| 55 | + Verifica a presença obrigatória de <label> |
| 56 | + """ |
| 57 | + label = self.data.get("label") |
| 58 | + valid = bool(label) |
| 59 | + return build_response( |
| 60 | + title="label", |
| 61 | + parent=self.data, |
| 62 | + item="supplementary-material", |
| 63 | + sub_item="label", |
| 64 | + is_valid=valid, |
| 65 | + validation_type="exist", |
| 66 | + expected="<label> in <supplementary-material>", |
| 67 | + obtained=label, |
| 68 | + advice="Add label in <supplementary-material>: <supplementary-material><label>. Consult SPS documentation for more detail.", |
| 69 | + error_level=self.params["label_error_level"], |
| 70 | + data=self.data, |
| 71 | + ) |
| 72 | + |
| 73 | + def validate_not_in_app_group(self): |
| 74 | + """ |
| 75 | + Ensures that <supplementary-material> does not occur inside <app-group> and <app>. |
| 76 | + """ |
| 77 | + valid = self.data.get("parent_suppl_mat") not in self.params["parent_suppl_mat_expected"] |
| 78 | + return build_response( |
| 79 | + title="Prohibition of <supplementary-material> inside <app-group> and <app>", |
| 80 | + parent=self.data, |
| 81 | + item="supplementary-material", |
| 82 | + sub_item="parent", |
| 83 | + is_valid=valid, |
| 84 | + validation_type="forbidden", |
| 85 | + expected="Outside <app-group> and <app>", |
| 86 | + obtained=self.data.get("parent_tag"), |
| 87 | + advice="Do not use <supplementary-material> inside <app-group> or <app>.", |
| 88 | + error_level=self.params["app_group_error_level"], |
| 89 | + data=self.data, |
| 90 | + ) |
| 91 | + |
| 92 | + |
| 93 | +class XmlSupplementaryMaterialValidation: |
| 94 | + def __init__(self, xml_tree, params): |
| 95 | + self.article_supp = list(XmlSupplementaryMaterials(xml_tree).items) |
| 96 | + self.xml_tree = xml_tree |
| 97 | + self.params = params |
| 98 | + |
| 99 | + |
| 100 | + def validate_prohibited_inline(self): |
| 101 | + """ |
| 102 | + Ensures that <inline-supplementary-material> is not used. |
| 103 | + """ |
| 104 | + |
| 105 | + nodes = self.xml_tree.xpath(".//inline-supplementary-material") |
| 106 | + obtained = etree.tostring(nodes[0]) if nodes else "None" |
| 107 | + valid = not bool(nodes) |
| 108 | + |
| 109 | + return build_response( |
| 110 | + title="Prohibition of inline-supplementary-material", |
| 111 | + parent={}, |
| 112 | + item="inline-supplementary-material", |
| 113 | + sub_item=None, |
| 114 | + is_valid=valid, |
| 115 | + validation_type="forbidden", |
| 116 | + expected="No <inline-supplementary-material>", |
| 117 | + obtained=obtained, |
| 118 | + advice="The use of <inline-supplementary-material> is prohibited.", |
| 119 | + error_level=self.params["inline_error_level"], |
| 120 | + data={}, |
| 121 | + ) |
| 122 | + |
| 123 | + def validate_position(self): |
| 124 | + """ |
| 125 | + Verifies if the supplementary materials section is in the last position of <body> or inside <back>. |
| 126 | + """ |
| 127 | + sections = self.xml_tree.xpath('.//sec[@sec-type="supplementary-material"]') |
| 128 | + if not sections: |
| 129 | + return |
| 130 | + |
| 131 | + article_body = self.xml_tree.find("body") |
| 132 | + article_back = self.xml_tree.find("back") |
| 133 | + |
| 134 | + is_last_in_body = False |
| 135 | + is_in_back = False |
| 136 | + |
| 137 | + if article_body is not None: |
| 138 | + sections = article_body.findall("sec") |
| 139 | + if sections and sections[-1].get("sec-type") == "supplementary-material": |
| 140 | + is_last_in_body = True |
| 141 | + |
| 142 | + if article_back is not None: |
| 143 | + sections = article_back.findall("sec") |
| 144 | + is_in_back = any( |
| 145 | + sec.get("sec-type") == "supplementary-material" for sec in sections |
46 | 146 | )
|
| 147 | + |
| 148 | + valid = is_last_in_body or is_in_back |
| 149 | + |
| 150 | + if is_last_in_body: |
| 151 | + parent_tag = "body (last section)" |
| 152 | + elif is_in_back: |
| 153 | + parent_tag = "back" |
| 154 | + else: |
| 155 | + parent_tag = None |
| 156 | + |
| 157 | + return build_response( |
| 158 | + title="Position of supplementary materials", |
| 159 | + parent={}, |
| 160 | + item="supplementary-material", |
| 161 | + sub_item=None, |
| 162 | + is_valid=valid, |
| 163 | + validation_type="position", |
| 164 | + expected="Last section of <body> or inside <back>", |
| 165 | + obtained=parent_tag, |
| 166 | + advice="The supplementary materials section must be at the end of <body> or inside <back>.", |
| 167 | + error_level=self.params["position_error_level"], |
| 168 | + data={}, |
| 169 | + ) |
| 170 | + |
| 171 | + def validate(self): |
| 172 | + for supp in self.article_supp: |
| 173 | + yield from SupplementaryMaterialValidation( |
| 174 | + supp, self.params |
| 175 | + ).validate() |
| 176 | + |
| 177 | + yield self.validate_prohibited_inline() |
| 178 | + yield self.validate_position() |
0 commit comments