Skip to content

Commit ed5c58b

Browse files
committed
Reduce code duplication
1 parent 4d31a7b commit ed5c58b

4 files changed

Lines changed: 63 additions & 93 deletions

File tree

pontoon/base/models/entity.py

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from django.contrib.postgres.fields import ArrayField
99
from django.db import models
10-
from django.db.models import Count, F, Prefetch, Q
10+
from django.db.models import F, Prefetch, Q
1111
from django.utils import timezone
1212

1313
from pontoon.base import utils
@@ -283,56 +283,6 @@ class Meta:
283283
def __str__(self):
284284
return self.string
285285

286-
def get_stats(self, locale) -> dict[str, int]:
287-
"""
288-
Get stats for a single (entity, locale) pair.
289-
290-
:arg Locale locale: filter translations for this locale.
291-
:return: a dictionary with stats for the Entity+Locale
292-
"""
293-
stats = self.translation_set.filter(locale=locale).aggregate(
294-
approved_count=Count(
295-
"pk",
296-
filter=Q(approved=True, errors__isnull=True, warnings__isnull=True),
297-
),
298-
pretranslated_count=Count(
299-
"pk",
300-
filter=Q(
301-
pretranslated=True, errors__isnull=True, warnings__isnull=True
302-
),
303-
),
304-
errors_count=Count(
305-
"pk",
306-
distinct=True,
307-
filter=Q(
308-
Q(Q(approved=True) | Q(pretranslated=True) | Q(fuzzy=True))
309-
& Q(errors__isnull=False)
310-
),
311-
),
312-
warnings_count=Count(
313-
"pk",
314-
distinct=True,
315-
filter=Q(
316-
Q(Q(approved=True) | Q(pretranslated=True) | Q(fuzzy=True))
317-
& Q(warnings__isnull=False)
318-
),
319-
),
320-
unreviewed_count=Count(
321-
"pk",
322-
distinct=True,
323-
filter=Q(
324-
approved=False, rejected=False, pretranslated=False, fuzzy=False
325-
),
326-
),
327-
)
328-
return {
329-
"approved": stats["approved_count"],
330-
"pretranslated": stats["pretranslated_count"],
331-
"errors": stats["errors_count"],
332-
"warnings": stats["warnings_count"],
333-
"unreviewed": stats["unreviewed_count"],
334-
}
335-
336286
def has_changed(self, locale):
337287
"""
338288
Check if translations in the given locale have changed since the

pontoon/base/models/stats.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from django.db.models import Count, Q
2+
3+
4+
def aggregate_translation_stats(queryset) -> dict[str, int]:
5+
"""
6+
Aggregate translation stats for a given Translation queryset.
7+
8+
:return: a dictionary with approved, pretranslated, errors, warnings,
9+
and unreviewed counts.
10+
"""
11+
stats = queryset.aggregate(
12+
approved_count=Count(
13+
"pk",
14+
filter=Q(approved=True, errors__isnull=True, warnings__isnull=True),
15+
),
16+
pretranslated_count=Count(
17+
"pk",
18+
filter=Q(pretranslated=True, errors__isnull=True, warnings__isnull=True),
19+
),
20+
errors_count=Count(
21+
"pk",
22+
distinct=True,
23+
filter=Q(
24+
Q(Q(approved=True) | Q(pretranslated=True) | Q(fuzzy=True))
25+
& Q(errors__isnull=False)
26+
),
27+
),
28+
warnings_count=Count(
29+
"pk",
30+
distinct=True,
31+
filter=Q(
32+
Q(Q(approved=True) | Q(pretranslated=True) | Q(fuzzy=True))
33+
& Q(warnings__isnull=False)
34+
),
35+
),
36+
unreviewed_count=Count(
37+
"pk",
38+
filter=Q(approved=False, rejected=False, pretranslated=False, fuzzy=False),
39+
),
40+
)
41+
return {
42+
"approved": stats["approved_count"],
43+
"pretranslated": stats["pretranslated_count"],
44+
"errors": stats["errors_count"],
45+
"warnings": stats["warnings_count"],
46+
"unreviewed": stats["unreviewed_count"],
47+
}

pontoon/base/models/translated_resource.py

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import logging
22

33
from django.db import models
4-
from django.db.models import Count, F, Q, Sum
4+
from django.db.models import F, Sum
55

66
from .locale import Locale
77
from .project import Project
88
from .resource import Resource
9+
from .stats import aggregate_translation_stats
910
from .translation import Translation
1011
from .user import User
1112

@@ -158,46 +159,13 @@ def calculate_stats(self, save=True):
158159
locale=self.locale,
159160
)
160161

161-
stats = translations.aggregate(
162-
approved_count=Count(
163-
"pk",
164-
filter=Q(approved=True, errors__isnull=True, warnings__isnull=True),
165-
),
166-
pretranslated_count=Count(
167-
"pk",
168-
filter=Q(
169-
pretranslated=True, errors__isnull=True, warnings__isnull=True
170-
),
171-
),
172-
errors_count=Count(
173-
"pk",
174-
distinct=True,
175-
filter=Q(
176-
Q(Q(approved=True) | Q(pretranslated=True) | Q(fuzzy=True))
177-
& Q(errors__isnull=False)
178-
),
179-
),
180-
warnings_count=Count(
181-
"pk",
182-
distinct=True,
183-
filter=Q(
184-
Q(Q(approved=True) | Q(pretranslated=True) | Q(fuzzy=True))
185-
& Q(warnings__isnull=False)
186-
),
187-
),
188-
unreviewed_count=Count(
189-
"pk",
190-
filter=Q(
191-
approved=False, rejected=False, pretranslated=False, fuzzy=False
192-
),
193-
),
194-
)
162+
stats = aggregate_translation_stats(translations)
195163

196-
self.approved_strings = stats["approved_count"]
197-
self.pretranslated_strings = stats["pretranslated_count"]
198-
self.strings_with_errors = stats["errors_count"]
199-
self.strings_with_warnings = stats["warnings_count"]
200-
self.unreviewed_strings = stats["unreviewed_count"]
164+
self.approved_strings = stats["approved"]
165+
self.pretranslated_strings = stats["pretranslated"]
166+
self.strings_with_errors = stats["errors"]
167+
self.strings_with_warnings = stats["warnings"]
168+
self.unreviewed_strings = stats["unreviewed"]
201169

202170
if save:
203171
self.save(

pontoon/base/models/translation.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pontoon.base.models.locale import Locale
1414
from pontoon.base.models.project import Project
1515
from pontoon.base.models.project_locale import ProjectLocale
16+
from pontoon.base.models.stats import aggregate_translation_stats
1617
from pontoon.base.models.user import User
1718
from pontoon.base.simple_preview import get_simple_preview
1819
from pontoon.checks import DB_FORMATS
@@ -249,7 +250,9 @@ def save(self, failed_checks=None, *args, **kwargs):
249250
from pontoon.base.models.translated_resource import TranslatedResource
250251
from pontoon.base.models.translation_memory import TranslationMemoryEntry
251252

252-
stats_before = self.entity.get_stats(self.locale)
253+
stats_before = aggregate_translation_stats(
254+
self.entity.translation_set.filter(locale=self.locale)
255+
)
253256

254257
super().save(*args, **kwargs)
255258

@@ -324,7 +327,9 @@ def save(self, failed_checks=None, *args, **kwargs):
324327
# Update stats AFTER changing approval status.
325328
# Use entity-scoped aggregate delta for performance. Fall back to a
326329
# full resource recount on IntegrityError.
327-
stats_after = self.entity.get_stats(self.locale)
330+
stats_after = aggregate_translation_stats(
331+
self.entity.translation_set.filter(locale=self.locale)
332+
)
328333
try:
329334
with transaction.atomic():
330335
translatedresource.adjust_stats(stats_before, stats_after, created)

0 commit comments

Comments
 (0)