Convert Blender-Purge to a more generic Blender-Crawl Tool #42

Merged
Nick Alberelli merged 34 commits from feature/blender-crawl into main 2023-05-17 15:38:47 +02:00
Showing only changes of commit 39d9345887 - Show all commits

View File

@ -1,4 +1,3 @@
# ***** BEGIN GPL LICENSE BLOCK ***** # ***** BEGIN GPL LICENSE BLOCK *****
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
@ -20,6 +19,11 @@
# (c) 2021, Blender Foundation # (c) 2021, Blender Foundation
#TODO
# Supply Many Script Files
# Supply Many .blend Files
import argparse import argparse
import sys import sys
import os import os
@ -32,11 +36,15 @@ from typing import List
# Command line arguments. # Command line arguments.
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
"path", help="Path to a file or folder on which to perform crawl", type=str, "path",
help="Path to a file or folder on which to perform crawl",
type=str,
) )
parser.add_argument( parser.add_argument(
"--script", help="Path to blender python script to execute inside .blend files during crawl. Execution is skipped if no script is provided", type=str "--script",
help="Path to blender python script to execute inside .blend files during crawl. Execution is skipped if no script is provided",
type=str,
) )
parser.add_argument( parser.add_argument(
"-R", "-R",
@ -64,16 +72,17 @@ parser.add_argument(
parser.add_argument( parser.add_argument(
"--exec", "--exec",
help="If --exec user must provide blender executable path, OS default blender will not be used if found.", type=str help="If --exec user must provide blender executable path, OS default blender will not be used if found.",
type=str,
) )
# MAIN LOGIC # MAIN LOGIC
def main(): def main():
args = parser.parse_args() args = parser.parse_args()
run_blender_crawl(args) run_blender_crawl(args)
def cancel_program(message: str): def cancel_program(message: str):
print(message) print(message)

I don't think there is much of a reason to have this function?

When I look at the code, it seems like all calls to this could be replaced with sys.exit(0) without any loss.

I don't think there is much of a reason to have this function? When I look at the code, it seems like all calls to this could be replaced with `sys.exit(0)` without any loss.

We handled this together on the phone! Issue has been resolved. 81083cdb01

We handled this together on the phone! Issue has been resolved. https://projects.blender.org/studio/blender-studio-pipeline/commit/81083cdb01fa4d61229f28b38df5f6fbc6096288
sys.exit(0) sys.exit(0)
@ -81,14 +90,15 @@ def cancel_program(message:str):
def find_executable() -> Path: def find_executable() -> Path:
if os.name != 'nt': if os.name != 'nt':
output = subprocess.check_output(['whereis', 'blender']) # TODO Replace with command check syntax output = subprocess.run(
default_blender_str = f'/{str(output).split(" /")[1]}' ['which', 'blender'], capture_output=True, encoding="utf-8"
default_blender_binary = Path(default_blender_str) )
if default_blender_binary.exists(): if output.returncode == 0:
print("Blender Executable location Automatically Detected!") # Returncode includes \n in string to indicate a new line
return default_blender_binary return Path(output.stdout.strip('\n'))
cancel_program("Blender Executable not found please provide --exec argument") cancel_program("Blender Executable not found please provide --exec argument")
def prompt_confirm(list_length: int): def prompt_confirm(list_length: int):
file_plural = "files" if list_length > 1 else "file" file_plural = "files" if list_length > 1 else "file"
confirm_str = f"Do you want to crawl {list_length} {file_plural}? ([y]es/[n]o)" confirm_str = f"Do you want to crawl {list_length} {file_plural}? ([y]es/[n]o)"
@ -104,8 +114,6 @@ def prompt_confirm(list_length: int):
return True return True
def blender_crawl_file(exec: Path, path: Path, script: Path) -> int: def blender_crawl_file(exec: Path, path: Path, script: Path) -> int:
# Get cmd list. # Get cmd list.
cmd_list = ( cmd_list = (
@ -121,7 +129,6 @@ def blender_crawl_file(exec: Path, path: Path, script: Path) -> int:
def is_filepath_valid(path: Path) -> None: def is_filepath_valid(path: Path) -> None:
# Check if path is file. # Check if path is file.
if not path.is_file(): if not path.is_file():
cancel_program(f"Not a file: {path.suffix}") cancel_program(f"Not a file: {path.suffix}")
@ -131,7 +138,6 @@ def is_filepath_valid(path: Path) -> None:
cancel_program(f"Not a blend file: {path.suffix}") cancel_program(f"Not a blend file: {path.suffix}")
def check_file_exists(file_path_str: str, error_msg: str): def check_file_exists(file_path_str: str, error_msg: str):
if file_path_str is None: if file_path_str is None:
return return
@ -141,18 +147,24 @@ def check_file_exists(file_path_str:str, error_msg:str):
else: else:
cancel_program(error_msg) cancel_program(error_msg)
def get_purge_path(purge: bool): def get_purge_path(purge: bool):
# Cancel function if user has not supplied purge arg # Cancel function if user has not supplied purge arg
if not purge: if not purge:
return return
purge_script = os.path.join(Path(__file__).parent.resolve(), "default_scripts", "purge.py") purge_script = os.path.join(
Path(__file__).parent.resolve(), "default_scripts", "purge.py"
)
return check_file_exists(str(purge_script), "no purge found") return check_file_exists(str(purge_script), "no purge found")
def run_blender_crawl(args: argparse.Namespace) -> int: def run_blender_crawl(args: argparse.Namespace) -> int:
# Parse arguments. # Parse arguments.
path = Path(args.path).absolute() path = Path(args.path).absolute()
script = check_file_exists(args.script, "No --script was not provided as argument, printed found .blend files, exiting program.") script = check_file_exists(
args.script,
"No --script was not provided as argument, printed found .blend files, exiting program.",
)
purge_path = get_purge_path(args.purge) purge_path = get_purge_path(args.purge)
recursive = args.recursive recursive = args.recursive
exec = args.exec exec = args.exec
@ -165,14 +177,12 @@ def run_blender_crawl(args: argparse.Namespace) -> int:
if not path.exists(): if not path.exists():
cancel_program(f"Path does not exist: {path.as_posix()}") cancel_program(f"Path does not exist: {path.as_posix()}")
if not exec: if not exec:
blende_exec = find_executable() blender_exec = find_executable()
else: else:
blende_exec = Path(exec).absolute() blender_exec = Path(exec).absolute()
if not blender_exec.exists():
if not blende_exec.exists():
cancel_program("Blender Executable Path is not valid") cancel_program("Blender Executable Path is not valid")
# Vars. # Vars.
files = [] files = []
@ -215,22 +225,20 @@ def run_blender_crawl(args: argparse.Namespace) -> int:
for file in files: for file in files:
print(f"Found: `{file}`") print(f"Found: `{file}`")
if ask_for_confirmation: if ask_for_confirmation:
if not prompt_confirm(len(files)): if not prompt_confirm(len(files)):
sys.exit(0) sys.exit(0)
if not scripts: if not scripts:
cancel_program("No --script was not provided as argument, printed found .blend files, exiting program. BIG") cancel_program(
"No --script was not provided as argument, printed found .blend files, exiting program. BIG"
)
sys.exit(0) sys.exit(0)
# crawl each file two times. # crawl each file two times.
for blend_file in files: for blend_file in files:
for script in scripts: for script in scripts:
return_code = blender_crawl_file(blende_exec, blend_file, script) return_code = blender_crawl_file(blender_exec, blend_file, script)
if return_code != 0: if return_code != 0:
cancel_program(f"Blender Crashed on file: {blend_file.as_posix()}") cancel_program(f"Blender Crashed on file: {blend_file.as_posix()}")
return 0 return 0
@ -238,7 +246,3 @@ def run_blender_crawl(args: argparse.Namespace) -> int:
if __name__ == "__main__": if __name__ == "__main__":
main() main()