diff --git a/.all-contributorsrc b/.all-contributorsrc index b30f3b2499..60812cdb3c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1,6 +1,6 @@ { "projectName": "OpenPype", - "projectOwner": "pypeclub", + "projectOwner": "ynput", "repoType": "github", "repoHost": "https://github.com", "files": [ @@ -319,8 +319,18 @@ "code", "doc" ] + }, + { + "login": "movalex", + "name": "Alexey Bogomolov", + "avatar_url": "https://avatars.githubusercontent.com/u/11698866?v=4", + "profile": "http://abogomolov.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, - "skipCi": true + "skipCi": true, + "commitType": "docs" } diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index a9f1f1cc02..039b42bff3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -35,106 +35,106 @@ body: label: Version description: What version are you running? Look to OpenPype Tray options: + - 3.18.6-nightly.1 + - 3.18.5 + - 3.18.5-nightly.3 + - 3.18.5-nightly.2 + - 3.18.5-nightly.1 + - 3.18.4 + - 3.18.4-nightly.1 + - 3.18.3 + - 3.18.3-nightly.2 + - 3.18.3-nightly.1 + - 3.18.2 + - 3.18.2-nightly.6 + - 3.18.2-nightly.5 + - 3.18.2-nightly.4 + - 3.18.2-nightly.3 + - 3.18.2-nightly.2 + - 3.18.2-nightly.1 + - 3.18.1 + - 3.18.1-nightly.1 + - 3.18.0 + - 3.17.7 + - 3.17.7-nightly.7 + - 3.17.7-nightly.6 + - 3.17.7-nightly.5 + - 3.17.7-nightly.4 + - 3.17.7-nightly.3 + - 3.17.7-nightly.2 + - 3.17.7-nightly.1 + - 3.17.6 + - 3.17.6-nightly.3 + - 3.17.6-nightly.2 + - 3.17.6-nightly.1 + - 3.17.5 + - 3.17.5-nightly.3 + - 3.17.5-nightly.2 + - 3.17.5-nightly.1 + - 3.17.4 + - 3.17.4-nightly.2 + - 3.17.4-nightly.1 + - 3.17.3 + - 3.17.3-nightly.2 + - 3.17.3-nightly.1 + - 3.17.2 + - 3.17.2-nightly.4 + - 3.17.2-nightly.3 + - 3.17.2-nightly.2 + - 3.17.2-nightly.1 + - 3.17.1 + - 3.17.1-nightly.3 + - 3.17.1-nightly.2 + - 3.17.1-nightly.1 + - 3.17.0 + - 3.16.7 + - 3.16.7-nightly.2 + - 3.16.7-nightly.1 + - 3.16.6 + - 3.16.6-nightly.1 + - 3.16.5 + - 3.16.5-nightly.5 + - 3.16.5-nightly.4 + - 3.16.5-nightly.3 + - 3.16.5-nightly.2 + - 3.16.5-nightly.1 + - 3.16.4 + - 3.16.4-nightly.3 + - 3.16.4-nightly.2 + - 3.16.4-nightly.1 + - 3.16.3 + - 3.16.3-nightly.5 + - 3.16.3-nightly.4 + - 3.16.3-nightly.3 + - 3.16.3-nightly.2 + - 3.16.3-nightly.1 + - 3.16.2 + - 3.16.2-nightly.2 + - 3.16.2-nightly.1 + - 3.16.1 + - 3.16.0 + - 3.16.0-nightly.2 + - 3.16.0-nightly.1 + - 3.15.12 + - 3.15.12-nightly.4 + - 3.15.12-nightly.3 + - 3.15.12-nightly.2 + - 3.15.12-nightly.1 + - 3.15.11 + - 3.15.11-nightly.5 + - 3.15.11-nightly.4 + - 3.15.11-nightly.3 + - 3.15.11-nightly.2 + - 3.15.11-nightly.1 + - 3.15.10 + - 3.15.10-nightly.2 + - 3.15.10-nightly.1 + - 3.15.9 + - 3.15.9-nightly.2 + - 3.15.9-nightly.1 + - 3.15.8 - 3.15.8-nightly.3 - 3.15.8-nightly.2 - - 3.15.8-nightly.1 - - 3.15.7 - - 3.15.7-nightly.3 - - 3.15.7-nightly.2 - - 3.15.7-nightly.1 - - 3.15.6 - - 3.15.6-nightly.3 - - 3.15.6-nightly.2 - - 3.15.6-nightly.1 - - 3.15.5 - - 3.15.5-nightly.2 - - 3.15.5-nightly.1 - - 3.15.4 - - 3.15.4-nightly.3 - - 3.15.4-nightly.2 - - 3.15.4-nightly.1 - - 3.15.3 - - 3.15.3-nightly.4 - - 3.15.3-nightly.3 - - 3.15.3-nightly.2 - - 3.15.3-nightly.1 - - 3.15.2 - - 3.15.2-nightly.6 - - 3.15.2-nightly.5 - - 3.15.2-nightly.4 - - 3.15.2-nightly.3 - - 3.15.2-nightly.2 - - 3.15.2-nightly.1 - - 3.15.1 - - 3.15.1-nightly.6 - - 3.15.1-nightly.5 - - 3.15.1-nightly.4 - - 3.15.1-nightly.3 - - 3.15.1-nightly.2 - - 3.15.1-nightly.1 - - 3.15.0 - - 3.15.0-nightly.1 - - 3.14.11-nightly.4 - - 3.14.11-nightly.3 - - 3.14.11-nightly.2 - - 3.14.11-nightly.1 - - 3.14.10 - - 3.14.10-nightly.9 - - 3.14.10-nightly.8 - - 3.14.10-nightly.7 - - 3.14.10-nightly.6 - - 3.14.10-nightly.5 - - 3.14.10-nightly.4 - - 3.14.10-nightly.3 - - 3.14.10-nightly.2 - - 3.14.10-nightly.1 - - 3.14.9 - - 3.14.9-nightly.5 - - 3.14.9-nightly.4 - - 3.14.9-nightly.3 - - 3.14.9-nightly.2 - - 3.14.9-nightly.1 - - 3.14.8 - - 3.14.8-nightly.4 - - 3.14.8-nightly.3 - - 3.14.8-nightly.2 - - 3.14.8-nightly.1 - - 3.14.7 - - 3.14.7-nightly.8 - - 3.14.7-nightly.7 - - 3.14.7-nightly.6 - - 3.14.7-nightly.5 - - 3.14.7-nightly.4 - - 3.14.7-nightly.3 - - 3.14.7-nightly.2 - - 3.14.7-nightly.1 - - 3.14.6 - - 3.14.6-nightly.3 - - 3.14.6-nightly.2 - - 3.14.6-nightly.1 - - 3.14.5 - - 3.14.5-nightly.3 - - 3.14.5-nightly.2 - - 3.14.5-nightly.1 - - 3.14.4 - - 3.14.4-nightly.4 - - 3.14.4-nightly.3 - - 3.14.4-nightly.2 - - 3.14.4-nightly.1 - - 3.14.3 - - 3.14.3-nightly.7 - - 3.14.3-nightly.6 - - 3.14.3-nightly.5 - - 3.14.3-nightly.4 - - 3.14.3-nightly.3 - - 3.14.3-nightly.2 - - 3.14.3-nightly.1 - - 3.14.2 - - 3.14.2-nightly.5 - - 3.14.2-nightly.4 - - 3.14.2-nightly.3 - - 3.14.2-nightly.2 - - 3.14.2-nightly.1 validations: required: true - type: dropdown diff --git a/.github/workflows/miletone_release_trigger.yml b/.github/workflows/miletone_release_trigger.yml index 4a031be7f9..d755f7eb9f 100644 --- a/.github/workflows/miletone_release_trigger.yml +++ b/.github/workflows/miletone_release_trigger.yml @@ -5,12 +5,6 @@ on: inputs: milestone: required: true - release-type: - type: choice - description: What release should be created - options: - - release - - pre-release milestone: types: closed diff --git a/.gitignore b/.gitignore index 50f52f65a3..622d55fb88 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ Temporary Items ########### /build /dist/ +/server_addon/packages/* /vendor/bin/* /vendor/python/* diff --git a/CHANGELOG.md b/CHANGELOG.md index bba6b64bfe..14f0bc469f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9943 @@ # Changelog +## [3.18.5](https://github.com/ynput/OpenPype/tree/3.18.5) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.18.4...3.18.5) + +### **🚀 Enhancements** + + +
+Chore: Add addons dir only if exists #6140 + +Do not add addons directory path for addons discovery if does not exists. + + +___ + +
+ + +
+Hiero: Effect Categories - OP-7397 #6143 + +This PR introduces `Effect Categories` for the Hiero settings. This allows studios to split effect stacks into meaningful subsets. + + +___ + +
+ + +
+Nuke: Render Workfile Attributes #6146 + +`Workfile Dependency` default value can now be controlled from project settings.`Use Published Workfile` makes using published workfiles for rendering optional. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Attributes are locked after publishing if they are locked in Camera Family #6073 + +This PR is to make sure unlock attributes only during the bake context, make sure attributes are relocked after to preserve the lock state of the original node being baked. + + +___ + +
+ + +
+Missing nuke family Windows arguments #6131 + +Default Windows arguments for launching the Nuke family was missing. + + +___ + +
+ + +
+AYON: Fix the bug on the limit group not being set correctly in Maya Deadline Setting #6139 + +This PR is to bug-fix the limit groups from maya deadline settings errored out when the user tries to edit the setting. + + +___ + +
+ + +
+Chore: Transcoding extensions add missing '.tif' extension #6142 + +Image extensions in transcoding helper was missing `.tif` extension and had `.tiff` twice. + + +___ + +
+ + +
+Blender: Use the new API for override context #6145 + +Blender 4.0 disabled the old API to override context. This API updates the code to use the new API. + + +___ + +
+ + +
+BugFix: Include Model in FBX Loader in Houdini #6150 + +A quick bugfig where we can't load fbx exported from blender. The bug was reported here. + + +___ + +
+ + +
+Blender: Restore actions to objects after update #6153 + +Restore the actions assigned to objects after updating assets from blend files. + + +___ + +
+ + +
+Chore: Collect template data with hierarchy context #6154 + +Fixed queue loop where is used wrong variable to pop items from queue. + + +___ + +
+ + +
+OP-6382 - Thumbnail Integration Problem #6156 + +This ticket alerted to 3 different cases of integration issues; +- [x] Using the Tray Publisher with the same image format (extension) for representation and review representation. +- [x] Clash on publish file path from output definitions in `ExtractOIIOTranscode`. +- [x] Clash on publish file from thumbnail in `ExtractThumbnail`There might be an issue with this fix, if a studio does not use the `{output}` token in their `render` anatomy template. But thinking if they have customized it, they will be responsible to maintain these edge cases. + + +___ + +
+ + +
+Max: Bugfix saving camera scene errored out when creating render instance with multi-camera option turned off #6163 + +This PR is to make sure the integrator of saving camera scene turned off and the render submitted successfully when multi-camera options being turned off in 3dsmax + + +___ + +
+ + +
+Chore: Fix duplicated project name on create project structure #6166 + +Small fix in project folders. It is not used same variable name to change values which breaks values on any next loop. + + +___ + +
+ +### **Merged pull requests** + + +
+Maya: Remove duplicate plugin #6157 + +The two plugins below are doing the same work, so we can remove the one focused solely on lookdev.https://github.com/ynput/OpenPype/blob/develop/openpype/hosts/maya/plugins/publish/validate_look_members_unique.pyhttps://github.com/ynput/OpenPype/blob/develop/openpype/hosts/maya/plugins/publish/validate_node_ids_unique.py + + +___ + +
+ + +
+Publish report viewer: Report items sorting #6092 + +Proposal of items sorting in Publish report viewer tool. Items are sorted by report creation time. Creation time is also added to publish report data when saved from publisher tool. + + +___ + +
+ + +
+Maya: Extended error message #6161 + +Added more details to message + + +___ + +
+ + +
+Fusion: Added settings for Fusion creators to legacy OP #6162 + +Added missing OP variant of setting for new Fusion creator. + + +___ + +
+ + + + +## [3.18.4](https://github.com/ynput/OpenPype/tree/3.18.4) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.18.3...3.18.4) + +### **🚀 Enhancements** + + +
+multiple render camera supports for 3dsmax #5124 + +Supports for rendering with multiple cameras in 3dsmax +- [x] Add Batch Render Layers functions +- [x] Rewrite lib.rendersetting and lib.renderproduct +- [x] Add multi-camera options in creator. +- [x] Collector with batch render-layer when multi-camera enabled. +- [x] Add instance plugin for saving scene files with different cameras respectively by using subprocess +- [x] Refactor submit_max_deadline +- [x] Check with metadata.json in submit publish job + + +___ + +
+ + +
+Fusion: new creator for image product type #6057 + +In many DCC `render` product type is expected to be sequence of files. This PR adds new explicit creator for `image` product type which is focused on single frame image. Workflows for both product types might be a bit different, this gives artists more granularity to choose better workflow. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Account and ignore free image planes. #5993 + +Free image planes do not have the `->` path separator, so we need to account for that. + + +___ + +
+ + +
+Blender: Fix long names for instances #6070 + +Changed naming for instances to use only final part of the `folderPath`. + + +___ + +
+ + +
+Traypublisher & Chore: Instance version on follow workfile version #6117 + +If `follow_workfile_version` is enabled but context does not have filled workfile version, a version on instance is used instead. + + +___ + +
+ + +
+Substance Painter: Thumbnail errors with PBR Texture Set #6127 + +When publishing with PBR Metallic Roughness as Output Template, Emissive Map errors out because of the missing channel in the material and the map can't be generated in Substance Painter. This PR is to make sure `imagestance.data["publish"] = False` so that the related "empty" texture instance would be skipped to generate the output. + + +___ + +
+ + +
+Transcoding: Fix reading image sequences through oiiotool #6129 + +When transcoding image sequences, the second image onwards includes the invalid xml line of `Reading path/to/file.exr` of the oiiotool output.This is most likely not the best solution, but it fixes the issue and illustrates the problem.Error: +``` +ERROR:pyblish.plugin:Traceback (most recent call last): + File "C:\Users\tokejepsen\AppData\Local\Ynput\AYON\dependency_packages\ayon_2310271602_windows.zip\dependencies\pyblish\plugin.py", line 527, in __explicit_process + runner(*args) + File "C:\Users\tokejepsen\OpenPype\openpype\plugins\publish\extract_color_transcode.py", line 152, in process + File "C:\Users\tokejepsen\OpenPype\openpype\lib\transcoding.py", line 1136, in convert_colorspace + input_info = get_oiio_info_for_input(input_path, logger=logger) + File "C:\Users\tokejepsen\OpenPype\openpype\lib\transcoding.py", line 124, in get_oiio_info_for_input + output.append(parse_oiio_xml_output(xml_text, logger=logger)) + File "C:\Users\tokejepsen\OpenPype\openpype\lib\transcoding.py", line 276, in parse_oiio_xml_output + tree = xml.etree.ElementTree.fromstring(xml_string) + File "xml\etree\ElementTree.py", line 1347, in XML +xml.etree.ElementTree.ParseError: syntax error: line 1, column 0 +Traceback (most recent call last): + File "C:\Users\tokejepsen\AppData\Local\Ynput\AYON\dependency_packages\ayon_2310271602_windows.zip\dependencies\pyblish\plugin.py", line 527, in __explicit_process + runner(*args) + File "", line 152, in process + File "C:\Users\tokejepsen\OpenPype\openpype\lib\transcoding.py", line 1136, in convert_colorspace + input_info = get_oiio_info_for_input(input_path, logger=logger) + File "C:\Users\tokejepsen\OpenPype\openpype\lib\transcoding.py", line 124, in get_oiio_info_for_input + output.append(parse_oiio_xml_output(xml_text, logger=logger)) + File "C:\Users\tokejepsen\OpenPype\openpype\lib\transcoding.py", line 276, in parse_oiio_xml_output + tree = xml.etree.ElementTree.fromstring(xml_string) + File "xml\etree\ElementTree.py", line 1347, in XML +xml.etree.ElementTree.ParseError: syntax error: line 1, column 0 +``` + + + +___ + +
+ + +
+AYON: Remove 'IntegrateHeroVersion' conversion #6130 + +Remove settings conversion for `IntegrateHeroVersion`. + + +___ + +
+ + +
+Chore tools: Make sure style object is not garbage collected #6136 + +Minor fix in tool utils to make sure style C++ object is not garbage collected when not stored into variable. + + +___ + +
+ + + + +## [3.18.3](https://github.com/ynput/OpenPype/tree/3.18.3) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.18.2...3.18.3) + +### **🚀 Enhancements** + + +
+Maya: Apply initial viewport shader for Redshift Proxy after loading #6102 + +When the published redshift proxy is being loaded, the shader of the proxy is missing. This is different from the manual load through creating redshift proxy for files. This PR is to assign the default lambert to the redshift proxy, which replicates the same approach when the user manually loads the proxy with filepath. + + +___ + +
+ + +
+General: We should keep current subset version when we switch only the representation type #4629 + +When we switch only the representation type of subsets, we should not get the representation from the last version of the subset. + + +___ + +
+ + +
+Houdini: Add loader for redshift proxy family #5948 + +Loader for Redshift Proxy in Houdini (Thanks for @BigRoy contribution) + + +___ + +
+ + +
+AfterEffects: exposing Deadline pools fields in Publisher UI #6079 + +Deadline pools might be adhoc set by an artist during publishing. AfterEffects implementation wasn't providing this. + + +___ + +
+ + +
+Chore: Event callbacks can have order #6080 + +Event callbacks can have order in which are called, and fixed issue with getting function name and file when using `partial` function as callback. + + +___ + +
+ + +
+AYON: OpenPype addon defines runtime dependencies #6095 + +Moved runtime dependencies from ayon-launcher to openpype addon. + + +___ + +
+ + +
+Max: User's setting for scene unit scale #6097 + +Options for users to set the default scene unit scale for their scenes.AYONLegacy OP + + +___ + +
+ + +
+Chore: Remove deprecated templates profiles #6103 + +Remove deprecated usage of template profiles from settings. + + +___ + +
+ + +
+Publisher: Window is not always on top #6107 + +Goal of this PR is to avoid using `WindowStaysOnTopHint` which causes issues, especially in cases when DCC shows a popup dialog that is behind the window, in that case both Publisher and DCC are frozen and there is nothing to do. + + +___ + +
+ + +
+Houdini: add split job export support for Redshift ROP #6108 + +This is adding support for splitting of export and render jobs for Redshift as is already implemented for Vray, Mantra and Arnold. + + +___ + +
+ + +
+Fusion: automatic installation of PySide2 #6111 + +This PR adds hook which tries to check if PySide2 is installed in Python used by Fusion and if not, it tries to install it automatically. + + +___ + +
+ + +
+AYON: OpenPype addon dependencies #6113 + +Added `click` and `six` to requirements of openpype addon, and removed `Qt.py` requirement, which is not used anywhere. + + +___ + +
+ + +
+Chore: Thumbnail representation has 'outputName' #6114 + +Add thumbnail output name to thumbnail representation to prevent same output filename during integration. + + +___ + +
+ + +
+Kitsu: Clear credentials is safe #6116 + +Do not remove not existing keyring items. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: bug fix the playblast without textures #5942 + +Bug fix the texture not being displayed when users enable texture placement in the OP/AYON setting + + +___ + +
+ + +
+Blender: Workfile instance update fix #6048 + +Make sure workfile instance has always available 'instance_node' in transient data. + + +___ + +
+ + +
+Publisher: Fix issue with parenting of widgets #6106 + +Don't use publisher window parent (usually main DCC window) as parent for report widget. + + +___ + +
+ + +
+:wrench: fix and update pydocstyle configuration #6109 + +Fix pydocstyle configuration and move it to `pyproject.toml` + + +___ + +
+ + +
+Nuke: Create camera node with the latest camera node class in Nuke 14 #6118 + +Creating instance fails for certain cameras, and it seems to only exist in Nuke 14. The reason of causing that contributes to the new camera node class `Camera4` while the camera creator is working with the `Camera2` class. + + +___ + +
+ + +
+Site Sync: small fixes in Loader #6119 + +Resolves issue: +- local and studio icons were same, they should be different +- `TypeError: string indices must be integers` error when downloading/uploading workfiles + + +___ + +
+ + +
+Chore: Template data for editorial publishing #6120 + +Template data for editorial publishing are filled during `CollectInstanceAnatomyData`. The structure for editorial is determined, as it's required for ExtractHierarchy AYON/OpenPype plugins. + + +___ + +
+ + +
+SceneInventory: Fix site sync icon conversion #6123 + +Use 'get_qt_icon' to convert icon definitions from site sync. + + +___ + +
+ + + + +## [3.18.2](https://github.com/ynput/OpenPype/tree/3.18.2) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.18.1...3.18.2) + +### **🚀 Enhancements** + + +
+Testing: Release Maya/Deadline job from pending when testing. #5988 + +When testing we wont put the Deadline jobs into pending with dependencies, so the worker can start as soon as possible. + + +___ + +
+ + +
+Max: Tweaks on Extractions for the exporters #5814 + +With this PR +- Suspend Refresh would be introduced in abc & obj extractors for optimization. +- Allow users to choose the custom attributes to be included in abc exports + + +___ + +
+ + +
+Maya: Optional preserve references. #5994 + +Optional preserve references when publishing Maya scenes. + + +___ + +
+ + +
+AYON ftrack: Expect 'ayon' group in custom attributes #6066 + +Expect `ayon` group as one of options to get custom attributes. + + +___ + +
+ + +
+AYON Chore: Remove dependencies related to separated addons #6074 + +Removed dependencies from openpype client pyproject.toml that are already defined by addons which require them. + + +___ + +
+ + +
+Editorial & chore: Stop using pathlib2 #6075 + +Do not use `pathlib2` which is Python 2 backport for `pathlib` module in python 3. + + +___ + +
+ + +
+Traypublisher: Correct validator label #6084 + +Use correct label for Validate filepaths. + + +___ + +
+ + +
+Nuke: Extract Review Intermediate disabled when both Extract Review Mov and Extract Review Intermediate disabled in setting #6089 + +Report in Discord https://discord.com/channels/517362899170230292/563751989075378201/1187874498234556477 + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Bug fix the file from texture node not being collected correctly in Yeti Rig #5990 + +Fix the bug of collect Yeti Rig not being able to get the file parameter(s) from the texture node(s), resulting to the failure of publishing the textures to the resource directory. + + +___ + +
+ + +
+Bug: fix AYON settings for Maya workspace #6069 + +This is changing bug in default AYON setting for Maya workspace, where missing semicolumn caused workspace not being set. This is also syncing default workspace settings to OpenPype + + +___ + +
+ + +
+Refactor colorspace handling in CollectColorspace plugin #6033 + +Traypublisher is now capable set available colorspaces or roles to publishing images sequence or video. This is fix of new implementation where we allowed to use roles in the enumerator selector. + + +___ + +
+ + +
+Bugfix: Houdini render split bugs #6037 + +This PR is a follow up PR to https://github.com/ynput/OpenPype/pull/5420This PR does: +- refactor `get_output_parameter` to what is used to be. +- fix a bug with split render +- rename `exportJob` flag to `split_render` + + +___ + +
+ + +
+Fusion: fix for single frame rendering #6056 + +Fixes publishes of single frame of `render` product type. + + +___ + +
+ + +
+Photoshop: fix layer publish thumbnail missing in loader #6061 + +Thumbnails from any products (either `review` nor separate layer instances) weren't stored in Ayon.This resulted in not showing them in Loader and Server UI. After this PR thumbnails should be shown in the Loader and on the Server (`http://YOUR_AYON_HOSTNAME:5000/projects/YOUR_PROJECT/browser`). + + +___ + +
+ + +
+AYON Chore: Do not use thumbnailSource for thumbnail integration #6063 + +Do not use `thumbnailSource` for thumbnail integration. + + +___ + +
+ + +
+Photoshop: fix creation of .mov #6064 + +Generation of .mov file with 1 frame per published layer was failing. + + +___ + +
+ + +
+Photoshop: fix Collect Color Coded settings #6065 + +Fix for wrong default value for `Collect Color Coded Instances` Settings + + +___ + +
+ + +
+Bug: Fix Publisher parent window in Nuke #6067 + +Fixing issue where publisher parent window wasn't set because wrong use of version constant. + + +___ + +
+ + +
+Python console widget: Save registry fix #6076 + +Do not save registry until there is something to save. + + +___ + +
+ + +
+Ftrack: update asset names for multiple reviewable items #6077 + +Multiple reviewable assetVersion components with better grouping to asset version name. + + +___ + +
+ + +
+Ftrack: DJV action fixes #6098 + +Fix bugs in DJV ftrack action. + + +___ + +
+ + +
+AYON Workfiles tool: Fix arrow to timezone typo #6099 + +Fix parenthesis typo with arrow local timezone function. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Chore: Update folder-favorite icon to ayon icon #5718 + +Updates old "Pype-2.0-era" (from ancient greece times) to AYON logo equivalent.I believe it's only used in Nuke. + + +___ + +
+ +### **Merged pull requests** + + +
+Chore: Maya / Nuke remove publish gui filters from settings #5570 + +- Remove Publish GUI Filters from Nuke settings +- Remove Publish GUI Filters from Maya settings + + +___ + +
+ + +
+Fusion: Project/User option for output format (create_saver) #6045 + +Adds "Output Image Format" option which can be set via project settings and overwritten by users in "Create" menu. This replaces the current behaviour of being hardcoded to "exr". Replacing the need for people to manually edit the saver path if they require a different extension. + + +___ + +
+ + +
+Fusion: Output Image Format Updating Instances (create_saver) #6060 + +Adds the ability to update Saver image output format if changed in the Publish UI.~~Adds an optional validator that compares "Output Image Format" in the Publish menu against the one currently found on the saver. It then offers a repair action to update the output extension on the saver.~~ + + +___ + +
+ + +
+Tests: Fix representation count for AE legacy test #6072 + + +___ + +
+ + + + +## [3.18.1](https://github.com/ynput/OpenPype/tree/3.18.1) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.18.0...3.18.1) + +### **🚀 Enhancements** + + +
+AYON: Update ayon api to 1.0.0-rc.3 #6052 + +Updated ayon python api to 1.0.0-rc.3. + + +___ + +
+ + + + +## [3.18.0](https://github.com/ynput/OpenPype/tree/3.18.0) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/...3.18.0) + +### **🐛 Bug fixes** + + +
+Chore: Fix subst paths handling #5702 + +Make sure that source disk ends with `\` instead of destination disk. + + +___ + +
+ + + + +## [3.17.7](https://github.com/ynput/OpenPype/tree/3.17.7) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.6...3.17.7) + +### **🆕 New features** + + +
+AYON: Use folder path as unique identifier #5817 + +Use folder path instead of asset name as unique identifier, with OpenPype compatibility. + + +___ + +
+ + +
+Houdini: Farm caching submission to Deadline #4903 + +Implements functionality to offload instances of the specific families to be processed on Deadline instead of locally. This increases productivity as artist can use local machine could be used for other tasks.Implemented for families: +- [x] ass +- [x] redshift proxy +- [x] ifd +- [x] abc +- [x] bgeo +- [x] vdb + + +___ + +
+ + +
+Houdini: Add support to split Deadline render tasks in export + render #5420 + +This adds initial support in Houdini so when submitting render jobs to Deadline it's not running as a single Houdini task but rather it gets split in two different tasks: Export + Render. This way it's more efficient as we only need a Houdini license during the export step and the render tasks can run exclusively with a render license. Moreover, we aren't wasting all the overhead time of opening the render scene in Houdini for every frame.I have also added the corresponding settings json files so we can set some of the default values for the Houdini deadline submitter. + + +___ + +
+ + +
+Wrap: new integration #5823 + +These modifications are necessary for adding Wrap integration (DCC handling scans and textures) . + + +___ + +
+ + +
+AYON: Prepare for 'data' via graphql #5923 + +AYON server does support to query 'data' field for hierarchy entities (project > ... > representation) using GraphQl since version 0.5.5. Because of this PR in ayon-python-api it is required to modify custom graphql function in `openpype.client` to support that option. + + +___ + +
+ + +
+Chore AYON: AYON addon class #5937 + +Introduced base class for AYON addon in openpype modules discovery logic. + + +___ + +
+ + +
+Asset Usage Reporter Tool #5946 + +This adds simple tool for OpenPype mode that will go over all published workfiles and print linked assets and their version:This is created per project and can be exported in csv file or copied to clipboard in _"ASCII Human readable form"_. + + +___ + +
+ + +
+Testing: dump_databases flag #5955 + +This introduces a `dump_databases` flag which makes it convenient to output the resulting database of a successful test run. The flag supports two formats; `bson` and `json`.Due to outputting to the test data folder, when dumping the databases, the test data folder will persist.Split from https://github.com/ynput/OpenPype/pull/5644 + + +___ + +
+ + +
+SiteSync: implemented in Ayon Loader #5962 + +Implemented `Availability` column in Ayon loader and redo of loaders to `ActionItems` in representation window there. + + +___ + +
+ + +
+AYON: Workfile template build works #5975 + +Modified workfile template builder to work, to some degree, in AYON mode. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: Small Tweaks on Validator for Look Default Shader Connection for Maya 2024 #5957 + +Resolve https://github.com/ynput/OpenPype/issues/5269 + + +___ + +
+ + +
+Settings: Changes in default settings #5983 + +We've made some changes in the default settings as several application versions were obsolete (Maya 18, Nuke 11, PS 2020, etc). Also added tools and changed settings for Blender, Maya, and Blender. + +All should work as usual. +___ + +
+ + +
+Testing: Do not persist data by default in Maya/Deadline. #5987 + +This is similar to the Maya publishing test. + + +___ + +
+ + +
+Max: Validate loaded plugins tweaks #5820 + +In the current development of 3dsMax, users need to use separate validators to validate if certain plugins being loaded before the extraction. For example, usd extractor in model family, prt/tycache extractor in pointcloud/tycache family.But with the PR where implements optional validate loaded plugin, users just need to put what kind of plugins they want to validate in the settings. They no longer need to go through all the separate plugin validators when publishing, and only one validator would do all the check on the loaded plugins before extraction. + + +___ + +
+ + +
+Nuke: Change context label enhancement #5887 + +Use QAction to change label of context label in Nuke pipeline menu. + + +___ + +
+ + +
+Chore: Do not use template data as source for context #5918 + +Use available information on context to receive context data instead of using `"anatomyData"` during publishing. + + +___ + +
+ + +
+Houdini: Add python3.10 libs for Houdini 20 startup #5932 + +Add python3.10 libs for Houdini 20 startup + + +___ + +
+ + +
+General: Use colorspace data when creating thumbnail #5938 + +Thumbnails with applied colormanagement. + + +___ + +
+ + +
+Ftrack: rewriting component creation to support multiple thumbnails #5939 + +The creation of Ftrack components needs to allow for multiple thumbnails. This is important in situations where there could be several reviewable streams, like in the case of a nuke intermediate files preset. Customers have asked for unique thumbnails for each data stream.For instance, one stream might contain a baked LUT file along with Display and View. Another stream might only include the baked Display and View. These variations can change the overall look. Thus, we found it necessary to depict these differences via thumbnails. + + +___ + +
+ + +
+Chore: PySide6 tree view style #5940 + +Define solid color for background of branch in QTreeView. + + +___ + +
+ + +
+Nuke: Explicit Thumbnail workflow #5941 + +Nuke made a shift from using its own plugin to a global one for thumbnail creation. This was because it had to handle several thumbnail workflows for baking intermediate data streams. To manage this, the global plugin had to be upgraded. Now, each baking stream can set a unique tag 'need_thumbnail'. This tag is used to mark representations that need a thumbnail. + + +___ + +
+ + +
+Global: extract thumbnail with new settings #5944 + +Settings are now configurable for the following: +- target size of thumbnail - source or constrained to specific +- where should be frame taken from in sequence or video file +- if thumbnail should be integrated or not +- background color for letter boxes +- added AYON settings + + +___ + +
+ + +
+RoyalRender: inject submitter environment to the royal render job #5958 + +This is an attempt to solve runtime environment injection for render jobs in RoyalRender as there is no easy way to implement something like `GlobalJobPreload` logic in Deadline. Idea is to inject OpenPype environments directly to the job itself. + + +___ + +
+ + +
+General: Use manual thumbnail if present when publishing #5969 + +Use manual thumbnail added to the publisher instead of using it from published representation. + + +___ + +
+ + +
+AYON: Change of server url should work as expected #5971 + +Using login action in tray menu to change server url should correctly start new process without issues of missing bundle or previous url. + + +___ + +
+ + +
+AYON: make sure the AYON menu bar in 3dsMax is named AYON when AYON launches #5972 + +Renaming the menu bar in 3dsMax for AYON and some cosmetic fix in the docstring + + +___ + +
+ + +
+Resolve: renaming menu to AYON #5974 + +Resolve in Ayon is now having aligned name. + + +___ + +
+ + +
+Hiero: custom tools menu rename #5976 + +- OpenPype Tools are now Custom Tools menu +- fixing order of tools. Create should be first. + + +___ + +
+ + +
+nuke: updating name for custom tools menu item #5977 + +- Ayon variant of settings renamed `Custom Tools` menu item + + +___ + +
+ + +
+fusion: AYON renaming menu #5978 + +Fusion is having Ayon menu. + + +___ + +
+ + +
+Blender: Changed the labels for Layout JSON Extractor #5981 + +Changed the labels for Blender's Layout JSON Extractor. + + +___ + +
+ + +
+Testing: Skip Arnold license for test rendering. #5984 + +Skip license check when rendering for testing. + + +___ + +
+ + +
+Testing: Validate errors and failed status from Deadline jobs. #5986 + +While waiting for the Deadline jobs to finish, we query the errors on the job and its dependent jobs to fail as early as possible. Plus the failed status. + + +___ + +
+ + +
+AYON: rename Openpype Tools as Custom Tools in Maya Host #5991 + +Rename Openpype Tools as Custom Tools in Maya Host in + + +___ + +
+ + +
+AYON: Use AYON label in ayon mode #5995 + +Replaced OpenPype with AYON in AYON mode and added bundle nam to information. + + +___ + +
+ + +
+AYON: Update ayon python api #6002 + +Updated ayon-python-api to '1.0.0-rc.1'. + + +___ + +
+ + +
+Max: Add missing repair action in validate resolution setting #6014 + +Add missing repair action for validate resolution setting + + +___ + +
+ + +
+Add the AYON/OP settings to enable extractor for model family in 3dsmax #6027 + +Add the AYON/OP settings to enable extractor for model family in 3dsmax + + +___ + +
+ + +
+Bugfix: Fix error message formatting if ayon executable can't be found by deadline #6028 + +Without this fix the error message would report executables string with `;` between EACH character, similar to this PR: https://github.com/ynput/OpenPype/pull/5815However that PR apparently missed also fixing it in `GlobalJobPreLoad` and only fixed it in `Ayon.py` plugin. + + +___ + +
+ + +
+Show slightly different info in AYON mode #6031 + +This PR changes what is shown in Tray menu in AYON mode. Previously, it showed version of OpenPype that is very confusing in AYON mode. So this now shows AYON version instead. When clicked, it will opene AYON info window, where OpenPype version is now added, for debugging purposes. + + +___ + +
+ + +
+AYON Editorial: Hierarchy context have names as keys #6041 + +Use folder name as keys in `hierarchyContext` and modify hierachy extraction accordingly. + + +___ + +
+ + +
+AYON: Convert the createAt value to local timezone #6043 + +Show correct create time in UIs. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Render creation - fix broken imports #5893 + +Maya specific imports were moved to specific methods but not in all cases by #5775. This is just quickly restoring functionality without questioning that decision. + + +___ + +
+ + +
+Maya: fix crashing model renderset collector #5929 + +This fix is handling case where model is in some type of render sets but no other connections are made there. Publishing this model would fail with `RuntimeError: Found no items to list the history for.` + + +___ + +
+ + +
+Maya: Remove duplicated attributes of MTOA verbosity level #5945 + +Remove duplicated attributes implementation mentioned in https://github.com/ynput/OpenPype/pull/5931#discussion_r1402175289 + + +___ + +
+ + +
+Maya: Bug fix Redshift Proxy not being successfully published #5956 + +Bug fix redshift proxy family not being successfully published due to the error found in integrate.py + + +___ + +
+ + +
+Maya: Bug fix load image for texturesetMain #6011 + +Bug fix load image with file node for texturesetMain + + +___ + +
+ + +
+Maya: bug fix the repair function in validate_rendersettings #6021 + +The following error has been encountered below: +``` +// pyblish.pyblish.plugin.Action : Finding failed instances.. +// pyblish.pyblish.plugin.Action : Attempting repair for instance: renderLookdevMain ... +// Error: pyblish.plugin : Traceback (most recent call last): +// File "C:\Users\lbate\AppData\Local\Ynput\AYON\dependency_packages\ayon_2310271602_windows.zip\dependencies\pyblish\plugin.py", line 527, in __explicit_process +// runner(*args) +// File "C:\Users\lbate\AppData\Local\Ynput\AYON\addons\openpype_3.17.7-nightly.6\openpype\pipeline\publish\publish_plugins.py", line 241, in process +// plugin.repair(instance) +// File "C:\Users\lbate\AppData\Local\Ynput\AYON\addons\openpype_3.17.7-nightly.6\openpype\hosts\maya\plugins\publish\validate_rendersettings.py", line 395, in repair +// cmds.setAttr("{}.{}".format(node, prefix_attr), +// UnboundLocalError: local variable 'node' referenced before assignment +// Traceback (most recent call last): +// File "C:\Users\lbate\AppData\Local\Ynput\AYON\dependency_packages\ayon_2310271602_windows.zip\dependencies\pyblish\plugin.py", line 527, in __explicit_process +// runner(*args) +// File "C:\Users\lbate\AppData\Local\Ynput\AYON\addons\openpype_3.17.7-nightly.6\openpype\pipeline\publish\publish_plugins.py", line 241, in process +// plugin.repair(instance) +// File "C:\Users\lbate\AppData\Local\Ynput\AYON\addons\openpype_3.17.7-nightly.6\openpype\hosts\maya\plugins\publish\validate_rendersettings.py", line 395, in repair +// cmds.setAttr("{}.{}".format(node, prefix_attr), +// UnboundLocalError: local variable 'node' referenced before assignment +``` +This PR is a fix for that + + +___ + +
+ + +
+Fusion: Render avoid unhashable type `BlackmagicFusion.PyRemoteObject` error #5672 + +Fix Fusion 18.6+ support: Avoid issues with Fusion's `BlackmagicFusion.PyRemoteObject` instances being unhashable. +```python +Traceback (most recent call last): + File "E:\openpype\OpenPype\.venv\lib\site-packages\pyblish\plugin.py", line 527, in __explicit_process + runner(*args) + File "E:\openpype\OpenPype\openpype\hosts\fusion\plugins\publish\extract_render_local.py", line 61, in process + result = self.render(instance) + File "E:\openpype\OpenPype\openpype\hosts\fusion\plugins\publish\extract_render_local.py", line 118, in render + with enabled_savers(current_comp, savers_to_render): + File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\contextlib.py", line 119, in __enter__ + return next(self.gen) + File "E:\openpype\OpenPype\openpype\hosts\fusion\plugins\publish\extract_render_local.py", line 33, in enabled_savers + original_states[saver] = original_state +TypeError: unhashable type: 'BlackmagicFusion.PyRemoteObject' +``` + + + +___ + +
+ + +
+Nuke: Validate Nuke Write Nodes refactor to use variable `node_value` instead of `value` #5764 + +Nuke: Validate Nuke Write Nodes refactor to use variable `node_value` instead of `value`The variable `value` only exists as the last variable value in the `for value in values` loop and might not be declared if `values` is an empty iterable. + + +___ + +
+ + +
+resolve: fixing loader handles calculation #5863 + +Resolve was not correctly calculating duration of database related duration. + + +___ + +
+ + +
+Chore: Staging mode determination #5895 + +Resources use `is_staging_enabled` function instead of `is_running_staging` to determine if should use staging icon. And fixed comparison bug in `is_running_staging`. + + +___ + +
+ + +
+AYON: Handle staging templates category #5905 + +Staging anatomy templates category is handled during project templates conversion. The keys are stored into `others` with `"staging_"` prefix. + + +___ + +
+ + +
+Max: fix the subset name not changing accordingly after the variant name changes #5911 + +Resolve #5902 + + +___ + +
+ + +
+AYON: Loader tool bugs hunt #5915 + +Fix issues with invalid representation ids in loaded containers and handle missing product type in server database. + + +___ + +
+ + +
+Publisher: Bugfixes and enhancements #5924 + +Small fixes/enhancements in publisher UI. + + +___ + +
+ + +
+Maya: Supports for additional Job Info and Plugin Info in deadline submission #5931 + +This PR is to resolve some of the attributes such as MTOA's `ArnoldVerbose` are not preserved on farm and users can use the project settings to add the attributes back to either job or plugin Info. + + +___ + +
+ + +
+Bugfix: Houdini license validator missing families #5934 + +Adding missing families to Houdini license validator. + + +___ + +
+ + +
+TrayPublisher: adding back `asset_doc` variable #5943 + +Returning variable which had been removed accidentally in previous PR. + + +___ + +
+ + +
+Settings: Fix ModulesManager init args #5947 + +Remove usage of kwargs to create ModulesManager. + + +___ + +
+ + +
+Blender: Fix Deadline Frames per task #5949 + +Fixed a problem with Frames per task setting not being applied when publishing a render. + + +___ + +
+ + +
+Testing: Fix is_test_failed #5951 + +`is_test_failed` is used (exclusively) on module fixtures to determine whether the tests have failed or not. This determines whether to run tear down code like cleaning up the database and temporary files.But in the module scope `request.node.rep_call` is not available, which results in `is_test_failed` always returning `True`, and no tear down code get executed.The solution was taken from; https://github.com/pytest-dev/pytest/issues/5090 + + +___ + +
+ + +
+Harmony: Fix local rendering #5953 + +Local rendering was throwing warning about license, but didn't fail per se. It just didn't produce anything. + + +___ + +
+ + +
+Testing: hou module should be within class code. #5954 + +`hou` module should be within the class code else we'll get pyblish errors from needing to skip the plugin. + + +___ + +
+ + +
+Maya: Add Label to MayaUSDReferenceLoader #5964 + +As the create placeholder dialog displays the two distinct loaders with the same name, this PR is to distinguish Maya USD Reference Loaders from the loaders of which inherited from. See the screenshot below: + + +___ + +
+ + +
+Max: Bug fix the resolution not being shown correctly in review burnin #5965 + +The resolution is not being shown correctly in review burnin + + +___ + +
+ + +
+AYON: Fix thumbnail integration #5970 + +Thumbnail integration could cause crash of server if thumbnail id was changed for the same entity id multiple times. Modified the code to avoid that issue. + + +___ + +
+ + +
+Photoshop: Updated label in Settings #5980 + +Replaced wrong label from different plugin. + + +___ + +
+ + +
+Photoshop: Fix removed unsupported Path #5996 + +Path is not json serializable by default, it is not necessary, better model reused. + + +___ + +
+ + +
+AYON: Prepare functions for newer ayon-python-api #5997 + +Newer ayon python api will add new filtering options or change order of existing. Kwargs are used in client code to prevent issues on update. + + +___ + +
+ + +
+AYON: Conversion of the new playblast settings in Maya #6000 + +Conversion of the new playblast settings in Maya + + +___ + +
+ + +
+AYON: Bug fix for loading Mesh in Substance Painter as new project not working #6004 + +Substance Painter in AYON can't load mesh for creating a new project + + +___ + +
+ + +
+Deadline: correct webservice couldn't be selected in Ayon #6007 + +Changed the Setting model to mimic more OP approach as it needs to live together for time being. + + +___ + +
+ + +
+AYON tools: Fix refresh thread #6008 + +Trigger 'refresh_finished' signal out of 'run' method. + + +___ + +
+ + +
+Ftrack: multiple reviewable components missing variable #6013 + +Missing variable in code for editorial publishing in traypublisher. + + +___ + +
+ + +
+TVPaint: Expect legacy instances in metadata #6015 + +Do not expect `"workfileInstances"` constains only new type instance data with `creator_identifier`. + + +___ + +
+ + +
+Bugfix: handle missing key in Deadline #6019 + +This quickly fixes bug introduced by #5420 + + +___ + +
+ + +
+Revert `extractenvironments` behaviour #6020 + +This is returning original behaviour of `extractenvironments` command from before #5958 so we restore functionality. + + +___ + +
+ + +
+OP-7535 - Fix renaming composition in AE #6025 + +Removing of `render` instance caused renaming of composition to `dummyComp` which caused issue in publishing in next attempt.This PR stores original composition name(cleaned up for product name creation) and uses it if instance needs to be removed. + + +___ + +
+ + +
+Refactor code to skip instance creation for new assets #6029 + +Publishing effects from hiero during editorial publish is working as expected again. + + +___ + +
+ + +
+Refactor code to handle missing "representations" key in instance data #6032 + +Minor code change for optimisation of thumbnail workflow. + + +___ + +
+ + +
+Traypublisher: editorial preserve clip case sensitivity #6036 + +Keep EDL clip name inheritance with case sensitivity. + + +___ + +
+ + +
+Bugfix/add missing houdini settings #6039 + +add missing settings. now, it looks like this:| Ayon | OpenPype || -- | -- | | | || | | + + +___ + +
+ +### **🔀 Refactored code** + + +
+Maya: Remove RenderSetup layer observers #5836 + +Remove RenderSetup layer observers that are not needed since new publisher since Renderlayer Creators manage these themselves on Collect and Save/Update of instances. + + +___ + +
+ +### **Merged pull requests** + + +
+Tests: Removed render instance #6026 + +This test was created as simple model and workfile publish, without Deadline rendering. Cleaned up render elements. + + +___ + +
+ + +
+Tests: update after thumbnail default change #6040 + +https://github.com/ynput/OpenPype/pull/5944 changed default state of integration of Thumbnails to NOT integrate. This PR updates automatic tests to follow that. + + +___ + +
+ + +
+Houdini: Remove legacy LOPs USD output processors #5861 + +Remove unused/broken legacy code for Houdini Solaris USD LOPs output processors. The code was originally written in Avalon, against early Houdini 18 betas which had a different API for output processors and thus the current state doesn't even work in recent versions of Houdini. + + +___ + +
+ + +
+Chore: Substance Painter Addons for Ayon #5914 + +Substance Painter Addons for Ayon + + +___ + +
+ + +
+Ayon: Updated name of Adobe extension to Ayon #5992 + +This changes name in menu in Adobe extensions to Ayon. + + +___ + +
+ + +
+Chore/houdini update startup log #6003 + +print `Installing AYON ...` on startup when launching houdini from launcher in ayon mode.also update submenu to `ayon_menu` instead of `openpype_menu` + + +___ + +
+ + +
+Revert "Ayon: Updated name of Adobe extension to Ayon" #6010 + +Reverts ynput/OpenPype#5992 + +That PR is only applicable to Ayon. +___ + +
+ + +
+Standalone/Tray Publisher: Remove simple Unreal texture publishing #6012 + +We are removing _simple Unreal Texture publishing_ that was just renaming texture files to fit to Unreal naming conventions but without any additional functionality. We might return this functionality back with better texture publishing system.Related to #5983 + + +___ + +
+ + +
+Deadline: Bump version because of Settings changes for Deadline #6023 + + +___ + +
+ + +
+Change ASCII art in the Console based on the server mode #6030 + +This changes ASCII art in the console based on the AYON/OpenPype mode + + +___ + +
+ + + + +## [3.17.6](https://github.com/ynput/OpenPype/tree/3.17.6) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.5...3.17.6) + +### **🚀 Enhancements** + + +
+Testing: Validate Maya Logs #5775 + +This PR adds testing of the logs within Maya such as Python and Pyblish errors.The reason why we need to touch so many files outside of Maya is because of the pyblish errors below; +``` +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "collect_otio_frame_ranges" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "collect_otio_frame_ranges" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "collect_otio_review" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "collect_otio_review" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "collect_otio_subset_resources" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "collect_otio_subset_resources" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "extract_otio_audio_tracks" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "extract_otio_audio_tracks" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "extract_otio_file" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "extract_otio_file" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "extract_otio_review" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "extract_otio_review" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "extract_otio_trimming_video" (No module named 'opentimelineio') +# Error: pyblish.plugin : Skipped: "extract_otio_trimming_video" (No module named 'opentimelineio') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "submit_blender_deadline" (No module named 'bpy') +# Error: pyblish.plugin : Skipped: "submit_blender_deadline" (No module named 'bpy') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "submit_houdini_remote_publish" (No module named 'hou') +# Error: pyblish.plugin : Skipped: "submit_houdini_remote_publish" (No module named 'hou') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "submit_houdini_render_deadline" (No module named 'hou') +# Error: pyblish.plugin : Skipped: "submit_houdini_render_deadline" (No module named 'hou') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "submit_max_deadline" (No module named 'pymxs') +# Error: pyblish.plugin : Skipped: "submit_max_deadline" (No module named 'pymxs') # +pyblish (ERROR) (line: 1371) pyblish.plugin: +Skipped: "submit_nuke_deadline" (No module named 'nuke') +# Error: pyblish.plugin : Skipped: "submit_nuke_deadline" (No module named 'nuke') # +``` +We also needed to `stdout` and `stderr` from the launched application to capture the output.Split from #5644.Dependent on #5734 + + +___ + +
+ + +
+Maya: Render Settings cleanup remove global `RENDER_ATTRS` #5801 + +Remove global `lib.RENDER_ATTRS` and implement a `RenderSettings.get_padding_attr(renderer)` method instead. + + +___ + +
+ + +
+Testing: Ingest expected files and input workfile #5840 + +This ingests the Maya workfile from the Drive storage. Have changed the format to MayaAscii so its easier to see what changes are happening in a PR. This meant changing the expected files and database entries as well. + + +___ + +
+ + +
+Chore: Create plugin auto-apply settings #5908 + +Create plugins can auto-apply settings. + + +___ + +
+ + +
+Resolve: Add save current file button + "Save" shortcut when menu is active #5691 + +Adds a "Save current file" to the OpenPype menu.Also adds a "Save" shortcut key sequence (CTRL+S on Windows) to the button, so that clicking CTRL+S when the menu is active will save the current workfile. However this of course does not work if the menu does not receive the key press event (e.g. when Resolve UI is active instead)Resolves #5684 + + +___ + +
+ + +
+Reference USD file as maya native geometry #5781 + +Add MayaUsdReferenceLoader to reference USD as Maya native geometry using `mayaUSDImport` file translator. + + +___ + +
+ + +
+Max: Bug fix on wrong aspect ratio and viewport not being maximized during context in review family #5839 + +This PR will fix the bug on wrong aspect ratio and viewport not being maximized when creating preview animationBesides, the support of tga image format and the options for AA quality are implemented in this PR + + +___ + +
+ + +
+Blender: Incorporate blender "Collections" into Publish/Load #5841 + +Allow `blendScene` family to include collections. + + +___ + +
+ + +
+Max: Allows user preset the setting of preview animation in OP/AYON Setting #5859 + +Allows user preset the setting of preview animation in OP/AYON Setting for review family. +- [x] Openpype +- [x] AYON + + +___ + +
+ + +
+Publisher: Center publisher window on first show #5877 + +Move publisher window to center of a screen on first show. + + +___ + +
+ + +
+Publisher: Instance context changes confirm works #5881 + +Confirmation of context changes in publisher on existing instances does not cause glitches. + + +___ + +
+ + +
+AYON workfiles tools: Revisit workfiles tool #5897 + +Revisited workfiles tool for AYON mode to reuse common models and widgets. + + +___ + +
+ + +
+Nuke: updated colorspace settings #5906 + +Updating nuke colorspace settings into more convenient way with usage of ocio config roles rather then particular colorspace names. This way we should not have troubles to switch between linear Rec709 or ACES configs without any additional settings changes. + + +___ + +
+ + +
+Blender: Refactor to new publisher #5910 + +Refactor Blender integration to use the new publisher + + +___ + +
+ + +
+Enhancement: Some publish logs cosmetics #5917 + +General logging message tweaks: +- Sort some lists of folder/filenames so they appear sorted in the logs +- Fix some grammar / typos +- In some cases provide slightly more information in a log + + +___ + +
+ + +
+Blender: Better name of 'asset_name' function #5927 + +Renamed function `asset_name` to `prepare_scene_name`. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Bug fix the fbx animation export errored out when the skeletonAnim set is empty #5875 + +Resolve this bug discordIf the skeletonAnim SET is empty and fbx animation collect, the fbx animation extractor would skip the fbx extraction + + +___ + +
+ + +
+Bugfix: fix few typos in houdini's and Maya's Ayon settings #5882 + +Fixing few typos +- [x] Maya unreal static mesh +- [x] Houdini static mesh +- [x] Houdini collect asset handles + + +___ + +
+ + +
+Bugfix: Ayon Deadline env vars + error message on no executable found #5815 + +Fix some Ayon x Deadline issues as came up in this topic: +- missing Environment Variables issue explained here for `deadlinePlugin.RunProcess` for the AYON _extract environments_ call. +- wrong error formatting described here with a `;` between each character like this: `Ayon executable was not found in the semicolon separated list "C;:;/;P;r;o;g;r;a;m; ;F;i;l;e;s;/;Y;n;p;u;t;/;A;Y;O;N; ;1;.;0;.;0;-;b;e;t;a;.;5;/;a;y;o;n;_;c;o;n;s;o;l;e;.;e;x;e". The path to the render executable can be configured from the Plugin Configuration in the Deadline Monitor.` + + +___ + +
+ + +
+AYON: Fix bundles access in settings #5856 + +Fixed access to bundles data in settings to define correct develop variant. + + +___ + +
+ + +
+AYON 3dsMax settings: 'ValidateAttributes' settings converte only if available #5878 + +Convert `ValidateAttributes` settings only if are available in AYON settings. + + +___ + +
+ + +
+AYON: Fix TrayPublisher editorial settings #5880 + +Fixing Traypublisher settings for adding task in simple editorial. + + +___ + +
+ + +
+TrayPublisher: editorial frame range check not needed #5884 + +Validator for frame ranges is not needed during editorial publishing since entity data are not yet in database. + + +___ + +
+ + +
+Update houdini license validator #5886 + +As reported in this community commentHoudini USD publishing is only restricted in Houdini apprentice. + + +___ + +
+ + +
+Blender: Fix blend extraction and packed images #5888 + +Fixed a with blend extractor and packed images. + + +___ + +
+ + +
+AYON: Initialize connection with all information #5890 + +Create global AYON api connection with all informations all the time. + + +___ + +
+ + +
+AYON: Scene inventory tool without site sync #5896 + +Skip 'get_site_icons' if site sync addon is disabled. + + +___ + +
+ + +
+Publish report tool: Fix PySide6 #5898 + +Use constants from classes instead of objects. + + +___ + +
+ + +
+fusion: removing hardcoded template name for saver #5907 + +Fusion is not hardcoded for `render` anatomy template only anymore. This was blocking AYON deployment. + + +___ + +
+ + + + +## [3.17.5](https://github.com/ynput/OpenPype/tree/3.17.5) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.4...3.17.5) + +### **🆕 New features** + + +
+Fusion: Add USD loader #4896 + +Add an OpenPype managed USD loader (`uLoader`) for Fusion. + + +___ + +
+ + +
+Fusion: Resolution validator #5325 + +Added a resolution validator.The code is from my old PR (https://github.com/ynput/OpenPype/pull/4921) that I closed because the PR also contained a frame range validator that no longer is needed. + + +___ + +
+ + +
+Context Selection tool: Refactor Context tool (for AYON) #5766 + +Context selection tool has AYON variant. + + +___ + +
+ + +
+AYON: Use AYON username for user in template data #5842 + +Use ayon username for template data in AYON mode. + + +___ + +
+ + +
+Testing: app_group flag #5869 + +`app_group` command flag. This is for changing which flavour of the host to launch. In the case of Maya, you can launch Maya and MayaPy, but it can be used for the Nuke family as well.Split from #5644 + + +___ + +
+ +### **🚀 Enhancements** + + +
+Enhancement: Fusion fix saver creation + minor Blender/Fusion logging tweaks #5558 + +- Blender change logs to `debug` level in preparation for new publisher artist facing reports (note that it currently still uses the old publisher) +- Fusion: Create Saver fix redeclaration of default_variants +- Fusion: Fix saver being created in incorrect state without saving directly after create +- Fusion: Allow reset frame range on render family +- Fusion: Tweak logging level for artist-facing report + + +___ + +
+ + +
+Resolve: load clip to timeline at set time #5665 + +It is possible to load clip to correct place on timeline. + + +___ + +
+ + +
+Nuke: Optional Deadline workfile dependency. #5732 + +Adds option to add the workfile as dependency for the Deadline job.Think it used to have something like this, but it disappeared. Usecase is for remote workflow where the Nuke script needs to be synced before the job can start. + + +___ + +
+ + +
+Enhancement/houdini rearrange ayon houdini settings files #5748 + +Rearranging Houdini Settings to be more readable, easier to edit, update settings (include all families/product types)This PR is mainly for Ayon Settings to have more organized files. For Openpype, I'll make sure that each Houdini setting in Ayon has an equivalent in Openpype. +- [x] update Ayon settings, fix typos and remove deprecated settings. +- [x] Sync with Openpype +- [x] Test in Openpype +- [x] Test in Ayon + + +___ + +
+ + +
+Chore: updating create ayon addon script #5822 + +Adding developers environment options. + + +___ + +
+ + +
+Max: Implement Validator for Properties/Attributes Value Check #5824 + +Add optional validator which can check if the property attributes are valid in Max + + +___ + +
+ + +
+Nuke: Remove unused 'get_render_path' function #5826 + +Remove unused function `get_render_path` from nuke integration. + + +___ + +
+ + +
+Chore: Limit current context template data function #5845 + +Current implementation of `get_current_context_template_data` does return the same values as base template data function `get_template_data`. + + +___ + +
+ + +
+Max: Make sure Collect Render not ignoring instance asset #5847 + +- Make sure Collect Render is not always using asset from context. +- Make sure Scene version being collected +- Clean up unnecessary uses of code in the collector. + + +___ + +
+ + +
+Ftrack: Events are not processed if project is not available in OpenPype #5853 + +Events that happened on project which is not in OpenPype is not processed. + + +___ + +
+ + +
+Nuke: Add Nuke 11.0 as default setting #5855 + +Found I needed Nuke 11.0 in the default settings to help with unit testing. + + +___ + +
+ + +
+TVPaint: Code cleanup #5857 + +Removed unused import. Use `AYON` label in ayon mode. Removed unused data in publish context `"previous_context"`. + + +___ + +
+ + +
+AYON settings: Use correct label for follow workfile version #5874 + +Follow workfile version label was marked as Collect Anatomy Instance Data label. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Nuke: Fix workfile template builder so representations get loaded next to each other #5061 + +Refactor when the cleanup of the placeholder happens for the cases where multiple representations are loaded by a single placeholder.The existing code didn't take into account the case where a template placeholder can load multiple representations so it was trying to do the cleanup of the placeholder node and the re-arrangement of the imported nodes too early. I assume this was designed only for the cases where a single representation can load multiple nodes. + + +___ + +
+ + +
+Nuke: Dont update node name on update #5704 + +When updating `Image` containers the code is trying to set the name of the node. This results in a warning message from Nuke shown below;Suggesting to not change the node name when updating. + + +___ + +
+ + +
+UIDefLabel can be unique #5827 + +`UILabelDef` have implemented comparison and uniqueness. + + +___ + +
+ + +
+AYON: Skip kitsu module when creating ayon addons #5828 + +Create AYON packages is skipping kitsu module in creation of modules/addons and kitsu module is not loaded from modules on start. The addon already has it's repository https://github.com/ynput/ayon-kitsu. + + +___ + +
+ + +
+Bugfix: Collect Rendered Files only collecting first instance #5832 + +Collect all instances from the metadata file - don't return on first instance iteration. + + +___ + +
+ + +
+Houdini: set frame range for the created composite ROP #5833 + +Quick bug fix for created composite ROP, set its frame range to the frame range of the playbar. + + +___ + +
+ + +
+Fix registering launcher actions from OpenPypeModules #5843 + +Fix typo `actions_dir` -> `path` to fix register launcher actions fromm OpenPypeModule + + +___ + +
+ + +
+Bugfix in houdini shelves manager and beautify settings #5844 + +This PR fixes the problem in this PR https://github.com/ynput/OpenPype/issues/5457 by using the right function to load a pre-made houdini `.shelf` fileAlso, it beautifies houdini shelves settings to provide better guidance for users which helps with other issue https://github.com/ynput/OpenPype/issues/5458 , Rather adding default shelf and set names, I'll educate users how to use the tool correctly.Users now are able to select between the two options.| OpenPype | Ayon || -- | -- || | | + + +___ + +
+ + +
+Blender: Fix missing Grease Pencils in review #5848 + +Fix Grease Pencil missing in review when isolating objects. + + +___ + +
+ + +
+Blender: Fix Render Settings in Ayon #5849 + +Fix Render Settings in Ayon for Blender. + + +___ + +
+ + +
+Bugfix: houdini tab menu working as expected #5850 + +This PR:Tab menu name changes to Ayon when using ayon get_network_categories is checked in all creator plugins. | Product | Network Category | | -- | -- | | Alembic camera | rop, obj | | Arnold Ass | rop | | Arnold ROP | rop | | Bgeo | rop, sop | | composite sequence | cop2, rop | | hda | obj | | Karma ROP | rop | | Mantra ROP | rop | | ABC | rop, sop | | RS proxy | rop, sop| | RS ROP | rop | | Review | rop | | Static mesh | rop, obj, sop | | USD | lop, rop | | USD Render | rop | | VDB | rop, obj, sop | | V Ray | rop | + + +___ + +
+ + +
+Bigfix: Houdini skip frame_range_validator if node has no 'trange' parameter #5851 + +I faced a bug when publishing HDA instance as it has no `trange` parameter. As this PR title says : skip frame_range_validator if node has no 'trange' parameter + + +___ + +
+ + +
+Bugfix: houdini image sequence loading and missing frames #5852 + +I made this PR in to fix issues mentioned here https://github.com/ynput/OpenPype/pull/5833#issuecomment-1789207727in short: +- image load doesn't work +- publisher only publish one frame + + +___ + +
+ + +
+Nuke: loaders' containers updating as nodes #5854 + +Nuke loaded containers are updating correctly even they have been duplicating of originally loaded nodes. This had previously been removed duplicated nodes. + + +___ + +
+ + +
+deadline: settings are not blocking extension input #5864 + +Settings are not blocking user input. + + +___ + +
+ + +
+Blender: Fix loading of blend layouts #5866 + +Fix a problem with loading blend layouts. + + +___ + +
+ + +
+AYON: Launcher refresh issues #5867 + +Fixed refresh of projects issue in launcher tool. And renamed Qt models to contain `Qt` in their name (it was really hard to find out where were used). It is not possible to click on disabled item in launcher's projects view. + + +___ + +
+ + +
+Fix the Wrong key words for tycache workfile template settings in AYON #5870 + +Fix the wrong key words for the tycache workfile template settings in AYON(i.e. Instead of families, product_types should be used) + + +___ + +
+ + +
+AYON tools: Handle empty icon definition #5876 + +Ignore if passed icon definition is `None`. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Houdini: Remove on instance toggled callback #5860 + +Remove on instance toggled callback which isn't relevant to the new publisher + + +___ + +
+ + +
+Chore: Remove unused `instanceToggled` callbacks #5862 + +The `instanceToggled` callbacks should be irrelevant for new publisher. + + +___ + +
+ + + + +## [3.17.4](https://github.com/ynput/OpenPype/tree/3.17.4) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.3...3.17.4) + +### **🆕 New features** + + +
+Add Support for Husk-AYON Integration #5816 + +This draft pull request introduces support for integrating Husk with AYON within the OpenPype repository. + + +___ + +
+ + +
+Push to project tool: Prepare push to project tool for AYON #5770 + +Cloned Push to project tool for AYON and modified it. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Max: tycache family support #5624 + +Tycache family supports for Tyflow Plugin in Max + + +___ + +
+ + +
+Unreal: Changed behaviour for updating assets #5670 + +Changed how assets are updated in Unreal. + + +___ + +
+ + +
+Unreal: Improved error reporting for Sequence Frame Validator #5730 + +Improved error reporting for Sequence Frame Validator. + + +___ + +
+ + +
+Max: Setting tweaks on Review Family #5744 + +- Bug fix of not being able to publish the preferred visual style when creating preview animation +- Exposes the parameters after creating instance +- Add the Quality settings and viewport texture settings for preview animation +- add use selection for create review + + +___ + +
+ + +
+Max: Add families with frame range extractions back to the frame range validator #5757 + +In 3dsMax, there are some instances which exports the files in frame range but not being added to the optional frame range validator. In this PR, these instances would have the optional frame range validators to allow users to check if frame range aligns with the context data from DB.The following families have been added to have optional frame range validator: +- maxrender +- review +- camera +- redshift proxy +- pointcache +- point cloud(tyFlow PRT) + + +___ + +
+ + +
+TimersManager: Use available data to get context info #5804 + +Get context information from pyblish context data instead of using `legacy_io`. + + +___ + +
+ + +
+Chore: Removed unused variable from `AbstractCollectRender` #5805 + +Removed unused `_asset` variable from `RenderInstance`. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Bugfix/houdini: wrong frame calculation with handles #5698 + +This PR make collect plugins to consider `handleStart` and `handleEnd` when collecting frame range it affects three parts: +- get frame range in collect plugins +- expected file in render plugins +- submit houdini job deadline plugin + + +___ + +
+ + +
+Nuke: ayon server settings improvements #5746 + +Nuke settings were not aligned with OpenPype settings. Also labels needed to be improved. + + +___ + +
+ + +
+Blender: Fix pointcache family and fix alembic extractor #5747 + +Fixed `pointcache` family and fixed behaviour of the alembic extractor. + + +___ + +
+ + +
+AYON: Remove 'shotgun_api3' from dependencies #5803 + +Removed `shotgun_api3` dependency from openpype dependencies for AYON launcher. The dependency is already defined in shotgrid addon and change of version causes clashes. + + +___ + +
+ + +
+Chore: Fix typo in filename #5807 + +Move content of `contants.py` into `constants.py`. + + +___ + +
+ + +
+Chore: Create context respects instance changes #5809 + +Fix issue with unrespected change propagation in `CreateContext`. All successfully saved instances are marked as saved so they have no changes. Origin data of an instance are explicitly not handled directly by the object but by the attribute wrappers. + + +___ + +
+ + +
+Blender: Fix tools handling in AYON mode #5811 + +Skip logic in `before_window_show` in blender when in AYON mode. Most of the stuff called there happes on show automatically. + + +___ + +
+ + +
+Blender: Include Grease Pencil in review and thumbnails #5812 + +Include Grease Pencil in review and thumbnails. + + +___ + +
+ + +
+Workfiles tool AYON: Fix double click of workfile #5813 + +Fix double click on workfiles in workfiles tool to open the file. + + +___ + +
+ + +
+Webpublisher: removal of usage of no_of_frames in error message #5819 + +If it throws exception, `no_of_frames` value wont be available, so it doesn't make sense to log it. + + +___ + +
+ + +
+Attribute Defs: Hide multivalue widget in Number by default #5821 + +Fixed default look of `NumberAttrWidget` by hiding its multiselection widget. + + +___ + +
+ +### **Merged pull requests** + + +
+Corrected a typo in Readme.md (Top -> To) #5800 + + +___ + +
+ + +
+Photoshop: Removed redundant copy of extension.zxp #5802 + +`extension.zxp` shouldn't be inside of extension folder. + + +___ + +
+ + + + +## [3.17.3](https://github.com/ynput/OpenPype/tree/3.17.3) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.2...3.17.3) + +### **🆕 New features** + + +
+Maya: Multi-shot Layout Creator #5710 + +New Multi-shot Layout creator is a way of automating creation of the new Layout instances in Maya, associated with correct shots, frame ranges and Camera Sequencer in Maya. + + +___ + +
+ + +
+Colorspace: ociolook file product type workflow #5541 + +Traypublisher support for publishing of colorspace look files (ociolook) which are json files holding any LUT files. This new product is available for loading in Nuke host at the moment.Added colorspace selector to publisher attribute with better labeling. We are supporting also Roles and Alias (only v2 configs). + + +___ + +
+ + +
+Scene Inventory tool: Refactor Scene Inventory tool (for AYON) #5758 + +Modified scene inventory tool for AYON. The main difference is in how project name is defined and replacement of assets combobox with folders dialog. + + +___ + +
+ + +
+AYON: Support dev bundles #5783 + +Modules can be loaded in AYON dev mode from different location. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Testing: Ingest Maya userSetup #5734 + +Suggesting to ingest `userSetup.py` startup script for easier collaboration and transparency of testing. + + +___ + +
+ + +
+Fusion: Work with pathmaps #5329 + +Path maps are a big part of our Fusion workflow. We map the project folder to a path map within Fusion so all loaders and savers point to the path map variable. This way any computer on any OS can open any comp no matter where the project folder is located. + + +___ + +
+ + +
+Maya: Add Maya 2024 and remove pre 2022. #5674 + +Adding Maya 2024 as default application variant.Removing Maya 2020 and older, as these are not supported anymore. + + +___ + +
+ + +
+Enhancement: Houdini: Allow using template keys in Houdini shelves manager #5727 + +Allow using Template keys in Houdini shelves manager. + + +___ + +
+ + +
+Houdini: Fix Show in usdview loader action #5737 + +Fix the "Show in USD View" loader to show up in Houdini + + +___ + +
+ + +
+Nuke: validator of asset context with repair actions #5749 + +Instance nodes with different context of asset and task can be now validated and repaired via repair action. + + +___ + +
+ + +
+AYON: Tools enhancements #5753 + +Few enhancements and tweaks of AYON related tools. + + +___ + +
+ + +
+Max: Tweaks on ValidateMaxContents #5759 + +This PR provides enhancements on ValidateMaxContent as follow: +- Rename `ValidateMaxContents` to `ValidateContainers` +- Add related families which are required to pass the validation(All families except `Render` as the render instance is the one which only allows empty container) + + +___ + +
+ + +
+Enhancement: Nuke refactor `SelectInvalidAction` #5762 + +Refactor `SelectInvalidAction` to behave like other action for other host, create `SelectInstanceNodeAction` as dedicated action to select the instance node for a failed plugin. +- Note: Selecting Instance Node will still select the instance node even if the user has currently 'fixed' the problem. + + +___ + +
+ + +
+Enhancement: Tweak logging for Nuke for artist facing reports #5763 + +Tweak logs that are not artist-facing to debug level + in some cases clarify what the logged value is. + + +___ + +
+ + +
+AYON Settings: Disk mapping #5786 + +Added disk mapping settings to core addon settings. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: add colorspace argument to redshiftTextureProcessor #5645 + +In color managed Maya, texture processing during Look Extraction wasn't passing texture colorspaces set on textures to `redshiftTextureProcessor` tool. This in effect caused this tool to produce non-zero exit code (even though the texture was converted into wrong colorspace) and therefor crash of the extractor. This PR is passing colorspace to that tool if color management is enabled. + + +___ + +
+ + +
+Maya: don't call `cmds.ogs()` in headless mode #5769 + +`cmds.ogs()` is a call that will crash if Maya is running in headless mode (mayabatch, mayapy). This is handling that case. + + +___ + +
+ + +
+Resolve: inventory management fix #5673 + +Loaded Timeline item containers are now updating correctly and version management is working as it suppose to. +- [x] updating loaded timeline items +- [x] Removing of loaded timeline items + + +___ + +
+ + +
+Blender: Remove 'update_hierarchy' #5756 + +Remove `update_hierarchy` function which is causing crashes in scene inventory tool. + + +___ + +
+ + +
+Max: bug fix on the settings in pointcloud family #5768 + +Bug fix on the settings being errored out in validate point cloud(see links:https://github.com/ynput/OpenPype/pull/5759#pullrequestreview-1676681705) and passibly in point cloud extractor. + + +___ + +
+ + +
+AYON settings: Fix default factory of tools #5773 + +Fix default factory of application tools. + + +___ + +
+ + +
+Fusion: added missing OPENPYPE_VERSION #5776 + +Fusion submission to Deadline was missing OPENPYPE_VERSION env var when submitting from build (not source code directly). This missing env var might break rendering on DL if path to OP executable (openpype_console.exe) is not set explicitly and might cause an issue when different versions of OP are deployed.This PR adds this environment variable. + + +___ + +
+ + +
+Ftrack: Skip tasks when looking for asset equivalent entity #5777 + +Skip tasks when looking for asset equivalent entity. + + +___ + +
+ + +
+Nuke: loading gizmos fixes #5779 + +Gizmo product is not offered in Loader as plugin. It is also updating as expected. + + +___ + +
+ + +
+General: thumbnail extractor as last extractor #5780 + +Fixing issue with the order of the `ExtractOIIOTranscode` and `ExtractThumbnail` plugins. The problem was that the `ExtractThumbnail` plugin was processed before the `ExtractOIIOTranscode` plugin. As a result, the `ExtractThumbnail` plugin did not inherit the `review` tag into the representation data. This caused the `ExtractThumbnail` plugin to fail in processing and creating thumbnails. + + +___ + +
+ + +
+Bug: fix key in application json #5787 + +In PR #5705 `maya` was wrongly used instead of `mayapy`, breaking AYON defaults in AYON Application Addon. + + +___ + +
+ + +
+'NumberAttrWidget' shows 'Multiselection' label on multiselection #5792 + +Attribute definition widget 'NumberAttrWidget' shows `< Multiselection >` label on multiselection. + + +___ + +
+ + +
+Publisher: Selection change by enabled checkbox on instance update attributes #5793 + +Change of instance by clicking on enabled checkbox will actually update attributes on right side to match the selection. + + +___ + +
+ + +
+Houdini: Remove `setParms` call since it's responsibility of `self.imprint` to set the values #5796 + +Revert a recent change made in #5621 due to this comment. However the change is faulty as can be seen mentioned here + + +___ + +
+ + +
+AYON loader: Fix SubsetLoader functionality #5799 + +Fix SubsetLoader plugin processing in AYON loader tool. + + +___ + +
+ +### **Merged pull requests** + + +
+Houdini: Add self publish button #5621 + +This PR allows single publishing by adding a publish button to created rop nodes in HoudiniAdmins are much welcomed to enable it from houdini general settingsPublish Button also includes all input publish instances. in this screen shot the alembic instance is ignored because the switch is turned off + + +___ + +
+ + +
+Nuke: fixing UNC support for OCIO path #5771 + +UNC paths were broken on windows for custom OCIO path and this is solving the issue with removed double slash at start of path + + +___ + +
+ + + + +## [3.17.2](https://github.com/ynput/OpenPype/tree/3.17.2) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.1...3.17.2) + +### **🆕 New features** + + +
+Maya: Add MayaPy application. #5705 + +This adds mayapy to the application to be launched from a task. + + +___ + +
+ + +
+Feature: Copy resources when downloading last workfile #4944 + +When the last published workfile is downloaded as a prelaunch hook, all resource files referenced in the workfile representation are copied to the `resources` folder, which is inside the local workfile folder. + + +___ + +
+ + +
+Blender: Deadline support #5438 + +Add Deadline support for Blender. + + +___ + +
+ + +
+Fusion: implement toggle to use Deadline plugin FusionCmd #5678 + +Fusion 17 doesn't work in DL 10.3, but FusionCmd does. It might be probably better option as headless variant.Fusion plugin seems to be closing and reopening application when worker is running on artist machine, not so with FusionCmdAdded configuration to Project Settings for admin to select appropriate Deadline plugin: + + +___ + +
+ + +
+Loader tool: Refactor loader tool (for AYON) #5729 + +Refactored loader tool to new tool. Separated backend and frontend logic. Refactored logic is AYON-centric and is used only in AYON mode, so it does not affect OpenPype. The tool is also replacing library loader. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: implement matchmove publishing #5445 + +Add possibility to export multiple cameras in single `matchmove` family instance, both in `abc` and `ma`.Exposed flag 'Keep image planes' to control export of image planes. + + +___ + +
+ + +
+Maya: Add optional Fbx extractors in Rig and Animation family #5589 + +This PR allows user to export control rigs(optionally with mesh) and animated rig in fbx optionally by attaching the rig objects to the two newly introduced sets. + + +___ + +
+ + +
+Maya: Optional Resolution Validator for Render #5693 + +Adding optional resolution validator for maya in render family, similar to the one in Max.It checks if the resolution in render setting aligns with that in setting from the db. + + +___ + +
+ + +
+Use host's node uniqueness for instance id in new publisher #5490 + +Instead of writing `instance_id` as parm or attributes on the publish instances we can, for some hosts, just rely on a unique name or path within the scene to refer to that particular instance. By doing so we fix #4820 because upon duplicating such a publish instance using the host's (DCC) functionality the uniqueness for the duplicate is then already ensured instead of attributes remaining exact same value as where to were duplicated from, making `instance_id` a non-unique value. + + +___ + +
+ + +
+Max: Implementation of OCIO configuration #5499 + +Resolve #5473 Implementation of OCIO configuration for Max 2024 regarding to the update of Max 2024 + + +___ + +
+ + +
+Nuke: Multiple format supports for ExtractReviewDataMov #5623 + +This PR would fix the bug of the plugin `ExtractReviewDataMov` not being able to support extensions other than `mov`. The plugin is also renamed to `ExtractReviewDataBakingStreams` as i provides multiple format supoort. + + +___ + +
+ + +
+Bugfix: houdini switching context doesnt update variables #5651 + +Allows admins to have a list of vars (e.g. JOB) with (dynamic) values that will be updated on context changes, e.g. when switching to another asset or task.Using template keys is supported but formatting keys capitalization variants is not, e.g. {Asset} and {ASSET} won't workDisabling Update Houdini vars on context change feature will leave all Houdini vars unmanaged and thus no context update changes will occur.Also, this PR adds a new button in menu to update vars on demand. + + +___ + +
+ + +
+Publisher: Fix report maker memory leak + optimize lookups using set #5667 + +Fixes a memory leak where resetting publisher does not clear the stored plugins for the Publish Report Maker.Also changes the stored plugins to a `set` to optimize the lookup speeds. + + +___ + +
+ + +
+Add openpype_mongo command flag for testing. #5676 + +Instead of changing the environment, this command flag allows for changing the database. + + +___ + +
+ + +
+Nuke: minor docstring and code tweaks for ExtractReviewMov #5695 + +Code and docstring tweaks on https://github.com/ynput/OpenPype/pull/5623 + + +___ + +
+ + +
+AYON: Small settings fixes #5699 + +Small changes/fixes related to AYON settings. All foundry apps variant `13-0` has label `13.0`. Key `"ExtractReviewIntermediates"` is not mandatory in settings. + + +___ + +
+ + +
+Blender: Alembic Animation loader #5711 + +Implemented loading Alembic Animations in Blender. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Missing "data" field and enabling of audio #5618 + +When updating audio containers, the field "data" was missing and the audio node was not enabled on the timeline. + + +___ + +
+ + +
+Maya: Bug in validate Plug-in Path Attribute #5687 + +Overwriting list with string is causing `TypeError: string indices must be integers` in subsequent iterations, crashing the validator plugin. + + +___ + +
+ + +
+General: Avoid fallback if value is 0 for handle start/end #5652 + +There's a bug on the `pyblish_functions.get_time_data_from_instance_or_context` where if `handleStart` or `handleEnd` on the instance are set to value 0 it's falling back to grabbing the handles from the instance context. Instead, the logic should be that it only falls back to the `instance.context` if the key doesn't exist.This change was only affecting me on the `handleStart`/`handleEnd` and it's unlikely it could cause issues on `frameStart`, `frameEnd` or `fps` but regardless, the `get` logic is wrong. + + +___ + +
+ + +
+Fusion: added missing env vars to Deadline submission #5659 + +Environment variables discerning type of job was missing. Without this injection of environment variables won't start. + + +___ + +
+ + +
+Nuke: workfile version synchronization settings fixed #5662 + +Settings for synchronizing workfile version to published products is fixed. + + +___ + +
+ + +
+AYON Workfiles Tool: Open workfile changes context #5671 + +Change context when workfile is opened. + + +___ + +
+ + +
+Blender: Fix remove/update in new layout instance #5679 + +Fixes an error that occurs when removing or updating an asset in a new layout instance. + + +___ + +
+ + +
+AYON Launcher tool: Fix refresh btn #5685 + +Refresh button does propagate refreshed content properly. Folders and tasks are cached for 60 seconds instead of 10 seconds. Auto-refresh in launcher will refresh only actions and related data which is project and project settings. + + +___ + +
+ + +
+Deadline: handle all valid paths in RenderExecutable #5694 + +This commit enhances the path resolution mechanism in the RenderExecutable function of the Ayon plugin. Previously, the function only considered paths starting with a tilde (~), ignoring other valid paths listed in exe_list. This limitation led to an empty expanded_paths list when none of the paths in exe_list started with a tilde, causing the function to fail in finding the Ayon executable.With this fix, the RenderExecutable function now correctly processes and includes all valid paths from exe_list, improving its reliability and preventing unnecessary errors related to Ayon executable location. + + +___ + +
+ + +
+AYON Launcher tool: Fix skip last workfile boolean #5700 + +Skip last workfile boolean works as expected. + + +___ + +
+ + +
+Chore: Explore here action can work without task #5703 + +Explore here action does not crash when task is not selected, and change error message a little. + + +___ + +
+ + +
+Testing: Inject mongo_url argument earlier #5706 + +Fix for https://github.com/ynput/OpenPype/pull/5676The Mongo url is used earlier in the execution. + + +___ + +
+ + +
+Blender: Add support to auto-install PySide2 in blender 4 #5723 + +Change version regex to support blender 4 subfolder. + + +___ + +
+ + +
+Fix: Hardcoded main site and wrongly copied workfile #5733 + +Fixing these two issues: +- Hardcoded main site -> Replaced by `anatomy.fill_root`. +- Workfiles can sometimes be copied while they shouldn't. + + +___ + +
+ + +
+Bugfix: ServerDeleteOperation asset -> folder conversion typo #5735 + +Fix ServerDeleteOperation asset -> folder conversion typo + + +___ + +
+ + +
+Nuke: loaders are filtering correctly #5739 + +Variable name for filtering by extensions were not correct - it suppose to be plural. It is fixed now and filtering is working as suppose to. + + +___ + +
+ + +
+Nuke: failing multiple thumbnails integration #5741 + +This handles the situation when `ExtractReviewIntermediates` (previously `ExtractReviewDataMov`) has multiple outputs, including thumbnails that need to be integrated. Previously, integrating the thumbnail representation was causing an issue in the integration process. However, we have now resolved this issue by no longer integrating thumbnails as loadable representations.NOW default is that thumbnail representation are NOT integrated (eg. they will not show up in DB > couldn't be Loaded in Loader) and no `_thumb.jpg` will be left in `render` (most likely) publish folder.IF there would be need to override this behavior, please use `project_settings/global/publish/PreIntegrateThumbnails` + + +___ + +
+ + +
+AYON Settings: Fix global overrides #5745 + +The `output` dictionary that gets passed into `ayon_settings._convert_global_project_settings` gets replaced when converting the settings for `ExtractOIIOTranscode`. This results in `global` not being in the output dictionary and thus the defaults being used and not the project overrides. + + +___ + +
+ + +
+Chore: AYON query functions arguments #5752 + +Fixed how `archived` argument is handled in get subsets/assets function. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Publisher: Refactor Report Maker plugin data storage to be a dict by plugin.id #5668 + +Refactor Report Maker plugin data storage to be a dict by `plugin.id`Also fixes `_current_plugin_data` type on `__init__` + + +___ + +
+ + +
+Chore: Refactor Resolve into new style HostBase, IWorkfileHost, ILoadHost #5701 + +Refactor Resolve into new style HostBase, IWorkfileHost, ILoadHost + + +___ + +
+ +### **Merged pull requests** + + +
+Chore: Maya reduce get project settings calls #5669 + +Re-use system settings / project settings where we can instead of requerying. + + +___ + +
+ + +
+Extended error message when getting subset name #5649 + +Each Creator is using `get_subset_name` functions which collects context data and fills configured template with placeholders.If any key is missing in the template, non descriptive error is thrown.This should provide more verbose message: + + +___ + +
+ + +
+Tests: Remove checks for env var #5696 + +Env var will be filled in `env_var` fixture, here it is too early to check + + +___ + +
+ + + + +## [3.17.1](https://github.com/ynput/OpenPype/tree/3.17.1) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.0...3.17.1) + +### **🆕 New features** + + +
+Unreal: Yeti support #5643 + +Implemented Yeti support for Unreal. + + +___ + +
+ + +
+Houdini: Add Static Mesh product-type (family) #5481 + +This PR adds support to publish Unreal Static Mesh in Houdini as FBXQuick recap +- [x] Add UE Static Mesh Creator +- [x] Dynamic subset name like in Maya +- [x] Collect Static Mesh Type +- [x] Update collect output node +- [x] Validate FBX output node +- [x] Validate mesh is static +- [x] Validate Unreal Static Mesh Name +- [x] Validate Subset Name +- [x] FBX Extractor +- [x] FBX Loader +- [x] Update OP Settings +- [x] Update AYON Settings + + +___ + +
+ + +
+Launcher tool: Refactor launcher tool (for AYON) #5612 + +Refactored launcher tool to new tool. Separated backend and frontend logic. Refactored logic is AYON-centric and is used only in AYON mode, so it does not affect OpenPype. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: Use custom staging dir function for Maya renders - OP-5265 #5186 + +Check for custom staging dir when setting the renders output folder in Maya. + + +___ + +
+ + +
+Colorspace: updating file path detection methods #5273 + +Support for OCIO v2 file rules integrated into the available color management API + + +___ + +
+ + +
+Chore: add default isort config #5572 + +Add default configuration for isort tool + + +___ + +
+ + +
+Deadline: set PATH environment in deadline jobs by GlobalJobPreLoad #5622 + +This PR makes `GlobalJobPreLoad` to set `PATH` environment in deadline jobs so that we don't have to use the full executable path for deadline to launch the dcc app. This trick should save us adding logic to pass houdini patch version and modifying Houdini deadline plugin. This trick should work with other DCCs + + +___ + +
+ + +
+nuke: extract review data mov read node with expression #5635 + +Some productions might have set default values for read nodes, those settings are not colliding anymore now. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Support new publisher for colorsets validation. #5630 + +Fix `validate_color_sets` for the new publisher.In current `develop` the repair option does not appear due to wrong error raising. + + +___ + +
+ + +
+Houdini: Camera Loader fix mismatch for Maya cameras #5584 + +This PR adds +- A workaround to match Maya render mask in Houdini +- `SetCameraResolution` inventory action +- set camera resolution when loading or updating camera + + +___ + +
+ + +
+Nuke: fix set colorspace on writes #5634 + +Colorspace is set correctly to any write node created from publisher. + + +___ + +
+ + +
+TVPaint: Fix review family extraction #5637 + +Extractor marks representation of review instance with review tag. + + +___ + +
+ + +
+AYON settings: Extract OIIO transcode settings #5639 + +Output definitions of Extract OIIO transcode have name to match OpenPype settings, and the settings are converted to dictionary in settings conversion. + + +___ + +
+ + +
+AYON: Fix task type short name conversion #5641 + +Convert AYON task type short name for OpenPype correctly. + + +___ + +
+ + +
+colorspace: missing `allowed_exts` fix #5646 + +Colorspace module is not failing due to missing `allowed_exts` attribute. + + +___ + +
+ + +
+Photoshop: remove trailing underscore in subset name #5647 + +If {layer} placeholder is at the end of subset name template and not used (for example in `auto_image` where separating it by layer doesn't make any sense) trailing '_' was kept. This updates cleaning logic and extracts it as it might be similar in regular `image` instance. + + +___ + +
+ + +
+traypublisher: missing `assetEntity` in context data #5648 + +Issue with missing `assetEnity` key in context data is not problem anymore. + + +___ + +
+ + +
+AYON: Workfiles tool save button works #5653 + +Fix save as button in workfiles tool.(It is mystery why this stopped to work??) + + +___ + +
+ + +
+Max: bug fix delete items from container #5658 + +Fix the bug shown when clicking "Delete Items from Container" and selecting nothing and press ok. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Chore: Remove unused functions from Fusion integration #5617 + +Cleanup unused code from Fusion integration + + +___ + +
+ +### **Merged pull requests** + + +
+Increase timout for deadline test #5654 + +DL picks up jobs quite slow, so bump up delay. + + +___ + +
+ + + + +## [3.17.0](https://github.com/ynput/OpenPype/tree/3.17.0) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.7...3.17.0) + +### **🚀 Enhancements** + + +
+Chore: Remove schema from OpenPype root #5355 + +Remove unused schema directory in root of repository which was moved inside openpype/pipeline/schema. + + +___ + +
+ + +
+Igniter: Allow custom Qt scale factor rounding policy #5554 + +Do not force `PassThrough` rounding policy if different policy is defined via env variable. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Chore: Lower urllib3 to support older OpenSSL #5538 + +Lowered `urllib3` to `1.26.16` to support older OpenSSL. + + +___ + +
+ + +
+Chore: Do not try to add schema to zip files #5557 + +Do not add `schema` folder to zip file. This fixes issue cause by https://github.com/ynput/OpenPype/pull/5355 . + + +___ + +
+ + +
+Chore: Lower click dependency version #5629 + +Lower click version to support older versions of python. + + +___ + +
+ +### **Merged pull requests** + + +
+Bump certifi from 2023.5.7 to 2023.7.22 #5351 + +Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22. +
+Commits + +
+
+ + +[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=certifi&package-manager=pip&previous-version=2023.5.7&new-version=2023.7.22)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) + +You can trigger a rebase of this PR by commenting `@dependabot rebase`. + +[//]: # (dependabot-automerge-start) +[//]: # (dependabot-automerge-end) + +--- + +
+Dependabot commands and options +
+ +You can trigger Dependabot actions by commenting on this PR: +- `@dependabot rebase` will rebase this PR +- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it +- `@dependabot merge` will merge this PR after your CI passes on it +- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it +- `@dependabot cancel merge` will cancel a previously requested merge and block automerging +- `@dependabot reopen` will reopen this PR if it is closed +- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually +- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) +- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) +- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) +You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ynput/OpenPype/network/alerts). + +
+ +> **Note** +> Automatic rebases have been disabled on this pull request as it has been open for over 30 days. + +___ + +
+ + + + +## [3.16.7](https://github.com/ynput/OpenPype/tree/3.16.7) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.6...3.16.7) + +### **🆕 New features** + + +
+Maya: Extract active view as thumbnail when no thumbnail set #5426 + +This sets the Maya instance's thumbnail to the current active view if no thumbnail was set yet. + + +___ + +
+ + +
+Maya: Implement USD publish and load using native `mayaUsdPlugin` #5573 + +Implement Creator and Loaders for extraction and loading of USD files using Maya's own `mayaUsdPlugin`.Also adds support to load a `usd` file into an Arnold Standin (`aiStandin`) and assigning looks to it. + + +___ + +
+ + +
+AYON: Ignore separated modules #5619 + +Do not load already separated modules from default directory. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: Reduce amount of code for Collect Looks #5253 + +- Refactor `get_file_node_files` because popping from `paths` by index should have been done in reversed order anyway. It's now changed to not need popping at all. +- Removed unused `RENDERER_NODE_TYPES` and if-branch which collected `node_attrs` list which was unused + collected members which was also done outside of the if branch and thus generated no extra data. +- Collected all materials from look set attributes at once instead of multiple queries +- Collected all file nodes in history from a single query instead of per type +- Restructured assignment of `instance.data["resources"]` to be more readable +- Cached `PXR_NODES` only ones (Note: plugin load is checked on discovery of the collect look plugin) instead of querying plugin load and its nodes per file node per attribute +- Removed some debug logs or combined some messages + + +___ + +
+ + +
+AYON: Mark deprecated settings in Maya #5627 + +Added deprecated info to docstrings of maya colormanagement settings.Resolves: https://github.com/ynput/OpenPype/issues/5556 + + +___ + +
+ + +
+Max: switching versions of maxScene maintain parentage/links with the loaders #5424 + +When using scene inventory to manage or update the version of the loading objects, the linked modifiers or parentage of the objects would be kept.Meanwhile, loaded objects from all loaders no longer parented to the container with OP Data. + + +___ + +
+ + +
+3ds max: small tweaks to obj extractor and model publishing flow #5605 + +There migh be situation where OBJ Extractor passes without failure, but no obj file is produced. This is adding simple check directly into the extractor to catch it earlier then in the integration phase. Also switched `Validate USD Plugin` to optional, because it was always run no matter if the Extract USD was enabled or not, hindering testing (and publishing). + + +___ + +
+ + +
+TVPaint: Plugin can be reopened #5610 + +TVPaint plugin can be reopened. + + +___ + +
+ + +
+Maya: Remove context prompt #5632 + +More of a plea than a PR, but could we please remove the context prompt in Maya when switching tasks? + + +___ + +
+ + +
+General: Create a desktop icon is checked #5636 + +In OP Installer `Create a desktop icon` is checked by default. +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Extract look is not AYON compatible - OP-5375 #5341 + +The textures that would use hardlinking are going through texture processors. Currently all texture processors are hardcoded to copy texture instead of respecting the settings of forcing to copy.The texture processors were last modified 4 months ago, so effectively all clients that are on any pipeline updated in the last 4 months wont be utilizing hardlinking at all, since the hardcoded texture processors will copy texture no matter the OS.This opts for completely disabling the hardlinking feature, while we figure out what to do about it. + + +___ + +
+ + +
+Maya: Multiverse USD Override inherit from correct new style creator #5566 + +Fix Creator for Multiverse USD Override by inheriting from correct new style creator class type + + +___ + +
+ + +
+Max: Bug Fix Alembic Loaders with Ornatrix #5434 + +Bugfix the alembic loader with both ornatrix alembic and max alembic supportsAdd the ornatrix alembic loaders for loading the alembic with Ornatrix-related modifiers. + + +___ + +
+ + +
+AYON: Avoid creation of duplicated links #5593 + +Handle cases when an existing link should be recreated and do not create the same link multitple times during single publishing. + + +___ + +
+ + +
+Extract Review: Multilayer specification for ffmpeg #5613 + +Extract review is specifying layer name when exr is multilayer. + + +___ + +
+ + +
+Fussion: added support for Fusion 17 #5614 + +Fusion 17 still uses Python 3.6 which causes issues with some our delivered libraries. Vendorized necessary set for Python 3.6 + + +___ + +
+ + +
+Publisher: Fix screenshot widget #5615 + +Use correct super method name.EDITED:Removed fade animation which is not triggered at some cases, e.g. in Nuke the animation does not start. I do expect that is caused by `exec_` on the dialog, which blocks event processing to the animation, even when I've added the window as parent it still didn't trigger registered callback.Modified how the "empty" space is not filled by using paths instead of clear mode on painter. Added render hints to add antialiasing. + + +___ + +
+ + +
+Photoshop: auto_images without alpha will not fail #5620 + +ExtractReview caused issue on `auto_image` instance without alpha channel, this fixes it. + + +___ + +
+ + +
+Fix - _id key used instead of id in get_last_version_by_subset_name #5626 + +Just 'id' is not returned because value in fields. Caused KeyError. + + +___ + +
+ + +
+Bugfix: create symlinks for ssl libs on Centos 7 #5633 + +Docker build was missing `libssl.1.1.so` and `libcrypto.1.1.so` symlinks needed by the executable itself, because Python is now explicitly built with OpenSSL 1.1.1 + + +___ + +
+ +### **📃 Documentation** + + +
+Documentation/local settings #5102 + +I completed the "Working with local settings" page. I updated the screenshot, wrote an explanation for each empty category, and if available, linked the more detailed pages already existing. I also added the "Environments" category. + + +___ + +
+ + + + +## [3.16.6](https://github.com/ynput/OpenPype/tree/3.16.6) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.5...3.16.6) + +### **🆕 New features** + + +
+Workfiles tool: Refactor workfiles tool (for AYON) #5550 + +Refactored workfiles tool to new tool. Separated backend and frontend logic. Refactored logic is AYON-centric and is used only in AYON mode, so it does not affect OpenPype. + + +___ + +
+ + +
+AfterEffects: added validator for missing files in FootageItems #5590 + +Published composition in AE could contain multiple FootageItems as a layers. If FootageItem contains imported file and it doesn't exist, render triggered by Publish process will silently fail and no output is generated. This could cause failure later in the process with unclear reason. (In `ExtractReview`).This PR adds validation to protect from this. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: Yeti Cache Include viewport preview settings from source #5561 + +When publishing and loading yeti caches persist the display output and preview colors + settings to ensure consistency in the view + + +___ + +
+ + +
+Houdini: validate colorspace in review rop #5322 + +Adding a validator that checks if 'OCIO Colorspace' parameter on review rop was set to a valid value.It is a step towards managing colorspace in review ropvalid values are the ones in the dropdown menuthis validator also provides some helper actions This PR is related to #4836 and #4833 + + +___ + +
+ + +
+Colorspace: adding abstraction of publishing related functions #5497 + +The functionality of Colorspace has been abstracted for greater usability. + + +___ + +
+ + +
+Nuke: removing redundant workfile colorspace attributes #5580 + +Nuke root workfile colorspace data type knobs are long time configured automatically via config roles or the default values are also working well. Therefore there is no need for pipeline managed knobs. + + +___ + +
+ + +
+Ftrack: Less verbose logs for Ftrack integration in artist facing logs #5596 + +- Reduce artist-facing logs for component integration for Ftrack +- Avoid "Comment is not set" log in artist facing report for Kitsu and Ftrack +- Remove info log about `ffprobe` inspecting a file (changed to debug log) +- interesting to see however that it ffprobes the same jpeg twice - but maybe once for thumbnail? + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Fix rig validators for new out_SET and controls_SET names #5595 + +Fix usage of `out_SET` and `controls_SET` since #5310 because they can now be prefixed by the subset name. + + +___ + +
+ + +
+TrayPublisher: set default frame values to sequential data #5530 + +We are inheriting default frame handles and fps data either from project or setting them to 0. This is just for case a production will decide not to injest the sequential representations with asset based metadata. + + +___ + +
+ + +
+Publisher: Screenshot opacity value fix #5576 + +Fix opacity value. + + +___ + +
+ + +
+AfterEffects: fix imports of image sequences #5581 + +#4602 broke imports of image sequences. + + +___ + +
+ + +
+AYON: Fix representation context conversion #5591 + +Do not fix `"folder"` key in representation context until it is needed. + + +___ + +
+ + +
+ayon-nuke: default factory to lists #5594 + +Default factory were missing in settings schemas for complicated objects like lists and it was causing settings to be failing saving. + + +___ + +
+ + +
+Maya: Fix look assigner showing no asset if 'not found' representations are present #5597 + +Fix Maya Look assigner failing to show any content if it finds an invalid container for which it can't find the asset in the current project. (This can happen when e.g. loading something from a library project).There was logic already to avoid this but there was a bug where it used variable `_id` which did not exist and likely had to be `asset_id`.I've fixed that and improved the logged message a bit, e.g.: +``` +// Warning: openpype.hosts.maya.tools.mayalookassigner.commands : Id found on 22 nodes for which no asset is found database, skipping '641d78ec85c3c5b102e836b0' +``` +Example not found representation in Loader:The issue isn't necessarily related to NOT FOUND representations but in essence boils down to finding nodes with asset ids that do not exist in the current project which could very well just be local meshes in your scene.**Note:**I've excluded logging the nodes themselves because that tends to be a very long list of nodes. Only downside to removing that is that it's unclear which nodes are related to that `id`. If there are any ideas on how to still provide a concise informational message about that that'd be great so I could add it. Things I had considered: +- Report the containers, issue here is that it's about asset ids on nodes which don't HAVE to be in containers - it could be local geometry +- Report the namespaces, issue here is that it could be nodes without namespaces (plus potentially not about ALL nodes in a namespace) +- Report the short names of the nodes; it's shorter and readable but still likely a lot of nodes.@tokejepsen @LiborBatek any other ideas? + + +___ + +
+ + +
+Photoshop: fixed blank Flatten image #5600 + +Flatten image is simplified publishing approach where all visible layers are "flatten" and published together. This image could be used as a reference etc.This is implemented by auto creator which wasn't updated after first publish. This would result in missing newly created layers after `auto_image` instance was created. + + +___ + +
+ + +
+Blender: Remove Hardcoded Subset Name for Reviews #5603 + +Fixes hardcoded subset name for Reviews in Blender. + + +___ + +
+ + +
+TVPaint: Fix tool callbacks #5608 + +Do not wait for callback to finish. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Chore: Remove unused variables and cleanup #5588 + +Removing some unused variables. In some cases the unused variables _seemed like they should've been used - maybe?_ so please **double check the code whether it doesn't hint to an already existing bug**.Also tweaked some other small bugs in code + tweaked logging levels. + + +___ + +
+ +### **Merged pull requests** + + +
+Chore: Loader log deprecation warning for 'fname' attribute #5587 + +Since https://github.com/ynput/OpenPype/pull/4602 the `fname` attribute on the `LoaderPlugin` should've been deprecated and set for removal over time. However, no deprecation warning was logged whatsoever and thus one usage appears to have sneaked in (fixed with this PR) and a new one tried to sneak in with a recent PR + + +___ + +
+ + + + +## [3.16.5](https://github.com/ynput/OpenPype/tree/3.16.5) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.4...3.16.5) + +### **🆕 New features** + + +
+Attribute Definitions: Multiselection enum def #5547 + +Added `multiselection` option to `EnumDef`. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Farm: adding target collector #5494 + +Enhancing farm publishing workflow. + + +___ + +
+ + +
+Maya: Optimize validate plug-in path attributes #5522 + +- Optimize query (use `cmds.ls` once) +- Add Select Invalid action +- Improve validation report +- Avoid "Unknown object type" errors + + +___ + +
+ + +
+Maya: Remove Validate Instance Attributes plug-in #5525 + +Remove Validate Instance Attributes plug-in. + + +___ + +
+ + +
+Enhancement: Tweak logging for artist facing reports #5537 + +Tweak the logging of publishing for global, deadline, maya and a fusion plugin to have a cleaner artist-facing report. +- Fix context being reported correctly from CollectContext +- Fix ValidateMeshArnoldAttributes: fix when arnold is not loaded, fix applying settings, fix for when ai attributes do not exist + + +___ + +
+ + +
+AYON: Update settings #5544 + +Updated settings in AYON addons and conversion of AYON settings in OpenPype. + + +___ + +
+ + +
+Chore: Removed Ass export script #5560 + +Removed Arnold render script, which was obsolete and unused. + + +___ + +
+ + +
+Nuke: Allow for knob values to be validated against multiple values. #5042 + +Knob values can now be validated against multiple values, so you can allow write nodes to be `exr` and `png`, or `16-bit` and `32-bit`. + + +___ + +
+ + +
+Enhancement: Cosmetics for Higher version of publish already exists validation error #5190 + +Fix double spaces in message.Example output **after** the PR: + + +___ + +
+ + +
+Nuke: publish existing frames on farm #5409 + +This PR proposes adding a fourth option in Nuke render publish called "Use Existing Frames - Farm". This would be useful when the farm is busy or when the artist lacks enough farm licenses. Additionally, some artists prefer rendering on the farm but still want to check frames before publishing.By adding the "Use Existing Frames - Farm" option, artists will have more flexibility and control over their render publishing process. This enhancement will streamline the workflow and improve efficiency for Nuke users. + + +___ + +
+ + +
+Unreal: Create project in temp location and move to final when done #5476 + +Create Unreal project in local temporary folder and when done, move it to final destination. + + +___ + +
+ + +
+TrayPublisher: adding audio product type into default presets #5489 + +Adding Audio product type into default presets so anybody can publish audio to their shots. + + +___ + +
+ + +
+Global: avoiding cleanup of flagged representation #5502 + +Publishing folder can be flagged as persistent at representation level. + + +___ + +
+ + +
+General: missing tag could raise error #5511 + +- avoiding potential situation where missing Tag key could raise error + + +___ + +
+ + +
+Chore: Queued event system #5514 + +Implemented event system with more expected behavior of event system. If an event is triggered during other event callback, it is not processed immediately but waits until all callbacks of previous events are done. The event system also allows to not trigger events directly once `emit_event` is called which gives option to process events in custom loops. + + +___ + +
+ + +
+Publisher: Tweak log message to provide plugin name after "Plugin" #5521 + +Fix logged message for settings automatically applied to plugin attributes + + +___ + +
+ + +
+Houdini: Improve VDB Selection #5523 + +Improves VDB selection if selection is `SopNode`: return the selected sop nodeif selection is `ObjNode`: get the output node with the minimum 'outputidx' or the node with display flag + + +___ + +
+ + +
+Maya: Refactor/tweak Validate Instance In same Context plug-in #5526 + +- Chore/Refactor: Re-use existing select invalid and repair actions +- Enhancement: provide more elaborate PublishValidationError report +- Bugfix: fix "optional" support by using `OptionalPyblishPluginMixin` base class. + + +___ + +
+ + +
+Enhancement: Update houdini main menu #5527 + +This PR adds two updates: +- dynamic main menu +- dynamic asset name and task + + +___ + +
+ + +
+Houdini: Reset FPS when clicking Set Frame Range #5528 + +_Similar to Maya,_ Make `Set Frame Range` resets FPS, issue https://github.com/ynput/OpenPype/issues/5516 + + +___ + +
+ + +
+Enhancement: Deadline plugins optimize, cleanup and fix optional support for validate deadline pools #5531 + +- Fix optional support of validate deadline pools +- Query deadline webservice only once per URL for verification, and once for available deadline pools instead of for every instance +- Use `deadlineUrl` in `instance.data` when validating pools if it is set. +- Code cleanup: Re-use existing `requests_get` implementation + + +___ + +
+ + +
+Chore: PowerShell script for docker build #5535 + +Added PowerShell script to run docker build. + + +___ + +
+ + +
+AYON: Deadline expand userpaths in executables list #5540 + +Expande `~` paths in executables list. + + +___ + +
+ + +
+Chore: Use correct git url #5542 + +Fixed github url in README.md. + + +___ + +
+ + +
+Chore: Create plugin does not expect system settings #5553 + +System settings are not passed to initialization of create plugin initialization (and `apply_settings`). + + +___ + +
+ + +
+Chore: Allow custom Qt scale factor rounding policy #5555 + +Do not force `PassThrough` rounding policy if different policy is defined via env variable. + + +___ + +
+ + +
+Houdini: Fix outdated containers pop-up on opening last workfile on launch #5567 + +Fix Houdini not showing outdated containers pop-up on scene open when launching with last workfile argument + + +___ + +
+ + +
+Houdini: Improve errors e.g. raise PublishValidationError or cosmetics #5568 + +Improve errors e.g. raise PublishValidationError or cosmeticsThis also fixes the Increment Current File plug-in since due to an invalid import it was previously broken + + +___ + +
+ + +
+Fusion: Code updates #5569 + +Update fusion code which contains obsolete code. Removed `switch_ui.py` script from fusion with related script in scripts. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Validate Shape Zero fix repair action + provide informational artist-facing report #5524 + +Refactor to PublishValidationError to allow the RepairAction to work + provide informational report message + + +___ + +
+ + +
+Maya: Fix attribute definitions for `CreateYetiCache` #5574 + +Fix attribute definitions for `CreateYetiCache` + + +___ + +
+ + +
+Max: Optional Renderable Camera Validator for Render Instance #5286 + +Optional validation to check on renderable camera being set up correctly for deadline submission.If not being set up correctly, it wont pass the validation and user can perform repair actions. + + +___ + +
+ + +
+Max: Adding custom modifiers back to the loaded objects #5378 + +The custom parameters OpenpypeData doesn't show in the loaded container when it is being loaded through the loader. + + +___ + +
+ + +
+Houdini: Use default_variant to Houdini Node TAB Creator #5421 + +Use the default variant of the creator plugins on the interactive creator from the TAB node search instead of hard-coding it to `Main`. + + +___ + +
+ + +
+Nuke: adding inherited colorspace from instance #5454 + +Thumbnails are extracted with inherited colorspace collected from rendering write node. + + +___ + +
+ + +
+Add kitsu credentials to deadline publish job #5455 + +This PR hopefully fixes this issue #5440 + + +___ + +
+ + +
+AYON: Fill entities during editorial #5475 + +Fill entities and update template data on instances during extract AYON hierarchy. + + +___ + +
+ + +
+Ftrack: Fix version 0 when integrating to Ftrack - OP-6595 #5477 + +Fix publishing version 0 to Ftrack. + + +___ + +
+ + +
+OCIO: windows unc path support in Nuke and Hiero #5479 + +Hiero and Nuke is not supporting windows unc path formatting in OCIO environment variable. + + +___ + +
+ + +
+Deadline: Added super call to init #5480 + +DL 10.3 requires plugin inheriting from DeadlinePlugin to call super's **init** explicitly. + + +___ + +
+ + +
+Nuke: fixing thumbnail and monitor out root attributes #5483 + +Nuke Root Colorspace settings for Thumbnail and Monitor Out schema was gradually changed between version 12, 13, 14 and we needed to address those changes individually for particular version. + + +___ + +
+ + +
+Nuke: fixing missing `instance_id` error #5484 + +Workfiles with Instances created in old publisher workflow were rising error during converting method since they were missing `instance_id` key introduced in new publisher workflow. + + +___ + +
+ + +
+Nuke: existing frames validator is repairing render target #5486 + +Nuke is now correctly repairing render target after the existing frames validator finds missing frames and repair action is used. + + +___ + +
+ + +
+added UE to extract burnins families #5487 + +This PR fixes missing burnins in reviewables when rendering from UE. +___ + +
+ + +
+Harmony: refresh code for current Deadline #5493 + +- Added support in Deadline Plug-in for new versions of Harmony, in particular version 21 and 22. +- Remove review=False flag on render instance +- Add farm=True flag on render instance +- Fix is_in_tests function call in Harmony Deadline submission plugin +- Force HarmonyOpenPype.py Deadline Python plug-in to py3 +- Fix cosmetics/hound in HarmonyOpenPype.py Deadline Python plug-in + + +___ + +
+ + +
+Publisher: Fix multiselection value #5505 + +Selection of multiple instances in Publisher does not cause that all instances change all publish attributes to the same value. + + +___ + +
+ + +
+Publisher: Avoid warnings on thumbnails if source image also has alpha channel #5510 + +Avoids the following warning from `ExtractThumbnailFromSource`: +``` +// pyblish.ExtractThumbnailFromSource : oiiotool WARNING: -o : Can't save 4 channels to jpeg... saving only R,G,B +``` + + + +___ + +
+ + +
+Update ayon-python-api #5512 + +Update ayon python api and related callbacks. + + +___ + +
+ + +
+Max: Fixing the bug of falling back to use workfile for Arnold or any renderers except Redshift #5520 + +Fix the bug of falling back to use workfile for Arnold + + +___ + +
+ + +
+General: Fix Validate Publish Dir Validator #5534 + +Nonsensical "family" key was used instead of real value (as 'render' etc.) which would result in wrong translation of intermediate family names.Updated docstring. + + +___ + +
+ + +
+have the addons loading respect a custom AYON_ADDONS_DIR #5539 + +When using a custom AYON_ADDONS_DIR environment variable that variable is used in the launcher correctly and downloads and extracts addons to there, however when running Ayon does not respect this environment variable + + +___ + +
+ + +
+Deadline: files on representation cannot be single item list #5545 + +Further logic expects that single item files will be only 'string' not 'list' (eg. repre["files"] = "abc.exr" not repre["files"] = ["abc.exr"].This would cause an issue in ExtractReview later.This could happen if DL rendered single frame file with different frame value. + + +___ + +
+ + +
+Webpublisher: better encode list values for click #5546 + +Targets could be a list, original implementation pushed it as a separate items, it must be added as `--targets webpulish --targets filepublish`.`wepublish_routes` handles triggering from UI, changes in `publish_functions` handle triggering from cmd (for tests, api access). + + +___ + +
+ + +
+Houdini: Introduce imprint function for correct version in hda loader #5548 + +Resolve #5478 + + +___ + +
+ + +
+AYON: Fill entities during editorial (2) #5549 + +Fix changes made in https://github.com/ynput/OpenPype/pull/5475. + + +___ + +
+ + +
+Max: OP Data updates in Loaders #5563 + +Fix the bug on the loaders not being able to load the objects when iterating key and values with the dict.Max prefers list over the list in dict. + + +___ + +
+ + +
+Create Plugins: Better check of overriden '__init__' method #5571 + +Create plugins do not log warning messages about each create plugin because of wrong `__init__` method check. + + +___ + +
+ +### **Merged pull requests** + + +
+Tests: fix unit tests #5533 + +Fixed failing tests.Updated Unreal's validator to match removed general one which had a couple of issues fixed. + + +___ + +
+ + + + +## [3.16.4](https://github.com/ynput/OpenPype/tree/3.16.4) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.3...3.16.4) + +### **🆕 New features** + + +
+Feature: Download last published workfile specify version #4998 + +Setting `workfile_version` key to hook's `self.launch_context.data` allow you to specify the workfile version you want sync service to download if none is matched locally. This is helpful if the last version hasn't been correctly published/synchronized, and you want to recover the previous one (or some you'd like).Version could be set in two ways: +- OP's absolute version, matching the `version` index in DB. +- Relative version in reverse order from the last one: `-2`, `-3`...I don't know where I should write documentation about that. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: allow not creation of group for Import loaders #5427 + +This PR enhances previous one. All ReferenceLoaders could not wrap imported products into explicit group.Also `Import` Loaders have same options. Control for this is separate in Settings, eg. Reference might wrap loaded items in group, `Import` might not. + + +___ + +
+ + +
+3dsMax: Settings for Ayon #5388 + +Max Addon Setting for Ayon + + +___ + +
+ + +
+General: Navigation to Folder from Launcher #5404 + +Adds an action in launcher to open the directory of the asset. + + +___ + +
+ + +
+Chore: Default variant in create plugin #5429 + +Attribute `default_variant` on create plugins always returns string and if default variant is not filled other ways how to get one are implemented. + + +___ + +
+ + +
+Publisher: Thumbnail widget enhancements #5439 + +Thumbnails widget in Publisher has new 3 options to choose from: Paste (from clipboard), Take screenshot and Browse. Clear button and new options are not visible by default, user must expand options button to show them. + + +___ + +
+ + +
+AYON: Update ayon api to '0.3.5' #5460 + +Updated ayon-python-api to 0.3.5. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+AYON: Apply unknown ayon settings first #5435 + +Settings of custom addons are available in converted settings. + + +___ + +
+ + +
+Maya: Fix wrong subset name of render family in deadline #5442 + +New Publisher is creating different subset names than previously which resulted in duplication of `render` string in final subset name of `render` family published on Deadline.This PR solves that, it also fixes issues with legacy instances from old publisher, it matches the subset name as was before.This solves same issue in Max implementation. + + +___ + +
+ + +
+Maya: Fix setting of version to workfile instance #5452 + +If there are multiple instances of renderlayer published, previous logic resulted in unpredictable rewrite of instance family to 'workfile' if `Sync render version with workfile` was on. + + +___ + +
+ + +
+Maya: Context plugin shouldn't be tied to family #5464 + +`Maya Current File` collector was tied to `workfile` unnecessary. It should run even if `workile` instance is not being published. + + +___ + +
+ + +
+Unreal: Fix loading hero version for static and skeletal meshes #5393 + +Fixed a problem with loading hero versions for static ans skeletal meshes. + + +___ + +
+ + +
+TVPaint: Fix 'repeat' behavior #5412 + +Calculation of frames for repeat behavior is working correctly. + + +___ + +
+ + +
+AYON: Thumbnails cache and api prep #5437 + +Moved thumbnails cache from ayon python api to OpenPype and prepare AYON thumbnail resolver for new api functions. Current implementation should work with old and new ayon-python-api. + + +___ + +
+ + +
+Nuke: Name of the Read Node should be updated correctly when switching versions or assets. #5444 + +Bug fixing of the read node's name not being updated correctly when setting version or switching asset. + + +___ + +
+ + +
+Farm publishing: asymmetric handles fixed #5446 + +Handles are now set correctly on farm published product version if asymmetric were set to shot attributes. + + +___ + +
+ + +
+Scene Inventory: Provider icons fix #5450 + +Fix how provider icons are accessed in scene inventory. + + +___ + +
+ + +
+Fix typo on Deadline OP plugin name #5453 + +Surprised that no one has hit this bug yet... but it seems like there was a typo on the name of the OP Deadline plugin when submitting jobs to it. + + +___ + +
+ + +
+AYON: Fix version attributes update #5472 + +Fixed updates of attribs in AYON mode. + + +___ + +
+ +### **Merged pull requests** + + +
+Added missing defaults for import_loader #5447 + + +___ + +
+ + +
+Bug: Local settings don't open on 3.14.7 #5220 + +### Before posting a new ticket, have you looked through the documentation to find an answer? + +Yes I have + +### Have you looked through the existing tickets to find any related issues ? + +Not yet + +### Author of the bug + +@FadyFS + +### Version + +3.15.11-nightly.3 + +### What platform you are running OpenPype on? + +Linux / Centos + +### Current Behavior: + +the previous behavior (bug) : +![image](https://github.com/quadproduction/OpenPype/assets/135602303/09bff9d5-3f8b-4339-a1e5-30c04ade828c) + + +### Expected Behavior: + +![image](https://github.com/quadproduction/OpenPype/assets/135602303/c505a103-7965-4796-bcdf-73bcc48a469b) + + +### What type of bug is it ? + +Happened only once in a particular configuration + +### Which project / workfile / asset / ... + +open settings with 3.14.7 + +### Steps To Reproduce: + +1. Run openpype on the 3.15.11-nightly.3 version +2. Open settings in 3.14.7 version + +### Relevant log output: + +_No response_ + +### Additional context: + +_No response_ + +___ + +
+ + +
+Tests: Add automated targets for tests #5443 + +Without it plugins with 'automated' targets won't be triggered (eg `CloseAE` etc.) + + +___ + +
+ + + + +## [3.16.3](https://github.com/ynput/OpenPype/tree/3.16.3) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.2...3.16.3) + +### **🆕 New features** + + +
+AYON: 3rd party addon usage #5300 + +Prepare OpenPype code to be able use `ayon-third-party` addon which supply ffmpeg and OpenImageIO executables. Because they both can support to define custom arguments (more than one) a new functions were needed to supply.New functions are `get_ffmpeg_tool_args` and `get_oiio_tool_args`. They work similar to previous but instead of string are returning list of strings. All places using previous functions `get_ffmpeg_tool_path` and `get_oiio_tool_path` are now using new ones. They should be backwards compatible and even with addon if returns single argument. + + +___ + +
+ + +
+AYON: Addon settings in OpenPype #5347 + +Moved settings addons to OpenPype server addon. Modified create package to create zip files for server for each settings addon and for openpype addon. + + +___ + +
+ + +
+AYON: Add folder to template data #5417 + +Added `folder` to template data, so `{folder[name]}` can be used in templates. + + +___ + +
+ + +
+Option to start versioning from 0 #5262 + +This PR adds a settings option to start all versioning from 0.This PR will replace #4455. + + +___ + +
+ + +
+Ayon: deadline implementation #5321 + +Quick implementation of deadline in Ayon. New Ayon plugin added for Deadline repository + + +___ + +
+ + +
+AYON: Remove AYON launch logic from OpenPype #5348 + +Removed AYON launch logic from OpenPype. The logic is outdated at this moment and is replaced by `ayon-launcher`. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Bug: Error on multiple instance rig with maya #5310 + +I change endswith method by startswith method because the set are automacaly name out_SET, out_SET1, out_SET2 ... + + +___ + +
+ + +
+Applications: Use prelaunch hooks to extract environments #5387 + +Environment variable preparation is based on prelaunch hooks. This should allow to pass OCIO environment variables to farm jobs. + + +___ + +
+ + +
+Applications: Launch hooks cleanup #5395 + +Use `set` instead of `list` for filtering attributes in launch hooks. Celaction hooks dir does not contain `__init__.py`. Celaction prelaunch hook is reusing `CELACTION_ROOT_DIR`. Launch hooks are using full import from `openpype.lib.applications`. + + +___ + +
+ + +
+Applications: Environment variables order #5245 + +Changed order of set environment variables. First are set context environment variables and then project environment overrides. Also asset and task environemnt variables are optional. + + +___ + +
+ + +
+Autosave preferences can be read after Nuke opens the script #5295 + +Looks like I need to open the script in Nuke to be able to correctly load the autosave preferences.This PR reads the Nuke script in context, and offers owerwriting the current script with autosaved one if autosave exists. + + +___ + +
+ + +
+Resolve: Update with compatible resolve version and latest docs #5317 + +Missing information about compatible Resolve version and latest docs from https://github.com/ynput/OpenPype/tree/develop/openpype/hosts/resolve + + +___ + +
+ + +
+Chore: Remove deprecated functions #5323 + +Removed functions/classes that are deprecated and marked to be removed. + + +___ + +
+ + +
+Nuke Render and Prerender nodes Process Order - OP-3555 #5332 + +This PR exposes control over the order of processing of the instances, by sorting the instances created. The sorting happens on the `render_order` and subset name. If the knob `render_order` is found on the instance, we'll sort by that first before sorting by subset name.`render_order` instances are processed before nodes without `render_order`. This could be extended in the future by querying other knobs but I dont know of a usecase for this.Hardcoded the creator `order` attribute of the `prerender` class to be before the `render`. Could be exposed to the user/studio but dont know of a use case for this. + + +___ + +
+ + +
+Unreal: Python Environment Improvements #5344 + +Automatically set `UE_PYTHONPATH` as `PYTHONPATH` when launching Unreal. + + +___ + +
+ + +
+Unreal: Custom location for Unreal Ayon Plugin #5346 + +Added a new environment variable `AYON_BUILT_UNREAL_PLUGIN` to set an already existing and built Ayon Plugin for Unreal. + + +___ + +
+ + +
+Unreal: Better handling of Exceptions in UE Worker threads #5349 + +Implemented a new `UEWorker` base class to handle exception during the execution of UE Workers. + + +___ + +
+ + +
+Houdini: Add farm toggle on creation menu #5350 + +Deadline Farm publishing and Rendering for Houdini was possible with this PR #4825 farm publishing is enabled by default some ROP nodes which may surprise new users (like me).I think adding a toggle (on by default) on creation UI is better so that users will be aware that there's a farm option for this publish instance.ROPs Modified : +- [x] Mantra ROP +- [x] Karma ROP +- [x] Arnold ROP +- [x] Redshift ROP +- [x] Vray ROP + + +___ + +
+ + +
+Ftrack: Sync to avalon settings #5353 + +Added roles settings for sync to avalon action. + + +___ + +
+ + +
+Chore: Schemas inside OpenPype #5354 + +Moved/copied schemas from repository root inside openpype/pipeline. + + +___ + +
+ + +
+AYON: Addons creation enhancements #5356 + +Enhanced AYON addons creation. Fix issue with `Pattern` typehint. Zip filenames contain version. OpenPype package is skipping modules that are already separated in AYON. Updated settings of addons. + + +___ + +
+ + +
+AYON: Update staging icons #5372 + +Updated staging icons for staging mode. + + +___ + +
+ + +
+Enhancement: Houdini Update pointcache labels #5373 + +To me it's logical to find pointcaches types listed one after another, but they were named differentlySo, I made this PR to update their labels + + +___ + +
+ + +
+nuke: split write node product instance features #5389 + +Improving Write node product instances by allowing precise activation of specific features. + + +___ + +
+ + +
+Max: Use the empty modifiers in container to store AYON Parameter #5396 + +Instead of adding AYON/OP Parameter along with other attributes inside the container, empty modifiers would be created to store AYON/OP custom attributes + + +___ + +
+ + +
+AfterEffects: Removed unused imports #5397 + +Removed unused import from extract local render plugin file. + + +___ + +
+ + +
+Nuke: adding BBox knob type to settings #5405 + +Nuke knob types in settings having new `Box` type for reposition nodes like Crop or Reformat. + + +___ + +
+ + +
+SyncServer: Existence of module is optional #5413 + +Existence of SyncServer module is optional and not required. Added `sync_server` module back to ignored modules when openpype addon is created for AYON. Command `syncserver` is marked as deprecated and redirected to sync server cli. + + +___ + +
+ + +
+Webpublisher: Self contain test publish logic #5414 + +Moved test logic of publishing to webpublisher. Simplified `remote_publish` to remove webpublisher specific logic. + + +___ + +
+ + +
+Webpublisher: Cleanup targets #5418 + +Removed `remote` target from webpublisher and replaced it with 2 targets `webpublisher` and `automated`. + + +___ + +
+ + +
+nuke: update server addon settings with box #5419 + +updtaing nuke ayon server settings for Box option in knob types. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: fix validate frame range on review attached to other instances #5296 + +Fixes situation where frame range validator can't be turned off on models if they are attached to reviewable camera in Maya. + + +___ + +
+ + +
+Maya: Apply project settings to creators #5303 + +Project settings were not applied to the creators. + + +___ + +
+ + +
+Maya: Validate Model Content #5336 + +`assemblies` in `cmds.ls` does not seem to work; +```python + +from maya import cmds + + +content_instance = ['|group2|pSphere1_GEO', '|group2|pSphere1_GEO|pSphere1_GEOShape', '|group1|pSphere1_GEO', '|group1|pSphere1_GEO|pSphere1_GEOShape'] +assemblies = cmds.ls(content_instance, assemblies=True, long=True) +print(assemblies) +``` + +Fixing with string splitting instead. + + +___ + +
+ + +
+Bugfix: Maya update defaults variable #5368 + +So, something was forgotten while moving out from `LegacyCreator` to `NewCreator``LegacyCreator` used `defaults` to list suggested subset names which was changed into `default_variants` in the the `NewCreator`and setting `defaults` to any values has no effect!This update affects: +- [x] Model +- [x] Set Dress + + +___ + +
+ + +
+Chore: Python 2 support fix #5375 + +Fix Python 2 support by adding `click` into python 2 dependencies and removing f-string from maya. + + +___ + +
+ + +
+Maya: do not create top level group on reference #5402 + +This PR allows to not wrapping loaded referenced assets in top level group either explicitly for artist or by configuration in Settings.Artists can control group creation in ReferenceLoader options.Default no group creation could be set by emptying `Group Name` in `project_settings/maya/load/reference_loader` + + +___ + +
+ + +
+Settings: Houdini & Maya create plugin settings #5436 + +Fixes related to Maya and Houdini settings. Renamed `defaults` to `default_variants` in plugin settings to match attribute name on create plugin in both OpenPype and AYON settings. Fixed Houdini AYON settings where were missing settings for defautlt varaints and fixed Maya AYON settings where default factory had wrong assignment. + + +___ + +
+ + +
+Maya: Hide CreateAnimation #5297 + +When converting `animation` family or loading a `rig` family, need to include the `animation` creator but hide it in creator context. + + +___ + +
+ + +
+Nuke Anamorphic slate - Read pixel aspect from input #5304 + +When asset pixel aspect differs from rendered pixel aspect, Nuke slate pixel aspect is not longer taken from asset, but is readed via ffprobe. + + +___ + +
+ + +
+Nuke - Allow ExtractReviewDataMov with no timecode knob #5305 + +ExtractReviewDataMov allows to specify file type. Trying to write some other extension than mov fails on generate_mov assuming that mov64_write_timecode knob exists. + + +___ + +
+ + +
+Nuke: removing settings schema with defaults for OpenPype #5306 + +continuation of https://github.com/ynput/OpenPype/pull/5275 + + +___ + +
+ + +
+Bugfix: Dependency without 'inputLinks' not downloaded #5337 + +Remove condition that avoids downloading dependency without `inputLinks`. + + +___ + +
+ + +
+Bugfix: Houdini Creator use selection even if it was toggled off #5359 + +When creating many product types (families) one after another without refreshing the creator window manually if you toggled `Use selection` once, all the later product types will use selection even if it was toggled offHere's Before it will keep use selection even if it was toggled off, unless you refresh window manuallyhttps://github.com/ynput/OpenPype/assets/20871534/8b890122-5b53-4c6b-897d-6a2f3aa3388aHere's After it works as expectedhttps://github.com/ynput/OpenPype/assets/20871534/6b1db990-de1b-428e-8828-04ab59a44e28 + + +___ + +
+ + +
+Houdini: Correct camera selection for karma renderer when using selected node #5360 + +When user creates the karma rop with selected camera by use selection, it will give the error message of "no render camera found in selection".This PR is to fix the bug of creating karma rop when using selected camera node in Houdini + + +___ + +
+ + +
+AYON: Environment variables and functions #5361 + +Prepare code for ayon-launcher compatibility. Fix ayon launcher subprocess calls, added more checks for `AYON_SERVER_ENABLED`, use ayon launcher suitable environment variables in AYON mode and changed outputs of some functions. Replaced usages of `OPENPYPE_REPOS_ROOT` environment variable with `PACKAGE_DIR` variable -> correct paths are used. + + +___ + +
+ + +
+Nuke: farm rendering of prerender ignore roots in nuke #5366 + +`prerender` family was using wrong subset, same as `render` which should be different. + + +___ + +
+ + +
+Bugfix: Houdini update defaults variable #5367 + +So, something was forgotten while moving out from `LegacyCreator` to `NewCreator``LegacyCreator` used `defaults` to list suggested subset names which was changed into `default_variants` in the the `NewCreator`and setting `defaults` to any values has no effect!This update affects: +- [x] Arnold ASS +- [x] Arnold ROP +- [x] Karma ROP +- [x] Mantra ROP +- [x] Redshift ROP +- [x] VRay ROP + + +___ + +
+ + +
+Publisher: Fix create/publish animation #5369 + +Use geometry movement instead of changing min/max width. + + +___ + +
+ + +
+Unreal: Move unreal splash screen to unreal #5370 + +Moved splash screen code to unreal integration and removed import from Igniter. + + +___ + +
+ + +
+Nuke: returned not cleaning of renders folder on the farm #5374 + +Previous PR enabled explicit cleanup of `renders` folder after farm publishing. This is not matching customer's workflows. Customer wants to have access to files in `renders` folder and potentially redo some frames for long frame sequences.This PR extends logic of marking rendered files for deletion only if instance doesn't have `stagingDir_persistent`.For backwards compatibility all Nuke instances have `stagingDir_persistent` set to True, eg. `renders` folder won't be cleaned after farm publish. + + +___ + +
+ + +
+Nuke: loading sequences is working #5376 + +Loading image sequences was broken after the latest release, version 3.16. However, I am pleased to inform you that it is now functioning as expected. + + +___ + +
+ + +
+AYON: Fix settings conversion for ayon addons #5377 + +AYON addon settings are available in system settings and does not have available the same values in `"modules"` subkey. + + +___ + +
+ + +
+Nuke: OCIO env var workflow #5379 + +The OCIO environment variable needs to be consistently handled across all platforms. Nuke resolves the custom OCIO config path differently depending on the platform, so we included the ocio config path in the workfile with a partial replacement using an environment variable. Additionally, for Windows sessions, we replaced backward slashes with a TCL expression. + + +___ + +
+ + +
+Unreal: Fix Unreal build script #5381 + +Define 'AYON_UNREAL_ROOT' environment variable in unreal addon. + + +___ + +
+ + +
+3dsMax: Use relative path to MAX_HOST_DIR #5382 + +Use `MAX_HOST_DIR` to calculate startup script path instead of use relative path to `OPENPYPE_ROOT` environment variable. + + +___ + +
+ + +
+Bugfix: Houdini abc validator error message #5386 + +When ABC path validator fails, it prints node objects not node paths or namesThis bug happened because of updating `get_invalid` method to return nodes instead of node pathsBeforeAfter + + +___ + +
+ + +
+Nuke: node name influence product (subset) name #5392 + +Nuke now allows users to duplicate publishing instances, making the workflow easier. By duplicating a node and changing its name, users can set the product (subset) name in the publishing context.Users now have the ability to change the variant name in Publisher, which will automatically rename the associated instance node. + + +___ + +
+ + +
+Houdini: delete redundant bgeo sop validator #5394 + +I found out that this `Validate BGEO SOP Path` validator is redundant, it catches two cases that are already implemented in "Validate Output Node". "Validate Output Node" works with `bgeo` as well as `abc` because `"pointcache"` is listed in its families + + +___ + +
+ + +
+Nuke: workfile is not reopening after change of context #5399 + +Nuke no longer reopens the latest workfile when the context is changed to a different task using the Workfile tool. The issue also affected the Script Clean (from Nuke File menu) and Close feature, but it has now been fixed. + + +___ + +
+ + +
+Bugfix: houdini hard coded project settings #5400 + +I made this PR to solve the issue with hard-coded settings in houdini + + +___ + +
+ + +
+AYON: 3dsMax settings #5401 + +Keep `adsk_3dsmax` group in applications settings. + + +___ + +
+ + +
+Bugfix: update defaults to default_variants in maya and houdini OP DCC settings #5407 + +On moving out to new creator in Maya and Houdini updating settings was missed. + + +___ + +
+ + +
+Applications: Attributes creation #5408 + +Applications addon does not cause infinite server restart loop. + + +___ + +
+ + +
+Max: fix the bug of handling Object deletion in OP Parameter #5410 + +If the object is added to the OP parameter and user delete it in the scene thereafter, it will error out the container with OP attributes. This PR resolves the bug.This PR also fixes the bug of not adding the attribute into OP parameter correctly when the user enables "use selections" to link the object into the OP parameter. + + +___ + +
+ + +
+Colorspace: including environments from launcher process #5411 + +Fixed bug in GitHub PR where the OCIO config template was not properly formatting environment variables from System Settings `general/environment`. + + +___ + +
+ + +
+Nuke: workfile template fixes #5428 + +Some bunch of small bugs needed to be fixed + + +___ + +
+ + +
+Houdini, Max: Fix missed function interface change #5430 + +This PR https://github.com/ynput/OpenPype/pull/5321/files from @kalisp missed updating the `add_render_job_env_var` in Houdini and Max as they are passing an extra arg: +``` +TypeError: add_render_job_env_var() takes 1 positional argument but 2 were given +``` + + +___ + +
+ + +
+Scene Inventory: Fix issue with 'sync_server' #5431 + +Fix accesss to `sync_server` attribute in scene inventory. + + +___ + +
+ + +
+Unpack project: Fix import issue #5433 + +Added `load_json_file`, `replace_project_documents` and `store_project_documents` to mongo init. + + +___ + +
+ + +
+Chore: Versions post fixes #5441 + +Fixed issues caused by my fault. Filled right version value to anatomy data. + + +___ + +
+ +### **📃 Testing** + + +
+Tests: Copy file_handler as it will be removed by purging ayon code #5357 + +Ayon code will get purged in the future from this repo/addon, therefore all `ayon_common` will be gone. `file_handler` gets internalized to tests as it is not used anywhere else. + + +___ + +
+ + + + +## [3.16.2](https://github.com/ynput/OpenPype/tree/3.16.2) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.1...3.16.2) + +### **🆕 New features** + + +
+Fusion - Set selected tool to active #5327 + +When you run the action to select a node, this PR makes the node-flow show the selected node + you'll see the nodes controls in the inspector. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: All base create plugins #5326 + +Prepared base classes for each creator type in Maya. Extended `MayaCreatorBase` to have default implementations of common logic with instances which is used in each type of plugin. + + +___ + +
+ + +
+Windows: Support long paths on zip updates. #5265 + +Support long paths for version extract on Windows.Use case is when having long paths in for example an addon. You can install to the C drive but because the zip files are extracted in the local users folder, it'll add additional sub directories to the paths and quickly get too long paths for Windows to handle the zip updates. + + +___ + +
+ + +
+Blender: Added setting to set resolution and start/end frames at startup #5338 + +This PR adds `set_resolution_startup`and `set_frames_startup` settings. They automatically set respectively the resolution and start/end frames and FPS in Blender when opening a file or creating a new one. + + +___ + +
+ + +
+Blender: Support for ExtractBurnin #5339 + +This PR adds support for ExtractBurnin for Blender, when publishing a Review. + + +___ + +
+ + +
+Blender: Extract Camera as Alembic #5343 + +Added support to extract Alembic Cameras in Blender. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Validate Instance In Context #5335 + +Missing new publisher error so the repair action shows up. + + +___ + +
+ + +
+Settings: Fix default settings #5311 + +Fixed defautl settings for shotgrid. Renamed `FarmRootEnumEntity` to `DynamicEnumEntity` and removed doubled ABC metaclass definition (all settings entities have abstract metaclass). + + +___ + +
+ + +
+Deadline: missing context argument #5312 + +Updated function arguments + + +___ + +
+ + +
+Qt UI: Multiselection combobox PySide6 compatibility #5314 + +- The check states are replaced with the values for PySide6 +- `QtCore.Qt.ItemIsUserTristate` is used instead of `QtCore.Qt.ItemIsTristate` to avoid crashes on PySide6 + + +___ + +
+ + +
+Docker: handle openssl 1.1.1 for centos 7 docker build #5319 + +Move to python 3.9 has added need to use openssl 1.1.x - but it is not by default available on centos 7 image. This is fixing it. + + +___ + +
+ + +
+houdini: fix typo in redshift proxy #5320 + +I believe there's a typo in `create_redshift_proxy.py` ( extra ` ) in filename, and I made this PR to suggest a fix + + +___ + +
+ + +
+Houdini: fix wrong creator identifier in pointCache workflow #5324 + +FIxing a bug in publishing alembics, were invalid creator identifier caused missing family association. + + +___ + +
+ + +
+Fix colorspace compatibility check #5334 + +for some reason a user may have `PyOpenColorIO` installed to his machine, _in my case it came with renderman._it can trick the compatibility check as `import PyOpenColorIO` won't raise an error however it may be an old version _like my case_Beforecompatibility check was true and It used wrapper directly After Fix It will use wrapper via subprocess instead + + +___ + +
+ +### **Merged pull requests** + + +
+Remove forgotten dev logging #5315 + + +___ + +
+ + + + +## [3.16.1](https://github.com/ynput/OpenPype/tree/3.16.1) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.16.0...3.16.1) + +### **🆕 New features** + + +
+Royal Render: Maya and Nuke support #5191 + +Basic working implementation of Royal Render support in Maya.It expects New publisher implemented in Maya. + + +___ + +
+ + +
+Blender: Blend File Family #4321 + +Implementation of the Blend File family analogue to the Maya Scene one. + + +___ + +
+ + +
+Houdini: simple bgeo publishing #4588 + +Support for simple publishing of bgeo files. + +This is adding basic support for bgeo publishing in Houdini. It will allow publishing bgeo in all supported formats (selectable in the creator options). If selected node has `output` on sop level, it will be used automatically as path in file node. + + +___ + +
+ +### **🚀 Enhancements** + + +
+General: delivery action add renamed frame number in Loader #5024 + +Frame Offset options for delivery in Openpype loader + + +___ + +
+ + +
+Enhancement/houdini add path action for abc validator #5237 + +Add a default path attribute Action.it's a helper action more than a repair action, which used to add a default single value. + + +___ + +
+ + +
+Nuke: auto apply all settings after template build #5277 + +Adding auto run of Apply All Settings after template is builder is finishing its process. This will apply Frame-range, Image size, Colorspace found in context of a task shot. + + +___ + +
+ + +
+Harmony:Removed loader settings for Harmony #5289 + +It shouldn't be configurable, it is internal logic. By adding additional extension it wouldn't start to work magically. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+AYON: Make appdirs case sensitive #5298 + +Appdirs for AYON are case sensitive for linux and mac so we needed to change them to match ayon launcher. Changed 'ayon' to 'AYON' and 'ynput' to 'Ynput'. + + +___ + +
+ + +
+Traypublisher: Fix plugin order #5299 + +Frame range collector for traypublisher was moved to traypublisher plugins and changed order to make sure `assetEntity` is filled in `instance.data`. + + +___ + +
+ + +
+Deadline: removing OPENPYPE_VERSION from some host submitters #5302 + +Removing deprecated method of adding OPENPYPE_VERSION to job environment. It was leftover and other hosts have already been cleared. + + +___ + +
+ + +
+AYON: Fix args for workfile conversion util #5308 + +Workfile update conversion util function have right expected arguments. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Maya: Refactor imports to `lib.get_reference_node` since the other function… #5258 + +Refactor imports to `lib.get_reference_node` since the other function is deprecated. + + +___ + +
+ + + + +## [3.16.0](https://github.com/ynput/OpenPype/tree/3.16.0) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/...3.16.0) + +### **🆕 New features** + + +
+General: Reduce usage of legacy io #4723 + +Replace usages of `legacy_io` with getter methods or reuse already available information. Create plugins using CreateContext are using context from CreateContext object. Loaders are usign getter function from context tools. Publish plugin are using information instance.data or context.data. In some cases were pieces of code refactored a little e.g. fps getter in maya. + + +___ + +
+ + +
+Documentation: API docs reborn - yet again #4419 + +## Feature + +Add functional base for API Documentation using Sphinx and AutoAPI. + +After unsuccessful #2512, #834 and #210 this is yet another try. But this time without ambition to solve the whole issue. This is making Shinx script to work and nothing else. Any changes and improvements in API docs should be made in subsequent PRs. + +## How to use it + +You can run: + +```sh +cd .\docs +make.bat html +``` + +or + +```sh +cd ./docs +make html +``` + +This will go over our code and generate **.rst** files in `/docs/source/autoapi` and from those it will generate full html documentation in `/docs/build/html`. + +During the build you'll see tons of red errors that are pointing to our issues: + +1) **Wrong imports** + Invalid import are usually wrong relative imports (too deep) or circular imports. + +2) **Invalid doc-strings** + Doc-strings to be processed into documentation needs to follow some syntax - this can be checked by running + `pydocstyle` that is already included with OpenPype +3) **Invalid markdown/rst files** + md/rst files can be included inside rst files using `.. include::` directive. But they have to be properly formatted. + + +## Editing rst templates + +Everything starts with `/docs/source/index.rst` - this file should be properly edited, Right now it just includes `readme.rst` that in turn include and parse main `README.md`. This is entrypoint to API documentation. All templates generated by AutoAPI are in `/docs/source/autoapi`. They should be eventually commited to repository and edited too. + +## Steps for enhancing API documentation + +1) Run `/docs/make.bat html` +2) Read the red errors/warnings - fix it in the code +3) Run `/docs/make.bat html` again until there are not red lines +4) Edit rst files and add some meaningfull content there + +> **Note** +> This can (should) be merged as is without doc-string fixes in the code or changes in templates. All additional improvements on API documentation should be made in new PRs. + +> **Warning** +> You need to add new dependencies to use it. Run `create_venv`. + +Connected to #2490 +___ + +
+ + +
+Global: custom location for OP local versions #4673 + +This provides configurable location to unzip Openpype version zips. By default, it was hardcoded to artist's app data folder, which might be problematic/slow with roaming profiles.Location must be accessible by user running OP Tray with write permissions (so `Program Files` might be problematic) + + +___ + +
+ + +
+AYON: Update settings conversion #4837 + +Updated conversion script of AYON settings to v3 settings. PR is related to changes in addons repository https://github.com/ynput/ayon-addons/pull/6 . Changed how the conversion happens -> conversion output does not start with openpype defaults but as empty dictionary. + + +___ + +
+ + +
+AYON: Implement integrate links publish plugin #4842 + +Implemented entity links get/create functions. Added new integrator which replaces v3 integrator for links. + + +___ + +
+ + +
+General: Version attributes integration #4991 + +Implemented unified integrate plugin to update version attributes after all integrations for AYON. The goal is to be able update attribute values in a unified way to a version when all addon integrators are done, so e.g. ftrack can add ftrack id to matching version in AYON server etc.The can be stored under `"versionAttributes"` key. + + +___ + +
+ + +
+AYON: Staging versions can be used #4992 + +Added ability to use staging versions in AYON mode. + + +___ + +
+ + +
+AYON: Preparation for products #5038 + +Prepare ayon settings conversion script for `product` settings conversion. + + +___ + +
+ + +
+Loader: Hide inactive versions in UI #5101 + +Added support for `active` argument to hide versions with active set to False in Loader UI when in AYON mode. + + +___ + +
+ + +
+General: CLI addon command #5109 + +Added `addon` alias for `module` in OpenPype cli commands. + + +___ + +
+ + +
+AYON: OpenPype as server addon #5199 + +OpenPype repository can be converted to AYON addon for distribution. Addon has defined dependencies that are required to use it and are not in base ayon-launcher (desktop application). + + +___ + +
+ + +
+General: Runtime dependencies #5206 + +Defined runtime dependencies in pyproject toml. Moved python ocio and otio modules there. + + +___ + +
+ + +
+AYON: Bundle distribution #5209 + +Since AYON server 0.3.0 are addon versions defined by bundles which affects how addons, dependency packages and installers are handled. Only source of truth, about any version of anything that should be used, is server bundle. + + +___ + +
+ + +
+Feature/blender handle q application #5264 + +This edit is to change the way the QApplication is run for Blender. It calls in the singleton (QApplication) during the register. This is made so that other Qt applications and addons are able to run on Blender. In its current implementation, if a QApplication is already running, all functionality of OpenPype becomes unavailable. + + +___ + +
+ +### **🚀 Enhancements** + + +
+General: Connect to AYON server (base) #3924 + +Initial implementation of being able use AYON server in current OpenPype client. Added ability to connect to AYON server and use base queries. + +AYON mode has it's own executable (and start script). To start in AYON mode just replace `start.py` with `ayon_start.py` (added tray start script to tools). Added constant `AYON_SERVER_ENABLED` to `openpype/__init__.py` to know if ayon mode is enabled. In that case Mongo is not used at all and any attempts will cause crashes.I had to modify `~/openpype/client` content to be able do this switch. Mongo implementation was moved to `mongo` subfolder and use "star imports" in files from where current imports are used. Logic of any tool or query in code was not changed at all. Since functions were based on mongo queries they don't use full potential of AYON server abilities.ATM implementation has login UI, distribution of files from server and replacement of mongo queries. For queries is used `ayon_api` module. Which is in live development so the versions may change from day to day. + + +___ + +
+ + +
+Enhancement kitsu note with exceptions #4537 + +Adding a setting to choose some exceptions to IntegrateKitsuNote task status changes. + + +___ + +
+ + +
+General: Environment variable for default OCIO configs #4670 + +Define environment variable which lead to root of builtin ocio configs to be able change the root without changing settings. For the path in settings was used `"{OPENPYPE_ROOT}/vendor/bin/ocioconfig/OpenColorIOConfig"` which disallow to change the root somewhere else. That will be needed in AYON where configs won't be part of desktop application but downloaded from server. + + +___ + +
+ + +
+AYON: Editorial hierarchy creation #4699 + +Implemented extract hierarchy to AYON plugin which created entities in AYON using ayon api. + + +___ + +
+ + +
+AYON: Vendorize ayon api #4753 + +Vendorize ayon api into openpype vendor directory. The reason is that `ayon-python-api` is in live development and will fix/add features often in next few weeks/months, and because update of dependency requires new release -> new build, we want to avoid the need of doing that as it would affect OpenPype development. + + +___ + +
+ + +
+General: Update PySide 6 for MacOs #4764 + +New version of PySide6 does not have issues with settings UI. It is still breaking UI stylesheets so it is not changed for other plaforms but it is enhancement from previous state. + + +___ + +
+ + +
+General: Removed unused cli commands #4902 + +Removed `texturecopy` and `launch` cli commands from cli commands. + + +___ + +
+ + +
+AYON: Linux & MacOS launch script #4970 + +Added shell script to launch tray in AYON mode. + + +___ + +
+ + +
+General: Qt scale enhancement #5059 + +Set ~~'QT_SCALE_FACTOR_ROUNDING_POLICY'~~ scale factor rounding policy of QApplication to `PassThrough` so the scaling can be 'float' number and not just 'int' (150% -> 1.5 scale). + + +___ + +
+ + +
+CI: WPS linting instead of Hound (rebase) 2 #5115 + +Because Hound currently used to lint the code on GH ships with really old flake8 support, it fails miserably on any newer Python syntax. This PR is adding WPS linter to GitHub workflows that should step in. + + +___ + +
+ + +
+Max: OP parameters only displays what is attached to the container #5229 + +The OP parameter in 3dsmax only displays what is currently attached to the container while deleting while you can see the items which is not added when you are adding to the container. + + +___ + +
+ + +
+Testing: improving logging during testing #5271 + +Unit testing logging was crashing on more then one nested layers of inherited loggers. + + +___ + +
+ + +
+Nuke: removing deprecated settings in baking #5275 + +Removing deprecated settings for baking with reformat. This option was only for single reformat node and it had been substituted with multiple reposition nodes. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+AYON: General fixes and updates #4975 + +Few smaller fixes related to AYON connection. Some of fixes were taken from this PR. + + +___ + +
+ + +
+Start script: Change returncode on validate or list versions #4515 + +Change exit code from `1` to `0` when versions are printed or when version is validated. + +Return code `1` is indicating error but there didn't happen any error. + + +___ + +
+ + +
+AYON: Change login UI works #4754 + +Fixed change of login UI. Logic change UI did show up, new login was successful, but after restart was used the previous login. This change fix the issue. + + +___ + +
+ + +
+AYON: General issues #4763 + +Vendorized `ayon_api` from PR broke OpenPype launch, because `ayon_api` is not available. Moved `ayon_api` from ayon specific subforlder to `common` python vendor in OpenPype, and removed login in ayon start script (which was invalid anyway). Also made fixed compatibility with PySide6 by using `qtpy` instead of `Qt` and changing code which is not PySide6 compatible. + + +___ + +
+ + +
+AYON: Small fixes #4841 + +Bugsfixes and enhancements related to AYON logic. Define `BUILTIN_OCIO_ROOT` environment variable so OCIO configs are working. Use constants from ayon api instead of hardcoding them in codebase. Change process name from "openpype" to "ayon". Don't execute login dialog when application is not yet running but use `open` method instead. Fixed missing modules settings which were not taken from openpype defaults. Updated ayon api to `0.1.17`. + + +___ + +
+ + +
+Bugfix - Update gazu to 0.9.3 #4845 + +This updates Gazu to 0.9.3 to make sure Gazu works with Kitsu and Zou 0.16.x+ + + +___ + +
+ + +
+Igniter: fix error reports in silent mode #4909 + +Some errors in silent mode commands in Igniter were suppressed and not visible for example in Deadline log. + + +___ + +
+ + +
+General: Remove ayon api from poetry lock #4964 + +Remove AYON python api from pyproject.toml and poetry.lock again. + + +___ + +
+ + +
+Ftrack: Fix AYON settings conversion #4967 + +Fix conversion of ftrack settings in AYON mode. + + +___ + +
+ + +
+AYON: ISO date format conversion issues #4981 + +Function `datetime.fromisoformat` was replaced with `arrow.get` to be used instead. + + +___ + +
+ + +
+AYON: Missing files on representations #4989 + +Fix integration of files into representation in server database. + + +___ + +
+ + +
+General: Fix Python 2 vendor for arrow #4993 + +Moved remaining dependencies for arrow from ftrack to python 2 vendor. + + +___ + +
+ + +
+General: Fix new load plugins for next minor relase #5000 + +Fix access to `fname` attribute which is not available on load plugin anymore. + + +___ + +
+ + +
+General: Fix mongo secure connection #5031 + +Fix `ssl` and `tls` keys checks in mongo uri query string. + + +___ + +
+ + +
+AYON: Fix site sync settings #5069 + +Fixed settings for AYON variant of sync server. + + +___ + +
+ + +
+General: Replace deprecated keyword argument in PyMongo #5080 + +Use argument `tlsCAFile` instead of `ssl_ca_certs` to avoid deprecation warnings. + + +___ + +
+ + +
+Igniter: QApplication is created #5081 + +Function `_get_qt_app` actually creates new `QApplication` if was not created yet. + + +___ + +
+ + +
+General: Lower unidecode version #5090 + +Use older version of Unidecode module to support Python 2. + + +___ + +
+ + +
+General: Lower cryptography to 39.0.0 #5099 + +Lower cryptography to 39.0.0 to avoid breaking of DCCs like Maya and Nuke. + + +___ + +
+ + +
+AYON: Global environments key fix #5118 + +Seems that when converting ayon settings to OP settings the `environments` setting is put under the `environments` key in `general` however when populating the environment the `environment` key gets picked up, which does not contain the environment variables from the `core/environments` setting + + +___ + +
+ + +
+Add collector to tray publisher for getting frame range data #5152 + +Add collector to tray publisher to get frame range data. User can choose to enable this collector if they need this in the publisher.Resolve #5136 + + +___ + +
+ + +
+Unreal: get current project settings not using unreal project name #5170 + +There was a bug where Unreal project name was used to query project settings. But Unreal project name can differ from the "real" one because of naming convention rules set by Unreal. This is fixing it by asking for current project settings. + + +___ + +
+ + +
+Substance Painter: Fix Collect Texture Set Images unable to copy.deepcopy due to QMenu #5238 + +Fix `copy.deepcopy` of `instance.data`. + + +___ + +
+ + +
+Ayon: server returns different key #5251 + +Package returned from server has `filename` instead of `name`. + + +___ + +
+ + +
+Substance Painter: Fix default color management settings #5259 + +The default settings for color management for Substance Painter were invalid, it was set to override the global config by default but specified no valid config paths of its own - and thus errored that the paths were not correct.This sets the defaults correctly to match other hosts._I quickly checked - this seems to be the only host with the wrong default settings_ + + +___ + +
+ + +
+Nuke: fixing container data if windows path in value #5267 + +Windows path in container data are reformatted. Previously it was reported that Nuke was rising `utf8 0xc0` error if backward slashes were in data values. + + +___ + +
+ + +
+Houdini: fix typo error in collect arnold rop #5281 + +Fixing a typo error in `collect_arnold_rop.py`Reference: #5280 + + +___ + +
+ + +
+Slack - enhanced logging and protection against failure #5287 + +Covered issues found in production on customer site. SlackAPI exception doesn't need to have 'error', covered uncaught exception. + + +___ + +
+ + +
+Maya: Removed unnecessary import of pyblish.cli #5292 + +This import resulted in adding additional logging handler which lead to duplication of logs in hosts with plugins containing `is_in_tests` method. Import is unnecessary for testing functionality. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Loader: Remove `context` argument from Loader.__init__() #4602 + +Remove the previously required `context` argument. + + +___ + +
+ + +
+Global: Remove legacy integrator #4786 + +Remove the legacy integrator. + + +___ + +
+ +### **📃 Documentation** + + +
+Next Minor Release #5291 + + +___ + +
+ +### **Merged pull requests** + + +
+Maya: Refactor to new publisher #4388 + +**Refactor Maya to use the new publisher with new creators.** + + +- [x] Legacy instance can be converted in UI using `SubsetConvertorPlugin` +- [x] Fix support for old style "render" and "vrayscene" instance to the new per layer format. +- [x] Context data is stored with scene +- [x] Workfile instance converted to AutoCreator +- [x] Converted Creator classes +- [x] Create animation +- [x] Create ass +- [x] Create assembly +- [x] Create camera +- [x] Create layout +- [x] Create look +- [x] Create mayascene +- [x] Create model +- [x] Create multiverse look +- [x] Create multiverse usd +- [x] Create multiverse usd comp +- [x] Create multiverse usd over +- [x] Create pointcache +- [x] Create proxy abc +- [x] Create redshift proxy +- [x] Create render +- [x] Create rendersetup +- [x] Create review +- [x] Create rig +- [x] Create setdress +- [x] Create unreal skeletalmesh +- [x] Create unreal staticmesh +- [x] Create vrayproxy +- [x] Create vrayscene +- [x] Create xgen +- [x] Create yeti cache +- [x] Create yeti rig +- [ ] Tested new Creator publishes +- [x] Publish animation +- [x] Publish ass +- [x] Publish assembly +- [x] Publish camera +- [x] Publish layout +- [x] Publish look +- [x] Publish mayascene +- [x] Publish model +- [ ] Publish multiverse look +- [ ] Publish multiverse usd +- [ ] Publish multiverse usd comp +- [ ] Publish multiverse usd over +- [x] Publish pointcache +- [x] Publish proxy abc +- [x] Publish redshift proxy +- [x] Publish render +- [x] Publish rendersetup +- [x] Publish review +- [x] Publish rig +- [x] Publish setdress +- [x] Publish unreal skeletalmesh +- [x] Publish unreal staticmesh +- [x] Publish vrayproxy +- [x] Publish vrayscene +- [x] Publish xgen +- [x] Publish yeti cache +- [x] Publish yeti rig +- [x] Publish workfile +- [x] Rig loader correctly generates a new style animation creator instance +- [ ] Validations / Error messages for common validation failures look nice and usable as a report. +- [ ] Make Create Animation hidden to the user (should not create manually?) +- [x] Correctly detect difference between **'creator_attributes'** and **'instance_data'** since both are "flattened" to the top node. + + +___ + +
+ + +
+Start script: Fix possible issues with destination drive path #4478 + +Drive paths for windows are fixing possibly missing slash at the end of destination path. + +Windows `subst` command require to have destination path with slash if it's a drive (it should be `G:\` not `G:`). + + +___ + +
+ + +
+Global: Move PyOpenColorIO to vendor/python #4946 + +So that DCCs don't conflict with their own. + +See https://github.com/ynput/OpenPype/pull/4267#issuecomment-1537153263 for the issue with Gaffer. + +I'm not sure if this is the correct approach, but I assume PySide/Shiboken is under `vendor/python` for this reason as well... +___ + +
+ + +
+RuntimeError with Click on deadline publish #5065 + +I changed Click to version 8.0 instead of 7.1.2 to solve this error: +``` +2023-05-30 16:16:51: 0: STDOUT: Traceback (most recent call last): +2023-05-30 16:16:51: 0: STDOUT: File "start.py", line 1126, in boot +2023-05-30 16:16:51: 0: STDOUT: File "/prod/softprod/apps/openpype/LINUX/3.15/dependencies/click/core.py", line 829, in __call__ +2023-05-30 16:16:51: 0: STDOUT: return self.main(*args, **kwargs) +2023-05-30 16:16:51: 0: STDOUT: File "/prod/softprod/apps/openpype/LINUX/3.15/dependencies/click/core.py", line 760, in main +2023-05-30 16:16:51: 0: STDOUT: _verify_python3_env() +2023-05-30 16:16:51: 0: STDOUT: File "/prod/softprod/apps/openpype/LINUX/3.15/dependencies/click/_unicodefun.py", line 126, in _verify_python3_env +2023-05-30 16:16:51: 0: STDOUT: raise RuntimeError( +2023-05-30 16:16:51: 0: STDOUT: RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment. Consult https://click.palletsprojects.com/python3/ for mitigation steps. +``` + + +___ + +
+ + + + +## [3.15.12](https://github.com/ynput/OpenPype/tree/3.15.12) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.11...3.15.12) + +### **🆕 New features** + + +
+Tray Publisher: User can set colorspace per instance explicitly #4901 + +With this feature a user can set/override the colorspace for the representations of an instance explicitly instead of relying on the File Rules from project settings or alike. This way you can ingest any file and explicitly say "this file is colorspace X". + + +___ + +
+ + +
+Review Family in Max #5001 + +Review Feature by creating preview animation in 3dsmax(The code is still cleaning up so there is going to be some updates until it is ready for review) + + +___ + +
+ + +
+AfterEffects: support for workfile template builder #5163 + +This PR add functionality of templated workfile builder. It allows someone to prepare AE workfile with placeholders as for automatically loading particular representation of particular subset of particular asset from context where workfile is opened.Selection from multiple prepared workfiles is provided with usage of templates, specific type of tasks could use particular workfile template etc.Artists then can build workfile from template when opening new workfile. + + +___ + +
+ + +
+CreatePlugin: Get next version helper #5242 + +Implemented helper functions to get next available versions for create instances. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: Improve Templates #4854 + +Use library method for fetching reference node and support parent in hierarchy. + + +___ + +
+ + +
+Bug: Maya - xgen sidecar files arent moved when saving workfile as an new asset workfile changing context - OP-6222 #5215 + +This PR manages the Xgen files when switching context in the Workfiles app. + + +___ + +
+ + +
+node references to check for duplicates in Max #5192 + +No duplicates for node references in Max when users trying to select nodes before publishing + + +___ + +
+ + +
+Tweak profiles logging to debug level #5194 + +Tweak profiles logging to debug level since they aren't artist facing logs. + + +___ + +
+ + +
+Enhancement: Reduce more visual clutter for artists in new publisher reports #5208 + +Got this from one of our artists' reports - figured some of these logs were definitely not for the artist, reduced those logs to debug level. + + +___ + +
+ + +
+Cosmetics: Tweak pyblish repair actions (icon, logs, docstring) #5213 + +- Add icon to RepairContextAction +- logs to debug level +- also add attempt repair for RepairAction for consistency +- fix RepairContextAction docstring to mention correct argument name + +#### Additional info + +We should not forget to remove this ["deprecated" actions.py file](https://github.com/ynput/OpenPype/blob/3501d0d23a78fbaef106da2fffe946cb49bef855/openpype/action.py) in 3.16 (next-minor) + +## Testing notes: + +1. Run some fabulous repairs! + +___ + +
+ + +
+Maya: fix save file prompt on launch last workfile with color management enabled + restructure `set_colorspace` #5225 + +- Only set `configFilePath` when OCIO env var is not set since it doesn't do anything if OCIO var is set anyway. +- Set the Maya 2022+ default OCIO path using the resources path instead of "" to avoid Maya Save File on new file after launch +- **Bugfix: This is what fixes the Save prompt on open last workfile feature with Global color management enabled** +- Move all code related to applying the maya settings together after querying the settings +- Swap around the `if use_workfile_settings` since the check was reversed +- Use `get_current_project_name()` instead of environment vars + + +___ + +
+ + +
+Enhancement: More descriptive error messages for Loaders #5227 + +Tweak raised errors and error messages for loader errors. + + +___ + +
+ + +
+Houdini: add select invalid action for ValidateSopOutputNode #5231 + +This PR adds `SelectROPAction` action to `houdini\api\action.py`and it's used in `Validate Output Node``SelectROPAction` is used to select the associated ROPs with the errored instances. + + +___ + +
+ + +
+Remove new lines from the delivery template string #5235 + +If the delivery template has a new line symbol at the end, say it was copied from the text editor, the delivery process will fail with `OSError` due to incorrect destination path. To avoid that I added `rstrip()` to the `delivery_path` processing. + + +___ + +
+ + +
+Houdini: better selection on pointcache creation #5250 + +Houdini allows `ObjNode` path as `sop_path` in the `ROP` unlike OP/ Ayon require `sop_path` to be set to a sop node path explicitly In this code, better selection is used to filter out invalid selections from OP/ Ayon point of viewValid selections are +- `SopNode` that has parent of type `geo` or `subnet` +- `ObjNode` of type `geo` that has +- `SopNode` of type `output` +- `SopNode` with render flag `on` (if no `Sopnode` of type `output`)this effectively filter +- empty `ObjNode` +- `ObjNode`(s) of other types like `cam` and `dopnet` +- `SopNode`(s) that thier parents of other types like `cam` and `sop solver` + + +___ + +
+ + +
+Update scene inventory even if any errors occurred during update #5252 + +When selecting many items in the scene inventory to update versions and one of the items would error out the updating stops. However, before this PR the scene inventory would also NOT refresh making you think it did nothing.Also implemented as method to allow some code deduplication. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Convert frame values to integers #5188 + +Convert frame values to integers. + + +___ + +
+ + +
+Maya: fix the register_event_callback correctly collecting workfile save after #5214 + +fixing the bug of register_event_callback not being able to collect action of "workfile_save_after" for lock file action + + +___ + +
+ + +
+Maya: aligning default settings to distributed aces 1.2 config #5233 + +Maya colorspace setttings defaults are set the way they align our distributed ACES 1.2 config file set in global colorspace configs. + + +___ + +
+ + +
+RepairAction and SelectInvalidAction filter instances failed on the exact plugin #5240 + +RepairAction and SelectInvalidAction actually filter to instances that failed on the exact plugin - not on "any failure" + + +___ + +
+ + +
+Maya: Bugfix look update nodes by id with non-unique shape names (query with `fullPath`) #5257 + +Fixes a bug where updating attributes on nodes with assigned shader if shape name existed more than once in the scene due to `cmds.listRelatives` call not being done with the `fullPath=True` flag.Original error: +```python +# Traceback (most recent call last): +# File "E:\openpype\OpenPype\openpype\tools\sceneinventory\view.py", line 264, in +# lambda: self._show_version_dialog(items)) +# File "E:\openpype\OpenPype\openpype\tools\sceneinventory\view.py", line 722, in _show_version_dialog +# self._update_containers(items, version) +# File "E:\openpype\OpenPype\openpype\tools\sceneinventory\view.py", line 849, in _update_containers +# update_container(item, item_version) +# File "E:\openpype\OpenPype\openpype\pipeline\load\utils.py", line 502, in update_container +# return loader.update(container, new_representation) +# File "E:\openpype\OpenPype\openpype\hosts\maya\plugins\load\load_look.py", line 119, in update +# nodes_by_id[lib.get_id(n)].append(n) +# File "E:\openpype\OpenPype\openpype\hosts\maya\api\lib.py", line 1420, in get_id +# sel.add(node) +``` + + +___ + +
+ + +
+Nuke: Create nodes with inpanel=False #5051 + +This PR is meant to remove the annoyance of the UI changing focus to the properties window just for the property window of the newly created node to disappear. Instead of using node.hideControlPanel I'm implementing the concealment during the creation of the node which will not change the focus of the current window. +___ + +
+ + +
+Fix the reset frame range not setting up the right timeline in Max #5187 + +Resolve #5181 + + +___ + +
+ + +
+Resolve: after launch automatization fixes #5193 + +Workfile is no correctly created and aligned witch actual project. Also the launching mechanism is now fixed so even no workfile had been saved yet it will open OpenPype menu automatically. + + +___ + +
+ + +
+General: Revert backward incompatible change of path to template to multiplatform #5197 + +Now platformity is still handed by usage of `work[root]` (or any other root that is accessible across platforms.) + + +___ + +
+ + +
+Nuke: root set format updating in node graph #5198 + +Nuke root node needs to be reset on some values so any knobs could be updated in node graph. This works the same way as an user would change frame number so expressions would update its values in knobs. + + +___ + +
+ + +
+Hiero: fixing otio current project and cosmetics #5200 + +Otio were not returning correct current project once additional Untitled project was open in project manager stack. + + +___ + +
+ + +
+Max: Publisher instances dont hold its enabled disabled states when Publisher reopened again #5202 + +Resolve #5183, general maxscript conversion issue to python (e.g. bool conversion, true in maxscript while True in Python)(Also resolve the ValueError when you change the subset to publish into list view menu) + + +___ + +
+ + +
+Burnins: Filter script is defined only for video streams #5205 + +Burnins are working for inputs with audio. + + +___ + +
+ + +
+Colorspace lib fix compatible python version comparison #5212 + +Fix python version comparison. + + +___ + +
+ + +
+Houdini: Fix `get_color_management_preferences` #5217 + +Fix the issue described here where the logic for retrieving the current OCIO display and view was incorrectly trying to apply a regex to it. + + +___ + +
+ + +
+Houdini: Redshift ROP image format bug #5218 + +Problem : +"RS_outputFileFormat" parm value was missing +and there were more "image_format" than redshift rop supports + +Fix: +1) removed unnecessary formats from `image_format_enum` +2) add the selected format value to `RS_outputFileFormat` +___ + +
+ + +
+Colorspace: check PyOpenColorIO rather then python version #5223 + +Fixing previously merged PR (https://github.com/ynput/OpenPype/pull/5212) And applying better way to check compatibility with PyOpenColorIO python api. + + +___ + +
+ + +
+Validate delivery action representations status #5228 + +- disable delivery button if no representations checked +- fix macos combobox layout +- add error message if no delivery templates found + + +___ + +
+ + +
+ Houdini: Add geometry check for pointcache family #5230 + +When `sop_path` on ABC ROP node points to a non `SopNode`, these validators `validate_abc_primitive_to_detail.py`, `validate_primitive_hierarchy_paths.py` will error and crash when this line is executed `geo = output_node.geometryAtFrame(frame)` + + +___ + +
+ + +
+Houdini: Add geometry check for VDB family #5232 + +When `sop_path` on Geometry ROP node points to a non SopNode, this validator `validate_vdb_output_node.py` will error and crash when this line is executed`sop_node.geometryAtFrame(frame)` + + +___ + +
+ + +
+Substance Painter: Include the setting only in publish tab #5234 + +Instead of having two settings in both create and publish tab, there is solely one setting in the publish tab for users to set up the parameters.Resolve #5172 + + +___ + +
+ + +
+Maya: Fix collecting arnold prefix when none #5243 + +When no prefix is specified in render settings, the renderlayer collector would error. + + +___ + +
+ + +
+Deadline: OPENPYPE_VERSION should only be added when running from build #5244 + +When running from source the environment variable `OPENPYPE_VERSION` should not be added. This is a bugfix for the feature #4489 + + +___ + +
+ + +
+Fix no prompt for "unsaved changes" showing when opening workfile in Houdini #5246 + +Fix no prompt for "unsaved changes" showing when opening workfile in Houdini. + + +___ + +
+ + +
+Fix no prompt for "unsaved changes" showing when opening workfile in Substance Painter #5248 + +Fix no prompt for "unsaved changes" showing when opening workfile in Substance Painter. + + +___ + +
+ + +
+General: add the os library before os.environ.get #5249 + +Adding os library into `creator_plugins.py` due to `os.environ.get` in line 667 + + +___ + +
+ + +
+Maya: Fix set_attribute for enum attributes #5261 + +Fix for #5260 + + +___ + +
+ + +
+Unreal: Move Qt imports away from module init #5268 + +Importing `Window` creates errors in headless mode. +``` +*** WRN: >>> { ModulesLoader }: [ FAILED to import host folder unreal ] +============================= +No Qt bindings could be found +============================= +Traceback (most recent call last): + File "C:\Users\tokejepsen\OpenPype\.venv\lib\site-packages\qtpy\__init__.py", line 252, in + from PySide6 import __version__ as PYSIDE_VERSION # analysis:ignore +ModuleNotFoundERROR: No module named 'PySide6' + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "C:\Users\tokejepsen\OpenPype\openpype\modules\base.py", line 385, in _load_modules + default_module = __import__( + File "C:\Users\tokejepsen\OpenPype\openpype\hosts\unreal\__init__.py", line 1, in + from .addon import UnrealAddon + File "C:\Users\tokejepsen\OpenPype\openpype\hosts\unreal\addon.py", line 4, in + from openpype.widgets.message_window import Window + File "C:\Users\tokejepsen\OpenPype\openpype\widgets\__init__.py", line 1, in + from .password_dialog import PasswordDialog + File "C:\Users\tokejepsen\OpenPype\openpype\widgets\password_dialog.py", line 1, in + from qtpy import QtWidgets, QtCore, QtGui + File "C:\Users\tokejepsen\OpenPype\.venv\lib\site-packages\qtpy\__init__.py", line 259, in + raise QtBindingsNotFoundERROR() +qtpy.QtBindingsNotFoundERROR: No Qt bindings could be found +``` + + +___ + +
+ +### **🔀 Refactored code** + + +
+Maya: Minor refactoring and code cleanup #5226 + +Some small cleanup and refactoring of logic. Removing old comments, unused imports and some minor optimization. Also removed the prints of the loader names of each container the scene in `fix_incompatible_containers` + optimizing by using `set` and defining only once. Moved some UI related code/tweaks to run `on_init` only if not in headless mode. Removed an empty `obj.py` file.Each commit message kind of describes why the change was made. + + +___ + +
+ +### **Merged pull requests** + + +
+Bug: Template builder fails when loading data without outliner representation #5222 + +I add an assertion management in case the container does not have a represention in outliner. + + +___ + +
+ + +
+AfterEffects - add container check validator to AE settings #5203 + +Adds check if scene contains only latest version of loaded containers. + + +___ + +
+ + + + +## [3.15.11](https://github.com/ynput/OpenPype/tree/3.15.11) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.10...3.15.11) + +### **🆕 New features** + + +
+Ftrack: Task status during publishing #5123 + +Added option to change task status during publishing for 3 possible cases: "sending to farm", "local integration" and "on farm integration". + + +___ + +
+ + +
+Nuke: Allow for more complex temp rendering paths #5132 + +When changing the temporary rendering template (i.e., add `{asset}` to the path) to something a bit more complex the formatting was erroring due to missing keys. + + +___ + +
+ + +
+Blender: Add support for custom path for app templates #5137 + +This PR adds support for a custom App Templates path in Blender by setting the `BLENDER_USER_SCRIPTS` environment variable to the path specified in `OPENPYPE_APP_TEMPLATES_PATH`. This allows users to use their own custom app templates in Blender. + + +___ + +
+ + +
+TrayPublisher & StandalonePublisher: Specify version #5142 + +Simple creators in TrayPublisher can affect which version will be integrated. Standalone publisher respects the version change from UI. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Workfile Builder UI: Workfile builder window is not modal #5131 + +Workfile Templates Builder: +- Create dialog is not a modal dialog +- Create dialog remains open after create, so you can directly create a new placeholder with similar settings +- In Maya allow to create root level placeholders (no selection during create) - **this felt more like a bugfix than anything else.** + + +___ + +
+ + +
+3dsmax: Use custom modifiers to hold instance members #4931 + +Moving logic to handle members of publishing instance from children/parent relationship on Container to tracking via custom attribute on modifier. This eliminates limitations where you couldn't have one node multiple times under one Container and because it stores those relationships as weak references, they are easily transferable even when original nodes are renamed. + + +___ + +
+ + +
+Add height, width and fps setup to project manager #5075 + +Add Width, Height, FPS, Pixel Aspect and Frame Start/End to the Project creation dialogue in the Project Manager.I understand that the Project manager will be replaced in the upcoming Ayon, but for the time being I believe setting new project with these options available would be more fun. + + +___ + +
+ + +
+Nuke: connect custom write node script to the OP setting #5113 + +Allows user to customize the values of knobs attribute in the OP setting and use it in custom write node + + +___ + +
+ + +
+Keep `publisher.create_widget` variant when creating subsets #5119 + +Whenever a person is creating a subset to publish, the "creator" widget resets (where you choose the variant, product, etc.) so if the person is publishing several images of the a variant which is not the default one, they have to keep selecting the correct one after every "create". + +This commit resets the original variant upon successful creation of a subset for publishing. + +Demo: +[Screencast from 2023-06-08 10-46-40.webm](https://github.com/ynput/OpenPype/assets/1800151/ca1c91d4-b8f3-43d2-a7b7-35987f5b6a3f) + +## Testing notes: +1. Launch AYON/OP +2. Launch the publisher (select a project, shot, etc.) +3. Crete a publish type (any works) +4. Choose a variant for the publish that is not the default +5. "Create >>" + +The Variant fields should still have the variant you choose. + + + +___ + +
+ + +
+Color Management- added color management support for simple expected files on Deadline #5122 + +Running of `ExtractOIIOTranscode` during Deadline publish was previously implemented only on DCCs with AOVs (Maya, Max).This PR extends this for other DCCs with flat structure of expected files. + + +___ + +
+ + +
+hide macos dock icon on build #5133 + +Set `LSUIElement` to `1` in the `Info.plist` to hide OP icon from the macos dock by default. + + +___ + +
+ + +
+Pack project: Raise exception with reasonable message #5145 + +Pack project crashes with relevant message when destination directory is not set. + + +___ + +
+ + +
+Allow "inventory" actions to be supplied by a Module/Addon. #5146 + +Adds "inventory" as a possible key to the plugin paths to be returned from a module. + + +___ + +
+ + +
+3dsmax: make code compatible with 3dsmax 2022 #5164 + +Python 3.7 in 3dsmax 2022 is not supporting walrus operator. This is removing it from the code for the sake of compatibility + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Support same attribute names on different node types. #5054 + +When validating render settings attributes, support same attribute names on different node types. + + +___ + +
+ + +
+Maya: bug fix the standin being not loaded when they are first loaded #5143 + +fix the bug of raising error when the first two standins are loaded through the loaderThe bug mentioned in the related issue: https://github.com/ynput/OpenPype/issues/5129For some reason, `defaultArnoldRenderOptions.operator` is not listed in the connection node attribute even if `cmds.loadPlugin("mtoa", quiet=True)` executed before loading the object as standins for the first time.But if you manually turn on mtoa through plugin preference and load the standins for the first time, it won't raise the related `defaultArnoldRenderOptions.operator` error. + + +___ + +
+ + +
+Maya: bug fix arnoldExportAss unable to export selected set members #5150 + +See #5108 fix the bug arnoldExportAss being not able to export and error out during extraction. + + +___ + +
+ + +
+Maya: Xgen multiple descriptions on single shape - OP-6039 #5160 + +When having multiple descriptions on the same geometry, the extraction would produce redundant duplicate geometries. + + +___ + +
+ + +
+Maya: Xgen export of Abc's during Render Publishing - OP-6206 #5167 + +Shading assignments was missing duplicating the setup for Xgen publishing and the exporting of patches was getting the end frame incorrectly. + + +___ + +
+ + +
+Maya: Include handles - OP-6236 #5175 + +Render range was missing the handles. + + +___ + +
+ + +
+OCIO: Support working with single frame renders #5053 + +When there is only 1 file, the datamember `files` on the representation should be a string. + + +___ + +
+ + +
+Burnins: Refactored burnins script #5094 + +Refactored list value for burnins and fixed command length limit by using temp file for filters string. + + +___ + +
+ + +
+Nuke: open_file function can open autosave script #5107 + +Fix the bug of the workfile dialog being unable to open autosave nuke script + + +___ + +
+ + +
+ImageIO: Minor fixes #5147 + +Resolve few minor fixes related to latest image io changes from PR. + + +___ + +
+ + +
+Publisher: Fix save shortcut #5148 + +Save shortcut should work for both PySide2 and PySide6. + + +___ + +
+ + +
+Pack Project: Fix files packing #5154 + +Packing of project with files does work again. + + +___ + +
+ + +
+Maya: Xgen version mismatch after publish - OP-6204 #5161 + +Xgen was not updating correctly when for example adding or removing descriptions. This resolve the issue by overwritting the workspace xgen file. + + +___ + +
+ + +
+Publisher: Edge case fixes #5165 + +Fix few edge case issues that may cause issues in Publisher UI. + + +___ + +
+ + +
+Colorspace: host config path backward compatibility #5166 + +Old project settings overrides are now fully backward compatible. The issue with host config paths overrides were solved and now once a project used to be set to ocio_config **enabled** with found filepaths - this is now considered as activated host ocio_config paths overrides.Nuke is having an popup dialogue which is letting know to a user that settings for config path were changed. + + +___ + +
+ + +
+Maya: import workfile missing - OP-6233 #5174 + +Missing `workfile` family to import. + + +___ + +
+ + +
+Ftrack: Fix ignore sync filter #5176 + +Ftrack ignore filter does not crash because of dictionary modifications during it's iteration. + + +___ + +
+ + +
+Webpublisher - headless publish shouldn't be blocking operation #5177 + +`subprocess.call` was blocking, which resulted in UI non responsiveness as it was waiting for publish to finish. + + +___ + +
+ + +
+Publisher: Fix disappearing actions #5184 + +Pyblish plugin actions are visible as expected. + + +___ + +
+ +### **Merged pull requests** + + +
+Enhancement:animation family loaded as standing (abc) uses "use file sequence" #5110 + +The changes are the following. We started by updating the the is_sequence(files) function allowing it to return True for a list of files which has only one file, since our animation in this provides just one alembic file. For the correct FPS number, we got the fps from the published ass/abc from the version data. + + +___ + +
+ + +
+add label to matching family #5128 + +I added the possibility to filter the `family smart select` with the label in addition to the family. + + +___ + +
+ + + + +## [3.15.10](https://github.com/ynput/OpenPype/tree/3.15.10) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.9...3.15.10) + +### **🆕 New features** + + +
+ImageIO: Adding ImageIO activation toggle to all hosts #4700 + +Colorspace management can now be enabled at the project level, although it is disabled by default. Once enabled, all hosts will use the OCIO config file defined in the settings. If settings are disabled, the system switches to DCC's native color space management, and we do not store colorspace information at the representative level. + + +___ + +
+ + +
+Redshift Proxy Support in 3dsMax #4625 + +Redshift Proxy Support for 3dsMax. +- [x] Creator +- [x] Loader +- [x] Extractor +- [x] Validator +- [x] Add documentation + + +___ + +
+ + +
+Houdini farm publishing and rendering #4825 + +Deadline Farm publishing and Rendering for Houdini +- [x] Mantra +- [x] Karma(including usd renders) +- [x] Arnold +- [x] Elaborate Redshift ROP for deadline submission +- [x] fix the existing bug in Redshift ROP +- [x] Vray +- [x] add docs + + +___ + +
+ + +
+Feature: Blender hook to execute python scripts at launch #4905 + +Hook to allow hooks to add path to a python script that will be executed when Blender starts. + + +___ + +
+ + +
+Feature: Resolve: Open last workfile on launch through .scriptlib #5047 + +Added implementation to Resolve integration to open last workfile on launch. + + +___ + +
+ + +
+General: Remove default windowFlags from publisher #5089 + +The default windowFlags is making the publisher window (in Linux at least) only show the close button and it's frustrating as many times you just want to minimize the window and get back to the validation after. Removing that line I get what I'd expect.**Before:****After:** + + +___ + +
+ + +
+General: Show user who created the workfile on the details pane of workfile manager #5093 + +New PR for https://github.com/ynput/OpenPype/pull/5087, which was closed after merging `next-minor` branch and then realizing we don't need to target it as it was decided it's not required to support windows. More info on that PR discussion.Small addition to add name of the `user` who created the workfile on the details pane of the workfile manager: + + +___ + +
+ + +
+Loader: Hide inactive versions in UI #5100 + +Hide versions with `active` set to `False` in Loader UI. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Maya: Repair RenderPass token when merging AOVs. #5055 + +Validator was flagging that `` was in the image prefix, but did not repair the issue. + + +___ + +
+ + +
+Maya: Improve error feedback when no renderable cameras exist for ASS family. #5092 + +When collecting cameras for `ass` family, this improves the error message when no cameras are renderable. + + +___ + +
+ + +
+Nuke: Custom script to set frame range of read nodes #5039 + +Adding option to set frame range specifically for the read nodes in Openpype Panel. User can set up their preferred frame range with the frame range dialog, which can be showed after clicking `Set Frame Range (Read Node)` in Openpype Tools + + +___ + +
+ + +
+Update extract review letterbox docs #5074 + +Update Extract Review - Letter Box section in Docs. Letterbox type description is removed. + + +___ + +
+ + +
+Project pack: Documents only skips roots validation #5082 + +Single roots validation is skipped if only documents are extracted. + + +___ + +
+ + +
+Nuke: custom settings for write node without publish #5084 + +Set Render Output and other settings to write nodes for non-publish purposes. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Deadline servers #5052 + +Fix working with multiple Deadline servers in Maya. +- Pools (primary and secondary) attributes were not recreated correctly. +- Order of collector plugins were wrong, so collected data was not injected into render instances. +- Server attribute was not converted to string so comparing with settings was incorrect. +- Improve debug logging for where the webservice url is getting fetched from. + + +___ + +
+ + +
+Maya: Fix Load Reference. #5091 + +Fix bug introduced with https://github.com/ynput/OpenPype/pull/4751 where `cmds.ls` returns a list. + + +___ + +
+ + +
+3dsmax: Publishing Deadline jobs from RedShift #4960 + +Fix the bug of being uable to publish deadline jobs from RedshiftUse Current File instead of Published Scene for just Redshift. +- add save scene before rendering to ensure the scene is saved after the modification. +- add separated aov files option to allow users to choose to have aovs in render output +- add validator for render publish to aovid overriding the previous renders + + +___ + +
+ + +
+Houdini: Fix missing frame range for pointcache and camera exports #5026 + +Fix missing frame range for pointcache and camera exports on published version. + + +___ + +
+ + +
+Global: collect_frame_fix plugin fix and cleanup #5064 + +Previous implementation https://github.com/ynput/OpenPype/pull/5036 was broken this is fixing the issue where attribute is found in instance data although the settings were disabled for the plugin. + + +___ + +
+ + +
+Hiero: Fix apply settings Clip Load #5073 + +Changed `apply_settings` to classmethod which fixes the issue with settings. + + +___ + +
+ + +
+Resolve: Make sure scripts dir exists #5078 + +Make sure the scripts directory exists before looping over it's content. + + +___ + +
+ + +
+removing info knob from nuke creators #5083 + +- removing instance node if removed via publisher +- removing info knob since it is not needed any more (was there only for the transition phase) + + +___ + +
+ + +
+Tray: Fix restart arguments on update #5085 + +Fix arguments on restart. + + +___ + +
+ + +
+Maya: bug fix on repair action in Arnold Scene Source CBID Validator #5096 + +Fix the bug of not being able to use repair action in Arnold Scene Source CBID Validator + + +___ + +
+ + +
+Nuke: batch of small fixes #5103 + +- default settings for `imageio.requiredNodes` **CreateWriteImage** +- default settings for **LoadImage** representations +- **Create** and **Publish** menu items with `parent=main_window` (version > 14) + + +___ + +
+ + +
+Deadline: make prerender check safer #5104 + +Prerender wasn't correctly recognized and was replaced with just 'render' family.In Nuke it is correctly `prerender.farm` in families, which wasn't handled here. It resulted into using `render` in templates even if `render` and `prerender` templates were split. + + +___ + +
+ + +
+General: Sort launcher actions alphabetically #5106 + +The launcher actions weren't being sorted by its label but its name (which on the case of the apps it's the version number) and thus the order wasn't consistent and we kept getting a different order on every launch. From my debugging session, this was the result of what the `actions` variable held after the `filter_compatible_actions` function before these changes: +``` +(Pdb) for p in actions: print(p.order, p.name) +0 14-02 +0 14-02 +0 14-02 +0 14-02 +0 14-02 +0 19-5-493 +0 2023 +0 3-41 +0 6-01 +```This caused already a couple bugs from our artists thinking they had launched Nuke X and instead launched Nuke and telling us their Nuke was missing nodes**Before:****After:** + + +___ + +
+ + +
+TrayPublisher: Editorial video stream discovery #5120 + +Editorial create plugin in traypublisher does not expect that first stream in input is video. + + +___ + +
+ +### **🔀 Refactored code** + + +
+3dsmax: Move from deprecated interface #5117 + +`INewPublisher` interface is deprecated, this PR is changing the use to `IPublishHost` instead. + + +___ + +
+ +### **Merged pull requests** + + +
+add movalex as a contributor for code #5076 + +Adds @movalex as a contributor for code. + +This was requested by mkolar [in this comment](https://github.com/ynput/OpenPype/pull/4916#issuecomment-1571498425) + +[skip ci] +___ + +
+ + +
+3dsmax: refactor load plugins #5079 + + +___ + +
+ + + + +## [3.15.9](https://github.com/ynput/OpenPype/tree/3.15.9) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.8...3.15.9) + +### **🆕 New features** + + +
+Blender: Implemented Loading of Alembic Camera #4990 + +Implemented loading of Alembic cameras in Blender. + + +___ + +
+ + +
+Unreal: Implemented Creator, Loader and Extractor for Levels #5008 + +Creator, Loader and Extractor for Unreal Levels have been implemented. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Blender: Added setting for base unit scale #4987 + +A setting for the base unit scale has been added for Blender.The unit scale is automatically applied when opening a file or creating a new one. + + +___ + +
+ + +
+Unreal: Changed naming and path of Camera Levels #5010 + +The levels created for the camera in Unreal now include `_camera` in the name, to be better identifiable, and are placed in the camera folder. + + +___ + +
+ + +
+Settings: Added option to nest settings templates #5022 + +It is possible to nest settings templates in another templates. + + +___ + +
+ + +
+Enhancement/publisher: Remove "hit play to continue" label on continue #5029 + +Remove "hit play to continue" message on continue so that it doesn't show anymore when play was clicked. + + +___ + +
+ + +
+Ftrack: Limit number of ftrack events to query at once #5033 + +Limit the amount of ftrack events received from mongo at once to 100. + + +___ + +
+ + +
+General: Small code cleanups #5034 + +Small code cleanup and updates. + + +___ + +
+ + +
+Global: collect frames to fix with settings #5036 + +Settings for `Collect Frames to Fix` will allow disable per project the plugin. Also `Rewriting latest version` attribute is hiddable from settings. + + +___ + +
+ + +
+General: Publish plugin apply settings can expect only project settings #5037 + +Only project settings are passed to optional `apply_settings` method, if the method expects only one argument. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Maya: Load Assembly fix invalid imports #4859 + +Refactors imports so they are now correct. + + +___ + +
+ + +
+Maya: Skipping rendersetup for members. #4973 + +When publishing a `rendersetup`, the objectset is and should be empty. + + +___ + +
+ + +
+Maya: Validate Rig Output IDs #5016 + +Absolute names of node were not used, so plugin did not fetch the nodes properly.Also missed pymel command. + + +___ + +
+ + +
+Deadline: escape rootless path in publish job #4910 + +If the publish path on Deadline job contains spaces or other characters, command was failing because the path wasn't properly escaped. This is fixing it. + + +___ + +
+ + +
+General: Company name and URL changed #4974 + +The current records were obsolete in inno_setup, changed to the up-to-date. +___ + +
+ + +
+Unreal: Fix usage of 'get_full_path' function #5014 + +This PR changes all the occurrences of `get_full_path` functions to alternatives to get the path of the objects. + + +___ + +
+ + +
+Unreal: Fix sequence frames validator to use correct data #5021 + +Fix sequence frames validator to use clipIn and clipOut data instead of frameStart and frameEnd. + + +___ + +
+ + +
+Unreal: Fix render instances collection to use correct data #5023 + +Fix render instances collection to use `frameStart` and `frameEnd` from the Project Manager, instead of the sequence's ones. + + +___ + +
+ + +
+Resolve: loader is opening even if no timeline in project #5025 + +Loader is opening now even no timeline is available in a project. + + +___ + +
+ + +
+nuke: callback for dirmapping is on demand #5030 + +Nuke was slowed down on processing due this callback. Since it is disabled by default it made sense to add it only on demand. + + +___ + +
+ + +
+Publisher: UI works with instances without label #5032 + +Publisher UI does not crash if instance don't have filled 'label' key in instance data. + + +___ + +
+ + +
+Publisher: Call explicitly prepared tab methods #5044 + +It is not possible to go to Create tab during publishing from OpenPype menu. + + +___ + +
+ + +
+Ftrack: Role names are not case sensitive in ftrack event server status action #5058 + +Event server status action is not case sensitive for role names of user. + + +___ + +
+ + +
+Publisher: Fix border widget #5063 + +Fixed border lines in Publisher UI to be painted correctly with correct indentation and size. + + +___ + +
+ + +
+Unreal: Fix Commandlet Project and Permissions #5066 + +Fix problem when creating an Unreal Project when Commandlet Project is in a protected location. + + +___ + +
+ + +
+Unreal: Added verification for Unreal app name format #5070 + +The Unreal app name is used to determine the Unreal version folder, so it is necessary that if follows the format `x-x`, where `x` is any integer. This PR adds a verification that the app name follows that format. + + +___ + +
+ +### **📃 Documentation** + + +
+Docs: Display wrong image in ExtractOIIOTranscode #5045 + +Wrong image display in `https://openpype.io/docs/project_settings/settings_project_global#extract-oiio-transcode`. + + +___ + +
+ +### **Merged pull requests** + + +
+Drop-down menu to list all families in create placeholder #4928 + +Currently in the create placeholder window, we need to write the family manually. This replace the text field by an enum field with all families for the current software. + + +___ + +
+ + +
+add sync to specific projects or listen only #4919 + +Extend kitsu sync service with additional arguments to sync specific projects. + + +___ + +
+ + + + +## [3.15.8](https://github.com/ynput/OpenPype/tree/3.15.8) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.15.7...3.15.8) + +### **🆕 New features** + + +
+Publisher: Show instances in report page #4915 + +Show publish instances in report page. Also added basic log view with logs grouped by instance. Validation error detail now have 2 colums, one with erro details second with logs. Crashed state shows fast access to report action buttons. Success will show only logs. Publish frame is shrunked automatically on publish stop. + + +___ + +
+ + +
+Fusion - Loader plugins updates #4920 + +Update to some Fusion loader plugins:The sequence loader can now load footage from the image and online family.The FBX loader can now import all formats Fusions FBX node can read.You can now import the content of another workfile into your current comp with the workfile loader. + + +___ + +
+ + +
+Fusion: deadline farm rendering #4955 + +Enabling Fusion for deadline farm rendering. + + +___ + +
+ + +
+AfterEffects: set frame range and resolution #4983 + +Frame information (frame start, duration, fps) and resolution (width and height) is applied to selected composition from Asset Management System (Ftrack or DB) automatically when published instance is created.It is also possible explicitly propagate both values from DB to selected composition by newly added menu buttons. + + +___ + +
+ + +
+Publish: Enhance automated publish plugin settings #4986 + +Added plugins option to define settings category where to look for settings of a plugin and added public helper functions to apply settings `get_plugin_settings` and `apply_plugin_settings_automatically`. + + +___ + +
+ +### **🚀 Enhancements** + + +
+Load Rig References - Change Rig to Animation in Animation instance #4877 + +We are using the template builder to build an animation scene. All the rig placeholders are imported correctly, but the automatically created animation instances retain the rig family in their names and subsets. In our example, we need animationMain instead of rigMain, because this name will be used in the following steps like lighting.Here is the result we need. I checked, and it's not a template builder problem, because even if I load a rig as a reference, the result is the same. For me, since we are in the animation instance, it makes more sense to have animation instead of rig in the name. The naming is just fine if we use create from the Openpype menu. + + +___ + +
+ + +
+Enhancement: Resolve prelaunch code refactoring and update defaults #4916 + +The main reason of this PR is wrong default settings in `openpype/settings/defaults/system_settings/applications.json` for Resolve host. The `bin` folder should not be a part of the macos and Linux `RESOLVE_PYTHON3_PATH` variable.The rest of this PR is some code cleanups for Resolve prelaunch hook to simplify further development.Also added a .gitignore for vscode workspace files. + + +___ + +
+ + +
+Unreal: 🚚 move Unreal plugin to separate repository #4980 + +To support Epic Marketplace have to move AYON Unreal integration plugins to separate repository. This is replacing current files with git submodule, so the change should be functionally without impact.New repository lives here: https://github.com/ynput/ayon-unreal-plugin + + +___ + +
+ + +
+General: Lib code cleanup #5003 + +Small cleanup in lib files in openpype. + + +___ + +
+ + +
+Allow to open with djv by extension instead of representation name #5004 + +Filter open in djv action by extension instead of representation. + + +___ + +
+ + +
+DJV open action `extensions` as `set` #5005 + +Change `extensions` attribute to `set`. + + +___ + +
+ + +
+Nuke: extract thumbnail with multiple reposition nodes #5011 + +Added support for multiple reposition nodes. + + +___ + +
+ + +
+Enhancement: Improve logging levels and messages for artist facing publish reports #5018 + +Tweak the logging levels and messages to try and only show those logs that an artist should see and could understand. Move anything that's slightly more involved into a "debug" message instead. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Bugfix/frame variable fix #4978 + +Renamed variables to match OpenPype terminology to reduce confusion and add consistency. +___ + +
+ + +
+Global: plugins cleanup plugin will leave beauty rendered files #4790 + +Attempt to mark more files to be cleaned up explicitly in intermediate `renders` folder in work area for farm jobs. + + +___ + +
+ + +
+Fix: Download last workfile doesn't work if not already downloaded #4942 + +Some optimization condition is messing with the feature: if the published workfile is not already downloaded, it won't download it... + + +___ + +
+ + +
+Unreal: Fix transform when loading layout to match existing assets #4972 + +Fixed transform when loading layout to match existing assets. + + +___ + +
+ + +
+fix the bug of fbx loaders in Max #4977 + +bug fix of fbx loaders for not being able to parent to the CON instances while importing cameras(and models) which is published from other DCCs such as Maya. + + +___ + +
+ + +
+AfterEffects: allow returning stub with not saved workfile #4984 + +Allows to use Workfile app to Save first empty workfile. + + +___ + +
+ + +
+Blender: Fix Alembic loading #4985 + +Fixed problem occurring when trying to load an Alembic model in Blender. + + +___ + +
+ + +
+Unreal: Addon Py2 compatibility #4994 + +Fixed Python 2 compatibility of unreal addon. + + +___ + +
+ + +
+Nuke: fixed missing files key in representation #4999 + +Issue with missing keys once rendering target set to existing frames is fixed. Instance has to be evaluated in validation for missing files. + + +___ + +
+ + +
+Unreal: Fix the frame range when loading camera #5002 + +The keyframes of the camera, when loaded, were not using the correct frame range. + + +___ + +
+ + +
+Fusion: fixing frame range targeting #5013 + +Frame range targeting at Rendering instances is now following configured options. + + +___ + +
+ + +
+Deadline: fix selection from multiple webservices #5015 + +Multiple different DL webservice could be configured. First they must by configured in System Settings., then they could be configured per project in `project_settings/deadline/deadline_servers`.Only single webservice could be a target of publish though. + + +___ + +
+ +### **Merged pull requests** + + +
+3dsmax: Refactored publish plugins to use proper implementation of pymxs #4988 + + +___ + +
+ + + + ## [3.15.7](https://github.com/ynput/OpenPype/tree/3.15.7) @@ -525,7 +10462,7 @@ ___
Maya Load References - Add Display Handle Setting #4904 -When we load a reference in Maya using OpenPype loader, display handle is checked by default and prevent us to select easily the object in the viewport. I understand that some productions like to keep this option, so I propose to add display handle to the reference loader settings. +When we load a reference in Maya using OpenPype loader, display handle is checked by default and prevent us to select easily the object in the viewport. I understand that some productions like to keep this option, so I propose to add display handle to the reference loader settings. ___ @@ -633,7 +10570,7 @@ ___
Patchelf version locked #4853 -For Centos dockerfile it is necessary to lock the patchelf version to the older, otherwise the build process fails. +For Centos dockerfile it is necessary to lock the patchelf version to the older, otherwise the build process fails. ___ diff --git a/Dockerfile.centos7 b/Dockerfile.centos7 index ce1a624a4f..ab1d3f8253 100644 --- a/Dockerfile.centos7 +++ b/Dockerfile.centos7 @@ -32,12 +32,16 @@ RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.n wget \ gcc \ zlib-devel \ + pcre-devel \ + perl-core \ bzip2 \ bzip2-devel \ readline-devel \ sqlite sqlite-devel \ openssl-devel \ openssl-libs \ + openssl11-devel \ + openssl11-libs \ tk-devel libffi-devel \ patchelf \ automake \ @@ -71,7 +75,12 @@ RUN echo 'export PATH="$HOME/.pyenv/bin:$PATH"'>> $HOME/.bashrc \ && echo 'eval "$(pyenv init -)"' >> $HOME/.bashrc \ && echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc \ && echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc -RUN source $HOME/.bashrc && pyenv install ${OPENPYPE_PYTHON_VERSION} +RUN source $HOME/.bashrc \ + && export CPPFLAGS="-I/usr/include/openssl11" \ + && export LDFLAGS="-L/usr/lib64/openssl11 -lssl -lcrypto" \ + && export PATH=/usr/local/openssl/bin:$PATH \ + && export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH \ + && pyenv install ${OPENPYPE_PYTHON_VERSION} COPY . /opt/openpype/ RUN rm -rf /openpype/.poetry || echo "No Poetry installed yet." @@ -93,12 +102,15 @@ RUN source $HOME/.bashrc \ RUN source $HOME/.bashrc \ && ./tools/fetch_thirdparty_libs.sh +RUN echo 'export PYTHONPATH="/opt/openpype/vendor/python:$PYTHONPATH"'>> $HOME/.bashrc RUN source $HOME/.bashrc \ && bash ./tools/build.sh RUN cp /usr/lib64/libffi* ./build/exe.linux-x86_64-3.9/lib \ - && cp /usr/lib64/libssl* ./build/exe.linux-x86_64-3.9/lib \ - && cp /usr/lib64/libcrypto* ./build/exe.linux-x86_64-3.9/lib \ + && cp /usr/lib64/openssl11/libssl* ./build/exe.linux-x86_64-3.9/lib \ + && cp /usr/lib64/openssl11/libcrypto* ./build/exe.linux-x86_64-3.9/lib \ + && ln -sr ./build/exe.linux-x86_64-3.9/lib/libssl.so ./build/exe.linux-x86_64-3.9/lib/libssl.1.1.so \ + && ln -sr ./build/exe.linux-x86_64-3.9/lib/libcrypto.so ./build/exe.linux-x86_64-3.9/lib/libcrypto.1.1.so \ && cp /root/.pyenv/versions/${OPENPYPE_PYTHON_VERSION}/lib/libpython* ./build/exe.linux-x86_64-3.9/lib \ && cp /usr/lib64/libxcb* ./build/exe.linux-x86_64-3.9/vendor/python/PySide2/Qt/lib diff --git a/README.md b/README.md index 514ffb62c0..a79b9f2582 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ -[![All Contributors](https://img.shields.io/badge/all_contributors-27-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square)](#contributors-) OpenPype -==== +======== [![documentation](https://github.com/pypeclub/pype/actions/workflows/documentation.yml/badge.svg)](https://github.com/pypeclub/pype/actions/workflows/documentation.yml) ![GitHub VFX Platform](https://img.shields.io/badge/vfx%20platform-2022-lightgrey?labelColor=303846) +## Important Notice! + +OpenPype as a standalone product has reach end of it's life and this repository is now used as a pipeline core code for [AYON](https://ynput.io/ayon/). You can read more details about the end of life process here https://community.ynput.io/t/openpype-end-of-life-timeline/877 + Introduction ------------ @@ -47,7 +51,7 @@ It can be built and ran on all common platforms. We develop and test on the foll For more details on requirements visit [requirements documentation](https://openpype.io/docs/dev_requirements) Building OpenPype -------------- +----------------- To build OpenPype you currently need [Python 3.9](https://www.python.org/downloads/) as we are following [vfx platform](https://vfxplatform.com). Because of some Linux distros comes with newer Python version @@ -62,14 +66,14 @@ development tools like [CMake](https://cmake.org/) and [Visual Studio](https://v #### Clone repository: ```sh -git clone --recurse-submodules git@github.com:Pypeclub/OpenPype.git +git clone --recurse-submodules git@github.com:ynput/OpenPype.git ``` #### To build OpenPype: -1) Run `.\tools\create_env.ps1` to create virtual environment in `.\venv` +1) Run `.\tools\create_env.ps1` to create virtual environment in `.\venv`. 2) Run `.\tools\fetch_thirdparty_libs.ps1` to download third-party dependencies like ffmpeg and oiio. Those will be included in build. -3) Run `.\tools\build.ps1` to build OpenPype executables in `.\build\` +3) Run `.\tools\build.ps1` to build OpenPype executables in `.\build\`. To create distributable OpenPype versions, run `./tools/create_zip.ps1` - that will create zip file with name `openpype-vx.x.x.zip` parsed from current OpenPype repository and @@ -88,38 +92,38 @@ some OpenPype dependencies like [CMake](https://cmake.org/) and **XCode Command Easy way of installing everything necessary is to use [Homebrew](https://brew.sh): 1) Install **Homebrew**: -```sh -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -``` + ```sh + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + ``` 2) Install **cmake**: -```sh -brew install cmake -``` + ```sh + brew install cmake + ``` 3) Install [pyenv](https://github.com/pyenv/pyenv): -```sh -brew install pyenv -echo 'eval "$(pyenv init -)"' >> ~/.zshrc -pyenv init -exec "$SHELL" -PATH=$(pyenv root)/shims:$PATH -``` + ```sh + brew install pyenv + echo 'eval "$(pyenv init -)"' >> ~/.zshrc + pyenv init + exec "$SHELL" + PATH=$(pyenv root)/shims:$PATH + ``` -4) Pull in required Python version 3.9.x -```sh -# install Python build dependences -brew install openssl readline sqlite3 xz zlib +4) Pull in required Python version 3.9.x: + ```sh + # install Python build dependences + brew install openssl readline sqlite3 xz zlib -# replace with up-to-date 3.9.x version -pyenv install 3.9.6 -``` + # replace with up-to-date 3.9.x version + pyenv install 3.9.6 + ``` -5) Set local Python version -```sh -# switch to OpenPype source directory -pyenv local 3.9.6 -``` +5) Set local Python version: + ```sh + # switch to OpenPype source directory + pyenv local 3.9.6 + ``` #### To build OpenPype: @@ -144,6 +148,10 @@ sudo ./tools/docker_build.sh centos7 If all is successful, you'll find built OpenPype in `./build/` folder. +Docker build can be also started from Windows machine, just use `./tools/docker_build.ps1` instead of shell script. + +This could be used even for building linux build (with argument `centos7` or `debian`) + #### Manual build You will need [Python >= 3.9](https://www.python.org/downloads/) and [git](https://git-scm.com/downloads). You'll also need [curl](https://curl.se) on systems that doesn't have one preinstalled. @@ -241,7 +249,7 @@ pyenv local 3.9.6 Running OpenPype ------------- +---------------- OpenPype can by executed either from live sources (this repository) or from *"frozen code"* - executables that can be build using steps described above. @@ -275,7 +283,7 @@ arguments and it will create zip file that OpenPype can use. Building documentation ---------------------- -Top build API documentation, run `.\tools\make_docs(.ps1|.sh)`. It will create html documentation +To build API documentation, run `.\tools\make_docs(.ps1|.sh)`. It will create html documentation from current sources in `.\docs\build`. **Note that it needs existing virtual environment.** @@ -289,7 +297,7 @@ To run tests, execute `.\tools\run_tests(.ps1|.sh)`. Developer tools -------------- +--------------- In case you wish to add your own tools to `.\tools` folder without git tracking, it is possible by adding it with `dev_*` suffix (example: `dev_clear_pyc(.ps1|.sh)`). @@ -303,41 +311,44 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Milan Kolar

💻 📖 🚇 💼 🖋 🔍 🚧 📆 👀 🧑‍🏫 💬

Jakub Ježek

💻 📖 🚇 🖋 👀 🚧 🧑‍🏫 📆 💬

Ondřej Samohel

💻 📖 🚇 🖋 👀 🚧 🧑‍🏫 📆 💬

Jakub Trllo

💻 📖 🚇 👀 🚧 💬

Petr Kalis

💻 📖 🚇 👀 🚧 💬

64qam

💻 👀 📖 🚇 📆 🚧 🖋 📓

Roy Nieterau

💻 📖 👀 🧑‍🏫 💬

Toke Jepsen

💻 📖 👀 🧑‍🏫 💬

Jiri Sindelar

💻 👀 📖 🖋 📓

Simone Barbieri

💻 📖

karimmozilla

💻

Allan I. A.

💻

murphy

💻 👀 📓 📖 📆

Wijnand Koreman

💻

Bo Zhou

💻

Clément Hector

💻 👀

David Lai

💻 👀

Derek

💻 📖

Gábor Marinov

💻 📖

icyvapor

💻 📖

Jérôme LORRAIN

💻

David Morris-Oliveros

💻

BenoitConnan

💻

Malthaldar

💻

Sven Neve

💻

zafrs

💻

Félix David

💻 📖
Milan Kolar
Milan Kolar

💻 📖 🚇 💼 🖋 🔍 🚧 📆 👀 🧑‍🏫 💬
Jakub Ježek
Jakub Ježek

💻 📖 🚇 🖋 👀 🚧 🧑‍🏫 📆 💬
Ondřej Samohel
Ondřej Samohel

💻 📖 🚇 🖋 👀 🚧 🧑‍🏫 📆 💬
Jakub Trllo
Jakub Trllo

💻 📖 🚇 👀 🚧 💬
Petr Kalis
Petr Kalis

💻 📖 🚇 👀 🚧 💬
64qam
64qam

💻 👀 📖 🚇 📆 🚧 🖋 📓
Roy Nieterau
Roy Nieterau

💻 📖 👀 🧑‍🏫 💬
Toke Jepsen
Toke Jepsen

💻 📖 👀 🧑‍🏫 💬
Jiri Sindelar
Jiri Sindelar

💻 👀 📖 🖋 📓
Simone Barbieri
Simone Barbieri

💻 📖
karimmozilla
karimmozilla

💻
Allan I. A.
Allan I. A.

💻
murphy
murphy

💻 👀 📓 📖 📆
Wijnand Koreman
Wijnand Koreman

💻
Bo Zhou
Bo Zhou

💻
Clément Hector
Clément Hector

💻 👀
David Lai
David Lai

💻 👀
Derek
Derek

💻 📖
Gábor Marinov
Gábor Marinov

💻 📖
icyvapor
icyvapor

💻 📖
Jérôme LORRAIN
Jérôme LORRAIN

💻
David Morris-Oliveros
David Morris-Oliveros

💻
BenoitConnan
BenoitConnan

💻
Malthaldar
Malthaldar

💻
Sven Neve
Sven Neve

💻
zafrs
zafrs

💻
Félix David
Félix David

💻 📖
Alexey Bogomolov
Alexey Bogomolov

💻
diff --git a/common/openpype_common/distribution/README.md b/common/openpype_common/distribution/README.md deleted file mode 100644 index 212eb267b8..0000000000 --- a/common/openpype_common/distribution/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Addon distribution tool ------------------------- - -Code in this folder is backend portion of Addon distribution logic for v4 server. - -Each host, module will be separate Addon in the future. Each v4 server could run different set of Addons. - -Client (running on artist machine) will in the first step ask v4 for list of enabled addons. -(It expects list of json documents matching to `addon_distribution.py:AddonInfo` object.) -Next it will compare presence of enabled addon version in local folder. In the case of missing version of -an addon, client will use information in the addon to download (from http/shared local disk/git) zip file -and unzip it. - -Required part of addon distribution will be sharing of dependencies (python libraries, utilities) which is not part of this folder. - -Location of this folder might change in the future as it will be required for a clint to add this folder to sys.path reliably. - -This code needs to be independent on Openpype code as much as possible! \ No newline at end of file diff --git a/common/openpype_common/distribution/addon_distribution.py b/common/openpype_common/distribution/addon_distribution.py deleted file mode 100644 index 5e48639dec..0000000000 --- a/common/openpype_common/distribution/addon_distribution.py +++ /dev/null @@ -1,208 +0,0 @@ -import os -from enum import Enum -from abc import abstractmethod -import attr -import logging -import requests -import platform -import shutil - -from .file_handler import RemoteFileHandler -from .addon_info import AddonInfo - - -class UpdateState(Enum): - EXISTS = "exists" - UPDATED = "updated" - FAILED = "failed" - - -class AddonDownloader: - log = logging.getLogger(__name__) - - def __init__(self): - self._downloaders = {} - - def register_format(self, downloader_type, downloader): - self._downloaders[downloader_type.value] = downloader - - def get_downloader(self, downloader_type): - downloader = self._downloaders.get(downloader_type) - if not downloader: - raise ValueError(f"{downloader_type} not implemented") - return downloader() - - @classmethod - @abstractmethod - def download(cls, source, destination): - """Returns url to downloaded addon zip file. - - Args: - source (dict): {type:"http", "url":"https://} ...} - destination (str): local folder to unzip - Returns: - (str) local path to addon zip file - """ - pass - - @classmethod - def check_hash(cls, addon_path, addon_hash): - """Compares 'hash' of downloaded 'addon_url' file. - - Args: - addon_path (str): local path to addon zip file - addon_hash (str): sha256 hash of zip file - Raises: - ValueError if hashes doesn't match - """ - if not os.path.exists(addon_path): - raise ValueError(f"{addon_path} doesn't exist.") - if not RemoteFileHandler.check_integrity(addon_path, - addon_hash, - hash_type="sha256"): - raise ValueError(f"{addon_path} doesn't match expected hash.") - - @classmethod - def unzip(cls, addon_zip_path, destination): - """Unzips local 'addon_zip_path' to 'destination'. - - Args: - addon_zip_path (str): local path to addon zip file - destination (str): local folder to unzip - """ - RemoteFileHandler.unzip(addon_zip_path, destination) - os.remove(addon_zip_path) - - @classmethod - def remove(cls, addon_url): - pass - - -class OSAddonDownloader(AddonDownloader): - - @classmethod - def download(cls, source, destination): - # OS doesnt need to download, unzip directly - addon_url = source["path"].get(platform.system().lower()) - if not os.path.exists(addon_url): - raise ValueError("{} is not accessible".format(addon_url)) - return addon_url - - -class HTTPAddonDownloader(AddonDownloader): - CHUNK_SIZE = 100000 - - @classmethod - def download(cls, source, destination): - source_url = source["url"] - cls.log.debug(f"Downloading {source_url} to {destination}") - file_name = os.path.basename(destination) - _, ext = os.path.splitext(file_name) - if (ext.replace(".", '') not - in set(RemoteFileHandler.IMPLEMENTED_ZIP_FORMATS)): - file_name += ".zip" - RemoteFileHandler.download_url(source_url, - destination, - filename=file_name) - - return os.path.join(destination, file_name) - - -def get_addons_info(server_endpoint): - """Returns list of addon information from Server""" - # TODO temp - # addon_info = AddonInfo( - # **{"name": "openpype_slack", - # "version": "1.0.0", - # "addon_url": "c:/projects/openpype_slack_1.0.0.zip", - # "type": UrlType.FILESYSTEM, - # "hash": "4be25eb6215e91e5894d3c5475aeb1e379d081d3f5b43b4ee15b0891cf5f5658"}) # noqa - # - # http_addon = AddonInfo( - # **{"name": "openpype_slack", - # "version": "1.0.0", - # "addon_url": "https://drive.google.com/file/d/1TcuV8c2OV8CcbPeWi7lxOdqWsEqQNPYy/view?usp=sharing", # noqa - # "type": UrlType.HTTP, - # "hash": "4be25eb6215e91e5894d3c5475aeb1e379d081d3f5b43b4ee15b0891cf5f5658"}) # noqa - - response = requests.get(server_endpoint) - if not response.ok: - raise Exception(response.text) - - addons_info = [] - for addon in response.json(): - addons_info.append(AddonInfo(**addon)) - return addons_info - - -def update_addon_state(addon_infos, destination_folder, factory, - log=None): - """Loops through all 'addon_infos', compares local version, unzips. - - Loops through server provided list of dictionaries with information about - available addons. Looks if each addon is already present and deployed. - If isn't, addon zip gets downloaded and unzipped into 'destination_folder'. - Args: - addon_infos (list of AddonInfo) - destination_folder (str): local path - factory (AddonDownloader): factory to get appropriate downloader per - addon type - log (logging.Logger) - Returns: - (dict): {"addon_full_name": UpdateState.value - (eg. "exists"|"updated"|"failed") - """ - if not log: - log = logging.getLogger(__name__) - - download_states = {} - for addon in addon_infos: - full_name = "{}_{}".format(addon.name, addon.version) - addon_dest = os.path.join(destination_folder, full_name) - - if os.path.isdir(addon_dest): - log.debug(f"Addon version folder {addon_dest} already exists.") - download_states[full_name] = UpdateState.EXISTS.value - continue - - for source in addon.sources: - download_states[full_name] = UpdateState.FAILED.value - try: - downloader = factory.get_downloader(source.type) - zip_file_path = downloader.download(attr.asdict(source), - addon_dest) - downloader.check_hash(zip_file_path, addon.hash) - downloader.unzip(zip_file_path, addon_dest) - download_states[full_name] = UpdateState.UPDATED.value - break - except Exception: - log.warning(f"Error happened during updating {addon.name}", - exc_info=True) - if os.path.isdir(addon_dest): - log.debug(f"Cleaning {addon_dest}") - shutil.rmtree(addon_dest) - - return download_states - - -def check_addons(server_endpoint, addon_folder, downloaders): - """Main entry point to compare existing addons with those on server. - - Args: - server_endpoint (str): url to v4 server endpoint - addon_folder (str): local dir path for addons - downloaders (AddonDownloader): factory of downloaders - - Raises: - (RuntimeError) if any addon failed update - """ - addons_info = get_addons_info(server_endpoint) - result = update_addon_state(addons_info, - addon_folder, - downloaders) - if UpdateState.FAILED.value in result.values(): - raise RuntimeError(f"Unable to update some addons {result}") - - -def cli(*args): - raise NotImplementedError diff --git a/common/openpype_common/distribution/addon_info.py b/common/openpype_common/distribution/addon_info.py deleted file mode 100644 index 00ece11f3b..0000000000 --- a/common/openpype_common/distribution/addon_info.py +++ /dev/null @@ -1,80 +0,0 @@ -import attr -from enum import Enum - - -class UrlType(Enum): - HTTP = "http" - GIT = "git" - FILESYSTEM = "filesystem" - - -@attr.s -class MultiPlatformPath(object): - windows = attr.ib(default=None) - linux = attr.ib(default=None) - darwin = attr.ib(default=None) - - -@attr.s -class AddonSource(object): - type = attr.ib() - - -@attr.s -class LocalAddonSource(AddonSource): - path = attr.ib(default=attr.Factory(MultiPlatformPath)) - - -@attr.s -class WebAddonSource(AddonSource): - url = attr.ib(default=None) - - -@attr.s -class VersionData(object): - version_data = attr.ib(default=None) - - -@attr.s -class AddonInfo(object): - """Object matching json payload from Server""" - name = attr.ib() - version = attr.ib() - title = attr.ib(default=None) - sources = attr.ib(default=attr.Factory(dict)) - hash = attr.ib(default=None) - description = attr.ib(default=None) - license = attr.ib(default=None) - authors = attr.ib(default=None) - - @classmethod - def from_dict(cls, data): - sources = [] - - production_version = data.get("productionVersion") - if not production_version: - return - - # server payload contains info about all versions - # active addon must have 'productionVersion' and matching version info - version_data = data.get("versions", {})[production_version] - - for source in version_data.get("clientSourceInfo", []): - if source.get("type") == UrlType.FILESYSTEM.value: - source_addon = LocalAddonSource(type=source["type"], - path=source["path"]) - if source.get("type") == UrlType.HTTP.value: - source_addon = WebAddonSource(type=source["type"], - url=source["url"]) - - sources.append(source_addon) - - return cls(name=data.get("name"), - version=production_version, - sources=sources, - hash=data.get("hash"), - description=data.get("description"), - title=data.get("title"), - license=data.get("license"), - authors=data.get("authors")) - diff --git a/common/openpype_common/distribution/tests/test_addon_distributtion.py b/common/openpype_common/distribution/tests/test_addon_distributtion.py deleted file mode 100644 index 765ea0596a..0000000000 --- a/common/openpype_common/distribution/tests/test_addon_distributtion.py +++ /dev/null @@ -1,167 +0,0 @@ -import pytest -import attr -import tempfile - -from common.openpype_common.distribution.addon_distribution import ( - AddonDownloader, - OSAddonDownloader, - HTTPAddonDownloader, - AddonInfo, - update_addon_state, - UpdateState -) -from common.openpype_common.distribution.addon_info import UrlType - - -@pytest.fixture -def addon_downloader(): - addon_downloader = AddonDownloader() - addon_downloader.register_format(UrlType.FILESYSTEM, OSAddonDownloader) - addon_downloader.register_format(UrlType.HTTP, HTTPAddonDownloader) - - yield addon_downloader - - -@pytest.fixture -def http_downloader(addon_downloader): - yield addon_downloader.get_downloader(UrlType.HTTP.value) - - -@pytest.fixture -def temp_folder(): - yield tempfile.mkdtemp() - - -@pytest.fixture -def sample_addon_info(): - addon_info = { - "versions": { - "1.0.0": { - "clientPyproject": { - "tool": { - "poetry": { - "dependencies": { - "nxtools": "^1.6", - "orjson": "^3.6.7", - "typer": "^0.4.1", - "email-validator": "^1.1.3", - "python": "^3.10", - "fastapi": "^0.73.0" - } - } - } - }, - "hasSettings": True, - "clientSourceInfo": [ - { - "type": "http", - "url": "https://drive.google.com/file/d/1TcuV8c2OV8CcbPeWi7lxOdqWsEqQNPYy/view?usp=sharing" # noqa - }, - { - "type": "filesystem", - "path": { - "windows": ["P:/sources/some_file.zip", - "W:/sources/some_file.zip"], # noqa - "linux": ["/mnt/srv/sources/some_file.zip"], - "darwin": ["/Volumes/srv/sources/some_file.zip"] - } - } - ], - "frontendScopes": { - "project": { - "sidebar": "hierarchy" - } - } - } - }, - "description": "", - "title": "Slack addon", - "name": "openpype_slack", - "productionVersion": "1.0.0", - "hash": "4be25eb6215e91e5894d3c5475aeb1e379d081d3f5b43b4ee15b0891cf5f5658" # noqa - } - yield addon_info - - -def test_register(printer): - addon_downloader = AddonDownloader() - - assert len(addon_downloader._downloaders) == 0, "Contains registered" - - addon_downloader.register_format(UrlType.FILESYSTEM, OSAddonDownloader) - assert len(addon_downloader._downloaders) == 1, "Should contain one" - - -def test_get_downloader(printer, addon_downloader): - assert addon_downloader.get_downloader(UrlType.FILESYSTEM.value), "Should find" # noqa - - with pytest.raises(ValueError): - addon_downloader.get_downloader("unknown"), "Shouldn't find" - - -def test_addon_info(printer, sample_addon_info): - """Tests parsing of expected payload from v4 server into AadonInfo.""" - valid_minimum = { - "name": "openpype_slack", - "productionVersion": "1.0.0", - "versions": { - "1.0.0": { - "clientSourceInfo": [ - { - "type": "filesystem", - "path": { - "windows": [ - "P:/sources/some_file.zip", - "W:/sources/some_file.zip"], - "linux": [ - "/mnt/srv/sources/some_file.zip"], - "darwin": [ - "/Volumes/srv/sources/some_file.zip"] # noqa - } - } - ] - } - } - } - - assert AddonInfo.from_dict(valid_minimum), "Missing required fields" - - valid_minimum["versions"].pop("1.0.0") - with pytest.raises(KeyError): - assert not AddonInfo.from_dict(valid_minimum), "Must fail without version data" # noqa - - valid_minimum.pop("productionVersion") - assert not AddonInfo.from_dict( - valid_minimum), "none if not productionVersion" # noqa - - addon = AddonInfo.from_dict(sample_addon_info) - assert addon, "Should be created" - assert addon.name == "openpype_slack", "Incorrect name" - assert addon.version == "1.0.0", "Incorrect version" - - with pytest.raises(TypeError): - assert addon["name"], "Dict approach not implemented" - - addon_as_dict = attr.asdict(addon) - assert addon_as_dict["name"], "Dict approach should work" - - -def test_update_addon_state(printer, sample_addon_info, - temp_folder, addon_downloader): - """Tests possible cases of addon update.""" - addon_info = AddonInfo.from_dict(sample_addon_info) - orig_hash = addon_info.hash - - addon_info.hash = "brokenhash" - result = update_addon_state([addon_info], temp_folder, addon_downloader) - assert result["openpype_slack_1.0.0"] == UpdateState.FAILED.value, \ - "Update should failed because of wrong hash" - - addon_info.hash = orig_hash - result = update_addon_state([addon_info], temp_folder, addon_downloader) - assert result["openpype_slack_1.0.0"] == UpdateState.UPDATED.value, \ - "Addon should have been updated" - - result = update_addon_state([addon_info], temp_folder, addon_downloader) - assert result["openpype_slack_1.0.0"] == UpdateState.EXISTS.value, \ - "Addon should already exist" diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..102da990aa --- /dev/null +++ b/docs/README.md @@ -0,0 +1,74 @@ +API Documentation +================= + +This documents the way how to build and modify API documentation using Sphinx and AutoAPI. Ground for documentation +should be directly in sources - in docstrings and markdowns. Sphinx and AutoAPI will crawl over them and generate +RST files that are in turn used to generate HTML documentation. For docstrings we prefer "Napoleon" or "Google" style +docstrings, but RST is also acceptable mainly in cases where you need to use Sphinx directives. + +Using only docstrings is not really viable as some documentation should be done on higher level - like overview of +some modules/functionality and so on. This should be done directly in RST files and committed to repository. + +Configuration +------------- +Configuration is done in `/docs/source/conf.py`. The most important settings are: + +- `autodoc_mock_imports`: add modules that can't be actually imported by Sphinx in running environment, like `nuke`, `maya`, etc. +- `autoapi_ignore`: add directories that shouldn't be processed by **AutoAPI**, like vendor dirs, etc. +- `html_theme_options`: you can use these options to influence how the html theme of the generated files will look. +- `myst_gfm_only`: are Myst parser option for Markdown setting what flavour of Markdown should be used. + +How to build it +--------------- + +You can run: + +```sh +cd .\docs +make.bat html +``` + +on linux/macOS: + +```sh +cd ./docs +make html +``` + +This will go over our code and generate **.rst** files in `/docs/source/autoapi` and from those it will generate +full html documentation in `/docs/build/html`. + +During the build you may see tons of red errors that are pointing to our issues: + +1) **Wrong imports** - +Invalid import are usually wrong relative imports (too deep) or circular imports. +2) **Invalid docstrings** - +Docstrings to be processed into documentation needs to follow some syntax - this can be checked by running +`pydocstyle` that is already included with OpenPype +3) **Invalid markdown/rst files** - +Markdown/RST files can be included inside RST files using `.. include::` directive. But they have to be properly +formatted. + +Editing RST templates +--------------------- +Everything starts with `/docs/source/index.rst` - this file should be properly edited, Right now it just +includes `readme.rst` that in turn include and parse main `README.md`. This is entrypoint to API documentation. +All templates generated by AutoAPI are in `/docs/source/autoapi`. They should be eventually committed to repository +and edited too. + +Steps for enhancing API documentation +------------------------------------- + +1) Run `/docs/make.bat html` +2) Read the red errors/warnings - fix it in the code +3) Run `/docs/make.bat html` - again until there are no red lines +4) Edit RST files and add some meaningful content there + +Resources +========= + +- [ReStructuredText on Wikipedia](https://en.wikipedia.org/wiki/ReStructuredText) +- [RST Quick Reference](https://docutils.sourceforge.io/docs/user/rst/quickref.html) +- [Sphinx AutoAPI Documentation](https://sphinx-autoapi.readthedocs.io/en/latest/) +- [Example of Google Style Python Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) +- [Sphinx Directives](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html) diff --git a/docs/make.bat b/docs/make.bat index 4d9eb83d9f..1d261df277 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -5,7 +5,7 @@ pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build + set SPHINXBUILD=..\.poetry\bin\poetry run sphinx-build ) set SOURCEDIR=source set BUILDDIR=build diff --git a/docs/source/_static/AYON_tight_G.svg b/docs/source/_static/AYON_tight_G.svg new file mode 100644 index 0000000000..2c5b73deea --- /dev/null +++ b/docs/source/_static/AYON_tight_G.svg @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/common/openpype_common/distribution/__init__.py b/docs/source/_static/README.md similarity index 100% rename from common/openpype_common/distribution/__init__.py rename to docs/source/_static/README.md diff --git a/docs/source/_templates/autoapi/index.rst b/docs/source/_templates/autoapi/index.rst new file mode 100644 index 0000000000..95d0ad8911 --- /dev/null +++ b/docs/source/_templates/autoapi/index.rst @@ -0,0 +1,15 @@ +API Reference +============= + +This page contains auto-generated API reference documentation [#f1]_. + +.. toctree:: + :titlesonly: + + {% for page in pages %} + {% if page.top_level_object and page.display %} + {{ page.include_path }} + {% endif %} + {% endfor %} + +.. [#f1] Created with `sphinx-autoapi `_ diff --git a/docs/source/_templates/autoapi/python/attribute.rst b/docs/source/_templates/autoapi/python/attribute.rst new file mode 100644 index 0000000000..ebaba555ad --- /dev/null +++ b/docs/source/_templates/autoapi/python/attribute.rst @@ -0,0 +1 @@ +{% extends "python/data.rst" %} diff --git a/docs/source/_templates/autoapi/python/class.rst b/docs/source/_templates/autoapi/python/class.rst new file mode 100644 index 0000000000..df5edffb62 --- /dev/null +++ b/docs/source/_templates/autoapi/python/class.rst @@ -0,0 +1,58 @@ +{% if obj.display %} +.. py:{{ obj.type }}:: {{ obj.short_name }}{% if obj.args %}({{ obj.args }}){% endif %} +{% for (args, return_annotation) in obj.overloads %} + {{ " " * (obj.type | length) }} {{ obj.short_name }}{% if args %}({{ args }}){% endif %} +{% endfor %} + + + {% if obj.bases %} + {% if "show-inheritance" in autoapi_options %} + Bases: {% for base in obj.bases %}{{ base|link_objs }}{% if not loop.last %}, {% endif %}{% endfor %} + {% endif %} + + + {% if "show-inheritance-diagram" in autoapi_options and obj.bases != ["object"] %} + .. autoapi-inheritance-diagram:: {{ obj.obj["full_name"] }} + :parts: 1 + {% if "private-members" in autoapi_options %} + :private-bases: + {% endif %} + + {% endif %} + {% endif %} + {% if obj.docstring %} + {{ obj.docstring|indent(3) }} + {% endif %} + {% if "inherited-members" in autoapi_options %} + {% set visible_classes = obj.classes|selectattr("display")|list %} + {% else %} + {% set visible_classes = obj.classes|rejectattr("inherited")|selectattr("display")|list %} + {% endif %} + {% for klass in visible_classes %} + {{ klass.render()|indent(3) }} + {% endfor %} + {% if "inherited-members" in autoapi_options %} + {% set visible_properties = obj.properties|selectattr("display")|list %} + {% else %} + {% set visible_properties = obj.properties|rejectattr("inherited")|selectattr("display")|list %} + {% endif %} + {% for property in visible_properties %} + {{ property.render()|indent(3) }} + {% endfor %} + {% if "inherited-members" in autoapi_options %} + {% set visible_attributes = obj.attributes|selectattr("display")|list %} + {% else %} + {% set visible_attributes = obj.attributes|rejectattr("inherited")|selectattr("display")|list %} + {% endif %} + {% for attribute in visible_attributes %} + {{ attribute.render()|indent(3) }} + {% endfor %} + {% if "inherited-members" in autoapi_options %} + {% set visible_methods = obj.methods|selectattr("display")|list %} + {% else %} + {% set visible_methods = obj.methods|rejectattr("inherited")|selectattr("display")|list %} + {% endif %} + {% for method in visible_methods %} + {{ method.render()|indent(3) }} + {% endfor %} +{% endif %} diff --git a/docs/source/_templates/autoapi/python/data.rst b/docs/source/_templates/autoapi/python/data.rst new file mode 100644 index 0000000000..3d12b2d0c7 --- /dev/null +++ b/docs/source/_templates/autoapi/python/data.rst @@ -0,0 +1,37 @@ +{% if obj.display %} +.. py:{{ obj.type }}:: {{ obj.name }} + {%- if obj.annotation is not none %} + + :type: {%- if obj.annotation %} {{ obj.annotation }}{%- endif %} + + {%- endif %} + + {%- if obj.value is not none %} + + :value: {% if obj.value is string and obj.value.splitlines()|count > 1 -%} + Multiline-String + + .. raw:: html + +
Show Value + + .. code-block:: python + + """{{ obj.value|indent(width=8,blank=true) }}""" + + .. raw:: html + +
+ + {%- else -%} + {%- if obj.value is string -%} + {{ "%r" % obj.value|string|truncate(100) }} + {%- else -%} + {{ obj.value|string|truncate(100) }} + {%- endif -%} + {%- endif %} + {%- endif %} + + + {{ obj.docstring|indent(3) }} +{% endif %} diff --git a/docs/source/_templates/autoapi/python/exception.rst b/docs/source/_templates/autoapi/python/exception.rst new file mode 100644 index 0000000000..92f3d38fd5 --- /dev/null +++ b/docs/source/_templates/autoapi/python/exception.rst @@ -0,0 +1 @@ +{% extends "python/class.rst" %} diff --git a/docs/source/_templates/autoapi/python/function.rst b/docs/source/_templates/autoapi/python/function.rst new file mode 100644 index 0000000000..b00d5c2445 --- /dev/null +++ b/docs/source/_templates/autoapi/python/function.rst @@ -0,0 +1,15 @@ +{% if obj.display %} +.. py:function:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %} + +{% for (args, return_annotation) in obj.overloads %} + {{ obj.short_name }}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %} + +{% endfor %} + {% for property in obj.properties %} + :{{ property }}: + {% endfor %} + + {% if obj.docstring %} + {{ obj.docstring|indent(3) }} + {% endif %} +{% endif %} diff --git a/docs/source/_templates/autoapi/python/method.rst b/docs/source/_templates/autoapi/python/method.rst new file mode 100644 index 0000000000..723cb7bbe5 --- /dev/null +++ b/docs/source/_templates/autoapi/python/method.rst @@ -0,0 +1,19 @@ +{%- if obj.display %} +.. py:method:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %} + +{% for (args, return_annotation) in obj.overloads %} + {{ obj.short_name }}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %} + +{% endfor %} + {% if obj.properties %} + {% for property in obj.properties %} + :{{ property }}: + {% endfor %} + + {% else %} + + {% endif %} + {% if obj.docstring %} + {{ obj.docstring|indent(3) }} + {% endif %} +{% endif %} diff --git a/docs/source/_templates/autoapi/python/module.rst b/docs/source/_templates/autoapi/python/module.rst new file mode 100644 index 0000000000..d2714f6c9d --- /dev/null +++ b/docs/source/_templates/autoapi/python/module.rst @@ -0,0 +1,114 @@ +{% if not obj.display %} +:orphan: + +{% endif %} +:py:mod:`{{ obj.name }}` +=========={{ "=" * obj.name|length }} + +.. py:module:: {{ obj.name }} + +{% if obj.docstring %} +.. autoapi-nested-parse:: + + {{ obj.docstring|indent(3) }} + +{% endif %} + +{% block subpackages %} +{% set visible_subpackages = obj.subpackages|selectattr("display")|list %} +{% if visible_subpackages %} +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + +{% for subpackage in visible_subpackages %} + {{ subpackage.short_name }}/index.rst +{% endfor %} + + +{% endif %} +{% endblock %} +{% block submodules %} +{% set visible_submodules = obj.submodules|selectattr("display")|list %} +{% if visible_submodules %} +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + +{% for submodule in visible_submodules %} + {{ submodule.short_name }}/index.rst +{% endfor %} + + +{% endif %} +{% endblock %} +{% block content %} +{% if obj.all is not none %} +{% set visible_children = obj.children|selectattr("short_name", "in", obj.all)|list %} +{% elif obj.type is equalto("package") %} +{% set visible_children = obj.children|selectattr("display")|list %} +{% else %} +{% set visible_children = obj.children|selectattr("display")|rejectattr("imported")|list %} +{% endif %} +{% if visible_children %} +{{ obj.type|title }} Contents +{{ "-" * obj.type|length }}--------- + +{% set visible_classes = visible_children|selectattr("type", "equalto", "class")|list %} +{% set visible_functions = visible_children|selectattr("type", "equalto", "function")|list %} +{% set visible_attributes = visible_children|selectattr("type", "equalto", "data")|list %} +{% if "show-module-summary" in autoapi_options and (visible_classes or visible_functions) %} +{% block classes scoped %} +{% if visible_classes %} +Classes +~~~~~~~ + +.. autoapisummary:: + +{% for klass in visible_classes %} + {{ klass.id }} +{% endfor %} + + +{% endif %} +{% endblock %} + +{% block functions scoped %} +{% if visible_functions %} +Functions +~~~~~~~~~ + +.. autoapisummary:: + +{% for function in visible_functions %} + {{ function.id }} +{% endfor %} + + +{% endif %} +{% endblock %} + +{% block attributes scoped %} +{% if visible_attributes %} +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + +{% for attribute in visible_attributes %} + {{ attribute.id }} +{% endfor %} + + +{% endif %} +{% endblock %} +{% endif %} +{% for obj_item in visible_children %} +{{ obj_item.render()|indent(0) }} +{% endfor %} +{% endif %} +{% endblock %} diff --git a/docs/source/_templates/autoapi/python/package.rst b/docs/source/_templates/autoapi/python/package.rst new file mode 100644 index 0000000000..fb9a64965e --- /dev/null +++ b/docs/source/_templates/autoapi/python/package.rst @@ -0,0 +1 @@ +{% extends "python/module.rst" %} diff --git a/docs/source/_templates/autoapi/python/property.rst b/docs/source/_templates/autoapi/python/property.rst new file mode 100644 index 0000000000..70af24236f --- /dev/null +++ b/docs/source/_templates/autoapi/python/property.rst @@ -0,0 +1,15 @@ +{%- if obj.display %} +.. py:property:: {{ obj.short_name }} + {% if obj.annotation %} + :type: {{ obj.annotation }} + {% endif %} + {% if obj.properties %} + {% for property in obj.properties %} + :{{ property }}: + {% endfor %} + {% endif %} + + {% if obj.docstring %} + {{ obj.docstring|indent(3) }} + {% endif %} +{% endif %} diff --git a/docs/source/conf.py b/docs/source/conf.py index 5b34ff8dc0..916a397e8e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -17,18 +17,29 @@ import os import sys -pype_root = os.path.abspath('../..') -sys.path.insert(0, pype_root) +import revitron_sphinx_theme + +openpype_root = os.path.abspath('../..') +sys.path.insert(0, openpype_root) +# app = QApplication([]) + +""" repos = os.listdir(os.path.abspath("../../repos")) -repos = [os.path.join(pype_root, "repos", repo) for repo in repos] +repos = [os.path.join(openpype_root, "repos", repo) for repo in repos] for repo in repos: sys.path.append(repo) +""" + +todo_include_todos = True +autodoc_mock_imports = ["maya", "pymel", "nuke", "nukestudio", "nukescripts", + "hiero", "bpy", "fusion", "houdini", "hou", "unreal", + "__builtin__", "resolve", "pysync", "DaVinciResolveScript"] # -- Project information ----------------------------------------------------- -project = 'pype' -copyright = '2019, Orbi Tools' -author = 'Orbi Tools' +project = 'OpenPype' +copyright = '2023 Ynput' +author = 'Ynput' # The short X.Y version version = '' @@ -52,11 +63,41 @@ extensions = [ 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', - 'sphinx.ext.viewcode', 'sphinx.ext.autosummary', - 'recommonmark' + 'revitron_sphinx_theme', + 'autoapi.extension', + 'myst_parser' ] +############################## +# Autoapi settings +############################## + +autoapi_dirs = ['../../openpype', '../../igniter'] + +# bypass modules with a lot of python2 content for now +autoapi_ignore = [ + "*vendor*", + "*schemas*", + "*startup/*", + "*/website*", + "*openpype/hooks*", + "*openpype/style*", + "openpype/tests*", + # to many levels of relative import: + "*/modules/sync_server/*" +] +autoapi_keep_files = True +autoapi_options = [ + 'members', + 'undoc-members', + 'show-inheritance', + 'show-module-summary' +] +autoapi_add_toctree_entry = True +autoapi_template_dir = '_templates/autoapi' + + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -64,7 +105,7 @@ templates_path = ['_templates'] # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ['.rst', '.md'] # The master toctree document. master_doc = 'index' @@ -74,12 +115,15 @@ master_doc = 'index' # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "English" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] +exclude_patterns = [ + "openpype.hosts.resolve.*", + "openpype.tools.*" + ] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'friendly' @@ -97,15 +141,22 @@ autosummary_generate = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = 'revitron_sphinx_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = { - 'collapse_navigation': False + 'collapse_navigation': True, + 'sticky_navigation': True, + 'navigation_depth': 4, + 'includehidden': True, + 'titles_only': False, + 'github_url': '', } +html_logo = '_static/AYON_tight_G.svg' + # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -153,8 +204,8 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'pype.tex', 'pype Documentation', - 'OrbiTools', 'manual'), + (master_doc, 'openpype.tex', 'OpenPype Documentation', + 'Ynput', 'manual'), ] @@ -163,7 +214,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'pype', 'pype Documentation', + (master_doc, 'openpype', 'OpenPype Documentation', [author], 1) ] @@ -174,8 +225,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'pype', 'pype Documentation', - author, 'pype', 'One line description of project.', + (master_doc, 'OpenPype', 'OpenPype Documentation', + author, 'OpenPype', 'Pipeline for studios', 'Miscellaneous'), ] @@ -207,7 +258,4 @@ intersphinx_mapping = { 'https://docs.python.org/3/': None } -# -- Options for todo extension ---------------------------------------------- - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True +myst_gfm_only = True diff --git a/docs/source/igniter.bootstrap_repos.rst b/docs/source/igniter.bootstrap_repos.rst deleted file mode 100644 index 7c6e0a0757..0000000000 --- a/docs/source/igniter.bootstrap_repos.rst +++ /dev/null @@ -1,7 +0,0 @@ -igniter.bootstrap\_repos module -=============================== - -.. automodule:: igniter.bootstrap_repos - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/igniter.install_dialog.rst b/docs/source/igniter.install_dialog.rst deleted file mode 100644 index bf30ec270e..0000000000 --- a/docs/source/igniter.install_dialog.rst +++ /dev/null @@ -1,7 +0,0 @@ -igniter.install\_dialog module -============================== - -.. automodule:: igniter.install_dialog - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/igniter.install_thread.rst b/docs/source/igniter.install_thread.rst deleted file mode 100644 index 6c19516219..0000000000 --- a/docs/source/igniter.install_thread.rst +++ /dev/null @@ -1,7 +0,0 @@ -igniter.install\_thread module -============================== - -.. automodule:: igniter.install_thread - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/igniter.rst b/docs/source/igniter.rst deleted file mode 100644 index b4aebe88b0..0000000000 --- a/docs/source/igniter.rst +++ /dev/null @@ -1,42 +0,0 @@ -igniter package -=============== - -.. automodule:: igniter - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -igniter.bootstrap\_repos module -------------------------------- - -.. automodule:: igniter.bootstrap_repos - :members: - :undoc-members: - :show-inheritance: - -igniter.install\_dialog module ------------------------------- - -.. automodule:: igniter.install_dialog - :members: - :undoc-members: - :show-inheritance: - -igniter.install\_thread module ------------------------------- - -.. automodule:: igniter.install_thread - :members: - :undoc-members: - :show-inheritance: - -igniter.tools module --------------------- - -.. automodule:: igniter.tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/igniter.tools.rst b/docs/source/igniter.tools.rst deleted file mode 100644 index 4fdbdf9d29..0000000000 --- a/docs/source/igniter.tools.rst +++ /dev/null @@ -1,7 +0,0 @@ -igniter.tools module -==================== - -.. automodule:: igniter.tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/index.rst b/docs/source/index.rst index b54d153894..f703468fca 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,14 +1,15 @@ -.. pype documentation master file, created by +.. openpype documentation master file, created by sphinx-quickstart on Mon May 13 17:18:23 2019. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to pype's documentation! -================================ +Welcome to OpenPype's API documentation! +======================================== .. toctree:: - readme - modules + + Readme + Indices and tables ================== diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index 1956d9ed04..0000000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,8 +0,0 @@ -igniter -======= - -.. toctree:: - :maxdepth: 6 - - igniter - pype \ No newline at end of file diff --git a/docs/source/pype.action.rst b/docs/source/pype.action.rst deleted file mode 100644 index 62a32e08b5..0000000000 --- a/docs/source/pype.action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.action module -================== - -.. automodule:: pype.action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.api.rst b/docs/source/pype.api.rst deleted file mode 100644 index af3602a895..0000000000 --- a/docs/source/pype.api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.api module -=============== - -.. automodule:: pype.api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.cli.rst b/docs/source/pype.cli.rst deleted file mode 100644 index 7e4a336fa9..0000000000 --- a/docs/source/pype.cli.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.cli module -=============== - -.. automodule:: pype.cli - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.aftereffects.rst b/docs/source/pype.hosts.aftereffects.rst deleted file mode 100644 index 3c2b2dda41..0000000000 --- a/docs/source/pype.hosts.aftereffects.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.aftereffects package -=============================== - -.. automodule:: pype.hosts.aftereffects - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.blender.action.rst b/docs/source/pype.hosts.blender.action.rst deleted file mode 100644 index a6444b1efc..0000000000 --- a/docs/source/pype.hosts.blender.action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.blender.action module -================================ - -.. automodule:: pype.hosts.blender.action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.blender.plugin.rst b/docs/source/pype.hosts.blender.plugin.rst deleted file mode 100644 index cf6a8feec8..0000000000 --- a/docs/source/pype.hosts.blender.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.blender.plugin module -================================ - -.. automodule:: pype.hosts.blender.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.blender.rst b/docs/source/pype.hosts.blender.rst deleted file mode 100644 index 19cb85e5f3..0000000000 --- a/docs/source/pype.hosts.blender.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.hosts.blender package -========================== - -.. automodule:: pype.hosts.blender - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.blender.action module --------------------------------- - -.. automodule:: pype.hosts.blender.action - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.blender.plugin module --------------------------------- - -.. automodule:: pype.hosts.blender.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.celaction.cli.rst b/docs/source/pype.hosts.celaction.cli.rst deleted file mode 100644 index c8843b90bd..0000000000 --- a/docs/source/pype.hosts.celaction.cli.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.celaction.cli module -=============================== - -.. automodule:: pype.hosts.celaction.cli - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.celaction.rst b/docs/source/pype.hosts.celaction.rst deleted file mode 100644 index 1aa236397e..0000000000 --- a/docs/source/pype.hosts.celaction.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.hosts.celaction package -============================ - -.. automodule:: pype.hosts.celaction - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.celaction.cli module -------------------------------- - -.. automodule:: pype.hosts.celaction.cli - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.lib.rst b/docs/source/pype.hosts.fusion.lib.rst deleted file mode 100644 index 32b8f501f5..0000000000 --- a/docs/source/pype.hosts.fusion.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.lib module -============================ - -.. automodule:: pype.hosts.fusion.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.menu.rst b/docs/source/pype.hosts.fusion.menu.rst deleted file mode 100644 index ec5bf76612..0000000000 --- a/docs/source/pype.hosts.fusion.menu.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.menu module -============================= - -.. automodule:: pype.hosts.fusion.menu - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.pipeline.rst b/docs/source/pype.hosts.fusion.pipeline.rst deleted file mode 100644 index ff2a6440a8..0000000000 --- a/docs/source/pype.hosts.fusion.pipeline.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.pipeline module -================================= - -.. automodule:: pype.hosts.fusion.pipeline - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.rst b/docs/source/pype.hosts.fusion.rst deleted file mode 100644 index 7c2fee827c..0000000000 --- a/docs/source/pype.hosts.fusion.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.hosts.fusion package -========================= - -.. automodule:: pype.hosts.fusion - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.hosts.fusion.scripts - -Submodules ----------- - -pype.hosts.fusion.lib module ----------------------------- - -.. automodule:: pype.hosts.fusion.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.scripts.duplicate_with_inputs.rst b/docs/source/pype.hosts.fusion.scripts.duplicate_with_inputs.rst deleted file mode 100644 index 2503c20f3b..0000000000 --- a/docs/source/pype.hosts.fusion.scripts.duplicate_with_inputs.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.scripts.duplicate\_with\_inputs module -======================================================== - -.. automodule:: pype.hosts.fusion.scripts.duplicate_with_inputs - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.scripts.fusion_switch_shot.rst b/docs/source/pype.hosts.fusion.scripts.fusion_switch_shot.rst deleted file mode 100644 index 770300116f..0000000000 --- a/docs/source/pype.hosts.fusion.scripts.fusion_switch_shot.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.scripts.fusion\_switch\_shot module -===================================================== - -.. automodule:: pype.hosts.fusion.scripts.fusion_switch_shot - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.scripts.rst b/docs/source/pype.hosts.fusion.scripts.rst deleted file mode 100644 index 5de5f66652..0000000000 --- a/docs/source/pype.hosts.fusion.scripts.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.hosts.fusion.scripts package -================================= - -.. automodule:: pype.hosts.fusion.scripts - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.fusion.scripts.fusion\_switch\_shot module ------------------------------------------------------ - -.. automodule:: pype.hosts.fusion.scripts.fusion_switch_shot - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.fusion.scripts.publish\_filesequence module ------------------------------------------------------- - -.. automodule:: pype.hosts.fusion.scripts.publish_filesequence - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.scripts.set_rendermode.rst b/docs/source/pype.hosts.fusion.scripts.set_rendermode.rst deleted file mode 100644 index 27bff63466..0000000000 --- a/docs/source/pype.hosts.fusion.scripts.set_rendermode.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.scripts.set\_rendermode module -================================================ - -.. automodule:: pype.hosts.fusion.scripts.set_rendermode - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.fusion.utils.rst b/docs/source/pype.hosts.fusion.utils.rst deleted file mode 100644 index b6de3d0510..0000000000 --- a/docs/source/pype.hosts.fusion.utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.fusion.utils module -============================== - -.. automodule:: pype.hosts.fusion.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.harmony.rst b/docs/source/pype.hosts.harmony.rst deleted file mode 100644 index 60e1fcdce6..0000000000 --- a/docs/source/pype.hosts.harmony.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.harmony package -========================== - -.. automodule:: pype.hosts.harmony - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.hiero.events.rst b/docs/source/pype.hosts.hiero.events.rst deleted file mode 100644 index 874abbffba..0000000000 --- a/docs/source/pype.hosts.hiero.events.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.hiero.events module -============================== - -.. automodule:: pype.hosts.hiero.events - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.hiero.lib.rst b/docs/source/pype.hosts.hiero.lib.rst deleted file mode 100644 index 8c0d33b03b..0000000000 --- a/docs/source/pype.hosts.hiero.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.hiero.lib module -=========================== - -.. automodule:: pype.hosts.hiero.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.hiero.menu.rst b/docs/source/pype.hosts.hiero.menu.rst deleted file mode 100644 index baa1317e61..0000000000 --- a/docs/source/pype.hosts.hiero.menu.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.hiero.menu module -============================ - -.. automodule:: pype.hosts.hiero.menu - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.hiero.rst b/docs/source/pype.hosts.hiero.rst deleted file mode 100644 index 9a7891b45e..0000000000 --- a/docs/source/pype.hosts.hiero.rst +++ /dev/null @@ -1,19 +0,0 @@ -pype.hosts.hiero package -======================== - -.. automodule:: pype.hosts.hiero - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.hosts.hiero.events - pype.hosts.hiero.lib - pype.hosts.hiero.menu - pype.hosts.hiero.tags - pype.hosts.hiero.workio diff --git a/docs/source/pype.hosts.hiero.tags.rst b/docs/source/pype.hosts.hiero.tags.rst deleted file mode 100644 index 0df33279d5..0000000000 --- a/docs/source/pype.hosts.hiero.tags.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.hiero.tags module -============================ - -.. automodule:: pype.hosts.hiero.tags - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.hiero.workio.rst b/docs/source/pype.hosts.hiero.workio.rst deleted file mode 100644 index 11aae43212..0000000000 --- a/docs/source/pype.hosts.hiero.workio.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.hiero.workio module -============================== - -.. automodule:: pype.hosts.hiero.workio - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.houdini.lib.rst b/docs/source/pype.hosts.houdini.lib.rst deleted file mode 100644 index ba6e60d5f3..0000000000 --- a/docs/source/pype.hosts.houdini.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.houdini.lib module -============================= - -.. automodule:: pype.hosts.houdini.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.houdini.rst b/docs/source/pype.hosts.houdini.rst deleted file mode 100644 index 5db18ab3d4..0000000000 --- a/docs/source/pype.hosts.houdini.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.hosts.houdini package -========================== - -.. automodule:: pype.hosts.houdini - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.houdini.lib module ------------------------------ - -.. automodule:: pype.hosts.houdini.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.action.rst b/docs/source/pype.hosts.maya.action.rst deleted file mode 100644 index e1ad7e5d43..0000000000 --- a/docs/source/pype.hosts.maya.action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.maya.action module -============================= - -.. automodule:: pype.hosts.maya.action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.customize.rst b/docs/source/pype.hosts.maya.customize.rst deleted file mode 100644 index 335e75b0d4..0000000000 --- a/docs/source/pype.hosts.maya.customize.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.maya.customize module -================================ - -.. automodule:: pype.hosts.maya.customize - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.expected_files.rst b/docs/source/pype.hosts.maya.expected_files.rst deleted file mode 100644 index 0ecf22e502..0000000000 --- a/docs/source/pype.hosts.maya.expected_files.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.maya.expected\_files module -====================================== - -.. automodule:: pype.hosts.maya.expected_files - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.lib.rst b/docs/source/pype.hosts.maya.lib.rst deleted file mode 100644 index 7d7dbe4502..0000000000 --- a/docs/source/pype.hosts.maya.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.maya.lib module -========================== - -.. automodule:: pype.hosts.maya.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.menu.rst b/docs/source/pype.hosts.maya.menu.rst deleted file mode 100644 index 614e113769..0000000000 --- a/docs/source/pype.hosts.maya.menu.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.maya.menu module -=========================== - -.. automodule:: pype.hosts.maya.menu - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.plugin.rst b/docs/source/pype.hosts.maya.plugin.rst deleted file mode 100644 index 5796b40c70..0000000000 --- a/docs/source/pype.hosts.maya.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.maya.plugin module -============================= - -.. automodule:: pype.hosts.maya.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.maya.rst b/docs/source/pype.hosts.maya.rst deleted file mode 100644 index 0beab888fc..0000000000 --- a/docs/source/pype.hosts.maya.rst +++ /dev/null @@ -1,58 +0,0 @@ -pype.hosts.maya package -======================= - -.. automodule:: pype.hosts.maya - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.maya.action module ------------------------------ - -.. automodule:: pype.hosts.maya.action - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.maya.customize module --------------------------------- - -.. automodule:: pype.hosts.maya.customize - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.maya.expected\_files module --------------------------------------- - -.. automodule:: pype.hosts.maya.expected_files - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.maya.lib module --------------------------- - -.. automodule:: pype.hosts.maya.lib - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.maya.menu module ---------------------------- - -.. automodule:: pype.hosts.maya.menu - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.maya.plugin module ------------------------------ - -.. automodule:: pype.hosts.maya.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.actions.rst b/docs/source/pype.hosts.nuke.actions.rst deleted file mode 100644 index d5e8849a38..0000000000 --- a/docs/source/pype.hosts.nuke.actions.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.nuke.actions module -============================== - -.. automodule:: pype.hosts.nuke.actions - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.lib.rst b/docs/source/pype.hosts.nuke.lib.rst deleted file mode 100644 index c177a27f2d..0000000000 --- a/docs/source/pype.hosts.nuke.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.nuke.lib module -========================== - -.. automodule:: pype.hosts.nuke.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.menu.rst b/docs/source/pype.hosts.nuke.menu.rst deleted file mode 100644 index 190e488b95..0000000000 --- a/docs/source/pype.hosts.nuke.menu.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.nuke.menu module -=========================== - -.. automodule:: pype.hosts.nuke.menu - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.plugin.rst b/docs/source/pype.hosts.nuke.plugin.rst deleted file mode 100644 index ddd5f1db89..0000000000 --- a/docs/source/pype.hosts.nuke.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.nuke.plugin module -============================= - -.. automodule:: pype.hosts.nuke.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.presets.rst b/docs/source/pype.hosts.nuke.presets.rst deleted file mode 100644 index a69aa8a367..0000000000 --- a/docs/source/pype.hosts.nuke.presets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.nuke.presets module -============================== - -.. automodule:: pype.hosts.nuke.presets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.rst b/docs/source/pype.hosts.nuke.rst deleted file mode 100644 index 559de65927..0000000000 --- a/docs/source/pype.hosts.nuke.rst +++ /dev/null @@ -1,58 +0,0 @@ -pype.hosts.nuke package -======================= - -.. automodule:: pype.hosts.nuke - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.nuke.actions module ------------------------------- - -.. automodule:: pype.hosts.nuke.actions - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nuke.lib module --------------------------- - -.. automodule:: pype.hosts.nuke.lib - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nuke.menu module ---------------------------- - -.. automodule:: pype.hosts.nuke.menu - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nuke.plugin module ------------------------------ - -.. automodule:: pype.hosts.nuke.plugin - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nuke.presets module ------------------------------- - -.. automodule:: pype.hosts.nuke.presets - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nuke.utils module ----------------------------- - -.. automodule:: pype.hosts.nuke.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nuke.utils.rst b/docs/source/pype.hosts.nuke.utils.rst deleted file mode 100644 index 66974dc707..0000000000 --- a/docs/source/pype.hosts.nuke.utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.nuke.utils module -============================ - -.. automodule:: pype.hosts.nuke.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.nukestudio.rst b/docs/source/pype.hosts.nukestudio.rst deleted file mode 100644 index c718d699fa..0000000000 --- a/docs/source/pype.hosts.nukestudio.rst +++ /dev/null @@ -1,50 +0,0 @@ -pype.hosts.nukestudio package -============================= - -.. automodule:: pype.hosts.nukestudio - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.nukestudio.events module ------------------------------------ - -.. automodule:: pype.hosts.nukestudio.events - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nukestudio.lib module --------------------------------- - -.. automodule:: pype.hosts.nukestudio.lib - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nukestudio.menu module ---------------------------------- - -.. automodule:: pype.hosts.nukestudio.menu - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nukestudio.tags module ---------------------------------- - -.. automodule:: pype.hosts.nukestudio.tags - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.nukestudio.workio module ------------------------------------ - -.. automodule:: pype.hosts.nukestudio.workio - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.photoshop.rst b/docs/source/pype.hosts.photoshop.rst deleted file mode 100644 index f77ea79874..0000000000 --- a/docs/source/pype.hosts.photoshop.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.photoshop package -============================ - -.. automodule:: pype.hosts.photoshop - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.premiere.lib.rst b/docs/source/pype.hosts.premiere.lib.rst deleted file mode 100644 index e2c2723841..0000000000 --- a/docs/source/pype.hosts.premiere.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.premiere.lib module -============================== - -.. automodule:: pype.hosts.premiere.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.premiere.rst b/docs/source/pype.hosts.premiere.rst deleted file mode 100644 index 7c38d52c22..0000000000 --- a/docs/source/pype.hosts.premiere.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.hosts.premiere package -=========================== - -.. automodule:: pype.hosts.premiere - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.premiere.lib module ------------------------------- - -.. automodule:: pype.hosts.premiere.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.action.rst b/docs/source/pype.hosts.resolve.action.rst deleted file mode 100644 index 781694781f..0000000000 --- a/docs/source/pype.hosts.resolve.action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.action module -================================ - -.. automodule:: pype.hosts.resolve.action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.lib.rst b/docs/source/pype.hosts.resolve.lib.rst deleted file mode 100644 index 5860f783cc..0000000000 --- a/docs/source/pype.hosts.resolve.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.lib module -============================= - -.. automodule:: pype.hosts.resolve.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.menu.rst b/docs/source/pype.hosts.resolve.menu.rst deleted file mode 100644 index df87dcde98..0000000000 --- a/docs/source/pype.hosts.resolve.menu.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.menu module -============================== - -.. automodule:: pype.hosts.resolve.menu - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.otio.davinci_export.rst b/docs/source/pype.hosts.resolve.otio.davinci_export.rst deleted file mode 100644 index 498f96a7ed..0000000000 --- a/docs/source/pype.hosts.resolve.otio.davinci_export.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.otio.davinci\_export module -============================================== - -.. automodule:: pype.hosts.resolve.otio.davinci_export - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.otio.davinci_import.rst b/docs/source/pype.hosts.resolve.otio.davinci_import.rst deleted file mode 100644 index 30f43cc9fe..0000000000 --- a/docs/source/pype.hosts.resolve.otio.davinci_import.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.otio.davinci\_import module -============================================== - -.. automodule:: pype.hosts.resolve.otio.davinci_import - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.otio.rst b/docs/source/pype.hosts.resolve.otio.rst deleted file mode 100644 index 523d8937ca..0000000000 --- a/docs/source/pype.hosts.resolve.otio.rst +++ /dev/null @@ -1,17 +0,0 @@ -pype.hosts.resolve.otio package -=============================== - -.. automodule:: pype.hosts.resolve.otio - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.hosts.resolve.otio.davinci_export - pype.hosts.resolve.otio.davinci_import - pype.hosts.resolve.otio.utils diff --git a/docs/source/pype.hosts.resolve.otio.utils.rst b/docs/source/pype.hosts.resolve.otio.utils.rst deleted file mode 100644 index 765f492732..0000000000 --- a/docs/source/pype.hosts.resolve.otio.utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.otio.utils module -==================================== - -.. automodule:: pype.hosts.resolve.otio.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.pipeline.rst b/docs/source/pype.hosts.resolve.pipeline.rst deleted file mode 100644 index 3efc24137b..0000000000 --- a/docs/source/pype.hosts.resolve.pipeline.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.pipeline module -================================== - -.. automodule:: pype.hosts.resolve.pipeline - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.plugin.rst b/docs/source/pype.hosts.resolve.plugin.rst deleted file mode 100644 index 26f6c56aef..0000000000 --- a/docs/source/pype.hosts.resolve.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.plugin module -================================ - -.. automodule:: pype.hosts.resolve.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.preload_console.rst b/docs/source/pype.hosts.resolve.preload_console.rst deleted file mode 100644 index 0d38ae14ea..0000000000 --- a/docs/source/pype.hosts.resolve.preload_console.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.preload\_console module -========================================== - -.. automodule:: pype.hosts.resolve.preload_console - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.rst b/docs/source/pype.hosts.resolve.rst deleted file mode 100644 index 368129e43e..0000000000 --- a/docs/source/pype.hosts.resolve.rst +++ /dev/null @@ -1,74 +0,0 @@ -pype.hosts.resolve package -========================== - -.. automodule:: pype.hosts.resolve - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.resolve.action module --------------------------------- - -.. automodule:: pype.hosts.resolve.action - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.lib module ------------------------------ - -.. automodule:: pype.hosts.resolve.lib - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.menu module ------------------------------- - -.. automodule:: pype.hosts.resolve.menu - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.pipeline module ----------------------------------- - -.. automodule:: pype.hosts.resolve.pipeline - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.plugin module --------------------------------- - -.. automodule:: pype.hosts.resolve.plugin - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.preload\_console module ------------------------------------------- - -.. automodule:: pype.hosts.resolve.preload_console - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.utils module -------------------------------- - -.. automodule:: pype.hosts.resolve.utils - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.resolve.workio module --------------------------------- - -.. automodule:: pype.hosts.resolve.workio - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.todo-rendering.rst b/docs/source/pype.hosts.resolve.todo-rendering.rst deleted file mode 100644 index 8ea80183ce..0000000000 --- a/docs/source/pype.hosts.resolve.todo-rendering.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.todo\-rendering module -========================================= - -.. automodule:: pype.hosts.resolve.todo-rendering - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.utils.rst b/docs/source/pype.hosts.resolve.utils.rst deleted file mode 100644 index e390a5d026..0000000000 --- a/docs/source/pype.hosts.resolve.utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.utils module -=============================== - -.. automodule:: pype.hosts.resolve.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.resolve.workio.rst b/docs/source/pype.hosts.resolve.workio.rst deleted file mode 100644 index 5dceb99d64..0000000000 --- a/docs/source/pype.hosts.resolve.workio.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.resolve.workio module -================================ - -.. automodule:: pype.hosts.resolve.workio - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.rst b/docs/source/pype.hosts.rst deleted file mode 100644 index e2d9121501..0000000000 --- a/docs/source/pype.hosts.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.hosts package -================== - -.. automodule:: pype.hosts - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.hosts.blender - pype.hosts.celaction - pype.hosts.fusion - pype.hosts.harmony - pype.hosts.houdini - pype.hosts.maya - pype.hosts.nuke - pype.hosts.nukestudio - pype.hosts.photoshop - pype.hosts.premiere - pype.hosts.resolve - pype.hosts.unreal diff --git a/docs/source/pype.hosts.tvpaint.api.rst b/docs/source/pype.hosts.tvpaint.api.rst deleted file mode 100644 index 43273e8ec5..0000000000 --- a/docs/source/pype.hosts.tvpaint.api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.tvpaint.api package -============================== - -.. automodule:: pype.hosts.tvpaint.api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.tvpaint.rst b/docs/source/pype.hosts.tvpaint.rst deleted file mode 100644 index 561be3a9dc..0000000000 --- a/docs/source/pype.hosts.tvpaint.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.hosts.tvpaint package -========================== - -.. automodule:: pype.hosts.tvpaint - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 10 - - pype.hosts.tvpaint.api diff --git a/docs/source/pype.hosts.unreal.lib.rst b/docs/source/pype.hosts.unreal.lib.rst deleted file mode 100644 index b891e71c47..0000000000 --- a/docs/source/pype.hosts.unreal.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.unreal.lib module -============================ - -.. automodule:: pype.hosts.unreal.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.unreal.plugin.rst b/docs/source/pype.hosts.unreal.plugin.rst deleted file mode 100644 index e3ef81c7c7..0000000000 --- a/docs/source/pype.hosts.unreal.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.hosts.unreal.plugin module -=============================== - -.. automodule:: pype.hosts.unreal.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.hosts.unreal.rst b/docs/source/pype.hosts.unreal.rst deleted file mode 100644 index f46140298b..0000000000 --- a/docs/source/pype.hosts.unreal.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.hosts.unreal package -========================= - -.. automodule:: pype.hosts.unreal - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.hosts.unreal.lib module ----------------------------- - -.. automodule:: pype.hosts.unreal.lib - :members: - :undoc-members: - :show-inheritance: - -pype.hosts.unreal.plugin module -------------------------------- - -.. automodule:: pype.hosts.unreal.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.launcher_actions.rst b/docs/source/pype.launcher_actions.rst deleted file mode 100644 index c7525acbd1..0000000000 --- a/docs/source/pype.launcher_actions.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.launcher\_actions module -============================= - -.. automodule:: pype.launcher_actions - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.abstract_collect_render.rst b/docs/source/pype.lib.abstract_collect_render.rst deleted file mode 100644 index d6adadc271..0000000000 --- a/docs/source/pype.lib.abstract_collect_render.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.abstract\_collect\_render module -========================================= - -.. automodule:: pype.lib.abstract_collect_render - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.abstract_expected_files.rst b/docs/source/pype.lib.abstract_expected_files.rst deleted file mode 100644 index 904aeb3375..0000000000 --- a/docs/source/pype.lib.abstract_expected_files.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.abstract\_expected\_files module -========================================= - -.. automodule:: pype.lib.abstract_expected_files - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.abstract_metaplugins.rst b/docs/source/pype.lib.abstract_metaplugins.rst deleted file mode 100644 index 9f2751b630..0000000000 --- a/docs/source/pype.lib.abstract_metaplugins.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.abstract\_metaplugins module -===================================== - -.. automodule:: pype.lib.abstract_metaplugins - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.abstract_submit_deadline.rst b/docs/source/pype.lib.abstract_submit_deadline.rst deleted file mode 100644 index a57222add3..0000000000 --- a/docs/source/pype.lib.abstract_submit_deadline.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.abstract\_submit\_deadline module -========================================== - -.. automodule:: pype.lib.abstract_submit_deadline - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.anatomy.rst b/docs/source/pype.lib.anatomy.rst deleted file mode 100644 index 7bddb37c8a..0000000000 --- a/docs/source/pype.lib.anatomy.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.anatomy module -======================= - -.. automodule:: pype.lib.anatomy - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.applications.rst b/docs/source/pype.lib.applications.rst deleted file mode 100644 index 8d1ff9b2c6..0000000000 --- a/docs/source/pype.lib.applications.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.applications module -============================ - -.. automodule:: pype.lib.applications - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.avalon_context.rst b/docs/source/pype.lib.avalon_context.rst deleted file mode 100644 index 067ea3380f..0000000000 --- a/docs/source/pype.lib.avalon_context.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.avalon\_context module -=============================== - -.. automodule:: pype.lib.avalon_context - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.config.rst b/docs/source/pype.lib.config.rst deleted file mode 100644 index ce4c13f4e7..0000000000 --- a/docs/source/pype.lib.config.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.config module -====================== - -.. automodule:: pype.lib.config - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.deprecated.rst b/docs/source/pype.lib.deprecated.rst deleted file mode 100644 index ec5ee58d67..0000000000 --- a/docs/source/pype.lib.deprecated.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.deprecated module -========================== - -.. automodule:: pype.lib.deprecated - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.editorial.rst b/docs/source/pype.lib.editorial.rst deleted file mode 100644 index d32e495e51..0000000000 --- a/docs/source/pype.lib.editorial.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.editorial module -========================= - -.. automodule:: pype.lib.editorial - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.env_tools.rst b/docs/source/pype.lib.env_tools.rst deleted file mode 100644 index cb470207c8..0000000000 --- a/docs/source/pype.lib.env_tools.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.env\_tools module -========================== - -.. automodule:: pype.lib.env_tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.execute.rst b/docs/source/pype.lib.execute.rst deleted file mode 100644 index 82c4ef0ad8..0000000000 --- a/docs/source/pype.lib.execute.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.execute module -======================= - -.. automodule:: pype.lib.execute - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.ffmpeg_utils.rst b/docs/source/pype.lib.ffmpeg_utils.rst deleted file mode 100644 index 968a3f39c8..0000000000 --- a/docs/source/pype.lib.ffmpeg_utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.ffmpeg\_utils module -============================= - -.. automodule:: pype.lib.ffmpeg_utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.git_progress.rst b/docs/source/pype.lib.git_progress.rst deleted file mode 100644 index 017cf4c3c7..0000000000 --- a/docs/source/pype.lib.git_progress.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.git\_progress module -============================= - -.. automodule:: pype.lib.git_progress - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.log.rst b/docs/source/pype.lib.log.rst deleted file mode 100644 index 6282178850..0000000000 --- a/docs/source/pype.lib.log.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.log module -=================== - -.. automodule:: pype.lib.log - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.mongo.rst b/docs/source/pype.lib.mongo.rst deleted file mode 100644 index 34fbc6af7f..0000000000 --- a/docs/source/pype.lib.mongo.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.mongo module -===================== - -.. automodule:: pype.lib.mongo - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.path_tools.rst b/docs/source/pype.lib.path_tools.rst deleted file mode 100644 index c19c41eea3..0000000000 --- a/docs/source/pype.lib.path_tools.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.path\_tools module -=========================== - -.. automodule:: pype.lib.path_tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.plugin_tools.rst b/docs/source/pype.lib.plugin_tools.rst deleted file mode 100644 index 6eadc5d3be..0000000000 --- a/docs/source/pype.lib.plugin_tools.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.plugin\_tools module -============================= - -.. automodule:: pype.lib.plugin_tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.profiling.rst b/docs/source/pype.lib.profiling.rst deleted file mode 100644 index 1fded0c8fd..0000000000 --- a/docs/source/pype.lib.profiling.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.profiling module -========================= - -.. automodule:: pype.lib.profiling - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.python_module_tools.rst b/docs/source/pype.lib.python_module_tools.rst deleted file mode 100644 index c916080bce..0000000000 --- a/docs/source/pype.lib.python_module_tools.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.python\_module\_tools module -===================================== - -.. automodule:: pype.lib.python_module_tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.rst b/docs/source/pype.lib.rst deleted file mode 100644 index ea880eea3e..0000000000 --- a/docs/source/pype.lib.rst +++ /dev/null @@ -1,90 +0,0 @@ -pype.lib package -================ - -.. automodule:: pype.lib - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.lib.anatomy module ------------------------ - -.. automodule:: pype.lib.anatomy - :members: - :undoc-members: - :show-inheritance: - -pype.lib.config module ----------------------- - -.. automodule:: pype.lib.config - :members: - :undoc-members: - :show-inheritance: - -pype.lib.execute module ------------------------ - -.. automodule:: pype.lib.execute - :members: - :undoc-members: - :show-inheritance: - -pype.lib.git\_progress module ------------------------------ - -.. automodule:: pype.lib.git_progress - :members: - :undoc-members: - :show-inheritance: - -pype.lib.lib module -------------------- - -.. automodule:: pype.lib.lib - :members: - :undoc-members: - :show-inheritance: - -pype.lib.log module -------------------- - -.. automodule:: pype.lib.log - :members: - :undoc-members: - :show-inheritance: - -pype.lib.mongo module ---------------------- - -.. automodule:: pype.lib.mongo - :members: - :undoc-members: - :show-inheritance: - -pype.lib.profiling module -------------------------- - -.. automodule:: pype.lib.profiling - :members: - :undoc-members: - :show-inheritance: - -pype.lib.terminal module ------------------------- - -.. automodule:: pype.lib.terminal - :members: - :undoc-members: - :show-inheritance: - -pype.lib.user\_settings module ------------------------------- - -.. automodule:: pype.lib.user_settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.terminal.rst b/docs/source/pype.lib.terminal.rst deleted file mode 100644 index dafe1d8f69..0000000000 --- a/docs/source/pype.lib.terminal.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.terminal module -======================== - -.. automodule:: pype.lib.terminal - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.terminal_splash.rst b/docs/source/pype.lib.terminal_splash.rst deleted file mode 100644 index 06038f0f09..0000000000 --- a/docs/source/pype.lib.terminal_splash.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.terminal\_splash module -================================ - -.. automodule:: pype.lib.terminal_splash - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.lib.user_settings.rst b/docs/source/pype.lib.user_settings.rst deleted file mode 100644 index 7b4e8ced78..0000000000 --- a/docs/source/pype.lib.user_settings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.lib.user\_settings module -============================== - -.. automodule:: pype.lib.user_settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.adobe_communicator.adobe_comunicator.rst b/docs/source/pype.modules.adobe_communicator.adobe_comunicator.rst deleted file mode 100644 index aadbaa0dc5..0000000000 --- a/docs/source/pype.modules.adobe_communicator.adobe_comunicator.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.adobe\_communicator.adobe\_comunicator module -========================================================== - -.. automodule:: pype.modules.adobe_communicator.adobe_comunicator - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.adobe_communicator.lib.publish.rst b/docs/source/pype.modules.adobe_communicator.lib.publish.rst deleted file mode 100644 index a16bf1dd0a..0000000000 --- a/docs/source/pype.modules.adobe_communicator.lib.publish.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.adobe\_communicator.lib.publish module -=================================================== - -.. automodule:: pype.modules.adobe_communicator.lib.publish - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.adobe_communicator.lib.rest_api.rst b/docs/source/pype.modules.adobe_communicator.lib.rest_api.rst deleted file mode 100644 index 457bebef99..0000000000 --- a/docs/source/pype.modules.adobe_communicator.lib.rest_api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.adobe\_communicator.lib.rest\_api module -===================================================== - -.. automodule:: pype.modules.adobe_communicator.lib.rest_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.adobe_communicator.lib.rst b/docs/source/pype.modules.adobe_communicator.lib.rst deleted file mode 100644 index cdec4ce80e..0000000000 --- a/docs/source/pype.modules.adobe_communicator.lib.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.adobe\_communicator.lib package -============================================ - -.. automodule:: pype.modules.adobe_communicator.lib - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.adobe\_communicator.lib.publish module ---------------------------------------------------- - -.. automodule:: pype.modules.adobe_communicator.lib.publish - :members: - :undoc-members: - :show-inheritance: - -pype.modules.adobe\_communicator.lib.rest\_api module ------------------------------------------------------ - -.. automodule:: pype.modules.adobe_communicator.lib.rest_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.adobe_communicator.rst b/docs/source/pype.modules.adobe_communicator.rst deleted file mode 100644 index f2fa40ced4..0000000000 --- a/docs/source/pype.modules.adobe_communicator.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.adobe\_communicator package -======================================== - -.. automodule:: pype.modules.adobe_communicator - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.modules.adobe_communicator.lib - -Submodules ----------- - -pype.modules.adobe\_communicator.adobe\_comunicator module ----------------------------------------------------------- - -.. automodule:: pype.modules.adobe_communicator.adobe_comunicator - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.avalon_apps.avalon_app.rst b/docs/source/pype.modules.avalon_apps.avalon_app.rst deleted file mode 100644 index 43f467e748..0000000000 --- a/docs/source/pype.modules.avalon_apps.avalon_app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.avalon\_apps.avalon\_app module -============================================ - -.. automodule:: pype.modules.avalon_apps.avalon_app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.avalon_apps.rest_api.rst b/docs/source/pype.modules.avalon_apps.rest_api.rst deleted file mode 100644 index d89c979311..0000000000 --- a/docs/source/pype.modules.avalon_apps.rest_api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.avalon\_apps.rest\_api module -========================================== - -.. automodule:: pype.modules.avalon_apps.rest_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.avalon_apps.rst b/docs/source/pype.modules.avalon_apps.rst deleted file mode 100644 index 4755eddae6..0000000000 --- a/docs/source/pype.modules.avalon_apps.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.avalon\_apps package -================================= - -.. automodule:: pype.modules.avalon_apps - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.avalon\_apps.avalon\_app module --------------------------------------------- - -.. automodule:: pype.modules.avalon_apps.avalon_app - :members: - :undoc-members: - :show-inheritance: - -pype.modules.avalon\_apps.rest\_api module ------------------------------------------- - -.. automodule:: pype.modules.avalon_apps.rest_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.base.rst b/docs/source/pype.modules.base.rst deleted file mode 100644 index 7cd3cfbd44..0000000000 --- a/docs/source/pype.modules.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.base module -======================== - -.. automodule:: pype.modules.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.clockify.clockify.rst b/docs/source/pype.modules.clockify.clockify.rst deleted file mode 100644 index a3deaab81d..0000000000 --- a/docs/source/pype.modules.clockify.clockify.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.clockify.clockify module -===================================== - -.. automodule:: pype.modules.clockify.clockify - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.clockify.clockify_api.rst b/docs/source/pype.modules.clockify.clockify_api.rst deleted file mode 100644 index 2facc550c5..0000000000 --- a/docs/source/pype.modules.clockify.clockify_api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.clockify.clockify\_api module -========================================== - -.. automodule:: pype.modules.clockify.clockify_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.clockify.clockify_module.rst b/docs/source/pype.modules.clockify.clockify_module.rst deleted file mode 100644 index 85f8e75ad1..0000000000 --- a/docs/source/pype.modules.clockify.clockify_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.clockify.clockify\_module module -============================================= - -.. automodule:: pype.modules.clockify.clockify_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.clockify.constants.rst b/docs/source/pype.modules.clockify.constants.rst deleted file mode 100644 index e30a073bfc..0000000000 --- a/docs/source/pype.modules.clockify.constants.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.clockify.constants module -====================================== - -.. automodule:: pype.modules.clockify.constants - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.clockify.rst b/docs/source/pype.modules.clockify.rst deleted file mode 100644 index 550ba049c2..0000000000 --- a/docs/source/pype.modules.clockify.rst +++ /dev/null @@ -1,42 +0,0 @@ -pype.modules.clockify package -============================= - -.. automodule:: pype.modules.clockify - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.clockify.clockify module -------------------------------------- - -.. automodule:: pype.modules.clockify.clockify - :members: - :undoc-members: - :show-inheritance: - -pype.modules.clockify.clockify\_api module ------------------------------------------- - -.. automodule:: pype.modules.clockify.clockify_api - :members: - :undoc-members: - :show-inheritance: - -pype.modules.clockify.constants module --------------------------------------- - -.. automodule:: pype.modules.clockify.constants - :members: - :undoc-members: - :show-inheritance: - -pype.modules.clockify.widgets module ------------------------------------- - -.. automodule:: pype.modules.clockify.widgets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.clockify.widgets.rst b/docs/source/pype.modules.clockify.widgets.rst deleted file mode 100644 index e9809fb048..0000000000 --- a/docs/source/pype.modules.clockify.widgets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.clockify.widgets module -==================================== - -.. automodule:: pype.modules.clockify.widgets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.deadline.deadline_module.rst b/docs/source/pype.modules.deadline.deadline_module.rst deleted file mode 100644 index 43e7198a8b..0000000000 --- a/docs/source/pype.modules.deadline.deadline_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.deadline.deadline\_module module -============================================= - -.. automodule:: pype.modules.deadline.deadline_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.deadline.rst b/docs/source/pype.modules.deadline.rst deleted file mode 100644 index 7633b2b950..0000000000 --- a/docs/source/pype.modules.deadline.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.modules.deadline package -============================= - -.. automodule:: pype.modules.deadline - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.modules.deadline.deadline_module diff --git a/docs/source/pype.modules.ftrack.ftrack_module.rst b/docs/source/pype.modules.ftrack.ftrack_module.rst deleted file mode 100644 index 4188ffbed8..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_module module -========================================= - -.. automodule:: pype.modules.ftrack.ftrack_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.custom_db_connector.rst b/docs/source/pype.modules.ftrack.ftrack_server.custom_db_connector.rst deleted file mode 100644 index b42c3e054d..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.custom_db_connector.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.custom\_db\_connector module -=============================================================== - -.. automodule:: pype.modules.ftrack.ftrack_server.custom_db_connector - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.event_server_cli.rst b/docs/source/pype.modules.ftrack.ftrack_server.event_server_cli.rst deleted file mode 100644 index d6404f965c..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.event_server_cli.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.event\_server\_cli module -============================================================ - -.. automodule:: pype.modules.ftrack.ftrack_server.event_server_cli - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.ftrack_server.rst b/docs/source/pype.modules.ftrack.ftrack_server.ftrack_server.rst deleted file mode 100644 index af2783c263..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.ftrack_server.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.ftrack\_server module -======================================================== - -.. automodule:: pype.modules.ftrack.ftrack_server.ftrack_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.lib.rst b/docs/source/pype.modules.ftrack.ftrack_server.lib.rst deleted file mode 100644 index 2ac4cef517..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.lib module -============================================= - -.. automodule:: pype.modules.ftrack.ftrack_server.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.rst b/docs/source/pype.modules.ftrack.ftrack_server.rst deleted file mode 100644 index 417acc1a45..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.rst +++ /dev/null @@ -1,90 +0,0 @@ -pype.modules.ftrack.ftrack\_server package -========================================== - -.. automodule:: pype.modules.ftrack.ftrack_server - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.ftrack.ftrack\_server.custom\_db\_connector module ---------------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.custom_db_connector - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.event\_server\_cli module ------------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.event_server_cli - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.ftrack\_server module --------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.ftrack_server - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.lib module ---------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.lib - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.socket\_thread module --------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.socket_thread - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.sub\_event\_processor module ---------------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_event_processor - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.sub\_event\_status module ------------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_event_status - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.sub\_event\_storer module ------------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_event_storer - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.sub\_legacy\_server module -------------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_legacy_server - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.ftrack\_server.sub\_user\_server module ------------------------------------------------------------ - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_user_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.socket_thread.rst b/docs/source/pype.modules.ftrack.ftrack_server.socket_thread.rst deleted file mode 100644 index d8d24a8288..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.socket_thread.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.socket\_thread module -======================================================== - -.. automodule:: pype.modules.ftrack.ftrack_server.socket_thread - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.sub_event_processor.rst b/docs/source/pype.modules.ftrack.ftrack_server.sub_event_processor.rst deleted file mode 100644 index 04f863e347..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.sub_event_processor.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.sub\_event\_processor module -=============================================================== - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_event_processor - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.sub_event_status.rst b/docs/source/pype.modules.ftrack.ftrack_server.sub_event_status.rst deleted file mode 100644 index 876b7313cf..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.sub_event_status.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.sub\_event\_status module -============================================================ - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_event_status - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.sub_event_storer.rst b/docs/source/pype.modules.ftrack.ftrack_server.sub_event_storer.rst deleted file mode 100644 index 3d2d400d55..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.sub_event_storer.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.sub\_event\_storer module -============================================================ - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_event_storer - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.sub_legacy_server.rst b/docs/source/pype.modules.ftrack.ftrack_server.sub_legacy_server.rst deleted file mode 100644 index d25cdfe8de..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.sub_legacy_server.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.sub\_legacy\_server module -============================================================= - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_legacy_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.ftrack_server.sub_user_server.rst b/docs/source/pype.modules.ftrack.ftrack_server.sub_user_server.rst deleted file mode 100644 index c13095d5f1..0000000000 --- a/docs/source/pype.modules.ftrack.ftrack_server.sub_user_server.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.ftrack\_server.sub\_user\_server module -=========================================================== - -.. automodule:: pype.modules.ftrack.ftrack_server.sub_user_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.avalon_sync.rst b/docs/source/pype.modules.ftrack.lib.avalon_sync.rst deleted file mode 100644 index 954ec4d911..0000000000 --- a/docs/source/pype.modules.ftrack.lib.avalon_sync.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.avalon\_sync module -=========================================== - -.. automodule:: pype.modules.ftrack.lib.avalon_sync - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.credentials.rst b/docs/source/pype.modules.ftrack.lib.credentials.rst deleted file mode 100644 index 3965dc406d..0000000000 --- a/docs/source/pype.modules.ftrack.lib.credentials.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.credentials module -========================================== - -.. automodule:: pype.modules.ftrack.lib.credentials - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.ftrack_action_handler.rst b/docs/source/pype.modules.ftrack.lib.ftrack_action_handler.rst deleted file mode 100644 index cec38f9b8a..0000000000 --- a/docs/source/pype.modules.ftrack.lib.ftrack_action_handler.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.ftrack\_action\_handler module -====================================================== - -.. automodule:: pype.modules.ftrack.lib.ftrack_action_handler - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.ftrack_app_handler.rst b/docs/source/pype.modules.ftrack.lib.ftrack_app_handler.rst deleted file mode 100644 index 1f7395927d..0000000000 --- a/docs/source/pype.modules.ftrack.lib.ftrack_app_handler.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.ftrack\_app\_handler module -=================================================== - -.. automodule:: pype.modules.ftrack.lib.ftrack_app_handler - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.ftrack_base_handler.rst b/docs/source/pype.modules.ftrack.lib.ftrack_base_handler.rst deleted file mode 100644 index 94fab7c940..0000000000 --- a/docs/source/pype.modules.ftrack.lib.ftrack_base_handler.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.ftrack\_base\_handler module -==================================================== - -.. automodule:: pype.modules.ftrack.lib.ftrack_base_handler - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.ftrack_event_handler.rst b/docs/source/pype.modules.ftrack.lib.ftrack_event_handler.rst deleted file mode 100644 index 0b57219b50..0000000000 --- a/docs/source/pype.modules.ftrack.lib.ftrack_event_handler.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.ftrack\_event\_handler module -===================================================== - -.. automodule:: pype.modules.ftrack.lib.ftrack_event_handler - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.rst b/docs/source/pype.modules.ftrack.lib.rst deleted file mode 100644 index 32a219ab3a..0000000000 --- a/docs/source/pype.modules.ftrack.lib.rst +++ /dev/null @@ -1,58 +0,0 @@ -pype.modules.ftrack.lib package -=============================== - -.. automodule:: pype.modules.ftrack.lib - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.ftrack.lib.avalon\_sync module -------------------------------------------- - -.. automodule:: pype.modules.ftrack.lib.avalon_sync - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.lib.credentials module ------------------------------------------- - -.. automodule:: pype.modules.ftrack.lib.credentials - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.lib.ftrack\_action\_handler module ------------------------------------------------------- - -.. automodule:: pype.modules.ftrack.lib.ftrack_action_handler - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.lib.ftrack\_app\_handler module ---------------------------------------------------- - -.. automodule:: pype.modules.ftrack.lib.ftrack_app_handler - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.lib.ftrack\_base\_handler module ----------------------------------------------------- - -.. automodule:: pype.modules.ftrack.lib.ftrack_base_handler - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.lib.ftrack\_event\_handler module ------------------------------------------------------ - -.. automodule:: pype.modules.ftrack.lib.ftrack_event_handler - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.lib.settings.rst b/docs/source/pype.modules.ftrack.lib.settings.rst deleted file mode 100644 index 255d52178a..0000000000 --- a/docs/source/pype.modules.ftrack.lib.settings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.lib.settings module -======================================= - -.. automodule:: pype.modules.ftrack.lib.settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.rst b/docs/source/pype.modules.ftrack.rst deleted file mode 100644 index 13a92db808..0000000000 --- a/docs/source/pype.modules.ftrack.rst +++ /dev/null @@ -1,17 +0,0 @@ -pype.modules.ftrack package -=========================== - -.. automodule:: pype.modules.ftrack - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.modules.ftrack.ftrack_server - pype.modules.ftrack.lib - pype.modules.ftrack.tray diff --git a/docs/source/pype.modules.ftrack.tray.ftrack_module.rst b/docs/source/pype.modules.ftrack.tray.ftrack_module.rst deleted file mode 100644 index c4a370472c..0000000000 --- a/docs/source/pype.modules.ftrack.tray.ftrack_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.tray.ftrack\_module module -============================================== - -.. automodule:: pype.modules.ftrack.tray.ftrack_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.tray.ftrack_tray.rst b/docs/source/pype.modules.ftrack.tray.ftrack_tray.rst deleted file mode 100644 index 147647e9b4..0000000000 --- a/docs/source/pype.modules.ftrack.tray.ftrack_tray.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.tray.ftrack\_tray module -============================================ - -.. automodule:: pype.modules.ftrack.tray.ftrack_tray - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.tray.login_dialog.rst b/docs/source/pype.modules.ftrack.tray.login_dialog.rst deleted file mode 100644 index dabc2e73a7..0000000000 --- a/docs/source/pype.modules.ftrack.tray.login_dialog.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.tray.login\_dialog module -============================================= - -.. automodule:: pype.modules.ftrack.tray.login_dialog - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.tray.login_tools.rst b/docs/source/pype.modules.ftrack.tray.login_tools.rst deleted file mode 100644 index 00ec690866..0000000000 --- a/docs/source/pype.modules.ftrack.tray.login_tools.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.ftrack.tray.login\_tools module -============================================ - -.. automodule:: pype.modules.ftrack.tray.login_tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.ftrack.tray.rst b/docs/source/pype.modules.ftrack.tray.rst deleted file mode 100644 index 79772a9c3b..0000000000 --- a/docs/source/pype.modules.ftrack.tray.rst +++ /dev/null @@ -1,34 +0,0 @@ -pype.modules.ftrack.tray package -================================ - -.. automodule:: pype.modules.ftrack.tray - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.ftrack.tray.ftrack\_module module ----------------------------------------------- - -.. automodule:: pype.modules.ftrack.tray.ftrack_module - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.tray.login\_dialog module ---------------------------------------------- - -.. automodule:: pype.modules.ftrack.tray.login_dialog - :members: - :undoc-members: - :show-inheritance: - -pype.modules.ftrack.tray.login\_tools module --------------------------------------------- - -.. automodule:: pype.modules.ftrack.tray.login_tools - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.idle_manager.idle_manager.rst b/docs/source/pype.modules.idle_manager.idle_manager.rst deleted file mode 100644 index 8e93f97e6b..0000000000 --- a/docs/source/pype.modules.idle_manager.idle_manager.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.idle\_manager.idle\_manager module -=============================================== - -.. automodule:: pype.modules.idle_manager.idle_manager - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.idle_manager.rst b/docs/source/pype.modules.idle_manager.rst deleted file mode 100644 index a3f7922999..0000000000 --- a/docs/source/pype.modules.idle_manager.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.modules.idle\_manager package -================================== - -.. automodule:: pype.modules.idle_manager - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.idle\_manager.idle\_manager module ------------------------------------------------ - -.. automodule:: pype.modules.idle_manager.idle_manager - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.launcher_action.rst b/docs/source/pype.modules.launcher_action.rst deleted file mode 100644 index a63408e747..0000000000 --- a/docs/source/pype.modules.launcher_action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.launcher\_action module -==================================== - -.. automodule:: pype.modules.launcher_action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.log_viewer.log_view_module.rst b/docs/source/pype.modules.log_viewer.log_view_module.rst deleted file mode 100644 index 8d80170a9c..0000000000 --- a/docs/source/pype.modules.log_viewer.log_view_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.log\_viewer.log\_view\_module module -================================================= - -.. automodule:: pype.modules.log_viewer.log_view_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.log_viewer.rst b/docs/source/pype.modules.log_viewer.rst deleted file mode 100644 index e275d56086..0000000000 --- a/docs/source/pype.modules.log_viewer.rst +++ /dev/null @@ -1,23 +0,0 @@ -pype.modules.log\_viewer package -================================ - -.. automodule:: pype.modules.log_viewer - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 10 - - pype.modules.log_viewer.tray - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.modules.log_viewer.log_view_module diff --git a/docs/source/pype.modules.log_viewer.tray.app.rst b/docs/source/pype.modules.log_viewer.tray.app.rst deleted file mode 100644 index 0948a05594..0000000000 --- a/docs/source/pype.modules.log_viewer.tray.app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.log\_viewer.tray.app module -======================================== - -.. automodule:: pype.modules.log_viewer.tray.app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.log_viewer.tray.models.rst b/docs/source/pype.modules.log_viewer.tray.models.rst deleted file mode 100644 index 4da3887600..0000000000 --- a/docs/source/pype.modules.log_viewer.tray.models.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.log\_viewer.tray.models module -=========================================== - -.. automodule:: pype.modules.log_viewer.tray.models - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.log_viewer.tray.rst b/docs/source/pype.modules.log_viewer.tray.rst deleted file mode 100644 index 5f4b92f627..0000000000 --- a/docs/source/pype.modules.log_viewer.tray.rst +++ /dev/null @@ -1,17 +0,0 @@ -pype.modules.log\_viewer.tray package -===================================== - -.. automodule:: pype.modules.log_viewer.tray - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.modules.log_viewer.tray.app - pype.modules.log_viewer.tray.models - pype.modules.log_viewer.tray.widgets diff --git a/docs/source/pype.modules.log_viewer.tray.widgets.rst b/docs/source/pype.modules.log_viewer.tray.widgets.rst deleted file mode 100644 index cb57c96559..0000000000 --- a/docs/source/pype.modules.log_viewer.tray.widgets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.log\_viewer.tray.widgets module -============================================ - -.. automodule:: pype.modules.log_viewer.tray.widgets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.muster.muster.rst b/docs/source/pype.modules.muster.muster.rst deleted file mode 100644 index d3ba1e7052..0000000000 --- a/docs/source/pype.modules.muster.muster.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.muster.muster module -================================= - -.. automodule:: pype.modules.muster.muster - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.muster.rst b/docs/source/pype.modules.muster.rst deleted file mode 100644 index d8d0f762f4..0000000000 --- a/docs/source/pype.modules.muster.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.muster package -=========================== - -.. automodule:: pype.modules.muster - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.muster.muster module ---------------------------------- - -.. automodule:: pype.modules.muster.muster - :members: - :undoc-members: - :show-inheritance: - -pype.modules.muster.widget\_login module ----------------------------------------- - -.. automodule:: pype.modules.muster.widget_login - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.muster.widget_login.rst b/docs/source/pype.modules.muster.widget_login.rst deleted file mode 100644 index 1c59cec820..0000000000 --- a/docs/source/pype.modules.muster.widget_login.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.muster.widget\_login module -======================================== - -.. automodule:: pype.modules.muster.widget_login - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.base_class.rst b/docs/source/pype.modules.rest_api.base_class.rst deleted file mode 100644 index c2a1030a78..0000000000 --- a/docs/source/pype.modules.rest_api.base_class.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.rest\_api.base\_class module -========================================= - -.. automodule:: pype.modules.rest_api.base_class - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.lib.exceptions.rst b/docs/source/pype.modules.rest_api.lib.exceptions.rst deleted file mode 100644 index d755420ad0..0000000000 --- a/docs/source/pype.modules.rest_api.lib.exceptions.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.rest\_api.lib.exceptions module -============================================ - -.. automodule:: pype.modules.rest_api.lib.exceptions - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.lib.factory.rst b/docs/source/pype.modules.rest_api.lib.factory.rst deleted file mode 100644 index 2131d1b8da..0000000000 --- a/docs/source/pype.modules.rest_api.lib.factory.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.rest\_api.lib.factory module -========================================= - -.. automodule:: pype.modules.rest_api.lib.factory - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.lib.handler.rst b/docs/source/pype.modules.rest_api.lib.handler.rst deleted file mode 100644 index 6e340daf9b..0000000000 --- a/docs/source/pype.modules.rest_api.lib.handler.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.rest\_api.lib.handler module -========================================= - -.. automodule:: pype.modules.rest_api.lib.handler - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.lib.lib.rst b/docs/source/pype.modules.rest_api.lib.lib.rst deleted file mode 100644 index 19663788e0..0000000000 --- a/docs/source/pype.modules.rest_api.lib.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.rest\_api.lib.lib module -===================================== - -.. automodule:: pype.modules.rest_api.lib.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.lib.rst b/docs/source/pype.modules.rest_api.lib.rst deleted file mode 100644 index ed8288ee73..0000000000 --- a/docs/source/pype.modules.rest_api.lib.rst +++ /dev/null @@ -1,42 +0,0 @@ -pype.modules.rest\_api.lib package -================================== - -.. automodule:: pype.modules.rest_api.lib - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.rest\_api.lib.exceptions module --------------------------------------------- - -.. automodule:: pype.modules.rest_api.lib.exceptions - :members: - :undoc-members: - :show-inheritance: - -pype.modules.rest\_api.lib.factory module ------------------------------------------ - -.. automodule:: pype.modules.rest_api.lib.factory - :members: - :undoc-members: - :show-inheritance: - -pype.modules.rest\_api.lib.handler module ------------------------------------------ - -.. automodule:: pype.modules.rest_api.lib.handler - :members: - :undoc-members: - :show-inheritance: - -pype.modules.rest\_api.lib.lib module -------------------------------------- - -.. automodule:: pype.modules.rest_api.lib.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.rest_api.rst b/docs/source/pype.modules.rest_api.rest_api.rst deleted file mode 100644 index e3d951ac9f..0000000000 --- a/docs/source/pype.modules.rest_api.rest_api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.rest\_api.rest\_api module -======================================= - -.. automodule:: pype.modules.rest_api.rest_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rest_api.rst b/docs/source/pype.modules.rest_api.rst deleted file mode 100644 index 09c58c84f8..0000000000 --- a/docs/source/pype.modules.rest_api.rst +++ /dev/null @@ -1,34 +0,0 @@ -pype.modules.rest\_api package -============================== - -.. automodule:: pype.modules.rest_api - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.modules.rest_api.lib - -Submodules ----------- - -pype.modules.rest\_api.base\_class module ------------------------------------------ - -.. automodule:: pype.modules.rest_api.base_class - :members: - :undoc-members: - :show-inheritance: - -pype.modules.rest\_api.rest\_api module ---------------------------------------- - -.. automodule:: pype.modules.rest_api.rest_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.rst b/docs/source/pype.modules.rst deleted file mode 100644 index 148c2084b4..0000000000 --- a/docs/source/pype.modules.rst +++ /dev/null @@ -1,36 +0,0 @@ -pype.modules package -==================== - -.. automodule:: pype.modules - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.modules.adobe_communicator - pype.modules.avalon_apps - pype.modules.clockify - pype.modules.ftrack - pype.modules.idle_manager - pype.modules.muster - pype.modules.rest_api - pype.modules.standalonepublish - pype.modules.timers_manager - pype.modules.user - pype.modules.websocket_server - -Submodules ----------- - -pype.modules.base module ------------------------- - -.. automodule:: pype.modules.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.settings_action.rst b/docs/source/pype.modules.settings_action.rst deleted file mode 100644 index 10f0881ced..0000000000 --- a/docs/source/pype.modules.settings_action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.settings\_action module -==================================== - -.. automodule:: pype.modules.settings_action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.standalonepublish.rst b/docs/source/pype.modules.standalonepublish.rst deleted file mode 100644 index 2ed366af5c..0000000000 --- a/docs/source/pype.modules.standalonepublish.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.modules.standalonepublish package -====================================== - -.. automodule:: pype.modules.standalonepublish - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.standalonepublish.standalonepublish\_module module ---------------------------------------------------------------- - -.. automodule:: pype.modules.standalonepublish.standalonepublish_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.standalonepublish.standalonepublish_module.rst b/docs/source/pype.modules.standalonepublish.standalonepublish_module.rst deleted file mode 100644 index a78826a4b4..0000000000 --- a/docs/source/pype.modules.standalonepublish.standalonepublish_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.standalonepublish.standalonepublish\_module module -=============================================================== - -.. automodule:: pype.modules.standalonepublish.standalonepublish_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.standalonepublish_action.rst b/docs/source/pype.modules.standalonepublish_action.rst deleted file mode 100644 index d51dbcefa0..0000000000 --- a/docs/source/pype.modules.standalonepublish_action.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.standalonepublish\_action module -============================================= - -.. automodule:: pype.modules.standalonepublish_action - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.sync_server.rst b/docs/source/pype.modules.sync_server.rst deleted file mode 100644 index a26dc7e212..0000000000 --- a/docs/source/pype.modules.sync_server.rst +++ /dev/null @@ -1,16 +0,0 @@ -pype.modules.sync\_server package -================================= - -.. automodule:: pype.modules.sync_server - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.modules.sync_server.sync_server - pype.modules.sync_server.utils diff --git a/docs/source/pype.modules.sync_server.sync_server.rst b/docs/source/pype.modules.sync_server.sync_server.rst deleted file mode 100644 index 36d6aa68ed..0000000000 --- a/docs/source/pype.modules.sync_server.sync_server.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.sync\_server.sync\_server module -============================================= - -.. automodule:: pype.modules.sync_server.sync_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.sync_server.utils.rst b/docs/source/pype.modules.sync_server.utils.rst deleted file mode 100644 index 325d5e435d..0000000000 --- a/docs/source/pype.modules.sync_server.utils.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.sync\_server.utils module -====================================== - -.. automodule:: pype.modules.sync_server.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.timers_manager.rst b/docs/source/pype.modules.timers_manager.rst deleted file mode 100644 index 6c971e9dc1..0000000000 --- a/docs/source/pype.modules.timers_manager.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.timers\_manager package -==================================== - -.. automodule:: pype.modules.timers_manager - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.timers\_manager.timers\_manager module ---------------------------------------------------- - -.. automodule:: pype.modules.timers_manager.timers_manager - :members: - :undoc-members: - :show-inheritance: - -pype.modules.timers\_manager.widget\_user\_idle module ------------------------------------------------------- - -.. automodule:: pype.modules.timers_manager.widget_user_idle - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.timers_manager.timers_manager.rst b/docs/source/pype.modules.timers_manager.timers_manager.rst deleted file mode 100644 index fe18e4d15c..0000000000 --- a/docs/source/pype.modules.timers_manager.timers_manager.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.timers\_manager.timers\_manager module -=================================================== - -.. automodule:: pype.modules.timers_manager.timers_manager - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.timers_manager.widget_user_idle.rst b/docs/source/pype.modules.timers_manager.widget_user_idle.rst deleted file mode 100644 index b072879c7a..0000000000 --- a/docs/source/pype.modules.timers_manager.widget_user_idle.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.timers\_manager.widget\_user\_idle module -====================================================== - -.. automodule:: pype.modules.timers_manager.widget_user_idle - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.user.rst b/docs/source/pype.modules.user.rst deleted file mode 100644 index d181b263e5..0000000000 --- a/docs/source/pype.modules.user.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.user package -========================= - -.. automodule:: pype.modules.user - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.user.user\_module module -------------------------------------- - -.. automodule:: pype.modules.user.user_module - :members: - :undoc-members: - :show-inheritance: - -pype.modules.user.widget\_user module -------------------------------------- - -.. automodule:: pype.modules.user.widget_user - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.user.user_module.rst b/docs/source/pype.modules.user.user_module.rst deleted file mode 100644 index a8e0cd6bad..0000000000 --- a/docs/source/pype.modules.user.user_module.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.user.user\_module module -===================================== - -.. automodule:: pype.modules.user.user_module - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.user.widget_user.rst b/docs/source/pype.modules.user.widget_user.rst deleted file mode 100644 index 2979e5ead4..0000000000 --- a/docs/source/pype.modules.user.widget_user.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.user.widget\_user module -===================================== - -.. automodule:: pype.modules.user.widget_user - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.websocket_server.hosts.aftereffects.rst b/docs/source/pype.modules.websocket_server.hosts.aftereffects.rst deleted file mode 100644 index 9f4720ae14..0000000000 --- a/docs/source/pype.modules.websocket_server.hosts.aftereffects.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.websocket\_server.hosts.aftereffects module -======================================================== - -.. automodule:: pype.modules.websocket_server.hosts.aftereffects - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.websocket_server.hosts.external_app_1.rst b/docs/source/pype.modules.websocket_server.hosts.external_app_1.rst deleted file mode 100644 index 4ac69d9015..0000000000 --- a/docs/source/pype.modules.websocket_server.hosts.external_app_1.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.websocket\_server.hosts.external\_app\_1 module -============================================================ - -.. automodule:: pype.modules.websocket_server.hosts.external_app_1 - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.websocket_server.hosts.photoshop.rst b/docs/source/pype.modules.websocket_server.hosts.photoshop.rst deleted file mode 100644 index cbda61275a..0000000000 --- a/docs/source/pype.modules.websocket_server.hosts.photoshop.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.websocket\_server.hosts.photoshop module -===================================================== - -.. automodule:: pype.modules.websocket_server.hosts.photoshop - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.websocket_server.hosts.rst b/docs/source/pype.modules.websocket_server.hosts.rst deleted file mode 100644 index d5ce7c3f8e..0000000000 --- a/docs/source/pype.modules.websocket_server.hosts.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.websocket\_server.hosts package -============================================ - -.. automodule:: pype.modules.websocket_server.hosts - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.modules.websocket\_server.hosts.external\_app\_1 module ------------------------------------------------------------- - -.. automodule:: pype.modules.websocket_server.hosts.external_app_1 - :members: - :undoc-members: - :show-inheritance: - -pype.modules.websocket\_server.hosts.photoshop module ------------------------------------------------------ - -.. automodule:: pype.modules.websocket_server.hosts.photoshop - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.websocket_server.rst b/docs/source/pype.modules.websocket_server.rst deleted file mode 100644 index a83d371df1..0000000000 --- a/docs/source/pype.modules.websocket_server.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.modules.websocket\_server package -====================================== - -.. automodule:: pype.modules.websocket_server - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.modules.websocket_server.hosts - -Submodules ----------- - -pype.modules.websocket\_server.websocket\_server module -------------------------------------------------------- - -.. automodule:: pype.modules.websocket_server.websocket_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules.websocket_server.websocket_server.rst b/docs/source/pype.modules.websocket_server.websocket_server.rst deleted file mode 100644 index 354c9e6cf9..0000000000 --- a/docs/source/pype.modules.websocket_server.websocket_server.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules.websocket\_server.websocket\_server module -======================================================= - -.. automodule:: pype.modules.websocket_server.websocket_server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.modules_manager.rst b/docs/source/pype.modules_manager.rst deleted file mode 100644 index a5f2327d65..0000000000 --- a/docs/source/pype.modules_manager.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.modules\_manager module -============================ - -.. automodule:: pype.modules_manager - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugin.rst b/docs/source/pype.plugin.rst deleted file mode 100644 index c20bb77b2b..0000000000 --- a/docs/source/pype.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugin module -================== - -.. automodule:: pype.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_animation.rst b/docs/source/pype.plugins.maya.publish.collect_animation.rst deleted file mode 100644 index 497c497057..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_animation.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_animation module -=================================================== - -.. automodule:: pype.plugins.maya.publish.collect_animation - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_ass.rst b/docs/source/pype.plugins.maya.publish.collect_ass.rst deleted file mode 100644 index a44e61ce98..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_ass.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_ass module -============================================= - -.. automodule:: pype.plugins.maya.publish.collect_ass - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_assembly.rst b/docs/source/pype.plugins.maya.publish.collect_assembly.rst deleted file mode 100644 index 5baa91818b..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_assembly.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_assembly module -================================================== - -.. automodule:: pype.plugins.maya.publish.collect_assembly - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_file_dependencies.rst b/docs/source/pype.plugins.maya.publish.collect_file_dependencies.rst deleted file mode 100644 index efe857140e..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_file_dependencies.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_file\_dependencies module -============================================================ - -.. automodule:: pype.plugins.maya.publish.collect_file_dependencies - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_ftrack_family.rst b/docs/source/pype.plugins.maya.publish.collect_ftrack_family.rst deleted file mode 100644 index 872bbc69a4..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_ftrack_family.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_ftrack\_family module -======================================================== - -.. automodule:: pype.plugins.maya.publish.collect_ftrack_family - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_history.rst b/docs/source/pype.plugins.maya.publish.collect_history.rst deleted file mode 100644 index 5a98778c24..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_history.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_history module -================================================= - -.. automodule:: pype.plugins.maya.publish.collect_history - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_instances.rst b/docs/source/pype.plugins.maya.publish.collect_instances.rst deleted file mode 100644 index 33c8b97597..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_instances.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_instances module -=================================================== - -.. automodule:: pype.plugins.maya.publish.collect_instances - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_look.rst b/docs/source/pype.plugins.maya.publish.collect_look.rst deleted file mode 100644 index 234fcf20d1..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_look.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_look module -============================================== - -.. automodule:: pype.plugins.maya.publish.collect_look - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_maya_units.rst b/docs/source/pype.plugins.maya.publish.collect_maya_units.rst deleted file mode 100644 index 0cb01b0fa7..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_maya_units.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_maya\_units module -===================================================== - -.. automodule:: pype.plugins.maya.publish.collect_maya_units - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_maya_workspace.rst b/docs/source/pype.plugins.maya.publish.collect_maya_workspace.rst deleted file mode 100644 index 7447052004..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_maya_workspace.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_maya\_workspace module -========================================================= - -.. automodule:: pype.plugins.maya.publish.collect_maya_workspace - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_mayaascii.rst b/docs/source/pype.plugins.maya.publish.collect_mayaascii.rst deleted file mode 100644 index 14fe826229..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_mayaascii.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_mayaascii module -=================================================== - -.. automodule:: pype.plugins.maya.publish.collect_mayaascii - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_model.rst b/docs/source/pype.plugins.maya.publish.collect_model.rst deleted file mode 100644 index b30bf3fb22..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_model.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_model module -=============================================== - -.. automodule:: pype.plugins.maya.publish.collect_model - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_remove_marked.rst b/docs/source/pype.plugins.maya.publish.collect_remove_marked.rst deleted file mode 100644 index a0bf9498d7..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_remove_marked.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_remove\_marked module -======================================================== - -.. automodule:: pype.plugins.maya.publish.collect_remove_marked - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_render.rst b/docs/source/pype.plugins.maya.publish.collect_render.rst deleted file mode 100644 index 6de8827119..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_render.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_render module -================================================ - -.. automodule:: pype.plugins.maya.publish.collect_render - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_render_layer_aovs.rst b/docs/source/pype.plugins.maya.publish.collect_render_layer_aovs.rst deleted file mode 100644 index ab511fc5dd..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_render_layer_aovs.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_render\_layer\_aovs module -============================================================= - -.. automodule:: pype.plugins.maya.publish.collect_render_layer_aovs - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_renderable_camera.rst b/docs/source/pype.plugins.maya.publish.collect_renderable_camera.rst deleted file mode 100644 index c98e8000a1..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_renderable_camera.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_renderable\_camera module -============================================================ - -.. automodule:: pype.plugins.maya.publish.collect_renderable_camera - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_review.rst b/docs/source/pype.plugins.maya.publish.collect_review.rst deleted file mode 100644 index d73127aa85..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_review.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_review module -================================================ - -.. automodule:: pype.plugins.maya.publish.collect_review - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_rig.rst b/docs/source/pype.plugins.maya.publish.collect_rig.rst deleted file mode 100644 index e7c0528482..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_rig.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_rig module -============================================= - -.. automodule:: pype.plugins.maya.publish.collect_rig - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_scene.rst b/docs/source/pype.plugins.maya.publish.collect_scene.rst deleted file mode 100644 index c5c2fef222..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_scene.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_scene module -=============================================== - -.. automodule:: pype.plugins.maya.publish.collect_scene - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_unreal_staticmesh.rst b/docs/source/pype.plugins.maya.publish.collect_unreal_staticmesh.rst deleted file mode 100644 index 673f0865fd..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_unreal_staticmesh.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_unreal\_staticmesh module -============================================================ - -.. automodule:: pype.plugins.maya.publish.collect_unreal_staticmesh - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_workscene_fps.rst b/docs/source/pype.plugins.maya.publish.collect_workscene_fps.rst deleted file mode 100644 index ed4386a7ba..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_workscene_fps.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_workscene\_fps module -======================================================== - -.. automodule:: pype.plugins.maya.publish.collect_workscene_fps - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_yeti_cache.rst b/docs/source/pype.plugins.maya.publish.collect_yeti_cache.rst deleted file mode 100644 index 32ab50baca..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_yeti_cache.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_yeti\_cache module -===================================================== - -.. automodule:: pype.plugins.maya.publish.collect_yeti_cache - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.collect_yeti_rig.rst b/docs/source/pype.plugins.maya.publish.collect_yeti_rig.rst deleted file mode 100644 index 8cf968b7c5..0000000000 --- a/docs/source/pype.plugins.maya.publish.collect_yeti_rig.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.collect\_yeti\_rig module -=================================================== - -.. automodule:: pype.plugins.maya.publish.collect_yeti_rig - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.determine_future_version.rst b/docs/source/pype.plugins.maya.publish.determine_future_version.rst deleted file mode 100644 index 55c6155680..0000000000 --- a/docs/source/pype.plugins.maya.publish.determine_future_version.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.determine\_future\_version module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.determine_future_version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_animation.rst b/docs/source/pype.plugins.maya.publish.extract_animation.rst deleted file mode 100644 index 3649723042..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_animation.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_animation module -=================================================== - -.. automodule:: pype.plugins.maya.publish.extract_animation - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_ass.rst b/docs/source/pype.plugins.maya.publish.extract_ass.rst deleted file mode 100644 index be8123e5d7..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_ass.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_ass module -============================================= - -.. automodule:: pype.plugins.maya.publish.extract_ass - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_assembly.rst b/docs/source/pype.plugins.maya.publish.extract_assembly.rst deleted file mode 100644 index b36e8f6d30..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_assembly.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_assembly module -================================================== - -.. automodule:: pype.plugins.maya.publish.extract_assembly - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_assproxy.rst b/docs/source/pype.plugins.maya.publish.extract_assproxy.rst deleted file mode 100644 index fc97a2ee46..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_assproxy.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_assproxy module -================================================== - -.. automodule:: pype.plugins.maya.publish.extract_assproxy - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_camera_alembic.rst b/docs/source/pype.plugins.maya.publish.extract_camera_alembic.rst deleted file mode 100644 index a9df3da011..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_camera_alembic.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_camera\_alembic module -========================================================= - -.. automodule:: pype.plugins.maya.publish.extract_camera_alembic - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_camera_mayaScene.rst b/docs/source/pype.plugins.maya.publish.extract_camera_mayaScene.rst deleted file mode 100644 index db1799f52f..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_camera_mayaScene.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_camera\_mayaScene module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.extract_camera_mayaScene - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_fbx.rst b/docs/source/pype.plugins.maya.publish.extract_fbx.rst deleted file mode 100644 index fffd5a6394..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_fbx.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_fbx module -============================================= - -.. automodule:: pype.plugins.maya.publish.extract_fbx - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_look.rst b/docs/source/pype.plugins.maya.publish.extract_look.rst deleted file mode 100644 index f2708678ce..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_look.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_look module -============================================== - -.. automodule:: pype.plugins.maya.publish.extract_look - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_maya_scene_raw.rst b/docs/source/pype.plugins.maya.publish.extract_maya_scene_raw.rst deleted file mode 100644 index 1e080dd0eb..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_maya_scene_raw.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_maya\_scene\_raw module -========================================================== - -.. automodule:: pype.plugins.maya.publish.extract_maya_scene_raw - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_model.rst b/docs/source/pype.plugins.maya.publish.extract_model.rst deleted file mode 100644 index c78b49c777..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_model.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_model module -=============================================== - -.. automodule:: pype.plugins.maya.publish.extract_model - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_playblast.rst b/docs/source/pype.plugins.maya.publish.extract_playblast.rst deleted file mode 100644 index 1aa284b370..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_playblast.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_playblast module -=================================================== - -.. automodule:: pype.plugins.maya.publish.extract_playblast - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_pointcache.rst b/docs/source/pype.plugins.maya.publish.extract_pointcache.rst deleted file mode 100644 index 97ebde4933..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_pointcache.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_pointcache module -==================================================== - -.. automodule:: pype.plugins.maya.publish.extract_pointcache - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_rendersetup.rst b/docs/source/pype.plugins.maya.publish.extract_rendersetup.rst deleted file mode 100644 index 86cb178f42..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_rendersetup.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_rendersetup module -===================================================== - -.. automodule:: pype.plugins.maya.publish.extract_rendersetup - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_rig.rst b/docs/source/pype.plugins.maya.publish.extract_rig.rst deleted file mode 100644 index f6419c9473..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_rig.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_rig module -============================================= - -.. automodule:: pype.plugins.maya.publish.extract_rig - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_thumbnail.rst b/docs/source/pype.plugins.maya.publish.extract_thumbnail.rst deleted file mode 100644 index 2d03e11d55..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_thumbnail.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_thumbnail module -=================================================== - -.. automodule:: pype.plugins.maya.publish.extract_thumbnail - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_vrayproxy.rst b/docs/source/pype.plugins.maya.publish.extract_vrayproxy.rst deleted file mode 100644 index 5439ff59ca..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_vrayproxy.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_vrayproxy module -=================================================== - -.. automodule:: pype.plugins.maya.publish.extract_vrayproxy - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_yeti_cache.rst b/docs/source/pype.plugins.maya.publish.extract_yeti_cache.rst deleted file mode 100644 index 7ad84dfc70..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_yeti_cache.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_yeti\_cache module -===================================================== - -.. automodule:: pype.plugins.maya.publish.extract_yeti_cache - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.extract_yeti_rig.rst b/docs/source/pype.plugins.maya.publish.extract_yeti_rig.rst deleted file mode 100644 index 76d483d91b..0000000000 --- a/docs/source/pype.plugins.maya.publish.extract_yeti_rig.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.extract\_yeti\_rig module -=================================================== - -.. automodule:: pype.plugins.maya.publish.extract_yeti_rig - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.increment_current_file_deadline.rst b/docs/source/pype.plugins.maya.publish.increment_current_file_deadline.rst deleted file mode 100644 index 97126a6c77..0000000000 --- a/docs/source/pype.plugins.maya.publish.increment_current_file_deadline.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.increment\_current\_file\_deadline module -=================================================================== - -.. automodule:: pype.plugins.maya.publish.increment_current_file_deadline - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.rst b/docs/source/pype.plugins.maya.publish.rst deleted file mode 100644 index dba0a9118c..0000000000 --- a/docs/source/pype.plugins.maya.publish.rst +++ /dev/null @@ -1,146 +0,0 @@ -pype.plugins.maya.publish package -================================= - -.. automodule:: pype.plugins.maya.publish - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.plugins.maya.publish.collect_animation - pype.plugins.maya.publish.collect_ass - pype.plugins.maya.publish.collect_assembly - pype.plugins.maya.publish.collect_file_dependencies - pype.plugins.maya.publish.collect_ftrack_family - pype.plugins.maya.publish.collect_history - pype.plugins.maya.publish.collect_instances - pype.plugins.maya.publish.collect_look - pype.plugins.maya.publish.collect_maya_units - pype.plugins.maya.publish.collect_maya_workspace - pype.plugins.maya.publish.collect_mayaascii - pype.plugins.maya.publish.collect_model - pype.plugins.maya.publish.collect_remove_marked - pype.plugins.maya.publish.collect_render - pype.plugins.maya.publish.collect_render_layer_aovs - pype.plugins.maya.publish.collect_renderable_camera - pype.plugins.maya.publish.collect_review - pype.plugins.maya.publish.collect_rig - pype.plugins.maya.publish.collect_scene - pype.plugins.maya.publish.collect_unreal_staticmesh - pype.plugins.maya.publish.collect_workscene_fps - pype.plugins.maya.publish.collect_yeti_cache - pype.plugins.maya.publish.collect_yeti_rig - pype.plugins.maya.publish.determine_future_version - pype.plugins.maya.publish.extract_animation - pype.plugins.maya.publish.extract_ass - pype.plugins.maya.publish.extract_assembly - pype.plugins.maya.publish.extract_assproxy - pype.plugins.maya.publish.extract_camera_alembic - pype.plugins.maya.publish.extract_camera_mayaScene - pype.plugins.maya.publish.extract_fbx - pype.plugins.maya.publish.extract_look - pype.plugins.maya.publish.extract_maya_scene_raw - pype.plugins.maya.publish.extract_model - pype.plugins.maya.publish.extract_playblast - pype.plugins.maya.publish.extract_pointcache - pype.plugins.maya.publish.extract_rendersetup - pype.plugins.maya.publish.extract_rig - pype.plugins.maya.publish.extract_thumbnail - pype.plugins.maya.publish.extract_vrayproxy - pype.plugins.maya.publish.extract_yeti_cache - pype.plugins.maya.publish.extract_yeti_rig - pype.plugins.maya.publish.increment_current_file_deadline - pype.plugins.maya.publish.save_scene - pype.plugins.maya.publish.submit_maya_deadline - pype.plugins.maya.publish.submit_maya_muster - pype.plugins.maya.publish.validate_animation_content - pype.plugins.maya.publish.validate_animation_out_set_related_node_ids - pype.plugins.maya.publish.validate_ass_relative_paths - pype.plugins.maya.publish.validate_assembly_name - pype.plugins.maya.publish.validate_assembly_namespaces - pype.plugins.maya.publish.validate_assembly_transforms - pype.plugins.maya.publish.validate_attributes - pype.plugins.maya.publish.validate_camera_attributes - pype.plugins.maya.publish.validate_camera_contents - pype.plugins.maya.publish.validate_color_sets - pype.plugins.maya.publish.validate_current_renderlayer_renderable - pype.plugins.maya.publish.validate_deadline_connection - pype.plugins.maya.publish.validate_frame_range - pype.plugins.maya.publish.validate_instance_has_members - pype.plugins.maya.publish.validate_instance_subset - pype.plugins.maya.publish.validate_instancer_content - pype.plugins.maya.publish.validate_instancer_frame_ranges - pype.plugins.maya.publish.validate_joints_hidden - pype.plugins.maya.publish.validate_look_contents - pype.plugins.maya.publish.validate_look_default_shaders_connections - pype.plugins.maya.publish.validate_look_id_reference_edits - pype.plugins.maya.publish.validate_look_members_unique - pype.plugins.maya.publish.validate_look_no_default_shaders - pype.plugins.maya.publish.validate_look_sets - pype.plugins.maya.publish.validate_look_shading_group - pype.plugins.maya.publish.validate_look_single_shader - pype.plugins.maya.publish.validate_maya_units - pype.plugins.maya.publish.validate_mesh_arnold_attributes - pype.plugins.maya.publish.validate_mesh_has_uv - pype.plugins.maya.publish.validate_mesh_lamina_faces - pype.plugins.maya.publish.validate_mesh_no_negative_scale - pype.plugins.maya.publish.validate_mesh_non_manifold - pype.plugins.maya.publish.validate_mesh_non_zero_edge - pype.plugins.maya.publish.validate_mesh_normals_unlocked - pype.plugins.maya.publish.validate_mesh_overlapping_uvs - pype.plugins.maya.publish.validate_mesh_shader_connections - pype.plugins.maya.publish.validate_mesh_single_uv_set - pype.plugins.maya.publish.validate_mesh_uv_set_map1 - pype.plugins.maya.publish.validate_mesh_vertices_have_edges - pype.plugins.maya.publish.validate_model_content - pype.plugins.maya.publish.validate_model_name - pype.plugins.maya.publish.validate_muster_connection - pype.plugins.maya.publish.validate_no_animation - pype.plugins.maya.publish.validate_no_default_camera - pype.plugins.maya.publish.validate_no_namespace - pype.plugins.maya.publish.validate_no_null_transforms - pype.plugins.maya.publish.validate_no_unknown_nodes - pype.plugins.maya.publish.validate_no_vraymesh - pype.plugins.maya.publish.validate_node_ids - pype.plugins.maya.publish.validate_node_ids_deformed_shapes - pype.plugins.maya.publish.validate_node_ids_in_database - pype.plugins.maya.publish.validate_node_ids_related - pype.plugins.maya.publish.validate_node_ids_unique - pype.plugins.maya.publish.validate_node_no_ghosting - pype.plugins.maya.publish.validate_render_image_rule - pype.plugins.maya.publish.validate_render_no_default_cameras - pype.plugins.maya.publish.validate_render_single_camera - pype.plugins.maya.publish.validate_renderlayer_aovs - pype.plugins.maya.publish.validate_rendersettings - pype.plugins.maya.publish.validate_resources - pype.plugins.maya.publish.validate_rig_contents - pype.plugins.maya.publish.validate_rig_controllers - pype.plugins.maya.publish.validate_rig_controllers_arnold_attributes - pype.plugins.maya.publish.validate_rig_out_set_node_ids - pype.plugins.maya.publish.validate_rig_output_ids - pype.plugins.maya.publish.validate_scene_set_workspace - pype.plugins.maya.publish.validate_shader_name - pype.plugins.maya.publish.validate_shape_default_names - pype.plugins.maya.publish.validate_shape_render_stats - pype.plugins.maya.publish.validate_single_assembly - pype.plugins.maya.publish.validate_skinCluster_deformer_set - pype.plugins.maya.publish.validate_step_size - pype.plugins.maya.publish.validate_transform_naming_suffix - pype.plugins.maya.publish.validate_transform_zero - pype.plugins.maya.publish.validate_unicode_strings - pype.plugins.maya.publish.validate_unreal_mesh_triangulated - pype.plugins.maya.publish.validate_unreal_staticmesh_naming - pype.plugins.maya.publish.validate_unreal_up_axis - pype.plugins.maya.publish.validate_vray_distributed_rendering - pype.plugins.maya.publish.validate_vray_translator_settings - pype.plugins.maya.publish.validate_vrayproxy - pype.plugins.maya.publish.validate_vrayproxy_members - pype.plugins.maya.publish.validate_yeti_renderscript_callbacks - pype.plugins.maya.publish.validate_yeti_rig_cache_state - pype.plugins.maya.publish.validate_yeti_rig_input_in_instance - pype.plugins.maya.publish.validate_yeti_rig_settings diff --git a/docs/source/pype.plugins.maya.publish.save_scene.rst b/docs/source/pype.plugins.maya.publish.save_scene.rst deleted file mode 100644 index 2537bca03d..0000000000 --- a/docs/source/pype.plugins.maya.publish.save_scene.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.save\_scene module -============================================ - -.. automodule:: pype.plugins.maya.publish.save_scene - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.submit_maya_deadline.rst b/docs/source/pype.plugins.maya.publish.submit_maya_deadline.rst deleted file mode 100644 index 0e521cec4e..0000000000 --- a/docs/source/pype.plugins.maya.publish.submit_maya_deadline.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.submit\_maya\_deadline module -======================================================= - -.. automodule:: pype.plugins.maya.publish.submit_maya_deadline - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.submit_maya_muster.rst b/docs/source/pype.plugins.maya.publish.submit_maya_muster.rst deleted file mode 100644 index 4ae263e157..0000000000 --- a/docs/source/pype.plugins.maya.publish.submit_maya_muster.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.submit\_maya\_muster module -===================================================== - -.. automodule:: pype.plugins.maya.publish.submit_maya_muster - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_animation_content.rst b/docs/source/pype.plugins.maya.publish.validate_animation_content.rst deleted file mode 100644 index 65191bb957..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_animation_content.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_animation\_content module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_animation_content - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_animation_out_set_related_node_ids.rst b/docs/source/pype.plugins.maya.publish.validate_animation_out_set_related_node_ids.rst deleted file mode 100644 index ea289e84ed..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_animation_out_set_related_node_ids.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_animation\_out\_set\_related\_node\_ids module -================================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_animation_out_set_related_node_ids - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_ass_relative_paths.rst b/docs/source/pype.plugins.maya.publish.validate_ass_relative_paths.rst deleted file mode 100644 index f35ef916cc..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_ass_relative_paths.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_ass\_relative\_paths module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_ass_relative_paths - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_assembly_name.rst b/docs/source/pype.plugins.maya.publish.validate_assembly_name.rst deleted file mode 100644 index c8178226b2..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_assembly_name.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_assembly\_name module -========================================================= - -.. automodule:: pype.plugins.maya.publish.validate_assembly_name - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_assembly_namespaces.rst b/docs/source/pype.plugins.maya.publish.validate_assembly_namespaces.rst deleted file mode 100644 index 847b90281e..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_assembly_namespaces.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_assembly\_namespaces module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_assembly_namespaces - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_assembly_transforms.rst b/docs/source/pype.plugins.maya.publish.validate_assembly_transforms.rst deleted file mode 100644 index b4348a2908..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_assembly_transforms.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_assembly\_transforms module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_assembly_transforms - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_attributes.rst b/docs/source/pype.plugins.maya.publish.validate_attributes.rst deleted file mode 100644 index 862820a7c0..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_attributes.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_attributes module -===================================================== - -.. automodule:: pype.plugins.maya.publish.validate_attributes - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_camera_attributes.rst b/docs/source/pype.plugins.maya.publish.validate_camera_attributes.rst deleted file mode 100644 index 054198f812..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_camera_attributes.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_camera\_attributes module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_camera_attributes - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_camera_contents.rst b/docs/source/pype.plugins.maya.publish.validate_camera_contents.rst deleted file mode 100644 index 9cf6604f7a..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_camera_contents.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_camera\_contents module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_camera_contents - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_color_sets.rst b/docs/source/pype.plugins.maya.publish.validate_color_sets.rst deleted file mode 100644 index 59bb5607bf..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_color_sets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_color\_sets module -====================================================== - -.. automodule:: pype.plugins.maya.publish.validate_color_sets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_current_renderlayer_renderable.rst b/docs/source/pype.plugins.maya.publish.validate_current_renderlayer_renderable.rst deleted file mode 100644 index 31c52477aa..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_current_renderlayer_renderable.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_current\_renderlayer\_renderable module -=========================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_current_renderlayer_renderable - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_deadline_connection.rst b/docs/source/pype.plugins.maya.publish.validate_deadline_connection.rst deleted file mode 100644 index 3f8c4b6313..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_deadline_connection.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_deadline\_connection module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_deadline_connection - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_frame_range.rst b/docs/source/pype.plugins.maya.publish.validate_frame_range.rst deleted file mode 100644 index 0ccc8ed1cd..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_frame_range.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_frame\_range module -======================================================= - -.. automodule:: pype.plugins.maya.publish.validate_frame_range - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_instance_has_members.rst b/docs/source/pype.plugins.maya.publish.validate_instance_has_members.rst deleted file mode 100644 index 862d32f114..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_instance_has_members.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_instance\_has\_members module -================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_instance_has_members - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_instance_subset.rst b/docs/source/pype.plugins.maya.publish.validate_instance_subset.rst deleted file mode 100644 index f71febb73c..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_instance_subset.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_instance\_subset module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_instance_subset - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_instancer_content.rst b/docs/source/pype.plugins.maya.publish.validate_instancer_content.rst deleted file mode 100644 index 761889dd4d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_instancer_content.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_instancer\_content module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_instancer_content - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_instancer_frame_ranges.rst b/docs/source/pype.plugins.maya.publish.validate_instancer_frame_ranges.rst deleted file mode 100644 index 85338c3e2d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_instancer_frame_ranges.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_instancer\_frame\_ranges module -=================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_instancer_frame_ranges - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_joints_hidden.rst b/docs/source/pype.plugins.maya.publish.validate_joints_hidden.rst deleted file mode 100644 index ede5af0c67..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_joints_hidden.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_joints\_hidden module -========================================================= - -.. automodule:: pype.plugins.maya.publish.validate_joints_hidden - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_contents.rst b/docs/source/pype.plugins.maya.publish.validate_look_contents.rst deleted file mode 100644 index 946f924fb3..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_contents.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_contents module -========================================================= - -.. automodule:: pype.plugins.maya.publish.validate_look_contents - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_default_shaders_connections.rst b/docs/source/pype.plugins.maya.publish.validate_look_default_shaders_connections.rst deleted file mode 100644 index e293cfc0f1..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_default_shaders_connections.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_default\_shaders\_connections module -============================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_look_default_shaders_connections - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_id_reference_edits.rst b/docs/source/pype.plugins.maya.publish.validate_look_id_reference_edits.rst deleted file mode 100644 index 007f4e2d03..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_id_reference_edits.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_id\_reference\_edits module -===================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_look_id_reference_edits - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_members_unique.rst b/docs/source/pype.plugins.maya.publish.validate_look_members_unique.rst deleted file mode 100644 index 3378e8a0f6..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_members_unique.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_members\_unique module -================================================================ - -.. automodule:: pype.plugins.maya.publish.validate_look_members_unique - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_no_default_shaders.rst b/docs/source/pype.plugins.maya.publish.validate_look_no_default_shaders.rst deleted file mode 100644 index 662e2c7621..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_no_default_shaders.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_no\_default\_shaders module -===================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_look_no_default_shaders - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_sets.rst b/docs/source/pype.plugins.maya.publish.validate_look_sets.rst deleted file mode 100644 index 5427331568..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_sets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_sets module -===================================================== - -.. automodule:: pype.plugins.maya.publish.validate_look_sets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_shading_group.rst b/docs/source/pype.plugins.maya.publish.validate_look_shading_group.rst deleted file mode 100644 index 259f4952b7..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_shading_group.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_shading\_group module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_look_shading_group - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_look_single_shader.rst b/docs/source/pype.plugins.maya.publish.validate_look_single_shader.rst deleted file mode 100644 index fa43283416..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_look_single_shader.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_look\_single\_shader module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_look_single_shader - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_maya_units.rst b/docs/source/pype.plugins.maya.publish.validate_maya_units.rst deleted file mode 100644 index 16af19f6d9..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_maya_units.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_maya\_units module -====================================================== - -.. automodule:: pype.plugins.maya.publish.validate_maya_units - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_arnold_attributes.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_arnold_attributes.rst deleted file mode 100644 index ef18ad1457..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_arnold_attributes.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_arnold\_attributes module -=================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_arnold_attributes - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_has_uv.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_has_uv.rst deleted file mode 100644 index c6af7063c3..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_has_uv.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_has\_uv module -======================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_has_uv - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_lamina_faces.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_lamina_faces.rst deleted file mode 100644 index 006488e77f..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_lamina_faces.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_lamina\_faces module -============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_lamina_faces - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_no_negative_scale.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_no_negative_scale.rst deleted file mode 100644 index 8720f3d018..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_no_negative_scale.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_no\_negative\_scale module -==================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_no_negative_scale - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_non_manifold.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_non_manifold.rst deleted file mode 100644 index a69a4c6fc4..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_non_manifold.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_non\_manifold module -============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_non_manifold - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_non_zero_edge.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_non_zero_edge.rst deleted file mode 100644 index 89ea60d1bc..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_non_zero_edge.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_non\_zero\_edge module -================================================================ - -.. automodule:: pype.plugins.maya.publish.validate_mesh_non_zero_edge - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_normals_unlocked.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_normals_unlocked.rst deleted file mode 100644 index 7dfbd0717d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_normals_unlocked.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_normals\_unlocked module -================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_normals_unlocked - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_overlapping_uvs.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_overlapping_uvs.rst deleted file mode 100644 index f5df633124..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_overlapping_uvs.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_overlapping\_uvs module -================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_mesh_overlapping_uvs - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_shader_connections.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_shader_connections.rst deleted file mode 100644 index b3cd77ab2a..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_shader_connections.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_shader\_connections module -==================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_shader_connections - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_single_uv_set.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_single_uv_set.rst deleted file mode 100644 index 29a1217437..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_single_uv_set.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_single\_uv\_set module -================================================================ - -.. automodule:: pype.plugins.maya.publish.validate_mesh_single_uv_set - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_uv_set_map1.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_uv_set_map1.rst deleted file mode 100644 index 49d1b22497..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_uv_set_map1.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_uv\_set\_map1 module -============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_uv_set_map1 - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_mesh_vertices_have_edges.rst b/docs/source/pype.plugins.maya.publish.validate_mesh_vertices_have_edges.rst deleted file mode 100644 index 99e3047e3d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_mesh_vertices_have_edges.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_mesh\_vertices\_have\_edges module -====================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_mesh_vertices_have_edges - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_model_content.rst b/docs/source/pype.plugins.maya.publish.validate_model_content.rst deleted file mode 100644 index dc0a415718..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_model_content.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_model\_content module -========================================================= - -.. automodule:: pype.plugins.maya.publish.validate_model_content - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_model_name.rst b/docs/source/pype.plugins.maya.publish.validate_model_name.rst deleted file mode 100644 index ea78ceea70..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_model_name.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_model\_name module -====================================================== - -.. automodule:: pype.plugins.maya.publish.validate_model_name - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_muster_connection.rst b/docs/source/pype.plugins.maya.publish.validate_muster_connection.rst deleted file mode 100644 index 4a4a1e926b..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_muster_connection.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_muster\_connection module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_muster_connection - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_no_animation.rst b/docs/source/pype.plugins.maya.publish.validate_no_animation.rst deleted file mode 100644 index b42021369d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_no_animation.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_no\_animation module -======================================================== - -.. automodule:: pype.plugins.maya.publish.validate_no_animation - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_no_default_camera.rst b/docs/source/pype.plugins.maya.publish.validate_no_default_camera.rst deleted file mode 100644 index 59544369f6..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_no_default_camera.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_no\_default\_camera module -============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_no_default_camera - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_no_namespace.rst b/docs/source/pype.plugins.maya.publish.validate_no_namespace.rst deleted file mode 100644 index bdf4ceb324..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_no_namespace.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_no\_namespace module -======================================================== - -.. automodule:: pype.plugins.maya.publish.validate_no_namespace - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_no_null_transforms.rst b/docs/source/pype.plugins.maya.publish.validate_no_null_transforms.rst deleted file mode 100644 index 12beed8c33..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_no_null_transforms.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_no\_null\_transforms module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_no_null_transforms - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_no_unknown_nodes.rst b/docs/source/pype.plugins.maya.publish.validate_no_unknown_nodes.rst deleted file mode 100644 index 12c977dbb9..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_no_unknown_nodes.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_no\_unknown\_nodes module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_no_unknown_nodes - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_no_vraymesh.rst b/docs/source/pype.plugins.maya.publish.validate_no_vraymesh.rst deleted file mode 100644 index a1a0b9ee64..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_no_vraymesh.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_no\_vraymesh module -======================================================= - -.. automodule:: pype.plugins.maya.publish.validate_no_vraymesh - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_node_ids.rst b/docs/source/pype.plugins.maya.publish.validate_node_ids.rst deleted file mode 100644 index 7b1d79100f..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_node_ids.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_node\_ids module -==================================================== - -.. automodule:: pype.plugins.maya.publish.validate_node_ids - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_node_ids_deformed_shapes.rst b/docs/source/pype.plugins.maya.publish.validate_node_ids_deformed_shapes.rst deleted file mode 100644 index 90ef81c5b5..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_node_ids_deformed_shapes.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_node\_ids\_deformed\_shapes module -====================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_node_ids_deformed_shapes - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_node_ids_in_database.rst b/docs/source/pype.plugins.maya.publish.validate_node_ids_in_database.rst deleted file mode 100644 index 5eb0047d16..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_node_ids_in_database.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_node\_ids\_in\_database module -================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_node_ids_in_database - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_node_ids_related.rst b/docs/source/pype.plugins.maya.publish.validate_node_ids_related.rst deleted file mode 100644 index 1f030462ae..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_node_ids_related.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_node\_ids\_related module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_node_ids_related - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_node_ids_unique.rst b/docs/source/pype.plugins.maya.publish.validate_node_ids_unique.rst deleted file mode 100644 index 20ba3a3a6d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_node_ids_unique.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_node\_ids\_unique module -============================================================ - -.. automodule:: pype.plugins.maya.publish.validate_node_ids_unique - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_node_no_ghosting.rst b/docs/source/pype.plugins.maya.publish.validate_node_no_ghosting.rst deleted file mode 100644 index 8315888630..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_node_no_ghosting.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_node\_no\_ghosting module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_node_no_ghosting - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_render_image_rule.rst b/docs/source/pype.plugins.maya.publish.validate_render_image_rule.rst deleted file mode 100644 index 88870a9ea8..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_render_image_rule.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_render\_image\_rule module -============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_render_image_rule - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_render_no_default_cameras.rst b/docs/source/pype.plugins.maya.publish.validate_render_no_default_cameras.rst deleted file mode 100644 index b464dbeab6..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_render_no_default_cameras.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_render\_no\_default\_cameras module -======================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_render_no_default_cameras - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_render_single_camera.rst b/docs/source/pype.plugins.maya.publish.validate_render_single_camera.rst deleted file mode 100644 index 60a0cbd6fb..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_render_single_camera.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_render\_single\_camera module -================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_render_single_camera - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_renderlayer_aovs.rst b/docs/source/pype.plugins.maya.publish.validate_renderlayer_aovs.rst deleted file mode 100644 index 65d5181065..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_renderlayer_aovs.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_renderlayer\_aovs module -============================================================ - -.. automodule:: pype.plugins.maya.publish.validate_renderlayer_aovs - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_rendersettings.rst b/docs/source/pype.plugins.maya.publish.validate_rendersettings.rst deleted file mode 100644 index fce7dba5b8..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_rendersettings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_rendersettings module -========================================================= - -.. automodule:: pype.plugins.maya.publish.validate_rendersettings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_resources.rst b/docs/source/pype.plugins.maya.publish.validate_resources.rst deleted file mode 100644 index 0a866acdbb..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_resources.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_resources module -==================================================== - -.. automodule:: pype.plugins.maya.publish.validate_resources - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_rig_contents.rst b/docs/source/pype.plugins.maya.publish.validate_rig_contents.rst deleted file mode 100644 index dbd7d84bed..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_rig_contents.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_rig\_contents module -======================================================== - -.. automodule:: pype.plugins.maya.publish.validate_rig_contents - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_rig_controllers.rst b/docs/source/pype.plugins.maya.publish.validate_rig_controllers.rst deleted file mode 100644 index 3bf075e8ad..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_rig_controllers.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_rig\_controllers module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_rig_controllers - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_rig_controllers_arnold_attributes.rst b/docs/source/pype.plugins.maya.publish.validate_rig_controllers_arnold_attributes.rst deleted file mode 100644 index 67e9256f3a..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_rig_controllers_arnold_attributes.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_rig\_controllers\_arnold\_attributes module -=============================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_rig_controllers_arnold_attributes - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_rig_out_set_node_ids.rst b/docs/source/pype.plugins.maya.publish.validate_rig_out_set_node_ids.rst deleted file mode 100644 index e4f1cfc428..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_rig_out_set_node_ids.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_rig\_out\_set\_node\_ids module -=================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_rig_out_set_node_ids - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_rig_output_ids.rst b/docs/source/pype.plugins.maya.publish.validate_rig_output_ids.rst deleted file mode 100644 index e1d3b1a659..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_rig_output_ids.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_rig\_output\_ids module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_rig_output_ids - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_scene_set_workspace.rst b/docs/source/pype.plugins.maya.publish.validate_scene_set_workspace.rst deleted file mode 100644 index daf2f152d9..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_scene_set_workspace.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_scene\_set\_workspace module -================================================================ - -.. automodule:: pype.plugins.maya.publish.validate_scene_set_workspace - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_shader_name.rst b/docs/source/pype.plugins.maya.publish.validate_shader_name.rst deleted file mode 100644 index ae5b196a1d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_shader_name.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_shader\_name module -======================================================= - -.. automodule:: pype.plugins.maya.publish.validate_shader_name - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_shape_default_names.rst b/docs/source/pype.plugins.maya.publish.validate_shape_default_names.rst deleted file mode 100644 index 49effc932d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_shape_default_names.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_shape\_default\_names module -================================================================ - -.. automodule:: pype.plugins.maya.publish.validate_shape_default_names - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_shape_render_stats.rst b/docs/source/pype.plugins.maya.publish.validate_shape_render_stats.rst deleted file mode 100644 index 359af50a0f..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_shape_render_stats.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_shape\_render\_stats module -=============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_shape_render_stats - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_single_assembly.rst b/docs/source/pype.plugins.maya.publish.validate_single_assembly.rst deleted file mode 100644 index 090f57b3ff..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_single_assembly.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_single\_assembly module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_single_assembly - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_skinCluster_deformer_set.rst b/docs/source/pype.plugins.maya.publish.validate_skinCluster_deformer_set.rst deleted file mode 100644 index 607a610097..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_skinCluster_deformer_set.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_skinCluster\_deformer\_set module -===================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_skinCluster_deformer_set - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_step_size.rst b/docs/source/pype.plugins.maya.publish.validate_step_size.rst deleted file mode 100644 index bb883ea7b5..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_step_size.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_step\_size module -===================================================== - -.. automodule:: pype.plugins.maya.publish.validate_step_size - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_transform_naming_suffix.rst b/docs/source/pype.plugins.maya.publish.validate_transform_naming_suffix.rst deleted file mode 100644 index 4d7edda78d..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_transform_naming_suffix.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_transform\_naming\_suffix module -==================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_transform_naming_suffix - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_transform_zero.rst b/docs/source/pype.plugins.maya.publish.validate_transform_zero.rst deleted file mode 100644 index 6d5cacfe00..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_transform_zero.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_transform\_zero module -========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_transform_zero - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_unicode_strings.rst b/docs/source/pype.plugins.maya.publish.validate_unicode_strings.rst deleted file mode 100644 index 9cc17d6810..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_unicode_strings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_unicode\_strings module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_unicode_strings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_unreal_mesh_triangulated.rst b/docs/source/pype.plugins.maya.publish.validate_unreal_mesh_triangulated.rst deleted file mode 100644 index 4dcb518194..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_unreal_mesh_triangulated.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_unreal\_mesh\_triangulated module -===================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_unreal_mesh_triangulated - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_unreal_staticmesh_naming.rst b/docs/source/pype.plugins.maya.publish.validate_unreal_staticmesh_naming.rst deleted file mode 100644 index f7225ab395..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_unreal_staticmesh_naming.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_unreal\_staticmesh\_naming module -===================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_unreal_staticmesh_naming - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_unreal_up_axis.rst b/docs/source/pype.plugins.maya.publish.validate_unreal_up_axis.rst deleted file mode 100644 index ff688c493f..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_unreal_up_axis.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_unreal\_up\_axis module -=========================================================== - -.. automodule:: pype.plugins.maya.publish.validate_unreal_up_axis - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_vray_distributed_rendering.rst b/docs/source/pype.plugins.maya.publish.validate_vray_distributed_rendering.rst deleted file mode 100644 index f5d05e6d76..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_vray_distributed_rendering.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_vray\_distributed\_rendering module -======================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_vray_distributed_rendering - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_vray_referenced_aovs.rst b/docs/source/pype.plugins.maya.publish.validate_vray_referenced_aovs.rst deleted file mode 100644 index 16ad9666aa..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_vray_referenced_aovs.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_vray\_referenced\_aovs module -================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_vray_referenced_aovs - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_vray_translator_settings.rst b/docs/source/pype.plugins.maya.publish.validate_vray_translator_settings.rst deleted file mode 100644 index a06a9531dd..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_vray_translator_settings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_vray\_translator\_settings module -===================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_vray_translator_settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_vrayproxy.rst b/docs/source/pype.plugins.maya.publish.validate_vrayproxy.rst deleted file mode 100644 index 081f58924a..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_vrayproxy.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_vrayproxy module -==================================================== - -.. automodule:: pype.plugins.maya.publish.validate_vrayproxy - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_vrayproxy_members.rst b/docs/source/pype.plugins.maya.publish.validate_vrayproxy_members.rst deleted file mode 100644 index 7c587f39b0..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_vrayproxy_members.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_vrayproxy\_members module -============================================================= - -.. automodule:: pype.plugins.maya.publish.validate_vrayproxy_members - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_yeti_renderscript_callbacks.rst b/docs/source/pype.plugins.maya.publish.validate_yeti_renderscript_callbacks.rst deleted file mode 100644 index 889d469b2f..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_yeti_renderscript_callbacks.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_yeti\_renderscript\_callbacks module -======================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_yeti_renderscript_callbacks - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_yeti_rig_cache_state.rst b/docs/source/pype.plugins.maya.publish.validate_yeti_rig_cache_state.rst deleted file mode 100644 index 4138b1e8a4..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_yeti_rig_cache_state.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_yeti\_rig\_cache\_state module -================================================================== - -.. automodule:: pype.plugins.maya.publish.validate_yeti_rig_cache_state - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_yeti_rig_input_in_instance.rst b/docs/source/pype.plugins.maya.publish.validate_yeti_rig_input_in_instance.rst deleted file mode 100644 index 37b862926c..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_yeti_rig_input_in_instance.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_yeti\_rig\_input\_in\_instance module -========================================================================= - -.. automodule:: pype.plugins.maya.publish.validate_yeti_rig_input_in_instance - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.publish.validate_yeti_rig_settings.rst b/docs/source/pype.plugins.maya.publish.validate_yeti_rig_settings.rst deleted file mode 100644 index 9fd54193dc..0000000000 --- a/docs/source/pype.plugins.maya.publish.validate_yeti_rig_settings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.plugins.maya.publish.validate\_yeti\_rig\_settings module -============================================================== - -.. automodule:: pype.plugins.maya.publish.validate_yeti_rig_settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.plugins.maya.rst b/docs/source/pype.plugins.maya.rst deleted file mode 100644 index 129cf5fce9..0000000000 --- a/docs/source/pype.plugins.maya.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.plugins.maya package -========================= - -.. automodule:: pype.plugins.maya - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 10 - - pype.plugins.maya.publish diff --git a/docs/source/pype.plugins.rst b/docs/source/pype.plugins.rst deleted file mode 100644 index 8e5e45ba5d..0000000000 --- a/docs/source/pype.plugins.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.plugins package -==================== - -.. automodule:: pype.plugins - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 10 - - pype.plugins.maya diff --git a/docs/source/pype.pype_commands.rst b/docs/source/pype.pype_commands.rst deleted file mode 100644 index b8a416df7b..0000000000 --- a/docs/source/pype.pype_commands.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.pype\_commands module -========================== - -.. automodule:: pype.pype_commands - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.resources.rst b/docs/source/pype.resources.rst deleted file mode 100644 index 2fb5b92dce..0000000000 --- a/docs/source/pype.resources.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.resources package -====================== - -.. automodule:: pype.resources - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.rst b/docs/source/pype.rst deleted file mode 100644 index 3589d2f3fe..0000000000 --- a/docs/source/pype.rst +++ /dev/null @@ -1,99 +0,0 @@ -pype package -============ - -.. automodule:: pype - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.hosts - pype.lib - pype.modules - pype.resources - pype.scripts - pype.settings - pype.tests - pype.tools - pype.vendor - pype.widgets - -Submodules ----------- - -pype.action module ------------------- - -.. automodule:: pype.action - :members: - :undoc-members: - :show-inheritance: - -pype.api module ---------------- - -.. automodule:: pype.api - :members: - :undoc-members: - :show-inheritance: - -pype.cli module ---------------- - -.. automodule:: pype.cli - :members: - :undoc-members: - :show-inheritance: - -pype.launcher\_actions module ------------------------------ - -.. automodule:: pype.launcher_actions - :members: - :undoc-members: - :show-inheritance: - -pype.modules\_manager module ----------------------------- - -.. automodule:: pype.modules_manager - :members: - :undoc-members: - :show-inheritance: - -pype.plugin module ------------------- - -.. automodule:: pype.plugin - :members: - :undoc-members: - :show-inheritance: - -pype.pype\_commands module --------------------------- - -.. automodule:: pype.pype_commands - :members: - :undoc-members: - :show-inheritance: - -pype.setdress\_api module -------------------------- - -.. automodule:: pype.setdress_api - :members: - :undoc-members: - :show-inheritance: - -pype.version module -------------------- - -.. automodule:: pype.version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.export_maya_ass_job.rst b/docs/source/pype.scripts.export_maya_ass_job.rst deleted file mode 100644 index c35cc49ddd..0000000000 --- a/docs/source/pype.scripts.export_maya_ass_job.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.export\_maya\_ass\_job module -========================================== - -.. automodule:: pype.scripts.export_maya_ass_job - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.fusion_switch_shot.rst b/docs/source/pype.scripts.fusion_switch_shot.rst deleted file mode 100644 index 39d3473d16..0000000000 --- a/docs/source/pype.scripts.fusion_switch_shot.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.fusion\_switch\_shot module -======================================== - -.. automodule:: pype.scripts.fusion_switch_shot - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.otio_burnin.rst b/docs/source/pype.scripts.otio_burnin.rst deleted file mode 100644 index e6a93017f5..0000000000 --- a/docs/source/pype.scripts.otio_burnin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.otio\_burnin module -================================ - -.. automodule:: pype.scripts.otio_burnin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.publish_deadline.rst b/docs/source/pype.scripts.publish_deadline.rst deleted file mode 100644 index d134e17244..0000000000 --- a/docs/source/pype.scripts.publish_deadline.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.publish\_deadline module -===================================== - -.. automodule:: pype.scripts.publish_deadline - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.publish_filesequence.rst b/docs/source/pype.scripts.publish_filesequence.rst deleted file mode 100644 index 440d52caad..0000000000 --- a/docs/source/pype.scripts.publish_filesequence.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.publish\_filesequence module -========================================= - -.. automodule:: pype.scripts.publish_filesequence - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.rst b/docs/source/pype.scripts.rst deleted file mode 100644 index 5985771b97..0000000000 --- a/docs/source/pype.scripts.rst +++ /dev/null @@ -1,58 +0,0 @@ -pype.scripts package -==================== - -.. automodule:: pype.scripts - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.scripts.slates - -Submodules ----------- - -pype.scripts.export\_maya\_ass\_job module ------------------------------------------- - -.. automodule:: pype.scripts.export_maya_ass_job - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.fusion\_switch\_shot module ----------------------------------------- - -.. automodule:: pype.scripts.fusion_switch_shot - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.otio\_burnin module --------------------------------- - -.. automodule:: pype.scripts.otio_burnin - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.publish\_deadline module -------------------------------------- - -.. automodule:: pype.scripts.publish_deadline - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.publish\_filesequence module ------------------------------------------ - -.. automodule:: pype.scripts.publish_filesequence - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.rst b/docs/source/pype.scripts.slates.rst deleted file mode 100644 index 74b4cb4343..0000000000 --- a/docs/source/pype.scripts.slates.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.scripts.slates package -=========================== - -.. automodule:: pype.scripts.slates - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.scripts.slates.slate_base diff --git a/docs/source/pype.scripts.slates.slate_base.api.rst b/docs/source/pype.scripts.slates.slate_base.api.rst deleted file mode 100644 index 0016a5c42a..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.api module -========================================== - -.. automodule:: pype.scripts.slates.slate_base.api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.base.rst b/docs/source/pype.scripts.slates.slate_base.base.rst deleted file mode 100644 index 5e34d654b0..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.base module -=========================================== - -.. automodule:: pype.scripts.slates.slate_base.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.example.rst b/docs/source/pype.scripts.slates.slate_base.example.rst deleted file mode 100644 index 95ebcc835a..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.example.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.example module -============================================== - -.. automodule:: pype.scripts.slates.slate_base.example - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.font_factory.rst b/docs/source/pype.scripts.slates.slate_base.font_factory.rst deleted file mode 100644 index c53efef554..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.font_factory.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.font\_factory module -==================================================== - -.. automodule:: pype.scripts.slates.slate_base.font_factory - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.items.rst b/docs/source/pype.scripts.slates.slate_base.items.rst deleted file mode 100644 index 25abb11bb9..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.items.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.items module -============================================ - -.. automodule:: pype.scripts.slates.slate_base.items - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.layer.rst b/docs/source/pype.scripts.slates.slate_base.layer.rst deleted file mode 100644 index 8681e3accf..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.layer.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.layer module -============================================ - -.. automodule:: pype.scripts.slates.slate_base.layer - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.lib.rst b/docs/source/pype.scripts.slates.slate_base.lib.rst deleted file mode 100644 index c4ef2c912e..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.lib module -========================================== - -.. automodule:: pype.scripts.slates.slate_base.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.main_frame.rst b/docs/source/pype.scripts.slates.slate_base.main_frame.rst deleted file mode 100644 index 5093c28a74..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.main_frame.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.scripts.slates.slate\_base.main\_frame module -================================================== - -.. automodule:: pype.scripts.slates.slate_base.main_frame - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.scripts.slates.slate_base.rst b/docs/source/pype.scripts.slates.slate_base.rst deleted file mode 100644 index 00726c04bf..0000000000 --- a/docs/source/pype.scripts.slates.slate_base.rst +++ /dev/null @@ -1,74 +0,0 @@ -pype.scripts.slates.slate\_base package -======================================= - -.. automodule:: pype.scripts.slates.slate_base - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.scripts.slates.slate\_base.api module ------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.api - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.base module -------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.base - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.example module ----------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.example - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.font\_factory module ----------------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.font_factory - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.items module --------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.items - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.layer module --------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.layer - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.lib module ------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.lib - :members: - :undoc-members: - :show-inheritance: - -pype.scripts.slates.slate\_base.main\_frame module --------------------------------------------------- - -.. automodule:: pype.scripts.slates.slate_base.main_frame - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.setdress_api.rst b/docs/source/pype.setdress_api.rst deleted file mode 100644 index 95638ea64d..0000000000 --- a/docs/source/pype.setdress_api.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.setdress\_api module -========================= - -.. automodule:: pype.setdress_api - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.settings.constants.rst b/docs/source/pype.settings.constants.rst deleted file mode 100644 index ac652089c8..0000000000 --- a/docs/source/pype.settings.constants.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.settings.constants module -============================== - -.. automodule:: pype.settings.constants - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.settings.handlers.rst b/docs/source/pype.settings.handlers.rst deleted file mode 100644 index 60ea0ae952..0000000000 --- a/docs/source/pype.settings.handlers.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.settings.handlers module -============================= - -.. automodule:: pype.settings.handlers - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.settings.lib.rst b/docs/source/pype.settings.lib.rst deleted file mode 100644 index d6e3e8bd06..0000000000 --- a/docs/source/pype.settings.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.settings.lib module -======================== - -.. automodule:: pype.settings.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.settings.rst b/docs/source/pype.settings.rst deleted file mode 100644 index 5bf131d555..0000000000 --- a/docs/source/pype.settings.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.settings package -===================== - -.. automodule:: pype.settings - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.settings.lib module ------------------------- - -.. automodule:: pype.settings.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tests.lib.rst b/docs/source/pype.tests.lib.rst deleted file mode 100644 index 375ebd0258..0000000000 --- a/docs/source/pype.tests.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tests.lib module -===================== - -.. automodule:: pype.tests.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tests.rst b/docs/source/pype.tests.rst deleted file mode 100644 index 3f34cdcd77..0000000000 --- a/docs/source/pype.tests.rst +++ /dev/null @@ -1,42 +0,0 @@ -pype.tests package -================== - -.. automodule:: pype.tests - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.tests.lib module ---------------------- - -.. automodule:: pype.tests.lib - :members: - :undoc-members: - :show-inheritance: - -pype.tests.test\_avalon\_plugin\_presets module ------------------------------------------------ - -.. automodule:: pype.tests.test_avalon_plugin_presets - :members: - :undoc-members: - :show-inheritance: - -pype.tests.test\_mongo\_performance module ------------------------------------------- - -.. automodule:: pype.tests.test_mongo_performance - :members: - :undoc-members: - :show-inheritance: - -pype.tests.test\_pyblish\_filter module ---------------------------------------- - -.. automodule:: pype.tests.test_pyblish_filter - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tests.test_avalon_plugin_presets.rst b/docs/source/pype.tests.test_avalon_plugin_presets.rst deleted file mode 100644 index b4ff802256..0000000000 --- a/docs/source/pype.tests.test_avalon_plugin_presets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tests.test\_avalon\_plugin\_presets module -=============================================== - -.. automodule:: pype.tests.test_avalon_plugin_presets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tests.test_lib_restructuralization.rst b/docs/source/pype.tests.test_lib_restructuralization.rst deleted file mode 100644 index 8d426fcb6b..0000000000 --- a/docs/source/pype.tests.test_lib_restructuralization.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tests.test\_lib\_restructuralization module -================================================ - -.. automodule:: pype.tests.test_lib_restructuralization - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tests.test_mongo_performance.rst b/docs/source/pype.tests.test_mongo_performance.rst deleted file mode 100644 index 4686247e59..0000000000 --- a/docs/source/pype.tests.test_mongo_performance.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tests.test\_mongo\_performance module -========================================== - -.. automodule:: pype.tests.test_mongo_performance - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tests.test_pyblish_filter.rst b/docs/source/pype.tests.test_pyblish_filter.rst deleted file mode 100644 index 196ec02433..0000000000 --- a/docs/source/pype.tests.test_pyblish_filter.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tests.test\_pyblish\_filter module -======================================= - -.. automodule:: pype.tests.test_pyblish_filter - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.assetcreator.app.rst b/docs/source/pype.tools.assetcreator.app.rst deleted file mode 100644 index b46281b07a..0000000000 --- a/docs/source/pype.tools.assetcreator.app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.assetcreator.app module -================================== - -.. automodule:: pype.tools.assetcreator.app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.assetcreator.model.rst b/docs/source/pype.tools.assetcreator.model.rst deleted file mode 100644 index 752791d07c..0000000000 --- a/docs/source/pype.tools.assetcreator.model.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.assetcreator.model module -==================================== - -.. automodule:: pype.tools.assetcreator.model - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.assetcreator.rst b/docs/source/pype.tools.assetcreator.rst deleted file mode 100644 index b95c3b3c60..0000000000 --- a/docs/source/pype.tools.assetcreator.rst +++ /dev/null @@ -1,34 +0,0 @@ -pype.tools.assetcreator package -=============================== - -.. automodule:: pype.tools.assetcreator - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.tools.assetcreator.app module ----------------------------------- - -.. automodule:: pype.tools.assetcreator.app - :members: - :undoc-members: - :show-inheritance: - -pype.tools.assetcreator.model module ------------------------------------- - -.. automodule:: pype.tools.assetcreator.model - :members: - :undoc-members: - :show-inheritance: - -pype.tools.assetcreator.widget module -------------------------------------- - -.. automodule:: pype.tools.assetcreator.widget - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.assetcreator.widget.rst b/docs/source/pype.tools.assetcreator.widget.rst deleted file mode 100644 index 23ed335306..0000000000 --- a/docs/source/pype.tools.assetcreator.widget.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.assetcreator.widget module -===================================== - -.. automodule:: pype.tools.assetcreator.widget - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.actions.rst b/docs/source/pype.tools.launcher.actions.rst deleted file mode 100644 index e2ec217d4b..0000000000 --- a/docs/source/pype.tools.launcher.actions.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.actions module -================================== - -.. automodule:: pype.tools.launcher.actions - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.delegates.rst b/docs/source/pype.tools.launcher.delegates.rst deleted file mode 100644 index e8a7519cd5..0000000000 --- a/docs/source/pype.tools.launcher.delegates.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.delegates module -==================================== - -.. automodule:: pype.tools.launcher.delegates - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.flickcharm.rst b/docs/source/pype.tools.launcher.flickcharm.rst deleted file mode 100644 index 5105d3235e..0000000000 --- a/docs/source/pype.tools.launcher.flickcharm.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.flickcharm module -===================================== - -.. automodule:: pype.tools.launcher.flickcharm - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.lib.rst b/docs/source/pype.tools.launcher.lib.rst deleted file mode 100644 index 28db8a6540..0000000000 --- a/docs/source/pype.tools.launcher.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.lib module -============================== - -.. automodule:: pype.tools.launcher.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.models.rst b/docs/source/pype.tools.launcher.models.rst deleted file mode 100644 index 701826284e..0000000000 --- a/docs/source/pype.tools.launcher.models.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.models module -================================= - -.. automodule:: pype.tools.launcher.models - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.rst b/docs/source/pype.tools.launcher.rst deleted file mode 100644 index c4782bf9bb..0000000000 --- a/docs/source/pype.tools.launcher.rst +++ /dev/null @@ -1,66 +0,0 @@ -pype.tools.launcher package -=========================== - -.. automodule:: pype.tools.launcher - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.tools.launcher.actions module ----------------------------------- - -.. automodule:: pype.tools.launcher.actions - :members: - :undoc-members: - :show-inheritance: - -pype.tools.launcher.delegates module ------------------------------------- - -.. automodule:: pype.tools.launcher.delegates - :members: - :undoc-members: - :show-inheritance: - -pype.tools.launcher.flickcharm module -------------------------------------- - -.. automodule:: pype.tools.launcher.flickcharm - :members: - :undoc-members: - :show-inheritance: - -pype.tools.launcher.lib module ------------------------------- - -.. automodule:: pype.tools.launcher.lib - :members: - :undoc-members: - :show-inheritance: - -pype.tools.launcher.models module ---------------------------------- - -.. automodule:: pype.tools.launcher.models - :members: - :undoc-members: - :show-inheritance: - -pype.tools.launcher.widgets module ----------------------------------- - -.. automodule:: pype.tools.launcher.widgets - :members: - :undoc-members: - :show-inheritance: - -pype.tools.launcher.window module ---------------------------------- - -.. automodule:: pype.tools.launcher.window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.widgets.rst b/docs/source/pype.tools.launcher.widgets.rst deleted file mode 100644 index 400a5b7a2c..0000000000 --- a/docs/source/pype.tools.launcher.widgets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.widgets module -================================== - -.. automodule:: pype.tools.launcher.widgets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.launcher.window.rst b/docs/source/pype.tools.launcher.window.rst deleted file mode 100644 index ae92207795..0000000000 --- a/docs/source/pype.tools.launcher.window.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.launcher.window module -================================= - -.. automodule:: pype.tools.launcher.window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.app.rst b/docs/source/pype.tools.pyblish_pype.app.rst deleted file mode 100644 index a70aada725..0000000000 --- a/docs/source/pype.tools.pyblish_pype.app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.app module -=================================== - -.. automodule:: pype.tools.pyblish_pype.app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.awesome.rst b/docs/source/pype.tools.pyblish_pype.awesome.rst deleted file mode 100644 index 50a81ac5e8..0000000000 --- a/docs/source/pype.tools.pyblish_pype.awesome.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.awesome module -======================================= - -.. automodule:: pype.tools.pyblish_pype.awesome - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.compat.rst b/docs/source/pype.tools.pyblish_pype.compat.rst deleted file mode 100644 index 4beee41e00..0000000000 --- a/docs/source/pype.tools.pyblish_pype.compat.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.compat module -====================================== - -.. automodule:: pype.tools.pyblish_pype.compat - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.constants.rst b/docs/source/pype.tools.pyblish_pype.constants.rst deleted file mode 100644 index bab67a2270..0000000000 --- a/docs/source/pype.tools.pyblish_pype.constants.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.constants module -========================================= - -.. automodule:: pype.tools.pyblish_pype.constants - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.control.rst b/docs/source/pype.tools.pyblish_pype.control.rst deleted file mode 100644 index c2f8c0031e..0000000000 --- a/docs/source/pype.tools.pyblish_pype.control.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.control module -======================================= - -.. automodule:: pype.tools.pyblish_pype.control - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.delegate.rst b/docs/source/pype.tools.pyblish_pype.delegate.rst deleted file mode 100644 index 8796c9830f..0000000000 --- a/docs/source/pype.tools.pyblish_pype.delegate.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.delegate module -======================================== - -.. automodule:: pype.tools.pyblish_pype.delegate - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.mock.rst b/docs/source/pype.tools.pyblish_pype.mock.rst deleted file mode 100644 index 8c22e80856..0000000000 --- a/docs/source/pype.tools.pyblish_pype.mock.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.mock module -==================================== - -.. automodule:: pype.tools.pyblish_pype.mock - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.model.rst b/docs/source/pype.tools.pyblish_pype.model.rst deleted file mode 100644 index 983b06cc8a..0000000000 --- a/docs/source/pype.tools.pyblish_pype.model.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.model module -===================================== - -.. automodule:: pype.tools.pyblish_pype.model - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.rst b/docs/source/pype.tools.pyblish_pype.rst deleted file mode 100644 index 9479b5399f..0000000000 --- a/docs/source/pype.tools.pyblish_pype.rst +++ /dev/null @@ -1,130 +0,0 @@ -pype.tools.pyblish\_pype package -================================ - -.. automodule:: pype.tools.pyblish_pype - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.pyblish_pype.vendor - -Submodules ----------- - -pype.tools.pyblish\_pype.app module ------------------------------------ - -.. automodule:: pype.tools.pyblish_pype.app - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.awesome module ---------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.awesome - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.compat module --------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.compat - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.constants module ------------------------------------------ - -.. automodule:: pype.tools.pyblish_pype.constants - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.control module ---------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.control - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.delegate module ----------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.delegate - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.mock module ------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.mock - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.model module -------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.model - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.settings module ----------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.settings - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.util module ------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.util - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.version module ---------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.version - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.view module ------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.view - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.widgets module ---------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.widgets - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.window module --------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.settings.rst b/docs/source/pype.tools.pyblish_pype.settings.rst deleted file mode 100644 index 2e4e95cca0..0000000000 --- a/docs/source/pype.tools.pyblish_pype.settings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.settings module -======================================== - -.. automodule:: pype.tools.pyblish_pype.settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.util.rst b/docs/source/pype.tools.pyblish_pype.util.rst deleted file mode 100644 index fa34295f12..0000000000 --- a/docs/source/pype.tools.pyblish_pype.util.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.util module -==================================== - -.. automodule:: pype.tools.pyblish_pype.util - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.animation.rst b/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.animation.rst deleted file mode 100644 index a892128308..0000000000 --- a/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.animation.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.vendor.qtawesome.animation module -========================================================== - -.. automodule:: pype.tools.pyblish_pype.vendor.qtawesome.animation - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.iconic_font.rst b/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.iconic_font.rst deleted file mode 100644 index 4f4337348f..0000000000 --- a/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.iconic_font.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.vendor.qtawesome.iconic\_font module -============================================================= - -.. automodule:: pype.tools.pyblish_pype.vendor.qtawesome.iconic_font - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.rst b/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.rst deleted file mode 100644 index 68b2ec4659..0000000000 --- a/docs/source/pype.tools.pyblish_pype.vendor.qtawesome.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.tools.pyblish\_pype.vendor.qtawesome package -================================================= - -.. automodule:: pype.tools.pyblish_pype.vendor.qtawesome - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.tools.pyblish\_pype.vendor.qtawesome.animation module ----------------------------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.vendor.qtawesome.animation - :members: - :undoc-members: - :show-inheritance: - -pype.tools.pyblish\_pype.vendor.qtawesome.iconic\_font module -------------------------------------------------------------- - -.. automodule:: pype.tools.pyblish_pype.vendor.qtawesome.iconic_font - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.vendor.rst b/docs/source/pype.tools.pyblish_pype.vendor.rst deleted file mode 100644 index 69e6096053..0000000000 --- a/docs/source/pype.tools.pyblish_pype.vendor.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.tools.pyblish\_pype.vendor package -======================================= - -.. automodule:: pype.tools.pyblish_pype.vendor - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.pyblish_pype.vendor.qtawesome diff --git a/docs/source/pype.tools.pyblish_pype.version.rst b/docs/source/pype.tools.pyblish_pype.version.rst deleted file mode 100644 index a6ddcd5ce8..0000000000 --- a/docs/source/pype.tools.pyblish_pype.version.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.version module -======================================= - -.. automodule:: pype.tools.pyblish_pype.version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.view.rst b/docs/source/pype.tools.pyblish_pype.view.rst deleted file mode 100644 index 21d34d9daa..0000000000 --- a/docs/source/pype.tools.pyblish_pype.view.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.view module -==================================== - -.. automodule:: pype.tools.pyblish_pype.view - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.widgets.rst b/docs/source/pype.tools.pyblish_pype.widgets.rst deleted file mode 100644 index 8a0d3c380a..0000000000 --- a/docs/source/pype.tools.pyblish_pype.widgets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.widgets module -======================================= - -.. automodule:: pype.tools.pyblish_pype.widgets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.pyblish_pype.window.rst b/docs/source/pype.tools.pyblish_pype.window.rst deleted file mode 100644 index 10f7b1a36e..0000000000 --- a/docs/source/pype.tools.pyblish_pype.window.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.pyblish\_pype.window module -====================================== - -.. automodule:: pype.tools.pyblish_pype.window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.rst b/docs/source/pype.tools.rst deleted file mode 100644 index d82ed3384a..0000000000 --- a/docs/source/pype.tools.rst +++ /dev/null @@ -1,19 +0,0 @@ -pype.tools package -================== - -.. automodule:: pype.tools - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.assetcreator - pype.tools.launcher - pype.tools.pyblish_pype - pype.tools.settings - pype.tools.standalonepublish diff --git a/docs/source/pype.tools.settings.rst b/docs/source/pype.tools.settings.rst deleted file mode 100644 index ef54851ab1..0000000000 --- a/docs/source/pype.tools.settings.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.tools.settings package -=========================== - -.. automodule:: pype.tools.settings - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.settings.settings diff --git a/docs/source/pype.tools.settings.settings.rst b/docs/source/pype.tools.settings.settings.rst deleted file mode 100644 index 793914e1a8..0000000000 --- a/docs/source/pype.tools.settings.settings.rst +++ /dev/null @@ -1,16 +0,0 @@ -pype.tools.settings.settings package -==================================== - -.. automodule:: pype.tools.settings.settings - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.settings.settings.style - pype.tools.settings.settings.widgets diff --git a/docs/source/pype.tools.settings.settings.style.rst b/docs/source/pype.tools.settings.settings.style.rst deleted file mode 100644 index 228322245c..0000000000 --- a/docs/source/pype.tools.settings.settings.style.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.style package -========================================== - -.. automodule:: pype.tools.settings.settings.style - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.anatomy_types.rst b/docs/source/pype.tools.settings.settings.widgets.anatomy_types.rst deleted file mode 100644 index ca951c82f0..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.anatomy_types.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.anatomy\_types module -========================================================== - -.. automodule:: pype.tools.settings.settings.widgets.anatomy_types - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.base.rst b/docs/source/pype.tools.settings.settings.widgets.base.rst deleted file mode 100644 index 8964d6f628..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.base module -================================================ - -.. automodule:: pype.tools.settings.settings.widgets.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.item_types.rst b/docs/source/pype.tools.settings.settings.widgets.item_types.rst deleted file mode 100644 index 5e505538a7..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.item_types.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.item\_types module -======================================================= - -.. automodule:: pype.tools.settings.settings.widgets.item_types - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.lib.rst b/docs/source/pype.tools.settings.settings.widgets.lib.rst deleted file mode 100644 index ae100c74b2..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.lib module -=============================================== - -.. automodule:: pype.tools.settings.settings.widgets.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.multiselection_combobox.rst b/docs/source/pype.tools.settings.settings.widgets.multiselection_combobox.rst deleted file mode 100644 index 004f2ae21f..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.multiselection_combobox.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.multiselection\_combobox module -==================================================================== - -.. automodule:: pype.tools.settings.settings.widgets.multiselection_combobox - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.rst b/docs/source/pype.tools.settings.settings.widgets.rst deleted file mode 100644 index 8734280a08..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.rst +++ /dev/null @@ -1,74 +0,0 @@ -pype.tools.settings.settings.widgets package -============================================ - -.. automodule:: pype.tools.settings.settings.widgets - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.tools.settings.settings.widgets.anatomy\_types module ----------------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.anatomy_types - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.base module ------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.base - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.item\_types module -------------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.item_types - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.lib module ------------------------------------------------ - -.. automodule:: pype.tools.settings.settings.widgets.lib - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.multiselection\_combobox module --------------------------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.multiselection_combobox - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.tests module -------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.tests - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.widgets module ---------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.widgets - :members: - :undoc-members: - :show-inheritance: - -pype.tools.settings.settings.widgets.window module --------------------------------------------------- - -.. automodule:: pype.tools.settings.settings.widgets.window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.tests.rst b/docs/source/pype.tools.settings.settings.widgets.tests.rst deleted file mode 100644 index fe8d6dabef..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.tests module -================================================= - -.. automodule:: pype.tools.settings.settings.widgets.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.widgets.rst b/docs/source/pype.tools.settings.settings.widgets.widgets.rst deleted file mode 100644 index 238e584ac3..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.widgets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.widgets module -=================================================== - -.. automodule:: pype.tools.settings.settings.widgets.widgets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.settings.settings.widgets.window.rst b/docs/source/pype.tools.settings.settings.widgets.window.rst deleted file mode 100644 index d67678012f..0000000000 --- a/docs/source/pype.tools.settings.settings.widgets.window.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.settings.settings.widgets.window module -================================================== - -.. automodule:: pype.tools.settings.settings.widgets.window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.app.rst b/docs/source/pype.tools.standalonepublish.app.rst deleted file mode 100644 index 74776b80fe..0000000000 --- a/docs/source/pype.tools.standalonepublish.app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.app module -======================================= - -.. automodule:: pype.tools.standalonepublish.app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.publish.rst b/docs/source/pype.tools.standalonepublish.publish.rst deleted file mode 100644 index 47ad57e7fb..0000000000 --- a/docs/source/pype.tools.standalonepublish.publish.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.publish module -=========================================== - -.. automodule:: pype.tools.standalonepublish.publish - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.rst b/docs/source/pype.tools.standalonepublish.rst deleted file mode 100644 index 5ca8194b61..0000000000 --- a/docs/source/pype.tools.standalonepublish.rst +++ /dev/null @@ -1,34 +0,0 @@ -pype.tools.standalonepublish package -==================================== - -.. automodule:: pype.tools.standalonepublish - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.standalonepublish.widgets - -Submodules ----------- - -pype.tools.standalonepublish.app module ---------------------------------------- - -.. automodule:: pype.tools.standalonepublish.app - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.publish module -------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.publish - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_asset.rst b/docs/source/pype.tools.standalonepublish.widgets.model_asset.rst deleted file mode 100644 index 84d0ca2d93..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_asset.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_asset module -======================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.model_asset - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_filter_proxy_exact_match.rst b/docs/source/pype.tools.standalonepublish.widgets.model_filter_proxy_exact_match.rst deleted file mode 100644 index 0c3ae79b99..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_filter_proxy_exact_match.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_filter\_proxy\_exact\_match module -============================================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.model_filter_proxy_exact_match - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_filter_proxy_recursive_sort.rst b/docs/source/pype.tools.standalonepublish.widgets.model_filter_proxy_recursive_sort.rst deleted file mode 100644 index b828b75030..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_filter_proxy_recursive_sort.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_filter\_proxy\_recursive\_sort module -================================================================================= - -.. automodule:: pype.tools.standalonepublish.widgets.model_filter_proxy_recursive_sort - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_node.rst b/docs/source/pype.tools.standalonepublish.widgets.model_node.rst deleted file mode 100644 index 4789b14501..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_node.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_node module -======================================================= - -.. automodule:: pype.tools.standalonepublish.widgets.model_node - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_tasks_template.rst b/docs/source/pype.tools.standalonepublish.widgets.model_tasks_template.rst deleted file mode 100644 index dbee838530..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_tasks_template.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_tasks\_template module -================================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.model_tasks_template - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_tree.rst b/docs/source/pype.tools.standalonepublish.widgets.model_tree.rst deleted file mode 100644 index 38eecb095a..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_tree.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_tree module -======================================================= - -.. automodule:: pype.tools.standalonepublish.widgets.model_tree - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.model_tree_view_deselectable.rst b/docs/source/pype.tools.standalonepublish.widgets.model_tree_view_deselectable.rst deleted file mode 100644 index 9afb505113..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.model_tree_view_deselectable.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.model\_tree\_view\_deselectable module -=========================================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.model_tree_view_deselectable - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.resources.rst b/docs/source/pype.tools.standalonepublish.widgets.resources.rst deleted file mode 100644 index a0eddae63e..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.resources.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.resources package -====================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.resources - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.rst b/docs/source/pype.tools.standalonepublish.widgets.rst deleted file mode 100644 index 65bbcb62fc..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.rst +++ /dev/null @@ -1,146 +0,0 @@ -pype.tools.standalonepublish.widgets package -============================================ - -.. automodule:: pype.tools.standalonepublish.widgets - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.tools.standalonepublish.widgets.resources - -Submodules ----------- - -pype.tools.standalonepublish.widgets.model\_asset module --------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_asset - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.model\_filter\_proxy\_exact\_match module ------------------------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_filter_proxy_exact_match - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.model\_filter\_proxy\_recursive\_sort module ---------------------------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_filter_proxy_recursive_sort - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.model\_node module -------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_node - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.model\_tasks\_template module ------------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_tasks_template - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.model\_tree module -------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_tree - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.model\_tree\_view\_deselectable module ---------------------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.model_tree_view_deselectable - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_asset module ---------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_asset - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_component\_item module -------------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_component_item - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_components module --------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_components - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_components\_list module --------------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_components_list - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_drop\_empty module ---------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_drop_empty - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_drop\_frame module ---------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_drop_frame - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_family module ----------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_family - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_family\_desc module ----------------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_family_desc - :members: - :undoc-members: - :show-inheritance: - -pype.tools.standalonepublish.widgets.widget\_shadow module ----------------------------------------------------------- - -.. automodule:: pype.tools.standalonepublish.widgets.widget_shadow - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_asset.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_asset.rst deleted file mode 100644 index 51a3763628..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_asset.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_asset module -========================================================= - -.. automodule:: pype.tools.standalonepublish.widgets.widget_asset - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_component_item.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_component_item.rst deleted file mode 100644 index 3495fdf192..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_component_item.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_component\_item module -=================================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_component_item - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_components.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_components.rst deleted file mode 100644 index be7c19af9f..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_components.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_components module -============================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_components - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_components_list.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_components_list.rst deleted file mode 100644 index 051efe07fe..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_components_list.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_components\_list module -==================================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_components_list - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_drop_empty.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_drop_empty.rst deleted file mode 100644 index b5b0a6acac..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_drop_empty.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_drop\_empty module -=============================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_drop_empty - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_drop_frame.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_drop_frame.rst deleted file mode 100644 index 6b3e3690e0..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_drop_frame.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_drop\_frame module -=============================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_drop_frame - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_family.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_family.rst deleted file mode 100644 index 24c9d5496f..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_family.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_family module -========================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_family - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_family_desc.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_family_desc.rst deleted file mode 100644 index 5a7f92177f..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_family_desc.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_family\_desc module -================================================================ - -.. automodule:: pype.tools.standalonepublish.widgets.widget_family_desc - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.standalonepublish.widgets.widget_shadow.rst b/docs/source/pype.tools.standalonepublish.widgets.widget_shadow.rst deleted file mode 100644 index 19f5c22198..0000000000 --- a/docs/source/pype.tools.standalonepublish.widgets.widget_shadow.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.standalonepublish.widgets.widget\_shadow module -========================================================== - -.. automodule:: pype.tools.standalonepublish.widgets.widget_shadow - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.tray.pype_tray.rst b/docs/source/pype.tools.tray.pype_tray.rst deleted file mode 100644 index 9fc49c5763..0000000000 --- a/docs/source/pype.tools.tray.pype_tray.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.tray.pype\_tray module -================================= - -.. automodule:: pype.tools.tray.pype_tray - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.tray.rst b/docs/source/pype.tools.tray.rst deleted file mode 100644 index b28059d170..0000000000 --- a/docs/source/pype.tools.tray.rst +++ /dev/null @@ -1,15 +0,0 @@ -pype.tools.tray package -======================= - -.. automodule:: pype.tools.tray - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.tools.tray.pype_tray diff --git a/docs/source/pype.tools.workfiles.app.rst b/docs/source/pype.tools.workfiles.app.rst deleted file mode 100644 index a3a46b8a07..0000000000 --- a/docs/source/pype.tools.workfiles.app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.workfiles.app module -=============================== - -.. automodule:: pype.tools.workfiles.app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.workfiles.model.rst b/docs/source/pype.tools.workfiles.model.rst deleted file mode 100644 index 44cea32b97..0000000000 --- a/docs/source/pype.tools.workfiles.model.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.workfiles.model module -================================= - -.. automodule:: pype.tools.workfiles.model - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.tools.workfiles.rst b/docs/source/pype.tools.workfiles.rst deleted file mode 100644 index 147c4cebbe..0000000000 --- a/docs/source/pype.tools.workfiles.rst +++ /dev/null @@ -1,17 +0,0 @@ -pype.tools.workfiles package -============================ - -.. automodule:: pype.tools.workfiles - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 10 - - pype.tools.workfiles.app - pype.tools.workfiles.model - pype.tools.workfiles.view diff --git a/docs/source/pype.tools.workfiles.view.rst b/docs/source/pype.tools.workfiles.view.rst deleted file mode 100644 index acd32ed250..0000000000 --- a/docs/source/pype.tools.workfiles.view.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.tools.workfiles.view module -================================ - -.. automodule:: pype.tools.workfiles.view - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.backports.configparser.helpers.rst b/docs/source/pype.vendor.backports.configparser.helpers.rst deleted file mode 100644 index 8d44d0a8c4..0000000000 --- a/docs/source/pype.vendor.backports.configparser.helpers.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.backports.configparser.helpers module -================================================= - -.. automodule:: pype.vendor.backports.configparser.helpers - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.backports.configparser.rst b/docs/source/pype.vendor.backports.configparser.rst deleted file mode 100644 index 4f778a4a87..0000000000 --- a/docs/source/pype.vendor.backports.configparser.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.vendor.backports.configparser package -========================================== - -.. automodule:: pype.vendor.backports.configparser - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.backports.configparser.helpers module -------------------------------------------------- - -.. automodule:: pype.vendor.backports.configparser.helpers - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.backports.functools_lru_cache.rst b/docs/source/pype.vendor.backports.functools_lru_cache.rst deleted file mode 100644 index 26f2746cec..0000000000 --- a/docs/source/pype.vendor.backports.functools_lru_cache.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.backports.functools\_lru\_cache module -================================================== - -.. automodule:: pype.vendor.backports.functools_lru_cache - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.backports.rst b/docs/source/pype.vendor.backports.rst deleted file mode 100644 index ff9efc29c5..0000000000 --- a/docs/source/pype.vendor.backports.rst +++ /dev/null @@ -1,26 +0,0 @@ -pype.vendor.backports package -============================= - -.. automodule:: pype.vendor.backports - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.vendor.backports.configparser - -Submodules ----------- - -pype.vendor.backports.functools\_lru\_cache module --------------------------------------------------- - -.. automodule:: pype.vendor.backports.functools_lru_cache - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.builtins.rst b/docs/source/pype.vendor.builtins.rst deleted file mode 100644 index e21fb768ed..0000000000 --- a/docs/source/pype.vendor.builtins.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.builtins package -============================ - -.. automodule:: pype.vendor.builtins - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture.rst b/docs/source/pype.vendor.capture.rst deleted file mode 100644 index d42e073fb5..0000000000 --- a/docs/source/pype.vendor.capture.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture module -========================== - -.. automodule:: pype.vendor.capture - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.accordion.rst b/docs/source/pype.vendor.capture_gui.accordion.rst deleted file mode 100644 index cca228f151..0000000000 --- a/docs/source/pype.vendor.capture_gui.accordion.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.accordion module -========================================= - -.. automodule:: pype.vendor.capture_gui.accordion - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.app.rst b/docs/source/pype.vendor.capture_gui.app.rst deleted file mode 100644 index 291296834e..0000000000 --- a/docs/source/pype.vendor.capture_gui.app.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.app module -=================================== - -.. automodule:: pype.vendor.capture_gui.app - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.colorpicker.rst b/docs/source/pype.vendor.capture_gui.colorpicker.rst deleted file mode 100644 index c9e56500f2..0000000000 --- a/docs/source/pype.vendor.capture_gui.colorpicker.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.colorpicker module -=========================================== - -.. automodule:: pype.vendor.capture_gui.colorpicker - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.lib.rst b/docs/source/pype.vendor.capture_gui.lib.rst deleted file mode 100644 index e94a3bd196..0000000000 --- a/docs/source/pype.vendor.capture_gui.lib.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.lib module -=================================== - -.. automodule:: pype.vendor.capture_gui.lib - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.plugin.rst b/docs/source/pype.vendor.capture_gui.plugin.rst deleted file mode 100644 index 2e8f58c873..0000000000 --- a/docs/source/pype.vendor.capture_gui.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.plugin module -====================================== - -.. automodule:: pype.vendor.capture_gui.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.presets.rst b/docs/source/pype.vendor.capture_gui.presets.rst deleted file mode 100644 index c81b4e1c23..0000000000 --- a/docs/source/pype.vendor.capture_gui.presets.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.presets module -======================================= - -.. automodule:: pype.vendor.capture_gui.presets - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.rst b/docs/source/pype.vendor.capture_gui.rst deleted file mode 100644 index f7efce3501..0000000000 --- a/docs/source/pype.vendor.capture_gui.rst +++ /dev/null @@ -1,82 +0,0 @@ -pype.vendor.capture\_gui package -================================ - -.. automodule:: pype.vendor.capture_gui - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.vendor.capture_gui.vendor - -Submodules ----------- - -pype.vendor.capture\_gui.accordion module ------------------------------------------ - -.. automodule:: pype.vendor.capture_gui.accordion - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.app module ------------------------------------ - -.. automodule:: pype.vendor.capture_gui.app - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.colorpicker module -------------------------------------------- - -.. automodule:: pype.vendor.capture_gui.colorpicker - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.lib module ------------------------------------ - -.. automodule:: pype.vendor.capture_gui.lib - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.plugin module --------------------------------------- - -.. automodule:: pype.vendor.capture_gui.plugin - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.presets module ---------------------------------------- - -.. automodule:: pype.vendor.capture_gui.presets - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.tokens module --------------------------------------- - -.. automodule:: pype.vendor.capture_gui.tokens - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.capture\_gui.version module ---------------------------------------- - -.. automodule:: pype.vendor.capture_gui.version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.tokens.rst b/docs/source/pype.vendor.capture_gui.tokens.rst deleted file mode 100644 index 9e144a4d37..0000000000 --- a/docs/source/pype.vendor.capture_gui.tokens.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.tokens module -====================================== - -.. automodule:: pype.vendor.capture_gui.tokens - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.vendor.Qt.rst b/docs/source/pype.vendor.capture_gui.vendor.Qt.rst deleted file mode 100644 index 447e6dd812..0000000000 --- a/docs/source/pype.vendor.capture_gui.vendor.Qt.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.vendor.Qt module -========================================= - -.. automodule:: pype.vendor.capture_gui.vendor.Qt - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.vendor.rst b/docs/source/pype.vendor.capture_gui.vendor.rst deleted file mode 100644 index 0befc4bbb7..0000000000 --- a/docs/source/pype.vendor.capture_gui.vendor.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.vendor.capture\_gui.vendor package -======================================= - -.. automodule:: pype.vendor.capture_gui.vendor - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.capture\_gui.vendor.Qt module ------------------------------------------ - -.. automodule:: pype.vendor.capture_gui.vendor.Qt - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.capture_gui.version.rst b/docs/source/pype.vendor.capture_gui.version.rst deleted file mode 100644 index 3f0cfbabfd..0000000000 --- a/docs/source/pype.vendor.capture_gui.version.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.capture\_gui.version module -======================================= - -.. automodule:: pype.vendor.capture_gui.version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.accessor.base.rst b/docs/source/pype.vendor.ftrack_api_old.accessor.base.rst deleted file mode 100644 index 5155df82aa..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.accessor.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.accessor.base module -================================================= - -.. automodule:: pype.vendor.ftrack_api_old.accessor.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.accessor.disk.rst b/docs/source/pype.vendor.ftrack_api_old.accessor.disk.rst deleted file mode 100644 index 3040fe18fd..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.accessor.disk.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.accessor.disk module -================================================= - -.. automodule:: pype.vendor.ftrack_api_old.accessor.disk - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.accessor.rst b/docs/source/pype.vendor.ftrack_api_old.accessor.rst deleted file mode 100644 index 1f7b522460..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.accessor.rst +++ /dev/null @@ -1,34 +0,0 @@ -pype.vendor.ftrack\_api\_old.accessor package -============================================= - -.. automodule:: pype.vendor.ftrack_api_old.accessor - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.ftrack\_api\_old.accessor.base module -------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.accessor.base - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.accessor.disk module -------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.accessor.disk - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.accessor.server module ---------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.accessor.server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.accessor.server.rst b/docs/source/pype.vendor.ftrack_api_old.accessor.server.rst deleted file mode 100644 index db835f99c4..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.accessor.server.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.accessor.server module -=================================================== - -.. automodule:: pype.vendor.ftrack_api_old.accessor.server - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.attribute.rst b/docs/source/pype.vendor.ftrack_api_old.attribute.rst deleted file mode 100644 index 54276ceb2a..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.attribute.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.attribute module -============================================= - -.. automodule:: pype.vendor.ftrack_api_old.attribute - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.cache.rst b/docs/source/pype.vendor.ftrack_api_old.cache.rst deleted file mode 100644 index 396bc5a1cd..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.cache.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.cache module -========================================= - -.. automodule:: pype.vendor.ftrack_api_old.cache - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.collection.rst b/docs/source/pype.vendor.ftrack_api_old.collection.rst deleted file mode 100644 index de911619fc..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.collection.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.collection module -============================================== - -.. automodule:: pype.vendor.ftrack_api_old.collection - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.data.rst b/docs/source/pype.vendor.ftrack_api_old.data.rst deleted file mode 100644 index 2f67185cee..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.data.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.data module -======================================== - -.. automodule:: pype.vendor.ftrack_api_old.data - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.asset_version.rst b/docs/source/pype.vendor.ftrack_api_old.entity.asset_version.rst deleted file mode 100644 index 7ad3d87fd9..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.asset_version.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.asset\_version module -========================================================= - -.. automodule:: pype.vendor.ftrack_api_old.entity.asset_version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.base.rst b/docs/source/pype.vendor.ftrack_api_old.entity.base.rst deleted file mode 100644 index b87428f817..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.base module -=============================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.component.rst b/docs/source/pype.vendor.ftrack_api_old.entity.component.rst deleted file mode 100644 index 27901ab786..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.component.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.component module -==================================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.component - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.factory.rst b/docs/source/pype.vendor.ftrack_api_old.entity.factory.rst deleted file mode 100644 index caada5c3c8..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.factory.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.factory module -================================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.factory - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.job.rst b/docs/source/pype.vendor.ftrack_api_old.entity.job.rst deleted file mode 100644 index 6f4ca18323..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.job.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.job module -============================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.job - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.location.rst b/docs/source/pype.vendor.ftrack_api_old.entity.location.rst deleted file mode 100644 index 2f0b380349..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.location.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.location module -=================================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.location - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.note.rst b/docs/source/pype.vendor.ftrack_api_old.entity.note.rst deleted file mode 100644 index c04e959402..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.note.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.note module -=============================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.note - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.project_schema.rst b/docs/source/pype.vendor.ftrack_api_old.entity.project_schema.rst deleted file mode 100644 index 6332a2e523..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.project_schema.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.project\_schema module -========================================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.project_schema - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.rst b/docs/source/pype.vendor.ftrack_api_old.entity.rst deleted file mode 100644 index bb43a7621b..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.rst +++ /dev/null @@ -1,82 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity package -=========================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.ftrack\_api\_old.entity.asset\_version module ---------------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.entity.asset_version - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.base module ------------------------------------------------ - -.. automodule:: pype.vendor.ftrack_api_old.entity.base - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.component module ----------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.entity.component - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.factory module --------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.entity.factory - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.job module ----------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.entity.job - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.location module ---------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.entity.location - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.note module ------------------------------------------------ - -.. automodule:: pype.vendor.ftrack_api_old.entity.note - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.project\_schema module ----------------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.entity.project_schema - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.entity.user module ------------------------------------------------ - -.. automodule:: pype.vendor.ftrack_api_old.entity.user - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.entity.user.rst b/docs/source/pype.vendor.ftrack_api_old.entity.user.rst deleted file mode 100644 index c0fe6574a6..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.entity.user.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.entity.user module -=============================================== - -.. automodule:: pype.vendor.ftrack_api_old.entity.user - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.event.base.rst b/docs/source/pype.vendor.ftrack_api_old.event.base.rst deleted file mode 100644 index 74b86e3bb2..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.event.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.event.base module -============================================== - -.. automodule:: pype.vendor.ftrack_api_old.event.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.event.expression.rst b/docs/source/pype.vendor.ftrack_api_old.event.expression.rst deleted file mode 100644 index 860678797b..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.event.expression.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.event.expression module -==================================================== - -.. automodule:: pype.vendor.ftrack_api_old.event.expression - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.event.hub.rst b/docs/source/pype.vendor.ftrack_api_old.event.hub.rst deleted file mode 100644 index d09d52eedf..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.event.hub.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.event.hub module -============================================= - -.. automodule:: pype.vendor.ftrack_api_old.event.hub - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.event.rst b/docs/source/pype.vendor.ftrack_api_old.event.rst deleted file mode 100644 index 2db27bf7f8..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.event.rst +++ /dev/null @@ -1,50 +0,0 @@ -pype.vendor.ftrack\_api\_old.event package -========================================== - -.. automodule:: pype.vendor.ftrack_api_old.event - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.ftrack\_api\_old.event.base module ----------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.event.base - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.event.expression module ----------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.event.expression - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.event.hub module ---------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.event.hub - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.event.subscriber module ----------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.event.subscriber - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.event.subscription module ------------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.event.subscription - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.event.subscriber.rst b/docs/source/pype.vendor.ftrack_api_old.event.subscriber.rst deleted file mode 100644 index a9bd13aabc..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.event.subscriber.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.event.subscriber module -==================================================== - -.. automodule:: pype.vendor.ftrack_api_old.event.subscriber - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.event.subscription.rst b/docs/source/pype.vendor.ftrack_api_old.event.subscription.rst deleted file mode 100644 index 423fa9a688..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.event.subscription.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.event.subscription module -====================================================== - -.. automodule:: pype.vendor.ftrack_api_old.event.subscription - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.exception.rst b/docs/source/pype.vendor.ftrack_api_old.exception.rst deleted file mode 100644 index 54dbeeac36..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.exception.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.exception module -============================================= - -.. automodule:: pype.vendor.ftrack_api_old.exception - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.formatter.rst b/docs/source/pype.vendor.ftrack_api_old.formatter.rst deleted file mode 100644 index 75a23eefca..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.formatter.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.formatter module -============================================= - -.. automodule:: pype.vendor.ftrack_api_old.formatter - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.inspection.rst b/docs/source/pype.vendor.ftrack_api_old.inspection.rst deleted file mode 100644 index 2b8849b3d0..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.inspection.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.inspection module -============================================== - -.. automodule:: pype.vendor.ftrack_api_old.inspection - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.logging.rst b/docs/source/pype.vendor.ftrack_api_old.logging.rst deleted file mode 100644 index a10fa10c26..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.logging.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.logging module -=========================================== - -.. automodule:: pype.vendor.ftrack_api_old.logging - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.operation.rst b/docs/source/pype.vendor.ftrack_api_old.operation.rst deleted file mode 100644 index a1d9d606f8..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.operation.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.operation module -============================================= - -.. automodule:: pype.vendor.ftrack_api_old.operation - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.plugin.rst b/docs/source/pype.vendor.ftrack_api_old.plugin.rst deleted file mode 100644 index 0f26c705d2..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.plugin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.plugin module -========================================== - -.. automodule:: pype.vendor.ftrack_api_old.plugin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.query.rst b/docs/source/pype.vendor.ftrack_api_old.query.rst deleted file mode 100644 index 5cf5aba0e4..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.query.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.query module -========================================= - -.. automodule:: pype.vendor.ftrack_api_old.query - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.resource_identifier_transformer.base.rst b/docs/source/pype.vendor.ftrack_api_old.resource_identifier_transformer.base.rst deleted file mode 100644 index dccf51ea71..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.resource_identifier_transformer.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.resource\_identifier\_transformer.base module -========================================================================== - -.. automodule:: pype.vendor.ftrack_api_old.resource_identifier_transformer.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.resource_identifier_transformer.rst b/docs/source/pype.vendor.ftrack_api_old.resource_identifier_transformer.rst deleted file mode 100644 index 342ecd9321..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.resource_identifier_transformer.rst +++ /dev/null @@ -1,18 +0,0 @@ -pype.vendor.ftrack\_api\_old.resource\_identifier\_transformer package -====================================================================== - -.. automodule:: pype.vendor.ftrack_api_old.resource_identifier_transformer - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.ftrack\_api\_old.resource\_identifier\_transformer.base module --------------------------------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.resource_identifier_transformer.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.rst b/docs/source/pype.vendor.ftrack_api_old.rst deleted file mode 100644 index 51d0a29357..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.rst +++ /dev/null @@ -1,126 +0,0 @@ -pype.vendor.ftrack\_api\_old package -==================================== - -.. automodule:: pype.vendor.ftrack_api_old - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.vendor.ftrack_api_old.accessor - pype.vendor.ftrack_api_old.entity - pype.vendor.ftrack_api_old.event - pype.vendor.ftrack_api_old.resource_identifier_transformer - pype.vendor.ftrack_api_old.structure - -Submodules ----------- - -pype.vendor.ftrack\_api\_old.attribute module ---------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.attribute - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.cache module ------------------------------------------ - -.. automodule:: pype.vendor.ftrack_api_old.cache - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.collection module ----------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.collection - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.data module ----------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.data - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.exception module ---------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.exception - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.formatter module ---------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.formatter - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.inspection module ----------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.inspection - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.logging module -------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.logging - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.operation module ---------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.operation - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.plugin module ------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.plugin - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.query module ------------------------------------------ - -.. automodule:: pype.vendor.ftrack_api_old.query - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.session module -------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.session - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.symbol module ------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.symbol - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.session.rst b/docs/source/pype.vendor.ftrack_api_old.session.rst deleted file mode 100644 index beecdeb6af..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.session.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.session module -=========================================== - -.. automodule:: pype.vendor.ftrack_api_old.session - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.structure.base.rst b/docs/source/pype.vendor.ftrack_api_old.structure.base.rst deleted file mode 100644 index 617d8aaed7..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.structure.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.structure.base module -================================================== - -.. automodule:: pype.vendor.ftrack_api_old.structure.base - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.structure.entity_id.rst b/docs/source/pype.vendor.ftrack_api_old.structure.entity_id.rst deleted file mode 100644 index ab6fd0997a..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.structure.entity_id.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.structure.entity\_id module -======================================================== - -.. automodule:: pype.vendor.ftrack_api_old.structure.entity_id - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.structure.id.rst b/docs/source/pype.vendor.ftrack_api_old.structure.id.rst deleted file mode 100644 index 6b887b7917..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.structure.id.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.structure.id module -================================================ - -.. automodule:: pype.vendor.ftrack_api_old.structure.id - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.structure.origin.rst b/docs/source/pype.vendor.ftrack_api_old.structure.origin.rst deleted file mode 100644 index 8ad5fbdc11..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.structure.origin.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.structure.origin module -==================================================== - -.. automodule:: pype.vendor.ftrack_api_old.structure.origin - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.structure.rst b/docs/source/pype.vendor.ftrack_api_old.structure.rst deleted file mode 100644 index 2402430589..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.structure.rst +++ /dev/null @@ -1,50 +0,0 @@ -pype.vendor.ftrack\_api\_old.structure package -============================================== - -.. automodule:: pype.vendor.ftrack_api_old.structure - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.vendor.ftrack\_api\_old.structure.base module --------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.structure.base - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.structure.entity\_id module --------------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.structure.entity_id - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.structure.id module ------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.structure.id - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.structure.origin module ----------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.structure.origin - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.ftrack\_api\_old.structure.standard module ------------------------------------------------------- - -.. automodule:: pype.vendor.ftrack_api_old.structure.standard - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.structure.standard.rst b/docs/source/pype.vendor.ftrack_api_old.structure.standard.rst deleted file mode 100644 index 800201084f..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.structure.standard.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.structure.standard module -====================================================== - -.. automodule:: pype.vendor.ftrack_api_old.structure.standard - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.ftrack_api_old.symbol.rst b/docs/source/pype.vendor.ftrack_api_old.symbol.rst deleted file mode 100644 index bc358d374a..0000000000 --- a/docs/source/pype.vendor.ftrack_api_old.symbol.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.ftrack\_api\_old.symbol module -========================================== - -.. automodule:: pype.vendor.ftrack_api_old.symbol - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.pysync.rst b/docs/source/pype.vendor.pysync.rst deleted file mode 100644 index fbe5b33fb7..0000000000 --- a/docs/source/pype.vendor.pysync.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.vendor.pysync module -========================= - -.. automodule:: pype.vendor.pysync - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.vendor.rst b/docs/source/pype.vendor.rst deleted file mode 100644 index 23aa17f7ab..0000000000 --- a/docs/source/pype.vendor.rst +++ /dev/null @@ -1,37 +0,0 @@ -pype.vendor package -=================== - -.. automodule:: pype.vendor - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 6 - - pype.vendor.backports - pype.vendor.builtins - pype.vendor.capture_gui - pype.vendor.ftrack_api_old - -Submodules ----------- - -pype.vendor.capture module --------------------------- - -.. automodule:: pype.vendor.capture - :members: - :undoc-members: - :show-inheritance: - -pype.vendor.pysync module -------------------------- - -.. automodule:: pype.vendor.pysync - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.version.rst b/docs/source/pype.version.rst deleted file mode 100644 index 7ec69dc423..0000000000 --- a/docs/source/pype.version.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.version module -=================== - -.. automodule:: pype.version - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.widgets.message_window.rst b/docs/source/pype.widgets.message_window.rst deleted file mode 100644 index 60be203837..0000000000 --- a/docs/source/pype.widgets.message_window.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.widgets.message\_window module -=================================== - -.. automodule:: pype.widgets.message_window - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.widgets.popup.rst b/docs/source/pype.widgets.popup.rst deleted file mode 100644 index 7186ff48de..0000000000 --- a/docs/source/pype.widgets.popup.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.widgets.popup module -========================= - -.. automodule:: pype.widgets.popup - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.widgets.project_settings.rst b/docs/source/pype.widgets.project_settings.rst deleted file mode 100644 index 9589cf5479..0000000000 --- a/docs/source/pype.widgets.project_settings.rst +++ /dev/null @@ -1,7 +0,0 @@ -pype.widgets.project\_settings module -===================================== - -.. automodule:: pype.widgets.project_settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/pype.widgets.rst b/docs/source/pype.widgets.rst deleted file mode 100644 index 1f09318b67..0000000000 --- a/docs/source/pype.widgets.rst +++ /dev/null @@ -1,34 +0,0 @@ -pype.widgets package -==================== - -.. automodule:: pype.widgets - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -pype.widgets.message\_window module ------------------------------------ - -.. automodule:: pype.widgets.message_window - :members: - :undoc-members: - :show-inheritance: - -pype.widgets.popup module -------------------------- - -.. automodule:: pype.widgets.popup - :members: - :undoc-members: - :show-inheritance: - -pype.widgets.project\_settings module -------------------------------------- - -.. automodule:: pype.widgets.project_settings - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/readme.rst b/docs/source/readme.rst index 823c0df3c8..138b88bba8 100644 --- a/docs/source/readme.rst +++ b/docs/source/readme.rst @@ -1,2 +1,6 @@ -.. title:: Pype Readme +=============== +OpenPype Readme +=============== + .. include:: ../../README.md + :parser: myst_parser.sphinx_ diff --git a/igniter/__init__.py b/igniter/__init__.py index aa1b1d209e..085a825860 100644 --- a/igniter/__init__.py +++ b/igniter/__init__.py @@ -19,21 +19,41 @@ if "OpenPypeVersion" not in sys.modules: sys.modules["OpenPypeVersion"] = OpenPypeVersion +def _get_qt_app(): + from qtpy import QtWidgets, QtCore + + app = QtWidgets.QApplication.instance() + if app is not None: + return app + + for attr_name in ( + "AA_EnableHighDpiScaling", + "AA_UseHighDpiPixmaps", + ): + attr = getattr(QtCore.Qt, attr_name, None) + if attr is not None: + QtWidgets.QApplication.setAttribute(attr) + + policy = os.getenv("QT_SCALE_FACTOR_ROUNDING_POLICY") + if ( + hasattr(QtWidgets.QApplication, "setHighDpiScaleFactorRoundingPolicy") + and not policy + ): + QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy( + QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough + ) + + return QtWidgets.QApplication(sys.argv) + + def open_dialog(): """Show Igniter dialog.""" if os.getenv("OPENPYPE_HEADLESS_MODE"): print("!!! Can't open dialog in headless mode. Exiting.") sys.exit(1) - from qtpy import QtWidgets, QtCore from .install_dialog import InstallDialog - scale_attr = getattr(QtCore.Qt, "AA_EnableHighDpiScaling", None) - if scale_attr is not None: - QtWidgets.QApplication.setAttribute(scale_attr) - - app = QtWidgets.QApplication.instance() - if not app: - app = QtWidgets.QApplication(sys.argv) + app = _get_qt_app() d = InstallDialog() d.open() @@ -47,16 +67,10 @@ def open_update_window(openpype_version): if os.getenv("OPENPYPE_HEADLESS_MODE"): print("!!! Can't open dialog in headless mode. Exiting.") sys.exit(1) - from qtpy import QtWidgets, QtCore + from .update_window import UpdateWindow - scale_attr = getattr(QtCore.Qt, "AA_EnableHighDpiScaling", None) - if scale_attr is not None: - QtWidgets.QApplication.setAttribute(scale_attr) - - app = QtWidgets.QApplication.instance() - if not app: - app = QtWidgets.QApplication(sys.argv) + app = _get_qt_app() d = UpdateWindow(version=openpype_version) d.open() @@ -71,16 +85,10 @@ def show_message_dialog(title, message): if os.getenv("OPENPYPE_HEADLESS_MODE"): print("!!! Can't open dialog in headless mode. Exiting.") sys.exit(1) - from qtpy import QtWidgets, QtCore + from .message_dialog import MessageDialog - scale_attr = getattr(QtCore.Qt, "AA_EnableHighDpiScaling", None) - if scale_attr is not None: - QtWidgets.QApplication.setAttribute(scale_attr) - - app = QtWidgets.QApplication.instance() - if not app: - app = QtWidgets.QApplication(sys.argv) + app = _get_qt_app() dialog = MessageDialog(title, message) dialog.open() diff --git a/igniter/bootstrap_repos.py b/igniter/bootstrap_repos.py index 6c7c834062..e7b440f812 100644 --- a/igniter/bootstrap_repos.py +++ b/igniter/bootstrap_repos.py @@ -25,7 +25,8 @@ from .user_settings import ( from .tools import ( get_openpype_global_settings, get_openpype_path_from_settings, - get_expected_studio_version_str + get_expected_studio_version_str, + get_local_openpype_path_from_settings ) @@ -34,6 +35,29 @@ LOG_WARNING = 1 LOG_ERROR = 3 +def sanitize_long_path(path): + """Sanitize long paths (260 characters) when on Windows. + + Long paths are not capatible with ZipFile or reading a file, so we can + shorten the path to use. + + Args: + path (str): path to either directory or file. + + Returns: + str: sanitized path + """ + if platform.system().lower() != "windows": + return path + path = os.path.abspath(path) + + if path.startswith("\\\\"): + path = "\\\\?\\UNC\\" + path[2:] + else: + path = "\\\\?\\" + path + return path + + def sha256sum(filename): """Calculate sha256 for content of the file. @@ -53,6 +77,13 @@ def sha256sum(filename): return h.hexdigest() +class ZipFileLongPaths(ZipFile): + def _extract_member(self, member, targetpath, pwd): + return ZipFile._extract_member( + self, member, sanitize_long_path(targetpath), pwd + ) + + class OpenPypeVersion(semver.VersionInfo): """Class for storing information about OpenPype version. @@ -61,6 +92,8 @@ class OpenPypeVersion(semver.VersionInfo): """ path = None + + _local_openpype_path = None # this should match any string complying with https://semver.org/ _VERSION_REGEX = re.compile(r"(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P[a-zA-Z\d\-.]*))?(?:\+(?P[a-zA-Z\d\-.]*))?") # noqa: E501 _installed_version = None @@ -289,6 +322,23 @@ class OpenPypeVersion(semver.VersionInfo): """ return os.getenv("OPENPYPE_PATH") + @classmethod + def get_local_openpype_path(cls): + """Path to unzipped versions. + + By default it should be user appdata, but could be overridden by + settings. + """ + if cls._local_openpype_path: + return cls._local_openpype_path + + settings = get_openpype_global_settings(os.environ["OPENPYPE_MONGO"]) + data_dir = get_local_openpype_path_from_settings(settings) + if not data_dir: + data_dir = Path(user_data_dir("openpype", "pypeclub")) + cls._local_openpype_path = data_dir + return data_dir + @classmethod def openpype_path_is_set(cls): """Path to OpenPype zip directory is set.""" @@ -319,9 +369,8 @@ class OpenPypeVersion(semver.VersionInfo): list: of compatible versions available on the machine. """ - # DEPRECATED: backwards compatible way to look for versions in root - dir_to_search = Path(user_data_dir("openpype", "pypeclub")) - versions = OpenPypeVersion.get_versions_from_directory(dir_to_search) + dir_to_search = cls.get_local_openpype_path() + versions = cls.get_versions_from_directory(dir_to_search) return list(sorted(set(versions))) @@ -533,17 +582,15 @@ class BootstrapRepos: """ # vendor and app used to construct user data dir - self._vendor = "pypeclub" - self._app = "openpype" + self._message = message self._log = log.getLogger(str(__class__)) - self.data_dir = Path(user_data_dir(self._app, self._vendor)) + self.set_data_dir(None) self.secure_registry = OpenPypeSecureRegistry("mongodb") self.registry = OpenPypeSettingsRegistry() self.zip_filter = [".pyc", "__pycache__"] self.openpype_filter = [ - "openpype", "schema", "LICENSE" + "openpype", "LICENSE" ] - self._message = message # dummy progress reporter def empty_progress(x: int): @@ -554,6 +601,13 @@ class BootstrapRepos: progress_callback = empty_progress self._progress_callback = progress_callback + def set_data_dir(self, data_dir): + if not data_dir: + self.data_dir = Path(user_data_dir("openpype", "pypeclub")) + else: + self._print(f"overriding local folder: {data_dir}") + self.data_dir = data_dir + @staticmethod def get_version_path_from_list( version: str, version_list: list) -> Union[Path, None]: @@ -756,7 +810,7 @@ class BootstrapRepos: def _create_openpype_zip(self, zip_path: Path, openpype_path: Path) -> None: """Pack repositories and OpenPype into zip. - We are using :mod:`zipfile` instead :meth:`shutil.make_archive` + We are using :mod:`ZipFile` instead :meth:`shutil.make_archive` because we need to decide what file and directories to include in zip and what not. They are determined by :attr:`zip_filter` on file level and :attr:`openpype_filter` on top level directory in OpenPype @@ -810,7 +864,7 @@ class BootstrapRepos: checksums.append( ( - sha256sum(file.as_posix()), + sha256sum(sanitize_long_path(file.as_posix())), file.resolve().relative_to(openpype_root) ) ) @@ -934,7 +988,9 @@ class BootstrapRepos: if platform.system().lower() == "windows": file_name = file_name.replace("/", "\\") try: - current = sha256sum((path / file_name).as_posix()) + current = sha256sum( + sanitize_long_path((path / file_name).as_posix()) + ) except FileNotFoundError: return False, f"Missing file [ {file_name} ]" @@ -1246,7 +1302,7 @@ class BootstrapRepos: # extract zip there self._print("Extracting zip to destination ...") - with ZipFile(version.path, "r") as zip_ref: + with ZipFileLongPaths(version.path, "r") as zip_ref: zip_ref.extractall(destination) self._print(f"Installed as {version.path.stem}") @@ -1362,7 +1418,7 @@ class BootstrapRepos: # extract zip there self._print("extracting zip to destination ...") - with ZipFile(openpype_version.path, "r") as zip_ref: + with ZipFileLongPaths(openpype_version.path, "r") as zip_ref: self._progress_callback(75) zip_ref.extractall(destination) self._progress_callback(100) diff --git a/igniter/install_thread.py b/igniter/install_thread.py index 4723e6adfb..1d55213de7 100644 --- a/igniter/install_thread.py +++ b/igniter/install_thread.py @@ -14,7 +14,11 @@ from .bootstrap_repos import ( OpenPypeVersion ) -from .tools import validate_mongo_connection +from .tools import ( + get_openpype_global_settings, + get_local_openpype_path_from_settings, + validate_mongo_connection +) class InstallThread(QtCore.QThread): @@ -80,6 +84,15 @@ class InstallThread(QtCore.QThread): return os.environ["OPENPYPE_MONGO"] = self._mongo + if not validate_mongo_connection(self._mongo): + self.message.emit(f"Cannot connect to {self._mongo}", True) + self._set_result(-1) + return + + global_settings = get_openpype_global_settings(self._mongo) + data_dir = get_local_openpype_path_from_settings(global_settings) + bs.set_data_dir(data_dir) + self.message.emit( f"Detecting installed OpenPype versions in {bs.data_dir}", False) diff --git a/igniter/tools.py b/igniter/tools.py index 79235b2329..9dea203f0c 100644 --- a/igniter/tools.py +++ b/igniter/tools.py @@ -40,7 +40,7 @@ def should_add_certificate_path_to_mongo_url(mongo_url): add_certificate = False # Check if url 'ssl' or 'tls' are set to 'true' for key in ("ssl", "tls"): - if key in query and "true" in query["ssl"]: + if key in query and "true" in query[key]: add_certificate = True break @@ -73,7 +73,7 @@ def validate_mongo_connection(cnx: str) -> (bool, str): } # Add certificate path if should be required if should_add_certificate_path_to_mongo_url(cnx): - kwargs["ssl_ca_certs"] = certifi.where() + kwargs["tlsCAFile"] = certifi.where() try: client = MongoClient(cnx, **kwargs) @@ -147,7 +147,7 @@ def get_openpype_global_settings(url: str) -> dict: """ kwargs = {} if should_add_certificate_path_to_mongo_url(url): - kwargs["ssl_ca_certs"] = certifi.where() + kwargs["tlsCAFile"] = certifi.where() try: # Create mongo connection @@ -188,6 +188,26 @@ def get_openpype_path_from_settings(settings: dict) -> Union[str, None]: return next((path for path in paths if os.path.exists(path)), None) +def get_local_openpype_path_from_settings(settings: dict) -> Union[str, None]: + """Get OpenPype local path from global settings. + + Used to download and unzip OP versions. + Args: + settings (dict): settings from DB. + + Returns: + path to OpenPype or None if not found + """ + path = ( + settings + .get("local_openpype_path", {}) + .get(platform.system().lower()) + ) + if path: + return Path(path) + return None + + def get_expected_studio_version_str( staging=False, global_settings=None ) -> str: diff --git a/igniter/update_thread.py b/igniter/update_thread.py index e98c95f892..0223477d0a 100644 --- a/igniter/update_thread.py +++ b/igniter/update_thread.py @@ -48,6 +48,8 @@ class UpdateThread(QtCore.QThread): """ bs = BootstrapRepos( progress_callback=self.set_progress, message=self.message) + + bs.set_data_dir(OpenPypeVersion.get_local_openpype_path()) version_path = bs.install_version(self._openpype_version) self._set_result(version_path) diff --git a/inno_setup.iss b/inno_setup.iss index 3adde52a8b..d9a41d22ee 100644 --- a/inno_setup.iss +++ b/inno_setup.iss @@ -14,10 +14,10 @@ AppId={{B9E9DF6A-5BDA-42DD-9F35-C09D564C4D93} AppName={#MyAppName} AppVersion={#AppVer} AppVerName={#MyAppName} version {#AppVer} -AppPublisher=Orbi Tools s.r.o -AppPublisherURL=http://pype.club -AppSupportURL=http://pype.club -AppUpdatesURL=http://pype.club +AppPublisher=Ynput s.r.o +AppPublisherURL=https://ynput.io +AppSupportURL=https://ynput.io +AppUpdatesURL=https://ynput.io DefaultDirName={autopf}\{#MyAppName}\{#AppVer} UsePreviousAppDir=no DisableProgramGroupPage=yes @@ -36,7 +36,7 @@ WizardStyle=modern Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] -Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" [InstallDelete] ; clean everything in previous installation folder @@ -53,4 +53,3 @@ Name: "{autodesktop}\{#MyAppName} {#AppVer}"; Filename: "{app}\openpype_gui.exe" [Run] Filename: "{app}\openpype_gui.exe"; Description: "{cm:LaunchProgram,OpenPype}"; Flags: nowait postinstall skipifsilent - diff --git a/openpype/__init__.py b/openpype/__init__.py index 810664707a..e6b77b1853 100644 --- a/openpype/__init__.py +++ b/openpype/__init__.py @@ -3,3 +3,5 @@ import os PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__)) PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") + +AYON_SERVER_ENABLED = os.environ.get("USE_AYON_SERVER") == "1" diff --git a/openpype/action.py b/openpype/action.py deleted file mode 100644 index 15c96404b6..0000000000 --- a/openpype/action.py +++ /dev/null @@ -1,137 +0,0 @@ -import warnings -import functools -import pyblish.api - - -class ActionDeprecatedWarning(DeprecationWarning): - pass - - -def deprecated(new_destination): - """Mark functions as deprecated. - - It will result in a warning being emitted when the function is used. - """ - - func = None - if callable(new_destination): - func = new_destination - new_destination = None - - def _decorator(decorated_func): - if new_destination is None: - warning_message = ( - " Please check content of deprecated function to figure out" - " possible replacement." - ) - else: - warning_message = " Please replace your usage with '{}'.".format( - new_destination - ) - - @functools.wraps(decorated_func) - def wrapper(*args, **kwargs): - warnings.simplefilter("always", ActionDeprecatedWarning) - warnings.warn( - ( - "Call to deprecated function '{}'" - "\nFunction was moved or removed.{}" - ).format(decorated_func.__name__, warning_message), - category=ActionDeprecatedWarning, - stacklevel=4 - ) - return decorated_func(*args, **kwargs) - return wrapper - - if func is None: - return _decorator - return _decorator(func) - - -@deprecated("openpype.pipeline.publish.get_errored_instances_from_context") -def get_errored_instances_from_context(context): - """ - Deprecated: - Since 3.14.* will be removed in 3.16.* or later. - """ - - from openpype.pipeline.publish import get_errored_instances_from_context - - return get_errored_instances_from_context(context) - - -@deprecated("openpype.pipeline.publish.get_errored_plugins_from_context") -def get_errored_plugins_from_data(context): - """ - Deprecated: - Since 3.14.* will be removed in 3.16.* or later. - """ - - from openpype.pipeline.publish import get_errored_plugins_from_context - - return get_errored_plugins_from_context(context) - - -class RepairAction(pyblish.api.Action): - """Repairs the action - - To process the repairing this requires a static `repair(instance)` method - is available on the plugin. - - Deprecated: - 'RepairAction' and 'RepairContextAction' were moved to - 'openpype.pipeline.publish' please change you imports. - There is no "reasonable" way hot mark these classes as deprecated - to show warning of wrong import. Deprecated since 3.14.* will be - removed in 3.16.* - - """ - label = "Repair" - on = "failed" # This action is only available on a failed plug-in - icon = "wrench" # Icon from Awesome Icon - - def process(self, context, plugin): - - if not hasattr(plugin, "repair"): - raise RuntimeError("Plug-in does not have repair method.") - - # Get the errored instances - self.log.info("Finding failed instances..") - errored_instances = get_errored_instances_from_context(context) - - # Apply pyblish.logic to get the instances for the plug-in - instances = pyblish.api.instances_by_plugin(errored_instances, plugin) - for instance in instances: - plugin.repair(instance) - - -class RepairContextAction(pyblish.api.Action): - """Repairs the action - - To process the repairing this requires a static `repair(instance)` method - is available on the plugin. - - Deprecated: - 'RepairAction' and 'RepairContextAction' were moved to - 'openpype.pipeline.publish' please change you imports. - There is no "reasonable" way hot mark these classes as deprecated - to show warning of wrong import. Deprecated since 3.14.* will be - removed in 3.16.* - - """ - label = "Repair" - on = "failed" # This action is only available on a failed plug-in - - def process(self, context, plugin): - - if not hasattr(plugin, "repair"): - raise RuntimeError("Plug-in does not have repair method.") - - # Get the errored instances - self.log.info("Finding failed instances..") - errored_plugins = get_errored_plugins_from_data(context) - - # Apply pyblish.logic to get the instances for the plug-in - if plugin in errored_plugins: - self.log.info("Attempting fix ...") - plugin.repair(context) diff --git a/openpype/cli.py b/openpype/cli.py index 54af42920d..8caa139765 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -5,11 +5,25 @@ import sys import code import click -# import sys +from openpype import AYON_SERVER_ENABLED from .pype_commands import PypeCommands -@click.group(invoke_without_command=True) +class AliasedGroup(click.Group): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._aliases = {} + + def set_alias(self, src_name, dst_name): + self._aliases[dst_name] = src_name + + def get_command(self, ctx, cmd_name): + if cmd_name in self._aliases: + cmd_name = self._aliases[cmd_name] + return super().get_command(ctx, cmd_name) + + +@click.group(cls=AliasedGroup, invoke_without_command=True) @click.pass_context @click.option("--use-version", expose_value=False, help="use specified version") @@ -33,7 +47,11 @@ def main(ctx): if ctx.invoked_subcommand is None: # Print help if headless mode is used - if os.environ.get("OPENPYPE_HEADLESS_MODE") == "1": + if AYON_SERVER_ENABLED: + is_headless = os.getenv("AYON_HEADLESS_MODE") == "1" + else: + is_headless = os.getenv("OPENPYPE_HEADLESS_MODE") == "1" + if is_headless: print(ctx.get_help()) sys.exit(0) else: @@ -44,6 +62,9 @@ def main(ctx): @click.option("-d", "--dev", is_flag=True, help="Settings in Dev mode") def settings(dev): """Show Pype Settings UI.""" + + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'settings' command.") PypeCommands().launch_settings_gui(dev) @@ -58,16 +79,20 @@ def tray(): @PypeCommands.add_modules -@main.group(help="Run command line arguments of OpenPype modules") +@main.group(help="Run command line arguments of OpenPype addons") @click.pass_context def module(ctx): - """Module specific commands created dynamically. + """Addon specific commands created dynamically. - These commands are generated dynamically by currently loaded addon/modules. + These commands are generated dynamically by currently loaded addons. """ pass +# Add 'addon' as alias for module +main.set_alias("module", "addon") + + @main.command() @click.option("--ftrack-url", envvar="FTRACK_SERVER", help="Ftrack server url") @@ -93,6 +118,8 @@ def eventserver(ftrack_url, on linux and window service). """ + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'eventserver' command.") PypeCommands().launch_eventservercli( ftrack_url, ftrack_user, @@ -117,6 +144,10 @@ def webpublisherwebserver(executable, upload_dir, host=None, port=None): Expect "pype.club" user created on Ftrack. """ + if AYON_SERVER_ENABLED: + raise RuntimeError( + "AYON does not support 'webpublisherwebserver' command." + ) PypeCommands().launch_webpublisher_webservercli( upload_dir=upload_dir, executable=executable, @@ -165,122 +196,10 @@ def publish(paths, targets, gui): PypeCommands.publish(list(paths), targets, gui) -@main.command() -@click.argument("path") -@click.option("-h", "--host", help="Host") -@click.option("-u", "--user", help="User email address") -@click.option("-p", "--project", help="Project") -@click.option("-t", "--targets", help="Targets", default=None, - multiple=True) -def remotepublishfromapp(project, path, host, user=None, targets=None): - """Start CLI publishing. - - Publish collects json from paths provided as an argument. - More than one path is allowed. - """ - - PypeCommands.remotepublishfromapp( - project, path, host, user, targets=targets - ) - - -@main.command() -@click.argument("path") -@click.option("-u", "--user", help="User email address") -@click.option("-p", "--project", help="Project") -@click.option("-t", "--targets", help="Targets", default=None, - multiple=True) -def remotepublish(project, path, user=None, targets=None): - """Start CLI publishing. - - Publish collects json from paths provided as an argument. - More than one path is allowed. - """ - - PypeCommands.remotepublish(project, path, user, targets=targets) - - -@main.command() -@click.option("-p", "--project", required=True, - help="name of project asset is under") -@click.option("-a", "--asset", required=True, - help="name of asset to which we want to copy textures") -@click.option("--path", required=True, - help="path where textures are found", - type=click.Path(exists=True)) -def texturecopy(project, asset, path): - """Copy specified textures to provided asset path. - - It validates if project and asset exists. Then it will use speedcopy to - copy all textures found in all directories under --path to destination - folder, determined by template texture in anatomy. I will use source - filename and automatically rise version number on directory. - - Result will be copied without directory structure so it will be flat then. - Nothing is written to database. - """ - - PypeCommands().texture_copy(project, asset, path) - - -@main.command(context_settings={"ignore_unknown_options": True}) -@click.option("--app", help="Registered application name") -@click.option("--project", help="Project name", - default=lambda: os.environ.get('AVALON_PROJECT', '')) -@click.option("--asset", help="Asset name", - default=lambda: os.environ.get('AVALON_ASSET', '')) -@click.option("--task", help="Task name", - default=lambda: os.environ.get('AVALON_TASK', '')) -@click.option("--tools", help="List of tools to add") -@click.option("--user", help="Pype user name", - default=lambda: os.environ.get('OPENPYPE_USERNAME', '')) -@click.option("-fs", - "--ftrack-server", - help="Registered application name", - default=lambda: os.environ.get('FTRACK_SERVER', '')) -@click.option("-fu", - "--ftrack-user", - help="Registered application name", - default=lambda: os.environ.get('FTRACK_API_USER', '')) -@click.option("-fk", - "--ftrack-key", - help="Registered application name", - default=lambda: os.environ.get('FTRACK_API_KEY', '')) -@click.argument('arguments', nargs=-1) -def launch(app, project, asset, task, - ftrack_server, ftrack_user, ftrack_key, tools, arguments, user): - """Launch registered application name in Pype context. - - You can define applications in pype-config toml files. Project, asset name - and task name must be provided (even if they are not used by app itself). - Optionally you can specify ftrack credentials if needed. - - ARGUMENTS are passed to launched application. - - """ - # TODO: this needs to switch for Settings - if ftrack_server: - os.environ["FTRACK_SERVER"] = ftrack_server - - if ftrack_server: - os.environ["FTRACK_API_USER"] = ftrack_user - - if ftrack_server: - os.environ["FTRACK_API_KEY"] = ftrack_key - - if user: - os.environ["OPENPYPE_USERNAME"] = user - - # test required - if not project or not asset or not task: - print("!!! Missing required arguments") - return - - PypeCommands().run_application(app, project, asset, task, tools, arguments) - - @main.command(context_settings={"ignore_unknown_options": True}) def projectmanager(): + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'projectmanager' command.") PypeCommands().launch_project_manager() @@ -363,6 +282,9 @@ def run(script): "--app_variant", help="Provide specific app variant for test, empty for latest", default=None) +@click.option("--app_group", + help="Provide specific app group for test, empty for default", + default=None) @click.option("-t", "--timeout", help="Provide specific timeout value for test case", @@ -371,19 +293,32 @@ def run(script): "--setup_only", help="Only create dbs, do not run tests", default=None) +@click.option("--mongo_url", + help="MongoDB for testing.", + default=None) +@click.option("--dump_databases", + help="Dump all databases to data folder.", + default=None) def runtests(folder, mark, pyargs, test_data_folder, persist, app_variant, - timeout, setup_only): + timeout, setup_only, mongo_url, app_group, dump_databases): """Run all automatic tests after proper initialization via start.py""" PypeCommands().run_tests(folder, mark, pyargs, test_data_folder, - persist, app_variant, timeout, setup_only) + persist, app_variant, timeout, setup_only, + mongo_url, app_group, dump_databases) -@main.command() +@main.command(help="DEPRECATED - run sync server") +@click.pass_context @click.option("-a", "--active_site", required=True, - help="Name of active stie") -def syncserver(active_site): + help="Name of active site") +def syncserver(ctx, active_site): """Run sync site server in background. + Deprecated: + This command is deprecated and will be removed in future versions. + Use '~/openpype_console module sync_server syncservice' instead. + + Details: Some Site Sync use cases need to expose site to another one. For example if majority of artists work in studio, they are not using SS at all, but if you want to expose published assets to 'studio' site @@ -397,7 +332,12 @@ def syncserver(active_site): var OPENPYPE_LOCAL_ID set to 'active_site'. """ - PypeCommands().syncserver(active_site) + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'syncserver' command.") + + from openpype.modules.sync_server.sync_server_module import ( + syncservice) + ctx.invoke(syncservice, active_site=active_site) @main.command() @@ -409,6 +349,8 @@ def repack_version(directory): recalculating file checksums. It will try to use version detected in directory name. """ + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'repack-version' command.") PypeCommands().repack_version(directory) @@ -420,6 +362,9 @@ def repack_version(directory): "--dbonly", help="Store only Database data", default=False, is_flag=True) def pack_project(project, dirpath, dbonly): """Create a package of project with all files and database dump.""" + + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'pack-project' command.") PypeCommands().pack_project(project, dirpath, dbonly) @@ -432,6 +377,8 @@ def pack_project(project, dirpath, dbonly): "--dbonly", help="Store only Database data", default=False, is_flag=True) def unpack_project(zipfile, root, dbonly): """Create a package of project with all files and database dump.""" + if AYON_SERVER_ENABLED: + raise RuntimeError("AYON does not support 'unpack-project' command.") PypeCommands().unpack_project(zipfile, root, dbonly) @@ -446,9 +393,17 @@ def interactive(): Executable 'openpype_gui' on Windows won't work. """ - from openpype.version import __version__ + if AYON_SERVER_ENABLED: + version = os.environ["AYON_VERSION"] + banner = ( + f"AYON launcher {version}\nPython {sys.version} on {sys.platform}" + ) + else: + from openpype.version import __version__ - banner = f"OpenPype {__version__}\nPython {sys.version} on {sys.platform}" + banner = ( + f"OpenPype {__version__}\nPython {sys.version} on {sys.platform}" + ) code.interact(banner) @@ -457,11 +412,13 @@ def interactive(): is_flag=True, default=False) def version(build): """Print OpenPype version.""" + if AYON_SERVER_ENABLED: + print(os.environ["AYON_VERSION"]) + return from openpype.version import __version__ from igniter.bootstrap_repos import BootstrapRepos, OpenPypeVersion from pathlib import Path - import os if getattr(sys, 'frozen', False): local_version = BootstrapRepos.get_version( diff --git a/openpype/client/__init__.py b/openpype/client/__init__.py index 7831afd8ad..ba36d940e3 100644 --- a/openpype/client/__init__.py +++ b/openpype/client/__init__.py @@ -1,6 +1,7 @@ from .mongo import ( OpenPypeMongoConnection, ) +from .server.utils import get_ayon_server_api_connection from .entities import ( get_projects, @@ -43,6 +44,8 @@ from .entities import ( get_thumbnail_id_from_source, get_workfile_info, + + get_asset_name_identifier, ) from .entity_links import ( @@ -59,6 +62,8 @@ from .operations import ( __all__ = ( "OpenPypeMongoConnection", + "get_ayon_server_api_connection", + "get_projects", "get_project", "get_whole_project", @@ -105,4 +110,6 @@ __all__ = ( "get_linked_representation_id", "create_project", + + "get_asset_name_identifier", ) diff --git a/openpype/client/entities.py b/openpype/client/entities.py index 8004dc3019..cbaa943743 100644 --- a/openpype/client/entities.py +++ b/openpype/client/entities.py @@ -1,1543 +1,25 @@ -"""Unclear if these will have public functions like these. +from openpype import AYON_SERVER_ENABLED -Goal is that most of functions here are called on (or with) an object -that has project name as a context (e.g. on 'ProjectEntity'?). - -+ We will need more specific functions doing very specific queries really fast. -""" - -import re -import collections - -import six -from bson.objectid import ObjectId - -from .mongo import get_project_database, get_project_connection - -PatternType = type(re.compile("")) +if not AYON_SERVER_ENABLED: + from .mongo.entities import * +else: + from .server.entities import * -def _prepare_fields(fields, required_fields=None): - if not fields: - return None +def get_asset_name_identifier(asset_doc): + """Get asset name identifier by asset document. - output = { - field: True - for field in fields - } - if "_id" not in output: - output["_id"] = True + This function is added because of AYON implementation where name + identifier is not just a name but full path. - if required_fields: - for key in required_fields: - output[key] = True - return output - - -def convert_id(in_id): - """Helper function for conversion of id from string to ObjectId. + Asset document must have "name" key, and "data.parents" when in AYON mode. Args: - in_id (Union[str, ObjectId, Any]): Entity id that should be converted - to right type for queries. - - Returns: - Union[ObjectId, Any]: Converted ids to ObjectId or in type. + asset_doc (dict[str, Any]): Asset document. """ - if isinstance(in_id, six.string_types): - return ObjectId(in_id) - return in_id - - -def convert_ids(in_ids): - """Helper function for conversion of ids from string to ObjectId. - - Args: - in_ids (Iterable[Union[str, ObjectId, Any]]): List of entity ids that - should be converted to right type for queries. - - Returns: - List[ObjectId]: Converted ids to ObjectId. - """ - - _output = set() - for in_id in in_ids: - if in_id is not None: - _output.add(convert_id(in_id)) - return list(_output) - - -def get_projects(active=True, inactive=False, fields=None): - """Yield all project entity documents. - - Args: - active (Optional[bool]): Include active projects. Defaults to True. - inactive (Optional[bool]): Include inactive projects. - Defaults to False. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Yields: - dict: Project entity data which can be reduced to specified 'fields'. - None is returned if project with specified filters was not found. - """ - mongodb = get_project_database() - for project_name in mongodb.collection_names(): - if project_name in ("system.indexes",): - continue - project_doc = get_project( - project_name, active=active, inactive=inactive, fields=fields - ) - if project_doc is not None: - yield project_doc - - -def get_project(project_name, active=True, inactive=True, fields=None): - """Return project entity document by project name. - - Args: - project_name (str): Name of project. - active (Optional[bool]): Allow active project. Defaults to True. - inactive (Optional[bool]): Allow inactive project. Defaults to True. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Project entity data which can be reduced to - specified 'fields'. None is returned if project with specified - filters was not found. - """ - # Skip if both are disabled - if not active and not inactive: - return None - - query_filter = {"type": "project"} - # Keep query untouched if both should be available - if active and inactive: - pass - - # Add filter to keep only active - elif active: - query_filter["$or"] = [ - {"data.active": {"$exists": False}}, - {"data.active": True}, - ] - - # Add filter to keep only inactive - elif inactive: - query_filter["$or"] = [ - {"data.active": {"$exists": False}}, - {"data.active": False}, - ] - - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def get_whole_project(project_name): - """Receive all documents from project. - - Helper that can be used to get all document from whole project. For example - for backups etc. - - Returns: - Cursor: Query cursor as iterable which returns all documents from - project collection. - """ - - conn = get_project_connection(project_name) - return conn.find({}) - - -def get_asset_by_id(project_name, asset_id, fields=None): - """Receive asset data by its id. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_id (Union[str, ObjectId]): Asset's id. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Asset entity data which can be reduced to - specified 'fields'. None is returned if asset with specified - filters was not found. - """ - - asset_id = convert_id(asset_id) - if not asset_id: - return None - - query_filter = {"type": "asset", "_id": asset_id} - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def get_asset_by_name(project_name, asset_name, fields=None): - """Receive asset data by its name. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_name (str): Asset's name. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Asset entity data which can be reduced to - specified 'fields'. None is returned if asset with specified - filters was not found. - """ - - if not asset_name: - return None - - query_filter = {"type": "asset", "name": asset_name} - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -# NOTE this could be just public function? -# - any better variable name instead of 'standard'? -# - same approach can be used for rest of types -def _get_assets( - project_name, - asset_ids=None, - asset_names=None, - parent_ids=None, - standard=True, - archived=False, - fields=None -): - """Assets for specified project by passed filters. - - Passed filters (ids and names) are always combined so all conditions must - match. - - To receive all assets from project just keep filters empty. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_ids (Iterable[Union[str, ObjectId]]): Asset ids that should - be found. - asset_names (Iterable[str]): Name assets that should be found. - parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. - standard (bool): Query standard assets (type 'asset'). - archived (bool): Query archived assets (type 'archived_asset'). - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Query cursor as iterable which returns asset documents matching - passed filters. - """ - - asset_types = [] - if standard: - asset_types.append("asset") - if archived: - asset_types.append("archived_asset") - - if not asset_types: - return [] - - if len(asset_types) == 1: - query_filter = {"type": asset_types[0]} - else: - query_filter = {"type": {"$in": asset_types}} - - if asset_ids is not None: - asset_ids = convert_ids(asset_ids) - if not asset_ids: - return [] - query_filter["_id"] = {"$in": asset_ids} - - if asset_names is not None: - if not asset_names: - return [] - query_filter["name"] = {"$in": list(asset_names)} - - if parent_ids is not None: - parent_ids = convert_ids(parent_ids) - if not parent_ids: - return [] - query_filter["data.visualParent"] = {"$in": parent_ids} - - conn = get_project_connection(project_name) - - return conn.find(query_filter, _prepare_fields(fields)) - - -def get_assets( - project_name, - asset_ids=None, - asset_names=None, - parent_ids=None, - archived=False, - fields=None -): - """Assets for specified project by passed filters. - - Passed filters (ids and names) are always combined so all conditions must - match. - - To receive all assets from project just keep filters empty. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_ids (Iterable[Union[str, ObjectId]]): Asset ids that should - be found. - asset_names (Iterable[str]): Name assets that should be found. - parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. - archived (bool): Add also archived assets. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Query cursor as iterable which returns asset documents matching - passed filters. - """ - - return _get_assets( - project_name, - asset_ids, - asset_names, - parent_ids, - True, - archived, - fields - ) - - -def get_archived_assets( - project_name, - asset_ids=None, - asset_names=None, - parent_ids=None, - fields=None -): - """Archived assets for specified project by passed filters. - - Passed filters (ids and names) are always combined so all conditions must - match. - - To receive all archived assets from project just keep filters empty. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_ids (Iterable[Union[str, ObjectId]]): Asset ids that should - be found. - asset_names (Iterable[str]): Name assets that should be found. - parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Query cursor as iterable which returns asset documents matching - passed filters. - """ - - return _get_assets( - project_name, asset_ids, asset_names, parent_ids, False, True, fields - ) - - -def get_asset_ids_with_subsets(project_name, asset_ids=None): - """Find out which assets have existing subsets. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_ids (Iterable[Union[str, ObjectId]]): Look only for entered - asset ids. - - Returns: - Iterable[ObjectId]: Asset ids that have existing subsets. - """ - - subset_query = { - "type": "subset" - } - if asset_ids is not None: - asset_ids = convert_ids(asset_ids) - if not asset_ids: - return [] - subset_query["parent"] = {"$in": asset_ids} - - conn = get_project_connection(project_name) - result = conn.aggregate([ - { - "$match": subset_query - }, - { - "$group": { - "_id": "$parent", - "count": {"$sum": 1} - } - } - ]) - asset_ids_with_subsets = [] - for item in result: - asset_id = item["_id"] - count = item["count"] - if count > 0: - asset_ids_with_subsets.append(asset_id) - return asset_ids_with_subsets - - -def get_subset_by_id(project_name, subset_id, fields=None): - """Single subset entity data by its id. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_id (Union[str, ObjectId]): Id of subset which should be found. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Subset entity data which can be reduced to - specified 'fields'. None is returned if subset with specified - filters was not found. - """ - - subset_id = convert_id(subset_id) - if not subset_id: - return None - - query_filters = {"type": "subset", "_id": subset_id} - conn = get_project_connection(project_name) - return conn.find_one(query_filters, _prepare_fields(fields)) - - -def get_subset_by_name(project_name, subset_name, asset_id, fields=None): - """Single subset entity data by its name and its version id. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_name (str): Name of subset. - asset_id (Union[str, ObjectId]): Id of parent asset. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Subset entity data which can be reduced to - specified 'fields'. None is returned if subset with specified - filters was not found. - """ - if not subset_name: - return None - - asset_id = convert_id(asset_id) - if not asset_id: - return None - - query_filters = { - "type": "subset", - "name": subset_name, - "parent": asset_id - } - conn = get_project_connection(project_name) - return conn.find_one(query_filters, _prepare_fields(fields)) - - -def get_subsets( - project_name, - subset_ids=None, - subset_names=None, - asset_ids=None, - names_by_asset_ids=None, - archived=False, - fields=None -): - """Subset entities data from one project filtered by entered filters. - - Filters are additive (all conditions must pass to return subset). - - Args: - project_name (str): Name of project where to look for queried entities. - subset_ids (Iterable[Union[str, ObjectId]]): Subset ids that should be - queried. Filter ignored if 'None' is passed. - subset_names (Iterable[str]): Subset names that should be queried. - Filter ignored if 'None' is passed. - asset_ids (Iterable[Union[str, ObjectId]]): Asset ids under which - should look for the subsets. Filter ignored if 'None' is passed. - names_by_asset_ids (dict[ObjectId, List[str]]): Complex filtering - using asset ids and list of subset names under the asset. - archived (bool): Look for archived subsets too. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Iterable cursor yielding all matching subsets. - """ - - subset_types = ["subset"] - if archived: - subset_types.append("archived_subset") - - if len(subset_types) == 1: - query_filter = {"type": subset_types[0]} - else: - query_filter = {"type": {"$in": subset_types}} - - if asset_ids is not None: - asset_ids = convert_ids(asset_ids) - if not asset_ids: - return [] - query_filter["parent"] = {"$in": asset_ids} - - if subset_ids is not None: - subset_ids = convert_ids(subset_ids) - if not subset_ids: - return [] - query_filter["_id"] = {"$in": subset_ids} - - if subset_names is not None: - if not subset_names: - return [] - query_filter["name"] = {"$in": list(subset_names)} - - if names_by_asset_ids is not None: - or_query = [] - for asset_id, names in names_by_asset_ids.items(): - if asset_id and names: - or_query.append({ - "parent": convert_id(asset_id), - "name": {"$in": list(names)} - }) - if not or_query: - return [] - query_filter["$or"] = or_query - - conn = get_project_connection(project_name) - return conn.find(query_filter, _prepare_fields(fields)) - - -def get_subset_families(project_name, subset_ids=None): - """Set of main families of subsets. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_ids (Iterable[Union[str, ObjectId]]): Subset ids that should - be queried. All subsets from project are used if 'None' is passed. - - Returns: - set[str]: Main families of matching subsets. - """ - - subset_filter = { - "type": "subset" - } - if subset_ids is not None: - if not subset_ids: - return set() - subset_filter["_id"] = {"$in": list(subset_ids)} - - conn = get_project_connection(project_name) - result = list(conn.aggregate([ - {"$match": subset_filter}, - {"$project": { - "family": {"$arrayElemAt": ["$data.families", 0]} - }}, - {"$group": { - "_id": "family_group", - "families": {"$addToSet": "$family"} - }} - ])) - if result: - return set(result[0]["families"]) - return set() - - -def get_version_by_id(project_name, version_id, fields=None): - """Single version entity data by its id. - - Args: - project_name (str): Name of project where to look for queried entities. - version_id (Union[str, ObjectId]): Id of version which should be found. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Version entity data which can be reduced to - specified 'fields'. None is returned if version with specified - filters was not found. - """ - - version_id = convert_id(version_id) - if not version_id: - return None - - query_filter = { - "type": {"$in": ["version", "hero_version"]}, - "_id": version_id - } - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def get_version_by_name(project_name, version, subset_id, fields=None): - """Single version entity data by its name and subset id. - - Args: - project_name (str): Name of project where to look for queried entities. - version (int): name of version entity (its version). - subset_id (Union[str, ObjectId]): Id of version which should be found. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Version entity data which can be reduced to - specified 'fields'. None is returned if version with specified - filters was not found. - """ - - subset_id = convert_id(subset_id) - if not subset_id: - return None - - conn = get_project_connection(project_name) - query_filter = { - "type": "version", - "parent": subset_id, - "name": version - } - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def version_is_latest(project_name, version_id): - """Is version the latest from its subset. - - Note: - Hero versions are considered as latest. - - Todo: - Maybe raise exception when version was not found? - - Args: - project_name (str):Name of project where to look for queried entities. - version_id (Union[str, ObjectId]): Version id which is checked. - - Returns: - bool: True if is latest version from subset else False. - """ - - version_id = convert_id(version_id) - if not version_id: - return False - version_doc = get_version_by_id( - project_name, version_id, fields=["_id", "type", "parent"] - ) - # What to do when version is not found? - if not version_doc: - return False - - if version_doc["type"] == "hero_version": - return True - - last_version = get_last_version_by_subset_id( - project_name, version_doc["parent"], fields=["_id"] - ) - return last_version["_id"] == version_id - - -def _get_versions( - project_name, - subset_ids=None, - version_ids=None, - versions=None, - standard=True, - hero=False, - fields=None -): - version_types = [] - if standard: - version_types.append("version") - - if hero: - version_types.append("hero_version") - - if not version_types: - return [] - elif len(version_types) == 1: - query_filter = {"type": version_types[0]} - else: - query_filter = {"type": {"$in": version_types}} - - if subset_ids is not None: - subset_ids = convert_ids(subset_ids) - if not subset_ids: - return [] - query_filter["parent"] = {"$in": subset_ids} - - if version_ids is not None: - version_ids = convert_ids(version_ids) - if not version_ids: - return [] - query_filter["_id"] = {"$in": version_ids} - - if versions is not None: - versions = list(versions) - if not versions: - return [] - - if len(versions) == 1: - query_filter["name"] = versions[0] - else: - query_filter["name"] = {"$in": versions} - - conn = get_project_connection(project_name) - - return conn.find(query_filter, _prepare_fields(fields)) - - -def get_versions( - project_name, - version_ids=None, - subset_ids=None, - versions=None, - hero=False, - fields=None -): - """Version entities data from one project filtered by entered filters. - - Filters are additive (all conditions must pass to return subset). - - Args: - project_name (str): Name of project where to look for queried entities. - version_ids (Iterable[Union[str, ObjectId]]): Version ids that will - be queried. Filter ignored if 'None' is passed. - subset_ids (Iterable[str]): Subset ids that will be queried. - Filter ignored if 'None' is passed. - versions (Iterable[int]): Version names (as integers). - Filter ignored if 'None' is passed. - hero (bool): Look also for hero versions. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Iterable cursor yielding all matching versions. - """ - - return _get_versions( - project_name, - subset_ids, - version_ids, - versions, - standard=True, - hero=hero, - fields=fields - ) - - -def get_hero_version_by_subset_id(project_name, subset_id, fields=None): - """Hero version by subset id. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_id (Union[str, ObjectId]): Subset id under which - is hero version. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Hero version entity data which can be reduced to - specified 'fields'. None is returned if hero version with specified - filters was not found. - """ - - subset_id = convert_id(subset_id) - if not subset_id: - return None - - versions = list(_get_versions( - project_name, - subset_ids=[subset_id], - standard=False, - hero=True, - fields=fields - )) - if versions: - return versions[0] - return None - - -def get_hero_version_by_id(project_name, version_id, fields=None): - """Hero version by its id. - - Args: - project_name (str): Name of project where to look for queried entities. - version_id (Union[str, ObjectId]): Hero version id. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Hero version entity data which can be reduced to - specified 'fields'. None is returned if hero version with specified - filters was not found. - """ - - version_id = convert_id(version_id) - if not version_id: - return None - - versions = list(_get_versions( - project_name, - version_ids=[version_id], - standard=False, - hero=True, - fields=fields - )) - if versions: - return versions[0] - return None - - -def get_hero_versions( - project_name, - subset_ids=None, - version_ids=None, - fields=None -): - """Hero version entities data from one project filtered by entered filters. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_ids (Iterable[Union[str, ObjectId]]): Subset ids for which - should look for hero versions. Filter ignored if 'None' is passed. - version_ids (Iterable[Union[str, ObjectId]]): Hero version ids. Filter - ignored if 'None' is passed. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor|list: Iterable yielding hero versions matching passed filters. - """ - - return _get_versions( - project_name, - subset_ids, - version_ids, - standard=False, - hero=True, - fields=fields - ) - - -def get_output_link_versions(project_name, version_id, fields=None): - """Versions where passed version was used as input. - - Question: - Not 100% sure about the usage of the function so the name and docstring - maybe does not match what it does? - - Args: - project_name (str): Name of project where to look for queried entities. - version_id (Union[str, ObjectId]): Version id which can be used - as input link for other versions. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Iterable: Iterable cursor yielding versions that are used as input - links for passed version. - """ - - version_id = convert_id(version_id) - if not version_id: - return [] - - conn = get_project_connection(project_name) - # Does make sense to look for hero versions? - query_filter = { - "type": "version", - "data.inputLinks.id": version_id - } - return conn.find(query_filter, _prepare_fields(fields)) - - -def get_last_versions(project_name, subset_ids, fields=None): - """Latest versions for entered subset_ids. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_ids (Iterable[Union[str, ObjectId]]): List of subset ids. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - dict[ObjectId, int]: Key is subset id and value is last version name. - """ - - subset_ids = convert_ids(subset_ids) - if not subset_ids: - return {} - - if fields is not None: - fields = list(fields) - if not fields: - return {} - - # Avoid double query if only name and _id are requested - name_needed = False - limit_query = False - if fields: - fields_s = set(fields) - if "name" in fields_s: - name_needed = True - fields_s.remove("name") - - for field in ("_id", "parent"): - if field in fields_s: - fields_s.remove(field) - limit_query = len(fields_s) == 0 - - group_item = { - "_id": "$parent", - "_version_id": {"$last": "$_id"} - } - # Add name if name is needed (only for limit query) - if name_needed: - group_item["name"] = {"$last": "$name"} - - aggregation_pipeline = [ - # Find all versions of those subsets - {"$match": { - "type": "version", - "parent": {"$in": subset_ids} - }}, - # Sorting versions all together - {"$sort": {"name": 1}}, - # Group them by "parent", but only take the last - {"$group": group_item} - ] - - conn = get_project_connection(project_name) - aggregate_result = conn.aggregate(aggregation_pipeline) - if limit_query: - output = {} - for item in aggregate_result: - subset_id = item["_id"] - item_data = {"_id": item["_version_id"], "parent": subset_id} - if name_needed: - item_data["name"] = item["name"] - output[subset_id] = item_data - return output - - version_ids = [ - doc["_version_id"] - for doc in aggregate_result - ] - - fields = _prepare_fields(fields, ["parent"]) - - version_docs = get_versions( - project_name, version_ids=version_ids, fields=fields - ) - - return { - version_doc["parent"]: version_doc - for version_doc in version_docs - } - - -def get_last_version_by_subset_id(project_name, subset_id, fields=None): - """Last version for passed subset id. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_id (Union[str, ObjectId]): Id of version which should be found. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Version entity data which can be reduced to - specified 'fields'. None is returned if version with specified - filters was not found. - """ - - subset_id = convert_id(subset_id) - if not subset_id: - return None - - last_versions = get_last_versions( - project_name, subset_ids=[subset_id], fields=fields - ) - return last_versions.get(subset_id) - - -def get_last_version_by_subset_name( - project_name, subset_name, asset_id=None, asset_name=None, fields=None -): - """Last version for passed subset name under asset id/name. - - It is required to pass 'asset_id' or 'asset_name'. Asset id is recommended - if is available. - - Args: - project_name (str): Name of project where to look for queried entities. - subset_name (str): Name of subset. - asset_id (Union[str, ObjectId]): Asset id which is parent of passed - subset name. - asset_name (str): Asset name which is parent of passed subset name. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Version entity data which can be reduced to - specified 'fields'. None is returned if version with specified - filters was not found. - """ - - if not asset_id and not asset_name: - return None - - if not asset_id: - asset_doc = get_asset_by_name(project_name, asset_name, fields=["_id"]) - if not asset_doc: - return None - asset_id = asset_doc["_id"] - subset_doc = get_subset_by_name( - project_name, subset_name, asset_id, fields=["_id"] - ) - if not subset_doc: - return None - return get_last_version_by_subset_id( - project_name, subset_doc["_id"], fields=fields - ) - - -def get_representation_by_id(project_name, representation_id, fields=None): - """Representation entity data by its id. - - Args: - project_name (str): Name of project where to look for queried entities. - representation_id (Union[str, ObjectId]): Representation id. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Representation entity data which can be reduced to - specified 'fields'. None is returned if representation with - specified filters was not found. - """ - - if not representation_id: - return None - - repre_types = ["representation", "archived_representation"] - query_filter = { - "type": {"$in": repre_types} - } - if representation_id is not None: - query_filter["_id"] = convert_id(representation_id) - - conn = get_project_connection(project_name) - - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def get_representation_by_name( - project_name, representation_name, version_id, fields=None -): - """Representation entity data by its name and its version id. - - Args: - project_name (str): Name of project where to look for queried entities. - representation_name (str): Representation name. - version_id (Union[str, ObjectId]): Id of parent version entity. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[dict[str, Any], None]: Representation entity data which can be - reduced to specified 'fields'. None is returned if representation - with specified filters was not found. - """ - - version_id = convert_id(version_id) - if not version_id or not representation_name: - return None - repre_types = ["representation", "archived_representations"] - query_filter = { - "type": {"$in": repre_types}, - "name": representation_name, - "parent": version_id - } - - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def _flatten_dict(data): - flatten_queue = collections.deque() - flatten_queue.append(data) - output = {} - while flatten_queue: - item = flatten_queue.popleft() - for key, value in item.items(): - if not isinstance(value, dict): - output[key] = value - continue - - tmp = {} - for subkey, subvalue in value.items(): - new_key = "{}.{}".format(key, subkey) - tmp[new_key] = subvalue - flatten_queue.append(tmp) - return output - - -def _regex_filters(filters): - output = [] - for key, value in filters.items(): - regexes = [] - a_values = [] - if isinstance(value, PatternType): - regexes.append(value) - elif isinstance(value, (list, tuple, set)): - for item in value: - if isinstance(item, PatternType): - regexes.append(item) - else: - a_values.append(item) - else: - a_values.append(value) - - key_filters = [] - if len(a_values) == 1: - key_filters.append({key: a_values[0]}) - elif a_values: - key_filters.append({key: {"$in": a_values}}) - - for regex in regexes: - key_filters.append({key: {"$regex": regex}}) - - if len(key_filters) == 1: - output.append(key_filters[0]) - else: - output.append({"$or": key_filters}) - - return output - - -def _get_representations( - project_name, - representation_ids, - representation_names, - version_ids, - context_filters, - names_by_version_ids, - standard, - archived, - fields -): - default_output = [] - repre_types = [] - if standard: - repre_types.append("representation") - if archived: - repre_types.append("archived_representation") - - if not repre_types: - return default_output - - if len(repre_types) == 1: - query_filter = {"type": repre_types[0]} - else: - query_filter = {"type": {"$in": repre_types}} - - if representation_ids is not None: - representation_ids = convert_ids(representation_ids) - if not representation_ids: - return default_output - query_filter["_id"] = {"$in": representation_ids} - - if representation_names is not None: - if not representation_names: - return default_output - query_filter["name"] = {"$in": list(representation_names)} - - if version_ids is not None: - version_ids = convert_ids(version_ids) - if not version_ids: - return default_output - query_filter["parent"] = {"$in": version_ids} - - or_queries = [] - if names_by_version_ids is not None: - or_query = [] - for version_id, names in names_by_version_ids.items(): - if version_id and names: - or_query.append({ - "parent": convert_id(version_id), - "name": {"$in": list(names)} - }) - if not or_query: - return default_output - or_queries.append(or_query) - - if context_filters is not None: - if not context_filters: - return [] - _flatten_filters = _flatten_dict(context_filters) - flatten_filters = {} - for key, value in _flatten_filters.items(): - if not key.startswith("context"): - key = "context.{}".format(key) - flatten_filters[key] = value - - for item in _regex_filters(flatten_filters): - for key, value in item.items(): - if key != "$or": - query_filter[key] = value - - elif value: - or_queries.append(value) - - if len(or_queries) == 1: - query_filter["$or"] = or_queries[0] - elif or_queries: - and_query = [] - for or_query in or_queries: - if isinstance(or_query, list): - or_query = {"$or": or_query} - and_query.append(or_query) - query_filter["$and"] = and_query - - conn = get_project_connection(project_name) - - return conn.find(query_filter, _prepare_fields(fields)) - - -def get_representations( - project_name, - representation_ids=None, - representation_names=None, - version_ids=None, - context_filters=None, - names_by_version_ids=None, - archived=False, - standard=True, - fields=None -): - """Representation entities data from one project filtered by filters. - - Filters are additive (all conditions must pass to return subset). - - Args: - project_name (str): Name of project where to look for queried entities. - representation_ids (Iterable[Union[str, ObjectId]]): Representation ids - used as filter. Filter ignored if 'None' is passed. - representation_names (Iterable[str]): Representations names used - as filter. Filter ignored if 'None' is passed. - version_ids (Iterable[str]): Subset ids used as parent filter. Filter - ignored if 'None' is passed. - context_filters (Dict[str, List[str, PatternType]]): Filter by - representation context fields. - names_by_version_ids (dict[ObjectId, list[str]]): Complex filtering - using version ids and list of names under the version. - archived (bool): Output will also contain archived representations. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Iterable cursor yielding all matching representations. - """ - - return _get_representations( - project_name=project_name, - representation_ids=representation_ids, - representation_names=representation_names, - version_ids=version_ids, - context_filters=context_filters, - names_by_version_ids=names_by_version_ids, - standard=standard, - archived=archived, - fields=fields - ) - - -def get_archived_representations( - project_name, - representation_ids=None, - representation_names=None, - version_ids=None, - context_filters=None, - names_by_version_ids=None, - fields=None -): - """Archived representation entities data from project with applied filters. - - Filters are additive (all conditions must pass to return subset). - - Args: - project_name (str): Name of project where to look for queried entities. - representation_ids (Iterable[Union[str, ObjectId]]): Representation ids - used as filter. Filter ignored if 'None' is passed. - representation_names (Iterable[str]): Representations names used - as filter. Filter ignored if 'None' is passed. - version_ids (Iterable[str]): Subset ids used as parent filter. Filter - ignored if 'None' is passed. - context_filters (Dict[str, List[str, PatternType]]): Filter by - representation context fields. - names_by_version_ids (dict[ObjectId, List[str]]): Complex filtering - using version ids and list of names under the version. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Cursor: Iterable cursor yielding all matching representations. - """ - - return _get_representations( - project_name=project_name, - representation_ids=representation_ids, - representation_names=representation_names, - version_ids=version_ids, - context_filters=context_filters, - names_by_version_ids=names_by_version_ids, - standard=False, - archived=True, - fields=fields - ) - - -def get_representations_parents(project_name, representations): - """Prepare parents of representation entities. - - Each item of returned dictionary contains version, subset, asset - and project in that order. - - Args: - project_name (str): Name of project where to look for queried entities. - representations (List[dict]): Representation entities with at least - '_id' and 'parent' keys. - - Returns: - dict[ObjectId, tuple]: Parents by representation id. - """ - - repre_docs_by_version_id = collections.defaultdict(list) - version_docs_by_version_id = {} - version_docs_by_subset_id = collections.defaultdict(list) - subset_docs_by_subset_id = {} - subset_docs_by_asset_id = collections.defaultdict(list) - output = {} - for repre_doc in representations: - repre_id = repre_doc["_id"] - version_id = repre_doc["parent"] - output[repre_id] = (None, None, None, None) - repre_docs_by_version_id[version_id].append(repre_doc) - - version_docs = get_versions( - project_name, - version_ids=repre_docs_by_version_id.keys(), - hero=True - ) - for version_doc in version_docs: - version_id = version_doc["_id"] - subset_id = version_doc["parent"] - version_docs_by_version_id[version_id] = version_doc - version_docs_by_subset_id[subset_id].append(version_doc) - - subset_docs = get_subsets( - project_name, subset_ids=version_docs_by_subset_id.keys() - ) - for subset_doc in subset_docs: - subset_id = subset_doc["_id"] - asset_id = subset_doc["parent"] - subset_docs_by_subset_id[subset_id] = subset_doc - subset_docs_by_asset_id[asset_id].append(subset_doc) - - asset_docs = get_assets( - project_name, asset_ids=subset_docs_by_asset_id.keys() - ) - asset_docs_by_id = { - asset_doc["_id"]: asset_doc - for asset_doc in asset_docs - } - - project_doc = get_project(project_name) - - for version_id, repre_docs in repre_docs_by_version_id.items(): - asset_doc = None - subset_doc = None - version_doc = version_docs_by_version_id.get(version_id) - if version_doc: - subset_id = version_doc["parent"] - subset_doc = subset_docs_by_subset_id.get(subset_id) - if subset_doc: - asset_id = subset_doc["parent"] - asset_doc = asset_docs_by_id.get(asset_id) - - for repre_doc in repre_docs: - repre_id = repre_doc["_id"] - output[repre_id] = ( - version_doc, subset_doc, asset_doc, project_doc - ) - return output - - -def get_representation_parents(project_name, representation): - """Prepare parents of representation entity. - - Each item of returned dictionary contains version, subset, asset - and project in that order. - - Args: - project_name (str): Name of project where to look for queried entities. - representation (dict): Representation entities with at least - '_id' and 'parent' keys. - - Returns: - dict[ObjectId, tuple]: Parents by representation id. - """ - - if not representation: - return None - - repre_id = representation["_id"] - parents_by_repre_id = get_representations_parents( - project_name, [representation] - ) - return parents_by_repre_id[repre_id] - - -def get_thumbnail_id_from_source(project_name, src_type, src_id): - """Receive thumbnail id from source entity. - - Args: - project_name (str): Name of project where to look for queried entities. - src_type (str): Type of source entity ('asset', 'version'). - src_id (Union[str, ObjectId]): Id of source entity. - - Returns: - Union[ObjectId, None]: Thumbnail id assigned to entity. If Source - entity does not have any thumbnail id assigned. - """ - - if not src_type or not src_id: - return None - - query_filter = {"_id": convert_id(src_id)} - - conn = get_project_connection(project_name) - src_doc = conn.find_one(query_filter, {"data.thumbnail_id"}) - if src_doc: - return src_doc.get("data", {}).get("thumbnail_id") - return None - - -def get_thumbnails(project_name, thumbnail_ids, fields=None): - """Receive thumbnails entity data. - - Thumbnail entity can be used to receive binary content of thumbnail based - on its content and ThumbnailResolvers. - - Args: - project_name (str): Name of project where to look for queried entities. - thumbnail_ids (Iterable[Union[str, ObjectId]]): Ids of thumbnail - entities. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - cursor: Cursor of queried documents. - """ - - if thumbnail_ids: - thumbnail_ids = convert_ids(thumbnail_ids) - - if not thumbnail_ids: - return [] - query_filter = { - "type": "thumbnail", - "_id": {"$in": thumbnail_ids} - } - conn = get_project_connection(project_name) - return conn.find(query_filter, _prepare_fields(fields)) - - -def get_thumbnail(project_name, thumbnail_id, fields=None): - """Receive thumbnail entity data. - - Args: - project_name (str): Name of project where to look for queried entities. - thumbnail_id (Union[str, ObjectId]): Id of thumbnail entity. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Thumbnail entity data which can be reduced to - specified 'fields'.None is returned if thumbnail with specified - filters was not found. - """ - - if not thumbnail_id: - return None - query_filter = {"type": "thumbnail", "_id": convert_id(thumbnail_id)} - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -def get_workfile_info( - project_name, asset_id, task_name, filename, fields=None -): - """Document with workfile information. - - Warning: - Query is based on filename and context which does not meant it will - find always right and expected result. Information have limited usage - and is not recommended to use it as source information about workfile. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_id (Union[str, ObjectId]): Id of asset entity. - task_name (str): Task name on asset. - fields (Optional[Iterable[str]]): Fields that should be returned. All - fields are returned if 'None' is passed. - - Returns: - Union[Dict, None]: Workfile entity data which can be reduced to - specified 'fields'.None is returned if workfile with specified - filters was not found. - """ - - if not asset_id or not task_name or not filename: - return None - - query_filter = { - "type": "workfile", - "parent": convert_id(asset_id), - "task_name": task_name, - "filename": filename - } - conn = get_project_connection(project_name) - return conn.find_one(query_filter, _prepare_fields(fields)) - - -""" -## Custom data storage: -- Settings - OP settings overrides and local settings -- Logging - logs from Logger -- Webpublisher - jobs -- Ftrack - events -- Maya - Shaders - - openpype/hosts/maya/api/shader_definition_editor.py - - openpype/hosts/maya/plugins/publish/validate_model_name.py - -## Global publish plugins -- openpype/plugins/publish/extract_hierarchy_avalon.py - Create: - - asset - Update: - - asset - -## Lib -- openpype/lib/avalon_context.py - Update: - - workfile data -- openpype/lib/project_backpack.py - Update: - - project -""" + if not AYON_SERVER_ENABLED: + return asset_doc["name"] + parents = list(asset_doc["data"]["parents"]) + parents.append(asset_doc["name"]) + return "/" + "/".join(parents) diff --git a/openpype/client/entity_links.py b/openpype/client/entity_links.py index b74b4ce7f6..e18970de90 100644 --- a/openpype/client/entity_links.py +++ b/openpype/client/entity_links.py @@ -1,243 +1,6 @@ -from .mongo import get_project_connection -from .entities import ( - get_assets, - get_asset_by_id, - get_version_by_id, - get_representation_by_id, - convert_id, -) +from openpype import AYON_SERVER_ENABLED - -def get_linked_asset_ids(project_name, asset_doc=None, asset_id=None): - """Extract linked asset ids from asset document. - - One of asset document or asset id must be passed. - - Note: - Asset links now works only from asset to assets. - - Args: - asset_doc (dict): Asset document from DB. - - Returns: - List[Union[ObjectId, str]]: Asset ids of input links. - """ - - output = [] - if not asset_doc and not asset_id: - return output - - if not asset_doc: - asset_doc = get_asset_by_id( - project_name, asset_id, fields=["data.inputLinks"] - ) - - input_links = asset_doc["data"].get("inputLinks") - if not input_links: - return output - - for item in input_links: - # Backwards compatibility for "_id" key which was replaced with - # "id" - if "_id" in item: - link_id = item["_id"] - else: - link_id = item["id"] - output.append(link_id) - return output - - -def get_linked_assets( - project_name, asset_doc=None, asset_id=None, fields=None -): - """Return linked assets based on passed asset document. - - One of asset document or asset id must be passed. - - Args: - project_name (str): Name of project where to look for queried entities. - asset_doc (Dict[str, Any]): Asset document from database. - asset_id (Union[ObjectId, str]): Asset id. Can be used instead of - asset document. - fields (Iterable[str]): Fields that should be returned. All fields are - returned if 'None' is passed. - - Returns: - List[Dict[str, Any]]: Asset documents of input links for passed - asset doc. - """ - - if not asset_doc: - if not asset_id: - return [] - asset_doc = get_asset_by_id( - project_name, - asset_id, - fields=["data.inputLinks"] - ) - if not asset_doc: - return [] - - link_ids = get_linked_asset_ids(project_name, asset_doc=asset_doc) - if not link_ids: - return [] - - return list(get_assets(project_name, asset_ids=link_ids, fields=fields)) - - -def get_linked_representation_id( - project_name, repre_doc=None, repre_id=None, link_type=None, max_depth=None -): - """Returns list of linked ids of particular type (if provided). - - One of representation document or representation id must be passed. - Note: - Representation links now works only from representation through version - back to representations. - - Args: - project_name (str): Name of project where look for links. - repre_doc (Dict[str, Any]): Representation document. - repre_id (Union[ObjectId, str]): Representation id. - link_type (str): Type of link (e.g. 'reference', ...). - max_depth (int): Limit recursion level. Default: 0 - - Returns: - List[ObjectId] Linked representation ids. - """ - - if repre_doc: - repre_id = repre_doc["_id"] - - if repre_id: - repre_id = convert_id(repre_id) - - if not repre_id and not repre_doc: - return [] - - version_id = None - if repre_doc: - version_id = repre_doc.get("parent") - - if not version_id: - repre_doc = get_representation_by_id( - project_name, repre_id, fields=["parent"] - ) - version_id = repre_doc["parent"] - - if not version_id: - return [] - - version_doc = get_version_by_id( - project_name, version_id, fields=["type", "version_id"] - ) - if version_doc["type"] == "hero_version": - version_id = version_doc["version_id"] - - if max_depth is None: - max_depth = 0 - - match = { - "_id": version_id, - # Links are not stored to hero versions at this moment so filter - # is limited to just versions - "type": "version" - } - - graph_lookup = { - "from": project_name, - "startWith": "$data.inputLinks.id", - "connectFromField": "data.inputLinks.id", - "connectToField": "_id", - "as": "outputs_recursive", - "depthField": "depth" - } - if max_depth != 0: - # We offset by -1 since 0 basically means no recursion - # but the recursion only happens after the initial lookup - # for outputs. - graph_lookup["maxDepth"] = max_depth - 1 - - query_pipeline = [ - # Match - {"$match": match}, - # Recursive graph lookup for inputs - {"$graphLookup": graph_lookup} - ] - conn = get_project_connection(project_name) - result = conn.aggregate(query_pipeline) - referenced_version_ids = _process_referenced_pipeline_result( - result, link_type - ) - if not referenced_version_ids: - return [] - - ref_ids = conn.distinct( - "_id", - filter={ - "parent": {"$in": list(referenced_version_ids)}, - "type": "representation" - } - ) - - return list(ref_ids) - - -def _process_referenced_pipeline_result(result, link_type): - """Filters result from pipeline for particular link_type. - - Pipeline cannot use link_type directly in a query. - - Returns: - (list) - """ - - referenced_version_ids = set() - correctly_linked_ids = set() - for item in result: - input_links = item.get("data", {}).get("inputLinks") - if not input_links: - continue - - _filter_input_links( - input_links, - link_type, - correctly_linked_ids - ) - - # outputs_recursive in random order, sort by depth - outputs_recursive = item.get("outputs_recursive") - if not outputs_recursive: - continue - - for output in sorted(outputs_recursive, key=lambda o: o["depth"]): - output_links = output.get("data", {}).get("inputLinks") - if not output_links and output["type"] != "hero_version": - continue - - # Leaf - if output["_id"] not in correctly_linked_ids: - continue - - _filter_input_links( - output_links, - link_type, - correctly_linked_ids - ) - - referenced_version_ids.add(output["_id"]) - - return referenced_version_ids - - -def _filter_input_links(input_links, link_type, correctly_linked_ids): - if not input_links: # to handle hero versions - return - - for input_link in input_links: - if link_type and input_link["type"] != link_type: - continue - - link_id = input_link.get("id") or input_link.get("_id") - if link_id is not None: - correctly_linked_ids.add(link_id) +if not AYON_SERVER_ENABLED: + from .mongo.entity_links import * +else: + from .server.entity_links import * diff --git a/openpype/client/mongo/__init__.py b/openpype/client/mongo/__init__.py new file mode 100644 index 0000000000..9f62d7a9cf --- /dev/null +++ b/openpype/client/mongo/__init__.py @@ -0,0 +1,26 @@ +from .mongo import ( + MongoEnvNotSet, + get_default_components, + should_add_certificate_path_to_mongo_url, + validate_mongo_connection, + OpenPypeMongoConnection, + get_project_database, + get_project_connection, + load_json_file, + replace_project_documents, + store_project_documents, +) + + +__all__ = ( + "MongoEnvNotSet", + "get_default_components", + "should_add_certificate_path_to_mongo_url", + "validate_mongo_connection", + "OpenPypeMongoConnection", + "get_project_database", + "get_project_connection", + "load_json_file", + "replace_project_documents", + "store_project_documents", +) diff --git a/openpype/client/mongo/entities.py b/openpype/client/mongo/entities.py new file mode 100644 index 0000000000..260fde4594 --- /dev/null +++ b/openpype/client/mongo/entities.py @@ -0,0 +1,1555 @@ +"""Unclear if these will have public functions like these. + +Goal is that most of functions here are called on (or with) an object +that has project name as a context (e.g. on 'ProjectEntity'?). + ++ We will need more specific functions doing very specific queries really fast. +""" + +import re +import collections + +import six +from bson.objectid import ObjectId + +from .mongo import get_project_database, get_project_connection + +PatternType = type(re.compile("")) + + +def _prepare_fields(fields, required_fields=None): + if not fields: + return None + + output = { + field: True + for field in fields + } + if "_id" not in output: + output["_id"] = True + + if required_fields: + for key in required_fields: + output[key] = True + return output + + +def convert_id(in_id): + """Helper function for conversion of id from string to ObjectId. + + Args: + in_id (Union[str, ObjectId, Any]): Entity id that should be converted + to right type for queries. + + Returns: + Union[ObjectId, Any]: Converted ids to ObjectId or in type. + """ + + if isinstance(in_id, six.string_types): + return ObjectId(in_id) + return in_id + + +def convert_ids(in_ids): + """Helper function for conversion of ids from string to ObjectId. + + Args: + in_ids (Iterable[Union[str, ObjectId, Any]]): List of entity ids that + should be converted to right type for queries. + + Returns: + List[ObjectId]: Converted ids to ObjectId. + """ + + _output = set() + for in_id in in_ids: + if in_id is not None: + _output.add(convert_id(in_id)) + return list(_output) + + +def get_projects(active=True, inactive=False, fields=None): + """Yield all project entity documents. + + Args: + active (Optional[bool]): Include active projects. Defaults to True. + inactive (Optional[bool]): Include inactive projects. + Defaults to False. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Yields: + dict: Project entity data which can be reduced to specified 'fields'. + None is returned if project with specified filters was not found. + """ + mongodb = get_project_database() + for project_name in mongodb.collection_names(): + if project_name in ("system.indexes",): + continue + project_doc = get_project( + project_name, active=active, inactive=inactive, fields=fields + ) + if project_doc is not None: + yield project_doc + + +def get_project(project_name, active=True, inactive=True, fields=None): + """Return project entity document by project name. + + Args: + project_name (str): Name of project. + active (Optional[bool]): Allow active project. Defaults to True. + inactive (Optional[bool]): Allow inactive project. Defaults to True. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Project entity data which can be reduced to + specified 'fields'. None is returned if project with specified + filters was not found. + """ + # Skip if both are disabled + if not active and not inactive: + return None + + query_filter = {"type": "project"} + # Keep query untouched if both should be available + if active and inactive: + pass + + # Add filter to keep only active + elif active: + query_filter["$or"] = [ + {"data.active": {"$exists": False}}, + {"data.active": True}, + ] + + # Add filter to keep only inactive + elif inactive: + query_filter["$or"] = [ + {"data.active": {"$exists": False}}, + {"data.active": False}, + ] + + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def get_whole_project(project_name): + """Receive all documents from project. + + Helper that can be used to get all document from whole project. For example + for backups etc. + + Returns: + Cursor: Query cursor as iterable which returns all documents from + project collection. + """ + + conn = get_project_connection(project_name) + return conn.find({}) + + +def get_asset_by_id(project_name, asset_id, fields=None): + """Receive asset data by its id. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_id (Union[str, ObjectId]): Asset's id. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Asset entity data which can be reduced to + specified 'fields'. None is returned if asset with specified + filters was not found. + """ + + asset_id = convert_id(asset_id) + if not asset_id: + return None + + query_filter = {"type": "asset", "_id": asset_id} + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def get_asset_by_name(project_name, asset_name, fields=None): + """Receive asset data by its name. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_name (str): Asset's name. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Asset entity data which can be reduced to + specified 'fields'. None is returned if asset with specified + filters was not found. + """ + + if not asset_name: + return None + + query_filter = {"type": "asset", "name": asset_name} + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +# NOTE this could be just public function? +# - any better variable name instead of 'standard'? +# - same approach can be used for rest of types +def _get_assets( + project_name, + asset_ids=None, + asset_names=None, + parent_ids=None, + standard=True, + archived=False, + fields=None +): + """Assets for specified project by passed filters. + + Passed filters (ids and names) are always combined so all conditions must + match. + + To receive all assets from project just keep filters empty. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_ids (Iterable[Union[str, ObjectId]]): Asset ids that should + be found. + asset_names (Iterable[str]): Name assets that should be found. + parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. + standard (bool): Query standard assets (type 'asset'). + archived (bool): Query archived assets (type 'archived_asset'). + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Query cursor as iterable which returns asset documents matching + passed filters. + """ + + asset_types = [] + if standard: + asset_types.append("asset") + if archived: + asset_types.append("archived_asset") + + if not asset_types: + return [] + + if len(asset_types) == 1: + query_filter = {"type": asset_types[0]} + else: + query_filter = {"type": {"$in": asset_types}} + + if asset_ids is not None: + asset_ids = convert_ids(asset_ids) + if not asset_ids: + return [] + query_filter["_id"] = {"$in": asset_ids} + + if asset_names is not None: + if not asset_names: + return [] + query_filter["name"] = {"$in": list(asset_names)} + + if parent_ids is not None: + parent_ids = convert_ids(parent_ids) + if not parent_ids: + return [] + query_filter["data.visualParent"] = {"$in": parent_ids} + + conn = get_project_connection(project_name) + + return conn.find(query_filter, _prepare_fields(fields)) + + +def get_assets( + project_name, + asset_ids=None, + asset_names=None, + parent_ids=None, + archived=False, + fields=None +): + """Assets for specified project by passed filters. + + Passed filters (ids and names) are always combined so all conditions must + match. + + To receive all assets from project just keep filters empty. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_ids (Iterable[Union[str, ObjectId]]): Asset ids that should + be found. + asset_names (Iterable[str]): Name assets that should be found. + parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. + archived (bool): Add also archived assets. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Query cursor as iterable which returns asset documents matching + passed filters. + """ + + return _get_assets( + project_name, + asset_ids, + asset_names, + parent_ids, + True, + archived, + fields + ) + + +def get_archived_assets( + project_name, + asset_ids=None, + asset_names=None, + parent_ids=None, + fields=None +): + """Archived assets for specified project by passed filters. + + Passed filters (ids and names) are always combined so all conditions must + match. + + To receive all archived assets from project just keep filters empty. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_ids (Iterable[Union[str, ObjectId]]): Asset ids that should + be found. + asset_names (Iterable[str]): Name assets that should be found. + parent_ids (Iterable[Union[str, ObjectId]]): Parent asset ids. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Query cursor as iterable which returns asset documents matching + passed filters. + """ + + return _get_assets( + project_name, asset_ids, asset_names, parent_ids, False, True, fields + ) + + +def get_asset_ids_with_subsets(project_name, asset_ids=None): + """Find out which assets have existing subsets. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_ids (Iterable[Union[str, ObjectId]]): Look only for entered + asset ids. + + Returns: + Iterable[ObjectId]: Asset ids that have existing subsets. + """ + + subset_query = { + "type": "subset" + } + if asset_ids is not None: + asset_ids = convert_ids(asset_ids) + if not asset_ids: + return [] + subset_query["parent"] = {"$in": asset_ids} + + conn = get_project_connection(project_name) + result = conn.aggregate([ + { + "$match": subset_query + }, + { + "$group": { + "_id": "$parent", + "count": {"$sum": 1} + } + } + ]) + asset_ids_with_subsets = [] + for item in result: + asset_id = item["_id"] + count = item["count"] + if count > 0: + asset_ids_with_subsets.append(asset_id) + return asset_ids_with_subsets + + +def get_subset_by_id(project_name, subset_id, fields=None): + """Single subset entity data by its id. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_id (Union[str, ObjectId]): Id of subset which should be found. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Subset entity data which can be reduced to + specified 'fields'. None is returned if subset with specified + filters was not found. + """ + + subset_id = convert_id(subset_id) + if not subset_id: + return None + + query_filters = {"type": "subset", "_id": subset_id} + conn = get_project_connection(project_name) + return conn.find_one(query_filters, _prepare_fields(fields)) + + +def get_subset_by_name(project_name, subset_name, asset_id, fields=None): + """Single subset entity data by its name and its version id. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_name (str): Name of subset. + asset_id (Union[str, ObjectId]): Id of parent asset. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Subset entity data which can be reduced to + specified 'fields'. None is returned if subset with specified + filters was not found. + """ + if not subset_name: + return None + + asset_id = convert_id(asset_id) + if not asset_id: + return None + + query_filters = { + "type": "subset", + "name": subset_name, + "parent": asset_id + } + conn = get_project_connection(project_name) + return conn.find_one(query_filters, _prepare_fields(fields)) + + +def get_subsets( + project_name, + subset_ids=None, + subset_names=None, + asset_ids=None, + names_by_asset_ids=None, + archived=False, + fields=None +): + """Subset entities data from one project filtered by entered filters. + + Filters are additive (all conditions must pass to return subset). + + Args: + project_name (str): Name of project where to look for queried entities. + subset_ids (Iterable[Union[str, ObjectId]]): Subset ids that should be + queried. Filter ignored if 'None' is passed. + subset_names (Iterable[str]): Subset names that should be queried. + Filter ignored if 'None' is passed. + asset_ids (Iterable[Union[str, ObjectId]]): Asset ids under which + should look for the subsets. Filter ignored if 'None' is passed. + names_by_asset_ids (dict[ObjectId, List[str]]): Complex filtering + using asset ids and list of subset names under the asset. + archived (bool): Look for archived subsets too. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Iterable cursor yielding all matching subsets. + """ + + subset_types = ["subset"] + if archived: + subset_types.append("archived_subset") + + if len(subset_types) == 1: + query_filter = {"type": subset_types[0]} + else: + query_filter = {"type": {"$in": subset_types}} + + if asset_ids is not None: + asset_ids = convert_ids(asset_ids) + if not asset_ids: + return [] + query_filter["parent"] = {"$in": asset_ids} + + if subset_ids is not None: + subset_ids = convert_ids(subset_ids) + if not subset_ids: + return [] + query_filter["_id"] = {"$in": subset_ids} + + if subset_names is not None: + if not subset_names: + return [] + query_filter["name"] = {"$in": list(subset_names)} + + if names_by_asset_ids is not None: + or_query = [] + for asset_id, names in names_by_asset_ids.items(): + if asset_id and names: + or_query.append({ + "parent": convert_id(asset_id), + "name": {"$in": list(names)} + }) + if not or_query: + return [] + query_filter["$or"] = or_query + + conn = get_project_connection(project_name) + return conn.find(query_filter, _prepare_fields(fields)) + + +def get_subset_families(project_name, subset_ids=None): + """Set of main families of subsets. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_ids (Iterable[Union[str, ObjectId]]): Subset ids that should + be queried. All subsets from project are used if 'None' is passed. + + Returns: + set[str]: Main families of matching subsets. + """ + + subset_filter = { + "type": "subset" + } + if subset_ids is not None: + if not subset_ids: + return set() + subset_filter["_id"] = {"$in": list(subset_ids)} + + conn = get_project_connection(project_name) + result = list(conn.aggregate([ + {"$match": subset_filter}, + {"$project": { + "family": {"$arrayElemAt": ["$data.families", 0]} + }}, + {"$group": { + "_id": "family_group", + "families": {"$addToSet": "$family"} + }} + ])) + if result: + return set(result[0]["families"]) + return set() + + +def get_version_by_id(project_name, version_id, fields=None): + """Single version entity data by its id. + + Args: + project_name (str): Name of project where to look for queried entities. + version_id (Union[str, ObjectId]): Id of version which should be found. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Version entity data which can be reduced to + specified 'fields'. None is returned if version with specified + filters was not found. + """ + + version_id = convert_id(version_id) + if not version_id: + return None + + query_filter = { + "type": {"$in": ["version", "hero_version"]}, + "_id": version_id + } + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def get_version_by_name(project_name, version, subset_id, fields=None): + """Single version entity data by its name and subset id. + + Args: + project_name (str): Name of project where to look for queried entities. + version (int): name of version entity (its version). + subset_id (Union[str, ObjectId]): Id of version which should be found. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Version entity data which can be reduced to + specified 'fields'. None is returned if version with specified + filters was not found. + """ + + subset_id = convert_id(subset_id) + if not subset_id: + return None + + conn = get_project_connection(project_name) + query_filter = { + "type": "version", + "parent": subset_id, + "name": version + } + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def version_is_latest(project_name, version_id): + """Is version the latest from its subset. + + Note: + Hero versions are considered as latest. + + Todo: + Maybe raise exception when version was not found? + + Args: + project_name (str):Name of project where to look for queried entities. + version_id (Union[str, ObjectId]): Version id which is checked. + + Returns: + bool: True if is latest version from subset else False. + """ + + version_id = convert_id(version_id) + if not version_id: + return False + version_doc = get_version_by_id( + project_name, version_id, fields=["_id", "type", "parent"] + ) + # What to do when version is not found? + if not version_doc: + return False + + if version_doc["type"] == "hero_version": + return True + + last_version = get_last_version_by_subset_id( + project_name, version_doc["parent"], fields=["_id"] + ) + return last_version["_id"] == version_id + + +def _get_versions( + project_name, + subset_ids=None, + version_ids=None, + versions=None, + standard=True, + hero=False, + fields=None +): + version_types = [] + if standard: + version_types.append("version") + + if hero: + version_types.append("hero_version") + + if not version_types: + return [] + elif len(version_types) == 1: + query_filter = {"type": version_types[0]} + else: + query_filter = {"type": {"$in": version_types}} + + if subset_ids is not None: + subset_ids = convert_ids(subset_ids) + if not subset_ids: + return [] + query_filter["parent"] = {"$in": subset_ids} + + if version_ids is not None: + version_ids = convert_ids(version_ids) + if not version_ids: + return [] + query_filter["_id"] = {"$in": version_ids} + + if versions is not None: + versions = list(versions) + if not versions: + return [] + + if len(versions) == 1: + query_filter["name"] = versions[0] + else: + query_filter["name"] = {"$in": versions} + + conn = get_project_connection(project_name) + + return conn.find(query_filter, _prepare_fields(fields)) + + +def get_versions( + project_name, + version_ids=None, + subset_ids=None, + versions=None, + hero=False, + fields=None +): + """Version entities data from one project filtered by entered filters. + + Filters are additive (all conditions must pass to return subset). + + Args: + project_name (str): Name of project where to look for queried entities. + version_ids (Iterable[Union[str, ObjectId]]): Version ids that will + be queried. Filter ignored if 'None' is passed. + subset_ids (Iterable[str]): Subset ids that will be queried. + Filter ignored if 'None' is passed. + versions (Iterable[int]): Version names (as integers). + Filter ignored if 'None' is passed. + hero (bool): Look also for hero versions. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Iterable cursor yielding all matching versions. + """ + + return _get_versions( + project_name, + subset_ids, + version_ids, + versions, + standard=True, + hero=hero, + fields=fields + ) + + +def get_hero_version_by_subset_id(project_name, subset_id, fields=None): + """Hero version by subset id. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_id (Union[str, ObjectId]): Subset id under which + is hero version. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Hero version entity data which can be reduced to + specified 'fields'. None is returned if hero version with specified + filters was not found. + """ + + subset_id = convert_id(subset_id) + if not subset_id: + return None + + versions = list(_get_versions( + project_name, + subset_ids=[subset_id], + standard=False, + hero=True, + fields=fields + )) + if versions: + return versions[0] + return None + + +def get_hero_version_by_id(project_name, version_id, fields=None): + """Hero version by its id. + + Args: + project_name (str): Name of project where to look for queried entities. + version_id (Union[str, ObjectId]): Hero version id. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Hero version entity data which can be reduced to + specified 'fields'. None is returned if hero version with specified + filters was not found. + """ + + version_id = convert_id(version_id) + if not version_id: + return None + + versions = list(_get_versions( + project_name, + version_ids=[version_id], + standard=False, + hero=True, + fields=fields + )) + if versions: + return versions[0] + return None + + +def get_hero_versions( + project_name, + subset_ids=None, + version_ids=None, + fields=None +): + """Hero version entities data from one project filtered by entered filters. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_ids (Iterable[Union[str, ObjectId]]): Subset ids for which + should look for hero versions. Filter ignored if 'None' is passed. + version_ids (Iterable[Union[str, ObjectId]]): Hero version ids. Filter + ignored if 'None' is passed. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor|list: Iterable yielding hero versions matching passed filters. + """ + + return _get_versions( + project_name, + subset_ids, + version_ids, + standard=False, + hero=True, + fields=fields + ) + + +def get_output_link_versions(project_name, version_id, fields=None): + """Versions where passed version was used as input. + + Question: + Not 100% sure about the usage of the function so the name and docstring + maybe does not match what it does? + + Args: + project_name (str): Name of project where to look for queried entities. + version_id (Union[str, ObjectId]): Version id which can be used + as input link for other versions. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Iterable: Iterable cursor yielding versions that are used as input + links for passed version. + """ + + version_id = convert_id(version_id) + if not version_id: + return [] + + conn = get_project_connection(project_name) + # Does make sense to look for hero versions? + query_filter = { + "type": "version", + "data.inputLinks.id": version_id + } + return conn.find(query_filter, _prepare_fields(fields)) + + +def get_last_versions(project_name, subset_ids, active=None, fields=None): + """Latest versions for entered subset_ids. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_ids (Iterable[Union[str, ObjectId]]): List of subset ids. + active (Optional[bool]): If True only active versions are returned. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + dict[ObjectId, int]: Key is subset id and value is last version name. + """ + + subset_ids = convert_ids(subset_ids) + if not subset_ids: + return {} + + if fields is not None: + fields = list(fields) + if not fields: + return {} + + # Avoid double query if only name and _id are requested + name_needed = False + limit_query = False + if fields: + fields_s = set(fields) + if "name" in fields_s: + name_needed = True + fields_s.remove("name") + + for field in ("_id", "parent"): + if field in fields_s: + fields_s.remove(field) + limit_query = len(fields_s) == 0 + + group_item = { + "_id": "$parent", + "_version_id": {"$last": "$_id"} + } + # Add name if name is needed (only for limit query) + if name_needed: + group_item["name"] = {"$last": "$name"} + + aggregate_filter = { + "type": "version", + "parent": {"$in": subset_ids} + } + if active is False: + aggregate_filter["data.active"] = active + elif active is True: + aggregate_filter["$or"] = [ + {"data.active": {"$exists": 0}}, + {"data.active": active}, + ] + + aggregation_pipeline = [ + # Find all versions of those subsets + {"$match": aggregate_filter}, + # Sorting versions all together + {"$sort": {"name": 1}}, + # Group them by "parent", but only take the last + {"$group": group_item} + ] + + conn = get_project_connection(project_name) + aggregate_result = conn.aggregate(aggregation_pipeline) + if limit_query: + output = {} + for item in aggregate_result: + subset_id = item["_id"] + item_data = {"_id": item["_version_id"], "parent": subset_id} + if name_needed: + item_data["name"] = item["name"] + output[subset_id] = item_data + return output + + version_ids = [ + doc["_version_id"] + for doc in aggregate_result + ] + + fields = _prepare_fields(fields, ["parent"]) + + version_docs = get_versions( + project_name, version_ids=version_ids, fields=fields + ) + + return { + version_doc["parent"]: version_doc + for version_doc in version_docs + } + + +def get_last_version_by_subset_id(project_name, subset_id, fields=None): + """Last version for passed subset id. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_id (Union[str, ObjectId]): Id of version which should be found. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Version entity data which can be reduced to + specified 'fields'. None is returned if version with specified + filters was not found. + """ + + subset_id = convert_id(subset_id) + if not subset_id: + return None + + last_versions = get_last_versions( + project_name, subset_ids=[subset_id], fields=fields + ) + return last_versions.get(subset_id) + + +def get_last_version_by_subset_name( + project_name, subset_name, asset_id=None, asset_name=None, fields=None +): + """Last version for passed subset name under asset id/name. + + It is required to pass 'asset_id' or 'asset_name'. Asset id is recommended + if is available. + + Args: + project_name (str): Name of project where to look for queried entities. + subset_name (str): Name of subset. + asset_id (Union[str, ObjectId]): Asset id which is parent of passed + subset name. + asset_name (str): Asset name which is parent of passed subset name. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Version entity data which can be reduced to + specified 'fields'. None is returned if version with specified + filters was not found. + """ + + if not asset_id and not asset_name: + return None + + if not asset_id: + asset_doc = get_asset_by_name(project_name, asset_name, fields=["_id"]) + if not asset_doc: + return None + asset_id = asset_doc["_id"] + subset_doc = get_subset_by_name( + project_name, subset_name, asset_id, fields=["_id"] + ) + if not subset_doc: + return None + return get_last_version_by_subset_id( + project_name, subset_doc["_id"], fields=fields + ) + + +def get_representation_by_id(project_name, representation_id, fields=None): + """Representation entity data by its id. + + Args: + project_name (str): Name of project where to look for queried entities. + representation_id (Union[str, ObjectId]): Representation id. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Representation entity data which can be reduced to + specified 'fields'. None is returned if representation with + specified filters was not found. + """ + + if not representation_id: + return None + + repre_types = ["representation", "archived_representation"] + query_filter = { + "type": {"$in": repre_types} + } + if representation_id is not None: + query_filter["_id"] = convert_id(representation_id) + + conn = get_project_connection(project_name) + + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def get_representation_by_name( + project_name, representation_name, version_id, fields=None +): + """Representation entity data by its name and its version id. + + Args: + project_name (str): Name of project where to look for queried entities. + representation_name (str): Representation name. + version_id (Union[str, ObjectId]): Id of parent version entity. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[dict[str, Any], None]: Representation entity data which can be + reduced to specified 'fields'. None is returned if representation + with specified filters was not found. + """ + + version_id = convert_id(version_id) + if not version_id or not representation_name: + return None + repre_types = ["representation", "archived_representations"] + query_filter = { + "type": {"$in": repre_types}, + "name": representation_name, + "parent": version_id + } + + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def _flatten_dict(data): + flatten_queue = collections.deque() + flatten_queue.append(data) + output = {} + while flatten_queue: + item = flatten_queue.popleft() + for key, value in item.items(): + if not isinstance(value, dict): + output[key] = value + continue + + tmp = {} + for subkey, subvalue in value.items(): + new_key = "{}.{}".format(key, subkey) + tmp[new_key] = subvalue + flatten_queue.append(tmp) + return output + + +def _regex_filters(filters): + output = [] + for key, value in filters.items(): + regexes = [] + a_values = [] + if isinstance(value, PatternType): + regexes.append(value) + elif isinstance(value, (list, tuple, set)): + for item in value: + if isinstance(item, PatternType): + regexes.append(item) + else: + a_values.append(item) + else: + a_values.append(value) + + key_filters = [] + if len(a_values) == 1: + key_filters.append({key: a_values[0]}) + elif a_values: + key_filters.append({key: {"$in": a_values}}) + + for regex in regexes: + key_filters.append({key: {"$regex": regex}}) + + if len(key_filters) == 1: + output.append(key_filters[0]) + else: + output.append({"$or": key_filters}) + + return output + + +def _get_representations( + project_name, + representation_ids, + representation_names, + version_ids, + context_filters, + names_by_version_ids, + standard, + archived, + fields +): + default_output = [] + repre_types = [] + if standard: + repre_types.append("representation") + if archived: + repre_types.append("archived_representation") + + if not repre_types: + return default_output + + if len(repre_types) == 1: + query_filter = {"type": repre_types[0]} + else: + query_filter = {"type": {"$in": repre_types}} + + if representation_ids is not None: + representation_ids = convert_ids(representation_ids) + if not representation_ids: + return default_output + query_filter["_id"] = {"$in": representation_ids} + + if representation_names is not None: + if not representation_names: + return default_output + query_filter["name"] = {"$in": list(representation_names)} + + if version_ids is not None: + version_ids = convert_ids(version_ids) + if not version_ids: + return default_output + query_filter["parent"] = {"$in": version_ids} + + or_queries = [] + if names_by_version_ids is not None: + or_query = [] + for version_id, names in names_by_version_ids.items(): + if version_id and names: + or_query.append({ + "parent": convert_id(version_id), + "name": {"$in": list(names)} + }) + if not or_query: + return default_output + or_queries.append(or_query) + + if context_filters is not None: + if not context_filters: + return [] + _flatten_filters = _flatten_dict(context_filters) + flatten_filters = {} + for key, value in _flatten_filters.items(): + if not key.startswith("context"): + key = "context.{}".format(key) + flatten_filters[key] = value + + for item in _regex_filters(flatten_filters): + for key, value in item.items(): + if key != "$or": + query_filter[key] = value + + elif value: + or_queries.append(value) + + if len(or_queries) == 1: + query_filter["$or"] = or_queries[0] + elif or_queries: + and_query = [] + for or_query in or_queries: + if isinstance(or_query, list): + or_query = {"$or": or_query} + and_query.append(or_query) + query_filter["$and"] = and_query + + conn = get_project_connection(project_name) + + return conn.find(query_filter, _prepare_fields(fields)) + + +def get_representations( + project_name, + representation_ids=None, + representation_names=None, + version_ids=None, + context_filters=None, + names_by_version_ids=None, + archived=False, + standard=True, + fields=None +): + """Representation entities data from one project filtered by filters. + + Filters are additive (all conditions must pass to return subset). + + Args: + project_name (str): Name of project where to look for queried entities. + representation_ids (Iterable[Union[str, ObjectId]]): Representation ids + used as filter. Filter ignored if 'None' is passed. + representation_names (Iterable[str]): Representations names used + as filter. Filter ignored if 'None' is passed. + version_ids (Iterable[str]): Subset ids used as parent filter. Filter + ignored if 'None' is passed. + context_filters (Dict[str, List[str, PatternType]]): Filter by + representation context fields. + names_by_version_ids (dict[ObjectId, list[str]]): Complex filtering + using version ids and list of names under the version. + archived (bool): Output will also contain archived representations. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Iterable cursor yielding all matching representations. + """ + + return _get_representations( + project_name=project_name, + representation_ids=representation_ids, + representation_names=representation_names, + version_ids=version_ids, + context_filters=context_filters, + names_by_version_ids=names_by_version_ids, + standard=standard, + archived=archived, + fields=fields + ) + + +def get_archived_representations( + project_name, + representation_ids=None, + representation_names=None, + version_ids=None, + context_filters=None, + names_by_version_ids=None, + fields=None +): + """Archived representation entities data from project with applied filters. + + Filters are additive (all conditions must pass to return subset). + + Args: + project_name (str): Name of project where to look for queried entities. + representation_ids (Iterable[Union[str, ObjectId]]): Representation ids + used as filter. Filter ignored if 'None' is passed. + representation_names (Iterable[str]): Representations names used + as filter. Filter ignored if 'None' is passed. + version_ids (Iterable[str]): Subset ids used as parent filter. Filter + ignored if 'None' is passed. + context_filters (Dict[str, List[str, PatternType]]): Filter by + representation context fields. + names_by_version_ids (dict[ObjectId, List[str]]): Complex filtering + using version ids and list of names under the version. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Cursor: Iterable cursor yielding all matching representations. + """ + + return _get_representations( + project_name=project_name, + representation_ids=representation_ids, + representation_names=representation_names, + version_ids=version_ids, + context_filters=context_filters, + names_by_version_ids=names_by_version_ids, + standard=False, + archived=True, + fields=fields + ) + + +def get_representations_parents(project_name, representations): + """Prepare parents of representation entities. + + Each item of returned dictionary contains version, subset, asset + and project in that order. + + Args: + project_name (str): Name of project where to look for queried entities. + representations (List[dict]): Representation entities with at least + '_id' and 'parent' keys. + + Returns: + dict[ObjectId, tuple]: Parents by representation id. + """ + + repre_docs_by_version_id = collections.defaultdict(list) + version_docs_by_version_id = {} + version_docs_by_subset_id = collections.defaultdict(list) + subset_docs_by_subset_id = {} + subset_docs_by_asset_id = collections.defaultdict(list) + output = {} + for repre_doc in representations: + repre_id = repre_doc["_id"] + version_id = repre_doc["parent"] + output[repre_id] = (None, None, None, None) + repre_docs_by_version_id[version_id].append(repre_doc) + + version_docs = get_versions( + project_name, + version_ids=repre_docs_by_version_id.keys(), + hero=True + ) + for version_doc in version_docs: + version_id = version_doc["_id"] + subset_id = version_doc["parent"] + version_docs_by_version_id[version_id] = version_doc + version_docs_by_subset_id[subset_id].append(version_doc) + + subset_docs = get_subsets( + project_name, subset_ids=version_docs_by_subset_id.keys() + ) + for subset_doc in subset_docs: + subset_id = subset_doc["_id"] + asset_id = subset_doc["parent"] + subset_docs_by_subset_id[subset_id] = subset_doc + subset_docs_by_asset_id[asset_id].append(subset_doc) + + asset_docs = get_assets( + project_name, asset_ids=subset_docs_by_asset_id.keys() + ) + asset_docs_by_id = { + asset_doc["_id"]: asset_doc + for asset_doc in asset_docs + } + + project_doc = get_project(project_name) + + for version_id, repre_docs in repre_docs_by_version_id.items(): + asset_doc = None + subset_doc = None + version_doc = version_docs_by_version_id.get(version_id) + if version_doc: + subset_id = version_doc["parent"] + subset_doc = subset_docs_by_subset_id.get(subset_id) + if subset_doc: + asset_id = subset_doc["parent"] + asset_doc = asset_docs_by_id.get(asset_id) + + for repre_doc in repre_docs: + repre_id = repre_doc["_id"] + output[repre_id] = ( + version_doc, subset_doc, asset_doc, project_doc + ) + return output + + +def get_representation_parents(project_name, representation): + """Prepare parents of representation entity. + + Each item of returned dictionary contains version, subset, asset + and project in that order. + + Args: + project_name (str): Name of project where to look for queried entities. + representation (dict): Representation entities with at least + '_id' and 'parent' keys. + + Returns: + dict[ObjectId, tuple]: Parents by representation id. + """ + + if not representation: + return None + + repre_id = representation["_id"] + parents_by_repre_id = get_representations_parents( + project_name, [representation] + ) + return parents_by_repre_id[repre_id] + + +def get_thumbnail_id_from_source(project_name, src_type, src_id): + """Receive thumbnail id from source entity. + + Args: + project_name (str): Name of project where to look for queried entities. + src_type (str): Type of source entity ('asset', 'version'). + src_id (Union[str, ObjectId]): Id of source entity. + + Returns: + Union[ObjectId, None]: Thumbnail id assigned to entity. If Source + entity does not have any thumbnail id assigned. + """ + + if not src_type or not src_id: + return None + + query_filter = {"_id": convert_id(src_id)} + + conn = get_project_connection(project_name) + src_doc = conn.find_one(query_filter, {"data.thumbnail_id"}) + if src_doc: + return src_doc.get("data", {}).get("thumbnail_id") + return None + + +def get_thumbnails(project_name, thumbnail_ids, fields=None): + """Receive thumbnails entity data. + + Thumbnail entity can be used to receive binary content of thumbnail based + on its content and ThumbnailResolvers. + + Args: + project_name (str): Name of project where to look for queried entities. + thumbnail_ids (Iterable[Union[str, ObjectId]]): Ids of thumbnail + entities. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + cursor: Cursor of queried documents. + """ + + if thumbnail_ids: + thumbnail_ids = convert_ids(thumbnail_ids) + + if not thumbnail_ids: + return [] + query_filter = { + "type": "thumbnail", + "_id": {"$in": thumbnail_ids} + } + conn = get_project_connection(project_name) + return conn.find(query_filter, _prepare_fields(fields)) + + +def get_thumbnail( + project_name, thumbnail_id, entity_type, entity_id, fields=None +): + """Receive thumbnail entity data. + + Args: + project_name (str): Name of project where to look for queried entities. + thumbnail_id (Union[str, ObjectId]): Id of thumbnail entity. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Thumbnail entity data which can be reduced to + specified 'fields'.None is returned if thumbnail with specified + filters was not found. + """ + + if not thumbnail_id: + return None + query_filter = {"type": "thumbnail", "_id": convert_id(thumbnail_id)} + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +def get_workfile_info( + project_name, asset_id, task_name, filename, fields=None +): + """Document with workfile information. + + Warning: + Query is based on filename and context which does not meant it will + find always right and expected result. Information have limited usage + and is not recommended to use it as source information about workfile. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_id (Union[str, ObjectId]): Id of asset entity. + task_name (str): Task name on asset. + fields (Optional[Iterable[str]]): Fields that should be returned. All + fields are returned if 'None' is passed. + + Returns: + Union[Dict, None]: Workfile entity data which can be reduced to + specified 'fields'.None is returned if workfile with specified + filters was not found. + """ + + if not asset_id or not task_name or not filename: + return None + + query_filter = { + "type": "workfile", + "parent": convert_id(asset_id), + "task_name": task_name, + "filename": filename + } + conn = get_project_connection(project_name) + return conn.find_one(query_filter, _prepare_fields(fields)) + + +""" +## Custom data storage: +- Settings - OP settings overrides and local settings +- Logging - logs from Logger +- Webpublisher - jobs +- Ftrack - events +- Maya - Shaders + - openpype/hosts/maya/api/shader_definition_editor.py + - openpype/hosts/maya/plugins/publish/validate_model_name.py + +## Global publish plugins +- openpype/plugins/publish/extract_hierarchy_avalon.py + Create: + - asset + Update: + - asset + +## Lib +- openpype/lib/avalon_context.py + Update: + - workfile data +- openpype/lib/project_backpack.py + Update: + - project +""" diff --git a/openpype/client/mongo/entity_links.py b/openpype/client/mongo/entity_links.py new file mode 100644 index 0000000000..fd13a2d83b --- /dev/null +++ b/openpype/client/mongo/entity_links.py @@ -0,0 +1,240 @@ +from .mongo import get_project_connection +from .entities import ( + get_assets, + get_asset_by_id, + get_version_by_id, + get_representation_by_id, + convert_id, +) + + +def get_linked_asset_ids(project_name, asset_doc=None, asset_id=None): + """Extract linked asset ids from asset document. + + One of asset document or asset id must be passed. + + Note: + Asset links now works only from asset to assets. + + Args: + asset_doc (dict): Asset document from DB. + + Returns: + List[Union[ObjectId, str]]: Asset ids of input links. + """ + + output = [] + if not asset_doc and not asset_id: + return output + + if not asset_doc: + asset_doc = get_asset_by_id( + project_name, asset_id, fields=["data.inputLinks"] + ) + + input_links = asset_doc["data"].get("inputLinks") + if not input_links: + return output + + for item in input_links: + # Backwards compatibility for "_id" key which was replaced with + # "id" + if "_id" in item: + link_id = item["_id"] + else: + link_id = item["id"] + output.append(link_id) + return output + + +def get_linked_assets( + project_name, asset_doc=None, asset_id=None, fields=None +): + """Return linked assets based on passed asset document. + + One of asset document or asset id must be passed. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_doc (Dict[str, Any]): Asset document from database. + asset_id (Union[ObjectId, str]): Asset id. Can be used instead of + asset document. + fields (Iterable[str]): Fields that should be returned. All fields are + returned if 'None' is passed. + + Returns: + List[Dict[str, Any]]: Asset documents of input links for passed + asset doc. + """ + + if not asset_doc: + if not asset_id: + return [] + asset_doc = get_asset_by_id( + project_name, + asset_id, + fields=["data.inputLinks"] + ) + if not asset_doc: + return [] + + link_ids = get_linked_asset_ids(project_name, asset_doc=asset_doc) + if not link_ids: + return [] + + return list(get_assets(project_name, asset_ids=link_ids, fields=fields)) + + +def get_linked_representation_id( + project_name, repre_doc=None, repre_id=None, link_type=None, max_depth=None +): + """Returns list of linked ids of particular type (if provided). + + One of representation document or representation id must be passed. + Note: + Representation links now works only from representation through version + back to representations. + + Args: + project_name (str): Name of project where look for links. + repre_doc (Dict[str, Any]): Representation document. + repre_id (Union[ObjectId, str]): Representation id. + link_type (str): Type of link (e.g. 'reference', ...). + max_depth (int): Limit recursion level. Default: 0 + + Returns: + List[ObjectId] Linked representation ids. + """ + + if repre_doc: + repre_id = repre_doc["_id"] + + if repre_id: + repre_id = convert_id(repre_id) + + if not repre_id and not repre_doc: + return [] + + version_id = None + if repre_doc: + version_id = repre_doc.get("parent") + + if not version_id: + repre_doc = get_representation_by_id( + project_name, repre_id, fields=["parent"] + ) + version_id = repre_doc["parent"] + + if not version_id: + return [] + + version_doc = get_version_by_id( + project_name, version_id, fields=["type", "version_id"] + ) + if version_doc["type"] == "hero_version": + version_id = version_doc["version_id"] + + if max_depth is None: + max_depth = 0 + + match = { + "_id": version_id, + # Links are not stored to hero versions at this moment so filter + # is limited to just versions + "type": "version" + } + + graph_lookup = { + "from": project_name, + "startWith": "$data.inputLinks.id", + "connectFromField": "data.inputLinks.id", + "connectToField": "_id", + "as": "outputs_recursive", + "depthField": "depth" + } + if max_depth != 0: + # We offset by -1 since 0 basically means no recursion + # but the recursion only happens after the initial lookup + # for outputs. + graph_lookup["maxDepth"] = max_depth - 1 + + query_pipeline = [ + # Match + {"$match": match}, + # Recursive graph lookup for inputs + {"$graphLookup": graph_lookup} + ] + + conn = get_project_connection(project_name) + result = conn.aggregate(query_pipeline) + referenced_version_ids = _process_referenced_pipeline_result( + result, link_type + ) + if not referenced_version_ids: + return [] + + ref_ids = conn.distinct( + "_id", + filter={ + "parent": {"$in": list(referenced_version_ids)}, + "type": "representation" + } + ) + + return list(ref_ids) + + +def _process_referenced_pipeline_result(result, link_type): + """Filters result from pipeline for particular link_type. + + Pipeline cannot use link_type directly in a query. + + Returns: + (list) + """ + + referenced_version_ids = set() + correctly_linked_ids = set() + for item in result: + input_links = item.get("data", {}).get("inputLinks") + if not input_links: + continue + + _filter_input_links( + input_links, + link_type, + correctly_linked_ids + ) + + # outputs_recursive in random order, sort by depth + outputs_recursive = item.get("outputs_recursive") + if not outputs_recursive: + continue + + for output in sorted(outputs_recursive, key=lambda o: o["depth"]): + # Leaf + if output["_id"] not in correctly_linked_ids: + continue + + _filter_input_links( + output.get("data", {}).get("inputLinks"), + link_type, + correctly_linked_ids + ) + + referenced_version_ids.add(output["_id"]) + + return referenced_version_ids + + +def _filter_input_links(input_links, link_type, correctly_linked_ids): + if not input_links: # to handle hero versions + return + + for input_link in input_links: + if link_type and input_link["type"] != link_type: + continue + + link_id = input_link.get("id") or input_link.get("_id") + if link_id is not None: + correctly_linked_ids.add(link_id) diff --git a/openpype/client/mongo.py b/openpype/client/mongo/mongo.py similarity index 98% rename from openpype/client/mongo.py rename to openpype/client/mongo/mongo.py index 251041c028..2be426efeb 100644 --- a/openpype/client/mongo.py +++ b/openpype/client/mongo/mongo.py @@ -11,6 +11,7 @@ from bson.json_util import ( CANONICAL_JSON_OPTIONS ) +from openpype import AYON_SERVER_ENABLED if sys.version_info[0] == 2: from urlparse import urlparse, parse_qs else: @@ -134,7 +135,7 @@ def should_add_certificate_path_to_mongo_url(mongo_url): add_certificate = False # Check if url 'ssl' or 'tls' are set to 'true' for key in ("ssl", "tls"): - if key in query and "true" in query["ssl"]: + if key in query and "true" in query[key]: add_certificate = True break @@ -206,6 +207,8 @@ class OpenPypeMongoConnection: @classmethod def create_connection(cls, mongo_url, timeout=None, retry_attempts=None): + if AYON_SERVER_ENABLED: + raise RuntimeError("Created mongo connection in AYON mode") parsed = urlparse(mongo_url) # Force validation of scheme if parsed.scheme not in ["mongodb", "mongodb+srv"]: @@ -221,7 +224,7 @@ class OpenPypeMongoConnection: "serverSelectionTimeoutMS": timeout } if should_add_certificate_path_to_mongo_url(mongo_url): - kwargs["ssl_ca_certs"] = certifi.where() + kwargs["tlsCAFile"] = certifi.where() mongo_client = pymongo.MongoClient(mongo_url, **kwargs) diff --git a/openpype/client/mongo/operations.py b/openpype/client/mongo/operations.py new file mode 100644 index 0000000000..3537aa4a3d --- /dev/null +++ b/openpype/client/mongo/operations.py @@ -0,0 +1,632 @@ +import re +import copy +import collections + +from bson.objectid import ObjectId +from pymongo import DeleteOne, InsertOne, UpdateOne + +from openpype.client.operations_base import ( + REMOVED_VALUE, + CreateOperation, + UpdateOperation, + DeleteOperation, + BaseOperationsSession +) +from .mongo import get_project_connection +from .entities import get_project + + +PROJECT_NAME_ALLOWED_SYMBOLS = "a-zA-Z0-9_" +PROJECT_NAME_REGEX = re.compile( + "^[{}]+$".format(PROJECT_NAME_ALLOWED_SYMBOLS) +) + +CURRENT_PROJECT_SCHEMA = "openpype:project-3.0" +CURRENT_PROJECT_CONFIG_SCHEMA = "openpype:config-2.0" +CURRENT_ASSET_DOC_SCHEMA = "openpype:asset-3.0" +CURRENT_SUBSET_SCHEMA = "openpype:subset-3.0" +CURRENT_VERSION_SCHEMA = "openpype:version-3.0" +CURRENT_HERO_VERSION_SCHEMA = "openpype:hero_version-1.0" +CURRENT_REPRESENTATION_SCHEMA = "openpype:representation-2.0" +CURRENT_WORKFILE_INFO_SCHEMA = "openpype:workfile-1.0" +CURRENT_THUMBNAIL_SCHEMA = "openpype:thumbnail-1.0" + + +def _create_or_convert_to_mongo_id(mongo_id): + if mongo_id is None: + return ObjectId() + return ObjectId(mongo_id) + + +def new_project_document( + project_name, project_code, config, data=None, entity_id=None +): + """Create skeleton data of project document. + + Args: + project_name (str): Name of project. Used as identifier of a project. + project_code (str): Shorter version of projet without spaces and + special characters (in most of cases). Should be also considered + as unique name across projects. + config (Dic[str, Any]): Project config consist of roots, templates, + applications and other project Anatomy related data. + data (Dict[str, Any]): Project data with information about it's + attributes (e.g. 'fps' etc.) or integration specific keys. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of project document. + """ + + if data is None: + data = {} + + data["code"] = project_code + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "name": project_name, + "type": CURRENT_PROJECT_SCHEMA, + "entity_data": data, + "config": config + } + + +def new_asset_document( + name, project_id, parent_id, parents, data=None, entity_id=None +): + """Create skeleton data of asset document. + + Args: + name (str): Is considered as unique identifier of asset in project. + project_id (Union[str, ObjectId]): Id of project doument. + parent_id (Union[str, ObjectId]): Id of parent asset. + parents (List[str]): List of parent assets names. + data (Dict[str, Any]): Asset document data. Empty dictionary is used + if not passed. Value of 'parent_id' is used to fill 'visualParent'. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of asset document. + """ + + if data is None: + data = {} + if parent_id is not None: + parent_id = ObjectId(parent_id) + data["visualParent"] = parent_id + data["parents"] = parents + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "type": "asset", + "name": name, + "parent": ObjectId(project_id), + "data": data, + "schema": CURRENT_ASSET_DOC_SCHEMA + } + + +def new_subset_document(name, family, asset_id, data=None, entity_id=None): + """Create skeleton data of subset document. + + Args: + name (str): Is considered as unique identifier of subset under asset. + family (str): Subset's family. + asset_id (Union[str, ObjectId]): Id of parent asset. + data (Dict[str, Any]): Subset document data. Empty dictionary is used + if not passed. Value of 'family' is used to fill 'family'. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of subset document. + """ + + if data is None: + data = {} + data["family"] = family + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "schema": CURRENT_SUBSET_SCHEMA, + "type": "subset", + "name": name, + "data": data, + "parent": asset_id + } + + +def new_version_doc(version, subset_id, data=None, entity_id=None): + """Create skeleton data of version document. + + Args: + version (int): Is considered as unique identifier of version + under subset. + subset_id (Union[str, ObjectId]): Id of parent subset. + data (Dict[str, Any]): Version document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of version document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "schema": CURRENT_VERSION_SCHEMA, + "type": "version", + "name": int(version), + "parent": subset_id, + "data": data + } + + +def new_hero_version_doc(version_id, subset_id, data=None, entity_id=None): + """Create skeleton data of hero version document. + + Args: + version_id (ObjectId): Is considered as unique identifier of version + under subset. + subset_id (Union[str, ObjectId]): Id of parent subset. + data (Dict[str, Any]): Version document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of version document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "schema": CURRENT_HERO_VERSION_SCHEMA, + "type": "hero_version", + "version_id": version_id, + "parent": subset_id, + "data": data + } + + +def new_representation_doc( + name, version_id, context, data=None, entity_id=None +): + """Create skeleton data of asset document. + + Args: + version (int): Is considered as unique identifier of version + under subset. + version_id (Union[str, ObjectId]): Id of parent version. + context (Dict[str, Any]): Representation context used for fill template + of to query. + data (Dict[str, Any]): Representation document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of version document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "schema": CURRENT_REPRESENTATION_SCHEMA, + "type": "representation", + "parent": version_id, + "name": name, + "data": data, + + # Imprint shortcut to context for performance reasons. + "context": context + } + + +def new_thumbnail_doc(data=None, entity_id=None): + """Create skeleton data of thumbnail document. + + Args: + data (Dict[str, Any]): Thumbnail document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of thumbnail document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "type": "thumbnail", + "schema": CURRENT_THUMBNAIL_SCHEMA, + "data": data + } + + +def new_workfile_info_doc( + filename, asset_id, task_name, files, data=None, entity_id=None +): + """Create skeleton data of workfile info document. + + Workfile document is at this moment used primarily for artist notes. + + Args: + filename (str): Filename of workfile. + asset_id (Union[str, ObjectId]): Id of asset under which workfile live. + task_name (str): Task under which was workfile created. + files (List[str]): List of rootless filepaths related to workfile. + data (Dict[str, Any]): Additional metadata. + + Returns: + Dict[str, Any]: Skeleton of workfile info document. + """ + + if not data: + data = {} + + return { + "_id": _create_or_convert_to_mongo_id(entity_id), + "type": "workfile", + "parent": ObjectId(asset_id), + "task_name": task_name, + "filename": filename, + "data": data, + "files": files + } + + +def _prepare_update_data(old_doc, new_doc, replace): + changes = {} + for key, value in new_doc.items(): + if key not in old_doc or value != old_doc[key]: + changes[key] = value + + if replace: + for key in old_doc.keys(): + if key not in new_doc: + changes[key] = REMOVED_VALUE + return changes + + +def prepare_subset_update_data(old_doc, new_doc, replace=True): + """Compare two subset documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +def prepare_version_update_data(old_doc, new_doc, replace=True): + """Compare two version documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +def prepare_hero_version_update_data(old_doc, new_doc, replace=True): + """Compare two hero version documents and prepare update data. + + Based on compared values will create update data for 'UpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +def prepare_representation_update_data(old_doc, new_doc, replace=True): + """Compare two representation documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +def prepare_workfile_info_update_data(old_doc, new_doc, replace=True): + """Compare two workfile info documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +class MongoCreateOperation(CreateOperation): + """Operation to create an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + data (Dict[str, Any]): Data of entity that will be created. + """ + + operation_name = "create" + + def __init__(self, project_name, entity_type, data): + super(MongoCreateOperation, self).__init__( + project_name, entity_type, data + ) + + if "_id" not in self._data: + self._data["_id"] = ObjectId() + else: + self._data["_id"] = ObjectId(self._data["_id"]) + + @property + def entity_id(self): + return self._data["_id"] + + def to_mongo_operation(self): + return InsertOne(copy.deepcopy(self._data)) + + +class MongoUpdateOperation(UpdateOperation): + """Operation to update an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + entity_id (Union[str, ObjectId]): Identifier of an entity. + update_data (Dict[str, Any]): Key -> value changes that will be set in + database. If value is set to 'REMOVED_VALUE' the key will be + removed. Only first level of dictionary is checked (on purpose). + """ + + operation_name = "update" + + def __init__(self, project_name, entity_type, entity_id, update_data): + super(MongoUpdateOperation, self).__init__( + project_name, entity_type, entity_id, update_data + ) + + self._entity_id = ObjectId(self._entity_id) + + def to_mongo_operation(self): + unset_data = {} + set_data = {} + for key, value in self._update_data.items(): + if value is REMOVED_VALUE: + unset_data[key] = None + else: + set_data[key] = value + + op_data = {} + if unset_data: + op_data["$unset"] = unset_data + if set_data: + op_data["$set"] = set_data + + if not op_data: + return None + + return UpdateOne( + {"_id": self.entity_id}, + op_data + ) + + +class MongoDeleteOperation(DeleteOperation): + """Operation to delete an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + entity_id (Union[str, ObjectId]): Entity id that will be removed. + """ + + operation_name = "delete" + + def __init__(self, project_name, entity_type, entity_id): + super(MongoDeleteOperation, self).__init__( + project_name, entity_type, entity_id + ) + + self._entity_id = ObjectId(self._entity_id) + + def to_mongo_operation(self): + return DeleteOne({"_id": self.entity_id}) + + +class MongoOperationsSession(BaseOperationsSession): + """Session storing operations that should happen in an order. + + At this moment does not handle anything special can be sonsidered as + stupid list of operations that will happen after each other. If creation + of same entity is there multiple times it's handled in any way and document + values are not validated. + + All operations must be related to single project. + + Args: + project_name (str): Project name to which are operations related. + """ + + def commit(self): + """Commit session operations.""" + + operations, self._operations = self._operations, [] + if not operations: + return + + operations_by_project = collections.defaultdict(list) + for operation in operations: + operations_by_project[operation.project_name].append(operation) + + for project_name, operations in operations_by_project.items(): + bulk_writes = [] + for operation in operations: + mongo_op = operation.to_mongo_operation() + if mongo_op is not None: + bulk_writes.append(mongo_op) + + if bulk_writes: + collection = get_project_connection(project_name) + collection.bulk_write(bulk_writes) + + def create_entity(self, project_name, entity_type, data): + """Fast access to 'MongoCreateOperation'. + + Returns: + MongoCreateOperation: Object of update operation. + """ + + operation = MongoCreateOperation(project_name, entity_type, data) + self.add(operation) + return operation + + def update_entity(self, project_name, entity_type, entity_id, update_data): + """Fast access to 'MongoUpdateOperation'. + + Returns: + MongoUpdateOperation: Object of update operation. + """ + + operation = MongoUpdateOperation( + project_name, entity_type, entity_id, update_data + ) + self.add(operation) + return operation + + def delete_entity(self, project_name, entity_type, entity_id): + """Fast access to 'MongoDeleteOperation'. + + Returns: + MongoDeleteOperation: Object of delete operation. + """ + + operation = MongoDeleteOperation(project_name, entity_type, entity_id) + self.add(operation) + return operation + + +def create_project( + project_name, + project_code, + library_project=False, +): + """Create project using OpenPype settings. + + This project creation function is not validating project document on + creation. It is because project document is created blindly with only + minimum required information about project which is it's name, code, type + and schema. + + Entered project name must be unique and project must not exist yet. + + Note: + This function is here to be OP v4 ready but in v3 has more logic + to do. That's why inner imports are in the body. + + Args: + project_name(str): New project name. Should be unique. + project_code(str): Project's code should be unique too. + library_project(bool): Project is library project. + + Raises: + ValueError: When project name already exists in MongoDB. + + Returns: + dict: Created project document. + """ + + from openpype.settings import ProjectSettings, SaveWarningExc + from openpype.pipeline.schema import validate + + if get_project(project_name, fields=["name"]): + raise ValueError("Project with name \"{}\" already exists".format( + project_name + )) + + if not PROJECT_NAME_REGEX.match(project_name): + raise ValueError(( + "Project name \"{}\" contain invalid characters" + ).format(project_name)) + + project_doc = { + "type": "project", + "name": project_name, + "data": { + "code": project_code, + "library_project": library_project + }, + "schema": CURRENT_PROJECT_SCHEMA + } + + op_session = MongoOperationsSession() + # Insert document with basic data + create_op = op_session.create_entity( + project_name, project_doc["type"], project_doc + ) + op_session.commit() + + # Load ProjectSettings for the project and save it to store all attributes + # and Anatomy + try: + project_settings_entity = ProjectSettings(project_name) + project_settings_entity.save() + except SaveWarningExc as exc: + print(str(exc)) + except Exception: + op_session.delete_entity( + project_name, project_doc["type"], create_op.entity_id + ) + op_session.commit() + raise + + project_doc = get_project(project_name) + + try: + # Validate created project document + validate(project_doc) + except Exception: + # Remove project if is not valid + op_session.delete_entity( + project_name, project_doc["type"], create_op.entity_id + ) + op_session.commit() + raise + + return project_doc diff --git a/openpype/client/operations.py b/openpype/client/operations.py index ef48f2a1c4..8bc09dffd3 100644 --- a/openpype/client/operations.py +++ b/openpype/client/operations.py @@ -1,794 +1,24 @@ -import re -import uuid -import copy -import collections -from abc import ABCMeta, abstractmethod, abstractproperty +from openpype import AYON_SERVER_ENABLED -import six -from bson.objectid import ObjectId -from pymongo import DeleteOne, InsertOne, UpdateOne +from .operations_base import REMOVED_VALUE +if not AYON_SERVER_ENABLED: + from .mongo.operations import * + OperationsSession = MongoOperationsSession -from .mongo import get_project_connection -from .entities import get_project - -REMOVED_VALUE = object() - -PROJECT_NAME_ALLOWED_SYMBOLS = "a-zA-Z0-9_" -PROJECT_NAME_REGEX = re.compile( - "^[{}]+$".format(PROJECT_NAME_ALLOWED_SYMBOLS) -) - -CURRENT_PROJECT_SCHEMA = "openpype:project-3.0" -CURRENT_PROJECT_CONFIG_SCHEMA = "openpype:config-2.0" -CURRENT_ASSET_DOC_SCHEMA = "openpype:asset-3.0" -CURRENT_SUBSET_SCHEMA = "openpype:subset-3.0" -CURRENT_VERSION_SCHEMA = "openpype:version-3.0" -CURRENT_HERO_VERSION_SCHEMA = "openpype:hero_version-1.0" -CURRENT_REPRESENTATION_SCHEMA = "openpype:representation-2.0" -CURRENT_WORKFILE_INFO_SCHEMA = "openpype:workfile-1.0" -CURRENT_THUMBNAIL_SCHEMA = "openpype:thumbnail-1.0" - - -def _create_or_convert_to_mongo_id(mongo_id): - if mongo_id is None: - return ObjectId() - return ObjectId(mongo_id) - - -def new_project_document( - project_name, project_code, config, data=None, entity_id=None -): - """Create skeleton data of project document. - - Args: - project_name (str): Name of project. Used as identifier of a project. - project_code (str): Shorter version of projet without spaces and - special characters (in most of cases). Should be also considered - as unique name across projects. - config (Dic[str, Any]): Project config consist of roots, templates, - applications and other project Anatomy related data. - data (Dict[str, Any]): Project data with information about it's - attributes (e.g. 'fps' etc.) or integration specific keys. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of project document. - """ - - if data is None: - data = {} - - data["code"] = project_code - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "name": project_name, - "type": CURRENT_PROJECT_SCHEMA, - "entity_data": data, - "config": config - } - - -def new_asset_document( - name, project_id, parent_id, parents, data=None, entity_id=None -): - """Create skeleton data of asset document. - - Args: - name (str): Is considered as unique identifier of asset in project. - project_id (Union[str, ObjectId]): Id of project doument. - parent_id (Union[str, ObjectId]): Id of parent asset. - parents (List[str]): List of parent assets names. - data (Dict[str, Any]): Asset document data. Empty dictionary is used - if not passed. Value of 'parent_id' is used to fill 'visualParent'. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of asset document. - """ - - if data is None: - data = {} - if parent_id is not None: - parent_id = ObjectId(parent_id) - data["visualParent"] = parent_id - data["parents"] = parents - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "type": "asset", - "name": name, - "parent": ObjectId(project_id), - "data": data, - "schema": CURRENT_ASSET_DOC_SCHEMA - } - - -def new_subset_document(name, family, asset_id, data=None, entity_id=None): - """Create skeleton data of subset document. - - Args: - name (str): Is considered as unique identifier of subset under asset. - family (str): Subset's family. - asset_id (Union[str, ObjectId]): Id of parent asset. - data (Dict[str, Any]): Subset document data. Empty dictionary is used - if not passed. Value of 'family' is used to fill 'family'. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of subset document. - """ - - if data is None: - data = {} - data["family"] = family - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "schema": CURRENT_SUBSET_SCHEMA, - "type": "subset", - "name": name, - "data": data, - "parent": asset_id - } - - -def new_version_doc(version, subset_id, data=None, entity_id=None): - """Create skeleton data of version document. - - Args: - version (int): Is considered as unique identifier of version - under subset. - subset_id (Union[str, ObjectId]): Id of parent subset. - data (Dict[str, Any]): Version document data. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of version document. - """ - - if data is None: - data = {} - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "schema": CURRENT_VERSION_SCHEMA, - "type": "version", - "name": int(version), - "parent": subset_id, - "data": data - } - - -def new_hero_version_doc(version_id, subset_id, data=None, entity_id=None): - """Create skeleton data of hero version document. - - Args: - version_id (ObjectId): Is considered as unique identifier of version - under subset. - subset_id (Union[str, ObjectId]): Id of parent subset. - data (Dict[str, Any]): Version document data. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of version document. - """ - - if data is None: - data = {} - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "schema": CURRENT_HERO_VERSION_SCHEMA, - "type": "hero_version", - "version_id": version_id, - "parent": subset_id, - "data": data - } - - -def new_representation_doc( - name, version_id, context, data=None, entity_id=None -): - """Create skeleton data of asset document. - - Args: - version (int): Is considered as unique identifier of version - under subset. - version_id (Union[str, ObjectId]): Id of parent version. - context (Dict[str, Any]): Representation context used for fill template - of to query. - data (Dict[str, Any]): Representation document data. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of version document. - """ - - if data is None: - data = {} - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "schema": CURRENT_REPRESENTATION_SCHEMA, - "type": "representation", - "parent": version_id, - "name": name, - "data": data, - - # Imprint shortcut to context for performance reasons. - "context": context - } - - -def new_thumbnail_doc(data=None, entity_id=None): - """Create skeleton data of thumbnail document. - - Args: - data (Dict[str, Any]): Thumbnail document data. - entity_id (Union[str, ObjectId]): Predefined id of document. New id is - created if not passed. - - Returns: - Dict[str, Any]: Skeleton of thumbnail document. - """ - - if data is None: - data = {} - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "type": "thumbnail", - "schema": CURRENT_THUMBNAIL_SCHEMA, - "data": data - } - - -def new_workfile_info_doc( - filename, asset_id, task_name, files, data=None, entity_id=None -): - """Create skeleton data of workfile info document. - - Workfile document is at this moment used primarily for artist notes. - - Args: - filename (str): Filename of workfile. - asset_id (Union[str, ObjectId]): Id of asset under which workfile live. - task_name (str): Task under which was workfile created. - files (List[str]): List of rootless filepaths related to workfile. - data (Dict[str, Any]): Additional metadata. - - Returns: - Dict[str, Any]: Skeleton of workfile info document. - """ - - if not data: - data = {} - - return { - "_id": _create_or_convert_to_mongo_id(entity_id), - "type": "workfile", - "parent": ObjectId(asset_id), - "task_name": task_name, - "filename": filename, - "data": data, - "files": files - } - - -def _prepare_update_data(old_doc, new_doc, replace): - changes = {} - for key, value in new_doc.items(): - if key not in old_doc or value != old_doc[key]: - changes[key] = value - - if replace: - for key in old_doc.keys(): - if key not in new_doc: - changes[key] = REMOVED_VALUE - return changes - - -def prepare_subset_update_data(old_doc, new_doc, replace=True): - """Compare two subset documents and prepare update data. - - Based on compared values will create update data for 'UpdateOperation'. - - Empty output means that documents are identical. - - Returns: - Dict[str, Any]: Changes between old and new document. - """ - - return _prepare_update_data(old_doc, new_doc, replace) - - -def prepare_version_update_data(old_doc, new_doc, replace=True): - """Compare two version documents and prepare update data. - - Based on compared values will create update data for 'UpdateOperation'. - - Empty output means that documents are identical. - - Returns: - Dict[str, Any]: Changes between old and new document. - """ - - return _prepare_update_data(old_doc, new_doc, replace) - - -def prepare_hero_version_update_data(old_doc, new_doc, replace=True): - """Compare two hero version documents and prepare update data. - - Based on compared values will create update data for 'UpdateOperation'. - - Empty output means that documents are identical. - - Returns: - Dict[str, Any]: Changes between old and new document. - """ - - return _prepare_update_data(old_doc, new_doc, replace) - - -def prepare_representation_update_data(old_doc, new_doc, replace=True): - """Compare two representation documents and prepare update data. - - Based on compared values will create update data for 'UpdateOperation'. - - Empty output means that documents are identical. - - Returns: - Dict[str, Any]: Changes between old and new document. - """ - - return _prepare_update_data(old_doc, new_doc, replace) - - -def prepare_workfile_info_update_data(old_doc, new_doc, replace=True): - """Compare two workfile info documents and prepare update data. - - Based on compared values will create update data for 'UpdateOperation'. - - Empty output means that documents are identical. - - Returns: - Dict[str, Any]: Changes between old and new document. - """ - - return _prepare_update_data(old_doc, new_doc, replace) - - -@six.add_metaclass(ABCMeta) -class AbstractOperation(object): - """Base operation class. - - Operation represent a call into database. The call can create, change or - remove data. - - Args: - project_name (str): On which project operation will happen. - entity_type (str): Type of entity on which change happens. - e.g. 'asset', 'representation' etc. - """ - - def __init__(self, project_name, entity_type): - self._project_name = project_name - self._entity_type = entity_type - self._id = str(uuid.uuid4()) - - @property - def project_name(self): - return self._project_name - - @property - def id(self): - """Identifier of operation.""" - - return self._id - - @property - def entity_type(self): - return self._entity_type - - @abstractproperty - def operation_name(self): - """Stringified type of operation.""" - - pass - - @abstractmethod - def to_mongo_operation(self): - """Convert operation to Mongo batch operation.""" - - pass - - def to_data(self): - """Convert operation to data that can be converted to json or others. - - Warning: - Current state returns ObjectId objects which cannot be parsed by - json. - - Returns: - Dict[str, Any]: Description of operation. - """ - - return { - "id": self._id, - "entity_type": self.entity_type, - "project_name": self.project_name, - "operation": self.operation_name - } - - -class CreateOperation(AbstractOperation): - """Operation to create an entity. - - Args: - project_name (str): On which project operation will happen. - entity_type (str): Type of entity on which change happens. - e.g. 'asset', 'representation' etc. - data (Dict[str, Any]): Data of entity that will be created. - """ - - operation_name = "create" - - def __init__(self, project_name, entity_type, data): - super(CreateOperation, self).__init__(project_name, entity_type) - - if not data: - data = {} - else: - data = copy.deepcopy(dict(data)) - - if "_id" not in data: - data["_id"] = ObjectId() - else: - data["_id"] = ObjectId(data["_id"]) - - self._entity_id = data["_id"] - self._data = data - - def __setitem__(self, key, value): - self.set_value(key, value) - - def __getitem__(self, key): - return self.data[key] - - def set_value(self, key, value): - self.data[key] = value - - def get(self, key, *args, **kwargs): - return self.data.get(key, *args, **kwargs) - - @property - def entity_id(self): - return self._entity_id - - @property - def data(self): - return self._data - - def to_mongo_operation(self): - return InsertOne(copy.deepcopy(self._data)) - - def to_data(self): - output = super(CreateOperation, self).to_data() - output["data"] = copy.deepcopy(self.data) - return output - - -class UpdateOperation(AbstractOperation): - """Operation to update an entity. - - Args: - project_name (str): On which project operation will happen. - entity_type (str): Type of entity on which change happens. - e.g. 'asset', 'representation' etc. - entity_id (Union[str, ObjectId]): Identifier of an entity. - update_data (Dict[str, Any]): Key -> value changes that will be set in - database. If value is set to 'REMOVED_VALUE' the key will be - removed. Only first level of dictionary is checked (on purpose). - """ - - operation_name = "update" - - def __init__(self, project_name, entity_type, entity_id, update_data): - super(UpdateOperation, self).__init__(project_name, entity_type) - - self._entity_id = ObjectId(entity_id) - self._update_data = update_data - - @property - def entity_id(self): - return self._entity_id - - @property - def update_data(self): - return self._update_data - - def to_mongo_operation(self): - unset_data = {} - set_data = {} - for key, value in self._update_data.items(): - if value is REMOVED_VALUE: - unset_data[key] = None - else: - set_data[key] = value - - op_data = {} - if unset_data: - op_data["$unset"] = unset_data - if set_data: - op_data["$set"] = set_data - - if not op_data: - return None - - return UpdateOne( - {"_id": self.entity_id}, - op_data - ) - - def to_data(self): - changes = {} - for key, value in self._update_data.items(): - if value is REMOVED_VALUE: - value = None - changes[key] = value - - output = super(UpdateOperation, self).to_data() - output.update({ - "entity_id": self.entity_id, - "changes": changes - }) - return output - - -class DeleteOperation(AbstractOperation): - """Operation to delete an entity. - - Args: - project_name (str): On which project operation will happen. - entity_type (str): Type of entity on which change happens. - e.g. 'asset', 'representation' etc. - entity_id (Union[str, ObjectId]): Entity id that will be removed. - """ - - operation_name = "delete" - - def __init__(self, project_name, entity_type, entity_id): - super(DeleteOperation, self).__init__(project_name, entity_type) - - self._entity_id = ObjectId(entity_id) - - @property - def entity_id(self): - return self._entity_id - - def to_mongo_operation(self): - return DeleteOne({"_id": self.entity_id}) - - def to_data(self): - output = super(DeleteOperation, self).to_data() - output["entity_id"] = self.entity_id - return output - - -class OperationsSession(object): - """Session storing operations that should happen in an order. - - At this moment does not handle anything special can be sonsidered as - stupid list of operations that will happen after each other. If creation - of same entity is there multiple times it's handled in any way and document - values are not validated. - - All operations must be related to single project. - - Args: - project_name (str): Project name to which are operations related. - """ - - def __init__(self): - self._operations = [] - - def add(self, operation): - """Add operation to be processed. - - Args: - operation (BaseOperation): Operation that should be processed. - """ - if not isinstance( - operation, - (CreateOperation, UpdateOperation, DeleteOperation) - ): - raise TypeError("Expected Operation object got {}".format( - str(type(operation)) - )) - - self._operations.append(operation) - - def append(self, operation): - """Add operation to be processed. - - Args: - operation (BaseOperation): Operation that should be processed. - """ - - self.add(operation) - - def extend(self, operations): - """Add operations to be processed. - - Args: - operations (List[BaseOperation]): Operations that should be - processed. - """ - - for operation in operations: - self.add(operation) - - def remove(self, operation): - """Remove operation.""" - - self._operations.remove(operation) - - def clear(self): - """Clear all registered operations.""" - - self._operations = [] - - def to_data(self): - return [ - operation.to_data() - for operation in self._operations - ] - - def commit(self): - """Commit session operations.""" - - operations, self._operations = self._operations, [] - if not operations: - return - - operations_by_project = collections.defaultdict(list) - for operation in operations: - operations_by_project[operation.project_name].append(operation) - - for project_name, operations in operations_by_project.items(): - bulk_writes = [] - for operation in operations: - mongo_op = operation.to_mongo_operation() - if mongo_op is not None: - bulk_writes.append(mongo_op) - - if bulk_writes: - collection = get_project_connection(project_name) - collection.bulk_write(bulk_writes) - - def create_entity(self, project_name, entity_type, data): - """Fast access to 'CreateOperation'. - - Returns: - CreateOperation: Object of update operation. - """ - - operation = CreateOperation(project_name, entity_type, data) - self.add(operation) - return operation - - def update_entity(self, project_name, entity_type, entity_id, update_data): - """Fast access to 'UpdateOperation'. - - Returns: - UpdateOperation: Object of update operation. - """ - - operation = UpdateOperation( - project_name, entity_type, entity_id, update_data - ) - self.add(operation) - return operation - - def delete_entity(self, project_name, entity_type, entity_id): - """Fast access to 'DeleteOperation'. - - Returns: - DeleteOperation: Object of delete operation. - """ - - operation = DeleteOperation(project_name, entity_type, entity_id) - self.add(operation) - return operation - - -def create_project(project_name, project_code, library_project=False): - """Create project using OpenPype settings. - - This project creation function is not validating project document on - creation. It is because project document is created blindly with only - minimum required information about project which is it's name, code, type - and schema. - - Entered project name must be unique and project must not exist yet. - - Note: - This function is here to be OP v4 ready but in v3 has more logic - to do. That's why inner imports are in the body. - - Args: - project_name(str): New project name. Should be unique. - project_code(str): Project's code should be unique too. - library_project(bool): Project is library project. - - Raises: - ValueError: When project name already exists in MongoDB. - - Returns: - dict: Created project document. - """ - - from openpype.settings import ProjectSettings, SaveWarningExc - from openpype.pipeline.schema import validate - - if get_project(project_name, fields=["name"]): - raise ValueError("Project with name \"{}\" already exists".format( - project_name - )) - - if not PROJECT_NAME_REGEX.match(project_name): - raise ValueError(( - "Project name \"{}\" contain invalid characters" - ).format(project_name)) - - project_doc = { - "type": "project", - "name": project_name, - "data": { - "code": project_code, - "library_project": library_project - }, - "schema": CURRENT_PROJECT_SCHEMA - } - - op_session = OperationsSession() - # Insert document with basic data - create_op = op_session.create_entity( - project_name, project_doc["type"], project_doc +else: + from ayon_api.server_api import ( + PROJECT_NAME_ALLOWED_SYMBOLS, + PROJECT_NAME_REGEX, + ) + from .server.operations import * + from .mongo.operations import ( + CURRENT_PROJECT_SCHEMA, + CURRENT_PROJECT_CONFIG_SCHEMA, + CURRENT_ASSET_DOC_SCHEMA, + CURRENT_SUBSET_SCHEMA, + CURRENT_VERSION_SCHEMA, + CURRENT_HERO_VERSION_SCHEMA, + CURRENT_REPRESENTATION_SCHEMA, + CURRENT_WORKFILE_INFO_SCHEMA, + CURRENT_THUMBNAIL_SCHEMA ) - op_session.commit() - - # Load ProjectSettings for the project and save it to store all attributes - # and Anatomy - try: - project_settings_entity = ProjectSettings(project_name) - project_settings_entity.save() - except SaveWarningExc as exc: - print(str(exc)) - except Exception: - op_session.delete_entity( - project_name, project_doc["type"], create_op.entity_id - ) - op_session.commit() - raise - - project_doc = get_project(project_name) - - try: - # Validate created project document - validate(project_doc) - except Exception: - # Remove project if is not valid - op_session.delete_entity( - project_name, project_doc["type"], create_op.entity_id - ) - op_session.commit() - raise - - return project_doc diff --git a/openpype/client/operations_base.py b/openpype/client/operations_base.py new file mode 100644 index 0000000000..887b237b1c --- /dev/null +++ b/openpype/client/operations_base.py @@ -0,0 +1,289 @@ +import uuid +import copy +from abc import ABCMeta, abstractmethod, abstractproperty +import six + +REMOVED_VALUE = object() + + +@six.add_metaclass(ABCMeta) +class AbstractOperation(object): + """Base operation class. + + Operation represent a call into database. The call can create, change or + remove data. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + """ + + def __init__(self, project_name, entity_type): + self._project_name = project_name + self._entity_type = entity_type + self._id = str(uuid.uuid4()) + + @property + def project_name(self): + return self._project_name + + @property + def id(self): + """Identifier of operation.""" + + return self._id + + @property + def entity_type(self): + return self._entity_type + + @abstractproperty + def operation_name(self): + """Stringified type of operation.""" + + pass + + def to_data(self): + """Convert operation to data that can be converted to json or others. + + Warning: + Current state returns ObjectId objects which cannot be parsed by + json. + + Returns: + Dict[str, Any]: Description of operation. + """ + + return { + "id": self._id, + "entity_type": self.entity_type, + "project_name": self.project_name, + "operation": self.operation_name + } + + +class CreateOperation(AbstractOperation): + """Operation to create an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + data (Dict[str, Any]): Data of entity that will be created. + """ + + operation_name = "create" + + def __init__(self, project_name, entity_type, data): + super(CreateOperation, self).__init__(project_name, entity_type) + + if not data: + data = {} + else: + data = copy.deepcopy(dict(data)) + self._data = data + + def __setitem__(self, key, value): + self.set_value(key, value) + + def __getitem__(self, key): + return self.data[key] + + def set_value(self, key, value): + self.data[key] = value + + def get(self, key, *args, **kwargs): + return self.data.get(key, *args, **kwargs) + + @abstractproperty + def entity_id(self): + pass + + @property + def data(self): + return self._data + + def to_data(self): + output = super(CreateOperation, self).to_data() + output["data"] = copy.deepcopy(self.data) + return output + + +class UpdateOperation(AbstractOperation): + """Operation to update an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + entity_id (Union[str, ObjectId]): Identifier of an entity. + update_data (Dict[str, Any]): Key -> value changes that will be set in + database. If value is set to 'REMOVED_VALUE' the key will be + removed. Only first level of dictionary is checked (on purpose). + """ + + operation_name = "update" + + def __init__(self, project_name, entity_type, entity_id, update_data): + super(UpdateOperation, self).__init__(project_name, entity_type) + + self._entity_id = entity_id + self._update_data = update_data + + @property + def entity_id(self): + return self._entity_id + + @property + def update_data(self): + return self._update_data + + def to_data(self): + changes = {} + for key, value in self._update_data.items(): + if value is REMOVED_VALUE: + value = None + changes[key] = value + + output = super(UpdateOperation, self).to_data() + output.update({ + "entity_id": self.entity_id, + "changes": changes + }) + return output + + +class DeleteOperation(AbstractOperation): + """Operation to delete an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + entity_id (Union[str, ObjectId]): Entity id that will be removed. + """ + + operation_name = "delete" + + def __init__(self, project_name, entity_type, entity_id): + super(DeleteOperation, self).__init__(project_name, entity_type) + + self._entity_id = entity_id + + @property + def entity_id(self): + return self._entity_id + + def to_data(self): + output = super(DeleteOperation, self).to_data() + output["entity_id"] = self.entity_id + return output + + +class BaseOperationsSession(object): + """Session storing operations that should happen in an order. + + At this moment does not handle anything special can be considered as + stupid list of operations that will happen after each other. If creation + of same entity is there multiple times it's handled in any way and document + values are not validated. + """ + + def __init__(self): + self._operations = [] + + def __len__(self): + return len(self._operations) + + def add(self, operation): + """Add operation to be processed. + + Args: + operation (BaseOperation): Operation that should be processed. + """ + if not isinstance( + operation, + (CreateOperation, UpdateOperation, DeleteOperation) + ): + raise TypeError("Expected Operation object got {}".format( + str(type(operation)) + )) + + self._operations.append(operation) + + def append(self, operation): + """Add operation to be processed. + + Args: + operation (BaseOperation): Operation that should be processed. + """ + + self.add(operation) + + def extend(self, operations): + """Add operations to be processed. + + Args: + operations (List[BaseOperation]): Operations that should be + processed. + """ + + for operation in operations: + self.add(operation) + + def remove(self, operation): + """Remove operation.""" + + self._operations.remove(operation) + + def clear(self): + """Clear all registered operations.""" + + self._operations = [] + + def to_data(self): + return [ + operation.to_data() + for operation in self._operations + ] + + @abstractmethod + def commit(self): + """Commit session operations.""" + pass + + def create_entity(self, project_name, entity_type, data): + """Fast access to 'CreateOperation'. + + Returns: + CreateOperation: Object of update operation. + """ + + operation = CreateOperation(project_name, entity_type, data) + self.add(operation) + return operation + + def update_entity(self, project_name, entity_type, entity_id, update_data): + """Fast access to 'UpdateOperation'. + + Returns: + UpdateOperation: Object of update operation. + """ + + operation = UpdateOperation( + project_name, entity_type, entity_id, update_data + ) + self.add(operation) + return operation + + def delete_entity(self, project_name, entity_type, entity_id): + """Fast access to 'DeleteOperation'. + + Returns: + DeleteOperation: Object of delete operation. + """ + + operation = DeleteOperation(project_name, entity_type, entity_id) + self.add(operation) + return operation diff --git a/openpype/hosts/celaction/hooks/__init__.py b/openpype/client/server/__init__.py similarity index 100% rename from openpype/hosts/celaction/hooks/__init__.py rename to openpype/client/server/__init__.py diff --git a/openpype/client/server/constants.py b/openpype/client/server/constants.py new file mode 100644 index 0000000000..1d3f94c702 --- /dev/null +++ b/openpype/client/server/constants.py @@ -0,0 +1,18 @@ +# --- Folders --- +DEFAULT_FOLDER_FIELDS = { + "id", + "name", + "path", + "parentId", + "active", + "parents", + "thumbnailId" +} + +REPRESENTATION_FILES_FIELDS = { + "files.name", + "files.hash", + "files.id", + "files.path", + "files.size", +} diff --git a/openpype/client/server/conversion_utils.py b/openpype/client/server/conversion_utils.py new file mode 100644 index 0000000000..e8d3c4cbe4 --- /dev/null +++ b/openpype/client/server/conversion_utils.py @@ -0,0 +1,1362 @@ +import os +import arrow +import collections +import json + +import six + +from openpype.client.operations_base import REMOVED_VALUE +from openpype.client.mongo.operations import ( + CURRENT_PROJECT_SCHEMA, + CURRENT_ASSET_DOC_SCHEMA, + CURRENT_SUBSET_SCHEMA, + CURRENT_VERSION_SCHEMA, + CURRENT_HERO_VERSION_SCHEMA, + CURRENT_REPRESENTATION_SCHEMA, + CURRENT_WORKFILE_INFO_SCHEMA, +) +from .constants import REPRESENTATION_FILES_FIELDS +from .utils import create_entity_id, prepare_entity_changes + +# --- Project entity --- +PROJECT_FIELDS_MAPPING_V3_V4 = { + "_id": {"name"}, + "name": {"name"}, + "data": {"data", "code"}, + "data.library_project": {"library"}, + "data.code": {"code"}, + "data.active": {"active"}, +} + +# TODO this should not be hardcoded but received from server!!! +# --- Folder entity --- +FOLDER_FIELDS_MAPPING_V3_V4 = { + "_id": {"id"}, + "name": {"name"}, + "label": {"label"}, + "data": { + "parentId", "parents", "active", "tasks", "thumbnailId" + }, + "data.visualParent": {"parentId"}, + "data.parents": {"parents"}, + "data.active": {"active"}, + "data.thumbnail_id": {"thumbnailId"}, + "data.entityType": {"folderType"} +} + +# --- Subset entity --- +SUBSET_FIELDS_MAPPING_V3_V4 = { + "_id": {"id"}, + "name": {"name"}, + "data.active": {"active"}, + "parent": {"folderId"} +} + +# --- Version entity --- +VERSION_FIELDS_MAPPING_V3_V4 = { + "_id": {"id"}, + "name": {"version"}, + "parent": {"productId"} +} + +# --- Representation entity --- +REPRESENTATION_FIELDS_MAPPING_V3_V4 = { + "_id": {"id"}, + "name": {"name"}, + "parent": {"versionId"}, + "context": {"context"}, + "files": {"files"}, +} + + +def project_fields_v3_to_v4(fields, con): + """Convert project fields from v3 to v4 structure. + + Args: + fields (Union[Iterable(str), None]): fields to be converted. + + Returns: + Union[Set(str), None]: Converted fields to v4 fields. + """ + + # TODO config fields + # - config.apps + # - config.groups + if not fields: + return None + + project_attribs = con.get_attributes_for_type("project") + output = set() + for field in fields: + # If config is needed the rest api call must be used + if field.startswith("config"): + return None + + if field in PROJECT_FIELDS_MAPPING_V3_V4: + output |= PROJECT_FIELDS_MAPPING_V3_V4[field] + if field == "data": + output |= { + "attrib.{}".format(attr) + for attr in project_attribs + } + + elif field.startswith("data"): + field_parts = field.split(".") + field_parts.pop(0) + data_key = ".".join(field_parts) + if data_key in project_attribs: + output.add("attrib.{}".format(data_key)) + else: + output.add("data") + print("Requested specific key from data {}".format(data_key)) + + else: + raise ValueError("Unknown field mapping for {}".format(field)) + + if "name" not in output: + output.add("name") + return output + + +def _get_default_template_name(templates): + default_template = None + for name, template in templates.items(): + if name == "default": + return "default" + + if default_template is None: + default_template = name + + return default_template + + +def _template_replacements_to_v3(template): + return ( + template + .replace("{product[name]}", "{subset}") + .replace("{product[type]}", "{family}") + ) + + +def _convert_template_item(template_item): + for key, value in tuple(template_item.items()): + template_item[key] = _template_replacements_to_v3(value) + + # Change 'directory' to 'folder' + if "directory" in template_item: + template_item["folder"] = template_item.pop("directory") + + if ( + "path" not in template_item + and "file" in template_item + and "folder" in template_item + ): + template_item["path"] = "/".join( + (template_item["folder"], template_item["file"]) + ) + + +def _fill_template_category(templates, cat_templates, cat_key): + default_template_name = _get_default_template_name(cat_templates) + for template_name, cat_template in cat_templates.items(): + _convert_template_item(cat_template) + if template_name == default_template_name: + templates[cat_key] = cat_template + else: + new_name = "{}_{}".format(cat_key, template_name) + templates["others"][new_name] = cat_template + + +def convert_v4_project_to_v3(project): + """Convert Project entity data from v4 structure to v3 structure. + + Args: + project (Dict[str, Any]): Project entity queried from v4 server. + + Returns: + Dict[str, Any]: Project converted to v3 structure. + """ + + if not project: + return project + + project_name = project["name"] + output = { + "_id": project_name, + "name": project_name, + "schema": CURRENT_PROJECT_SCHEMA, + "type": "project" + } + + data = project.get("data") or {} + attribs = project.get("attrib") or {} + apps_attr = attribs.pop("applications", None) or [] + applications = [ + {"name": app_name} + for app_name in apps_attr + ] + data.update(attribs) + if "tools" in data: + data["tools_env"] = data.pop("tools") + + data["entityType"] = "Project" + + config = {} + project_config = project.get("config") + + if project_config: + config["apps"] = applications + config["roots"] = project_config["roots"] + + templates = project_config["templates"] + templates["defaults"] = templates.pop("common", None) or {} + + others_templates = templates.pop("others", None) or {} + new_others_templates = {} + templates["others"] = new_others_templates + for name, template in others_templates.items(): + _convert_template_item(template) + new_others_templates[name] = template + + staging_templates = templates.pop("staging", None) + # Key 'staging_directories' is legacy key that changed + # to 'staging_dir' + _legacy_staging_templates = templates.pop("staging_directories", None) + if staging_templates is None: + staging_templates = _legacy_staging_templates + + if staging_templates is None: + staging_templates = {} + + # Prefix all staging template names with 'staging_' prefix + # and add them to 'others' + for name, template in staging_templates.items(): + _convert_template_item(template) + new_name = "staging_{}".format(name) + new_others_templates[new_name] = template + + for key in ( + "work", + "publish", + "hero", + ): + cat_templates = templates.pop(key) + _fill_template_category(templates, cat_templates, key) + + delivery_templates = templates.pop("delivery", None) or {} + new_delivery_templates = {} + for name, delivery_template in delivery_templates.items(): + new_delivery_templates[name] = "/".join( + (delivery_template["directory"], delivery_template["file"]) + ) + templates["delivery"] = new_delivery_templates + + config["templates"] = templates + + if "taskTypes" in project: + task_types = project["taskTypes"] + new_task_types = {} + for task_type in task_types: + name = task_type.pop("name") + # Change 'shortName' to 'short_name' + task_type["short_name"] = task_type.pop("shortName", None) + new_task_types[name] = task_type + + config["tasks"] = new_task_types + + if config: + output["config"] = config + + for data_key, key in ( + ("library_project", "library"), + ("code", "code"), + ("active", "active") + ): + if key in project: + data[data_key] = project[key] + + if "attrib" in project: + for key, value in project["attrib"].items(): + data[key] = value + + if data: + output["data"] = data + return output + + +def folder_fields_v3_to_v4(fields, con): + """Convert folder fields from v3 to v4 structure. + + Args: + fields (Union[Iterable(str), None]): fields to be converted. + + Returns: + Union[Set(str), None]: Converted fields to v4 fields. + """ + + if not fields: + return None + + folder_attributes = con.get_attributes_for_type("folder") + output = set() + for field in fields: + if field in ("schema", "type", "parent"): + continue + + if field in FOLDER_FIELDS_MAPPING_V3_V4: + output |= FOLDER_FIELDS_MAPPING_V3_V4[field] + if field == "data": + output |= { + "attrib.{}".format(attr) + for attr in folder_attributes + } + + elif field.startswith("data"): + field_parts = field.split(".") + field_parts.pop(0) + data_key = ".".join(field_parts) + if data_key == "label": + output.add("name") + + elif data_key in ("icon", "color"): + continue + + elif data_key.startswith("tasks"): + output.add("tasks") + + elif data_key in folder_attributes: + output.add("attrib.{}".format(data_key)) + + else: + output.add("data") + print("Requested specific key from data {}".format(data_key)) + + else: + raise ValueError("Unknown field mapping for {}".format(field)) + + if "id" not in output: + output.add("id") + return output + + +def convert_v4_tasks_to_v3(tasks): + """Convert v4 task item to v3 task. + + Args: + tasks (List[Dict[str, Any]]): Task entites. + + Returns: + Dict[str, Dict[str, Any]]: Tasks in v3 variant ready for v3 asset. + """ + + output = {} + for task in tasks: + task_name = task["name"] + new_task = { + "type": task["taskType"] + } + output[task_name] = new_task + return output + + +def convert_v4_folder_to_v3(folder, project_name): + """Convert v4 folder to v3 asset. + + Args: + folder (Dict[str, Any]): Folder entity data. + project_name (str): Project name from which folder was queried. + + Returns: + Dict[str, Any]: Converted v4 folder to v3 asset. + """ + + output = { + "_id": folder["id"], + "parent": project_name, + "type": "asset", + "schema": CURRENT_ASSET_DOC_SCHEMA + } + + output_data = folder.get("data") or {} + + if "name" in folder: + output["name"] = folder["name"] + output_data["label"] = folder["name"] + + if "folderType" in folder: + output_data["entityType"] = folder["folderType"] + + for src_key, dst_key in ( + ("parentId", "visualParent"), + ("active", "active"), + ("thumbnailId", "thumbnail_id"), + ("parents", "parents"), + ): + if src_key in folder: + output_data[dst_key] = folder[src_key] + + if "attrib" in folder: + output_data.update(folder["attrib"]) + + if "tools" in output_data: + output_data["tools_env"] = output_data.pop("tools") + + if "tasks" in folder: + output_data["tasks"] = convert_v4_tasks_to_v3(folder["tasks"]) + + output["data"] = output_data + + return output + + +def subset_fields_v3_to_v4(fields, con): + """Convert subset fields from v3 to v4 structure. + + Args: + fields (Union[Iterable(str), None]): fields to be converted. + + Returns: + Union[Set(str), None]: Converted fields to v4 fields. + """ + + if not fields: + return None + + product_attributes = con.get_attributes_for_type("product") + + output = set() + for field in fields: + if field in ("schema", "type"): + continue + + if field in SUBSET_FIELDS_MAPPING_V3_V4: + output |= SUBSET_FIELDS_MAPPING_V3_V4[field] + + elif field == "data": + output.add("productType") + output.add("active") + output |= { + "attrib.{}".format(attr) + for attr in product_attributes + } + + elif field.startswith("data"): + field_parts = field.split(".") + field_parts.pop(0) + data_key = ".".join(field_parts) + if data_key in ("family", "families"): + output.add("productType") + + elif data_key in product_attributes: + output.add("attrib.{}".format(data_key)) + + else: + output.add("data") + print("Requested specific key from data {}".format(data_key)) + + else: + raise ValueError("Unknown field mapping for {}".format(field)) + + if "id" not in output: + output.add("id") + return output + + +def convert_v4_subset_to_v3(subset): + output = { + "_id": subset["id"], + "type": "subset", + "schema": CURRENT_SUBSET_SCHEMA + } + if "folderId" in subset: + output["parent"] = subset["folderId"] + + output_data = subset.get("data") or {} + + if "name" in subset: + output["name"] = subset["name"] + + if "active" in subset: + output_data["active"] = subset["active"] + + if "attrib" in subset: + attrib = subset["attrib"] + if "productGroup" in attrib: + attrib["subsetGroup"] = attrib.pop("productGroup") + output_data.update(attrib) + + family = subset.get("productType") + if family: + output_data["family"] = family + output_data["families"] = [family] + + output["data"] = output_data + + return output + + +def version_fields_v3_to_v4(fields, con): + """Convert version fields from v3 to v4 structure. + + Args: + fields (Union[Iterable(str), None]): fields to be converted. + + Returns: + Union[Set(str), None]: Converted fields to v4 fields. + """ + + if not fields: + return None + + version_attributes = con.get_attributes_for_type("version") + + output = set() + for field in fields: + if field in ("type", "schema", "version_id"): + continue + + if field in VERSION_FIELDS_MAPPING_V3_V4: + output |= VERSION_FIELDS_MAPPING_V3_V4[field] + + elif field == "data": + output |= { + "attrib.{}".format(attr) + for attr in version_attributes + } + output |= { + "author", + "createdAt", + "thumbnailId", + } + + elif field.startswith("data"): + field_parts = field.split(".") + field_parts.pop(0) + data_key = ".".join(field_parts) + if data_key in version_attributes: + output.add("attrib.{}".format(data_key)) + + elif data_key == "thumbnail_id": + output.add("thumbnailId") + + elif data_key == "time": + output.add("createdAt") + + elif data_key == "author": + output.add("author") + + elif data_key in ("tags", ): + continue + + else: + output.add("data") + print("Requested specific key from data {}".format(data_key)) + + else: + raise ValueError("Unknown field mapping for {}".format(field)) + + if "id" not in output: + output.add("id") + return output + + +def convert_v4_version_to_v3(version): + """Convert v4 version entity to v4 version. + + Args: + version (Dict[str, Any]): Queried v4 version entity. + + Returns: + Dict[str, Any]: Conveted version entity to v3 structure. + """ + + version_num = version["version"] + if version_num < 0: + output = { + "_id": version["id"], + "type": "hero_version", + "schema": CURRENT_HERO_VERSION_SCHEMA, + } + if "productId" in version: + output["parent"] = version["productId"] + + if "data" in version: + output["data"] = version["data"] + return output + + output = { + "_id": version["id"], + "type": "version", + "name": version_num, + "schema": CURRENT_VERSION_SCHEMA + } + if "productId" in version: + output["parent"] = version["productId"] + + output_data = version.get("data") or {} + if "attrib" in version: + output_data.update(version["attrib"]) + + for src_key, dst_key in ( + ("active", "active"), + ("thumbnailId", "thumbnail_id"), + ("author", "author") + ): + if src_key in version: + output_data[dst_key] = version[src_key] + + if "createdAt" in version: + created_at = arrow.get(version["createdAt"]).to("local") + output_data["time"] = created_at.strftime("%Y%m%dT%H%M%SZ") + + output["data"] = output_data + + return output + + +def representation_fields_v3_to_v4(fields, con): + """Convert representation fields from v3 to v4 structure. + + Args: + fields (Union[Iterable(str), None]): fields to be converted. + + Returns: + Union[Set(str), None]: Converted fields to v4 fields. + """ + + if not fields: + return None + + representation_attributes = con.get_attributes_for_type("representation") + + output = set() + for field in fields: + if field in ("type", "schema"): + continue + + if field in REPRESENTATION_FIELDS_MAPPING_V3_V4: + output |= REPRESENTATION_FIELDS_MAPPING_V3_V4[field] + + elif field.startswith("context"): + output.add("context") + + # TODO: 'files' can have specific attributes but the keys in v3 and v4 + # are not the same (content is not the same) + elif field.startswith("files"): + output |= REPRESENTATION_FILES_FIELDS + + elif field.startswith("data"): + output |= { + "attrib.{}".format(attr) + for attr in representation_attributes + } + + else: + raise ValueError("Unknown field mapping for {}".format(field)) + + if "id" not in output: + output.add("id") + return output + + +def convert_v4_representation_to_v3(representation): + """Convert v4 representation to v3 representation. + + Args: + representation (Dict[str, Any]): Queried representation from v4 server. + + Returns: + Dict[str, Any]: Converted representation to v3 structure. + """ + + output = { + "type": "representation", + "schema": CURRENT_REPRESENTATION_SCHEMA, + } + if "id" in representation: + output["_id"] = representation["id"] + + for v3_key, v4_key in ( + ("name", "name"), + ("parent", "versionId") + ): + if v4_key in representation: + output[v3_key] = representation[v4_key] + + if "context" in representation: + context = representation["context"] + if isinstance(context, six.string_types): + context = json.loads(context) + + if "asset" not in context and "folder" in context: + _c_folder = context["folder"] + context["asset"] = _c_folder["name"] + + elif "asset" in context and "folder" not in context: + context["folder"] = {"name": context["asset"]} + + if "product" in context: + _c_product = context.pop("product") + context["family"] = _c_product["type"] + context["subset"] = _c_product["name"] + + output["context"] = context + + if "files" in representation: + files = representation["files"] + new_files = [] + # From GraphQl is list + if isinstance(files, list): + for file_info in files: + file_info["_id"] = file_info["id"] + new_files.append(file_info) + + # From RestPoint is dictionary + elif isinstance(files, dict): + for file_id, file_info in files: + file_info["_id"] = file_id + new_files.append(file_info) + + for file_info in new_files: + if not file_info.get("sites"): + file_info["sites"] = [{ + "name": "studio" + }] + + output["files"] = new_files + + if representation.get("active") is False: + output["type"] = "archived_representation" + output["old_id"] = output["_id"] + + output_data = representation.get("data") or {} + if "attrib" in representation: + output_data.update(representation["attrib"]) + + for key, data_key in ( + ("active", "active"), + ): + if key in representation: + output_data[data_key] = representation[key] + + if "template" in output_data: + output_data["template"] = ( + output_data["template"] + .replace("{product[name]}", "{subset}") + .replace("{product[type]}", "{family}") + ) + + output["data"] = output_data + + return output + + +def workfile_info_fields_v3_to_v4(fields): + if not fields: + return None + + new_fields = set() + fields = set(fields) + for v3_key, v4_key in ( + ("_id", "id"), + ("files", "path"), + ("filename", "name"), + ("data", "data"), + ): + if v3_key in fields: + new_fields.add(v4_key) + + if "parent" in fields or "task_name" in fields: + new_fields.add("taskId") + + return new_fields + + +def convert_v4_workfile_info_to_v3(workfile_info, task): + output = { + "type": "workfile", + "schema": CURRENT_WORKFILE_INFO_SCHEMA, + } + if "id" in workfile_info: + output["_id"] = workfile_info["id"] + + if "path" in workfile_info: + output["files"] = [workfile_info["path"]] + + if "name" in workfile_info: + output["filename"] = workfile_info["name"] + + if "taskId" in workfile_info: + output["task_name"] = task["name"] + output["parent"] = task["folderId"] + + return output + + +def convert_create_asset_to_v4(asset, project, con): + folder_attributes = con.get_attributes_for_type("folder") + + asset_data = asset["data"] + parent_id = asset_data["visualParent"] + + folder = { + "name": asset["name"], + "parentId": parent_id, + } + entity_id = asset.get("_id") + if entity_id: + folder["id"] = entity_id + + attribs = {} + data = {} + for key, value in asset_data.items(): + if key in ( + "visualParent", + "thumbnail_id", + "parents", + "inputLinks", + "avalon_mongo_id", + ): + continue + + if key not in folder_attributes: + data[key] = value + elif value is not None: + attribs[key] = value + + if attribs: + folder["attrib"] = attribs + + if data: + folder["data"] = data + return folder + + +def convert_create_task_to_v4(task, project, con): + if not project["taskTypes"]: + raise ValueError( + "Project \"{}\" does not have any task types".format( + project["name"])) + + task_type = task["type"] + if task_type not in project["taskTypes"]: + task_type = tuple(project["taskTypes"].keys())[0] + + return { + "name": task["name"], + "taskType": task_type, + "folderId": task["folderId"] + } + + +def convert_create_subset_to_v4(subset, con): + product_attributes = con.get_attributes_for_type("product") + + subset_data = subset["data"] + product_type = subset_data.get("family") + if not product_type: + product_type = subset_data["families"][0] + + converted_product = { + "name": subset["name"], + "productType": product_type, + "folderId": subset["parent"], + } + entity_id = subset.get("_id") + if entity_id: + converted_product["id"] = entity_id + + attribs = {} + data = {} + if "subsetGroup" in subset_data: + subset_data["productGroup"] = subset_data.pop("subsetGroup") + for key, value in subset_data.items(): + if key not in product_attributes: + data[key] = value + elif value is not None: + attribs[key] = value + + if attribs: + converted_product["attrib"] = attribs + + if data: + converted_product["data"] = data + + return converted_product + + +def convert_create_version_to_v4(version, con): + version_attributes = con.get_attributes_for_type("version") + converted_version = { + "version": version["name"], + "productId": version["parent"], + } + entity_id = version.get("_id") + if entity_id: + converted_version["id"] = entity_id + + version_data = version["data"] + attribs = {} + data = {} + for key, value in version_data.items(): + if key not in version_attributes: + data[key] = value + elif value is not None: + attribs[key] = value + + if attribs: + converted_version["attrib"] = attribs + + if data: + converted_version["data"] = attribs + + return converted_version + + +def convert_create_hero_version_to_v4(hero_version, project_name, con): + if "version_id" in hero_version: + version_id = hero_version["version_id"] + version = con.get_version_by_id(project_name, version_id) + version["version"] = - version["version"] + + for auto_key in ( + "name", + "createdAt", + "updatedAt", + "author", + ): + version.pop(auto_key, None) + + return version + + version_attributes = con.get_attributes_for_type("version") + converted_version = { + "version": hero_version["version"], + "productId": hero_version["parent"], + } + entity_id = hero_version.get("_id") + if entity_id: + converted_version["id"] = entity_id + + version_data = hero_version["data"] + attribs = {} + data = {} + for key, value in version_data.items(): + if key not in version_attributes: + data[key] = value + elif value is not None: + attribs[key] = value + + if attribs: + converted_version["attrib"] = attribs + + if data: + converted_version["data"] = attribs + + return converted_version + + +def convert_create_representation_to_v4(representation, con): + representation_attributes = con.get_attributes_for_type("representation") + + converted_representation = { + "name": representation["name"], + "versionId": representation["parent"], + } + entity_id = representation.get("_id") + if entity_id: + converted_representation["id"] = entity_id + + if representation.get("type") == "archived_representation": + converted_representation["active"] = False + + new_files = [] + for file_item in representation["files"]: + new_file_item = { + key: value + for key, value in file_item.items() + if key in ("hash", "path", "size") + } + new_file_item.update({ + "id": create_entity_id(), + "hash_type": "op3", + "name": os.path.basename(new_file_item["path"]) + }) + new_files.append(new_file_item) + + converted_representation["files"] = new_files + + context = representation["context"] + if "folder" not in context: + context["folder"] = { + "name": context.get("asset") + } + + context["product"] = { + "type": context.pop("family", None), + "name": context.pop("subset", None), + } + + attribs = {} + data = { + "context": context, + } + + representation_data = representation["data"] + representation_data["template"] = ( + representation_data["template"] + .replace("{subset}", "{product[name]}") + .replace("{family}", "{product[type]}") + ) + + for key, value in representation_data.items(): + if key not in representation_attributes: + data[key] = value + elif value is not None: + attribs[key] = value + + if attribs: + converted_representation["attrib"] = attribs + + if data: + converted_representation["data"] = data + + return converted_representation + + +def convert_create_workfile_info_to_v4(data, project_name, con): + folder_id = data["parent"] + task_name = data["task_name"] + task = con.get_task_by_name(project_name, folder_id, task_name) + if not task: + return None + + workfile_attributes = con.get_attributes_for_type("workfile") + filename = data["filename"] + possible_attribs = { + "extension": os.path.splitext(filename)[-1] + } + attribs = {} + for attr in workfile_attributes: + if attr in possible_attribs: + attribs[attr] = possible_attribs[attr] + + output = { + "path": data["files"][0], + "name": filename, + "taskId": task["id"] + } + if "_id" in data: + output["id"] = data["_id"] + + if attribs: + output["attrib"] = attribs + + output_data = data.get("data") + if output_data: + output["data"] = output_data + return output + + +def _from_flat_dict(data): + output = {} + for key, value in data.items(): + output_value = output + subkeys = key.split(".") + last_key = subkeys.pop(-1) + for subkey in subkeys: + if subkey not in output_value: + output_value[subkey] = {} + output_value = output_value[subkey] + + output_value[last_key] = value + return output + + +def _to_flat_dict(data): + output = {} + flat_queue = collections.deque() + flat_queue.append(([], data)) + while flat_queue: + item = flat_queue.popleft() + parent_keys, data = item + for key, value in data.items(): + keys = list(parent_keys) + keys.append(key) + if isinstance(value, dict): + flat_queue.append((keys, value)) + else: + full_key = ".".join(keys) + output[full_key] = value + + return output + + +def convert_update_folder_to_v4(project_name, asset_id, update_data, con): + new_update_data = {} + + folder_attributes = con.get_attributes_for_type("folder") + full_update_data = _from_flat_dict(update_data) + data = full_update_data.get("data") + + has_new_parent = False + has_task_changes = False + parent_id = None + tasks = None + new_data = {} + attribs = full_update_data.pop("attrib", {}) + if "type" in update_data: + new_update_data["active"] = update_data["type"] == "asset" + + if data: + if "thumbnail_id" in data: + new_update_data["thumbnailId"] = data.pop("thumbnail_id") + + if "tasks" in data: + tasks = data.pop("tasks") + has_task_changes = True + + if "visualParent" in data: + has_new_parent = True + parent_id = data.pop("visualParent") + + for key, value in data.items(): + if key in folder_attributes: + attribs[key] = value + else: + new_data[key] = value + + if "name" in update_data: + new_update_data["name"] = update_data["name"] + + if "type" in update_data: + new_type = update_data["type"] + if new_type == "asset": + new_update_data["active"] = True + elif new_type == "archived_asset": + new_update_data["active"] = False + + if has_new_parent: + new_update_data["parentId"] = parent_id + + if new_data: + print("Folder has new data: {}".format(new_data)) + new_update_data["data"] = new_data + + if attribs: + new_update_data["attrib"] = attribs + + if has_task_changes: + raise ValueError("Task changes of folder are not implemented") + + return _to_flat_dict(new_update_data) + + +def convert_update_subset_to_v4(project_name, subset_id, update_data, con): + new_update_data = {} + + product_attributes = con.get_attributes_for_type("product") + full_update_data = _from_flat_dict(update_data) + data = full_update_data.get("data") + new_data = {} + attribs = full_update_data.pop("attrib", {}) + if data: + if "family" in data: + family = data.pop("family") + new_update_data["productType"] = family + + if "families" in data: + families = data.pop("families") + if "productType" not in new_update_data: + new_update_data["productType"] = families[0] + + if "subsetGroup" in data: + data["productGroup"] = data.pop("subsetGroup") + for key, value in data.items(): + if key in product_attributes: + if value is REMOVED_VALUE: + value = None + attribs[key] = value + + elif value is not REMOVED_VALUE: + new_data[key] = value + + if "name" in update_data: + new_update_data["name"] = update_data["name"] + + if "type" in update_data: + new_type = update_data["type"] + if new_type == "subset": + new_update_data["active"] = True + elif new_type == "archived_subset": + new_update_data["active"] = False + + if "parent" in update_data: + new_update_data["folderId"] = update_data["parent"] + + flat_data = _to_flat_dict(new_update_data) + if attribs: + flat_data["attrib"] = attribs + + if new_data: + print("Subset has new data: {}".format(new_data)) + flat_data["data"] = new_data + + return flat_data + + +def convert_update_version_to_v4(project_name, version_id, update_data, con): + new_update_data = {} + + version_attributes = con.get_attributes_for_type("version") + full_update_data = _from_flat_dict(update_data) + data = full_update_data.get("data") + new_data = {} + attribs = full_update_data.pop("attrib", {}) + if data: + if "author" in data: + new_update_data["author"] = data.pop("author") + + if "thumbnail_id" in data: + new_update_data["thumbnailId"] = data.pop("thumbnail_id") + + for key, value in data.items(): + if key in version_attributes: + if value is REMOVED_VALUE: + value = None + attribs[key] = value + + elif value is not REMOVED_VALUE: + new_data[key] = value + + if "name" in update_data: + new_update_data["version"] = update_data["name"] + + if "type" in update_data: + new_type = update_data["type"] + if new_type == "version": + new_update_data["active"] = True + elif new_type == "archived_version": + new_update_data["active"] = False + + if "parent" in update_data: + new_update_data["productId"] = update_data["parent"] + + flat_data = _to_flat_dict(new_update_data) + if attribs: + flat_data["attrib"] = attribs + + if new_data: + print("Version has new data: {}".format(new_data)) + flat_data["data"] = new_data + return flat_data + + +def convert_update_hero_version_to_v4( + project_name, hero_version_id, update_data, con +): + if "version_id" not in update_data: + return None + + version_id = update_data["version_id"] + hero_version = con.get_hero_version_by_id(project_name, hero_version_id) + version = con.get_version_by_id(project_name, version_id) + version["version"] = - version["version"] + version["id"] = hero_version_id + + for auto_key in ( + "name", + "createdAt", + "updatedAt", + "author", + ): + version.pop(auto_key, None) + + return prepare_entity_changes(hero_version, version) + + +def convert_update_representation_to_v4( + project_name, repre_id, update_data, con +): + new_update_data = {} + + folder_attributes = con.get_attributes_for_type("folder") + full_update_data = _from_flat_dict(update_data) + data = full_update_data.get("data") + + new_data = {} + attribs = full_update_data.pop("attrib", {}) + if data: + for key, value in data.items(): + if key in folder_attributes: + attribs[key] = value + else: + new_data[key] = value + + if "template" in attribs: + attribs["template"] = ( + attribs["template"] + .replace("{family}", "{product[type]}") + .replace("{subset}", "{product[name]}") + ) + + if "name" in update_data: + new_update_data["name"] = update_data["name"] + + if "type" in update_data: + new_type = update_data["type"] + if new_type == "representation": + new_update_data["active"] = True + elif new_type == "archived_representation": + new_update_data["active"] = False + + if "parent" in update_data: + new_update_data["versionId"] = update_data["parent"] + + if "context" in update_data: + context = update_data["context"] + if "folder" not in context and "asset" in context: + context["folder"] = {"name": context.pop("asset")} + + if "family" in context or "subset" in context: + context["product"] = { + "name": context.pop("subset"), + "type": context.pop("family"), + } + new_data["context"] = context + + if "files" in update_data: + new_files = update_data["files"] + if isinstance(new_files, dict): + new_files = list(new_files.values()) + + for item in new_files: + for key in tuple(item.keys()): + if key not in ("hash", "path", "size"): + item.pop(key) + item.update({ + "id": create_entity_id(), + "name": os.path.basename(item["path"]), + "hash_type": "op3", + }) + new_update_data["files"] = new_files + + flat_data = _to_flat_dict(new_update_data) + if attribs: + flat_data["attrib"] = attribs + + if new_data: + print("Representation has new data: {}".format(new_data)) + flat_data["data"] = new_data + + return flat_data + + +def convert_update_workfile_info_to_v4( + project_name, workfile_id, update_data, con +): + return { + key: value + for key, value in update_data.items() + if key.startswith("data") + } diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py new file mode 100644 index 0000000000..75b5dc2cdd --- /dev/null +++ b/openpype/client/server/entities.py @@ -0,0 +1,725 @@ +import collections + +from openpype.client.mongo.operations import CURRENT_THUMBNAIL_SCHEMA + +from .utils import get_ayon_server_api_connection +from .openpype_comp import get_folders_with_tasks +from .conversion_utils import ( + project_fields_v3_to_v4, + convert_v4_project_to_v3, + + folder_fields_v3_to_v4, + convert_v4_folder_to_v3, + + subset_fields_v3_to_v4, + convert_v4_subset_to_v3, + + version_fields_v3_to_v4, + convert_v4_version_to_v3, + + representation_fields_v3_to_v4, + convert_v4_representation_to_v3, + + workfile_info_fields_v3_to_v4, + convert_v4_workfile_info_to_v3, +) + + +def get_projects(active=True, inactive=False, library=None, fields=None): + if not active and not inactive: + return + + if active and inactive: + active = None + elif active: + active = True + elif inactive: + active = False + + con = get_ayon_server_api_connection() + fields = project_fields_v3_to_v4(fields, con) + for project in con.get_projects(active, library, fields=fields): + yield convert_v4_project_to_v3(project) + + +def get_project(project_name, active=True, inactive=False, fields=None): + # Skip if both are disabled + con = get_ayon_server_api_connection() + fields = project_fields_v3_to_v4(fields, con) + return convert_v4_project_to_v3( + con.get_project(project_name, fields=fields) + ) + + +def get_whole_project(*args, **kwargs): + raise NotImplementedError("'get_whole_project' not implemented") + + +def _get_subsets( + project_name, + subset_ids=None, + subset_names=None, + folder_ids=None, + names_by_folder_ids=None, + archived=False, + fields=None +): + # Convert fields and add minimum required fields + con = get_ayon_server_api_connection() + fields = subset_fields_v3_to_v4(fields, con) + if fields is not None: + for key in ( + "id", + "active" + ): + fields.add(key) + + active = True + if archived: + active = None + + for subset in con.get_products( + project_name, + product_ids=subset_ids, + product_names=subset_names, + folder_ids=folder_ids, + names_by_folder_ids=names_by_folder_ids, + active=active, + fields=fields, + ): + yield convert_v4_subset_to_v3(subset) + + +def _get_versions( + project_name, + version_ids=None, + subset_ids=None, + versions=None, + hero=True, + standard=True, + latest=None, + active=None, + fields=None +): + con = get_ayon_server_api_connection() + + fields = version_fields_v3_to_v4(fields, con) + + # Make sure 'productId' and 'version' are available when hero versions + # are queried + if fields and hero: + fields = set(fields) + fields |= {"productId", "version"} + + queried_versions = con.get_versions( + project_name, + version_ids=version_ids, + product_ids=subset_ids, + versions=versions, + hero=hero, + standard=standard, + latest=latest, + active=active, + fields=fields + ) + + version_entities = [] + hero_versions = [] + for version in queried_versions: + if version["version"] < 0: + hero_versions.append(version) + else: + version_entities.append(convert_v4_version_to_v3(version)) + + if hero_versions: + subset_ids = set() + versions_nums = set() + for hero_version in hero_versions: + versions_nums.add(abs(hero_version["version"])) + subset_ids.add(hero_version["productId"]) + + hero_eq_versions = con.get_versions( + project_name, + product_ids=subset_ids, + versions=versions_nums, + hero=False, + fields=["id", "version", "productId"] + ) + hero_eq_by_subset_id = collections.defaultdict(list) + for version in hero_eq_versions: + hero_eq_by_subset_id[version["productId"]].append(version) + + for hero_version in hero_versions: + abs_version = abs(hero_version["version"]) + subset_id = hero_version["productId"] + version_id = None + for version in hero_eq_by_subset_id.get(subset_id, []): + if version["version"] == abs_version: + version_id = version["id"] + break + conv_hero = convert_v4_version_to_v3(hero_version) + conv_hero["version_id"] = version_id + version_entities.append(conv_hero) + + return version_entities + + +def get_asset_by_id(project_name, asset_id, fields=None): + assets = get_assets( + project_name, asset_ids=[asset_id], fields=fields + ) + for asset in assets: + return asset + return None + + +def get_asset_by_name(project_name, asset_name, fields=None): + assets = get_assets( + project_name, asset_names=[asset_name], fields=fields + ) + for asset in assets: + return asset + return None + + +def _folders_query(project_name, con, fields, **kwargs): + if fields is None or "tasks" in fields: + folders = get_folders_with_tasks( + con, project_name, fields=fields, **kwargs + ) + + else: + folders = con.get_folders(project_name, fields=fields, **kwargs) + + for folder in folders: + yield folder + + +def get_assets( + project_name, + asset_ids=None, + asset_names=None, + parent_ids=None, + archived=False, + fields=None +): + if not project_name: + return + + active = True + if archived: + active = None + + con = get_ayon_server_api_connection() + fields = folder_fields_v3_to_v4(fields, con) + kwargs = dict( + folder_ids=asset_ids, + parent_ids=parent_ids, + active=active, + ) + if not asset_names: + for folder in _folders_query(project_name, con, fields, **kwargs): + yield convert_v4_folder_to_v3(folder, project_name) + return + + new_asset_names = set() + folder_paths = set() + for name in asset_names: + if "/" in name: + folder_paths.add(name) + else: + new_asset_names.add(name) + + yielded_ids = set() + if folder_paths: + for folder in _folders_query( + project_name, con, fields, folder_paths=folder_paths, **kwargs + ): + yielded_ids.add(folder["id"]) + yield convert_v4_folder_to_v3(folder, project_name) + + if not new_asset_names: + return + + for folder in _folders_query( + project_name, con, fields, folder_names=new_asset_names, **kwargs + ): + if folder["id"] not in yielded_ids: + yielded_ids.add(folder["id"]) + yield convert_v4_folder_to_v3(folder, project_name) + + +def get_archived_assets( + project_name, + asset_ids=None, + asset_names=None, + parent_ids=None, + fields=None +): + return get_assets( + project_name, + asset_ids, + asset_names, + parent_ids, + True, + fields + ) + + +def get_asset_ids_with_subsets(project_name, asset_ids=None): + con = get_ayon_server_api_connection() + return con.get_folder_ids_with_products(project_name, asset_ids) + + +def get_subset_by_id(project_name, subset_id, fields=None): + subsets = get_subsets( + project_name, subset_ids=[subset_id], fields=fields + ) + for subset in subsets: + return subset + return None + + +def get_subset_by_name(project_name, subset_name, asset_id, fields=None): + subsets = get_subsets( + project_name, + subset_names=[subset_name], + asset_ids=[asset_id], + fields=fields + ) + for subset in subsets: + return subset + return None + + +def get_subsets( + project_name, + subset_ids=None, + subset_names=None, + asset_ids=None, + names_by_asset_ids=None, + archived=False, + fields=None +): + return _get_subsets( + project_name, + subset_ids, + subset_names, + asset_ids, + names_by_asset_ids, + archived, + fields=fields + ) + + +def get_subset_families(project_name, subset_ids=None): + con = get_ayon_server_api_connection() + return con.get_product_type_names(project_name, subset_ids) + + +def get_version_by_id(project_name, version_id, fields=None): + versions = get_versions( + project_name, + version_ids=[version_id], + fields=fields, + hero=True + ) + for version in versions: + return version + return None + + +def get_version_by_name(project_name, version, subset_id, fields=None): + versions = get_versions( + project_name, + subset_ids=[subset_id], + versions=[version], + fields=fields + ) + for version in versions: + return version + return None + + +def get_versions( + project_name, + version_ids=None, + subset_ids=None, + versions=None, + hero=False, + fields=None +): + return _get_versions( + project_name, + version_ids, + subset_ids, + versions, + hero=hero, + standard=True, + fields=fields + ) + + +def get_hero_version_by_id(project_name, version_id, fields=None): + versions = get_hero_versions( + project_name, + version_ids=[version_id], + fields=fields + ) + for version in versions: + return version + return None + + +def get_hero_version_by_subset_id( + project_name, subset_id, fields=None +): + versions = get_hero_versions( + project_name, + subset_ids=[subset_id], + fields=fields + ) + for version in versions: + return version + return None + + +def get_hero_versions( + project_name, subset_ids=None, version_ids=None, fields=None +): + return _get_versions( + project_name, + version_ids=version_ids, + subset_ids=subset_ids, + hero=True, + standard=False, + fields=fields + ) + + +def get_last_versions(project_name, subset_ids, active=None, fields=None): + if fields: + fields = set(fields) + fields.add("parent") + + versions = _get_versions( + project_name, + subset_ids=subset_ids, + latest=True, + hero=False, + active=active, + fields=fields + ) + return { + version["parent"]: version + for version in versions + } + + +def get_last_version_by_subset_id(project_name, subset_id, fields=None): + versions = _get_versions( + project_name, + subset_ids=[subset_id], + latest=True, + hero=False, + fields=fields + ) + if not versions: + return None + return versions[0] + + +def get_last_version_by_subset_name( + project_name, + subset_name, + asset_id=None, + asset_name=None, + fields=None +): + if not asset_id and not asset_name: + return None + + if not asset_id: + asset = get_asset_by_name( + project_name, asset_name, fields=["_id"] + ) + if not asset: + return None + asset_id = asset["_id"] + + subset = get_subset_by_name( + project_name, subset_name, asset_id, fields=["_id"] + ) + if not subset: + return None + return get_last_version_by_subset_id( + project_name, subset["_id"], fields=fields + ) + + +def get_output_link_versions(project_name, version_id, fields=None): + if not version_id: + return [] + + con = get_ayon_server_api_connection() + version_links = con.get_version_links( + project_name, version_id, link_direction="out") + + version_ids = { + link["entityId"] + for link in version_links + if link["entityType"] == "version" + } + if not version_ids: + return [] + + return get_versions(project_name, version_ids=version_ids, fields=fields) + + +def version_is_latest(project_name, version_id): + con = get_ayon_server_api_connection() + return con.version_is_latest(project_name, version_id) + + +def get_representation_by_id(project_name, representation_id, fields=None): + representations = get_representations( + project_name, + representation_ids=[representation_id], + fields=fields + ) + for representation in representations: + return representation + return None + + +def get_representation_by_name( + project_name, representation_name, version_id, fields=None +): + representations = get_representations( + project_name, + representation_names=[representation_name], + version_ids=[version_id], + fields=fields + ) + for representation in representations: + return representation + return None + + +def get_representations( + project_name, + representation_ids=None, + representation_names=None, + version_ids=None, + context_filters=None, + names_by_version_ids=None, + archived=False, + standard=True, + fields=None +): + if context_filters is not None: + # TODO should we add the support? + # - there was ability to fitler using regex + raise ValueError("OP v4 can't filter by representation context.") + + if not archived and not standard: + return + + if archived and not standard: + active = False + elif not archived and standard: + active = True + else: + active = None + + con = get_ayon_server_api_connection() + fields = representation_fields_v3_to_v4(fields, con) + if fields and active is not None: + fields.add("active") + + representations = con.get_representations( + project_name, + representation_ids=representation_ids, + representation_names=representation_names, + version_ids=version_ids, + names_by_version_ids=names_by_version_ids, + active=active, + fields=fields + ) + for representation in representations: + yield convert_v4_representation_to_v3(representation) + + +def get_representation_parents(project_name, representation): + if not representation: + return None + + repre_id = representation["_id"] + parents_by_repre_id = get_representations_parents( + project_name, [representation] + ) + return parents_by_repre_id[repre_id] + + +def get_representations_parents(project_name, representations): + repre_ids = { + repre["_id"] + for repre in representations + } + con = get_ayon_server_api_connection() + parents_by_repre_id = con.get_representations_parents(project_name, + repre_ids) + folder_ids = set() + for parents in parents_by_repre_id .values(): + folder_ids.add(parents[2]["id"]) + + tasks_by_folder_id = {} + + new_parents = {} + for repre_id, parents in parents_by_repre_id .items(): + version, subset, folder, project = parents + folder_tasks = tasks_by_folder_id.get(folder["id"]) or {} + folder["tasks"] = folder_tasks + new_parents[repre_id] = ( + convert_v4_version_to_v3(version), + convert_v4_subset_to_v3(subset), + convert_v4_folder_to_v3(folder, project_name), + project + ) + return new_parents + + +def get_archived_representations( + project_name, + representation_ids=None, + representation_names=None, + version_ids=None, + context_filters=None, + names_by_version_ids=None, + fields=None +): + return get_representations( + project_name, + representation_ids=representation_ids, + representation_names=representation_names, + version_ids=version_ids, + context_filters=context_filters, + names_by_version_ids=names_by_version_ids, + archived=True, + standard=False, + fields=fields + ) + + +def get_thumbnail( + project_name, thumbnail_id, entity_type, entity_id, fields=None +): + """Receive thumbnail entity data. + + Args: + project_name (str): Name of project where to look for queried entities. + thumbnail_id (Union[str, ObjectId]): Id of thumbnail entity. + entity_type (str): Type of entity for which the thumbnail should be + received. + entity_id (str): Id of entity for which the thumbnail should be + received. + fields (Iterable[str]): Fields that should be returned. All fields are + returned if 'None' is passed. + + Returns: + None: If thumbnail with specified id was not found. + Dict: Thumbnail entity data which can be reduced to specified 'fields'. + """ + + if not thumbnail_id or not entity_type or not entity_id: + return None + + if entity_type == "asset": + entity_type = "folder" + + elif entity_type == "hero_version": + entity_type = "version" + + return { + "_id": thumbnail_id, + "type": "thumbnail", + "schema": CURRENT_THUMBNAIL_SCHEMA, + "data": { + "entity_type": entity_type, + "entity_id": entity_id + } + } + + +def get_thumbnails(project_name, thumbnail_contexts, fields=None): + """Get thumbnail entities. + + Warning: + This function is not OpenPype compatible. There is none usage of this + function in codebase so there is nothing to convert. The previous + implementation cannot be AYON compatible without entity types. + """ + + thumbnail_items = set() + for thumbnail_context in thumbnail_contexts: + thumbnail_id, entity_type, entity_id = thumbnail_context + thumbnail_item = get_thumbnail( + project_name, thumbnail_id, entity_type, entity_id + ) + if thumbnail_item: + thumbnail_items.add(thumbnail_item) + return list(thumbnail_items) + + +def get_thumbnail_id_from_source(project_name, src_type, src_id): + """Receive thumbnail id from source entity. + + Args: + project_name (str): Name of project where to look for queried entities. + src_type (str): Type of source entity ('asset', 'version'). + src_id (Union[str, ObjectId]): Id of source entity. + + Returns: + ObjectId: Thumbnail id assigned to entity. + None: If Source entity does not have any thumbnail id assigned. + """ + + if not src_type or not src_id: + return None + + if src_type == "version": + version = get_version_by_id( + project_name, src_id, fields=["data.thumbnail_id"] + ) or {} + return version.get("data", {}).get("thumbnail_id") + + if src_type == "asset": + asset = get_asset_by_id( + project_name, src_id, fields=["data.thumbnail_id"] + ) or {} + return asset.get("data", {}).get("thumbnail_id") + + return None + + +def get_workfile_info( + project_name, asset_id, task_name, filename, fields=None +): + if not asset_id or not task_name or not filename: + return None + + con = get_ayon_server_api_connection() + task = con.get_task_by_name( + project_name, asset_id, task_name, fields=["id", "name", "folderId"] + ) + if not task: + return None + + fields = workfile_info_fields_v3_to_v4(fields) + + for workfile_info in con.get_workfiles_info( + project_name, task_ids=[task["id"]], fields=fields + ): + if workfile_info["name"] == filename: + return convert_v4_workfile_info_to_v3(workfile_info, task) + return None diff --git a/openpype/client/server/entity_links.py b/openpype/client/server/entity_links.py new file mode 100644 index 0000000000..7fb9fbde6f --- /dev/null +++ b/openpype/client/server/entity_links.py @@ -0,0 +1,157 @@ +from .utils import get_ayon_server_api_connection +from .entities import get_assets, get_representation_by_id + + +def get_linked_asset_ids(project_name, asset_doc=None, asset_id=None): + """Extract linked asset ids from asset document. + + One of asset document or asset id must be passed. + + Note: + Asset links now works only from asset to assets. + + Args: + project_name (str): Project where to look for asset. + asset_doc (dict): Asset document from DB. + asset_id (str): Asset id to find its document. + + Returns: + List[Union[ObjectId, str]]: Asset ids of input links. + """ + + output = [] + if not asset_doc and not asset_id: + return output + + if not asset_id: + asset_id = asset_doc["_id"] + + con = get_ayon_server_api_connection() + links = con.get_folder_links(project_name, asset_id, link_direction="in") + return [ + link["entityId"] + for link in links + if link["entityType"] == "folder" + ] + + +def get_linked_assets( + project_name, asset_doc=None, asset_id=None, fields=None +): + """Return linked assets based on passed asset document. + + One of asset document or asset id must be passed. + + Args: + project_name (str): Name of project where to look for queried entities. + asset_doc (Dict[str, Any]): Asset document from database. + asset_id (Union[ObjectId, str]): Asset id. Can be used instead of + asset document. + fields (Iterable[str]): Fields that should be returned. All fields are + returned if 'None' is passed. + + Returns: + List[Dict[str, Any]]: Asset documents of input links for passed + asset doc. + """ + + link_ids = get_linked_asset_ids(project_name, asset_doc, asset_id) + if not link_ids: + return [] + return list(get_assets(project_name, asset_ids=link_ids, fields=fields)) + + + +def get_linked_representation_id( + project_name, repre_doc=None, repre_id=None, link_type=None, max_depth=None +): + """Returns list of linked ids of particular type (if provided). + + One of representation document or representation id must be passed. + Note: + Representation links now works only from representation through version + back to representations. + + Todos: + Missing depth query. Not sure how it did find more representations in + depth, probably links to version? + + Args: + project_name (str): Name of project where look for links. + repre_doc (Dict[str, Any]): Representation document. + repre_id (Union[ObjectId, str]): Representation id. + link_type (str): Type of link (e.g. 'reference', ...). + max_depth (int): Limit recursion level. Default: 0 + + Returns: + List[ObjectId] Linked representation ids. + """ + + if repre_doc: + repre_id = repre_doc["_id"] + + if not repre_id and not repre_doc: + return [] + + version_id = None + if repre_doc: + version_id = repre_doc.get("parent") + + if not version_id: + repre_doc = get_representation_by_id( + project_name, repre_id, fields=["parent"] + ) + if repre_doc: + version_id = repre_doc["parent"] + + if not version_id: + return [] + + if max_depth is None or max_depth == 0: + max_depth = 1 + + link_types = None + if link_type: + link_types = [link_type] + + con = get_ayon_server_api_connection() + # Store already found version ids to avoid recursion, and also to store + # output -> Don't forget to remove 'version_id' at the end!!! + linked_version_ids = {version_id} + # Each loop of depth will reset this variable + versions_to_check = {version_id} + for _ in range(max_depth): + if not versions_to_check: + break + + versions_links = con.get_versions_links( + project_name, + versions_to_check, + link_types=link_types, + link_direction="out") + + versions_to_check = set() + for links in versions_links.values(): + for link in links: + # Care only about version links + if link["entityType"] != "version": + continue + entity_id = link["entityId"] + # Skip already found linked version ids + if entity_id in linked_version_ids: + continue + linked_version_ids.add(entity_id) + versions_to_check.add(entity_id) + + linked_version_ids.remove(version_id) + if not linked_version_ids: + return [] + con = get_ayon_server_api_connection() + representations = con.get_representations( + project_name, + version_ids=linked_version_ids, + fields=["id"]) + return [ + repre["id"] + for repre in representations + ] diff --git a/openpype/client/server/openpype_comp.py b/openpype/client/server/openpype_comp.py new file mode 100644 index 0000000000..71a141e913 --- /dev/null +++ b/openpype/client/server/openpype_comp.py @@ -0,0 +1,159 @@ +import collections +import json + +import six +from ayon_api.graphql import GraphQlQuery, FIELD_VALUE, fields_to_dict + +from .constants import DEFAULT_FOLDER_FIELDS + + +def folders_tasks_graphql_query(fields): + query = GraphQlQuery("FoldersQuery") + project_name_var = query.add_variable("projectName", "String!") + folder_ids_var = query.add_variable("folderIds", "[String!]") + parent_folder_ids_var = query.add_variable("parentFolderIds", "[String!]") + folder_paths_var = query.add_variable("folderPaths", "[String!]") + folder_names_var = query.add_variable("folderNames", "[String!]") + has_products_var = query.add_variable("folderHasProducts", "Boolean!") + + project_field = query.add_field("project") + project_field.set_filter("name", project_name_var) + + folders_field = project_field.add_field_with_edges("folders") + folders_field.set_filter("ids", folder_ids_var) + folders_field.set_filter("parentIds", parent_folder_ids_var) + folders_field.set_filter("names", folder_names_var) + folders_field.set_filter("paths", folder_paths_var) + folders_field.set_filter("hasProducts", has_products_var) + + fields = set(fields) + fields.discard("tasks") + tasks_field = folders_field.add_field_with_edges("tasks") + tasks_field.add_field("name") + tasks_field.add_field("taskType") + + nested_fields = fields_to_dict(fields) + + query_queue = collections.deque() + for key, value in nested_fields.items(): + query_queue.append((key, value, folders_field)) + + while query_queue: + item = query_queue.popleft() + key, value, parent = item + field = parent.add_field(key) + if value is FIELD_VALUE: + continue + + for k, v in value.items(): + query_queue.append((k, v, field)) + return query + + +def get_folders_with_tasks( + con, + project_name, + folder_ids=None, + folder_paths=None, + folder_names=None, + parent_ids=None, + active=True, + fields=None +): + """Query folders with tasks from server. + + This is for v4 compatibility where tasks were stored on assets. This is + an inefficient way how folders and tasks are queried so it was added only + as compatibility function. + + Todos: + Folder name won't be unique identifier, so we should add folder path + filtering. + + Notes: + Filter 'active' don't have direct filter in GraphQl. + + Args: + con (ServerAPI): Connection to server. + project_name (str): Name of project where folders are. + folder_ids (Iterable[str]): Folder ids to filter. + folder_paths (Iterable[str]): Folder paths used for filtering. + folder_names (Iterable[str]): Folder names used for filtering. + parent_ids (Iterable[str]): Ids of folder parents. Use 'None' + if folder is direct child of project. + active (Union[bool, None]): Filter active/inactive folders. Both + are returned if is set to None. + fields (Union[Iterable(str), None]): Fields to be queried + for folder. All possible folder fields are returned if 'None' + is passed. + + Yields: + Dict[str, Any]: Queried folder entities. + """ + + if not project_name: + return + + filters = { + "projectName": project_name + } + if folder_ids is not None: + folder_ids = set(folder_ids) + if not folder_ids: + return + filters["folderIds"] = list(folder_ids) + + if folder_paths is not None: + folder_paths = set(folder_paths) + if not folder_paths: + return + filters["folderPaths"] = list(folder_paths) + + if folder_names is not None: + folder_names = set(folder_names) + if not folder_names: + return + filters["folderNames"] = list(folder_names) + + if parent_ids is not None: + parent_ids = set(parent_ids) + if not parent_ids: + return + if None in parent_ids: + # Replace 'None' with '"root"' which is used during GraphQl + # query for parent ids filter for folders without folder + # parent + parent_ids.remove(None) + parent_ids.add("root") + + if project_name in parent_ids: + # Replace project name with '"root"' which is used during + # GraphQl query for parent ids filter for folders without + # folder parent + parent_ids.remove(project_name) + parent_ids.add("root") + + filters["parentFolderIds"] = list(parent_ids) + + if fields: + fields = set(fields) + else: + fields = con.get_default_fields_for_type("folder") + fields |= DEFAULT_FOLDER_FIELDS + + if active is not None: + fields.add("active") + + query = folders_tasks_graphql_query(fields) + for attr, filter_value in filters.items(): + query.set_variable_value(attr, filter_value) + + parsed_data = query.query(con) + folders = parsed_data["project"]["folders"] + for folder in folders: + if active is not None and folder["active"] is not active: + continue + folder_data = folder.get("data") + if isinstance(folder_data, six.string_types): + folder["data"] = json.loads(folder_data) + yield folder diff --git a/openpype/client/server/operations.py b/openpype/client/server/operations.py new file mode 100644 index 0000000000..eddc1eaf60 --- /dev/null +++ b/openpype/client/server/operations.py @@ -0,0 +1,880 @@ +import copy +import json +import collections +import uuid +import datetime + +from bson.objectid import ObjectId + +from openpype.client.operations_base import ( + REMOVED_VALUE, + CreateOperation, + UpdateOperation, + DeleteOperation, + BaseOperationsSession +) + +from openpype.client.mongo.operations import ( + CURRENT_THUMBNAIL_SCHEMA, + CURRENT_REPRESENTATION_SCHEMA, + CURRENT_HERO_VERSION_SCHEMA, + CURRENT_VERSION_SCHEMA, + CURRENT_SUBSET_SCHEMA, + CURRENT_ASSET_DOC_SCHEMA, + CURRENT_PROJECT_SCHEMA, +) + +from .conversion_utils import ( + convert_create_asset_to_v4, + convert_create_task_to_v4, + convert_create_subset_to_v4, + convert_create_version_to_v4, + convert_create_hero_version_to_v4, + convert_create_representation_to_v4, + convert_create_workfile_info_to_v4, + + convert_update_folder_to_v4, + convert_update_subset_to_v4, + convert_update_version_to_v4, + convert_update_hero_version_to_v4, + convert_update_representation_to_v4, + convert_update_workfile_info_to_v4, +) +from .utils import create_entity_id, get_ayon_server_api_connection + + +def _create_or_convert_to_id(entity_id=None): + if entity_id is None: + return create_entity_id() + + if isinstance(entity_id, ObjectId): + raise TypeError("Type of 'ObjectId' is not supported anymore.") + + # Validate if can be converted to uuid + uuid.UUID(entity_id) + return entity_id + + +def new_project_document( + project_name, project_code, config, data=None, entity_id=None +): + """Create skeleton data of project document. + + Args: + project_name (str): Name of project. Used as identifier of a project. + project_code (str): Shorter version of projet without spaces and + special characters (in most of cases). Should be also considered + as unique name across projects. + config (Dic[str, Any]): Project config consist of roots, templates, + applications and other project Anatomy related data. + data (Dict[str, Any]): Project data with information about it's + attributes (e.g. 'fps' etc.) or integration specific keys. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of project document. + """ + + if data is None: + data = {} + + data["code"] = project_code + + return { + "_id": _create_or_convert_to_id(entity_id), + "name": project_name, + "type": CURRENT_PROJECT_SCHEMA, + "entity_data": data, + "config": config + } + + +def new_asset_document( + name, project_id, parent_id, parents, data=None, entity_id=None +): + """Create skeleton data of asset document. + + Args: + name (str): Is considered as unique identifier of asset in project. + project_id (Union[str, ObjectId]): Id of project doument. + parent_id (Union[str, ObjectId]): Id of parent asset. + parents (List[str]): List of parent assets names. + data (Dict[str, Any]): Asset document data. Empty dictionary is used + if not passed. Value of 'parent_id' is used to fill 'visualParent'. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of asset document. + """ + + if data is None: + data = {} + if parent_id is not None: + parent_id = _create_or_convert_to_id(parent_id) + data["visualParent"] = parent_id + data["parents"] = parents + + return { + "_id": _create_or_convert_to_id(entity_id), + "type": "asset", + "name": name, + # This will be ignored + "parent": project_id, + "data": data, + "schema": CURRENT_ASSET_DOC_SCHEMA + } + + +def new_subset_document(name, family, asset_id, data=None, entity_id=None): + """Create skeleton data of subset document. + + Args: + name (str): Is considered as unique identifier of subset under asset. + family (str): Subset's family. + asset_id (Union[str, ObjectId]): Id of parent asset. + data (Dict[str, Any]): Subset document data. Empty dictionary is used + if not passed. Value of 'family' is used to fill 'family'. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of subset document. + """ + + if data is None: + data = {} + data["family"] = family + return { + "_id": _create_or_convert_to_id(entity_id), + "schema": CURRENT_SUBSET_SCHEMA, + "type": "subset", + "name": name, + "data": data, + "parent": _create_or_convert_to_id(asset_id) + } + + +def new_version_doc(version, subset_id, data=None, entity_id=None): + """Create skeleton data of version document. + + Args: + version (int): Is considered as unique identifier of version + under subset. + subset_id (Union[str, ObjectId]): Id of parent subset. + data (Dict[str, Any]): Version document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of version document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_id(entity_id), + "schema": CURRENT_VERSION_SCHEMA, + "type": "version", + "name": int(version), + "parent": _create_or_convert_to_id(subset_id), + "data": data + } + + +def new_hero_version_doc(subset_id, data, version=None, entity_id=None): + """Create skeleton data of hero version document. + + Args: + subset_id (Union[str, ObjectId]): Id of parent subset. + data (Dict[str, Any]): Version document data. + version (int): Version of source version. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of version document. + """ + + if version is None: + version = -1 + elif version > 0: + version = -version + + return { + "_id": _create_or_convert_to_id(entity_id), + "schema": CURRENT_HERO_VERSION_SCHEMA, + "type": "hero_version", + "version": version, + "parent": _create_or_convert_to_id(subset_id), + "data": data + } + + +def new_representation_doc( + name, version_id, context, data=None, entity_id=None +): + """Create skeleton data of representation document. + + Args: + name (str): Representation name considered as unique identifier + of representation under version. + version_id (Union[str, ObjectId]): Id of parent version. + context (Dict[str, Any]): Representation context used for fill template + of to query. + data (Dict[str, Any]): Representation document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of version document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_id(entity_id), + "schema": CURRENT_REPRESENTATION_SCHEMA, + "type": "representation", + "parent": _create_or_convert_to_id(version_id), + "name": name, + "data": data, + + # Imprint shortcut to context for performance reasons. + "context": context + } + + +def new_thumbnail_doc(data=None, entity_id=None): + """Create skeleton data of thumbnail document. + + Args: + data (Dict[str, Any]): Thumbnail document data. + entity_id (Union[str, ObjectId]): Predefined id of document. New id is + created if not passed. + + Returns: + Dict[str, Any]: Skeleton of thumbnail document. + """ + + if data is None: + data = {} + + return { + "_id": _create_or_convert_to_id(entity_id), + "type": "thumbnail", + "schema": CURRENT_THUMBNAIL_SCHEMA, + "data": data + } + + +def new_workfile_info_doc( + filename, asset_id, task_name, files, data=None, entity_id=None +): + """Create skeleton data of workfile info document. + + Workfile document is at this moment used primarily for artist notes. + + Args: + filename (str): Filename of workfile. + asset_id (Union[str, ObjectId]): Id of asset under which workfile live. + task_name (str): Task under which was workfile created. + files (List[str]): List of rootless filepaths related to workfile. + data (Dict[str, Any]): Additional metadata. + + Returns: + Dict[str, Any]: Skeleton of workfile info document. + """ + + if not data: + data = {} + + return { + "_id": _create_or_convert_to_id(entity_id), + "type": "workfile", + "parent": _create_or_convert_to_id(asset_id), + "task_name": task_name, + "filename": filename, + "data": data, + "files": files + } + + +def _prepare_update_data(old_doc, new_doc, replace): + changes = {} + for key, value in new_doc.items(): + if key not in old_doc or value != old_doc[key]: + changes[key] = value + + if replace: + for key in old_doc.keys(): + if key not in new_doc: + changes[key] = REMOVED_VALUE + return changes + + +def prepare_subset_update_data(old_doc, new_doc, replace=True): + """Compare two subset documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +def prepare_version_update_data(old_doc, new_doc, replace=True): + """Compare two version documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +def prepare_hero_version_update_data(old_doc, new_doc, replace=True): + """Compare two hero version documents and prepare update data. + + Based on compared values will create update data for 'UpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + changes = _prepare_update_data(old_doc, new_doc, replace) + changes.pop("version_id", None) + return changes + + +def prepare_representation_update_data(old_doc, new_doc, replace=True): + """Compare two representation documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + changes = _prepare_update_data(old_doc, new_doc, replace) + context = changes.get("data", {}).get("context") + # Make sure that both 'family' and 'subset' are in changes if + # one of them changed (they'll both become 'product'). + if ( + context + and ("family" in context or "subset" in context) + ): + context["family"] = new_doc["data"]["context"]["family"] + context["subset"] = new_doc["data"]["context"]["subset"] + + return changes + + +def prepare_workfile_info_update_data(old_doc, new_doc, replace=True): + """Compare two workfile info documents and prepare update data. + + Based on compared values will create update data for + 'MongoUpdateOperation'. + + Empty output means that documents are identical. + + Returns: + Dict[str, Any]: Changes between old and new document. + """ + + return _prepare_update_data(old_doc, new_doc, replace) + + +class FailedOperations(Exception): + pass + + +def entity_data_json_default(value): + if isinstance(value, datetime.datetime): + return int(value.timestamp()) + + raise TypeError( + "Object of type {} is not JSON serializable".format(str(type(value))) + ) + + +def failed_json_default(value): + return "< Failed value {} > {}".format(type(value), str(value)) + + +class ServerCreateOperation(CreateOperation): + """Operation to create an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + data (Dict[str, Any]): Data of entity that will be created. + """ + + def __init__(self, project_name, entity_type, data, session): + self._session = session + + if not data: + data = {} + data = copy.deepcopy(data) + if entity_type == "project": + raise ValueError("Project cannot be created using operations") + + tasks = None + if entity_type in "asset": + # TODO handle tasks + entity_type = "folder" + if "data" in data: + tasks = data["data"].get("tasks") + + project = self._session.get_project(project_name) + new_data = convert_create_asset_to_v4(data, project, self.con) + + elif entity_type == "task": + project = self._session.get_project(project_name) + new_data = convert_create_task_to_v4(data, project, self.con) + + elif entity_type == "subset": + new_data = convert_create_subset_to_v4(data, self.con) + entity_type = "product" + + elif entity_type == "version": + new_data = convert_create_version_to_v4(data, self.con) + + elif entity_type == "hero_version": + new_data = convert_create_hero_version_to_v4( + data, project_name, self.con + ) + entity_type = "version" + + elif entity_type in ("representation", "archived_representation"): + new_data = convert_create_representation_to_v4(data, self.con) + entity_type = "representation" + + elif entity_type == "workfile": + new_data = convert_create_workfile_info_to_v4( + data, project_name, self.con + ) + + else: + raise ValueError( + "Unhandled entity type \"{}\"".format(entity_type) + ) + + # Simple check if data can be dumped into json + # - should raise error on 'ObjectId' object + try: + new_data = json.loads( + json.dumps(new_data, default=entity_data_json_default) + ) + + except: + raise ValueError("Couldn't json parse body: {}".format( + json.dumps(new_data, default=failed_json_default) + )) + + super(ServerCreateOperation, self).__init__( + project_name, entity_type, new_data + ) + + if "id" not in self._data: + self._data["id"] = create_entity_id() + + if tasks: + copied_tasks = copy.deepcopy(tasks) + for task_name, task in copied_tasks.items(): + task["name"] = task_name + task["folderId"] = self._data["id"] + self.session.create_entity( + project_name, "task", task, nested_id=self.id + ) + + @property + def con(self): + return self.session.con + + @property + def session(self): + return self._session + + @property + def entity_id(self): + return self._data["id"] + + def to_server_operation(self): + return { + "id": self.id, + "type": "create", + "entityType": self.entity_type, + "entityId": self.entity_id, + "data": self._data + } + + +class ServerUpdateOperation(UpdateOperation): + """Operation to update an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + entity_id (Union[str, ObjectId]): Identifier of an entity. + update_data (Dict[str, Any]): Key -> value changes that will be set in + database. If value is set to 'REMOVED_VALUE' the key will be + removed. Only first level of dictionary is checked (on purpose). + """ + + def __init__( + self, project_name, entity_type, entity_id, update_data, session + ): + self._session = session + + update_data = copy.deepcopy(update_data) + if entity_type == "project": + raise ValueError("Project cannot be created using operations") + + if entity_type in ("asset", "archived_asset"): + new_update_data = convert_update_folder_to_v4( + project_name, entity_id, update_data, self.con + ) + entity_type = "folder" + + elif entity_type == "subset": + new_update_data = convert_update_subset_to_v4( + project_name, entity_id, update_data, self.con + ) + entity_type = "product" + + elif entity_type == "version": + new_update_data = convert_update_version_to_v4( + project_name, entity_id, update_data, self.con + ) + + elif entity_type == "hero_version": + new_update_data = convert_update_hero_version_to_v4( + project_name, entity_id, update_data, self.con + ) + entity_type = "version" + + elif entity_type in ("representation", "archived_representation"): + new_update_data = convert_update_representation_to_v4( + project_name, entity_id, update_data, self.con + ) + entity_type = "representation" + + elif entity_type == "workfile": + new_update_data = convert_update_workfile_info_to_v4( + project_name, entity_id, update_data, self.con + ) + + else: + raise ValueError( + "Unhandled entity type \"{}\"".format(entity_type) + ) + + try: + new_update_data = json.loads( + json.dumps(new_update_data, default=entity_data_json_default) + ) + + except: + raise ValueError("Couldn't json parse body: {}".format( + json.dumps(new_update_data, default=failed_json_default) + )) + + super(ServerUpdateOperation, self).__init__( + project_name, entity_type, entity_id, new_update_data + ) + + @property + def con(self): + return self.session.con + + @property + def session(self): + return self._session + + def to_server_operation(self): + if not self._update_data: + return None + + update_data = {} + for key, value in self._update_data.items(): + if value is REMOVED_VALUE: + value = None + update_data[key] = value + + return { + "id": self.id, + "type": "update", + "entityType": self.entity_type, + "entityId": self.entity_id, + "data": update_data + } + + +class ServerDeleteOperation(DeleteOperation): + """Operation to delete an entity. + + Args: + project_name (str): On which project operation will happen. + entity_type (str): Type of entity on which change happens. + e.g. 'asset', 'representation' etc. + entity_id (Union[str, ObjectId]): Entity id that will be removed. + """ + + def __init__(self, project_name, entity_type, entity_id, session): + self._session = session + + if entity_type == "asset": + entity_type = "folder" + + elif entity_type == "hero_version": + entity_type = "version" + + elif entity_type == "subset": + entity_type = "product" + + super(ServerDeleteOperation, self).__init__( + project_name, entity_type, entity_id + ) + + @property + def con(self): + return self.session.con + + @property + def session(self): + return self._session + + def to_server_operation(self): + return { + "id": self.id, + "type": self.operation_name, + "entityId": self.entity_id, + "entityType": self.entity_type, + } + + +class OperationsSession(BaseOperationsSession): + def __init__(self, con=None, *args, **kwargs): + super(OperationsSession, self).__init__(*args, **kwargs) + if con is None: + con = get_ayon_server_api_connection() + self._con = con + self._project_cache = {} + self._nested_operations = collections.defaultdict(list) + + @property + def con(self): + return self._con + + def get_project(self, project_name): + if project_name not in self._project_cache: + self._project_cache[project_name] = self.con.get_project( + project_name) + return copy.deepcopy(self._project_cache[project_name]) + + def commit(self): + """Commit session operations.""" + + operations, self._operations = self._operations, [] + if not operations: + return + + operations_by_project = collections.defaultdict(list) + for operation in operations: + operations_by_project[operation.project_name].append(operation) + + body_by_id = {} + results = [] + for project_name, operations in operations_by_project.items(): + operations_body = [] + for operation in operations: + body = operation.to_server_operation() + if body is not None: + try: + json.dumps(body) + except: + raise ValueError("Couldn't json parse body: {}".format( + json.dumps( + body, indent=4, default=failed_json_default + ) + )) + + body_by_id[operation.id] = body + operations_body.append(body) + + if operations_body: + result = self._con.post( + "projects/{}/operations".format(project_name), + operations=operations_body, + canFail=False + ) + results.append(result.data) + + for result in results: + if result.get("success"): + continue + + if "operations" not in result: + raise FailedOperations( + "Operation failed. Content: {}".format(str(result)) + ) + + for op_result in result["operations"]: + if not op_result["success"]: + operation_id = op_result["id"] + raise FailedOperations(( + "Operation \"{}\" failed with data:\n{}\nError: {}." + ).format( + operation_id, + json.dumps(body_by_id[operation_id], indent=4), + op_result.get("error", "unknown"), + )) + + def create_entity(self, project_name, entity_type, data, nested_id=None): + """Fast access to 'ServerCreateOperation'. + + Args: + project_name (str): On which project the creation happens. + entity_type (str): Which entity type will be created. + data (Dicst[str, Any]): Entity data. + nested_id (str): Id of other operation from which is triggered + operation -> Operations can trigger suboperations but they + must be added to operations list after it's parent is added. + + Returns: + ServerCreateOperation: Object of update operation. + """ + + operation = ServerCreateOperation( + project_name, entity_type, data, self + ) + + if nested_id: + self._nested_operations[nested_id].append(operation) + else: + self.add(operation) + if operation.id in self._nested_operations: + self.extend(self._nested_operations.pop(operation.id)) + + return operation + + def update_entity( + self, project_name, entity_type, entity_id, update_data, nested_id=None + ): + """Fast access to 'ServerUpdateOperation'. + + Returns: + ServerUpdateOperation: Object of update operation. + """ + + operation = ServerUpdateOperation( + project_name, entity_type, entity_id, update_data, self + ) + if nested_id: + self._nested_operations[nested_id].append(operation) + else: + self.add(operation) + if operation.id in self._nested_operations: + self.extend(self._nested_operations.pop(operation.id)) + return operation + + def delete_entity( + self, project_name, entity_type, entity_id, nested_id=None + ): + """Fast access to 'ServerDeleteOperation'. + + Returns: + ServerDeleteOperation: Object of delete operation. + """ + + operation = ServerDeleteOperation( + project_name, entity_type, entity_id, self + ) + if nested_id: + self._nested_operations[nested_id].append(operation) + else: + self.add(operation) + if operation.id in self._nested_operations: + self.extend(self._nested_operations.pop(operation.id)) + return operation + + +def create_project( + project_name, + project_code, + library_project=False, + preset_name=None, + con=None +): + """Create project using OpenPype settings. + + This project creation function is not validating project document on + creation. It is because project document is created blindly with only + minimum required information about project which is it's name, code, type + and schema. + + Entered project name must be unique and project must not exist yet. + + Note: + This function is here to be OP v4 ready but in v3 has more logic + to do. That's why inner imports are in the body. + + Args: + project_name (str): New project name. Should be unique. + project_code (str): Project's code should be unique too. + library_project (bool): Project is library project. + preset_name (str): Name of anatomy preset. Default is used if not + passed. + con (ServerAPI): Connection to server with logged user. + + Raises: + ValueError: When project name already exists in MongoDB. + + Returns: + dict: Created project document. + """ + + if con is None: + con = get_ayon_server_api_connection() + + return con.create_project( + project_name, + project_code, + library_project, + preset_name + ) + + +def delete_project(project_name, con=None): + if con is None: + con = get_ayon_server_api_connection() + + return con.delete_project(project_name) + + +def create_thumbnail(project_name, src_filepath, thumbnail_id=None, con=None): + if con is None: + con = get_ayon_server_api_connection() + return con.create_thumbnail(project_name, src_filepath, thumbnail_id) diff --git a/openpype/client/server/thumbnails.py b/openpype/client/server/thumbnails.py new file mode 100644 index 0000000000..dc649b9651 --- /dev/null +++ b/openpype/client/server/thumbnails.py @@ -0,0 +1,229 @@ +"""Cache of thumbnails downloaded from AYON server. + +Thumbnails are cached to appdirs to predefined directory. + +This should be moved to thumbnails logic in pipeline but because it would +overflow OpenPype logic it's here for now. +""" + +import os +import time +import collections + +import appdirs + +FileInfo = collections.namedtuple( + "FileInfo", + ("path", "size", "modification_time") +) + + +class AYONThumbnailCache: + """Cache of thumbnails on local storage. + + Thumbnails are cached to appdirs to predefined directory. Each project has + own subfolder with thumbnails -> that's because each project has own + thumbnail id validation and file names are thumbnail ids with matching + extension. Extensions are predefined (.png and .jpeg). + + Cache has cleanup mechanism which is triggered on initialized by default. + + The cleanup has 2 levels: + 1. soft cleanup which remove all files that are older then 'days_alive' + 2. max size cleanup which remove all files until the thumbnails folder + contains less then 'max_filesize' + - this is time consuming so it's not triggered automatically + + Args: + cleanup (bool): Trigger soft cleanup (Cleanup expired thumbnails). + """ + + # Lifetime of thumbnails (in seconds) + # - default 3 days + days_alive = 3 + # Max size of thumbnail directory (in bytes) + # - default 2 Gb + max_filesize = 2 * 1024 * 1024 * 1024 + + def __init__(self, cleanup=True): + self._thumbnails_dir = None + self._days_alive_secs = self.days_alive * 24 * 60 * 60 + if cleanup: + self.cleanup() + + def get_thumbnails_dir(self): + """Root directory where thumbnails are stored. + + Returns: + str: Path to thumbnails root. + """ + + if self._thumbnails_dir is None: + # TODO use generic function + directory = appdirs.user_data_dir("AYON", "Ynput") + self._thumbnails_dir = os.path.join(directory, "thumbnails") + return self._thumbnails_dir + + thumbnails_dir = property(get_thumbnails_dir) + + def get_thumbnails_dir_file_info(self): + """Get information about all files in thumbnails directory. + + Returns: + List[FileInfo]: List of file information about all files. + """ + + thumbnails_dir = self.thumbnails_dir + files_info = [] + if not os.path.exists(thumbnails_dir): + return files_info + + for root, _, filenames in os.walk(thumbnails_dir): + for filename in filenames: + path = os.path.join(root, filename) + files_info.append(FileInfo( + path, os.path.getsize(path), os.path.getmtime(path) + )) + return files_info + + def get_thumbnails_dir_size(self, files_info=None): + """Got full size of thumbnail directory. + + Args: + files_info (List[FileInfo]): Prepared file information about + files in thumbnail directory. + + Returns: + int: File size of all files in thumbnail directory. + """ + + if files_info is None: + files_info = self.get_thumbnails_dir_file_info() + + if not files_info: + return 0 + + return sum( + file_info.size + for file_info in files_info + ) + + def cleanup(self, check_max_size=False): + """Cleanup thumbnails directory. + + Args: + check_max_size (bool): Also cleanup files to match max size of + thumbnails directory. + """ + + thumbnails_dir = self.get_thumbnails_dir() + # Skip if thumbnails dir does not exists yet + if not os.path.exists(thumbnails_dir): + return + + self._soft_cleanup(thumbnails_dir) + if check_max_size: + self._max_size_cleanup(thumbnails_dir) + + def _soft_cleanup(self, thumbnails_dir): + current_time = time.time() + for root, _, filenames in os.walk(thumbnails_dir): + for filename in filenames: + path = os.path.join(root, filename) + modification_time = os.path.getmtime(path) + if current_time - modification_time > self._days_alive_secs: + os.remove(path) + + def _max_size_cleanup(self, thumbnails_dir): + files_info = self.get_thumbnails_dir_file_info() + size = self.get_thumbnails_dir_size(files_info) + if size < self.max_filesize: + return + + sorted_file_info = collections.deque( + sorted(files_info, key=lambda item: item.modification_time) + ) + diff = size - self.max_filesize + while diff > 0: + if not sorted_file_info: + break + + file_info = sorted_file_info.popleft() + diff -= file_info.size + os.remove(file_info.path) + + def get_thumbnail_filepath(self, project_name, thumbnail_id): + """Get thumbnail by thumbnail id. + + Args: + project_name (str): Name of project. + thumbnail_id (str): Thumbnail id. + + Returns: + Union[str, None]: Path to thumbnail image or None if thumbnail + is not cached yet. + """ + + if not thumbnail_id: + return None + + for ext in ( + ".png", + ".jpeg", + ): + filepath = os.path.join( + self.thumbnails_dir, project_name, thumbnail_id + ext + ) + if os.path.exists(filepath): + return filepath + return None + + def get_project_dir(self, project_name): + """Path to root directory for specific project. + + Args: + project_name (str): Name of project for which root directory path + should be returned. + + Returns: + str: Path to root of project's thumbnails. + """ + + return os.path.join(self.thumbnails_dir, project_name) + + def make_sure_project_dir_exists(self, project_name): + project_dir = self.get_project_dir(project_name) + if not os.path.exists(project_dir): + os.makedirs(project_dir) + return project_dir + + def store_thumbnail(self, project_name, thumbnail_id, content, mime_type): + """Store thumbnail to cache folder. + + Args: + project_name (str): Project where the thumbnail belong to. + thumbnail_id (str): Id of thumbnail. + content (bytes): Byte content of thumbnail file. + mime_data (str): Type of content. + + Returns: + str: Path to cached thumbnail image file. + """ + + if mime_type == "image/png": + ext = ".png" + elif mime_type == "image/jpeg": + ext = ".jpeg" + else: + raise ValueError( + "Unknown mime type for thumbnail \"{}\"".format(mime_type)) + + project_dir = self.make_sure_project_dir_exists(project_name) + thumbnail_path = os.path.join(project_dir, thumbnail_id + ext) + with open(thumbnail_path, "wb") as stream: + stream.write(content) + + current_time = time.time() + os.utime(thumbnail_path, (current_time, current_time)) + + return thumbnail_path diff --git a/openpype/client/server/utils.py b/openpype/client/server/utils.py new file mode 100644 index 0000000000..a9dcf539bd --- /dev/null +++ b/openpype/client/server/utils.py @@ -0,0 +1,134 @@ +import os +import uuid + +import ayon_api + +from openpype.client.operations_base import REMOVED_VALUE + + +class _GlobalCache: + initialized = False + + +def get_ayon_server_api_connection(): + if _GlobalCache.initialized: + con = ayon_api.get_server_api_connection() + else: + from openpype.lib.local_settings import get_local_site_id + + _GlobalCache.initialized = True + site_id = get_local_site_id() + version = os.getenv("AYON_VERSION") + if ayon_api.is_connection_created(): + con = ayon_api.get_server_api_connection() + con.set_site_id(site_id) + con.set_client_version(version) + else: + con = ayon_api.create_connection(site_id, version) + return con + + +def create_entity_id(): + return uuid.uuid1().hex + + +def prepare_attribute_changes(old_entity, new_entity, replace=False): + """Prepare changes of attributes on entities. + + Compare 'attrib' of old and new entity data to prepare only changed + values that should be sent to server for update. + + Example: + >>> # Limited entity data to 'attrib' + >>> old_entity = { + ... "attrib": {"attr_1": 1, "attr_2": "MyString", "attr_3": True} + ... } + >>> new_entity = { + ... "attrib": {"attr_1": 2, "attr_3": True, "attr_4": 3} + ... } + >>> # Changes if replacement should not happen + >>> expected_changes = { + ... "attr_1": 2, + ... "attr_4": 3 + ... } + >>> changes = prepare_attribute_changes(old_entity, new_entity) + >>> changes == expected_changes + True + + >>> # Changes if replacement should happen + >>> expected_changes_replace = { + ... "attr_1": 2, + ... "attr_2": REMOVED_VALUE, + ... "attr_4": 3 + ... } + >>> changes_replace = prepare_attribute_changes( + ... old_entity, new_entity, True) + >>> changes_replace == expected_changes_replace + True + + Args: + old_entity (dict[str, Any]): Data of entity queried from server. + new_entity (dict[str, Any]): Entity data with applied changes. + replace (bool): New entity should fully replace all old entity values. + + Returns: + Dict[str, Any]: Values from new entity only if value has changed. + """ + + attrib_changes = {} + new_attrib = new_entity.get("attrib") + old_attrib = old_entity.get("attrib") + if new_attrib is None: + if not replace: + return attrib_changes + new_attrib = {} + + if old_attrib is None: + return new_attrib + + for attr, new_attr_value in new_attrib.items(): + old_attr_value = old_attrib.get(attr) + if old_attr_value != new_attr_value: + attrib_changes[attr] = new_attr_value + + if replace: + for attr in old_attrib: + if attr not in new_attrib: + attrib_changes[attr] = REMOVED_VALUE + + return attrib_changes + + +def prepare_entity_changes(old_entity, new_entity, replace=False): + """Prepare changes of AYON entities. + + Compare old and new entity to filter values from new data that changed. + + Args: + old_entity (dict[str, Any]): Data of entity queried from server. + new_entity (dict[str, Any]): Entity data with applied changes. + replace (bool): All attributes should be replaced by new values. So + all attribute values that are not on new entity will be removed. + + Returns: + Dict[str, Any]: Only values from new entity that changed. + """ + + changes = {} + for key, new_value in new_entity.items(): + if key == "attrib": + continue + + old_value = old_entity.get(key) + if old_value != new_value: + changes[key] = new_value + + if replace: + for key in old_entity: + if key not in new_entity: + changes[key] = REMOVED_VALUE + + attr_changes = prepare_attribute_changes(old_entity, new_entity, replace) + if attr_changes: + changes["attrib"] = attr_changes + return changes diff --git a/openpype/hooks/pre_add_last_workfile_arg.py b/openpype/hooks/pre_add_last_workfile_arg.py index c54acbc203..6e255ae82a 100644 --- a/openpype/hooks/pre_add_last_workfile_arg.py +++ b/openpype/hooks/pre_add_last_workfile_arg.py @@ -1,6 +1,6 @@ import os -from openpype.lib import PreLaunchHook +from openpype.lib.applications import PreLaunchHook, LaunchTypes class AddLastWorkfileToLaunchArgs(PreLaunchHook): @@ -13,8 +13,8 @@ class AddLastWorkfileToLaunchArgs(PreLaunchHook): # Execute after workfile template copy order = 10 - app_groups = [ - "3dsmax", + app_groups = { + "3dsmax", "adsk_3dsmax", "maya", "nuke", "nukex", @@ -26,8 +26,10 @@ class AddLastWorkfileToLaunchArgs(PreLaunchHook): "photoshop", "tvpaint", "substancepainter", - "aftereffects" - ] + "aftereffects", + "wrap" + } + launch_types = {LaunchTypes.local} def execute(self): if not self.data.get("start_last_workfile"): diff --git a/openpype/hooks/pre_copy_template_workfile.py b/openpype/hooks/pre_copy_template_workfile.py index 70c549919f..4d91d83c95 100644 --- a/openpype/hooks/pre_copy_template_workfile.py +++ b/openpype/hooks/pre_copy_template_workfile.py @@ -1,7 +1,7 @@ import os import shutil -from openpype.lib import PreLaunchHook from openpype.settings import get_project_settings +from openpype.lib.applications import PreLaunchHook, LaunchTypes from openpype.pipeline.workfile import ( get_custom_workfile_template, get_custom_workfile_template_by_string_context @@ -19,7 +19,9 @@ class CopyTemplateWorkfile(PreLaunchHook): # Before `AddLastWorkfileToLaunchArgs` order = 0 - app_groups = ["blender", "photoshop", "tvpaint", "aftereffects"] + app_groups = {"blender", "photoshop", "tvpaint", "aftereffects", + "wrap"} + launch_types = {LaunchTypes.local} def execute(self): """Check if can copy template for context and do it if possible. diff --git a/openpype/hooks/pre_create_extra_workdir_folders.py b/openpype/hooks/pre_create_extra_workdir_folders.py index 8856281120..4c9d08b375 100644 --- a/openpype/hooks/pre_create_extra_workdir_folders.py +++ b/openpype/hooks/pre_create_extra_workdir_folders.py @@ -1,5 +1,5 @@ import os -from openpype.lib import PreLaunchHook +from openpype.lib.applications import PreLaunchHook, LaunchTypes from openpype.pipeline.workfile import create_workdir_extra_folders @@ -14,6 +14,7 @@ class CreateWorkdirExtraFolders(PreLaunchHook): # Execute after workfile template copy order = 15 + launch_types = {LaunchTypes.local} def execute(self): if not self.application.is_host: diff --git a/openpype/hooks/pre_global_host_data.py b/openpype/hooks/pre_global_host_data.py index 8a178915fb..813df24af0 100644 --- a/openpype/hooks/pre_global_host_data.py +++ b/openpype/hooks/pre_global_host_data.py @@ -1,15 +1,16 @@ from openpype.client import get_project, get_asset_by_name -from openpype.lib import ( +from openpype.lib.applications import ( PreLaunchHook, EnvironmentPrepData, prepare_app_environments, prepare_context_environments ) -from openpype.pipeline import AvalonMongoDB, Anatomy +from openpype.pipeline import Anatomy class GlobalHostDataHook(PreLaunchHook): order = -100 + launch_types = set() def execute(self): """Prepare global objects to `data` that will be used for sure.""" @@ -26,7 +27,6 @@ class GlobalHostDataHook(PreLaunchHook): "app": app, - "dbcon": self.data["dbcon"], "project_doc": self.data["project_doc"], "asset_doc": self.data["asset_doc"], @@ -62,13 +62,6 @@ class GlobalHostDataHook(PreLaunchHook): # Anatomy self.data["anatomy"] = Anatomy(project_name) - # Mongo connection - dbcon = AvalonMongoDB() - dbcon.Session["AVALON_PROJECT"] = project_name - dbcon.install() - - self.data["dbcon"] = dbcon - # Project document project_doc = get_project(project_name) self.data["project_doc"] = project_doc diff --git a/openpype/hooks/pre_host_set_ocio.py b/openpype/hooks/pre_host_set_ocio.py deleted file mode 100644 index 3620d88db6..0000000000 --- a/openpype/hooks/pre_host_set_ocio.py +++ /dev/null @@ -1,37 +0,0 @@ -from openpype.lib import PreLaunchHook - -from openpype.pipeline.colorspace import get_imageio_config -from openpype.pipeline.template_data import get_template_data - - -class PreLaunchHostSetOCIO(PreLaunchHook): - """Set OCIO environment for the host""" - - order = 0 - app_groups = ["substancepainter"] - - def execute(self): - """Hook entry method.""" - - anatomy_data = get_template_data( - project_doc=self.data["project_doc"], - asset_doc=self.data["asset_doc"], - task_name=self.data["task_name"], - host_name=self.host_name, - system_settings=self.data["system_settings"] - ) - - ocio_config = get_imageio_config( - project_name=self.data["project_doc"]["name"], - host_name=self.host_name, - project_settings=self.data["project_settings"], - anatomy_data=anatomy_data, - anatomy=self.data["anatomy"] - ) - - if ocio_config: - ocio_path = ocio_config["path"] - self.log.info(f"Setting OCIO config path: {ocio_path}") - self.launch_context.env["OCIO"] = ocio_path - else: - self.log.debug("OCIO not set or enabled") diff --git a/openpype/hooks/pre_mac_launch.py b/openpype/hooks/pre_mac_launch.py index f85557a4f0..402e9a5517 100644 --- a/openpype/hooks/pre_mac_launch.py +++ b/openpype/hooks/pre_mac_launch.py @@ -1,5 +1,5 @@ import os -from openpype.lib import PreLaunchHook +from openpype.lib.applications import PreLaunchHook, LaunchTypes class LaunchWithTerminal(PreLaunchHook): @@ -12,7 +12,8 @@ class LaunchWithTerminal(PreLaunchHook): """ order = 1000 - platforms = ["darwin"] + platforms = {"darwin"} + launch_types = {LaunchTypes.local} def execute(self): executable = str(self.launch_context.executable) diff --git a/openpype/hooks/pre_foundry_apps.py b/openpype/hooks/pre_new_console_apps.py similarity index 71% rename from openpype/hooks/pre_foundry_apps.py rename to openpype/hooks/pre_new_console_apps.py index 21ec8e7881..9727b4fb78 100644 --- a/openpype/hooks/pre_foundry_apps.py +++ b/openpype/hooks/pre_new_console_apps.py @@ -1,8 +1,8 @@ import subprocess -from openpype.lib import PreLaunchHook +from openpype.lib.applications import PreLaunchHook, LaunchTypes -class LaunchFoundryAppsWindows(PreLaunchHook): +class LaunchNewConsoleApps(PreLaunchHook): """Foundry applications have specific way how to launch them. Nuke is executed "like" python process so it is required to pass @@ -13,12 +13,15 @@ class LaunchFoundryAppsWindows(PreLaunchHook): # Should be as last hook because must change launch arguments to string order = 1000 - app_groups = ["nuke", "nukeassist", "nukex", "hiero", "nukestudio"] - platforms = ["windows"] + app_groups = { + "nuke", "nukeassist", "nukex", "hiero", "nukestudio", "mayapy" + } + platforms = {"windows"} + launch_types = {LaunchTypes.local} def execute(self): # Change `creationflags` to CREATE_NEW_CONSOLE - # - on Windows nuke will create new window using its console + # - on Windows some apps will create new window using its console # Set `stdout` and `stderr` to None so new created console does not # have redirected output to DEVNULL in build self.launch_context.kwargs.update({ diff --git a/openpype/hooks/pre_non_python_host_launch.py b/openpype/hooks/pre_non_python_host_launch.py index 043cb3c7f6..d9e912c826 100644 --- a/openpype/hooks/pre_non_python_host_launch.py +++ b/openpype/hooks/pre_non_python_host_launch.py @@ -1,10 +1,11 @@ import os -from openpype.lib import ( +from openpype.lib import get_openpype_execute_args +from openpype.lib.applications import ( + get_non_python_host_kwargs, PreLaunchHook, - get_openpype_execute_args + LaunchTypes, ) -from openpype.lib.applications import get_non_python_host_kwargs from openpype import PACKAGE_DIR as OPENPYPE_DIR @@ -16,9 +17,10 @@ class NonPythonHostHook(PreLaunchHook): python script which launch the host. For these cases it is necessary to prepend python (or openpype) executable and script path before application's. """ - app_groups = ["harmony", "photoshop", "aftereffects"] + app_groups = {"harmony", "photoshop", "aftereffects"} order = 20 + launch_types = {LaunchTypes.local} def execute(self): # Pop executable @@ -54,4 +56,3 @@ class NonPythonHostHook(PreLaunchHook): self.launch_context.kwargs = \ get_non_python_host_kwargs(self.launch_context.kwargs) - diff --git a/openpype/hooks/pre_ocio_hook.py b/openpype/hooks/pre_ocio_hook.py new file mode 100644 index 0000000000..e695cf3fe8 --- /dev/null +++ b/openpype/hooks/pre_ocio_hook.py @@ -0,0 +1,56 @@ +from openpype.lib.applications import PreLaunchHook + +from openpype.pipeline.colorspace import get_imageio_config +from openpype.pipeline.template_data import get_template_data_with_names + + +class OCIOEnvHook(PreLaunchHook): + """Set OCIO environment variable for hosts that use OpenColorIO.""" + + order = 0 + hosts = { + "substancepainter", + "fusion", + "blender", + "aftereffects", + "3dsmax", + "houdini", + "maya", + "nuke", + "hiero", + "resolve", + } + launch_types = set() + + def execute(self): + """Hook entry method.""" + + template_data = get_template_data_with_names( + project_name=self.data["project_name"], + asset_name=self.data["asset_name"], + task_name=self.data["task_name"], + host_name=self.host_name, + system_settings=self.data["system_settings"] + ) + + config_data = get_imageio_config( + project_name=self.data["project_name"], + host_name=self.host_name, + project_settings=self.data["project_settings"], + anatomy_data=template_data, + anatomy=self.data["anatomy"], + env=self.launch_context.env, + ) + + if config_data: + ocio_path = config_data["path"] + + if self.host_name in ["nuke", "hiero"]: + ocio_path = ocio_path.replace("\\", "/") + + self.log.info( + f"Setting OCIO environment to config path: {ocio_path}") + + self.launch_context.env["OCIO"] = ocio_path + else: + self.log.debug("OCIO not set or enabled") diff --git a/openpype/host/dirmap.py b/openpype/host/dirmap.py index 42bf80ecec..96a98e808e 100644 --- a/openpype/host/dirmap.py +++ b/openpype/host/dirmap.py @@ -32,19 +32,26 @@ class HostDirmap(object): """ def __init__( - self, host_name, project_name, project_settings=None, sync_module=None + self, + host_name, + project_name, + project_settings=None, + sync_module=None ): self.host_name = host_name self.project_name = project_name self._project_settings = project_settings - self._sync_module = sync_module # to limit reinit of Modules + self._sync_module = sync_module + # to limit reinit of Modules + self._sync_module_discovered = sync_module is not None self._log = None @property def sync_module(self): - if self._sync_module is None: + if not self._sync_module_discovered: + self._sync_module_discovered = True manager = ModulesManager() - self._sync_module = manager["sync_server"] + self._sync_module = manager.get("sync_server") return self._sync_module @property @@ -149,23 +156,27 @@ class HostDirmap(object): Returns: dict : { "source-path": [XXX], "destination-path": [YYYY]} """ - project_name = os.getenv("AVALON_PROJECT") + project_name = self.project_name + sync_module = self.sync_module mapping = {} - if (not self.sync_module.enabled or - project_name not in self.sync_module.get_enabled_projects()): + if ( + sync_module is None + or not sync_module.enabled + or project_name not in sync_module.get_enabled_projects() + ): return mapping - active_site = self.sync_module.get_local_normalized_site( - self.sync_module.get_active_site(project_name)) - remote_site = self.sync_module.get_local_normalized_site( - self.sync_module.get_remote_site(project_name)) + active_site = sync_module.get_local_normalized_site( + sync_module.get_active_site(project_name)) + remote_site = sync_module.get_local_normalized_site( + sync_module.get_remote_site(project_name)) self.log.debug( "active {} - remote {}".format(active_site, remote_site) ) if active_site == "local" and active_site != remote_site: - sync_settings = self.sync_module.get_sync_project_setting( + sync_settings = sync_module.get_sync_project_setting( project_name, exclude_locals=False, cached=False) @@ -179,7 +190,7 @@ class HostDirmap(object): self.log.debug("remote overrides {}".format(remote_overrides)) current_platform = platform.system().lower() - remote_provider = self.sync_module.get_provider_for_site( + remote_provider = sync_module.get_provider_for_site( project_name, remote_site ) # dirmap has sense only with regular disk provider, in the workfile diff --git a/openpype/host/host.py b/openpype/host/host.py index 630fb873a8..afe06d1f55 100644 --- a/openpype/host/host.py +++ b/openpype/host/host.py @@ -170,7 +170,7 @@ class HostBase(object): if project_name: items.append(project_name) if asset_name: - items.append(asset_name) + items.append(asset_name.lstrip("/")) if task_name: items.append(task_name) if items: diff --git a/openpype/hosts/aftereffects/api/README.md b/openpype/hosts/aftereffects/api/README.md index 790c9f859a..9c4bad3689 100644 --- a/openpype/hosts/aftereffects/api/README.md +++ b/openpype/hosts/aftereffects/api/README.md @@ -1,6 +1,6 @@ # AfterEffects Integration -Requirements: This extension requires use of Javascript engine, which is +Requirements: This extension requires use of Javascript engine, which is available since CC 16.0. Please check your File>Project Settings>Expressions>Expressions Engine @@ -13,26 +13,28 @@ The After Effects integration requires two components to work; `extension` and ` To install the extension download [Extension Manager Command Line tool (ExManCmd)](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install#option-2---exmancmd). ``` -ExManCmd /install {path to avalon-core}\avalon\photoshop\extension.zxp +ExManCmd /install {path to addon}/api/extension.zxp ``` OR download [Anastasiy’s Extension Manager](https://install.anastasiy.com/) +`{path to addon}` will be most likely in your AppData (on Windows, in your user data folder in Linux and MacOS.) + ### Server The easiest way to get the server and After Effects launch is with: ``` -python -c ^"import avalon.photoshop;avalon.aftereffects.launch(""c:\Program Files\Adobe\Adobe After Effects 2020\Support Files\AfterFX.exe"")^" +python -c ^"import openpype.hosts.photoshop;openpype.hosts..aftereffects.launch(""c:\Program Files\Adobe\Adobe After Effects 2020\Support Files\AfterFX.exe"")^" ``` `avalon.aftereffects.launch` launches the application and server, and also closes the server when After Effects exists. ## Usage -The After Effects extension can be found under `Window > Extensions > OpenPype`. Once launched you should be presented with a panel like this: +The After Effects extension can be found under `Window > Extensions > AYON`. Once launched you should be presented with a panel like this: -![Avalon Panel](panel.PNG "Avalon Panel") +![Ayon Panel](panel.png "Ayon Panel") ## Developing @@ -43,8 +45,8 @@ When developing the extension you can load it [unsigned](https://github.com/Adob When signing the extension you can use this [guide](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install#package-distribute-install-guide). ``` -ZXPSignCmd -selfSignedCert NA NA Avalon Avalon-After-Effects avalon extension.p12 -ZXPSignCmd -sign {path to avalon-core}\avalon\aftereffects\extension {path to avalon-core}\avalon\aftereffects\extension.zxp extension.p12 avalon +ZXPSignCmd -selfSignedCert NA NA Ayon Avalon-After-Effects Ayon extension.p12 +ZXPSignCmd -sign {path to addon}/api/extension {path to addon}/api/extension.zxp extension.p12 Ayon ``` ### Plugin Examples @@ -52,14 +54,14 @@ ZXPSignCmd -sign {path to avalon-core}\avalon\aftereffects\extension {path to av These plugins were made with the [polly config](https://github.com/mindbender-studio/config). To fully integrate and load, you will have to use this config and add `image` to the [integration plugin](https://github.com/mindbender-studio/config/blob/master/polly/plugins/publish/integrate_asset.py). Expected deployed extension location on default Windows: -`c:\Program Files (x86)\Common Files\Adobe\CEP\extensions\com.openpype.AE.panel` +`c:\Program Files (x86)\Common Files\Adobe\CEP\extensions\io.ynput.AE.panel` For easier debugging of Javascript: https://community.adobe.com/t5/download-install/adobe-extension-debuger-problem/td-p/10911704?page=1 Add (optional) --enable-blink-features=ShadowDOMV0,CustomElementsV0 when starting Chrome then localhost:8092 -Or use Visual Studio Code https://medium.com/adobetech/extendscript-debugger-for-visual-studio-code-public-release-a2ff6161fa01 +Or use Visual Studio Code https://medium.com/adobetech/extendscript-debugger-for-visual-studio-code-public-release-a2ff6161fa01 ## Resources - https://javascript-tools-guide.readthedocs.io/introduction/index.html - https://github.com/Adobe-CEP/Getting-Started-guides diff --git a/openpype/hosts/aftereffects/api/extension.zxp b/openpype/hosts/aftereffects/api/extension.zxp index 50fda416f8..104a5c9e99 100644 Binary files a/openpype/hosts/aftereffects/api/extension.zxp and b/openpype/hosts/aftereffects/api/extension.zxp differ diff --git a/openpype/hosts/aftereffects/api/extension/.debug b/openpype/hosts/aftereffects/api/extension/.debug index b06ec515dd..20a6713ab2 100644 --- a/openpype/hosts/aftereffects/api/extension/.debug +++ b/openpype/hosts/aftereffects/api/extension/.debug @@ -1,32 +1,31 @@ - + - + - + - + - + - + - + - + - + - + - \ No newline at end of file diff --git a/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml b/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml index 9f65720ef0..cf6ba67f44 100644 --- a/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml +++ b/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml @@ -1,8 +1,8 @@ - + - + @@ -10,22 +10,22 @@ - + - + - - + + - + - - + + - + @@ -38,7 +38,7 @@ - + ./index.html @@ -49,7 +49,7 @@ Panel - OpenPype + AYON 200 @@ -63,17 +63,17 @@ 550 400 --> - + - ./icons/iconNormal.png + ./icons/ayon_logo.png ./icons/iconRollover.png ./icons/iconDisabled.png ./icons/iconDarkNormal.png ./icons/iconDarkRollover.png - + - \ No newline at end of file + diff --git a/openpype/hosts/aftereffects/api/extension/icons/ayon_logo.png b/openpype/hosts/aftereffects/api/extension/icons/ayon_logo.png new file mode 100644 index 0000000000..3a96f8e2b4 Binary files /dev/null and b/openpype/hosts/aftereffects/api/extension/icons/ayon_logo.png differ diff --git a/openpype/hosts/aftereffects/api/extension/index.html b/openpype/hosts/aftereffects/api/extension/index.html index 291965559f..480b814a57 100644 --- a/openpype/hosts/aftereffects/api/extension/index.html +++ b/openpype/hosts/aftereffects/api/extension/index.html @@ -104,6 +104,39 @@ }); + + + + + +