Some odd tweaks and repo management code

This commit is contained in:
Ellwood Zwovic
2017-07-18 15:10:11 -07:00
parent c0d2419bea
commit 6193437636
2 changed files with 118 additions and 21 deletions

View File

@@ -126,7 +126,7 @@ class SubprocMixin:
def handle_received_data(self):
recvd = self.pipe_blender.recv()
self.log.info('Received message from subprocess: %s', recvd)
self.log.debug('Received message from subprocess: %s', recvd)
try:
handler = self.msg_handlers[type(recvd)]
except KeyError:
@@ -261,7 +261,7 @@ class BPKG_OT_refresh(SubprocMixin, bpy.types.Operator):
import pathlib
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'addons', create=True))
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'packages', create=True))
repository_url = bpy.context.user_preferences.addons[__package__].preferences.repository_url
proc = multiprocessing.Process(target=subproc.refresh,
@@ -326,6 +326,68 @@ class BPKG_OT_hang(SubprocMixin, bpy.types.Operator):
def report_process_died(self):
self.report({'ERROR'}, 'Process died, exit code %s' % self.process.exitcode)
class BPKG_OT_load_repositories(SubprocMixin, bpy.types.Operator):
bl_idname = 'bpkg.load_repositories'
bl_label = 'Load Repositories'
bl_description = 'Load repositories from disk'
bl_options = {'REGISTER'}
log = logging.getLogger(__name__ + '.BPKG_OT_load_repositories')
def create_subprocess(self):
"""
Start the load process and register message handlers
"""
import multiprocessing
import pathlib
# TODO: We need other paths besides this one on subprocess end, so it might be better to pass them all at once.
# For now, just pass this one.
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'packages', create=True))
self.log.debug("Using %s as install path", install_path)
import addon_utils
proc = multiprocessing.Process(
target=subproc.load_repositories,
args=(self.pipe_subproc, self.storage_path)
)
return proc
self.msg_handlers = {
subproc.SubprocError: self._subproc_error,
subproc.RepositoryResult: self._subproc_repository_result,
subproc.Success: self._subproc_success,
subproc.Aborted: self._subproc_aborted,
}
def _subproc_error(self, error: subproc.SubprocError):
self.report({'ERROR'}, 'Failed to load repositories: %s' % error.message)
self.quit()
def _subproc_repository_result(self, result: subproc.RepositoryResult):
bpy.context.user_preferences.addons[__package__].preferences['repo'] = result.repository
self.log.info("Loaded repository %s", result.repository.name)
def _subproc_success(self, success: subproc.Success):
self.log.info("Successfully loaded repositories")
self.quit()
def _subproc_aborted(self, aborted: subproc.Aborted):
self.report({'ERROR'}, 'Package installation aborted per your request')
self.quit()
def report_process_died(self):
if self.process.exitcode:
self.log.error('Process died without telling us! Exit code was %i', self.process.exitcode)
self.report({'ERROR'}, 'Error downloading package, exit code %i' % self.process.exitcode)
else:
self.log.error('Process died without telling us! Exit code was 0 though')
self.report({'WARNING'}, 'Error downloading package, but process finished OK. This is weird.')
class USERPREF_PT_packages(bpy.types.Panel):
bl_label = "Package Management"
bl_space_type = 'USER_PREFERENCES'
@@ -340,12 +402,6 @@ class USERPREF_PT_packages(bpy.types.Panel):
return (userpref.active_section == 'PACKAGES')
def draw(self, context):
try:
repo = context.user_preferences.addons[__package__].preferences['repo']
except KeyError:
# HACK:
# If no repositories are initialized, we should try to refresh them. If that doesn't work, display a message
repo = {'packages': []}
layout = self.layout
@@ -365,7 +421,7 @@ class USERPREF_PT_packages(bpy.types.Panel):
#TODO: more advanced filter/sorting; sort matches which match the filter string from the start higher
#Also some caching of this would be nice, this only needs to be re-run when any of the filters change.
def filter_package(package):
def filter_package(package):# {{{
"""Returns true if the given package matches all filters"""
filterstr = bpy.context.window_manager.package_search
category = bpy.context.window_manager.addon_filter
@@ -390,9 +446,9 @@ class USERPREF_PT_packages(bpy.types.Panel):
if match_search() and match_category():
return True
return False
return False# }}}
def draw_package(pkg, layout):
def draw_package(pkg, layout):# {{{
"""Draws the given package"""
pkgbox = layout.box()
spl = pkgbox.split(.8)
@@ -461,12 +517,35 @@ class USERPREF_PT_packages(bpy.types.Panel):
spl.label("{}:".format(prop.title()))
spl.label(str(blinfo[prop]))
if pkg.get('expand'):
expanded()
else:
collapsed()
collapsed()# }}}
def center_message(layout, msg: str):
"""draw a label in the center of an extra-tall row"""
row = layout.row()
row.label(text=msg)
row.alignment='CENTER'
row.scale_y = 10
try:
#TODO either store repos in windowmanager and reload from disk every time, or store them in the .blend. Not both
repo = context.user_preferences.addons[__package__].preferences['repo']
except KeyError:
center_message("Loading Repositories...")
import pathlib
# TODO: read repository synchronously for now; can't run an operator to do async monitoring from draw code
prefs = bpy.context.user_preferences.addons[__package__].preferences
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'packages', create=True))
res = subproc._load_repo(storage_path)
prefs['repo'] = res.to_dict(sort=True, ids=True)
return
if repo is None:
center_message("No repository found. Add one in the addon preferences.")
return
for pkg in repo['packages']:
@@ -527,6 +606,7 @@ class PackageManagerPreferences(bpy.types.AddonPreferences):
def register():
bpy.utils.register_class(BPKG_OT_install)
bpy.utils.register_class(BPKG_OT_refresh)
bpy.utils.register_class(BPKG_OT_load_repositories)
bpy.utils.register_class(BPKG_OT_hang)
bpy.utils.register_class(USERPREF_PT_packages)
bpy.utils.register_class(WM_OT_package_toggle_expand)
@@ -549,6 +629,7 @@ def register():
def unregister():
bpy.utils.unregister_class(BPKG_OT_install)
bpy.utils.unregister_class(BPKG_OT_refresh)
bpy.utils.unregister_class(BPKG_OT_load_repositories)
bpy.utils.unregister_class(BPKG_OT_hang)
bpy.utils.unregister_class(USERPREF_PT_packages)
bpy.utils.unregister_class(WM_OT_package_toggle_expand)