From 673ec68f5cfc3f15790a1b979a3719d99d56a722 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 11 May 2023 23:14:45 +0200 Subject: add fietsctl track list Especially the sizes might be useful to have, we should also add this to the admin web view at some point. --- fietsboek/data.py | 11 +++++++++++ fietsboek/scripts/fietsctl.py | 35 ++++++++++++++++++++++++++++++++++- fietsboek/util.py | 19 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/fietsboek/data.py b/fietsboek/data.py index 7457986..6bb2c8c 100644 --- a/fietsboek/data.py +++ b/fietsboek/data.py @@ -5,6 +5,7 @@ the database itself. This module makes access to such data objects easier. """ import datetime import logging +import os import random import shutil import string @@ -242,6 +243,16 @@ class TrackDataDir: shutil.move(self.path, new_name) self.journal.append(("purge", new_name)) + def size(self) -> int: + """Returns the size of the data that this track entails. + + :return: The size of bytes that this track consumes. + """ + size = 0 + for root, _, files in os.walk(self.path): + size += sum(os.path.getsize(os.path.join(root, fname)) for fname in files) + return size + def gpx_path(self) -> Path: """Returns the path of the GPX file. diff --git a/fietsboek/scripts/fietsctl.py b/fietsboek/scripts/fietsctl.py index 39d9e8a..913da69 100644 --- a/fietsboek/scripts/fietsctl.py +++ b/fietsboek/scripts/fietsctl.py @@ -8,7 +8,7 @@ from pyramid.paster import bootstrap, setup_logging from pyramid.scripting import AppEnvironment from sqlalchemy import select -from .. import __VERSION__, hittekaart, models +from .. import __VERSION__, hittekaart, models, util from ..data import DataManager from . import config_option @@ -311,6 +311,39 @@ def cmd_user_hittekaart( click.echo(f"Generated {mode.value}") +@cli.group("track") +def cmd_track(): + """Management functions for tracks.""" + + +@cmd_track.command("list") +@config_option +def cmd_track_list(config: str): + """List all tracks that are present in the system.""" + env = setup(config) + total_size = 0 + total_tracks = 0 + with env["request"].tm: + dbsession = env["request"].dbsession + data_manager: DataManager = env["request"].data_manager + tracks = dbsession.execute(select(models.Track)).scalars() + for track in tracks: + total_tracks += 1 + try: + track_size = data_manager.open(track.id).size() + except FileNotFoundError: + size = "---" + else: + total_size += track_size + size = util.human_size(track_size) + click.echo( + f"{track.id:>4} - {size:>10} - {track.owner.name} <{track.owner.email}>" + f" - {track.title}" + ) + click.echo("-" * 80) + click.echo(f"Total: {total_tracks} - {util.human_size(total_size)}") + + @cli.command("maintenance-mode") @config_option @click.option("--disable", help="Disable the maintenance mode.", is_flag=True) diff --git a/fietsboek/util.py b/fietsboek/util.py index a296151..ecd2f31 100644 --- a/fietsboek/util.py +++ b/fietsboek/util.py @@ -202,6 +202,25 @@ def mps_to_kph(mps: float) -> float: return mps / 1000 * 60 * 60 +def human_size(num_bytes: int) -> str: + """Formats the amount of bytes for human consumption. + + :param num_bytes: The amount of bytes. + :return: The formatted amount. + """ + num_bytes = float(num_bytes) + suffixes = ["B", "KiB", "MiB", "GiB"] + for suffix in suffixes: + if num_bytes < 1024 or suffix == suffixes[-1]: + if suffix == "B": + # Don't do the decimal point for bytes + return f"{int(num_bytes)} {suffix}" + return f"{num_bytes:.1f} {suffix}" + num_bytes /= 1024 + # Unreachable: + return "" + + def month_name(request: Request, month: int) -> str: """Returns the localized name for the month with the given number. -- cgit v1.2.3