From 9b027954d13c0595a4eb3097597d318cafc418d2 Mon Sep 17 00:00:00 2001 From: Plom Heller Date: Sun, 2 Aug 2026 20:55:18 +0200 Subject: [PATCH] Add descriptors for "?" results on -m, -f, -s. --- bricksplom.py | 99 ++++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/bricksplom.py b/bricksplom.py index 0169813..6fd40af 100755 --- a/bricksplom.py +++ b/bricksplom.py @@ -46,7 +46,6 @@ BOX_PREFIX = 'box:' ARG_Q_MARK = '?' PARAM_Q_ID = f'id{CHAR_ATTR_EQ}' -PARAM_Q_TEXT = f'text{CHAR_TEXTCONTAINS}' PARAM_Q_DELIMITERS = {CHAR_ATTR_EQ, CHAR_TEXTCONTAINS} TOK_SORT_BOX = 'box' TOK_SORT_ID = 'id' @@ -58,6 +57,12 @@ LDRAW_MODES = {LDRAW_MODE_FILL_PATHS, LDRAW_MODE_VERIFY_PATHS, LDRAW_MODE_VERIFY_N_STUDS} +ATTR_DESCS: dict[str, str] = { + 'n_studs': 'number of studs', + 'description': 'guesstimate what this be', + 'ldraw': 'path of associated LDRAW file' +} + BrickListing = tuple[int, str, str] # count, ID, comment PageColumn = tuple[BrickListing, ...] Page = tuple[PageColumn, ...] @@ -153,25 +158,31 @@ class Lookupable: @classmethod def formatters( cls - ) -> dict[str, Callable[[Self], str]]: + ) -> dict[str, tuple[str, Callable[[Self], str]]]: 'Available per-item string formatters.' formatters = { - 'default': lambda item: item.show() + 'default': ( + 'most commonly relevant infos', + lambda item: item.show()) } if issubclass(cls, Textfiled): - formatters['raw'] = lambda item: item.raw() + formatters['raw'] = ( + 'in source-file format', + lambda item: item.raw()) return formatters @classmethod def matchers( cls - ) -> dict[str, Callable[[Self, str], bool]]: + ) -> dict[str, tuple[str, Callable[[Self, str], bool]]]: 'Available lookup matchers.' return { - PARAM_Q_ID: (lambda item, q_body: - item.id_ == q_body), - PARAM_Q_TEXT: (lambda item, q_body: - q_body.upper() in str(item).upper()) + PARAM_Q_ID: ( + 'by ID of individual item', + lambda item, q_body: item.id_ == q_body), + f'text{CHAR_TEXTCONTAINS}': ( + 'text contained in item description', + lambda item, q_body: q_body.upper() in item.show().upper()) } def match( @@ -180,13 +191,15 @@ class Lookupable: query_body: str ) -> bool: 'Return if self matches query.' - return self.matchers()[query_char](self, query_body) + return self.matchers()[query_char][1](self, query_body) @classmethod def _by_box_sorter( cls, to_id_of='' - ) -> Callable[['BricksDb', tuple[Self, ...]], tuple[Self, ...]]: + ) -> tuple[str, + Callable[['BricksDb', tuple[Self, ...]], + tuple[Self, ...]]]: def by_box( db: 'BricksDb', pre_sorted: tuple[Self, ...] @@ -204,18 +217,20 @@ class Lookupable: items += [to_move] remains.remove(to_move) return tuple(items + remains) - return by_box + return 'by IDs of containing boxes', by_box @classmethod def sorters( cls - ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]], - tuple[Self, ...]]]: + ) -> dict[str, tuple[str, Callable[['BricksDb', tuple[Self, ...]], + tuple[Self, ...]]]]: 'Available sorters.' return { - TOK_SORT_ID: (lambda _, pre_sorted: - tuple(sorted(pre_sorted, - key=lambda item: item.id_indented()))) + TOK_SORT_ID: ( + 'by individual items\' IDs', + lambda _, pre_sorted: + tuple(sorted(pre_sorted, + key=lambda item: item.id_indented()))) } @@ -250,8 +265,9 @@ class BrickColor(Textfiled, Lookupable): @classmethod def sorters( cls - ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]], - tuple[Self, ...]]]: + ) -> dict[str, tuple[str, + Callable[['BricksDb', tuple[Self, ...]], + tuple[Self, ...]]]]: return super().sorters() | {TOK_SORT_BOX: cls._by_box_sorter('color')} def raw( @@ -305,17 +321,17 @@ class BrickDesign(Textfiled, Lookupable): @classmethod def matchers( cls - ) -> dict[str, Callable[[Self, str], bool]]: + ) -> dict[str, tuple[str, Callable[[Self, str], bool]]]: def attr_matcher( attr_name: str - ) -> Callable[[Self, str], bool]: + ) -> tuple[str, Callable[[Self, str], bool]]: def match( item: Self, q_body: str ) -> bool: assert q_body.isdigit() return getattr(item, attr_name) == int(q_body) - return match + return 'by ' + ATTR_DESCS[attr_name], match return super().matchers() | { f'{attr_name}{CHAR_ATTR_EQ}': attr_matcher(attr_name) for attr_name, attr_type in BrickDesignData.__annotations__.items() @@ -324,18 +340,20 @@ class BrickDesign(Textfiled, Lookupable): @classmethod def sorters( cls - ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]], - tuple[Self, ...]]]: + ) -> dict[str, tuple[str, + Callable[['BricksDb', tuple[Self, ...]], + tuple[Self, ...]]]]: def attr_sorter( attr_name: str, - ) -> Callable[[BricksDb, tuple[Self, ...]], tuple[Self, ...]]: + ) -> tuple[str, Callable[[BricksDb, tuple[Self, ...]], + tuple[Self, ...]]]: def f_sort( _: BricksDb, pre_sorted: tuple[Self, ...] ) -> tuple[Self, ...]: return tuple(sorted(pre_sorted, key=lambda item: getattr(item, attr_name))) - return f_sort + return 'by ' + ATTR_DESCS[attr_name], f_sort return super().sorters()\ | {TOK_SORT_BOX: cls._by_box_sorter('design')}\ | {attr_name: attr_sorter(attr_name) @@ -415,8 +433,8 @@ class Brick(Textfiled, WithDb, Lookupable): @classmethod def sorters( cls - ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]], - tuple[Self, ...]]]: + ) -> dict[str, tuple[str, Callable[['BricksDb', tuple[Self, ...]], + tuple[Self, ...]]]]: return super().sorters() | {TOK_SORT_BOX: cls._by_box_sorter()} @classmethod @@ -537,15 +555,6 @@ class BrickSet(Textfiled, WithDb, Lookupable): ) -> str: return f'{self.id_} {self._is_in_str} {self.description}' - @classmethod - def matchers( - cls - ) -> dict[str, Callable[[Self, str], bool]]: - return super().matchers() | { - PARAM_Q_TEXT: (lambda item, q_body: - q_body.upper() in item.show().upper()) - } - def _format_paginated( self, format_line: Callable[[int, str, str], str] @@ -823,19 +832,21 @@ class BricksDb: match_val = match_by[idx+1:] break cls = self.lookupables[table_name] - for arg_key, keys in [(arg, m().keys()) - for arg, m in ((match_key, cls.matchers), - (sort_by, cls.sorters), - (formatter, cls.formatters))]: + for arg_key, x_ers in [(arg, m()) + for arg, m in ((match_key, cls.matchers), + (sort_by, cls.sorters), + (formatter, cls.formatters))]: + keys = x_ers.keys() if arg_key == ARG_Q_MARK: - return CHAR_NEWLINE.join(keys) + 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) items = tuple(getattr(self, table_name).values()) if items and sort_by: - items = cls.sorters()[sort_by](self, items) + items = cls.sorters()[sort_by][1](self, items) if items and match_by: items = tuple(x for x in items if x.match(match_key, match_val)) - return CHAR_NEWLINE.join([cls.formatters()[formatter](item) + return CHAR_NEWLINE.join([cls.formatters()[formatter][1](item) for item in items]) -- 2.30.2