Skip to content
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

Modifica e acrescenta a validação de existência dos resumos condicionando ao article-type #729

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -81,27 +81,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