aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fietsboek/alembic/versions/20220808_d085998b49ca.py23
-rw-r--r--fietsboek/models/track.py28
-rw-r--r--fietsboek/templates/browse.jinja26
-rw-r--r--fietsboek/templates/details.jinja26
-rw-r--r--fietsboek/templates/edit.jinja22
-rw-r--r--fietsboek/templates/edit_form.jinja29
-rw-r--r--fietsboek/templates/finish_upload.jinja22
-rw-r--r--fietsboek/views/default.py3
-rw-r--r--fietsboek/views/detail.py1
-rw-r--r--fietsboek/views/edit.py3
-rw-r--r--fietsboek/views/upload.py4
11 files changed, 82 insertions, 5 deletions
diff --git a/fietsboek/alembic/versions/20220808_d085998b49ca.py b/fietsboek/alembic/versions/20220808_d085998b49ca.py
new file mode 100644
index 0000000..56dbbf7
--- /dev/null
+++ b/fietsboek/alembic/versions/20220808_d085998b49ca.py
@@ -0,0 +1,23 @@
+"""Add track.type column.
+
+Revision ID: d085998b49ca
+Revises: 091ce24409fe
+Create Date: 2022-08-08 14:11:40.746008
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'd085998b49ca'
+down_revision = '091ce24409fe'
+branch_labels = None
+depends_on = None
+
+def upgrade():
+ op.add_column('tracks', sa.Column('type', sa.Enum('ORGANIC', 'SYNTHETIC', name='tracktype'), nullable=True))
+ op.execute("UPDATE tracks SET type='ORGANIC';")
+
+def downgrade():
+ op.drop_column('tracks', 'type')
diff --git a/fietsboek/models/track.py b/fietsboek/models/track.py
index 83c725f..ce7b4d0 100644
--- a/fietsboek/models/track.py
+++ b/fietsboek/models/track.py
@@ -84,6 +84,19 @@ class Visibility(enum.Enum):
"""Anyone can see the track."""
+class TrackType(enum.Enum):
+ """An enum that represents the type of a track."""
+
+ ORGANIC = enum.auto()
+ """An organic track that represents a recording of a user."""
+
+ SYNTHETIC = enum.auto()
+ """A planned track that represents a route, but not an actual recording.
+
+ This is also called a "template".
+ """
+
+
track_people_assoc = Table(
"track_people_assoc",
Base.metadata,
@@ -150,6 +163,8 @@ class Track(Base):
:vartype tags: list[Tag]
:ivar link_secret: The secret string for the share link.
:vartype link_secret: str
+ :ivar type: Type of the track
+ :vartype type: TrackType
:ivar owner: Owner of the track.
:vartype owner: fietsboek.models.user.User
:ivar cache: Cache for the computed track metadata.
@@ -173,6 +188,7 @@ class Track(Base):
gpx = Column(LargeBinary)
visibility = Column(Enum(Visibility))
link_secret = Column(Text)
+ type = Column(Enum(TrackType))
owner = relationship('User', back_populates='tracks')
cache = relationship('TrackCache', back_populates='track', uselist=False,
@@ -285,6 +301,18 @@ class Track(Base):
self.date_tz = value.tzinfo.utcoffset(value).total_seconds() // 60
self.date_raw = value.replace(tzinfo=None)
+ def show_organic_data(self):
+ """Determines whether the organic data should be shown.
+
+ This includes average speed, maximum speed, record start time and record end time.
+
+ For synthetic tracks, we only show the length, uphill and downhill values.
+
+ :return: Whether the organic data should be shown.
+ :rtype: bool
+ """
+ return self.type == TrackType.ORGANIC
+
def is_visible_to(self, user):
"""Checks whether the track is visible to the given user.
diff --git a/fietsboek/templates/browse.jinja2 b/fietsboek/templates/browse.jinja2
index 0f98192..6a479ea 100644
--- a/fietsboek/templates/browse.jinja2
+++ b/fietsboek/templates/browse.jinja2
@@ -117,18 +117,21 @@
<th scope="row">{{ _("page.details.length") }}</th>
<td>{{ (track.length / 1000) | round(2) | format_decimal }} km</td>
</tr>
+ {% if track.show_organic_data() %}
<tr>
<th scope="row">{{ _("page.details.start_time") }}</th>
<td>{{ track.start_time | format_datetime }}</td>
<th scope="row">{{ _("page.details.end_time") }}</th>
<td>{{ track.end_time | format_datetime }}</td>
</tr>
+ {% endif %}
<tr>
<th scope="row">{{ _("page.details.uphill") }}</th>
<td>{{ track.uphill | round(2) | format_decimal }} m</td>
<th scope="row">{{ _("page.details.downhill") }}</th>
<td>{{ track.downhill | round(2) | format_decimal }} m</td>
</tr>
+ {% if track.show_organic_data() %}
<tr>
<th scope="row">{{ _("page.details.moving_time") }}</th>
<td>{{ track.moving_time }}</td>
@@ -141,15 +144,18 @@
<th scope="row">{{ _("page.details.avg_speed") }}</th>
<td>{{ mps_to_kph(track.avg_speed) | round(2) | format_decimal }} km/h</td>
</tr>
+ {% endif %}
</tbody>
</table>
+ {% if track.show_organic_data() %}
<ul>
<li>{{ track.owner.name }}</li>
{% for user in track.tagged_people %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
+ {% endif %}
</div>
</div>
{% endfor %}
diff --git a/fietsboek/templates/details.jinja2 b/fietsboek/templates/details.jinja2
index 55a5c26..4d67f07 100644
--- a/fietsboek/templates/details.jinja2
+++ b/fietsboek/templates/details.jinja2
@@ -56,12 +56,14 @@
{% endif %}
+ {% if is_organic %}
<ul>
<li>{{ track.owner.name }}</li>
{% for user in track.tagged_people %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
+ {% endif %}
<p>
{{ _("page.details.tags") }}: {% for tag in track.tags %}<span class="badge rounded-pill bg-info text-dark">{{ tag.tag }}</span> {% endfor %}
@@ -86,6 +88,7 @@
<th scope="row">{{ _("page.details.date") }}</th>
<td>{{ track.date | format_datetime }}</td>
</tr>
+ {% if show_organic %}
<tr>
<th scope="row">{{ _("page.details.start_time") }}</th>
<td>{{ track.start_time | format_datetime }}</td>
@@ -94,6 +97,7 @@
<th scope="row">{{ _("page.details.end_time") }}</th>
<td>{{ track.end_time | format_datetime }}</td>
</tr>
+ {% endif %}
<tr>
<th scope="row">{{ _("page.details.length") }}</th>
<td>{{ (track.length / 1000) | round(2) | format_decimal }} km</td>
@@ -106,6 +110,7 @@
<th scope="row">{{ _("page.details.downhill") }}</th>
<td>{{ track.downhill | round(2) | format_decimal }} m</td>
</tr>
+ {% if show_organic %}
<tr>
<th scope="row">{{ _("page.details.moving_time") }}</th>
<td>{{ track.moving_time }}</td>
@@ -122,6 +127,7 @@
<th scope="row">{{ _("page.details.avg_speed") }}</th>
<td>{{ mps_to_kph(track.avg_speed) | round(2) | format_decimal }} km/h</td>
</tr>
+ {% endif %}
</tbody>
</table>
{% if track.badges %}
diff --git a/fietsboek/templates/edit.jinja2 b/fietsboek/templates/edit.jinja2
index 4e64f69..91c44e3 100644
--- a/fietsboek/templates/edit.jinja2
+++ b/fietsboek/templates/edit.jinja2
@@ -10,7 +10,7 @@
<noscript><p>{{ _("page.noscript") }}<p></noscript>
</div>
<form method="POST" enctype="multipart/form-data">
- {{ edit_form.edit_track(track.title, track.date_raw, track.date_tz or 0, track.visibility, track.description, track.text_tags(), badges, track.tagged_people, images) }}
+ {{ edit_form.edit_track(track.title, track.date_raw, track.date_tz or 0, track.visibility, track.type, track.description, track.text_tags(), badges, track.tagged_people, images) }}
{{ util.hidden_csrf_input() }}
<div class="btn-group" role="group">
<button type="submit" class="btn btn-primary"><i class="bi bi-save"></i> {{ _("page.edit.form.submit") }}</button>
diff --git a/fietsboek/templates/edit_form.jinja2 b/fietsboek/templates/edit_form.jinja2
index c4a478c..34c34c3 100644
--- a/fietsboek/templates/edit_form.jinja2
+++ b/fietsboek/templates/edit_form.jinja2
@@ -1,4 +1,4 @@
-{% macro edit_track(title, date, date_tz, visibility, description, tags, badges, friends, images) %}
+{% macro edit_track(title, date, date_tz, visibility, type, description, tags, badges, friends, images) %}
<div class="mb-3">
<label for="formTitle" class="form-label">{{ _("page.track.form.title") }}</label>
<input class="form-control" type="text" id="formTitle" name="title" value="{{ title | default("", true) }}">
@@ -22,6 +22,13 @@
</p>
</div>
<div class="mb-3">
+ <label for="formType" class="form-label">{{ _("page.track.form.type") }}</label>
+ <select class="form-select" id="formType" name="type">
+ <option value="ORGANIC"{% if type.name == "ORGANIC" %} selected{% endif%}>{{ _("page.track.form.type.organic") }}</option>
+ <option value="SYNTHETIC"{% if type.name == "SYNTHETIC" %} selected{% endif%}>{{ _("page.track.form.type.synthetic") }}</option>
+ </select>
+</div>
+<div class="mb-3">
<div>{{ _("page.track.form.tags") }}</div>
<div id="formTags" class="mb-1">
{% for tag in tags %}
diff --git a/fietsboek/templates/finish_upload.jinja2 b/fietsboek/templates/finish_upload.jinja2
index d6f9f00..0d32392 100644
--- a/fietsboek/templates/finish_upload.jinja2
+++ b/fietsboek/templates/finish_upload.jinja2
@@ -10,7 +10,7 @@
<noscript><p>{{ _("page.noscript") }}<p></noscript>
</div>
<form method="POST" enctype="multipart/form-data">
- {{ edit_form.edit_track(upload_title, upload_date, upload_date_tz, upload_visibility, upload_description, upload_tags, badges, upload_tagged_people, []) }}
+ {{ edit_form.edit_track(upload_title, upload_date, upload_date_tz, upload_visibility, upload_type, upload_description, upload_tags, badges, upload_tagged_people, []) }}
{{ util.hidden_csrf_input() }}
<div class="btn-group" role="group">
<button type="submit" class="btn btn-primary">{{ _("page.upload.form.submit") }}</button>
diff --git a/fietsboek/views/default.py b/fietsboek/views/default.py
index e7a1cb0..1d7bfa9 100644
--- a/fietsboek/views/default.py
+++ b/fietsboek/views/default.py
@@ -10,6 +10,7 @@ from sqlalchemy.exc import NoResultFound
from .. import models, summaries, util, email
from ..models.user import PasswordMismatch, TokenType
+from ..models.track import TrackType
@view_config(route_name='home', renderer='fietsboek:templates/home.jinja2')
@@ -32,6 +33,8 @@ def home(request):
summary = summaries.Summary()
for track in all_tracks:
+ if track.type != TrackType.ORGANIC:
+ continue
track.ensure_cache()
request.dbsession.add(track.cache)
summary.add(track)
diff --git a/fietsboek/views/detail.py b/fietsboek/views/detail.py
index 6eba3ce..38dc31f 100644
--- a/fietsboek/views/detail.py
+++ b/fietsboek/views/detail.py
@@ -40,6 +40,7 @@ def details(request):
return {
'track': track,
+ 'show_organic': track.show_organic_data(),
'show_edit_link': show_edit_link,
'mps_to_kph': util.mps_to_kph,
'comment_md_to_html': util.safe_markdown,
diff --git a/fietsboek/views/edit.py b/fietsboek/views/edit.py
index 946a862..ff71282 100644
--- a/fietsboek/views/edit.py
+++ b/fietsboek/views/edit.py
@@ -10,7 +10,7 @@ from pyramid.httpexceptions import HTTPFound, HTTPBadRequest
from sqlalchemy import select
from .. import models, util
-from ..models.track import Visibility
+from ..models.track import Visibility, TrackType
ImageEmbed = namedtuple("ImageEmbed", "name url description")
@@ -78,6 +78,7 @@ def do_edit(request):
track.tagged_people = tagged_people
track.title = request.params["title"]
track.visibility = Visibility[request.params["visibility"]]
+ track.type = TrackType[request.params["type"]]
track.description = request.params["description"]
track.badges = badges
tags = request.params.getall("tag[]")
diff --git a/fietsboek/views/upload.py b/fietsboek/views/upload.py
index 95008b4..f63f45d 100644
--- a/fietsboek/views/upload.py
+++ b/fietsboek/views/upload.py
@@ -13,7 +13,7 @@ import gpxpy
from . import edit
from .. import models, util
-from ..models.track import Visibility
+from ..models.track import Visibility, TrackType
LOGGER = logging.getLogger(__name__)
@@ -120,6 +120,7 @@ def finish_upload(request):
'upload_date': date,
'upload_date_tz': int(tz_offset.total_seconds() // 60),
'upload_visibility': Visibility.PRIVATE,
+ 'upload_type': TrackType.ORGANIC,
'upload_description': gpx.description,
'upload_tags': set(),
'upload_tagged_people': [],
@@ -153,6 +154,7 @@ def do_finish_upload(request):
owner=request.identity,
title=request.params["title"],
visibility=Visibility[request.params["visibility"]],
+ type=TrackType[request.params["type"]],
description=request.params["description"],
badges=badges,
link_secret=util.random_link_secret(),