From: Plom Heller Date: Sat, 30 May 2026 03:48:14 +0000 (+0200) Subject: Streamline querying. X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/static/%7B%7Bdb.prefix%7D%7D/%7B%7Bprefix%7D%7D?a=commitdiff_plain;ds=sidebyside;p=bricksplom Streamline querying. --- diff --git a/bricksplom.py b/bricksplom.py index d826f77..8aed7e6 100755 --- a/bricksplom.py +++ b/bricksplom.py @@ -25,7 +25,9 @@ CHAR_COLL_SEP_COLUMN = '-' CHAR_COLL_SEP_PAGE = '=' CHAR_COL_SOLID = '+' CHAR_COL_TRANSPARENT = '-' -CHAR_INQUIRY = '?' +CHAR_Q_EQ_ID = ':' +CHAR_Q_STUDS = 's' +CHAR_Q_TEXT = '?' BOX_PREFIX = 'box:' PieceListing = tuple[int, str, str] @@ -101,19 +103,18 @@ class Lookupable: id_: str @classmethod - def indent_id(cls, id_: str) -> str: + def indent_id( + cls, + id_: str + ) -> str: 'id_ indented by value of cls._id_indent.' return (max(0, cls._id_indent - len(id_)) * ' ') + id_ - def id_indented(self) -> str: - 'self.id_ indented by value of self._id_indent.' - return self.indent_id(self.id_) - - def searchable( + def id_indented( self ) -> str: - 'String analyzed by "?" full-text searches.' - return str(self) + 'self.id_ indented by value of self._id_indent.' + return self.indent_id(self.id_) def show( self @@ -121,6 +122,24 @@ class Lookupable: 'Default single-item display of self.' return str(self) + @property + def matchers( + self + ) -> dict[str, Callable[[str], bool]]: + 'Available lookup matchers.' + return { + CHAR_Q_TEXT: lambda q_body: q_body.upper() in str(self).upper() + } + + def match( + self, + query_char: str, + query_body: str + ) -> bool: + 'Return if self matches query.' + assert query_char in self.matchers + return self.matchers[query_char](query_body) + class Color(Textfiled, Lookupable): 'Color incl. solidness/transparency field.' @@ -197,6 +216,15 @@ class Design(Textfiled, Lookupable): 'Own .id_ plus (sorted) .alternate_ids.' return tuple([self.id_] + sorted(list(self.alternate_ids))) + @property + def matchers( + self + ) -> dict[str, Callable[[str], bool]]: + def q_studs(q_body) -> bool: + assert q_body.isdigit() + return self.n_studs == int(q_body) + return super().matchers | {CHAR_Q_STUDS: q_studs} + @classmethod def from_textfile( cls, @@ -230,7 +258,7 @@ class Design(Textfiled, Lookupable): ) -> str: return (f'{self.id_indented()} ' + (f'={self.alternate_to.id_}' if self.alternate_to - else ('_' + else (CHAR_DESIGN_DESC + ('?' if self._n_studs < 0 else str(self._n_studs)) + f' {self._description}'))) @@ -368,10 +396,13 @@ class Collection(Textfiled, WithDb, Lookupable): ) -> str: return f'{self.id_} {self._is_in_str} {self.description}' - def searchable( + @property + def matchers( self - ) -> str: - return self.show() + ) -> dict[str, Callable[[str], bool]]: + return super().matchers | { + CHAR_Q_TEXT: lambda q_body: q_body.upper() in self.show().upper() + } def _format_paginated( self, @@ -568,22 +599,14 @@ class BricksDb: assert table_name in self.lookupable maybe_dict = getattr(self, table_name) table = maybe_dict if isinstance(maybe_dict, dict) else maybe_dict() - if inquiry.startswith(CHAR_INQUIRY): - return CHAR_NEWLINE.join( - [(v.raw() if show_raw else str(v)) for - v in sorted(table.values(), - key=lambda v: f'{v.id_indented()}') - if inquiry[1:].upper() in str(v.searchable()).upper()]) - if table_name == 'designs' and inquiry.startswith('s'): - n_studs_str = inquiry[1:] - assert n_studs_str.isdigit() - return CHAR_NEWLINE.join( - [(v.raw() if show_raw else str(v)) for - v in sorted(table.values(), - key=lambda v: f'{v.id_indented()}') - if v.n_studs == int(n_studs_str)]) - item = table[inquiry] - return item.raw() if show_raw else item.show() + query_char, query_body = inquiry[0], inquiry[1:] + if query_char == CHAR_Q_EQ_ID: + item = table[query_body] + return item.raw() if show_raw else item.show() + return CHAR_NEWLINE.join( + [(r.raw() if show_raw else str(r)) for + r in sorted(table.values(), key=lambda r: r.id_indented()) + if r.match(query_char, query_body)]) def main( @@ -608,7 +631,7 @@ def main( db = BricksDb(environ.get(NAME_ENV_DIRNAME, '.')) parser = ArgumentParser() add_abbrev_choices_arg(parser, 'table', set(db.lookupable)) - parser.add_argument('inquiry', nargs='?', default=CHAR_INQUIRY) + parser.add_argument('inquiry', nargs='?', default=CHAR_Q_TEXT) parser.add_argument('--raw', action='store_true') args = parser.parse_args() print(db.lookup(args.table, args.inquiry, args.raw).rstrip())