Commit 8aa794cc authored by Michal Čihař's avatar Michal Čihař

One code to calculate current percents

- It can be shared for subproject, project and language.
- Much faster as it fetches just once from database instead of fetching
  every value separately
parent 981bf0da
...@@ -345,6 +345,13 @@ class Language(models.Model): ...@@ -345,6 +345,13 @@ class Language(models.Model):
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
def __init__(self, *args, **kwargs):
'''
Constructor to initialize some cache properties.
'''
super(Language, self).__init__(*args, **kwargs)
self._percents = None
def __unicode__(self): def __unicode__(self):
if (not '(' in self.name if (not '(' in self.name
and ('_' in self.code or '-' in self.code) and ('_' in self.code or '-' in self.code)
...@@ -377,68 +384,42 @@ class Language(models.Model): ...@@ -377,68 +384,42 @@ class Language(models.Model):
'lang': self.code 'lang': self.code
}) })
def get_translated_percent(self): def _get_percents(self):
''' '''
Returns status of translations in this language. Returns percentages of translation status.
''' '''
from trans.models import Translation # Use cache if available
if self._percents is not None:
return self._percents
translations = Translation.objects.filter( # Import translations
language=self from trans.models.translation import Translation
).aggregate(
Sum('translated'),
Sum('total')
)
translated = translations['translated__sum'] # Get prercents
total = translations['total__sum'] result = Translation.objects.get_percents(language=self)
# Prevent division by zero on no translations # Update cache
if total == 0: self._percents = result
return 0
return round(translated * 100.0 / total, 1)
def get_fuzzy_percent(self): return result
def get_translated_percent(self):
''' '''
Returns status of translations in this language. Returns percent of translated strings.
''' '''
from trans.models import Translation return self._get_percents()[0]
translations = Translation.objects.filter(
language=self
).aggregate(
Sum('fuzzy'),
Sum('total')
)
fuzzy = translations['fuzzy__sum']
total = translations['total__sum']
# Prevent division by zero on no translations def get_fuzzy_percent(self):
if total == 0: '''
return 0 Returns percent of fuzzy strings.
return round(fuzzy * 100.0 / total, 1) '''
return self._get_percents()[1]
def get_failing_checks_percent(self): def get_failing_checks_percent(self):
''' '''
Returns status of translations in this language. Returns percentage of failed checks.
''' '''
from trans.models import Translation return self._get_percents()[2]
translations = Translation.objects.filter(
language=self
).aggregate(
Sum('failing_checks'),
Sum('total')
)
failing_checks = translations['failing_checks__sum']
total = translations['total__sum']
# Prevent division by zero on no translations
if total == 0:
return 0
return round(failing_checks * 100.0 / total, 1)
def get_html(self): def get_html(self):
''' '''
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
from django.db import models from django.db import models
from weblate import appsettings from weblate import appsettings
from django.db.models import Sum
from django.utils.translation import ugettext as _, ugettext_lazy from django.utils.translation import ugettext as _, ugettext_lazy
from django.core.exceptions import ValidationError, PermissionDenied from django.core.exceptions import ValidationError, PermissionDenied
from django.contrib import messages from django.contrib import messages
...@@ -154,6 +153,13 @@ class Project(models.Model): ...@@ -154,6 +153,13 @@ class Project(models.Model):
ordering = ['name'] ordering = ['name']
app_label = 'trans' app_label = 'trans'
def __init__(self, *args, **kwargs):
'''
Constructor to initialize some cache properties.
'''
super(Project, self).__init__(*args, **kwargs)
self._percents = None
def has_acl(self, user): def has_acl(self, user):
''' '''
Checks whether current user is allowed to access this Checks whether current user is allowed to access this
...@@ -282,53 +288,43 @@ class Project(models.Model): ...@@ -282,53 +288,43 @@ class Project(models.Model):
content_type=content_type content_type=content_type
) )
def get_translated_percent(self, lang=None): def _get_percents(self, lang=None):
'''
Returns percentages of translation status.
'''
# Use cache if no filtering
if lang is None and self._percents is not None:
return self._percents
# Import translations
from trans.models.translation import Translation from trans.models.translation import Translation
# Filter all translations
translations = Translation.objects.filter(subproject__project=self) # Get prercents
# Filter by language result = Translation.objects.get_percents(project=self, language=lang)
if lang is not None:
translations = translations.filter(language=lang) # Update cache
# Aggregate if lang is None:
translations = translations.aggregate(Sum('translated'), Sum('total')) self._percents = result
total = translations['total__sum']
translated = translations['translated__sum'] return result
# Catch no translations
if total == 0 or total is None: def get_translated_percent(self, lang=None):
return 0 '''
# Return percent Returns percent of translated strings.
return round(translated * 100.0 / total, 1) '''
return self._get_percents(lang)[0]
def get_fuzzy_percent(self): def get_fuzzy_percent(self):
from trans.models.translation import Translation '''
# Filter all translations Returns percent of fuzzy strings.
translations = Translation.objects.filter(subproject__project=self) '''
# Aggregate return self._get_percents()[1]
translations = translations.aggregate(Sum('fuzzy'), Sum('total'))
total = translations['total__sum']
fuzzy = translations['fuzzy__sum']
# Catch no translations
if total == 0 or total is None:
return 0
# Return percent
return round(fuzzy * 100.0 / total, 1)
def get_failing_checks_percent(self): def get_failing_checks_percent(self):
''' '''
Returns percentage of failed checks. Returns percentage of failed checks.
''' '''
from trans.models.translation import Translation return self._get_percents()[2]
# Filter all translations
translations = Translation.objects.filter(subproject__project=self)
# Aggregate
translations = translations.aggregate(Sum('failing_checks'), Sum('total'))
total = translations['total__sum']
failing_checks = translations['failing_checks__sum']
# Catch no translations
if total == 0 or total is None:
return 0
# Return percent
return round(failing_checks * 100.0 / total, 1)
def get_total(self): def get_total(self):
''' '''
......
...@@ -164,6 +164,7 @@ class SubProject(models.Model): ...@@ -164,6 +164,7 @@ class SubProject(models.Model):
self._git_repo = None self._git_repo = None
self._file_format = None self._file_format = None
self._template_store = None self._template_store = None
self._percents = None
def has_acl(self, user): def has_acl(self, user):
''' '''
...@@ -836,53 +837,39 @@ class SubProject(models.Model): ...@@ -836,53 +837,39 @@ class SubProject(models.Model):
if changed_git: if changed_git:
self.create_translations() self.create_translations()
def get_translated_percent(self): def _get_percents(self):
''' '''
Returns percent of translated strings. Returns percentages of translation status.
''' '''
translations = self.translation_set.aggregate( # Use cache if available
Sum('translated'), Sum('total') if self._percents is not None:
) return self._percents
# Get prercents
result = self.translation_set.get_percents()
total = translations['total__sum'] # Update cache
translated = translations['translated__sum'] self._percents = result
if total == 0: return result
return 0
return round(translated * 100.0 / total, 1) def get_translated_percent(self):
'''
Returns percent of translated strings.
'''
return self._get_percents()[0]
def get_fuzzy_percent(self): def get_fuzzy_percent(self):
''' '''
Returns percent of fuzzy strings. Returns percent of fuzzy strings.
''' '''
translations = self.translation_set.aggregate( return self._get_percents()[1]
Sum('fuzzy'), Sum('total')
)
total = translations['total__sum']
fuzzy = translations['fuzzy__sum']
if total == 0:
return 0
return round(fuzzy * 100.0 / total, 1)
def get_failing_checks_percent(self): def get_failing_checks_percent(self):
''' '''
Returns percentage of failed checks. Returns percentage of failed checks.
''' '''
translations = self.translation_set.aggregate( return self._get_percents()[2]
Sum('failing_checks'), Sum('total')
)
total = translations['total__sum']
failing_checks = translations['failing_checks__sum']
if total == 0:
return 0
return round(failing_checks * 100.0 / total, 1)
def git_needs_commit(self): def git_needs_commit(self):
''' '''
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from weblate import appsettings from weblate import appsettings
from django.db.models import Q from django.db.models import Q, Sum
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
...@@ -76,6 +76,43 @@ class TranslationManager(models.Manager): ...@@ -76,6 +76,43 @@ class TranslationManager(models.Manager):
return self.all() return self.all()
return self.filter(subproject__project__in=projects) return self.filter(subproject__project__in=projects)
def get_percents(self, project=None, subproject=None, language=None):
'''
Returns tuple consting of status percents -
(translated, fuzzy, failing checks)
'''
# Filter translations
translations = self
if project is not None:
translations = translations.filter(subproject__project=project)
if subproject is not None:
translations = translations.filter(subproject=subproject)
if language is not None:
translations = translations.filter(language=language)
# Aggregate
translations = translations.aggregate(
Sum('translated'),
Sum('fuzzy'),
Sum('failing_checks'),
Sum('total'),
)
total = translations['total__sum']
if total == 0 or total is None:
# Catch no translations (division by zero)
return (0, 0 ,0)
# Fetch values
result = [
translations['translated__sum'],
translations['fuzzy__sum'],
translations['failing_checks__sum'],
]
# Calculate percent
return tuple([round(value * 100.0 / total, 1) for value in result])
class Translation(models.Model): class Translation(models.Model):
subproject = models.ForeignKey(SubProject) subproject = models.ForeignKey(SubProject)
......
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