mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
adding lock task workfiles when users are working on them
This commit is contained in:
parent
3782ad4782
commit
26ae84df16
5 changed files with 116 additions and 47 deletions
|
|
@ -33,9 +33,10 @@ from openpype.pipeline import (
|
|||
from openpype.pipeline.load import any_outdated_containers
|
||||
from openpype.pipeline.workfile.lock_workfile import (
|
||||
create_workfile_lock,
|
||||
get_username,
|
||||
get_user_from_lock,
|
||||
remove_workfile_lock,
|
||||
is_workfile_locked
|
||||
is_workfile_locked,
|
||||
is_workfile_lock_enabled
|
||||
)
|
||||
from openpype.hosts.maya import MAYA_ROOT_DIR
|
||||
from openpype.hosts.maya.lib import copy_workspace_mel
|
||||
|
|
@ -266,11 +267,21 @@ def _before_scene_save(return_code, client_data):
|
|||
|
||||
|
||||
def _remove_workfile_lock():
|
||||
"""Remove workfile lock on current file"""
|
||||
if not handle_workfile_locks():
|
||||
return
|
||||
filepath = current_file()
|
||||
if filepath:
|
||||
remove_workfile_lock(filepath)
|
||||
|
||||
|
||||
def handle_workfile_locks():
|
||||
if lib.IS_HEADLESS:
|
||||
return False
|
||||
project_name = legacy_io.active_project()
|
||||
return is_workfile_lock_enabled(MayaHost.name, project_name)
|
||||
|
||||
|
||||
def uninstall():
|
||||
pyblish.api.deregister_plugin_path(PUBLISH_PATH)
|
||||
pyblish.api.deregister_host("mayabatch")
|
||||
|
|
@ -468,8 +479,10 @@ def on_before_save():
|
|||
return lib.validate_fps()
|
||||
|
||||
|
||||
def after_file_open():
|
||||
def check_lock_on_current_file():
|
||||
"""Check if there is a user opening the file"""
|
||||
if not handle_workfile_locks():
|
||||
return
|
||||
log.info("Running callback on checking the lock file...")
|
||||
|
||||
# add the lock file when opening the file
|
||||
|
|
@ -477,23 +490,25 @@ def after_file_open():
|
|||
|
||||
if not is_workfile_locked(filepath):
|
||||
create_workfile_lock(filepath)
|
||||
return
|
||||
|
||||
else:
|
||||
username = get_username(filepath)
|
||||
reminder = cmds.window(title="Reminder", width=400, height=30)
|
||||
cmds.columnLayout(adjustableColumn=True)
|
||||
cmds.separator()
|
||||
cmds.columnLayout(adjustableColumn=True)
|
||||
comment = " %s is working the same workfile!" % username
|
||||
cmds.text(comment, align='center')
|
||||
cmds.text(vis=False)
|
||||
cmds.rowColumnLayout(numberOfColumns=3,
|
||||
columnWidth=[(1, 300), (2, 100)],
|
||||
columnSpacing=[(2, 10)])
|
||||
cmds.separator(vis=False)
|
||||
quit_command = "cmds.quit(force=True);cmds.deleteUI('%s')" % reminder
|
||||
cmds.button(label='Ok', command=quit_command)
|
||||
cmds.showWindow(reminder)
|
||||
username = get_user_from_lock(filepath)
|
||||
reminder = cmds.window(title="Reminder", width=400, height=30)
|
||||
cmds.columnLayout(adjustableColumn=True)
|
||||
cmds.separator()
|
||||
cmds.columnLayout(adjustableColumn=True)
|
||||
comment = " %s is working the same workfile!" % username
|
||||
cmds.text(comment, align='center')
|
||||
cmds.text(vis=False)
|
||||
cmds.rowColumnLayout(numberOfColumns=3,
|
||||
columnWidth=[(1,200), (2, 100), (3, 100)],
|
||||
columnSpacing=[(3, 10)])
|
||||
cmds.separator(vis=False)
|
||||
cancel_command = "cmds.file(new=True);cmds.deleteUI('%s')" % reminder
|
||||
ignore_command ="cmds.deleteUI('%s')" % reminder
|
||||
cmds.button(label='Cancel', command=cancel_command)
|
||||
cmds.button(label = "Ignore", command=ignore_command)
|
||||
cmds.showWindow(reminder)
|
||||
|
||||
|
||||
def on_before_close():
|
||||
|
|
@ -501,12 +516,13 @@ def on_before_close():
|
|||
log.info("Closing Maya...")
|
||||
# delete the lock file
|
||||
filepath = current_file()
|
||||
remove_workfile_lock(filepath)
|
||||
if handle_workfile_locks():
|
||||
remove_workfile_lock(filepath)
|
||||
|
||||
|
||||
def before_file_open():
|
||||
"""check lock file when the file changed"""
|
||||
log.info("check lock file when file changed...")
|
||||
log.info("Removing lock on current file before scene open...")
|
||||
# delete the lock file
|
||||
_remove_workfile_lock()
|
||||
|
||||
|
|
@ -579,7 +595,7 @@ def on_open():
|
|||
dialog.show()
|
||||
|
||||
# create lock file for the maya scene
|
||||
after_file_open()
|
||||
check_lock_on_current_file()
|
||||
|
||||
|
||||
def on_new():
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
import os
|
||||
import json
|
||||
from uuid import uuid4
|
||||
from openpype.lib import Logger, filter_profiles
|
||||
from openpype.lib.pype_info import get_workstation_info
|
||||
from openpype.settings import get_project_settings
|
||||
|
||||
|
||||
def _read_lock_file(lock_filepath):
|
||||
if not os.path.exists(lock_filepath):
|
||||
log = Logger.get_logger("_read_lock_file")
|
||||
log.debug("lock file is not created or readable as expected!")
|
||||
with open(lock_filepath, "r") as stream:
|
||||
data = json.load(stream)
|
||||
return data
|
||||
|
||||
|
||||
def _get_lock_file(filepath):
|
||||
return filepath + ".lock"
|
||||
return filepath + ".oplock"
|
||||
|
||||
|
||||
def is_workfile_locked(filepath):
|
||||
|
|
@ -22,46 +27,59 @@ def is_workfile_locked(filepath):
|
|||
|
||||
|
||||
def is_workfile_locked_for_current_process(filepath):
|
||||
if not is_workfile_locked():
|
||||
if not is_workfile_locked(filepath):
|
||||
return False
|
||||
|
||||
lock_filepath = _get_lock_file(filepath)
|
||||
process_id = os.environ["OPENPYPE_PROCESS_ID"]
|
||||
data = _read_lock_file(lock_filepath)
|
||||
return data["process_id"] == process_id
|
||||
return data["process_id"] == _get_process_id()
|
||||
|
||||
|
||||
def delete_workfile_lock(filepath):
|
||||
lock_filepath = _get_lock_file(filepath)
|
||||
if not os.path.exists(lock_filepath):
|
||||
return
|
||||
|
||||
if is_workfile_locked_for_current_process(filepath):
|
||||
os.remove(filepath)
|
||||
if os.path.exists(lock_filepath):
|
||||
os.remove(lock_filepath)
|
||||
|
||||
|
||||
def create_workfile_lock(filepath):
|
||||
lock_filepath = _get_lock_file(filepath)
|
||||
process_id = os.environ.get("OPENPYPE_PROCESS_ID")
|
||||
if not process_id:
|
||||
process_id = str(uuid4())
|
||||
os.environ["OPENPYPE_PROCESS_ID"] = process_id
|
||||
info = get_workstation_info()
|
||||
info["process_id"] = process_id
|
||||
info["process_id"] = _get_process_id()
|
||||
with open(lock_filepath, "w") as stream:
|
||||
json.dump(info, stream)
|
||||
|
||||
|
||||
def get_username(filepath):
|
||||
def get_user_from_lock(filepath):
|
||||
lock_filepath = _get_lock_file(filepath)
|
||||
with open(lock_filepath, "r") as stream:
|
||||
data = json.load(stream)
|
||||
if not os.path.exists(lock_filepath):
|
||||
return
|
||||
data = _read_lock_file(lock_filepath)
|
||||
username = data["username"]
|
||||
return username
|
||||
|
||||
|
||||
def remove_workfile_lock(filepath):
|
||||
lock_filepath = _get_lock_file(filepath)
|
||||
if not os.path.exists(lock_filepath):
|
||||
return
|
||||
return os.remove(lock_filepath)
|
||||
if is_workfile_locked_for_current_process(filepath):
|
||||
delete_workfile_lock(filepath)
|
||||
|
||||
|
||||
def _get_process_id():
|
||||
process_id = os.environ.get("OPENPYPE_PROCESS_ID")
|
||||
if not process_id:
|
||||
process_id = str(uuid4())
|
||||
os.environ["OPENPYPE_PROCESS_ID"] = process_id
|
||||
return process_id
|
||||
|
||||
def is_workfile_lock_enabled(host_name, project_name, project_setting=None):
|
||||
if project_setting is None:
|
||||
project_setting = get_project_settings(project_name)
|
||||
workfile_lock_profiles = (
|
||||
project_setting
|
||||
["global"]
|
||||
["tools"]
|
||||
["Workfiles"]
|
||||
["workfile_lock_profiles"])
|
||||
profile = filter_profiles(workfile_lock_profiles,{"host_name": host_name})
|
||||
if not profile:
|
||||
return False
|
||||
return profile["enabled"]
|
||||
|
|
|
|||
|
|
@ -403,7 +403,8 @@
|
|||
"enabled": false
|
||||
}
|
||||
],
|
||||
"extra_folders": []
|
||||
"extra_folders": [],
|
||||
"workfile_lock_profiles": []
|
||||
},
|
||||
"loader": {
|
||||
"family_filter_profiles": [
|
||||
|
|
|
|||
|
|
@ -238,6 +238,31 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "workfile_lock_profiles",
|
||||
"label": "Workfile lock profiles",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"type": "hosts-enum",
|
||||
"key": "host_name",
|
||||
"label": "Hosts",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"type": "splitter"
|
||||
},
|
||||
{
|
||||
"key": "enabled",
|
||||
"label": "Enabled",
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ from openpype.host import IWorkfileHost
|
|||
from openpype.client import get_asset_by_id
|
||||
from openpype.pipeline.workfile.lock_workfile import (
|
||||
is_workfile_locked,
|
||||
get_username
|
||||
get_user_from_lock,
|
||||
is_workfile_lock_enabled,
|
||||
is_workfile_locked_for_current_process
|
||||
)
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
from openpype.tools.utils.delegates import PrettyTimeDelegate
|
||||
|
|
@ -456,10 +458,17 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
"host_name": self.host_name
|
||||
}
|
||||
|
||||
def _is_workfile_locked(self, filepath):
|
||||
if not is_workfile_lock_enabled(self.host_name, self.project_name):
|
||||
return False
|
||||
if not is_workfile_locked(filepath):
|
||||
return False
|
||||
return not is_workfile_locked_for_current_process(filepath)
|
||||
|
||||
def open_file(self, filepath):
|
||||
host = self.host
|
||||
if is_workfile_locked(filepath):
|
||||
username = get_username(filepath)
|
||||
if self._is_workfile_locked(filepath):
|
||||
username = get_user_from_lock(filepath)
|
||||
popup_dialog = QtWidgets.QMessageBox(parent=self)
|
||||
popup_dialog.setWindowTitle("Warning")
|
||||
popup_dialog.setText(username + " is using the file")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue