From 7bef86ac79a246487437e50e6c2f2252491f7bf4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 15 Jul 2024 12:55:57 +0200 Subject: [PATCH 01/15] Enable Validate Outdated Containers by default for Fusion --- server/settings/publish_plugins.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 36bb3f7340..1ca487969f 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -964,7 +964,8 @@ DEFAULT_PUBLISH_VALUES = { "nuke", "harmony", "photoshop", - "aftereffects" + "aftereffects", + "fusion" ], "enabled": True, "optional": True, From 947ecfd9182b405a618af1a89e476676cb927e4c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:16:39 +0200 Subject: [PATCH 02/15] add username to tray information --- client/ayon_core/tools/tray/ui/tray.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/tools/tray/ui/tray.py b/client/ayon_core/tools/tray/ui/tray.py index 660c61ac94..aed1fe2139 100644 --- a/client/ayon_core/tools/tray/ui/tray.py +++ b/client/ayon_core/tools/tray/ui/tray.py @@ -3,12 +3,11 @@ import sys import time import collections import atexit -import json import platform -from aiohttp.web_response import Response import ayon_api from qtpy import QtCore, QtGui, QtWidgets +from aiohttp.web import Response, json_response, Request from ayon_core import resources, style from ayon_core.lib import ( @@ -91,6 +90,10 @@ class TrayManager: self._services_submenu = None self._start_time = time.time() + # Cache AYON username used in process + # - it can change only by changing ayon_api global connection + # should be safe for tray application to cache the value only once + self._cached_username = None self._closing = False try: set_tray_server_url( @@ -143,7 +146,7 @@ class TrayManager: self._addons_manager.initialize(tray_menu) self._addons_manager.add_route( - "GET", "/tray", self._get_web_tray_info + "GET", "/tray", self._web_get_tray_info ) admin_submenu = ITrayAction.admin_submenu(tray_menu) @@ -274,8 +277,12 @@ class TrayManager: return item - async def _get_web_tray_info(self, request): - return Response(text=json.dumps({ + async def _web_get_tray_info(self, _request: Request) -> Response: + if self._cached_username is None: + self._cached_username = ayon_api.get_user()["name"] + + return json_response({ + "username": self._cached_username, "bundle": os.getenv("AYON_BUNDLE_NAME"), "dev_mode": is_dev_mode_enabled(), "staging_mode": is_staging_enabled(), From 90bb6a841be6fbf7a9095f1977f9dfddceee4014 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:49:15 +0200 Subject: [PATCH 03/15] added force option to tray # Conflicts: # client/ayon_core/tools/tray/lib.py --- client/ayon_core/cli.py | 11 +++++++++-- client/ayon_core/cli_commands.py | 6 ------ client/ayon_core/tools/tray/lib.py | 10 +++++++++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/cli.py b/client/ayon_core/cli.py index e97b8f1c5a..ee993ecd82 100644 --- a/client/ayon_core/cli.py +++ b/client/ayon_core/cli.py @@ -59,13 +59,20 @@ def main_cli(ctx): @main_cli.command() -def tray(): +@click.option( + "--force", + is_flag=True, + help="Force to start tray and close any existing one.") +def tray(force): """Launch AYON tray. Default action of AYON command is to launch tray widget to control basic aspects of AYON. See documentation for more information. """ - Commands.launch_tray() + + from ayon_core.tools.tray import main + + main(force) @main_cli.group(help="Run command line arguments of AYON addons") diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index 9d871c54b1..8ae1ebb3ba 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -13,12 +13,6 @@ class Commands: Most of its methods are called by :mod:`cli` module. """ - @staticmethod - def launch_tray(): - from ayon_core.tools.tray import main - - main() - @staticmethod def publish( path: str, diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index e13c682ab0..752c1ee842 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -344,12 +344,20 @@ def is_tray_running( return state != TrayState.NOT_RUNNING -def main(): +def main(force=False): from ayon_core.tools.tray.ui import main Logger.set_process_name("Tray") state = get_tray_state() + if force and state in (TrayState.RUNNING, TrayState.STARTING): + file_info = get_tray_file_info() or {} + pid = file_info.get("pid") + if pid is not None: + _kill_tray_process(pid) + remove_tray_server_url(force=True) + state = TrayState.NOT_RUNNING + if state == TrayState.RUNNING: print("Tray is already running.") return From d1c85ea2af856063d789e28719641aaa78fd50b0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:09:50 +0200 Subject: [PATCH 04/15] added hidden force to main cli --- client/ayon_core/cli.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/cli.py b/client/ayon_core/cli.py index ee993ecd82..5936316e2c 100644 --- a/client/ayon_core/cli.py +++ b/client/ayon_core/cli.py @@ -43,6 +43,7 @@ class AliasedGroup(click.Group): help="Enable debug") @click.option("--verbose", expose_value=False, help=("Change AYON log level (debug - critical or 0-50)")) +@click.option("--force", is_flag=True, expose_value=False, hidden=True) def main_cli(ctx): """AYON is main command serving as entry point to pipeline system. From 9c01ddaf638f19988fefcef76cd6b516d4cfc57c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:47:08 +0200 Subject: [PATCH 05/15] make starting tray check faster --- client/ayon_core/tools/tray/lib.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index e13c682ab0..16a6770d82 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -122,6 +122,10 @@ def _wait_for_starting_tray( if data.get("started") is True: return data + pid = data.get("pid") + if pid and not _is_process_running(pid): + return None + if time.time() - started_at > timeout: return None time.sleep(0.1) From 6bbd48e989cd8251e921fff520a4b513bdb234e9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:17:39 +0200 Subject: [PATCH 06/15] fix closing bracket --- client/ayon_core/tools/tray/ui/tray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/tray/ui/tray.py b/client/ayon_core/tools/tray/ui/tray.py index aed1fe2139..16e8434302 100644 --- a/client/ayon_core/tools/tray/ui/tray.py +++ b/client/ayon_core/tools/tray/ui/tray.py @@ -292,7 +292,7 @@ class TrayManager: }, "installer_version": os.getenv("AYON_VERSION"), "running_time": time.time() - self._start_time, - })) + }) def _on_update_check_timer(self): try: From a4de305fde378698ae59cfe4d66472213a7024c9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:31:10 +0200 Subject: [PATCH 07/15] remove tray filepath if pid is not running --- client/ayon_core/tools/tray/lib.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 16a6770d82..abe8a7a11d 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -278,7 +278,12 @@ def remove_tray_server_url(force: Optional[bool] = False): except BaseException: data = {} - if force or not data or data.get("pid") == os.getpid(): + if ( + force + or not data + or data.get("pid") == os.getpid() + or not _is_process_running(data.get("pid")) + ): os.remove(filepath) From 17e04cd8849216b85557e32293936abce85f7344 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:31:23 +0200 Subject: [PATCH 08/15] call 'remove_tray_server_url' in wait for tray to start --- client/ayon_core/tools/tray/lib.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index abe8a7a11d..2c3a577641 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -124,6 +124,7 @@ def _wait_for_starting_tray( pid = data.get("pid") if pid and not _is_process_running(pid): + remove_tray_server_url() return None if time.time() - started_at > timeout: From 715f547adf1e4539b6841d70774754bb143b28fa Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:11:00 +0200 Subject: [PATCH 09/15] fix possible encoding issues --- client/ayon_core/tools/tray/lib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 752c1ee842..20770d5136 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -7,6 +7,7 @@ import subprocess import csv import time import signal +import locale from typing import Optional, Dict, Tuple, Any import ayon_api @@ -50,7 +51,8 @@ def _get_server_and_variant( def _windows_pid_is_running(pid: int) -> bool: args = ["tasklist.exe", "/fo", "csv", "/fi", f"PID eq {pid}"] output = subprocess.check_output(args) - csv_content = csv.DictReader(output.decode("utf-8").splitlines()) + encoding = locale.getpreferredencoding() + csv_content = csv.DictReader(output.decode(encoding).splitlines()) # if "PID" not in csv_content.fieldnames: # return False for _ in csv_content: From 5d18e69c7a98d417acfa62ff061905ff46812c39 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:25:20 +0200 Subject: [PATCH 10/15] forward force to tray --- client/ayon_core/cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/cli.py b/client/ayon_core/cli.py index 5936316e2c..0a9bb2aa9c 100644 --- a/client/ayon_core/cli.py +++ b/client/ayon_core/cli.py @@ -43,8 +43,8 @@ class AliasedGroup(click.Group): help="Enable debug") @click.option("--verbose", expose_value=False, help=("Change AYON log level (debug - critical or 0-50)")) -@click.option("--force", is_flag=True, expose_value=False, hidden=True) -def main_cli(ctx): +@click.option("--force", is_flag=True, hidden=True) +def main_cli(ctx, force): """AYON is main command serving as entry point to pipeline system. It wraps different commands together. @@ -56,7 +56,7 @@ def main_cli(ctx): print(ctx.get_help()) sys.exit(0) else: - ctx.invoke(tray) + ctx.forward(tray) @main_cli.command() From 4511f8db5bb3b44fcac30ba8231e00ebd1c02f1d Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:32:16 +0200 Subject: [PATCH 11/15] move addons manager to ui --- client/ayon_core/tools/tray/__init__.py | 2 -- client/ayon_core/tools/tray/{ => ui}/addons_manager.py | 0 client/ayon_core/tools/tray/ui/tray.py | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) rename client/ayon_core/tools/tray/{ => ui}/addons_manager.py (100%) diff --git a/client/ayon_core/tools/tray/__init__.py b/client/ayon_core/tools/tray/__init__.py index 9dbacc54c2..c8fcd7841e 100644 --- a/client/ayon_core/tools/tray/__init__.py +++ b/client/ayon_core/tools/tray/__init__.py @@ -1,5 +1,4 @@ from .webserver import HostMsgAction -from .addons_manager import TrayAddonsManager from .lib import ( TrayState, get_tray_state, @@ -11,7 +10,6 @@ from .lib import ( __all__ = ( "HostMsgAction", - "TrayAddonsManager", "TrayState", "get_tray_state", diff --git a/client/ayon_core/tools/tray/addons_manager.py b/client/ayon_core/tools/tray/ui/addons_manager.py similarity index 100% rename from client/ayon_core/tools/tray/addons_manager.py rename to client/ayon_core/tools/tray/ui/addons_manager.py diff --git a/client/ayon_core/tools/tray/ui/tray.py b/client/ayon_core/tools/tray/ui/tray.py index 660c61ac94..2a2c79129b 100644 --- a/client/ayon_core/tools/tray/ui/tray.py +++ b/client/ayon_core/tools/tray/ui/tray.py @@ -28,13 +28,13 @@ from ayon_core.tools.utils import ( WrappedCallbackItem, get_ayon_qt_app, ) -from ayon_core.tools.tray import TrayAddonsManager from ayon_core.tools.tray.lib import ( set_tray_server_url, remove_tray_server_url, TrayIsRunningError, ) +from .addons_manager import TrayAddonsManager from .host_console_listener import HostListener from .info_widget import InfoWidget from .dialogs import ( From a4bb042337daf099c1a4adb5a9414da892b603b8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:32:45 +0200 Subject: [PATCH 12/15] move structures out of webserver --- client/ayon_core/tools/tray/__init__.py | 2 +- client/ayon_core/tools/tray/{webserver => }/structures.py | 0 client/ayon_core/tools/tray/webserver/__init__.py | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) rename client/ayon_core/tools/tray/{webserver => }/structures.py (100%) diff --git a/client/ayon_core/tools/tray/__init__.py b/client/ayon_core/tools/tray/__init__.py index c8fcd7841e..2490122358 100644 --- a/client/ayon_core/tools/tray/__init__.py +++ b/client/ayon_core/tools/tray/__init__.py @@ -1,4 +1,4 @@ -from .webserver import HostMsgAction +from .structures import HostMsgAction from .lib import ( TrayState, get_tray_state, diff --git a/client/ayon_core/tools/tray/webserver/structures.py b/client/ayon_core/tools/tray/structures.py similarity index 100% rename from client/ayon_core/tools/tray/webserver/structures.py rename to client/ayon_core/tools/tray/structures.py diff --git a/client/ayon_core/tools/tray/webserver/__init__.py b/client/ayon_core/tools/tray/webserver/__init__.py index 93bfbd6aee..c40b5b85c3 100644 --- a/client/ayon_core/tools/tray/webserver/__init__.py +++ b/client/ayon_core/tools/tray/webserver/__init__.py @@ -1,10 +1,8 @@ -from .structures import HostMsgAction from .base_routes import RestApiEndpoint from .server import find_free_port, WebServerManager __all__ = ( - "HostMsgAction", "RestApiEndpoint", "find_free_port", "WebServerManager", From 5bf69857378cb1fe653be7fbb774f543ca8d78a6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:33:04 +0200 Subject: [PATCH 13/15] implemented helper function 'make_sure_tray_is_running' to run tray --- client/ayon_core/tools/tray/__init__.py | 2 ++ client/ayon_core/tools/tray/lib.py | 40 ++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/tray/__init__.py b/client/ayon_core/tools/tray/__init__.py index 2490122358..2e179f0620 100644 --- a/client/ayon_core/tools/tray/__init__.py +++ b/client/ayon_core/tools/tray/__init__.py @@ -4,6 +4,7 @@ from .lib import ( get_tray_state, is_tray_running, get_tray_server_url, + make_sure_tray_is_running, main, ) @@ -15,5 +16,6 @@ __all__ = ( "get_tray_state", "is_tray_running", "get_tray_server_url", + "make_sure_tray_is_running", "main", ) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 76cf20d3b4..5018dc6620 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -13,7 +13,7 @@ from typing import Optional, Dict, Tuple, Any import ayon_api import requests -from ayon_core.lib import Logger +from ayon_core.lib import Logger, get_ayon_launcher_args, run_detached_process from ayon_core.lib.local_settings import get_ayon_appdirs @@ -356,6 +356,44 @@ def is_tray_running( return state != TrayState.NOT_RUNNING +def make_sure_tray_is_running( + ayon_url: Optional[str] = None, + variant: Optional[str] = None, + env: Optional[Dict[str, str]] = None +): + """Make sure that tray for AYON url and variant is running. + + Args: + ayon_url (Optional[str]): AYON server url. + variant (Optional[str]): Settings variant. + env (Optional[Dict[str, str]]): Environment variables for the process. + + """ + state = get_tray_state(ayon_url, variant) + if state == TrayState.RUNNING: + return + + if state == TrayState.STARTING: + _wait_for_starting_tray(ayon_url, variant) + state = get_tray_state(ayon_url, variant) + if state == TrayState.RUNNING: + return + + args = get_ayon_launcher_args("tray", "--force") + if env is None: + env = os.environ.copy() + + if ayon_url: + env["AYON_SERVER_URL"] = ayon_url + + # TODO maybe handle variant in a better way + if variant: + if variant == "staging": + args.append("--use-staging") + + run_detached_process(args, env=env) + + def main(force=False): from ayon_core.tools.tray.ui import main From adc55dee1a844575c3bf8cc46fd4e3ca26174067 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:38:52 +0200 Subject: [PATCH 14/15] unset QT_API --- client/ayon_core/tools/tray/lib.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 5018dc6620..c26f4835b1 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -382,6 +382,9 @@ def make_sure_tray_is_running( args = get_ayon_launcher_args("tray", "--force") if env is None: env = os.environ.copy() + + # Make sure 'QT_API' is not set + env.pop("QT_API", None) if ayon_url: env["AYON_SERVER_URL"] = ayon_url From 1d23d076fc49fc4c56bf63a5cb0dc4e4f6b2348a Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:40:46 +0200 Subject: [PATCH 15/15] fix import in broker --- client/ayon_core/tools/stdout_broker/broker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/stdout_broker/broker.py b/client/ayon_core/tools/stdout_broker/broker.py index 4f7118e2a8..c449fa7df9 100644 --- a/client/ayon_core/tools/stdout_broker/broker.py +++ b/client/ayon_core/tools/stdout_broker/broker.py @@ -8,7 +8,7 @@ from datetime import datetime import websocket from ayon_core.lib import Logger -from ayon_core.tools.tray.webserver import HostMsgAction +from ayon_core.tools.tray import HostMsgAction log = Logger.get_logger(__name__)