diff options
-rw-r--r-- | fietsboek/alembic/versions/20220808_d085998b49ca.py | 23 | ||||
-rw-r--r-- | fietsboek/models/track.py | 28 | ||||
-rw-r--r-- | fietsboek/templates/browse.jinja2 | 6 | ||||
-rw-r--r-- | fietsboek/templates/details.jinja2 | 6 | ||||
-rw-r--r-- | fietsboek/templates/edit.jinja2 | 2 | ||||
-rw-r--r-- | fietsboek/templates/edit_form.jinja2 | 9 | ||||
-rw-r--r-- | fietsboek/templates/finish_upload.jinja2 | 2 | ||||
-rw-r--r-- | fietsboek/views/default.py | 3 | ||||
-rw-r--r-- | fietsboek/views/detail.py | 1 | ||||
-rw-r--r-- | fietsboek/views/edit.py | 3 | ||||
-rw-r--r-- | fietsboek/views/upload.py | 4 |
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(), |