aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fietsboek/jinja2.py3
-rw-r--r--fietsboek/views/profile.py27
-rw-r--r--tests/unit/views/test_profile.py21
3 files changed, 41 insertions, 10 deletions
diff --git a/fietsboek/jinja2.py b/fietsboek/jinja2.py
index 3832e66..5106c38 100644
--- a/fietsboek/jinja2.py
+++ b/fietsboek/jinja2.py
@@ -37,6 +37,8 @@ def filter_format_datetime(ctx: Context, value: datetime.datetime, format: str="
:param format: The format string, see https://babel.pocoo.org/en/latest/dates.html.
:return: The formatted date.
"""
+ # We redefine format because it's the same name as used by babel
+ # pylint: disable=redefined-builtin
request = ctx.get("request")
locale = request.localizer.locale_name
return format_datetime(value, format=format, locale=locale)
@@ -51,6 +53,7 @@ def filter_format_date(ctx: Context, value: datetime.date, format: str="medium")
:param format: The format string, see https://babel.pocoo.org/en/latest/dates.html.
:return: The formatted date.
"""
+ # pylint: disable=redefined-builtin
request = ctx.get("request")
locale = request.localizer.locale_name
return format_date(value, format=format, locale=locale)
diff --git a/fietsboek/views/profile.py b/fietsboek/views/profile.py
index 0127cd3..a002a81 100644
--- a/fietsboek/views/profile.py
+++ b/fietsboek/views/profile.py
@@ -7,6 +7,7 @@ import urllib.parse
from dataclasses import dataclass
from typing import Optional
+import sqlalchemy
from pyramid.httpexceptions import HTTPNotFound
from pyramid.request import Request
from pyramid.response import Response
@@ -250,22 +251,28 @@ def user_calendar_ym(request: Request) -> dict:
def cell_style(tracks: list[TrackWithMetadata]) -> str:
+ """Returns the correct CSS style for a day with the given tracks.
+
+ The style is determined by the amount of kilometers cycled on that day.
+
+ :param tracks: The list of tracks.
+ :return: The CSS style for the calendar cell.
+ """
length = sum(track.length for track in tracks)
# kilometers
length = length / 1000
# Arbitrary cutoffs for the moment
if length == 0:
return "cell-length-0"
- elif length <= 25:
+ if length <= 25:
return "cell-length-1"
- elif length <= 50:
+ if length <= 50:
return "cell-length-2"
- elif length <= 75:
+ if length <= 75:
return "cell-length-3"
- elif length <= 100:
+ if length <= 100:
return "cell-length-4"
- else:
- return "cell-length-5"
+ return "cell-length-5"
def calendar_rows(
@@ -308,7 +315,7 @@ def calendar_rows(
# Step 3: Associate days and tracks
days = [
- (day, [track for track in tracks if track.date.date() == day])
+ (day, [track for track in tracks if track.date and track.date.date() == day])
for day in days
]
@@ -319,7 +326,7 @@ def calendar_rows(
# Step 4: Layout
rows = []
- row = []
+ row: list[None | tuple[datetime.date, str, list[TrackWithMetadata]]] = []
while days:
next_day = days.pop(0)
# This should only matter in the first row, when the month does not
@@ -338,7 +345,7 @@ def calendar_rows(
return rows
-def prev_next_month(date: datetime.date) -> datetime.date:
+def prev_next_month(date: datetime.date) -> tuple[datetime.date, datetime.date]:
"""Return the previous and next months.
Months are normalized to the first day of the month.
@@ -418,4 +425,4 @@ def json_summary(request: Request) -> Response:
return {y.year: {m.month: m.total_length for m in y} for y in summary}
-__all__ = ["profile", "user_tile", "json_summary"]
+__all__ = ["profile", "user_tile", "user_calendar_ym", "json_summary"]
diff --git a/tests/unit/views/test_profile.py b/tests/unit/views/test_profile.py
new file mode 100644
index 0000000..bc8e794
--- /dev/null
+++ b/tests/unit/views/test_profile.py
@@ -0,0 +1,21 @@
+import pytest
+import datetime
+
+from fietsboek.views import profile
+
+
+@pytest.mark.parametrize("current, prev_month, next_month", [
+ ((2024, 2, 1), (2024, 1, 1), (2024, 3, 1)),
+ ((2024, 1, 1), (2023, 12, 1), (2024, 2, 1)),
+ ((2024, 12, 1), (2024, 11, 1), (2025, 1, 1)),
+ ((2024, 5, 5), (2024, 4, 1), (2024, 6, 1)),
+ ((2024, 7, 31), (2024, 6, 1), (2024, 8, 1)),
+])
+def test_prev_next_month(current, prev_month, next_month):
+ current = datetime.date(*current)
+ prev_month = datetime.date(*prev_month)
+ next_month = datetime.date(*next_month)
+
+ actual_prev, actual_next = profile.prev_next_month(current)
+ assert actual_prev == prev_month
+ assert actual_next == next_month