From 6764ee8259f7abf54cab2212662a85db39f83a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 15 Mar 2022 18:37:39 +0100 Subject: [PATCH] Addon: actually allow setting the job storage path --- addon/flamenco/gui.py | 2 ++ addon/flamenco/job_submission.py | 28 --------------- addon/flamenco/job_types_propgroup.py | 25 +++++++++++++ addon/flamenco/operators.py | 27 +++++++++----- addon/flamenco/preferences.py | 51 +++++++++++++++++++++++++-- 5 files changed, 93 insertions(+), 40 deletions(-) diff --git a/addon/flamenco/gui.py b/addon/flamenco/gui.py index ee28132a..d316ea51 100644 --- a/addon/flamenco/gui.py +++ b/addon/flamenco/gui.py @@ -39,6 +39,8 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel): col = layout.column(align=True) col.prop(context.scene, "flamenco_job_name", text="Job Name") + row = col.row(align=True) + row.prop(context.scene, "flamenco_job_storage", text="Job Storage") layout.separator() diff --git a/addon/flamenco/job_submission.py b/addon/flamenco/job_submission.py index 8e6d77e4..806ed3cb 100644 --- a/addon/flamenco/job_submission.py +++ b/addon/flamenco/job_submission.py @@ -68,34 +68,6 @@ def set_blend_file( job.settings[BLENDFILE_SETTING_KEY] = str(blendfile) -def eval_hidden_settings( - context: bpy.types.Context, job_type: _AvailableJobType, job: _SubmittedJob -) -> None: - """Assign values to settings hidden from the UI. - - If the setting has an `eval` property, it'll be evaluated and used as the - setting value. Otherwise the default is used. - """ - for setting in job_type.settings: - if setting.get("visible", True): - # Skip those settings that will be visible in the GUI. - continue - - setting_eval = setting.get("eval", "") - if setting_eval: - value = JobTypePropertyGroup.eval_setting( - context, job, setting.key, setting_eval - ) - elif "default" in setting: - value = setting.default - else: - # No way to get a default value, so just don't bother overwriting - # anything. - continue - - job.settings[setting.key] = value - - def submit_job(job: _SubmittedJob, api_client: _ApiClient) -> _Job: """Send the given job to Flamenco Manager.""" from flamenco.manager import ApiClient diff --git a/addon/flamenco/job_types_propgroup.py b/addon/flamenco/job_types_propgroup.py index 0faf8ecd..b23f0191 100644 --- a/addon/flamenco/job_types_propgroup.py +++ b/addon/flamenco/job_types_propgroup.py @@ -115,6 +115,31 @@ class JobTypePropertyGroup: raise SettingEvalError(setting_key, setting_eval, eval_locals, ex) from ex return value + def eval_hidden_settings_of_job( + self, context: bpy.types.Context, job: _SubmittedJob + ) -> None: + """Assign values to settings hidden from the UI. + + If the setting has an `eval` property, it'll be evaluated and used as the + setting value. Otherwise the default is used. + """ + for setting in self.job_type.settings: + if setting.get("visible", True): + # Skip those settings that will be visible in the GUI. + continue + + setting_eval = setting.get("eval", "") + if setting_eval: + value = self.eval_setting(context, setting.key, setting_eval) + elif "default" in setting: + value = setting.default + else: + # No way to get a default value, so just don't bother overwriting + # anything. + continue + + job.settings[setting.key] = value + @staticmethod def last_n_dir_parts(n: int, filepath: Union[str, Path, None] = None) -> Path: """Return the last `n` parts of the directory of `filepath`. diff --git a/addon/flamenco/operators.py b/addon/flamenco/operators.py index d2ca267e..f611e455 100644 --- a/addon/flamenco/operators.py +++ b/addon/flamenco/operators.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # +import datetime import logging from pathlib import Path from typing import Optional, TYPE_CHECKING @@ -226,8 +227,12 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): self.report({"ERROR"}, "Project path %s does not exist" % project_path) return {"CANCELLED"} - # Determine where the render output will be stored. - pack_target_dir = Path("/render/_flamenco/tests/renders") / self.job_name + # Determine where the blend file will be stored. + unique_dir = "%s-%s" % ( + datetime.datetime.now().isoformat("-").replace(":", ""), + self.job_name, + ) + pack_target_dir = Path(context.scene.flamenco_job_storage) / unique_dir # TODO: this should take the blendfile location relative to the project path into account. pack_target_file = pack_target_dir / blendfile.name @@ -237,7 +242,7 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): self.packthread = bat_interface.copy( base_blendfile=blendfile, project=project_path, - target=pack_target_dir, + target=str(pack_target_dir), exclusion_filter="", # TODO: get from GUI. relative_only=True, # TODO: get from GUI. ) @@ -276,14 +281,18 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): api_client = self.get_api_client(context) - job_type = job_types.active_job_type(context.scene) - assert job_type is not None # If we're here, the job type should be known. + propgroup = getattr(context.scene, "flamenco_job_settings", None) + assert isinstance(propgroup, JobTypePropertyGroup), "did not expect %s" % ( + type(propgroup) + ) + propgroup.eval_hidden_settings_of_job(context, self.job) - job_submission.set_blend_file(job_type, self.job, self.blendfile_on_farm) - job_submission.eval_hidden_settings(context, job_type, self.job) - job = job_submission.submit_job(self.job, api_client) + job_submission.set_blend_file( + propgroup.job_type, self.job, self.blendfile_on_farm + ) - self.report({"INFO"}, "Job %s submitted" % job.name) + submitted_job = job_submission.submit_job(self.job, api_client) + self.report({"INFO"}, "Job %s submitted" % submitted_job.name) def _quit(self, context: bpy.types.Context) -> set[str]: """Stop any timer and return a 'FINISHED' status. diff --git a/addon/flamenco/preferences.py b/addon/flamenco/preferences.py index 6f406744..28d710c8 100644 --- a/addon/flamenco/preferences.py +++ b/addon/flamenco/preferences.py @@ -11,6 +11,13 @@ def discard_flamenco_client(prefs, context): comms.discard_flamenco_data() +def _update_default_job_storage( + prefs: "FlamencoPreferences", context: bpy.types.Context +) -> None: + _unregister_rna_props() + _register_rna_props(prefs) + + class FlamencoPreferences(bpy.types.AddonPreferences): bl_idname = "flamenco" @@ -21,14 +28,27 @@ class FlamencoPreferences(bpy.types.AddonPreferences): update=discard_flamenco_client, ) + job_storage: bpy.props.StringProperty( # type: ignore + name="Job Storage Directory", + subtype="DIR_PATH", + default="", + description="Directory where blend files are stored, when submitting them to Flamenco", + update=_update_default_job_storage, + ) + def draw(self, context: bpy.types.Context) -> None: layout = self.layout col = layout.column() + col.use_property_split = True + 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) + row.operator("flamenco.ping_manager", text="", icon="CHECKMARK") + if context.window_manager.flamenco_status_ping: + col.label(text=context.window_manager.flamenco_status_ping) + + col.prop(self, "job_storage") def get(context: bpy.types.Context) -> FlamencoPreferences: @@ -46,5 +66,30 @@ def manager_url(context: bpy.types.Context) -> str: return str(prefs.manager_url) +def _register_rna_props(prefs: FlamencoPreferences) -> None: + """RNA properties that have their defaults set in the preferences get registered here.""" + + bpy.types.Scene.flamenco_job_storage = bpy.props.StringProperty( + name="Flamenco Job Storage", + subtype="DIR_PATH", + default=prefs.job_storage, + description="Directory where blend files are stored, when submitting them to Flamenco", + ) + + +def _unregister_rna_props() -> None: + del bpy.types.Scene.flamenco_job_storage + + classes = (FlamencoPreferences,) -register, unregister = bpy.utils.register_classes_factory(classes) +_register, _unregister = bpy.utils.register_classes_factory(classes) + + +def register(): + _register() + _register_rna_props(get(bpy.context)) + + +def unregister(): + _unregister_rna_props() + _unregister()