Coverage for app/venv/lib/python3.14/site-packages/weblate/metrics/tasks.py: 76%
33 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
5from datetime import timedelta
7from celery.schedules import crontab
8from django.utils import timezone
10from weblate.auth.models import User
11from weblate.lang.models import Language
12from weblate.metrics.models import Metric
13from weblate.trans.models import Component, ComponentList, Project, Translation
14from weblate.utils.celery import app
15from weblate.utils.stats import prefetch_stats
18@app.task(trail=False)
19def collect_metrics() -> None:
20 Metric.objects.collect_global()
21 for project in prefetch_stats(Project.objects.all()): 21 ↛ 22line 21 didn't jump to line 22 because the loop on line 21 never started
22 Metric.objects.collect_project(project)
23 for component in prefetch_stats(Component.objects.all()): 23 ↛ 24line 23 didn't jump to line 24 because the loop on line 23 never started
24 Metric.objects.collect_component(component)
25 for clist in prefetch_stats(ComponentList.objects.all()): 25 ↛ 26line 25 didn't jump to line 26 because the loop on line 25 never started
26 Metric.objects.collect_component_list(clist)
27 for translation in prefetch_stats(Translation.objects.all()): 27 ↛ 28line 27 didn't jump to line 28 because the loop on line 27 never started
28 Metric.objects.collect_translation(translation)
29 for user in User.objects.filter():
30 Metric.objects.collect_user(user)
31 for language in prefetch_stats(Language.objects.all()):
32 Metric.objects.collect_language(language)
35@app.task(trail=False)
36def cleanup_metrics() -> None:
37 """Remove stale metrics."""
38 today = timezone.now().date()
39 # Remove past metrics, but we need data for last 24 months
40 Metric.objects.filter(date__lte=today - timedelta(days=800)).delete()
42 # Remove detailed data for past metrics, we need details only for two months
43 # - avoid filtering on data field as that one is not indexed
44 # - wipe only interval of data with assumption that this task is executed daily
45 Metric.objects.filter(
46 date__range=(today - timedelta(days=75), today - timedelta(days=65))
47 ).update(data=None)
50@app.on_after_finalize.connect
51def setup_periodic_tasks(sender, **kwargs) -> None:
52 sender.add_periodic_task(
53 crontab(hour=0, minute=1), collect_metrics.s(), name="collect-metrics"
54 )
55 sender.add_periodic_task(
56 crontab(hour=23, minute=1), cleanup_metrics.s(), name="cleanup-metrics"
57 )