diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 8cc2a25..0000000 --- a/.coveragerc +++ /dev/null @@ -1,8 +0,0 @@ -[run] -disable_warnings = - DeprecationWarning - -[report] - -omit = - keynote_parser/generated/* diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index ebe7bd6..38cac32 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} @@ -32,13 +32,13 @@ jobs: echo "::set-env name=PATH::$PATH:$PWD/protoc/bin/" sudo apt-get install -qq libsnappy-dev python -m pip install --upgrade pip - pip install ruff pytest + pip install ruff pytest rich 'protobuf>=3.20.0rc1,<4' pip install -r requirements.txt env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - - name: Build package - run: make + - name: Build gencode + run: PYTHONPATH=$PYTHONPATH:$(pwd) python3 dumper/run.py - name: Lint with ruff - run: ruff check . --exclude keynote_parser/generated + run: ruff check . - name: Test with pytest - run: PYTHONPATH=$PYTHONPATH:$(pwd) pytest --cov=keynote_parser + run: PYTHONPATH=$PYTHONPATH:$(pwd) pytest diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index fca6696..36eb471 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -28,12 +28,15 @@ jobs: sudo apt-get install -qq libsnappy-dev pip install -r requirements.txt python -m pip install --upgrade pip - pip install setuptools wheel twine + pip install setuptools wheel twine build rich 'protobuf>=3.20.0rc1,<4' - name: Build and publish env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} run: | - make - python setup.py sdist bdist_wheel + # Build the gencode: + PYTHONPATH=$PYTHONPATH:$(pwd) python3 dumper/run.py + # Build the package: + python -m build + # Upload the package: twine upload dist/* diff --git a/.gitignore b/.gitignore index 588f68d..a659625 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ __pycache__/ *.py[cod] *$py.class -keynote_parser/generated/ +keynote_parser/versions/v*/generated/ # C extensions *.so @@ -115,4 +115,6 @@ venv.bak/ dmypy.json # Pyre type checker -.pyre/ \ No newline at end of file +.pyre/ + +uv.lock diff --git a/Makefile b/Makefile deleted file mode 100644 index 8e7d5d5..0000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -PROTO_SOURCES = $(wildcard protos/*.proto) -PROTO_CLASSES = $(patsubst protos/%.proto,keynote_parser/generated/%_pb2.py,$(PROTO_SOURCES)) - -.PHONY: all clean install test - -all: $(PROTO_CLASSES) keynote_parser/generated/__init__.py - -install: $(PROTO_CLASSES) keynote_parser/generated/__init__.py keynote_parser/* - python3 setup.py install - -upload: $(PROTO_CLASSES) keynote_parser/generated/__init__.py keynote_parser/* - python3 setup.py upload - -keynote_parser/generated: - mkdir -p keynote_parser/generated - -keynote_parser/generated/%_pb2.py: protos/%.proto keynote_parser/generated - protoc -I=protos --proto_path protos --python_out=keynote_parser/generated $< - -keynote_parser/generated/__init__.py: keynote_parser/generated $(PROTO_CLASSES) - touch $@ - python3 dumper/rewrite_imports.py keynote_parser/generated/*.py - -clean: - rm -rf keynote_parser/generated - rm -rf keynote_parser.egg_info - rm -rf dist - -test: all - python3 -m pytest . --cov=keynote_parser -W ignore::DeprecationWarning diff --git a/dumper/Makefile b/dumper/Makefile deleted file mode 100644 index 88e50ce..0000000 --- a/dumper/Makefile +++ /dev/null @@ -1,53 +0,0 @@ - -.PHONY=clean all - -# Find whichever version of Python is installed in the LLVM directory: -LLVM_DIR := /opt/homebrew/opt/llvm/ -# Error if LLVM_DIR is not set: -ifeq ($(LLVM_DIR),) -$(error LLVM_DIR is not set) -endif -LLVM_PYTHON_PATH := $(shell find $(LLVM_DIR) -name "python3.*" | head -n 1) -ifeq ($(LLVM_PYTHON_PATH),) -$(error LLVM_PYTHON_PATH is not set) -endif -LLVM_PYTHON := $(shell basename $(LLVM_PYTHON_PATH)) -ifeq ($(LLVM_PYTHON),) -$(error LLVM_PYTHON is not set) -endif - -# TODO: Verify that this identity is valid and not expired; this causes silent failures. -IDENTITY := $(shell security find-identity -v -p codesigning | head -n 1 | uv run python -c 'import sys; print(sys.stdin.read().split("\"")[1])') - -all: mapping.py proto - -mapping.json: Keynote.unsigned.app/Contents/MacOS/Keynote ./extract_mapping.py - PYTHONPATH=${LLVM_PYTHON_PATH}/site-packages xcrun $(LLVM_PYTHON) ./extract_mapping.py Keynote.unsigned.app/Contents/MacOS/Keynote --output $@ - rm -rf Keynote.unsigned.app - -proto: /Applications/Keynote.app - uv run protodump.py /Applications/Keynote.app ./proto/ - # Note that if any of the incoming Protobuf definitions contain periods, - # protoc will put them into their own Python packages. This is not desirable - # for import rules in Python, so we replace non-final period characters with - # underscores. - uv run ./rename_proto_files.py proto - cp ./proto/*.proto ../protos/ - rm -rfv proto - -Keynote.unsigned.app/Contents/MacOS/Keynote: /Applications/Keynote.app - cp -r /Applications/Keynote.app ./Keynote.unsigned.app - codesign --remove-signature --verbose ./Keynote.unsigned.app/Contents/MacOS/Keynote - codesign --sign "${IDENTITY}" --verbose ./Keynote.unsigned.app/Contents/MacOS/Keynote - -mapping.py: mapping.json - uv run generate_mapping.py - mv mapping.py ../keynote_parser/mapping.py - echo "mapping.py generated (size: $(shell wc -c < mapping.py) bytes); the dumper worked!" - rm -rf mapping.json - -clean: - rm -rf Keynote.unsigned.app - rm -rf mapping.json - rm -rf mapping.py - rm -rf proto diff --git a/dumper/__init__.py b/dumper/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dumper/extract_mapping.py b/dumper/extract_mapping.py index cf9ac96..73b5bae 100755 --- a/dumper/extract_mapping.py +++ b/dumper/extract_mapping.py @@ -11,11 +11,11 @@ import argparse import enum import json +import logging import os +import sys import time -import lldb - class StateType(enum.Enum): Invalid = 0 @@ -26,6 +26,10 @@ class StateType(enum.Enum): Stopped = 5 Running = 6 Stepping = 7 + Crashed = 8 + Detached = 9 + Exited = 10 + Suspended = 11 class StopReason(enum.Enum): @@ -59,43 +63,85 @@ def main(): args = parser.parse_args() if os.path.exists(args.output): - print(f"Removing output file {args.output}...") + logging.info(f"Removing output file {args.output}...") os.remove(args.output) - print("Creating debugger...") + mapping = extract_mapping(args.exe) + with open(args.output, "w") as f: + json.dump(mapping, f, indent=2) + + +def extract_mapping(exe: str) -> dict[int, str]: + # Add the installed LLVM Python path to the Python path and error if the Python version does not match: + # i.e.: /opt/homebrew/opt/llvm/libexec/python3.13/site-packages + LLVM_PYTHON_ROOT = "/opt/homebrew/opt/llvm/libexec" + if not os.path.exists(LLVM_PYTHON_ROOT): + raise ImportError( + f"{LLVM_PYTHON_ROOT} does not exist. Please install LLVM/LLDB first." + ) + + existing_versions = [ + x for x in os.listdir(LLVM_PYTHON_ROOT) if x.startswith("python") + ] + + THIS_PYTHON_LLVM_PATH = f"{LLVM_PYTHON_ROOT}/python{sys.version_info.major}.{sys.version_info.minor}/site-packages" + if not os.path.exists(THIS_PYTHON_LLVM_PATH): + raise ImportError( + "Your system has LLVM/LLDB installed, but it is not the same version as the Python interpreter " + f"you are using; found: {', '.join(existing_versions)}, but the current Python version is " + f"{sys.version_info.major}.{sys.version_info.minor}. Please install the same " + "version of LLVM/LLDB as your Python interpreter." + ) + + sys.path.append(THIS_PYTHON_LLVM_PATH) + + import lldb + + logging.info("Creating debugger...") debugger = lldb.SBDebugger.Create() debugger.SetAsync(False) - print(f"Creating target of {args.exe}...") - target = debugger.CreateTargetWithFileAndArch(args.exe, None) - print("Setting breakpoint for _sendFinishLaunchingNotification...") + logging.info(f"Creating target of {exe}...") + target = debugger.CreateTargetWithFileAndArch(exe, None) + logging.info("Setting breakpoint for _sendFinishLaunchingNotification...") target.BreakpointCreateByName("_sendFinishLaunchingNotification") - print("Setting breakpoint for _handleAEOpenEvent:...") + logging.info("Setting breakpoint for _handleAEOpenEvent:...") target.BreakpointCreateByName("_handleAEOpenEvent:") - print("Setting breakpoint for [CKContainer containerWithIdentifier:]...") + logging.info("Setting breakpoint for [CKContainer containerWithIdentifier:]...") # let's break in the CloudKit code and early exit the function before it can raise an exception: target.BreakpointCreateByName("[CKContainer containerWithIdentifier:]") - print("Setting breakpoint for ___lldb_unnamed_symbol[0-9]+...") + logging.info("Setting breakpoint for ___lldb_unnamed_symbol[0-9]+...") # In later Keynote versions, 'containerWithIdentifier' isn't called directly, but we can break on similar methods: # Note: this __lldb_unnamed_symbol hack was determined by painstaking experimentation. It will break again for sure. target.BreakpointCreateByRegex("___lldb_unnamed_symbol[0-9]+", "CloudKit") - print("Launching process...") + logging.info("Launching process...") process = target.LaunchSimple(None, None, os.getcwd()) if not process: - raise ValueError("Failed to launch process: " + args.exe) + raise ValueError(f"Failed to launch process: {exe}") try: - print("Waiting for process to stop on a breakpoint...") - while process.GetState() != lldb.eStateStopped: - print(f"Current state: {StateType(process.GetState())}") + logging.info("Waiting for process to stop on a breakpoint...") + while ( + process.GetState() != lldb.eStateStopped + and process.GetState() != lldb.eStateExited + ): + logging.info(f"Current state: {StateType(process.GetState())}") time.sleep(0.1) + if process.GetState() == lldb.eStateExited: + raise ValueError( + "Process exited before stopping on a breakpoint. " + "Ensure the process is properly code signed." + ) + while process.GetState() == lldb.eStateStopped: thread = process.GetThreadAtIndex(0) - print(f"Thread: {thread} stopped at: {StopReason(thread.GetStopReason())}") + logging.info( + f"Thread: {thread} stopped at: {StopReason(thread.GetStopReason())}" + ) match thread.GetStopReason(): case lldb.eStopReasonBreakpoint: if any( @@ -113,7 +159,7 @@ def main(): else: break case lldb.eStopReasonException: - print(repr(thread) + "\n") + logging.info(repr(thread) + "\n") raise NotImplementedError( f"LLDB caught exception, {__file__} needs to be updated to handle." ) @@ -134,11 +180,8 @@ def main(): if x.strip() ] mapping = [(int(a), b.split(" ")[-1]) for a, b in split if "null" not in b] - print(f"Extracted mapping with {len(mapping):,} elements.") - results = json.dumps(dict(sorted(mapping)), indent=2) - with open(args.output, "w") as f: - f.write(results) - print(f"Wrote {len(results):,} bytes of mapping to {args.output}.") + logging.info(f"Extracted mapping with {len(mapping):,} elements.") + return dict(sorted(mapping)) finally: process.Kill() diff --git a/dumper/generate_mapping.py b/dumper/generate_mapping.py index 594686e..3a35461 100644 --- a/dumper/generate_mapping.py +++ b/dumper/generate_mapping.py @@ -1,3 +1,4 @@ +import argparse import glob import json import os @@ -23,46 +24,65 @@ def compute_maps(): """ -def main(): - output_filename = "mapping.py" - mapping_filename = "mapping.json" +def generate_mapping(mapping: dict[int, str], proto_dir: str) -> str: + lines = [] + lines.append(f"# Generated code! Edit {__file__} instead.") + lines.append("") - with open(output_filename, "w") as f: - f.write(f"# Generated code! Edit {__file__} instead.\n") - f.write("\n") + lines.append("from __future__ import absolute_import") - f.write("from __future__ import absolute_import\n") - f.write("\n") + proto_files = sorted( + [ + os.path.basename(path) + for path in glob.glob(os.path.join(proto_dir, "*.proto")) + ] + ) - proto_files = sorted( + proto_identifiers = sorted( + set( [ - os.path.basename(path) - for path in glob.glob(os.path.join("..", "protos", "*.proto")) + proto_file.replace(".proto", "").replace(".", "_") + for proto_file in proto_files ] ) + ) + + for identifier in proto_identifiers: + lines.append(f"from .generated import {identifier}_pb2 as {identifier}") + + lines.append("\n") - for proto_file in proto_files: - f.write( - f"from .generated import {proto_file.replace('.proto', '')}_pb2 as" - f" {proto_file.replace('.proto', '')}\n" - ) + lines.append("PROTO_FILES = [") + for identifier in proto_identifiers: + lines.append(f"\t{identifier},") + lines.append("]") + lines.append("") - f.write("\n\n") + lines.append(f"TSPRegistryMapping = {repr(mapping)}") - f.write("PROTO_FILES = [\n") - for proto_file in proto_files: - f.write(f"\t{proto_file.replace('.proto', '')},\n") - f.write("]\n") - f.write("\n") + lines.append(RUNTIME_CODE) - with open(mapping_filename) as mapping_file: - mapping_file_contents = mapping_file.read() - if mapping_file_contents == "": - raise ValueError(f"Mapping file {mapping_filename} is empty.") - mapping_file_contents = json.loads(mapping_file_contents) - f.write(f"TSPRegistryMapping = {repr(mapping_file_contents)}\n") + return "\n".join(lines) - f.write(RUNTIME_CODE) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("mapping_filename", type=str, help="Path to the mapping file.") + parser.add_argument( + "proto_dir", + type=str, + help="Path to a directory containing proto files referenced by the mapping.", + ) + parser.add_argument( + "output_filename", + type=str, + help="Path to the output file to write to. Will be overwritten.", + ) + args = parser.parse_args() + + mapping = json.load(open(args.mapping_filename)) + with open(args.output_filename, "w") as f: + f.write(generate_mapping(mapping, args.proto_dir)) if __name__ == "__main__": diff --git a/dumper/protodump.py b/dumper/protodump.py index 51fbe62..e1cbdb7 100644 --- a/dumper/protodump.py +++ b/dumper/protodump.py @@ -14,6 +14,7 @@ Inspired by Sean Patrick O'Brien (@obriensp)'s 2013 "proto-dump": https://github.com/obriensp/proto-dump """ +import logging from collections import defaultdict from pathlib import Path from typing import List @@ -22,7 +23,6 @@ from google.protobuf.descriptor_pool import DescriptorPool from google.protobuf.internal.decoder import SkipField, _DecodeVarint from google.protobuf.message import DecodeError -from rich import print from rich.progress import track PROTO_TYPES = { @@ -319,14 +319,19 @@ def main(): ) args = parser.parse_args() + + extract_proto_files(args.input_path, args.output_path) + + +def extract_proto_files(input_path: str, output_path: str): GLOBAL_DESCRIPTOR_POOL = DescriptorPool() all_filenames = [ - str(path) for path in Path(args.input_path).rglob("*") if not path.is_dir() + str(path) for path in Path(input_path).rglob("*") if not path.is_dir() ] - print( - f"Scanning {len(all_filenames):,} files under {args.input_path} for protobuf definitions..." + logging.info( + f"Scanning {len(all_filenames):,} files under {input_path} for protobuf definitions..." ) proto_files_found = set() @@ -334,7 +339,9 @@ def main(): for proto in extract_proto_from_file(path, GLOBAL_DESCRIPTOR_POOL): proto_files_found.add(proto) - print(f"Found what look like {len(proto_files_found):,} protobuf definitions.") + logging.info( + f"Found what look like {len(proto_files_found):,} protobuf definitions." + ) missing_deps = set() for found in proto_files_found: @@ -350,28 +357,28 @@ def main(): if missing_deps: missing_deps = sorted(missing_deps, key=str) if not proto_files_found: - print( + logging.error( f"All {len(missing_deps):,} proto files could not be found:\n" + "\n".join(f"\t{d}" for d in missing_deps) ) else: all_possible = set(proto_files_found) | set(missing_deps) - print( + logging.error( f"Unable to print out {len(missing_deps):,} of {len(all_possible):,} " f"Protobuf definitions:\n" + "\n".join(f"\t{d}" for d in missing_deps) ) raise SystemExit(1) else: for proto_file in track(proto_files_found): - Path(args.output_path).mkdir(parents=True, exist_ok=True) - with open(Path(args.output_path) / proto_file.path, "w") as f: + Path(output_path).mkdir(parents=True, exist_ok=True) + with open(Path(output_path) / proto_file.path, "w") as f: source = proto_file.source if source: f.write(source) else: - print(f"Warning: no source available for {proto_file}") - print( - f"Done! Wrote {len(proto_files_found):,} proto files to {args.output_path}." + logging.error(f"Warning: no source available for {proto_file}") + logging.info( + f"Done! Wrote {len(proto_files_found):,} proto files to {output_path}." ) diff --git a/dumper/rename_proto_files.py b/dumper/rename_proto_files.py index 3137307..55668bb 100644 --- a/dumper/rename_proto_files.py +++ b/dumper/rename_proto_files.py @@ -1,3 +1,4 @@ +import logging import os import sys from glob import glob @@ -6,23 +7,24 @@ def rename_proto_files(_dir): replacements = {} for proto_file in glob(os.path.join(_dir, "*.proto")): + proto_file = os.path.basename(proto_file) no_ext = proto_file.replace(".proto", "") replaced = no_ext.replace(".", "_") + ".proto" - replacements[os.path.basename(proto_file)] = os.path.basename(replaced) + replacements[proto_file] = replaced if proto_file != replaced: - os.rename(proto_file, replaced) - print("Renamed %s to %s." % (proto_file, replaced)) + os.rename(os.path.join(_dir, proto_file), os.path.join(_dir, replaced)) + logging.info("Renamed %s to %s." % (proto_file, replaced)) for proto_file in glob(os.path.join(_dir, "*.proto")): - original_contents = open(proto_file).read() + proto_file = os.path.basename(proto_file) + original_contents = open(os.path.join(_dir, proto_file)).read() contents = original_contents for old, new in replacements.items(): contents = contents.replace('import "%s";' % old, 'import "%s";' % new) if contents != original_contents: - with open(proto_file, "w") as f: + with open(os.path.join(_dir, proto_file), "w") as f: f.write(contents) - print("Updated %s." % proto_file) - print("Done!") + logging.info("Updated %s." % proto_file) if __name__ == "__main__": diff --git a/dumper/rewrite_imports.py b/dumper/rewrite_imports.py index bde6b7c..a0d9c37 100644 --- a/dumper/rewrite_imports.py +++ b/dumper/rewrite_imports.py @@ -1,4 +1,6 @@ import argparse +import logging +import os import re REGEX = re.compile(r"^import (.*_pb2) as (.*__pb2)") @@ -7,17 +9,26 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument("files", nargs="+") + parser.add_argument( + "--package-prefix", + help="Prefix to add to the generated package name", + default="keynote_parser.generated", + ) args = parser.parse_args() - for file in args.files: + rewrite_imports(args.files, args.package_prefix) + + +def rewrite_imports(files: list[str], package_prefix: str): + for file in files: with open(file, "r") as f: content = f.read() new_content = [] for line in content.splitlines(): - new_line = REGEX.sub(r"import keynote_parser.generated.\1 as \2", line) + new_line = REGEX.sub(rf"import {package_prefix}.\1 as \2", line) if new_line != line: - print(f"Rewrote {file}: {line} -> {new_line}") + logging.info(f"Rewrote {os.path.basename(file)}: {line} -> {new_line}") new_content.append(new_line) with open(file, "w") as f: f.write("\n".join(new_content)) diff --git a/dumper/run.py b/dumper/run.py new file mode 100644 index 0000000..faae7c8 --- /dev/null +++ b/dumper/run.py @@ -0,0 +1,184 @@ +# /// script +# dependencies = [ +# "protobuf>=3.20.0rc1,<4", +# "rich", +# ] +# /// +""" +Extract iWork protobufs from a .app bundle and dump them into +the appropriate locations in the keynote_parser directory tree. +""" + +import argparse +import glob +import logging +import os +import plistlib +import shutil +import subprocess +import tempfile +from contextlib import contextmanager +from typing import Generator + +from rich.logging import RichHandler + +from dumper.extract_mapping import extract_mapping +from dumper.generate_mapping import generate_mapping +from dumper.protodump import extract_proto_files +from dumper.rename_proto_files import rename_proto_files +from dumper.rewrite_imports import rewrite_imports + +logging.basicConfig( + level="NOTSET", + format="%(message)s", + datefmt="[%X]", + handlers=[RichHandler(markup=True)], +) + + +@contextmanager +def unsigned_copy_of(app_path: str) -> Generator[str, None, None]: + app_name = os.path.basename(app_path).replace(".app", "") + unsigned_app_bundle_filename = f"{app_name}.unsigned.app" + + # Get the identity from the system: + logging.info("Getting codesigning identity...") + identity = subprocess.check_output( + ["security", "find-identity", "-v", "-p", "codesigning"] + ).decode() + identity = identity.split('"')[1] + if not identity: + raise ValueError( + "No codesigning identity found; please create one in Keychain Access first." + ) + logging.info(f"Resigning {app_path} with local codesigning identity: {identity!r}") + + with tempfile.TemporaryDirectory() as temp_dir: + target = os.path.join(temp_dir, unsigned_app_bundle_filename) + logging.info(f"Copying {app_path} to {target}...") + shutil.copytree(app_path, target) + logging.info(f"Removing signature from {target}...") + subprocess.run( + [ + "codesign", + "--remove-signature", + "--verbose", + os.path.join(target, "Contents", "MacOS", app_name), + ] + ) + # Resign the app with the local identity: + logging.info( + f"Resigning {target} with local codesigning identity: {identity!r}" + ) + subprocess.run( + [ + "codesign", + "--sign", + identity, + "--verbose", + os.path.join(target, "Contents", "MacOS", app_name), + ] + ) + logging.info(f"Successfully re-signed {target}.") + yield target + logging.info(f"Cleaning up {target}...") + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--app-path", + type=str, + default=None, + help="Path to the .app bundle. If not provided, only the proto compilation step will be done.", + ) + args = parser.parse_args() + + repo_root_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + if args.app_path: + logging.info(f"Running dumper on {args.app_path}...") + + # Step 0: Get the version of the app to use as the output directory name. + version_plist = plistlib.load( + open(os.path.join(args.app_path, "Contents", "version.plist"), "rb") + ) + version = version_plist["CFBundleShortVersionString"] + bundle_version = version_plist["CFBundleVersion"] + build_version = version_plist["ProductBuildVersion"] + python_identifier_version = "v" + version.replace(".", "_") + + logging.info(f"Version: {version}") + + proto_output_directory = os.path.join( + repo_root_directory, "protos", "versions", version + ) + os.makedirs(proto_output_directory, exist_ok=True) + + # Remove the existing output directory if it exists. + gencode_output_directory = os.path.join( + repo_root_directory, "keynote_parser", "versions", python_identifier_version + ) + os.makedirs(gencode_output_directory, exist_ok=True) + + logging.info(f"Proto output directory: {proto_output_directory}") + # Step 1: Extract the protobuf files from the app bundle if we don't have them yet. + if not glob.glob(os.path.join(proto_output_directory, "*.proto")): + extract_proto_files(args.app_path, proto_output_directory) + + # Step 2: Extract the proto type mapping from the app bundle. + if not os.path.exists(os.path.join(gencode_output_directory, "mapping.py")): + with unsigned_copy_of(args.app_path) as temp_dir: + mapping = extract_mapping(temp_dir) + + # Step 3: Generate the mapping.py file from the generated mapping. + mapping_py_contents = generate_mapping(mapping, proto_output_directory) + with open(os.path.join(gencode_output_directory, "mapping.py"), "w") as f: + f.write(mapping_py_contents) + with open(os.path.join(gencode_output_directory, "__init__.py"), "w") as f: + f.write( + "from keynote_parser.macos_app_version import MacOSAppVersion\n\n" + f"VERSION = MacOSAppVersion({version!r}, {bundle_version!r}, {build_version!r})\n\n" + ) + + # Step 4: Rename the proto files: + rename_proto_files(proto_output_directory) + + # Step 5: Run protoc on the proto files in each version directory: + for version_directory in glob.glob( + os.path.join(repo_root_directory, "protos", "versions", "*") + ): + version = os.path.basename(version_directory) + python_identifier_version = "v" + version.replace(".", "_") + gencode_version_directory = os.path.join( + repo_root_directory, "keynote_parser", "versions", python_identifier_version + ) + gencode_proto_output_directory = os.path.join( + gencode_version_directory, "generated" + ) + os.makedirs(gencode_proto_output_directory, exist_ok=True) + subprocess.run( + [ + "protoc", + "--proto_path", + version_directory, + "--python_out", + gencode_proto_output_directory, + ] + + glob.glob(os.path.join(version_directory, "*.proto")), + ) + # Step 6: Touch init.py in the generated code directory. + open(os.path.join(gencode_proto_output_directory, "__init__.py"), "w").close() + + # Step 7: Rewrite the imports in the generated code. + rewrite_imports( + glob.glob(os.path.join(gencode_proto_output_directory, "*.py")), + f"keynote_parser.versions.{python_identifier_version}.generated", + ) + + logging.info(f"Dumped {version} to {gencode_proto_output_directory}.") + logging.info("Done!") + + +if __name__ == "__main__": + main() diff --git a/keynote_parser/__init__.py b/keynote_parser/__init__.py index 47814dc..019bdab 100644 --- a/keynote_parser/__init__.py +++ b/keynote_parser/__init__.py @@ -3,13 +3,12 @@ __author__ = "Peter Sobot" -import keynote_parser.macos_app_version +from keynote_parser.versions import VERSIONS __major_version__ = 1 __patch_version__ = 0 -__supported_keynote_version__ = keynote_parser.macos_app_version.MacOSAppVersion( - "14.4", "7043.0.93", "1A89s" -) + +__supported_keynote_version__ = max(VERSIONS) __version_tuple__ = ( __major_version__, __supported_keynote_version__.major, diff --git a/keynote_parser/codec.py b/keynote_parser/codec.py index 545f6a1..499673e 100644 --- a/keynote_parser/codec.py +++ b/keynote_parser/codec.py @@ -1,3 +1,4 @@ +import importlib import struct import sys import traceback @@ -10,12 +11,33 @@ from google.protobuf.json_format import MessageToDict, ParseDict from google.protobuf.message import EncodeError -from .generated.TSPArchiveMessages_pb2 import ArchiveInfo -from .mapping import ID_NAME_MAP, NAME_CLASS_MAP +from keynote_parser.versions import LATEST_VERSION as LATEST_VERSION_OBJECT + +LATEST_VERSION = LATEST_VERSION_OBJECT.short_version_string MAX_FLOAT = 340282346638528859811704183484516925440.000000000000000000 +def import_version(version: str = LATEST_VERSION): + try: + mapping = importlib.import_module( + f"keynote_parser.versions.v{version.replace('.', '_')}.mapping" + ) + except ImportError: + raise KeyError(f"Mapping for version {version} not found.") + try: + tsp_archive_messages_pb2 = importlib.import_module( + f"keynote_parser.versions.v{version.replace('.', '_')}.generated.TSPArchiveMessages_pb2" + ) + except ImportError: + raise KeyError(f"Archive for version {version} not found.") + return ( + mapping.ID_NAME_MAP, + mapping.NAME_CLASS_MAP, + tsp_archive_messages_pb2.ArchiveInfo, + ) + + class IWAFile(object): def __init__(self, chunks, filename=None): self.chunks = chunks @@ -136,7 +158,7 @@ def to_dict(self): return message_to_dict(self.data) @classmethod - def FromString(cls, message_info, proto_klass, data): + def FromString(cls, message_info, proto_klass, data, version: str = LATEST_VERSION): if len(message_info.diff_field_path.path) != 1: raise NotImplementedError( "Not sure how to deserialize ProtobufPatch without exactly one diff_field_path. " @@ -149,7 +171,9 @@ def FromString(cls, message_info, proto_klass, data): ) for diff_path in message_info.diff_field_path.path: patched_field = proto_klass.DESCRIPTOR.fields_by_number[diff_path] - field_message_class = NAME_CLASS_MAP[patched_field.message_type.full_name] + field_message_class = import_version(version)[1][ + patched_field.message_type.full_name + ] return cls(field_message_class.FromString(data)) def SerializeToString(self): @@ -172,8 +196,8 @@ def __repr__(self): ) @classmethod - def from_buffer(cls, buf, filename=None): - archive_info, payload = get_archive_info_and_remainder(buf) + def from_buffer(cls, buf, filename=None, version: str = LATEST_VERSION): + archive_info, payload = get_archive_info_and_remainder(buf, version=version) if not repr(archive_info): raise ValueError("Segment doesn't seem to start with an ArchiveInfo!") @@ -189,10 +213,10 @@ def from_buffer(cls, buf, filename=None): klass = partial( ProtobufPatch.FromString, message_info, - ID_NAME_MAP[base_message.type], + import_version(version)[0][base_message.type], ) else: - klass = ID_NAME_MAP[message_info.type] + klass = import_version(version)[0][message_info.type] except KeyError: raise NotImplementedError( "Don't know how to parse Protobuf message type " @@ -215,7 +239,7 @@ def from_buffer(cls, buf, filename=None): return cls(archive_info, payloads), payload[n:] @classmethod - def from_dict(cls, _dict): + def from_dict(cls, _dict, version: str = LATEST_VERSION): header = dict_to_header(_dict["header"]) objects = [] for message_info, o in zip(header.message_infos, _dict["objects"]): @@ -223,7 +247,7 @@ def from_dict(cls, _dict): base_message_info = header.message_infos[ message_info.base_message_index ] - message_class = ID_NAME_MAP[base_message_info.type] + message_class = import_version(version)[0][base_message_info.type] objects.append(ProtobufPatch(message_class, o)) else: objects.append(dict_to_message(o)) @@ -286,11 +310,13 @@ def _work_around_protobuf_max_float_handling(_dict): return _dict -def dict_to_message(_dict): +def dict_to_message(_dict, version: str = LATEST_VERSION): _type = _dict["_pbtype"] del _dict["_pbtype"] _dict = _work_around_protobuf_max_float_handling(_dict) - return ParseDict(_dict, NAME_CLASS_MAP[_type](), ignore_unknown_fields=True) + return ParseDict( + _dict, import_version(version)[1][_type](), ignore_unknown_fields=True + ) def dict_to_header(_dict): @@ -300,12 +326,12 @@ def dict_to_header(_dict): return dict_to_message(_dict) -def get_archive_info_and_remainder(buf): +def get_archive_info_and_remainder(buf, version: str = LATEST_VERSION): msg_len, new_pos = _DecodeVarint32(buf, 0) n = new_pos msg_buf = buf[n : n + msg_len] n += msg_len - return ArchiveInfo.FromString(msg_buf), buf[n:] + return import_version(version)[2].FromString(msg_buf), buf[n:] if __name__ == "__main__": diff --git a/keynote_parser/mapping.py b/keynote_parser/mapping.py deleted file mode 100644 index face11d..0000000 --- a/keynote_parser/mapping.py +++ /dev/null @@ -1,728 +0,0 @@ -# Generated code! Edit /Users/psobot/Code/keynote-parser/dumper/generate_mapping.py instead. - -from __future__ import absolute_import - -from .generated import KNArchives_pb2 as KNArchives -from .generated import KNArchives_sos_pb2 as KNArchives_sos -from .generated import KNCommandArchives_pb2 as KNCommandArchives -from .generated import KNCommandArchives_sos_pb2 as KNCommandArchives_sos -from .generated import TSAArchives_pb2 as TSAArchives -from .generated import TSAArchives_sos_pb2 as TSAArchives_sos -from .generated import TSACommandArchives_sos_pb2 as TSACommandArchives_sos -from .generated import TSCEArchives_pb2 as TSCEArchives -from .generated import TSCH3DArchives_pb2 as TSCH3DArchives -from .generated import TSCHArchives_pb2 as TSCHArchives -from .generated import TSCHArchives_Common_pb2 as TSCHArchives_Common -from .generated import TSCHArchives_GEN_pb2 as TSCHArchives_GEN -from .generated import TSCHArchives_sos_pb2 as TSCHArchives_sos -from .generated import TSCHCommandArchives_pb2 as TSCHCommandArchives -from .generated import TSCHPreUFFArchives_pb2 as TSCHPreUFFArchives -from .generated import TSCKArchives_pb2 as TSCKArchives -from .generated import TSCKArchives_sos_pb2 as TSCKArchives_sos -from .generated import TSDArchives_pb2 as TSDArchives -from .generated import TSDArchives_sos_pb2 as TSDArchives_sos -from .generated import TSDCommandArchives_pb2 as TSDCommandArchives -from .generated import TSKArchives_pb2 as TSKArchives -from .generated import TSKArchives_sos_pb2 as TSKArchives_sos -from .generated import TSPArchiveMessages_pb2 as TSPArchiveMessages -from .generated import TSPDatabaseMessages_pb2 as TSPDatabaseMessages -from .generated import TSPMessages_pb2 as TSPMessages -from .generated import TSSArchives_pb2 as TSSArchives -from .generated import TSSArchives_sos_pb2 as TSSArchives_sos -from .generated import TSTArchives_pb2 as TSTArchives -from .generated import TSTArchives_sos_pb2 as TSTArchives_sos -from .generated import TSTCommandArchives_pb2 as TSTCommandArchives -from .generated import TSTStylePropertyArchiving_pb2 as TSTStylePropertyArchiving -from .generated import TSWPArchives_pb2 as TSWPArchives -from .generated import TSWPArchives_sos_pb2 as TSWPArchives_sos -from .generated import TSWPCommandArchives_pb2 as TSWPCommandArchives - - -PROTO_FILES = [ - KNArchives, - KNArchives_sos, - KNCommandArchives, - KNCommandArchives_sos, - TSAArchives, - TSAArchives_sos, - TSACommandArchives_sos, - TSCEArchives, - TSCH3DArchives, - TSCHArchives, - TSCHArchives_Common, - TSCHArchives_GEN, - TSCHArchives_sos, - TSCHCommandArchives, - TSCHPreUFFArchives, - TSCKArchives, - TSCKArchives_sos, - TSDArchives, - TSDArchives_sos, - TSDCommandArchives, - TSKArchives, - TSKArchives_sos, - TSPArchiveMessages, - TSPDatabaseMessages, - TSPMessages, - TSSArchives, - TSSArchives_sos, - TSTArchives, - TSTArchives_sos, - TSTCommandArchives, - TSTStylePropertyArchiving, - TSWPArchives, - TSWPArchives_sos, - TSWPCommandArchives, -] - -TSPRegistryMapping = { - "1": "KN.DocumentArchive", - "2": "KN.ShowArchive", - "3": "KN.UIStateArchive", - "4": "KN.SlideNodeArchive", - "5": "KN.SlideArchive", - "6": "KN.SlideArchive", - "7": "KN.PlaceholderArchive", - "8": "KN.BuildArchive", - "9": "KN.SlideStyleArchive", - "10": "KN.ThemeArchive", - "11": "KN.PasteboardNativeStorageArchive", - "12": "KN.PlaceholderArchive", - "14": "TSWP.TextualAttachmentArchive", - "15": "KN.NoteArchive", - "16": "KN.RecordingArchive", - "17": "KN.RecordingEventTrackArchive", - "18": "KN.RecordingMovieTrackArchive", - "19": "KN.ClassicStylesheetRecordArchive", - "20": "KN.ClassicThemeRecordArchive", - "21": "KN.Soundtrack", - "22": "KN.SlideNumberAttachmentArchive", - "23": "KN.DesktopUILayoutArchive", - "24": "KN.CanvasSelectionArchive", - "25": "KN.SlideCollectionSelectionArchive", - "26": "KN.MotionBackgroundStyleArchive", - "100": "KN.CommandBuildSetValueArchive", - "101": "KN.CommandShowInsertSlideArchive", - "102": "KN.CommandShowMoveSlideArchive", - "103": "KN.CommandShowRemoveSlideArchive", - "104": "KN.CommandSlideInsertDrawablesArchive", - "105": "KN.CommandSlideRemoveDrawableArchive", - "106": "KN.CommandSlideNodeSetPropertyArchive", - "107": "KN.CommandSlideInsertBuildArchive", - "109": "KN.CommandSlideRemoveBuildArchive", - "110": "KN.CommandSlideInsertBuildChunkArchive", - "111": "KN.CommandSlideMoveBuildChunksArchive", - "112": "KN.CommandSlideRemoveBuildChunkArchive", - "114": "KN.CommandTransitionSetValueArchive", - "118": "KN.CommandSlideMoveDrawableZOrderArchive", - "119": "KN.CommandChangeTemplateSlideArchive", - "123": "KN.CommandShowSetSlideNumberVisibilityArchive", - "124": "KN.CommandShowSetValueArchive", - "128": "KN.CommandShowMarkOutOfSyncRecordingArchive", - "129": "KN.CommandShowRemoveRecordingArchive", - "130": "KN.CommandShowReplaceRecordingArchive", - "131": "KN.CommandShowSetSoundtrack", - "132": "KN.CommandSoundtrackSetValue", - "134": "KN.CommandMoveTemplatesArchive", - "135": "KN.CommandInsertTemplateArchive", - "136": "KN.CommandSlideSetStyleArchive", - "137": "KN.CommandSlideSetPlaceholdersForTagsArchive", - "138": "KN.CommandBuildChunkSetValueArchive", - "140": "KN.CommandRemoveTemplateArchive", - "142": "KN.CommandTemplateSetThumbnailTextArchive", - "143": "KN.CommandShowChangeThemeArchive", - "144": "KN.CommandSlidePrimitiveSetTemplateArchive", - "145": "KN.CommandTemplateSetBodyStylesArchive", - "146": "KNSOS.CommandSlideReapplyTemplateSlideArchive", - "148": "KN.ChartInfoGeometryCommandArchive", - "150": "KN.CommandSlideUpdateTemplateDrawables", - "152": "KN.CommandSlideSetBackgroundFillArchive", - "153": "KN.BuildChunkArchive", - "156": "KN.CommandSlideNodeSetViewStatePropertyArchive", - "157": "KN.CommandBuildUpdateChunkCountArchive", - "158": "KN.CommandBuildUpdateChunkReferentsArchive", - "159": "KN.BuildAttributeTupleArchive", - "160": "KN.CommandSetThemeCustomEffectTimingCurveArchive", - "161": "KN.CommandShowChangeSlideSizeArchive", - "162": "KN.InsertBuildDescriptionArchive", - "163": "KN.RemoveBuildDescriptionArchive", - "164": "KN.DocumentSelectionTransformerArchive", - "165": "KN.SlideCollectionSelectionTransformerArchive", - "166": "KN.OutlineCanvasSelectionTransformerArchive", - "167": "KN.NoteCanvasSelectionTransformerArchive", - "168": "KN.CanvasSelectionTransformerArchive", - "169": "KN.OutlineSelectionTransformerArchive", - "170": "KN.UndoObjectArchive", - "172": "KN.PrototypeForUndoTemplateChangeArchive", - "173": "KN.CommandShowMarkOutOfSyncRecordingIfNeededArchive", - "174": "KNSOS.InducedVerifyDocumentWithServerCommandArchive", - "175": "KNSOS.InducedVerifyDrawableZOrdersWithServerCommandArchive", - "176": "KN.CommandPrimitiveInsertTemplateArchive", - "177": "KN.CommandPrimitiveRemoveTemplateArchive", - "178": "KN.CommandTemplateSlideSetPlaceholderForTagArchive", - "179": "KN.CommandSlidePropagateSetPlaceholderForTagArchive", - "180": "KN.ActionGhostSelectionArchive", - "181": "KN.ActionGhostSelectionTransformerArchive", - "182": "KN.CommandSlideResetTemplateBackgroundObjectsArchive", - "184": "KN.LiveVideoSource", - "185": "KN.LiveVideoSourceCollection", - "186": "KN.CommandLiveVideoInfoApplyPreset", - "187": "KN.CommandLiveVideoInfoSetSource", - "188": "KN.CommandLiveVideoInfoSetValue", - "189": "KN.CommandLiveVideoSourceSetValue", - "190": "KN.CommandLiveVideoStyleSetValue", - "191": "KN.CommandThemeAddLiveVideoSource", - "192": "KN.CommandThemeRemoveLiveVideoSource", - "194": "KN.CommandMotionBackgroundStyleSetValueArchive", - "195": "KN.CommandMotionBackgroundStyleUpdatePosterFrameDataArchive", - "200": "TSK.DocumentArchive", - "201": "TSK.LocalCommandHistory", - "202": "TSK.CommandGroupArchive", - "203": "TSK.CommandContainerArchive", - "205": "TSK.TreeNode", - "210": "TSK.ViewStateArchive", - "211": "TSK.DocumentSupportArchive", - "212": "TSK.AnnotationAuthorArchive", - "213": "TSK.AnnotationAuthorStorageArchive", - "215": "TSCK.SetAnnotationAuthorColorCommandArchive", - "218": "TSCK.CollaborationCommandHistory", - "219": "TSK.DocumentSelectionArchive", - "220": "TSK.CommandSelectionBehaviorArchive", - "221": "TSK.NullCommandArchive", - "222": "TSK.CustomFormatListArchive", - "223": "TSK.GroupCommitCommandArchive", - "224": "TSK.InducedCommandCollectionArchive", - "225": "TSK.InducedCommandCollectionCommitCommandArchive", - "226": "TSCK.CollaborationDocumentSessionState", - "227": "TSCK.CollaborationCommandHistoryCoalescingGroup", - "228": "TSCK.CollaborationCommandHistoryCoalescingGroupNode", - "229": "TSCK.CollaborationCommandHistoryOriginatingCommandAcknowledgementObserver", - "230": "TSCK.DocumentSupportCollaborationState", - "231": "TSK.ChangeDocumentPackageTypeCommandArchive", - "232": "TSK.UpgradeDocPostProcessingCommandArchive", - "233": "TSK.FinalCommandPairArchive", - "234": "TSK.OutgoingCommandQueueItem", - "235": "TSCK.TransformerEntry", - "238": "TSCK.CreateLocalStorageSnapshotCommandArchive", - "240": "TSK.SelectionPathTransformerArchive", - "241": "TSK.NativeContentDescription", - "242": "TSD.PencilAnnotationStorageArchive", - "245": "TSCK.OperationStorage", - "246": "TSCK.OperationStorageEntryArray", - "247": "TSCK.OperationStorageEntryArraySegment", - "248": "TSCK.BlockDiffsAtCurrentRevisionCommand", - "249": "TSCK.OutgoingCommandQueue", - "250": "TSCK.OutgoingCommandQueueSegment", - "251": "TSK.PropagatedCommandCollectionArchive", - "252": "TSK.LocalCommandHistoryItem", - "253": "TSK.LocalCommandHistoryArray", - "254": "TSK.LocalCommandHistoryArraySegment", - "255": "TSCK.CollaborationCommandHistoryItem", - "256": "TSCK.CollaborationCommandHistoryArray", - "257": "TSCK.CollaborationCommandHistoryArraySegment", - "258": "TSK.PencilAnnotationUIState", - "259": "TSCKSOS.FixCorruptedDataCommandArchive", - "260": "TSCK.CommandAssetChunkArchive", - "261": "TSCK.AssetUploadStatusCommandArchive", - "262": "TSCK.AssetUnmaterializedOnServerCommandArchive", - "263": "TSK.CommandBehaviorArchive", - "264": "TSK.CommandBehaviorSelectionPathStorageArchive", - "265": "TSCK.CommandActivityBehaviorArchive", - "273": "TSCK.ActivityOnlyCommandArchive", - "275": "TSCK.SetActivityAuthorShareParticipantIDCommandArchive", - "279": "TSCK.ActivityAuthorCacheArchive", - "280": "TSCK.ActivityStreamArchive", - "281": "TSCK.ActivityArchive", - "282": "TSCK.ActivityCommitCommandArchive", - "283": "TSCK.ActivityStreamActivityArray", - "284": "TSCK.ActivityStreamActivityArraySegment", - "285": "TSCK.ActivityStreamRemovedAuthorAuditorPendingStateArchive", - "286": "TSCK.ActivityAuthorArchive", - "287": "TSCKSOS.ResetActivityStreamCommandArchive", - "288": "TSCKSOS.RemoveAuthorIdentifiersCommandArchive", - "289": "TSCK.ActivityCursorCollectionPersistenceWrapperArchive", - "400": "TSS.StyleArchive", - "401": "TSS.StylesheetArchive", - "402": "TSS.ThemeArchive", - "412": "TSS.StyleUpdatePropertyMapCommandArchive", - "413": "TSS.ThemeReplacePresetCommandArchive", - "414": "TSS.ThemeAddStylePresetCommandArchive", - "415": "TSS.ThemeRemoveStylePresetCommandArchive", - "416": "TSS.ThemeReplaceColorPresetCommandArchive", - "417": "TSS.ThemeMovePresetCommandArchive", - "419": "TSS.ThemeReplaceStylePresetAndDisconnectStylesCommandArchive", - "600": "TSA.DocumentArchive", - "601": "TSA.FunctionBrowserStateArchive", - "602": "TSA.PropagatePresetCommandArchive", - "603": "TSA.ShortcutControllerArchive", - "604": "TSA.ShortcutCommandArchive", - "605": "TSA.AddCustomFormatCommandArchive", - "606": "TSA.UpdateCustomFormatCommandArchive", - "607": "TSA.ReplaceCustomFormatCommandArchive", - "611": "TSASOS.VerifyObjectsWithServerCommandArchive", - "612": "TSA.InducedVerifyObjectsWithServerCommandArchive", - "613": "TSASOS.VerifyDocumentWithServerCommandArchive", - "614": "TSASOS.VerifyDrawableZOrdersWithServerCommandArchive", - "615": "TSASOS.InducedVerifyDrawableZOrdersWithServerCommandArchive", - "616": "TSA.NeedsMediaCompatibilityUpgradeCommandArchive", - "617": "TSA.ChangeDocumentLocaleCommandArchive", - "618": "TSA.StyleUpdatePropertyMapCommandArchive", - "619": "TSA.RemoteDataChangeCommandArchive", - "623": "TSA.GalleryItem", - "624": "TSA.GallerySelectionTransformer", - "625": "TSA.GalleryItemSelection", - "626": "TSA.GalleryItemSelectionTransformer", - "627": "TSA.GalleryInfoSetValueCommandArchive", - "628": "TSA.GalleryItemSetGeometryCommand", - "629": "TSA.GalleryItemSetValueCommand", - "630": "TSA.InducedVerifyTransformHistoryWithServerCommandArchive", - "631": "TSASOS.CommandReapplyMasterArchive", - "632": "TSASOS.PropagateMasterChangeCommandArchive", - "633": "TSA.CaptionInfoArchive", - "634": "TSA.CaptionPlacementArchive", - "635": "TSA.TitlePlacementCommandArchive", - "636": "TSA.GalleryInfoInsertItemsCommandArchive", - "637": "TSA.GalleryInfoRemoveItemsCommandArchive", - "638": "TSASOS.VerifyActivityStreamWithServerCommandArchive", - "639": "TSASOS.InducedVerifyActivityStreamWithServerCommandArchive", - "640": "TSASOS.VerifyTransformHistoryWithServerCommandArchive", - "641": "TSA.Object3DInfoSetValueCommandArchive", - "642": "TSA.Object3DInfoCommandArchive", - "2001": "TSWP.StorageArchive", - "2002": "TSWP.SelectionArchive", - "2003": "TSWP.DrawableAttachmentArchive", - "2004": "TSWP.TextualAttachmentArchive", - "2005": "TSWP.StorageArchive", - "2006": "TSWP.UIGraphicalAttachment", - "2007": "TSWP.TextualAttachmentArchive", - "2008": "TSWP.FootnoteReferenceAttachmentArchive", - "2009": "TSWP.TextualAttachmentArchive", - "2010": "TSWP.TSWPTOCPageNumberAttachmentArchive", - "2011": "TSWP.ShapeInfoArchive", - "2013": "TSWP.HighlightArchive", - "2014": "TSWP.CommentInfoArchive", - "2015": "TSWP.EquationInfoArchive", - "2016": "TSWP.PencilAnnotationArchive", - "2021": "TSWP.CharacterStyleArchive", - "2022": "TSWP.ParagraphStyleArchive", - "2023": "TSWP.ListStyleArchive", - "2024": "TSWP.ColumnStyleArchive", - "2025": "TSWP.ShapeStyleArchive", - "2026": "TSWP.TOCEntryStyleArchive", - "2031": "TSWP.PlaceholderSmartFieldArchive", - "2032": "TSWP.HyperlinkFieldArchive", - "2033": "TSWP.FilenameSmartFieldArchive", - "2034": "TSWP.DateTimeSmartFieldArchive", - "2035": "TSWP.BookmarkFieldArchive", - "2036": "TSWP.MergeSmartFieldArchive", - "2037": "TSWP.CitationRecordArchive", - "2038": "TSWP.CitationSmartFieldArchive", - "2039": "TSWP.UnsupportedHyperlinkFieldArchive", - "2040": "TSWP.BibliographySmartFieldArchive", - "2041": "TSWP.TOCSmartFieldArchive", - "2042": "TSWP.RubyFieldArchive", - "2043": "TSWP.NumberAttachmentArchive", - "2050": "TSWP.TextStylePresetArchive", - "2051": "TSWP.TOCSettingsArchive", - "2052": "TSWP.TOCEntryInstanceArchive", - "2053": "TSWPSOS.StyleDiffArchive", - "2060": "TSWP.ChangeArchive", - "2061": "TSK.DeprecatedChangeAuthorArchive", - "2062": "TSWP.ChangeSessionArchive", - "2101": "TSWP.TextCommandArchive", - "2107": "TSWP.ApplyPlaceholderTextCommandArchive", - "2116": "TSWP.ApplyRubyTextCommandArchive", - "2118": "TSWP.ModifyRubyTextCommandArchive", - "2120": "TSWP.ModifyTOCSettingsBaseCommandArchive", - "2121": "TSWP.ModifyTOCSettingsForTOCInfoCommandArchive", - "2123": "TSWP.SetObjectPropertiesCommandArchive", - "2124": "TSWP.UpdateFlowInfoCommandArchive", - "2125": "TSWP.AddFlowInfoCommandArchive", - "2126": "TSWP.RemoveFlowInfoCommandArchive", - "2127": "TSWP.ContainedObjectsCommandArchive", - "2128": "TSWP.EquationInfoGeometryCommandArchive", - "2206": "TSWP.AnchorAttachmentCommandArchive", - "2217": "TSWP.TextCommentReplyCommandArchive", - "2231": "TSWP.ShapeApplyPresetCommandArchive", - "2240": "TSWP.TOCInfoArchive", - "2241": "TSWP.TOCAttachmentArchive", - "2242": "TSWP.TOCLayoutHintArchive", - "2400": "TSWP.StyleBaseCommandArchive", - "2401": "TSWP.StyleCreateCommandArchive", - "2402": "TSWP.StyleRenameCommandArchive", - "2404": "TSWP.StyleDeleteCommandArchive", - "2405": "TSWP.StyleReorderCommandArchive", - "2406": "TSWP.StyleUpdatePropertyMapCommandArchive", - "2407": "TSWP.StorageActionCommandArchive", - "2408": "TSWP.ShapeStyleSetValueCommandArchive", - "2409": "TSWP.HyperlinkSelectionArchive", - "2410": "TSWP.FlowInfoArchive", - "2411": "TSWP.FlowInfoContainerArchive", - "2412": "TSWP.PencilAnnotationSelectionTransformerArchive", - "2413": "TSWP.DateTimeSelectionArchive", - "3002": "TSD.DrawableArchive", - "3003": "TSD.ContainerArchive", - "3004": "TSD.ShapeArchive", - "3005": "TSD.ImageArchive", - "3006": "TSD.MaskArchive", - "3007": "TSD.MovieArchive", - "3008": "TSD.GroupArchive", - "3009": "TSD.ConnectionLineArchive", - "3015": "TSD.ShapeStyleArchive", - "3016": "TSD.MediaStyleArchive", - "3021": "TSD.InfoGeometryCommandArchive", - "3022": "TSD.DrawablePathSourceCommandArchive", - "3024": "TSD.ImageMaskCommandArchive", - "3025": "TSD.ImageMediaCommandArchive", - "3026": "TSD.ImageReplaceCommandArchive", - "3027": "TSD.MediaOriginalSizeCommandArchive", - "3028": "TSD.ShapeStyleSetValueCommandArchive", - "3030": "TSD.MediaStyleSetValueCommandArchive", - "3031": "TSD.ShapeApplyPresetCommandArchive", - "3032": "TSD.MediaApplyPresetCommandArchive", - "3034": "TSD.MovieSetValueCommandArchive", - "3036": "TSD.ExteriorTextWrapCommandArchive", - "3037": "TSD.MediaFlagsCommandArchive", - "3040": "TSD.DrawableHyperlinkCommandArchive", - "3041": "TSD.ConnectionLineConnectCommandArchive", - "3042": "TSD.InstantAlphaCommandArchive", - "3043": "TSD.DrawableLockCommandArchive", - "3044": "TSD.ImageNaturalSizeCommandArchive", - "3045": "TSD.CanvasSelectionArchive", - "3047": "TSD.GuideStorageArchive", - "3048": "TSD.StyledInfoSetStyleCommandArchive", - "3049": "TSD.DrawableInfoCommentCommandArchive", - "3050": "TSD.GuideCommandArchive", - "3051": "TSD.DrawableAspectRatioLockedCommandArchive", - "3052": "TSD.ContainerRemoveChildrenCommandArchive", - "3053": "TSD.ContainerInsertChildrenCommandArchive", - "3054": "TSD.ContainerReorderChildrenCommandArchive", - "3055": "TSD.ImageAdjustmentsCommandArchive", - "3056": "TSD.CommentStorageArchive", - "3057": "TSD.ThemeReplaceFillPresetCommandArchive", - "3058": "TSD.DrawableAccessibilityDescriptionCommandArchive", - "3059": "TSD.PasteStyleCommandArchive", - "3061": "TSD.DrawableSelectionArchive", - "3062": "TSD.GroupSelectionArchive", - "3063": "TSD.PathSelectionArchive", - "3064": "TSD.CommentInvalidatingCommandSelectionBehaviorArchive", - "3065": "TSD.ImageInfoAbstractGeometryCommandArchive", - "3066": "TSD.ImageInfoGeometryCommandArchive", - "3067": "TSD.ImageInfoMaskGeometryCommandArchive", - "3068": "TSD.UndoObjectArchive", - "3070": "TSD.ReplaceAnnotationAuthorCommandArchive", - "3071": "TSD.DrawableSelectionTransformerArchive", - "3072": "TSD.GroupSelectionTransformerArchive", - "3073": "TSD.ShapeSelectionTransformerArchive", - "3074": "TSD.PathSelectionTransformerArchive", - "3080": "TSD.MediaInfoGeometryCommandArchive", - "3082": "TSD.GroupUngroupInformativeCommandArchive", - "3083": "TSD.DrawableContentDescription", - "3084": "TSD.ContainerRemoveDrawablesCommandArchive", - "3085": "TSD.ContainerInsertDrawablesCommandArchive", - "3086": "TSD.PencilAnnotationArchive", - "3087": "TSD.FreehandDrawingOpacityCommandArchive", - "3088": "TSD.DrawablePencilAnnotationCommandArchive", - "3089": "TSD.PencilAnnotationSelectionArchive", - "3090": "TSD.FreehandDrawingContentDescription", - "3091": "TSD.FreehandDrawingToolkitUIState", - "3092": "TSD.PencilAnnotationSelectionTransformerArchive", - "3094": "TSD.FreehandDrawingAnimationCommandArchive", - "3095": "TSD.InsertCaptionOrTitleCommandArchive", - "3096": "TSD.RemoveCaptionOrTitleCommandArchive", - "3097": "TSD.StandinCaptionArchive", - "3098": "TSD.SetCaptionOrTitleVisibilityCommandArchive", - "4000": "TSCE.CalculationEngineArchive", - "4001": "TSCE.FormulaRewriteCommandArchive", - "4003": "TSCE.NamedReferenceManagerArchive", - "4004": "TSCE.TrackedReferenceStoreArchive", - "4005": "TSCE.TrackedReferenceArchive", - "4007": "TSCE.RemoteDataStoreArchive", - "4008": "TSCE.FormulaOwnerDependenciesArchive", - "4009": "TSCE.CellRecordTileArchive", - "4010": "TSCE.RangePrecedentsTileArchive", - "4011": "TSCE.ReferencesToDirtyArchive", - "5000": "TSCH.PreUFF.ChartInfoArchive", - "5002": "TSCH.PreUFF.ChartGridArchive", - "5004": "TSCH.ChartMediatorArchive", - "5010": "TSCH.PreUFF.ChartStyleArchive", - "5011": "TSCH.PreUFF.ChartSeriesStyleArchive", - "5012": "TSCH.PreUFF.ChartAxisStyleArchive", - "5013": "TSCH.PreUFF.LegendStyleArchive", - "5014": "TSCH.PreUFF.ChartNonStyleArchive", - "5015": "TSCH.PreUFF.ChartSeriesNonStyleArchive", - "5016": "TSCH.PreUFF.ChartAxisNonStyleArchive", - "5017": "TSCH.PreUFF.LegendNonStyleArchive", - "5020": "TSCH.ChartStylePreset", - "5021": "TSCH.ChartDrawableArchive", - "5022": "TSCH.ChartStyleArchive", - "5023": "TSCH.ChartNonStyleArchive", - "5024": "TSCH.LegendStyleArchive", - "5025": "TSCH.LegendNonStyleArchive", - "5026": "TSCH.ChartAxisStyleArchive", - "5027": "TSCH.ChartAxisNonStyleArchive", - "5028": "TSCH.ChartSeriesStyleArchive", - "5029": "TSCH.ChartSeriesNonStyleArchive", - "5030": "TSCH.ReferenceLineStyleArchive", - "5031": "TSCH.ReferenceLineNonStyleArchive", - "5103": "TSCH.CommandSetChartTypeArchive", - "5104": "TSCH.CommandSetSeriesNameArchive", - "5105": "TSCH.CommandSetCategoryNameArchive", - "5107": "TSCH.CommandSetScatterFormatArchive", - "5108": "TSCH.CommandSetLegendFrameArchive", - "5109": "TSCH.CommandSetGridValueArchive", - "5110": "TSCH.CommandSetGridDirectionArchive", - "5115": "TSCH.CommandAddGridRowsArchive", - "5116": "TSCH.CommandAddGridColumnsArchive", - "5118": "TSCH.CommandMoveGridRowsArchive", - "5119": "TSCH.CommandMoveGridColumnsArchive", - "5122": "TSCH.CommandSetPieWedgeExplosion", - "5123": "TSCH.CommandStyleSwapArchive", - "5125": "TSCH.CommandChartApplyPreset", - "5126": "TSCH.ChartCommandArchive", - "5127": "TSCH.CommandReplaceGridValuesArchive", - "5129": "TSCH.StylePasteboardDataArchive", - "5130": "TSCH.CommandSetMultiDataSetIndexArchive", - "5131": "TSCH.CommandReplaceThemePresetArchive", - "5132": "TSCH.CommandInvalidateWPCaches", - "5135": "TSCH.CommandMutatePropertiesArchive", - "5136": "TSCH.CommandScaleAllTextArchive", - "5137": "TSCH.CommandSetFontFamilyArchive", - "5138": "TSCH.CommandApplyFillSetArchive", - "5139": "TSCH.CommandReplaceCustomFormatArchive", - "5140": "TSCH.CommandAddReferenceLineArchive", - "5141": "TSCH.CommandDeleteReferenceLineArchive", - "5142": "TSCH.CommandDeleteGridColumnsArchive", - "5143": "TSCH.CommandDeleteGridRowsArchive", - "5145": "TSCH.ChartSelectionArchive", - "5146": "TSCH.ChartTextSelectionTransformerArchive", - "5147": "TSCH.ChartSubselectionTransformerArchive", - "5148": "TSCH.ChartDrawableSelectionTransformerArchive", - "5149": "TSCH.ChartSubselectionTransformerHelperArchive", - "5150": "TSCH.ChartRefLineSubselectionTransformerHelperArchive", - "5151": "TSCH.CDESelectionTransformerArchive", - "5152": "TSCH.ChartSubselectionIdentityTransformerHelperArchive", - "5154": "TSCH.CommandPasteStyleArchive", - "5155": "TSCH.CommandInducedReplaceChartGrid", - "5156": "TSCH.CommandReplaceImageDataArchive", - "5157": "TSCH.CommandInduced3DChartGeometry", - "6000": "TST.TableInfoArchive", - "6001": "TST.TableModelArchive", - "6002": "TST.Tile", - "6003": "TST.TableStyleArchive", - "6004": "TST.CellStyleArchive", - "6005": "TST.TableDataList", - "6006": "TST.HeaderStorageBucket", - "6007": "TST.WPTableInfoArchive", - "6008": "TST.TableStylePresetArchive", - "6009": "TST.TableStrokePresetArchive", - "6010": "TST.ConditionalStyleSetArchive", - "6011": "TST.TableDataListSegment", - "6030": "TST.SelectionArchive", - "6031": "TST.CellMapArchive", - "6032": "TST.DeathhawkRdar39989167CellSelectionArchive", - "6033": "TST.ConcurrentCellMapArchive", - "6034": "TST.ConcurrentCellListArchive", - "6100": "TST.TableCommandArchive", - "6101": "TST.CommandDeleteCellsArchive", - "6102": "TST.CommandInsertColumnsOrRowsArchive", - "6103": "TST.CommandRemoveColumnsOrRowsArchive", - "6104": "TST.CommandResizeColumnOrRowArchive", - "6107": "TST.CommandSetTableNameArchive", - "6111": "TST.CommandChangeFreezeHeaderStateArchive", - "6114": "TST.CommandSetTableNameEnabledArchive", - "6117": "TST.CommandApplyTableStylePresetArchive", - "6120": "TST.CommandSetRepeatingHeaderEnabledArchive", - "6123": "TST.CommandSortArchive", - "6125": "TST.CommandStyleTableArchive", - "6126": "TST.CommandSetNumberOfDecimalPlacesArchive", - "6127": "TST.CommandSetShowThousandsSeparatorArchive", - "6128": "TST.CommandSetNegativeNumberStyleArchive", - "6129": "TST.CommandSetFractionAccuracyArchive", - "6131": "TST.CommandSetCurrencyCodeArchive", - "6132": "TST.CommandSetUseAccountingStyleArchive", - "6136": "TST.CommandSetTableFontNameArchive", - "6137": "TST.CommandSetTableFontSizeArchive", - "6142": "TST.CommandSetTableNameHeightArchive", - "6144": "TST.MergeRegionMapArchive", - "6145": "TST.CommandHideShowArchive", - "6146": "TST.CommandSetBaseArchive", - "6147": "TST.CommandSetBasePlacesArchive", - "6148": "TST.CommandSetBaseUseMinusSignArchive", - "6149": "TST.CommandSetTextStylePropertiesArchive", - "6150": "TST.CommandCategoryChangeSummaryAggregateType", - "6152": "TST.CommandCategoryResizeColumnOrRowArchive", - "6153": "TST.CommandCategoryMoveRowsArchive", - "6156": "TST.CommandSetPencilAnnotationsArchive", - "6157": "TST.CommandCategoryWillChangeGroupValue", - "6158": "TST.CommandApplyConcurrentCellMapArchive", - "6159": "TST.CommandSetGroupSortOrderArchive", - "6179": "TST.FormulaEqualsTokenAttachmentArchive", - "6181": "TST.TokenAttachmentArchive", - "6182": "TST.ExpressionNodeArchive", - "6183": "TST.BooleanNodeArchive", - "6184": "TST.NumberNodeArchive", - "6185": "TST.StringNodeArchive", - "6186": "TST.ArrayNodeArchive", - "6187": "TST.ListNodeArchive", - "6188": "TST.OperatorNodeArchive", - "6189": "TST.FunctionNodeArchive", - "6190": "TST.DateNodeArchive", - "6191": "TST.ReferenceNodeArchive", - "6192": "TST.DurationNodeArchive", - "6193": "TST.ArgumentPlaceholderNodeArchive", - "6194": "TST.PostfixOperatorNodeArchive", - "6195": "TST.PrefixOperatorNodeArchive", - "6196": "TST.FunctionEndNodeArchive", - "6197": "TST.EmptyExpressionNodeArchive", - "6198": "TST.LayoutHintArchive", - "6199": "TST.CompletionTokenAttachmentArchive", - "6201": "TST.TableDataList", - "6204": "TST.HiddenStateFormulaOwnerArchive", - "6205": "TST.CommandSetAutomaticDurationUnitsArchive", - "6206": "TST.PopUpMenuModel", - "6218": "TST.RichTextPayloadArchive", - "6220": "TST.FilterSetArchive", - "6221": "TST.CommandSetFiltersEnabledArchive", - "6224": "TST.CommandRewriteFilterFormulasForTableResizeArchive", - "6226": "TST.CommandTextPreflightInsertCellArchive", - "6228": "TST.CommandDeleteCellContentsArchive", - "6229": "TST.CommandPostflightSetCellArchive", - "6235": "TST.IdentifierNodeArchive", - "6238": "TST.CommandSetDateTimeFormatArchive", - "6239": "TST.TableCommandSelectionBehaviorArchive", - "6244": "TST.CommandApplyCellCommentArchive", - "6246": "TST.CommandSetFormulaTokenizationArchive", - "6247": "TST.TableStyleNetworkArchive", - "6250": "TST.CommandSetFilterSetTypeArchive", - "6255": "TST.CommandSetTextStyleArchive", - "6256": "TST.CommandJustForNotifyingArchive", - "6258": "TST.CommandSetSortOrderArchive", - "6262": "TST.CommandAddTableStylePresetArchive", - "6264": "TST.CellDiffMapArchive", - "6265": "TST.CommandApplyCellContentsArchive", - "6266": "TST.CommandRemoveTableStylePresetArchive", - "6267": "TST.ColumnRowUIDMapArchive", - "6268": "TST.CommandMoveColumnsOrRowsArchive", - "6269": "TST.CommandReplaceCustomFormatArchive", - "6270": "TST.CommandReplaceTableStylePresetArchive", - "6271": "TST.FormulaSelectionArchive", - "6273": "TST.CellListArchive", - "6275": "TST.CommandApplyCellDiffMapArchive", - "6276": "TST.CommandSetFilterSetArchive", - "6277": "TST.CommandMutateCellFormatArchive", - "6278": "TST.CommandSetStorageLanguageArchive", - "6280": "TST.CommandMergeArchive", - "6281": "TST.CommandUnmergeArchive", - "6282": "TST.CommandApplyCellMapArchive", - "6283": "TST.ControlCellSelectionArchive", - "6284": "TST.TableNameSelectionArchive", - "6285": "TST.CommandRewriteFormulasForTransposeArchive", - "6287": "TST.CommandTransposeTableArchive", - "6289": "TST.CommandSetDurationStyleArchive", - "6290": "TST.CommandSetDurationUnitSmallestLargestArchive", - "6291": "TST.CommandRewriteTableFormulasForRewriteSpecArchive", - "6292": "TST.CommandRewriteConditionalStylesForRewriteSpecArchive", - "6293": "TST.CommandRewriteFilterFormulasForRewriteSpecArchive", - "6294": "TST.CommandRewriteSortOrderForRewriteSpecArchive", - "6295": "TST.StrokeSelectionArchive", - "6298": "TST.VariableNodeArchive", - "6300": "TST.CommandInverseMergeArchive", - "6301": "TST.CommandMoveCellsArchive", - "6302": "TST.DefaultCellStylesContainerArchive", - "6303": "TST.CommandRewriteMergeFormulasArchive", - "6304": "TST.CommandChangeTableAreaForColumnOrRowArchive", - "6305": "TST.StrokeSidecarArchive", - "6306": "TST.StrokeLayerArchive", - "6307": "TST.CommandChooseTableIdRemapperArchive", - "6310": "TST.CommandSetWasCutArchive", - "6311": "TST.AutofillSelectionArchive", - "6312": "TST.StockCellSelectionArchive", - "6313": "TST.CommandSetNowArchive", - "6314": "TST.CommandSetStructuredTextImportRecordArchive", - "6315": "TST.CommandRewriteCategoryFormulasArchive", - "6316": "TST.SummaryModelArchive", - "6317": "TST.SummaryCellVendorArchive", - "6318": "TST.CategoryOrderArchive", - "6320": "TST.CommandCategoryCollapseExpandGroupArchive", - "6321": "TST.CommandCategorySetGroupingColumnsArchive", - "6323": "TST.CommandRewriteHiddenStatesForGroupByChangeArchive", - "6350": "TST.IdempotentSelectionTransformerArchive", - "6351": "TST.TableSubSelectionTransformerBaseArchive", - "6352": "TST.TableNameSelectionTransformerArchive", - "6353": "TST.RegionSelectionTransformerArchive", - "6354": "TST.RowColumnSelectionTransformerArchive", - "6355": "TST.ControlCellSelectionTransformerArchive", - "6357": "TST.ChangePropagationMapWrapper", - "6358": "TST.WPSelectionTransformerArchive", - "6359": "TST.StockCellSelectionTransformerArchive", - "6360": "TST.CommandSetRangeControlMinMaxIncArchive", - "6361": "TST.CommandCategorySetLabelRowVisibility", - "6362": "TST.CommandRewritePencilAnnotationFormulasArchive", - "6363": "TST.PencilAnnotationArchive", - "6364": "TST.StrokeSelectionTransformerArchive", - "6365": "TST.HeaderNameMgrTileArchive", - "6366": "TST.HeaderNameMgrArchive", - "6367": "TST.CellDiffArray", - "6368": "TST.CellDiffArraySegment", - "6369": "TST.PivotOrderArchive", - "6370": "TST.PivotOwnerArchive", - "6371": "TST.CommandPivotSetPivotRulesArchive", - "6372": "TST.CategoryOwnerRefArchive", - "6373": "TST.GroupByArchive", - "6374": "TST.PivotGroupingColumnOptionsMapArchive", - "6375": "TST.CommandPivotSetGroupingColumnOptionsArchive", - "6376": "TST.CommandPivotHideShowGrandTotalsArchive", - "6377": "TST.CommandPivotSortArchive", - "6379": "TST.CommandRewritePivotOwnerFormulasArchive", - "6380": "TST.CommandRewriteTrackedReferencesArchive", - "6381": "TST.CommandExtendTableIDHistoryArchive", - "6382": "TST.GroupByArchive.AggregatorArchive", - "6383": "TST.GroupByArchive.GroupNodeArchive", - "6384": "TST.SpillOriginRefNodeArchive", - "10011": "TSWP.SectionPlaceholderArchive", - "10020": "TSWP.ShapeSelectionTransformerArchive", - "10021": "TSWP.SelectionTransformerArchive", - "10022": "TSWP.ShapeContentDescription", - "10023": "TSWP.TateChuYokoFieldArchive", - "10024": "TSWP.DropCapStyleArchive", - "11000": "TSP.PasteboardObject", - "11006": "TSP.PackageMetadata", - "11007": "TSP.PasteboardMetadata", - "11008": "TSP.ObjectContainer", - "11009": "TSP.ViewStateMetadata", - "11010": "TSP.ObjectCollection", - "11011": "TSP.DocumentMetadata", - "11012": "TSP.SupportMetadata", - "11013": "TSP.ObjectSerializationMetadata", - "11014": "TSP.DataMetadata", - "11015": "TSP.DataMetadataMap", - "11016": "TSP.LargeNumberArraySegment", - "11017": "TSP.LargeStringArraySegment", - "11018": "TSP.LargeLazyObjectArraySegment", - "11019": "TSP.LargeNumberArray", - "11020": "TSP.LargeStringArray", - "11021": "TSP.LargeLazyObjectArray", - "11024": "TSP.LargeUUIDArraySegment", - "11025": "TSP.LargeUUIDArray", - "11026": "TSP.LargeObjectArraySegment", - "11027": "TSP.LargeObjectArray", -} - - -def compute_maps(): - name_class_map = {} - for file in PROTO_FILES: - for message_name in file.DESCRIPTOR.message_types_by_name: - message_type = getattr(file, message_name) - name_class_map[message_type.DESCRIPTOR.full_name] = message_type - - id_name_map = {} - for k, v in list(TSPRegistryMapping.items()): - if v in name_class_map: - id_name_map[int(k)] = name_class_map[v] - - return name_class_map, id_name_map - - -NAME_CLASS_MAP, ID_NAME_MAP = compute_maps() diff --git a/keynote_parser/versions/__init__.py b/keynote_parser/versions/__init__.py new file mode 100644 index 0000000..9cd084f --- /dev/null +++ b/keynote_parser/versions/__init__.py @@ -0,0 +1,15 @@ +import importlib +import os + +VERSIONS = [] + +for _dir in os.listdir(os.path.dirname(__file__)): + if os.path.isdir(os.path.join(os.path.dirname(__file__), _dir)) and os.path.exists( + os.path.join(os.path.dirname(__file__), _dir, "__init__.py") + ): + module = importlib.import_module(f".{_dir}", package="keynote_parser.versions") + VERSIONS.append(module.VERSION) + +LATEST_VERSION = max(VERSIONS) + +__all__ = ["VERSIONS", "LATEST_VERSION"] diff --git a/keynote_parser/versions/v14_4/__init__.py b/keynote_parser/versions/v14_4/__init__.py new file mode 100644 index 0000000..510647a --- /dev/null +++ b/keynote_parser/versions/v14_4/__init__.py @@ -0,0 +1,3 @@ +from keynote_parser.macos_app_version import MacOSAppVersion + +VERSION = MacOSAppVersion("14.4", "7043.0.93", "1A89s") diff --git a/keynote_parser/versions/v14_4/mapping.py b/keynote_parser/versions/v14_4/mapping.py new file mode 100644 index 0000000..18a5db2 --- /dev/null +++ b/keynote_parser/versions/v14_4/mapping.py @@ -0,0 +1,727 @@ +# Generated code! Edit /Users/psobot/Code/keynote-parser/dumper/generate_mapping.py instead. + +from __future__ import absolute_import + +from .generated import KNArchives_pb2 as KNArchives +from .generated import KNArchives_sos_pb2 as KNArchives_sos +from .generated import KNCommandArchives_pb2 as KNCommandArchives +from .generated import KNCommandArchives_sos_pb2 as KNCommandArchives_sos +from .generated import TSAArchives_pb2 as TSAArchives +from .generated import TSAArchives_sos_pb2 as TSAArchives_sos +from .generated import TSACommandArchives_sos_pb2 as TSACommandArchives_sos +from .generated import TSCEArchives_pb2 as TSCEArchives +from .generated import TSCH3DArchives_pb2 as TSCH3DArchives +from .generated import TSCHArchives_Common_pb2 as TSCHArchives_Common +from .generated import TSCHArchives_GEN_pb2 as TSCHArchives_GEN +from .generated import TSCHArchives_pb2 as TSCHArchives +from .generated import TSCHArchives_sos_pb2 as TSCHArchives_sos +from .generated import TSCHCommandArchives_pb2 as TSCHCommandArchives +from .generated import TSCHPreUFFArchives_pb2 as TSCHPreUFFArchives +from .generated import TSCKArchives_pb2 as TSCKArchives +from .generated import TSCKArchives_sos_pb2 as TSCKArchives_sos +from .generated import TSDArchives_pb2 as TSDArchives +from .generated import TSDArchives_sos_pb2 as TSDArchives_sos +from .generated import TSDCommandArchives_pb2 as TSDCommandArchives +from .generated import TSKArchives_pb2 as TSKArchives +from .generated import TSKArchives_sos_pb2 as TSKArchives_sos +from .generated import TSPArchiveMessages_pb2 as TSPArchiveMessages +from .generated import TSPDatabaseMessages_pb2 as TSPDatabaseMessages +from .generated import TSPMessages_pb2 as TSPMessages +from .generated import TSSArchives_pb2 as TSSArchives +from .generated import TSSArchives_sos_pb2 as TSSArchives_sos +from .generated import TSTArchives_pb2 as TSTArchives +from .generated import TSTArchives_sos_pb2 as TSTArchives_sos +from .generated import TSTCommandArchives_pb2 as TSTCommandArchives +from .generated import TSTStylePropertyArchiving_pb2 as TSTStylePropertyArchiving +from .generated import TSWPArchives_pb2 as TSWPArchives +from .generated import TSWPArchives_sos_pb2 as TSWPArchives_sos +from .generated import TSWPCommandArchives_pb2 as TSWPCommandArchives + +PROTO_FILES = [ + KNArchives, + KNArchives_sos, + KNCommandArchives, + KNCommandArchives_sos, + TSAArchives, + TSAArchives_sos, + TSACommandArchives_sos, + TSCEArchives, + TSCH3DArchives, + TSCHArchives, + TSCHArchives_Common, + TSCHArchives_GEN, + TSCHArchives_sos, + TSCHCommandArchives, + TSCHPreUFFArchives, + TSCKArchives, + TSCKArchives_sos, + TSDArchives, + TSDArchives_sos, + TSDCommandArchives, + TSKArchives, + TSKArchives_sos, + TSPArchiveMessages, + TSPDatabaseMessages, + TSPMessages, + TSSArchives, + TSSArchives_sos, + TSTArchives, + TSTArchives_sos, + TSTCommandArchives, + TSTStylePropertyArchiving, + TSWPArchives, + TSWPArchives_sos, + TSWPCommandArchives, +] + +TSPRegistryMapping = { + 1: "KN.DocumentArchive", + 2: "KN.ShowArchive", + 3: "KN.UIStateArchive", + 4: "KN.SlideNodeArchive", + 5: "KN.SlideArchive", + 6: "KN.SlideArchive", + 7: "KN.PlaceholderArchive", + 8: "KN.BuildArchive", + 9: "KN.SlideStyleArchive", + 10: "KN.ThemeArchive", + 11: "KN.PasteboardNativeStorageArchive", + 12: "KN.PlaceholderArchive", + 14: "TSWP.TextualAttachmentArchive", + 15: "KN.NoteArchive", + 16: "KN.RecordingArchive", + 17: "KN.RecordingEventTrackArchive", + 18: "KN.RecordingMovieTrackArchive", + 19: "KN.ClassicStylesheetRecordArchive", + 20: "KN.ClassicThemeRecordArchive", + 21: "KN.Soundtrack", + 22: "KN.SlideNumberAttachmentArchive", + 23: "KN.DesktopUILayoutArchive", + 24: "KN.CanvasSelectionArchive", + 25: "KN.SlideCollectionSelectionArchive", + 26: "KN.MotionBackgroundStyleArchive", + 100: "KN.CommandBuildSetValueArchive", + 101: "KN.CommandShowInsertSlideArchive", + 102: "KN.CommandShowMoveSlideArchive", + 103: "KN.CommandShowRemoveSlideArchive", + 104: "KN.CommandSlideInsertDrawablesArchive", + 105: "KN.CommandSlideRemoveDrawableArchive", + 106: "KN.CommandSlideNodeSetPropertyArchive", + 107: "KN.CommandSlideInsertBuildArchive", + 109: "KN.CommandSlideRemoveBuildArchive", + 110: "KN.CommandSlideInsertBuildChunkArchive", + 111: "KN.CommandSlideMoveBuildChunksArchive", + 112: "KN.CommandSlideRemoveBuildChunkArchive", + 114: "KN.CommandTransitionSetValueArchive", + 118: "KN.CommandSlideMoveDrawableZOrderArchive", + 119: "KN.CommandChangeTemplateSlideArchive", + 123: "KN.CommandShowSetSlideNumberVisibilityArchive", + 124: "KN.CommandShowSetValueArchive", + 128: "KN.CommandShowMarkOutOfSyncRecordingArchive", + 129: "KN.CommandShowRemoveRecordingArchive", + 130: "KN.CommandShowReplaceRecordingArchive", + 131: "KN.CommandShowSetSoundtrack", + 132: "KN.CommandSoundtrackSetValue", + 134: "KN.CommandMoveTemplatesArchive", + 135: "KN.CommandInsertTemplateArchive", + 136: "KN.CommandSlideSetStyleArchive", + 137: "KN.CommandSlideSetPlaceholdersForTagsArchive", + 138: "KN.CommandBuildChunkSetValueArchive", + 140: "KN.CommandRemoveTemplateArchive", + 142: "KN.CommandTemplateSetThumbnailTextArchive", + 143: "KN.CommandShowChangeThemeArchive", + 144: "KN.CommandSlidePrimitiveSetTemplateArchive", + 145: "KN.CommandTemplateSetBodyStylesArchive", + 146: "KNSOS.CommandSlideReapplyTemplateSlideArchive", + 148: "KN.ChartInfoGeometryCommandArchive", + 150: "KN.CommandSlideUpdateTemplateDrawables", + 152: "KN.CommandSlideSetBackgroundFillArchive", + 153: "KN.BuildChunkArchive", + 156: "KN.CommandSlideNodeSetViewStatePropertyArchive", + 157: "KN.CommandBuildUpdateChunkCountArchive", + 158: "KN.CommandBuildUpdateChunkReferentsArchive", + 159: "KN.BuildAttributeTupleArchive", + 160: "KN.CommandSetThemeCustomEffectTimingCurveArchive", + 161: "KN.CommandShowChangeSlideSizeArchive", + 162: "KN.InsertBuildDescriptionArchive", + 163: "KN.RemoveBuildDescriptionArchive", + 164: "KN.DocumentSelectionTransformerArchive", + 165: "KN.SlideCollectionSelectionTransformerArchive", + 166: "KN.OutlineCanvasSelectionTransformerArchive", + 167: "KN.NoteCanvasSelectionTransformerArchive", + 168: "KN.CanvasSelectionTransformerArchive", + 169: "KN.OutlineSelectionTransformerArchive", + 170: "KN.UndoObjectArchive", + 172: "KN.PrototypeForUndoTemplateChangeArchive", + 173: "KN.CommandShowMarkOutOfSyncRecordingIfNeededArchive", + 174: "KNSOS.InducedVerifyDocumentWithServerCommandArchive", + 175: "KNSOS.InducedVerifyDrawableZOrdersWithServerCommandArchive", + 176: "KN.CommandPrimitiveInsertTemplateArchive", + 177: "KN.CommandPrimitiveRemoveTemplateArchive", + 178: "KN.CommandTemplateSlideSetPlaceholderForTagArchive", + 179: "KN.CommandSlidePropagateSetPlaceholderForTagArchive", + 180: "KN.ActionGhostSelectionArchive", + 181: "KN.ActionGhostSelectionTransformerArchive", + 182: "KN.CommandSlideResetTemplateBackgroundObjectsArchive", + 184: "KN.LiveVideoSource", + 185: "KN.LiveVideoSourceCollection", + 186: "KN.CommandLiveVideoInfoApplyPreset", + 187: "KN.CommandLiveVideoInfoSetSource", + 188: "KN.CommandLiveVideoInfoSetValue", + 189: "KN.CommandLiveVideoSourceSetValue", + 190: "KN.CommandLiveVideoStyleSetValue", + 191: "KN.CommandThemeAddLiveVideoSource", + 192: "KN.CommandThemeRemoveLiveVideoSource", + 194: "KN.CommandMotionBackgroundStyleSetValueArchive", + 195: "KN.CommandMotionBackgroundStyleUpdatePosterFrameDataArchive", + 200: "TSK.DocumentArchive", + 201: "TSK.LocalCommandHistory", + 202: "TSK.CommandGroupArchive", + 203: "TSK.CommandContainerArchive", + 205: "TSK.TreeNode", + 210: "TSK.ViewStateArchive", + 211: "TSK.DocumentSupportArchive", + 212: "TSK.AnnotationAuthorArchive", + 213: "TSK.AnnotationAuthorStorageArchive", + 215: "TSCK.SetAnnotationAuthorColorCommandArchive", + 218: "TSCK.CollaborationCommandHistory", + 219: "TSK.DocumentSelectionArchive", + 220: "TSK.CommandSelectionBehaviorArchive", + 221: "TSK.NullCommandArchive", + 222: "TSK.CustomFormatListArchive", + 223: "TSK.GroupCommitCommandArchive", + 224: "TSK.InducedCommandCollectionArchive", + 225: "TSK.InducedCommandCollectionCommitCommandArchive", + 226: "TSCK.CollaborationDocumentSessionState", + 227: "TSCK.CollaborationCommandHistoryCoalescingGroup", + 228: "TSCK.CollaborationCommandHistoryCoalescingGroupNode", + 229: "TSCK.CollaborationCommandHistoryOriginatingCommandAcknowledgementObserver", + 230: "TSCK.DocumentSupportCollaborationState", + 231: "TSK.ChangeDocumentPackageTypeCommandArchive", + 232: "TSK.UpgradeDocPostProcessingCommandArchive", + 233: "TSK.FinalCommandPairArchive", + 234: "TSK.OutgoingCommandQueueItem", + 235: "TSCK.TransformerEntry", + 238: "TSCK.CreateLocalStorageSnapshotCommandArchive", + 240: "TSK.SelectionPathTransformerArchive", + 241: "TSK.NativeContentDescription", + 242: "TSD.PencilAnnotationStorageArchive", + 245: "TSCK.OperationStorage", + 246: "TSCK.OperationStorageEntryArray", + 247: "TSCK.OperationStorageEntryArraySegment", + 248: "TSCK.BlockDiffsAtCurrentRevisionCommand", + 249: "TSCK.OutgoingCommandQueue", + 250: "TSCK.OutgoingCommandQueueSegment", + 251: "TSK.PropagatedCommandCollectionArchive", + 252: "TSK.LocalCommandHistoryItem", + 253: "TSK.LocalCommandHistoryArray", + 254: "TSK.LocalCommandHistoryArraySegment", + 255: "TSCK.CollaborationCommandHistoryItem", + 256: "TSCK.CollaborationCommandHistoryArray", + 257: "TSCK.CollaborationCommandHistoryArraySegment", + 258: "TSK.PencilAnnotationUIState", + 259: "TSCKSOS.FixCorruptedDataCommandArchive", + 260: "TSCK.CommandAssetChunkArchive", + 261: "TSCK.AssetUploadStatusCommandArchive", + 262: "TSCK.AssetUnmaterializedOnServerCommandArchive", + 263: "TSK.CommandBehaviorArchive", + 264: "TSK.CommandBehaviorSelectionPathStorageArchive", + 265: "TSCK.CommandActivityBehaviorArchive", + 273: "TSCK.ActivityOnlyCommandArchive", + 275: "TSCK.SetActivityAuthorShareParticipantIDCommandArchive", + 279: "TSCK.ActivityAuthorCacheArchive", + 280: "TSCK.ActivityStreamArchive", + 281: "TSCK.ActivityArchive", + 282: "TSCK.ActivityCommitCommandArchive", + 283: "TSCK.ActivityStreamActivityArray", + 284: "TSCK.ActivityStreamActivityArraySegment", + 285: "TSCK.ActivityStreamRemovedAuthorAuditorPendingStateArchive", + 286: "TSCK.ActivityAuthorArchive", + 287: "TSCKSOS.ResetActivityStreamCommandArchive", + 288: "TSCKSOS.RemoveAuthorIdentifiersCommandArchive", + 289: "TSCK.ActivityCursorCollectionPersistenceWrapperArchive", + 400: "TSS.StyleArchive", + 401: "TSS.StylesheetArchive", + 402: "TSS.ThemeArchive", + 412: "TSS.StyleUpdatePropertyMapCommandArchive", + 413: "TSS.ThemeReplacePresetCommandArchive", + 414: "TSS.ThemeAddStylePresetCommandArchive", + 415: "TSS.ThemeRemoveStylePresetCommandArchive", + 416: "TSS.ThemeReplaceColorPresetCommandArchive", + 417: "TSS.ThemeMovePresetCommandArchive", + 419: "TSS.ThemeReplaceStylePresetAndDisconnectStylesCommandArchive", + 600: "TSA.DocumentArchive", + 601: "TSA.FunctionBrowserStateArchive", + 602: "TSA.PropagatePresetCommandArchive", + 603: "TSA.ShortcutControllerArchive", + 604: "TSA.ShortcutCommandArchive", + 605: "TSA.AddCustomFormatCommandArchive", + 606: "TSA.UpdateCustomFormatCommandArchive", + 607: "TSA.ReplaceCustomFormatCommandArchive", + 611: "TSASOS.VerifyObjectsWithServerCommandArchive", + 612: "TSA.InducedVerifyObjectsWithServerCommandArchive", + 613: "TSASOS.VerifyDocumentWithServerCommandArchive", + 614: "TSASOS.VerifyDrawableZOrdersWithServerCommandArchive", + 615: "TSASOS.InducedVerifyDrawableZOrdersWithServerCommandArchive", + 616: "TSA.NeedsMediaCompatibilityUpgradeCommandArchive", + 617: "TSA.ChangeDocumentLocaleCommandArchive", + 618: "TSA.StyleUpdatePropertyMapCommandArchive", + 619: "TSA.RemoteDataChangeCommandArchive", + 623: "TSA.GalleryItem", + 624: "TSA.GallerySelectionTransformer", + 625: "TSA.GalleryItemSelection", + 626: "TSA.GalleryItemSelectionTransformer", + 627: "TSA.GalleryInfoSetValueCommandArchive", + 628: "TSA.GalleryItemSetGeometryCommand", + 629: "TSA.GalleryItemSetValueCommand", + 630: "TSA.InducedVerifyTransformHistoryWithServerCommandArchive", + 631: "TSASOS.CommandReapplyMasterArchive", + 632: "TSASOS.PropagateMasterChangeCommandArchive", + 633: "TSA.CaptionInfoArchive", + 634: "TSA.CaptionPlacementArchive", + 635: "TSA.TitlePlacementCommandArchive", + 636: "TSA.GalleryInfoInsertItemsCommandArchive", + 637: "TSA.GalleryInfoRemoveItemsCommandArchive", + 638: "TSASOS.VerifyActivityStreamWithServerCommandArchive", + 639: "TSASOS.InducedVerifyActivityStreamWithServerCommandArchive", + 640: "TSASOS.VerifyTransformHistoryWithServerCommandArchive", + 641: "TSA.Object3DInfoSetValueCommandArchive", + 642: "TSA.Object3DInfoCommandArchive", + 2001: "TSWP.StorageArchive", + 2002: "TSWP.SelectionArchive", + 2003: "TSWP.DrawableAttachmentArchive", + 2004: "TSWP.TextualAttachmentArchive", + 2005: "TSWP.StorageArchive", + 2006: "TSWP.UIGraphicalAttachment", + 2007: "TSWP.TextualAttachmentArchive", + 2008: "TSWP.FootnoteReferenceAttachmentArchive", + 2009: "TSWP.TextualAttachmentArchive", + 2010: "TSWP.TSWPTOCPageNumberAttachmentArchive", + 2011: "TSWP.ShapeInfoArchive", + 2013: "TSWP.HighlightArchive", + 2014: "TSWP.CommentInfoArchive", + 2015: "TSWP.EquationInfoArchive", + 2016: "TSWP.PencilAnnotationArchive", + 2021: "TSWP.CharacterStyleArchive", + 2022: "TSWP.ParagraphStyleArchive", + 2023: "TSWP.ListStyleArchive", + 2024: "TSWP.ColumnStyleArchive", + 2025: "TSWP.ShapeStyleArchive", + 2026: "TSWP.TOCEntryStyleArchive", + 2031: "TSWP.PlaceholderSmartFieldArchive", + 2032: "TSWP.HyperlinkFieldArchive", + 2033: "TSWP.FilenameSmartFieldArchive", + 2034: "TSWP.DateTimeSmartFieldArchive", + 2035: "TSWP.BookmarkFieldArchive", + 2036: "TSWP.MergeSmartFieldArchive", + 2037: "TSWP.CitationRecordArchive", + 2038: "TSWP.CitationSmartFieldArchive", + 2039: "TSWP.UnsupportedHyperlinkFieldArchive", + 2040: "TSWP.BibliographySmartFieldArchive", + 2041: "TSWP.TOCSmartFieldArchive", + 2042: "TSWP.RubyFieldArchive", + 2043: "TSWP.NumberAttachmentArchive", + 2050: "TSWP.TextStylePresetArchive", + 2051: "TSWP.TOCSettingsArchive", + 2052: "TSWP.TOCEntryInstanceArchive", + 2053: "TSWPSOS.StyleDiffArchive", + 2060: "TSWP.ChangeArchive", + 2061: "TSK.DeprecatedChangeAuthorArchive", + 2062: "TSWP.ChangeSessionArchive", + 2101: "TSWP.TextCommandArchive", + 2107: "TSWP.ApplyPlaceholderTextCommandArchive", + 2116: "TSWP.ApplyRubyTextCommandArchive", + 2118: "TSWP.ModifyRubyTextCommandArchive", + 2120: "TSWP.ModifyTOCSettingsBaseCommandArchive", + 2121: "TSWP.ModifyTOCSettingsForTOCInfoCommandArchive", + 2123: "TSWP.SetObjectPropertiesCommandArchive", + 2124: "TSWP.UpdateFlowInfoCommandArchive", + 2125: "TSWP.AddFlowInfoCommandArchive", + 2126: "TSWP.RemoveFlowInfoCommandArchive", + 2127: "TSWP.ContainedObjectsCommandArchive", + 2128: "TSWP.EquationInfoGeometryCommandArchive", + 2206: "TSWP.AnchorAttachmentCommandArchive", + 2217: "TSWP.TextCommentReplyCommandArchive", + 2231: "TSWP.ShapeApplyPresetCommandArchive", + 2240: "TSWP.TOCInfoArchive", + 2241: "TSWP.TOCAttachmentArchive", + 2242: "TSWP.TOCLayoutHintArchive", + 2400: "TSWP.StyleBaseCommandArchive", + 2401: "TSWP.StyleCreateCommandArchive", + 2402: "TSWP.StyleRenameCommandArchive", + 2404: "TSWP.StyleDeleteCommandArchive", + 2405: "TSWP.StyleReorderCommandArchive", + 2406: "TSWP.StyleUpdatePropertyMapCommandArchive", + 2407: "TSWP.StorageActionCommandArchive", + 2408: "TSWP.ShapeStyleSetValueCommandArchive", + 2409: "TSWP.HyperlinkSelectionArchive", + 2410: "TSWP.FlowInfoArchive", + 2411: "TSWP.FlowInfoContainerArchive", + 2412: "TSWP.PencilAnnotationSelectionTransformerArchive", + 2413: "TSWP.DateTimeSelectionArchive", + 3002: "TSD.DrawableArchive", + 3003: "TSD.ContainerArchive", + 3004: "TSD.ShapeArchive", + 3005: "TSD.ImageArchive", + 3006: "TSD.MaskArchive", + 3007: "TSD.MovieArchive", + 3008: "TSD.GroupArchive", + 3009: "TSD.ConnectionLineArchive", + 3015: "TSD.ShapeStyleArchive", + 3016: "TSD.MediaStyleArchive", + 3021: "TSD.InfoGeometryCommandArchive", + 3022: "TSD.DrawablePathSourceCommandArchive", + 3024: "TSD.ImageMaskCommandArchive", + 3025: "TSD.ImageMediaCommandArchive", + 3026: "TSD.ImageReplaceCommandArchive", + 3027: "TSD.MediaOriginalSizeCommandArchive", + 3028: "TSD.ShapeStyleSetValueCommandArchive", + 3030: "TSD.MediaStyleSetValueCommandArchive", + 3031: "TSD.ShapeApplyPresetCommandArchive", + 3032: "TSD.MediaApplyPresetCommandArchive", + 3034: "TSD.MovieSetValueCommandArchive", + 3036: "TSD.ExteriorTextWrapCommandArchive", + 3037: "TSD.MediaFlagsCommandArchive", + 3040: "TSD.DrawableHyperlinkCommandArchive", + 3041: "TSD.ConnectionLineConnectCommandArchive", + 3042: "TSD.InstantAlphaCommandArchive", + 3043: "TSD.DrawableLockCommandArchive", + 3044: "TSD.ImageNaturalSizeCommandArchive", + 3045: "TSD.CanvasSelectionArchive", + 3047: "TSD.GuideStorageArchive", + 3048: "TSD.StyledInfoSetStyleCommandArchive", + 3049: "TSD.DrawableInfoCommentCommandArchive", + 3050: "TSD.GuideCommandArchive", + 3051: "TSD.DrawableAspectRatioLockedCommandArchive", + 3052: "TSD.ContainerRemoveChildrenCommandArchive", + 3053: "TSD.ContainerInsertChildrenCommandArchive", + 3054: "TSD.ContainerReorderChildrenCommandArchive", + 3055: "TSD.ImageAdjustmentsCommandArchive", + 3056: "TSD.CommentStorageArchive", + 3057: "TSD.ThemeReplaceFillPresetCommandArchive", + 3058: "TSD.DrawableAccessibilityDescriptionCommandArchive", + 3059: "TSD.PasteStyleCommandArchive", + 3061: "TSD.DrawableSelectionArchive", + 3062: "TSD.GroupSelectionArchive", + 3063: "TSD.PathSelectionArchive", + 3064: "TSD.CommentInvalidatingCommandSelectionBehaviorArchive", + 3065: "TSD.ImageInfoAbstractGeometryCommandArchive", + 3066: "TSD.ImageInfoGeometryCommandArchive", + 3067: "TSD.ImageInfoMaskGeometryCommandArchive", + 3068: "TSD.UndoObjectArchive", + 3070: "TSD.ReplaceAnnotationAuthorCommandArchive", + 3071: "TSD.DrawableSelectionTransformerArchive", + 3072: "TSD.GroupSelectionTransformerArchive", + 3073: "TSD.ShapeSelectionTransformerArchive", + 3074: "TSD.PathSelectionTransformerArchive", + 3080: "TSD.MediaInfoGeometryCommandArchive", + 3082: "TSD.GroupUngroupInformativeCommandArchive", + 3083: "TSD.DrawableContentDescription", + 3084: "TSD.ContainerRemoveDrawablesCommandArchive", + 3085: "TSD.ContainerInsertDrawablesCommandArchive", + 3086: "TSD.PencilAnnotationArchive", + 3087: "TSD.FreehandDrawingOpacityCommandArchive", + 3088: "TSD.DrawablePencilAnnotationCommandArchive", + 3089: "TSD.PencilAnnotationSelectionArchive", + 3090: "TSD.FreehandDrawingContentDescription", + 3091: "TSD.FreehandDrawingToolkitUIState", + 3092: "TSD.PencilAnnotationSelectionTransformerArchive", + 3094: "TSD.FreehandDrawingAnimationCommandArchive", + 3095: "TSD.InsertCaptionOrTitleCommandArchive", + 3096: "TSD.RemoveCaptionOrTitleCommandArchive", + 3097: "TSD.StandinCaptionArchive", + 3098: "TSD.SetCaptionOrTitleVisibilityCommandArchive", + 4000: "TSCE.CalculationEngineArchive", + 4001: "TSCE.FormulaRewriteCommandArchive", + 4003: "TSCE.NamedReferenceManagerArchive", + 4004: "TSCE.TrackedReferenceStoreArchive", + 4005: "TSCE.TrackedReferenceArchive", + 4007: "TSCE.RemoteDataStoreArchive", + 4008: "TSCE.FormulaOwnerDependenciesArchive", + 4009: "TSCE.CellRecordTileArchive", + 4010: "TSCE.RangePrecedentsTileArchive", + 4011: "TSCE.ReferencesToDirtyArchive", + 5000: "TSCH.PreUFF.ChartInfoArchive", + 5002: "TSCH.PreUFF.ChartGridArchive", + 5004: "TSCH.ChartMediatorArchive", + 5010: "TSCH.PreUFF.ChartStyleArchive", + 5011: "TSCH.PreUFF.ChartSeriesStyleArchive", + 5012: "TSCH.PreUFF.ChartAxisStyleArchive", + 5013: "TSCH.PreUFF.LegendStyleArchive", + 5014: "TSCH.PreUFF.ChartNonStyleArchive", + 5015: "TSCH.PreUFF.ChartSeriesNonStyleArchive", + 5016: "TSCH.PreUFF.ChartAxisNonStyleArchive", + 5017: "TSCH.PreUFF.LegendNonStyleArchive", + 5020: "TSCH.ChartStylePreset", + 5021: "TSCH.ChartDrawableArchive", + 5022: "TSCH.ChartStyleArchive", + 5023: "TSCH.ChartNonStyleArchive", + 5024: "TSCH.LegendStyleArchive", + 5025: "TSCH.LegendNonStyleArchive", + 5026: "TSCH.ChartAxisStyleArchive", + 5027: "TSCH.ChartAxisNonStyleArchive", + 5028: "TSCH.ChartSeriesStyleArchive", + 5029: "TSCH.ChartSeriesNonStyleArchive", + 5030: "TSCH.ReferenceLineStyleArchive", + 5031: "TSCH.ReferenceLineNonStyleArchive", + 5103: "TSCH.CommandSetChartTypeArchive", + 5104: "TSCH.CommandSetSeriesNameArchive", + 5105: "TSCH.CommandSetCategoryNameArchive", + 5107: "TSCH.CommandSetScatterFormatArchive", + 5108: "TSCH.CommandSetLegendFrameArchive", + 5109: "TSCH.CommandSetGridValueArchive", + 5110: "TSCH.CommandSetGridDirectionArchive", + 5115: "TSCH.CommandAddGridRowsArchive", + 5116: "TSCH.CommandAddGridColumnsArchive", + 5118: "TSCH.CommandMoveGridRowsArchive", + 5119: "TSCH.CommandMoveGridColumnsArchive", + 5122: "TSCH.CommandSetPieWedgeExplosion", + 5123: "TSCH.CommandStyleSwapArchive", + 5125: "TSCH.CommandChartApplyPreset", + 5126: "TSCH.ChartCommandArchive", + 5127: "TSCH.CommandReplaceGridValuesArchive", + 5129: "TSCH.StylePasteboardDataArchive", + 5130: "TSCH.CommandSetMultiDataSetIndexArchive", + 5131: "TSCH.CommandReplaceThemePresetArchive", + 5132: "TSCH.CommandInvalidateWPCaches", + 5135: "TSCH.CommandMutatePropertiesArchive", + 5136: "TSCH.CommandScaleAllTextArchive", + 5137: "TSCH.CommandSetFontFamilyArchive", + 5138: "TSCH.CommandApplyFillSetArchive", + 5139: "TSCH.CommandReplaceCustomFormatArchive", + 5140: "TSCH.CommandAddReferenceLineArchive", + 5141: "TSCH.CommandDeleteReferenceLineArchive", + 5142: "TSCH.CommandDeleteGridColumnsArchive", + 5143: "TSCH.CommandDeleteGridRowsArchive", + 5145: "TSCH.ChartSelectionArchive", + 5146: "TSCH.ChartTextSelectionTransformerArchive", + 5147: "TSCH.ChartSubselectionTransformerArchive", + 5148: "TSCH.ChartDrawableSelectionTransformerArchive", + 5149: "TSCH.ChartSubselectionTransformerHelperArchive", + 5150: "TSCH.ChartRefLineSubselectionTransformerHelperArchive", + 5151: "TSCH.CDESelectionTransformerArchive", + 5152: "TSCH.ChartSubselectionIdentityTransformerHelperArchive", + 5154: "TSCH.CommandPasteStyleArchive", + 5155: "TSCH.CommandInducedReplaceChartGrid", + 5156: "TSCH.CommandReplaceImageDataArchive", + 5157: "TSCH.CommandInduced3DChartGeometry", + 6000: "TST.TableInfoArchive", + 6001: "TST.TableModelArchive", + 6002: "TST.Tile", + 6003: "TST.TableStyleArchive", + 6004: "TST.CellStyleArchive", + 6005: "TST.TableDataList", + 6006: "TST.HeaderStorageBucket", + 6007: "TST.WPTableInfoArchive", + 6008: "TST.TableStylePresetArchive", + 6009: "TST.TableStrokePresetArchive", + 6010: "TST.ConditionalStyleSetArchive", + 6011: "TST.TableDataListSegment", + 6030: "TST.SelectionArchive", + 6031: "TST.CellMapArchive", + 6032: "TST.DeathhawkRdar39989167CellSelectionArchive", + 6033: "TST.ConcurrentCellMapArchive", + 6034: "TST.ConcurrentCellListArchive", + 6100: "TST.TableCommandArchive", + 6101: "TST.CommandDeleteCellsArchive", + 6102: "TST.CommandInsertColumnsOrRowsArchive", + 6103: "TST.CommandRemoveColumnsOrRowsArchive", + 6104: "TST.CommandResizeColumnOrRowArchive", + 6107: "TST.CommandSetTableNameArchive", + 6111: "TST.CommandChangeFreezeHeaderStateArchive", + 6114: "TST.CommandSetTableNameEnabledArchive", + 6117: "TST.CommandApplyTableStylePresetArchive", + 6120: "TST.CommandSetRepeatingHeaderEnabledArchive", + 6123: "TST.CommandSortArchive", + 6125: "TST.CommandStyleTableArchive", + 6126: "TST.CommandSetNumberOfDecimalPlacesArchive", + 6127: "TST.CommandSetShowThousandsSeparatorArchive", + 6128: "TST.CommandSetNegativeNumberStyleArchive", + 6129: "TST.CommandSetFractionAccuracyArchive", + 6131: "TST.CommandSetCurrencyCodeArchive", + 6132: "TST.CommandSetUseAccountingStyleArchive", + 6136: "TST.CommandSetTableFontNameArchive", + 6137: "TST.CommandSetTableFontSizeArchive", + 6142: "TST.CommandSetTableNameHeightArchive", + 6144: "TST.MergeRegionMapArchive", + 6145: "TST.CommandHideShowArchive", + 6146: "TST.CommandSetBaseArchive", + 6147: "TST.CommandSetBasePlacesArchive", + 6148: "TST.CommandSetBaseUseMinusSignArchive", + 6149: "TST.CommandSetTextStylePropertiesArchive", + 6150: "TST.CommandCategoryChangeSummaryAggregateType", + 6152: "TST.CommandCategoryResizeColumnOrRowArchive", + 6153: "TST.CommandCategoryMoveRowsArchive", + 6156: "TST.CommandSetPencilAnnotationsArchive", + 6157: "TST.CommandCategoryWillChangeGroupValue", + 6158: "TST.CommandApplyConcurrentCellMapArchive", + 6159: "TST.CommandSetGroupSortOrderArchive", + 6179: "TST.FormulaEqualsTokenAttachmentArchive", + 6181: "TST.TokenAttachmentArchive", + 6182: "TST.ExpressionNodeArchive", + 6183: "TST.BooleanNodeArchive", + 6184: "TST.NumberNodeArchive", + 6185: "TST.StringNodeArchive", + 6186: "TST.ArrayNodeArchive", + 6187: "TST.ListNodeArchive", + 6188: "TST.OperatorNodeArchive", + 6189: "TST.FunctionNodeArchive", + 6190: "TST.DateNodeArchive", + 6191: "TST.ReferenceNodeArchive", + 6192: "TST.DurationNodeArchive", + 6193: "TST.ArgumentPlaceholderNodeArchive", + 6194: "TST.PostfixOperatorNodeArchive", + 6195: "TST.PrefixOperatorNodeArchive", + 6196: "TST.FunctionEndNodeArchive", + 6197: "TST.EmptyExpressionNodeArchive", + 6198: "TST.LayoutHintArchive", + 6199: "TST.CompletionTokenAttachmentArchive", + 6201: "TST.TableDataList", + 6204: "TST.HiddenStateFormulaOwnerArchive", + 6205: "TST.CommandSetAutomaticDurationUnitsArchive", + 6206: "TST.PopUpMenuModel", + 6218: "TST.RichTextPayloadArchive", + 6220: "TST.FilterSetArchive", + 6221: "TST.CommandSetFiltersEnabledArchive", + 6224: "TST.CommandRewriteFilterFormulasForTableResizeArchive", + 6226: "TST.CommandTextPreflightInsertCellArchive", + 6228: "TST.CommandDeleteCellContentsArchive", + 6229: "TST.CommandPostflightSetCellArchive", + 6235: "TST.IdentifierNodeArchive", + 6238: "TST.CommandSetDateTimeFormatArchive", + 6239: "TST.TableCommandSelectionBehaviorArchive", + 6244: "TST.CommandApplyCellCommentArchive", + 6246: "TST.CommandSetFormulaTokenizationArchive", + 6247: "TST.TableStyleNetworkArchive", + 6250: "TST.CommandSetFilterSetTypeArchive", + 6255: "TST.CommandSetTextStyleArchive", + 6256: "TST.CommandJustForNotifyingArchive", + 6258: "TST.CommandSetSortOrderArchive", + 6262: "TST.CommandAddTableStylePresetArchive", + 6264: "TST.CellDiffMapArchive", + 6265: "TST.CommandApplyCellContentsArchive", + 6266: "TST.CommandRemoveTableStylePresetArchive", + 6267: "TST.ColumnRowUIDMapArchive", + 6268: "TST.CommandMoveColumnsOrRowsArchive", + 6269: "TST.CommandReplaceCustomFormatArchive", + 6270: "TST.CommandReplaceTableStylePresetArchive", + 6271: "TST.FormulaSelectionArchive", + 6273: "TST.CellListArchive", + 6275: "TST.CommandApplyCellDiffMapArchive", + 6276: "TST.CommandSetFilterSetArchive", + 6277: "TST.CommandMutateCellFormatArchive", + 6278: "TST.CommandSetStorageLanguageArchive", + 6280: "TST.CommandMergeArchive", + 6281: "TST.CommandUnmergeArchive", + 6282: "TST.CommandApplyCellMapArchive", + 6283: "TST.ControlCellSelectionArchive", + 6284: "TST.TableNameSelectionArchive", + 6285: "TST.CommandRewriteFormulasForTransposeArchive", + 6287: "TST.CommandTransposeTableArchive", + 6289: "TST.CommandSetDurationStyleArchive", + 6290: "TST.CommandSetDurationUnitSmallestLargestArchive", + 6291: "TST.CommandRewriteTableFormulasForRewriteSpecArchive", + 6292: "TST.CommandRewriteConditionalStylesForRewriteSpecArchive", + 6293: "TST.CommandRewriteFilterFormulasForRewriteSpecArchive", + 6294: "TST.CommandRewriteSortOrderForRewriteSpecArchive", + 6295: "TST.StrokeSelectionArchive", + 6298: "TST.VariableNodeArchive", + 6300: "TST.CommandInverseMergeArchive", + 6301: "TST.CommandMoveCellsArchive", + 6302: "TST.DefaultCellStylesContainerArchive", + 6303: "TST.CommandRewriteMergeFormulasArchive", + 6304: "TST.CommandChangeTableAreaForColumnOrRowArchive", + 6305: "TST.StrokeSidecarArchive", + 6306: "TST.StrokeLayerArchive", + 6307: "TST.CommandChooseTableIdRemapperArchive", + 6310: "TST.CommandSetWasCutArchive", + 6311: "TST.AutofillSelectionArchive", + 6312: "TST.StockCellSelectionArchive", + 6313: "TST.CommandSetNowArchive", + 6314: "TST.CommandSetStructuredTextImportRecordArchive", + 6315: "TST.CommandRewriteCategoryFormulasArchive", + 6316: "TST.SummaryModelArchive", + 6317: "TST.SummaryCellVendorArchive", + 6318: "TST.CategoryOrderArchive", + 6320: "TST.CommandCategoryCollapseExpandGroupArchive", + 6321: "TST.CommandCategorySetGroupingColumnsArchive", + 6323: "TST.CommandRewriteHiddenStatesForGroupByChangeArchive", + 6350: "TST.IdempotentSelectionTransformerArchive", + 6351: "TST.TableSubSelectionTransformerBaseArchive", + 6352: "TST.TableNameSelectionTransformerArchive", + 6353: "TST.RegionSelectionTransformerArchive", + 6354: "TST.RowColumnSelectionTransformerArchive", + 6355: "TST.ControlCellSelectionTransformerArchive", + 6357: "TST.ChangePropagationMapWrapper", + 6358: "TST.WPSelectionTransformerArchive", + 6359: "TST.StockCellSelectionTransformerArchive", + 6360: "TST.CommandSetRangeControlMinMaxIncArchive", + 6361: "TST.CommandCategorySetLabelRowVisibility", + 6362: "TST.CommandRewritePencilAnnotationFormulasArchive", + 6363: "TST.PencilAnnotationArchive", + 6364: "TST.StrokeSelectionTransformerArchive", + 6365: "TST.HeaderNameMgrTileArchive", + 6366: "TST.HeaderNameMgrArchive", + 6367: "TST.CellDiffArray", + 6368: "TST.CellDiffArraySegment", + 6369: "TST.PivotOrderArchive", + 6370: "TST.PivotOwnerArchive", + 6371: "TST.CommandPivotSetPivotRulesArchive", + 6372: "TST.CategoryOwnerRefArchive", + 6373: "TST.GroupByArchive", + 6374: "TST.PivotGroupingColumnOptionsMapArchive", + 6375: "TST.CommandPivotSetGroupingColumnOptionsArchive", + 6376: "TST.CommandPivotHideShowGrandTotalsArchive", + 6377: "TST.CommandPivotSortArchive", + 6379: "TST.CommandRewritePivotOwnerFormulasArchive", + 6380: "TST.CommandRewriteTrackedReferencesArchive", + 6381: "TST.CommandExtendTableIDHistoryArchive", + 6382: "TST.GroupByArchive.AggregatorArchive", + 6383: "TST.GroupByArchive.GroupNodeArchive", + 6384: "TST.SpillOriginRefNodeArchive", + 10011: "TSWP.SectionPlaceholderArchive", + 10020: "TSWP.ShapeSelectionTransformerArchive", + 10021: "TSWP.SelectionTransformerArchive", + 10022: "TSWP.ShapeContentDescription", + 10023: "TSWP.TateChuYokoFieldArchive", + 10024: "TSWP.DropCapStyleArchive", + 11000: "TSP.PasteboardObject", + 11006: "TSP.PackageMetadata", + 11007: "TSP.PasteboardMetadata", + 11008: "TSP.ObjectContainer", + 11009: "TSP.ViewStateMetadata", + 11010: "TSP.ObjectCollection", + 11011: "TSP.DocumentMetadata", + 11012: "TSP.SupportMetadata", + 11013: "TSP.ObjectSerializationMetadata", + 11014: "TSP.DataMetadata", + 11015: "TSP.DataMetadataMap", + 11016: "TSP.LargeNumberArraySegment", + 11017: "TSP.LargeStringArraySegment", + 11018: "TSP.LargeLazyObjectArraySegment", + 11019: "TSP.LargeNumberArray", + 11020: "TSP.LargeStringArray", + 11021: "TSP.LargeLazyObjectArray", + 11024: "TSP.LargeUUIDArraySegment", + 11025: "TSP.LargeUUIDArray", + 11026: "TSP.LargeObjectArraySegment", + 11027: "TSP.LargeObjectArray", +} + + +def compute_maps(): + name_class_map = {} + for file in PROTO_FILES: + for message_name in file.DESCRIPTOR.message_types_by_name: + message_type = getattr(file, message_name) + name_class_map[message_type.DESCRIPTOR.full_name] = message_type + + id_name_map = {} + for k, v in list(TSPRegistryMapping.items()): + if v in name_class_map: + id_name_map[int(k)] = name_class_map[v] + + return name_class_map, id_name_map + + +NAME_CLASS_MAP, ID_NAME_MAP = compute_maps() diff --git a/protos/KNArchives.proto b/protos/versions/14.4/KNArchives.proto similarity index 100% rename from protos/KNArchives.proto rename to protos/versions/14.4/KNArchives.proto diff --git a/protos/KNArchives_sos.proto b/protos/versions/14.4/KNArchives_sos.proto similarity index 100% rename from protos/KNArchives_sos.proto rename to protos/versions/14.4/KNArchives_sos.proto diff --git a/protos/KNCommandArchives.proto b/protos/versions/14.4/KNCommandArchives.proto similarity index 100% rename from protos/KNCommandArchives.proto rename to protos/versions/14.4/KNCommandArchives.proto diff --git a/protos/KNCommandArchives_sos.proto b/protos/versions/14.4/KNCommandArchives_sos.proto similarity index 100% rename from protos/KNCommandArchives_sos.proto rename to protos/versions/14.4/KNCommandArchives_sos.proto diff --git a/protos/TSAArchives.proto b/protos/versions/14.4/TSAArchives.proto similarity index 100% rename from protos/TSAArchives.proto rename to protos/versions/14.4/TSAArchives.proto diff --git a/protos/TSAArchives_sos.proto b/protos/versions/14.4/TSAArchives_sos.proto similarity index 100% rename from protos/TSAArchives_sos.proto rename to protos/versions/14.4/TSAArchives_sos.proto diff --git a/protos/TSACommandArchives_sos.proto b/protos/versions/14.4/TSACommandArchives_sos.proto similarity index 100% rename from protos/TSACommandArchives_sos.proto rename to protos/versions/14.4/TSACommandArchives_sos.proto diff --git a/protos/TSCEArchives.proto b/protos/versions/14.4/TSCEArchives.proto similarity index 100% rename from protos/TSCEArchives.proto rename to protos/versions/14.4/TSCEArchives.proto diff --git a/protos/TSCH3DArchives.proto b/protos/versions/14.4/TSCH3DArchives.proto similarity index 100% rename from protos/TSCH3DArchives.proto rename to protos/versions/14.4/TSCH3DArchives.proto diff --git a/protos/TSCHArchives.proto b/protos/versions/14.4/TSCHArchives.proto similarity index 100% rename from protos/TSCHArchives.proto rename to protos/versions/14.4/TSCHArchives.proto diff --git a/protos/TSCHArchives_Common.proto b/protos/versions/14.4/TSCHArchives_Common.proto similarity index 100% rename from protos/TSCHArchives_Common.proto rename to protos/versions/14.4/TSCHArchives_Common.proto diff --git a/protos/TSCHArchives_GEN.proto b/protos/versions/14.4/TSCHArchives_GEN.proto similarity index 100% rename from protos/TSCHArchives_GEN.proto rename to protos/versions/14.4/TSCHArchives_GEN.proto diff --git a/protos/TSCHArchives_sos.proto b/protos/versions/14.4/TSCHArchives_sos.proto similarity index 100% rename from protos/TSCHArchives_sos.proto rename to protos/versions/14.4/TSCHArchives_sos.proto diff --git a/protos/TSCHCommandArchives.proto b/protos/versions/14.4/TSCHCommandArchives.proto similarity index 100% rename from protos/TSCHCommandArchives.proto rename to protos/versions/14.4/TSCHCommandArchives.proto diff --git a/protos/TSCHPreUFFArchives.proto b/protos/versions/14.4/TSCHPreUFFArchives.proto similarity index 100% rename from protos/TSCHPreUFFArchives.proto rename to protos/versions/14.4/TSCHPreUFFArchives.proto diff --git a/protos/TSCKArchives.proto b/protos/versions/14.4/TSCKArchives.proto similarity index 100% rename from protos/TSCKArchives.proto rename to protos/versions/14.4/TSCKArchives.proto diff --git a/protos/TSCKArchives_sos.proto b/protos/versions/14.4/TSCKArchives_sos.proto similarity index 100% rename from protos/TSCKArchives_sos.proto rename to protos/versions/14.4/TSCKArchives_sos.proto diff --git a/protos/TSDArchives.proto b/protos/versions/14.4/TSDArchives.proto similarity index 100% rename from protos/TSDArchives.proto rename to protos/versions/14.4/TSDArchives.proto diff --git a/protos/TSDArchives_sos.proto b/protos/versions/14.4/TSDArchives_sos.proto similarity index 100% rename from protos/TSDArchives_sos.proto rename to protos/versions/14.4/TSDArchives_sos.proto diff --git a/protos/TSDCommandArchives.proto b/protos/versions/14.4/TSDCommandArchives.proto similarity index 100% rename from protos/TSDCommandArchives.proto rename to protos/versions/14.4/TSDCommandArchives.proto diff --git a/protos/TSKArchives.proto b/protos/versions/14.4/TSKArchives.proto similarity index 100% rename from protos/TSKArchives.proto rename to protos/versions/14.4/TSKArchives.proto diff --git a/protos/TSKArchives_sos.proto b/protos/versions/14.4/TSKArchives_sos.proto similarity index 100% rename from protos/TSKArchives_sos.proto rename to protos/versions/14.4/TSKArchives_sos.proto diff --git a/protos/TSPArchiveMessages.proto b/protos/versions/14.4/TSPArchiveMessages.proto similarity index 100% rename from protos/TSPArchiveMessages.proto rename to protos/versions/14.4/TSPArchiveMessages.proto diff --git a/protos/TSPDatabaseMessages.proto b/protos/versions/14.4/TSPDatabaseMessages.proto similarity index 100% rename from protos/TSPDatabaseMessages.proto rename to protos/versions/14.4/TSPDatabaseMessages.proto diff --git a/protos/TSPMessages.proto b/protos/versions/14.4/TSPMessages.proto similarity index 100% rename from protos/TSPMessages.proto rename to protos/versions/14.4/TSPMessages.proto diff --git a/protos/TSSArchives.proto b/protos/versions/14.4/TSSArchives.proto similarity index 100% rename from protos/TSSArchives.proto rename to protos/versions/14.4/TSSArchives.proto diff --git a/protos/TSSArchives_sos.proto b/protos/versions/14.4/TSSArchives_sos.proto similarity index 100% rename from protos/TSSArchives_sos.proto rename to protos/versions/14.4/TSSArchives_sos.proto diff --git a/protos/TSTArchives.proto b/protos/versions/14.4/TSTArchives.proto similarity index 100% rename from protos/TSTArchives.proto rename to protos/versions/14.4/TSTArchives.proto diff --git a/protos/TSTArchives_sos.proto b/protos/versions/14.4/TSTArchives_sos.proto similarity index 100% rename from protos/TSTArchives_sos.proto rename to protos/versions/14.4/TSTArchives_sos.proto diff --git a/protos/TSTCommandArchives.proto b/protos/versions/14.4/TSTCommandArchives.proto similarity index 100% rename from protos/TSTCommandArchives.proto rename to protos/versions/14.4/TSTCommandArchives.proto diff --git a/protos/TSTStylePropertyArchiving.proto b/protos/versions/14.4/TSTStylePropertyArchiving.proto similarity index 100% rename from protos/TSTStylePropertyArchiving.proto rename to protos/versions/14.4/TSTStylePropertyArchiving.proto diff --git a/protos/TSWPArchives.proto b/protos/versions/14.4/TSWPArchives.proto similarity index 100% rename from protos/TSWPArchives.proto rename to protos/versions/14.4/TSWPArchives.proto diff --git a/protos/TSWPArchives_sos.proto b/protos/versions/14.4/TSWPArchives_sos.proto similarity index 100% rename from protos/TSWPArchives_sos.proto rename to protos/versions/14.4/TSWPArchives_sos.proto diff --git a/protos/TSWPCommandArchives.proto b/protos/versions/14.4/TSWPCommandArchives.proto similarity index 100% rename from protos/TSWPCommandArchives.proto rename to protos/versions/14.4/TSWPCommandArchives.proto diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5700189 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,57 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "keynote-parser" +dynamic = ["version"] +description = "A tool for manipulating Apple Keynote presentation files." +readme = "README.md" +license = { text = "MIT License" } +authors = [{ name = "Peter Sobot", email = "github@petersobot.com" }] +requires-python = ">=3.9" +keywords = ["keynote", "macOS", "apple", "presentation", "powerpoint"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] +dependencies = [ + "protobuf>=3.13.0", + "tqdm>=4.14.0", + "python-snappy>=0.5.3", + "PyYAML>=5.3.1", + "Pillow>=7.1.0", + "future>=0.17.1", + "colorama>=0.4.3", +] + +[project.optional-dependencies] +dev = ["check-manifest"] +test = ["coverage"] + +[project.scripts] +keynote-parser = "keynote_parser.command_line:main" + +[project.urls] +"Bug Reports" = "https://github.com/psobot/keynote-parser/issues" +"Source" = "https://github.com/psobot/keynote-parser/" + +[tool.setuptools.dynamic] +version = { attr = "keynote_parser.__version__" } + +[tool.setuptools.packages.find] +exclude = ["contrib*", "docs*", "tests*", "protos*"] + +[tool.coverage.run] +omit = ["keynote_parser/versions/*"] + +[tool.pytest.ini_options] +addopts = "--cov=keynote_parser" diff --git a/setup.py b/setup.py deleted file mode 100644 index c7a0b68..0000000 --- a/setup.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python - -# Always prefer setuptools over distutils -import codecs -import os - -# io.open is needed for projects that support Python 2.7 -# It ensures open() defaults to text mode with universal newlines, -# and accepts an argument to specify the text encoding -# Python 3 only projects can skip this import -from io import open - -from setuptools import find_packages, setup - -import keynote_parser - -HERE = os.path.abspath(os.path.dirname(__file__)) - -# Get the long description from the README file -with open(os.path.join(HERE, "README.md"), encoding="utf-8") as f: - long_description = f.read() - - -##### -# Helper functions -##### -def read(*filenames, **kwargs): - """ - Build an absolute path from ``*filenames``, and return contents of - resulting file. Defaults to UTF-8 encoding. - """ - encoding = kwargs.get("encoding", "utf-8") - sep = kwargs.get("sep", "\n") - buf = [] - for fl in filenames: - with codecs.open(os.path.join(HERE, fl), "rb", encoding) as f: - buf.append(f.read()) - return sep.join(buf) - - -NAME = "keynote-parser" - - -def find_meta(meta): - attr = getattr(keynote_parser, "__{meta}__".format(meta=meta), None) - if not attr: - raise RuntimeError("Unable to find __{meta}__ string.".format(meta=meta)) - return attr - - -# Arguments marked as "Required" below must be included for upload to PyPI. -# Fields marked as "Optional" may be commented out. - -setup( - # This is the name of your project. The first time you publish this - # package, this name will be registered for you. It will determine how - # users can install this project, e.g.: - # - # $ pip install sampleproject - # - # And where it will live on PyPI: https://pypi.org/project/sampleproject/ - # - # There are some restrictions on what makes a valid project name - # specification here: - # https://packaging.python.org/specifications/core-metadata/#name - name=NAME, - # Versions should comply with PEP 440: - # https://www.python.org/dev/peps/pep-0440/ - # - # For a discussion on single-sourcing the version across setup.py and the - # project code, see - # https://packaging.python.org/en/latest/single_source_version.html - version=find_meta("version"), - # This is a one-line description or tagline of what your project does. This - # corresponds to the "Summary" metadata field: - # https://packaging.python.org/specifications/core-metadata/#summary - description=find_meta("description"), - # This is an optional longer description of your project that represents - # the body of text which users will see when they visit PyPI. - # - # Often, this is the same as your README, so you can just read it in from - # that file directly (as we have already done above) - # - # This field corresponds to the "Description" metadata field: - # https://packaging.python.org/specifications/core-metadata/#description-optional - long_description=long_description, # Optional - # Denotes that our long_description is in Markdown; valid values are - # text/plain, text/x-rst, and text/markdown - # - # Optional if long_description is written in reStructuredText (rst) but - # required for plain-text or Markdown; if unspecified, "applications should - # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and - # fall back to text/plain if it is not valid rst" (see link below) - # - # This field corresponds to the "Description-Content-Type" metadata field: - # https://packaging.python.org/specifications/core-metadata/#description-content-type-optional - long_description_content_type="text/markdown", - # This should be a valid link to your project's main homepage. - # - # This field corresponds to the "Home-Page" metadata field: - # https://packaging.python.org/specifications/core-metadata/#home-page-optional - url=find_meta("url"), - # This should be your name or the name of the organization which owns the - # project. - author=find_meta("author"), - # This should be a valid email address corresponding to the author listed - # above. - author_email=find_meta("email"), - # Classifiers help users find your project by categorizing it. - # - # For a list of valid classifiers, see https://pypi.org/classifiers/ - classifiers=[ # Optional - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - "Development Status :: 4 - Beta", - # Indicate who your project is intended for - "Intended Audience :: Developers", - "Topic :: Software Development :: Build Tools", - # Pick your license as you wish - "License :: OSI Approved :: MIT License", - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - ], - # This field adds keywords for your project which will appear on the - # project page. What does your project relate to? - # - # Note that this is a string of words separated by whitespace, not a list. - keywords="keynote macOS apple presentation powerpoint", - # You can just specify package directories manually here if your project is - # simple. Or you can use find_packages(). - # - # Alternatively, if you just want to distribute a single Python file, use - # the `py_modules` argument instead as follows, which will expect a file - # called `my_module.py` to exist: - # - # py_modules=["my_module"], - # - packages=find_packages(exclude=["contrib", "docs", "tests", "protos"]), - # This field lists other packages that your project depends on to run. - # Any package you put here will be installed by pip when your project is - # installed, so they must be valid existing projects. - # - # For an analysis of "install_requires" vs pip's requirements files see: - # https://packaging.python.org/en/latest/requirements.html - install_requires=[ - "protobuf>=3.13.0", - "tqdm>=4.14.0", - "python-snappy>=0.5.3", - "PyYAML>=5.3.1", - "Pillow>=7.1.0", - "future>=0.17.1", - "colorama>=0.4.3", - ], - # List additional groups of dependencies here (e.g. development - # dependencies). Users will be able to install these using the "extras" - # syntax, for example: - # - # $ pip install sampleproject[dev] - # - # Similar to `install_requires` above, these must be valid existing - # projects. - extras_require={"dev": ["check-manifest"], "test": ["coverage"]}, - # If there are data files included in your packages that need to be - # installed, specify them here. - # - # If using Python 2.6 or earlier, then these have to be included in - # MANIFEST.in as well. - package_data={}, - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. See: - # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files - # - # In this case, 'data_file' will be installed into '/my_data' - data_files=[], - # To provide executable scripts, use entry points in preference to the - # "scripts" keyword. Entry points provide cross-platform support and allow - # `pip` to create the appropriate form of executable for the target - # platform. - # - # For example, the following would provide a command called `sample` which - # executes the function `main` from this package when invoked: - entry_points={ - "console_scripts": ["keynote-parser=keynote_parser.command_line:main"] - }, - # List additional URLs that are relevant to your project as a dict. - # - # This field corresponds to the "Project-URL" metadata fields: - # https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use - # - # Examples listed include a pattern for specifying where the package tracks - # issues, where the source is hosted, where to say thanks to the package - # maintainers, and where to support the project financially. The key is - # what's used to render the link text on PyPI. - project_urls={ - "Bug Reports": "https://github.com/psobot/keynote-parser/issues", - "Source": "https://github.com/psobot/keynote-parser/", - }, -) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_codec.py b/tests/test_codec.py index ff2c00e..6b2a255 100644 --- a/tests/test_codec.py +++ b/tests/test_codec.py @@ -1,18 +1,19 @@ try: - from yaml import CLoader as Loader, CDumper as Dumper + from yaml import CDumper as Dumper + from yaml import CLoader as Loader except ImportError: - from yaml import Loader, Dumper + from yaml import Dumper, Loader -import yaml import pytest +import yaml +from google.protobuf.json_format import MessageToDict, ParseDict + from keynote_parser import codec from keynote_parser.unicode_utils import fix_unicode -from keynote_parser.generated.TSCHArchives_GEN_pb2 import ( +from keynote_parser.versions.v14_4.generated.TSCHArchives_GEN_pb2 import ( ChartSeriesStyleArchive as Archive, ) -from google.protobuf.json_format import MessageToDict, ParseDict - SIMPLE_FILENAME = "./tests/data/simple-oneslide.iwa" MULTILINE_FILENAME = "./tests/data/multiline-oneslide.iwa" MULTICHUNK_FILENAME = "./tests/data/multi-chunk.iwa"