Skip to content

Commit

Permalink
Change validation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
insolor committed Oct 2, 2023
1 parent 6458ed7 commit d237f93
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 26 deletions.
10 changes: 7 additions & 3 deletions df_translation_toolkit/convert/objects_po_to_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from df_translation_toolkit.utils.fix_translated_strings import cleanup_string, fix_spaces
from df_translation_toolkit.utils.maybe_open import maybe_open
from df_translation_toolkit.validation.validate_objects import validate_tag
from df_translation_toolkit.validation.validation_models import ValidationException, ValidationProblem


def get_translations_from_tag_parts(original_parts: list[str], translation_parts: list[str]):
Expand All @@ -35,14 +36,17 @@ def get_translations_from_tag_parts(original_parts: list[str], translation_parts


def get_translations_from_tag(original_tag: str, translation_tag: str):
validate_tag(original_tag, translation_tag)
validation_problems = list(validate_tag(original_tag, translation_tag))
if ValidationProblem.contains_errors(validation_problems):
raise ValidationException(validation_problems)

original_parts = split_tag(original_tag)
translation_parts = split_tag(translation_tag)
original_parts = original_parts[1:]
translation_parts = translation_parts[1:]

yield from get_translations_from_tag_parts(original_parts, translation_parts)
raise ValidationException(validation_problems) # pass warnings


def prepare_dictionary(dictionary: Iterable[tuple[str, str]], errors_file: TextIO) -> Iterable[tuple[str, str]]:
Expand All @@ -52,8 +56,8 @@ def prepare_dictionary(dictionary: Iterable[tuple[str, str]], errors_file: TextI
for original_string, translation in get_translations_from_tag(original_string_tag, translation_tag):
translation = fix_spaces(original_string, translation)
yield original_string, cleanup_string(translation)
except AssertionError as ex:
error_text = f"Error: {ex}\nProblematic tag pair: {original_string_tag!r}, {translation_tag!r}"
except ValidationException as ex:
error_text = f"Problematic tag pair: {original_string_tag!r}, {translation_tag!r}\nProblems:\n{ex}"
logger.error("\n" + error_text)
if errors_file:
print(error_text, end="\n\n", file=errors_file)
Expand Down
64 changes: 42 additions & 22 deletions df_translation_toolkit/validation/validate_objects.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
from typing import Iterator

from df_translation_toolkit.parse.parse_raws import all_caps, split_tag
from df_translation_toolkit.validation.validation_models import ProblemSeverity, ValidationProblem


def validate_brackets(tag: str) -> bool:
return tag.startswith("[") and tag.endswith("]") and tag.count("[") == 1 and tag.count("]") == 1


def validate_tag(original_tag: str, translation_tag: str):
assert len(translation_tag) > 2, "Too short or empty translation"
assert validate_brackets(translation_tag.strip()), "Wrong tag translation format (fix square brackets)"
assert translation_tag.strip() == translation_tag, "Extra spaces at the beginning or at the end of the translation"
def validate_tag(original_tag: str, translation_tag: str) -> Iterator[ValidationProblem]:
if len(translation_tag) <= 2:
yield ValidationProblem("Too short or empty translation")
return

if not translation_tag.strip() == translation_tag:
yield ValidationProblem("Extra spaces at the beginning or at the end of the translation")
translation_tag = translation_tag.strip()
# No return to check issues with brackets after stripping spaces

if not validate_brackets(translation_tag):
yield ValidationProblem("Wrong tag translation format (fix square brackets)")
return

original_parts = split_tag(original_tag)
translation_parts = split_tag(translation_tag)
assert len(original_parts) == len(translation_parts), "Tag parts count mismatch"
validate_tag_parts(original_parts, translation_parts)

if len(original_parts) != len(translation_parts):
yield ValidationProblem("Tag parts count mismatch")
return

yield from validate_tag_parts(original_parts, translation_parts)


def validate_tag_parts(original_parts: list[str], translation_parts: list[str]):
def validate_tag_parts(original_parts: list[str], translation_parts: list[str]) -> Iterator[ValidationProblem]:
for original, translation in zip(original_parts, translation_parts):
if all_caps(original) or original.isdecimal():
valid = not (original != translation and original == translation.strip())
assert valid, "Don't add extra spaces at the beginning or at the end of a tag part"
if not valid:
yield ValidationProblem("Don't add extra spaces at the beginning or at the end of a tag part")

valid = original == translation or original in ("STP", "NP", "SINGULAR", "PLURAL")
assert valid, f"Part {original!r} should not be translated"
if not valid:
yield ValidationProblem(f"Part {original!r} should not be translated")

valid = original not in {"SINGULAR", "PLURAL"} or translation in {"SINGULAR", "PLURAL"}
assert valid, "SINGULAR can be changed only to PLURAL, and PLURAL can be changed only to SINGULAR"

if original == "STP":
# TODO: this should be a warning, not error
# assert translation != "STP", (
# "Replace STP with a translation of the previous word in the tag in a plural form, "
# "otherwise, the game will create a plural form with adding -s at the end. "
# "If the translation with adding -s at the end is valid for your language, "
# "just ignore this message."
# )
pass
elif original:
assert translation, "Translation should not be empty"
if not valid:
yield ValidationProblem(
"SINGULAR can be changed only to PLURAL, and PLURAL can be changed only to SINGULAR"
)

if original == "STP" and translation == "STP":
yield ValidationProblem(
"Replace STP with a translation of the previous word in the tag in a plural form, "
"otherwise, the game will create a plural form with adding -s at the end. "
"If the translation with adding -s at the end is valid for your language, "
"just ignore this message.",
ProblemSeverity.WARNING,
)
elif original and not translation:
yield ValidationProblem("Translation should not be empty")
32 changes: 32 additions & 0 deletions df_translation_toolkit/validation/validation_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations

from enum import Enum, auto
from typing import NamedTuple


class ProblemSeverity(Enum):
ERROR = auto()
WARNING = auto()

def __str__(self):
return self.name.title()


class ValidationProblem(NamedTuple):
text: str
severity: ProblemSeverity = ProblemSeverity.ERROR

def __str__(self):
return f"{self.severity}: {self.text}"

@staticmethod
def contains_errors(problems: list[ValidationProblem]) -> bool:
return any(problem.severity is ProblemSeverity.ERROR for problem in problems)


class ValidationException(Exception):
def __init__(self, problems: list[ValidationProblem]):
self.problems = problems

def __str__(self):
return "\n".join(str(error) for error in self.problems)
2 changes: 1 addition & 1 deletion tests/test_validate_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
("[text", False),
("text]", False),
("[text[]", False),
]
],
)
def test_validate_brackets(text, expected):
assert validate_brackets(text) == expected

0 comments on commit d237f93

Please sign in to comment.