From 850678f49573142fcf393eda1ea62f354892e072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 10 Mar 2022 17:57:26 +0100 Subject: [PATCH] Addon: allow configuring the Manager URL Previously it was hard-coded to `http://localhost:8080/`, now that's just the default value. --- addon/flamenco/__init__.py | 9 ++++- addon/flamenco/comms.py | 4 +-- addon/flamenco/operators.py | 62 ++++++++++++++++++++++++++++++----- addon/flamenco/preferences.py | 44 +++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 addon/flamenco/preferences.py diff --git a/addon/flamenco/__init__.py b/addon/flamenco/__init__.py index 676dbb8c..200d9252 100644 --- a/addon/flamenco/__init__.py +++ b/addon/flamenco/__init__.py @@ -16,7 +16,7 @@ bl_info = { __is_first_load = "operators" not in locals() if __is_first_load: - from . import operators, gui, job_types, comms + from . import operators, gui, job_types, comms, preferences else: import importlib @@ -24,6 +24,7 @@ else: gui = importlib.reload(gui) job_types = importlib.reload(job_types) comms = importlib.reload(comms) + preferences = importlib.reload(preferences) import bpy @@ -42,6 +43,11 @@ def register() -> None: bpy.app.handlers.load_pre.append(discard_global_flamenco_data) bpy.app.handlers.load_factory_preferences_post.append(discard_global_flamenco_data) + # Placeholder to contain the result of a 'ping' to Flamenco Manager, + # so that it can be shown in the preferences panel. + bpy.types.WindowManager.flamenco_status_ping = bpy.props.StringProperty() + + preferences.register() operators.register() gui.register() job_types.register() @@ -55,3 +61,4 @@ def unregister() -> None: job_types.unregister() gui.unregister() operators.unregister() + preferences.unregister() diff --git a/addon/flamenco/comms.py b/addon/flamenco/comms.py index 56b90636..fc716151 100644 --- a/addon/flamenco/comms.py +++ b/addon/flamenco/comms.py @@ -4,13 +4,11 @@ import logging -import bpy - _flamenco_client = None _log = logging.getLogger(__name__) -def flamenco_api_client(manager_url="http://localhost:8080"): +def flamenco_api_client(manager_url: str): """Returns an API client for communicating with a Manager.""" global _flamenco_client diff --git a/addon/flamenco/operators.py b/addon/flamenco/operators.py index f295477c..a8df5608 100644 --- a/addon/flamenco/operators.py +++ b/addon/flamenco/operators.py @@ -1,23 +1,34 @@ # SPDX-License-Identifier: GPL-3.0-or-later - # import bpy -class FLAMENCO_OT_fetch_job_types(bpy.types.Operator): +class FlamencoOpMixin: + @staticmethod + def get_api_client(context): + """Get a Flamenco API client to talk to the Manager. + + Getting the client also loads the dependencies, so only import things + from `flamenco.manager` after calling this function. + """ + from . import comms, preferences + + manager_url = preferences.manager_url(context) + api_client = comms.flamenco_api_client(manager_url) + return api_client + + +class FLAMENCO_OT_fetch_job_types(FlamencoOpMixin, bpy.types.Operator): bl_idname = "flamenco.fetch_job_types" bl_label = "Fetch Job Types" - bl_description = "Query Flamenco Manager to obtain the available job types." + bl_description = "Query Flamenco Manager to obtain the available job types" def execute(self, context: bpy.types.Context) -> set[str]: - from . import comms, job_types - - # Getting the client also loads the dependencies, so we can only import - # API stuff after it. - api_client = comms.flamenco_api_client() + api_client = self.get_api_client(context) from flamenco.manager import ApiException + from . import job_types old_job_type_name = getattr(context.window_manager, "flamenco_job_type", "") @@ -34,5 +45,38 @@ class FLAMENCO_OT_fetch_job_types(bpy.types.Operator): return {"FINISHED"} -classes = (FLAMENCO_OT_fetch_job_types,) +class FLAMENCO_OT_ping_manager(FlamencoOpMixin, bpy.types.Operator): + bl_idname = "flamenco.ping_manager" + bl_label = "Flamenco: Ping Manager" + bl_description = "Attempt to connect to the Manager" + bl_options = {"REGISTER"} # No UNDO. + + def execute(self, context: bpy.types.Context) -> set[str]: + api_client = self.get_api_client(context) + + from flamenco.manager import ApiException + from flamenco.manager.apis import MetaApi + from flamenco.manager.models import FlamencoVersion + + context.window_manager.flamenco_status_ping = "..." + + meta_api = MetaApi(api_client) + try: + response: FlamencoVersion = meta_api.get_version() + except ApiException as ex: + report = "Manager cannot be reached: %s" % ex + level = "ERROR" + else: + report = "%s version %s found" % (response.name, response.version) + level = "INFO" + + self.report({level}, report) + context.window_manager.flamenco_status_ping = report + return {"FINISHED"} + + +classes = ( + FLAMENCO_OT_fetch_job_types, + FLAMENCO_OT_ping_manager, +) register, unregister = bpy.utils.register_classes_factory(classes) diff --git a/addon/flamenco/preferences.py b/addon/flamenco/preferences.py new file mode 100644 index 00000000..ad45e633 --- /dev/null +++ b/addon/flamenco/preferences.py @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# + +import bpy + + +def discard_flamenco_client(prefs, context): + """Discard any cached Flamenco client after the Manager URL changes.""" + from flamenco import comms + + comms.discard_flamenco_data() + + +class FlamencoPreferences(bpy.types.AddonPreferences): + bl_idname = "flamenco" + + manager_url: bpy.props.StringProperty( # type: ignore + name="Manager URL", + description="Location of the Manager", + default="http://localhost:8080/", + update=discard_flamenco_client, + ) + + def draw(self, context: bpy.types.Context) -> None: + layout = self.layout + + col = layout.column() + row = col.row(align=True) + row.prop(self, "manager_url") + row.operator("flamenco.ping_manager", text="Test Connection") + col.label(text=context.window_manager.flamenco_status_ping) + + +def manager_url(context: bpy.types.Context) -> str: + """Returns the configured Manager URL.""" + prefs = context.preferences.addons["flamenco"].preferences + assert isinstance( + prefs, FlamencoPreferences + ), "Expected FlamencoPreferences, got %s instead" % (type(prefs)) + return prefs.manager_url + + +classes = (FlamencoPreferences,) +register, unregister = bpy.utils.register_classes_factory(classes)