From 88411c91f83614a3918c2a553e2592862c147175 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Wed, 12 Aug 2026 22:17:31 +0200 Subject: add year-track-activity overview --- asset-sources/theme.scss | 31 +++++++++ babel.cfg | 1 + fietsboek/locale/de/LC_MESSAGES/messages.mo | Bin 20324 -> 20548 bytes fietsboek/locale/de/LC_MESSAGES/messages.po | 26 ++++--- fietsboek/locale/en/LC_MESSAGES/messages.mo | Bin 19139 -> 19355 bytes fietsboek/locale/en/LC_MESSAGES/messages.po | 26 ++++--- fietsboek/locale/fietslog.pot | 26 ++++--- fietsboek/static/theme.css | 41 ++++++++--- fietsboek/static/theme.css.map | 2 +- fietsboek/summaries.py | 101 +++++++++++++++++++++++++++- fietsboek/templates/profile_overview.jinja2 | 29 ++++++++ fietsboek/views/profile.py | 5 +- 12 files changed, 252 insertions(+), 36 deletions(-) diff --git a/asset-sources/theme.scss b/asset-sources/theme.scss index ba05782..cdb4923 100644 --- a/asset-sources/theme.scss +++ b/asset-sources/theme.scss @@ -271,6 +271,37 @@ strong { } } +.contributions { + tbody td.contribs-cell { + div { + border: 2px solid rgba(0, 0, 0, 0.175); + border-radius: calc(0.375rem - (1px)); + + width: 1em; + height: 1em; + } + } + + .contribs-length-0 div { + background-color: #FFFFFF; + } + .contribs-length-1 div { + background-color: #8FF0A4; + } + .contribs-length-2 div { + background-color: #75DD95; + } + .contribs-length-3 div { + background-color: #5BC987; + } + .contribs-length-4 div { + background-color: #40B678; + } + .contribs-length-5 div { + background-color: #26A269; + } +} + .browse-summary { font-variant: lining-nums; } diff --git a/babel.cfg b/babel.cfg index 6de4aaa..650a00a 100644 --- a/babel.cfg +++ b/babel.cfg @@ -4,3 +4,4 @@ jinja2 = jinja2.ext:babel_extract [jinja2: **.jinja2] [python: **.py] +keywords = _ pluralize:1,2 diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.mo b/fietsboek/locale/de/LC_MESSAGES/messages.mo index 356be25..4ffa423 100644 Binary files a/fietsboek/locale/de/LC_MESSAGES/messages.mo and b/fietsboek/locale/de/LC_MESSAGES/messages.mo differ diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.po b/fietsboek/locale/de/LC_MESSAGES/messages.po index 9367d28..8342327 100644 --- a/fietsboek/locale/de/LC_MESSAGES/messages.po +++ b/fietsboek/locale/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-01-03 19:25+0100\n" +"POT-Creation-Date: 2026-08-12 22:13+0200\n" "PO-Revision-Date: 2022-07-02 17:35+0200\n" "Last-Translator: FULL NAME \n" "Language: de\n" @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.17.0\n" +"Generated-By: Babel 2.18.0\n" #: fietsboek/actions.py:266 msgid "email.verify_mail.subject" @@ -61,6 +61,12 @@ msgstr "Maximalgeschwindigkeit" msgid "pdf.table.avg_speed" msgstr "Durchschnittsgeschwindigkeit" +#: fietsboek/summaries.py:384 +msgid "page.profile.contribution_card.tooltip" +msgid_plural "page.profile.contribution_card.tooltips" +msgstr[0] "${count} Strecke am ${date}" +msgstr[1] "${count} Strecken am ${date}" + #: fietsboek/util.py:299 msgid "password_constraint.mismatch" msgstr "Passwörter stimmen nicht überein" @@ -1008,27 +1014,31 @@ msgstr "durchschnittliche Geschwindigkeit" msgid "page.profile.number_of_tracks" msgstr "Anzahl der Strecken" -#: fietsboek/templates/profile_overview.jinja2:113 +#: fietsboek/templates/profile_overview.jinja2:112 +msgid "page.profile.contribution_card.title" +msgstr "Streckenaktivität" + +#: fietsboek/templates/profile_overview.jinja2:142 msgid "page.profile.longest_distance_track" msgstr "Weiteste Strecke" -#: fietsboek/templates/profile_overview.jinja2:118 +#: fietsboek/templates/profile_overview.jinja2:147 msgid "page.profile.shortest_distance_track" msgstr "Kürzeste Strecke" -#: fietsboek/templates/profile_overview.jinja2:123 +#: fietsboek/templates/profile_overview.jinja2:152 msgid "page.profile.longest_duration_track" msgstr "Am Längsten Dauernde Strecke" -#: fietsboek/templates/profile_overview.jinja2:128 +#: fietsboek/templates/profile_overview.jinja2:157 msgid "page.profile.shortest_duration_track" msgstr "Am Kürzesten Dauernde Strecke" -#: fietsboek/templates/profile_overview.jinja2:149 +#: fietsboek/templates/profile_overview.jinja2:178 msgid "page.profile.heatmap" msgstr "Heatmap" -#: fietsboek/templates/profile_overview.jinja2:157 +#: fietsboek/templates/profile_overview.jinja2:186 msgid "page.profile.tilehunt" msgstr "Kacheljäger" diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.mo b/fietsboek/locale/en/LC_MESSAGES/messages.mo index f4b7bbf..39eabb5 100644 Binary files a/fietsboek/locale/en/LC_MESSAGES/messages.mo and b/fietsboek/locale/en/LC_MESSAGES/messages.mo differ diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.po b/fietsboek/locale/en/LC_MESSAGES/messages.po index d52960b..a8e6c0c 100644 --- a/fietsboek/locale/en/LC_MESSAGES/messages.po +++ b/fietsboek/locale/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-01-03 19:25+0100\n" +"POT-Creation-Date: 2026-08-12 22:13+0200\n" "PO-Revision-Date: 2023-04-03 20:42+0200\n" "Last-Translator: \n" "Language: en\n" @@ -16,7 +16,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.17.0\n" +"Generated-By: Babel 2.18.0\n" #: fietsboek/actions.py:266 msgid "email.verify_mail.subject" @@ -61,6 +61,12 @@ msgstr "Max Speed" msgid "pdf.table.avg_speed" msgstr "Average Speed" +#: fietsboek/summaries.py:384 +msgid "page.profile.contribution_card.tooltip" +msgid_plural "page.profile.contribution_card.tooltips" +msgstr[0] "${count} track on ${date}" +msgstr[1] "${count} tracks on ${date}" + #: fietsboek/util.py:299 msgid "password_constraint.mismatch" msgstr "Passwords don't match" @@ -1002,27 +1008,31 @@ msgstr "Average Speed" msgid "page.profile.number_of_tracks" msgstr "Number of tracks" -#: fietsboek/templates/profile_overview.jinja2:113 +#: fietsboek/templates/profile_overview.jinja2:112 +msgid "page.profile.contribution_card.title" +msgstr "Track Activity" + +#: fietsboek/templates/profile_overview.jinja2:142 msgid "page.profile.longest_distance_track" msgstr "Longest Track" -#: fietsboek/templates/profile_overview.jinja2:118 +#: fietsboek/templates/profile_overview.jinja2:147 msgid "page.profile.shortest_distance_track" msgstr "Shortest Track" -#: fietsboek/templates/profile_overview.jinja2:123 +#: fietsboek/templates/profile_overview.jinja2:152 msgid "page.profile.longest_duration_track" msgstr "Most Time-Consuming Track" -#: fietsboek/templates/profile_overview.jinja2:128 +#: fietsboek/templates/profile_overview.jinja2:157 msgid "page.profile.shortest_duration_track" msgstr "Quickest Track" -#: fietsboek/templates/profile_overview.jinja2:149 +#: fietsboek/templates/profile_overview.jinja2:178 msgid "page.profile.heatmap" msgstr "Heat Map" -#: fietsboek/templates/profile_overview.jinja2:157 +#: fietsboek/templates/profile_overview.jinja2:186 msgid "page.profile.tilehunt" msgstr "Tilehunt" diff --git a/fietsboek/locale/fietslog.pot b/fietsboek/locale/fietslog.pot index 50a43a0..7f7e325 100644 --- a/fietsboek/locale/fietslog.pot +++ b/fietsboek/locale/fietslog.pot @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-01-03 19:25+0100\n" +"POT-Creation-Date: 2026-08-12 22:13+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.17.0\n" +"Generated-By: Babel 2.18.0\n" #: fietsboek/actions.py:266 msgid "email.verify_mail.subject" @@ -57,6 +57,12 @@ msgstr "" msgid "pdf.table.avg_speed" msgstr "" +#: fietsboek/summaries.py:384 +msgid "page.profile.contribution_card.tooltip" +msgid_plural "page.profile.contribution_card.tooltips" +msgstr[0] "" +msgstr[1] "" + #: fietsboek/util.py:299 msgid "password_constraint.mismatch" msgstr "" @@ -994,27 +1000,31 @@ msgstr "" msgid "page.profile.number_of_tracks" msgstr "" -#: fietsboek/templates/profile_overview.jinja2:113 +#: fietsboek/templates/profile_overview.jinja2:112 +msgid "page.profile.contribution_card.title" +msgstr "" + +#: fietsboek/templates/profile_overview.jinja2:142 msgid "page.profile.longest_distance_track" msgstr "" -#: fietsboek/templates/profile_overview.jinja2:118 +#: fietsboek/templates/profile_overview.jinja2:147 msgid "page.profile.shortest_distance_track" msgstr "" -#: fietsboek/templates/profile_overview.jinja2:123 +#: fietsboek/templates/profile_overview.jinja2:152 msgid "page.profile.longest_duration_track" msgstr "" -#: fietsboek/templates/profile_overview.jinja2:128 +#: fietsboek/templates/profile_overview.jinja2:157 msgid "page.profile.shortest_duration_track" msgstr "" -#: fietsboek/templates/profile_overview.jinja2:149 +#: fietsboek/templates/profile_overview.jinja2:178 msgid "page.profile.heatmap" msgstr "" -#: fietsboek/templates/profile_overview.jinja2:157 +#: fietsboek/templates/profile_overview.jinja2:186 msgid "page.profile.tilehunt" msgstr "" diff --git a/fietsboek/static/theme.css b/fietsboek/static/theme.css index 65e6881..aa9fe1b 100644 --- a/fietsboek/static/theme.css +++ b/fietsboek/static/theme.css @@ -80,14 +80,6 @@ strong { flex-wrap: wrap; } -.track-image-preview { - position: relative; - width: min(317px, 100%); - height: 178.3125px; - border: 1px solid grey; - margin-right: 5px; - margin-bottom: 5px; -} .track-image-preview .delete-image { position: absolute; z-index: 5; @@ -120,6 +112,14 @@ strong { left: 50%; transform: translate(-50%, -50%); } +.track-image-preview { + position: relative; + width: min(317px, 100%); + height: 178.3125px; + border: 1px solid grey; + margin-right: 5px; + margin-bottom: 5px; +} .track-description img { max-width: 100%; @@ -259,6 +259,31 @@ strong { color: inherit; } +.contributions tbody td.contribs-cell div { + border: 2px solid rgba(0, 0, 0, 0.175); + border-radius: calc(0.375rem - 1px); + width: 1em; + height: 1em; +} +.contributions .contribs-length-0 div { + background-color: #FFFFFF; +} +.contributions .contribs-length-1 div { + background-color: #8FF0A4; +} +.contributions .contribs-length-2 div { + background-color: #75DD95; +} +.contributions .contribs-length-3 div { + background-color: #5BC987; +} +.contributions .contribs-length-4 div { + background-color: #40B678; +} +.contributions .contribs-length-5 div { + background-color: #26A269; +} + .browse-summary { font-variant: lining-nums; } diff --git a/fietsboek/static/theme.css.map b/fietsboek/static/theme.css.map index 3ddb9bc..6c87d3e 100644 --- a/fietsboek/static/theme.css.map +++ b/fietsboek/static/theme.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../asset-sources/theme.scss"],"names":[],"mappings":"AAAA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EAqCE;EACA;EACA;EACA;EACA;EACA;;AAzCA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAWJ;EACI;;;AAGJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAEF;EACE;;AACA;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;EACA;;AACA;EACE;;AAIJ;EACE;EACA;;;AAIJ;EACE;;;AAGF;AACA;EACE;;;AAGF;EACE;EACA;;AAEA;EAJF;IAKI,eACE;;;AAIJ;EACE;;AAGF;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;;AAIJ;EACE;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE","file":"theme.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../asset-sources/theme.scss"],"names":[],"mappings":"AAAA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAIA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAlCJ;EAqCE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACI;;;AAGJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAEF;EACE;;AACA;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;EACA;;AACA;EACE;;AAIJ;EACE;EACA;;;AAMA;EACE;EACA;EAEA;EACA;;AAIJ;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;;AAIJ;EACE;;;AAGF;AACA;EACE;;;AAGF;EACE;EACA;;AAEA;EAJF;IAKI,eACE;;;AAIJ;EACE;;AAGF;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;;AAIJ;EACE;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE","file":"theme.css"} \ No newline at end of file diff --git a/fietsboek/summaries.py b/fietsboek/summaries.py index 0bee6ca..aa8a84c 100644 --- a/fietsboek/summaries.py +++ b/fietsboek/summaries.py @@ -2,11 +2,17 @@ import datetime from dataclasses import dataclass -from typing import Optional +from typing import Optional, Iterator + +from babel.dates import format_date +from pyramid.i18n import Localizer +from pyramid.i18n import TranslationString as _ from . import util from .models.track import TrackWithMetadata +ONE_WEEK = datetime.timedelta(days=7) + class Summary: """A summary of a user's tracks. @@ -294,4 +300,95 @@ class CumulativeStats: return util.round_to_seconds((self.moving_time + self.stopped_time) / self.count) -__all__ = ["Summary", "YearSummary", "MonthSummary", "CumulativeStats"] +class YearContributions: + """Github-contributions-tracker-like overview for tracks.""" + + def __init__(self, end_date: datetime.date): + self.end_date = end_date + self.start_date = end_date - 52 * ONE_WEEK + # Make sure the start of the range is on a Monday + self.start_date -= datetime.timedelta(days=end_date.weekday()) + assert (self.start_date - self.end_date).days <= 53 * 7 + + self.tracks = {} + + def add(self, track: TrackWithMetadata): + date = track.date.date() + if date >= self.start_date and date <= self.end_date: + self.tracks.setdefault(date, []).append(track) + + def rows(self) -> Iterator[Iterator[DayContributions]]: + for weekday in range(7): + row = [] + day = self.start_date + datetime.timedelta(days=weekday) + while day <= self.end_date: + row.append(DayContributions(day, self.tracks.get(day, []))) + day += ONE_WEEK + yield row + + def header_row(self, localizer: Localizer) -> Iterator[str | None]: + locale = localizer.locale_name + day = self.start_date + while day <= self.end_date: + diq = day + datetime.timedelta(days=6) + if diq.day <= 7: + yield format_date(diq, "MMM", locale=locale) + day += 3 * ONE_WEEK + else: + yield None + day += ONE_WEEK + + +class DayContributions: + """A single cell (representing one day) for the YearContributions.""" + + def __init__(self, day: datetime.date, tracks: list[TrackWithMetadata]): + self.day = day + self.tracks = tracks + + def total_length(self) -> float: + """The total length of all tracks on this day, in meters.""" + return sum(track.length for track in self.tracks) + + def count(self) -> int: + """The number of tracks in this day.""" + return len(self.tracks) + + def cell_style(self) -> str: + """Returns the CSS style that should be applied to the cell. + + :return: The CSS class. + """ + length = self.total_length() / 1000 + # Arbitrary cutoffs, should maybe be the same as for the calendar + if length == 0: + return "contribs-length-0" + if length <= 25: + return "contribs-length-1" + if length <= 50: + return "contribs-length-2" + if length <= 75: + return "contribs-length-3" + if length <= 100: + return "contribs-length-4" + return "contribs-length-5" + + def tooltip(self, localizer: Localizer) -> str: + """Generates the tooltip for the cell, localized to the given language. + + :param localizer: The localizer to use. + :return: The tooltip text. + """ + formatted_date = format_date(self.day, locale=localizer.locale_name) + return localizer.pluralize( + "page.profile.contribution_card.tooltip", + "page.profile.contribution_card.tooltips", + self.count(), + mapping={ + "count": self.count(), + "date": formatted_date, + }, + ) + + +__all__ = ["Summary", "YearSummary", "MonthSummary", "CumulativeStats", "YearContributions"] diff --git a/fietsboek/templates/profile_overview.jinja2 b/fietsboek/templates/profile_overview.jinja2 index eaa10c6..f563ad9 100644 --- a/fietsboek/templates/profile_overview.jinja2 +++ b/fietsboek/templates/profile_overview.jinja2 @@ -109,6 +109,35 @@ +

{{ _("page.profile.contribution_card.title") }}

+
+ + + + {% for cell in year_contributions.header_row(request.localizer) %} + {% if cell is none %} + + {% else %} + + {% endif %} + {% endfor %} + + + + {% for row in year_contributions.rows() %} + + {% for cell in row %} + + {% endfor %} + + {% endfor %} + +
{{ cell }}
+ +
+
+
+ {% if total.longest_distance_track %}

{{ _("page.profile.longest_distance_track") }}

{{ render_track_card(total.longest_distance_track) }} diff --git a/fietsboek/views/profile.py b/fietsboek/views/profile.py index 6d671b9..414dfae 100644 --- a/fietsboek/views/profile.py +++ b/fietsboek/views/profile.py @@ -16,7 +16,7 @@ from sqlalchemy.orm import aliased from .. import models, util from ..data import UserDataDir from ..models.track import TrackType, TrackWithMetadata -from ..summaries import CumulativeStats, Summary +from ..summaries import CumulativeStats, Summary, YearContributions # A well-made transparent tile is actually pretty small (only 116 bytes), which # is even smaller than our HTTP 404 page. So not only is it more efficient @@ -49,6 +49,7 @@ LOGGER = logging.getLogger(__name__) def profile_data(request: Request) -> dict: """Retrieves the profile data for the given request.""" total = CumulativeStats() + year_contribs = YearContributions(datetime.date.today() - datetime.timedelta(days=365)) query = request.context.all_tracks_query() query = select(aliased(models.Track, query)).where(query.c.type == TrackType.ORGANIC) @@ -56,6 +57,7 @@ def profile_data(request: Request) -> dict: for track in request.dbsession.execute(query).scalars(): meta = TrackWithMetadata(track) total.add(meta) + year_contribs.add(meta) total.moving_time = util.round_to_seconds(total.moving_time) total.stopped_time = util.round_to_seconds(total.stopped_time) @@ -79,6 +81,7 @@ def profile_data(request: Request) -> dict: "mps_to_kph": util.mps_to_kph, "heatmap_url": heatmap_url, "tilehunt_url": tilehunt_url, + "year_contributions": year_contribs, } -- cgit v1.2.3