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