From 3bc6b0609a9821aa3bbd6abd80b867205b74dba4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 17:09:22 +0100 Subject: [PATCH 01/16] credentials are stored as json --- pype/ftrack/credentials.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pype/ftrack/credentials.py b/pype/ftrack/credentials.py index 6f756e8a52..c6019b2da7 100644 --- a/pype/ftrack/credentials.py +++ b/pype/ftrack/credentials.py @@ -1,12 +1,11 @@ import os -import toml - +import json import ftrack_api import appdirs config_path = os.path.normpath(appdirs.user_data_dir('pype-app', 'pype')) -config_name = 'ftrack_cred.toml' +config_name = 'ftrack_cred.json' fpath = os.path.join(config_path, config_name) folder = os.path.dirname(fpath) @@ -28,7 +27,7 @@ def _get_credentials(): filecreate.close() file = open(fpath, 'r') - credentials = toml.load(file) + credentials = json.load(file) file.close() return credentials @@ -42,7 +41,7 @@ def _save_credentials(username, apiKey): 'apiKey': apiKey } - credentials = toml.dumps(data) + credentials = json.dumps(data) file.write(credentials) file.close() From 39b08f6057916c8f93652d730ae0f854e65315d8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 17:10:29 +0100 Subject: [PATCH 02/16] ftrack server added to pype/ftrack --- pype/ftrack/__init__.py | 1 + pype/ftrack/ftrack_server/__init__.py | 8 + .../{ => ftrack_server}/event_server.py | 2 +- pype/ftrack/ftrack_server/event_server_cli.py | 121 ++++++++++++++ pype/ftrack/ftrack_server/ftrack_server.py | 157 ++++++++++++++++++ 5 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 pype/ftrack/ftrack_server/__init__.py rename pype/ftrack/{ => ftrack_server}/event_server.py (96%) create mode 100644 pype/ftrack/ftrack_server/event_server_cli.py create mode 100644 pype/ftrack/ftrack_server/ftrack_server.py diff --git a/pype/ftrack/__init__.py b/pype/ftrack/__init__.py index 1224715000..bf18979e91 100644 --- a/pype/ftrack/__init__.py +++ b/pype/ftrack/__init__.py @@ -1 +1,2 @@ from .lib import * +from .ftrack_server import * diff --git a/pype/ftrack/ftrack_server/__init__.py b/pype/ftrack/ftrack_server/__init__.py new file mode 100644 index 0000000000..b7f8651da0 --- /dev/null +++ b/pype/ftrack/ftrack_server/__init__.py @@ -0,0 +1,8 @@ +from .ftrack_server import FtrackServer +from . import event_server, event_server_cli + +__all__ = [ + 'event_server', + 'event_server_cli', + 'FtrackServer' +] diff --git a/pype/ftrack/event_server.py b/pype/ftrack/ftrack_server/event_server.py similarity index 96% rename from pype/ftrack/event_server.py rename to pype/ftrack/ftrack_server/event_server.py index 9c6207d6a2..24cc5f22ee 100644 --- a/pype/ftrack/event_server.py +++ b/pype/ftrack/ftrack_server/event_server.py @@ -1,6 +1,6 @@ import sys from pype.ftrack import credentials, login_dialog as login_dialog -from FtrackServer import FtrackServer +from . import FtrackServer from app.vendor.Qt import QtWidgets from pype import api diff --git a/pype/ftrack/ftrack_server/event_server_cli.py b/pype/ftrack/ftrack_server/event_server_cli.py new file mode 100644 index 0000000000..b09a1cd851 --- /dev/null +++ b/pype/ftrack/ftrack_server/event_server_cli.py @@ -0,0 +1,121 @@ +import os +import json +import appdirs +import ftrack_api +from . import FtrackServer +from app import api + +log = api.Logger.getLogger(__name__) + + +def check_cred(user, key): + os.environ["FTRACK_API_USER"] = user + os.environ["FTRACK_API_KEY"] = key + + try: + session = ftrack_api.Session() + session.close() + return True + except Exception: + return False + + +def ask_yes_no(): + possible_yes = ["y", "yes"] + possible_no = ["n", "no"] + log.info("Y/N:") + cont = input() + if cont.lower() in possible_yes: + return True + elif cont.lower() in possible_no: + return False + else: + log.info( + "Invalid input. Possible entries: [y, yes, n, no]. Try it again:" + ) + return ask_yes_no() + + +def cli_login(): + config_path = os.path.normpath(appdirs.user_data_dir('pype-app', 'pype')) + config_name = 'ftrack_event_cred.json' + event_credentials_file = os.path.join(config_path, config_name) + + if not os.path.isdir(config_path): + os.makedirs(config_path) + if not os.path.exists(event_credentials_file): + open(event_credentials_file, 'w').close() + enter_cred = True + + with open(event_credentials_file, 'r') as fp: + try: + cred_data = json.load(fp) + except Exception: + cred_data = {} + + user = cred_data.get("FTRACK_API_USER", None) + key = cred_data.get("FTRACK_API_KEY", None) + auto = cred_data.get("AUTO_CONNECT", False) + if user is None or key is None: + log.info("Credentials are not set. Do you want to enter them now? (Y/N)") + if ask_yes_no() is False: + log.info("Exiting...") + return + elif check_cred(user, key): + if auto is False: + log.info("Do you want to log with username {}? (Y/N)".format( + cred_data["FTRACK_API_USER"] + )) + if ask_yes_no(): + enter_cred = False + else: + enter_cred = False + else: + log.info( + "Stored credentials are not valid. " + "Do you want enter them now?(Y/N)" + ) + if ask_yes_no() is False: + log.info("Exiting...") + return + + while enter_cred: + log.info("Please enter Ftrack API User:") + user = input() + log.info("And now enter Ftrack API Key:") + key = input() + if check_cred(user, key): + export = { + "FTRACK_API_USER": user, + "FTRACK_API_KEY": key + } + log.info( + "Credentials are valid." + " Do you want to auto-connect next time?(Y/N)" + ) + if ask_yes_no(): + export["AUTO_CONNECT"] = True + + with open(event_credentials_file, 'w') as fp: + json.dump(export, fp) + enter_cred = False + break + else: + log.info( + "Entered credentials are not valid." + " Do you want to try it again?(Y/N)" + ) + if ask_yes_no() is False: + log.info("Exiting...") + return + + server = FtrackServer('event') + server.run_server() + + +def main(): + cli_login() + + +if (__name__ == ('__main__')): + main() diff --git a/pype/ftrack/ftrack_server/ftrack_server.py b/pype/ftrack/ftrack_server/ftrack_server.py new file mode 100644 index 0000000000..91caff216e --- /dev/null +++ b/pype/ftrack/ftrack_server/ftrack_server.py @@ -0,0 +1,157 @@ +import os +import sys +import types +import importlib +import ftrack_api +import time +import logging +from app.api import Logger + +log = Logger.getLogger(__name__) + +""" +# Required - Needed for connection to Ftrack +FTRACK_SERVER # Ftrack server e.g. "https://myFtrack.ftrackapp.com" +FTRACK_API_KEY # Ftrack user's API key "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +FTRACK_API_USER # Ftrack username e.g. "user.name" + +# Required - Paths to folder with actions +FTRACK_ACTIONS_PATH # Paths to folders where are located actions + - EXAMPLE: "M:/FtrackApi/../actions/" +FTRACK_EVENTS_PATH # Paths to folders where are located actions + - EXAMPLE: "M:/FtrackApi/../events/" + +# Required - Needed for import included modules +PYTHONPATH # Path to ftrack_api and paths to all modules used in actions + - path to ftrack_action_handler, etc. +""" + + +class FtrackServer(): + def __init__(self, type='action'): + """ + - 'type' is by default set to 'action' - Runs Action server + - enter 'event' for Event server + + EXAMPLE FOR EVENT SERVER: + ... + server = FtrackServer('event') + server.run_server() + .. + """ + # set Ftrack logging to Warning only - OPTIONAL + ftrack_log = logging.getLogger("ftrack_api") + ftrack_log.setLevel(logging.WARNING) + + self.type = type + self.actionsAvailable = True + self.eventsAvailable = True + # Separate all paths + if "FTRACK_ACTIONS_PATH" in os.environ: + all_action_paths = os.environ["FTRACK_ACTIONS_PATH"] + self.actionsPaths = all_action_paths.split(os.pathsep) + else: + self.actionsAvailable = False + + if "FTRACK_EVENTS_PATH" in os.environ: + all_event_paths = os.environ["FTRACK_EVENTS_PATH"] + self.eventsPaths = all_event_paths.split(os.pathsep) + else: + self.eventsAvailable = False + + def stop_session(self): + if self.session.event_hub.connected is True: + self.session.event_hub.disconnect() + self.session.close() + self.session = None + + def set_files(self, paths): + # Iterate all paths + functions = [] + for path in paths: + # add path to PYTHON PATH + if path not in sys.path: + sys.path.append(path) + + # Get all modules with functions + for file in os.listdir(path): + # Get only .py files with action functions + try: + if '.pyc' in file or '.py' not in file: + continue + + ignore = 'ignore_me' + mod = importlib.import_module(os.path.splitext(file)[0]) + importlib.reload(mod) + mod_functions = dict( + [ + (name, function) + for name, function in mod.__dict__.items() + if isinstance(function, types.FunctionType) or + name == ignore + ] + ) + # Don't care about ignore_me files + if ( + ignore in mod_functions and + mod_functions[ignore] is True + ): + continue + # separate files by register function + if 'register' not in mod_functions: + msg = ( + '"{0}" - Missing register method' + ).format(file, self.type) + log.warning(msg) + continue + + functions.append({ + 'name': file, + 'register': mod_functions['register'] + }) + except Exception as e: + msg = 'Loading of file "{}" failed ({})'.format( + file, str(e) + ) + log.warning(msg) + + if len(functions) < 1: + raise Exception + + for function in functions: + try: + function['register'](self.session) + except Exception as e: + msg = '"{}" - register was not successful ({})'.format( + function['name'], str(e) + ) + log.warning(msg) + time.sleep(0.05) + + def run_server(self): + self.session = ftrack_api.Session(auto_connect_event_hub=True,) + + if self.type.lower() == 'event': + if self.eventsAvailable is False: + msg = ( + 'FTRACK_EVENTS_PATH is not set' + ', event server won\'t launch' + ) + log.error(msg) + return + self.set_files(self.eventsPaths) + else: + if self.actionsAvailable is False: + msg = ( + 'FTRACK_ACTIONS_PATH is not set' + ', action server won\'t launch' + ) + log.error(msg) + return + self.set_files(self.actionsPaths) + + log.info(60*"*") + log.info('Registration of actions/events has finished!') + + # keep event_hub on session running + self.session.event_hub.wait() From 71291c5d3f8a6d742dfe9448054731a83fa06859 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 17:10:55 +0100 Subject: [PATCH 03/16] changed FtrackServer import in ftrack run --- pype/ftrack/ftrack_run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/ftrack/ftrack_run.py b/pype/ftrack/ftrack_run.py index a2214e7912..a722f8d3fe 100644 --- a/pype/ftrack/ftrack_run.py +++ b/pype/ftrack/ftrack_run.py @@ -9,7 +9,7 @@ from app.vendor.Qt import QtCore, QtGui, QtWidgets from pype.ftrack import credentials, login_dialog as login_dialog from pype.vendor.pynput import mouse, keyboard -from FtrackServer import FtrackServer +from . import FtrackServer from pype import api as pype From 7205675402ff68d9746b27ba3faf20dda8315443 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 18:09:16 +0100 Subject: [PATCH 04/16] added launch log into actions and events --- pype/ftrack/ftrack_server/event_server_cli.py | 2 +- pype/ftrack/lib/ftrack_app_handler.py | 4 ---- pype/ftrack/lib/ftrack_base_handler.py | 24 +++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/pype/ftrack/ftrack_server/event_server_cli.py b/pype/ftrack/ftrack_server/event_server_cli.py index b09a1cd851..d6df742085 100644 --- a/pype/ftrack/ftrack_server/event_server_cli.py +++ b/pype/ftrack/ftrack_server/event_server_cli.py @@ -5,7 +5,7 @@ import ftrack_api from . import FtrackServer from app import api -log = api.Logger.getLogger(__name__) +log = api.Logger.getLogger(__name__, "ftrack-event-server-cli") def check_cred(user, key): diff --git a/pype/ftrack/lib/ftrack_app_handler.py b/pype/ftrack/lib/ftrack_app_handler.py index 25ed81946a..fd5b758f22 100644 --- a/pype/ftrack/lib/ftrack_app_handler.py +++ b/pype/ftrack/lib/ftrack_app_handler.py @@ -143,10 +143,6 @@ class AppAction(BaseHandler): ''' - self.log.info(( - "Action - {0} ({1}) - just started" - ).format(self.label, self.identifier)) - entity = entities[0] project_name = entity['project']['full_name'] diff --git a/pype/ftrack/lib/ftrack_base_handler.py b/pype/ftrack/lib/ftrack_base_handler.py index 591cb98be8..3ef50a0de6 100644 --- a/pype/ftrack/lib/ftrack_base_handler.py +++ b/pype/ftrack/lib/ftrack_base_handler.py @@ -26,6 +26,7 @@ class BaseHandler(object): # Using decorator self.register = self.register_log(self.register) + self.launch = self.launch_log(self.launch) # Decorator def register_log(self, func): @@ -58,6 +59,29 @@ class BaseHandler(object): ) return wrapper_register + # Decorator + def launch_log(self, func): + @functools.wraps(func) + def wrapper_launch(*args, **kwargs): + label = self.__class__.__name__ + if hasattr(self, 'label'): + if self.variant is None: + label = self.label + else: + label = '{} {}'.format(self.label, self.variant) + + try: + result = func(*args, **kwargs) + self.log.info(( + '{} "{}" Launched' + ).format(self.type, label)) + return result + except Exception as e: + self.log.error('{} "{}": Launch failed ({})'.format( + self.type, label, str(e)) + ) + return wrapper_launch + @property def session(self): '''Return current session.''' From f275583de40c4e0454d286f57060b105de5923ae Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 18:46:18 +0100 Subject: [PATCH 05/16] credentials module and ftrack login count with event credentials --- pype/ftrack/credentials.py | 56 ++++++++++++++++++++++--------------- pype/ftrack/login_dialog.py | 7 +++-- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/pype/ftrack/credentials.py b/pype/ftrack/credentials.py index c6019b2da7..89353ea984 100644 --- a/pype/ftrack/credentials.py +++ b/pype/ftrack/credentials.py @@ -5,49 +5,61 @@ import appdirs config_path = os.path.normpath(appdirs.user_data_dir('pype-app', 'pype')) -config_name = 'ftrack_cred.json' -fpath = os.path.join(config_path, config_name) -folder = os.path.dirname(fpath) - -if not os.path.isdir(folder): - os.makedirs(folder) - - -def _get_credentials(): - - folder = os.path.dirname(fpath) +action_file_name = 'ftrack_cred.json' +event_file_name = 'ftrack_event_cred.json' +action_fpath = os.path.join(config_path, action_file_name) +event_fpath = os.path.join(config_path, event_file_name) +folders = set([os.path.dirname(action_fpath), os.path.dirname(event_fpath)]) +for folder in folders: if not os.path.isdir(folder): os.makedirs(folder) + +def _get_credentials(event=False): + if event: + fpath = event_fpath + else: + fpath = action_fpath + + credentials = {} try: file = open(fpath, 'r') + credentials = json.load(file) except Exception: - filecreate = open(fpath, 'w') - filecreate.close() - file = open(fpath, 'r') + file = open(fpath, 'w') - credentials = json.load(file) file.close() return credentials -def _save_credentials(username, apiKey): - file = open(fpath, 'w') - +def _save_credentials(username, apiKey, event=False, auto_connect=None): data = { 'username': username, 'apiKey': apiKey } - credentials = json.dumps(data) - file.write(credentials) + if event: + fpath = event_fpath + if auto_connect is None: + cred = _get_credentials(True) + auto_connect = cred.get('auto_connect', False) + data['auto_connect'] = auto_connect + else: + fpath = action_fpath + + file = open(fpath, 'w') + file.write(json.dumps(data)) file.close() -def _clear_credentials(): - file = open(fpath, 'w').close() +def _clear_credentials(event=False): + if event: + fpath = event_fpath + else: + fpath = action_fpath + open(fpath, 'w').close() _set_env(None, None) diff --git a/pype/ftrack/login_dialog.py b/pype/ftrack/login_dialog.py index c4011b0169..2828afe539 100644 --- a/pype/ftrack/login_dialog.py +++ b/pype/ftrack/login_dialog.py @@ -16,11 +16,12 @@ class Login_Dialog_ui(QtWidgets.QWidget): buttons = [] labels = [] - def __init__(self, parent=None): + def __init__(self, parent=None, is_event=False): super(Login_Dialog_ui, self).__init__() self.parent = parent + self.is_event = is_event if hasattr(parent, 'icon'): self.setWindowIcon(self.parent.icon) @@ -205,7 +206,7 @@ class Login_Dialog_ui(QtWidgets.QWidget): verification = credentials._check_credentials(username, apiKey) if verification: - credentials._save_credentials(username, apiKey) + credentials._save_credentials(username, apiKey, self.is_event) credentials._set_env(username, apiKey) if self.parent is not None: self.parent.loginChange() @@ -305,7 +306,7 @@ class Login_Dialog_ui(QtWidgets.QWidget): verification = credentials._check_credentials(username, apiKey) if verification is True: - credentials._save_credentials(username, apiKey) + credentials._save_credentials(username, apiKey, self.is_event) credentials._set_env(username, apiKey) if self.parent is not None: self.parent.loginChange() From aa19c52c0e3a987b2a69bbd8d2bd4eff750a5a8f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 18:47:01 +0100 Subject: [PATCH 06/16] fixed ftrackserver import --- pype/ftrack/ftrack_server/event_server.py | 2 +- pype/ftrack/ftrack_server/event_server_cli.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/ftrack/ftrack_server/event_server.py b/pype/ftrack/ftrack_server/event_server.py index 24cc5f22ee..bd174fee25 100644 --- a/pype/ftrack/ftrack_server/event_server.py +++ b/pype/ftrack/ftrack_server/event_server.py @@ -1,6 +1,6 @@ import sys from pype.ftrack import credentials, login_dialog as login_dialog -from . import FtrackServer +from pype.ftrack.ftrack_server import FtrackServer from app.vendor.Qt import QtWidgets from pype import api diff --git a/pype/ftrack/ftrack_server/event_server_cli.py b/pype/ftrack/ftrack_server/event_server_cli.py index d6df742085..6c8bc62a73 100644 --- a/pype/ftrack/ftrack_server/event_server_cli.py +++ b/pype/ftrack/ftrack_server/event_server_cli.py @@ -2,7 +2,7 @@ import os import json import appdirs import ftrack_api -from . import FtrackServer +from pype.ftrack.ftrack_server import FtrackServer from app import api log = api.Logger.getLogger(__name__, "ftrack-event-server-cli") From e5107d4dab39f4cb68f9abf89ebb2956f3ac7643 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 18:47:30 +0100 Subject: [PATCH 07/16] event server with gui uses event's credentials --- pype/ftrack/ftrack_server/event_server.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pype/ftrack/ftrack_server/event_server.py b/pype/ftrack/ftrack_server/event_server.py index bd174fee25..e824d1d899 100644 --- a/pype/ftrack/ftrack_server/event_server.py +++ b/pype/ftrack/ftrack_server/event_server.py @@ -9,10 +9,12 @@ log = api.Logger.getLogger(__name__, "ftrack-event-server") class EventServer: def __init__(self): - self.login_widget = login_dialog.Login_Dialog_ui(self) + self.login_widget = login_dialog.Login_Dialog_ui( + parent=self, is_event=True + ) self.event_server = FtrackServer('event') - cred = credentials._get_credentials() + cred = credentials._get_credentials(True) if 'username' in cred and 'apiKey' in cred: self.login_widget.user_input.setText(cred['username']) @@ -24,6 +26,7 @@ class EventServer: def loginChange(self): log.info("Logged successfully") + self.login_widget.close() self.event_server.run_server() From d8106a56e9fc22b91b5ec5a43e70974f3bc4d551 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 1 Mar 2019 18:48:21 +0100 Subject: [PATCH 08/16] cli event server works with credentials module and few more possibilities on entry were added --- pype/ftrack/ftrack_server/event_server_cli.py | 121 +++++++++--------- 1 file changed, 57 insertions(+), 64 deletions(-) diff --git a/pype/ftrack/ftrack_server/event_server_cli.py b/pype/ftrack/ftrack_server/event_server_cli.py index 6c8bc62a73..a466bf5723 100644 --- a/pype/ftrack/ftrack_server/event_server_cli.py +++ b/pype/ftrack/ftrack_server/event_server_cli.py @@ -1,112 +1,105 @@ -import os -import json -import appdirs -import ftrack_api +import sys +from pype.ftrack import credentials from pype.ftrack.ftrack_server import FtrackServer from app import api log = api.Logger.getLogger(__name__, "ftrack-event-server-cli") +possible_yes = ['y', 'yes'] +possible_no = ['n', 'no'] +possible_third = ['a', 'auto'] +possible_exit = ['exit'] -def check_cred(user, key): - os.environ["FTRACK_API_USER"] = user - os.environ["FTRACK_API_KEY"] = key - try: - session = ftrack_api.Session() - session.close() +def ask_yes_no(third=False): + msg = "Y/N:" + if third: + msg = "Y/N/AUTO:" + log.info(msg) + response = input().lower() + if response in possible_exit: + sys.exit() + elif response in possible_yes: return True - except Exception: - return False - - -def ask_yes_no(): - possible_yes = ["y", "yes"] - possible_no = ["n", "no"] - log.info("Y/N:") - cont = input() - if cont.lower() in possible_yes: - return True - elif cont.lower() in possible_no: + elif response in possible_no: return False else: + all_entries = possible_no + all_entries.extend(possible_yes) + if third is True: + if response in possible_third: + return 'auto' + else: + all_entries.extend(possible_third) + all_entries.extend(possible_exit) + all_entries = ', '.join(all_entries) log.info( - "Invalid input. Possible entries: [y, yes, n, no]. Try it again:" + 'Invalid input. Possible entries: [{}]. Try it again:'.foramt( + all_entries + ) ) return ask_yes_no() def cli_login(): - config_path = os.path.normpath(appdirs.user_data_dir('pype-app', 'pype')) - config_name = 'ftrack_event_cred.json' - event_credentials_file = os.path.join(config_path, config_name) - - if not os.path.isdir(config_path): - os.makedirs(config_path) - if not os.path.exists(event_credentials_file): - open(event_credentials_file, 'w').close() enter_cred = True + cred_data = credentials._get_credentials(True) - with open(event_credentials_file, 'r') as fp: - try: - cred_data = json.load(fp) - except Exception: - cred_data = {} - - user = cred_data.get("FTRACK_API_USER", None) - key = cred_data.get("FTRACK_API_KEY", None) - auto = cred_data.get("AUTO_CONNECT", False) + user = cred_data.get('username', None) + key = cred_data.get('apiKey', None) + auto = cred_data.get('auto_connect', False) if user is None or key is None: - log.info("Credentials are not set. Do you want to enter them now? (Y/N)") + log.info( + 'Credentials are not set. Do you want to enter them now? (Y/N)' + ) if ask_yes_no() is False: log.info("Exiting...") return - elif check_cred(user, key): + elif credentials._check_credentials(user, key): if auto is False: - log.info("Do you want to log with username {}? (Y/N)".format( - cred_data["FTRACK_API_USER"] + log.info(( + 'Do you want to log with username {}' + ' enter "auto" if want to autoconnect next time (Y/N/AUTO)' + ).format( + user )) - if ask_yes_no(): + result = ask_yes_no(True) + if result is True: + enter_cred = False + elif result == 'auto': + credentials._save_credentials(user, key, True, True) enter_cred = False else: enter_cred = False else: log.info( - "Stored credentials are not valid. " - "Do you want enter them now?(Y/N)" + 'Stored credentials are not valid.' + ' Do you want enter them now?(Y/N)' ) if ask_yes_no() is False: log.info("Exiting...") return while enter_cred: - log.info("Please enter Ftrack API User:") + log.info('Please enter Ftrack API User:') user = input() - log.info("And now enter Ftrack API Key:") + log.info('And now enter Ftrack API Key:') key = input() - if check_cred(user, key): - export = { - "FTRACK_API_USER": user, - "FTRACK_API_KEY": key - } + if credentials._check_credentials(user, key): log.info( - "Credentials are valid." - " Do you want to auto-connect next time?(Y/N)" + 'Credentials are valid.' + ' Do you want to auto-connect next time?(Y/N)' ) - if ask_yes_no(): - export["AUTO_CONNECT"] = True - - with open(event_credentials_file, 'w') as fp: - json.dump(export, fp) + credentials._save_credentials(user, key, True, ask_yes_no()) enter_cred = False break else: log.info( - "Entered credentials are not valid." - " Do you want to try it again?(Y/N)" + 'Entered credentials are not valid.' + ' Do you want to try it again?(Y/N)' ) if ask_yes_no() is False: - log.info("Exiting...") + log.info('Exiting...') return server = FtrackServer('event') From c1c483390de7b8b08bdc30af2653416b9cf379c7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Sun, 3 Mar 2019 21:44:55 +0100 Subject: [PATCH 09/16] added role check to base handler --- pype/ftrack/lib/ftrack_base_handler.py | 28 +++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/pype/ftrack/lib/ftrack_base_handler.py b/pype/ftrack/lib/ftrack_base_handler.py index 3ef50a0de6..d155213cab 100644 --- a/pype/ftrack/lib/ftrack_base_handler.py +++ b/pype/ftrack/lib/ftrack_base_handler.py @@ -4,6 +4,11 @@ import time from pype import api as pype +class MissingPermision(Exception): + def __init__(self): + super().__init__('Missing permission') + + class BaseHandler(object): '''Custom Action base class @@ -25,11 +30,11 @@ class BaseHandler(object): self.log = pype.Logger.getLogger(self.__class__.__name__) # Using decorator - self.register = self.register_log(self.register) + self.register = self.register_decorator(self.register) self.launch = self.launch_log(self.launch) # Decorator - def register_log(self, func): + def register_decorator(self, func): @functools.wraps(func) def wrapper_register(*args, **kwargs): label = self.__class__.__name__ @@ -38,8 +43,21 @@ class BaseHandler(object): label = self.label else: label = '{} {}'.format(self.label, self.variant) - try: + if hasattr(self, "role_list") and len(self.role_list) > 0: + username = self.session.api_user + user = self.session.query( + 'User where username is "{}"'.format(username) + ).one() + available = False + for role in user['user_security_roles']: + if role['security_role']['name'] in self.role_list: + available = True + break + if available is False: + raise MissingPermision + + start_time = time.perf_counter() func(*args, **kwargs) end_time = time.perf_counter() @@ -47,6 +65,10 @@ class BaseHandler(object): self.log.info(( '{} "{}" - Registered successfully ({:.4f}sec)' ).format(self.type, label, run_time)) + except MissingPermision: + self.log.info(( + '!{} "{}" - You\'re missing required permissions' + ).format(self.type, label)) except NotImplementedError: self.log.error(( '{} "{}" - Register method is not implemented' From 931f461cd8c823bc2b3816b8f06ed104272986fd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Sun, 3 Mar 2019 21:47:41 +0100 Subject: [PATCH 10/16] available user roles are set in actions --- .../actions/action_create_cust_attrs.py | 20 +++------------- pype/ftrack/actions/action_delete_asset.py | 22 ++++-------------- .../actions/action_delete_asset_byname.py | 20 +++------------- pype/ftrack/actions/action_job_killer.py | 20 +++------------- .../actions/action_sync_to_avalon_local.py | 19 +++------------ pype/ftrack/actions/action_test.py | 23 ++++--------------- 6 files changed, 20 insertions(+), 104 deletions(-) diff --git a/pype/ftrack/actions/action_create_cust_attrs.py b/pype/ftrack/actions/action_create_cust_attrs.py index 527f0daaf5..784b55682d 100644 --- a/pype/ftrack/actions/action_create_cust_attrs.py +++ b/pype/ftrack/actions/action_create_cust_attrs.py @@ -111,6 +111,8 @@ class CustomAttributes(BaseAction): label = 'Create/Update Avalon Attributes' #: Action description. description = 'Creates Avalon/Mongo ID for double check' + #: roles that are allowed to register this action + role_list = ['Pypeclub', 'Administrator'] def __init__(self, session): super().__init__(session) @@ -576,23 +578,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - roleList = ['Pypeclub', 'Administrator'] - - username = session.api_user - user = session.query('User where username is "{}"'.format(username)).one() - available = False - for role in user['user_security_roles']: - if role['security_role']['name'] in roleList: - available = True - break - if available is True: - CustomAttributes(session).register() - else: - logging.info( - "!!! You're missing required permissions for action {}".format( - CustomAttributes.__name__ - ) - ) + CustomAttributes(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_delete_asset.py b/pype/ftrack/actions/action_delete_asset.py index f1d2941420..0c46df36fd 100644 --- a/pype/ftrack/actions/action_delete_asset.py +++ b/pype/ftrack/actions/action_delete_asset.py @@ -13,10 +13,12 @@ class DeleteAsset(BaseAction): #: Action identifier. identifier = 'delete.asset' #: Action label. - label = 'Delete asset/subsets' + label = 'Delete Asset/Subsets' #: Action description. description = 'Removes from Avalon with all childs and asset from Ftrack' icon = "https://www.iconsdb.com/icons/preview/white/full-trash-xxl.png" + #: roles that are allowed to register this action + role_list = ['Pypeclub', 'Administrator'] #: Db db = DbConnector() @@ -310,23 +312,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - roleList = ['Pypeclub', 'Administrator'] - - username = session.api_user - user = session.query('User where username is "{}"'.format(username)).one() - available = False - for role in user['user_security_roles']: - if role['security_role']['name'] in roleList: - available = True - break - if available is True: - DeleteAsset(session).register() - else: - logging.info( - "!!! You're missing required permissions for action {}".format( - DeleteAsset.__name__ - ) - ) + DeleteAsset(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_delete_asset_byname.py b/pype/ftrack/actions/action_delete_asset_byname.py index 3b26854867..3115d5560a 100644 --- a/pype/ftrack/actions/action_delete_asset_byname.py +++ b/pype/ftrack/actions/action_delete_asset_byname.py @@ -15,6 +15,8 @@ class AssetsRemover(BaseAction): label = 'Delete Assets by Name' #: Action description. description = 'Removes assets from Ftrack and Avalon db with all childs' + #: roles that are allowed to register this action + role_list = ['Pypeclub', 'Administrator'] #: Db db = DbConnector() @@ -135,23 +137,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - roleList = ['Pypeclub', 'Administrator'] - - username = session.api_user - user = session.query('User where username is "{}"'.format(username)).one() - available = False - for role in user['user_security_roles']: - if role['security_role']['name'] in roleList: - available = True - break - if available is True: - AssetsRemover(session).register() - else: - logging.info( - "!!! You're missing required permissions for action {}".format( - AssetsRemover.__name__ - ) - ) + AssetsRemover(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_job_killer.py b/pype/ftrack/actions/action_job_killer.py index f4aa7b1816..9adf9c85e7 100644 --- a/pype/ftrack/actions/action_job_killer.py +++ b/pype/ftrack/actions/action_job_killer.py @@ -17,7 +17,8 @@ class JobKiller(BaseAction): label = 'Job Killer' #: Action description. description = 'Killing all running jobs younger than day' - + #: roles that are allowed to register this action + role_list = ['Pypeclub', 'Administrator'] def prediscover(self, event): ''' Validation ''' @@ -103,23 +104,8 @@ def register(session, **kw): # return without doing anything. if not isinstance(session, ftrack_api.session.Session): return - roleList = ['Pypeclub', 'Administrator'] - username = session.api_user - user = session.query('User where username is "{}"'.format(username)).one() - available = False - for role in user['user_security_roles']: - if role['security_role']['name'] in roleList: - available = True - break - if available is True: - JobKiller(session).register() - else: - logging.info( - "!!! You're missing required permissions for action {}".format( - JobKiller.__name__ - ) - ) + JobKiller(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_sync_to_avalon_local.py b/pype/ftrack/actions/action_sync_to_avalon_local.py index cc5df18444..68c55be652 100644 --- a/pype/ftrack/actions/action_sync_to_avalon_local.py +++ b/pype/ftrack/actions/action_sync_to_avalon_local.py @@ -54,6 +54,8 @@ class SyncToAvalon(BaseAction): 'https://cdn1.iconfinder.com/data/icons/hawcons/32/' '699650-icon-92-inbox-download-512.png' ) + #: roles that are allowed to register this action + role_list = ['Pypeclub'] #: Action priority priority = 200 @@ -223,23 +225,8 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - roleList = ['Pypeclub'] + SyncToAvalon(session).register() - username = session.api_user - user = session.query('User where username is "{}"'.format(username)).one() - available = False - for role in user['user_security_roles']: - if role['security_role']['name'] in roleList: - available = True - break - if available is True: - SyncToAvalon(session).register() - else: - logging.info( - "!!! You're missing required permissions for action {}".format( - SyncToAvalon.__name__ - ) - ) def main(arguments=None): '''Set up logging and register action.''' diff --git a/pype/ftrack/actions/action_test.py b/pype/ftrack/actions/action_test.py index d88bcf7290..5555d8cea7 100644 --- a/pype/ftrack/actions/action_test.py +++ b/pype/ftrack/actions/action_test.py @@ -25,8 +25,9 @@ class TestAction(BaseAction): description = 'Test action' #: priority priority = 10000 - - def prediscover(self, session, entities, event): + #: roles that are allowed to register this action + role_list = ['Pypecub'] + def prediscover(self, event): ''' Validation ''' return True @@ -43,23 +44,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - roleList = ['Pypeclub'] - - username = session.api_user - user = session.query('User where username is "{}"'.format(username)).one() - available = False - for role in user['user_security_roles']: - if role['security_role']['name'] in roleList: - available = True - break - if available is True: - TestAction(session).register() - else: - logging.info( - "!!! You're missing required permissions for action {}".format( - TestAction.__name__ - ) - ) + TestAction(session).register() def main(arguments=None): From cff2839a18f8f95ab463f530141f621ed139cecf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Sun, 3 Mar 2019 21:48:16 +0100 Subject: [PATCH 11/16] added/changed icons in few actions --- pype/ftrack/actions/action_create_cust_attrs.py | 5 +++++ pype/ftrack/actions/action_delete_asset.py | 6 +++++- pype/ftrack/actions/action_delete_asset_byname.py | 5 +++++ pype/ftrack/actions/action_job_killer.py | 4 ++++ pype/ftrack/actions/action_test.py | 4 ++++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pype/ftrack/actions/action_create_cust_attrs.py b/pype/ftrack/actions/action_create_cust_attrs.py index 784b55682d..f75d10591d 100644 --- a/pype/ftrack/actions/action_create_cust_attrs.py +++ b/pype/ftrack/actions/action_create_cust_attrs.py @@ -113,6 +113,11 @@ class CustomAttributes(BaseAction): description = 'Creates Avalon/Mongo ID for double check' #: roles that are allowed to register this action role_list = ['Pypeclub', 'Administrator'] + icon = ( + 'https://cdn4.iconfinder.com/data/icons/' + 'ios-web-user-interface-multi-circle-flat-vol-4/512/' + 'Bullet_list_menu_lines_points_items_options-512.png' + ) def __init__(self, session): super().__init__(session) diff --git a/pype/ftrack/actions/action_delete_asset.py b/pype/ftrack/actions/action_delete_asset.py index 0c46df36fd..ad10ed6696 100644 --- a/pype/ftrack/actions/action_delete_asset.py +++ b/pype/ftrack/actions/action_delete_asset.py @@ -16,7 +16,11 @@ class DeleteAsset(BaseAction): label = 'Delete Asset/Subsets' #: Action description. description = 'Removes from Avalon with all childs and asset from Ftrack' - icon = "https://www.iconsdb.com/icons/preview/white/full-trash-xxl.png" + icon = ( + 'https://cdn4.iconfinder.com/data/icons/' + 'ios-web-user-interface-multi-circle-flat-vol-5/512/' + 'Delete_dustbin_empty_recycle_recycling_remove_trash-512.png' + ) #: roles that are allowed to register this action role_list = ['Pypeclub', 'Administrator'] #: Db diff --git a/pype/ftrack/actions/action_delete_asset_byname.py b/pype/ftrack/actions/action_delete_asset_byname.py index 3115d5560a..e1480bb092 100644 --- a/pype/ftrack/actions/action_delete_asset_byname.py +++ b/pype/ftrack/actions/action_delete_asset_byname.py @@ -17,6 +17,11 @@ class AssetsRemover(BaseAction): description = 'Removes assets from Ftrack and Avalon db with all childs' #: roles that are allowed to register this action role_list = ['Pypeclub', 'Administrator'] + icon = ( + 'https://cdn4.iconfinder.com/data/icons/' + 'ios-web-user-interface-multi-circle-flat-vol-5/512/' + 'Clipboard_copy_delete_minus_paste_remove-512.png' + ) #: Db db = DbConnector() diff --git a/pype/ftrack/actions/action_job_killer.py b/pype/ftrack/actions/action_job_killer.py index 9adf9c85e7..4324fceda8 100644 --- a/pype/ftrack/actions/action_job_killer.py +++ b/pype/ftrack/actions/action_job_killer.py @@ -19,6 +19,10 @@ class JobKiller(BaseAction): description = 'Killing all running jobs younger than day' #: roles that are allowed to register this action role_list = ['Pypeclub', 'Administrator'] + icon = ( + 'https://cdn2.iconfinder.com/data/icons/new-year-resolutions/64/' + 'resolutions-23-512.png' + ) def prediscover(self, event): ''' Validation ''' diff --git a/pype/ftrack/actions/action_test.py b/pype/ftrack/actions/action_test.py index 5555d8cea7..a55d971db2 100644 --- a/pype/ftrack/actions/action_test.py +++ b/pype/ftrack/actions/action_test.py @@ -27,6 +27,10 @@ class TestAction(BaseAction): priority = 10000 #: roles that are allowed to register this action role_list = ['Pypecub'] + icon = ( + 'https://cdn4.iconfinder.com/data/icons/hospital-19/512/' + '8_hospital-512.png' + ) def prediscover(self, event): ''' Validation ''' From 14b62f61fab9e24bdedfb2393f6a10febf43b567 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Sun, 3 Mar 2019 21:49:07 +0100 Subject: [PATCH 12/16] shortened code to register actions without variables --- pype/ftrack/actions/action_asset_delete.py | 3 +-- pype/ftrack/actions/action_delete_unpublished.py | 3 +-- pype/ftrack/actions/action_set_version.py | 3 +-- pype/ftrack/actions/action_thumbToChildern.py | 3 +-- pype/ftrack/actions/action_thumbToParent.py | 3 +-- pype/ftrack/events/action_sync_to_avalon.py | 3 +-- pype/ftrack/events/event_next_task_update.py | 3 +-- pype/ftrack/events/event_sync_to_avalon.py | 3 +-- pype/ftrack/events/event_test.py | 3 +-- pype/ftrack/events/event_thumbnail_updates.py | 3 +-- pype/ftrack/events/event_version_to_task_statuses.py | 3 +-- 11 files changed, 11 insertions(+), 22 deletions(-) diff --git a/pype/ftrack/actions/action_asset_delete.py b/pype/ftrack/actions/action_asset_delete.py index 2359c2e499..c47c8ac4ac 100644 --- a/pype/ftrack/actions/action_asset_delete.py +++ b/pype/ftrack/actions/action_asset_delete.py @@ -87,8 +87,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - action_handler = AssetDelete(session) - action_handler.register() + AssetDelete(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_delete_unpublished.py b/pype/ftrack/actions/action_delete_unpublished.py index 9c7ae60f3b..018a70b423 100644 --- a/pype/ftrack/actions/action_delete_unpublished.py +++ b/pype/ftrack/actions/action_delete_unpublished.py @@ -51,8 +51,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - action_handler = VersionsCleanup(session) - action_handler.register() + VersionsCleanup(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_set_version.py b/pype/ftrack/actions/action_set_version.py index 9156f23055..3954733041 100644 --- a/pype/ftrack/actions/action_set_version.py +++ b/pype/ftrack/actions/action_set_version.py @@ -80,8 +80,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - action_handler = SetVersion(session) - action_handler.register() + SetVersion(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_thumbToChildern.py b/pype/ftrack/actions/action_thumbToChildern.py index a314e98871..2ff6faec48 100644 --- a/pype/ftrack/actions/action_thumbToChildern.py +++ b/pype/ftrack/actions/action_thumbToChildern.py @@ -69,8 +69,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - action_handler = ThumbToChildren(session) - action_handler.register() + ThumbToChildren(session).register() def main(arguments=None): diff --git a/pype/ftrack/actions/action_thumbToParent.py b/pype/ftrack/actions/action_thumbToParent.py index 25d87d4dad..98124aca70 100644 --- a/pype/ftrack/actions/action_thumbToParent.py +++ b/pype/ftrack/actions/action_thumbToParent.py @@ -91,8 +91,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - action_handler = ThumbToParent(session) - action_handler.register() + ThumbToParent(session).register() def main(arguments=None): diff --git a/pype/ftrack/events/action_sync_to_avalon.py b/pype/ftrack/events/action_sync_to_avalon.py index 67db0d808f..a3ad4d34cf 100644 --- a/pype/ftrack/events/action_sync_to_avalon.py +++ b/pype/ftrack/events/action_sync_to_avalon.py @@ -240,8 +240,7 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - action_handler = Sync_To_Avalon(session) - action_handler.register() + Sync_To_Avalon(session).register() def main(arguments=None): diff --git a/pype/ftrack/events/event_next_task_update.py b/pype/ftrack/events/event_next_task_update.py index 8be146fc36..b6c82b930c 100644 --- a/pype/ftrack/events/event_next_task_update.py +++ b/pype/ftrack/events/event_next_task_update.py @@ -83,5 +83,4 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - event = NextTaskUpdate(session) - event.register() + NextTaskUpdate(session).register() diff --git a/pype/ftrack/events/event_sync_to_avalon.py b/pype/ftrack/events/event_sync_to_avalon.py index 2c740c1955..1699ea5d3c 100644 --- a/pype/ftrack/events/event_sync_to_avalon.py +++ b/pype/ftrack/events/event_sync_to_avalon.py @@ -165,5 +165,4 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - event = Sync_to_Avalon(session) - event.register() + Sync_to_Avalon(session).register() diff --git a/pype/ftrack/events/event_test.py b/pype/ftrack/events/event_test.py index f1917addf0..ecefc628f3 100644 --- a/pype/ftrack/events/event_test.py +++ b/pype/ftrack/events/event_test.py @@ -27,5 +27,4 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - event = Test_Event(session) - event.register() + Test_Event(session).register() diff --git a/pype/ftrack/events/event_thumbnail_updates.py b/pype/ftrack/events/event_thumbnail_updates.py index b7429bcfaf..62a194d167 100644 --- a/pype/ftrack/events/event_thumbnail_updates.py +++ b/pype/ftrack/events/event_thumbnail_updates.py @@ -45,5 +45,4 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - event = ThumbnailEvents(session) - event.register() + ThumbnailEvents(session).register() diff --git a/pype/ftrack/events/event_version_to_task_statuses.py b/pype/ftrack/events/event_version_to_task_statuses.py index fabf8c2859..c5c1d9b664 100644 --- a/pype/ftrack/events/event_version_to_task_statuses.py +++ b/pype/ftrack/events/event_version_to_task_statuses.py @@ -75,5 +75,4 @@ def register(session, **kw): if not isinstance(session, ftrack_api.session.Session): return - event = VersionToTaskStatus(session) - event.register() + VersionToTaskStatus(session).register() From 12f288114dda5d10e31c9cd943c004c481d4176e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 4 Mar 2019 17:04:49 +0100 Subject: [PATCH 13/16] added 's' to subset if more than 1 --- pype/ftrack/actions/action_delete_asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/ftrack/actions/action_delete_asset.py b/pype/ftrack/actions/action_delete_asset.py index ad10ed6696..e453edcaa4 100644 --- a/pype/ftrack/actions/action_delete_asset.py +++ b/pype/ftrack/actions/action_delete_asset.py @@ -177,7 +177,7 @@ class DeleteAsset(BaseAction): ) else: title = title.format( - '{} subset'.format(len_subsets) + '{} subsets'.format(len_subsets) ) self.values = values From 9c2edaf5590d91d6f0ec4514ad34c83f11a82cc3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 4 Mar 2019 17:40:51 +0100 Subject: [PATCH 14/16] added event that collects entities --- pype/ftrack/actions/event_collect_entities.py | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 pype/ftrack/actions/event_collect_entities.py diff --git a/pype/ftrack/actions/event_collect_entities.py b/pype/ftrack/actions/event_collect_entities.py new file mode 100644 index 0000000000..1b2cdce47f --- /dev/null +++ b/pype/ftrack/actions/event_collect_entities.py @@ -0,0 +1,70 @@ +import ftrack_api +from pype.ftrack import BaseEvent + + +class CollectEntities(BaseEvent): + + priority = 1 + + def launch(self, event): + entities, entity_types = self.translate_event(event) + entities_count = len(entities) + event['data']['entities'] = entities + event['data']['entity_types'] = entity_types + event['data']['entities_count'] = entities_count + + return True + + def translate_event(self, event): + selection = event['data'].get('selection', []) + + entities = list() + entity_types = set() + for entity in selection: + ent = self.session.get( + self.get_entity_type(entity), + entity.get('entityId') + ) + entities.append(ent) + entity_types.add(ent.entity_type) + + return [entities, entity_types] + + def get_entity_type(self, entity): + '''Return translated entity type tht can be used with API.''' + # Get entity type and make sure it is lower cased. Most places except + # the component tab in the Sidebar will use lower case notation. + entity_type = entity.get('entityType').replace('_', '').lower() + + for schema in self.session.schemas: + alias_for = schema.get('alias_for') + + if ( + alias_for and isinstance(alias_for, str) and + alias_for.lower() == entity_type + ): + return schema['id'] + + for schema in self.session.schemas: + if schema['id'].lower() == entity_type: + return schema['id'] + + raise ValueError( + 'Unable to translate entity type: {0}.'.format(entity_type) + ) + + def register(self): + self.session.event_hub.subscribe( + 'topic=ftrack.action.discover' + ' and source.user.username={0}'.format(self.session.api_user), + self.launch, + priority=self.priority + ) + + +def register(session, **kw): + '''Register plugin. Called when used as an plugin.''' + if not isinstance(session, ftrack_api.session.Session): + return + + CollectEntities(session).register() From 2cb6c6260d28d0e19d349cc118b2654ef9c160f6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 4 Mar 2019 17:41:55 +0100 Subject: [PATCH 15/16] changed base handler so it uses collected entities from event --- pype/ftrack/lib/ftrack_base_handler.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/pype/ftrack/lib/ftrack_base_handler.py b/pype/ftrack/lib/ftrack_base_handler.py index d155213cab..e9f5b8e9a3 100644 --- a/pype/ftrack/lib/ftrack_base_handler.py +++ b/pype/ftrack/lib/ftrack_base_handler.py @@ -57,7 +57,6 @@ class BaseHandler(object): if available is False: raise MissingPermision - start_time = time.perf_counter() func(*args, **kwargs) end_time = time.perf_counter() @@ -172,19 +171,7 @@ class BaseHandler(object): '''Return *event* translated structure to be used with the API.''' - _selection = event['data'].get('selection', []) - - _entities = list() - for entity in _selection: - _entities.append( - ( - session.get( - self._get_entity_type(entity), - entity.get('entityId') - ) - ) - ) - + _entities = event['data']['entities'] return [ _entities, event From 021970140412e6fb264f8075cf6c3d872eac55ee Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 4 Mar 2019 17:51:35 +0100 Subject: [PATCH 16/16] changed launch to _lanuch so it won't log each time --- pype/ftrack/actions/event_collect_entities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/ftrack/actions/event_collect_entities.py b/pype/ftrack/actions/event_collect_entities.py index 1b2cdce47f..14ad581efc 100644 --- a/pype/ftrack/actions/event_collect_entities.py +++ b/pype/ftrack/actions/event_collect_entities.py @@ -6,7 +6,7 @@ class CollectEntities(BaseEvent): priority = 1 - def launch(self, event): + def _launch(self, event): entities, entity_types = self.translate_event(event) entities_count = len(entities) event['data']['entities'] = entities @@ -57,7 +57,7 @@ class CollectEntities(BaseEvent): self.session.event_hub.subscribe( 'topic=ftrack.action.discover' ' and source.user.username={0}'.format(self.session.api_user), - self.launch, + self._launch, priority=self.priority )