Source code for spil.sid.read.finders.find_constants

"""
This file is part of SPIL, The Simple Pipeline Lib.

(C) copyright 2019-2023 Michael Haussmann, spil@xeo.info

SPIL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

SPIL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with SPIL.
If not, see <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
from typing import Iterator, List

from spil import Sid, Finder
from spil.sid.read.finders.find_glob import FindByGlob
from spil.util.exception import SpilException
from spil.util.log import debug


[docs]class FindInConstants(FindByGlob): """ Finds Sid from a list, for a specific type. Whereas FindInList looks inside a list of Sids, FindInConstants looks inside a list for one specific keytype. Implements star_search for a specific key, by getting the values from a given, constant, list. If there is a search "above" the given key, the search is delegated to the given "parent_source". This is used to create a Data Source for constant values. Examples: We instantiate a parent Finder >>> from spil import FindInPaths >>> fp = FindInPaths() Finding a constant list of asset types >>> finder = FindInConstants('assettype', ['char', 'location', 'prop', 'fx'], parent_source=fp) >>> list( finder.find('hamlet/a/*') ) [Sid('asset__assettype:hamlet/a/char'), Sid('asset__assettype:hamlet/a/location'), Sid('asset__assettype:hamlet/a/prop'), Sid('asset__assettype:hamlet/a/fx')] Search "above" in the hierarchy is delegated to the parent >>> list( finder.find('hamlet/*/prop') ) [Sid('asset__assettype:hamlet/a/prop')] Other examples, defining a constant list of "states" and searching for states >>> finder_states = FindInConstants('state', ["w", "p"], parent_source=fp) >>> list( finder_states.find('hamlet/a/location/ramparts/rig/v001/*') ) [Sid('asset__state:hamlet/a/location/ramparts/rig/v001/w'), Sid('asset__state:hamlet/a/location/ramparts/rig/v001/p')] Finding a state with a parent search >>> list( finder_states.find('hamlet/a/location/ramparts/rig/*/p') ) [Sid('asset__state:hamlet/a/location/ramparts/rig/v001/p'), Sid('asset__state:hamlet/a/location/ramparts/rig/v002/p')] Finding a state with a multi-parent search >>> sorted(list( finder_states.find('hamlet/a/location/*/rig/*/p') )) [Sid('asset__state:hamlet/a/location/elsinore/rig/v001/p'), Sid('asset__state:hamlet/a/location/elsinore/rig/v002/p'), Sid('asset__state:hamlet/a/location/garden/rig/v001/p'), Sid('asset__state:hamlet/a/location/garden/rig/v002/p'), Sid('asset__state:hamlet/a/location/lakeside/rig/v001/p'), Sid('asset__state:hamlet/a/location/lakeside/rig/v002/p'), Sid('asset__state:hamlet/a/location/queens_chamber/rig/v001/p'), Sid('asset__state:hamlet/a/location/queens_chamber/rig/v002/p'), Sid('asset__state:hamlet/a/location/ramparts/rig/v001/p'), Sid('asset__state:hamlet/a/location/ramparts/rig/v002/p')] Combining parent and constant search >>> list( finder_states.find('hamlet/a/location/ramparts/rig/*/*') ) [Sid('asset__state:hamlet/a/location/ramparts/rig/v001/w'), Sid('asset__state:hamlet/a/location/ramparts/rig/v001/p'), Sid('asset__state:hamlet/a/location/ramparts/rig/v002/w'), Sid('asset__state:hamlet/a/location/ramparts/rig/v002/p')] Finds itself if needed. >>> list( finder_states.find('hamlet/a/location/ramparts/rig/v001/p') ) [Sid('asset__state:hamlet/a/location/ramparts/rig/v001/p')] This is still beta code. """
[docs] def __init__(self, key: str, values: List[str], parent_source: Finder | None = None): # noqa """ Args: key: the keytype for which this Finder operates. values: the list of values that this Finder always finds, for the given key. parent_source: delegates to this finder for searches above the keytype (parents of the keytype) """ self.key = key self.values = values self.parent_source = parent_source
def _append_value( self, root: Sid, done: set, as_sid: bool = False ) -> Iterator[Sid] | Iterator[str]: """ This method fills the keytype with the values, by appending them to the parent root. Args: root: done: as_sid: Returns: """ for value in self.values: result = root.get_with(key=self.key, value=value) if not result: debug(f'Generated Sid "{result}" is not valid, skipped (used {self.key}:{value})') continue if result not in done: # done.add(result) if as_sid: yield result else: yield str(result) def __str__(self): return f'[spil.{self.__class__.__name__} -- Key: "{self.key}" -- values: {self.values} -- parent source: \n\t"{self.parent_source}"]'
if __name__ == "__main__": from spil.conf import projects, asset_types from spil.util.log import setLevel, WARN setLevel(WARN) cs1 = FindInConstants("project", projects) cs2 = FindInConstants("type", ["a", "s"], parent_source=cs1) cs3 = FindInConstants("assettype", asset_types, parent_source=cs2) cs4 = FindInConstants("sequence", ["sq088"], parent_source=cs2) print(cs2) for i in cs1.find("*"): print(f"sid: {i} / {type(i)} / path: {i.path()}") print("-" * 20) for i in cs2.find("hamlet/*"): print(f"sid: {i} / {type(i)} / path: {i.path()}") print("-" * 20) for i in cs3.find("hamlet/*/*"): print(f"sid: {i} / {type(i)} / path: {i.path()}") print("-" * 20) for i in cs4.find("hamlet/*/*"): print(f"sid: {i} / {type(i)} / path: {i.path()}") print("-" * 20)