diff --git a/__init__.py b/__init__.py index 61e34a1..97b7ada 100644 --- a/__init__.py +++ b/__init__.py @@ -9,11 +9,18 @@ import bpy class PackageSettings(bpy.types.PropertyGroup): url = bpy.props.StringProperty(name="URL") +# class PackageManager: + # # For some reason accessing 'settings' PointerProperty via wm.package_manager.settings gives a value error + # # but accessing it when not stored in this class (wm.package_manager_settings) is fine? + # # settings = bpy.props.PointerProperty(type=PackageSettings) + # pipes = [] + def register(): from . import (pkg_ops, pkg_ui) bpy.utils.register_class(PackageSettings) - bpy.types.WindowManager.PackageManagerSettings = bpy.props.PointerProperty(type=PackageSettings) + # bpy.types.WindowManager.package_manager = PackageManager() + bpy.types.WindowManager.package_manager_settings = bpy.props.PointerProperty(type=PackageSettings) pkg_ops.register() pkg_ui.register() @@ -22,5 +29,6 @@ def unregister(): pkg_ops.unregister() pkg_ui.unregister(); - del bpy.types.WindowManager.PackageManagerSettings + bpy.utils.unregister_class(PackageSettings) + del bpy.types.WindowManager.package_manager diff --git a/blenderpack.py b/blenderpack.py index 8606150..7b0d7d3 100755 --- a/blenderpack.py +++ b/blenderpack.py @@ -21,10 +21,20 @@ SCHEMA_VERSION = 1 class BadAddon(Exception): pass -def fetch(url): - # TODO: do conditional request - re = requests.get(url) - print(re.json()) +def fetch(url, pipe): + pipe[0].close() + try: + # TODO: do conditional request + re = requests.get(url) + # print(re.json()) + pipe[1].send(re.headers) + finally: + pipe[1].close() + + + +# class Package(): +# def __init__(self): def parse_blinfo(source: str) -> dict: diff --git a/pkg_ops.py b/pkg_ops.py index 6b10233..746dd10 100644 --- a/pkg_ops.py +++ b/pkg_ops.py @@ -1,21 +1,72 @@ import bpy -from multiprocessing import Process +import logging +from multiprocessing import Process, Pipe from . import blenderpack -class PACKAGE_OT_fetch_lists(bpy.types.Operator): - bl_idname = "package.fetch_lists" - bl_label = "Update package list(s)" +class SubprocessOperatorMixin: + timer = None + + # run once in invoke + def setup(self): + pass + # run on receipt of data from subprocess + def handle_response(self, resp): + pass + + def __init__(self): + self.pipe = Pipe() + self.subprocess = None + + def execute(self, context): + return self.invoke(context, None) + + def invoke(self, context, event): + self.subprocess.start() + # we have to explicitly close the end of the pipe we are NOT using, + # otherwise no exception will be generated when the other process closes its end. + self.pipe[1].close() + + wm = context.window_manager + wm.modal_handler_add(self) + self.timer = wm.event_timer_add(.01, context.window) + + self.setup() + + return {'RUNNING_MODAL'} + + def modal(self, context, event): + print("polling") + try: + if self.pipe[0].poll(): + newdata = self.pipe[0].recv() + else: + newdata = None + except EOFError: + return {'FINISHED'} + + if newdata is not None: + self.handle_response(newdata) + return {'PASS_THROUGH'} + +class PACKAGE_OT_fetch(SubprocessOperatorMixin, bpy.types.Operator): + bl_idname = "package.fetch" + bl_label = "Update package list(s)" + + def __init__(self): + SubprocessOperatorMixin.__init__(self) + settings = bpy.context.window_manager.package_manager_settings + self.subprocess = Process(target=blenderpack.fetch, args=(settings.url, self.pipe)) + + def handle_response(self, resp): + print("your response:", resp) def execute(self, context): - settings = context.window_manager.PackageManagerSettings - proc = Process(target=lambda: blenderpack.fetch(settings.url)) - proc.start() return {'FINISHED'} def register(): - bpy.utils.register_class(PACKAGE_OT_fetch_lists) + bpy.utils.register_class(PACKAGE_OT_fetch) def unregister(): - bpy.utils.unregister_class(PACKAGE_OT_fetch_lists) + bpy.utils.unregister_class(PACKAGE_OT_fetch) diff --git a/pkg_ui.py b/pkg_ui.py index af3ce6d..4de5338 100644 --- a/pkg_ui.py +++ b/pkg_ui.py @@ -16,8 +16,8 @@ class USERPREF_PT_packages(bpy.types.Panel): layout = self.layout row = layout.row() - row.prop(context.window_manager.PackageManagerSettings, "url") - row.operator(pkg_ops.PACKAGE_OT_fetch_lists.bl_idname, text="Fetch") + row.prop(context.window_manager.package_manager_settings, "url") + row.operator(pkg_ops.PACKAGE_OT_fetch.bl_idname, text="Fetch") def register(): bpy.utils.register_class(USERPREF_PT_packages)