CHAR_Q_STUDS = 's'
CHAR_Q_TEXT = '?'
BOX_PREFIX = 'box:'
+TOK_SORT_BOX = 'box'
+TOK_SORT_ID = 'id'
+TOK_SORT_STUDS = 'studs'
-BrickListing = tuple[int, str, str]
+BrickListing = tuple[int, str, str] # count, ID, comment
PageColumn = tuple[BrickListing, ...]
Page = tuple[PageColumn, ...]
assert query_char in self.matchers, query_char
return self.matchers[query_char](query_body)
+ @classmethod
+ def _by_box_sorter(
+ cls,
+ to_id_of=''
+ ) -> Callable[['BricksDb', tuple[Self, ...]], tuple[Self, ...]]:
+ def by_box(
+ db: 'BricksDb',
+ pre_sorted: tuple[Self, ...]
+ ) -> tuple[Self, ...]:
+ remains = list(pre_sorted)
+ items: list[Self] = []
+ for box in sorted(db.boxes().values(),
+ key=lambda box: box.id_indented()):
+ for item_id in [t[1] for t in box.brick_listings_flat()]:
+ if to_id_of:
+ item_id = getattr(db.bricks[item_id], f'{to_id_of}_id')
+ if item_id not in [item.id_ for item in items]:
+ to_move = [item for item in remains
+ if item.id_ == item_id][0]
+ items += [to_move]
+ remains.remove(to_move)
+ return tuple(items + remains)
+ return by_box
+
+ @property
+ def sorters(
+ self
+ ) -> dict[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()))
+ }
+
class BrickColor(Textfiled, Lookupable):
'Color incl. solidness/transparency field.'
collected[id_] = cls(id_, desc[0] == CHAR_COL_SOLID, desc[1:])
return collected
+ @property
+ def sorters(
+ self
+ ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]],
+ tuple[Self, ...]]]:
+ return super().sorters | {TOK_SORT_BOX: self._by_box_sorter('color')}
+
def raw(
self
) -> str:
def matchers(
self
) -> dict[str, Callable[[str], bool]]:
- def q_studs(q_body) -> 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}
+ @property
+ def sorters(
+ self
+ ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]],
+ tuple[Self, ...]]]:
+ return super().sorters | {
+ TOK_SORT_BOX: self._by_box_sorter('design'),
+ TOK_SORT_STUDS: lambda _, pre_sorted: tuple(
+ sorted(pre_sorted, key=lambda item: item.n_studs))
+ }
+
@classmethod
def from_textfile(
cls,
self.comment = comment
super().__init__(**kwargs)
+ @property
+ def sorters(
+ self
+ ) -> dict[str, Callable[['BricksDb', tuple[Self, ...]],
+ tuple[Self, ...]]]:
+ return super().sorters | {TOK_SORT_BOX: self._by_box_sorter()}
+
@classmethod
def from_textfile(
cls,
self.id_ = id_
self._set = bricks_set
designed_listings: list[tuple[BrickDesign, list[BrickListing]]] = []
- for listing in self._set.brick_listings_flat():
+ for listing in self.brick_listings_flat():
design = self._db.designs[self._db.bricks[listing[1]].design_id]
design = design.alternate_to or design
if not (designed_listings and designed_listings[-1][0] == design):
+ ', '.join('/'.join(design.all_ids)
for design, _ in self.designs_to_listings))
+ def brick_listings_flat(
+ self
+ ) -> tuple[BrickListing, ...]:
+ 'Shortcut to BrickSet method of same name.'
+ return self._set.brick_listings_flat()
+
def show(
self,
) -> str:
table_name: str,
item_id: str,
show_raw: bool,
- filter_by: str
+ filter_by: str,
+ sort_by: str
) -> str:
'Return result of inquiry on table of table_name.'
assert table_name in self.lookupable
table = maybe_dict if isinstance(maybe_dict, dict) else maybe_dict()
if item_id:
filter_by = CHAR_Q_ID + item_id
- items = sorted(table.values(), key=lambda x: x.id_indented())
+ items = tuple(table.values())
+ if items and sort_by:
+ items = items[0].sorters[sort_by](self, items)
if filter_by:
- items = [item for item in items
- if item.match(filter_by[0], filter_by[1:])]
- return CHAR_NEWLINE.join([(item.raw() if show_raw else str(item))
- for item in items])
+ items = tuple(item for item in items
+ if item.match(filter_by[0], filter_by[1:]))
+ return CHAR_NEWLINE.join(
+ [(item.raw() if isinstance(item, Textfiled) and show_raw
+ else str(item))
+ for item in items])
def main(
parser.add_argument('item_id', nargs='?', metavar='ITEM_ID')
parser.add_argument('-r', '--raw', action='store_true')
parser.add_argument('-f', '--filter-by', action='store')
+ parser.add_argument('-s', '--sort-by', action='store', default=TOK_SORT_ID)
args = parser.parse_args()
print(
db.lookup(
table_name=args.table,
item_id=args.item_id,
show_raw=args.raw,
- filter_by=args.filter_by
+ filter_by=args.filter_by,
+ sort_by=args.sort_by
).rstrip())