mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
OP-4181 - clean up after review comments
This commit is contained in:
parent
640971a49b
commit
a7150bd6f1
17 changed files with 2982 additions and 3 deletions
BIN
igniter/GPUCache/data_0
Normal file
BIN
igniter/GPUCache/data_0
Normal file
Binary file not shown.
BIN
igniter/GPUCache/data_1
Normal file
BIN
igniter/GPUCache/data_1
Normal file
Binary file not shown.
BIN
igniter/GPUCache/data_2
Normal file
BIN
igniter/GPUCache/data_2
Normal file
Binary file not shown.
BIN
igniter/GPUCache/data_3
Normal file
BIN
igniter/GPUCache/data_3
Normal file
Binary file not shown.
BIN
igniter/GPUCache/index
Normal file
BIN
igniter/GPUCache/index
Normal file
Binary file not shown.
35
openpype/hooks/pre_python2_prelaunch.py
Normal file
35
openpype/hooks/pre_python2_prelaunch.py
Normal 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)
|
||||
51
openpype/hosts/photoshop/tests/expr.py
Normal file
51
openpype/hosts/photoshop/tests/expr.py
Normal 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
1
openpype/lib/token
Normal file
|
|
@ -0,0 +1 @@
|
|||
5d58370a7702b2efee5120704246baf4abb865323fc9db9a04827bfb478569d6
|
||||
275
openpype/modules/ftrack/event_handlers_user/action_edl_create.py
Normal file
275
openpype/modules/ftrack/event_handlers_user/action_edl_create.py
Normal 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)
|
||||
1330
openpype/pipeline/temp_anatomy.py
Normal file
1330
openpype/pipeline/temp_anatomy.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
11
tests/unit/test_unzip.py
Normal 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
1
vendor/configs/OpenColorIO-Configs
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 0bb079c08be410030669cbf5f19ff869b88af953
|
||||
1133
vendor/instance.json
vendored
Normal file
1133
vendor/instance.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
vendor/response.json
vendored
Normal file
1
vendor/response.json
vendored
Normal 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
46
vendor/temp.json
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue