aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fietsboek/locale/en/LC_MESSAGES/messages.mobin2536 -> 3289 bytes
-rw-r--r--fietsboek/locale/en/LC_MESSAGES/messages.po104
-rw-r--r--fietsboek/locale/fietslog.pot104
-rw-r--r--fietsboek/models/track.py108
-rw-r--r--fietsboek/templates/details.jinja224
-rw-r--r--fietsboek/templates/login.jinja22
-rw-r--r--fietsboek/util.py23
-rw-r--r--fietsboek/views/detail.py1
8 files changed, 319 insertions, 47 deletions
diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.mo b/fietsboek/locale/en/LC_MESSAGES/messages.mo
index 8e5c45e..05007c8 100644
--- a/fietsboek/locale/en/LC_MESSAGES/messages.mo
+++ b/fietsboek/locale/en/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.po b/fietsboek/locale/en/LC_MESSAGES/messages.po
index b061d0d..4ba489a 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: 2022-06-29 01:22+0200\n"
+"POT-Creation-Date: 2022-06-29 13:38+0200\n"
"PO-Revision-Date: 2022-06-28 13:11+0200\n"
"Last-Translator: \n"
"Language: en\n"
@@ -18,54 +18,82 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.10.3\n"
-#: fietsboek/util.py:66
+#: fietsboek/util.py:87
msgid "month.january"
msgstr "January"
-#: fietsboek/util.py:67
+#: fietsboek/util.py:88
msgid "month.february"
msgstr "February"
-#: fietsboek/util.py:68
+#: fietsboek/util.py:89
msgid "month.march"
msgstr "March"
-#: fietsboek/util.py:69
+#: fietsboek/util.py:90
msgid "month.april"
msgstr "April"
-#: fietsboek/util.py:70
+#: fietsboek/util.py:91
msgid "month.may"
msgstr "May"
-#: fietsboek/util.py:71
+#: fietsboek/util.py:92
msgid "month.june"
msgstr "June"
-#: fietsboek/util.py:72
+#: fietsboek/util.py:93
msgid "month.july"
msgstr "July"
-#: fietsboek/util.py:73
+#: fietsboek/util.py:94
msgid "month.august"
msgstr "August"
-#: fietsboek/util.py:74
+#: fietsboek/util.py:95
msgid "month.september"
msgstr "September"
-#: fietsboek/util.py:75
+#: fietsboek/util.py:96
msgid "month.october"
msgstr "October"
-#: fietsboek/util.py:76
+#: fietsboek/util.py:97
msgid "month.november"
msgstr "November"
-#: fietsboek/util.py:77
+#: fietsboek/util.py:98
msgid "month.december"
msgstr "December"
+#: fietsboek/models/track.py:218
+msgid "tooltip.table.length"
+msgstr "Length"
+
+#: fietsboek/models/track.py:219
+msgid "tooltip.table.uphill"
+msgstr "Uphill"
+
+#: fietsboek/models/track.py:220
+msgid "tooltip.table.downhill"
+msgstr "Downhill"
+
+#: fietsboek/models/track.py:221
+msgid "tooltip.table.moving_time"
+msgstr "Moving Time"
+
+#: fietsboek/models/track.py:222
+msgid "tooltip.table.stopped_time"
+msgstr "Stopped Time"
+
+#: fietsboek/models/track.py:223
+msgid "tooltip.table.max_speed"
+msgstr "Max Speed"
+
+#: fietsboek/models/track.py:224
+msgid "tooltip.table.avg_speed"
+msgstr "Average Speed"
+
#: fietsboek/templates/details.jinja2:5
msgid "page.details.title"
msgstr "Track Details"
@@ -92,18 +120,42 @@ msgid "page.details.date"
msgstr "Date"
#: fietsboek/templates/details.jinja2:33
+msgid "page.details.start_time"
+msgstr "Record Start"
+
+#: fietsboek/templates/details.jinja2:37
+msgid "page.details.end_time"
+msgstr "Record End"
+
+#: fietsboek/templates/details.jinja2:41
msgid "page.details.length"
msgstr "Length"
-#: fietsboek/templates/details.jinja2:37
+#: fietsboek/templates/details.jinja2:45
msgid "page.details.uphill"
msgstr "Uphill"
-#: fietsboek/templates/details.jinja2:41
+#: fietsboek/templates/details.jinja2:49
msgid "page.details.downhill"
msgstr "Downhill"
-#: fietsboek/templates/details.jinja2:50
+#: fietsboek/templates/details.jinja2:53
+msgid "page.details.moving_time"
+msgstr "Moving Time"
+
+#: fietsboek/templates/details.jinja2:57
+msgid "page.details.stopped_time"
+msgstr "Stopped Time"
+
+#: fietsboek/templates/details.jinja2:61
+msgid "page.details.max_speed"
+msgstr "Max Speed"
+
+#: fietsboek/templates/details.jinja2:65
+msgid "page.details.avg_speed"
+msgstr "Average Speed"
+
+#: fietsboek/templates/details.jinja2:74
msgid "page.details.comments"
msgstr "Comments"
@@ -161,15 +213,23 @@ msgstr "Home"
msgid "page.home.total"
msgstr "Total"
-#: fietsboek/templates/layout.jinja2:34
+#: fietsboek/templates/layout.jinja2:31
+msgid "page.navbar.toggle"
+msgstr "Toggle navigation"
+
+#: fietsboek/templates/layout.jinja2:37
+msgid "page.navbar.home"
+msgstr "Home"
+
+#: fietsboek/templates/layout.jinja2:41
msgid "page.navbar.login"
msgstr "Login"
-#: fietsboek/templates/layout.jinja2:36
+#: fietsboek/templates/layout.jinja2:45
msgid "page.navbar.logout"
msgstr "Logout"
-#: fietsboek/templates/layout.jinja2:37
+#: fietsboek/templates/layout.jinja2:48
msgid "page.navbar.upload"
msgstr "Upload"
@@ -193,15 +253,15 @@ msgstr "Login"
msgid "page.upload.form.gpx"
msgstr "GPX file"
-#: fietsboek/views/default.py:44
+#: fietsboek/views/default.py:46
msgid "flash.invalid_credentials"
msgstr "Invalid login credentials"
-#: fietsboek/views/default.py:47
+#: fietsboek/views/default.py:49
msgid "flash.logged_in"
msgstr "You are now logged in"
-#: fietsboek/views/default.py:54
+#: fietsboek/views/default.py:56
msgid "flash.logged_out"
msgstr "You have been logged out"
diff --git a/fietsboek/locale/fietslog.pot b/fietsboek/locale/fietslog.pot
index 4a4cd92..0446056 100644
--- a/fietsboek/locale/fietslog.pot
+++ b/fietsboek/locale/fietslog.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2022-06-29 01:22+0200\n"
+"POT-Creation-Date: 2022-06-29 13:38+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,54 +17,82 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.10.3\n"
-#: fietsboek/util.py:66
+#: fietsboek/util.py:87
msgid "month.january"
msgstr ""
-#: fietsboek/util.py:67
+#: fietsboek/util.py:88
msgid "month.february"
msgstr ""
-#: fietsboek/util.py:68
+#: fietsboek/util.py:89
msgid "month.march"
msgstr ""
-#: fietsboek/util.py:69
+#: fietsboek/util.py:90
msgid "month.april"
msgstr ""
-#: fietsboek/util.py:70
+#: fietsboek/util.py:91
msgid "month.may"
msgstr ""
-#: fietsboek/util.py:71
+#: fietsboek/util.py:92
msgid "month.june"
msgstr ""
-#: fietsboek/util.py:72
+#: fietsboek/util.py:93
msgid "month.july"
msgstr ""
-#: fietsboek/util.py:73
+#: fietsboek/util.py:94
msgid "month.august"
msgstr ""
-#: fietsboek/util.py:74
+#: fietsboek/util.py:95
msgid "month.september"
msgstr ""
-#: fietsboek/util.py:75
+#: fietsboek/util.py:96
msgid "month.october"
msgstr ""
-#: fietsboek/util.py:76
+#: fietsboek/util.py:97
msgid "month.november"
msgstr ""
-#: fietsboek/util.py:77
+#: fietsboek/util.py:98
msgid "month.december"
msgstr ""
+#: fietsboek/models/track.py:218
+msgid "tooltip.table.length"
+msgstr ""
+
+#: fietsboek/models/track.py:219
+msgid "tooltip.table.uphill"
+msgstr ""
+
+#: fietsboek/models/track.py:220
+msgid "tooltip.table.downhill"
+msgstr ""
+
+#: fietsboek/models/track.py:221
+msgid "tooltip.table.moving_time"
+msgstr ""
+
+#: fietsboek/models/track.py:222
+msgid "tooltip.table.stopped_time"
+msgstr ""
+
+#: fietsboek/models/track.py:223
+msgid "tooltip.table.max_speed"
+msgstr ""
+
+#: fietsboek/models/track.py:224
+msgid "tooltip.table.avg_speed"
+msgstr ""
+
#: fietsboek/templates/details.jinja2:5
msgid "page.details.title"
msgstr ""
@@ -91,18 +119,42 @@ msgid "page.details.date"
msgstr ""
#: fietsboek/templates/details.jinja2:33
-msgid "page.details.length"
+msgid "page.details.start_time"
msgstr ""
#: fietsboek/templates/details.jinja2:37
-msgid "page.details.uphill"
+msgid "page.details.end_time"
msgstr ""
#: fietsboek/templates/details.jinja2:41
+msgid "page.details.length"
+msgstr ""
+
+#: fietsboek/templates/details.jinja2:45
+msgid "page.details.uphill"
+msgstr ""
+
+#: fietsboek/templates/details.jinja2:49
msgid "page.details.downhill"
msgstr ""
-#: fietsboek/templates/details.jinja2:50
+#: fietsboek/templates/details.jinja2:53
+msgid "page.details.moving_time"
+msgstr ""
+
+#: fietsboek/templates/details.jinja2:57
+msgid "page.details.stopped_time"
+msgstr ""
+
+#: fietsboek/templates/details.jinja2:61
+msgid "page.details.max_speed"
+msgstr ""
+
+#: fietsboek/templates/details.jinja2:65
+msgid "page.details.avg_speed"
+msgstr ""
+
+#: fietsboek/templates/details.jinja2:74
msgid "page.details.comments"
msgstr ""
@@ -160,15 +212,23 @@ msgstr ""
msgid "page.home.total"
msgstr ""
-#: fietsboek/templates/layout.jinja2:34
+#: fietsboek/templates/layout.jinja2:31
+msgid "page.navbar.toggle"
+msgstr ""
+
+#: fietsboek/templates/layout.jinja2:37
+msgid "page.navbar.home"
+msgstr ""
+
+#: fietsboek/templates/layout.jinja2:41
msgid "page.navbar.login"
msgstr ""
-#: fietsboek/templates/layout.jinja2:36
+#: fietsboek/templates/layout.jinja2:45
msgid "page.navbar.logout"
msgstr ""
-#: fietsboek/templates/layout.jinja2:37
+#: fietsboek/templates/layout.jinja2:48
msgid "page.navbar.upload"
msgstr ""
@@ -192,15 +252,15 @@ msgstr ""
msgid "page.upload.form.gpx"
msgstr ""
-#: fietsboek/views/default.py:44
+#: fietsboek/views/default.py:46
msgid "flash.invalid_credentials"
msgstr ""
-#: fietsboek/views/default.py:47
+#: fietsboek/views/default.py:49
msgid "flash.logged_in"
msgstr ""
-#: fietsboek/views/default.py:54
+#: fietsboek/views/default.py:56
msgid "flash.logged_out"
msgstr ""
diff --git a/fietsboek/models/track.py b/fietsboek/models/track.py
index 4c0583b..d2b43d5 100644
--- a/fietsboek/models/track.py
+++ b/fietsboek/models/track.py
@@ -17,6 +17,7 @@ from pyramid.i18n import TranslationString as _
import enum
import gzip
+import datetime
from markupsafe import Markup
@@ -89,25 +90,120 @@ class Track(Base):
self.cache.length = meta["length"]
self.cache.uphill = meta["uphill"]
self.cache.downhill = meta["downhill"]
+ self.cache.moving_time = meta["moving_time"]
+ self.cache.stopped_time = meta["stopped_time"]
+ self.cache.max_speed = meta["max_speed"]
+ self.cache.avg_speed = meta["avg_speed"]
+ self.cache.start_time = meta["start_time"]
+ self.cache.end_time = meta["end_time"]
@property
def length(self):
+ """Returns the length of the track..
+
+ :return: Length of the track in meters.
+ :rtype: float
+ """
if self.cache is None:
return util.tour_metadata(self.gpx_data)["length"]
return self.cache.length
@property
def downhill(self):
+ """Returns the downhill of the track.
+
+ :return: Downhill in meters.
+ :rtype: float
+ """
if self.cache is None:
return util.tour_metadata(self.gpx_data)["downhill"]
return self.cache.downhill
@property
def uphill(self):
+ """Returns the uphill of the track.
+
+ :return: Uphill in meters.
+ :rtype: float
+ """
if self.cache is None:
return util.tour_metadata(self.gpx_data)["uphill"]
return self.cache.uphill
+ @property
+ def moving_time(self):
+ """Returns the moving time.
+
+ :return: Moving time in seconds.
+ :rtype: datetime.timedelta
+ """
+ if self.cache is None:
+ value = util.tour_metadata(self.gpx_data)["moving_time"]
+ else:
+ value = self.cache.moving_time
+ return datetime.timedelta(seconds=value)
+
+ @property
+ def stopped_time(self):
+ """Returns the stopped time.
+
+ :return: Stopped time in seconds.
+ :rtype: datetime.timedelta
+ """
+ if self.cache is None:
+ value = util.tour_metadata(self.gpx_data)["stopped_time"]
+ else:
+ value = self.cache.stopped_time
+ return datetime.timedelta(seconds=value)
+
+ @property
+ def max_speed(self):
+ """Returns the maximum speed.
+
+ :return: Maximum speed in meters/second.
+ :rtype: float
+ """
+ if self.cache is None:
+ return util.tour_metadata(self.gpx_data)["max_speed"]
+ return self.cache.max_speed
+
+ @property
+ def avg_speed(self):
+ """Returns the average speed.
+
+ :return: Average speed in meters/second.
+ :rtype: float
+ """
+ if self.cache is None:
+ return util.tour_metadata(self.gpx_data)["avg_speed"]
+ return self.cache.avg_speed
+
+ @property
+ def start_time(self):
+ """Returns the start time.
+
+ This is the time embedded in the GPX file, not the time in the ``date`` column.
+
+ :return: Start time.
+ :rtype: datetime.datetime
+ """
+ if self.cache is None:
+ return util.tour_metadata(self.gpx_data)["start_time"]
+ return self.cache.start_time
+
+ @property
+ def end_time(self):
+ """Returns the end time.
+
+ This is the time embedded in the GPX file, not the time in the ``date`` column.
+
+ :return: End time.
+ :rtype: float
+ """
+ if self.cache is None:
+ return util.tour_metadata(self.gpx_data)["end_time"]
+ return self.cache.end_time
+
def html_tooltip(self, localizer):
"""Generate a quick summary of the track as a HTML element.
@@ -119,9 +215,13 @@ class Track(Base):
:rtype: Markup
"""
rows = [
- (_("tooltip.table.length"), f'{round(self.length, 2)} km'),
+ (_("tooltip.table.length"), f'{round(self.length / 1000, 2)} km'),
(_("tooltip.table.uphill"), f'{round(self.uphill, 2)} m'),
(_("tooltip.table.downhill"), f'{round(self.downhill, 2)} m'),
+ (_("tooltip.table.moving_time"), f'{self.moving_time}'),
+ (_("tooltip.table.stopped_time"), f'{self.stopped_time}'),
+ (_("tooltip.table.max_speed"), f'{round(util.mps_to_kph(self.max_speed), 2)} km/h'),
+ (_("tooltip.table.avg_speed"), f'{round(util.mps_to_kph(self.avg_speed), 2)} km/h'),
]
rows = [
"<tr><td>{}</td><td>{}</td></tr>".format(localizer.translate(name), value)
@@ -137,6 +237,12 @@ class TrackCache(Base):
length = Column(Float)
uphill = Column(Float)
downhill = Column(Float)
+ moving_time = Column(Float)
+ stopped_time = Column(Float)
+ max_speed = Column(Float)
+ avg_speed = Column(Float)
+ start_time = Column(DateTime)
+ end_time = Column(DateTime)
track = relationship('Track', back_populates='cache')
diff --git a/fietsboek/templates/details.jinja2 b/fietsboek/templates/details.jinja2
index fddd572..f4ed75a 100644
--- a/fietsboek/templates/details.jinja2
+++ b/fietsboek/templates/details.jinja2
@@ -30,6 +30,14 @@
<td>{{ track.date }}</td>
</tr>
<tr>
+ <th scope="row">{{ _("page.details.start_time") }}</th>
+ <td>{{ track.start_time }}</td>
+ </tr>
+ <tr>
+ <th scope="row">{{ _("page.details.end_time") }}</th>
+ <td>{{ track.end_time }}</td>
+ </tr>
+ <tr>
<th scope="row">{{ _("page.details.length") }}</th>
<td>{{ (track.length / 1000) | round(2) }} km</td>
</tr>
@@ -41,6 +49,22 @@
<th scope="row">{{ _("page.details.downhill") }}</th>
<td>{{ track.downhill | round(2) }} m</td>
</tr>
+ <tr>
+ <th scope="row">{{ _("page.details.moving_time") }}</th>
+ <td>{{ track.moving_time }}</td>
+ </tr>
+ <tr>
+ <th scope="row">{{ _("page.details.stopped_time") }}</th>
+ <td>{{ track.stopped_time }}</td>
+ </tr>
+ <tr>
+ <th scope="row">{{ _("page.details.max_speed") }}</th>
+ <td>{{ mps_to_kph(track.max_speed) | round(2) }} km/h</td>
+ </tr>
+ <tr>
+ <th scope="row">{{ _("page.details.avg_speed") }}</th>
+ <td>{{ mps_to_kph(track.avg_speed) | round(2) }} km/h</td>
+ </tr>
</tbody>
</table>
{% if description %}
diff --git a/fietsboek/templates/login.jinja2 b/fietsboek/templates/login.jinja2
index 7a1f442..0f2d0c3 100644
--- a/fietsboek/templates/login.jinja2
+++ b/fietsboek/templates/login.jinja2
@@ -3,7 +3,7 @@
{% block content %}
<div class="container">
<h1>{{ _("page.login.title") }}</h1>
- <form method="POST" target="{{ request.route_url('login') }}">
+ <form method="POST" target="{{ request.route_path('login') }}">
<label for="loginEmail" class="form-label">{{ _("page.login.email") }}</label>
<div class="row mb-3">
<div class="col-lg-5">
diff --git a/fietsboek/util.py b/fietsboek/util.py
index b6fb7e1..733b4ab 100644
--- a/fietsboek/util.py
+++ b/fietsboek/util.py
@@ -34,7 +34,9 @@ def safe_markdown(md_source):
def tour_metadata(gpx_data):
"""Calculate the metadata of the tour.
- Returns a dict with ``length``, ``uphill``, ``downhill``.
+ Returns a dict with ``length``, ``uphill``, ``downhill``, ``moving_time``,
+ ``stopped_time``, ``max_speed``, ``avg_speed``, ``start_time`` and
+ ``end_time``.
:param gpx_data: The GPX data of the tour.
:type gpx_data: str
@@ -43,13 +45,32 @@ def tour_metadata(gpx_data):
"""
gpx = gpxpy.parse(gpx_data)
uphill, downhill = gpx.get_uphill_downhill()
+ moving_data = gpx.get_moving_data()
+ time_bounds = gpx.get_time_bounds()
return {
'length': gpx.length_3d(),
'uphill': uphill,
'downhill': downhill,
+ 'moving_time': moving_data.moving_time,
+ 'stopped_time': moving_data.stopped_time,
+ 'max_speed': moving_data.max_speed,
+ 'avg_speed': moving_data.moving_distance / moving_data.moving_time,
+ 'start_time': time_bounds.start_time,
+ 'end_time': time_bounds.end_time,
}
+def mps_to_kph(mps):
+ """Converts meters/second to kilometers/hour.
+
+ :param mps: Input meters/second.
+ :type mps: float
+ :return: The converted km/h value.
+ :rtype: float
+ """
+ return mps / 1000 * 60 * 60
+
+
def month_name(request, month):
"""Returns the localized name for the month with the given number.
diff --git a/fietsboek/views/detail.py b/fietsboek/views/detail.py
index 0b5083d..ce14af2 100644
--- a/fietsboek/views/detail.py
+++ b/fietsboek/views/detail.py
@@ -14,6 +14,7 @@ def details(request):
return {
'track': track,
'show_edit_link': show_edit_link,
+ 'mps_to_kph': util.mps_to_kph,
'description': description,
}