Compare commits
No commits in common. "dba8414fd9569fc99a70fe52d50f22c61a830ff4" and "c4b0347f3b783cdc2433703e78f82cae9869d7b4" have entirely different histories.
dba8414fd9
...
c4b0347f3b
|
@ -1,11 +1,3 @@
|
||||||
## 1.1.2 / 2023-10-13 16:30+02:00
|
|
||||||
|
|
||||||
### Enhancements
|
|
||||||
* Durations are formatted in a consisent manner across all pages
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
* Game Overview: display duration when >1 hour instead of displaying 0
|
|
||||||
|
|
||||||
## 1.1.1 / 2023-10-09 20:52+02:00
|
## 1.1.1 / 2023-10-09 20:52+02:00
|
||||||
|
|
||||||
### New
|
### New
|
||||||
|
|
|
@ -6,7 +6,7 @@ RUN npm install && \
|
||||||
|
|
||||||
FROM python:3.10.9-slim-bullseye
|
FROM python:3.10.9-slim-bullseye
|
||||||
|
|
||||||
ENV VERSION_NUMBER 1.1.2
|
ENV VERSION_NUMBER 1.1.1
|
||||||
ENV PROD 1
|
ENV PROD 1
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,6 @@ def format_duration(
|
||||||
from the formatting string. For example:
|
from the formatting string. For example:
|
||||||
- 61 seconds as "%s" = 61 seconds
|
- 61 seconds as "%s" = 61 seconds
|
||||||
- 61 seconds as "%m %s" = 1 minutes 1 seconds"
|
- 61 seconds as "%m %s" = 1 minutes 1 seconds"
|
||||||
Format specifiers can include width and precision options:
|
|
||||||
- %5.2H: hours formatted with width 5 and 2 decimal places (padded with zeros)
|
|
||||||
"""
|
"""
|
||||||
minute_seconds = 60
|
minute_seconds = 60
|
||||||
hour_seconds = 60 * minute_seconds
|
hour_seconds = 60 * minute_seconds
|
||||||
|
@ -48,29 +46,18 @@ def format_duration(
|
||||||
remainder = seconds = seconds_total
|
remainder = seconds = seconds_total
|
||||||
if "%d" in format_string:
|
if "%d" in format_string:
|
||||||
days, remainder = divmod(seconds_total, day_seconds)
|
days, remainder = divmod(seconds_total, day_seconds)
|
||||||
if re.search(r"%\d*\.?\d*H", format_string):
|
if "%H" in format_string:
|
||||||
hours_float, remainder = divmod(remainder, hour_seconds)
|
hours, remainder = divmod(remainder, hour_seconds)
|
||||||
hours = float(hours_float) + remainder / hour_seconds
|
if "%m" in format_string:
|
||||||
if re.search(r"%\d*\.?\d*m", format_string):
|
|
||||||
minutes, seconds = divmod(remainder, minute_seconds)
|
minutes, seconds = divmod(remainder, minute_seconds)
|
||||||
literals = {
|
literals = {
|
||||||
"d": str(days),
|
"%d": str(days),
|
||||||
"H": str(hours),
|
"%H": str(hours),
|
||||||
"m": str(minutes),
|
"%m": str(minutes),
|
||||||
"s": str(seconds),
|
"%s": str(seconds),
|
||||||
"r": str(seconds_total),
|
"%r": str(seconds_total),
|
||||||
}
|
}
|
||||||
formatted_string = format_string
|
formatted_string = format_string
|
||||||
for pattern, replacement in literals.items():
|
for pattern, replacement in literals.items():
|
||||||
# Match format specifiers with optional width and precision
|
formatted_string = re.sub(pattern, replacement, formatted_string)
|
||||||
match = re.search(rf"%(\d*\.?\d*){pattern}", formatted_string)
|
|
||||||
if match:
|
|
||||||
format_spec = match.group(1)
|
|
||||||
if format_spec:
|
|
||||||
# Format the number according to the specifier
|
|
||||||
replacement = f"{float(replacement):{format_spec}f}"
|
|
||||||
# Replace the format specifier with the formatted number
|
|
||||||
formatted_string = re.sub(
|
|
||||||
rf"%\d*\.?\d*{pattern}", replacement, formatted_string
|
|
||||||
)
|
|
||||||
return formatted_string
|
return formatted_string
|
||||||
|
|
|
@ -114,7 +114,7 @@ class Session(models.Model):
|
||||||
return timedelta(seconds=(manual + calculated).total_seconds())
|
return timedelta(seconds=(manual + calculated).total_seconds())
|
||||||
|
|
||||||
def duration_formatted(self) -> str:
|
def duration_formatted(self) -> str:
|
||||||
result = format_duration(self.duration_seconds(), "%02.0H:%02.0m")
|
result = format_duration(self.duration_seconds(), "%H:%m")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -101,8 +101,8 @@ def view_game(request, game_id=None):
|
||||||
context["sessions"] = Session.objects.filter(
|
context["sessions"] = Session.objects.filter(
|
||||||
purchase__edition__game_id=game_id
|
purchase__edition__game_id=game_id
|
||||||
).order_by("-timestamp_start")
|
).order_by("-timestamp_start")
|
||||||
context["total_hours"] = float(
|
context["total_hours"] = int(
|
||||||
format_duration(context["sessions"].total_duration_unformatted(), "%2.1H")
|
format_duration(context["sessions"].total_duration_unformatted(), "%H")
|
||||||
)
|
)
|
||||||
context["session_average"] = round(
|
context["session_average"] = round(
|
||||||
(context["total_hours"]) / int(context["sessions"].count()), 1
|
(context["total_hours"]) / int(context["sessions"].count()), 1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "timetracker"
|
name = "timetracker"
|
||||||
version = "1.1.2"
|
version = "1.1.1"
|
||||||
description = "A simple time tracker."
|
description = "A simple time tracker."
|
||||||
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
authors = ["Lukáš Kucharczyk <lukas@kucharczyk.xyz>"]
|
||||||
license = "GPL"
|
license = "GPL"
|
||||||
|
|
Loading…
Reference in New Issue