Skip to content

Commit

Permalink
Modifica e acrescenta a validação de existência dos resumos condicion…
Browse files Browse the repository at this point in the history
…ando ao article-type (#729)

* Modifica AbstractsValidationBase.validate_exists condicionando à presença de resumos de acordo com article-type e melhora a validação de abstract-type

* Adiciona regras para a validação dos tipos de resumos: padrão, graphical, key-points

* Corrige os testes

* Adiciona a validação de existência para os tipos de resumos: padrão, graphical, key-points
  • Loading branch information
robertatakenaka authored Dec 27, 2024
1 parent 54786fd commit d213b7a
Show file tree
Hide file tree
Showing 6 changed files with 407 additions and 191 deletions.
178 changes: 123 additions & 55 deletions packtools/sps/validation/article_abstract.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from packtools.sps.models.article_abstract import ArticleVisualAbstracts, ArticleHighlights, ArticleAbstract
from packtools.sps.models.article_abstract import (
ArticleVisualAbstracts,
ArticleHighlights,
ArticleAbstract,
)
from packtools.sps.validation.utils import format_response


Expand Down Expand Up @@ -32,7 +36,7 @@ def validate_unexpected_kwd(self, error_level="ERROR"):
validation_type="exist",
obtained=self.abstract.get("kwds"),
advice=f"Remove keywords (<kwd>) from <abstract abstract-type='{self.abstract.get('abstract_type')}'>",
error_level=error_level
error_level=error_level,
)

def validate_tag_title_in_abstract(self, error_level="ERROR"):
Expand All @@ -53,11 +57,20 @@ def validate_tag_title_in_abstract(self, error_level="ERROR"):
is_valid=False,
expected="title",
advice="Provide title",
error_level=error_level
error_level=error_level,
)

def _format_response(self, title, sub_item, is_valid, validation_type, expected=None, obtained=None, advice=None,
error_level='WARNING'):
def _format_response(
self,
title,
sub_item,
is_valid,
validation_type,
expected=None,
obtained=None,
advice=None,
error_level="WARNING",
):
"""
Formats the validation response.
Expand Down Expand Up @@ -88,7 +101,7 @@ def _format_response(self, title, sub_item, is_valid, validation_type, expected=
obtained=obtained,
advice=advice,
data=self.abstract,
error_level=error_level
error_level=error_level,
)


Expand All @@ -101,38 +114,62 @@ class AbstractsValidationBase:
abstracts (list): List of abstracts to be validated.
"""

def __init__(self, xml_tree, abstracts):
def __init__(self, xml_tree):
self.xml_tree = xml_tree
# this is a list of dictionaries with abstract data
self.abstracts = abstracts

def validate_exists(self, error_level="WARNING"):
"""
Validates if the article contains any abstracts.
Args:
error_level (str): Error level to be reported. Default is "WARNING".
Returns:
dict: Formatted validation response if no abstracts are found.
"""
if not self.abstracts:
return format_response(
title="Article abstracts",
parent="article",
parent_id=None,
parent_article_type=self.xml_tree.get("id"),
parent_lang=self.xml_tree.get("{http://www.w3.org/XML/1998/namespace}lang"),
item="abstract",
sub_item=None,
validation_type="exist",
is_valid=False,
expected="abstracts",
obtained=self.abstracts,
advice="article has no abstract",
data=None,
error_level=error_level
self.article_type = xml_tree.find(".").get("article-type")
self.lang = xml_tree.get("{http://www.w3.org/XML/1998/namespace}lang")

def validate_exists(
self,
article_type_requires,
article_type_unexpects,
article_type_neutral,
article_type_accepts,
):
data = self.abstracts
obtained = self.abstracts
error_level = "INFO"
is_valid = True

if self.article_type in article_type_requires:
expected = f"{self.abstract_title} is required"
if not self.abstracts:
is_valid = False
error_level = "CRITICAL"
advice = f"It is required that documents which article-type={self.article_type} have {self.abstract_title}. Check if article-type is correct."
elif self.article_type in article_type_unexpects:
expected = f"{self.abstract_title} is unexpected"
if self.abstracts:
is_valid = False
error_level = "CRITICAL"
advice = f"It is unexpected that documents which article-type={self.article_type} have {self.abstract_title}. Check if article-type is correct."
elif self.article_type in article_type_neutral:
expected = f"{self.abstract_title} is not required and not unexpected"
advice = None
elif self.article_type in article_type_accepts:
expected = f"{self.abstract_title} is acceptable"
advice = None
error_level = "INFO"
else:
raise ValueError(
f"Unable to identify if {self.abstract_title} is required or unexpected or neutral or acceptable"
)
return format_response(
title=self.abstract_title,
parent="article",
parent_id=None,
parent_article_type=self.article_type,
parent_lang=self.lang,
item=self.abstract_title,
sub_item=None,
validation_type="exist",
is_valid=is_valid,
expected=expected,
obtained=obtained,
advice=advice,
data=data,
error_level=error_level,
)


class HighlightValidation(AbstractValidationBase):
Expand All @@ -156,9 +193,9 @@ def validate_tag_list_in_abstract(self, error_level="ERROR"):
sub_item="list",
validation_type="exist",
is_valid=False,
obtained=self.abstract.get('list'),
obtained=self.abstract.get("list"),
advice="Remove <list> and add <p>",
error_level=error_level
error_level=error_level,
)

def validate_tag_p_in_abstract(self, error_level="ERROR"):
Expand All @@ -180,7 +217,7 @@ def validate_tag_p_in_abstract(self, error_level="ERROR"):
expected="p",
obtained=self.abstract.get("highlights"),
advice="Provide more than one p",
error_level=error_level
error_level=error_level,
)


Expand All @@ -191,11 +228,17 @@ class HighlightsValidation(AbstractsValidationBase):

def __init__(self, xml_tree):
# this is a list of dictionaries with highlight abstract data
super().__init__(xml_tree)
self.abstracts = list(ArticleHighlights(xml_tree).article_abstracts())
super().__init__(xml_tree, self.abstracts)

def validate(self, kwd_error_level="ERROR", title_error_level="ERROR", p_error_level="ERROR",
list_error_level="ERROR"):
self.abstract_title = "abstracts (key-points)"

def validate(
self,
kwd_error_level="ERROR",
title_error_level="ERROR",
p_error_level="ERROR",
list_error_level="ERROR",
):
"""
Runs the validation checks for keywords, title, paragraph, and list tags in highlights.
Expand Down Expand Up @@ -239,7 +282,7 @@ def validate_tag_graphic_in_abstract(self, error_level="ERROR"):
is_valid=False,
expected="graphic",
advice="Provide graphic",
error_level=error_level
error_level=error_level,
)


Expand All @@ -250,10 +293,16 @@ class VisualAbstractsValidation(AbstractsValidationBase):

def __init__(self, xml_tree):
# this is a list of dictionaries with visual abstract data
super().__init__(xml_tree)
self.abstracts = list(ArticleVisualAbstracts(xml_tree).article_abstracts())
super().__init__(xml_tree, self.abstracts)

def validate(self, kwd_error_level="ERROR", title_error_level="ERROR", graphic_error_level="ERROR"):
self.abstract_title = "abstracts (graphical)"

def validate(
self,
kwd_error_level="ERROR",
title_error_level="ERROR",
graphic_error_level="ERROR",
):
"""
Runs the validation checks for keywords, title, and graphic tags in visual abstracts.
Expand All @@ -272,6 +321,20 @@ def validate(self, kwd_error_level="ERROR", title_error_level="ERROR", graphic_e
yield validations.validate_tag_graphic_in_abstract(graphic_error_level)


class AbstractsValidation(AbstractsValidationBase):
"""
Standard abstracts validation
"""

def __init__(self, xml_tree):
# this is a list of dictionaries with highlight abstract data
super().__init__(xml_tree)
self.abstracts = list(
ArticleAbstract(xml_tree, selection="standard").get_abstracts()
)
self.abstract_title = "standard abstracts"


class ArticleAbstractsValidation:
"""
Class to validate various types of abstracts in an article.
Expand All @@ -282,9 +345,14 @@ class ArticleAbstractsValidation:

def __init__(self, xml_tree):
# this is a list of dictionaries with abstract data
self.abstracts = list(ArticleAbstract(xml_tree, selection="all").get_abstracts())
self.xml_tree = xml_tree
self.abstracts = list(
ArticleAbstract(xml_tree, selection="all").get_abstracts()
)

def validate_abstracts_type(self, error_level="ERROR", expected_abstract_type_list=None):
def validate_abstracts_type(
self, error_level="ERROR", expected_abstract_type_list=None
):
"""
Validates if the abstract types are within an expected list of types.
Expand All @@ -298,18 +366,18 @@ def validate_abstracts_type(self, error_level="ERROR", expected_abstract_type_li
for abstract in self.abstracts:
if abstract.get("abstract_type") not in (expected_abstract_type_list or []):
yield format_response(
title="abstract-type attribute",
title="@abstract-type",
parent=abstract.get("parent"),
parent_id=abstract.get("parent_id"),
parent_article_type=abstract.get("parent_article_type"),
parent_lang=abstract.get("parent_lang"),
item="abstract",
sub_item='@abstract-type',
sub_item="@abstract-type",
validation_type="value in list",
is_valid=False,
expected='<abstract abstract-type="key-points"> or <abstract abstract-type="graphical">',
obtained=f'<abstract abstract-type="{abstract.get("abstract_type")}">',
advice='Provide <abstract abstract-type="key-points"> or <abstract abstract-type="graphical">',
expected=expected_abstract_type_list,
obtained=abstract.get("abstract_type"),
advice=f"Use one of {expected_abstract_type_list} as abstract-type",
data=abstract,
error_level=error_level
error_level=error_level,
)
25 changes: 21 additions & 4 deletions packtools/sps/validation/xml_validations.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,27 +77,44 @@ def validate_abstracts(xmltree, params):
expected_abstract_type_list=abstract_rules["abstract_type_list"],
)

# FIXME
# yield from validator.validate_exists(
# error_level=abstract_rules["abstract_presence_error_level"],
# )
validator = AbstractsValidation(xmltree)
yield from validator.validate_exists(
article_type_requires=abstract_rules["article_type_requires"],
article_type_unexpects=abstract_rules["article_type_unexpects"],
article_type_neutral=abstract_rules["article_type_neutral"],
article_type_accepts=[]
)

highlight_rules = params["highlight_rules"]

validator = HighlightsValidation(xmltree)
yield from validator.validate(
kwd_error_level=highlight_rules["kwd_error_level"],
title_error_level=highlight_rules["title_error_level"],
p_error_level=highlight_rules["p_error_level"],
list_error_level=highlight_rules["list_error_level"],
)
yield validator.validate_exists(
article_type_requires=[],
article_type_unexpects=highlight_rules["article_type_unexpects"],
article_type_neutral=highlight_rules["article_type_neutral"],
article_type_accepts=highlight_rules["article_type_accepts"]
)

graphical_abstract_rules = params["graphical_abstract_rules"]

validator = VisualAbstractsValidation(xmltree)
yield from validator.validate(
kwd_error_level=graphical_abstract_rules["kwd_error_level"],
title_error_level=graphical_abstract_rules["title_error_level"],
graphic_error_level=graphical_abstract_rules["graphic_error_level"],
)
yield validator.validate_exists(
article_type_requires=[],
article_type_unexpects=graphical_abstract_rules["article_type_unexpects"],
article_type_neutral=graphical_abstract_rules["article_type_neutral"],
article_type_accepts=graphical_abstract_rules["article_type_accepts"]
)


def validate_article(xmltree, params):
Expand Down
25 changes: 25 additions & 0 deletions packtools/sps/validation_rules/abstract_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@
"key-points",
"graphical",
null
],
"article_type_requires": [
"case-report",
"research-article",
"review-article",
],
"article_type_unexpects": [
"addendum",
"article-commentary",
"book-review",
"brief-report",
"correction",
"editorial",
"letter",
"obituary",
"partial-retraction",
"product-review",
"rapid-communication",
"reply",
"retraction",
"other"
],
"article_type_neutral": [
"reviewer-report",
"data-article",
]
}
}
28 changes: 27 additions & 1 deletion packtools/sps/validation_rules/graphical_abstract_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@
"graphical_abstract_rules": {
"kwd_error_level": "CRITICAL",
"title_error_level": "WARNING",
"graphic_error_level": "CRITICAL"
"graphic_error_level": "CRITICAL",
"absence_error_level": "WARNING",
"article_type_accepts": [
"case-report",
"research-article",
"review-article",
],
"article_type_unexpects": [
"addendum",
"article-commentary",
"book-review",
"brief-report",
"correction",
"editorial",
"letter",
"obituary",
"partial-retraction",
"product-review",
"rapid-communication",
"reply",
"retraction",
"other"
],
"article_type_neutral": [
"reviewer-report",
"data-article",
]
}
}
Loading

0 comments on commit d213b7a

Please sign in to comment.