aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/fietsctl.rst20
-rw-r--r--fietsboek/scripts/fietsctl.py90
2 files changed, 109 insertions, 1 deletions
diff --git a/doc/man/fietsctl.rst b/doc/man/fietsctl.rst
index 1d30b20..8a91408 100644
--- a/doc/man/fietsctl.rst
+++ b/doc/man/fietsctl.rst
@@ -186,6 +186,26 @@ For each track, the following information is shown:
* The track's owner (both name and email address)
* The track's title.
+ADDING A TRACK
+##############
+
+.. code-block:: text
+
+ fietsctl track add [-c CONFIG] [-i/--id ID] [-e/--email] [--visibility PRIVATE|FRIENDS|FRIENDS_TAGGED|LOGGED_IN|PUBLIC] [--track-type ORGANIC|SYNTHETIC] FILENAME...
+
+Adds a track to the system. You specify the owner via the ``--id`` or
+``--email`` options, similar to the ``user modify`` command.
+
+One or multiple ``FILENAME`` might be given. Any supported input format may be
+used.
+
+The titles and dates are attempted to be read from the files. Other metadata
+(tags, images, ...) is left empty. The ``--visibility`` and ``--track-type``
+options can be used to set the visibility and type of the added tracks.
+
+For each file read, the resulting ID in the database is printed. If an error
+occurs for one file, the error is shown and the next track is read.
+
REMOVING A TRACK
################
diff --git a/fietsboek/scripts/fietsctl.py b/fietsboek/scripts/fietsctl.py
index fa751b7..bd6aae8 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,92 @@ def cmd_track_list(config: str):
)
+@cmd_track.command("add")
+@config_option
+@click.option(
+ "--visibility",
+ help="Visibility of the added tracks.",
+ type=click.Choice([vis.name for vis in models.track.Visibility]),
+ default="PUBLIC",
+)
+@click.option(
+ "--track-type",
+ help="Type of the added tracks.",
+ type=click.Choice([typ.name for typ in models.track.TrackType]),
+ default="ORGANIC",
+)
+@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,
+ visibility: str,
+ track_type: str,
+ id_: int | None,
+ email: str | None,
+ filename: list[str],
+):
+ """Add a track.
+
+ The track is added for the specified user (via --id/--email).
+ """
+ env = setup(config)
+ if id_ is not None:
+ query = select(models.User).filter_by(id=id_)
+ else:
+ query = models.User.query_by_email(email)
+ visibility = models.track.Visibility[visibility]
+ track_type = models.track.TrackType[track_type]
+ 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,
+ visibility,
+ track_type,
+ "",
+ [],
+ [],
+ [],
+ [],
+ 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)