Skip to content

Instantly share code, notes, and snippets.

@jminor
Created May 12, 2022 22:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jminor/4ab918836f1dba78789b29e0479931ca to your computer and use it in GitHub Desktop.
Save jminor/4ab918836f1dba78789b29e0479931ca to your computer and use it in GitHub Desktop.
Proof-of-concept OpenTimelineIO schema downgrader
#!/usr/bin/env python
#
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the OpenTimelineIO project
#
# This file is for discussion regarding this OpenTimelineIO issue:
# https://github.com/PixarAnimationStudios/OpenTimelineIO/issues/1295
"""Experimental tool to downgrade an OTIO file.
"""
import argparse
import json
import sys
import os
from urllib.parse import urlparse
def parse_args():
"""parse arguments out of sys.argv"""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-i", "--input", type=str, required=True, help="File to read.")
parser.add_argument("-o", "--output", type=str, help="File to write.")
parser.add_argument(
"-d",
"--dryrun",
action="store_true",
default=False,
help="Print changes without saving anything.",
)
args = parser.parse_args()
if not (args.output or args.dryrun):
print("ERROR: You must specify either --output or --dryrun")
sys.exit(1)
return args
def downgrade_Example_7(example):
"""Downgrade an Example.7 to Example.6"""
example['OTIO_SCHEMA'] = 'Example.6'
example['old_field'] = example.get('modern_field', 'default value')
del example['modern_field']
# Chain to the next downgrader, if needed
return downgrade_Example_6(example)
def downgrade_Clip_2(clip):
"""Downgrade a Clip.2 to Clip.1 by retaining only the active media reference."""
key = clip.get('active_media_reference_key', 'DEFAULT_MEDIA')
media_ref = clip.get('media_references', {}).get(key)
# Should we stash the lost media references into metadata?
clip['metadata']['otio-schema-downgrader'] = {
'downgraded_from': clip['OTIO_SCHEMA'],
'lost_values': {
'active_media_reference_key': key,
'media_references': clip.get('media_references')
}
}
# Modify the clip
clip['OTIO_SCHEMA'] = 'Clip.1'
clip['media_reference'] = media_ref
del clip['media_references']
del clip['active_media_reference_key']
# NOTE: We can leave 'enabled' as-is. That was added after Clip.1,
# but didn't warrant an upgrade to Clip.2 because it was purely additive.
# del clip['enabled']
return clip
def downgrade(data):
if isinstance(data, dict):
schema = data.get('OTIO_SCHEMA')
if schema:
# This is an OTIO schema object.
# Check it's version
schema_name, version = schema.split('.')
# Is there a downgrade function for this?
downgrader_name = 'downgrade_{}_{}'.format(schema_name, version)
downgrader_fn = globals().get(downgrader_name)
if downgrader_fn:
# Call the downgrade function
data = downgrader_fn(data)
# TODO: Should this happen before or after the downgrade?
for key, val in data.items():
data[key] = downgrade(val)
elif isinstance(data, list):
for i, val in enumerate(data):
data[i] = downgrade(val)
return data
def main():
args = parse_args()
input_text = open(args.input).read()
input_data = json.loads(input_text)
output_data = downgrade(input_data)
output_text = json.dumps(
output_data,
indent = 4,
# sort_keys = True
)
if args.dryrun:
print(output_text)
else:
open(args.output, "w").write(output_text)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment