From 409c5601451973f4cabd03a22b587733ed9cdecc Mon Sep 17 00:00:00 2001 From: antirotor Date: Tue, 4 Jun 2019 00:17:02 +0200 Subject: [PATCH] fix(deadline): support for UNC fix(muster): multiple fixes in logon widget for muster and muster submitter --- pype/muster/muster.py | 8 +- pype/muster/widget_login.py | 11 +- .../maya/publish/submit_maya_muster.py | 268 +++++++++++++++++- .../maya/publish/submit_vray_deadline.py | 2 +- .../publish/validate_deadline_connection.py | 3 + pype/scripts/publish_deadline.py | 12 +- pype/scripts/publish_filesequence.py | 20 +- 7 files changed, 297 insertions(+), 27 deletions(-) diff --git a/pype/muster/muster.py b/pype/muster/muster.py index 6af8352542..28f1c2ddd1 100644 --- a/pype/muster/muster.py +++ b/pype/muster/muster.py @@ -12,7 +12,7 @@ class MusterModule: asking for user credentials for Muster if not already specified. """ cred_folder_path = os.path.normpath( - appdirs.user_data_dir('pype-app', 'pype', 'muster') + appdirs.user_data_dir('pype-app', 'pype') ) cred_filename = 'muster_cred.json' @@ -24,7 +24,7 @@ class MusterModule: self.parent = parent self.widget_login = MusterLogin(main_parent, self) - def start_up(self): + def tray_start(self): """ Show login dialog if credentials not found. """ @@ -52,7 +52,7 @@ class MusterModule: ) self.menu.addAction(self.aShowLogin) - self.aShowLogin.triggered.connect(self.show_settings) + self.aShowLogin.triggered.connect(self.show_login) return self.menu @@ -65,7 +65,7 @@ class MusterModule: file = open(self.cred_path, 'r') credentials = json.load(file) except Exception: - file = open(self.cred_path, 'w') + file = open(self.cred_path, 'w+') file.close() return credentials diff --git a/pype/muster/widget_login.py b/pype/muster/widget_login.py index 8967089791..8cb07fe2fe 100644 --- a/pype/muster/widget_login.py +++ b/pype/muster/widget_login.py @@ -16,7 +16,6 @@ class MusterLogin(QtWidgets.QWidget): self.parent_widget = parent self.main_parent = main_parent - self.clockapi = parent.clockapi # Icon if hasattr(parent, 'icon'): @@ -80,7 +79,7 @@ class MusterLogin(QtWidgets.QWidget): self.label_password.setTextFormat(QtCore.Qt.RichText) self.input_password = QtWidgets.QLineEdit() - self.input_password.setEchoMode(QtGui.QLineEdit.Password) + self.input_password.setEchoMode(QtWidgets.QLineEdit.Password) self.input_password.setEnabled(True) self.input_password.setFrame(True) self.input_password.setPlaceholderText( @@ -132,6 +131,14 @@ class MusterLogin(QtWidgets.QWidget): self.setError("Username cannot be empty") self.invalid_input(self.input_username) self.save_credentials(username, password) + self._close_widget() def save_credentials(self, username, password): self.parent_widget.save_credentials(username, password) + + def closeEvent(self, event): + event.ignore() + self._close_widget() + + def _close_widget(self): + self.hide() diff --git a/pype/plugins/maya/publish/submit_maya_muster.py b/pype/plugins/maya/publish/submit_maya_muster.py index 123a98a64e..fc38e31b8e 100644 --- a/pype/plugins/maya/publish/submit_maya_muster.py +++ b/pype/plugins/maya/publish/submit_maya_muster.py @@ -7,7 +7,9 @@ import pyblish.api import pype.maya.lib as lib import appdirs import platform -from pypeapp.lib.config import get_presets +# from pypeapp.lib.config import get_presets + +from pprint import pprint def get_renderer_variables(renderlayer=None): @@ -112,16 +114,18 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): `MUSTER_PASSWORD`, `MUSTER_REST_URL` is loaded from presets. """ app_dir = os.path.normpath( - appdirs.user_data_dir('pype-app', 'pype', 'muster') + appdirs.user_data_dir('pype-app', 'pype') ) file_name = 'muster_cred.json' fpath = os.path.join(app_dir, file_name) file = open(fpath, 'r') muster_json = json.load(file) - self.MUSTER_USER = muster_json.get('user', None) + self.MUSTER_USER = muster_json.get('username', None) self.MUSTER_PASSWORD = muster_json.get('password', None) file.close() - self.MUSTER_REST_URL = get_presets()['tools']['muster']['url'] + self.MUSTER_REST_URL = os.environ.get("MUSTER_REST_URL") + if not self.MUSTER_REST_URL: + raise Exception("Muster REST API url not set") def _authenticate(self): """ @@ -173,7 +177,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): raise Exception('Muster server returned unexpected data') templates = {} - for t in response_templates.items(): + for t in response_templates: templates[t.get("name")] = t.get("id") self._templates = templates @@ -189,6 +193,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): :raises: Exception if template ID isn't found """ try: + self.log.info("Trying to find template for [{}]".format(renderer)) return self._templates.get(renderer) except ValueError: raise Exception('Unimplemented renderer {}'.format(renderer)) @@ -206,7 +211,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): "authToken": self._token, "name": "submit" } - api_entry = 'api/queue/actions' + api_entry = '/api/queue/actions' response = requests.post( self.MUSTER_REST_URL + api_entry, params=params, json=payload) @@ -269,6 +274,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): padding=render_variables["padding"], ext=render_variables["ext"]) + instance.data["outputDir"] = os.path.dirname(output_filename_0) # build path for metadata file metadata_filename = "{}_metadata.json".format(instance.data["subset"]) output_dir = instance.data["outputDir"] @@ -293,14 +299,82 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): payload = { "RequestData": { + "platform": 0, "job": { "jobName": jobname, "templateId": self._resolve_template( instance.data["renderer"]), + "camera": "", + "chunksInterleave": 2, + "chunksPriority": "0", + "chunksTimeoutValue": 320, + "department": "", + "dependIds": [""], + "dependLinkMode": 0, + "dependMode": 0, + "emergencyQueue": False, + "excludedPools": [""], + "exitCodesErrorCheckType": 0, + "includedPools": [""], + "logsErrorCheckType": 0, + "mailNotificationsAtChunkLevelType": "1", + "mailNotificationsAtJobLevelType": "1", + "maximumInstances": 0, + "mobileNotificationsAtChunkLevelType": "1", + "mobileNotificationsAtJobLevelType": "1", + "notificatorNotificationsAtChunkLevelType": "1", + "notificatorNotificationsAtJobLevelType": "1", + "overrideChunksTimeout": False, + "overrideErrorExitCodes": False, + "overrideErrorExitCodesValue": "", + "overrideMailNotificationsAtChunkLevel": False, + "overrideMailNotificationsAtJobLevel": False, + "overrideMaximumChunksRequeue": False, + "overrideMaximumChunksRequeueValue": 0, + "overrideMinimumCores": False, + "overrideMinimumCoresValue": 0, + "overrideMinimumDiskSpace": False, + "overrideMinimumDiskSpaceValue": 0, + "overrideMinimumPhysical": False, + "overrideMinimumPhysicalValue": 0, + "overrideMinimumRam": False, + "overrideMinimumRamValue": 0, + "overrideMinimumSpeed": False, + "overrideMinimumSpeedValue": 0, + "overrideMinimumThreads": False, + "overrideMinimumThreadsValue": 0, + "overrideMobileNotificationsAtChunkLevel": False, + "overrideMobileNotificationsAtJobLevel": False, + "overrideNotificatorNotificationsAtChunkLevel": False, + "overrideNotificatorNotificationsAtJobLevel": False, + "overrideStartMailNotificationsAtChunkLevel": False, + "overrideStartMailNotificationsAtJobLevel": False, + "overrideStartMobileNotificationsAtChunkLevel": False, + "overrideStartMobileNotificationsAtJobLevel": False, + "overrideStartNotificatorNotificationsAtChunkLevel": False, + "overrideStartNotificatorNotificationsAtJobLevel": False, + "overrideValidExitCodes": False, + "overrideValidExitCodesValue": "", + "overrideWarningExitCodes": False, + "overrideWarningExitCodesValue": "", + "packetSize": 4, + "packetType": 1, + "priority": 1, + "project": "test", + "sequence": "", + "shot": "", + "startMailNotificationsAtChunkLevelType": "1", + "startMailNotificationsAtJobLevelType": "1", + "startMobileNotificationsAtChunkLevelType": "1", + "startMobileNotificationsAtJobLevelType": "1", + "startNotificatorNotificationsAtChunkLevelType": "1", + "startNotificatorNotificationsAtJobLevelType": "1", + "startOn": 0, + "templateVersion": "", + "jobId": -1, "startOn": 0, "parentId": -1, - "dependIds": [], "dependMode": 0, "packetSize": 4, "packetType": 1, @@ -308,10 +382,10 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): "maximumInstances": 0, "assignedInstances": 0, "attributes": { - "environmental_variables": { - "value": ", ".join("{!s}={!r}".format(k, v) - for (k, v) in env.iteritems()) - }, + # "environmental_variables": { + # "value": ", ".join("{!s}={!r}".format(k, v) + # for (k, v) in env.iteritems()) + # }, "memo": { "value": comment, "state": True, @@ -338,6 +412,176 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): "value": postjob_command, "state": True, "subst": True + }, + "overridestatus": { + "value": "0", + "state": True, + "subst": False + }, + "frame_check": { + "value": "0", + "state": True, + "subst": False + }, + "fc_recursion": { + "value": "1", + "state": True, + "subst": False + }, + "fc_check_file": { + "value": "1", + "state": True, + "subst": False + }, + "fc_file_low": { + "value": "0", + "state": True, + "subst": False + }, + "fc_file_high": { + "value": "0", + "state": True, + "subst": False + }, + "fc_open_image": { + "value": "1", + "state": True, + "subst": False + }, + "fc_render_layer_mode": { + "value": "0", + "state": True, + "subst": False + }, + "fc_check_image_dimensions": { + "value": "0", + "state": True, + "subst": False + }, + "fc_image_width": { + "value": "1920", + "state": True, + "subst": False + }, + "fc_image_height": { + "value": "1080", + "state": True, + "subst": False + }, + "movie_assembler": { + "value": "0", + "state": True, + "subst": False + }, + "movie_assembler_output": { + "value": "", + "state": True, + "subst": True + }, + "movie_assembler_framerate": { + "value": "30", + "state": True, + "subst": False + }, + "movie_assembler_template": { + "value": "48", + "state": True, + "subst": False + }, + "movie_assembler_input_flags": { + "value": "", + "state": False, + "subst": False + }, + "movie_assembler_output_flags": { + "value": "", + "state": False, + "subst": False + }, + "pre_job_action": { + "value": "", + "state": False, + "subst": True + }, + "pre_job_action_check_retcode": { + "value": 0, + "state": False, + "subst": False + }, + "pre_job_action_timeout": { + "value": 0, + "state": False, + "subst": False + }, + "post_job_action_check_retcode": { + "value": 0, + "state": False, + "subst": False + }, + "post_job_action_timeout": { + "value": 0, + "state": False, + "subst": False + }, + "pre_chunk_action": { + "value": "", + "state": False, + "subst": True + }, + "pre_chunk_action_check_retcode": { + "value": 0, + "state": False, + "subst": False + }, + "pre_chunk_action_timeout": { + "value": 0, + "state": False, + "subst": False + }, + "post_chunk_action": { + "value": "", + "state": False, + "subst": True + }, + "post_chunk_action_check_retcode": { + "value": 0, + "state": False, + "subst": False + }, + "post_chunk_action_timeout": { + "value": 0, + "state": False, + "subst": False + }, + "ARNOLDMODE": { + "value": "0", + "state": True, + "subst": False + }, + "job_project": { + "value": "D:\\D001_projectx\\maya\\work", + "state": True, + "subst": True + }, + "MAYADIGITS": { + "value": 1, + "state": True, + "subst": False + }, + "ABORTRENDER": { + "value": "0", + "state": True, + "subst": True + }, + "ARNOLDLICENSE": { + "value": "0", + "state": False, + "subst": False + }, + "ADD_FLAGS": { + "value": "", + "state": True, + "subst": True } } } @@ -355,7 +599,7 @@ class MayaSubmitMuster(pyblish.api.InstancePlugin): raise Exception(response.text) # Store output dir for unified publisher (filesequence) - instance.data["outputDir"] = os.path.dirname(output_filename_0) + instance.data["musterSubmissionJob"] = response.json() def clean_environment(self): diff --git a/pype/plugins/maya/publish/submit_vray_deadline.py b/pype/plugins/maya/publish/submit_vray_deadline.py index 16625e73f7..fab6d8ff43 100644 --- a/pype/plugins/maya/publish/submit_vray_deadline.py +++ b/pype/plugins/maya/publish/submit_vray_deadline.py @@ -29,7 +29,7 @@ class VraySubmitDeadline(pyblish.api.InstancePlugin): def process(self, instance): DEADLINE_REST_URL = api.Session.get("DEADLINE_REST_URL", - "http://localhost:8082") + "http://localhost:8082") assert DEADLINE_REST_URL, "Requires DEADLINE_REST_URL" context = instance.context diff --git a/pype/plugins/maya/publish/validate_deadline_connection.py b/pype/plugins/maya/publish/validate_deadline_connection.py index b89e3c9b2e..2daf7aebe0 100644 --- a/pype/plugins/maya/publish/validate_deadline_connection.py +++ b/pype/plugins/maya/publish/validate_deadline_connection.py @@ -4,6 +4,7 @@ from avalon.vendor import requests from pype.plugin import contextplugin_should_run import os + class ValidateDeadlineConnection(pyblish.api.ContextPlugin): """Validate Deadline Web Service is running""" @@ -11,6 +12,8 @@ class ValidateDeadlineConnection(pyblish.api.ContextPlugin): order = pyblish.api.ValidatorOrder hosts = ["maya"] families = ["renderlayer"] + if not os.environ.get("DEADLINE_REST_URL"): + active = False def process(self, context): diff --git a/pype/scripts/publish_deadline.py b/pype/scripts/publish_deadline.py index 9dc81d805e..e6052dbfd2 100644 --- a/pype/scripts/publish_deadline.py +++ b/pype/scripts/publish_deadline.py @@ -19,11 +19,19 @@ def __main__(): raise Exception("PYPE_ROOT is not set") # TODO: set correct path - pype_command = "pype.bat" + pype_command = "pype.ps1" if platform.system().lower() == "linux": pype_command = "pype" + args = [os.path.join(pype_root, pype_command), - "--publish", "--paths", kwargs.paths] + "--node", "--publish", "--paths", kwargs.paths] + + # if we are using windows, run powershell command directly to support + # UNC paths. + if platform.system().lower() == "windows": + args = ["powershell", "-NoProfile", "-noexit", "-nologo", + "-executionPolicy bypass", "-command", + '"{}; exit $LASTEXITCODE"'.format(" ".join(args))] print('>>> running pype ...') p = subprocess.call(args, shell=True) diff --git a/pype/scripts/publish_filesequence.py b/pype/scripts/publish_filesequence.py index 38a275877f..0da7d5ac94 100644 --- a/pype/scripts/publish_filesequence.py +++ b/pype/scripts/publish_filesequence.py @@ -36,15 +36,23 @@ def __main__(): print("Set pype root to: {}".format(pype_root)) print("Paths: {}".format(kwargs.paths or [os.getcwd()])) - pype_command = "pype.bat" + paths = kwargs.paths or [os.getcwd()] + pype_command = "pype.ps1" if platform.system().lower() == "linux": pype_command = "pype" - paths = kwargs.paths or [os.getcwd()] - print("Pype command: {}".format(os.path.join(pype_root, pype_command))) - subprocess.call([os.path.join(pype_root, pype_command), - "--ignore", "--publish", "--paths", - " ".join(paths)], shell=True) + args = [os.path.join(pype_root, pype_command), + "--node", "--publish", "--paths", " ".join(paths)] + + # if we are using windows, run powershell command directly to support + # UNC paths. + if platform.system().lower() == "windows": + args = ["powershell", "-NoProfile", "-noexit", "-nologo", + "-executionpolicy", "bypass", "-command", + '"{}; exit $LASTEXITCODE"'.format(" ".join(args))] + + print("Pype command: {}".format(" ".join(args))) + subprocess.call(args, shell=True) if __name__ == '__main__':