Commit ab138d04 authored by Michal Čihař's avatar Michal Čihař

Include check severity

This adds a visual clue how important the check might be.

Fixes #475
Signed-off-by: default avatarMichal Čihař <michal@cihar.com>
parent 1937692b
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<div class="col-md-4"> <div class="col-md-4">
<div class="list-group"> <div class="list-group">
{% for c in checks %} {% for c in checks %}
<a class="list-group-item" href="{{ review_url }}?type={{ c.0 }}"><span class="badge">{{ c.2 }}</span>{{ c.1 }}</a> <a class="list-group-item list-group-item-{{ c.3 }}" href="{{ review_url }}?type={{ c.0 }}"><span class="badge">{{ c.2 }}</span>{{ c.1 }}</a>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
<div class="panel-body"> <div class="panel-body">
<div class="list-group"> <div class="list-group">
{% for c in object.get_translation_checks %} {% for c in object.get_translation_checks %}
<a class="list-group-item" href="{{ object.get_translate_url }}?type={{ c.0 }}"><span class="badge">{{ c.2 }}</span>{{ c.1 }}</a> <a class="list-group-item list-group-item-{{ c.3 }}" href="{{ object.get_translate_url }}?type={{ c.0 }}"><span class="badge">{{ c.2 }}</span>{{ c.1 }}</a>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
......
...@@ -32,6 +32,7 @@ class Check(object): ...@@ -32,6 +32,7 @@ class Check(object):
target = False target = False
source = False source = False
ignore_untranslated = True ignore_untranslated = True
severity = 'info'
def __init__(self): def __init__(self):
id_dash = self.check_id.replace('_', '-') id_dash = self.check_id.replace('_', '-')
......
...@@ -29,6 +29,7 @@ class BeginNewlineCheck(TargetCheck): ...@@ -29,6 +29,7 @@ class BeginNewlineCheck(TargetCheck):
check_id = 'begin_newline' check_id = 'begin_newline'
name = _('Starting newline') name = _('Starting newline')
description = _('Source and translation do not both start with a newline') description = _('Source and translation do not both start with a newline')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
return self.check_chars(source, target, 0, ['\n']) return self.check_chars(source, target, 0, ['\n'])
...@@ -41,6 +42,7 @@ class EndNewlineCheck(TargetCheck): ...@@ -41,6 +42,7 @@ class EndNewlineCheck(TargetCheck):
check_id = 'end_newline' check_id = 'end_newline'
name = _('Trailing newline') name = _('Trailing newline')
description = _('Source and translation do not both end with a newline') description = _('Source and translation do not both end with a newline')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
return self.check_chars(source, target, -1, ['\n']) return self.check_chars(source, target, -1, ['\n'])
...@@ -55,6 +57,7 @@ class BeginSpaceCheck(TargetCheck): ...@@ -55,6 +57,7 @@ class BeginSpaceCheck(TargetCheck):
description = _( description = _(
'Source and translation do not both start with same number of spaces' 'Source and translation do not both start with same number of spaces'
) )
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
# One letter things are usually decimal/thousand separators # One letter things are usually decimal/thousand separators
...@@ -83,6 +86,7 @@ class EndSpaceCheck(TargetCheck): ...@@ -83,6 +86,7 @@ class EndSpaceCheck(TargetCheck):
check_id = 'end_space' check_id = 'end_space'
name = _('Trailing space') name = _('Trailing space')
description = _('Source and translation do not both end with a space') description = _('Source and translation do not both end with a space')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
# One letter things are usually decimal/thousand separators # One letter things are usually decimal/thousand separators
...@@ -116,6 +120,7 @@ class EndStopCheck(TargetCheck): ...@@ -116,6 +120,7 @@ class EndStopCheck(TargetCheck):
check_id = 'end_stop' check_id = 'end_stop'
name = _('Trailing stop') name = _('Trailing stop')
description = _('Source and translation do not both end with a full stop') description = _('Source and translation do not both end with a full stop')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
if len(source) <= 4: if len(source) <= 4:
...@@ -158,6 +163,7 @@ class EndColonCheck(TargetCheck): ...@@ -158,6 +163,7 @@ class EndColonCheck(TargetCheck):
'or colon is not correctly spaced' 'or colon is not correctly spaced'
) )
colon_fr = (' :', '&nbsp;:', u' :') colon_fr = (' :', '&nbsp;:', u' :')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
if not source or not target: if not source or not target:
...@@ -207,6 +213,7 @@ class EndQuestionCheck(TargetCheck): ...@@ -207,6 +213,7 @@ class EndQuestionCheck(TargetCheck):
) )
question_fr = (' ?', ' ? ', '&nbsp;? ', '&nbsp;?', u' ?', u' ? ') question_fr = (' ?', ' ? ', '&nbsp;? ', '&nbsp;?', u' ?', u' ? ')
question_el = ('?', ';', u';') question_el = ('?', ';', u';')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
if not source or not target: if not source or not target:
...@@ -249,6 +256,7 @@ class EndExclamationCheck(TargetCheck): ...@@ -249,6 +256,7 @@ class EndExclamationCheck(TargetCheck):
'or it is not correctly spaced' 'or it is not correctly spaced'
) )
exclamation_fr = (' !', '&nbsp;!', u' !', ' ! ', '&nbsp;! ', u' ! ') exclamation_fr = (' !', '&nbsp;!', u' !', ' ! ', '&nbsp;! ', u' ! ')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
if not source or not target: if not source or not target:
...@@ -281,6 +289,7 @@ class EndEllipsisCheck(TargetCheck): ...@@ -281,6 +289,7 @@ class EndEllipsisCheck(TargetCheck):
check_id = 'end_ellipsis' check_id = 'end_ellipsis'
name = _('Trailing ellipsis') name = _('Trailing ellipsis')
description = _('Source and translation do not both end with an ellipsis') description = _('Source and translation do not both end with an ellipsis')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
if not target: if not target:
...@@ -299,6 +308,7 @@ class NewlineCountingCheck(CountingCheck): ...@@ -299,6 +308,7 @@ class NewlineCountingCheck(CountingCheck):
check_id = 'escaped_newline' check_id = 'escaped_newline'
name = _('Mismatched \\n') name = _('Mismatched \\n')
description = _('Number of \\n in translation does not match source') description = _('Number of \\n in translation does not match source')
severity = 'warning'
class ZeroWidthSpaceCheck(TargetCheck): class ZeroWidthSpaceCheck(TargetCheck):
...@@ -308,6 +318,7 @@ class ZeroWidthSpaceCheck(TargetCheck): ...@@ -308,6 +318,7 @@ class ZeroWidthSpaceCheck(TargetCheck):
check_id = 'zero-width-space' check_id = 'zero-width-space'
name = _('Zero-width space') name = _('Zero-width space')
description = _('Translation contains extra zero-width space character') description = _('Translation contains extra zero-width space character')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
if self.is_language(unit, ('km', )): if self.is_language(unit, ('km', )):
......
...@@ -29,6 +29,7 @@ class PluralsCheck(TargetCheck): ...@@ -29,6 +29,7 @@ class PluralsCheck(TargetCheck):
check_id = 'plurals' check_id = 'plurals'
name = _('Missing plurals') name = _('Missing plurals')
description = _('Some plural forms are not translated') description = _('Some plural forms are not translated')
severity = 'danger'
def check_target_unit(self, sources, targets, unit): def check_target_unit(self, sources, targets, unit):
# Is this plural? # Is this plural?
...@@ -57,6 +58,7 @@ class ConsistencyCheck(TargetCheck): ...@@ -57,6 +58,7 @@ class ConsistencyCheck(TargetCheck):
'This message has more than one translation in this project' 'This message has more than one translation in this project'
) )
ignore_untranslated = False ignore_untranslated = False
severity = 'warning'
def check_target_unit(self, sources, targets, unit): def check_target_unit(self, sources, targets, unit):
from weblate.trans.models import Unit from weblate.trans.models import Unit
......
...@@ -105,6 +105,7 @@ class BaseFormatCheck(TargetCheck): ...@@ -105,6 +105,7 @@ class BaseFormatCheck(TargetCheck):
''' '''
flag = None flag = None
regexp = None regexp = None
severity = 'danger'
def check_target_unit(self, sources, targets, unit): def check_target_unit(self, sources, targets, unit):
''' '''
......
...@@ -46,6 +46,7 @@ class BBCodeCheck(TargetCheck): ...@@ -46,6 +46,7 @@ class BBCodeCheck(TargetCheck):
check_id = 'bbcode' check_id = 'bbcode'
name = _('Mismatched BBcode') name = _('Mismatched BBcode')
description = _('BBcode in translation does not match source') description = _('BBcode in translation does not match source')
severity = 'warning'
def check_single(self, source, target, unit, cache_slot): def check_single(self, source, target, unit, cache_slot):
# Try geting source parsing from cache # Try geting source parsing from cache
...@@ -75,6 +76,7 @@ class XMLTagsCheck(TargetCheck): ...@@ -75,6 +76,7 @@ class XMLTagsCheck(TargetCheck):
check_id = 'xml-tags' check_id = 'xml-tags'
name = _('XML tags mismatch') name = _('XML tags mismatch')
description = _('XML tags in translation do not match source') description = _('XML tags in translation do not match source')
severity = 'warning'
def parse_xml(self, text): def parse_xml(self, text):
''' '''
......
...@@ -906,6 +906,7 @@ class SameCheck(TargetCheck): ...@@ -906,6 +906,7 @@ class SameCheck(TargetCheck):
check_id = 'same' check_id = 'same'
name = _('Not translated') name = _('Not translated')
description = _('Source and translated strings are same') description = _('Source and translated strings are same')
severity = 'warning'
def should_ignore(self, source, unit, cache_slot): def should_ignore(self, source, unit, cache_slot):
''' '''
......
...@@ -35,6 +35,7 @@ class OptionalPluralCheck(SourceCheck): ...@@ -35,6 +35,7 @@ class OptionalPluralCheck(SourceCheck):
description = _( description = _(
'The string is optionally used as plural, but not using plural forms' 'The string is optionally used as plural, but not using plural forms'
) )
severity = 'info'
def check_source(self, source, unit): def check_source(self, source, unit):
if len(source) > 1: if len(source) > 1:
...@@ -52,6 +53,7 @@ class EllipsisCheck(SourceCheck): ...@@ -52,6 +53,7 @@ class EllipsisCheck(SourceCheck):
u'The string uses three dots (...) ' u'The string uses three dots (...) '
u'instead of an ellipsis character (…)' u'instead of an ellipsis character (…)'
) )
severity = 'info'
def check_source(self, source, unit): def check_source(self, source, unit):
return '...' in source[0] return '...' in source[0]
...@@ -66,6 +68,7 @@ class MultipleFailingCheck(SourceCheck): ...@@ -66,6 +68,7 @@ class MultipleFailingCheck(SourceCheck):
description = _( description = _(
'The translations in several languages have failing checks' 'The translations in several languages have failing checks'
) )
severity = 'info'
def check_source(self, source, unit): def check_source(self, source, unit):
from weblate.trans.models.unitdata import Check from weblate.trans.models.unitdata import Check
......
...@@ -1012,7 +1012,14 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1012,7 +1012,14 @@ class Translation(models.Model, URLMixin, PercentMixin):
''' '''
Returns list of failing source checks on current subproject. Returns list of failing source checks on current subproject.
''' '''
result = [('all', _('All strings'), self.total)] result = [
(
'all',
_('All strings'),
self.total,
'success',
)
]
# All checks # All checks
sourcechecks = self.unit_set.count_type('sourcechecks', self) sourcechecks = self.unit_set.count_type('sourcechecks', self)
...@@ -1020,7 +1027,8 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1020,7 +1027,8 @@ class Translation(models.Model, URLMixin, PercentMixin):
result.append(( result.append((
'sourcechecks', 'sourcechecks',
_('Strings with any failing checks'), _('Strings with any failing checks'),
sourcechecks sourcechecks,
'danger',
)) ))
# Process specific checks # Process specific checks
...@@ -1032,7 +1040,8 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1032,7 +1040,8 @@ class Translation(models.Model, URLMixin, PercentMixin):
result.append(( result.append((
check, check,
CHECKS[check].description, CHECKS[check].description,
cnt cnt,
CHECKS[check].severity,
)) ))
# Grab comments # Grab comments
...@@ -1042,6 +1051,7 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1042,6 +1051,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'sourcecomments', 'sourcecomments',
_('Strings with comments'), _('Strings with comments'),
sourcecomments, sourcecomments,
'info',
)) ))
return result return result
...@@ -1050,7 +1060,14 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1050,7 +1060,14 @@ class Translation(models.Model, URLMixin, PercentMixin):
''' '''
Returns list of failing checks on current translation. Returns list of failing checks on current translation.
''' '''
result = [('all', _('All strings'), self.total)] result = [
(
'all',
_('All strings'),
self.total,
'success',
)
]
# Untranslated strings # Untranslated strings
nottranslated = self.unit_set.count_type('untranslated', self) nottranslated = self.unit_set.count_type('untranslated', self)
...@@ -1059,6 +1076,7 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1059,6 +1076,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'untranslated', 'untranslated',
_('Untranslated strings'), _('Untranslated strings'),
nottranslated, nottranslated,
'danger',
)) ))
# Fuzzy strings # Fuzzy strings
...@@ -1068,6 +1086,7 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1068,6 +1086,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'fuzzy', 'fuzzy',
_('Fuzzy strings'), _('Fuzzy strings'),
fuzzy, fuzzy,
'danger',
)) ))
# Translations with suggestions # Translations with suggestions
...@@ -1076,6 +1095,7 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1076,6 +1095,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'suggestions', 'suggestions',
_('Strings with suggestions'), _('Strings with suggestions'),
self.have_suggestion, self.have_suggestion,
'info',
)) ))
# All checks # All checks
...@@ -1084,6 +1104,7 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1084,6 +1104,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'allchecks', 'allchecks',
_('Strings with any failing checks'), _('Strings with any failing checks'),
self.failing_checks, self.failing_checks,
'danger',
)) ))
# Process specific checks # Process specific checks
...@@ -1095,7 +1116,8 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1095,7 +1116,8 @@ class Translation(models.Model, URLMixin, PercentMixin):
result.append(( result.append((
check, check,
CHECKS[check].description, CHECKS[check].description,
cnt cnt,
CHECKS[check].severity,
)) ))
# Grab comments # Grab comments
...@@ -1105,6 +1127,7 @@ class Translation(models.Model, URLMixin, PercentMixin): ...@@ -1105,6 +1127,7 @@ class Translation(models.Model, URLMixin, PercentMixin):
'targetcomments', 'targetcomments',
_('Strings with comments'), _('Strings with comments'),
targetcomments, targetcomments,
'info',
)) ))
return result return result
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment