refactor: yield GroupBySource instead of slugified key

This commit is contained in:
relikd
2022-12-20 00:11:51 +01:00
parent 7582029abf
commit 85df707d63
2 changed files with 20 additions and 11 deletions

View File

@@ -23,16 +23,21 @@ class GroupBy:
self._building = False self._building = False
self._watcher = [] # type: List[Watcher] self._watcher = [] # type: List[Watcher]
self._results = [] # type: List[GroupBySource] self._results = [] # type: List[GroupBySource]
self._pre_build_priority = [] # type: List[str] # config.key
self.resolver = resolver self.resolver = resolver
@property @property
def isBuilding(self) -> bool: def isBuilding(self) -> bool:
return self._building return self._building
def add_watcher(self, key: str, config: 'AnyConfig') -> Watcher: def add_watcher(
self, key: str, config: 'AnyConfig', *, pre_build: bool = False
) -> Watcher:
''' Init Config and add to watch list. ''' ''' Init Config and add to watch list. '''
w = Watcher(Config.from_any(key, config)) w = Watcher(Config.from_any(key, config))
self._watcher.append(w) self._watcher.append(w)
if pre_build:
self._pre_build_priority.append(w.config.key)
return w return w
def queue_all(self, builder: 'Builder') -> None: def queue_all(self, builder: 'Builder') -> None:
@@ -56,6 +61,10 @@ class GroupBy:
for w in self._watcher: for w in self._watcher:
if w.should_process(record): if w.should_process(record):
w.remember(record) w.remember(record)
# build sources which need building before actual lektor build
if self._pre_build_priority:
self.make_once(self._pre_build_priority)
self._pre_build_priority.clear()
def make_once(self, filter_keys: Optional[Iterable[str]] = None) -> None: def make_once(self, filter_keys: Optional[Iterable[str]] = None) -> None:
''' '''

View File

@@ -19,7 +19,7 @@ class GroupByCallbackArgs(NamedTuple):
GroupingCallback = Callable[[GroupByCallbackArgs], Union[ GroupingCallback = Callable[[GroupByCallbackArgs], Union[
Iterator[Any], Iterator[Any],
Generator[Any, Optional[str], None], Generator[Any, Optional[GroupBySource], None],
]] ]]
@@ -73,19 +73,19 @@ class Watcher:
key_obj = next(_gen) key_obj = next(_gen)
while True: while True:
if self.config.key_obj_fn: if self.config.key_obj_fn:
slug = self._persist_multiple(args, key_obj) vobj = self._persist_multiple(args, key_obj)
else: else:
slug = self._persist(args, key_obj) vobj = self._persist(args, key_obj)
# return slugified key and continue iteration # return groupby virtual object and continue iteration
if isinstance(_gen, Generator) and not _gen.gi_yieldfrom: if isinstance(_gen, Generator) and not _gen.gi_yieldfrom:
key_obj = _gen.send(slug) key_obj = _gen.send(vobj)
else: else:
key_obj = next(_gen) key_obj = next(_gen)
except StopIteration: except StopIteration:
del _gen del _gen
def _persist_multiple(self, args: 'GroupByCallbackArgs', obj: Any) \ def _persist_multiple(self, args: 'GroupByCallbackArgs', obj: Any) \
-> Optional[str]: -> Optional[GroupBySource]:
# if custom key mapping function defined, use that first # if custom key mapping function defined, use that first
res = self.config.eval_key_obj_fn(on=args.record, res = self.config.eval_key_obj_fn(on=args.record,
context={'X': obj, 'ARGS': args}) context={'X': obj, 'ARGS': args})
@@ -96,8 +96,8 @@ class Watcher:
return self._persist(args, res) # normal & null replacement return self._persist(args, res) # normal & null replacement
def _persist(self, args: 'GroupByCallbackArgs', obj: Any) \ def _persist(self, args: 'GroupByCallbackArgs', obj: Any) \
-> Optional[str]: -> Optional[GroupBySource]:
''' Update internal state. Return slugified string. ''' ''' Update internal state. Return grouping parent. '''
if not isinstance(obj, (str, bool, int, float)) and obj is not None: if not isinstance(obj, (str, bool, int, float)) and obj is not None:
raise ValueError( raise ValueError(
'Unsupported groupby yield type for [{}]:' 'Unsupported groupby yield type for [{}]:'
@@ -113,7 +113,7 @@ class Watcher:
slug = self.config.slugify(str(obj)) or None slug = self.config.slugify(str(obj)) or None
# if neither custom mapping succeeded, do not process further # if neither custom mapping succeeded, do not process further
if not slug or obj is None: if not slug or obj is None:
return slug return None
# update internal object storage # update internal object storage
alt = args.record.alt alt = args.record.alt
if slug not in self._state[alt]: if slug not in self._state[alt]:
@@ -125,7 +125,7 @@ class Watcher:
src.append_child(args.record, obj) src.append_child(args.record, obj)
# reverse reference # reverse reference
VGroups.of(args.record).add(args.key, src) VGroups.of(args.record).add(args.key, src)
return slug return src
def remember(self, record: 'Record') -> None: def remember(self, record: 'Record') -> None:
self._rmmbr.append(record) self._rmmbr.append(record)