From f66f67971078cb137484796d13692ff1ec064592 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 18:22:23 +0100 Subject: [PATCH 01/10] renamed 'root' to '_workfiles_root' --- openpype/tools/workfiles/app.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index f4a86050cb..e05a51a962 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -367,7 +367,7 @@ class FilesWidget(QtWidgets.QWidget): self.template_key = "work" # This is not root but workfile directory - self.root = None + self._workfiles_root = None self.host = api.registered_host() # Whether to automatically select the latest modified @@ -465,8 +465,8 @@ class FilesWidget(QtWidgets.QWidget): # This way we can browse it even before we enter it. if self._asset_id and self._task_name and self._task_type: session = self._get_session() - self.root = self.host.work_root(session) - self.files_model.set_root(self.root) + self._workfiles_root = self.host.work_root(session) + self.files_model.set_root(self._workfiles_root) else: self.files_model.set_root(None) @@ -590,7 +590,7 @@ class FilesWidget(QtWidgets.QWidget): window = NameWindow( parent=self, - root=self.root, + root=self._workfiles_root, anatomy=self.anatomy, template_key=self.template_key, session=session @@ -605,7 +605,7 @@ class FilesWidget(QtWidgets.QWidget): return src = self._get_selected_filepath() - dst = os.path.join(self.root, work_file) + dst = os.path.join(self._workfiles_root, work_file) shutil.copy(src, dst) self.workfile_created.emit(dst) @@ -638,9 +638,9 @@ class FilesWidget(QtWidgets.QWidget): "filter": ext_filter } if Qt.__binding__ in ("PySide", "PySide2"): - kwargs["dir"] = self.root + kwargs["dir"] = self._workfiles_root else: - kwargs["directory"] = self.root + kwargs["directory"] = self._workfiles_root work_file = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0] if work_file: @@ -652,17 +652,21 @@ class FilesWidget(QtWidgets.QWidget): return # Initialize work directory if it has not been initialized before - if not os.path.exists(self.root): - log.debug("Initializing Work Directory: %s", self.root) + if not os.path.exists(self._workfiles_root): + log.debug("Initializing Work Directory: %s", self._workfiles_root) self.initialize_work_directory() - if not os.path.exists(self.root): + if not os.path.exists(self._workfiles_root): # Failed to initialize Work Directory log.error( - "Failed to initialize Work Directory: {}".format(self.root) + "Failed to initialize Work Directory: {}".format( + self._workfiles_root + ) ) return - file_path = os.path.join(os.path.normpath(self.root), work_file) + file_path = os.path.join( + os.path.normpath(self._workfiles_root), work_file + ) pipeline.emit("before.workfile.save", [file_path]) @@ -673,7 +677,7 @@ class FilesWidget(QtWidgets.QWidget): self._asset_id, self._task_name, self._task_type ) create_workdir_extra_folders( - self.root, + self._workfiles_root, api.Session["AVALON_APP"], self._task_type, self._task_name, From 82432e476434ac36724dee72bd830cfcd678c7c5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 18:22:40 +0100 Subject: [PATCH 02/10] added variable '_workdir_path' which is used to create extra folders --- openpype/tools/workfiles/app.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index e05a51a962..04dc1ed40b 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -368,6 +368,7 @@ class FilesWidget(QtWidgets.QWidget): # This is not root but workfile directory self._workfiles_root = None + self._workdir_path = None self.host = api.registered_host() # Whether to automatically select the latest modified @@ -465,6 +466,7 @@ class FilesWidget(QtWidgets.QWidget): # This way we can browse it even before we enter it. if self._asset_id and self._task_name and self._task_type: session = self._get_session() + self._workdir_path = session["AVALON_WORKDIR"] self._workfiles_root = self.host.work_root(session) self.files_model.set_root(self._workfiles_root) @@ -677,6 +679,7 @@ class FilesWidget(QtWidgets.QWidget): self._asset_id, self._task_name, self._task_type ) create_workdir_extra_folders( + self._workdir_path, self._workfiles_root, api.Session["AVALON_APP"], self._task_type, From 7075183a47e0f6848d98db9b804a92f94bfec6e5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 18:26:12 +0100 Subject: [PATCH 03/10] emit also workdir for 'before.workfile.save' --- openpype/hosts/maya/api/__init__.py | 9 +++------ openpype/tools/workfiles/app.py | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/maya/api/__init__.py b/openpype/hosts/maya/api/__init__.py index b25fd44217..17ec7ac56d 100644 --- a/openpype/hosts/maya/api/__init__.py +++ b/openpype/hosts/maya/api/__init__.py @@ -218,12 +218,9 @@ def on_task_changed(*args): ) -def before_workfile_save(workfile_path): - if not workfile_path: - return - - workdir = os.path.dirname(workfile_path) - copy_workspace_mel(workdir) +def before_workfile_save(workfile_path, workdir_path): + if workdir_path: + copy_workspace_mel(workdir_path) class MayaDirmap(HostDirmap): diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 04dc1ed40b..bd666d9d4f 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -670,7 +670,7 @@ class FilesWidget(QtWidgets.QWidget): os.path.normpath(self._workfiles_root), work_file ) - pipeline.emit("before.workfile.save", [file_path]) + pipeline.emit("before.workfile.save", [file_path, self._workdir_path]) self._enter_session() # Make sure we are in the right session self.host.save_file(file_path) From 7a1edd6b1eb50fe3c2c3fec50fa7f75689e7dda7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 18:39:14 +0100 Subject: [PATCH 04/10] added base of event objects --- openpype/pipeline/lib/__init__.py | 8 +++++++ openpype/pipeline/lib/events.py | 38 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 openpype/pipeline/lib/events.py diff --git a/openpype/pipeline/lib/__init__.py b/openpype/pipeline/lib/__init__.py index 1bb65be79b..e2c15cbd2d 100644 --- a/openpype/pipeline/lib/__init__.py +++ b/openpype/pipeline/lib/__init__.py @@ -1,3 +1,8 @@ +from .events import ( + BaseEvent, + BeforeWorkfileSave +) + from .attribute_definitions import ( AbtractAttrDef, UnknownDef, @@ -9,6 +14,9 @@ from .attribute_definitions import ( __all__ = ( + "BaseEvent", + "BeforeWorkfileSave", + "AbtractAttrDef", "UnknownDef", "NumberDef", diff --git a/openpype/pipeline/lib/events.py b/openpype/pipeline/lib/events.py new file mode 100644 index 0000000000..8e7dcbd70e --- /dev/null +++ b/openpype/pipeline/lib/events.py @@ -0,0 +1,38 @@ +"""Events holding data about specific event.""" + + +class BaseEvent: + """Base event object. + + Can be used to anything because data are not much specific. Only required + argument is topic which defines why event is happening and may be used for + filtering. + + Arg: + topic (str): Identifier of event. + data (Any): Data specific for event. Dictionary is recommended. + """ + _data = {} + + def __init__(self, topic, data=None): + self._topic = topic + if data is None: + data = {} + self._data = data + + @property + def data(self): + return self._data + + @property + def topic(self): + return self._topic + + +class BeforeWorkfileSave(BaseEvent): + """Before workfile changes event data.""" + def __init__(self, new_workfile, workdir): + super(BeforeWorkfileSave, self).__init__("before.workfile.save") + + self.workfile_path = new_workfile + self.workdir_path = workdir From 4aa096d5bc0d4d812abcabdf9cc2e154f0461ef5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 18:54:11 +0100 Subject: [PATCH 05/10] added emit function --- openpype/pipeline/lib/events.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openpype/pipeline/lib/events.py b/openpype/pipeline/lib/events.py index 8e7dcbd70e..9a6bd12f2d 100644 --- a/openpype/pipeline/lib/events.py +++ b/openpype/pipeline/lib/events.py @@ -1,7 +1,8 @@ """Events holding data about specific event.""" -class BaseEvent: +# Inherit from 'object' for Python 2 hosts +class BaseEvent(object): """Base event object. Can be used to anything because data are not much specific. Only required @@ -28,6 +29,13 @@ class BaseEvent: def topic(self): return self._topic + @classmethod + def emit(cls, *args, **kwargs): + from avalon import pipeline + + obj = cls(*args, **kwargs) + pipeline.emit(obj.topic, [obj]) + class BeforeWorkfileSave(BaseEvent): """Before workfile changes event data.""" From 4e904288ad707b764676607f9aa1bbc2abdf077e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 18:55:30 +0100 Subject: [PATCH 06/10] emit BeforeWorkfileSave event in workfiles tool --- openpype/hosts/maya/api/__init__.py | 3 ++- openpype/pipeline/lib/events.py | 6 ++++++ openpype/tools/workfiles/app.py | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/api/__init__.py b/openpype/hosts/maya/api/__init__.py index 17ec7ac56d..0ad1c8ba29 100644 --- a/openpype/hosts/maya/api/__init__.py +++ b/openpype/hosts/maya/api/__init__.py @@ -218,7 +218,8 @@ def on_task_changed(*args): ) -def before_workfile_save(workfile_path, workdir_path): +def before_workfile_save(event): + workdir_path = event.workdir_path if workdir_path: copy_workspace_mel(workdir_path) diff --git a/openpype/pipeline/lib/events.py b/openpype/pipeline/lib/events.py index 9a6bd12f2d..b9ad889383 100644 --- a/openpype/pipeline/lib/events.py +++ b/openpype/pipeline/lib/events.py @@ -31,10 +31,16 @@ class BaseEvent(object): @classmethod def emit(cls, *args, **kwargs): + """Create object of event and emit. + + Args: + Same args as '__init__' expects which may be class specific. + """ from avalon import pipeline obj = cls(*args, **kwargs) pipeline.emit(obj.topic, [obj]) + return obj class BeforeWorkfileSave(BaseEvent): diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index bd666d9d4f..763e0f796d 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -11,6 +11,7 @@ from Qt import QtWidgets, QtCore from avalon import io, api, pipeline from openpype import style +from openpype.pipeline.lib import BeforeWorkfileSave from openpype.tools.utils.lib import ( qt_app_context ) @@ -670,7 +671,7 @@ class FilesWidget(QtWidgets.QWidget): os.path.normpath(self._workfiles_root), work_file ) - pipeline.emit("before.workfile.save", [file_path, self._workdir_path]) + BeforeWorkfileSave.emit(file_path, self._workdir_path) self._enter_session() # Make sure we are in the right session self.host.save_file(file_path) From c94ce278f15428c4b717471378cb7f29c320988f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 19:04:46 +0100 Subject: [PATCH 07/10] added data to event --- openpype/pipeline/lib/events.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/pipeline/lib/events.py b/openpype/pipeline/lib/events.py index b9ad889383..d9920b38e3 100644 --- a/openpype/pipeline/lib/events.py +++ b/openpype/pipeline/lib/events.py @@ -46,7 +46,11 @@ class BaseEvent(object): class BeforeWorkfileSave(BaseEvent): """Before workfile changes event data.""" def __init__(self, new_workfile, workdir): - super(BeforeWorkfileSave, self).__init__("before.workfile.save") + data = { + "workfile_path": new_workfile, + "workdir_path": workdir + } + super(BeforeWorkfileSave, self).__init__("before.workfile.save", data) self.workfile_path = new_workfile self.workdir_path = workdir From 34830ee8813a6256131dea57eb6ac312b8d465b4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 21:22:02 +0100 Subject: [PATCH 08/10] removed line --- openpype/tools/workfiles/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 763e0f796d..703d077448 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -681,7 +681,6 @@ class FilesWidget(QtWidgets.QWidget): ) create_workdir_extra_folders( self._workdir_path, - self._workfiles_root, api.Session["AVALON_APP"], self._task_type, self._task_name, From 3d2a39b592ae11a96bbb1f293d632110629e034a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 22:45:42 +0100 Subject: [PATCH 09/10] trigger before save event as first thing --- openpype/pipeline/lib/events.py | 11 +++-------- openpype/tools/workfiles/app.py | 6 +++--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/openpype/pipeline/lib/events.py b/openpype/pipeline/lib/events.py index d9920b38e3..05dea20e8c 100644 --- a/openpype/pipeline/lib/events.py +++ b/openpype/pipeline/lib/events.py @@ -45,12 +45,7 @@ class BaseEvent(object): class BeforeWorkfileSave(BaseEvent): """Before workfile changes event data.""" - def __init__(self, new_workfile, workdir): - data = { - "workfile_path": new_workfile, - "workdir_path": workdir - } - super(BeforeWorkfileSave, self).__init__("before.workfile.save", data) - - self.workfile_path = new_workfile + def __init__(self, filename, workdir): + super(BeforeWorkfileSave, self).__init__("before.workfile.save") + self.filename = filename self.workdir_path = workdir diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 703d077448..92cb23b619 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -654,6 +654,9 @@ class FilesWidget(QtWidgets.QWidget): if not work_file: return + # Trigger before save event + BeforeWorkfileSave.emit(work_file, self._workdir_path) + # Initialize work directory if it has not been initialized before if not os.path.exists(self._workfiles_root): log.debug("Initializing Work Directory: %s", self._workfiles_root) @@ -670,9 +673,6 @@ class FilesWidget(QtWidgets.QWidget): file_path = os.path.join( os.path.normpath(self._workfiles_root), work_file ) - - BeforeWorkfileSave.emit(file_path, self._workdir_path) - self._enter_session() # Make sure we are in the right session self.host.save_file(file_path) From d3eac428adf7d34fbee2cb73763c32a743c64246 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 7 Jan 2022 22:49:09 +0100 Subject: [PATCH 10/10] reorganized on save as method --- openpype/tools/workfiles/app.py | 91 +++++++++------------------------ 1 file changed, 24 insertions(+), 67 deletions(-) diff --git a/openpype/tools/workfiles/app.py b/openpype/tools/workfiles/app.py index 92cb23b619..b73f0e4930 100644 --- a/openpype/tools/workfiles/app.py +++ b/openpype/tools/workfiles/app.py @@ -650,35 +650,33 @@ class FilesWidget(QtWidgets.QWidget): self.open_file(work_file) def on_save_as_pressed(self): - work_file = self.get_filename() - if not work_file: + work_filename = self.get_filename() + if not work_filename: return # Trigger before save event - BeforeWorkfileSave.emit(work_file, self._workdir_path) - - # Initialize work directory if it has not been initialized before - if not os.path.exists(self._workfiles_root): - log.debug("Initializing Work Directory: %s", self._workfiles_root) - self.initialize_work_directory() - if not os.path.exists(self._workfiles_root): - # Failed to initialize Work Directory - log.error( - "Failed to initialize Work Directory: {}".format( - self._workfiles_root - ) - ) - return - - file_path = os.path.join( - os.path.normpath(self._workfiles_root), work_file - ) - self._enter_session() # Make sure we are in the right session - self.host.save_file(file_path) + BeforeWorkfileSave.emit(work_filename, self._workdir_path) + # Make sure workfiles root is updated + # - this triggers 'workio.work_root(...)' which may change value of + # '_workfiles_root' self.set_asset_task( self._asset_id, self._task_name, self._task_type ) + + # Create workfiles root folder + if not os.path.exists(self._workfiles_root): + log.debug("Initializing Work Directory: %s", self._workfiles_root) + os.makedirs(self._workfiles_root) + + # Update session if context has changed + self._enter_session() + # Prepare full path to workfile and save it + filepath = os.path.join( + os.path.normpath(self._workfiles_root), work_filename + ) + self.host.save_file(filepath) + # Create extra folders create_workdir_extra_folders( self._workdir_path, api.Session["AVALON_APP"], @@ -686,57 +684,16 @@ class FilesWidget(QtWidgets.QWidget): self._task_name, api.Session["AVALON_PROJECT"] ) - pipeline.emit("after.workfile.save", [file_path]) - - self.workfile_created.emit(file_path) + # Trigger after save events + pipeline.emit("after.workfile.save", [filepath]) + self.workfile_created.emit(filepath) + # Refresh files model self.refresh() def on_file_select(self): self.file_selected.emit(self._get_selected_filepath()) - def initialize_work_directory(self): - """Initialize Work Directory. - - This is used when the Work Directory does not exist yet. - - This finds the current AVALON_APP_NAME and tries to triggers its - `.toml` initialization step. Note that this will only be valid - whenever `AVALON_APP_NAME` is actually set in the current session. - - """ - - # Inputs (from the switched session and running app) - session = api.Session.copy() - changes = pipeline.compute_session_changes( - session, - asset=self._get_asset_doc(), - task=self._task_name, - template_key=self.template_key - ) - session.update(changes) - - # Prepare documents to get workdir data - project_doc = io.find_one({"type": "project"}) - asset_doc = io.find_one( - { - "type": "asset", - "name": session["AVALON_ASSET"] - } - ) - task_name = session["AVALON_TASK"] - host_name = session["AVALON_APP"] - - # Get workdir from collected documents - workdir = get_workdir(project_doc, asset_doc, task_name, host_name) - # Create workdir if does not exist yet - if not os.path.exists(workdir): - os.makedirs(workdir) - - # Force a full to the asset as opposed to just self.refresh() so - # that it will actually check again whether the Work directory exists - self.set_asset_task(self._asset_id, self._task_name, self._task_type) - def refresh(self): """Refresh listed files for current selection in the interface""" self.files_model.refresh()