Code exists already for checking if an addon can be enabled. Blender returns {'CANCELLED'} if addon isn't found:
elif m.startswith('enable '):
command, addon = m.split()
t = bpy.ops.wm.addon_enable(module=addon)
if t == {'FINISHED'}:
msg = 'enabled {0}'.format(addon)
elif t == {'CANCELLED'}:
msg = 'addon not enabled, is it spelled correctly?'
add_scrollback(msg, 'INFO')
The problem with that is, well, who can remember full addon names? I can't.. This means making a dict of addons mapping to their full names.. something like
# this to be used for addons which are definitely present..
lazy_dict = {
'-imgp': [addon_enable, "io_import_images_as_planes"],
'-bb2': [addon_enable, "BioBlender"],
'-idxv': [addon_enable, "view3d_idx_view"]
}
and my super lazy 'enable if present, or download and enable if not'
def lazy_power_download(mod, dl_url, op_path, op_name):
registers_operator = [op_path, op_name]
packaged = dict(
operator=registers_operator,
module_to_enable=mod,
url=dl_url
)
test_dl_run(packaged)
where test_dl_run
is this monstrocity..
def test_dl_run(packaged, invoke_type=None):
'''
This implementation:
- test if the operator already exists in bpy.ops.xxxx
- if yes, run
- if no, try (enable and run).
- if failed to enable then the packaged dict includes a download url
- attempts a download and then (enable and run)
Restrictions:
- Expects only a single download file not a folder structure yet.
'''
_ops, _name = packaged['operator']
_module = packaged['module_to_enable']
_url = packaged['url']
# first check if the operator exists.
addon_enabled = _name in dir(_ops)
def run_addon(_ops, _name, invoke_type):
if invoke_type:
getattr(_ops, _name)(invoke_type)
else:
getattr(_ops, _name)()
if not addon_enabled:
try:
bpy.ops.wm.addon_enable(module=_module)
# getattr(_ops, _name)()
run_addon(_ops, _name, invoke_type)
return
except:
print('\'{0}\' addon not found.'.format(_module))
print('will attempt download: ')
# I only want the shortest path.
script_paths = bpy.utils.script_paths()
sp = list(sorted(script_paths, key=len))[0]
contrib_path = os.path.join(sp, 'addons_contrib')
if not os.path.isdir(contrib_path):
print('attempting to make path...')
shutil.os.mkdir(contrib_path)
# path should exist now.
print('downloading from:', _url)
filename = _url.split('/')[-1]
py_destination = os.path.join(contrib_path, filename)
urlretrieve(_url, py_destination)
# must happen or the new script isn't found.
bpy.utils.refresh_script_paths()
# try one last time to enable and run.
try:
bpy.ops.wm.addon_enable(module=_module)
# getattr(_ops, _name)()
run_addon(_ops, _name, invoke_type)
return
except:
msg = 'blender console has failed miserably, let me know'
print(msg)
else:
# the ops is present, just call it.
print('STEP 6 operator is present, simply call operator')
# getattr(_ops, _name)() # get and call
run_addon(_ops, _name, invoke_type)