OP-4181 - clean up after review comments

This commit is contained in:
Petr Kalis 2022-10-06 17:28:30 +02:00
parent 640971a49b
commit a7150bd6f1
17 changed files with 2982 additions and 3 deletions

BIN
igniter/GPUCache/data_0 Normal file

Binary file not shown.

BIN
igniter/GPUCache/data_1 Normal file

Binary file not shown.

BIN
igniter/GPUCache/data_2 Normal file

Binary file not shown.

BIN
igniter/GPUCache/data_3 Normal file

Binary file not shown.

BIN
igniter/GPUCache/index Normal file

Binary file not shown.

View file

@ -0,0 +1,35 @@
import os
from openpype.lib import PreLaunchHook
class PrePython2Vendor(PreLaunchHook):
"""Prepend python 2 dependencies for py2 hosts."""
order = 10
def execute(self):
if not self.application.use_python_2:
return
# Prepare vendor dir path
self.log.info("adding global python 2 vendor")
pype_root = os.getenv("OPENPYPE_REPOS_ROOT")
python_2_vendor = os.path.join(
pype_root,
"openpype",
"vendor",
"python",
"python_2"
)
# Add Python 2 modules
python_paths = [
python_2_vendor
]
# Load PYTHONPATH from current launch context
python_path = self.launch_context.env.get("PYTHONPATH")
if python_path:
python_paths.append(python_path)
# Set new PYTHONPATH to launch context environments
self.launch_context.env["PYTHONPATH"] = os.pathsep.join(python_paths)

View file

@ -0,0 +1,51 @@
import json
data = [
{
"schema": "openpype:container-2.0",
"id": "pyblish.avalon.container",
"name": "imageArtNeew",
"namespace": "Jungle_imageArtNeew_001",
"loader": "ReferenceLoader",
"representation": "61c1eb91e1a4d1e5a23582f6",
"members": [
"131"
]
},
{
"id": "pyblish.avalon.instance",
"family": "image",
"asset": "Jungle",
"subset": "imageMainBg",
"active": True,
"variant": "Main",
"uuid": "199",
"long_name": "BG"
},
{
"id": "pyblish.avalon.instance",
"family": "image",
"asset": "Jungle",
"subset": "imageMain",
"active": True,
"variant": "Main",
"uuid": "192",
"long_name": "imageMain"
},
{
"id": "pyblish.avalon.instance",
"family": "workfile",
"subset": "workfile",
"active": True,
"creator_identifier": "workfile",
"asset": "Jungle",
"task": "art",
"variant": "",
"instance_id": "3ed19342-cd8e-4bb6-8cda-d6e74d9a7efe",
"creator_attributes": {},
"publish_attributes": {}
}
]
with open("C:\\Users\\petrk\\PycharmProjects\\Pype3.0\\pype\\openpype\\hosts\\photoshop\\tests\\mock_get_layers_metadata.json", 'w') as fp:
fp.write(json.dumps(data, indent=4))

1
openpype/lib/token Normal file
View file

@ -0,0 +1 @@
5d58370a7702b2efee5120704246baf4abb865323fc9db9a04827bfb478569d6

View file

@ -0,0 +1,275 @@
import os
import subprocess
import tempfile
import shutil
import json
import sys
import opentimelineio as otio
import ftrack_api
import requests
from openpype_modules.ftrack.lib import BaseAction
def download_file(url, path):
with open(path, "wb") as f:
print("\nDownloading %s" % path)
response = requests.get(url, stream=True)
total_length = response.headers.get('content-length')
if total_length is None:
f.write(response.content)
else:
dl = 0
total_length = int(total_length)
for data in response.iter_content(chunk_size=4096):
dl += len(data)
f.write(data)
done = int(50 * dl / total_length)
sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50-done)))
sys.stdout.flush()
class ExportEditorialAction(BaseAction):
'''Export Editorial action'''
label = "Export Editorial"
variant = None
identifier = "export-editorial"
description = None
component_name_order = ["exr", "mov", "ftrackreview-mp4_src"]
def export_editorial(self, entity, output_path):
session = ftrack_api.Session()
unmanaged_location = session.query(
"Location where name is \"ftrack.unmanaged\""
).one()
temp_path = tempfile.mkdtemp()
files = {}
for obj in entity["review_session_objects"]:
data = {}
parent_name = obj["asset_version"]["asset"]["parent"]["name"]
component_query = "Component where version_id is \"{}\""
component_query += " and name is \"{}\""
for name in self.component_name_order:
try:
component = session.query(
component_query.format(
obj["asset_version"]["id"], name
)
).one()
path = unmanaged_location.get_filesystem_path(component)
data["path"] = path.replace("\\", "/")
break
except ftrack_api.exception.NoResultFoundError:
pass
# Download online review if not local path found.
if "path" not in data:
component = session.query(
component_query.format(
obj["asset_version"]["id"], "ftrackreview-mp4"
)
).one()
location = component["component_locations"][0]
component_url = location["location"].get_url(component)
asset_name = obj["asset_version"]["asset"]["name"]
version = obj["asset_version"]["version"]
filename = "{}_{}_v{:03d}.mp4".format(
parent_name, asset_name, version
)
filepath = os.path.join(
output_path, "downloads", filename
).replace("\\", "/")
if not os.path.exists(os.path.dirname(filepath)):
os.makedirs(os.path.dirname(filepath))
download_file(component_url, filepath)
data["path"] = filepath
# Get frame duration and framerate.
query = "Component where version_id is \"{}\""
query += " and name is \"ftrackreview-mp4\""
component = session.query(
query.format(obj["asset_version"]["id"])
).one()
metadata = json.loads(component["metadata"]["ftr_meta"])
data["framerate"] = metadata["frameRate"]
data["frames"] = metadata["frameOut"] - metadata["frameIn"]
# Find audio if it exists.
query = "Asset where parent.id is \"{}\""
query += " and type.name is \"Audio\""
asset = session.query(
query.format(obj["asset_version"]["asset"]["parent"]["id"])
)
if asset:
asset_version = asset[0]["versions"][-1]
query = "Component where version_id is \"{}\""
query += " and name is \"{}\""
comp = session.query(
query.format(asset_version["id"], "wav")
).one()
src = unmanaged_location.get_filesystem_path(comp)
dst = os.path.join(temp_path, parent_name + ".wav")
shutil.copy(src, dst)
# Collect data.
files[parent_name] = data
clips = []
for name, data in files.items():
self.log.info("Processing {} with {}".format(name, data))
f = data["path"]
range = otio.opentime.TimeRange(
start_time=otio.opentime.RationalTime(0, data["framerate"]),
duration=otio.opentime.RationalTime(
data["frames"], data["framerate"]
)
)
media_reference = otio.schema.ExternalReference(
available_range=range,
target_url=f"file://{f}"
)
clip = otio.schema.Clip(
name=name,
media_reference=media_reference,
source_range=range
)
clips.append(clip)
# path = os.path.join(temp_path, name + ".wav").replace("\\", "/")
# if not os.path.exists(path):
# args = ["ffmpeg", "-y", "-i", f, path]
# self.log.info(subprocess.list2cmdline(args))
# subprocess.call(args)
timeline = otio.schema.timeline_from_clips(clips)
otio.adapters.write_to_file(
timeline, os.path.join(output_path, entity["name"] + ".xml")
)
data = ""
for f in os.listdir(temp_path):
f = f.replace("\\", "/")
data += f"file '{f}'\n"
path = os.path.join(temp_path, "temp.txt")
with open(path, "w") as f:
f.write(data)
args = [
"ffmpeg", "-y", "-f", "concat", "-safe", "0",
"-i", os.path.basename(path),
os.path.join(output_path, entity["name"] + ".wav")
]
self.log.info(subprocess.list2cmdline(args))
subprocess.call(args, cwd=temp_path)
shutil.rmtree(temp_path)
def discover(self, session, entities, event):
'''Return true if we can handle the selected entities.
*session* is a `ftrack_api.Session` instance
*entities* is a list of tuples each containing the entity type and the
entity id.
If the entity is a hierarchical you will always get the entity
type TypedContext, once retrieved through a get operation you
will have the "real" entity type ie. example Shot, Sequence
or Asset Build.
*event* the unmodified original event
'''
if len(entities) == 1:
if entities[0].entity_type == "ReviewSession":
return True
return False
def launch(self, session, entities, event):
'''Callback method for the custom action.
return either a bool ( True if successful or False if the action
failed ) or a dictionary with they keys `message` and `success`, the
message should be a string and will be displayed as feedback to the
user, success should be a bool, True if successful or False if the
action failed.
*session* is a `ftrack_api.Session` instance
*entities* is a list of tuples each containing the entity type and the
entity id.
If the entity is a hierarchical you will always get the entity
type TypedContext, once retrieved through a get operation you
will have the "real" entity type ie. example Shot, Sequence
or Asset Build.
*event* the unmodified original event
'''
if 'values' in event['data']:
userId = event['source']['user']['id']
user = session.query('User where id is ' + userId).one()
job = session.create(
'Job',
{
'user': user,
'status': 'running',
'data': json.dumps({
'description': 'Export Editorial.'
})
}
)
session.commit()
try:
output_path = event["data"]["values"]["output_path"]
if not os.path.exists(output_path):
os.makedirs(output_path)
self.export_editorial(entities[0], output_path)
job['status'] = 'done'
session.commit()
except Exception:
session.rollback()
job["status"] = "failed"
session.commit()
self.log.error(
"Exporting editorial failed ({})", exc_info=True
)
return {
'success': True,
'message': 'Action completed successfully'
}
items = [
{
'label': 'Output folder:',
'type': 'text',
'value': '',
'name': 'output_path'
}
]
return {
'success': True,
'message': "",
'items': items
}
def register(session):
'''Register action. Called when used as an event plugin.'''
ExportEditorialAction(session).register()
if __name__ == "__main__":
session = ftrack_api.Session()
action = ExportEditorialAction(session)
id = "bfe0477c-d5a8-49d8-88b9-6d44d2e48fd9"
review_session = session.get("ReviewSession", id)
path = r"c:/projects"
action.export_editorial(review_session, path)

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,6 @@ from openpype.client import (
)
from openpype.client.operations import (
OperationsSession,
_create_or_convert_to_mongo_id,
new_hero_version_doc,
prepare_hero_version_update_data,
prepare_representation_update_data,
@ -193,9 +192,13 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
op_session = OperationsSession()
entity_id = None
if old_version:
entity_id = old_version["_id"]
new_hero_version = new_hero_version_doc(
src_version_entity["_id"],
src_version_entity["parent"]
src_version_entity["parent"],
entity_id=entity_id
)
if old_version:
@ -408,7 +411,7 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
# Create representation
else:
repre["_id"] = _create_or_convert_to_mongo_id(None)
repre.pop("_id", None)
op_session.create_entity(project_name, "representation",
repre)

View file

@ -0,0 +1,92 @@
[
{
"_id": {
"$oid": "623c9d53db3f5046eb1ad5f4"
},
"schema": "openpype:version-3.0",
"type": "version",
"parent": {
"$oid": "5f3e439a30a9464d6c181cbc"
},
"name": 94,
"data": {
"families": [
"workfile"
],
"time": "20220324T173254Z",
"author": "petrk",
"source": "C:/projects_local/petr_test/assets/locations/Jungle/work/art/petr_test_Jungle_art_v009.psd",
"comment": "",
"machine": "LAPTOP-UB778LHG",
"fps": 25.0,
"intent": "-",
"inputLinks": [
{
"type": "reference",
"id": {
"$oid": "618eb14f0a55a9c1591e913c"
},
"linkedBy": "publish"
}
]
},
"outputs_recursive": [
{
"_id": {
"$oid": "618eb14f0a55a9c1591e913c"
},
"schema": "openpype:version-3.0",
"type": "version",
"parent": {
"$oid": "618e42a72ff49bd543bc1768"
},
"name": 8,
"data": {
"families": [
"image"
],
"time": "20211112T192359Z",
"author": "petrk",
"source": "C:/projects_local/petr_test/assets/locations/Town/work/art/petr_test_Town_art_v005.psd",
"comment": "",
"machine": "LAPTOP-UB778LHG",
"fps": 25.0,
"intent": "-",
"inputLinks": [
{
"type": "reference",
"id": {
"$oid": "5f3cd2d530a94638544837c3"
},
"linkedBy": "publish"
}
]
},
"depth": 0
},
{
"_id": {
"$oid": "5f3cd2d530a94638544837c3"
},
"schema": "pype:version-3.0",
"type": "version",
"parent": {
"$oid": "5f3a714030a9464bfc7d2382"
},
"name": 7,
"data": {
"families": [
"image"
],
"time": "20200819T092032Z",
"author": "petrk",
"source": "/c/projects/petr_test/assets/characters/Hero/work/art/Hero_v019.psd",
"comment": "",
"machine": "LAPTOP-UB778LHG",
"fps": null
},
"depth": 1
}
]
}
]

11
tests/unit/test_unzip.py Normal file
View file

@ -0,0 +1,11 @@
from openpype.hosts.harmony.api.lib import _ZipFile
from pathlib import Path
def test_zip():
source = "c:/Users/petrk/Downloads/fbb_fbb100_sh0020_workfileAnimation_v010.zip"
dest = "c:/projects/temp/unzipped_with_python_111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\\2222222222222222222222222222222222222222222222222222222222222222222222222222222222"
dest = Path(dest)
with _ZipFile(source, "r") as zip_ref:
zip_ref.extractall(dest.as_posix())

1
vendor/configs/OpenColorIO-Configs vendored Submodule

@ -0,0 +1 @@
Subproject commit 0bb079c08be410030669cbf5f19ff869b88af953

1133
vendor/instance.json vendored Normal file

File diff suppressed because it is too large Load diff

1
vendor/response.json vendored Normal file
View file

@ -0,0 +1 @@
{status: 200, headers: {'date': 'Tue, 11 Jan 2022 11:08:57 GMT', 'server': 'Apache', 'x-powered-by': 'HHVM/4.128.0', 'access-control-allow-origin': '*', 'referrer-policy': 'no-referrer', 'x-slack-backend': 'r', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'access-control-allow-headers': 'slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled, x-b3-flags', 'access-control-expose-headers': 'x-slack-req-id, retry-after', 'x-oauth-scopes': 'chat:write,chat:write.public,files:write,chat:write.customize', 'x-accepted-oauth-scopes': 'chat:write', 'expires': 'Mon, 26 Jul 1997 05:00:00 GMT', 'cache-control': 'private, no-cache, no-store, must-revalidate', 'pragma': 'no-cache', 'x-xss-protection': '0', 'x-content-type-options': 'nosniff', 'x-slack-req-id': '9d1d11399a44c8751f89bb4dcd2b91fb', 'vary': 'Accept-Encoding', 'content-type': 'application/json; charset=utf-8', 'x-envoy-upstream-service-time': '52', 'x-backend': 'main_normal main_bedrock_normal_with_overflow main_canary_with_overflow main_bedrock_canary_with_overflow main_control_with_overflow main_bedrock_control_with_overflow', 'x-server': 'slack-www-hhvm-main-iad-qno3', 'x-slack-shared-secret-outcome': 'no-match', 'via': 'envoy-www-iad-omsy, envoy-edge-iad-bgfx', 'x-edge-backend': 'envoy-www', 'x-slack-edge-shared-secret-outcome': 'no-match', 'connection': 'close', 'transfer-encoding': 'chunked'}, body: {"ok":true,"channel":"C024DUFM8MB","ts":"1641899337.001100","message":{"type":"message","subtype":"bot_message","text":"RenderCompositingDefault published for Jungle\n\nHere should be link to review C:\\projects\\petr_test\\assets\\locations\\Jungle\\publish\\render\\renderCompositingDefault\\v253\\petr_test_Jungle_renderCompositingDefault_v253_h264.mp4\n\n Attachment links: \n\n<https:\/\/pypeclub.slack.com\/files\/U0256Q9CX7S\/F02TVM24PTK\/petr_test_jungle_rendercompositingdefault_v253.jpg|petr_test_Jungle_renderCompositingDefault_v253.jpg>","ts":"1641899337.001100","username":"OpenPypeNotifier","icons":{"image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/bot_icons\/2022-01-07\/2934353684385_48.png"},"bot_id":"B024H0P0CAE"}}

46
vendor/temp.json vendored Normal file
View file

@ -0,0 +1,46 @@
{
project(name: "demo_Big_Episodic") {
representations(
first: 0,
after: 0,
localSite: "local",
remoteSite: "local"
) {
edges {
node {
id
name
# Sorry: totalSize is not implemented, but it will be
# totalSize
fileCount
# overal sync state
localState{
status
size
timestamp
}
remoteState{
status
size
timestamp
}
# crawl to the top to get parent info
version {
version
subset {
family
name
folder {
name
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}