diff --git a/uv.lock b/uv.lock
index e4c68f6ef..ccf065398 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2245,7 +2245,7 @@ dev = [
{ name = "tblib", specifier = "~=3.2.0" },
{ name = "wheel", specifier = "==0.45.1" },
]
-docker = [{ name = "gunicorn", specifier = "==23.0.0" }]
+docker = [{ name = "gunicorn", specifier = "~=23.0.0" }]
[[package]]
name = "wheel"
diff --git a/wger/trophies/checkers/base.py b/wger/trophies/checkers/base.py
index d36a6e65e..1b6dd62fd 100644
--- a/wger/trophies/checkers/base.py
+++ b/wger/trophies/checkers/base.py
@@ -19,6 +19,7 @@ from abc import (
ABC,
abstractmethod,
)
+from decimal import Decimal
from typing import (
Any,
Optional,
@@ -26,6 +27,10 @@ from typing import (
# Django
from django.contrib.auth.models import User
+from django.utils import formats
+
+# wger
+from wger.trophies.models import Trophy
class BaseTrophyChecker(ABC):
@@ -135,5 +140,14 @@ class BaseTrophyChecker(ABC):
"""
return None
+ @staticmethod
+ def format_number(val: Decimal | float):
+ return formats.number_format(
+ val,
+ decimal_pos=0 if val >= 1000 else 1,
+ use_l10n=True,
+ force_grouping=True,
+ )
+
def __repr__(self) -> str:
return f'<{self.__class__.__name__}(user={self.user.username}, trophy={self.trophy.name})>'
diff --git a/wger/trophies/checkers/date_based.py b/wger/trophies/checkers/date_based.py
index 6fa43d922..07c4ece9e 100644
--- a/wger/trophies/checkers/date_based.py
+++ b/wger/trophies/checkers/date_based.py
@@ -14,9 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-# Standard Library
-from typing import Any
-
# Local
from .base import BaseTrophyChecker
diff --git a/wger/trophies/checkers/inactivity_return.py b/wger/trophies/checkers/inactivity_return.py
index 2533d3b01..7614c7d74 100644
--- a/wger/trophies/checkers/inactivity_return.py
+++ b/wger/trophies/checkers/inactivity_return.py
@@ -16,7 +16,6 @@
# Standard Library
import datetime
-from typing import Any
# Local
from .base import BaseTrophyChecker
diff --git a/wger/trophies/checkers/personal_record.py b/wger/trophies/checkers/personal_record.py
index 6fc09f63c..80993db14 100644
--- a/wger/trophies/checkers/personal_record.py
+++ b/wger/trophies/checkers/personal_record.py
@@ -18,6 +18,7 @@
from typing import Optional
# wger
+from wger.manager.models import WorkoutLog
from wger.trophies.models.trophy import Trophy
from wger.trophies.models.user_trophy import UserTrophy
@@ -40,7 +41,7 @@ class PersonalRecordChecker(BaseTrophyChecker):
"""
Brzycki's formula: 1RM = weight * (36 / (37 - repetitions))
"""
- log = self.params.get('log', None)
+ log: WorkoutLog | None = self.params.get('log', None)
if not log:
raise ValueError('Log should not be None')
diff --git a/wger/trophies/checkers/registry.py b/wger/trophies/checkers/registry.py
index 17f2d93e7..df7a619d9 100644
--- a/wger/trophies/checkers/registry.py
+++ b/wger/trophies/checkers/registry.py
@@ -39,6 +39,7 @@ from .volume import VolumeChecker
from .weekend_warrior import WeekendWarriorChecker
from .workout_count_based import WorkoutCountBasedChecker
+
logger = logging.getLogger(__name__)
diff --git a/wger/trophies/checkers/streak.py b/wger/trophies/checkers/streak.py
index a5a3bbc23..d682032cc 100644
--- a/wger/trophies/checkers/streak.py
+++ b/wger/trophies/checkers/streak.py
@@ -14,9 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-# Standard Library
-from typing import Any
-
# Local
from .base import BaseTrophyChecker
diff --git a/wger/trophies/checkers/volume.py b/wger/trophies/checkers/volume.py
index 0a7649ed5..3c3c2a7ac 100644
--- a/wger/trophies/checkers/volume.py
+++ b/wger/trophies/checkers/volume.py
@@ -16,10 +16,6 @@
# Standard Library
from decimal import Decimal
-from typing import (
- Any,
- Union,
-)
# Local
from .base import BaseTrophyChecker
@@ -74,15 +70,4 @@ class VolumeChecker(BaseTrophyChecker):
current = self.get_current_value()
target = self.get_target_value()
- # Format large numbers with commas for readability
- if current >= 1000:
- current_str = f'{current:,.0f}'
- else:
- current_str = f'{current:.1f}'
-
- if target >= 1000:
- target_str = f'{target:,.0f}'
- else:
- target_str = f'{target:.1f}'
-
- return f'{current_str} / {target_str} kg'
+ return f'{self.format_number(current)} / {self.format_number(target)} kg'
diff --git a/wger/trophies/checkers/weekend_warrior.py b/wger/trophies/checkers/weekend_warrior.py
index 5325d5081..d27348330 100644
--- a/wger/trophies/checkers/weekend_warrior.py
+++ b/wger/trophies/checkers/weekend_warrior.py
@@ -14,9 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-# Standard Library
-from typing import Any
-
# Local
from .base import BaseTrophyChecker
diff --git a/wger/trophies/migrations/0001_initial.py b/wger/trophies/migrations/0001_initial.py
index 157f16909..b9973c59b 100644
--- a/wger/trophies/migrations/0001_initial.py
+++ b/wger/trophies/migrations/0001_initial.py
@@ -306,7 +306,7 @@ class Migration(migrations.Migration):
help_text='Additional information concerning this trophy',
null=True,
verbose_name='Context data',
- )
+ ),
),
],
options={
diff --git a/wger/trophies/migrations/0002_load_initial_trophies.py b/wger/trophies/migrations/0002_load_initial_trophies.py
index 015020ce1..59dc066b0 100644
--- a/wger/trophies/migrations/0002_load_initial_trophies.py
+++ b/wger/trophies/migrations/0002_load_initial_trophies.py
@@ -135,7 +135,7 @@ trophies_data = [
'name': 'Blue whale lifter',
'description': 'Lift a cumulative total of 150.000 kg',
'checker_params': {'kg': 150_000},
- 'is_hidden':True,
+ 'is_hidden': True,
'order': 13,
},
{
@@ -144,7 +144,7 @@ trophies_data = [
'name': 'Space Station lifter',
'description': 'Lift a cumulative total of 450.000 kg',
'checker_params': {'kg': 450_000},
- 'is_hidden':True,
+ 'is_hidden': True,
'order': 14,
},
{
@@ -153,7 +153,7 @@ trophies_data = [
'name': 'Millionaire',
'description': 'Lift a cumulative total of 1.000.000 kg',
'checker_params': {'kg': 1_000_000},
- 'is_hidden':True,
+ 'is_hidden': True,
'order': 15,
},
{
@@ -162,7 +162,7 @@ trophies_data = [
'name': 'Atlas',
'description': 'Lift a cumulative total of 10.000.000 kg',
'checker_params': {'kg': 10_000_000},
- 'is_hidden':True,
+ 'is_hidden': True,
'order': 16,
},
{
diff --git a/wger/trophies/services/trophy.py b/wger/trophies/services/trophy.py
index 5cbc229cd..53d33dfe1 100644
--- a/wger/trophies/services/trophy.py
+++ b/wger/trophies/services/trophy.py
@@ -244,7 +244,8 @@ class TrophyService:
current = progress_data['current_value']
target = progress_data['target_value']
if current is not None and target is not None:
- progress_data['progress_display'] = f'{current}/{target}'
+ progress_data['progress_display'] = checker.get_progress_display()
+ # progress_data['progress_display'] = f'{current}/{target}'
except Exception as e:
logger.error(f'Error getting progress for trophy {trophy.name}: {e}')
diff --git a/wger/trophies/signals.py b/wger/trophies/signals.py
index 749281e85..55aafe330 100644
--- a/wger/trophies/signals.py
+++ b/wger/trophies/signals.py
@@ -44,6 +44,7 @@ from wger.trophies.services import UserStatisticsService
from wger.trophies.services.trophy import TrophyService
from wger.trophies.tasks import evaluate_user_trophies_task
+
logger = logging.getLogger(__name__)
diff --git a/wger/trophies/urls.py b/wger/trophies/urls.py
index 35434a0ff..59d698c52 100644
--- a/wger/trophies/urls.py
+++ b/wger/trophies/urls.py
@@ -19,6 +19,7 @@ from django.urls import re_path
# wger
from wger.core.views.react import ReactView
+
urlpatterns = [
re_path(
'',
diff --git a/wger/urls.py b/wger/urls.py
index fefe77d5a..f47ec6672 100644
--- a/wger/urls.py
+++ b/wger/urls.py
@@ -52,6 +52,7 @@ from wger.trophies.api import views as trophies_api_views
from wger.utils.generic_views import TextTemplateView
from wger.weight.api import views as weight_api_views
+
#
# REST API
#