diff --git a/.gitmodules b/.gitmodules index 52f2fc0750..82fd194d26 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,9 @@ [submodule "repos/avalon-unreal-integration"] path = repos/avalon-unreal-integration url = https://github.com/pypeclub/avalon-unreal-integration.git -[submodule "openpype/modules/ftrack/python2_vendor/ftrack-python-api"] - path = openpype/modules/ftrack/python2_vendor/ftrack-python-api +[submodule "openpype/modules/default_modules/ftrack/python2_vendor/arrow"] + path = openpype/modules/default_modules/ftrack/python2_vendor/arrow + url = git@github.com:arrow-py/arrow.git +[submodule "openpype/modules/default_modules/ftrack/python2_vendor/ftrack-python-api"] + path = openpype/modules/default_modules/ftrack/python2_vendor/ftrack-python-api url = https://bitbucket.org/ftrack/ftrack-python-api.git -[submodule "openpype/modules/ftrack/python2_vendor/arrow"] - path = openpype/modules/ftrack/python2_vendor/arrow - url = https://github.com/arrow-py/arrow.git \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f25a1b63d..5c55be842a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,91 +1,91 @@ # Changelog -## [3.3.0-nightly.10](https://github.com/pypeclub/OpenPype/tree/HEAD) +## [3.4.0-nightly.2](https://github.com/pypeclub/OpenPype/tree/HEAD) -[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.2.0...HEAD) +[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.3.1...HEAD) -**πŸš€ Enhancements** +**Merged pull requests:** +- Maya: Add Xgen family support [\#1947](https://github.com/pypeclub/OpenPype/pull/1947) +- Add face sets to exported alembics [\#1942](https://github.com/pypeclub/OpenPype/pull/1942) +- Environments: Tool environments in alphabetical order [\#1910](https://github.com/pypeclub/OpenPype/pull/1910) +- Dynamic modules [\#1872](https://github.com/pypeclub/OpenPype/pull/1872) + +## [3.3.1](https://github.com/pypeclub/OpenPype/tree/3.3.1) (2021-08-20) + +[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.3.1-nightly.1...3.3.1) + +**Merged pull requests:** + +- TVPaint: Fixed rendered frame indexes [\#1946](https://github.com/pypeclub/OpenPype/pull/1946) +- Maya: Menu actions fix [\#1945](https://github.com/pypeclub/OpenPype/pull/1945) +- standalone: editorial shared object problem [\#1941](https://github.com/pypeclub/OpenPype/pull/1941) +- Bugfix nuke deadline app name [\#1928](https://github.com/pypeclub/OpenPype/pull/1928) + +## [3.3.0](https://github.com/pypeclub/OpenPype/tree/3.3.0) (2021-08-17) + +[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.3.0-nightly.11...3.3.0) + +**Merged pull requests:** + +- Python console interpreter [\#1940](https://github.com/pypeclub/OpenPype/pull/1940) +- Fix - make AE workfile publish to Ftrack configurable [\#1937](https://github.com/pypeclub/OpenPype/pull/1937) +- Fix - ftrack family was added incorrectly in some cases [\#1935](https://github.com/pypeclub/OpenPype/pull/1935) +- Settings UI: Breadcrumbs in settings [\#1932](https://github.com/pypeclub/OpenPype/pull/1932) +- Fix - Deadline publish on Linux started Tray instead of headless publishing [\#1930](https://github.com/pypeclub/OpenPype/pull/1930) +- Maya: Validate Model Name - repair accident deletion in settings defaults [\#1929](https://github.com/pypeclub/OpenPype/pull/1929) - Global: Updated logos and Default settings [\#1927](https://github.com/pypeclub/OpenPype/pull/1927) +- Nuke: submit to farm failed due `ftrack` family remove [\#1926](https://github.com/pypeclub/OpenPype/pull/1926) - Check for missing ✨ Python when using `pyenv` [\#1925](https://github.com/pypeclub/OpenPype/pull/1925) - Maya: Scene patching 🩹on submission to Deadline [\#1923](https://github.com/pypeclub/OpenPype/pull/1923) +- Fix - validate takes repre\["files"\] as list all the time [\#1922](https://github.com/pypeclub/OpenPype/pull/1922) - Settings: Default values for enum [\#1920](https://github.com/pypeclub/OpenPype/pull/1920) - Settings UI: Modifiable dict view enhance [\#1919](https://github.com/pypeclub/OpenPype/pull/1919) +- standalone: validator asset parents [\#1917](https://github.com/pypeclub/OpenPype/pull/1917) +- Nuke: update video file crassing [\#1916](https://github.com/pypeclub/OpenPype/pull/1916) +- Fix - texture validators for workfiles triggers only for textures workfiles [\#1914](https://github.com/pypeclub/OpenPype/pull/1914) - submodules: avalon-core update [\#1911](https://github.com/pypeclub/OpenPype/pull/1911) +- Settings UI: List order works as expected [\#1906](https://github.com/pypeclub/OpenPype/pull/1906) +- Add support for multiple Deadline β˜ οΈβž– servers [\#1905](https://github.com/pypeclub/OpenPype/pull/1905) +- Hiero: loaded clip was not set colorspace from version data [\#1904](https://github.com/pypeclub/OpenPype/pull/1904) +- Pyblish UI: Fix collecting stage processing [\#1903](https://github.com/pypeclub/OpenPype/pull/1903) +- Burnins: Use input's bitrate in h624 [\#1902](https://github.com/pypeclub/OpenPype/pull/1902) - Feature AE local render [\#1901](https://github.com/pypeclub/OpenPype/pull/1901) - Ftrack: Where I run action enhancement [\#1900](https://github.com/pypeclub/OpenPype/pull/1900) - Ftrack: Private project server actions [\#1899](https://github.com/pypeclub/OpenPype/pull/1899) - Support nested studio plugins paths. [\#1898](https://github.com/pypeclub/OpenPype/pull/1898) +- Bug: fixed python detection [\#1893](https://github.com/pypeclub/OpenPype/pull/1893) - Settings: global validators with options [\#1892](https://github.com/pypeclub/OpenPype/pull/1892) - Settings: Conditional dict enum positioning [\#1891](https://github.com/pypeclub/OpenPype/pull/1891) +- global: integrate name missing default template [\#1890](https://github.com/pypeclub/OpenPype/pull/1890) +- publisher: editorial plugins fixes [\#1889](https://github.com/pypeclub/OpenPype/pull/1889) - Expose stop timer through rest api. [\#1886](https://github.com/pypeclub/OpenPype/pull/1886) - TVPaint: Increment workfile [\#1885](https://github.com/pypeclub/OpenPype/pull/1885) - Allow Multiple Notes to run on tasks. [\#1882](https://github.com/pypeclub/OpenPype/pull/1882) +- Normalize path returned from Workfiles. [\#1880](https://github.com/pypeclub/OpenPype/pull/1880) - Prepare for pyside2 [\#1869](https://github.com/pypeclub/OpenPype/pull/1869) - Filter hosts in settings host-enum [\#1868](https://github.com/pypeclub/OpenPype/pull/1868) - Local actions with process identifier [\#1867](https://github.com/pypeclub/OpenPype/pull/1867) - Workfile tool start at host launch support [\#1865](https://github.com/pypeclub/OpenPype/pull/1865) -- Anatomy schema validation [\#1864](https://github.com/pypeclub/OpenPype/pull/1864) -- Ftrack prepare project structure [\#1861](https://github.com/pypeclub/OpenPype/pull/1861) -- Maya: support for configurable `dirmap` πŸ—ΊοΈ [\#1859](https://github.com/pypeclub/OpenPype/pull/1859) -- Independent general environments [\#1853](https://github.com/pypeclub/OpenPype/pull/1853) -- TVPaint Start Frame [\#1844](https://github.com/pypeclub/OpenPype/pull/1844) -- Standalone Publish of textures family [\#1834](https://github.com/pypeclub/OpenPype/pull/1834) -- Settings list can use template or schema as object type [\#1815](https://github.com/pypeclub/OpenPype/pull/1815) - -**πŸ› Bug fixes** - -- Fix - ftrack family was added incorrectly in some cases [\#1935](https://github.com/pypeclub/OpenPype/pull/1935) -- Fix - Deadline publish on Linux started Tray instead of headless publishing [\#1930](https://github.com/pypeclub/OpenPype/pull/1930) -- Maya: Validate Model Name - repair accident deletion in settings defaults [\#1929](https://github.com/pypeclub/OpenPype/pull/1929) -- Nuke: submit to farm failed due `ftrack` family remove [\#1926](https://github.com/pypeclub/OpenPype/pull/1926) -- Fix - validate takes repre\["files"\] as list all the time [\#1922](https://github.com/pypeclub/OpenPype/pull/1922) -- standalone: validator asset parents [\#1917](https://github.com/pypeclub/OpenPype/pull/1917) -- Fix - texture validators for workfiles triggers only for textures workfiles [\#1914](https://github.com/pypeclub/OpenPype/pull/1914) -- Settings UI: List order works as expected [\#1906](https://github.com/pypeclub/OpenPype/pull/1906) -- Hiero: loaded clip was not set colorspace from version data [\#1904](https://github.com/pypeclub/OpenPype/pull/1904) -- Pyblish UI: Fix collecting stage processing [\#1903](https://github.com/pypeclub/OpenPype/pull/1903) -- Burnins: Use input's bitrate in h624 [\#1902](https://github.com/pypeclub/OpenPype/pull/1902) -- Bug: fixed python detection [\#1893](https://github.com/pypeclub/OpenPype/pull/1893) -- global: integrate name missing default template [\#1890](https://github.com/pypeclub/OpenPype/pull/1890) -- publisher: editorial plugins fixes [\#1889](https://github.com/pypeclub/OpenPype/pull/1889) -- Normalize path returned from Workfiles. [\#1880](https://github.com/pypeclub/OpenPype/pull/1880) -- Workfiles tool event arguments fix [\#1862](https://github.com/pypeclub/OpenPype/pull/1862) -- imageio: fix grouping [\#1856](https://github.com/pypeclub/OpenPype/pull/1856) -- Ftrack type error fix in sync to avalon event handler [\#1845](https://github.com/pypeclub/OpenPype/pull/1845) -- Settings error dialog on show [\#1798](https://github.com/pypeclub/OpenPype/pull/1798) - -**Merged pull requests:** - -- Fix - make AE workfile publish to Ftrack configurable [\#1937](https://github.com/pypeclub/OpenPype/pull/1937) -- Settings UI: Breadcrumbs in settings [\#1932](https://github.com/pypeclub/OpenPype/pull/1932) - Maya: add support for `RedshiftNormalMap` node, fix `tx` linear space πŸš€ [\#1863](https://github.com/pypeclub/OpenPype/pull/1863) +- Workfiles tool event arguments fix [\#1862](https://github.com/pypeclub/OpenPype/pull/1862) +- Maya: support for configurable `dirmap` πŸ—ΊοΈ [\#1859](https://github.com/pypeclub/OpenPype/pull/1859) +- Maya: don't add reference members as connections to the container set πŸ“¦ [\#1855](https://github.com/pypeclub/OpenPype/pull/1855) +- Settings list can use template or schema as object type [\#1815](https://github.com/pypeclub/OpenPype/pull/1815) +- Maya: expected files -\> render products βš™οΈ overhaul [\#1812](https://github.com/pypeclub/OpenPype/pull/1812) +- Settings error dialog on show [\#1798](https://github.com/pypeclub/OpenPype/pull/1798) ## [3.2.0](https://github.com/pypeclub/OpenPype/tree/3.2.0) (2021-07-13) [Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.2.0-nightly.7...3.2.0) -**πŸš€ Enhancements** - -- Standalone publisher last project [\#1799](https://github.com/pypeclub/OpenPype/pull/1799) -- Ftrack Multiple notes as server action [\#1795](https://github.com/pypeclub/OpenPype/pull/1795) -- Settings conditional dict [\#1777](https://github.com/pypeclub/OpenPype/pull/1777) -- Settings application use python 2 only where needed [\#1776](https://github.com/pypeclub/OpenPype/pull/1776) - -**πŸ› Bug fixes** - -- nuke: fixing wrong name of family folder when `used existing frames` [\#1803](https://github.com/pypeclub/OpenPype/pull/1803) -- Collect ftrack family bugs [\#1801](https://github.com/pypeclub/OpenPype/pull/1801) -- Invitee email can be None which break the Ftrack commit. [\#1788](https://github.com/pypeclub/OpenPype/pull/1788) -- Fix: staging and `--use-version` option [\#1786](https://github.com/pypeclub/OpenPype/pull/1786) -- Otio unrelated error on import [\#1782](https://github.com/pypeclub/OpenPype/pull/1782) -- FFprobe streams order [\#1775](https://github.com/pypeclub/OpenPype/pull/1775) - **Merged pull requests:** -- PS, AE - send actual context when another webserver is running [\#1811](https://github.com/pypeclub/OpenPype/pull/1811) - Build: don't add Poetry to `PATH` [\#1808](https://github.com/pypeclub/OpenPype/pull/1808) -- Bump prismjs from 1.23.0 to 1.24.0 in /website [\#1773](https://github.com/pypeclub/OpenPype/pull/1773) +- Nuke: ftrack family plugin settings preset [\#1805](https://github.com/pypeclub/OpenPype/pull/1805) +- nuke: fixing wrong name of family folder when `used existing frames` [\#1803](https://github.com/pypeclub/OpenPype/pull/1803) +- Collect ftrack family bugs [\#1801](https://github.com/pypeclub/OpenPype/pull/1801) +- Standalone publisher last project [\#1799](https://github.com/pypeclub/OpenPype/pull/1799) ## [2.18.4](https://github.com/pypeclub/OpenPype/tree/2.18.4) (2021-06-24) diff --git a/openpype/__init__.py b/openpype/__init__.py index e7462e14e9..9d55006a67 100644 --- a/openpype/__init__.py +++ b/openpype/__init__.py @@ -68,6 +68,10 @@ def patched_discover(superclass): def install(): """Install Pype to Avalon.""" from pyblish.lib import MessageHandler + from openpype.modules import load_modules + + # Make sure modules are loaded + load_modules() def modified_emit(obj, record): """Method replacing `emit` in Pyblish's MessageHandler.""" diff --git a/openpype/hosts/maya/api/menu.py b/openpype/hosts/maya/api/menu.py index 0dced48868..ad225dcd28 100644 --- a/openpype/hosts/maya/api/menu.py +++ b/openpype/hosts/maya/api/menu.py @@ -16,12 +16,9 @@ log = logging.getLogger(__name__) def _get_menu(menu_name=None): """Return the menu instance if it currently exists in Maya""" - - project_settings = get_project_settings(os.getenv("AVALON_PROJECT")) - _menu = project_settings["maya"]["scriptsmenu"]["name"] - if menu_name is None: - menu_name = _menu + menu_name = pipeline._menu + widgets = dict(( w.objectName(), w) for w in QtWidgets.QApplication.allWidgets()) menu = widgets.get(menu_name) @@ -58,11 +55,64 @@ def deferred(): parent=pipeline._parent ) + # Find the pipeline menu + top_menu = _get_menu() + + # Try to find workfile tool action in the menu + workfile_action = None + for action in top_menu.actions(): + if action.text() == "Work Files": + workfile_action = action + break + + # Add at the top of menu if "Work Files" action was not found + after_action = "" + if workfile_action: + # Use action's object name for `insertAfter` argument + after_action = workfile_action.objectName() + + # Insert action to menu + cmds.menuItem( + "Work Files", + parent=pipeline._menu, + command=launch_workfiles_app, + insertAfter=after_action + ) + + # Remove replaced action + if workfile_action: + top_menu.removeAction(workfile_action) + + def remove_project_manager(): + top_menu = _get_menu() + + # Try to find "System" menu action in the menu + system_menu = None + for action in top_menu.actions(): + if action.text() == "System": + system_menu = action + break + + if system_menu is None: + return + + # Try to find "Project manager" action in "System" menu + project_manager_action = None + for action in system_menu.menu().children(): + if hasattr(action, "text") and action.text() == "Project Manager": + project_manager_action = action + break + + # Remove "Project manager" action if was found + if project_manager_action is not None: + system_menu.menu().removeAction(project_manager_action) + log.info("Attempting to install scripts menu ...") add_build_workfiles_item() add_look_assigner_item() modify_workfiles() + remove_project_manager() try: import scriptsmenu.launchformaya as launchformaya @@ -110,7 +160,6 @@ def install(): log.info("Skipping openpype.menu initialization in batch mode..") return - uninstall() # Allow time for uninstallation to finish. cmds.evalDeferred(deferred) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 257908c768..121f7a08a7 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -99,14 +99,24 @@ class ReferenceLoader(api.Loader): nodes = self[:] if not nodes: return - - loaded_containers.append(containerise( - name=name, - namespace=namespace, - nodes=nodes, - context=context, - loader=self.__class__.__name__ - )) + # FIXME: there is probably better way to do this for looks. + if "look" in self.families: + loaded_containers.append(containerise( + name=name, + namespace=namespace, + nodes=nodes, + context=context, + loader=self.__class__.__name__ + )) + else: + ref_node = self._get_reference_node(nodes) + loaded_containers.append(containerise( + name=name, + namespace=namespace, + nodes=[ref_node], + context=context, + loader=self.__class__.__name__ + )) c += 1 namespace = None @@ -235,9 +245,6 @@ class ReferenceLoader(api.Loader): self.log.info("Setting %s.verticesOnlySet to False", node) cmds.setAttr("{}.verticesOnlySet".format(node), False) - # Add new nodes of the reference to the container - cmds.sets(content, forceElement=node) - # Remove any placeHolderList attribute entries from the set that # are remaining from nodes being removed from the referenced file. members = cmds.sets(node, query=True) diff --git a/openpype/hosts/maya/plugins/create/create_animation.py b/openpype/hosts/maya/plugins/create/create_animation.py index 5155aec0ab..7ce96166f7 100644 --- a/openpype/hosts/maya/plugins/create/create_animation.py +++ b/openpype/hosts/maya/plugins/create/create_animation.py @@ -24,6 +24,7 @@ class CreateAnimation(plugin.Creator): # Write vertex colors with the geometry. self.data["writeColorSets"] = False + self.data["writeFaceSets"] = False # Include only renderable visible shapes. # Skips locators and empty transforms diff --git a/openpype/hosts/maya/plugins/create/create_model.py b/openpype/hosts/maya/plugins/create/create_model.py index f1d9d22c1c..37faad23a0 100644 --- a/openpype/hosts/maya/plugins/create/create_model.py +++ b/openpype/hosts/maya/plugins/create/create_model.py @@ -15,6 +15,7 @@ class CreateModel(plugin.Creator): # Vertex colors with the geometry self.data["writeColorSets"] = False + self.data["writeFaceSets"] = False # Include attributes by attribute name or prefix self.data["attr"] = "" diff --git a/openpype/hosts/maya/plugins/create/create_pointcache.py b/openpype/hosts/maya/plugins/create/create_pointcache.py index 9afea731fd..d8e5fd43a7 100644 --- a/openpype/hosts/maya/plugins/create/create_pointcache.py +++ b/openpype/hosts/maya/plugins/create/create_pointcache.py @@ -20,6 +20,7 @@ class CreatePointCache(plugin.Creator): self.data.update(lib.collect_animation_data()) self.data["writeColorSets"] = False # Vertex colors with the geometry. + self.data["writeFaceSets"] = False # Vertex colors with the geometry. self.data["renderableOnly"] = False # Only renderable visible shapes self.data["visibleOnly"] = False # only nodes that are visible self.data["includeParentHierarchy"] = False # Include parent groups diff --git a/openpype/hosts/maya/plugins/create/create_xgen.py b/openpype/hosts/maya/plugins/create/create_xgen.py new file mode 100644 index 0000000000..3953972952 --- /dev/null +++ b/openpype/hosts/maya/plugins/create/create_xgen.py @@ -0,0 +1,11 @@ +from openpype.hosts.maya.api import plugin + + +class CreateXgen(plugin.Creator): + """Xgen interactive export""" + + name = "xgen" + label = "Xgen Interactive" + family = "xgen" + icon = "pagelines" + defaults = ['Main'] diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py index 96269f2771..d5952ed267 100644 --- a/openpype/hosts/maya/plugins/load/load_reference.py +++ b/openpype/hosts/maya/plugins/load/load_reference.py @@ -17,7 +17,8 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): "layout", "camera", "rig", - "camerarig"] + "camerarig", + "xgen"] representations = ["ma", "abc", "fbx", "mb"] label = "Reference" diff --git a/openpype/hosts/maya/plugins/publish/extract_animation.py b/openpype/hosts/maya/plugins/publish/extract_animation.py index b86ded1fb0..7ecc40a68d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_animation.py @@ -57,7 +57,8 @@ class ExtractAnimation(openpype.api.Extractor): "uvWrite": True, "selection": True, "worldSpace": instance.data.get("worldSpace", True), - "writeColorSets": instance.data.get("writeColorSets", False) + "writeColorSets": instance.data.get("writeColorSets", False), + "writeFaceSets": instance.data.get("writeFaceSets", False) } if not instance.data.get("includeParentHierarchy", True): diff --git a/openpype/hosts/maya/plugins/publish/extract_maya_scene_raw.py b/openpype/hosts/maya/plugins/publish/extract_maya_scene_raw.py index c85bc0387d..3c2b70900d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_maya_scene_raw.py +++ b/openpype/hosts/maya/plugins/publish/extract_maya_scene_raw.py @@ -19,7 +19,8 @@ class ExtractMayaSceneRaw(openpype.api.Extractor): families = ["mayaAscii", "setdress", "layout", - "camerarig"] + "camerarig", + "xgen"] scene_type = "ma" def process(self, instance): diff --git a/openpype/hosts/maya/plugins/publish/extract_model.py b/openpype/hosts/maya/plugins/publish/extract_model.py index 1773297826..40cc9427f3 100644 --- a/openpype/hosts/maya/plugins/publish/extract_model.py +++ b/openpype/hosts/maya/plugins/publish/extract_model.py @@ -28,6 +28,7 @@ class ExtractModel(openpype.api.Extractor): hosts = ["maya"] families = ["model"] scene_type = "ma" + optional = True def process(self, instance): """Plugin entry point.""" diff --git a/openpype/hosts/maya/plugins/publish/extract_pointcache.py b/openpype/hosts/maya/plugins/publish/extract_pointcache.py index ba716c0d18..630cc39398 100644 --- a/openpype/hosts/maya/plugins/publish/extract_pointcache.py +++ b/openpype/hosts/maya/plugins/publish/extract_pointcache.py @@ -38,6 +38,7 @@ class ExtractAlembic(openpype.api.Extractor): # Get extra export arguments writeColorSets = instance.data.get("writeColorSets", False) + writeFaceSets = instance.data.get("writeFaceSets", False) self.log.info("Extracting pointcache..") dirname = self.staging_dir(instance) @@ -53,6 +54,7 @@ class ExtractAlembic(openpype.api.Extractor): "writeVisibility": True, "writeCreases": True, "writeColorSets": writeColorSets, + "writeFaceSets": writeFaceSets, "uvWrite": True, "selection": True, "worldSpace": instance.data.get("worldSpace", True) diff --git a/openpype/hosts/maya/plugins/publish/extract_xgen_cache.py b/openpype/hosts/maya/plugins/publish/extract_xgen_cache.py new file mode 100644 index 0000000000..d69911c404 --- /dev/null +++ b/openpype/hosts/maya/plugins/publish/extract_xgen_cache.py @@ -0,0 +1,61 @@ +import os + +from maya import cmds + +import avalon.maya +import openpype.api + + +class ExtractXgenCache(openpype.api.Extractor): + """Produce an alembic of just xgen interactive groom + + """ + + label = "Extract Xgen ABC Cache" + hosts = ["maya"] + families = ["xgen"] + optional = True + + def process(self, instance): + + # Collect the out set nodes + out_descriptions = [node for node in instance + if cmds.nodeType(node) == "xgmSplineDescription"] + + start = 1 + end = 1 + + self.log.info("Extracting Xgen Cache..") + dirname = self.staging_dir(instance) + + parent_dir = self.staging_dir(instance) + filename = "{name}.abc".format(**instance.data) + path = os.path.join(parent_dir, filename) + + with avalon.maya.suspended_refresh(): + with avalon.maya.maintained_selection(): + command = ( + '-file ' + + path + + ' -df "ogawa" -fr ' + + str(start) + + ' ' + + str(end) + + ' -step 1 -mxf -wfw' + ) + for desc in out_descriptions: + command += (" -obj " + desc) + cmds.xgmSplineCache(export=True, j=command) + + if "representations" not in instance.data: + instance.data["representations"] = [] + + representation = { + 'name': 'abc', + 'ext': 'abc', + 'files': filename, + "stagingDir": dirname, + } + instance.data["representations"].append(representation) + + self.log.info("Extracted {} to {}".format(instance, dirname)) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial_instances.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial_instances.py index 3a9a7a3445..45c6a264dd 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial_instances.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_editorial_instances.py @@ -2,7 +2,7 @@ import os import opentimelineio as otio import pyblish.api from openpype import lib as plib - +from copy import deepcopy class CollectInstances(pyblish.api.InstancePlugin): """Collect instances from editorial's OTIO sequence""" @@ -186,8 +186,8 @@ class CollectInstances(pyblish.api.InstancePlugin): properities.pop("version") # adding Review-able instance - subset_instance_data = instance_data.copy() - subset_instance_data.update(properities) + subset_instance_data = deepcopy(instance_data) + subset_instance_data.update(deepcopy(properities)) subset_instance_data.update({ # unique attributes "name": f"{name}_{subset}", diff --git a/openpype/hosts/tvpaint/plugins/publish/extract_sequence.py b/openpype/hosts/tvpaint/plugins/publish/extract_sequence.py index 1df7512588..36f0b0c954 100644 --- a/openpype/hosts/tvpaint/plugins/publish/extract_sequence.py +++ b/openpype/hosts/tvpaint/plugins/publish/extract_sequence.py @@ -50,12 +50,12 @@ class ExtractSequence(pyblish.api.Extractor): mark_in = instance.context.data["sceneMarkIn"] mark_out = instance.context.data["sceneMarkOut"] - # Scene start frame offsets the output files, so we need to offset the - # marks. + # Change scene Start Frame to 0 to prevent frame index issues + # - issue is that TVPaint versions deal with frame indexes in a + # different way when Start Frame is not `0` + # NOTE It will be set back after rendering scene_start_frame = instance.context.data["sceneStartFrame"] - difference = scene_start_frame - mark_in - mark_in += difference - mark_out += difference + lib.execute_george("tv_startframe 0") # Frame start/end may be stored as float frame_start = int(instance.data["frameStart"]) @@ -145,6 +145,9 @@ class ExtractSequence(pyblish.api.Extractor): filtered_layers ) + # Change scene frame Start back to previous value + lib.execute_george("tv_startframe {}".format(scene_start_frame)) + # Sequence of one frame if not output_filenames: self.log.warning("Extractor did not create any output.") diff --git a/openpype/lib/__init__.py b/openpype/lib/__init__.py index 12c04a4236..9bcd0f7587 100644 --- a/openpype/lib/__init__.py +++ b/openpype/lib/__init__.py @@ -52,9 +52,11 @@ from .vendor_bin_utils import ( ) from .python_module_tools import ( + import_filepath, modules_from_path, recursive_bases_from_class, - classes_from_module + classes_from_module, + import_module_from_dirpath ) from .avalon_context import ( @@ -170,9 +172,11 @@ __all__ = [ "get_ffmpeg_tool_path", "ffprobe_streams", + "import_filepath", "modules_from_path", "recursive_bases_from_class", "classes_from_module", + "import_module_from_dirpath", "CURRENT_DOC_SCHEMAS", "PROJECT_NAME_ALLOWED_SYMBOLS", diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index fe964d3bab..71ab2eac61 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -1105,7 +1105,7 @@ def prepare_host_environments(data, implementation_envs=True): asset_doc = data.get("asset_doc") # Add tools environments groups_by_name = {} - tool_by_group_name = collections.defaultdict(list) + tool_by_group_name = collections.defaultdict(dict) if asset_doc: # Make sure each tool group can be added only once for key in asset_doc["data"].get("tools_env") or []: @@ -1113,12 +1113,14 @@ def prepare_host_environments(data, implementation_envs=True): if not tool: continue groups_by_name[tool.group.name] = tool.group - tool_by_group_name[tool.group.name].append(tool) + tool_by_group_name[tool.group.name][tool.name] = tool - for group_name, group in groups_by_name.items(): + for group_name in sorted(groups_by_name.keys()): + group = groups_by_name[group_name] environments.append(group.environment) added_env_keys.add(group_name) - for tool in tool_by_group_name[group_name]: + for tool_name in sorted(tool_by_group_name[group_name].keys()): + tool = tool_by_group_name[group_name][tool_name] environments.append(tool.environment) added_env_keys.add(tool.name) diff --git a/openpype/lib/python_module_tools.py b/openpype/lib/python_module_tools.py index 44a1007889..cb5f285ddd 100644 --- a/openpype/lib/python_module_tools.py +++ b/openpype/lib/python_module_tools.py @@ -9,6 +9,38 @@ log = logging.getLogger(__name__) PY3 = sys.version_info[0] == 3 +def import_filepath(filepath, module_name=None): + """Import python file as python module. + + Python 2 and Python 3 compatibility. + + Args: + filepath(str): Path to python file. + module_name(str): Name of loaded module. Only for Python 3. By default + is filled with filename of filepath. + """ + if module_name is None: + module_name = os.path.splitext(os.path.basename(filepath))[0] + + # Prepare module object where content of file will be parsed + module = types.ModuleType(module_name) + + if PY3: + # Use loader so module has full specs + module_loader = importlib.machinery.SourceFileLoader( + module_name, filepath + ) + module_loader.exec_module(module) + else: + # Execute module code and store content to module + with open(filepath) as _stream: + # Execute content and store it to module object + exec(_stream.read(), module.__dict__) + + module.__file__ = filepath + return module + + def modules_from_path(folder_path): """Get python scripts as modules from a path. @@ -55,23 +87,7 @@ def modules_from_path(folder_path): continue try: - # Prepare module object where content of file will be parsed - module = types.ModuleType(mod_name) - - if PY3: - # Use loader so module has full specs - module_loader = importlib.machinery.SourceFileLoader( - mod_name, full_path - ) - module_loader.exec_module(module) - else: - # Execute module code and store content to module - with open(full_path) as _stream: - # Execute content and store it to module object - exec(_stream.read(), module.__dict__) - - module.__file__ = full_path - + module = import_filepath(full_path, mod_name) modules.append((full_path, module)) except Exception: @@ -127,3 +143,96 @@ def classes_from_module(superclass, module): classes.append(obj) return classes + + +def _import_module_from_dirpath_py2(dirpath, module_name, dst_module_name): + """Import passed dirpath as python module using `imp`.""" + if dst_module_name: + full_module_name = "{}.{}".format(dst_module_name, module_name) + dst_module = sys.modules[dst_module_name] + else: + full_module_name = module_name + dst_module = None + + if full_module_name in sys.modules: + return sys.modules[full_module_name] + + import imp + + fp, pathname, description = imp.find_module(module_name, [dirpath]) + module = imp.load_module(full_module_name, fp, pathname, description) + if dst_module is not None: + setattr(dst_module, module_name, module) + + return module + + +def _import_module_from_dirpath_py3(dirpath, module_name, dst_module_name): + """Import passed dirpath as python module using Python 3 modules.""" + if dst_module_name: + full_module_name = "{}.{}".format(dst_module_name, module_name) + dst_module = sys.modules[dst_module_name] + else: + full_module_name = module_name + dst_module = None + + # Skip import if is already imported + if full_module_name in sys.modules: + return sys.modules[full_module_name] + + import importlib.util + from importlib._bootstrap_external import PathFinder + + # Find loader for passed path and name + loader = PathFinder.find_module(full_module_name, [dirpath]) + + # Load specs of module + spec = importlib.util.spec_from_loader( + full_module_name, loader, origin=dirpath + ) + + # Create module based on specs + module = importlib.util.module_from_spec(spec) + + # Store module to destination module and `sys.modules` + # WARNING this mus be done before module execution + if dst_module is not None: + setattr(dst_module, module_name, module) + + sys.modules[full_module_name] = module + + # Execute module import + loader.exec_module(module) + + return module + + +def import_module_from_dirpath(dirpath, folder_name, dst_module_name=None): + """Import passed directory as a python module. + + Python 2 and 3 compatible. + + Imported module can be assigned as a child attribute of already loaded + module from `sys.modules` if has support of `setattr`. That is not default + behavior of python modules so parent module must be a custom module with + that ability. + + It is not possible to reimport already cached module. If you need to + reimport module you have to remove it from caches manually. + + Args: + dirpath(str): Parent directory path of loaded folder. + folder_name(str): Folder name which should be imported inside passed + directory. + dst_module_name(str): Parent module name under which can be loaded + module added. + """ + if PY3: + module = _import_module_from_dirpath_py3( + dirpath, folder_name, dst_module_name + ) + else: + module = _import_module_from_dirpath_py2( + dirpath, folder_name, dst_module_name + ) + return module diff --git a/openpype/modules/README.md b/openpype/modules/README.md index 818375461f..a3733518ac 100644 --- a/openpype/modules/README.md +++ b/openpype/modules/README.md @@ -1,7 +1,19 @@ -# Pype modules -Pype modules should contain separated logic of specific kind of implementation, like Ftrack connection and usage code or Deadline farm rendering. +# OpenPype modules/addons +OpenPype modules should contain separated logic of specific kind of implementation, like Ftrack connection and usage code or Deadline farm rendering or may contain only special plugins. Addons work the same way currently there is no difference in module and addon. -## Base class `PypeModule` +## Modules concept +- modules and addons are dynamically imported to virtual python module `openpype_modules` from which it is possible to import them no matter where is the modulo located +- modules or addons should never be imported directly even if you know possible full import path + - it is because all of their content must be imported in specific order and should not be imported without defined functions as it may also break few implementation parts + +### TODOs +- add module/addon manifest + - definition of module (not 100% defined content e.g. minimum require OpenPype version etc.) + - defying that folder is content of a module or an addon +- module/addon have it's settings schemas and default values outside OpenPype +- add general setting of paths to modules + +## Base class `OpenPypeModule` - abstract class as base for each module - implementation should be module's api withou GUI parts - may implement `get_global_environments` method which should return dictionary of environments that are globally appliable and value is the same for whole studio if launched at any workstation (except os specific paths) @@ -17,6 +29,16 @@ Pype modules should contain separated logic of specific kind of implementation, - interface is class that has defined abstract methods to implement and may contain preimplemented helper methods - module that inherit from an interface must implement those abstract methods otherwise won't be initialized - it is easy to find which module object inherited from which interfaces withh 100% chance they have implemented required methods +- interfaces can be defined in `interfaces.py` inside module directory + - the file can't use relative imports or import anything from other parts + of module itself at the header of file + - this is one of reasons why modules/addons can't be imported directly without using defined functions in OpenPype modules implementation + +## Base class `OpenPypeInterface` +- has nothing implemented +- has ABCMeta as metaclass +- is defined to be able find out classes which inherit from this base to be + able tell this is an Interface ## Global interfaces - few interfaces are implemented for global usage @@ -70,7 +92,7 @@ Pype modules should contain separated logic of specific kind of implementation, - Clockify has more inharitance it's class definition looks like ``` class ClockifyModule( - PypeModule, # Says it's Pype module so ModulesManager will try to initialize. + OpenPypeModule, # Says it's Pype module so ModulesManager will try to initialize. ITrayModule, # Says has special implementation when used in tray. IPluginPaths, # Says has plugin paths that want to register (paths to clockify actions for launcher). IFtrackEventHandlerPaths, # Says has Ftrack actions/events for user/server. diff --git a/openpype/modules/__init__.py b/openpype/modules/__init__.py index 068aeb98af..583480b049 100644 --- a/openpype/modules/__init__.py +++ b/openpype/modules/__init__.py @@ -1,86 +1,21 @@ # -*- coding: utf-8 -*- from .base import ( - PypeModule, - ITrayModule, - ITrayAction, - ITrayService, - IPluginPaths, - ILaunchHookPaths, + OpenPypeModule, + OpenPypeInterface, + + load_modules, + ModulesManager, TrayModulesManager ) -from .settings_action import ( - SettingsAction, - ISettingsChangeListener, - LocalSettingsAction -) -from .webserver import ( - WebServerModule, - IWebServerRoutes -) -from .idle_manager import ( - IdleManager, - IIdleManager -) -from .timers_manager import ( - TimersManager, - ITimersManager -) -from .avalon_apps import AvalonModule -from .launcher_action import LauncherAction -from .ftrack import ( - FtrackModule, - IFtrackEventHandlerPaths -) -from .clockify import ClockifyModule -from .log_viewer import LogViewModule -from .muster import MusterModule -from .deadline import DeadlineModule -from .project_manager_action import ProjectManagerAction -from .standalonepublish_action import StandAlonePublishAction -from .python_console_interpreter import PythonInterpreterAction -from .sync_server import SyncServerModule -from .slack import SlackIntegrationModule __all__ = ( - "PypeModule", - "ITrayModule", - "ITrayAction", - "ITrayService", - "IPluginPaths", - "ILaunchHookPaths", + "OpenPypeModule", + "OpenPypeInterface", + + "load_modules", + "ModulesManager", - "TrayModulesManager", - - "SettingsAction", - "LocalSettingsAction", - - "WebServerModule", - "IWebServerRoutes", - - "IdleManager", - "IIdleManager", - - "TimersManager", - "ITimersManager", - - "AvalonModule", - "LauncherAction", - - "FtrackModule", - "IFtrackEventHandlerPaths", - - "ClockifyModule", - "IdleManager", - "LogViewModule", - "MusterModule", - "DeadlineModule", - "ProjectManagerAction", - "StandAlonePublishAction", - "PythonInterpreterAction", - - "SyncServerModule", - - "SlackIntegrationModule" + "TrayModulesManager" ) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index c7efbd5ab3..d43d5635d1 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- """Base class for Pype Modules.""" +import os +import sys import time import inspect import logging +import threading import collections from uuid import uuid4 from abc import ABCMeta, abstractmethod @@ -11,11 +14,305 @@ import six import openpype from openpype.settings import get_system_settings from openpype.lib import PypeLogger -from openpype import resources + + +# Inherit from `object` for Python 2 hosts +class _ModuleClass(object): + """Fake module class for storing OpenPype modules. + + Object of this class can be stored to `sys.modules` and used for storing + dynamically imported modules. + """ + def __init__(self, name): + # Call setattr on super class + super(_ModuleClass, self).__setattr__("name", name) + + # Where modules and interfaces are stored + super(_ModuleClass, self).__setattr__("__attributes__", dict()) + super(_ModuleClass, self).__setattr__("__defaults__", set()) + + super(_ModuleClass, self).__setattr__("_log", None) + + def __getattr__(self, attr_name): + if attr_name not in self.__attributes__: + if attr_name in ("__path__"): + return None + raise ImportError("No module named {}.{}".format( + self.name, attr_name + )) + return self.__attributes__[attr_name] + + def __iter__(self): + for module in self.values(): + yield module + + def __setattr__(self, attr_name, value): + if attr_name in self.__attributes__: + self.log.warning( + "Duplicated name \"{}\" in {}. Overriding.".format( + self.name, attr_name + ) + ) + self.__attributes__[attr_name] = value + + def __setitem__(self, key, value): + self.__setattr__(key, value) + + def __getitem__(self, key): + return getattr(self, key) + + @property + def log(self): + if self._log is None: + super(_ModuleClass, self).__setattr__( + "_log", PypeLogger.get_logger(self.name) + ) + return self._log + + def get(self, key, default=None): + return self.__attributes__.get(key, default) + + def keys(self): + return self.__attributes__.keys() + + def values(self): + return self.__attributes__.values() + + def items(self): + return self.__attributes__.items() + + +class _InterfacesClass(_ModuleClass): + """Fake module class for storing OpenPype interfaces. + + MissingInterface object is returned if interfaces does not exists. + - this is because interfaces must be available even if are missing + implementation + """ + def __getattr__(self, attr_name): + if attr_name not in self.__attributes__: + # Fake Interface if is not missing + self.__attributes__[attr_name] = type( + attr_name, + (MissingInteface, ), + {} + ) + + return self.__attributes__[attr_name] + + +class _LoadCache: + interfaces_lock = threading.Lock() + modules_lock = threading.Lock() + interfaces_loaded = False + modules_loaded = False + + +def get_default_modules_dir(): + """Path to default OpenPype modules.""" + current_dir = os.path.abspath(os.path.dirname(__file__)) + + return os.path.join(current_dir, "default_modules") + + +def get_module_dirs(): + """List of paths where OpenPype modules can be found.""" + dirpaths = [ + get_default_modules_dir() + ] + return dirpaths + + +def load_interfaces(force=False): + """Load interfaces from modules into `openpype_interfaces`. + + Only classes which inherit from `OpenPypeInterface` are loaded and stored. + + Args: + force(bool): Force to load interfaces even if are already loaded. + This won't update already loaded and used (cached) interfaces. + """ + + if _LoadCache.interfaces_loaded and not force: + return + + if not _LoadCache.interfaces_lock.locked(): + with _LoadCache.interfaces_lock: + _load_interfaces() + _LoadCache.interfaces_loaded = True + else: + # If lock is locked wait until is finished + while _LoadCache.interfaces_lock.locked(): + time.sleep(0.1) + + +def _load_interfaces(): + # Key under which will be modules imported in `sys.modules` + from openpype.lib import import_filepath + + modules_key = "openpype_interfaces" + + sys.modules[modules_key] = openpype_interfaces = ( + _InterfacesClass(modules_key) + ) + + log = PypeLogger.get_logger("InterfacesLoader") + + dirpaths = get_module_dirs() + + interface_paths = [] + interface_paths.append( + os.path.join(get_default_modules_dir(), "interfaces.py") + ) + for dirpath in dirpaths: + for filename in os.listdir(dirpath): + if filename in ("__pycache__", ): + continue + + full_path = os.path.join(dirpath, filename) + if not os.path.isdir(full_path): + continue + + interfaces_path = os.path.join(full_path, "interfaces.py") + if os.path.exists(interfaces_path): + interface_paths.append(interfaces_path) + + for full_path in interface_paths: + if not os.path.exists(full_path): + continue + + try: + # Prepare module object where content of file will be parsed + module = import_filepath(full_path) + + except Exception: + log.warning( + "Failed to load path: \"{0}\"".format(full_path), + exc_info=True + ) + continue + + for attr_name in dir(module): + attr = getattr(module, attr_name) + if ( + not inspect.isclass(attr) + or attr is OpenPypeInterface + or not issubclass(attr, OpenPypeInterface) + ): + continue + setattr(openpype_interfaces, attr_name, attr) + + +def load_modules(force=False): + """Load OpenPype modules as python modules. + + Modules does not load only classes (like in Interfaces) because there must + be ability to use inner code of module and be able to import it from one + defined place. + + With this it is possible to import module's content from predefined module. + + Function makes sure that `load_interfaces` was triggered. Modules import + has specific order which can't be changed. + + Args: + force(bool): Force to load modules even if are already loaded. + This won't update already loaded and used (cached) modules. + """ + + if _LoadCache.modules_loaded and not force: + return + + # First load interfaces + # - modules must not be imported before interfaces + load_interfaces(force) + + if not _LoadCache.modules_lock.locked(): + with _LoadCache.modules_lock: + _load_modules() + _LoadCache.modules_loaded = True + else: + # If lock is locked wait until is finished + while _LoadCache.modules_lock.locked(): + time.sleep(0.1) + + +def _load_modules(): + # Import helper functions from lib + from openpype.lib import ( + import_filepath, + import_module_from_dirpath + ) + + # Key under which will be modules imported in `sys.modules` + modules_key = "openpype_modules" + + # Change `sys.modules` + sys.modules[modules_key] = openpype_modules = _ModuleClass(modules_key) + + log = PypeLogger.get_logger("ModulesLoader") + + # Look for OpenPype modules in paths defined with `get_module_dirs` + dirpaths = get_module_dirs() + + for dirpath in dirpaths: + if not os.path.exists(dirpath): + log.warning(( + "Could not find path when loading OpenPype modules \"{}\"" + ).format(dirpath)) + continue + + for filename in os.listdir(dirpath): + # Ignore filenames + if filename in ("__pycache__", ): + continue + + fullpath = os.path.join(dirpath, filename) + basename, ext = os.path.splitext(filename) + + # TODO add more logic how to define if folder is module or not + # - check manifest and content of manifest + if os.path.isdir(fullpath): + import_module_from_dirpath(dirpath, filename, modules_key) + + elif ext in (".py", ): + module = import_filepath(fullpath) + setattr(openpype_modules, basename, module) + + +class _OpenPypeInterfaceMeta(ABCMeta): + """OpenPypeInterface meta class to print proper string.""" + def __str__(self): + return "<'OpenPypeInterface.{}'>".format(self.__name__) + + def __repr__(self): + return str(self) + + +@six.add_metaclass(_OpenPypeInterfaceMeta) +class OpenPypeInterface: + """Base class of Interface that can be used as Mixin with abstract parts. + + This is way how OpenPype module or addon can tell that has implementation + for specific part or for other module/addon. + + Child classes of OpenPypeInterface may be used as mixin in different + OpenPype modules which means they have to have implemented methods defined + in the interface. By default interface does not have any abstract parts. + """ + pass + + +class MissingInteface(OpenPypeInterface): + """Class representing missing interface class. + + Used when interface is not available from currently registered paths. + """ + pass @six.add_metaclass(ABCMeta) -class PypeModule: +class OpenPypeModule: """Base class of pype module. Attributes: @@ -38,7 +335,7 @@ class PypeModule: def __init__(self, manager, settings): self.manager = manager - self.log = PypeLogger().get_logger(self.name) + self.log = PypeLogger.get_logger(self.name) self.initialize(settings) @@ -70,265 +367,8 @@ class PypeModule: return {} -@six.add_metaclass(ABCMeta) -class IPluginPaths: - """Module has plugin paths to return. - - Expected result is dictionary with keys "publish", "create", "load" or - "actions" and values as list or string. - { - "publish": ["path/to/publish_plugins"] - } - """ - # TODO validation of an output - @abstractmethod - def get_plugin_paths(self): - pass - - -@six.add_metaclass(ABCMeta) -class ILaunchHookPaths: - """Module has launch hook paths to return. - - Expected result is list of paths. - ["path/to/launch_hooks_dir"] - """ - - @abstractmethod - def get_launch_hook_paths(self): - pass - - -@six.add_metaclass(ABCMeta) -class ITrayModule: - """Module has special procedures when used in Pype Tray. - - IMPORTANT: - The module still must be usable if is not used in tray even if - would do nothing. - """ - tray_initialized = False - _tray_manager = None - - @abstractmethod - def tray_init(self): - """Initialization part of tray implementation. - - Triggered between `initialization` and `connect_with_modules`. - - This is where GUIs should be loaded or tray specific parts should be - prepared. - """ - pass - - @abstractmethod - def tray_menu(self, tray_menu): - """Add module's action to tray menu.""" - pass - - @abstractmethod - def tray_start(self): - """Start procedure in Pype tray.""" - pass - - @abstractmethod - def tray_exit(self): - """Cleanup method which is executed on tray shutdown. - - This is place where all threads should be shut. - """ - pass - - def execute_in_main_thread(self, callback): - """ Pushes callback to the queue or process 'callback' on a main thread - - Some callbacks need to be processed on main thread (menu actions - must be added on main thread or they won't get triggered etc.) - """ - # called without initialized tray, still main thread needed - if not self.tray_initialized: - try: - callback = self._main_thread_callbacks.popleft() - callback() - except: - self.log.warning( - "Failed to execute {} in main thread".format(callback), - exc_info=True) - - return - self.manager.tray_manager.execute_in_main_thread(callback) - - def show_tray_message(self, title, message, icon=None, msecs=None): - """Show tray message. - - Args: - title (str): Title of message. - message (str): Content of message. - icon (QSystemTrayIcon.MessageIcon): Message's icon. Default is - Information icon, may differ by Qt version. - msecs (int): Duration of message visibility in miliseconds. - Default is 10000 msecs, may differ by Qt version. - """ - if self._tray_manager: - self._tray_manager.show_tray_message(title, message, icon, msecs) - - def add_doubleclick_callback(self, callback): - if hasattr(self.manager, "add_doubleclick_callback"): - self.manager.add_doubleclick_callback(self, callback) - - -class ITrayAction(ITrayModule): - """Implementation of Tray action. - - Add action to tray menu which will trigger `on_action_trigger`. - It is expected to be used for showing tools. - - Methods `tray_start`, `tray_exit` and `connect_with_modules` are overriden - as it's not expected that action will use them. But it is possible if - necessary. - """ - - admin_action = False - _admin_submenu = None - - @property - @abstractmethod - def label(self): - """Service label showed in menu.""" - pass - - @abstractmethod - def on_action_trigger(self): - """What happens on actions click.""" - pass - - def tray_menu(self, tray_menu): - from Qt import QtWidgets - - if self.admin_action: - menu = self.admin_submenu(tray_menu) - action = QtWidgets.QAction(self.label, menu) - menu.addAction(action) - if not menu.menuAction().isVisible(): - menu.menuAction().setVisible(True) - - else: - action = QtWidgets.QAction(self.label, tray_menu) - tray_menu.addAction(action) - - action.triggered.connect(self.on_action_trigger) - - def tray_start(self): - return - - def tray_exit(self): - return - - @staticmethod - def admin_submenu(tray_menu): - if ITrayAction._admin_submenu is None: - from Qt import QtWidgets - - admin_submenu = QtWidgets.QMenu("Admin", tray_menu) - admin_submenu.menuAction().setVisible(False) - ITrayAction._admin_submenu = admin_submenu - return ITrayAction._admin_submenu - - -class ITrayService(ITrayModule): - # Module's property - menu_action = None - - # Class properties - _services_submenu = None - _icon_failed = None - _icon_running = None - _icon_idle = None - - @property - @abstractmethod - def label(self): - """Service label showed in menu.""" - pass - - # TODO be able to get any sort of information to show/print - # @abstractmethod - # def get_service_info(self): - # pass - - @staticmethod - def services_submenu(tray_menu): - if ITrayService._services_submenu is None: - from Qt import QtWidgets - - services_submenu = QtWidgets.QMenu("Services", tray_menu) - services_submenu.menuAction().setVisible(False) - ITrayService._services_submenu = services_submenu - return ITrayService._services_submenu - - @staticmethod - def add_service_action(action): - ITrayService._services_submenu.addAction(action) - if not ITrayService._services_submenu.menuAction().isVisible(): - ITrayService._services_submenu.menuAction().setVisible(True) - - @staticmethod - def _load_service_icons(): - from Qt import QtGui - ITrayService._failed_icon = QtGui.QIcon( - resources.get_resource("icons", "circle_red.png") - ) - ITrayService._icon_running = QtGui.QIcon( - resources.get_resource("icons", "circle_green.png") - ) - ITrayService._icon_idle = QtGui.QIcon( - resources.get_resource("icons", "circle_orange.png") - ) - - @staticmethod - def get_icon_running(): - if ITrayService._icon_running is None: - ITrayService._load_service_icons() - return ITrayService._icon_running - - @staticmethod - def get_icon_idle(): - if ITrayService._icon_idle is None: - ITrayService._load_service_icons() - return ITrayService._icon_idle - - @staticmethod - def get_icon_failed(): - if ITrayService._failed_icon is None: - ITrayService._load_service_icons() - return ITrayService._failed_icon - - def tray_menu(self, tray_menu): - from Qt import QtWidgets - action = QtWidgets.QAction( - self.label, - self.services_submenu(tray_menu) - ) - self.menu_action = action - - self.add_service_action(action) - - self.set_service_running_icon() - - def set_service_running_icon(self): - """Change icon of an QAction to green circle.""" - if self.menu_action: - self.menu_action.setIcon(self.get_icon_running()) - - def set_service_failed_icon(self): - """Change icon of an QAction to red circle.""" - if self.menu_action: - self.menu_action.setIcon(self.get_icon_failed()) - - def set_service_idle_icon(self): - """Change icon of an QAction to orange circle.""" - if self.menu_action: - self.menu_action.setIcon(self.get_icon_idle()) +class OpenPypeAddOn(OpenPypeModule): + pass class ModulesManager: @@ -357,6 +397,11 @@ class ModulesManager: def initialize_modules(self): """Import and initialize modules.""" + # Make sure modules are loaded + load_modules() + + import openpype_modules + self.log.debug("*** Pype modules initialization.") # Prepare settings for modules system_settings = getattr(self, "_system_settings", None) @@ -368,33 +413,43 @@ class ModulesManager: time_start = time.time() prev_start_time = time_start - # Go through globals in `pype.modules` - for name in dir(openpype.modules): - modules_item = getattr(openpype.modules, name, None) - # Filter globals that are not classes which inherit from PypeModule - if ( - not inspect.isclass(modules_item) - or modules_item is openpype.modules.PypeModule - or not issubclass(modules_item, openpype.modules.PypeModule) - ): - continue + module_classes = [] + for module in openpype_modules: + # Go through globals in `pype.modules` + for name in dir(module): + modules_item = getattr(module, name, None) + # Filter globals that are not classes which inherit from + # OpenPypeModule + if ( + not inspect.isclass(modules_item) + or modules_item is OpenPypeModule + or not issubclass(modules_item, OpenPypeModule) + ): + continue - # Check if class is abstract (Developing purpose) - if inspect.isabstract(modules_item): - # Find missing implementations by convetion on `abc` module - not_implemented = [] - for attr_name in dir(modules_item): - attr = getattr(modules_item, attr_name, None) - if attr and getattr(attr, "__isabstractmethod__", None): - not_implemented.append(attr_name) + # Check if class is abstract (Developing purpose) + if inspect.isabstract(modules_item): + # Find missing implementations by convetion on `abc` module + not_implemented = [] + for attr_name in dir(modules_item): + attr = getattr(modules_item, attr_name, None) + abs_method = getattr( + attr, "__isabstractmethod__", None + ) + if attr and abs_method: + not_implemented.append(attr_name) - # Log missing implementations - self.log.warning(( - "Skipping abstract Class: {}. Missing implementations: {}" - ).format(name, ", ".join(not_implemented))) - continue + # Log missing implementations + self.log.warning(( + "Skipping abstract Class: {}." + " Missing implementations: {}" + ).format(name, ", ".join(not_implemented))) + continue + module_classes.append(modules_item) + for modules_item in module_classes: try: + name = modules_item.__name__ # Try initialize module module = modules_item(self, modules_settings) # Store initialized object @@ -492,6 +547,8 @@ class ModulesManager: and "actions" each containing list of paths. """ # Output structure + from openpype_interfaces import IPluginPaths + output = { "publish": [], "create": [], @@ -544,6 +601,8 @@ class ModulesManager: Returns: list: Paths to launch hook directories. """ + from openpype_interfaces import ILaunchHookPaths + str_type = type("") expected_types = (list, tuple, set) @@ -711,6 +770,7 @@ class TrayModulesManager(ModulesManager): self.modules_by_id = {} self.modules_by_name = {} self._report = {} + self.tray_manager = None self.doubleclick_callbacks = {} @@ -743,6 +803,8 @@ class TrayModulesManager(ModulesManager): self.tray_menu(tray_menu) def get_enabled_tray_modules(self): + from openpype_interfaces import ITrayModule + output = [] for module in self.modules: if module.enabled and isinstance(module, ITrayModule): @@ -818,6 +880,8 @@ class TrayModulesManager(ModulesManager): self._report["Tray menu"] = report def start_modules(self): + from openpype_interfaces import ITrayService + report = {} time_start = time.time() prev_start_time = time_start diff --git a/openpype/modules/avalon_apps/__init__.py b/openpype/modules/default_modules/avalon_apps/__init__.py similarity index 100% rename from openpype/modules/avalon_apps/__init__.py rename to openpype/modules/default_modules/avalon_apps/__init__.py diff --git a/openpype/modules/avalon_apps/avalon_app.py b/openpype/modules/default_modules/avalon_apps/avalon_app.py similarity index 95% rename from openpype/modules/avalon_apps/avalon_app.py rename to openpype/modules/default_modules/avalon_apps/avalon_app.py index 4e95f6e72b..53e06ec90a 100644 --- a/openpype/modules/avalon_apps/avalon_app.py +++ b/openpype/modules/default_modules/avalon_apps/avalon_app.py @@ -1,14 +1,14 @@ import os import openpype from openpype import resources -from .. import ( - PypeModule, +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( ITrayModule, IWebServerRoutes ) -class AvalonModule(PypeModule, ITrayModule, IWebServerRoutes): +class AvalonModule(OpenPypeModule, ITrayModule, IWebServerRoutes): name = "avalon" def initialize(self, modules_settings): diff --git a/openpype/modules/avalon_apps/rest_api.py b/openpype/modules/default_modules/avalon_apps/rest_api.py similarity index 97% rename from openpype/modules/avalon_apps/rest_api.py rename to openpype/modules/default_modules/avalon_apps/rest_api.py index b77c256398..533050fc0c 100644 --- a/openpype/modules/avalon_apps/rest_api.py +++ b/openpype/modules/default_modules/avalon_apps/rest_api.py @@ -1,16 +1,13 @@ import os -import re import json import datetime -import bson from bson.objectid import ObjectId -import bson.json_util from aiohttp.web_response import Response from avalon.api import AvalonMongoDB -from openpype.modules.webserver.base_routes import RestApiEndpoint +from openpype_modules.webserver.base_routes import RestApiEndpoint class _RestApiEndpoint(RestApiEndpoint): diff --git a/openpype/modules/clockify/__init__.py b/openpype/modules/default_modules/clockify/__init__.py similarity index 100% rename from openpype/modules/clockify/__init__.py rename to openpype/modules/default_modules/clockify/__init__.py diff --git a/openpype/modules/clockify/clockify_api.py b/openpype/modules/default_modules/clockify/clockify_api.py similarity index 100% rename from openpype/modules/clockify/clockify_api.py rename to openpype/modules/default_modules/clockify/clockify_api.py diff --git a/openpype/modules/clockify/clockify_module.py b/openpype/modules/default_modules/clockify/clockify_module.py similarity index 98% rename from openpype/modules/clockify/clockify_module.py rename to openpype/modules/default_modules/clockify/clockify_module.py index e3751c46b8..a9e989f4ec 100644 --- a/openpype/modules/clockify/clockify_module.py +++ b/openpype/modules/default_modules/clockify/clockify_module.py @@ -7,8 +7,8 @@ from .constants import ( CLOCKIFY_FTRACK_USER_PATH, CLOCKIFY_FTRACK_SERVER_PATH ) -from openpype.modules import ( - PypeModule, +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( ITrayModule, IPluginPaths, IFtrackEventHandlerPaths, @@ -17,7 +17,7 @@ from openpype.modules import ( class ClockifyModule( - PypeModule, + OpenPypeModule, ITrayModule, IPluginPaths, IFtrackEventHandlerPaths, diff --git a/openpype/modules/clockify/constants.py b/openpype/modules/default_modules/clockify/constants.py similarity index 100% rename from openpype/modules/clockify/constants.py rename to openpype/modules/default_modules/clockify/constants.py diff --git a/openpype/modules/clockify/ftrack/server/action_clockify_sync_server.py b/openpype/modules/default_modules/clockify/ftrack/server/action_clockify_sync_server.py similarity index 97% rename from openpype/modules/clockify/ftrack/server/action_clockify_sync_server.py rename to openpype/modules/default_modules/clockify/ftrack/server/action_clockify_sync_server.py index 495f87dc7e..c6b55947da 100644 --- a/openpype/modules/clockify/ftrack/server/action_clockify_sync_server.py +++ b/openpype/modules/default_modules/clockify/ftrack/server/action_clockify_sync_server.py @@ -1,7 +1,7 @@ import os import json -from openpype.modules.ftrack.lib import ServerAction -from openpype.modules.clockify.clockify_api import ClockifyAPI +from openpype_modules.ftrack.lib import ServerAction +from openpype_modules.clockify.clockify_api import ClockifyAPI class SyncClocifyServer(ServerAction): diff --git a/openpype/modules/clockify/ftrack/user/action_clockify_sync_local.py b/openpype/modules/default_modules/clockify/ftrack/user/action_clockify_sync_local.py similarity index 96% rename from openpype/modules/clockify/ftrack/user/action_clockify_sync_local.py rename to openpype/modules/default_modules/clockify/ftrack/user/action_clockify_sync_local.py index 4f4579a8bf..a430791906 100644 --- a/openpype/modules/clockify/ftrack/user/action_clockify_sync_local.py +++ b/openpype/modules/default_modules/clockify/ftrack/user/action_clockify_sync_local.py @@ -1,6 +1,6 @@ import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon -from openpype.modules.clockify.clockify_api import ClockifyAPI +from openpype_modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.clockify.clockify_api import ClockifyAPI class SyncClocifyLocal(BaseAction): diff --git a/openpype/modules/clockify/launcher_actions/ClockifyStart.py b/openpype/modules/default_modules/clockify/launcher_actions/ClockifyStart.py similarity index 95% rename from openpype/modules/clockify/launcher_actions/ClockifyStart.py rename to openpype/modules/default_modules/clockify/launcher_actions/ClockifyStart.py index c431ea240d..db51964eb7 100644 --- a/openpype/modules/clockify/launcher_actions/ClockifyStart.py +++ b/openpype/modules/default_modules/clockify/launcher_actions/ClockifyStart.py @@ -1,6 +1,6 @@ from avalon import api, io from openpype.api import Logger -from openpype.modules.clockify.clockify_api import ClockifyAPI +from openpype_modules.clockify.clockify_api import ClockifyAPI log = Logger().get_logger(__name__) diff --git a/openpype/modules/clockify/launcher_actions/ClockifySync.py b/openpype/modules/default_modules/clockify/launcher_actions/ClockifySync.py similarity index 97% rename from openpype/modules/clockify/launcher_actions/ClockifySync.py rename to openpype/modules/default_modules/clockify/launcher_actions/ClockifySync.py index 1bb168a80b..02982d373a 100644 --- a/openpype/modules/clockify/launcher_actions/ClockifySync.py +++ b/openpype/modules/default_modules/clockify/launcher_actions/ClockifySync.py @@ -1,5 +1,5 @@ from avalon import api, io -from openpype.modules.clockify.clockify_api import ClockifyAPI +from openpype_modules.clockify.clockify_api import ClockifyAPI from openpype.api import Logger log = Logger().get_logger(__name__) diff --git a/openpype/modules/clockify/widgets.py b/openpype/modules/default_modules/clockify/widgets.py similarity index 100% rename from openpype/modules/clockify/widgets.py rename to openpype/modules/default_modules/clockify/widgets.py diff --git a/openpype/modules/deadline/__init__.py b/openpype/modules/default_modules/deadline/__init__.py similarity index 100% rename from openpype/modules/deadline/__init__.py rename to openpype/modules/default_modules/deadline/__init__.py diff --git a/openpype/modules/deadline/deadline_module.py b/openpype/modules/default_modules/deadline/deadline_module.py similarity index 88% rename from openpype/modules/deadline/deadline_module.py rename to openpype/modules/default_modules/deadline/deadline_module.py index a07cb1a660..ada5e8225a 100644 --- a/openpype/modules/deadline/deadline_module.py +++ b/openpype/modules/default_modules/deadline/deadline_module.py @@ -1,9 +1,9 @@ import os -from openpype.modules import ( - PypeModule, IPluginPaths) +from openpype.modules import OpenPypeModule +from openpype_interfaces import IPluginPaths -class DeadlineModule(PypeModule, IPluginPaths): +class DeadlineModule(OpenPypeModule, IPluginPaths): name = "deadline" def __init__(self, manager, settings): diff --git a/openpype/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py b/openpype/modules/default_modules/deadline/plugins/publish/collect_deadline_server_from_instance.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py rename to openpype/modules/default_modules/deadline/plugins/publish/collect_deadline_server_from_instance.py diff --git a/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py b/openpype/modules/default_modules/deadline/plugins/publish/collect_default_deadline_server.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py rename to openpype/modules/default_modules/deadline/plugins/publish/collect_default_deadline_server.py diff --git a/openpype/modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/submit_aftereffects_deadline.py rename to openpype/modules/default_modules/deadline/plugins/publish/submit_aftereffects_deadline.py diff --git a/openpype/modules/deadline/plugins/publish/submit_harmony_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/submit_harmony_deadline.py rename to openpype/modules/default_modules/deadline/plugins/publish/submit_harmony_deadline.py diff --git a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_maya_deadline.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/submit_maya_deadline.py rename to openpype/modules/default_modules/deadline/plugins/publish/submit_maya_deadline.py diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_nuke_deadline.py similarity index 92% rename from openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py rename to openpype/modules/default_modules/deadline/plugins/publish/submit_nuke_deadline.py index 1baef5c297..4cba35963c 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/default_modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -251,39 +251,11 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): environment = dict({key: os.environ[key] for key in keys if key in os.environ}, **api.Session) - # self.log.debug("enviro: {}".format(pprint(environment))) for _path in os.environ: if _path.lower().startswith('openpype_'): environment[_path] = os.environ[_path] - clean_environment = {} - for key, value in environment.items(): - clean_path = "" - self.log.debug("key: {}".format(key)) - if "://" in value: - clean_path = value - else: - valid_paths = [] - for path in value.split(os.pathsep): - if not path: - continue - try: - path.decode('UTF-8', 'strict') - valid_paths.append(os.path.normpath(path)) - except UnicodeDecodeError: - print('path contains non UTF characters') - - if valid_paths: - clean_path = os.pathsep.join(valid_paths) - - if key == "PYTHONPATH": - clean_path = clean_path.replace('python2', 'python3') - - self.log.debug("clean path: {}".format(clean_path)) - clean_environment[key] = clean_path - - environment = clean_environment # to recognize job from PYPE for turning Event On/Off environment["OPENPYPE_RENDER_JOB"] = "1" diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/default_modules/deadline/plugins/publish/submit_publish_job.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/submit_publish_job.py rename to openpype/modules/default_modules/deadline/plugins/publish/submit_publish_job.py diff --git a/openpype/modules/deadline/plugins/publish/validate_deadline_connection.py b/openpype/modules/default_modules/deadline/plugins/publish/validate_deadline_connection.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/validate_deadline_connection.py rename to openpype/modules/default_modules/deadline/plugins/publish/validate_deadline_connection.py diff --git a/openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py b/openpype/modules/default_modules/deadline/plugins/publish/validate_expected_and_rendered_files.py similarity index 100% rename from openpype/modules/deadline/plugins/publish/validate_expected_and_rendered_files.py rename to openpype/modules/default_modules/deadline/plugins/publish/validate_expected_and_rendered_files.py diff --git a/openpype/modules/ftrack/__init__.py b/openpype/modules/default_modules/ftrack/__init__.py similarity index 67% rename from openpype/modules/ftrack/__init__.py rename to openpype/modules/default_modules/ftrack/__init__.py index c1a557812c..7261254c6f 100644 --- a/openpype/modules/ftrack/__init__.py +++ b/openpype/modules/default_modules/ftrack/__init__.py @@ -1,11 +1,9 @@ from .ftrack_module import ( FtrackModule, - IFtrackEventHandlerPaths, FTRACK_MODULE_DIR ) __all__ = ( "FtrackModule", - "IFtrackEventHandlerPaths", "FTRACK_MODULE_DIR" ) diff --git a/openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py b/openpype/modules/default_modules/ftrack/event_handlers_server/action_clone_review_session.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/action_clone_review_session.py index 59c8bffb75..1ad7a17785 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_clone_review_session.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/action_clone_review_session.py @@ -1,6 +1,6 @@ import json -from openpype.modules.ftrack.lib import ServerAction +from openpype_modules.ftrack.lib import ServerAction def clone_review_session(session, entity): diff --git a/openpype/modules/ftrack/event_handlers_server/action_multiple_notes.py b/openpype/modules/default_modules/ftrack/event_handlers_server/action_multiple_notes.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_server/action_multiple_notes.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/action_multiple_notes.py index 9ad7b1a969..f9aac2c80a 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_multiple_notes.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/action_multiple_notes.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import ServerAction +from openpype_modules.ftrack.lib import ServerAction class MultipleNotesServer(ServerAction): diff --git a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py b/openpype/modules/default_modules/ftrack/event_handlers_server/action_prepare_project.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/action_prepare_project.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/action_prepare_project.py index 3a96ae3311..85317031b2 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/action_prepare_project.py @@ -4,7 +4,7 @@ from avalon.api import AvalonMongoDB from openpype.api import ProjectSettings from openpype.lib import create_project -from openpype.modules.ftrack.lib import ( +from openpype_modules.ftrack.lib import ( ServerAction, get_openpype_attr, CUST_ATTR_AUTO_SYNC diff --git a/openpype/modules/ftrack/event_handlers_server/action_private_project_detection.py b/openpype/modules/default_modules/ftrack/event_handlers_server/action_private_project_detection.py similarity index 97% rename from openpype/modules/ftrack/event_handlers_server/action_private_project_detection.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/action_private_project_detection.py index 5213e10ba3..62772740cd 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_private_project_detection.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/action_private_project_detection.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import ServerAction +from openpype_modules.ftrack.lib import ServerAction class PrivateProjectDetectionAction(ServerAction): diff --git a/openpype/modules/ftrack/event_handlers_server/action_push_frame_values_to_task.py b/openpype/modules/default_modules/ftrack/event_handlers_server/action_push_frame_values_to_task.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/action_push_frame_values_to_task.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/action_push_frame_values_to_task.py index b38e18d089..3f63ce6fac 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_push_frame_values_to_task.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/action_push_frame_values_to_task.py @@ -2,7 +2,7 @@ import sys import json import collections import ftrack_api -from openpype.modules.ftrack.lib import ServerAction +from openpype_modules.ftrack.lib import ServerAction class PushHierValuesToNonHier(ServerAction): diff --git a/openpype/modules/ftrack/event_handlers_server/action_sync_to_avalon.py b/openpype/modules/default_modules/ftrack/event_handlers_server/action_sync_to_avalon.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_server/action_sync_to_avalon.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/action_sync_to_avalon.py index 8f78f998ac..d449c4b7df 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_sync_to_avalon.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/action_sync_to_avalon.py @@ -1,8 +1,8 @@ import time import traceback -from openpype.modules.ftrack.lib import ServerAction -from openpype.modules.ftrack.lib.avalon_sync import SyncEntitiesFactory +from openpype_modules.ftrack.lib import ServerAction +from openpype_modules.ftrack.lib.avalon_sync import SyncEntitiesFactory class SyncToAvalonServer(ServerAction): diff --git a/openpype/modules/ftrack/event_handlers_server/event_del_avalon_id_from_new.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_del_avalon_id_from_new.py similarity index 90% rename from openpype/modules/ftrack/event_handlers_server/event_del_avalon_id_from_new.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_del_avalon_id_from_new.py index 078596cc2e..35b5d809fd 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_del_avalon_id_from_new.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_del_avalon_id_from_new.py @@ -1,6 +1,6 @@ -from openpype.modules.ftrack.lib import BaseEvent -from openpype.modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY -from openpype.modules.ftrack.event_handlers_server.event_sync_to_avalon import ( +from openpype_modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY +from openpype_modules.ftrack.event_handlers_server.event_sync_to_avalon import ( SyncToAvalonEvent ) diff --git a/openpype/modules/ftrack/event_handlers_server/event_first_version_status.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_first_version_status.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_first_version_status.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_first_version_status.py index 511f62a207..ecc6c95d90 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_first_version_status.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_first_version_status.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class FirstVersionStatus(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_next_task_update.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_next_task_update.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_next_task_update.py index ad62beb296..a65ae46545 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_next_task_update.py @@ -1,5 +1,5 @@ import collections -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class NextTaskUpdate(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py index 81719258e1..10b165e7f6 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py @@ -2,7 +2,7 @@ import collections import datetime import ftrack_api -from openpype.modules.ftrack.lib import ( +from openpype_modules.ftrack.lib import ( BaseEvent, query_custom_attributes ) diff --git a/openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_radio_buttons.py similarity index 96% rename from openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_radio_buttons.py index 1ebd7b68d2..99ad3aec37 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_radio_buttons.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_radio_buttons.py @@ -1,5 +1,5 @@ import ftrack_api -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class RadioButtons(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_sync_to_avalon.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_sync_to_avalon.py index 1dd056adee..93a0404c0b 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_sync_to_avalon.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_sync_to_avalon.py @@ -17,7 +17,7 @@ import ftrack_api from avalon import schema from avalon.api import AvalonMongoDB -from openpype.modules.ftrack.lib import ( +from openpype_modules.ftrack.lib import ( get_openpype_attr, CUST_ATTR_ID_KEY, CUST_ATTR_AUTO_SYNC, diff --git a/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_task_to_parent_status.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_task_to_parent_status.py index 4192a4bed0..a0e039926e 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_task_to_parent_status.py @@ -1,5 +1,5 @@ import collections -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class TaskStatusToParent(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_task_to_version_status.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_task_to_version_status.py index f2d3723021..b77849c678 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_task_to_version_status.py @@ -1,5 +1,5 @@ import collections -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class TaskToVersionStatus(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_thumbnail_updates.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_thumbnail_updates.py index cbeeeee5c5..64673f792c 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_thumbnail_updates.py @@ -1,5 +1,5 @@ import collections -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class ThumbnailEvents(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_server/event_user_assigment.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_user_assigment.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_server/event_user_assigment.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_user_assigment.py index a0734e14a1..efc1e76775 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_user_assigment.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_user_assigment.py @@ -2,8 +2,8 @@ import os import re import subprocess -from openpype.modules.ftrack.lib import BaseEvent -from openpype.modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY +from openpype_modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY from avalon.api import AvalonMongoDB from bson.objectid import ObjectId diff --git a/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py b/openpype/modules/default_modules/ftrack/event_handlers_server/event_version_to_task_statuses.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py rename to openpype/modules/default_modules/ftrack/event_handlers_server/event_version_to_task_statuses.py index f215bedcc2..e36c3eecd9 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_server/event_version_to_task_statuses.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import BaseEvent +from openpype_modules.ftrack.lib import BaseEvent class VersionToTaskStatus(BaseEvent): diff --git a/openpype/modules/ftrack/event_handlers_user/action_applications.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_applications.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_applications.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_applications.py index 74d14c2fc4..6d45d43958 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_applications.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_applications.py @@ -1,7 +1,7 @@ import os from uuid import uuid4 -from openpype.modules.ftrack.lib import BaseAction +from openpype_modules.ftrack.lib import BaseAction from openpype.lib import ( ApplicationManager, ApplicationLaunchFailed, diff --git a/openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_batch_task_creation.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_batch_task_creation.py index b9f0e7c5d3..c7fb1af98b 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_batch_task_creation.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_batch_task_creation.py @@ -2,7 +2,7 @@ Taken from https://github.com/tokejepsen/ftrack-hooks/tree/master/batch_tasks """ -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class BatchTasksAction(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_clean_hierarchical_attributes.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_clean_hierarchical_attributes.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_user/action_clean_hierarchical_attributes.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_clean_hierarchical_attributes.py index 45cc9adf55..dc97ed972d 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_clean_hierarchical_attributes.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_clean_hierarchical_attributes.py @@ -1,6 +1,6 @@ import collections import ftrack_api -from openpype.modules.ftrack.lib import ( +from openpype_modules.ftrack.lib import ( BaseAction, statics_icon, get_openpype_attr diff --git a/openpype/modules/ftrack/event_handlers_user/action_client_review_sort.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_client_review_sort.py similarity index 97% rename from openpype/modules/ftrack/event_handlers_user/action_client_review_sort.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_client_review_sort.py index 7c9a2881d6..5ad5f10e8e 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_client_review_sort.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_client_review_sort.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon try: from functools import cmp_to_key except Exception: diff --git a/openpype/modules/ftrack/event_handlers_user/action_component_open.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_component_open.py similarity index 96% rename from openpype/modules/ftrack/event_handlers_user/action_component_open.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_component_open.py index b3cdac0722..c731713c10 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_component_open.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_component_open.py @@ -1,7 +1,7 @@ import os import sys import subprocess -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class ComponentOpen(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_create_cust_attrs.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_create_cust_attrs.py index 63605eda5e..3869d8ad08 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_create_cust_attrs.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_create_cust_attrs.py @@ -2,7 +2,7 @@ import collections import json import arrow import ftrack_api -from openpype.modules.ftrack.lib import ( +from openpype_modules.ftrack.lib import ( BaseAction, statics_icon, @@ -43,7 +43,7 @@ dictionary level, task's attributes are nested more. group (string) - name of group - - based on attribute `openpype.modules.ftrack.lib.CUST_ATTR_GROUP` + - based on attribute `openpype_modules.ftrack.lib.CUST_ATTR_GROUP` - "pype" by default *** Required *************************************************************** diff --git a/openpype/modules/ftrack/event_handlers_user/action_create_folders.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_create_folders.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_create_folders.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_create_folders.py index 075b8d3d25..994dbd90e4 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_create_folders.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_create_folders.py @@ -1,5 +1,5 @@ import os -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon from avalon import lib as avalonlib from openpype.api import ( Anatomy, diff --git a/openpype/modules/ftrack/event_handlers_user/action_create_project_structure.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_create_project_structure.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_create_project_structure.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_create_project_structure.py index 035a1c60de..121c9f652b 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_create_project_structure.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_create_project_structure.py @@ -2,7 +2,7 @@ import os import re import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon from openpype.api import Anatomy, get_project_settings diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_delete_asset.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_delete_asset.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_delete_asset.py index c20491349f..f860065b26 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_asset.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_delete_asset.py @@ -4,7 +4,7 @@ from datetime import datetime from queue import Queue from bson.objectid import ObjectId -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon from avalon.api import AvalonMongoDB diff --git a/openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_delete_old_versions.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_delete_old_versions.py index dbddc7a95e..063f086e9c 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delete_old_versions.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_delete_old_versions.py @@ -5,7 +5,7 @@ import uuid import clique from pymongo import UpdateOne -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon from avalon.api import AvalonMongoDB from openpype.api import Anatomy diff --git a/openpype/modules/ftrack/event_handlers_user/action_delivery.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_delivery.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_delivery.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_delivery.py index 2e7599647a..1f28b18900 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_delivery.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_delivery.py @@ -6,8 +6,8 @@ import collections from bson.objectid import ObjectId from openpype.api import Anatomy, config -from openpype.modules.ftrack.lib import BaseAction, statics_icon -from openpype.modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY +from openpype_modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY from openpype.lib.delivery import ( path_from_representation, get_format_dict, diff --git a/openpype/modules/ftrack/event_handlers_user/action_djvview.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_djvview.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_user/action_djvview.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_djvview.py index c05fbed2d0..c603a2d200 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_djvview.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_djvview.py @@ -1,7 +1,7 @@ import os import subprocess from operator import itemgetter -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class DJVViewAction(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_job_killer.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_job_killer.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_user/action_job_killer.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_job_killer.py index 47ed1e7895..af24e0280d 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_job_killer.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_job_killer.py @@ -1,5 +1,5 @@ import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class JobKiller(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_multiple_notes.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_multiple_notes.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_user/action_multiple_notes.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_multiple_notes.py index f5af044de0..825fd97b06 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_multiple_notes.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_multiple_notes.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class MultipleNotes(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_prepare_project.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_prepare_project.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_prepare_project.py index 4b42500e8f..87d3329179 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_prepare_project.py @@ -4,7 +4,7 @@ from avalon.api import AvalonMongoDB from openpype.api import ProjectSettings from openpype.lib import create_project -from openpype.modules.ftrack.lib import ( +from openpype_modules.ftrack.lib import ( BaseAction, statics_icon, get_openpype_attr, diff --git a/openpype/modules/ftrack/event_handlers_user/action_rv.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_rv.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_rv.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_rv.py index 3172b74261..71d790f7e7 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_rv.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_rv.py @@ -3,7 +3,7 @@ import subprocess import traceback import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon import ftrack_api from avalon import io, api diff --git a/openpype/modules/ftrack/event_handlers_user/action_seed.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_seed.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_seed.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_seed.py index 1f01f0af1d..4021d70c0a 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_seed.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_seed.py @@ -1,6 +1,6 @@ import os from operator import itemgetter -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class SeedDebugProject(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py similarity index 99% rename from openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py index 4464e51d3d..4820925844 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_store_thumbnails_to_avalon.py @@ -4,11 +4,11 @@ import json import requests from bson.objectid import ObjectId -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon from openpype.api import Anatomy from avalon.api import AvalonMongoDB -from openpype.modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY +from openpype_modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY class StoreThumbnailsToAvalon(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_sync_to_avalon.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_sync_to_avalon.py similarity index 98% rename from openpype/modules/ftrack/event_handlers_user/action_sync_to_avalon.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_sync_to_avalon.py index 89fac7cf80..d6ca561bbe 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_sync_to_avalon.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_sync_to_avalon.py @@ -1,8 +1,8 @@ import time import traceback -from openpype.modules.ftrack.lib import BaseAction, statics_icon -from openpype.modules.ftrack.lib.avalon_sync import SyncEntitiesFactory +from openpype_modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib.avalon_sync import SyncEntitiesFactory class SyncToAvalonLocal(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_test.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_test.py similarity index 89% rename from openpype/modules/ftrack/event_handlers_user/action_test.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_test.py index 206c67de50..bd71ba5bf9 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_test.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_test.py @@ -1,4 +1,4 @@ -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class TestAction(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_thumbnail_to_childern.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_thumbnail_to_childern.py similarity index 96% rename from openpype/modules/ftrack/event_handlers_user/action_thumbnail_to_childern.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_thumbnail_to_childern.py index a12f25b57d..3b90960160 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_thumbnail_to_childern.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_thumbnail_to_childern.py @@ -1,5 +1,5 @@ import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class ThumbToChildren(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_thumbnail_to_parent.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_thumbnail_to_parent.py similarity index 97% rename from openpype/modules/ftrack/event_handlers_user/action_thumbnail_to_parent.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_thumbnail_to_parent.py index 284723bb0f..2f0110b7aa 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_thumbnail_to_parent.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_thumbnail_to_parent.py @@ -1,5 +1,5 @@ import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction, statics_icon class ThumbToParent(BaseAction): diff --git a/openpype/modules/ftrack/event_handlers_user/action_where_run_ask.py b/openpype/modules/default_modules/ftrack/event_handlers_user/action_where_run_ask.py similarity index 97% rename from openpype/modules/ftrack/event_handlers_user/action_where_run_ask.py rename to openpype/modules/default_modules/ftrack/event_handlers_user/action_where_run_ask.py index 2c427cfff7..0d69913996 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_where_run_ask.py +++ b/openpype/modules/default_modules/ftrack/event_handlers_user/action_where_run_ask.py @@ -2,7 +2,7 @@ import platform import socket import getpass -from openpype.modules.ftrack.lib import BaseAction, statics_icon +from openpype_modules.ftrack.lib import BaseAction class ActionWhereIRun(BaseAction): diff --git a/openpype/modules/ftrack/ftrack_module.py b/openpype/modules/default_modules/ftrack/ftrack_module.py similarity index 96% rename from openpype/modules/ftrack/ftrack_module.py rename to openpype/modules/default_modules/ftrack/ftrack_module.py index ee139a500e..1de152535c 100644 --- a/openpype/modules/ftrack/ftrack_module.py +++ b/openpype/modules/default_modules/ftrack/ftrack_module.py @@ -1,35 +1,24 @@ import os import json import collections -from abc import ABCMeta, abstractmethod -import six import openpype -from openpype.modules import ( - PypeModule, +from openpype.modules import OpenPypeModule + +from openpype_interfaces import ( ITrayModule, IPluginPaths, ITimersManager, ILaunchHookPaths, - ISettingsChangeListener + ISettingsChangeListener, + IFtrackEventHandlerPaths ) from openpype.settings import SaveWarningExc FTRACK_MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) -@six.add_metaclass(ABCMeta) -class IFtrackEventHandlerPaths: - """Other modules interface to return paths to ftrack event handlers. - - Expected output is dictionary with "server" and "user" keys. - """ - @abstractmethod - def get_event_handler_paths(self): - pass - - class FtrackModule( - PypeModule, + OpenPypeModule, ITrayModule, IPluginPaths, ITimersManager, @@ -242,7 +231,7 @@ class FtrackModule( return import ftrack_api - from openpype.modules.ftrack.lib import get_openpype_attr + from openpype_modules.ftrack.lib import get_openpype_attr try: session = self.create_ftrack_session() diff --git a/openpype/modules/ftrack/ftrack_server/__init__.py b/openpype/modules/default_modules/ftrack/ftrack_server/__init__.py similarity index 100% rename from openpype/modules/ftrack/ftrack_server/__init__.py rename to openpype/modules/default_modules/ftrack/ftrack_server/__init__.py diff --git a/openpype/modules/ftrack/ftrack_server/event_server_cli.py b/openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py similarity index 97% rename from openpype/modules/ftrack/ftrack_server/event_server_cli.py rename to openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py index 8bba22b475..d8e4d05580 100644 --- a/openpype/modules/ftrack/ftrack_server/event_server_cli.py +++ b/openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py @@ -18,17 +18,10 @@ from openpype.lib import ( get_pype_execute_args, OpenPypeMongoConnection ) -from openpype.modules.ftrack import FTRACK_MODULE_DIR -from openpype.modules.ftrack.lib import ( - credentials, - get_ftrack_url_from_settings -) -from openpype.modules.ftrack.ftrack_server.lib import ( - check_ftrack_url, - get_ftrack_event_mongo_info -) - -from openpype.modules.ftrack.ftrack_server import socket_thread +from openpype_modules.ftrack import FTRACK_MODULE_DIR +from openpype_modules.ftrack.lib import credentials +from openpype_modules.ftrack.ftrack_server.lib import check_ftrack_url +from openpype_modules.ftrack.ftrack_server import socket_thread class MongoPermissionsError(Exception): diff --git a/openpype/modules/ftrack/ftrack_server/ftrack_server.py b/openpype/modules/default_modules/ftrack/ftrack_server/ftrack_server.py similarity index 100% rename from openpype/modules/ftrack/ftrack_server/ftrack_server.py rename to openpype/modules/default_modules/ftrack/ftrack_server/ftrack_server.py diff --git a/openpype/modules/ftrack/ftrack_server/lib.py b/openpype/modules/default_modules/ftrack/ftrack_server/lib.py similarity index 99% rename from openpype/modules/ftrack/ftrack_server/lib.py rename to openpype/modules/default_modules/ftrack/ftrack_server/lib.py index 88f849e765..e80d6a3a6b 100644 --- a/openpype/modules/ftrack/ftrack_server/lib.py +++ b/openpype/modules/default_modules/ftrack/ftrack_server/lib.py @@ -22,7 +22,7 @@ try: from weakref import WeakMethod except ImportError: from ftrack_api._weakref import WeakMethod -from openpype.modules.ftrack.lib import get_ftrack_event_mongo_info +from openpype_modules.ftrack.lib import get_ftrack_event_mongo_info from openpype.lib import OpenPypeMongoConnection from openpype.api import Logger diff --git a/openpype/modules/ftrack/ftrack_server/socket_thread.py b/openpype/modules/default_modules/ftrack/ftrack_server/socket_thread.py similarity index 100% rename from openpype/modules/ftrack/ftrack_server/socket_thread.py rename to openpype/modules/default_modules/ftrack/ftrack_server/socket_thread.py diff --git a/openpype/modules/default_modules/ftrack/interfaces.py b/openpype/modules/default_modules/ftrack/interfaces.py new file mode 100644 index 0000000000..16ce0d2e62 --- /dev/null +++ b/openpype/modules/default_modules/ftrack/interfaces.py @@ -0,0 +1,12 @@ +from abc import abstractmethod +from openpype.modules import OpenPypeInterface + + +class IFtrackEventHandlerPaths(OpenPypeInterface): + """Other modules interface to return paths to ftrack event handlers. + + Expected output is dictionary with "server" and "user" keys. + """ + @abstractmethod + def get_event_handler_paths(self): + pass diff --git a/openpype/modules/ftrack/launch_hooks/post_ftrack_changes.py b/openpype/modules/default_modules/ftrack/launch_hooks/post_ftrack_changes.py similarity index 100% rename from openpype/modules/ftrack/launch_hooks/post_ftrack_changes.py rename to openpype/modules/default_modules/ftrack/launch_hooks/post_ftrack_changes.py diff --git a/openpype/modules/ftrack/launch_hooks/pre_python2_vendor.py b/openpype/modules/default_modules/ftrack/launch_hooks/pre_python2_vendor.py similarity index 96% rename from openpype/modules/ftrack/launch_hooks/pre_python2_vendor.py rename to openpype/modules/default_modules/ftrack/launch_hooks/pre_python2_vendor.py index d34b6533fb..0dd894bebf 100644 --- a/openpype/modules/ftrack/launch_hooks/pre_python2_vendor.py +++ b/openpype/modules/default_modules/ftrack/launch_hooks/pre_python2_vendor.py @@ -1,6 +1,6 @@ import os from openpype.lib import PreLaunchHook -from openpype.modules.ftrack import FTRACK_MODULE_DIR +from openpype_modules.ftrack import FTRACK_MODULE_DIR class PrePython2Support(PreLaunchHook): diff --git a/openpype/modules/ftrack/lib/__init__.py b/openpype/modules/default_modules/ftrack/lib/__init__.py similarity index 100% rename from openpype/modules/ftrack/lib/__init__.py rename to openpype/modules/default_modules/ftrack/lib/__init__.py diff --git a/openpype/modules/ftrack/lib/avalon_sync.py b/openpype/modules/default_modules/ftrack/lib/avalon_sync.py similarity index 100% rename from openpype/modules/ftrack/lib/avalon_sync.py rename to openpype/modules/default_modules/ftrack/lib/avalon_sync.py diff --git a/openpype/modules/ftrack/lib/constants.py b/openpype/modules/default_modules/ftrack/lib/constants.py similarity index 100% rename from openpype/modules/ftrack/lib/constants.py rename to openpype/modules/default_modules/ftrack/lib/constants.py diff --git a/openpype/modules/ftrack/lib/credentials.py b/openpype/modules/default_modules/ftrack/lib/credentials.py similarity index 100% rename from openpype/modules/ftrack/lib/credentials.py rename to openpype/modules/default_modules/ftrack/lib/credentials.py diff --git a/openpype/modules/ftrack/lib/custom_attributes.json b/openpype/modules/default_modules/ftrack/lib/custom_attributes.json similarity index 100% rename from openpype/modules/ftrack/lib/custom_attributes.json rename to openpype/modules/default_modules/ftrack/lib/custom_attributes.json diff --git a/openpype/modules/ftrack/lib/custom_attributes.py b/openpype/modules/default_modules/ftrack/lib/custom_attributes.py similarity index 100% rename from openpype/modules/ftrack/lib/custom_attributes.py rename to openpype/modules/default_modules/ftrack/lib/custom_attributes.py diff --git a/openpype/modules/ftrack/lib/ftrack_action_handler.py b/openpype/modules/default_modules/ftrack/lib/ftrack_action_handler.py similarity index 100% rename from openpype/modules/ftrack/lib/ftrack_action_handler.py rename to openpype/modules/default_modules/ftrack/lib/ftrack_action_handler.py diff --git a/openpype/modules/ftrack/lib/ftrack_base_handler.py b/openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py similarity index 99% rename from openpype/modules/ftrack/lib/ftrack_base_handler.py rename to openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py index 7b7ebfb099..7027154d86 100644 --- a/openpype/modules/ftrack/lib/ftrack_base_handler.py +++ b/openpype/modules/default_modules/ftrack/lib/ftrack_base_handler.py @@ -10,7 +10,7 @@ from openpype.api import Logger from openpype.settings import get_project_settings import ftrack_api -from openpype.modules.ftrack import ftrack_server +from openpype_modules.ftrack import ftrack_server class MissingPermision(Exception): diff --git a/openpype/modules/ftrack/lib/ftrack_event_handler.py b/openpype/modules/default_modules/ftrack/lib/ftrack_event_handler.py similarity index 100% rename from openpype/modules/ftrack/lib/ftrack_event_handler.py rename to openpype/modules/default_modules/ftrack/lib/ftrack_event_handler.py diff --git a/openpype/modules/ftrack/lib/settings.py b/openpype/modules/default_modules/ftrack/lib/settings.py similarity index 100% rename from openpype/modules/ftrack/lib/settings.py rename to openpype/modules/default_modules/ftrack/lib/settings.py diff --git a/openpype/modules/ftrack/plugins/_unused_publish/integrate_ftrack_comments.py b/openpype/modules/default_modules/ftrack/plugins/_unused_publish/integrate_ftrack_comments.py similarity index 100% rename from openpype/modules/ftrack/plugins/_unused_publish/integrate_ftrack_comments.py rename to openpype/modules/default_modules/ftrack/plugins/_unused_publish/integrate_ftrack_comments.py diff --git a/openpype/modules/ftrack/plugins/publish/collect_ftrack_api.py b/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/collect_ftrack_api.py rename to openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_api.py diff --git a/openpype/modules/ftrack/plugins/publish/collect_ftrack_family.py b/openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_family.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/collect_ftrack_family.py rename to openpype/modules/default_modules/ftrack/plugins/publish/collect_ftrack_family.py diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_api.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_api.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/integrate_ftrack_api.py rename to openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_api.py diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_component_overwrite.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_component_overwrite.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/integrate_ftrack_component_overwrite.py rename to openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_component_overwrite.py diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_instances.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/integrate_ftrack_instances.py rename to openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_instances.py diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_note.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_note.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/integrate_ftrack_note.py rename to openpype/modules/default_modules/ftrack/plugins/publish/integrate_ftrack_note.py diff --git a/openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py similarity index 99% rename from openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py rename to openpype/modules/default_modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py index 118a73a636..fbd64d9f70 100644 --- a/openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py +++ b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py @@ -4,12 +4,12 @@ import six import pyblish.api from avalon import io -# Copy of constant `openpype.modules.ftrack.lib.avalon_sync.CUST_ATTR_AUTO_SYNC` +# Copy of constant `openpype_modules.ftrack.lib.avalon_sync.CUST_ATTR_AUTO_SYNC` CUST_ATTR_AUTO_SYNC = "avalon_auto_sync" CUST_ATTR_GROUP = "openpype" -# Copy of `get_pype_attr` from openpype.modules.ftrack.lib +# Copy of `get_pype_attr` from openpype_modules.ftrack.lib # TODO import from openpype's ftrack module when possible to not break Python 2 def get_pype_attr(session, split_hierarchical=True): custom_attributes = [] diff --git a/openpype/modules/ftrack/plugins/publish/integrate_remove_components.py b/openpype/modules/default_modules/ftrack/plugins/publish/integrate_remove_components.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/integrate_remove_components.py rename to openpype/modules/default_modules/ftrack/plugins/publish/integrate_remove_components.py diff --git a/openpype/modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py b/openpype/modules/default_modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py similarity index 100% rename from openpype/modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py rename to openpype/modules/default_modules/ftrack/plugins/publish/validate_custom_ftrack_attributes.py diff --git a/openpype/modules/default_modules/ftrack/python2_vendor/arrow b/openpype/modules/default_modules/ftrack/python2_vendor/arrow new file mode 160000 index 0000000000..b746fedf72 --- /dev/null +++ b/openpype/modules/default_modules/ftrack/python2_vendor/arrow @@ -0,0 +1 @@ +Subproject commit b746fedf7286c3755a46f07ab72f4c414cd41fc0 diff --git a/openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/__init__.py b/openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/__init__.py similarity index 100% rename from openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/__init__.py rename to openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/__init__.py diff --git a/openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/__init__.py b/openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/__init__.py similarity index 100% rename from openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/__init__.py rename to openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/__init__.py diff --git a/openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/helpers.py b/openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/helpers.py similarity index 100% rename from openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/helpers.py rename to openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/configparser/helpers.py diff --git a/openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/functools_lru_cache.py b/openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/functools_lru_cache.py similarity index 100% rename from openpype/modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/functools_lru_cache.py rename to openpype/modules/default_modules/ftrack/python2_vendor/backports.functools_lru_cache/backports/functools_lru_cache.py diff --git a/openpype/modules/ftrack/python2_vendor/builtins/builtins/__init__.py b/openpype/modules/default_modules/ftrack/python2_vendor/builtins/builtins/__init__.py similarity index 100% rename from openpype/modules/ftrack/python2_vendor/builtins/builtins/__init__.py rename to openpype/modules/default_modules/ftrack/python2_vendor/builtins/builtins/__init__.py diff --git a/openpype/modules/default_modules/ftrack/python2_vendor/ftrack-python-api b/openpype/modules/default_modules/ftrack/python2_vendor/ftrack-python-api new file mode 160000 index 0000000000..d277f474ab --- /dev/null +++ b/openpype/modules/default_modules/ftrack/python2_vendor/ftrack-python-api @@ -0,0 +1 @@ +Subproject commit d277f474ab016e7b53479c36af87cb861d0cc53e diff --git a/openpype/modules/ftrack/scripts/sub_event_processor.py b/openpype/modules/default_modules/ftrack/scripts/sub_event_processor.py similarity index 95% rename from openpype/modules/ftrack/scripts/sub_event_processor.py rename to openpype/modules/default_modules/ftrack/scripts/sub_event_processor.py index 0d94fa7264..51b45eb93b 100644 --- a/openpype/modules/ftrack/scripts/sub_event_processor.py +++ b/openpype/modules/default_modules/ftrack/scripts/sub_event_processor.py @@ -4,8 +4,8 @@ import signal import socket import datetime -from openpype.modules.ftrack.ftrack_server.ftrack_server import FtrackServer -from openpype.modules.ftrack.ftrack_server.lib import ( +from openpype_modules.ftrack.ftrack_server.ftrack_server import FtrackServer +from openpype_modules.ftrack.ftrack_server.lib import ( SocketSession, ProcessEventHub, TOPIC_STATUS_SERVER diff --git a/openpype/modules/ftrack/scripts/sub_event_status.py b/openpype/modules/default_modules/ftrack/scripts/sub_event_status.py similarity index 98% rename from openpype/modules/ftrack/scripts/sub_event_status.py rename to openpype/modules/default_modules/ftrack/scripts/sub_event_status.py index 24b9bfb789..8a2733b635 100644 --- a/openpype/modules/ftrack/scripts/sub_event_status.py +++ b/openpype/modules/default_modules/ftrack/scripts/sub_event_status.py @@ -7,8 +7,8 @@ import socket import datetime import ftrack_api -from openpype.modules.ftrack.ftrack_server.ftrack_server import FtrackServer -from openpype.modules.ftrack.ftrack_server.lib import ( +from openpype_modules.ftrack.ftrack_server.ftrack_server import FtrackServer +from openpype_modules.ftrack.ftrack_server.lib import ( SocketSession, StatusEventHub, TOPIC_STATUS_SERVER, diff --git a/openpype/modules/ftrack/scripts/sub_event_storer.py b/openpype/modules/default_modules/ftrack/scripts/sub_event_storer.py similarity index 96% rename from openpype/modules/ftrack/scripts/sub_event_storer.py rename to openpype/modules/default_modules/ftrack/scripts/sub_event_storer.py index 6e2990ef0b..a8649e0ccc 100644 --- a/openpype/modules/ftrack/scripts/sub_event_storer.py +++ b/openpype/modules/default_modules/ftrack/scripts/sub_event_storer.py @@ -6,14 +6,14 @@ import socket import pymongo import ftrack_api -from openpype.modules.ftrack.ftrack_server.ftrack_server import FtrackServer -from openpype.modules.ftrack.ftrack_server.lib import ( +from openpype_modules.ftrack.ftrack_server.ftrack_server import FtrackServer +from openpype_modules.ftrack.ftrack_server.lib import ( SocketSession, StorerEventHub, TOPIC_STATUS_SERVER, TOPIC_STATUS_SERVER_RESULT ) -from openpype.modules.ftrack.lib import get_ftrack_event_mongo_info +from openpype_modules.ftrack.lib import get_ftrack_event_mongo_info from openpype.lib import OpenPypeMongoConnection from openpype.api import Logger diff --git a/openpype/modules/ftrack/scripts/sub_legacy_server.py b/openpype/modules/default_modules/ftrack/scripts/sub_legacy_server.py similarity index 97% rename from openpype/modules/ftrack/scripts/sub_legacy_server.py rename to openpype/modules/default_modules/ftrack/scripts/sub_legacy_server.py index ae6aefa908..e3a623c376 100644 --- a/openpype/modules/ftrack/scripts/sub_legacy_server.py +++ b/openpype/modules/default_modules/ftrack/scripts/sub_legacy_server.py @@ -7,7 +7,7 @@ import threading import ftrack_api from openpype.api import Logger from openpype.modules import ModulesManager -from openpype.modules.ftrack.ftrack_server.ftrack_server import FtrackServer +from openpype_modules.ftrack.ftrack_server.ftrack_server import FtrackServer log = Logger().get_logger("Event Server Legacy") diff --git a/openpype/modules/ftrack/scripts/sub_user_server.py b/openpype/modules/default_modules/ftrack/scripts/sub_user_server.py similarity index 93% rename from openpype/modules/ftrack/scripts/sub_user_server.py rename to openpype/modules/default_modules/ftrack/scripts/sub_user_server.py index 971a31b703..a3701a0950 100644 --- a/openpype/modules/ftrack/scripts/sub_user_server.py +++ b/openpype/modules/default_modules/ftrack/scripts/sub_user_server.py @@ -2,8 +2,8 @@ import sys import signal import socket -from openpype.modules.ftrack.ftrack_server.ftrack_server import FtrackServer -from openpype.modules.ftrack.ftrack_server.lib import ( +from openpype_modules.ftrack.ftrack_server.ftrack_server import FtrackServer +from openpype_modules.ftrack.ftrack_server.lib import ( SocketSession, SocketBaseEventHub ) diff --git a/openpype/modules/ftrack/tray/__init__.py b/openpype/modules/default_modules/ftrack/tray/__init__.py similarity index 100% rename from openpype/modules/ftrack/tray/__init__.py rename to openpype/modules/default_modules/ftrack/tray/__init__.py diff --git a/openpype/modules/ftrack/tray/ftrack_tray.py b/openpype/modules/default_modules/ftrack/tray/ftrack_tray.py similarity index 100% rename from openpype/modules/ftrack/tray/ftrack_tray.py rename to openpype/modules/default_modules/ftrack/tray/ftrack_tray.py diff --git a/openpype/modules/ftrack/tray/login_dialog.py b/openpype/modules/default_modules/ftrack/tray/login_dialog.py similarity index 99% rename from openpype/modules/ftrack/tray/login_dialog.py rename to openpype/modules/default_modules/ftrack/tray/login_dialog.py index cc5689bee5..6384621c8e 100644 --- a/openpype/modules/ftrack/tray/login_dialog.py +++ b/openpype/modules/default_modules/ftrack/tray/login_dialog.py @@ -1,7 +1,7 @@ import os import requests from openpype import style -from openpype.modules.ftrack.lib import credentials +from openpype_modules.ftrack.lib import credentials from . import login_tools from openpype import resources from Qt import QtCore, QtGui, QtWidgets diff --git a/openpype/modules/ftrack/tray/login_tools.py b/openpype/modules/default_modules/ftrack/tray/login_tools.py similarity index 100% rename from openpype/modules/ftrack/tray/login_tools.py rename to openpype/modules/default_modules/ftrack/tray/login_tools.py diff --git a/openpype/modules/idle_manager/__init__.py b/openpype/modules/default_modules/idle_manager/__init__.py similarity index 54% rename from openpype/modules/idle_manager/__init__.py rename to openpype/modules/default_modules/idle_manager/__init__.py index 651f360c50..9d6e10bf39 100644 --- a/openpype/modules/idle_manager/__init__.py +++ b/openpype/modules/default_modules/idle_manager/__init__.py @@ -1,10 +1,8 @@ from .idle_module import ( - IdleManager, - IIdleManager + IdleManager ) __all__ = ( "IdleManager", - "IIdleManager" ) diff --git a/openpype/modules/idle_manager/idle_module.py b/openpype/modules/default_modules/idle_manager/idle_module.py similarity index 74% rename from openpype/modules/idle_manager/idle_module.py rename to openpype/modules/default_modules/idle_manager/idle_module.py index 5dd5160aa7..1a6d71a961 100644 --- a/openpype/modules/idle_manager/idle_module.py +++ b/openpype/modules/default_modules/idle_manager/idle_module.py @@ -1,38 +1,14 @@ import platform import collections -from abc import ABCMeta, abstractmethod -import six - -from openpype.modules import PypeModule, ITrayService +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( + ITrayService, + IIdleManager +) -@six.add_metaclass(ABCMeta) -class IIdleManager: - """Other modules interface to return callbacks by idle time in seconds. - - Expected output is dictionary with seconds as keys and callback/s - as value, value may be callback of list of callbacks. - EXAMPLE: - ``` - { - 60: self.on_minute_idle - } - ``` - """ - idle_manager = None - - @abstractmethod - def callbacks_by_idle_time(self): - pass - - @property - def idle_time(self): - if self.idle_manager: - return self.idle_manager.idle_time - - -class IdleManager(PypeModule, ITrayService): +class IdleManager(OpenPypeModule, ITrayService): """ Measure user's idle time in seconds. Idle time resets on keyboard/mouse input. Is able to emit signals at specific time idle. diff --git a/openpype/modules/idle_manager/idle_threads.py b/openpype/modules/default_modules/idle_manager/idle_threads.py similarity index 100% rename from openpype/modules/idle_manager/idle_threads.py rename to openpype/modules/default_modules/idle_manager/idle_threads.py diff --git a/openpype/modules/default_modules/idle_manager/interfaces.py b/openpype/modules/default_modules/idle_manager/interfaces.py new file mode 100644 index 0000000000..71cd17a64a --- /dev/null +++ b/openpype/modules/default_modules/idle_manager/interfaces.py @@ -0,0 +1,26 @@ +from abc import abstractmethod +from openpype.modules import OpenPypeInterface + + +class IIdleManager(OpenPypeInterface): + """Other modules interface to return callbacks by idle time in seconds. + + Expected output is dictionary with seconds as keys and callback/s + as value, value may be callback of list of callbacks. + EXAMPLE: + ``` + { + 60: self.on_minute_idle + } + ``` + """ + idle_manager = None + + @abstractmethod + def callbacks_by_idle_time(self): + pass + + @property + def idle_time(self): + if self.idle_manager: + return self.idle_manager.idle_time diff --git a/openpype/modules/default_modules/interfaces.py b/openpype/modules/default_modules/interfaces.py new file mode 100644 index 0000000000..a60c5fa606 --- /dev/null +++ b/openpype/modules/default_modules/interfaces.py @@ -0,0 +1,265 @@ +from abc import abstractmethod + +from openpype import resources + +from openpype.modules import OpenPypeInterface + + +class IPluginPaths(OpenPypeInterface): + """Module has plugin paths to return. + + Expected result is dictionary with keys "publish", "create", "load" or + "actions" and values as list or string. + { + "publish": ["path/to/publish_plugins"] + } + """ + # TODO validation of an output + @abstractmethod + def get_plugin_paths(self): + pass + + +class ILaunchHookPaths(OpenPypeInterface): + """Module has launch hook paths to return. + + Expected result is list of paths. + ["path/to/launch_hooks_dir"] + """ + + @abstractmethod + def get_launch_hook_paths(self): + pass + + +class ITrayModule(OpenPypeInterface): + """Module has special procedures when used in Pype Tray. + + IMPORTANT: + The module still must be usable if is not used in tray even if + would do nothing. + """ + tray_initialized = False + _tray_manager = None + + @abstractmethod + def tray_init(self): + """Initialization part of tray implementation. + + Triggered between `initialization` and `connect_with_modules`. + + This is where GUIs should be loaded or tray specific parts should be + prepared. + """ + pass + + @abstractmethod + def tray_menu(self, tray_menu): + """Add module's action to tray menu.""" + pass + + @abstractmethod + def tray_start(self): + """Start procedure in Pype tray.""" + pass + + @abstractmethod + def tray_exit(self): + """Cleanup method which is executed on tray shutdown. + + This is place where all threads should be shut. + """ + pass + + def execute_in_main_thread(self, callback): + """ Pushes callback to the queue or process 'callback' on a main thread + + Some callbacks need to be processed on main thread (menu actions + must be added on main thread or they won't get triggered etc.) + """ + if not self.tray_initialized: + # TODO Called without initialized tray, still main thread needed + try: + callback() + + except Exception: + self.log.warning( + "Failed to execute {} in main thread".format(callback), + exc_info=True) + + return + self.manager.tray_manager.execute_in_main_thread(callback) + + def show_tray_message(self, title, message, icon=None, msecs=None): + """Show tray message. + + Args: + title (str): Title of message. + message (str): Content of message. + icon (QSystemTrayIcon.MessageIcon): Message's icon. Default is + Information icon, may differ by Qt version. + msecs (int): Duration of message visibility in miliseconds. + Default is 10000 msecs, may differ by Qt version. + """ + if self._tray_manager: + self._tray_manager.show_tray_message(title, message, icon, msecs) + + def add_doubleclick_callback(self, callback): + if hasattr(self.manager, "add_doubleclick_callback"): + self.manager.add_doubleclick_callback(self, callback) + + +class ITrayAction(ITrayModule): + """Implementation of Tray action. + + Add action to tray menu which will trigger `on_action_trigger`. + It is expected to be used for showing tools. + + Methods `tray_start`, `tray_exit` and `connect_with_modules` are overriden + as it's not expected that action will use them. But it is possible if + necessary. + """ + + admin_action = False + _admin_submenu = None + + @property + @abstractmethod + def label(self): + """Service label showed in menu.""" + pass + + @abstractmethod + def on_action_trigger(self): + """What happens on actions click.""" + pass + + def tray_menu(self, tray_menu): + from Qt import QtWidgets + + if self.admin_action: + menu = self.admin_submenu(tray_menu) + action = QtWidgets.QAction(self.label, menu) + menu.addAction(action) + if not menu.menuAction().isVisible(): + menu.menuAction().setVisible(True) + + else: + action = QtWidgets.QAction(self.label, tray_menu) + tray_menu.addAction(action) + + action.triggered.connect(self.on_action_trigger) + + def tray_start(self): + return + + def tray_exit(self): + return + + @staticmethod + def admin_submenu(tray_menu): + if ITrayAction._admin_submenu is None: + from Qt import QtWidgets + + admin_submenu = QtWidgets.QMenu("Admin", tray_menu) + admin_submenu.menuAction().setVisible(False) + ITrayAction._admin_submenu = admin_submenu + return ITrayAction._admin_submenu + + +class ITrayService(ITrayModule): + # Module's property + menu_action = None + + # Class properties + _services_submenu = None + _icon_failed = None + _icon_running = None + _icon_idle = None + + @property + @abstractmethod + def label(self): + """Service label showed in menu.""" + pass + + # TODO be able to get any sort of information to show/print + # @abstractmethod + # def get_service_info(self): + # pass + + @staticmethod + def services_submenu(tray_menu): + if ITrayService._services_submenu is None: + from Qt import QtWidgets + + services_submenu = QtWidgets.QMenu("Services", tray_menu) + services_submenu.menuAction().setVisible(False) + ITrayService._services_submenu = services_submenu + return ITrayService._services_submenu + + @staticmethod + def add_service_action(action): + ITrayService._services_submenu.addAction(action) + if not ITrayService._services_submenu.menuAction().isVisible(): + ITrayService._services_submenu.menuAction().setVisible(True) + + @staticmethod + def _load_service_icons(): + from Qt import QtGui + + ITrayService._failed_icon = QtGui.QIcon( + resources.get_resource("icons", "circle_red.png") + ) + ITrayService._icon_running = QtGui.QIcon( + resources.get_resource("icons", "circle_green.png") + ) + ITrayService._icon_idle = QtGui.QIcon( + resources.get_resource("icons", "circle_orange.png") + ) + + @staticmethod + def get_icon_running(): + if ITrayService._icon_running is None: + ITrayService._load_service_icons() + return ITrayService._icon_running + + @staticmethod + def get_icon_idle(): + if ITrayService._icon_idle is None: + ITrayService._load_service_icons() + return ITrayService._icon_idle + + @staticmethod + def get_icon_failed(): + if ITrayService._failed_icon is None: + ITrayService._load_service_icons() + return ITrayService._failed_icon + + def tray_menu(self, tray_menu): + from Qt import QtWidgets + + action = QtWidgets.QAction( + self.label, + self.services_submenu(tray_menu) + ) + self.menu_action = action + + self.add_service_action(action) + + self.set_service_running_icon() + + def set_service_running_icon(self): + """Change icon of an QAction to green circle.""" + if self.menu_action: + self.menu_action.setIcon(self.get_icon_running()) + + def set_service_failed_icon(self): + """Change icon of an QAction to red circle.""" + if self.menu_action: + self.menu_action.setIcon(self.get_icon_failed()) + + def set_service_idle_icon(self): + """Change icon of an QAction to orange circle.""" + if self.menu_action: + self.menu_action.setIcon(self.get_icon_idle()) diff --git a/openpype/modules/launcher_action.py b/openpype/modules/default_modules/launcher_action.py similarity index 89% rename from openpype/modules/launcher_action.py rename to openpype/modules/default_modules/launcher_action.py index 0059ff021b..e3252e3842 100644 --- a/openpype/modules/launcher_action.py +++ b/openpype/modules/default_modules/launcher_action.py @@ -1,7 +1,8 @@ -from . import PypeModule, ITrayAction +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayAction -class LauncherAction(PypeModule, ITrayAction): +class LauncherAction(OpenPypeModule, ITrayAction): label = "Launcher" name = "launcher_tool" diff --git a/openpype/modules/log_viewer/__init__.py b/openpype/modules/default_modules/log_viewer/__init__.py similarity index 100% rename from openpype/modules/log_viewer/__init__.py rename to openpype/modules/default_modules/log_viewer/__init__.py diff --git a/openpype/modules/log_viewer/log_view_module.py b/openpype/modules/default_modules/log_viewer/log_view_module.py similarity index 89% rename from openpype/modules/log_viewer/log_view_module.py rename to openpype/modules/default_modules/log_viewer/log_view_module.py index dde482b04c..bc1a98f4ad 100644 --- a/openpype/modules/log_viewer/log_view_module.py +++ b/openpype/modules/default_modules/log_viewer/log_view_module.py @@ -1,8 +1,9 @@ from openpype.api import Logger -from .. import PypeModule, ITrayModule +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayModule -class LogViewModule(PypeModule, ITrayModule): +class LogViewModule(OpenPypeModule, ITrayModule): name = "log_viewer" def initialize(self, modules_settings): diff --git a/openpype/modules/log_viewer/tray/__init__.py b/openpype/modules/default_modules/log_viewer/tray/__init__.py similarity index 100% rename from openpype/modules/log_viewer/tray/__init__.py rename to openpype/modules/default_modules/log_viewer/tray/__init__.py diff --git a/openpype/modules/log_viewer/tray/app.py b/openpype/modules/default_modules/log_viewer/tray/app.py similarity index 100% rename from openpype/modules/log_viewer/tray/app.py rename to openpype/modules/default_modules/log_viewer/tray/app.py diff --git a/openpype/modules/log_viewer/tray/models.py b/openpype/modules/default_modules/log_viewer/tray/models.py similarity index 100% rename from openpype/modules/log_viewer/tray/models.py rename to openpype/modules/default_modules/log_viewer/tray/models.py diff --git a/openpype/modules/log_viewer/tray/widgets.py b/openpype/modules/default_modules/log_viewer/tray/widgets.py similarity index 100% rename from openpype/modules/log_viewer/tray/widgets.py rename to openpype/modules/default_modules/log_viewer/tray/widgets.py diff --git a/openpype/modules/muster/__init__.py b/openpype/modules/default_modules/muster/__init__.py similarity index 100% rename from openpype/modules/muster/__init__.py rename to openpype/modules/default_modules/muster/__init__.py diff --git a/openpype/modules/muster/muster.py b/openpype/modules/default_modules/muster/muster.py similarity index 97% rename from openpype/modules/muster/muster.py rename to openpype/modules/default_modules/muster/muster.py index 1a82926802..a0e72006af 100644 --- a/openpype/modules/muster/muster.py +++ b/openpype/modules/default_modules/muster/muster.py @@ -2,14 +2,14 @@ import os import json import appdirs import requests -from .. import ( - PypeModule, +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( ITrayModule, IWebServerRoutes ) -class MusterModule(PypeModule, ITrayModule, IWebServerRoutes): +class MusterModule(OpenPypeModule, ITrayModule, IWebServerRoutes): """ Module handling Muster Render credentials. This will display dialog asking for user credentials for Muster if not already specified. diff --git a/openpype/modules/muster/rest_api.py b/openpype/modules/default_modules/muster/rest_api.py similarity index 100% rename from openpype/modules/muster/rest_api.py rename to openpype/modules/default_modules/muster/rest_api.py diff --git a/openpype/modules/muster/widget_login.py b/openpype/modules/default_modules/muster/widget_login.py similarity index 100% rename from openpype/modules/muster/widget_login.py rename to openpype/modules/default_modules/muster/widget_login.py diff --git a/openpype/modules/project_manager_action.py b/openpype/modules/default_modules/project_manager_action.py similarity index 92% rename from openpype/modules/project_manager_action.py rename to openpype/modules/default_modules/project_manager_action.py index 1387aa258c..c1f984a8cb 100644 --- a/openpype/modules/project_manager_action.py +++ b/openpype/modules/default_modules/project_manager_action.py @@ -1,7 +1,8 @@ -from . import PypeModule, ITrayAction +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayAction -class ProjectManagerAction(PypeModule, ITrayAction): +class ProjectManagerAction(OpenPypeModule, ITrayAction): label = "Project Manager (beta)" name = "project_manager" admin_action = True diff --git a/openpype/modules/python_console_interpreter/__init__.py b/openpype/modules/default_modules/python_console_interpreter/__init__.py similarity index 100% rename from openpype/modules/python_console_interpreter/__init__.py rename to openpype/modules/default_modules/python_console_interpreter/__init__.py diff --git a/openpype/modules/python_console_interpreter/module.py b/openpype/modules/default_modules/python_console_interpreter/module.py similarity index 83% rename from openpype/modules/python_console_interpreter/module.py rename to openpype/modules/default_modules/python_console_interpreter/module.py index b37f35dfe0..f4df3fb6d8 100644 --- a/openpype/modules/python_console_interpreter/module.py +++ b/openpype/modules/default_modules/python_console_interpreter/module.py @@ -1,7 +1,8 @@ -from .. import PypeModule, ITrayAction +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayAction -class PythonInterpreterAction(PypeModule, ITrayAction): +class PythonInterpreterAction(OpenPypeModule, ITrayAction): label = "Console" name = "python_interpreter" admin_action = True @@ -25,7 +26,7 @@ class PythonInterpreterAction(PypeModule, ITrayAction): if self._interpreter_window: return - from openpype.modules.python_console_interpreter.window import ( + from openpype_modules.python_console_interpreter.window import ( PythonInterpreterWidget ) diff --git a/openpype/modules/python_console_interpreter/window/__init__.py b/openpype/modules/default_modules/python_console_interpreter/window/__init__.py similarity index 100% rename from openpype/modules/python_console_interpreter/window/__init__.py rename to openpype/modules/default_modules/python_console_interpreter/window/__init__.py diff --git a/openpype/modules/python_console_interpreter/window/widgets.py b/openpype/modules/default_modules/python_console_interpreter/window/widgets.py similarity index 100% rename from openpype/modules/python_console_interpreter/window/widgets.py rename to openpype/modules/default_modules/python_console_interpreter/window/widgets.py diff --git a/openpype/modules/default_modules/settings_module/__init__.py b/openpype/modules/default_modules/settings_module/__init__.py new file mode 100644 index 0000000000..95510eba9d --- /dev/null +++ b/openpype/modules/default_modules/settings_module/__init__.py @@ -0,0 +1,9 @@ +from .settings_action import ( + LocalSettingsAction, + SettingsAction +) + +__all__ = ( + "LocalSettingsAction", + "SettingsAction" +) diff --git a/openpype/modules/default_modules/settings_module/interfaces.py b/openpype/modules/default_modules/settings_module/interfaces.py new file mode 100644 index 0000000000..42db395649 --- /dev/null +++ b/openpype/modules/default_modules/settings_module/interfaces.py @@ -0,0 +1,30 @@ +from abc import abstractmethod +from openpype.modules import OpenPypeInterface + + +class ISettingsChangeListener(OpenPypeInterface): + """Module has plugin paths to return. + + Expected result is dictionary with keys "publish", "create", "load" or + "actions" and values as list or string. + { + "publish": ["path/to/publish_plugins"] + } + """ + @abstractmethod + def on_system_settings_save( + self, old_value, new_value, changes, new_value_metadata + ): + pass + + @abstractmethod + def on_project_settings_save( + self, old_value, new_value, changes, project_name, new_value_metadata + ): + pass + + @abstractmethod + def on_project_anatomy_save( + self, old_value, new_value, changes, project_name, new_value_metadata + ): + pass diff --git a/openpype/modules/settings_action.py b/openpype/modules/default_modules/settings_module/settings_action.py similarity index 80% rename from openpype/modules/settings_action.py rename to openpype/modules/default_modules/settings_module/settings_action.py index 9db4a252bc..7140c57bab 100644 --- a/openpype/modules/settings_action.py +++ b/openpype/modules/default_modules/settings_module/settings_action.py @@ -1,40 +1,8 @@ -from abc import ABCMeta, abstractmethod - -import six - -from . import PypeModule, ITrayAction +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayAction -@six.add_metaclass(ABCMeta) -class ISettingsChangeListener: - """Module has plugin paths to return. - - Expected result is dictionary with keys "publish", "create", "load" or - "actions" and values as list or string. - { - "publish": ["path/to/publish_plugins"] - } - """ - @abstractmethod - def on_system_settings_save( - self, old_value, new_value, changes, new_value_metadata - ): - pass - - @abstractmethod - def on_project_settings_save( - self, old_value, new_value, changes, project_name, new_value_metadata - ): - pass - - @abstractmethod - def on_project_anatomy_save( - self, old_value, new_value, changes, project_name, new_value_metadata - ): - pass - - -class SettingsAction(PypeModule, ITrayAction): +class SettingsAction(OpenPypeModule, ITrayAction): """Action to show Setttings tool.""" name = "settings" label = "Studio Settings" @@ -103,7 +71,7 @@ class SettingsAction(PypeModule, ITrayAction): self.settings_window.reset() -class LocalSettingsAction(PypeModule, ITrayAction): +class LocalSettingsAction(OpenPypeModule, ITrayAction): """Action to show Setttings tool.""" name = "local_settings" label = "Settings" diff --git a/openpype/modules/slack/README.md b/openpype/modules/default_modules/slack/README.md similarity index 100% rename from openpype/modules/slack/README.md rename to openpype/modules/default_modules/slack/README.md diff --git a/openpype/modules/slack/__init__.py b/openpype/modules/default_modules/slack/__init__.py similarity index 100% rename from openpype/modules/slack/__init__.py rename to openpype/modules/default_modules/slack/__init__.py diff --git a/openpype/modules/slack/launch_hooks/pre_python2_vendor.py b/openpype/modules/default_modules/slack/launch_hooks/pre_python2_vendor.py similarity index 95% rename from openpype/modules/slack/launch_hooks/pre_python2_vendor.py rename to openpype/modules/default_modules/slack/launch_hooks/pre_python2_vendor.py index a2c1f8a9e0..0f4bc22a34 100644 --- a/openpype/modules/slack/launch_hooks/pre_python2_vendor.py +++ b/openpype/modules/default_modules/slack/launch_hooks/pre_python2_vendor.py @@ -1,6 +1,6 @@ import os from openpype.lib import PreLaunchHook -from openpype.modules.slack import SLACK_MODULE_DIR +from openpype_modules.slack import SLACK_MODULE_DIR class PrePython2Support(PreLaunchHook): diff --git a/openpype/modules/slack/manifest.yml b/openpype/modules/default_modules/slack/manifest.yml similarity index 100% rename from openpype/modules/slack/manifest.yml rename to openpype/modules/default_modules/slack/manifest.yml diff --git a/openpype/modules/slack/plugins/publish/collect_slack_family.py b/openpype/modules/default_modules/slack/plugins/publish/collect_slack_family.py similarity index 100% rename from openpype/modules/slack/plugins/publish/collect_slack_family.py rename to openpype/modules/default_modules/slack/plugins/publish/collect_slack_family.py diff --git a/openpype/modules/slack/plugins/publish/integrate_slack_api.py b/openpype/modules/default_modules/slack/plugins/publish/integrate_slack_api.py similarity index 100% rename from openpype/modules/slack/plugins/publish/integrate_slack_api.py rename to openpype/modules/default_modules/slack/plugins/publish/integrate_slack_api.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.appveyor.yml b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.appveyor.yml similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.appveyor.yml rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.appveyor.yml diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.coveragerc b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.coveragerc similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.coveragerc rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.coveragerc diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.flake8 b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.flake8 similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.flake8 rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.flake8 diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/contributing.md b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/contributing.md similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/contributing.md rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/contributing.md diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/issue_template.md b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/issue_template.md similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/issue_template.md rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/issue_template.md diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/maintainers_guide.md b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/maintainers_guide.md similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/maintainers_guide.md rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/maintainers_guide.md diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/pull_request_template.md b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/pull_request_template.md similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.github/pull_request_template.md rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.github/pull_request_template.md diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.gitignore b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.gitignore similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.gitignore rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.gitignore diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/.travis.yml b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.travis.yml similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/.travis.yml rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/.travis.yml diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/LICENSE b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/LICENSE similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/LICENSE rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/LICENSE diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/MANIFEST.in b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/MANIFEST.in similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/MANIFEST.in rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/MANIFEST.in diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/README.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/README.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/README.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/README.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/.gitignore b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/.gitignore similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/.gitignore rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/.gitignore diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/Makefile b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/Makefile similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/Makefile rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/Makefile diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/conf.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/conf.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/conf.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/conf.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/layout.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/layout.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/layout.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/layout.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/localtoc.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/localtoc.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/localtoc.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/localtoc.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/relations.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/relations.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/relations.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/relations.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/sidebar.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/sidebar.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/sidebar.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/sidebar.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/default.css_t b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/default.css_t similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/default.css_t rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/default.css_t diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/docs.css_t b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/docs.css_t similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/docs.css_t rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/docs.css_t diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/pygments.css_t b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/pygments.css_t similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/pygments.css_t rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/static/pygments.css_t diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/theme.conf b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/theme.conf similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/theme.conf rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/_themes/slack/theme.conf diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/about.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/about.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/about.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/about.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/auth.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/auth.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/auth.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/auth.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/basic_usage.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/basic_usage.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/basic_usage.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/basic_usage.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/changelog.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/changelog.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/changelog.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/changelog.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conf.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conf.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conf.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conf.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conversations.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conversations.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conversations.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/conversations.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/faq.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/faq.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/faq.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/faq.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/index.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/index.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/index.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/index.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/make.bat b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/make.bat similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/make.bat rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/make.bat diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/metadata.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/metadata.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/metadata.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/metadata.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/real_time_messaging.rst b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/real_time_messaging.rst similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs-src/real_time_messaging.rst rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs-src/real_time_messaging.rst diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs.sh b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs.sh similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs.sh rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs.sh diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/.buildinfo b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/.buildinfo similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/.buildinfo rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/.buildinfo diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/.nojekyll b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/.nojekyll similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/.nojekyll rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/.nojekyll diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/ajax-loader.gif b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/ajax-loader.gif similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/ajax-loader.gif rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/ajax-loader.gif diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/basic.css b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/basic.css similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/basic.css rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/basic.css diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/classic.css b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/classic.css similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/classic.css rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/classic.css diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-bright.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-bright.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-bright.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-bright.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-close.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-close.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-close.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment-close.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/comment.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/default.css b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/default.css similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/default.css rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/default.css diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/docs.css b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/docs.css similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/docs.css rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/docs.css diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/doctools.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/doctools.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/doctools.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/doctools.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/documentation_options.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/documentation_options.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/documentation_options.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/documentation_options.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down-pressed.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down-pressed.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down-pressed.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down-pressed.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/down.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/file.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/file.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/file.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/file.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery-3.2.1.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery-3.2.1.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery-3.2.1.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery-3.2.1.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/jquery.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/language_data.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/language_data.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/language_data.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/language_data.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/minus.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/minus.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/minus.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/minus.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/plus.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/plus.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/plus.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/plus.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/pygments.css b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/pygments.css similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/pygments.css rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/pygments.css diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/searchtools.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/searchtools.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/searchtools.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/searchtools.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/sidebar.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/sidebar.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/sidebar.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/sidebar.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore-1.3.1.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore-1.3.1.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore-1.3.1.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore-1.3.1.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/underscore.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up-pressed.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up-pressed.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up-pressed.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up-pressed.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/up.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/websupport.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/websupport.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/websupport.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/_static/websupport.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/about.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/about.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/about.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/about.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/auth.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/auth.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/auth.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/auth.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/basic_usage.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/basic_usage.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/basic_usage.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/basic_usage.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/changelog.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/changelog.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/changelog.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/changelog.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/conversations.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/conversations.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/conversations.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/conversations.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/faq.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/faq.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/faq.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/faq.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/genindex.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/genindex.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/genindex.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/genindex.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/index.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/index.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/index.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/index.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/metadata.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/metadata.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/metadata.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/metadata.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/objects.inv b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/objects.inv similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/objects.inv rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/objects.inv diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/real_time_messaging.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/real_time_messaging.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/real_time_messaging.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/real_time_messaging.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/search.html b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/search.html similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/search.html rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/search.html diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/searchindex.js b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/searchindex.js similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/docs/searchindex.js rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/docs/searchindex.js diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/requirements.txt b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/requirements.txt similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/requirements.txt rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/requirements.txt diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/setup.cfg b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/setup.cfg similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/setup.cfg rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/setup.cfg diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/setup.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/setup.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/setup.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/setup.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/__init__.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/__init__.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/__init__.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/__init__.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/channel.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/channel.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/channel.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/channel.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/client.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/client.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/client.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/client.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/exceptions.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/exceptions.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/exceptions.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/exceptions.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/im.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/im.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/im.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/im.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/server.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/server.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/server.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/server.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/slackrequest.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/slackrequest.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/slackrequest.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/slackrequest.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/user.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/user.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/user.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/user.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/util.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/util.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/util.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/util.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/version.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/version.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/slackclient/version.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/slackclient/version.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/test_requirements.txt b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/test_requirements.txt similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/test_requirements.txt rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/test_requirements.txt diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/conftest.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/conftest.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/conftest.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/conftest.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/channel.created.json b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/channel.created.json similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/channel.created.json rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/channel.created.json diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/im.created.json b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/im.created.json similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/im.created.json rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/im.created.json diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/rtm.start.json b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/rtm.start.json similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/rtm.start.json rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/rtm.start.json diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/slack_logo.png b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/slack_logo.png similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/data/slack_logo.png rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/data/slack_logo.png diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_channel.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_channel.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_channel.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_channel.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_server.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_server.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_server.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_server.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackclient.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackclient.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackclient.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackclient.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackrequest.py b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackrequest.py similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackrequest.py rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tests/test_slackrequest.py diff --git a/openpype/modules/slack/python2_vendor/python-slack-sdk-1/tox.ini b/openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tox.ini similarity index 100% rename from openpype/modules/slack/python2_vendor/python-slack-sdk-1/tox.ini rename to openpype/modules/default_modules/slack/python2_vendor/python-slack-sdk-1/tox.ini diff --git a/openpype/modules/slack/slack_module.py b/openpype/modules/default_modules/slack/slack_module.py similarity index 80% rename from openpype/modules/slack/slack_module.py rename to openpype/modules/default_modules/slack/slack_module.py index 9dd5a3d02b..e3f7b4ad19 100644 --- a/openpype/modules/slack/slack_module.py +++ b/openpype/modules/default_modules/slack/slack_module.py @@ -1,11 +1,14 @@ import os -from openpype.modules import ( - PypeModule, IPluginPaths, ILaunchHookPaths) +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( + IPluginPaths, + ILaunchHookPaths +) SLACK_MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) -class SlackIntegrationModule(PypeModule, IPluginPaths, ILaunchHookPaths): +class SlackIntegrationModule(OpenPypeModule, IPluginPaths, ILaunchHookPaths): """Allows sending notification to Slack channels during publishing.""" name = "slack" diff --git a/openpype/modules/standalonepublish_action.py b/openpype/modules/default_modules/standalonepublish_action.py similarity index 90% rename from openpype/modules/standalonepublish_action.py rename to openpype/modules/default_modules/standalonepublish_action.py index 4f87f9704c..9321a415a9 100644 --- a/openpype/modules/standalonepublish_action.py +++ b/openpype/modules/default_modules/standalonepublish_action.py @@ -2,10 +2,11 @@ import os import platform import subprocess from openpype.lib import get_pype_execute_args -from . import PypeModule, ITrayAction +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayAction -class StandAlonePublishAction(PypeModule, ITrayAction): +class StandAlonePublishAction(OpenPypeModule, ITrayAction): label = "Publish" name = "standalonepublish_tool" diff --git a/openpype/modules/sync_server/README.md b/openpype/modules/default_modules/sync_server/README.md similarity index 100% rename from openpype/modules/sync_server/README.md rename to openpype/modules/default_modules/sync_server/README.md diff --git a/openpype/modules/default_modules/sync_server/__init__.py b/openpype/modules/default_modules/sync_server/__init__.py new file mode 100644 index 0000000000..430ab53c91 --- /dev/null +++ b/openpype/modules/default_modules/sync_server/__init__.py @@ -0,0 +1,6 @@ +from .sync_server_module import SyncServerModule + + +__all__ = ( + "SyncServerModule", +) diff --git a/openpype/modules/sync_server/providers/__init__.py b/openpype/modules/default_modules/sync_server/providers/__init__.py similarity index 100% rename from openpype/modules/sync_server/providers/__init__.py rename to openpype/modules/default_modules/sync_server/providers/__init__.py diff --git a/openpype/modules/sync_server/providers/abstract_provider.py b/openpype/modules/default_modules/sync_server/providers/abstract_provider.py similarity index 100% rename from openpype/modules/sync_server/providers/abstract_provider.py rename to openpype/modules/default_modules/sync_server/providers/abstract_provider.py diff --git a/openpype/modules/sync_server/providers/gdrive.py b/openpype/modules/default_modules/sync_server/providers/gdrive.py similarity index 100% rename from openpype/modules/sync_server/providers/gdrive.py rename to openpype/modules/default_modules/sync_server/providers/gdrive.py diff --git a/openpype/modules/sync_server/providers/lib.py b/openpype/modules/default_modules/sync_server/providers/lib.py similarity index 100% rename from openpype/modules/sync_server/providers/lib.py rename to openpype/modules/default_modules/sync_server/providers/lib.py diff --git a/openpype/modules/sync_server/providers/local_drive.py b/openpype/modules/default_modules/sync_server/providers/local_drive.py similarity index 100% rename from openpype/modules/sync_server/providers/local_drive.py rename to openpype/modules/default_modules/sync_server/providers/local_drive.py diff --git a/openpype/modules/sync_server/providers/resources/folder.png b/openpype/modules/default_modules/sync_server/providers/resources/folder.png similarity index 100% rename from openpype/modules/sync_server/providers/resources/folder.png rename to openpype/modules/default_modules/sync_server/providers/resources/folder.png diff --git a/openpype/modules/sync_server/providers/resources/gdrive.png b/openpype/modules/default_modules/sync_server/providers/resources/gdrive.png similarity index 100% rename from openpype/modules/sync_server/providers/resources/gdrive.png rename to openpype/modules/default_modules/sync_server/providers/resources/gdrive.png diff --git a/openpype/modules/sync_server/providers/resources/local_drive.png b/openpype/modules/default_modules/sync_server/providers/resources/local_drive.png similarity index 100% rename from openpype/modules/sync_server/providers/resources/local_drive.png rename to openpype/modules/default_modules/sync_server/providers/resources/local_drive.png diff --git a/openpype/modules/sync_server/providers/resources/studio.png b/openpype/modules/default_modules/sync_server/providers/resources/studio.png similarity index 100% rename from openpype/modules/sync_server/providers/resources/studio.png rename to openpype/modules/default_modules/sync_server/providers/resources/studio.png diff --git a/openpype/modules/sync_server/resources/paused.png b/openpype/modules/default_modules/sync_server/resources/paused.png similarity index 100% rename from openpype/modules/sync_server/resources/paused.png rename to openpype/modules/default_modules/sync_server/resources/paused.png diff --git a/openpype/modules/sync_server/resources/synced.png b/openpype/modules/default_modules/sync_server/resources/synced.png similarity index 100% rename from openpype/modules/sync_server/resources/synced.png rename to openpype/modules/default_modules/sync_server/resources/synced.png diff --git a/openpype/modules/sync_server/sync_server.py b/openpype/modules/default_modules/sync_server/sync_server.py similarity index 100% rename from openpype/modules/sync_server/sync_server.py rename to openpype/modules/default_modules/sync_server/sync_server.py diff --git a/openpype/modules/sync_server/sync_server_module.py b/openpype/modules/default_modules/sync_server/sync_server_module.py similarity index 99% rename from openpype/modules/sync_server/sync_server_module.py rename to openpype/modules/default_modules/sync_server/sync_server_module.py index 15de4b12e9..e65a410551 100644 --- a/openpype/modules/sync_server/sync_server_module.py +++ b/openpype/modules/default_modules/sync_server/sync_server_module.py @@ -7,7 +7,8 @@ import copy from avalon.api import AvalonMongoDB -from .. import PypeModule, ITrayModule +from openpype.modules import OpenPypeModule +from openpype_interfaces import ITrayModule from openpype.api import ( Anatomy, get_project_settings, @@ -28,7 +29,7 @@ from .utils import time_function, SyncStatus, EditableScopes log = PypeLogger().get_logger("SyncServer") -class SyncServerModule(PypeModule, ITrayModule): +class SyncServerModule(OpenPypeModule, ITrayModule): """ Synchronization server that is syncing published files from local to any of implemented providers (like GDrive, S3 etc.) diff --git a/openpype/modules/sync_server/tray/app.py b/openpype/modules/default_modules/sync_server/tray/app.py similarity index 98% rename from openpype/modules/sync_server/tray/app.py rename to openpype/modules/default_modules/sync_server/tray/app.py index dd2b4be749..106076d81c 100644 --- a/openpype/modules/sync_server/tray/app.py +++ b/openpype/modules/default_modules/sync_server/tray/app.py @@ -5,7 +5,7 @@ from openpype.tools.settings import style from openpype.lib import PypeLogger from openpype import resources -from openpype.modules.sync_server.tray.widgets import ( +from .widgets import ( SyncProjectListWidget, SyncRepresentationSummaryWidget ) diff --git a/openpype/modules/sync_server/tray/delegates.py b/openpype/modules/default_modules/sync_server/tray/delegates.py similarity index 98% rename from openpype/modules/sync_server/tray/delegates.py rename to openpype/modules/default_modules/sync_server/tray/delegates.py index 9316ec2c3e..461b9fffb3 100644 --- a/openpype/modules/sync_server/tray/delegates.py +++ b/openpype/modules/default_modules/sync_server/tray/delegates.py @@ -2,7 +2,7 @@ import os from Qt import QtCore, QtWidgets, QtGui from openpype.lib import PypeLogger -from openpype.modules.sync_server.tray import lib +from . import lib log = PypeLogger().get_logger("SyncServer") diff --git a/openpype/modules/sync_server/tray/lib.py b/openpype/modules/default_modules/sync_server/tray/lib.py similarity index 100% rename from openpype/modules/sync_server/tray/lib.py rename to openpype/modules/default_modules/sync_server/tray/lib.py diff --git a/openpype/modules/sync_server/tray/models.py b/openpype/modules/default_modules/sync_server/tray/models.py similarity index 99% rename from openpype/modules/sync_server/tray/models.py rename to openpype/modules/default_modules/sync_server/tray/models.py index efef039b8b..8c86d3b98f 100644 --- a/openpype/modules/sync_server/tray/models.py +++ b/openpype/modules/default_modules/sync_server/tray/models.py @@ -11,7 +11,7 @@ from avalon.vendor import qtawesome from openpype.lib import PypeLogger from openpype.api import get_local_site_id -from openpype.modules.sync_server.tray import lib +from . import lib log = PypeLogger().get_logger("SyncServer") diff --git a/openpype/modules/sync_server/tray/widgets.py b/openpype/modules/default_modules/sync_server/tray/widgets.py similarity index 99% rename from openpype/modules/sync_server/tray/widgets.py rename to openpype/modules/default_modules/sync_server/tray/widgets.py index d38416fbce..c9160733a0 100644 --- a/openpype/modules/sync_server/tray/widgets.py +++ b/openpype/modules/default_modules/sync_server/tray/widgets.py @@ -17,13 +17,13 @@ from openpype.lib import PypeLogger from avalon.tools.delegates import pretty_timestamp from avalon.vendor import qtawesome -from openpype.modules.sync_server.tray.models import ( +from .models import ( SyncRepresentationSummaryModel, SyncRepresentationDetailModel ) -from openpype.modules.sync_server.tray import lib -from openpype.modules.sync_server.tray import delegates +from . import lib +from . import delegates log = PypeLogger().get_logger("SyncServer") @@ -187,7 +187,7 @@ class _SyncRepresentationWidget(QtWidgets.QWidget): detail_window = SyncServerDetailWindow( self.sync_server, _id, self.model.project, parent=self) detail_window.exec() - + def _on_context_menu(self, point): """ Shows menu with loader actions on Right-click. diff --git a/openpype/modules/sync_server/utils.py b/openpype/modules/default_modules/sync_server/utils.py similarity index 100% rename from openpype/modules/sync_server/utils.py rename to openpype/modules/default_modules/sync_server/utils.py diff --git a/openpype/modules/timers_manager/__init__.py b/openpype/modules/default_modules/timers_manager/__init__.py similarity index 51% rename from openpype/modules/timers_manager/__init__.py rename to openpype/modules/default_modules/timers_manager/__init__.py index 1b565cc59a..5d7a4166d3 100644 --- a/openpype/modules/timers_manager/__init__.py +++ b/openpype/modules/default_modules/timers_manager/__init__.py @@ -1,9 +1,7 @@ from .timers_manager import ( - ITimersManager, TimersManager ) __all__ = ( - "ITimersManager", - "TimersManager" + "TimersManager", ) diff --git a/openpype/modules/default_modules/timers_manager/interfaces.py b/openpype/modules/default_modules/timers_manager/interfaces.py new file mode 100644 index 0000000000..179013cffe --- /dev/null +++ b/openpype/modules/default_modules/timers_manager/interfaces.py @@ -0,0 +1,26 @@ +from abc import abstractmethod +from openpype.modules import OpenPypeInterface + + +class ITimersManager(OpenPypeInterface): + timer_manager_module = None + + @abstractmethod + def stop_timer(self): + pass + + @abstractmethod + def start_timer(self, data): + pass + + def timer_started(self, data): + if not self.timer_manager_module: + return + + self.timer_manager_module.timer_started(self.id, data) + + def timer_stopped(self): + if not self.timer_manager_module: + return + + self.timer_manager_module.timer_stopped(self.id) diff --git a/openpype/modules/timers_manager/rest_api.py b/openpype/modules/default_modules/timers_manager/rest_api.py similarity index 100% rename from openpype/modules/timers_manager/rest_api.py rename to openpype/modules/default_modules/timers_manager/rest_api.py diff --git a/openpype/modules/timers_manager/timers_manager.py b/openpype/modules/default_modules/timers_manager/timers_manager.py similarity index 90% rename from openpype/modules/timers_manager/timers_manager.py rename to openpype/modules/default_modules/timers_manager/timers_manager.py index 92edd5aeaa..80f448095f 100644 --- a/openpype/modules/timers_manager/timers_manager.py +++ b/openpype/modules/default_modules/timers_manager/timers_manager.py @@ -1,37 +1,18 @@ import os import collections -from abc import ABCMeta, abstractmethod -import six -from .. import PypeModule, ITrayService, IIdleManager, IWebServerRoutes +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( + ITimersManager, + ITrayService, + IIdleManager, + IWebServerRoutes +) from avalon.api import AvalonMongoDB -@six.add_metaclass(ABCMeta) -class ITimersManager: - timer_manager_module = None - - @abstractmethod - def stop_timer(self): - pass - - @abstractmethod - def start_timer(self, data): - pass - - def timer_started(self, data): - if not self.timer_manager_module: - return - - self.timer_manager_module.timer_started(self.id, data) - - def timer_stopped(self): - if not self.timer_manager_module: - return - - self.timer_manager_module.timer_stopped(self.id) - - -class TimersManager(PypeModule, ITrayService, IIdleManager, IWebServerRoutes): +class TimersManager( + OpenPypeModule, ITrayService, IIdleManager, IWebServerRoutes +): """ Handles about Timers. Should be able to start/stop all timers at once. diff --git a/openpype/modules/timers_manager/widget_user_idle.py b/openpype/modules/default_modules/timers_manager/widget_user_idle.py similarity index 100% rename from openpype/modules/timers_manager/widget_user_idle.py rename to openpype/modules/default_modules/timers_manager/widget_user_idle.py diff --git a/openpype/modules/webserver/__init__.py b/openpype/modules/default_modules/webserver/__init__.py similarity index 52% rename from openpype/modules/webserver/__init__.py rename to openpype/modules/default_modules/webserver/__init__.py index defd115e57..899b97d6d4 100644 --- a/openpype/modules/webserver/__init__.py +++ b/openpype/modules/default_modules/webserver/__init__.py @@ -1,10 +1,8 @@ from .webserver_module import ( - WebServerModule, - IWebServerRoutes + WebServerModule ) __all__ = ( "WebServerModule", - "IWebServerRoutes" ) diff --git a/openpype/modules/webserver/base_routes.py b/openpype/modules/default_modules/webserver/base_routes.py similarity index 100% rename from openpype/modules/webserver/base_routes.py rename to openpype/modules/default_modules/webserver/base_routes.py diff --git a/openpype/modules/webserver/host_console_listener.py b/openpype/modules/default_modules/webserver/host_console_listener.py similarity index 99% rename from openpype/modules/webserver/host_console_listener.py rename to openpype/modules/default_modules/webserver/host_console_listener.py index 01a8af643e..bcf4cadf6a 100644 --- a/openpype/modules/webserver/host_console_listener.py +++ b/openpype/modules/default_modules/webserver/host_console_listener.py @@ -5,7 +5,7 @@ import logging from concurrent.futures import CancelledError from Qt import QtWidgets -from openpype.modules import ITrayService +from openpype_interfaces import ITrayService log = logging.getLogger(__name__) diff --git a/openpype/modules/default_modules/webserver/interfaces.py b/openpype/modules/default_modules/webserver/interfaces.py new file mode 100644 index 0000000000..779361a9ec --- /dev/null +++ b/openpype/modules/default_modules/webserver/interfaces.py @@ -0,0 +1,9 @@ +from abc import abstractmethod +from openpype.modules import OpenPypeInterface + + +class IWebServerRoutes(OpenPypeInterface): + """Other modules interface to register their routes.""" + @abstractmethod + def webserver_initialization(self, server_manager): + pass diff --git a/openpype/modules/webserver/server.py b/openpype/modules/default_modules/webserver/server.py similarity index 100% rename from openpype/modules/webserver/server.py rename to openpype/modules/default_modules/webserver/server.py diff --git a/openpype/modules/webserver/webserver_module.py b/openpype/modules/default_modules/webserver/webserver_module.py similarity index 89% rename from openpype/modules/webserver/webserver_module.py rename to openpype/modules/default_modules/webserver/webserver_module.py index b61619acde..ff3456f903 100644 --- a/openpype/modules/webserver/webserver_module.py +++ b/openpype/modules/default_modules/webserver/webserver_module.py @@ -1,22 +1,15 @@ import os import socket -from abc import ABCMeta, abstractmethod - -import six from openpype import resources -from .. import PypeModule, ITrayService +from openpype.modules import OpenPypeModule +from openpype_interfaces import ( + ITrayService, + IWebServerRoutes +) -@six.add_metaclass(ABCMeta) -class IWebServerRoutes: - """Other modules interface to register their routes.""" - @abstractmethod - def webserver_initialization(self, server_manager): - pass - - -class WebServerModule(PypeModule, ITrayService): +class WebServerModule(OpenPypeModule, ITrayService): name = "webserver" label = "WebServer" @@ -57,7 +50,7 @@ class WebServerModule(PypeModule, ITrayService): ) def _add_listeners(self): - from openpype.modules.webserver import host_console_listener + from openpype_modules.webserver import host_console_listener self._host_listener = host_console_listener.HostListener( self.server_manager, self diff --git a/openpype/modules/sync_server/__init__.py b/openpype/modules/sync_server/__init__.py deleted file mode 100644 index a814f0db62..0000000000 --- a/openpype/modules/sync_server/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from openpype.modules.sync_server.sync_server_module import SyncServerModule - - -def tray_init(tray_widget, main_widget): - return SyncServerModule() diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index 3504206fe1..67e9f9ca19 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -97,7 +97,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "background", "camerarig", "redshiftproxy", - "effect" + "effect", + "xgen" ] exclude_families = ["clip"] db_representation_context_keys = [ diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 7c47d8c613..978dcbc0d7 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -35,7 +35,7 @@ class PypeCommands: @staticmethod def launch_eventservercli(*args): - from openpype.modules.ftrack.ftrack_server.event_server_cli import ( + from openpype_modules.ftrack.ftrack_server.event_server_cli import ( run_event_server ) return run_event_server(*args) diff --git a/openpype/settings/entities/enum_entity.py b/openpype/settings/entities/enum_entity.py index 917e376904..5db31959a5 100644 --- a/openpype/settings/entities/enum_entity.py +++ b/openpype/settings/entities/enum_entity.py @@ -419,7 +419,7 @@ class ProvidersEnum(BaseEnumEntity): self.placeholder = None def _get_enum_values(self): - from openpype.modules.sync_server.providers import lib as lib_providers + from openpype_modules.sync_server.providers import lib as lib_providers providers = lib_providers.factory.providers diff --git a/openpype/settings/lib.py b/openpype/settings/lib.py index 5c2c0dcd94..4a363910b8 100644 --- a/openpype/settings/lib.py +++ b/openpype/settings/lib.py @@ -114,7 +114,8 @@ def save_studio_settings(data): SaveWarningExc: If any module raises the exception. """ # Notify Pype modules - from openpype.modules import ModulesManager, ISettingsChangeListener + from openpype.modules import ModulesManager + from openpype_interfaces import ISettingsChangeListener old_data = get_system_settings() default_values = get_default_settings()[SYSTEM_SETTINGS_KEY] @@ -161,7 +162,8 @@ def save_project_settings(project_name, overrides): SaveWarningExc: If any module raises the exception. """ # Notify Pype modules - from openpype.modules import ModulesManager, ISettingsChangeListener + from openpype.modules import ModulesManager + from openpype_interfaces import ISettingsChangeListener default_values = get_default_settings()[PROJECT_SETTINGS_KEY] if project_name: @@ -222,7 +224,8 @@ def save_project_anatomy(project_name, anatomy_data): SaveWarningExc: If any module raises the exception. """ # Notify Pype modules - from openpype.modules import ModulesManager, ISettingsChangeListener + from openpype.modules import ModulesManager + from openpype_interfaces import ISettingsChangeListener default_values = get_default_settings()[PROJECT_ANATOMY_KEY] if project_name: diff --git a/openpype/tools/mayalookassigner/commands.py b/openpype/tools/mayalookassigner/commands.py index 2add5d3499..a53251cdef 100644 --- a/openpype/tools/mayalookassigner/commands.py +++ b/openpype/tools/mayalookassigner/commands.py @@ -103,12 +103,19 @@ def create_asset_id_hash(nodes): """ node_id_hash = defaultdict(list) for node in nodes: - value = lib.get_id(node) - if value is None: - continue + # iterate over content of reference node + if cmds.nodeType(node) == "reference": + ref_hashes = create_asset_id_hash( + cmds.referenceQuery(node, nodes=True)) + for asset_id, ref_nodes in ref_hashes.items(): + node_id_hash[asset_id] += ref_nodes + else: + value = lib.get_id(node) + if value is None: + continue - asset_id = value.split(":")[0] - node_id_hash[asset_id].append(node) + asset_id = value.split(":")[0] + node_id_hash[asset_id].append(node) return dict(node_id_hash) @@ -135,18 +142,19 @@ def create_items_from_nodes(nodes): id_hashes = create_asset_id_hash(nodes) # get ids from alembic - vray_proxy_nodes = cmds.ls(nodes, type="VRayProxy") - for vp in vray_proxy_nodes: - path = cmds.getAttr("{}.fileName".format(vp)) - ids = vray_proxies.get_alembic_ids_cache(path) - parent_id = {} - for k, _ in ids.items(): - pid = k.split(":")[0] - if not parent_id.get(pid): - parent_id.update({pid: [vp]}) + if cmds.pluginInfo('vrayformaya', query=True, loaded=True): + vray_proxy_nodes = cmds.ls(nodes, type="VRayProxy") + for vp in vray_proxy_nodes: + path = cmds.getAttr("{}.fileName".format(vp)) + ids = vray_proxies.get_alembic_ids_cache(path) + parent_id = {} + for k, _ in ids.items(): + pid = k.split(":")[0] + if not parent_id.get(pid): + parent_id.update({pid: [vp]}) - print("Adding ids from alembic {}".format(path)) - id_hashes.update(parent_id) + print("Adding ids from alembic {}".format(path)) + id_hashes.update(parent_id) if not id_hashes: return asset_view_items diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 794312f389..ed66f1a80f 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -15,11 +15,7 @@ from openpype.api import ( get_system_settings ) from openpype.lib import get_pype_execute_args -from openpype.modules import ( - TrayModulesManager, - ITrayAction, - ITrayService -) +from openpype.modules import TrayModulesManager from openpype import style from .pype_info_widget import PypeInfoWidget @@ -80,6 +76,10 @@ class TrayManager: def initialize_modules(self): """Add modules to tray.""" + from openpype_interfaces import ( + ITrayAction, + ITrayService + ) self.modules_manager.initialize(self, self.tray_widget.menu) diff --git a/openpype/tools/tray_app/app.py b/openpype/tools/tray_app/app.py index 339e6343f8..03f8321464 100644 --- a/openpype/tools/tray_app/app.py +++ b/openpype/tools/tray_app/app.py @@ -9,7 +9,7 @@ import itertools from datetime import datetime from avalon import style -from openpype.modules.webserver import host_console_listener +from openpype_modules.webserver import host_console_listener from Qt import QtWidgets, QtCore diff --git a/openpype/version.py b/openpype/version.py index f5c8081d61..5fd6520953 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.3.0-nightly.10" +__version__ = "3.4.0-nightly.2" diff --git a/website/docs/artist_hosts_maya.md b/website/docs/artist_hosts_maya.md index 6fbd59ae1e..6387da4adc 100644 --- a/website/docs/artist_hosts_maya.md +++ b/website/docs/artist_hosts_maya.md @@ -701,6 +701,32 @@ under `input_SET`). This mechanism uses *cbId* attribute on those shapes. If match is found shapes are connected using their `outMesh` and `outMesh`. Thus you can easily connect existing animation to loaded rig. ::: +## Working with Xgen in OpenPype + +OpenPype support publishing and loading of Xgen interactive grooms. You can publish +them as mayaAscii files with scalps that can be loaded into another maya scene, or as +alembic caches. + +### Publishing Xgen Grooms + +To prepare xgen for publishing just select all the descriptions that should be published together and the create Xgen Subset in the scene using - **OpenPype menu** β†’ **Create**... and select **Xgen Interactive**. Leave Use selection checked. + +For actual publishing of your groom to go **OpenPype β†’ Publish** and then press β–Ά to publish. This will export `.ma` file containing your grooms with any geometries they are attached to and also a baked cache in `.abc` format + + +:::tip adding more descriptions +You can add multiple xgen desctiption into the subset you are about to publish, simply by +adding them to the maya set that was created for you. Please make sure that only xgen description nodes are present inside of the set and not the scalp geometry. +::: + +### Loading Xgen + +You can use published xgens by loading them using OpenPype Publisher. You can choose to reference or import xgen. We don't have any automatic mesh linking at the moment and it is expected, that groom is published with a scalp, that can then be manually attached to your animated mesh for example. + +The alembic representation can be loaded too and it contains the groom converted to curves. Keep in mind that the density of the alembic directly depends on your viewport xgen density at the point of export. + + + ## Using Redshift Proxies OpenPype supports working with Redshift Proxy files. You can create Redshift Proxy from almost