Merge branch 'release/2.14.1' into develop

This commit is contained in:
Milan Kolar 2020-11-27 21:43:12 +01:00
commit f58e5a1d45
19 changed files with 953 additions and 64 deletions

View file

@ -2,7 +2,8 @@ pr-wo-labels=False
exclude-labels=duplicate,question,invalid,wontfix,weekly-digest
author=False
unreleased=True
since-tag=2.11.0
since-tag=2.13.6
release-branch=master
enhancement-label=**Enhancements:**
issues=False
pulls=False

View file

@ -1,5 +1,48 @@
# Changelog
## [2.14.0](https://github.com/pypeclub/pype/tree/2.14.0) (2020-11-24)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.7...2.14.0)
**Enhancements:**
- Shot asset build trigger status [\#736](https://github.com/pypeclub/pype/pull/736)
- Maya: add camera rig publishing option [\#721](https://github.com/pypeclub/pype/pull/721)
- Sort instances by label in pyblish gui [\#719](https://github.com/pypeclub/pype/pull/719)
- Synchronize ftrack hierarchical and shot attributes [\#716](https://github.com/pypeclub/pype/pull/716)
- 686 standalonepublisher editorial from image sequences [\#699](https://github.com/pypeclub/pype/pull/699)
- TV Paint: initial implementation of creators and local rendering [\#693](https://github.com/pypeclub/pype/pull/693)
- Render publish plugins abstraction [\#687](https://github.com/pypeclub/pype/pull/687)
- Ask user to select non-default camera from scene or create a new. [\#678](https://github.com/pypeclub/pype/pull/678)
- TVPaint: image loader with options [\#675](https://github.com/pypeclub/pype/pull/675)
- Maya: Camera name can be added to burnins. [\#674](https://github.com/pypeclub/pype/pull/674)
- After Effects: base integration with loaders [\#667](https://github.com/pypeclub/pype/pull/667)
- Harmony: Javascript refactoring and overall stability improvements [\#666](https://github.com/pypeclub/pype/pull/666)
**Fixed bugs:**
- TVPaint extract review fix [\#740](https://github.com/pypeclub/pype/pull/740)
- After Effects: Review were not being sent to ftrack [\#738](https://github.com/pypeclub/pype/pull/738)
- Asset fetch second fix [\#726](https://github.com/pypeclub/pype/pull/726)
- Maya: vray proxy was not loading [\#722](https://github.com/pypeclub/pype/pull/722)
- Maya: Vray expected file fixes [\#682](https://github.com/pypeclub/pype/pull/682)
**Deprecated:**
- Removed artist view from pyblish gui [\#717](https://github.com/pypeclub/pype/pull/717)
- Maya: disable legacy override check for cameras [\#715](https://github.com/pypeclub/pype/pull/715)
## [2.13.7](https://github.com/pypeclub/pype/tree/2.13.7) (2020-11-19)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.6...2.13.7)
**Merged pull requests:**
- fix\(SP\): getting fps from context instead of nonexistent entity [\#729](https://github.com/pypeclub/pype/pull/729)
# Changelog
## [2.13.6](https://github.com/pypeclub/pype/tree/2.13.6) (2020-11-15)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.5...2.13.6)
@ -789,4 +832,7 @@ A large cleanup release. Most of the change are under the hood.
- _(avalon)_ subsets in maya 2019 weren't behaving correctly in the outliner
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*

View file

@ -1,3 +1,360 @@
# Changelog
## [2.13.6](https://github.com/pypeclub/pype/tree/2.13.6) (2020-11-15)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.5...2.13.6)
**Fixed bugs:**
- Maya workfile version wasn't syncing with renders properly [\#711](https://github.com/pypeclub/pype/pull/711)
- Maya: Fix for publishing multiple cameras with review from the same scene [\#710](https://github.com/pypeclub/pype/pull/710)
## [2.13.5](https://github.com/pypeclub/pype/tree/2.13.5) (2020-11-12)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.4...2.13.5)
**Enhancements:**
- 3.0 lib refactor [\#664](https://github.com/pypeclub/pype/issues/664)
**Fixed bugs:**
- Wrong thumbnail file was picked when publishing sequence in standalone publisher [\#703](https://github.com/pypeclub/pype/pull/703)
- Fix: Burnin data pass and FFmpeg tool check [\#701](https://github.com/pypeclub/pype/pull/701)
## [2.13.4](https://github.com/pypeclub/pype/tree/2.13.4) (2020-11-09)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.3...2.13.4)
**Enhancements:**
- AfterEffects integration with Websocket [\#663](https://github.com/pypeclub/pype/issues/663)
**Fixed bugs:**
- Photoshop uhiding hidden layers [\#688](https://github.com/pypeclub/pype/issues/688)
- \#688 - Fix publishing hidden layers [\#692](https://github.com/pypeclub/pype/pull/692)
**Closed issues:**
- Nuke Favorite directories "shot dir" "project dir" - not working [\#684](https://github.com/pypeclub/pype/issues/684)
**Merged pull requests:**
- Nuke Favorite directories "shot dir" "project dir" - not working \#684 [\#685](https://github.com/pypeclub/pype/pull/685)
## [2.13.3](https://github.com/pypeclub/pype/tree/2.13.3) (2020-11-03)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.2...2.13.3)
**Enhancements:**
- TV paint base integration [\#612](https://github.com/pypeclub/pype/issues/612)
**Fixed bugs:**
- Fix ffmpeg executable path with spaces [\#680](https://github.com/pypeclub/pype/pull/680)
- Hotfix: Added default version number [\#679](https://github.com/pypeclub/pype/pull/679)
## [2.13.2](https://github.com/pypeclub/pype/tree/2.13.2) (2020-10-28)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.1...2.13.2)
**Fixed bugs:**
- Nuke: wrong conditions when fixing legacy write nodes [\#665](https://github.com/pypeclub/pype/pull/665)
## [2.13.1](https://github.com/pypeclub/pype/tree/2.13.1) (2020-10-23)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.13.0...2.13.1)
**Enhancements:**
- move maya look assigner to pype menu [\#292](https://github.com/pypeclub/pype/issues/292)
**Fixed bugs:**
- Layer name is not propagating to metadata in Photoshop [\#654](https://github.com/pypeclub/pype/issues/654)
- Loader in Photoshop fails with "can't set attribute" [\#650](https://github.com/pypeclub/pype/issues/650)
- Nuke Load mp4 wrong frame range [\#661](https://github.com/pypeclub/pype/issues/661)
- Hiero: Review video file adding one frame to the end [\#659](https://github.com/pypeclub/pype/issues/659)
## [2.13.0](https://github.com/pypeclub/pype/tree/2.13.0) (2020-10-18)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.5...2.13.0)
**Enhancements:**
- Deadline Output Folder [\#636](https://github.com/pypeclub/pype/issues/636)
- Nuke Camera Loader [\#565](https://github.com/pypeclub/pype/issues/565)
- Deadline publish job shows publishing output folder [\#649](https://github.com/pypeclub/pype/pull/649)
- Get latest version in lib [\#642](https://github.com/pypeclub/pype/pull/642)
- Improved publishing of multiple representation from SP [\#638](https://github.com/pypeclub/pype/pull/638)
- Launch TvPaint shot work file from within Ftrack [\#631](https://github.com/pypeclub/pype/pull/631)
- Add mp4 support for RV action. [\#628](https://github.com/pypeclub/pype/pull/628)
- Maya: allow renders to have version synced with workfile [\#618](https://github.com/pypeclub/pype/pull/618)
- Renaming nukestudio host folder to hiero [\#617](https://github.com/pypeclub/pype/pull/617)
- Harmony: More efficient publishing [\#615](https://github.com/pypeclub/pype/pull/615)
- Ftrack server action improvement [\#608](https://github.com/pypeclub/pype/pull/608)
- Deadline user defaults to pype username if present [\#607](https://github.com/pypeclub/pype/pull/607)
- Standalone publisher now has icon [\#606](https://github.com/pypeclub/pype/pull/606)
- Nuke render write targeting knob improvement [\#603](https://github.com/pypeclub/pype/pull/603)
- Animated pyblish gui [\#602](https://github.com/pypeclub/pype/pull/602)
- Maya: Deadline - make use of asset dependencies optional [\#591](https://github.com/pypeclub/pype/pull/591)
- Nuke: Publishing, loading and updating alembic cameras [\#575](https://github.com/pypeclub/pype/pull/575)
- Maya: add look assigner to pype menu even if scriptsmenu is not available [\#573](https://github.com/pypeclub/pype/pull/573)
- Store task types in the database [\#572](https://github.com/pypeclub/pype/pull/572)
- Maya: Tiled EXRs to scanline EXRs render option [\#512](https://github.com/pypeclub/pype/pull/512)
- Fusion basic integration [\#452](https://github.com/pypeclub/pype/pull/452)
**Fixed bugs:**
- Burnin script did not propagate ffmpeg output [\#640](https://github.com/pypeclub/pype/issues/640)
- Pyblish-pype spacer in terminal wasn't transparent [\#646](https://github.com/pypeclub/pype/pull/646)
- Lib subprocess without logger [\#645](https://github.com/pypeclub/pype/pull/645)
- Nuke: prevent crash if we only have single frame in sequence [\#644](https://github.com/pypeclub/pype/pull/644)
- Burnin script logs better output [\#641](https://github.com/pypeclub/pype/pull/641)
- Missing audio on farm submission. [\#639](https://github.com/pypeclub/pype/pull/639)
- review from imagesequence error [\#633](https://github.com/pypeclub/pype/pull/633)
- Hiero: wrong order of fps clip instance data collecting [\#627](https://github.com/pypeclub/pype/pull/627)
- Add source for review instances. [\#625](https://github.com/pypeclub/pype/pull/625)
- Task processing in event sync [\#623](https://github.com/pypeclub/pype/pull/623)
- sync to avalon doesn t remove renamed task [\#619](https://github.com/pypeclub/pype/pull/619)
- Intent publish setting wasn't working with default value [\#562](https://github.com/pypeclub/pype/pull/562)
- Maya: Updating a look where the shader name changed, leaves the geo without a shader [\#514](https://github.com/pypeclub/pype/pull/514)
**Merged pull requests:**
- Avalon module without Qt [\#581](https://github.com/pypeclub/pype/pull/581)
- Ftrack module without Qt [\#577](https://github.com/pypeclub/pype/pull/577)
## [2.12.5](https://github.com/pypeclub/pype/tree/2.12.5) (2020-10-14)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.4...2.12.5)
**Enhancements:**
- Launch TvPaint shot work file from within Ftrack [\#629](https://github.com/pypeclub/pype/issues/629)
**Merged pull requests:**
- Harmony: Disable application launch logic [\#637](https://github.com/pypeclub/pype/pull/637)
## [2.12.4](https://github.com/pypeclub/pype/tree/2.12.4) (2020-10-08)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.3...2.12.4)
**Enhancements:**
- convert nukestudio to hiero host [\#616](https://github.com/pypeclub/pype/issues/616)
- Fusion basic integration [\#451](https://github.com/pypeclub/pype/issues/451)
**Fixed bugs:**
- Sync to avalon doesn't remove renamed task [\#605](https://github.com/pypeclub/pype/issues/605)
- NukeStudio: FPS collecting into clip instances [\#624](https://github.com/pypeclub/pype/pull/624)
**Merged pull requests:**
- NukeStudio: small fixes [\#622](https://github.com/pypeclub/pype/pull/622)
- NukeStudio: broken order of plugins [\#620](https://github.com/pypeclub/pype/pull/620)
## [2.12.3](https://github.com/pypeclub/pype/tree/2.12.3) (2020-10-06)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.2...2.12.3)
**Enhancements:**
- Nuke Publish Camera [\#567](https://github.com/pypeclub/pype/issues/567)
- Harmony: open xstage file no matter of its name [\#526](https://github.com/pypeclub/pype/issues/526)
- Stop integration of unwanted data [\#387](https://github.com/pypeclub/pype/issues/387)
- Move avalon-launcher functionality to pype [\#229](https://github.com/pypeclub/pype/issues/229)
- avalon workfiles api [\#214](https://github.com/pypeclub/pype/issues/214)
- Store task types [\#180](https://github.com/pypeclub/pype/issues/180)
- Avalon Mongo Connection split [\#136](https://github.com/pypeclub/pype/issues/136)
- nk camera workflow [\#71](https://github.com/pypeclub/pype/issues/71)
- Hiero integration added [\#590](https://github.com/pypeclub/pype/pull/590)
- Anatomy instance data collection is substantially faster for many instances [\#560](https://github.com/pypeclub/pype/pull/560)
**Fixed bugs:**
- test issue [\#596](https://github.com/pypeclub/pype/issues/596)
- Harmony: empty scene contamination [\#583](https://github.com/pypeclub/pype/issues/583)
- Edit publishing in SP doesn't respect shot selection for publishing [\#542](https://github.com/pypeclub/pype/issues/542)
- Pathlib breaks compatibility with python2 hosts [\#281](https://github.com/pypeclub/pype/issues/281)
- Updating a look where the shader name changed leaves the geo without a shader [\#237](https://github.com/pypeclub/pype/issues/237)
- Better error handling [\#84](https://github.com/pypeclub/pype/issues/84)
- Harmony: function signature [\#609](https://github.com/pypeclub/pype/pull/609)
- Nuke: gizmo publishing error [\#594](https://github.com/pypeclub/pype/pull/594)
- Harmony: fix clashing namespace of called js functions [\#584](https://github.com/pypeclub/pype/pull/584)
- Maya: fix maya scene type preset exception [\#569](https://github.com/pypeclub/pype/pull/569)
**Closed issues:**
- Nuke Gizmo publishing [\#597](https://github.com/pypeclub/pype/issues/597)
- nuke gizmo publishing error [\#592](https://github.com/pypeclub/pype/issues/592)
- Publish EDL [\#579](https://github.com/pypeclub/pype/issues/579)
- Publish render from SP [\#576](https://github.com/pypeclub/pype/issues/576)
- rename ftrack custom attribute group to `pype` [\#184](https://github.com/pypeclub/pype/issues/184)
**Merged pull requests:**
- Audio file existence check [\#614](https://github.com/pypeclub/pype/pull/614)
- NKS small fixes [\#587](https://github.com/pypeclub/pype/pull/587)
- Standalone publisher editorial plugins interfering [\#580](https://github.com/pypeclub/pype/pull/580)
## [2.12.2](https://github.com/pypeclub/pype/tree/2.12.2) (2020-09-25)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.1...2.12.2)
**Enhancements:**
- pype config GUI [\#241](https://github.com/pypeclub/pype/issues/241)
**Fixed bugs:**
- Harmony: Saving heavy scenes will crash [\#507](https://github.com/pypeclub/pype/issues/507)
- Extract review a representation name with `\*\_burnin` [\#388](https://github.com/pypeclub/pype/issues/388)
- Hierarchy data was not considering active isntances [\#551](https://github.com/pypeclub/pype/pull/551)
## [2.12.1](https://github.com/pypeclub/pype/tree/2.12.1) (2020-09-15)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.12.0...2.12.1)
**Fixed bugs:**
- Pype: changelog.md is outdated [\#503](https://github.com/pypeclub/pype/issues/503)
- dependency security alert ! [\#484](https://github.com/pypeclub/pype/issues/484)
- Maya: RenderSetup is missing update [\#106](https://github.com/pypeclub/pype/issues/106)
- \<pyblish plugin\> extract effects creates new instance [\#78](https://github.com/pypeclub/pype/issues/78)
## [2.12.0](https://github.com/pypeclub/pype/tree/2.12.0) (2020-09-10)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.8...2.12.0)
**Enhancements:**
- Less mongo connections [\#509](https://github.com/pypeclub/pype/pull/509)
- Nuke: adding image loader [\#499](https://github.com/pypeclub/pype/pull/499)
- Move launcher window to top if launcher action is clicked [\#450](https://github.com/pypeclub/pype/pull/450)
- Maya: better tile rendering support in Pype [\#446](https://github.com/pypeclub/pype/pull/446)
- Implementation of non QML launcher [\#443](https://github.com/pypeclub/pype/pull/443)
- Optional skip review on renders. [\#441](https://github.com/pypeclub/pype/pull/441)
- Ftrack: Option to push status from task to latest version [\#440](https://github.com/pypeclub/pype/pull/440)
- Properly containerize image plane loads. [\#434](https://github.com/pypeclub/pype/pull/434)
- Option to keep the review files. [\#426](https://github.com/pypeclub/pype/pull/426)
- Isolate view on instance members. [\#425](https://github.com/pypeclub/pype/pull/425)
- Maya: Publishing of tile renderings on Deadline [\#398](https://github.com/pypeclub/pype/pull/398)
- Feature/little bit better logging gui [\#383](https://github.com/pypeclub/pype/pull/383)
**Fixed bugs:**
- Maya: Fix tile order for Draft Tile Assembler [\#511](https://github.com/pypeclub/pype/pull/511)
- Remove extra dash [\#501](https://github.com/pypeclub/pype/pull/501)
- Fix: strip dot from repre names in single frame renders [\#498](https://github.com/pypeclub/pype/pull/498)
- Better handling of destination during integrating [\#485](https://github.com/pypeclub/pype/pull/485)
- Fix: allow thumbnail creation for single frame renders [\#460](https://github.com/pypeclub/pype/pull/460)
- added missing argument to launch\_application in ftrack app handler [\#453](https://github.com/pypeclub/pype/pull/453)
- Burnins: Copy bit rate of input video to match quality. [\#448](https://github.com/pypeclub/pype/pull/448)
- Standalone publisher is now independent from tray [\#442](https://github.com/pypeclub/pype/pull/442)
- Bugfix/empty enumerator attributes [\#436](https://github.com/pypeclub/pype/pull/436)
- Fixed wrong order of "other" category collapssing in publisher [\#435](https://github.com/pypeclub/pype/pull/435)
- Multiple reviews where being overwritten to one. [\#424](https://github.com/pypeclub/pype/pull/424)
- Cleanup plugin fail on instances without staging dir [\#420](https://github.com/pypeclub/pype/pull/420)
- deprecated -intra parameter in ffmpeg to new `-g` [\#417](https://github.com/pypeclub/pype/pull/417)
- Delivery action can now work with entered path [\#397](https://github.com/pypeclub/pype/pull/397)
**Merged pull requests:**
- Review on instance.data [\#473](https://github.com/pypeclub/pype/pull/473)
## [2.11.8](https://github.com/pypeclub/pype/tree/2.11.8) (2020-08-27)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.7...2.11.8)
**Enhancements:**
- DWAA support for Maya [\#382](https://github.com/pypeclub/pype/issues/382)
- Isolate View on Playblast [\#367](https://github.com/pypeclub/pype/issues/367)
- Maya: Tile rendering [\#297](https://github.com/pypeclub/pype/issues/297)
- single pype instance running [\#47](https://github.com/pypeclub/pype/issues/47)
- PYPE-649: projects don't guarantee backwards compatible environment [\#8](https://github.com/pypeclub/pype/issues/8)
- PYPE-663: separate venv for each deployed version [\#7](https://github.com/pypeclub/pype/issues/7)
**Fixed bugs:**
- pyblish pype - other group is collapsed before plugins are done [\#431](https://github.com/pypeclub/pype/issues/431)
- Alpha white edges in harmony on PNGs [\#412](https://github.com/pypeclub/pype/issues/412)
- harmony image loader picks wrong representations [\#404](https://github.com/pypeclub/pype/issues/404)
- Clockify crash when response contain symbol not allowed by UTF-8 [\#81](https://github.com/pypeclub/pype/issues/81)
## [2.11.7](https://github.com/pypeclub/pype/tree/2.11.7) (2020-08-21)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.6...2.11.7)
**Fixed bugs:**
- Clean Up Baked Movie [\#369](https://github.com/pypeclub/pype/issues/369)
- celaction last workfile [\#459](https://github.com/pypeclub/pype/pull/459)
## [2.11.6](https://github.com/pypeclub/pype/tree/2.11.6) (2020-08-18)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.5...2.11.6)
**Enhancements:**
- publisher app [\#56](https://github.com/pypeclub/pype/issues/56)
## [2.11.5](https://github.com/pypeclub/pype/tree/2.11.5) (2020-08-13)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.4...2.11.5)
**Enhancements:**
- Switch from master to equivalent [\#220](https://github.com/pypeclub/pype/issues/220)
- Standalone publisher now only groups sequence if the extension is known [\#439](https://github.com/pypeclub/pype/pull/439)
**Fixed bugs:**
- Logs have been disable for editorial by default to speed up publishing [\#433](https://github.com/pypeclub/pype/pull/433)
- additional fixes for celaction [\#430](https://github.com/pypeclub/pype/pull/430)
- Harmony: invalid variable scope in validate scene settings [\#428](https://github.com/pypeclub/pype/pull/428)
- new representation name for audio was not accepted [\#427](https://github.com/pypeclub/pype/pull/427)
## [2.11.4](https://github.com/pypeclub/pype/tree/2.11.4) (2020-08-10)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.3...2.11.4)
**Enhancements:**
- WebSocket server [\#135](https://github.com/pypeclub/pype/issues/135)
- standalonepublisher: editorial family features expansion \[master branch\] [\#411](https://github.com/pypeclub/pype/pull/411)
## [2.11.3](https://github.com/pypeclub/pype/tree/2.11.3) (2020-08-04)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.2...2.11.3)
**Fixed bugs:**
- Harmony: publishing performance issues [\#408](https://github.com/pypeclub/pype/pull/408)
## [2.11.2](https://github.com/pypeclub/pype/tree/2.11.2) (2020-07-31)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.1...2.11.2)
**Fixed bugs:**
- Ftrack to Avalon bug [\#406](https://github.com/pypeclub/pype/issues/406)
## [2.11.1](https://github.com/pypeclub/pype/tree/2.11.1) (2020-07-29)
[Full Changelog](https://github.com/pypeclub/pype/compare/2.11.0...2.11.1)
**Merged pull requests:**
- Celaction: metadata json folder fixes on path [\#393](https://github.com/pypeclub/pype/pull/393)
- CelAction - version up method taken fro pype.lib [\#391](https://github.com/pypeclub/pype/pull/391)
<a name="2.11.0"></a>
## 2.11.0 ##
@ -430,3 +787,6 @@ A large cleanup release. Most of the change are under the hood.
- work directory was sometimes not being created correctly
- major pype.lib cleanup. Removing of unused functions, merging those that were doing the same and general house cleaning.
- _(avalon)_ subsets in maya 2019 weren't behaving correctly in the outliner
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*

View file

@ -266,8 +266,8 @@ class AExpectedFiles:
def _generate_single_file_sequence(self, layer_data):
expected_files = []
file_prefix = layer_data["filePrefix"]
for cam in layer_data["cameras"]:
file_prefix = layer_data["filePrefix"]
mappings = (
(R_SUBSTITUTE_SCENE_TOKEN, layer_data["sceneName"]),
(R_SUBSTITUTE_LAYER_TOKEN, layer_data["layerName"]),
@ -299,9 +299,9 @@ class AExpectedFiles:
def _generate_aov_file_sequences(self, layer_data):
expected_files = []
aov_file_list = {}
file_prefix = layer_data["filePrefix"]
for aov in layer_data["enabledAOVs"]:
for cam in layer_data["cameras"]:
file_prefix = layer_data["filePrefix"]
mappings = (
(R_SUBSTITUTE_SCENE_TOKEN, layer_data["sceneName"]),
@ -418,13 +418,12 @@ class AExpectedFiles:
if connections:
for connection in connections:
if connection:
node_name = connection.split(".")[0]
if cmds.nodeType(node_name) == "renderLayer":
attr_name = "%s.value" % ".".join(
connection.split(".")[:-1]
)
if node_name == layer:
yield cmds.getAttr(attr_name)
# node_name = connection.split(".")[0]
attr_name = "%s.value" % ".".join(
connection.split(".")[:-1]
)
yield cmds.getAttr(attr_name)
def get_render_attribute(self, attr):
"""Get attribute from render options.
@ -572,11 +571,17 @@ class ExpectedFilesVray(AExpectedFiles):
expected_files = super(ExpectedFilesVray, self).get_files()
layer_data = self._get_layer_data()
# remove 'beauty' from filenames as vray doesn't output it
update = {}
if layer_data.get("enabledAOVs"):
expected_files[0][u"beauty"] = self._generate_single_file_sequence(
layer_data
) # noqa: E501
for aov, seq in expected_files[0].items():
if aov.startswith("beauty"):
new_list = []
for f in seq:
new_list.append(f.replace("_beauty", ""))
update[aov] = new_list
expected_files[0].update(update)
return expected_files
def get_aovs(self):
@ -630,28 +635,49 @@ class ExpectedFilesVray(AExpectedFiles):
# todo: find how vray set format for AOVs
enabled_aovs.append(
(self._get_vray_aov_name(aov), default_ext))
enabled_aovs.append(
(u"beauty", default_ext)
)
return enabled_aovs
def _get_vray_aov_name(self, node):
"""Get AOVs name from Vray.
# Get render element pass type
vray_node_attr = next(
attr
for attr in cmds.listAttr(node)
if attr.startswith("vray_name")
)
pass_type = vray_node_attr.rsplit("_", 1)[-1]
Args:
node (str): aov node name.
# Support V-Ray extratex explicit name (if set by user)
if pass_type == "extratex":
explicit_attr = "{}.vray_explicit_name_extratex".format(node)
explicit_name = cmds.getAttr(explicit_attr)
if explicit_name:
return explicit_name
Returns:
str: aov name.
# Node type is in the attribute name but we need to check if value
# of the attribute as it can be changed
return cmds.getAttr("{}.{}".format(node, vray_node_attr))
"""
vray_name = None
vray_explicit_name = None
vray_file_name = None
for attr in cmds.listAttr(node):
if attr.startswith("vray_filename"):
vray_file_name = cmds.getAttr("{}.{}".format(node, attr))
elif attr.startswith("vray_name"):
vray_name = cmds.getAttr("{}.{}".format(node, attr))
elif attr.startswith("vray_explicit_name"):
vray_explicit_name = cmds.getAttr("{}.{}".format(node, attr))
if vray_file_name is not None and vray_file_name != "":
final_name = vray_file_name
elif vray_explicit_name is not None and vray_explicit_name != "":
final_name = vray_explicit_name
elif vray_name is not None and vray_name != "":
final_name = vray_name
else:
continue
# special case for Material Select elements - these are named
# based on the materia they are connected to.
if "vray_mtl_mtlselect" in cmds.listAttr(node):
connections = cmds.listConnections(
"{}.vray_mtl_mtlselect".format(node))
if connections:
final_name += '_{}'.format(str(connections[0]))
return final_name
class ExpectedFilesRedshift(AExpectedFiles):

View file

@ -520,6 +520,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin):
f.replace(orig_scene, new_scene)
)
new_exp[aov] = replaced_files
# [] might be too much here, TODO
self._instance.data["expectedFiles"] = [new_exp]
else:
new_exp = []
@ -527,7 +528,8 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin):
new_exp.append(
f.replace(orig_scene, new_scene)
)
self._instance.data["expectedFiles"] = [new_exp]
self._instance.data["expectedFiles"] = new_exp
self.log.info("Scene name was switched {} -> {}".format(
orig_scene, new_scene
))

View file

@ -252,6 +252,9 @@ class AfterEffectsServerStub():
Args:
item_id (int):
Returns:
(namedtuple)
"""
res = self.websocketserver.call(self.client.call
('AfterEffects.get_work_area',
@ -305,6 +308,35 @@ class AfterEffectsServerStub():
image_path=project_path,
as_copy=as_copy))
def get_render_info(self):
""" Get render queue info for render purposes
Returns:
(namedtuple): with 'file_name' field
"""
res = self.websocketserver.call(self.client.call
('AfterEffects.get_render_info'))
records = self._to_records(res)
if records:
return records.pop()
log.debug("Render queue needs to have file extension in 'Output to'")
def get_audio_url(self, item_id):
""" Get audio layer absolute url for comp
Args:
item_id (int): composition id
Returns:
(str): absolute path url
"""
res = self.websocketserver.call(self.client.call
('AfterEffects.get_audio_url',
item_id=item_id))
return res
def close(self):
self.client.close()

View file

@ -0,0 +1,27 @@
import os
import pyblish.api
from avalon import aftereffects
class CollectAudio(pyblish.api.ContextPlugin):
"""Inject audio file url for rendered composition into context.
Needs to run AFTER 'collect_render'. Use collected comp_id to check
if there is an AVLayer in this composition
"""
order = pyblish.api.CollectorOrder + 0.499
label = "Collect Audio"
hosts = ["aftereffects"]
def process(self, context):
for instance in context:
if instance.data["family"] == 'render.farm':
comp_id = instance.data["comp_id"]
if not comp_id:
self.log.debug("No comp_id filled in instance")
return
context.data["audioFile"] = os.path.normpath(
aftereffects.stub().get_audio_url(comp_id)
).replace("\\", "/")

View file

@ -11,6 +11,7 @@ from avalon import aftereffects
class AERenderInstance(RenderInstance):
# extend generic, composition name is needed
comp_name = attr.ib(default=None)
comp_id = attr.ib(default=None)
class CollectAERender(abstract_collect_render.AbstractCollectRender):
@ -39,13 +40,11 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender):
continue
work_area_info = aftereffects.stub().get_work_area(int(item_id))
frameStart = round(float(work_area_info.workAreaStart) *
float(work_area_info.frameRate))
frameStart = work_area_info.workAreaStart
frameEnd = round(float(work_area_info.workAreaStart) *
float(work_area_info.frameRate) +
frameEnd = round(work_area_info.workAreaStart +
float(work_area_info.workAreaDuration) *
float(work_area_info.frameRate))
float(work_area_info.frameRate)) - 1
if inst["family"] == "render" and inst["active"]:
instance = AERenderInstance(
@ -83,6 +82,7 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender):
raise ValueError("There is no composition for item {}".
format(item_id))
instance.comp_name = comp.name
instance.comp_id = item_id
instance._anatomy = context.data["anatomy"]
instance.anatomyData = context.data["anatomyData"]
@ -108,18 +108,29 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender):
start = render_instance.frameStart
end = render_instance.frameEnd
# pull file name from Render Queue Output module
render_q = aftereffects.stub().get_render_info()
_, ext = os.path.splitext(os.path.basename(render_q.file_name))
base_dir = self._get_output_dir(render_instance)
expected_files = []
for frame in range(start, end + 1):
path = os.path.join(base_dir, "{}_{}_{}.{}.{}".format(
render_instance.asset,
render_instance.subset,
"v{:03d}".format(render_instance.version),
str(frame).zfill(self.padding_width),
self.rendered_extension
))
if "#" not in render_q.file_name: # single frame (mov)W
path = os.path.join(base_dir, "{}_{}_{}.{}".format(
render_instance.asset,
render_instance.subset,
"v{:03d}".format(render_instance.version),
ext.replace('.', '')
))
expected_files.append(path)
else:
for frame in range(start, end + 1):
path = os.path.join(base_dir, "{}_{}_{}.{}.{}".format(
render_instance.asset,
render_instance.subset,
"v{:03d}".format(render_instance.version),
str(frame).zfill(self.padding_width),
ext.replace('.', '')
))
expected_files.append(path)
return expected_files
def _get_output_dir(self, render_instance):

View file

@ -0,0 +1,14 @@
import pype.api
from avalon import aftereffects
class ExtractSaveScene(pype.api.Extractor):
"""Save scene before extraction."""
order = pype.api.Extractor.order - 0.49
label = "Extract Save Scene"
hosts = ["aftereffects"]
families = ["workfile"]
def process(self, instance):
aftereffects.stub().save()

View file

@ -18,15 +18,18 @@ class DeadlinePluginInfo():
ProjectPath = attr.ib(default=None)
AWSAssetFile0 = attr.ib(default=None)
Version = attr.ib(default=None)
MultiProcess = attr.ib(default=None)
class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
label = "Submit AE to Deadline"
order = pyblish.api.IntegratorOrder
order = pyblish.api.IntegratorOrder + 0.1
hosts = ["aftereffects"]
families = ["render.farm"] # cannot be "render' as that is integrated
use_published = False
use_published = True
chunk_size = 1000000
def get_job_info(self):
dln_job_info = DeadlineJobInfo(Plugin="AfterEffects")
@ -39,9 +42,12 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline
dln_job_info.Plugin = "AfterEffects"
dln_job_info.UserName = context.data.get(
"deadlineUser", getpass.getuser())
frame_range = "{}-{}".format(self._instance.data["frameStart"],
self._instance.data["frameEnd"])
dln_job_info.Frames = frame_range
if self._instance.data["frameEnd"] > self._instance.data["frameStart"]:
frame_range = "{}-{}".format(self._instance.data["frameStart"],
self._instance.data["frameEnd"])
dln_job_info.Frames = frame_range
dln_job_info.ChunkSize = self.chunk_size
dln_job_info.OutputFilename = \
os.path.basename(self._instance.data["expectedFiles"][0])
dln_job_info.OutputDirectory = \
@ -77,21 +83,25 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline
script_path = context.data["currentFile"]
render_path = self._instance.data["expectedFiles"][0]
# replace frame info ('000001') with Deadline's required '[#######]'
# expects filename in format project_asset_subset_version.FRAME.ext
render_dir = os.path.dirname(render_path)
file_name = os.path.basename(render_path)
arr = file_name.split('.')
assert len(arr) == 3, \
"Unable to parse frames from {}".format(file_name)
hashed = '[{}]'.format(len(arr[1]) * "#")
render_path = os.path.join(render_dir,
'{}.{}.{}'.format(arr[0], hashed, arr[2]))
if len(self._instance.data["expectedFiles"]) > 1:
# replace frame ('000001') with Deadline's required '[#######]'
# expects filename in format project_asset_subset_version.FRAME.ext
render_dir = os.path.dirname(render_path)
file_name = os.path.basename(render_path)
arr = file_name.split('.')
assert len(arr) == 3, \
"Unable to parse frames from {}".format(file_name)
hashed = '[{}]'.format(len(arr[1]) * "#")
render_path = os.path.join(render_dir,
'{}.{}.{}'.format(arr[0], hashed,
arr[2]))
deadline_plugin_info.MultiProcess = True
deadline_plugin_info.Comp = self._instance.data["comp_name"]
deadline_plugin_info.Version = "17.5"
deadline_plugin_info.SceneFile = script_path
deadline_plugin_info.SceneFile = self.scene_path
deadline_plugin_info.Output = render_path.replace("\\", "/")
return attr.asdict(deadline_plugin_info)

View file

@ -96,6 +96,7 @@ class CollectFtrackApi(pyblish.api.ContextPlugin):
task_entity = None
self.log.warning("Task name is not set.")
context.data["ftrackPythonModule"] = ftrack_api
context.data["ftrackProject"] = project_entity
context.data["ftrackEntity"] = asset_entity
context.data["ftrackTask"] = task_entity

View file

@ -36,6 +36,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
order = pyblish.api.IntegratorOrder - 0.04
label = 'Integrate Hierarchy To Ftrack'
families = ["shot"]
hosts = ["hiero"]
optional = False
def process(self, context):

View file

@ -0,0 +1,331 @@
import sys
import six
import collections
import pyblish.api
from avalon import io
from pype.modules.ftrack.lib.avalon_sync import (
CUST_ATTR_AUTO_SYNC,
get_pype_attr
)
class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
"""
Create entities in ftrack based on collected data from premiere
Example of entry data:
{
"ProjectXS": {
"entity_type": "Project",
"custom_attributes": {
"fps": 24,...
},
"tasks": [
"Compositing",
"Lighting",... *task must exist as task type in project schema*
],
"childs": {
"sq01": {
"entity_type": "Sequence",
...
}
}
}
}
"""
order = pyblish.api.IntegratorOrder - 0.04
label = 'Integrate Hierarchy To Ftrack'
families = ["shot"]
hosts = ["standalonepublisher"]
optional = False
def process(self, context):
self.context = context
if "hierarchyContext" not in self.context.data:
return
hierarchy_context = self.context.data["hierarchyContext"]
self.session = self.context.data["ftrackSession"]
project_name = self.context.data["projectEntity"]["name"]
query = 'Project where full_name is "{}"'.format(project_name)
project = self.session.query(query).one()
auto_sync_state = project[
"custom_attributes"][CUST_ATTR_AUTO_SYNC]
if not io.Session:
io.install()
self.ft_project = None
input_data = hierarchy_context
# disable termporarily ftrack project's autosyncing
if auto_sync_state:
self.auto_sync_off(project)
try:
# import ftrack hierarchy
self.import_to_ftrack(input_data)
except Exception:
raise
finally:
if auto_sync_state:
self.auto_sync_on(project)
def import_to_ftrack(self, input_data, parent=None):
# Prequery hiearchical custom attributes
hier_custom_attributes = get_pype_attr(self.session)[1]
hier_attr_by_key = {
attr["key"]: attr
for attr in hier_custom_attributes
}
# Get ftrack api module (as they are different per python version)
ftrack_api = self.context.data["ftrackPythonModule"]
for entity_name in input_data:
entity_data = input_data[entity_name]
entity_type = entity_data['entity_type']
self.log.debug(entity_data)
self.log.debug(entity_type)
if entity_type.lower() == 'project':
query = 'Project where full_name is "{}"'.format(entity_name)
entity = self.session.query(query).one()
self.ft_project = entity
self.task_types = self.get_all_task_types(entity)
elif self.ft_project is None or parent is None:
raise AssertionError(
"Collected items are not in right order!"
)
# try to find if entity already exists
else:
query = (
'TypedContext where name is "{0}" and '
'project_id is "{1}"'
).format(entity_name, self.ft_project["id"])
try:
entity = self.session.query(query).one()
except Exception:
entity = None
# Create entity if not exists
if entity is None:
entity = self.create_entity(
name=entity_name,
type=entity_type,
parent=parent
)
# self.log.info('entity: {}'.format(dict(entity)))
# CUSTOM ATTRIBUTES
custom_attributes = entity_data.get('custom_attributes', [])
instances = [
i for i in self.context if i.data['asset'] in entity['name']
]
for key in custom_attributes:
hier_attr = hier_attr_by_key.get(key)
# Use simple method if key is not hierarchical
if not hier_attr:
assert (key in entity['custom_attributes']), (
'Missing custom attribute key: `{0}` in attrs: '
'`{1}`'.format(key, entity['custom_attributes'].keys())
)
entity['custom_attributes'][key] = custom_attributes[key]
else:
# Use ftrack operations method to set hiearchical
# attribute value.
# - this is because there may be non hiearchical custom
# attributes with different properties
entity_key = collections.OrderedDict({
"configuration_id": hier_attr["id"],
"entity_id": entity["id"]
})
self.session.recorded_operations.push(
ftrack_api.operation.UpdateEntityOperation(
"ContextCustomAttributeValue",
entity_key,
"value",
ftrack_api.symbol.NOT_SET,
custom_attributes[key]
)
)
for instance in instances:
instance.data['ftrackEntity'] = entity
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
# TASKS
tasks = entity_data.get('tasks', [])
existing_tasks = []
tasks_to_create = []
for child in entity['children']:
if child.entity_type.lower() == 'task':
existing_tasks.append(child['name'].lower())
# existing_tasks.append(child['type']['name'])
for task_name in tasks:
task_type = tasks[task_name]["type"]
if task_name.lower() in existing_tasks:
print("Task {} already exists".format(task_name))
continue
tasks_to_create.append((task_name, task_type))
for task_name, task_type in tasks_to_create:
self.create_task(
name=task_name,
task_type=task_type,
parent=entity
)
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
# Incoming links.
self.create_links(entity_data, entity)
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
# Create notes.
user = self.session.query(
"User where username is \"{}\"".format(self.session.api_user)
).first()
if user:
for comment in entity_data.get("comments", []):
entity.create_note(comment, user)
else:
self.log.warning(
"Was not able to query current User {}".format(
self.session.api_user
)
)
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
# Import children.
if 'childs' in entity_data:
self.import_to_ftrack(
entity_data['childs'], entity)
def create_links(self, entity_data, entity):
# Clear existing links.
for link in entity.get("incoming_links", []):
self.session.delete(link)
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
# Create new links.
for input in entity_data.get("inputs", []):
input_id = io.find_one({"_id": input})["data"]["ftrackId"]
assetbuild = self.session.get("AssetBuild", input_id)
self.log.debug(
"Creating link from {0} to {1}".format(
assetbuild["name"], entity["name"]
)
)
self.session.create(
"TypedContextLink", {"from": assetbuild, "to": entity}
)
def get_all_task_types(self, project):
tasks = {}
proj_template = project['project_schema']
temp_task_types = proj_template['_task_type_schema']['types']
for type in temp_task_types:
if type['name'] not in tasks:
tasks[type['name']] = type
return tasks
def create_task(self, name, task_type, parent):
task = self.session.create('Task', {
'name': name,
'parent': parent
})
# TODO not secured!!! - check if task_type exists
self.log.info(task_type)
self.log.info(self.task_types)
task['type'] = self.task_types[task_type]
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
return task
def create_entity(self, name, type, parent):
entity = self.session.create(type, {
'name': name,
'parent': parent
})
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
return entity
def auto_sync_off(self, project):
project["custom_attributes"][CUST_ATTR_AUTO_SYNC] = False
self.log.info("Ftrack autosync swithed off")
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)
def auto_sync_on(self, project):
project["custom_attributes"][CUST_ATTR_AUTO_SYNC] = True
self.log.info("Ftrack autosync swithed on")
try:
self.session.commit()
except Exception:
tp, value, tb = sys.exc_info()
self.session.rollback()
self.session._configure_locations()
six.reraise(tp, value, tb)

View file

@ -280,6 +280,15 @@ class ExtractReview(pyblish.api.InstancePlugin):
handles_are_set = handle_start > 0 or handle_end > 0
with_audio = True
if (
# Check if has `no-audio` tag
"no-audio" in output_def["tags"]
# Check if instance has ny audio in data
or not instance.data.get("audio")
):
with_audio = False
return {
"fps": float(instance.data["fps"]),
"frame_start": frame_start,
@ -295,6 +304,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
"resolution_height": instance.data.get("resolutionHeight"),
"origin_repre": repre,
"input_is_sequence": self.input_is_sequence(repre),
"with_audio": with_audio,
"without_handles": without_handles,
"handles_are_set": handles_are_set
}
@ -389,7 +399,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
ffmpeg_output_args.append("-shortest")
# Add audio arguments if there are any. Skipped when output are images.
if not temp_data["output_ext_is_image"]:
if not temp_data["output_ext_is_image"] and temp_data["with_audio"]:
audio_in_args, audio_filters, audio_out_args = self.audio_args(
instance, temp_data
)

View file

@ -600,6 +600,13 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
"files": os.path.basename(remainder),
"stagingDir": os.path.dirname(remainder),
}
if "render" in instance.get("families"):
rep.update({
"fps": instance.get("fps"),
"tags": ["review"]
})
self._solve_families(instance, True)
if remainder in bake_render_path:
rep.update({
"fps": instance.get("fps"),

View file

@ -23,6 +23,8 @@ class ExtractReviewCutUp(pype.api.Extractor):
def process(self, instance):
inst_data = instance.data
asset = inst_data['asset']
item = inst_data['item']
event_number = int(item.eventNumber())
# get representation and loop them
representations = inst_data["representations"]
@ -97,7 +99,12 @@ class ExtractReviewCutUp(pype.api.Extractor):
index = 0
for image in collection:
dst_file_num = frame_start + index
dst_file_name = head + str(padding % dst_file_num) + tail
dst_file_name = "".join([
str(event_number),
head,
str(padding % dst_file_num),
tail
])
src = os.path.join(staging_dir, image)
dst = os.path.join(full_output_dir, dst_file_name)
self.log.info("Creating temp hardlinks: {}".format(dst))

View file

@ -350,7 +350,7 @@ class ExtractLook(pype.api.Extractor):
if existing and not force:
self.log.info("Found hash in database, preparing hardlink..")
source = next((p for p in existing if os.path.exists(p)), None)
if filepath:
if source:
return source, HARDLINK, texture_hash
else:
self.log.warning(

View file

@ -162,6 +162,9 @@ class LoadImage(pipeline.Loader):
"""
# Create new containers first
context = get_representation_context(representation)
# Change `fname` to new representation
self.fname = self.filepath_from_context(context)
name = container["name"]
namespace = container["namespace"]
new_container = self.load(context, name, namespace, {})

View file

@ -1 +1 @@
__version__ = "2.14.0"
__version__ = "2.14.1"