From 3e36e89459b563bee78579e628756e8f54afaca2 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Tue, 5 May 2026 23:23:57 +0200 Subject: add fietsctl track add --- fietsboek/scripts/fietsctl.py | 76 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/fietsboek/scripts/fietsctl.py b/fietsboek/scripts/fietsctl.py index fa751b7..d08be17 100644 --- a/fietsboek/scripts/fietsctl.py +++ b/fietsboek/scripts/fietsctl.py @@ -2,6 +2,7 @@ # pylint: disable=too-many-positional-arguments,too-many-arguments import logging +from pathlib import Path from typing import Optional import click @@ -11,8 +12,9 @@ from pyramid.scripting import AppEnvironment from sqlalchemy import select from sqlalchemy.exc import NoResultFound -from .. import __VERSION__, hittekaart, models, util +from .. import __VERSION__, actions, convert, hittekaart, models, util from ..data import DataManager +from ..views.tileproxy import ITileRequester from . import config_option LOGGER = logging.getLogger("fietsctl") @@ -380,6 +382,78 @@ def cmd_track_list(config: str): ) +@cmd_track.command("add") +@config_option +@optgroup.group("User selection", cls=RequiredMutuallyExclusiveOptionGroup) +@optgroup.option("--id", "-i", "id_", help="Database ID of the user.", type=int) +@optgroup.option("--email", "-e", help="Email address of the user.") +@click.argument("filename", nargs=-1) +@click.pass_context +def cmd_track_add( + ctx: click.Context, + config: str, + id_: int | None, + email: str | None, + filename: list[str], +): + """Add a track. + + The track is added for the specified user. + + The track type is set to "organic" and the visibility to "private". + """ + env = setup(config) + if id_ is not None: + query = select(models.User).filter_by(id=id_) + else: + query = models.User.query_by_email(email) + with env["request"].tm: + request = env["request"] + dbsession = request.dbsession + user = dbsession.execute(query).scalar_one_or_none() + if user is None: + click.echo("Error: No such user found.", err=True) + ctx.exit(EXIT_FAILURE) + + for fname in filename: + fpath = Path(fname) + try: + gpx_bytes = fpath.read_bytes() + except Exception as exc: + click.secho("Error", fg="red", nl=False) + click.echo(f" in {fname}: {exc}") + continue + + try: + track = convert.smart_convert(gpx_bytes) + except Exception as exc: + click.secho("Error", fg="red", nl=False) + click.echo(f" in {fname}: {exc}") + continue + + title = track.title or fpath.name + saved = actions.add_track( + dbsession, + request.data_manager, + request.registry.getUtility(ITileRequester), + request.config.public_tile_layers()[0], + user, + title, + track.date, + models.track.Visibility.PRIVATE, + models.track.TrackType.ORGANIC, + "", + [], + [], + [], + [], + gpx_bytes, + ) + + click.secho("Success", fg="green", nl=False) + click.echo(f" {fname} saved as track {saved.id}") + + @cmd_track.command("del") @config_option @click.option("--force", "-f", help="Override the safety check.", is_flag=True) -- cgit v1.2.3