From 66c6540294cff3781db462d8ad039072d1f5ac40 Mon Sep 17 00:00:00 2001 From: parker Date: Fri, 3 Oct 2025 16:27:21 +0100 Subject: [PATCH] feat: basic implementation --- docker/example-files | 1 - .../model/render/forest_beauty_v001.1001.exr | 0 docker/run.sh | 0 example-paths.txt | 8 ++ src/bb_asset_validation/cli.py | 109 +++++++++++++++++- 5 files changed, 116 insertions(+), 2 deletions(-) delete mode 120000 docker/example-files rename {example-files => docker/example-files}/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1001.exr (100%) mode change 100644 => 100755 docker/run.sh create mode 100644 example-paths.txt diff --git a/docker/example-files b/docker/example-files deleted file mode 120000 index 2f56ac4..0000000 --- a/docker/example-files +++ /dev/null @@ -1 +0,0 @@ -/home/parker/MyRepos/bluebolt-asset-version-validation/example-files \ No newline at end of file diff --git a/example-files/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1001.exr b/docker/example-files/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1001.exr similarity index 100% rename from example-files/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1001.exr rename to docker/example-files/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1001.exr diff --git a/docker/run.sh b/docker/run.sh old mode 100644 new mode 100755 diff --git a/example-paths.txt b/example-paths.txt new file mode 100644 index 0000000..60ef39e --- /dev/null +++ b/example-paths.txt @@ -0,0 +1,8 @@ +/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1001.exr +/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1002.exr +/shows/projectX/assets/environment/forest_v001/model/render/forest_beauty_v001.1003.exr +/shows/projectX/assets/environment/forest_v001/model/cache/forest_v001.fbx +/shows/projectX/assets/environment/forest_v002/model/render/forest_beauty_v002.1001.exr +/shows/projectX/assets/environment/forest_v002/model/render/forest_beauty_v002.1002.exr +/shows/projectX/assets/environment/forest_v002/model/render/forest_beauty_v002.1003.exr +/shows/projectX/assets/environment/forest_v002/model/cache/forest_v002.fbx diff --git a/src/bb_asset_validation/cli.py b/src/bb_asset_validation/cli.py index 8481c1d..9586960 100644 --- a/src/bb_asset_validation/cli.py +++ b/src/bb_asset_validation/cli.py @@ -1,5 +1,112 @@ +import argparse +import os.path +import sys + +def parse_args() -> argparse.Namespace: + """ + Parses cli arguments. + + Returns: + argparse.Namespace: Parsed argument namespace + """ + + parser = argparse.ArgumentParser( + prog="bb-asset-validation", + description="This program parses and validates paths in a given directory based on the BlueBolt asset delivery format.", + epilog="If you have any questions let me know at parker@parkerbritt.com" + ) + + parser.add_argument("--shows-directory", default="/shows", help="Specifies the directory shows are contained within.") + parser.add_argument("--paths-file", help="Specifies a file containing show paths to inspect and validate.") + + return parser.parse_args() + +def validate_shows_dir(shows_directory: str): + """ + Checks the given show directory is valid. + + Arguments: + shows_directory (str): The directory shows are stored within + + Returns: + bool: Whether the directory is valid. + """ + + # Check path exists + if(not os.path.exists(shows_directory)): + raise ValueError("Designated show path does not exist: " + shows_directory) + +def split_path(path): + PATH_DELIMETER = os.path.sep + + split_path = path.split(PATH_DELIMETER) + + # remove empty values + split_path = [i for i in split_path if i.strip()!=""] + + return split_path + +def validate_asset_path_structure(parsed_args, asset_path: str): + if(asset_path[0] != "/"): + print(f"\nError for path: {asset_path}\n-------------", file=sys.stderr) + print("Expected absolute asset path, recieved path does not start with '/'\n", file=sys.stderr) + + split_asset_path = split_path(os.path.normpath(asset_path)) + + + + # check path is prefixed with shows path + # valid_show_path = True + split_shows_path = split_path(os.path.realpath(parsed_args.shows_directory)) + valid_show_path = split_shows_path == split_asset_path[:len(split_shows_path)] + + if(not valid_show_path): + print(f"\nError for path: {asset_path}\n-------------", file=sys.stderr) + print(f"Path starting with '{split_asset_path[0]}' does not start with expected show directory '{parsed_args.shows_directory}'\n", file=sys.stderr) + else: + print("\n--------------\nGOOD PATH:", asset_path,"\n----------------\n") + + split_asset_path_suffix = split_asset_path[len(split_shows_path):] + + + path_components = { + "project_name" : split_asset_path_suffix[0], + "asset_type" : split_asset_path_suffix[2], + "asset_name" : split_asset_path_suffix[3].split("_")[0], + "task" : split_asset_path_suffix[4], + "version" : split_asset_path_suffix[3].split("_")[1], + "filename" : os.path.splitext(split_asset_path_suffix[6])[0].split("_")[0], + "file_extension" : os.path.splitext(split_asset_path_suffix[6])[1], + } + print(path_components) + + new_path = f"/shows/{path_components['project_name']}/staging/delivery/assets/{path_components['asset_type']}_{path_components['asset_name']}/{path_components['task']}_{path_components['version']}/{path_components['filename']}{path_components['file_extension']}" + print("new path:\n", new_path) + + + def main() -> None: - print("Hello world") + # Parse args + parsed_args = parse_args() + shows_directory = parsed_args.shows_directory + + # validate_shows_dir(shows_directory) + + if(parsed_args.paths_file): + with open(parsed_args.paths_file, "r") as f: + line = f.readline() + while(line): + line = f.readline() + + # clean line + line = line.strip() + # skip empty lines + if(line==""): + continue + + print('line:', line) + validate_asset_path_structure(parsed_args, line) + if __name__ == "__main__": main()