adding lock task workfiles when users are working on them

This commit is contained in:
Kayla Man 2022-09-09 13:20:49 +08:00
parent 3782ad4782
commit 26ae84df16
5 changed files with 116 additions and 47 deletions

View file

@ -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():

View file

@ -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"]

View file

@ -403,7 +403,8 @@
"enabled": false
}
],
"extra_folders": []
"extra_folders": [],
"workfile_lock_profiles": []
},
"loader": {
"family_filter_profiles": [

View file

@ -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"
}
]
}
}
]
},

View file

@ -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")