diff options
author | Owl <isaclien9752@gmail.com> | 2025-08-26 19:49:28 -0400 |
---|---|---|
committer | Owl <isaclien9752@gmail.com> | 2025-08-26 19:49:28 -0400 |
commit | a2ffb5ad9cb86a86a7fe92d258c893f982cf84c0 (patch) | |
tree | f95ae420de177ee70fea13cf1da2b3867dbb0688 /__init__.py | |
parent | 2119dafbffb9a948ae90ebbcbf3c1448f2395f29 (diff) | |
download | blenxy-a2ffb5ad9cb86a86a7fe92d258c893f982cf84c0.tar.gz blenxy-a2ffb5ad9cb86a86a7fe92d258c893f982cf84c0.zip |
more robust module checking/updating
Diffstat (limited to '__init__.py')
-rw-r--r-- | __init__.py | 116 |
1 files changed, 80 insertions, 36 deletions
diff --git a/__init__.py b/__init__.py index d20580a..e2971fd 100644 --- a/__init__.py +++ b/__init__.py @@ -2,74 +2,118 @@ # https://s-nako.work/2020/09/blender-error-attributeerror-_restrictcontext-object-has-no-attribute-view_layer/ # https://web.archive.org/web/20210925181415/https://blenderbrew.com/custom-application-templates-in-blender/ -# blenxy module -import importlib, bpy, sys +# elemental python modules blenxy needs +# that the python interpreter must have built in +import bpy, importlib, sys, subprocess, os, shutil +import math, mathutils, warnings, struct, site -# import the submmodules needed -# all submodules have a register/unregister function -# register function is to be executed on blenxy's load -# name can be anything but I want to keep the same nomenclature -# the dummy variable passed to the register funcs is needed -# since it is passed when being assigned to the load_post list -# (seems to be None always) -from . import required_modules # install needed modules for the bundled python -from . import basic_settings # user settings blenxy has -from . import collada_superbmd_import # custom importer for SuperBMD collada files -from . import collada_superbmd_export # custom exporter for SuperBMD collada files -from . import obj_kcl_export # custom exporter for OBJ files (collision) -from . import obj_neokclcreate_import # custom importer for OBJ files (collision, NeoKCLCreate) -from . import bck_import # custom importer for SMG BCK files -from . import bck_export # custom exporter for SMG BCK files +# elemental python modules blenxy needs +# that the python interpreter probably does not have built in/needs to be updated +pip_modules = ["pip", "wheel", "setuptools"] +new_modules = ["lxml", "numpy"] -# global variables -blenxy_modules = [required_modules, - basic_settings, - collada_superbmd_import, - collada_superbmd_export, - obj_kcl_export, - obj_neokclcreate_import, - bck_import, - bck_export] +# check which of the new modules needs to be installed +def new_mod_check(mod_names): + rtn = [] + for mod_name in mod_names: + try: + importlib.import_module(mod_name) + except: + rtn.append(mod_name) + return rtn + +# install given modules with pip but be sure to have pip first +def new_mod_install(mod_names): + # get python's interpreter binary path + py_bin = bpy.app.binary_path_python + pip_install = [py_bin, "-B", "-m", "pip", "install", + "--trusted-host", "pypi.python.org", + "--trusted-host", "files.pythonhosted.org", + "--trusted-host", "pypi.org", + "-U", "--force-reinstall", "--only-binary", ":all:"] + + # check if pip is available + pip = None + try: # import the pip module + pip = importlib.import_module("pip") + except: # install pip + subprocess.run([py_bin, "-B", "-m", "ensurepip"]) + subprocess.run(pip_install + pip_modules) + + # install the rest of the modules + if (mod_names != []): + for mod_name in mod_names: + if (mod_name == "numpy"): # specific to the numpy module + # get the numpy package path + numpy_path = None + for path in site.getsitepackages(): + if ("2.79" in path): + numpy_path = path + "/numpy" + break + os.rename(numpy_path, numpy_path + "_bad") + # normal module installation + subprocess.run(pip_install + [mod_name]) + return True + return False + +# all blenxy custom modules +blenxy_modules = ["basic_settings", # user settings blenxy has + "collada_superbmd_import", # custom importer for SuperBMD collada files + "collada_superbmd_export", # custom exporter for SuperBMD collada files + "obj_kcl_export", # custom exporter for OBJ files (collision) + "obj_neokclcreate_import", # custom importer for OBJ files (collision, NeoKCLCreate) + "bck_import", # custom importer for SMG BCK files + "bck_export"] # custom exporter for SMG BCK files -# function used to refresh blenxy's used modules +# function used to refresh blenxy's custom modules # so that they can be updated without closing blender @bpy.app.handlers.persistent def unload_blenxy_stuff(dummy): - # execute the unregister functions from each module # these functions won't die if the stuff to unregister isn't there - for mod in blenxy_modules: + for mod_name in blenxy_modules: + mod = importlib.import_module("." + mod_name, __package__) mod.unregister() # reload the modules in case they were modified (dev stuff) - for mod in blenxy_modules: + for mod_name in blenxy_modules: + mod = importlib.import_module("." + mod_name, __package__) importlib.reload(mod) # register function that blender will call when the template is loaded def register(): - # print the welcome print("\nWelcome to Blenxy!") print("Running on Blender: %s\n" % (bpy.app.version.__str__())) + # checking python modules + if (new_mod_install(new_mod_check(new_modules)) == True): + print("New modules installed. Exiting...") + exit(0) + for mod_name in new_modules: + mod = importlib.import_module(mod_name) + print("%s %s is installed!" % (mod_name, mod.__version__)) + # add this function to load_post first bpy.app.handlers.load_post.append(unload_blenxy_stuff) - # add the register functions to load_post (old_blenxy_modules) - for mod in blenxy_modules: + # add the register functions to load_post + for mod_name in blenxy_modules: + mod = importlib.import_module("." + mod_name, __package__) bpy.app.handlers.load_post.append(mod.register) # unregister function that blender will call when a new template is loaded def unregister(): - # print the goodbye print("\nLeaving Blenxy!\n") # remove the stuff added to the load_post list bpy.app.handlers.load_post.remove(unload_blenxy_stuff) - for mod in blenxy_modules: + for mod_name in blenxy_modules: + mod = importlib.import_module("." + mod_name, __package__) for func in bpy.app.handlers.load_post: if (mod.__name__ in func.__module__): bpy.app.handlers.load_post.remove(func) break # execute module's unregister functions - for mod in blenxy_modules: + for mod_name in blenxy_modules: + mod = importlib.import_module("." + mod_name, __package__) mod.unregister() |