From 5a26671dec17bf6c5a6e1852dca4646d95036ed2 Mon Sep 17 00:00:00 2001 From: Plom Heller Date: Mon, 3 Aug 2026 09:37:23 +0200 Subject: [PATCH] Re-organize into modularity handled by plomlib installer. --- .gitmodules | 3 + install.sh | 3 +- plomlib | 1 + src/bricksplom/__init__.py | 0 bricksplom.py => src/bricksplom/misc.py | 87 ++--------------------- src/run.py | 92 +++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 85 deletions(-) create mode 100644 .gitmodules create mode 160000 plomlib create mode 100644 src/bricksplom/__init__.py rename bricksplom.py => src/bricksplom/misc.py (90%) mode change 100755 => 100644 create mode 100755 src/run.py diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..42cf7f3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "plomlib"] + path = plomlib + url = https://plomlompom.com/repos/clone/plomlib diff --git a/install.sh b/install.sh index 0dc504b..6db0899 100755 --- a/install.sh +++ b/install.sh @@ -1,3 +1,2 @@ #!/usr/bin/sh -set -e -cp bricksplom.py ~/.local/bin/bricksplom +./plomlib/sh/install.sh bricksplom no_deps diff --git a/plomlib b/plomlib new file mode 160000 index 0000000..2f85135 --- /dev/null +++ b/plomlib @@ -0,0 +1 @@ +Subproject commit 2f851352484cd0f8ad415dd765163b4a94c95ba8 diff --git a/src/bricksplom/__init__.py b/src/bricksplom/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bricksplom.py b/src/bricksplom/misc.py old mode 100755 new mode 100644 similarity index 90% rename from bricksplom.py rename to src/bricksplom/misc.py index b12064c..ab22a1c --- a/bricksplom.py +++ b/src/bricksplom/misc.py @@ -1,18 +1,9 @@ -#!/usr/bin/env python3 -'Data structures for managing/sorting bricks of a certain kind.' +'Anything not peculiar.' from abc import ABC, abstractmethod -from argparse import ( - ArgumentError, - ArgumentParser, - Namespace as ArgumentNamespace, - ) from dataclasses import dataclass -from os import environ from pathlib import Path from typing import Callable, Optional, Self -NAME_ENV_DIRNAME = 'BRICKSPLOM_DIR' -NAME_ENV_LDRAW = 'PATH_LDRAW' LDRAW_STUDS = { 'stud.dat', 'studa.dat', @@ -44,7 +35,7 @@ CHAR_COL_SOLID = '+' CHAR_COL_TRANSPARENT = '-' BOX_PREFIX = 'box:' -ARG_Q_MARK = '?' +ARG_QMARK = '?' PARAM_Q_ID = f'id{CHAR_ATTR_EQ}' PARAM_Q_DELIMITERS = {CHAR_ATTR_EQ, CHAR_TEXTCONTAINS} TOK_SORT_BOX = 'box' @@ -449,7 +440,7 @@ class Brick(Textfiled, WithDb, Lookupable): collected = {} for toks in [cls.tokify(line, 3) for line in cls.lines_of(path)]: brick_id, design_id = toks[:2] - assert brick_id not in collected + assert brick_id not in collected, brick_id color_id, comment = (toks[-1].split(CHAR_SEP_TOKEN, maxsplit=1) + [''])[:2] collected[brick_id] = cls(brick_id, design_id, color_id, comment, @@ -849,7 +840,7 @@ class BricksDb: (sort_by, cls.sorters), (formatter, cls.formatters))]: keys = x_ers.keys() - if arg_key == ARG_Q_MARK: + if arg_key == ARG_QMARK: return CHAR_NEWLINE.join([f'{key} – {x_ers[key][0]}' for key in sorted(keys)]) assert (not arg_key) or arg_key in keys, (arg_key, keys) @@ -860,73 +851,3 @@ class BricksDb: items = tuple(x for x in items if x.match(match_key, match_val)) return CHAR_NEWLINE.join([cls.formatters()[formatter][1](item) for item in items]) - - -def main( - ) -> None: - 'Load tables from BRICKSPLOM_DIR and put out in reproducible listings.' - def parse_args( - ) -> ArgumentNamespace: - def add_abbreviable_table_arg( - ) -> None: - def complete( - arg: str - ) -> str: - candidates = tuple(c for c in choices if c.startswith(arg)) - if len(candidates) > 1: - raise ArgumentError( - action, - f'{arg} – ambiguous, matches: {", ".join(candidates)}') - return (candidates + (arg, ))[0] - choices = BricksDb.lookupables.keys() - msg = 'one of: ' + ', '.join(sorted(list(choices))) - msg += '; NB: abbreviable to first unambiguous character sequence' - action = parser.add_argument( - 'table', - choices=choices, type=complete, metavar='TABLE', help=msg) - parser = ArgumentParser() - add_abbreviable_table_arg() - hint_qmark = f'use "{ARG_Q_MARK}" to list options for chosen table' - hint_ldraw = 'allowed: ' + ', '.join(sorted(list(LDRAW_MODES))) - arg_match = '--match' - arg_item_id = 'ITEM_ID' - parser.add_argument( - arg_item_id.lower(), - nargs='?', metavar=arg_item_id, - help=f'shortcut to "{arg_match} {PARAM_Q_ID}{arg_item_id}"') - parser.add_argument( - '-f', '--format', - action='store', help=hint_qmark, default='default') - parser.add_argument( - '-m', arg_match, - action='store', help=hint_qmark, default='') - parser.add_argument( - '-s', '--sort', - action='store', help=hint_qmark, default=TOK_SORT_ID) - action_ldraw = parser.add_argument( - '-l', '--ldraw', - action='store', default='', - help=f'comma-separated; {hint_ldraw}') - args = parser.parse_args() - for _ in [m for m in args.ldraw.split(CHAR_SEP_LDRAW_MODES) - if m and m not in LDRAW_MODES]: - parser.error(str(ArgumentError(action_ldraw, hint_ldraw))) - if args.match != ARG_Q_MARK and args.item_id: - args.match = PARAM_Q_ID + args.item_id - return args - - args = parse_args() - db = BricksDb(environ.get(NAME_ENV_DIRNAME, '.'), - environ.get(NAME_ENV_LDRAW, ''), - args.ldraw) - print( - db.lookup( - table_name=args.table, - formatter=args.format, - match_by=args.match, - sort_by=args.sort - ).rstrip()) - - -if __name__ == '__main__': - main() diff --git a/src/run.py b/src/run.py new file mode 100755 index 0000000..8c841ae --- /dev/null +++ b/src/run.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +'Bricks inventory manager.' + +# standard libs +from argparse import ( + ArgumentError, + ArgumentParser, + Namespace as ArgumentNamespace, + ) +from os import environ +# ourselves +from bricksplom.misc import ( + BricksDb, + ARG_QMARK, + CHAR_SEP_LDRAW_MODES, + LDRAW_MODES, + PARAM_Q_ID, + TOK_SORT_ID, + ) + +NAME_ENV_DIRNAME = 'BRICKSPLOM_DIR' +NAME_ENV_LDRAW = 'PATH_LDRAW' + + +def main( + ) -> None: + 'Load tables from BRICKSPLOM_DIR and put out in reproducible listings.' + def parse_args( + ) -> ArgumentNamespace: + def add_abbreviable_table_arg( + ) -> None: + def complete( + arg: str + ) -> str: + candidates = tuple(c for c in choices if c.startswith(arg)) + if len(candidates) > 1: + raise ArgumentError( + action, + f'{arg} – ambiguous, matches: {", ".join(candidates)}') + return (candidates + (arg, ))[0] + choices = BricksDb.lookupables.keys() + msg = 'one of: ' + ', '.join(sorted(list(choices))) + msg += '; NB: abbreviable to first unambiguous character sequence' + action = parser.add_argument( + 'table', + choices=choices, type=complete, metavar='TABLE', help=msg) + parser = ArgumentParser() + add_abbreviable_table_arg() + hint_qmark = f'use "{ARG_QMARK}" to list options for chosen table' + hint_ldraw = 'allowed: ' + ', '.join(sorted(list(LDRAW_MODES))) + arg_match = '--match' + arg_item_id = 'ITEM_ID' + parser.add_argument( + arg_item_id.lower(), + nargs='?', metavar=arg_item_id, + help=f'shortcut to "{arg_match} {PARAM_Q_ID}{arg_item_id}"') + parser.add_argument( + '-f', '--format', + action='store', help=hint_qmark, default='default') + parser.add_argument( + '-m', arg_match, + action='store', help=hint_qmark, default='') + parser.add_argument( + '-s', '--sort', + action='store', help=hint_qmark, default=TOK_SORT_ID) + action_ldraw = parser.add_argument( + '-l', '--ldraw', + action='store', default='', + help=f'comma-separated; {hint_ldraw}') + args = parser.parse_args() + for _ in [m for m in args.ldraw.split(CHAR_SEP_LDRAW_MODES) + if m and m not in LDRAW_MODES]: + parser.error(str(ArgumentError(action_ldraw, hint_ldraw))) + if args.match != ARG_QMARK and args.item_id: + args.match = PARAM_Q_ID + args.item_id + return args + + args = parse_args() + db = BricksDb(environ.get(NAME_ENV_DIRNAME, '.'), + environ.get(NAME_ENV_LDRAW, ''), + args.ldraw) + print( + db.lookup( + table_name=args.table, + formatter=args.format, + match_by=args.match, + sort_by=args.sort + ).rstrip()) + + +if __name__ == '__main__': + main() -- 2.30.2