def install(): log.info("Registering global plug-ins..") pyblish.register_plugin_path(PUBLISH_PATH) pyblish.register_discovery_filter(filter_pyblish_plugins) avalon.register_plugin_path(avalon.Loader, LOAD_PATH) # Register project specific plugins project_name = os.environ.get("AVALON_PROJECT") if PROJECT_PLUGINS_PATH and project_name: for path in PROJECT_PLUGINS_PATH.split(os.pathsep): if not path: continue plugin_path = os.path.join(path, project_name, "plugins") if os.path.exists(plugin_path): pyblish.register_plugin_path(plugin_path) avalon.register_plugin_path(avalon.Loader, plugin_path) avalon.register_plugin_path(avalon.Creator, plugin_path) avalon.register_plugin_path(avalon.InventoryAction, plugin_path) # Register studio specific plugins if STUDIO_PLUGINS_PATH and project_name: for path in STUDIO_PLUGINS_PATH.split(os.pathsep): if not path: continue if os.path.exists(path): pyblish.register_plugin_path(path) avalon.register_plugin_path(avalon.Loader, path) avalon.register_plugin_path(avalon.Creator, path) avalon.register_plugin_path(avalon.InventoryAction, path) if project_name: anatomy = Anatomy(project_name) anatomy.set_root_environments() avalon.register_root(anatomy.roots) # apply monkey patched discover to original one avalon.discover = patched_discover
def run_application(self, app, project, asset, task, tools, arguments): """Run application in project/asset/task context. With default or specified tools enviornment. This uses pre-defined launcher in `pype-config/launchers` where there must be *toml* file with definition and in platform directory its launcher shell script or binary executables. Arguments will be passed to this script or executable. :param app: Full application name (`maya_2018`) :type app: Str :param project: Project name :type project: Str :param asset: Asset name :type asset: Str :param task: Task name :type task: Str :param tools: Comma separated list of tools (`"mtoa_2.1.0,yeti_4"`) :type tools: Str :param arguments: List of other arguments passed to app :type: List :rtype: None """ import toml import subprocess from pypeapp.lib.Terminal import Terminal from pypeapp import Anatomy t = Terminal() self._initialize() self._update_python_path() import acre from avalon import lib from pype import lib as pypelib abspath = lib.which_app(app) if abspath is None: t.echo("!!! Application [ {} ] is not registered.".format(app)) t.echo("*** Please define its toml file.") return app_toml = toml.load(abspath) executable = app_toml['executable'] app_dir = app_toml['application_dir'] # description = app_toml.get('description', None) # preactions = app_toml.get('preactions', []) launchers_path = os.path.join(os.environ["PYPE_CONFIG"], "launchers") database = pypelib.get_avalon_database() avalon_project = database[project].find_one({"type": "project"}) if avalon_project is None: t.echo( "!!! Project [ {} ] doesn't exists in Avalon.".format(project)) return False # get asset from db avalon_asset = database[project].find_one({ "type": "asset", "name": asset }) avalon_tools = avalon_project["data"]["tools_env"] if tools: avalon_tools = tools.split(",") or [] hierarchy = "" parents = avalon_asset["data"]["parents"] or [] if parents: hierarchy = os.path.join(*parents) data = { "project": { "name": project, "code": avalon_project['data']['code'] }, "task": task, "asset": asset, "app": app_dir, "hierarchy": hierarchy, } anatomy = Anatomy(project) anatomy_filled = anatomy.format(data) workdir = os.path.normpath(anatomy_filled["work"]["folder"]) # set PYPE_ROOT_* environments anatomy.set_root_environments() # set environments for Avalon os.environ["AVALON_PROJECT"] = project os.environ["AVALON_SILO"] = None os.environ["AVALON_ASSET"] = asset os.environ["AVALON_TASK"] = task os.environ["AVALON_APP"] = app.split("_")[0] os.environ["AVALON_APP_NAME"] = app os.environ["AVALON_WORKDIR"] = workdir os.environ["AVALON_HIERARCHY"] = hierarchy try: os.makedirs(workdir) except FileExistsError: pass tools_attr = [os.environ["AVALON_APP"], os.environ["AVALON_APP_NAME"]] tools_attr += avalon_tools print("TOOLS: {}".format(tools_attr)) tools_env = acre.get_tools(tools_attr) env = acre.compute(tools_env) env = acre.merge(env, current_env=dict(os.environ)) env = {k: str(v) for k, v in env.items()} # sanitize slashes in path env["PYTHONPATH"] = env["PYTHONPATH"].replace("/", "\\") env["PYTHONPATH"] = env["PYTHONPATH"].replace("\\\\", "\\") launchers_path = os.path.join(launchers_path, platform.system().lower()) execfile = None if sys.platform == "win32": # test all avaliable executable format, find first and use it for ext in os.environ["PATHEXT"].split(os.pathsep): fpath = os.path.join(launchers_path.strip('"'), executable + ext) if os.path.isfile(fpath) and os.access(fpath, os.X_OK): execfile = fpath break # Run SW if was found executable if execfile is not None: try: t.echo(">>> Running [ {} {} ]".format( executable, " ".join(arguments))) args = [execfile] args.extend(arguments) subprocess.run(args, env=env) except ValueError as e: t.echo("!!! Error while launching application:") t.echo(e) return else: t.echo( "!!! cannot find application launcher [ {} ]".format(app)) return if sys.platform.startswith('linux'): execfile = os.path.join(launchers_path.strip('"'), executable) if os.path.isfile(execfile): try: fp = open(execfile) except PermissionError as p: t.echo("!!! Access denied on launcher [ {} ]".format(app)) t.echo(p) return fp.close() else: t.echo("!!! Launcher doesn\'t exist [ {} ]".format(execfile)) return # Run SW if was found executable if execfile is not None: args = ['/usr/bin/env', 'bash', execfile] args.extend(arguments) t.echo(">>> Running [ {} ]".format(" ".join(args))) try: subprocess.run(args, env=env) except ValueError as e: t.echo("!!! Error while launching application:") t.echo(e) return else: t.echo( "!!! cannot find application launcher [ {} ]".format(app)) return