From 165b5b0b0bb335511d70d68e8db4f2b6b8d4679b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20LORRAIN?= Date: Mon, 13 Dec 2021 11:59:43 +0100 Subject: [PATCH 01/18] Add zero padding to otio burnins --- openpype/scripts/otio_burnin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/scripts/otio_burnin.py b/openpype/scripts/otio_burnin.py index 68f4728bc7..156550aab1 100644 --- a/openpype/scripts/otio_burnin.py +++ b/openpype/scripts/otio_burnin.py @@ -342,7 +342,8 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): if frame_start is None: replacement_final = replacement_size = str(MISSING_KEY_VALUE) else: - replacement_final = "%{eif:n+" + str(frame_start) + ":d}" + replacement_final = "%{eif:n+" + str(frame_start) + ":d:" + \ + str(len(str(frame_end))) + "}" replacement_size = str(frame_end) final_text = final_text.replace( From 9ec197acdaf7d064842214bd4540e8dec261ddc0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:53:35 +0100 Subject: [PATCH 02/18] added method get_timer_data_for_context to be able get timers related data for passed context --- .../timers_manager/timers_manager.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 0f165ff0ac..6541a9197c 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -151,6 +151,44 @@ class TimersManager(OpenPypeModule, ITrayService): self._idle_manager.stop() self._idle_manager.wait() + def get_timer_data_for_context(self, project_name, asset_name, task_name): + """Prepare data for timer related callbacks.""" + dbconn = AvalonMongoDB() + dbconn.install() + dbconn.Session["AVALON_PROJECT"] = project_name + + asset_doc = dbconn.find_one( + { + "type": "asset", + "name": asset_name + }, + { + "data.tasks": True, + "data.parents": True + } + ) + if not asset_doc: + raise ValueError("Uknown asset {}".format(asset_name)) + + asset_data = asset_doc.get("data") or {} + task_type = "" + try: + task_type = asset_data["tasks"][task_name]["type"] + except KeyError: + self.log.warning( + "Couldn't find task_type for {}".format(task_name) + ) + + hierarchy_items = asset_data.get("parents") or [] + hierarchy_items.append(asset_name) + + return { + "project_name": project_name, + "task_name": task_name, + "task_type": task_type, + "hierarchy": hierarchy_items + } + def start_timer(self, project_name, asset_name, task_name, hierarchy): """ Start timer for 'project_name', 'asset_name' and 'task_name' From 246bf8f1403cb9bc40cab5498eddb85f771cabe6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:54:16 +0100 Subject: [PATCH 03/18] use get_timer_data_for_context in start_timer and don't expect hierarchy --- .../timers_manager/rest_api.py | 15 +++--- .../timers_manager/timers_manager.py | 47 ++++--------------- 2 files changed, 18 insertions(+), 44 deletions(-) diff --git a/openpype/modules/default_modules/timers_manager/rest_api.py b/openpype/modules/default_modules/timers_manager/rest_api.py index 19b72d688b..4296610c23 100644 --- a/openpype/modules/default_modules/timers_manager/rest_api.py +++ b/openpype/modules/default_modules/timers_manager/rest_api.py @@ -39,17 +39,18 @@ class TimersManagerModuleRestApi: async def start_timer(self, request): data = await request.json() try: - project_name = data['project_name'] - asset_name = data['asset_name'] - task_name = data['task_name'] - hierarchy = data['hierarchy'] + project_name = data["project_name"] + asset_name = data["asset_name"] + task_name = data["task_name"] except KeyError: - log.error("Payload must contain fields 'project_name, " + - "'asset_name', 'task_name', 'hierarchy'") + log.error(( + "Payload must contain fields 'project_name," + " 'asset_name' and 'task_name'" + )) return Response(status=400) self.module.stop_timers() - self.module.start_timer(project_name, asset_name, task_name, hierarchy) + self.module.start_timer(project_name, asset_name, task_name) return Response(status=200) async def stop_timer(self, request): diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 6541a9197c..fc9897b022 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -189,44 +189,17 @@ class TimersManager(OpenPypeModule, ITrayService): "hierarchy": hierarchy_items } - def start_timer(self, project_name, asset_name, task_name, hierarchy): + def start_timer(self, project_name, asset_name, task_name): + """Start timer for passed context. + + Args: + project_name (str): Project name + asset_name (str): Asset name + task_name (str): Task name """ - Start timer for 'project_name', 'asset_name' and 'task_name' - - Called from REST api by hosts. - - Args: - project_name (string) - asset_name (string) - task_name (string) - hierarchy (string) - """ - dbconn = AvalonMongoDB() - dbconn.install() - dbconn.Session["AVALON_PROJECT"] = project_name - - asset_doc = dbconn.find_one({ - "type": "asset", "name": asset_name - }) - if not asset_doc: - raise ValueError("Uknown asset {}".format(asset_name)) - - task_type = '' - try: - task_type = asset_doc["data"]["tasks"][task_name]["type"] - except KeyError: - self.log.warning("Couldn't find task_type for {}". - format(task_name)) - - hierarchy = hierarchy.split("\\") - hierarchy.append(asset_name) - - data = { - "project_name": project_name, - "task_name": task_name, - "task_type": task_type, - "hierarchy": hierarchy - } + data = self.get_timer_data_for_context( + project_name, asset_name, task_name + ) self.timer_started(None, data) def get_task_time(self, project_name, asset_name, task_name): From 83887b918a507d7a7ffce528c39f6c0ac7227415 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:55:05 +0100 Subject: [PATCH 04/18] changed 'change_timer_from_host' to static method 'start_timer_with_webserver' --- .../timers_manager/timers_manager.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index fc9897b022..8aa8e18902 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -306,18 +306,29 @@ class TimersManager(OpenPypeModule, ITrayService): self, server_manager ) - def change_timer_from_host(self, project_name, asset_name, task_name): + @staticmethod + def start_timer_with_webserver( + project_name, asset_name, task_name, logger=None + ): """Prepared method for calling change timers on REST api""" webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL") if not webserver_url: - self.log.warning("Couldn't find webserver url") + msg = "Couldn't find webserver url" + if logger is not None: + logger.warning(msg) + else: + print(msg) return rest_api_url = "{}/timers_manager/start_timer".format(webserver_url) try: import requests except Exception: - self.log.warning("Couldn't start timer") + msg = "Couldn't start timer ('requests' is not available)" + if logger is not None: + logger.warning(msg) + else: + print(msg) return data = { "project_name": project_name, From fb096d0f68b3dc3171b6f9f0802d51d542b89bb2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:56:09 +0100 Subject: [PATCH 05/18] don't pass hierarchy in lib function --- openpype/lib/avalon_context.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index e3bceff275..cb5bca133d 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -1433,7 +1433,11 @@ def get_creator_by_name(creator_name, case_sensitive=False): @with_avalon def change_timer_to_current_context(): - """Called after context change to change timers""" + """Called after context change to change timers. + + TODO: + - use TimersManager's static method instead of reimplementing it here + """ webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL") if not webserver_url: log.warning("Couldn't find webserver url") @@ -1448,8 +1452,7 @@ def change_timer_to_current_context(): data = { "project_name": avalon.io.Session["AVALON_PROJECT"], "asset_name": avalon.io.Session["AVALON_ASSET"], - "task_name": avalon.io.Session["AVALON_TASK"], - "hierarchy": get_hierarchy() + "task_name": avalon.io.Session["AVALON_TASK"] } requests.post(rest_api_url, json=data) From c777bc8afcfebac4009ee2d9ab77e9558c8f3483 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:56:31 +0100 Subject: [PATCH 06/18] application launch context nad launch hooks have access to modules manager --- openpype/lib/applications.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index 6eb44a9694..184a57ea89 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -640,6 +640,10 @@ class LaunchHook: def app_name(self): return getattr(self.application, "full_name", None) + @property + def modules_manager(self): + return getattr(self.launch_context, "modules_manager", None) + def validate(self): """Optional validation of launch hook on initialization. @@ -702,9 +706,13 @@ class ApplicationLaunchContext: """ def __init__(self, application, executable, **data): + from openpype.modules import ModulesManager + # Application object self.application = application + self.modules_manager = ModulesManager() + # Logger logger_name = "{}-{}".format(self.__class__.__name__, self.app_name) self.log = PypeLogger.get_logger(logger_name) @@ -812,10 +820,7 @@ class ApplicationLaunchContext: paths.append(path) # Load modules paths - from openpype.modules import ModulesManager - - manager = ModulesManager() - paths.extend(manager.collect_launch_hook_paths()) + paths.extend(self.modules_manager.collect_launch_hook_paths()) return paths From 272f4fcc67f5f6ea9d3dffb4eb97b57848389bd5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:56:59 +0100 Subject: [PATCH 07/18] added new post launch hook that will trigger start timer using timers manager --- openpype/hooks/post_start_timer.py | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 openpype/hooks/post_start_timer.py diff --git a/openpype/hooks/post_start_timer.py b/openpype/hooks/post_start_timer.py new file mode 100644 index 0000000000..be2cec82b7 --- /dev/null +++ b/openpype/hooks/post_start_timer.py @@ -0,0 +1,48 @@ +import os + +from openpype.api import get_project_settings +from openpype.lib import PostLaunchHook + + +class PostStartTimerHook(PostLaunchHook): + """Start timer with TimersManager module. + + This module requires enabled TimerManager module. + """ + order = None + + def execute(self): + project_name = self.data.get("project_name") + asset_name = self.data.get("asset_name") + task_name = self.data.get("task_name") + + missing_context_keys = set() + if not project_name: + missing_context_keys.add("project_name") + if not asset_name: + missing_context_keys.add("asset_name") + if not task_name: + missing_context_keys.add("task_name") + + if missing_context_keys: + missing_keys_str = ", ".join([ + "\"{}\"".format(key) for key in missing_context_keys + ]) + self.log.debug("Hook {} skipped. Missing data keys: {}".format( + self.__class__.__name__, missing_keys_str + )) + return + + timers_manager = self.modules_manager.modules_by_name.get( + "timers_manager" + ) + if not timers_manager or not timers_manager.enabled: + self.log.info(( + "Skipping starting timer because" + " TimersManager is not available." + )) + return + + timers_manager.start_timer_with_webserver( + project_name, asset_name, task_name, logger=self.log + ) From def385836b88a3626e09fb338121ed5223695572 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 16:57:13 +0100 Subject: [PATCH 08/18] removed start timer in ftrack's post launch hook --- .../launch_hooks/post_ftrack_changes.py | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/openpype/modules/default_modules/ftrack/launch_hooks/post_ftrack_changes.py b/openpype/modules/default_modules/ftrack/launch_hooks/post_ftrack_changes.py index df16cde2b8..d5a95fad91 100644 --- a/openpype/modules/default_modules/ftrack/launch_hooks/post_ftrack_changes.py +++ b/openpype/modules/default_modules/ftrack/launch_hooks/post_ftrack_changes.py @@ -52,7 +52,7 @@ class PostFtrackHook(PostLaunchHook): ) if entity: self.ftrack_status_change(session, entity, project_name) - self.start_timer(session, entity, ftrack_api) + except Exception: self.log.warning( "Couldn't finish Ftrack procedure.", exc_info=True @@ -160,26 +160,3 @@ class PostFtrackHook(PostLaunchHook): " on Ftrack entity type \"{}\"" ).format(next_status_name, entity.entity_type) self.log.warning(msg) - - def start_timer(self, session, entity, _ftrack_api): - """Start Ftrack timer on task from context.""" - self.log.debug("Triggering timer start.") - - user_entity = session.query("User where username is \"{}\"".format( - os.environ["FTRACK_API_USER"] - )).first() - if not user_entity: - self.log.warning( - "Couldn't find user with username \"{}\" in Ftrack".format( - os.environ["FTRACK_API_USER"] - ) - ) - return - - try: - user_entity.start_timer(entity, force=True) - session.commit() - self.log.debug("Timer start triggered successfully.") - - except Exception: - self.log.warning("Couldn't trigger Ftrack timer.", exc_info=True) From 5528f064130663dda83bce12cc60a906f9c54733 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 17:05:19 +0100 Subject: [PATCH 09/18] added few docstrings --- .../timers_manager/timers_manager.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 8aa8e18902..5fffb24a5e 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -152,7 +152,11 @@ class TimersManager(OpenPypeModule, ITrayService): self._idle_manager.wait() def get_timer_data_for_context(self, project_name, asset_name, task_name): - """Prepare data for timer related callbacks.""" + """Prepare data for timer related callbacks. + + TODO: + - return predefined object that has access to asset document etc. + """ dbconn = AvalonMongoDB() dbconn.install() dbconn.Session["AVALON_PROJECT"] = project_name @@ -203,6 +207,11 @@ class TimersManager(OpenPypeModule, ITrayService): self.timer_started(None, data) def get_task_time(self, project_name, asset_name, task_name): + """Get total time for passed context. + + TODO: + - convert context to timer data + """ times = {} for module_id, connector in self._connectors_by_module_id.items(): if hasattr(connector, "get_task_time"): @@ -213,6 +222,10 @@ class TimersManager(OpenPypeModule, ITrayService): return times def timer_started(self, source_id, data): + """Connector triggered that timer has started. + + New timer has started for context in data. + """ for module_id, connector in self._connectors_by_module_id.items(): if module_id == source_id: continue @@ -230,6 +243,14 @@ class TimersManager(OpenPypeModule, ITrayService): self.is_running = True def timer_stopped(self, source_id): + """Connector triggered that hist timer has stopped. + + Should stop all other timers. + + TODO: + - pass context for which timer has stopped to validate if timers are + same and valid + """ for module_id, connector in self._connectors_by_module_id.items(): if module_id == source_id: continue @@ -248,6 +269,7 @@ class TimersManager(OpenPypeModule, ITrayService): self.timer_started(None, self.last_task) def stop_timers(self): + """Stop all timers.""" if self.is_running is False: return From 1984f9d8b484f1f37beb4ae9abf1b62448d36df8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 17:05:42 +0100 Subject: [PATCH 10/18] added helper method for future use --- .../timers_manager/timers_manager.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 5fffb24a5e..7c8ad25529 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -151,6 +151,22 @@ class TimersManager(OpenPypeModule, ITrayService): self._idle_manager.stop() self._idle_manager.wait() + def get_timer_data_for_path(self, task_path): + """Convert string path to a timer data. + + It is expected that first item is project name, last item is task name + and parent asset name is before task name. + """ + path_items = task_path.split("/") + if len(path_items) < 3: + raise ValueError("Invalid path") + task_name = path_items.pop(-1) + asset_name = path_items.pop(-1) + project_name = path_items.pop(0) + return self.get_timer_data_for_context( + project_name, asset_name, task_name + ) + def get_timer_data_for_context(self, project_name, asset_name, task_name): """Prepare data for timer related callbacks. From f4aa2d17b25b748ba9523c246e2fe86989af77bd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 17:12:04 +0100 Subject: [PATCH 11/18] added few lines of docstring --- .../timers_manager/timers_manager.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 7c8ad25529..0ae0af4cdb 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -348,7 +348,18 @@ class TimersManager(OpenPypeModule, ITrayService): def start_timer_with_webserver( project_name, asset_name, task_name, logger=None ): - """Prepared method for calling change timers on REST api""" + """Prepared method for calling change timers on REST api. + + Webserver must be active. At the moment is Webserver running only when + OpenPype Tray is used. + + Args: + project_name (str): Project name. + asset_name (str): Asset name. + task_name (str): Task name. + logger (logging.Logger): Logger object. Using 'print' if not + passed. + """ webserver_url = os.environ.get("OPENPYPE_WEBSERVER_URL") if not webserver_url: msg = "Couldn't find webserver url" From d4112eb3fafbaf2c817d7771c12e40b36701f2a0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 16 Dec 2021 17:15:27 +0100 Subject: [PATCH 12/18] moved the launch hook into timers manager --- .../launch_hooks}/post_start_timer.py | 3 --- .../timers_manager/timers_manager.py | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) rename openpype/{hooks => modules/default_modules/timers_manager/launch_hooks}/post_start_timer.py (96%) diff --git a/openpype/hooks/post_start_timer.py b/openpype/modules/default_modules/timers_manager/launch_hooks/post_start_timer.py similarity index 96% rename from openpype/hooks/post_start_timer.py rename to openpype/modules/default_modules/timers_manager/launch_hooks/post_start_timer.py index be2cec82b7..d6ae013403 100644 --- a/openpype/hooks/post_start_timer.py +++ b/openpype/modules/default_modules/timers_manager/launch_hooks/post_start_timer.py @@ -1,6 +1,3 @@ -import os - -from openpype.api import get_project_settings from openpype.lib import PostLaunchHook diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 0ae0af4cdb..964e6d9a58 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -1,7 +1,10 @@ import os import platform from openpype.modules import OpenPypeModule -from openpype_interfaces import ITrayService +from openpype_interfaces import ( + ITrayService, + ILaunchHookPaths +) from avalon.api import AvalonMongoDB @@ -64,7 +67,7 @@ class ExampleTimersManagerConnector: self._timers_manager_module.timer_stopped(self._module.id) -class TimersManager(OpenPypeModule, ITrayService): +class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): """ Handles about Timers. Should be able to start/stop all timers at once. @@ -167,6 +170,13 @@ class TimersManager(OpenPypeModule, ITrayService): project_name, asset_name, task_name ) + def get_launch_hook_paths(self): + """Implementation of `ILaunchHookPaths`.""" + return os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "launch_hooks" + ) + def get_timer_data_for_context(self, project_name, asset_name, task_name): """Prepare data for timer related callbacks. From db4dc04d8f5f8052c9e98c2c4212748ad52b4aed Mon Sep 17 00:00:00 2001 From: OpenPype Date: Sat, 18 Dec 2021 03:42:07 +0000 Subject: [PATCH 13/18] [Automated] Bump version --- CHANGELOG.md | 26 ++++++++------------------ openpype/version.py | 2 +- pyproject.toml | 2 +- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dde8138629..1eb8455a09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [3.7.0-nightly.8](https://github.com/pypeclub/OpenPype/tree/HEAD) +## [3.7.0-nightly.9](https://github.com/pypeclub/OpenPype/tree/HEAD) [Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.6.4...HEAD) @@ -14,6 +14,8 @@ **🚀 Enhancements** +- Settings UI: Hyperlinks to settings [\#2420](https://github.com/pypeclub/OpenPype/pull/2420) +- Modules: JobQueue module moved one hierarchy level higher [\#2419](https://github.com/pypeclub/OpenPype/pull/2419) - Ftrack: Check existence of object type on recreation [\#2404](https://github.com/pypeclub/OpenPype/pull/2404) - Flame: moving `utility\_scripts` to api folder also with `scripts` [\#2385](https://github.com/pypeclub/OpenPype/pull/2385) - Centos 7 dependency compatibility [\#2384](https://github.com/pypeclub/OpenPype/pull/2384) @@ -29,13 +31,14 @@ - General: OpenPype default modules hierarchy [\#2338](https://github.com/pypeclub/OpenPype/pull/2338) - General: FFprobe error exception contain original error message [\#2328](https://github.com/pypeclub/OpenPype/pull/2328) - Resolve: Add experimental button to menu [\#2325](https://github.com/pypeclub/OpenPype/pull/2325) -- Input links: Cleanup and unification of differences [\#2322](https://github.com/pypeclub/OpenPype/pull/2322) -- General: Don't validate vendor bin with executing them [\#2317](https://github.com/pypeclub/OpenPype/pull/2317) -- General: Multilayer EXRs support [\#2315](https://github.com/pypeclub/OpenPype/pull/2315) - General: Reduce vendor imports [\#2305](https://github.com/pypeclub/OpenPype/pull/2305) +- Ftrack: Synchronize input links [\#2287](https://github.com/pypeclub/OpenPype/pull/2287) **🐛 Bug fixes** +- PS: Introduced settings for invalid characters to use in ValidateNaming plugin [\#2417](https://github.com/pypeclub/OpenPype/pull/2417) +- Settings UI: Breadcrumbs path does not create new entities [\#2416](https://github.com/pypeclub/OpenPype/pull/2416) +- AfterEffects: Variant 2022 is in defaults but missing in schemas [\#2412](https://github.com/pypeclub/OpenPype/pull/2412) - General: Fix access to environments from default settings [\#2403](https://github.com/pypeclub/OpenPype/pull/2403) - Fix: Placeholder Input color set fix [\#2399](https://github.com/pypeclub/OpenPype/pull/2399) - Settings: Fix state change of wrapper label [\#2396](https://github.com/pypeclub/OpenPype/pull/2396) @@ -55,8 +58,7 @@ - Tools: Use Qt context on tools show [\#2340](https://github.com/pypeclub/OpenPype/pull/2340) - Flame: Fix default argument value in custom dictionary [\#2339](https://github.com/pypeclub/OpenPype/pull/2339) - Timers Manager: Disable auto stop timer on linux platform [\#2334](https://github.com/pypeclub/OpenPype/pull/2334) -- nuke: bake preset single input exception [\#2331](https://github.com/pypeclub/OpenPype/pull/2331) -- Hiero: fixing multiple templates at a hierarchy parent [\#2330](https://github.com/pypeclub/OpenPype/pull/2330) +- Fix - provider icons are pulled from a folder [\#2326](https://github.com/pypeclub/OpenPype/pull/2326) - Royal Render: Fix plugin order and OpenPype auto-detection [\#2291](https://github.com/pypeclub/OpenPype/pull/2291) **Merged pull requests:** @@ -66,7 +68,6 @@ - Linux : flip updating submodules logic [\#2357](https://github.com/pypeclub/OpenPype/pull/2357) - Update of avalon-core [\#2346](https://github.com/pypeclub/OpenPype/pull/2346) - Maya: configurable model top level validation [\#2321](https://github.com/pypeclub/OpenPype/pull/2321) -- Create test publish class for After Effects [\#2270](https://github.com/pypeclub/OpenPype/pull/2270) ## [3.6.4](https://github.com/pypeclub/OpenPype/tree/3.6.4) (2021-11-23) @@ -88,17 +89,6 @@ [Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.6.2-nightly.2...3.6.2) -**🚀 Enhancements** - -- Tools: Assets widget [\#2265](https://github.com/pypeclub/OpenPype/pull/2265) -- SceneInventory: Choose loader in asset switcher [\#2262](https://github.com/pypeclub/OpenPype/pull/2262) - -**🐛 Bug fixes** - -- Tools: Parenting of tools in Nuke and Hiero [\#2266](https://github.com/pypeclub/OpenPype/pull/2266) -- limiting validator to specific editorial hosts [\#2264](https://github.com/pypeclub/OpenPype/pull/2264) -- Tools: Select Context dialog attribute fix [\#2261](https://github.com/pypeclub/OpenPype/pull/2261) - ## [3.6.1](https://github.com/pypeclub/OpenPype/tree/3.6.1) (2021-11-16) [Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.6.1-nightly.1...3.6.1) diff --git a/openpype/version.py b/openpype/version.py index 06bc20ae43..544160d41c 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.7.0-nightly.8" +__version__ = "3.7.0-nightly.9" diff --git a/pyproject.toml b/pyproject.toml index e5d552bb3b..07a9ac8e43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "OpenPype" -version = "3.7.0-nightly.8" # OpenPype +version = "3.7.0-nightly.9" # OpenPype description = "Open VFX and Animation pipeline with support." authors = ["OpenPype Team "] license = "MIT License" From 5a194263fde0b9821d29479a26d92c0d5c3fe510 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Dec 2021 13:10:17 +0100 Subject: [PATCH 14/18] get_timer_data_for_context is static method --- .../timers_manager/timers_manager.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 964e6d9a58..11e1821912 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -167,7 +167,7 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): asset_name = path_items.pop(-1) project_name = path_items.pop(0) return self.get_timer_data_for_context( - project_name, asset_name, task_name + project_name, asset_name, task_name, self.log ) def get_launch_hook_paths(self): @@ -177,7 +177,10 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): "launch_hooks" ) - def get_timer_data_for_context(self, project_name, asset_name, task_name): + @staticmethod + def get_timer_data_for_context( + project_name, asset_name, task_name, logger=None + ): """Prepare data for timer related callbacks. TODO: @@ -205,9 +208,11 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): try: task_type = asset_data["tasks"][task_name]["type"] except KeyError: - self.log.warning( - "Couldn't find task_type for {}".format(task_name) - ) + msg = "Couldn't find task_type for {}".format(task_name) + if logger is not None: + logger.warning(msg) + else: + print(msg) hierarchy_items = asset_data.get("parents") or [] hierarchy_items.append(asset_name) @@ -228,7 +233,7 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): task_name (str): Task name """ data = self.get_timer_data_for_context( - project_name, asset_name, task_name + project_name, asset_name, task_name, self.log ) self.timer_started(None, data) From 03ba413b282e1ce8b4c2d63a2371617d16c0592a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Dec 2021 13:13:10 +0100 Subject: [PATCH 15/18] adde new exception --- openpype/modules/default_modules/timers_manager/exceptions.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 openpype/modules/default_modules/timers_manager/exceptions.py diff --git a/openpype/modules/default_modules/timers_manager/exceptions.py b/openpype/modules/default_modules/timers_manager/exceptions.py new file mode 100644 index 0000000000..5a9e00765d --- /dev/null +++ b/openpype/modules/default_modules/timers_manager/exceptions.py @@ -0,0 +1,3 @@ +class InvalidContextError(ValueError): + """Context for which the timer should be started is invalid.""" + pass From 3bb3211d4a63d6a93666e6c854f3f2d068fbe5e2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Dec 2021 13:13:42 +0100 Subject: [PATCH 16/18] raise InvalidContextError if context is not valid --- .../timers_manager/timers_manager.py | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 11e1821912..051b2d7c80 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -1,11 +1,14 @@ import os import platform + +from avalon.api import AvalonMongoDB + from openpype.modules import OpenPypeModule from openpype_interfaces import ( ITrayService, ILaunchHookPaths ) -from avalon.api import AvalonMongoDB +from .exceptions import InvalidContextError class ExampleTimersManagerConnector: @@ -162,7 +165,7 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): """ path_items = task_path.split("/") if len(path_items) < 3: - raise ValueError("Invalid path") + raise InvalidContextError("Invalid path \"{}\"".format(task_path)) task_name = path_items.pop(-1) asset_name = path_items.pop(-1) project_name = path_items.pop(0) @@ -186,6 +189,12 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): TODO: - return predefined object that has access to asset document etc. """ + if not project_name or not asset_name or not task_name: + raise InvalidContextError(( + "Missing context information got" + " Project: \"{}\" Asset: \"{}\" Task: \"{}\"" + ).format(str(project_name), str(asset_name), str(task_name))) + dbconn = AvalonMongoDB() dbconn.install() dbconn.Session["AVALON_PROJECT"] = project_name @@ -201,12 +210,22 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): } ) if not asset_doc: - raise ValueError("Uknown asset {}".format(asset_name)) + dbconn.uninstall() + raise InvalidContextError(( + "Asset \"{}\" not found in project \"{}\"" + ).format(asset_name, project_name)) asset_data = asset_doc.get("data") or {} + asset_tasks = asset_data.get("tasks") or {} + if task_name not in asset_tasks: + dbconn.uninstall() + raise InvalidContextError(( + "Task \"{}\" not found on asset \"{}\" in project \"{}\"" + ).format(task_name, asset_name, project_name)) + task_type = "" try: - task_type = asset_data["tasks"][task_name]["type"] + task_type = asset_tasks[task_name]["type"] except KeyError: msg = "Couldn't find task_type for {}".format(task_name) if logger is not None: @@ -217,6 +236,7 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): hierarchy_items = asset_data.get("parents") or [] hierarchy_items.append(asset_name) + dbconn.uninstall() return { "project_name": project_name, "task_name": task_name, From ddcdff611e55ed6dadfccf598ca882a70c56cdf2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Dec 2021 13:14:18 +0100 Subject: [PATCH 17/18] return error message in response --- .../default_modules/timers_manager/rest_api.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/openpype/modules/default_modules/timers_manager/rest_api.py b/openpype/modules/default_modules/timers_manager/rest_api.py index 4296610c23..f16cb316c3 100644 --- a/openpype/modules/default_modules/timers_manager/rest_api.py +++ b/openpype/modules/default_modules/timers_manager/rest_api.py @@ -43,14 +43,19 @@ class TimersManagerModuleRestApi: asset_name = data["asset_name"] task_name = data["task_name"] except KeyError: - log.error(( + msg = ( "Payload must contain fields 'project_name," " 'asset_name' and 'task_name'" - )) - return Response(status=400) + ) + log.error(msg) + return Response(status=400, message=msg) self.module.stop_timers() - self.module.start_timer(project_name, asset_name, task_name) + try: + self.module.start_timer(project_name, asset_name, task_name) + except Exception as exc: + return Response(status=404, message=str(exc)) + return Response(status=200) async def stop_timer(self, request): From 9605abfb13f64356aa382ef3e4ec0182345a1cae Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Dec 2021 13:14:54 +0100 Subject: [PATCH 18/18] return response from posted request --- .../modules/default_modules/timers_manager/timers_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/default_modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py index 051b2d7c80..47d020104b 100644 --- a/openpype/modules/default_modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -420,4 +420,4 @@ class TimersManager(OpenPypeModule, ITrayService, ILaunchHookPaths): "task_name": task_name } - requests.post(rest_api_url, json=data) + return requests.post(rest_api_url, json=data)