custom_shelf/utils.py
2025-12-01 17:26:08 +01:00

226 lines
5.4 KiB
Python

from pathlib import Path
from typing import Any
import bpy
import os
import subprocess
import json
from bpy.props import (
BoolProperty,
EnumProperty,
FloatProperty,
IntProperty,
PointerProperty,
StringProperty,
)
id_type = {
"Action": "actions",
"Armature": "armatures",
"Brush": "brushes",
"CacheFile": "cache_files",
"Camera": "cameras",
"Curve": "curves",
"FreestyleLineStyle": "linestyles",
"GreasePencil": "grease_pencil",
"Group": "groups",
"Image": "images",
"Key": "shape_keys",
"Light": "lights",
"Lattice": "lattices",
"Library": "librairies",
"Mask": "masks",
"Material": "materials",
"Mesh": "meshes",
"MetaBall": "metaballs",
"MovieClip": "movieclips",
"NodeTree": "node_groups",
"Object": "objects",
"PaintCurve": "paint_curves",
"Palette": "palettes",
"ParticleSettings": "particles",
"Scene": "scenes",
"Screen": "screens",
"Sound": "sounds",
"Speaker": "speakers",
"Text": "texts",
"Texture": "textures",
"Collection": "collections",
"VectorFont": "fonts",
"WindowManager": "window_managers",
"World": "worlds",
}
def read_json(path: Path):
jsonFile = path
if os.path.exists(jsonFile):
try:
with open(jsonFile) as data_file:
return json.load(data_file)
except Exception:
print("the file %s not json readable" % jsonFile)
return
def search_filter(search: str, str: str):
return search.lower() in str.lower()
def title(string: str):
return string.replace("_", " ").replace("-", " ").title()
def arg_name(string: str):
return string.replace(" ", "_").replace("-", "_").lower().strip("_")
def open_folder(path: Path):
try:
os.startfile(path)
except Exception:
_ = subprocess.Popen(["xdg-open", path])
def dic_to_args(dic):
import collections
args = collections.OrderedDict()
prop_type = {
str: StringProperty,
bool: BoolProperty,
float: FloatProperty,
int: IntProperty,
}
for k, v in dic.items():
if k in ("icon", "description") or not isinstance(k, str):
continue
if isinstance(v, str):
if "/" in v or "\\" in v:
args[k] = StringProperty(default=v, subtype="FILE_PATH")
else:
args[k] = StringProperty(default=v)
elif isinstance(v, bool):
args[k] = BoolProperty(default=v)
elif isinstance(v, float):
args[k] = FloatProperty(default=v, precision=3)
elif isinstance(v, int):
args[k] = IntProperty(default=v)
elif isinstance(v, dict):
if v.get("items") and isinstance(v["items"], (tuple, list)):
args[k] = EnumProperty(items=[(i, i, "") for i in v["items"]])
elif v.get("collection") and isinstance(v["collection"], str):
if v["collection"] not in id_type:
print(
"Collection %s not supported must be in %s"
% (v["collection"], id_type)
)
# args[k] = PointerProperty(type = getattr(bpy.types,v["collection"]))
else:
args[k] = PointerProperty(
type=getattr(bpy.types, v["collection"]), poll=v.get("poll")
)
else:
args[k] = prop_type[type(v["default"])](**v)
return args
def read_info(script_path: Path):
import collections
if isinstance(script_path, list):
lines = script_path
else:
with open(script_path, encoding="utf-8") as f:
lines = f.read().splitlines()
info = {}
for i, line in enumerate(lines):
if i >= 10:
return info, lines
if line.startswith("info"):
info_start = i
info_str = line
while (
info_str.endswith(",")
or not info_str.endswith("}")
or i == len(lines) - 1
):
i += 1
info_str += lines[i]
info_end = i
opening_brace_index = info_str.find("{")
try:
info = eval(info_str[opening_brace_index:])
except:
print("The info header in the file %s cannot be read" % script_path)
break
info = [(k, v) for k, v in info.items()]
info.sort(key=lambda x: info_str.find(x[0]))
info = collections.OrderedDict(info)
del lines[info_start : info_end + 1]
break
# remove backspace
for i in range(len(lines)):
if lines[0]:
break
else:
lines.pop(0)
for i in range(len(lines)):
if lines[-1]:
break
else:
lines.pop(-1)
return info, lines
def dic_to_str(dic: dict[str, Any], keys: list[str] | None = None, spaces: int = 4): # pyright: ignore[reportExplicitAny]
if not keys:
keys = sorted(dic)
line = "{\n"
for k in keys:
v = dic[k]
line += " " * spaces
if isinstance(k, str):
line += "'%s'" % k
else:
line += "%s" % k
line += " : "
if isinstance(v, str):
line += "'%s'" % v
else:
line += "%s" % v
line += ",\n"
line += "}\n\n"
return line