diff options
-rw-r--r-- | fietsboek/locale/en/LC_MESSAGES/messages.mo | bin | 2536 -> 3289 bytes | |||
-rw-r--r-- | fietsboek/locale/en/LC_MESSAGES/messages.po | 104 | ||||
-rw-r--r-- | fietsboek/locale/fietslog.pot | 104 | ||||
-rw-r--r-- | fietsboek/models/track.py | 108 | ||||
-rw-r--r-- | fietsboek/templates/details.jinja2 | 24 | ||||
-rw-r--r-- | fietsboek/templates/login.jinja2 | 2 | ||||
-rw-r--r-- | fietsboek/util.py | 23 | ||||
-rw-r--r-- | fietsboek/views/detail.py | 1 |
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 Binary files differindex 8e5c45e..05007c8 100644 --- a/fietsboek/locale/en/LC_MESSAGES/messages.mo +++ b/fietsboek/locale/en/LC_MESSAGES/messages.mo 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, } |