pz-scripts-data 1.1.0__tar.gz → 1.1.2__tar.gz
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.
- pz_scripts_data-1.1.2/PKG-INFO +61 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/pyproject.toml +4 -4
- pz_scripts_data-1.1.2/src/pz_scripts_data/blocks.py +6 -0
- pz_scripts_data-1.1.2/src/pz_scripts_data/formatBlocks.py +287 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data/schema.py +14 -11
- pz_scripts_data-1.1.2/src/pz_scripts_data.egg-info/PKG-INFO +61 -0
- pz_scripts_data-1.1.0/PKG-INFO +0 -18
- pz_scripts_data-1.1.0/src/pz_scripts_data/blocks.py +0 -65
- pz_scripts_data-1.1.0/src/pz_scripts_data/formatBlocks.py +0 -279
- pz_scripts_data-1.1.0/src/pz_scripts_data.egg-info/PKG-INFO +0 -18
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/LICENSE +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/README.md +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/setup.cfg +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data/py.typed +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data/release.py +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data/sortItemParameters.py +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data/validateBlocks.py +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/SOURCES.txt +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/dependency_links.txt +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/entry_points.txt +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/requires.txt +0 -0
- {pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pz-scripts-data
|
|
3
|
+
Version: 1.1.2
|
|
4
|
+
Summary: Dataset for the Scripts of Project Zomboid.
|
|
5
|
+
Author: SimKDT
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
8
|
+
Classifier: Topic :: Database
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.12.3
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: pyyaml
|
|
17
|
+
Requires-Dist: jsonschema
|
|
18
|
+
Requires-Dist: pydantic>=2.11
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# PZ Scripts Data
|
|
22
|
+
Provides information regarding various script blocks and parameters of Project Zomboid [scripts](https://pzwiki.net/wiki/Scripts) system. This dataset is used to provide a [ScriptsDocs](https://pz-wiki-modding.github.io/PZ-API-Docs/).
|
|
23
|
+
|
|
24
|
+
The translation data is now moved to [pz-translation-data](https://github.com/SirDoggyJvla/pz-translation-data) and are now deprecated. The main data files holding the last updated translation data are kept for tools that may use them, but will be removed in the future.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
PZ Scripts Data can be installed via PyPI, Git, or in development mode as described below.
|
|
29
|
+
|
|
30
|
+
<details open>
|
|
31
|
+
<summary>PyPI</summary>
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install pz-scripts-data
|
|
35
|
+
```
|
|
36
|
+
</details>
|
|
37
|
+
|
|
38
|
+
<details>
|
|
39
|
+
<summary>Git</summary>
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install git+https://github.com/PZ-Wiki-Modding/pz-scripts-data.git
|
|
43
|
+
```
|
|
44
|
+
</details>
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Dev</summary>
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install -e .
|
|
51
|
+
```
|
|
52
|
+
</details>
|
|
53
|
+
|
|
54
|
+
## Schema
|
|
55
|
+
You can find a Pydantic model defining the data format in the [schema.py](src/pz_scripts_data/schema.py) file. A JSON schema file exported from this model is available in the [schemas/blocks.json](schemas/blocks.json) file.
|
|
56
|
+
|
|
57
|
+
## Contributing
|
|
58
|
+
This dataset is aimed to accept any contributions. See [CONTRIBUTING](CONTRIBUTING.md) for more information on how to contribute to this dataset.
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
See [LICENSE](LICENSE) for more information.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pz-scripts-data"
|
|
3
3
|
description = "Dataset for the Scripts of Project Zomboid."
|
|
4
|
+
readme = { file = "README.md", content-type = "text/markdown" }
|
|
4
5
|
requires-python = ">=3.12.3"
|
|
5
|
-
version = "1.1.
|
|
6
|
-
license
|
|
6
|
+
version = "1.1.2"
|
|
7
|
+
license = "MIT"
|
|
7
8
|
authors = [
|
|
8
9
|
{ name = "SimKDT" },
|
|
9
10
|
]
|
|
@@ -14,7 +15,6 @@ dependencies = [
|
|
|
14
15
|
]
|
|
15
16
|
classifiers = [
|
|
16
17
|
"Programming Language :: Python :: 3.12",
|
|
17
|
-
"License :: OSI Approved :: MIT License",
|
|
18
18
|
"Topic :: Database",
|
|
19
19
|
"Operating System :: OS Independent",
|
|
20
20
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -31,4 +31,4 @@ package = true
|
|
|
31
31
|
[tool.setuptools.package-data]
|
|
32
32
|
pz_scripts_data = [
|
|
33
33
|
"py.typed"
|
|
34
|
-
]
|
|
34
|
+
]
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any, Literal, Optional, TypedDict
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
from pydantic import BaseModel, Field, ValidationError, model_validator
|
|
7
|
+
|
|
8
|
+
from pz_scripts_data.blocks import PropertyData
|
|
9
|
+
from pz_scripts_data.schema import BlockDefinition, ParameterDefinition
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ScriptsBlock(BlockDefinition):
|
|
13
|
+
"""Block used by the pipeline: parameters are keyed by lowercase name and relations are filled in during preparation."""
|
|
14
|
+
|
|
15
|
+
parameters: dict[str, ParameterDefinition] = Field(default_factory=dict) # type: ignore
|
|
16
|
+
children: list[str] | None = None
|
|
17
|
+
variants: list[str] | None = None
|
|
18
|
+
|
|
19
|
+
@model_validator(mode="before")
|
|
20
|
+
@classmethod
|
|
21
|
+
def _key_parameters_by_name(cls, data: Any) -> Any:
|
|
22
|
+
if not isinstance(data, dict):
|
|
23
|
+
return data
|
|
24
|
+
parameters = data.get("parameters", [])
|
|
25
|
+
if not isinstance(parameters, list):
|
|
26
|
+
return data
|
|
27
|
+
|
|
28
|
+
keyed: dict[str, Any] = {}
|
|
29
|
+
for param in parameters:
|
|
30
|
+
name = param.get("name") if isinstance(param, dict) else None
|
|
31
|
+
if not isinstance(name, str):
|
|
32
|
+
raise ValueError("every parameter must have a 'name' to be referenced")
|
|
33
|
+
keyed[name.lower()] = param
|
|
34
|
+
return {**data, "parameters": keyed}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Item(TypedDict):
|
|
38
|
+
input: Path
|
|
39
|
+
output: Path
|
|
40
|
+
data: Optional[dict[str, ScriptsBlock]]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
items: list[Item] = [
|
|
44
|
+
Item(
|
|
45
|
+
input=Path("data/blocks"),
|
|
46
|
+
output=Path("out/scriptsBlocks.json"),
|
|
47
|
+
data=None,
|
|
48
|
+
),
|
|
49
|
+
Item(
|
|
50
|
+
input=Path("data/roots"),
|
|
51
|
+
output=Path("out/roots.json"),
|
|
52
|
+
data=None,
|
|
53
|
+
),
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## PROCESS ITEM
|
|
61
|
+
|
|
62
|
+
def fetchBlocks(item: Item):
|
|
63
|
+
# combine all block yaml files into one, validating each against the schema
|
|
64
|
+
blocks: dict[str, ScriptsBlock] = {}
|
|
65
|
+
for file_path in item['input'].glob("*.yaml"):
|
|
66
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
67
|
+
data = yaml.safe_load(f)
|
|
68
|
+
try:
|
|
69
|
+
block = ScriptsBlock.model_validate(data)
|
|
70
|
+
except ValidationError as exc:
|
|
71
|
+
raise ValueError(f"Invalid block definition in '{file_path}':\n{exc}") from exc
|
|
72
|
+
if block.name.lower() in blocks:
|
|
73
|
+
raise ValueError(f"Duplicate block name '{block.name}' found in '{file_path}'.")
|
|
74
|
+
blocks[block.name.lower()] = block
|
|
75
|
+
return blocks
|
|
76
|
+
|
|
77
|
+
def process_properties(block: ScriptsBlock) -> ScriptsBlock:
|
|
78
|
+
# transform each property group's list into a dictionary keyed by property name
|
|
79
|
+
if block.properties is None:
|
|
80
|
+
return block
|
|
81
|
+
for property_data in block.properties.values():
|
|
82
|
+
properties: list = property_data[PropertyData.PROPERTIES]
|
|
83
|
+
property_data[PropertyData.PROPERTIES] = {prop[PropertyData.NAME]: prop for prop in properties}
|
|
84
|
+
return block
|
|
85
|
+
|
|
86
|
+
# main
|
|
87
|
+
|
|
88
|
+
def process(item: Item):
|
|
89
|
+
blocks = fetchBlocks(item)
|
|
90
|
+
for block in blocks.values():
|
|
91
|
+
process_properties(block)
|
|
92
|
+
|
|
93
|
+
return blocks
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
## PREPARE
|
|
98
|
+
|
|
99
|
+
# relationship and hierarchy
|
|
100
|
+
|
|
101
|
+
def add_source_ref_to_targets(
|
|
102
|
+
source_name: str,
|
|
103
|
+
targets_names: list[str],
|
|
104
|
+
items: list[Item],
|
|
105
|
+
array_type: Literal["children", "variants"]):
|
|
106
|
+
"""
|
|
107
|
+
This is used to add source_name to the targets's array_type.
|
|
108
|
+
|
|
109
|
+
For example:
|
|
110
|
+
- source_name -> child_name
|
|
111
|
+
- targets_names -> child_parents
|
|
112
|
+
- array_type -> children (of parent)
|
|
113
|
+
will add source_name in the array stored at key array_type of the targets of targets_names.
|
|
114
|
+
(child_name --append--> array (key: children) of each parents)
|
|
115
|
+
"""
|
|
116
|
+
_processed: list[str] = []
|
|
117
|
+
for item in items:
|
|
118
|
+
blocks = item['data']
|
|
119
|
+
assert blocks is not None, "Something went wrong."
|
|
120
|
+
|
|
121
|
+
# add children_name ref to every parents
|
|
122
|
+
for parent_name in targets_names:
|
|
123
|
+
parent_block = blocks.get(parent_name.lower(), None)
|
|
124
|
+
if parent_block is None:
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
# init if needed
|
|
128
|
+
if getattr(parent_block, array_type) is None:
|
|
129
|
+
setattr(parent_block, array_type, [])
|
|
130
|
+
|
|
131
|
+
# add name
|
|
132
|
+
children: list[str] = getattr(parent_block, array_type)
|
|
133
|
+
if source_name not in children:
|
|
134
|
+
children.append(source_name)
|
|
135
|
+
_processed.append(parent_name)
|
|
136
|
+
|
|
137
|
+
# we make sure they were all properly processed
|
|
138
|
+
for parent_name in targets_names:
|
|
139
|
+
if parent_name not in _processed:
|
|
140
|
+
raise ValueError(f"Parent block '{parent_name}' not found for block '{source_name}'.")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def prepare_relationship(block: ScriptsBlock, items: list[Item]):
|
|
144
|
+
"""
|
|
145
|
+
This will retrieve the parents of this block and add a reference to itself inside the data,
|
|
146
|
+
of this parent block
|
|
147
|
+
"""
|
|
148
|
+
# handle parents
|
|
149
|
+
parents = block.parents
|
|
150
|
+
if parents:
|
|
151
|
+
add_source_ref_to_targets(block.name, parents, items, "children")
|
|
152
|
+
|
|
153
|
+
# handle variants
|
|
154
|
+
variant = block.variant_of
|
|
155
|
+
if variant:
|
|
156
|
+
add_source_ref_to_targets(block.name, [variant], items, "variants")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# description and reference
|
|
160
|
+
|
|
161
|
+
def find_block_in_items(block_name: str, items: list[Item]) -> ScriptsBlock | None:
|
|
162
|
+
for item in items:
|
|
163
|
+
blocks = item['data']
|
|
164
|
+
assert blocks is not None, "Something is wrong."
|
|
165
|
+
|
|
166
|
+
if block_name.lower() in blocks:
|
|
167
|
+
return blocks[block_name.lower()]
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def copy_missing_fields(target: BaseModel, source: BaseModel) -> None:
|
|
172
|
+
"""Copies every field explicitly set on source that isn't already set on target."""
|
|
173
|
+
for field_name in source.model_fields_set:
|
|
174
|
+
if field_name not in target.model_fields_set:
|
|
175
|
+
setattr(target, field_name, getattr(source, field_name))
|
|
176
|
+
|
|
177
|
+
def copy_block_ref(block: ScriptsBlock, items: list[Item]) -> ScriptsBlock:
|
|
178
|
+
"""
|
|
179
|
+
#desc copies the description of the source block
|
|
180
|
+
#ref copies every field of that source block into the block (if not already present)
|
|
181
|
+
"""
|
|
182
|
+
# copy #desc
|
|
183
|
+
if block.ref_desc is not None:
|
|
184
|
+
desc_source = find_block_in_items(block.ref_desc, items)
|
|
185
|
+
|
|
186
|
+
if desc_source is not None:
|
|
187
|
+
if desc_source.description is None:
|
|
188
|
+
raise ValueError(f"Block '{block.name}' has #desc but source has no description.")
|
|
189
|
+
block.description = desc_source.description
|
|
190
|
+
|
|
191
|
+
# copy the short description if available too
|
|
192
|
+
if desc_source.short_description is not None:
|
|
193
|
+
block.short_description = desc_source.short_description
|
|
194
|
+
|
|
195
|
+
# copy #ref
|
|
196
|
+
if block.ref is not None:
|
|
197
|
+
ref_source = find_block_in_items(block.ref, items)
|
|
198
|
+
if ref_source is not None:
|
|
199
|
+
copy_missing_fields(block, ref_source)
|
|
200
|
+
|
|
201
|
+
return block
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# parameters
|
|
205
|
+
|
|
206
|
+
def get_source_parameter(ref_key: str, items: list[Item]) -> ParameterDefinition:
|
|
207
|
+
"""
|
|
208
|
+
This will return the source parameter from the ref_key.
|
|
209
|
+
The ref_key is in the format "BlockName/ParameterName"
|
|
210
|
+
"""
|
|
211
|
+
# find the source block and parameter
|
|
212
|
+
path = ref_key.split('/')
|
|
213
|
+
assert len(path) == 2, f"Invalid #ref format for '{ref_key}'. Needs to be in format 'BlockName/ParameterName'."
|
|
214
|
+
origin_block = path[0]
|
|
215
|
+
origin_param = path[1].lower()
|
|
216
|
+
|
|
217
|
+
origin_block_data = find_block_in_items(origin_block, items)
|
|
218
|
+
|
|
219
|
+
# make sure the source block and parameter exist
|
|
220
|
+
if origin_block_data is None:
|
|
221
|
+
raise ValueError(f"Source block '{origin_block}' not found for parameter '{origin_param}'.")
|
|
222
|
+
if origin_param not in origin_block_data.parameters:
|
|
223
|
+
raise ValueError(f"Source block '{origin_block}' has no parameter '{origin_param}'.")
|
|
224
|
+
|
|
225
|
+
return origin_block_data.parameters[origin_param]
|
|
226
|
+
|
|
227
|
+
def copy_parameters_ref(parameters: dict[str, ParameterDefinition], items: list[Item]):
|
|
228
|
+
for param_key, param in parameters.items():
|
|
229
|
+
if param.ref is not None:
|
|
230
|
+
source_param = get_source_parameter(param.ref, items)
|
|
231
|
+
|
|
232
|
+
# copy every field from the source parameter
|
|
233
|
+
# that isn't already set on the parameter
|
|
234
|
+
copy_missing_fields(param, source_param)
|
|
235
|
+
|
|
236
|
+
if param.ref_desc is not None:
|
|
237
|
+
source_param = get_source_parameter(param.ref_desc, items)
|
|
238
|
+
|
|
239
|
+
# make sure the source parameter has a description
|
|
240
|
+
if source_param.description is None:
|
|
241
|
+
raise ValueError(f"Parameter '{param_key}' has #desc but source has no description.")
|
|
242
|
+
|
|
243
|
+
# only copy the description
|
|
244
|
+
param.description = source_param.description
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# main
|
|
248
|
+
|
|
249
|
+
def prepare(item: Item, items: list[Item]):
|
|
250
|
+
blocks = item['data']
|
|
251
|
+
assert blocks is not None, "Something went wrong."
|
|
252
|
+
|
|
253
|
+
for block in blocks.values():
|
|
254
|
+
prepare_relationship(block, items)
|
|
255
|
+
copy_block_ref(block, items)
|
|
256
|
+
copy_parameters_ref(block.parameters, items)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
return blocks
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
# serialization
|
|
263
|
+
|
|
264
|
+
def serialize(blocks: dict[str, ScriptsBlock]) -> dict[str, dict[str, Any]]:
|
|
265
|
+
# only write the fields that were set, using their schema (alias) names
|
|
266
|
+
# the version is only used for validation, so it is not written
|
|
267
|
+
return {
|
|
268
|
+
name: block.model_dump(by_alias=True, exclude_unset=True, exclude={"version"})
|
|
269
|
+
for name, block in blocks.items()
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def main():
|
|
274
|
+
for item in items:
|
|
275
|
+
item['data'] = process(item)
|
|
276
|
+
for item in items:
|
|
277
|
+
item['data'] = prepare(item, items)
|
|
278
|
+
for item in items:
|
|
279
|
+
output_file = item['output']
|
|
280
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
281
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
282
|
+
assert item['data'] is not None
|
|
283
|
+
json.dump(serialize(item['data']), f, indent=2,
|
|
284
|
+
ensure_ascii=False, sort_keys=True)
|
|
285
|
+
|
|
286
|
+
if __name__ == "__main__":
|
|
287
|
+
main()
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
import json
|
|
8
8
|
import sys
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any, Literal, Self
|
|
10
|
+
from typing import Annotated, Any, Literal, Self
|
|
11
11
|
|
|
12
|
-
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
12
|
+
from pydantic import BaseModel, ConfigDict, Field, WithJsonSchema, model_validator
|
|
13
13
|
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
|
|
14
14
|
from pydantic_core import core_schema
|
|
15
15
|
|
|
@@ -17,6 +17,9 @@ DEFAULT_OUTPUT = Path(__file__).resolve().parents[2] / "schemas" / "blocks.json"
|
|
|
17
17
|
|
|
18
18
|
ScalarType = Literal["string", "float", "boolean", "integer"]
|
|
19
19
|
|
|
20
|
+
# Accepts whole numbers as int so they are not widened to float on output. The JSON Schema stays "number".
|
|
21
|
+
Number = Annotated[int | float, WithJsonSchema({"type": "number"})]
|
|
22
|
+
|
|
20
23
|
|
|
21
24
|
class SchemaModel(BaseModel):
|
|
22
25
|
"""Base model. Unknown keys are rejected and no value may be null."""
|
|
@@ -109,12 +112,12 @@ class BlockDeprecation(SchemaModel):
|
|
|
109
112
|
|
|
110
113
|
class _ArrayBase(SchemaModel):
|
|
111
114
|
separator: str = Field(description="Specifies the separator used to split the string into array items.")
|
|
112
|
-
min_items:
|
|
115
|
+
min_items: Number | None = Field(
|
|
113
116
|
None,
|
|
114
117
|
alias="min",
|
|
115
118
|
description="The minimum number of items required in the array.",
|
|
116
119
|
)
|
|
117
|
-
max_items:
|
|
120
|
+
max_items: Number | None = Field(
|
|
118
121
|
None,
|
|
119
122
|
alias="max",
|
|
120
123
|
description="The maximum number of items allowed in the array.",
|
|
@@ -270,7 +273,7 @@ class ParameterNeed(SchemaModel):
|
|
|
270
273
|
"""A condition on another parameter that must be met for this parameter to be valid."""
|
|
271
274
|
|
|
272
275
|
name: str | None = Field(None, description="The name of the parameter that this condition depends on.")
|
|
273
|
-
values: list[str |
|
|
276
|
+
values: list[str | Number | bool] | None = Field(
|
|
274
277
|
None,
|
|
275
278
|
description="The values of the dependent parameter that must be met for this parameter to be valid.",
|
|
276
279
|
)
|
|
@@ -280,11 +283,11 @@ class ParameterNeed(SchemaModel):
|
|
|
280
283
|
description="A mapping of values of the dependent parameter to the expected type of this parameter. For example, if the dependent parameter is 'type' and it has a value 'integer', then this parameter should be of type 'float'. The key is the value of the dependent parameter, and the value is the expected type of this parameter when the dependent parameter has that value.",
|
|
281
284
|
examples=[{"integer": "float", "double": "float", "boolean": "boolean", "string": "string"}],
|
|
282
285
|
)
|
|
283
|
-
minimum:
|
|
286
|
+
minimum: Number | None = Field(
|
|
284
287
|
None,
|
|
285
288
|
description="The minimum value for this parameter when the dependent parameter has a specific value. Requires the target parameter to be of type 'float' or 'integer'.",
|
|
286
289
|
)
|
|
287
|
-
maximum:
|
|
290
|
+
maximum: Number | None = Field(
|
|
288
291
|
None,
|
|
289
292
|
description="The maximum value for this parameter when the dependent parameter has a specific value. Requires the target parameter to be of type 'float' or 'integer'.",
|
|
290
293
|
)
|
|
@@ -335,16 +338,16 @@ class ParameterDefinition(SchemaModel):
|
|
|
335
338
|
description="DEPRECATED: A list of parent block types for which this parameter is applicable.",
|
|
336
339
|
)
|
|
337
340
|
required: bool | None = Field(None, description="Indicates whether the parameter is required.")
|
|
338
|
-
default_value: str |
|
|
341
|
+
default_value: str | Number | bool | list[Any] | dict[str, Any] | None = Field(
|
|
339
342
|
None,
|
|
340
343
|
alias="default",
|
|
341
344
|
description="The default value for the parameter if not specified.",
|
|
342
345
|
)
|
|
343
|
-
minimum:
|
|
346
|
+
minimum: Number | None = Field(
|
|
344
347
|
None,
|
|
345
348
|
description="The minimum value for the parameter if it is a number. Needs type.main to be 'float' or 'integer' to be applicable.",
|
|
346
349
|
)
|
|
347
|
-
maximum:
|
|
350
|
+
maximum: Number | None = Field(
|
|
348
351
|
None,
|
|
349
352
|
description="The maximum value for the parameter if it is a number. Needs type.main to be 'float' or 'integer' to be applicable.",
|
|
350
353
|
)
|
|
@@ -353,7 +356,7 @@ class ParameterDefinition(SchemaModel):
|
|
|
353
356
|
alias="type",
|
|
354
357
|
description="The data type of the parameter.",
|
|
355
358
|
)
|
|
356
|
-
values: list[str |
|
|
359
|
+
values: list[str | Number] | None = Field(None, description="A list of allowed values for the parameter.")
|
|
357
360
|
deprecated: ParameterDeprecation | None = None
|
|
358
361
|
needs: list[ParameterNeed] | None = Field(
|
|
359
362
|
None,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pz-scripts-data
|
|
3
|
+
Version: 1.1.2
|
|
4
|
+
Summary: Dataset for the Scripts of Project Zomboid.
|
|
5
|
+
Author: SimKDT
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
8
|
+
Classifier: Topic :: Database
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.12.3
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: pyyaml
|
|
17
|
+
Requires-Dist: jsonschema
|
|
18
|
+
Requires-Dist: pydantic>=2.11
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# PZ Scripts Data
|
|
22
|
+
Provides information regarding various script blocks and parameters of Project Zomboid [scripts](https://pzwiki.net/wiki/Scripts) system. This dataset is used to provide a [ScriptsDocs](https://pz-wiki-modding.github.io/PZ-API-Docs/).
|
|
23
|
+
|
|
24
|
+
The translation data is now moved to [pz-translation-data](https://github.com/SirDoggyJvla/pz-translation-data) and are now deprecated. The main data files holding the last updated translation data are kept for tools that may use them, but will be removed in the future.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
PZ Scripts Data can be installed via PyPI, Git, or in development mode as described below.
|
|
29
|
+
|
|
30
|
+
<details open>
|
|
31
|
+
<summary>PyPI</summary>
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install pz-scripts-data
|
|
35
|
+
```
|
|
36
|
+
</details>
|
|
37
|
+
|
|
38
|
+
<details>
|
|
39
|
+
<summary>Git</summary>
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install git+https://github.com/PZ-Wiki-Modding/pz-scripts-data.git
|
|
43
|
+
```
|
|
44
|
+
</details>
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Dev</summary>
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install -e .
|
|
51
|
+
```
|
|
52
|
+
</details>
|
|
53
|
+
|
|
54
|
+
## Schema
|
|
55
|
+
You can find a Pydantic model defining the data format in the [schema.py](src/pz_scripts_data/schema.py) file. A JSON schema file exported from this model is available in the [schemas/blocks.json](schemas/blocks.json) file.
|
|
56
|
+
|
|
57
|
+
## Contributing
|
|
58
|
+
This dataset is aimed to accept any contributions. See [CONTRIBUTING](CONTRIBUTING.md) for more information on how to contribute to this dataset.
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
See [LICENSE](LICENSE) for more information.
|
pz_scripts_data-1.1.0/PKG-INFO
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pz-scripts-data
|
|
3
|
-
Version: 1.1.0
|
|
4
|
-
Summary: Dataset for the Scripts of Project Zomboid.
|
|
5
|
-
Author: SimKDT
|
|
6
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
Classifier: Topic :: Database
|
|
9
|
-
Classifier: Operating System :: OS Independent
|
|
10
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Typing :: Typed
|
|
13
|
-
Requires-Python: >=3.12.3
|
|
14
|
-
License-File: LICENSE
|
|
15
|
-
Requires-Dist: pyyaml
|
|
16
|
-
Requires-Dist: jsonschema
|
|
17
|
-
Requires-Dist: pydantic>=2.11
|
|
18
|
-
Dynamic: license-file
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
from enum import StrEnum
|
|
2
|
-
|
|
3
|
-
class BlockProperties(StrEnum):
|
|
4
|
-
VERSION = 'version'
|
|
5
|
-
REF_DESC = '#desc'
|
|
6
|
-
REF_FULL = '#ref'
|
|
7
|
-
DEPRECATED = 'deprecated'
|
|
8
|
-
|
|
9
|
-
NAME = 'name'
|
|
10
|
-
ID = 'ID'
|
|
11
|
-
SOFT_OVERRIDE = 'softOverride'
|
|
12
|
-
NO_COMMA = 'noComma'
|
|
13
|
-
PATTERN = 'pattern'
|
|
14
|
-
|
|
15
|
-
DESCRIPTION = 'description'
|
|
16
|
-
SHORT_DESCRIPTION = 'short_description'
|
|
17
|
-
|
|
18
|
-
VARIANT = 'variantOf'
|
|
19
|
-
VARIANTS = 'variants'
|
|
20
|
-
|
|
21
|
-
PARENTS = 'parents'
|
|
22
|
-
CHILDREN = 'children'
|
|
23
|
-
NEEDS_CHILDREN = 'needsChildren'
|
|
24
|
-
PARAMETERS = 'parameters'
|
|
25
|
-
PROPERTIES = 'properties'
|
|
26
|
-
|
|
27
|
-
IS_ROOT = 'isRoot'
|
|
28
|
-
|
|
29
|
-
class IDProperties(StrEnum):
|
|
30
|
-
OPTIONAL = 'optional'
|
|
31
|
-
CAN_HAVE_SPACES = 'canHaveSpace'
|
|
32
|
-
FORBIDDEN = 'forbidden'
|
|
33
|
-
|
|
34
|
-
VALUES = 'values'
|
|
35
|
-
PARENTS_WITHOUT = 'parentsWithout'
|
|
36
|
-
AS_TYPE = 'asType'
|
|
37
|
-
|
|
38
|
-
TRANSLATION = 'translation'
|
|
39
|
-
|
|
40
|
-
class ParameterProperties(StrEnum):
|
|
41
|
-
REF_DESC = '#desc'
|
|
42
|
-
REF_FULL = '#ref'
|
|
43
|
-
|
|
44
|
-
NAME = 'name'
|
|
45
|
-
DESCRIPTION = 'description'
|
|
46
|
-
|
|
47
|
-
TYPE = 'type'
|
|
48
|
-
DEFAULT = 'default'
|
|
49
|
-
REQUIRED = 'required'
|
|
50
|
-
CAN_BE_EMPTY = 'canBeEmpty'
|
|
51
|
-
MINIMUM = 'minimum'
|
|
52
|
-
MAXIMUM = 'maximum'
|
|
53
|
-
VALUES = 'values'
|
|
54
|
-
|
|
55
|
-
DEPRECATED = 'deprecated'
|
|
56
|
-
IS_USELESS = 'isUseless'
|
|
57
|
-
ALLOW_DUPLICATES = 'allowDuplicates'
|
|
58
|
-
INCOMPATIBLE_WITH = 'incompatibleWith'
|
|
59
|
-
|
|
60
|
-
SEE_ALSO = 'seeAlso'
|
|
61
|
-
|
|
62
|
-
class PropertyData(StrEnum):
|
|
63
|
-
NAME = 'name'
|
|
64
|
-
DESCRIPTION = 'description'
|
|
65
|
-
PROPERTIES = 'properties'
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import os, json, yaml
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import TypedDict, Optional, Any
|
|
4
|
-
|
|
5
|
-
from pz_scripts_data.blocks import BlockProperties, ParameterProperties, IDProperties, PropertyData
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type ScriptsBlock = dict[str, Any]
|
|
9
|
-
class Item(TypedDict):
|
|
10
|
-
input: Path
|
|
11
|
-
output: Path
|
|
12
|
-
data: Optional[dict[str, ScriptsBlock]]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
items: list[Item] = [
|
|
16
|
-
Item(
|
|
17
|
-
input=Path("data/blocks"),
|
|
18
|
-
output=Path("out/scriptsBlocks.json"),
|
|
19
|
-
data=None,
|
|
20
|
-
),
|
|
21
|
-
Item(
|
|
22
|
-
input=Path("data/roots"),
|
|
23
|
-
output=Path("out/roots.json"),
|
|
24
|
-
data=None,
|
|
25
|
-
),
|
|
26
|
-
]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## PROCESS ITEM
|
|
33
|
-
|
|
34
|
-
def fetchBlocks(item: Item):
|
|
35
|
-
# combine all block json files into one
|
|
36
|
-
blocks: dict[str, ScriptsBlock] = {}
|
|
37
|
-
for file_path in item['input'].glob("*.yaml"):
|
|
38
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
|
39
|
-
data = yaml.safe_load(f)
|
|
40
|
-
key = data[ParameterProperties.NAME]
|
|
41
|
-
if key in blocks:
|
|
42
|
-
raise ValueError(f"Duplicate block name '{key}' found in '{file_path}'.")
|
|
43
|
-
blocks[key] = data
|
|
44
|
-
return blocks
|
|
45
|
-
|
|
46
|
-
def process_parameters(data: ScriptsBlock) -> ScriptsBlock:
|
|
47
|
-
# remove unnecessary fields
|
|
48
|
-
data.pop(BlockProperties.VERSION)
|
|
49
|
-
|
|
50
|
-
# replace parameters array into dictionary
|
|
51
|
-
# where keys are lowercased parameter names
|
|
52
|
-
parameters_data = data.get(BlockProperties.PARAMETERS, [])
|
|
53
|
-
parameters_new = {}
|
|
54
|
-
for param_data in parameters_data:
|
|
55
|
-
name = param_data[ParameterProperties.NAME]
|
|
56
|
-
parameters_new[name.lower()] = param_data
|
|
57
|
-
data[BlockProperties.PARAMETERS] = parameters_new
|
|
58
|
-
|
|
59
|
-
# handle properties
|
|
60
|
-
properties_data = data.get(BlockProperties.PROPERTIES, None)
|
|
61
|
-
if properties_data is not None:
|
|
62
|
-
for property_data in properties_data.values():
|
|
63
|
-
# transform into dictionary too
|
|
64
|
-
new_properties = {}
|
|
65
|
-
properties: list = property_data[PropertyData.PROPERTIES]
|
|
66
|
-
for prop_data in properties:
|
|
67
|
-
prop_name = prop_data[PropertyData.NAME]
|
|
68
|
-
new_properties[prop_name] = prop_data
|
|
69
|
-
property_data[PropertyData.PROPERTIES] = new_properties
|
|
70
|
-
|
|
71
|
-
return data
|
|
72
|
-
|
|
73
|
-
# main
|
|
74
|
-
|
|
75
|
-
def process(item: Item):
|
|
76
|
-
blocks = fetchBlocks(item)
|
|
77
|
-
for key, block in blocks.items():
|
|
78
|
-
blocks[key] = process_parameters(block)
|
|
79
|
-
|
|
80
|
-
return blocks
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## PREPARE
|
|
85
|
-
|
|
86
|
-
# relationship and hierarchy
|
|
87
|
-
|
|
88
|
-
def add_source_ref_to_targets(
|
|
89
|
-
source_name: str,
|
|
90
|
-
targets_names: list[str],
|
|
91
|
-
items: list[Item],
|
|
92
|
-
array_type: BlockProperties):
|
|
93
|
-
"""
|
|
94
|
-
This is used to add source_name to the targets's array_type.
|
|
95
|
-
|
|
96
|
-
For example:
|
|
97
|
-
- source_name -> child_name
|
|
98
|
-
- targets_names -> child_parents
|
|
99
|
-
- array_type -> children (of parent)
|
|
100
|
-
will add source_name in the array stored at key array_type of the targets of targets_names.
|
|
101
|
-
(child_name --append--> array (key: children) of each parents)
|
|
102
|
-
"""
|
|
103
|
-
_processed: list[str] = []
|
|
104
|
-
for item in items:
|
|
105
|
-
blocks = item['data']
|
|
106
|
-
assert blocks is not None, "Something went wrong."
|
|
107
|
-
|
|
108
|
-
# add children_name ref to every parents
|
|
109
|
-
for parent_name in targets_names:
|
|
110
|
-
parent_block = blocks.get(parent_name, None)
|
|
111
|
-
if parent_block is None:
|
|
112
|
-
continue
|
|
113
|
-
|
|
114
|
-
# init if needed
|
|
115
|
-
if array_type not in parent_block:
|
|
116
|
-
parent_block[array_type] = []
|
|
117
|
-
|
|
118
|
-
# add name
|
|
119
|
-
children: list[str] = parent_block[array_type]
|
|
120
|
-
if source_name not in children:
|
|
121
|
-
children.append(source_name)
|
|
122
|
-
_processed.append(parent_name)
|
|
123
|
-
|
|
124
|
-
# we make sure they were all properly processed
|
|
125
|
-
for parent_name in targets_names:
|
|
126
|
-
if parent_name not in _processed:
|
|
127
|
-
raise ValueError(f"Parent block '{parent_name}' not found for block '{source_name}'.")
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def prepare_relationship(block: ScriptsBlock, items: list[Item]):
|
|
131
|
-
"""
|
|
132
|
-
This will retrieve the parents of this block and add a reference to itself inside the data,
|
|
133
|
-
of this parent block
|
|
134
|
-
"""
|
|
135
|
-
# handle parents
|
|
136
|
-
parents = block.get(BlockProperties.PARENTS, [])
|
|
137
|
-
if parents:
|
|
138
|
-
add_source_ref_to_targets(
|
|
139
|
-
block[BlockProperties.NAME], parents, items,
|
|
140
|
-
BlockProperties.CHILDREN)
|
|
141
|
-
|
|
142
|
-
# handle variants
|
|
143
|
-
variant = block.get(BlockProperties.VARIANT, None)
|
|
144
|
-
if variant:
|
|
145
|
-
add_source_ref_to_targets(
|
|
146
|
-
block[BlockProperties.NAME], [variant], items,
|
|
147
|
-
BlockProperties.VARIANTS)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# description and reference
|
|
151
|
-
|
|
152
|
-
def find_block_in_items(block_name: str, items: list[Item]) -> ScriptsBlock | None:
|
|
153
|
-
for item in items:
|
|
154
|
-
blocks = item['data']
|
|
155
|
-
assert blocks is not None, "Something is wrong."
|
|
156
|
-
|
|
157
|
-
if block_name in blocks:
|
|
158
|
-
return blocks[block_name]
|
|
159
|
-
return None
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def copy_block_ref(block: ScriptsBlock, items: list[Item]) -> ScriptsBlock:
|
|
163
|
-
"""
|
|
164
|
-
#desc copies the description of the source block
|
|
165
|
-
#ref copies every key values of that source block into the block (if not already present)
|
|
166
|
-
"""
|
|
167
|
-
# copy #desc
|
|
168
|
-
if BlockProperties.REF_DESC in block:
|
|
169
|
-
desc_source_key: str = block[BlockProperties.REF_DESC]
|
|
170
|
-
desc_source = find_block_in_items(desc_source_key, items)
|
|
171
|
-
|
|
172
|
-
if desc_source is not None:
|
|
173
|
-
block[BlockProperties.DESCRIPTION] = desc_source[BlockProperties.DESCRIPTION]
|
|
174
|
-
|
|
175
|
-
# copy the short description if available too
|
|
176
|
-
if BlockProperties.SHORT_DESCRIPTION in desc_source:
|
|
177
|
-
block[BlockProperties.SHORT_DESCRIPTION] = desc_source[BlockProperties.SHORT_DESCRIPTION]
|
|
178
|
-
|
|
179
|
-
# copy #ref
|
|
180
|
-
if BlockProperties.REF_FULL in block:
|
|
181
|
-
ref_source_key: str = block[BlockProperties.REF_FULL]
|
|
182
|
-
ref_source = find_block_in_items(ref_source_key, items)
|
|
183
|
-
if ref_source is not None:
|
|
184
|
-
# we copy every key-value from the ref_block
|
|
185
|
-
# that doesn't already exist in the block
|
|
186
|
-
for key, value in ref_source.items():
|
|
187
|
-
if key not in block:
|
|
188
|
-
block[key] = value
|
|
189
|
-
|
|
190
|
-
return block
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
# parameters
|
|
194
|
-
|
|
195
|
-
def get_source_parameter(ref_key: str, items: list[Item]) -> dict:
|
|
196
|
-
"""
|
|
197
|
-
This will return the source parameter data from the ref_key.
|
|
198
|
-
The ref_key is in the format "BlockName/ParameterName"
|
|
199
|
-
"""
|
|
200
|
-
# find the source block and parameter
|
|
201
|
-
path = ref_key.split('/')
|
|
202
|
-
assert len(path) == 2, f"Invalid #ref format for '{ref_key}'. Needs to be in format 'BlockName/ParameterName'."
|
|
203
|
-
origin_block = path[0]
|
|
204
|
-
origin_param = path[1].lower()
|
|
205
|
-
|
|
206
|
-
origin_block_data = find_block_in_items(origin_block, items)
|
|
207
|
-
|
|
208
|
-
# make sure the source block and parameter exist
|
|
209
|
-
if origin_block_data is None:
|
|
210
|
-
raise ValueError(f"Source block '{origin_block}' not found for parameter '{origin_param}'.")
|
|
211
|
-
if BlockProperties.PARAMETERS not in origin_block_data:
|
|
212
|
-
raise ValueError(f"Source block '{origin_block}' has no parameters for parameter '{origin_param}'.")
|
|
213
|
-
if origin_param not in origin_block_data[BlockProperties.PARAMETERS]:
|
|
214
|
-
raise ValueError(f"Source block '{origin_block}' has no parameter '{origin_param}'.")
|
|
215
|
-
|
|
216
|
-
return origin_block_data[BlockProperties.PARAMETERS][origin_param]
|
|
217
|
-
|
|
218
|
-
def copy_parameters_ref(parameters: dict[str, dict], items: list[Item]):
|
|
219
|
-
for param_key, param_data in parameters.items():
|
|
220
|
-
if ParameterProperties.REF_FULL in param_data:
|
|
221
|
-
ref_key = param_data[ParameterProperties.REF_FULL]
|
|
222
|
-
|
|
223
|
-
source_param_data = get_source_parameter(ref_key, items)
|
|
224
|
-
assert source_param_data is not None, f"Source parameter '{ref_key}' not found for parameter '{param_key}'."
|
|
225
|
-
|
|
226
|
-
# copy every key-value from the source parameter data
|
|
227
|
-
# that doesn't already exist in the parameter data
|
|
228
|
-
for key, value in source_param_data.items():
|
|
229
|
-
if key not in param_data:
|
|
230
|
-
param_data[key] = value
|
|
231
|
-
|
|
232
|
-
if ParameterProperties.REF_DESC in param_data:
|
|
233
|
-
desc_key = param_data[ParameterProperties.REF_DESC]
|
|
234
|
-
|
|
235
|
-
source_param_data = get_source_parameter(desc_key, items)
|
|
236
|
-
assert source_param_data is not None, f"Source parameter '{desc_key}' not found for parameter '{param_key}'."
|
|
237
|
-
|
|
238
|
-
# make sure the source parameter has a description
|
|
239
|
-
if ParameterProperties.DESCRIPTION not in source_param_data:
|
|
240
|
-
raise ValueError(f"Parameter '{param_key}' has #desc but source has no description.")
|
|
241
|
-
|
|
242
|
-
# only copy the description
|
|
243
|
-
param_data[ParameterProperties.DESCRIPTION] = source_param_data[ParameterProperties.DESCRIPTION]
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
# main
|
|
247
|
-
|
|
248
|
-
def prepare(item: Item, items: list[Item]):
|
|
249
|
-
blocks = item['data']
|
|
250
|
-
assert blocks is not None, "Something went wrong."
|
|
251
|
-
|
|
252
|
-
for block in blocks.values():
|
|
253
|
-
prepare_relationship(block, items)
|
|
254
|
-
copy_block_ref(block, items)
|
|
255
|
-
|
|
256
|
-
parameters = block.get(BlockProperties.PARAMETERS, {})
|
|
257
|
-
copy_parameters_ref(parameters, items)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return blocks
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
def main():
|
|
268
|
-
for item in items:
|
|
269
|
-
item['data'] = process(item)
|
|
270
|
-
for item in items:
|
|
271
|
-
item['data'] = prepare(item, items)
|
|
272
|
-
for item in items:
|
|
273
|
-
output_file = item['output']
|
|
274
|
-
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
275
|
-
with open(output_file, 'w', encoding='utf-8') as f:
|
|
276
|
-
json.dump(item['data'], f, indent=2, ensure_ascii=False, sort_keys=True)
|
|
277
|
-
|
|
278
|
-
if __name__ == "__main__":
|
|
279
|
-
main()
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pz-scripts-data
|
|
3
|
-
Version: 1.1.0
|
|
4
|
-
Summary: Dataset for the Scripts of Project Zomboid.
|
|
5
|
-
Author: SimKDT
|
|
6
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
Classifier: Topic :: Database
|
|
9
|
-
Classifier: Operating System :: OS Independent
|
|
10
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Typing :: Typed
|
|
13
|
-
Requires-Python: >=3.12.3
|
|
14
|
-
License-File: LICENSE
|
|
15
|
-
Requires-Dist: pyyaml
|
|
16
|
-
Requires-Dist: jsonschema
|
|
17
|
-
Requires-Dist: pydantic>=2.11
|
|
18
|
-
Dynamic: license-file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{pz_scripts_data-1.1.0 → pz_scripts_data-1.1.2}/src/pz_scripts_data.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|