Skip to content

Blender addon

Blender addons can be enabled in File/Preferences, add-ons tab.

see Blender extensions

some helper functions regarding addons

import bpy  
import addon_utils  
from pathlib import Path  
import shutil  
import logging  


def is_installed(name):  
    """check if plugin is installed, use plugin_name from manifest, checking folder name in addons"""  
    local_script_dir = bpy.utils.script_path_user()  
    local_addons_dir = Path(local_script_dir) / "addons"  
    return (local_addons_dir / name).exists()  


def installed_plugins():  
    """return list of installed plugins"""  
    # Blender names returned are from the operator, but plugin_name in the manifest refers to the blender folder name  
    # todo ideally we return a name thats useable in the pluggest install commands  
    return [mod.bl_info.get("name") for mod in addon_utils.modules()]  


def enabled_plugins() -> list[str]:  
    """return list of enabled plugins"""  
    # Blender names returned are from the operator, but plugin_name in the manifest refers to the blender folder name  
    # todo ideally we return a name thats useable in the pluggest install commands  
    return bpy.context.preferences.addons.keys()  


def disabled_plugins() -> list[str]:  
    """return list of disabled plugins"""  
    # Blender names returned are from the operator, but plugin_name in the manifest refers to the blender folder name  
    # todo ideally we return a name thats useable in the pluggest install commands  
    return [p for p in installed_plugins() if p not in enabled_plugins()]  


def disable_plugin(name):  
    """disable plugin by name"""  
    bpy.ops.preferences.addon_disable(module=name)  


def enable_plugin(name):  
    """enable plugin by name"""  
    bpy.ops.preferences.addon_enable(module=name)  


def install_plugin(plugin_paths: list[Path]) -> bool:  # todo , force=False, enable=True):  
    """install plugin from path"""  
    # If the “overwrite” parameter is True, the add-on will be reinstalled, even if it has not been previously removed.  

    # manifest is named io_xray    # but subdir is io_scene_xray    # resulting in clashes. we cant just rename the subdir, might break code inside.    # so we need to track the "name" with plugin_name in the manifest  
    # todo fix only support 1 plugin  
    plugin_path = plugin_paths[0]  
    if len(plugin_paths) > 1:  
        raise NotImplemented("Only 1 plugin can be installed at a time for now")  

    local_script_dir = bpy.utils.script_path_user()  
    local_addons_dir = Path(local_script_dir) / "addons"  
    new_plugin_path = local_addons_dir / plugin_path.name  
    shutil.move(str(plugin_path), str(new_plugin_path.parent))  # copy plugin_path to local_addons_dir  

    # check if plugin folder was copied, by checking if any files are in new_plugin_path    if not any(new_plugin_path.iterdir()):  
        logging.warning(f"Failed to install plugin {plugin_path.name}")  
        return False  
    else:  
        return True  


def uninstall_plugin(name):  
    """uninstall plugin by name"""  
    if not name:  
        logging.warning("No plugin name given")  
        return  
    bpy.ops.preferences.addon_remove(module=name)  


def open_install_dir():  
    """Open the directory where plugins are installed"""  
    local_script_dir = bpy.utils.script_path_user()  
    local_addons_dir = Path(local_script_dir) / "addons"  
    bpy.ops.wm.path_open(filepath=str(local_addons_dir))

Blender Python