tgzr.cuisine 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tgzr/cuisine/__init__.py +0 -0
- tgzr/cuisine/_version.py +34 -0
- tgzr/cuisine/basics/__init__.py +35 -0
- tgzr/cuisine/basics/buildable.py +38 -0
- tgzr/cuisine/basics/builder.py +72 -0
- tgzr/cuisine/basics/computable.py +33 -0
- tgzr/cuisine/basics/editable.py +28 -0
- tgzr/cuisine/basics/editor.py +29 -0
- tgzr/cuisine/basics/env.py +216 -0
- tgzr/cuisine/basics/files_recipes/__init__.py +18 -0
- tgzr/cuisine/basics/panels/__init__.py +0 -0
- tgzr/cuisine/basics/panels/params_panel.py +540 -0
- tgzr/cuisine/basics/product.py +32 -0
- tgzr/cuisine/basics/recipe_contexts.py +10 -0
- tgzr/cuisine/basics/recipe_with_params.py +119 -0
- tgzr/cuisine/basics/viewable.py +33 -0
- tgzr/cuisine/basics/viewer.py +30 -0
- tgzr/cuisine/basics/workscene.py +5 -0
- tgzr/cuisine/chef.py +339 -0
- tgzr/cuisine/cli/__init__.py +232 -0
- tgzr/cuisine/cli/main.py +7 -0
- tgzr/cuisine/cli/utils.py +31 -0
- tgzr/cuisine/plugin.py +27 -0
- tgzr/cuisine/recipe.py +361 -0
- tgzr/cuisine/workbench.py +455 -0
- tgzr_cuisine-0.0.1.dist-info/METADATA +34 -0
- tgzr_cuisine-0.0.1.dist-info/RECORD +30 -0
- tgzr_cuisine-0.0.1.dist-info/WHEEL +4 -0
- tgzr_cuisine-0.0.1.dist-info/entry_points.txt +8 -0
- tgzr_cuisine-0.0.1.dist-info/licenses/LICENSE +674 -0
tgzr/cuisine/__init__.py
ADDED
|
File without changes
|
tgzr/cuisine/_version.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.0.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 1)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING, Type
|
|
3
|
+
|
|
4
|
+
from ..plugin import CuisinePlugin
|
|
5
|
+
|
|
6
|
+
from ..recipe import Recipe
|
|
7
|
+
from .recipe_with_params import RecipeWithParams
|
|
8
|
+
|
|
9
|
+
from .computable import Computable
|
|
10
|
+
from .files_recipes import FileRecipe
|
|
11
|
+
from .workscene import WorkScene
|
|
12
|
+
from .env import Env
|
|
13
|
+
from .editable import Editable
|
|
14
|
+
from .editor import Editor
|
|
15
|
+
from .buildable import Buildable
|
|
16
|
+
from .builder import Builder
|
|
17
|
+
from .viewable import Viewable
|
|
18
|
+
from .viewer import Viewer
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class BasicsPlugin(CuisinePlugin):
|
|
22
|
+
|
|
23
|
+
def get_recipe_types(self) -> list[Type[Recipe]]:
|
|
24
|
+
return [
|
|
25
|
+
Computable,
|
|
26
|
+
FileRecipe,
|
|
27
|
+
WorkScene,
|
|
28
|
+
Env,
|
|
29
|
+
Editable,
|
|
30
|
+
Editor,
|
|
31
|
+
Buildable,
|
|
32
|
+
Builder,
|
|
33
|
+
Viewable,
|
|
34
|
+
Viewer,
|
|
35
|
+
]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from .recipe_contexts import CookContext
|
|
5
|
+
from tgzr.cuisine.recipe import RecipeTypeInfo
|
|
6
|
+
from tgzr.cuisine.basics.files_recipes import FileRecipe
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@CookContext.context_type
|
|
10
|
+
class BuildContext(CookContext):
|
|
11
|
+
to_build: Buildable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Buildable(FileRecipe):
|
|
15
|
+
"""
|
|
16
|
+
A Recipe which cooks its 'build' input in its context.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
RECIPE_TYPE_INFO = RecipeTypeInfo(
|
|
20
|
+
category="Build",
|
|
21
|
+
color="#FF8800",
|
|
22
|
+
icon="sym_o_brick",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def build_if_needed(self):
|
|
26
|
+
if not self.file_exists():
|
|
27
|
+
CookContext.current().log(
|
|
28
|
+
f"Scene {self.file_path()} is missing, we need to build it."
|
|
29
|
+
)
|
|
30
|
+
self.build()
|
|
31
|
+
|
|
32
|
+
def build(self):
|
|
33
|
+
builder = self.get_unique_input("build")
|
|
34
|
+
with CookContext.get(BuildContext, recipe=builder, to_build=self):
|
|
35
|
+
builder.cook()
|
|
36
|
+
|
|
37
|
+
def cook(self):
|
|
38
|
+
self.build_if_needed()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from tgzr.cuisine.recipe import Recipe, RecipeTypeInfo
|
|
6
|
+
from tgzr.cuisine.basics.recipe_contexts import CookContext
|
|
7
|
+
from tgzr.cuisine.basics.buildable import BuildContext, Buildable
|
|
8
|
+
from tgzr.cuisine.basics.product import Product
|
|
9
|
+
from tgzr.cuisine.basics.env import Env, EnvBuilder
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Builder(Recipe):
|
|
13
|
+
"""
|
|
14
|
+
An Recipe which will build the 'file' from the current Buildable Recipe when
|
|
15
|
+
cooked.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def as_buildable(self, asset) -> Buildable | None:
|
|
19
|
+
if not isinstance(asset, Buildable):
|
|
20
|
+
return None
|
|
21
|
+
return asset
|
|
22
|
+
|
|
23
|
+
def as_product(self, asset) -> Product | None:
|
|
24
|
+
if not isinstance(asset, Product):
|
|
25
|
+
return None
|
|
26
|
+
return asset
|
|
27
|
+
|
|
28
|
+
def as_env(self, asset) -> Env | None:
|
|
29
|
+
if not isinstance(asset, Env):
|
|
30
|
+
return None
|
|
31
|
+
return asset
|
|
32
|
+
|
|
33
|
+
def build(self):
|
|
34
|
+
ctx = BuildContext.current()
|
|
35
|
+
if ctx is None:
|
|
36
|
+
raise Exception("Cannot build an Recipe outside of an EditContext.")
|
|
37
|
+
|
|
38
|
+
with ctx.log_group(
|
|
39
|
+
f"Cooking Products & Envs connected to {ctx.to_build.name!r}"
|
|
40
|
+
):
|
|
41
|
+
env_inputs = self.get_typed_inputs(Env, "")
|
|
42
|
+
env_builder = EnvBuilder()
|
|
43
|
+
for name, env_input in env_inputs.items():
|
|
44
|
+
env_builder.add_bases(env_input.cook())
|
|
45
|
+
env = {}
|
|
46
|
+
env_builder.apply_to(env)
|
|
47
|
+
ctx.log(f"Env computed: {env}")
|
|
48
|
+
|
|
49
|
+
product_inputs = self.get_typed_inputs(Product, "")
|
|
50
|
+
for name, product_input in product_inputs.items():
|
|
51
|
+
with ctx.log_group(f"Cooking Product {name!r}"):
|
|
52
|
+
product_input.cook()
|
|
53
|
+
ctx.log(f"All Products cooked: {env}")
|
|
54
|
+
|
|
55
|
+
for input_asset in ctx.to_build.get_inputs():
|
|
56
|
+
if product_input := self.as_product(input_asset):
|
|
57
|
+
with ctx.log_group(f"Cooking {product_input.name!r}"):
|
|
58
|
+
product_input.cook()
|
|
59
|
+
elif env_input := self.as_env(input_asset):
|
|
60
|
+
with ctx.log_group(f"Cooking {env_input.name!r}"):
|
|
61
|
+
env_builder = env_input.cook()
|
|
62
|
+
env = {}
|
|
63
|
+
|
|
64
|
+
ctx.log(f"Env computed: {env_builder}")
|
|
65
|
+
else:
|
|
66
|
+
ctx.log(f"Skipping non Product nor Env input: {input_asset.name}")
|
|
67
|
+
|
|
68
|
+
def cook(self):
|
|
69
|
+
build_ctx = BuildContext.current(raises=False)
|
|
70
|
+
if build_ctx is None:
|
|
71
|
+
raise Exception("Cannot build an asset outside of a BuildContext.")
|
|
72
|
+
self.build()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from tgzr.cuisine.recipe import Recipe, RecipeTypeInfo
|
|
5
|
+
from tgzr.cuisine.basics.recipe_with_params import RecipeWithParams
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Computable(Recipe):
|
|
9
|
+
"""
|
|
10
|
+
A Recipe returning a value in its 'cook()' method.
|
|
11
|
+
|
|
12
|
+
It can read params from inputs in the "params" group
|
|
13
|
+
with `get_inputs_params_dict()->dict[str, Any]`
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
RECIPE_TYPE_INFO = RecipeTypeInfo(
|
|
17
|
+
category="Compute",
|
|
18
|
+
color="#999999",
|
|
19
|
+
icon="sym_o_manufacturing",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def get_inputs_params_dict(self) -> dict[str, Any]:
|
|
23
|
+
inputs_with_param = self.get_typed_inputs(RecipeWithParams, "params")
|
|
24
|
+
params = {}
|
|
25
|
+
for name, input in inputs_with_param.items():
|
|
26
|
+
params.update(input.get_params_dict())
|
|
27
|
+
return params
|
|
28
|
+
|
|
29
|
+
def compute(self) -> Any:
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def cook(self) -> Any:
|
|
33
|
+
return self.compute()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from tgzr.cuisine.basics.buildable import Buildable
|
|
4
|
+
from tgzr.cuisine.basics.recipe_contexts import CookContext
|
|
5
|
+
|
|
6
|
+
CookContext.context_type
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EditContext(CookContext):
|
|
10
|
+
to_edit: Editable
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Editable(Buildable):
|
|
14
|
+
"""
|
|
15
|
+
A Buildable Recipe which cooks its 'edit' input in its context after building
|
|
16
|
+
it if needed.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def view(self):
|
|
20
|
+
current_context = CookContext.current()
|
|
21
|
+
current_context.log(f"Opening viewer for {self.file_path()}")
|
|
22
|
+
viewer = self.get_unique_input("view")
|
|
23
|
+
with current_context.get(EditContext, asset_to_view=self):
|
|
24
|
+
viewer.cook()
|
|
25
|
+
|
|
26
|
+
def cook(self):
|
|
27
|
+
super().cook()
|
|
28
|
+
self.view()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from tgzr.cuisine.recipe import Recipe, RecipeTypeInfo
|
|
6
|
+
from tgzr.cuisine.basics.recipe_contexts import CookContext
|
|
7
|
+
from tgzr.cuisine.basics.editable import EditContext
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Editor(Recipe):
|
|
11
|
+
"""
|
|
12
|
+
An asset which will open the 'scene' from the current Editable asset with
|
|
13
|
+
an defined DCC when cooked.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
RECIPE_TYPE_INFO = RecipeTypeInfo(
|
|
17
|
+
category="View",
|
|
18
|
+
color="#68FF98",
|
|
19
|
+
icon="sym_o_design_service",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def launch_editor(self, file_path: Path):
|
|
23
|
+
EditContext.current().log(f"Launching editor on {file_path}")
|
|
24
|
+
|
|
25
|
+
def cook(self):
|
|
26
|
+
ctx = EditContext.current(raises=False)
|
|
27
|
+
if ctx is None:
|
|
28
|
+
raise Exception("Cannot edit a Recipe outside of an EditContext.")
|
|
29
|
+
self.launch_editor(ctx.to_edit.file_path())
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Literal, Type, Any
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from tgzr.cuisine.recipe import RecipeTypeInfo
|
|
8
|
+
from tgzr.cuisine.basics.recipe_with_params import RecipeWithParams, RecipeParams
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# ------ Env Builder (should be extracted to dedicated project !)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EnvOp:
|
|
17
|
+
@classmethod
|
|
18
|
+
def op_name(cls) -> str:
|
|
19
|
+
return cls.__name__
|
|
20
|
+
|
|
21
|
+
def __init__(self, var_name: str, **kwargs):
|
|
22
|
+
self._var_name = var_name
|
|
23
|
+
self._kwargs = kwargs
|
|
24
|
+
self.configure(**kwargs)
|
|
25
|
+
|
|
26
|
+
def configure(self, **kwargs) -> None:
|
|
27
|
+
raise NotImplementedError()
|
|
28
|
+
|
|
29
|
+
def var_name(self) -> str:
|
|
30
|
+
return self._var_name
|
|
31
|
+
|
|
32
|
+
def kwargs(self) -> dict[str, Any]:
|
|
33
|
+
return self._kwargs
|
|
34
|
+
|
|
35
|
+
def apply_to(self, env: dict[str, str]) -> None:
|
|
36
|
+
raise NotImplementedError()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class Set(EnvOp):
|
|
40
|
+
"""Set a env var value."""
|
|
41
|
+
|
|
42
|
+
def configure(self, value: str) -> None:
|
|
43
|
+
self.value = value
|
|
44
|
+
|
|
45
|
+
def apply_to(self, base: dict[str, str]) -> None:
|
|
46
|
+
base[self.var_name()] = self.value
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Delete(EnvOp):
|
|
50
|
+
"""Remove a env var."""
|
|
51
|
+
|
|
52
|
+
def configure(self, value=None) -> None:
|
|
53
|
+
if value is not None:
|
|
54
|
+
logger.debug(f"Skipping provided value {value} for delete operation.")
|
|
55
|
+
|
|
56
|
+
def apply_to(self, base: dict[str, str]) -> None:
|
|
57
|
+
try:
|
|
58
|
+
del base[self.var_name()]
|
|
59
|
+
except KeyError:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class Append(EnvOp):
|
|
64
|
+
"""Append a value to a path env var."""
|
|
65
|
+
|
|
66
|
+
def configure(self, value: str) -> None:
|
|
67
|
+
self.value = value
|
|
68
|
+
|
|
69
|
+
def apply_to(self, base: dict[str, str]) -> None:
|
|
70
|
+
base_value = base.get(self.var_name(), "")
|
|
71
|
+
if base_value:
|
|
72
|
+
base_list = base_value.split(os.path.pathsep)
|
|
73
|
+
else:
|
|
74
|
+
base_list = []
|
|
75
|
+
base_list.append(self.value)
|
|
76
|
+
base[self.var_name()] = os.path.pathsep.join(base_list)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class Prepend(EnvOp):
|
|
80
|
+
"""Insert a value at the begining of a path env var."""
|
|
81
|
+
|
|
82
|
+
def configure(self, value: str) -> None:
|
|
83
|
+
self.value = value
|
|
84
|
+
|
|
85
|
+
def apply_to(self, base: dict[str, str]) -> None:
|
|
86
|
+
base_value = base.get(self.var_name(), "")
|
|
87
|
+
base_list = base_value.split(os.path.pathsep)
|
|
88
|
+
base_list.insert(0, self.value)
|
|
89
|
+
base[self.var_name()] = os.path.pathsep.join(base_list)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class EnvBuilder:
|
|
93
|
+
OPS: dict[str, Type[EnvOp]] = dict(
|
|
94
|
+
set=Set, delete=Delete, append=Append, prepend=Prepend
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def op_names(cls) -> tuple[str, ...]:
|
|
99
|
+
"""The valid values for the `op_name` argument of `self.add_op(...)`"""
|
|
100
|
+
return tuple(cls.OPS.keys())
|
|
101
|
+
|
|
102
|
+
def __init__(self, *bases: EnvBuilder):
|
|
103
|
+
self._bases: tuple[EnvBuilder, ...] = bases
|
|
104
|
+
self._ops: list[EnvOp] = []
|
|
105
|
+
|
|
106
|
+
def add_bases(self, *bases: EnvBuilder, validate_bases: bool = True) -> None:
|
|
107
|
+
validated = []
|
|
108
|
+
if validate_bases:
|
|
109
|
+
for base in bases:
|
|
110
|
+
if not isinstance(base, self.__class__):
|
|
111
|
+
print(
|
|
112
|
+
f"WARNING: can't use {base} as base for {self}: it is not a {self.__class__} ! (skipping it)"
|
|
113
|
+
)
|
|
114
|
+
else:
|
|
115
|
+
validated.append(base)
|
|
116
|
+
else:
|
|
117
|
+
validated = bases
|
|
118
|
+
self._bases = self._bases + tuple(validated)
|
|
119
|
+
|
|
120
|
+
def ops(self) -> tuple[EnvOp, ...]:
|
|
121
|
+
return tuple(self._ops)
|
|
122
|
+
|
|
123
|
+
def add_op(self, op_name: str, var_name: str, **op_kwargs: Any):
|
|
124
|
+
op = self.OPS[op_name](var_name=var_name, **op_kwargs)
|
|
125
|
+
self._ops.append(op)
|
|
126
|
+
|
|
127
|
+
def set(self, name: str, value: str) -> None:
|
|
128
|
+
self.add_op("set", name, value=value)
|
|
129
|
+
|
|
130
|
+
def delete(self, name: str) -> None:
|
|
131
|
+
self.add_op("delete", name)
|
|
132
|
+
|
|
133
|
+
def append(self, name: str, value) -> None:
|
|
134
|
+
self.add_op("append", name, value=value)
|
|
135
|
+
|
|
136
|
+
def prepend(self, name: str, value) -> None:
|
|
137
|
+
self.add_op("prepend", name, value=value)
|
|
138
|
+
|
|
139
|
+
def apply_to(self, env: dict[str, str]):
|
|
140
|
+
for base in self._bases:
|
|
141
|
+
base.apply_to(env)
|
|
142
|
+
for op in self._ops:
|
|
143
|
+
op.apply_to(env)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ------ Cusine stuff
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class OpParam(RecipeParams):
|
|
150
|
+
enabled: bool = True
|
|
151
|
+
var_name: str = "MyVar"
|
|
152
|
+
op_name: Literal["set", "delete", "append", "prepend"] = "set"
|
|
153
|
+
value: str | None = None
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class EnvParams(RecipeParams):
|
|
157
|
+
enabled: bool = True
|
|
158
|
+
operations: list[OpParam] = []
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class Env(RecipeWithParams[EnvParams]):
|
|
162
|
+
"""
|
|
163
|
+
A Computable Recipe returning a dict[str, str] from its cook method.
|
|
164
|
+
All input recipes must be Env recipes too, and the resulting dict will
|
|
165
|
+
confain the aggregation of all input dicts.
|
|
166
|
+
|
|
167
|
+
! the inputs order is not 100% assured !
|
|
168
|
+
(we may need to find a solution for that)
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
RECIPE_TYPE_INFO = RecipeTypeInfo(
|
|
172
|
+
category="env",
|
|
173
|
+
color="#82fffb",
|
|
174
|
+
icon="landscape",
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def get_local_env(self) -> EnvBuilder:
|
|
178
|
+
env = EnvBuilder()
|
|
179
|
+
env.append("visited_env_assets", self.name)
|
|
180
|
+
return env
|
|
181
|
+
|
|
182
|
+
def cook(self) -> EnvBuilder:
|
|
183
|
+
|
|
184
|
+
env = self.get_local_env()
|
|
185
|
+
for name, input in self.get_typed_inputs(Env, "").items():
|
|
186
|
+
input_env_builder = input.cook()
|
|
187
|
+
env.add_bases(input_env_builder)
|
|
188
|
+
return env
|
|
189
|
+
|
|
190
|
+
def _get_params_panel(self):
|
|
191
|
+
"""Overridden to add custom field renderers"""
|
|
192
|
+
panel = super()._get_params_panel()
|
|
193
|
+
|
|
194
|
+
from tgzr.cuisine.basics.panels.params_panel import ModelField, ui
|
|
195
|
+
|
|
196
|
+
class OpField(ModelField):
|
|
197
|
+
@classmethod
|
|
198
|
+
def handles(cls, value_type) -> bool:
|
|
199
|
+
return value_type is OpParam
|
|
200
|
+
|
|
201
|
+
def op_symbol(self, op_name: str) -> str:
|
|
202
|
+
return dict(
|
|
203
|
+
set="=",
|
|
204
|
+
delete="delete",
|
|
205
|
+
append="+=",
|
|
206
|
+
prepend="+@0",
|
|
207
|
+
).get(op_name, f"--{op_name}-->")
|
|
208
|
+
|
|
209
|
+
def _render_readonly_value(self):
|
|
210
|
+
op_param: OpParam = self._getter()
|
|
211
|
+
ui.label(
|
|
212
|
+
f"{op_param.var_name} {self.op_symbol(op_param.op_name)} {op_param.value or ''}"
|
|
213
|
+
).classes("pl-1 w-full font-mono").style(replace="")
|
|
214
|
+
|
|
215
|
+
panel.add_field_renderer(OpField)
|
|
216
|
+
return panel
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from tgzr.cuisine.recipe import Recipe, RecipeTypeInfo
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FileRecipe(Recipe):
|
|
7
|
+
RECIPE_TYPE_INFO = RecipeTypeInfo(
|
|
8
|
+
category="Files",
|
|
9
|
+
color="#00FFFF",
|
|
10
|
+
icon="sym_o_file",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
def file_path(self) -> Path:
|
|
14
|
+
print(f"!!! WARNING !!! {self} IS JUST A MOCKUP CLASS !!!")
|
|
15
|
+
return Path(f"/path/to/work/{self.name}/{self.name}.xstage")
|
|
16
|
+
|
|
17
|
+
def file_exists(self) -> bool:
|
|
18
|
+
return self.file_path().exists()
|
|
File without changes
|