Add repository list to package panel

Actually adding multiple repositories is disallowed for now
This commit is contained in:
Ellwood Zwovic
2017-07-24 16:44:35 -07:00
parent acad78f87c
commit 4cc865cd62

View File

@@ -75,7 +75,7 @@ class SubprocMixin:
def quit(self):
"""Signals the state machine to stop this operator from running."""
self.cancel(bpy.context)
self._state = 'QUIT'
def invoke(self, context, event):
@@ -87,6 +87,7 @@ class SubprocMixin:
# The subprocess should just be terminated when Blender quits. Without this,
# Blender would hang while closing, until the subprocess terminates itself.
# TODO: Perhaps it would be better to fork when blender exits?
self.process = self.create_subprocess()
self.process.daemon = True
self.process.start()
@@ -364,7 +365,19 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
bl_description = 'Check repositories for new and updated packages'
bl_options = {'REGISTER'}
log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh")
log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh_repositories")
_running = False
def invoke(self, context, event):
PACKAGE_OT_refresh_repositories._running = True
return super().invoke(context, event)
@classmethod
def poll(cls, context):
return not cls._running
def cancel(self, context):
PACKAGE_OT_refresh_repositories._running = False
def create_subprocess(self):
"""Starts the download process.
@@ -389,17 +402,7 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
import pathlib
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'packages', create=True))
repository_url = bpy.context.user_preferences.addons[__package__].preferences.repository_url
from urllib.parse import urlsplit, urlunsplit
parsed_url = urlsplit(repository_url)
if not parsed_url.path.endswith("repo.json"):
if parsed_url.path.endswith('/'):
new_path = parsed_url.path + "repo.json"
else:
new_path = parsed_url.path + "/repo.json"
repository_url = urlunsplit((parsed_url.scheme, parsed_url.netloc, new_path, parsed_url.query, parsed_url.fragment))
repository_url = bpy.context.user_preferences.addons[__package__].preferences.repositories[0].url
proc = multiprocessing.Process(target=subproc.refresh,
args=(self.pipe_subproc, storage_path, repository_url))
@@ -518,6 +521,63 @@ class PACKAGE_OT_load_repositories(SubprocMixin, bpy.types.Operator):
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 RepositoryProperty(bpy.types.PropertyGroup):
url = bpy.props.StringProperty(name="URL")
status = bpy.props.EnumProperty(name="Status", items=[
("OK", "Okay", "FILE_TICK"),
("NOTFOUND", "Not found", "ERROR"),
("NOCONNECT", "Could not connect", "QUESTION"),
])
class PACKAGE_UL_repositories(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
layout.alignment='LEFT'
if len(item.name) == 0:
layout.label(item['url'])
else:
layout.label(item.name)
def parse_repository_url(url: str) -> str:
"""Sanitize repository url"""
from urllib.parse import urlsplit, urlunsplit
parsed_url = urlsplit(url)
new_path = parsed_url.path.rstrip("repo.json")
return urlunsplit((parsed_url.scheme, parsed_url.netloc, new_path, parsed_url.query, parsed_url.fragment))
class PACKAGE_OT_add_repository(bpy.types.Operator):
bl_idname = "package.add_repository"
bl_label = "Add Repository"
url = bpy.props.StringProperty(name="Repository URL")
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def execute(self, context):
prefs = context.user_preferences.addons[__package__].preferences
if len(prefs.repositories) > 0:
self.report({'ERROR'}, "Only one repository at a time is currently supported")
return {'CANCELLED'}
if len(self.url) == 0:
self.report({'ERROR'}, "Repository URL not specified")
return {'CANCELLED'}
repo = prefs.repositories.add()
repo.url = parse_repository_url(self.url)
context.area.tag_redraw()
return {'FINISHED'}
class PACKAGE_OT_remove_repository(bpy.types.Operator):
bl_idname = "package.remove_repository"
bl_label = "Remove Repository"
def execute(self, context):
prefs = context.user_preferences.addons[__package__].preferences
prefs.repositories.remove(prefs.active_repository)
return {'FINISHED'}
class USERPREF_PT_packages(bpy.types.Panel):
bl_label = "Package Management"
@@ -539,12 +599,25 @@ class USERPREF_PT_packages(bpy.types.Panel):
def draw(self, context):
layout = self.layout
wm = context.window_manager
prefs = context.user_preferences.addons[__package__].preferences
main = layout.row()
spl = main.split(.12)
spl = main.split(.22)
sidebar = spl.column(align=True)
pkgzone = spl.column()
sidebar.label("Repositories")
row = sidebar.row()
row.template_list("PACKAGE_UL_repositories", "", prefs, "repositories", prefs, "active_repository")
col = row.column(align=True)
col.operator(PACKAGE_OT_add_repository.bl_idname, text="", icon='ZOOMIN')
col.operator(PACKAGE_OT_remove_repository.bl_idname, text="", icon='ZOOMOUT')
sidebar.separator()
sidebar.operator(PACKAGE_OT_refresh_repositories.bl_idname)
sidebar.separator()
sidebar.label(text="Category")
sidebar.prop(wm, "addon_filter", text="")
@@ -800,6 +873,12 @@ class PackageManagerPreferences(bpy.types.AddonPreferences):
name='Repository URL',
description='Temporary repository URL')
repositories = bpy.props.CollectionProperty(
type=RepositoryProperty,
name="Repositories",
)
active_repository = bpy.props.IntProperty()
def draw(self, context):
layout = self.layout
@@ -869,6 +948,12 @@ def register():
name="Install filter",
default='AVAILABLE',
)
bpy.utils.register_class(RepositoryProperty)
bpy.utils.register_class(PACKAGE_OT_add_repository)
bpy.utils.register_class(PACKAGE_OT_remove_repository)
bpy.utils.register_class(PACKAGE_UL_repositories)
bpy.utils.register_class(PackageManagerPreferences)
@@ -883,4 +968,10 @@ def unregister():
bpy.utils.unregister_class(WM_OT_package_toggle_expand)
del bpy.types.WindowManager.package_search
del bpy.types.WindowManager.package_install_filter
bpy.utils.unregister_class(RepositoryProperty)
bpy.utils.unregister_class(PACKAGE_OT_add_repository)
bpy.utils.unregister_class(PACKAGE_OT_remove_repository)
bpy.utils.unregister_class(PACKAGE_UL_repositories)
bpy.utils.unregister_class(PackageManagerPreferences)