mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
added support for muster login window, validator for muster connection, tweaks in muster dialog
This commit is contained in:
parent
5c4ae73046
commit
76d4fac940
4 changed files with 150 additions and 18 deletions
|
|
@ -38,9 +38,13 @@ class MusterModule:
|
|||
pass
|
||||
|
||||
def process_modules(self, modules):
|
||||
|
||||
def api_callback():
|
||||
self.aShowLogin.trigger()
|
||||
|
||||
if "RestApiServer" in modules:
|
||||
modules["RestApiServer"].register_callback(
|
||||
"muster/show_login", self.show_login, "post"
|
||||
"muster/show_login", api_callback, "post"
|
||||
)
|
||||
|
||||
# Definition of Tray menu
|
||||
|
|
@ -61,7 +65,7 @@ class MusterModule:
|
|||
self.menu.addAction(self.aShowLogin)
|
||||
self.aShowLogin.triggered.connect(self.show_login)
|
||||
|
||||
return self.menu
|
||||
parent.addMenu(self.menu)
|
||||
|
||||
def load_credentials(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -88,8 +88,7 @@ class MusterLogin(QtWidgets.QWidget):
|
|||
|
||||
self.error_label = QtWidgets.QLabel("")
|
||||
self.error_label.setFont(self.font)
|
||||
self.error_label.setTextFormat(QtCore.Qt.RichText)
|
||||
self.error_label.setObjectName("error_label")
|
||||
self.error_label.setStyleSheet('color: #FC6000')
|
||||
self.error_label.setWordWrap(True)
|
||||
self.error_label.hide()
|
||||
|
||||
|
|
@ -105,6 +104,9 @@ class MusterLogin(QtWidgets.QWidget):
|
|||
self.btn_ok.clicked.connect(self.click_ok)
|
||||
|
||||
self.btn_cancel = QtWidgets.QPushButton("Cancel")
|
||||
QtWidgets.QShortcut(
|
||||
QtGui.QKeySequence(
|
||||
QtCore.Qt.Key_Escape), self).activated.connect(self.close)
|
||||
self.btn_cancel.clicked.connect(self.close)
|
||||
|
||||
self.btn_group.addWidget(self.btn_ok)
|
||||
|
|
@ -115,7 +117,21 @@ class MusterLogin(QtWidgets.QWidget):
|
|||
|
||||
return self.main
|
||||
|
||||
def keyPressEvent(self, key_event):
|
||||
if key_event.key() == QtCore.Qt.Key_Return:
|
||||
if self.input_username.hasFocus():
|
||||
self.input_password.setFocus()
|
||||
|
||||
elif self.input_password.hasFocus() or self.btn_ok.hasFocus():
|
||||
self.click_ok()
|
||||
|
||||
elif self.btn_cancel.hasFocus():
|
||||
self.close()
|
||||
else:
|
||||
super().keyPressEvent(key_event)
|
||||
|
||||
def setError(self, msg):
|
||||
|
||||
self.error_label.setText(msg)
|
||||
self.error_label.show()
|
||||
|
||||
|
|
@ -130,8 +146,13 @@ class MusterLogin(QtWidgets.QWidget):
|
|||
if not username:
|
||||
self.setError("Username cannot be empty")
|
||||
self.invalid_input(self.input_username)
|
||||
self.save_credentials(username, password)
|
||||
self._close_widget()
|
||||
try:
|
||||
self.save_credentials(username, password)
|
||||
except Exception as e:
|
||||
self.setError(
|
||||
"<b>Cannot get auth token:</b>\n<code>{}</code>".format(e))
|
||||
else:
|
||||
self._close_widget()
|
||||
|
||||
def save_credentials(self, username, password):
|
||||
self.parent_widget.get_auth_token(username, password)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
from maya import cmds
|
||||
|
||||
import pype.maya.lib as lib
|
||||
|
||||
from avalon.vendor import requests
|
||||
import avalon.maya
|
||||
import os
|
||||
import json
|
||||
import appdirs
|
||||
import requests
|
||||
from maya import cmds
|
||||
import pype.maya.lib as lib
|
||||
import avalon.maya
|
||||
|
||||
|
||||
class CreateRenderGlobals(avalon.maya.Creator):
|
||||
|
|
@ -51,13 +49,17 @@ class CreateRenderGlobals(avalon.maya.Creator):
|
|||
self.data["secondaryPool"] = ["-"] + pools
|
||||
|
||||
if muster_url is None:
|
||||
self.log.warning("Muster REST API url not found.")
|
||||
self.log.warning("Muster REST API URL not found.")
|
||||
else:
|
||||
self.log.info(">>> Loading Muster credentials ...")
|
||||
self._load_credentials()
|
||||
self.log.info(">>> Getting pools ...")
|
||||
try:
|
||||
pools = self._get_muster_pools()
|
||||
except requests.exceptions.HTTPError as e:
|
||||
print(e)
|
||||
if e.startswith('401'):
|
||||
self.log.warning('access token expired')
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.log.error("Cannot connect to Muster API endpoint.")
|
||||
raise RuntimeError("Cannot connect to {}".format(muster_url))
|
||||
|
|
@ -131,13 +133,25 @@ class CreateRenderGlobals(avalon.maya.Creator):
|
|||
'authToken': self._token
|
||||
}
|
||||
api_entry = '/api/pools/list'
|
||||
response = requests.post(
|
||||
response = requests.get(
|
||||
self.MUSTER_REST_URL + api_entry, params=params)
|
||||
if response.status_code != 200:
|
||||
self.log.error(
|
||||
'Cannot get pools from Muster: {}'.format(
|
||||
response.status_code))
|
||||
raise Exception('Cannot get pools from Muster')
|
||||
if response.status_code == 401:
|
||||
self.log.warning('Authentication token expired.')
|
||||
# authentication token expired so we need to login to Muster
|
||||
# again to get it. We use Pype API call to show login window.
|
||||
api_url = "{}/muster/show_login".format(
|
||||
os.environ["PYPE_REST_API_URL"])
|
||||
self.log.debug(api_url)
|
||||
login_response = requests.post(api_url, timeout=1)
|
||||
if login_response.status_code != 200:
|
||||
self.log.error('Cannot show login form to Muster')
|
||||
raise Exception('Cannot show login form to Muster')
|
||||
else:
|
||||
self.log.error(
|
||||
'Cannot get pools from Muster: {}'.format(
|
||||
response.status_code))
|
||||
raise Exception('Cannot get pools from Muster')
|
||||
try:
|
||||
pools = response.json()['ResponseData']['pools']
|
||||
except ValueError as e:
|
||||
|
|
|
|||
93
pype/plugins/maya/publish/validate_muster_connection.py
Normal file
93
pype/plugins/maya/publish/validate_muster_connection.py
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import os
|
||||
import json
|
||||
import appdirs
|
||||
|
||||
import pyblish.api
|
||||
from avalon.vendor import requests
|
||||
from pype.plugin import contextplugin_should_run
|
||||
import pype.maya.action
|
||||
|
||||
|
||||
class ValidateMusterConnection(pyblish.api.ContextPlugin):
|
||||
"""
|
||||
Validate Muster REST API Service is running and we have valid auth token
|
||||
"""
|
||||
|
||||
label = "Validate Muster REST API Service"
|
||||
order = pyblish.api.ValidatorOrder
|
||||
hosts = ["maya"]
|
||||
families = ["renderlayer"]
|
||||
token = None
|
||||
if not os.environ.get("MUSTER_REST_URL"):
|
||||
active = False
|
||||
actions = [pype.api.RepairAction]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
# Workaround bug pyblish-base#250
|
||||
if not contextplugin_should_run(self, context):
|
||||
return
|
||||
|
||||
# test if we have environment set (redundant as this plugin shouldn'
|
||||
# be active otherwise).
|
||||
try:
|
||||
MUSTER_REST_URL = os.environ["MUSTER_REST_URL"]
|
||||
except KeyError:
|
||||
self.log.error("Muster REST API url not found.")
|
||||
raise ValueError("Muster REST API url not found.")
|
||||
|
||||
# Load credentials
|
||||
try:
|
||||
self._load_credentials()
|
||||
except RuntimeError:
|
||||
self.log.error("invalid or missing access token")
|
||||
|
||||
assert self._token is not None, "Invalid or missing token"
|
||||
|
||||
# We have token, lets do trivial query to web api to see if we can
|
||||
# connect and access token is valid.
|
||||
params = {
|
||||
'authToken': self._token
|
||||
}
|
||||
api_entry = '/api/pools/list'
|
||||
response = requests.get(
|
||||
MUSTER_REST_URL + api_entry, params=params)
|
||||
assert response.status_code == 200, "invalid response from server"
|
||||
assert response.json()['ResponseData'], "invalid data in response"
|
||||
|
||||
def _load_credentials(self):
|
||||
"""
|
||||
Load Muster credentials from file and set `MUSTER_USER`,
|
||||
`MUSTER_PASSWORD`, `MUSTER_REST_URL` is loaded from presets.
|
||||
|
||||
.. todo::
|
||||
|
||||
Show login dialog if access token is invalid or missing.
|
||||
"""
|
||||
app_dir = os.path.normpath(
|
||||
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._token = muster_json.get('token', None)
|
||||
if not self._token:
|
||||
raise RuntimeError("Invalid access token for Muster")
|
||||
file.close()
|
||||
self.MUSTER_REST_URL = os.environ.get("MUSTER_REST_URL")
|
||||
if not self.MUSTER_REST_URL:
|
||||
raise AttributeError("Muster REST API url not set")
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
"""
|
||||
Renew authentication token by logging into Muster
|
||||
"""
|
||||
api_url = "{}/muster/show_login".format(
|
||||
os.environ["PYPE_REST_API_URL"])
|
||||
cls.log.debug(api_url)
|
||||
response = requests.post(api_url, timeout=1)
|
||||
if response.status_code != 200:
|
||||
cls.log.error('Cannot show login form to Muster')
|
||||
raise Exception('Cannot show login form to Muster')
|
||||
Loading…
Add table
Add a link
Reference in a new issue