From 5f37ff14757b353c3c29b2620aa83ef7cb35c283 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Tue, 9 May 2023 18:15:33 -0400 Subject: [PATCH 01/34] [Blender-Crawl] Create Basic `Blender-Crawl` script --- scripts/blender-crawl/run-blender-crawl.sh | 16 ++++++++++++++++ scripts/blender-crawl/test-py-file.py | 4 ++++ 2 files changed, 20 insertions(+) create mode 100644 scripts/blender-crawl/run-blender-crawl.sh create mode 100644 scripts/blender-crawl/test-py-file.py diff --git a/scripts/blender-crawl/run-blender-crawl.sh b/scripts/blender-crawl/run-blender-crawl.sh new file mode 100644 index 00000000..94e75763 --- /dev/null +++ b/scripts/blender-crawl/run-blender-crawl.sh @@ -0,0 +1,16 @@ +#!/bin/bash +directory=$1 + +echo "Looking for .blend files in follwing directory: '$directory'" +for file in $directory/*.blend; do + if test -f "$file"; then + echo "FOUND FILE!" $(basename ${file}) + blender $file --background --python test-py-file.py + fi +done +echo "Blener-Crawl is done!" + + +# Usage! +# pass directory containing .blend files like example below: +# ./run-blender-crawl.sh /path/to/blends/ \ No newline at end of file diff --git a/scripts/blender-crawl/test-py-file.py b/scripts/blender-crawl/test-py-file.py new file mode 100644 index 00000000..0be7cc3e --- /dev/null +++ b/scripts/blender-crawl/test-py-file.py @@ -0,0 +1,4 @@ +import bpy +bpy.ops.object.add(type="EMPTY") +bpy.ops.wm.save_mainfile() +print("Example Py script execution completed!") \ No newline at end of file -- 2.30.2 From 49de93f733c061dea25d4240c98eef0a19ec697a Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 13:19:44 -0400 Subject: [PATCH 02/34] [Blender-Crawl] Simpify Blender-Purge Tool to One File --- .../blender-purge/blender_purge/__init__.py | 25 ---- .../blender_purge/{app.py => __main__.py} | 130 ++++++++++-------- scripts/blender-purge/blender_purge/check.py | 32 ----- scripts/blender-purge/blender_purge/cli.py | 72 ---------- .../blender-purge/blender_purge/exception.py | 27 ---- scripts/blender-purge/blender_purge/log.py | 42 ------ scripts/blender-purge/blender_purge/svn.py | 118 ---------------- scripts/blender-purge/blender_purge/vars.py | 29 ---- scripts/blender-purge/setup.py | 2 +- 9 files changed, 71 insertions(+), 406 deletions(-) delete mode 100644 scripts/blender-purge/blender_purge/__init__.py rename scripts/blender-purge/blender_purge/{app.py => __main__.py} (74%) delete mode 100644 scripts/blender-purge/blender_purge/check.py delete mode 100644 scripts/blender-purge/blender_purge/cli.py delete mode 100644 scripts/blender-purge/blender_purge/exception.py delete mode 100644 scripts/blender-purge/blender_purge/log.py delete mode 100644 scripts/blender-purge/blender_purge/svn.py delete mode 100644 scripts/blender-purge/blender_purge/vars.py diff --git a/scripts/blender-purge/blender_purge/__init__.py b/scripts/blender-purge/blender_purge/__init__.py deleted file mode 100644 index 61d5d5d3..00000000 --- a/scripts/blender-purge/blender_purge/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -"""Top-level package for blender_purge.""" - -__author__ = """Paul Golter""" -__email__ = "paul@blender.org" -__version__ = "0.1.0" diff --git a/scripts/blender-purge/blender_purge/app.py b/scripts/blender-purge/blender_purge/__main__.py similarity index 74% rename from scripts/blender-purge/blender_purge/app.py rename to scripts/blender-purge/blender_purge/__main__.py index e2979df1..0eb4a7d0 100644 --- a/scripts/blender-purge/blender_purge/app.py +++ b/scripts/blender-purge/blender_purge/__main__.py @@ -19,37 +19,68 @@ # # (c) 2021, Blender Foundation + +# PARSE ARUGMENTS +import argparse import sys +import os import subprocess import argparse import json import re from pathlib import Path -from typing import Tuple, List, Dict, Any, Union, Optional +from typing import Tuple, List, Any -from blender_purge import vars -from blender_purge.svn import SvnRepo -from blender_purge.log import LoggerFactory -from blender_purge.exception import SomethingWentWrongException, WrongInputException -logger = LoggerFactory.getLogger() +from pathlib import Path +# Command line arguments. +parser = argparse.ArgumentParser() +parser.add_argument( + "path", help="Path to a file or folder on which to perform purge", type=str +) +parser.add_argument( + "-R", + "--recursive", + help="If -R is provided in combination with a folder path will perform recursive purge", + action="store_true", +) + +parser.add_argument( + "--regex", + help="Provide any regex pattern that will be performed on each found filepath with re.search()", +) + +parser.add_argument( + "--yes", + help="If --yes is provided there will be no confirmation prompt.", + action="store_true", +) + +# MAIN LOGIC +PURGE_PATH = Path(os.path.abspath(__file__)).parent.joinpath("purge.py") + +PURGE_AMOUNT = 2 + +def main(): + args = parser.parse_args() + run_blender_purge(args) def exception_handler(func): def func_wrapper(*args, **kwargs): try: return func(*args, **kwargs) - except WrongInputException as error: - logger.info( + except Exception as error: + print( "# Oops. Seems like you gave some wrong input!" f"\n# Error: {error}" "\n# Program will be cancelled." ) cancel_program() - except SomethingWentWrongException as error: - logger.info( + except Exception as error: + print( "# Oops. Something went wrong during the execution of the Program!" f"\n# Error: {error}" "\n# Program will be cancelled." @@ -60,7 +91,7 @@ def exception_handler(func): def cancel_program() -> None: - logger.info("# Exiting blender-purge") + print("# Exiting blender-purge") sys.exit(0) @@ -82,7 +113,7 @@ def get_cmd_list(path: Path) -> Tuple[str]: path.as_posix(), "-b", "-P", - f"{vars.PURGE_PATH}", + f"{PURGE_PATH}", "--factory-startup", ) return cmd_list @@ -105,25 +136,14 @@ def prompt_confirm(path_list: List[Path]): user_input = input(input_str) if validate_user_input(user_input, options): if user_input in ["no", "n"]: - logger.info("\n# Process was canceled.") + print("\n# Process was canceled.") return False else: return True - logger.info("\n# Please enter a valid answer!") + print("\n# Please enter a valid answer!") continue -def run_check(): - cmd_list: Tuple[str] = ( - get_blender_path().as_posix(), - "-b", - "-P", - f"{vars.CHECK_PATH}", - ) - p = subprocess.Popen(cmd_list) - return p.wait() - - def purge_file(path: Path) -> int: # Get cmd list. cmd_list = get_cmd_list(path) @@ -136,11 +156,11 @@ def is_filepath_valid(path: Path) -> None: # Check if path is file. if not path.is_file(): - raise WrongInputException(f"Not a file: {path.suffix}") + raise Exception(f"Not a file: {path.suffix}") # Check if path is blend file. if path.suffix != ".blend": - raise WrongInputException(f"Not a blend file: {path.suffix}") + raise Exception(f"Not a blend file: {path.suffix}") def get_config_path() -> Path: @@ -161,11 +181,11 @@ def create_config_file(config_path: Path) -> None: with open(config_path.as_posix(), "w") as file: json.dump({}, file) except: - raise SomethingWentWrongException( + raise Exception( f"# Something went wrong creating config file at: {config_path.as_posix()}" ) - logger.info(f"# Created config file at: {config_path.as_posix()}") + print(f"# Created config file at: {config_path.as_posix()}") def load_json(path: Path) -> Any: @@ -185,12 +205,12 @@ def input_path(question: str) -> Path: try: path = Path(user_input) except: - logger.error("# Invalid input") + print("ERROR:# Invalid input") continue if path.exists(): return path.absolute() else: - logger.info("# Path does not exist") + print("# Path does not exist") def input_filepath(question: str) -> Path: @@ -211,7 +231,7 @@ def setup_config() -> None: "project_root": project_root.as_posix(), } save_to_json(obj, config_path) - logger.info("Updatet config at: %s", config_path.as_posix()) + print("Updatet config at: %s", config_path.as_posix()) def is_config_valid() -> bool: @@ -227,33 +247,32 @@ def is_config_valid() -> bool: @exception_handler -def purge(args: argparse.Namespace) -> int: +def run_blender_purge(args: argparse.Namespace) -> int: # Parse arguments. path = Path(args.path).absolute() recursive = args.recursive config_path = get_config_path() - no_commit = args.nocommit regex = args.regex yes = args.yes # Check config file. if not config_path.exists(): - logger.info("# Seems like you are starting blender-purge for the first time!") - logger.info("# Some things needs to be configured") + print("# Seems like you are starting blender-purge for the first time!") + print("# Some things needs to be configured") setup_config() else: if not is_config_valid(): - logger.info("# Config file at: %s is not valid", config_path.as_posix()) - logger.info("# Please set it up again") + print("# Config file at: %s is not valid", config_path.as_posix()) + print("# Please set it up again") setup_config() # Check user input. if not path: - raise WrongInputException("Please provide a path as first argument") + raise Exception("Please provide a path as first argument") if not path.exists(): - raise WrongInputException(f"Path does not exist: {path.as_posix()}") + raise Exception(f"Path does not exist: {path.as_posix()}") # Vars. files = [] @@ -288,7 +307,7 @@ def purge(args: argparse.Namespace) -> int: # Can only happen on folder here. if not files: - logger.info("# Found no .blend files to purge") + print("# Found no .blend files to purge") cancel_program() # Sort. @@ -299,30 +318,21 @@ def purge(args: argparse.Namespace) -> int: if not prompt_confirm(files): cancel_program() - """ - # Perform check of correct preference settings. - return_code = run_check() - if return_code == 1: - raise SomethingWentWrongException( - "Override auto resync is turned off. Turn it on in the preferences and try again." - ) - """ # Purge each file two times. for blend_file in files: - for i in range(vars.PURGE_AMOUNT): + for i in range(PURGE_AMOUNT): return_code = purge_file(blend_file) if return_code != 0: - raise SomethingWentWrongException( + raise Exception( f"Blender Crashed on file: {blend_file.as_posix()}", ) - - # Commit to svn. - if no_commit: - return 0 - - project_root = get_project_root_path() - svn_repo = SvnRepo(project_root) - file_rel = [p.relative_to(project_root) for p in files] - svn_repo.commit(file_rel) return 0 + + +if __name__ == "__main__": + main() + + + + diff --git a/scripts/blender-purge/blender_purge/check.py b/scripts/blender-purge/blender_purge/check.py deleted file mode 100644 index 416da781..00000000 --- a/scripts/blender-purge/blender_purge/check.py +++ /dev/null @@ -1,32 +0,0 @@ - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -import sys -import bpy - -import logging - -logger = logging.getLogger(__name__) - -# Check if recursive is on. -if not bpy.context.preferences.experimental.override_auto_resync: - logger.error("Override auto resync is turned off!") - sys.exit(1) diff --git a/scripts/blender-purge/blender_purge/cli.py b/scripts/blender-purge/blender_purge/cli.py deleted file mode 100644 index d3b4fe06..00000000 --- a/scripts/blender-purge/blender_purge/cli.py +++ /dev/null @@ -1,72 +0,0 @@ - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -import argparse -import sys -import os -import importlib - -from pathlib import Path - -from blender_purge import app -from blender_purge.log import LoggerFactory - -importlib.reload(app) -logger = LoggerFactory.getLogger() - -# Command line arguments. -parser = argparse.ArgumentParser() -parser.add_argument( - "path", help="Path to a file or folder on which to perform purge", type=str -) -parser.add_argument( - "-R", - "--recursive", - help="If -R is provided in combination with a folder path will perform recursive purge", - action="store_true", -) - -parser.add_argument( - "-N", - "--nocommit", - help="If -N is provided there will be no svn commit prompt with the purged files.", - action="store_true", -) - -parser.add_argument( - "--regex", - help="Provide any regex pattern that will be performed on each found filepath with re.search()", -) - -parser.add_argument( - "--yes", - help="If --yes is provided there will be no confirmation prompt.", - action="store_true", -) - - -def main(): - args = parser.parse_args() - app.purge(args) - - -if __name__ == "__main__": - main() diff --git a/scripts/blender-purge/blender_purge/exception.py b/scripts/blender-purge/blender_purge/exception.py deleted file mode 100644 index fde8c067..00000000 --- a/scripts/blender-purge/blender_purge/exception.py +++ /dev/null @@ -1,27 +0,0 @@ - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -class WrongInputException(Exception): - pass - - -class SomethingWentWrongException(Exception): - pass diff --git a/scripts/blender-purge/blender_purge/log.py b/scripts/blender-purge/blender_purge/log.py deleted file mode 100644 index 01802231..00000000 --- a/scripts/blender-purge/blender_purge/log.py +++ /dev/null @@ -1,42 +0,0 @@ - -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -import sys -import logging - - -class LoggerFactory: - - """ - Utility class to streamline logger creation - """ - - formatter = logging.Formatter("%(name)s: %(message)s") - consoleHandler = logging.StreamHandler(sys.stdout) - level = logging.INFO - - @classmethod - def getLogger(cls, name=__name__): - logger = logging.getLogger(name) - logger.addHandler(cls.consoleHandler) - logger.setLevel(cls.level) - - return logger diff --git a/scripts/blender-purge/blender_purge/svn.py b/scripts/blender-purge/blender_purge/svn.py deleted file mode 100644 index 4e07803c..00000000 --- a/scripts/blender-purge/blender_purge/svn.py +++ /dev/null @@ -1,118 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -import subprocess -import os -from typing import List, Union, Tuple, Any, Dict, Optional -from pathlib import Path - - -class SvnRepo: - def __init__(self, path: Path) -> None: - self._orig_pwd = Path(os.path.abspath(os.getcwd())) - self._path = path.absolute() - - @property - def path(self) -> Path: - return self._path - - def status(self) -> List[str]: - output = str( - subprocess.check_output( - ["svn status"], shell=True, cwd=self._path.as_posix() - ), - "utf-8", - ) - # Split output in string lines. - split = output.split("\n") - - # Remove empty lines. - while True: - try: - split.remove("") - except ValueError: - break - return split - - def get_modified(self, suffix: str = ".*") -> List[Path]: - output = self.status() - if not output: - return [] - - path_list: List[Path] = [] - - # Assemble path list. - for idx, line in enumerate(output): - if not line.startswith("M"): - continue - path = Path(line[5:].strip()) - - # If no suffix supplied append all files. - if suffix == ".*": - path_list.append(path) - # If suffix supplied only collect files that match. - else: - if path.suffix == suffix: - path_list.append(path) - - return path_list - - def revert(self, relpath_list: List[Path]) -> subprocess.Popen: - arg_list = " ".join([p.as_posix() for p in relpath_list]) - process = subprocess.call( - (f"svn revert {arg_list}"), shell=True, cwd=self._path.as_posix() - ) - return process - - def revert_all(self) -> None: - modified = self.get_modified() - self.revert(modified) - - def commit(self, relpath_list: List[Path]) -> Optional[subprocess.Popen]: - if not relpath_list: - return None - - cmd_list = f'svn commit {" ".join([p.as_posix() for p in relpath_list])}' - process = subprocess.call(cmd_list, shell=True, cwd=self._path.as_posix()) - return process - - def get_untracked(self) -> List[Path]: - output = self.status() - if not output: - return [] - - path_list: List[Path] = [] - - # Assemble path list. - for idx, line in enumerate(output): - if not line.startswith("?"): - continue - path = Path(line[5:].strip()) - path_list.append(path) - - return path_list - - -if __name__ == "__main__": - # Test status. - repo = SvnRepo(Path("/media/data/sprites")) - modified = repo.get_modified() - print(modified) - repo.commit(modified[:2]) diff --git a/scripts/blender-purge/blender_purge/vars.py b/scripts/blender-purge/blender_purge/vars.py deleted file mode 100644 index 32c380a7..00000000 --- a/scripts/blender-purge/blender_purge/vars.py +++ /dev/null @@ -1,29 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# ***** END GPL LICENCE BLOCK ***** -# -# (c) 2021, Blender Foundation - -import os -from pathlib import Path - -PURGE_PATH = Path(os.path.abspath(__file__)).parent.joinpath("purge.py") -CHECK_PATH = Path(os.path.abspath(__file__)).parent.joinpath("check.py") - -BLENDER_PATH = "/media/data/blender_guest/cmake_release/bin/blender" -PROJECT_PATH = "/media/data/sprites" -PURGE_AMOUNT = 2 diff --git a/scripts/blender-purge/setup.py b/scripts/blender-purge/setup.py index 3f7100af..29427bca 100644 --- a/scripts/blender-purge/setup.py +++ b/scripts/blender-purge/setup.py @@ -42,5 +42,5 @@ setup( tests_require=test_requirements, version="0.1.0", zip_safe=False, - entry_points={"console_scripts": ["bpurge=blender_purge.cli:main"]}, + entry_points={"console_scripts": ["bpurge = blender_purge.__main__:main"]}, ) -- 2.30.2 From 3c7eb6ad25d7b92f5a20ffb4d8db96623845245b Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 13:59:01 -0400 Subject: [PATCH 03/34] [Blender-Crawl] Pass Any Script as Argument --- .../blender-purge/blender_purge/__main__.py | 41 +++++++++---------- .../{ => default_scripts}/purge.py | 0 2 files changed, 20 insertions(+), 21 deletions(-) rename scripts/blender-purge/blender_purge/{ => default_scripts}/purge.py (100%) diff --git a/scripts/blender-purge/blender_purge/__main__.py b/scripts/blender-purge/blender_purge/__main__.py index 0eb4a7d0..110f10a4 100644 --- a/scripts/blender-purge/blender_purge/__main__.py +++ b/scripts/blender-purge/blender_purge/__main__.py @@ -39,6 +39,10 @@ parser = argparse.ArgumentParser() parser.add_argument( "path", help="Path to a file or folder on which to perform purge", type=str ) + +parser.add_argument( + "script", help="Name of default script like 'purge' or path to a valid python script file", type=str +) parser.add_argument( "-R", "--recursive", @@ -77,16 +81,7 @@ def exception_handler(func): f"\n# Error: {error}" "\n# Program will be cancelled." ) - cancel_program() - - except Exception as error: - print( - "# Oops. Something went wrong during the execution of the Program!" - f"\n# Error: {error}" - "\n# Program will be cancelled." - ) - cancel_program() - + cancel_program return func_wrapper @@ -101,19 +96,13 @@ def get_blender_path() -> Path: return Path(json_obj["blender_path"]) -def get_project_root_path() -> Path: - config_path = get_config_path() - json_obj = load_json(config_path) - return Path(json_obj["project_root"]) - - -def get_cmd_list(path: Path) -> Tuple[str]: +def get_cmd_list(path: Path, script: Path) -> Tuple[str]: cmd_list: Tuple[str] = ( get_blender_path().as_posix(), path.as_posix(), "-b", "-P", - f"{PURGE_PATH}", + script, "--factory-startup", ) return cmd_list @@ -144,9 +133,9 @@ def prompt_confirm(path_list: List[Path]): continue -def purge_file(path: Path) -> int: +def purge_file(path: Path, script: Path) -> int: # Get cmd list. - cmd_list = get_cmd_list(path) + cmd_list = get_cmd_list(path, script) p = subprocess.Popen(cmd_list, shell=False) # Stdout, stderr = p.communicate(). return p.wait() @@ -245,12 +234,19 @@ def is_config_valid() -> bool: return False return True +def get_default_scipt(script_input:str): + if script_input == "purge": + folder = Path(os.path.abspath(__file__)).parent + default_scripts = folder.joinpath("default_scripts") + return default_scripts.joinpath("purge.py").absolute() + return Path(script_input).absolute() @exception_handler def run_blender_purge(args: argparse.Namespace) -> int: # Parse arguments. path = Path(args.path).absolute() + script = get_default_scipt(args.script) recursive = args.recursive config_path = get_config_path() regex = args.regex @@ -270,6 +266,9 @@ def run_blender_purge(args: argparse.Namespace) -> int: # Check user input. if not path: raise Exception("Please provide a path as first argument") + + if not script.exists(): + raise Exception("Please provide a valid python script as second argument") if not path.exists(): raise Exception(f"Path does not exist: {path.as_posix()}") @@ -322,7 +321,7 @@ def run_blender_purge(args: argparse.Namespace) -> int: # Purge each file two times. for blend_file in files: for i in range(PURGE_AMOUNT): - return_code = purge_file(blend_file) + return_code = purge_file(blend_file, script) if return_code != 0: raise Exception( f"Blender Crashed on file: {blend_file.as_posix()}", diff --git a/scripts/blender-purge/blender_purge/purge.py b/scripts/blender-purge/blender_purge/default_scripts/purge.py similarity index 100% rename from scripts/blender-purge/blender_purge/purge.py rename to scripts/blender-purge/blender_purge/default_scripts/purge.py -- 2.30.2 From 3939faff7934c2613ae4bc9b6232350fe06e016e Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 13:59:26 -0400 Subject: [PATCH 04/34] [Blender-Crawl] Find Default Blender if Exists --- .../blender-purge/blender_purge/__main__.py | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/scripts/blender-purge/blender_purge/__main__.py b/scripts/blender-purge/blender_purge/__main__.py index 110f10a4..430c075b 100644 --- a/scripts/blender-purge/blender_purge/__main__.py +++ b/scripts/blender-purge/blender_purge/__main__.py @@ -61,8 +61,15 @@ parser.add_argument( action="store_true", ) +parser.add_argument( + "--exec", + help="If --exec user must provide blender executable path, OS default blender will not be used if found.", + action="store_true", +) + + # MAIN LOGIC -PURGE_PATH = Path(os.path.abspath(__file__)).parent.joinpath("purge.py") + PURGE_AMOUNT = 2 @@ -89,6 +96,12 @@ def cancel_program() -> None: print("# Exiting blender-purge") sys.exit(0) +def find_default_blender(): + output = subprocess.check_output(['whereis', 'blender']) + default_blender_str = f'/{str(output).split(" /")[1]}' + default_blender_binary = Path(default_blender_str) + if default_blender_binary.exists(): + return default_blender_binary def get_blender_path() -> Path: config_path = get_config_path() @@ -213,18 +226,21 @@ def input_filepath(question: str) -> Path: def setup_config() -> None: config_path = get_config_path() config_path.parent.mkdir(parents=True, exist_ok=True) - blender_path = input_filepath("# Path to Blender binary: ") - project_root = input_path("# Path to SVN project root: ") + default_blender_path = find_default_blender() + if default_blender_path: + blender_path = default_blender_path + else: + blender_path = input_filepath("# Path to Blender binary: ") + obj = { "blender_path": blender_path.as_posix(), - "project_root": project_root.as_posix(), } save_to_json(obj, config_path) print("Updatet config at: %s", config_path.as_posix()) def is_config_valid() -> bool: - keys = ["blender_path", "project_root"] + keys = ["blender_path",] config_path = get_config_path() json_obj = load_json(config_path) for key in keys: @@ -248,6 +264,7 @@ def run_blender_purge(args: argparse.Namespace) -> int: path = Path(args.path).absolute() script = get_default_scipt(args.script) recursive = args.recursive + find_blender_exec = args.exec config_path = get_config_path() regex = args.regex yes = args.yes @@ -256,12 +273,12 @@ def run_blender_purge(args: argparse.Namespace) -> int: if not config_path.exists(): print("# Seems like you are starting blender-purge for the first time!") print("# Some things needs to be configured") - setup_config() + setup_config(find_blender_exec) else: if not is_config_valid(): print("# Config file at: %s is not valid", config_path.as_posix()) print("# Please set it up again") - setup_config() + setup_config(find_blender_exec) # Check user input. if not path: -- 2.30.2 From 5acaa6060f9d29a88be3e7e87832018e81afaaea Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 14:24:09 -0400 Subject: [PATCH 05/34] [Blender-Crawl] Rename to Blender-Crawl --- .../.gitignore | 0 .../HISTORY.md | 0 .../{blender-purge => blender-crawl}/LICENSE | 0 .../README.md | 0 .../blender_crawl}/__main__.py | 38 +++++++++---------- .../blender_crawl}/default_scripts/purge.py | 0 .../install.sh | 0 scripts/blender-crawl/run-blender-crawl.sh | 16 -------- .../setup.cfg | 0 .../{blender-purge => blender-crawl}/setup.py | 0 scripts/blender-crawl/test-py-file.py | 4 -- 11 files changed, 19 insertions(+), 39 deletions(-) rename scripts/{blender-purge => blender-crawl}/.gitignore (100%) mode change 100755 => 100644 rename scripts/{blender-purge => blender-crawl}/HISTORY.md (100%) rename scripts/{blender-purge => blender-crawl}/LICENSE (100%) rename scripts/{blender-purge => blender-crawl}/README.md (100%) rename scripts/{blender-purge/blender_purge => blender-crawl/blender_crawl}/__main__.py (90%) rename scripts/{blender-purge/blender_purge => blender-crawl/blender_crawl}/default_scripts/purge.py (100%) rename scripts/{blender-purge => blender-crawl}/install.sh (100%) delete mode 100644 scripts/blender-crawl/run-blender-crawl.sh rename scripts/{blender-purge => blender-crawl}/setup.cfg (100%) rename scripts/{blender-purge => blender-crawl}/setup.py (100%) delete mode 100644 scripts/blender-crawl/test-py-file.py diff --git a/scripts/blender-purge/.gitignore b/scripts/blender-crawl/.gitignore old mode 100755 new mode 100644 similarity index 100% rename from scripts/blender-purge/.gitignore rename to scripts/blender-crawl/.gitignore diff --git a/scripts/blender-purge/HISTORY.md b/scripts/blender-crawl/HISTORY.md similarity index 100% rename from scripts/blender-purge/HISTORY.md rename to scripts/blender-crawl/HISTORY.md diff --git a/scripts/blender-purge/LICENSE b/scripts/blender-crawl/LICENSE similarity index 100% rename from scripts/blender-purge/LICENSE rename to scripts/blender-crawl/LICENSE diff --git a/scripts/blender-purge/README.md b/scripts/blender-crawl/README.md similarity index 100% rename from scripts/blender-purge/README.md rename to scripts/blender-crawl/README.md diff --git a/scripts/blender-purge/blender_purge/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py similarity index 90% rename from scripts/blender-purge/blender_purge/__main__.py rename to scripts/blender-crawl/blender_crawl/__main__.py index 430c075b..44338d0e 100644 --- a/scripts/blender-purge/blender_purge/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -37,16 +37,16 @@ from pathlib import Path # Command line arguments. parser = argparse.ArgumentParser() parser.add_argument( - "path", help="Path to a file or folder on which to perform purge", type=str + "path", help="Path to a file or folder on which to perform crawl", type=str ) parser.add_argument( - "script", help="Name of default script like 'purge' or path to a valid python script file", type=str + "script", help="Name of default script like 'crawl' or path to a valid python script file", type=str ) parser.add_argument( "-R", "--recursive", - help="If -R is provided in combination with a folder path will perform recursive purge", + help="If -R is provided in combination with a folder path will perform recursive crawl", action="store_true", ) @@ -71,11 +71,11 @@ parser.add_argument( # MAIN LOGIC -PURGE_AMOUNT = 2 +CRAWL_AMOUNT = 2 def main(): args = parser.parse_args() - run_blender_purge(args) + run_blender_crawl(args) def exception_handler(func): def func_wrapper(*args, **kwargs): @@ -93,7 +93,7 @@ def exception_handler(func): def cancel_program() -> None: - print("# Exiting blender-purge") + print("# Exiting blender-crawl") sys.exit(0) def find_default_blender(): @@ -132,8 +132,8 @@ def prompt_confirm(path_list: List[Path]): options = ["yes", "no", "y", "n"] list_str = "\n".join([p.as_posix() for p in path_list]) noun = "files" if len(path_list) > 1 else "file" - confirm_str = f"# Do you want to purge {len(path_list)} {noun}? ([y]es/[n]o)" - input_str = "# Files to purge:" + "\n" + list_str + "\n\n" + confirm_str + confirm_str = f"# Do you want to crawl {len(path_list)} {noun}? ([y]es/[n]o)" + input_str = "# Files to crawl:" + "\n" + list_str + "\n\n" + confirm_str while True: user_input = input(input_str) if validate_user_input(user_input, options): @@ -146,7 +146,7 @@ def prompt_confirm(path_list: List[Path]): continue -def purge_file(path: Path, script: Path) -> int: +def blender_crawl_file(path: Path, script: Path) -> int: # Get cmd list. cmd_list = get_cmd_list(path, script) p = subprocess.Popen(cmd_list, shell=False) @@ -169,11 +169,11 @@ def get_config_path() -> Path: home = Path.home() if sys.platform == "win32": - return home / "blender-purge/config.json" + return home / "blender-crawl/config.json" elif sys.platform == "linux": - return home / ".config/blender-purge/config.json" + return home / ".config/blender-crawl/config.json" elif sys.platform == "darwin": - return home / ".config/blender-purge/config.json" + return home / ".config/blender-crawl/config.json" def create_config_file(config_path: Path) -> None: @@ -258,7 +258,7 @@ def get_default_scipt(script_input:str): return Path(script_input).absolute() @exception_handler -def run_blender_purge(args: argparse.Namespace) -> int: +def run_blender_crawl(args: argparse.Namespace) -> int: # Parse arguments. path = Path(args.path).absolute() @@ -271,7 +271,7 @@ def run_blender_purge(args: argparse.Namespace) -> int: # Check config file. if not config_path.exists(): - print("# Seems like you are starting blender-purge for the first time!") + print("# Seems like you are starting blender-crawl for the first time!") print("# Some things needs to be configured") setup_config(find_blender_exec) else: @@ -293,7 +293,7 @@ def run_blender_purge(args: argparse.Namespace) -> int: # Vars. files = [] - # Collect files to purge + # Collect files to crawl # if dir. if path.is_dir(): if recursive: @@ -323,7 +323,7 @@ def run_blender_purge(args: argparse.Namespace) -> int: # Can only happen on folder here. if not files: - print("# Found no .blend files to purge") + print("# Found no .blend files to crawl") cancel_program() # Sort. @@ -335,10 +335,10 @@ def run_blender_purge(args: argparse.Namespace) -> int: cancel_program() - # Purge each file two times. + # crawl each file two times. for blend_file in files: - for i in range(PURGE_AMOUNT): - return_code = purge_file(blend_file, script) + for i in range(CRAWL_AMOUNT): + return_code = blender_crawl_file(blend_file, script) if return_code != 0: raise Exception( f"Blender Crashed on file: {blend_file.as_posix()}", diff --git a/scripts/blender-purge/blender_purge/default_scripts/purge.py b/scripts/blender-crawl/blender_crawl/default_scripts/purge.py similarity index 100% rename from scripts/blender-purge/blender_purge/default_scripts/purge.py rename to scripts/blender-crawl/blender_crawl/default_scripts/purge.py diff --git a/scripts/blender-purge/install.sh b/scripts/blender-crawl/install.sh similarity index 100% rename from scripts/blender-purge/install.sh rename to scripts/blender-crawl/install.sh diff --git a/scripts/blender-crawl/run-blender-crawl.sh b/scripts/blender-crawl/run-blender-crawl.sh deleted file mode 100644 index 94e75763..00000000 --- a/scripts/blender-crawl/run-blender-crawl.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -directory=$1 - -echo "Looking for .blend files in follwing directory: '$directory'" -for file in $directory/*.blend; do - if test -f "$file"; then - echo "FOUND FILE!" $(basename ${file}) - blender $file --background --python test-py-file.py - fi -done -echo "Blener-Crawl is done!" - - -# Usage! -# pass directory containing .blend files like example below: -# ./run-blender-crawl.sh /path/to/blends/ \ No newline at end of file diff --git a/scripts/blender-purge/setup.cfg b/scripts/blender-crawl/setup.cfg similarity index 100% rename from scripts/blender-purge/setup.cfg rename to scripts/blender-crawl/setup.cfg diff --git a/scripts/blender-purge/setup.py b/scripts/blender-crawl/setup.py similarity index 100% rename from scripts/blender-purge/setup.py rename to scripts/blender-crawl/setup.py diff --git a/scripts/blender-crawl/test-py-file.py b/scripts/blender-crawl/test-py-file.py deleted file mode 100644 index 0be7cc3e..00000000 --- a/scripts/blender-crawl/test-py-file.py +++ /dev/null @@ -1,4 +0,0 @@ -import bpy -bpy.ops.object.add(type="EMPTY") -bpy.ops.wm.save_mainfile() -print("Example Py script execution completed!") \ No newline at end of file -- 2.30.2 From bfae7365fecdc5d156a3d3d5ea036a21e41c3b14 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 14:28:36 -0400 Subject: [PATCH 06/34] [Blender-Crawl] Remove no-op code --- .../blender-crawl/blender_crawl/__main__.py | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 44338d0e..2241064d 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -20,7 +20,6 @@ # (c) 2021, Blender Foundation -# PARSE ARUGMENTS import argparse import sys import os @@ -31,9 +30,6 @@ import re from pathlib import Path from typing import Tuple, List, Any - -from pathlib import Path - # Command line arguments. parser = argparse.ArgumentParser() parser.add_argument( @@ -69,10 +65,6 @@ parser.add_argument( # MAIN LOGIC - - -CRAWL_AMOUNT = 2 - def main(): args = parser.parse_args() run_blender_crawl(args) @@ -175,21 +167,6 @@ def get_config_path() -> Path: elif sys.platform == "darwin": return home / ".config/blender-crawl/config.json" - -def create_config_file(config_path: Path) -> None: - if config_path.exists(): - return - try: - with open(config_path.as_posix(), "w") as file: - json.dump({}, file) - except: - raise Exception( - f"# Something went wrong creating config file at: {config_path.as_posix()}" - ) - - print(f"# Created config file at: {config_path.as_posix()}") - - def load_json(path: Path) -> Any: with open(path.as_posix(), "r") as file: obj = json.load(file) @@ -336,6 +313,7 @@ def run_blender_crawl(args: argparse.Namespace) -> int: # crawl each file two times. + CRAWL_AMOUNT = 2 # TODO Figure out why this is here and remove if not needed for blend_file in files: for i in range(CRAWL_AMOUNT): return_code = blender_crawl_file(blend_file, script) -- 2.30.2 From 53cb38ab2d5493cd3f229289ccdd8c5323dacda0 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 14:34:02 -0400 Subject: [PATCH 07/34] [Blender-Crawl] Remove no-op files --- scripts/blender-crawl/.gitignore | 106 ------------------------------- scripts/blender-crawl/setup.cfg | 16 ----- 2 files changed, 122 deletions(-) delete mode 100644 scripts/blender-crawl/.gitignore delete mode 100644 scripts/blender-crawl/setup.cfg diff --git a/scripts/blender-crawl/.gitignore b/scripts/blender-crawl/.gitignore deleted file mode 100644 index a7b90ceb..00000000 --- a/scripts/blender-crawl/.gitignore +++ /dev/null @@ -1,106 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# dotenv -.env - -# virtualenv -.venv -.venv* -venv/ -ENV/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ - -# IDE settings -.vscode/ diff --git a/scripts/blender-crawl/setup.cfg b/scripts/blender-crawl/setup.cfg deleted file mode 100644 index 4e6a7d24..00000000 --- a/scripts/blender-crawl/setup.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[bumpversion] -current_version = 0.1.0 -commit = True -tag = True - -[bumpversion:file:setup.py] -search = version='{current_version}' -replace = version='{new_version}' - -[bdist_wheel] -universal = 1 - -[flake8] -exclude = docs - -[aliases] -- 2.30.2 From c391a00145b5357b558a1dfbc4ea6971c1b718f4 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 14:34:23 -0400 Subject: [PATCH 08/34] [Blender-Crawl] Fix custom blender executable arg --- scripts/blender-crawl/blender_crawl/__main__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 2241064d..a3cfebb2 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -200,11 +200,11 @@ def input_filepath(question: str) -> Path: return path -def setup_config() -> None: +def setup_config(find_blender_exec) -> None: config_path = get_config_path() config_path.parent.mkdir(parents=True, exist_ok=True) default_blender_path = find_default_blender() - if default_blender_path: + if (not(find_blender_exec) and default_blender_path): blender_path = default_blender_path else: blender_path = input_filepath("# Path to Blender binary: ") @@ -247,7 +247,7 @@ def run_blender_crawl(args: argparse.Namespace) -> int: yes = args.yes # Check config file. - if not config_path.exists(): + if not config_path.exists() or find_blender_exec: print("# Seems like you are starting blender-crawl for the first time!") print("# Some things needs to be configured") setup_config(find_blender_exec) -- 2.30.2 From 65777a5345fb138292b0ef517d89bf881048b9c4 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Wed, 10 May 2023 14:55:29 -0400 Subject: [PATCH 09/34] [Blender-Crawl] Fix custom blender executable arg --- .../blender-crawl/blender_crawl/__main__.py | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index a3cfebb2..26991af9 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -93,6 +93,7 @@ def find_default_blender(): default_blender_str = f'/{str(output).split(" /")[1]}' default_blender_binary = Path(default_blender_str) if default_blender_binary.exists(): + print("Blender Executable location Automatically Detected!") return default_blender_binary def get_blender_path() -> Path: @@ -200,15 +201,20 @@ def input_filepath(question: str) -> Path: return path -def setup_config(find_blender_exec) -> None: +def setup_config(skip_finding_exec) -> None: + user_exec = True + + if not skip_finding_exec: + if find_default_blender() is not None: + user_exec = False + blender_path = find_default_blender() + + + if user_exec: + blender_path = input_filepath("# Path to Blender binary: ") + config_path = get_config_path() config_path.parent.mkdir(parents=True, exist_ok=True) - default_blender_path = find_default_blender() - if (not(find_blender_exec) and default_blender_path): - blender_path = default_blender_path - else: - blender_path = input_filepath("# Path to Blender binary: ") - obj = { "blender_path": blender_path.as_posix(), } @@ -241,21 +247,21 @@ def run_blender_crawl(args: argparse.Namespace) -> int: path = Path(args.path).absolute() script = get_default_scipt(args.script) recursive = args.recursive - find_blender_exec = args.exec + skip_finding_exec = args.exec config_path = get_config_path() regex = args.regex yes = args.yes # Check config file. - if not config_path.exists() or find_blender_exec: + if not config_path.exists() or skip_finding_exec: print("# Seems like you are starting blender-crawl for the first time!") print("# Some things needs to be configured") - setup_config(find_blender_exec) + setup_config(skip_finding_exec) else: if not is_config_valid(): print("# Config file at: %s is not valid", config_path.as_posix()) print("# Please set it up again") - setup_config(find_blender_exec) + setup_config(skip_finding_exec) # Check user input. if not path: -- 2.30.2 From ba0e35614d19e9b1b4f025595ba803165e05c559 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 08:36:44 -0400 Subject: [PATCH 10/34] [Blender-Crawl] remove cancel program --- scripts/blender-crawl/blender_crawl/__main__.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 26991af9..8da7d831 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -80,14 +80,9 @@ def exception_handler(func): f"\n# Error: {error}" "\n# Program will be cancelled." ) - cancel_program + sys.exit(0) return func_wrapper - -def cancel_program() -> None: - print("# Exiting blender-crawl") - sys.exit(0) - def find_default_blender(): output = subprocess.check_output(['whereis', 'blender']) default_blender_str = f'/{str(output).split(" /")[1]}' @@ -307,7 +302,7 @@ def run_blender_crawl(args: argparse.Namespace) -> int: # Can only happen on folder here. if not files: print("# Found no .blend files to crawl") - cancel_program() + sys.exit(0) # Sort. files.sort(key=lambda f: f.name) @@ -315,7 +310,7 @@ def run_blender_crawl(args: argparse.Namespace) -> int: # Prompt confirm. if not yes: if not prompt_confirm(files): - cancel_program() + sys.exit(0) # crawl each file two times. -- 2.30.2 From 05e9162731768c099089bed62f63ddac576c6a5f Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 10:55:21 -0400 Subject: [PATCH 11/34] [Blender-Crawl] Simplify Logic --- .../blender-crawl/blender_crawl/__main__.py | 277 ++++++------------ .../blender_crawl/default_scripts/purge.py | 14 +- 2 files changed, 98 insertions(+), 193 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 8da7d831..f9522863 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -25,19 +25,18 @@ import sys import os import subprocess import argparse -import json import re from pathlib import Path -from typing import Tuple, List, Any +from typing import List # Command line arguments. parser = argparse.ArgumentParser() 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( - "script", help="Name of default script like 'crawl' or path to a valid python script file", 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( "-R", @@ -52,93 +51,72 @@ parser.add_argument( ) parser.add_argument( - "--yes", - help="If --yes is provided there will be no confirmation prompt.", + "--ask", + help="If --ask is provided there will be no confirmation prompt before running script on .blend files.", + action="store_true", +) + +parser.add_argument( + "--purge", + help="Run 'built-in function to purge data-blocks from all .blend files found in crawl.'.", action="store_true", ) parser.add_argument( "--exec", - help="If --exec user must provide blender executable path, OS default blender will not be used if found.", - action="store_true", + help="If --exec user must provide blender executable path, OS default blender will not be used if found.", type=str ) + # MAIN LOGIC def main(): args = parser.parse_args() run_blender_crawl(args) -def exception_handler(func): - def func_wrapper(*args, **kwargs): - try: - return func(*args, **kwargs) - - except Exception as error: - print( - "# Oops. Seems like you gave some wrong input!" - f"\n# Error: {error}" - "\n# Program will be cancelled." - ) - sys.exit(0) - return func_wrapper - -def find_default_blender(): - output = subprocess.check_output(['whereis', 'blender']) - default_blender_str = f'/{str(output).split(" /")[1]}' - default_blender_binary = Path(default_blender_str) - if default_blender_binary.exists(): - print("Blender Executable location Automatically Detected!") - return default_blender_binary - -def get_blender_path() -> Path: - config_path = get_config_path() - json_obj = load_json(config_path) - return Path(json_obj["blender_path"]) +def cancel_program(message:str): + print(message) + sys.exit(0) -def get_cmd_list(path: Path, script: Path) -> Tuple[str]: - cmd_list: Tuple[str] = ( - get_blender_path().as_posix(), +def find_executable() -> Path: + if os.name != 'nt': + output = subprocess.check_output(['whereis', 'blender']) # TODO Replace with command check syntax + default_blender_str = f'/{str(output).split(" /")[1]}' + default_blender_binary = Path(default_blender_str) + if default_blender_binary.exists(): + print("Blender Executable location Automatically Detected!") + return default_blender_binary + cancel_program("Blender Executable not found please provide --exec argument") + +def prompt_confirm(list_length: int): + 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)" + while True: + user_input = input(confirm_str).lower() + if not user_input in ["yes", "no", "y", "n"]: + print("\nPlease enter a valid answer!") + continue + if user_input in ["no", "n"]: + print("\nProcess was canceled.") + return False + else: + return True + + + + +def blender_crawl_file(exec: Path, path: Path, script: Path) -> int: + # Get cmd list. + cmd_list = ( + exec.as_posix(), path.as_posix(), "-b", "-P", script, "--factory-startup", ) - return cmd_list - - -def validate_user_input(user_input, options): - if user_input.lower() in options: - return True - else: - return False - - -def prompt_confirm(path_list: List[Path]): - options = ["yes", "no", "y", "n"] - list_str = "\n".join([p.as_posix() for p in path_list]) - noun = "files" if len(path_list) > 1 else "file" - confirm_str = f"# Do you want to crawl {len(path_list)} {noun}? ([y]es/[n]o)" - input_str = "# Files to crawl:" + "\n" + list_str + "\n\n" + confirm_str - while True: - user_input = input(input_str) - if validate_user_input(user_input, options): - if user_input in ["no", "n"]: - print("\n# Process was canceled.") - return False - else: - return True - print("\n# Please enter a valid answer!") - continue - - -def blender_crawl_file(path: Path, script: Path) -> int: - # Get cmd list. - cmd_list = get_cmd_list(path, script) p = subprocess.Popen(cmd_list, shell=False) - # Stdout, stderr = p.communicate(). return p.wait() @@ -146,127 +124,54 @@ def is_filepath_valid(path: Path) -> None: # Check if path is file. if not path.is_file(): - raise Exception(f"Not a file: {path.suffix}") + cancel_program(f"Not a file: {path.suffix}") # Check if path is blend file. if path.suffix != ".blend": - raise Exception(f"Not a blend file: {path.suffix}") + cancel_program(f"Not a blend file: {path.suffix}") -def get_config_path() -> Path: - home = Path.home() - if sys.platform == "win32": - return home / "blender-crawl/config.json" - elif sys.platform == "linux": - return home / ".config/blender-crawl/config.json" - elif sys.platform == "darwin": - return home / ".config/blender-crawl/config.json" +def check_file_exists(file_path_str:str, error_msg:str): + if file_path_str is None: + return + file_path = Path(file_path_str).absolute() + if file_path.exists(): + return file_path + else: + cancel_program(error_msg) -def load_json(path: Path) -> Any: - with open(path.as_posix(), "r") as file: - obj = json.load(file) - return obj +def get_purge_path(purge:bool): + # Cancel function if user has not supplied purge arg + if not purge: + return + purge_script = os.path.join(Path(__file__).parent.resolve(), "default_scripts", "purge.py") + return check_file_exists(str(purge_script), "no purge found") - -def save_to_json(obj: Any, path: Path) -> None: - with open(path.as_posix(), "w") as file: - json.dump(obj, file, indent=4) - - -def input_path(question: str) -> Path: - while True: - user_input = input(question) - try: - path = Path(user_input) - except: - print("ERROR:# Invalid input") - continue - if path.exists(): - return path.absolute() - else: - print("# Path does not exist") - - -def input_filepath(question: str) -> Path: - while True: - path = input_path(question) - if not path.is_file(): - continue - return path - - -def setup_config(skip_finding_exec) -> None: - user_exec = True - if not skip_finding_exec: - if find_default_blender() is not None: - user_exec = False - blender_path = find_default_blender() - - - if user_exec: - blender_path = input_filepath("# Path to Blender binary: ") - - config_path = get_config_path() - config_path.parent.mkdir(parents=True, exist_ok=True) - obj = { - "blender_path": blender_path.as_posix(), - } - save_to_json(obj, config_path) - print("Updatet config at: %s", config_path.as_posix()) - - -def is_config_valid() -> bool: - keys = ["blender_path",] - config_path = get_config_path() - json_obj = load_json(config_path) - for key in keys: - if key not in json_obj: - return False - if not json_obj[key]: - return False - return True - -def get_default_scipt(script_input:str): - if script_input == "purge": - folder = Path(os.path.abspath(__file__)).parent - default_scripts = folder.joinpath("default_scripts") - return default_scripts.joinpath("purge.py").absolute() - return Path(script_input).absolute() - -@exception_handler def run_blender_crawl(args: argparse.Namespace) -> int: - # Parse arguments. path = Path(args.path).absolute() - script = get_default_scipt(args.script) + 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) recursive = args.recursive - skip_finding_exec = args.exec - config_path = get_config_path() + exec = args.exec regex = args.regex - yes = args.yes + ask_for_confirmation = args.ask - # Check config file. - if not config_path.exists() or skip_finding_exec: - print("# Seems like you are starting blender-crawl for the first time!") - print("# Some things needs to be configured") - setup_config(skip_finding_exec) - else: - if not is_config_valid(): - print("# Config file at: %s is not valid", config_path.as_posix()) - print("# Please set it up again") - setup_config(skip_finding_exec) - - # Check user input. - if not path: - raise Exception("Please provide a path as first argument") - - if not script.exists(): - raise Exception("Please provide a valid python script as second argument") + # Collect all possible scripts into list + scripts = [script for script in [script, purge_path] if script is not None] if not path.exists(): - raise Exception(f"Path does not exist: {path.as_posix()}") + cancel_program(f"Path does not exist: {path.as_posix()}") + if not exec: + blende_exec = find_executable() + else: + blende_exec = Path(exec).absolute() + + if not blende_exec.exists(): + cancel_program("Blender Executable Path is not valid") + # Vars. files = [] @@ -301,27 +206,33 @@ def run_blender_crawl(args: argparse.Namespace) -> int: # Can only happen on folder here. if not files: - print("# Found no .blend files to crawl") + print(" Found no .blend files to crawl") sys.exit(0) # Sort. files.sort(key=lambda f: f.name) - # Prompt confirm. - if not yes: - if not prompt_confirm(files): + for file in files: + print(f"Found: `{file}`") + + + if ask_for_confirmation: + if not prompt_confirm(len(files)): sys.exit(0) + if not scripts: + cancel_program("No --script was not provided as argument, printed found .blend files, exiting program. BIG") + sys.exit(0) + + + # crawl each file two times. - CRAWL_AMOUNT = 2 # TODO Figure out why this is here and remove if not needed for blend_file in files: - for i in range(CRAWL_AMOUNT): - return_code = blender_crawl_file(blend_file, script) + for script in scripts: + return_code = blender_crawl_file(blende_exec, blend_file, script) if return_code != 0: - raise Exception( - f"Blender Crashed on file: {blend_file.as_posix()}", - ) + cancel_program(f"Blender Crashed on file: {blend_file.as_posix()}") return 0 diff --git a/scripts/blender-crawl/blender_crawl/default_scripts/purge.py b/scripts/blender-crawl/blender_crawl/default_scripts/purge.py index 1759c8c4..57c1b2a2 100644 --- a/scripts/blender-crawl/blender_crawl/default_scripts/purge.py +++ b/scripts/blender-crawl/blender_crawl/default_scripts/purge.py @@ -19,25 +19,19 @@ # # (c) 2021, Blender Foundation -import sys -import logging - - -logger = logging.getLogger(__name__) - import bpy # Setup prefs. -bpy.context.preferences.filepaths.save_version = 0 +bpy.context.preferences.filepaths.save_version = 0 #TODO Figure out why this is here # Purge. -logger.info("Starting Recursive Purge") +print("Starting Recursive Purge") bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True) # Save. bpy.ops.wm.save_mainfile() -logger.info("Saved file: %s", bpy.data.filepath) +print("Saved file: %s", bpy.data.filepath) # Quit. -logger.info("Closing File") +print("Closing File") bpy.ops.wm.quit_blender() -- 2.30.2 From 39d93458878b14d86035adfce22e4d38663b7b9e Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 11:37:52 -0400 Subject: [PATCH 12/34] [Blender-Crawl] Find Blender Exec safely in Linux/Mac systems --- .../blender-crawl/blender_crawl/__main__.py | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index f9522863..04cc1c7e 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -1,4 +1,3 @@ - # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or @@ -20,6 +19,11 @@ # (c) 2021, Blender Foundation +#TODO + +# Supply Many Script Files +# Supply Many .blend Files + import argparse import sys import os @@ -32,11 +36,15 @@ from typing import List # Command line arguments. parser = argparse.ArgumentParser() 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( - "--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( "-R", @@ -64,31 +72,33 @@ parser.add_argument( parser.add_argument( "--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 def main(): args = parser.parse_args() run_blender_crawl(args) -def cancel_program(message:str): + +def cancel_program(message: str): print(message) sys.exit(0) def find_executable() -> Path: if os.name != 'nt': - output = subprocess.check_output(['whereis', 'blender']) # TODO Replace with command check syntax - default_blender_str = f'/{str(output).split(" /")[1]}' - default_blender_binary = Path(default_blender_str) - if default_blender_binary.exists(): - print("Blender Executable location Automatically Detected!") - return default_blender_binary + output = subprocess.run( + ['which', 'blender'], capture_output=True, encoding="utf-8" + ) + if output.returncode == 0: + # Returncode includes \n in string to indicate a new line + return Path(output.stdout.strip('\n')) cancel_program("Blender Executable not found please provide --exec argument") + def prompt_confirm(list_length: int): 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)" @@ -102,8 +112,6 @@ def prompt_confirm(list_length: int): return False else: return True - - def blender_crawl_file(exec: Path, path: Path, script: Path) -> int: @@ -121,7 +129,6 @@ def blender_crawl_file(exec: Path, path: Path, script: Path) -> int: def is_filepath_valid(path: Path) -> None: - # Check if path is file. if not path.is_file(): cancel_program(f"Not a file: {path.suffix}") @@ -131,8 +138,7 @@ def is_filepath_valid(path: Path) -> None: 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: return file_path = Path(file_path_str).absolute() @@ -141,18 +147,24 @@ def check_file_exists(file_path_str:str, error_msg:str): else: 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 if not purge: 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") - + def run_blender_crawl(args: argparse.Namespace) -> int: # Parse arguments. 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) recursive = args.recursive exec = args.exec @@ -165,13 +177,11 @@ def run_blender_crawl(args: argparse.Namespace) -> int: if not path.exists(): cancel_program(f"Path does not exist: {path.as_posix()}") if not exec: - blende_exec = find_executable() + blender_exec = find_executable() else: - blende_exec = Path(exec).absolute() - - if not blende_exec.exists(): - cancel_program("Blender Executable Path is not valid") - + blender_exec = Path(exec).absolute() + if not blender_exec.exists(): + cancel_program("Blender Executable Path is not valid") # Vars. files = [] @@ -214,23 +224,21 @@ def run_blender_crawl(args: argparse.Namespace) -> int: for file in files: print(f"Found: `{file}`") - if ask_for_confirmation: if not prompt_confirm(len(files)): sys.exit(0) 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) - - - # crawl each file two times. for blend_file in files: 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: cancel_program(f"Blender Crashed on file: {blend_file.as_posix()}") return 0 @@ -238,7 +246,3 @@ def run_blender_crawl(args: argparse.Namespace) -> int: if __name__ == "__main__": main() - - - - -- 2.30.2 From 1dbacb3250a8f4480956fe6aa58b8e62bc5b5ec2 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 11:50:41 -0400 Subject: [PATCH 13/34] [Blender-Crawl] Cleanup arguments --- scripts/blender-crawl/blender_crawl/__main__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 04cc1c7e..deccf671 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -20,7 +20,6 @@ #TODO - # Supply Many Script Files # Supply Many .blend Files @@ -47,24 +46,27 @@ parser.add_argument( type=str, ) parser.add_argument( - "-R", + "-r", "--recursive", help="If -R is provided in combination with a folder path will perform recursive crawl", action="store_true", ) parser.add_argument( - "--regex", - help="Provide any regex pattern that will be performed on each found filepath with re.search()", + "-f", + "--filter", + help="Provide a string to filter the found .blend files", ) parser.add_argument( + "-a", "--ask", help="If --ask is provided there will be no confirmation prompt before running script on .blend files.", action="store_true", ) parser.add_argument( + "-p", "--purge", help="Run 'built-in function to purge data-blocks from all .blend files found in crawl.'.", action="store_true", @@ -168,7 +170,7 @@ def run_blender_crawl(args: argparse.Namespace) -> int: purge_path = get_purge_path(args.purge) recursive = args.recursive exec = args.exec - regex = args.regex + regex = args.filter ask_for_confirmation = args.ask # Collect all possible scripts into list -- 2.30.2 From 4db4c4cc8481cf5c079678833e188e523794d21d Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 12:13:47 -0400 Subject: [PATCH 14/34] [Blender-Crawl] Pass Many Script/Blend Files --- .../blender-crawl/blender_crawl/__main__.py | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index deccf671..8c67accf 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -19,10 +19,6 @@ # (c) 2021, Blender Foundation -#TODO -# Supply Many Script Files -# Supply Many .blend Files - import argparse import sys import os @@ -36,14 +32,14 @@ from typing import List parser = argparse.ArgumentParser() parser.add_argument( "path", - help="Path to a file or folder on which to perform crawl", - type=str, + help="Path to a file(s) or folder(s) on which to perform crawl", + nargs='+' ) 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, + help="Path to blender python script(s) to execute inside .blend files during crawl. Execution is skipped if no script is provided", + nargs='+', ) parser.add_argument( "-r", @@ -130,7 +126,7 @@ def blender_crawl_file(exec: Path, path: Path, script: Path) -> int: return p.wait() -def is_filepath_valid(path: Path) -> None: +def is_filepath_blend(path: Path) -> None: # Check if path is file. if not path.is_file(): cancel_program(f"Not a file: {path.suffix}") @@ -161,23 +157,28 @@ def get_purge_path(purge: bool): def run_blender_crawl(args: argparse.Namespace) -> int: - # Parse arguments. - path = Path(args.path).absolute() - script = check_file_exists( - args.script, - "No --script was not provided as argument, printed found .blend files, exiting program.", - ) + # Parse arguments. purge_path = get_purge_path(args.purge) recursive = args.recursive exec = args.exec regex = args.filter + script_input = args.script ask_for_confirmation = args.ask - # Collect all possible scripts into list - scripts = [script for script in [script, purge_path] if script is not None] - if not path.exists(): - cancel_program(f"Path does not exist: {path.as_posix()}") + scripts = [] + if script_input: + for script in script_input: + script_name = check_file_exists( + script, + "No --script was not provided as argument, printed found .blend files, exiting program.", + ) + scripts.append(script_name) + + # Purge is optional so it can be none + if purge_path is not None: + script.append() + if not exec: blender_exec = find_executable() else: @@ -187,23 +188,27 @@ def run_blender_crawl(args: argparse.Namespace) -> int: # Vars. files = [] + for item in args.path: + file_path = Path(item).absolute() + if not file_path.exists(): + cancel_program(f"Path does not exist: {file_path.as_posix()}") - # Collect files to crawl - # if dir. - if path.is_dir(): - if recursive: - blend_files = [ - f for f in path.glob("**/*") if f.is_file() and f.suffix == ".blend" - ] + # Collect files to crawl + # if dir. + if file_path.is_dir(): + if recursive: + blend_files = [ + f for f in file_path.glob("**/*") if f.is_file() and f.suffix == ".blend" + ] + else: + blend_files = [ + f for f in file_path.iterdir() if f.is_file() and f.suffix == ".blend" + ] + files.extend(blend_files) + # If just one file. else: - blend_files = [ - f for f in path.iterdir() if f.is_file() and f.suffix == ".blend" - ] - files.extend(blend_files) - # If just one file. - else: - is_filepath_valid(path) - files.append(path) + is_filepath_blend(file_path) + files.append(file_path) # Apply regex. if regex: -- 2.30.2 From 2d131afb479760a84a0c6bec7297eff0e28a3656 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 12:24:26 -0400 Subject: [PATCH 15/34] [Blender-Crawl] Remove no-op code --- .../blender-crawl/blender_crawl/__main__.py | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 8c67accf..a2d3fa2b 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -75,12 +75,6 @@ parser.add_argument( ) -# MAIN LOGIC -def main(): - args = parser.parse_args() - run_blender_crawl(args) - - def cancel_program(message: str): print(message) sys.exit(0) @@ -112,20 +106,6 @@ def prompt_confirm(list_length: int): return True -def blender_crawl_file(exec: Path, path: Path, script: Path) -> int: - # Get cmd list. - cmd_list = ( - exec.as_posix(), - path.as_posix(), - "-b", - "-P", - script, - "--factory-startup", - ) - p = subprocess.Popen(cmd_list, shell=False) - return p.wait() - - def is_filepath_blend(path: Path) -> None: # Check if path is file. if not path.is_file(): @@ -156,8 +136,10 @@ def get_purge_path(purge: bool): return check_file_exists(str(purge_script), "no purge found") -def run_blender_crawl(args: argparse.Namespace) -> int: - # Parse arguments. +def main() -> int: + """Crawl blender files in a directory and run a provided scripts""" + # Parse arguments. + args = parser.parse_args() purge_path = get_purge_path(args.purge) recursive = args.recursive exec = args.exec @@ -165,7 +147,6 @@ def run_blender_crawl(args: argparse.Namespace) -> int: script_input = args.script ask_for_confirmation = args.ask - scripts = [] if script_input: for script in script_input: @@ -245,11 +226,18 @@ def run_blender_crawl(args: argparse.Namespace) -> int: # crawl each file two times. for blend_file in files: for script in scripts: - return_code = blender_crawl_file(blender_exec, blend_file, script) - if return_code != 0: + cmd_list = ( + blender_exec.as_posix(), + blend_file.as_posix(), + "-b", + "-P", + script, + "--factory-startup", + ) + process = subprocess.Popen(cmd_list, shell=False) + if process.wait() != 0: cancel_program(f"Blender Crashed on file: {blend_file.as_posix()}") return 0 - if __name__ == "__main__": main() -- 2.30.2 From 0053efc97de14aa3f93b1c031a3ee82b870cb6e7 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 13:28:18 -0400 Subject: [PATCH 16/34] [Blender-Crawl] Fix typo for purge argument --- scripts/blender-crawl/blender_crawl/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index a2d3fa2b..b4f5268e 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -158,7 +158,7 @@ def main() -> int: # Purge is optional so it can be none if purge_path is not None: - script.append() + scripts.append(purge_path) if not exec: blender_exec = find_executable() -- 2.30.2 From 81df9cd091a4171df8eaf6354c4bc4d61763d0e9 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 13:30:07 -0400 Subject: [PATCH 17/34] [Blender-Crawl] Update no scripts error message --- scripts/blender-crawl/blender_crawl/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index b4f5268e..ce8dbae9 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -219,7 +219,7 @@ def main() -> int: if not scripts: cancel_program( - "No --script was not provided as argument, printed found .blend files, exiting program. BIG" + "No valid script files were found. Exiting program." ) sys.exit(0) -- 2.30.2 From 9d29be38a440dd0cb9577d4af0f35b8826bfe843 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 13:30:34 -0400 Subject: [PATCH 18/34] [Blender-Crawl] Remove no-op files --- scripts/blender-crawl/HISTORY.md | 0 scripts/blender-crawl/install.sh | 46 -------------------------------- 2 files changed, 46 deletions(-) delete mode 100644 scripts/blender-crawl/HISTORY.md delete mode 100644 scripts/blender-crawl/install.sh diff --git a/scripts/blender-crawl/HISTORY.md b/scripts/blender-crawl/HISTORY.md deleted file mode 100644 index e69de29b..00000000 diff --git a/scripts/blender-crawl/install.sh b/scripts/blender-crawl/install.sh deleted file mode 100644 index 2cd05031..00000000 --- a/scripts/blender-crawl/install.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' # No Color. - -# Check if pip3 is installed. -if ! command -v pip3 &> /dev/null -then - echo "Pip3 is not installed" - - # Ask user to install pip. - while true; do - read -p "Do you wish to install this program? (Yy/Nn)" yn - case $yn in - [Yy]* ) sudo apt install python3-pip; break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done -fi - -# Cd into directory of install.sh script. -dirpath=`dirname "$0"` -cd $dirpath - -# Build wheel. -python3 setup.py bdist_wheel - -# Install wheel with pip. -pip3 install dist/blender_purge-0.1.0-py2.py3-none-any.whl --user --force-reinstall - -# Check if PATH variable is correct. -if ! [[ ":$PATH:" == *":$HOME/.local/lib/python3.8/site-packages:"* ]]; then - printf "\n${RED}\$HOME/.local/lib/python3.8/site-packages is missing in PATH variable\n" - printf "Please add 'export PATH=\"\$PATH:$HOME/.local/lib/python3.8/site-packages\"' to the file: \$HOME/.profile${NC}\n" -fi - -if ! [[ ":$PATH:" == *":$HOME/.local/bin:"* ]]; then - printf "\n${RED}\$HOME/.local/bin is missing in PATH variable\n" - printf "Please add 'export PATH=\"\$PATH:$HOME/.local/bin\"' to the file: \$HOME/.profile${NC}\n" -fi - -# Log end. -printf "\n${GREEN}Installed blender-purge. Type 'bpurge' in console to start program!\n" -printf "To uninstall type 'pip3 uninstall blender-purge'${NC}\n" -- 2.30.2 From cfcc74f7f9aedf9059b9a4fe3aa0c3e45471bb69 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 13:41:09 -0400 Subject: [PATCH 19/34] [Blender-Crawl] Update setup.py to use Blender_Crawl name --- scripts/blender-crawl/setup.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index 29427bca..1ca1a9a8 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +# TODO Put the default_scripts in /usr/share and adjust main Logic to accomodate + """The setup script.""" from setuptools import setup, find_packages @@ -7,8 +9,6 @@ from setuptools import setup, find_packages with open("README.md") as readme_file: readme = readme_file.read() -with open("HISTORY.md") as history_file: - history = history_file.read() requirements = [] @@ -17,11 +17,11 @@ setup_requirements = [] test_requirements = [] setup( - author="Paul Golter", - author_email="paul@blender.org", + author="Nick Alberelli", + author_email="nick@blender.org", python_requires=">=3.5", classifiers=[ - "Development Status :: 2 - Pre-Alpha", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Natural Language :: English", "Programming Language :: Python :: 3", @@ -30,17 +30,17 @@ setup( "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", ], - description="Command line tool to perform recursive purge of blend files in the console", + description="Command line tool to perform recursive crawl blend files from the console", install_requires=requirements, - long_description=readme + "\n\n" + history, + long_description=readme, include_package_data=True, - keywords="blender_purge", - name="blender_purge", - packages=find_packages(include=["blender_purge", "blender_purge.*"]), + keywords="blender_crawl", + name="blender_crawl", + packages=find_packages(include=["blender_crawl", "blender_crawl.*"]), setup_requires=setup_requirements, test_suite="tests", tests_require=test_requirements, version="0.1.0", zip_safe=False, - entry_points={"console_scripts": ["bpurge = blender_purge.__main__:main"]}, + entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, ) -- 2.30.2 From 1f3e993ea50ea9197b91ea3384930e970c3fcc48 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 15:58:01 -0400 Subject: [PATCH 20/34] [Blender-Crawl] Add TODO for setting default_script location with setup.py --- scripts/blender-crawl/blender_crawl/__main__.py | 8 ++++++++ scripts/blender-crawl/setup.py | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index ce8dbae9..882e232e 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -137,6 +137,14 @@ def get_purge_path(purge: bool): def main() -> int: + import sys + + # TODO Safely get 'default_purge' path set by setup.py, Debug why this doesn't work + # module = sys.modules['__main__'] + # https://stackoverflow.com/questions/6028000/how-to-read-a-static-file-from-inside-a-python-package + # print(pkg_resources.resource_stream("blender-crawl", 'default_purge')) + # print(module) + """Crawl blender files in a directory and run a provided scripts""" # Parse arguments. args = parser.parse_args() diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index 1ca1a9a8..d451f9e6 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -43,4 +43,7 @@ setup( version="0.1.0", zip_safe=False, entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, -) + data_files=[ + ('default_purge', ['blender_crawl/default_scripts/purge.py']) + ] +) \ No newline at end of file -- 2.30.2 From 84a78f194dfa20530d68b72098a6822b4333b8da Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 16:22:22 -0400 Subject: [PATCH 21/34] [Blender-Crawl] Set all naming to use '-' instead of '_' --- .../{blender_crawl => blender-crawl}/__main__.py | 0 .../default-scripts}/purge.py | 0 scripts/blender-crawl/setup.py | 11 ++++++----- 3 files changed, 6 insertions(+), 5 deletions(-) rename scripts/blender-crawl/{blender_crawl => blender-crawl}/__main__.py (100%) rename scripts/blender-crawl/{blender_crawl/default_scripts => blender-crawl/default-scripts}/purge.py (100%) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender-crawl/__main__.py similarity index 100% rename from scripts/blender-crawl/blender_crawl/__main__.py rename to scripts/blender-crawl/blender-crawl/__main__.py diff --git a/scripts/blender-crawl/blender_crawl/default_scripts/purge.py b/scripts/blender-crawl/blender-crawl/default-scripts/purge.py similarity index 100% rename from scripts/blender-crawl/blender_crawl/default_scripts/purge.py rename to scripts/blender-crawl/blender-crawl/default-scripts/purge.py diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index d451f9e6..c94cbca8 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -34,16 +34,17 @@ setup( install_requires=requirements, long_description=readme, include_package_data=True, - keywords="blender_crawl", - name="blender_crawl", - packages=find_packages(include=["blender_crawl", "blender_crawl.*"]), + keywords="blender-crawl", + name="blender-crawl", + packages=find_packages(include=["blender-crawl", "blender-crawl.*"]), setup_requires=setup_requirements, test_suite="tests", tests_require=test_requirements, version="0.1.0", zip_safe=False, - entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, + # TODO Verify entry point needs to use '_' isntead of '-' + entry_points={"console_scripts": ["blender-crawl = blender_crawl.__main__:main"]}, data_files=[ - ('default_purge', ['blender_crawl/default_scripts/purge.py']) + ('default_purge', ['blender-crawl/default-scripts/purge.py']) ] ) \ No newline at end of file -- 2.30.2 From e1752508ed9f2f5540539d7ac0d5f3ae31eff9e1 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Thu, 11 May 2023 16:22:41 -0400 Subject: [PATCH 22/34] [Blender-Crawl] Update readme to new options --- scripts/blender-crawl/README.md | 71 +++++++++++---------------------- 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/scripts/blender-crawl/README.md b/scripts/blender-crawl/README.md index d802d5c0..5712a956 100644 --- a/scripts/blender-crawl/README.md +++ b/scripts/blender-crawl/README.md @@ -1,71 +1,48 @@ -# blender-purge -blender-purge is a command line tools to purge orphan data of blend files via the console. +# blender-crawl +blender-crawl is a command line tools to purge orphan data of blend files via the console. ## Table of Contents - [Prerequisite](#prerequisite) - [Installation](#installation) - [How to get started](#how-to-get-started) -- [Development](#development) ## Prerequisite In order to use this tool you need: - python3 -- pip -- svn + +## Run without Installation +1. Clone repository +2. run `cd blender-crawl` to enter directory +3. Run program with `python blender-crawl /directory/` ## Installation Download or clone this repository. -This repository is a command line tool that can be installed with the python packaging manager. -In the root of this project you can find a `install.sh` script which simplifies this process on linux. - +This repository is a command line tool that can be installed with the python packaging manager. This script does the following (follow this if you want to do this manually or on another platform): -1. Install pip -2. Open a terminal in the root of the project directory -3. Run `python3 setup.py bdist_wheel` which builds a wheel in ./dist -4. Run `pip3 install dist/ --user` +1. Clone repository +2. Run `cd blender-crawl` to enter directory +3. Install with `python setup.py install` +4. Run with `sudo python -m blender-crawl /directory/` +5. Get help with `sudo python3 -m blender-crawl -h` -Ensure your $PATH variable contains: - -Linux/MacOs: -- `$HOME/.local/lib/python3.8/site-packages` -- `$HOME/.local/bin` - -Windows: -- TODO - -Open a new console and write `bpurge` to verify successful install. ## How to get started -After install you can write `bpurge` in to the console. +Run directly out of repo folder or follow above installation instructions. -If you use the tool the first time it will ask you to specify a path to a blender executable and a path to the svn project directory, which will be saved in a configuration file: - -Linux/MacOs: -- `$home/.config/blender-purge/config.json` - -Windows: -- `$home/blender-purge/config.json` - - -Give `bpurge` a path to a .blend file or a folder as first argument. +Give `blender-crawl` a path to a .blend file or a folder as first argument. The detected blend files will be opened in the background, their orphan data will be purged recursively, the file gets saved and closed again. This will happen twice for each .blend file. -You can modify the tool by providing these command line arguments: +If blender is not installed at the default location of your computer, you need to provide a blender executable +using the --exec flag. -- first arguments needs to be a path to a .blend file or a folder - -- **-R / --recursive**: If -R is provided in combination with a folder path will perform recursive purge. - -- **-N / --nocommit**: If -N is provided there will be no svn commit prompt with the purged files. - -- **--regex**: Provide any regex pattern that will be performed on each found filepath with re.search(). - -- **--yes**: If --yes is provided there will be no confirmation prompt. + - --script Path to blender python script(s) to execute inside .blend files during crawl. Execution is skipped if no script is provided + - -r, --recursive If -R is provided in combination with a folder path will perform recursive crawl + - -f --filter Provide a string to filter the found .blend files + - -a, --ask If --ask is provided there will be no confirmation prompt before running script on .blend files. + - -p, --purge Run 'built-in function to purge data-blocks from all .blend files found in crawl.'. + - --exec EXEC If --exec user must provide blender executable path, OS default blender will not be used if found. + - -h, --help show the above help message and exit -## Development -In the project root you will find a `pyproject.toml` and `peotry.lock` file. -With `poetry` you can easily generate a virtual env for the project which should get you setup quickly. -Basic Usage: https://python-poetry.org/docs/basic-usage/ -- 2.30.2 From e21f09ff34e879b425783ba69758c59a914d5cad Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 08:48:35 -0400 Subject: [PATCH 23/34] Revert "[Blender-Crawl] Set all naming to use '-' instead of '_'" This reverts commit c770bcab228c224872027262881e8c6566b065dc. --- .../{blender-crawl => blender_crawl}/__main__.py | 0 .../default_scripts}/purge.py | 0 scripts/blender-crawl/setup.py | 11 +++++------ 3 files changed, 5 insertions(+), 6 deletions(-) rename scripts/blender-crawl/{blender-crawl => blender_crawl}/__main__.py (100%) rename scripts/blender-crawl/{blender-crawl/default-scripts => blender_crawl/default_scripts}/purge.py (100%) diff --git a/scripts/blender-crawl/blender-crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py similarity index 100% rename from scripts/blender-crawl/blender-crawl/__main__.py rename to scripts/blender-crawl/blender_crawl/__main__.py diff --git a/scripts/blender-crawl/blender-crawl/default-scripts/purge.py b/scripts/blender-crawl/blender_crawl/default_scripts/purge.py similarity index 100% rename from scripts/blender-crawl/blender-crawl/default-scripts/purge.py rename to scripts/blender-crawl/blender_crawl/default_scripts/purge.py diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index c94cbca8..d451f9e6 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -34,17 +34,16 @@ setup( install_requires=requirements, long_description=readme, include_package_data=True, - keywords="blender-crawl", - name="blender-crawl", - packages=find_packages(include=["blender-crawl", "blender-crawl.*"]), + keywords="blender_crawl", + name="blender_crawl", + packages=find_packages(include=["blender_crawl", "blender_crawl.*"]), setup_requires=setup_requirements, test_suite="tests", tests_require=test_requirements, version="0.1.0", zip_safe=False, - # TODO Verify entry point needs to use '_' isntead of '-' - entry_points={"console_scripts": ["blender-crawl = blender_crawl.__main__:main"]}, + entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, data_files=[ - ('default_purge', ['blender-crawl/default-scripts/purge.py']) + ('default_purge', ['blender_crawl/default_scripts/purge.py']) ] ) \ No newline at end of file -- 2.30.2 From 1ebfa51fe386ebcc934dc1700986fc1444664639 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 08:54:51 -0400 Subject: [PATCH 24/34] [Blender-Crawl] Update Readme --- scripts/blender-crawl/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/blender-crawl/README.md b/scripts/blender-crawl/README.md index 5712a956..2113c437 100644 --- a/scripts/blender-crawl/README.md +++ b/scripts/blender-crawl/README.md @@ -1,5 +1,5 @@ -# blender-crawl -blender-crawl is a command line tools to purge orphan data of blend files via the console. +# blender_crawl +blender_crawl is a command line tools to purge orphan data of blend files via the console. ## Table of Contents - [Prerequisite](#prerequisite) @@ -11,9 +11,9 @@ In order to use this tool you need: - python3 ## Run without Installation -1. Clone repository -2. run `cd blender-crawl` to enter directory -3. Run program with `python blender-crawl /directory/` +1. Clone repository the +2. run `cd blender_crawl` to enter directory +3. Run program with `python blender_crawl /directory/` ## Installation Download or clone this repository. @@ -21,16 +21,16 @@ This repository is a command line tool that can be installed with the python pac This script does the following (follow this if you want to do this manually or on another platform): 1. Clone repository -2. Run `cd blender-crawl` to enter directory +2. Run `cd blender_crawl` to enter directory 3. Install with `python setup.py install` -4. Run with `sudo python -m blender-crawl /directory/` -5. Get help with `sudo python3 -m blender-crawl -h` +4. Run with `sudo python -m blender_crawl /directory/` +5. Get help with `sudo python3 -m blender_crawl -h` ## How to get started Run directly out of repo folder or follow above installation instructions. -Give `blender-crawl` a path to a .blend file or a folder as first argument. +Give ``blender_crawl`` a path to a .blend file or a folder as first argument. The detected blend files will be opened in the background, their orphan data will be purged recursively, the file gets saved and closed again. This will happen twice for each .blend file. -- 2.30.2 From 5f284110aaa4d23bef7a9d3ae8b3d065ea062ac2 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 09:51:59 -0400 Subject: [PATCH 25/34] [Blender_Crawl] Safely get default script loaction --- scripts/blender-crawl/blender_crawl/__main__.py | 14 +++----------- scripts/blender-crawl/setup.py | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 882e232e..d202fa7d 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -130,21 +130,13 @@ def get_purge_path(purge: bool): # Cancel function if user has not supplied purge arg if not purge: return - purge_script = os.path.join( - Path(__file__).parent.resolve(), "default_scripts", "purge.py" - ) - return check_file_exists(str(purge_script), "no purge found") + scripts_directory = Path((os.path.dirname(__file__))).joinpath("default_scripts/") + purge_script = os.path.join(scripts_directory.resolve(), "purge.py") + return check_file_exists(str(purge_script), "Default scripts location may be invalid") def main() -> int: import sys - - # TODO Safely get 'default_purge' path set by setup.py, Debug why this doesn't work - # module = sys.modules['__main__'] - # https://stackoverflow.com/questions/6028000/how-to-read-a-static-file-from-inside-a-python-package - # print(pkg_resources.resource_stream("blender-crawl", 'default_purge')) - # print(module) - """Crawl blender files in a directory and run a provided scripts""" # Parse arguments. args = parser.parse_args() diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index d451f9e6..3436ebb4 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -36,7 +36,7 @@ setup( include_package_data=True, keywords="blender_crawl", name="blender_crawl", - packages=find_packages(include=["blender_crawl", "blender_crawl.*"]), + packages=["blender_crawl",], setup_requires=setup_requirements, test_suite="tests", tests_require=test_requirements, -- 2.30.2 From f8e216772f38ce59f28240ec322b5708d915b1e6 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 10:30:51 -0400 Subject: [PATCH 26/34] [Blender-Crawl] Update documentation and Help Messages --- scripts/blender-crawl/README.md | 72 +++++++++++++------ .../blender-crawl/blender_crawl/__main__.py | 19 +++-- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/scripts/blender-crawl/README.md b/scripts/blender-crawl/README.md index 2113c437..a537c0b9 100644 --- a/scripts/blender-crawl/README.md +++ b/scripts/blender-crawl/README.md @@ -8,41 +8,69 @@ blender_crawl is a command line tools to purge orphan data of blend files via th ## Prerequisite In order to use this tool you need: -- python3 +- Python 3.5+ ## Run without Installation -1. Clone repository the -2. run `cd blender_crawl` to enter directory -3. Run program with `python blender_crawl /directory/` +1. Clone this repository with `git clone https://projects.blender.org/studio/blender-studio-pipeline.git` +2. Run `cd blender-studio-pipeline/scripts/blender-crawl` to enter directory +3. Run program with `python blender_crawl /my-folder/` ## Installation Download or clone this repository. This repository is a command line tool that can be installed with the python packaging manager. This script does the following (follow this if you want to do this manually or on another platform): -1. Clone repository -2. Run `cd blender_crawl` to enter directory +1. Clone this repository with `git clone https://projects.blender.org/studio/blender-studio-pipeline.git` +2. Run `cd blender-studio-pipeline/scripts/blender-crawl` to enter directory 3. Install with `python setup.py install` -4. Run with `sudo python -m blender_crawl /directory/` +4. Run with `sudo python -m blender_crawl /my-folder/` 5. Get help with `sudo python3 -m blender_crawl -h` ## How to get started -Run directly out of repo folder or follow above installation instructions. +Run directly out of repo folder or follow above installation instructions. Give `blender_crawl` a path to a .blend file or a folder as first argument, The detected blend files will be opened in the background, the python script will be executed, and the file closes. If blender is not installed at the default location of your computer, you need to provide a blender executable using the --exec flag. + +| Command | Description | +| ----------- | ----------- | +| --script| Path to blender python script(s) to execute inside .blend files during crawl.| +| -r, --recursive| If provided in combination with a folder path will perform recursive crawl| +| -f --filter| Provide a string to filter the found .blend files| +| -a, --ask| If provided there will be no confirmation prompt before running script on .blend files.| +| -p, --purge| Run 'built-in function to purge data-blocks from all .blend files found in crawl.'.| +| --exec| If provided user must provide blender executable path, OS default blender will not be used if found.| +| -h, --help| show the above help message and exit| + + +## Usage Examples +### Basic Operation +Prints the names of .blends in Current Directory +> `python -m blender_crawl ./` + +### Recursive +Print the names of .blends Recursively +> `python -m blender_crawl /my-folder/ --recursive` + +### Find +Print only the names of .blends matching a provided string +> `python -m blender_crawl /my-folder/ --find string` + +### Purge +Run default 'Purge' script on .blends in Current Directory +> `python -m blender_crawl /my-folder/ --purge` + +### Script +Run custom script on all .blends in Current Directory +> `python -m blender_crawl /my-folder/ --script /my-directory/my-script.py` + +### Ask +Ask/Prompt before script execution +> `python -m blender_crawl /my-folder/ --script /my-directory/my-script.py --ask` + +### Exec +Run with a custom blender executable +> `python -m blender_crawl /my-folder/ --exec /path-to-blender-executable/blender` + + -Give ``blender_crawl`` a path to a .blend file or a folder as first argument. -The detected blend files will be opened in the background, their orphan data will be -purged recursively, the file gets saved and closed again. This will happen twice for each .blend file. - -If blender is not installed at the default location of your computer, you need to provide a blender executable -using the --exec flag. - - - --script Path to blender python script(s) to execute inside .blend files during crawl. Execution is skipped if no script is provided - - -r, --recursive If -R is provided in combination with a folder path will perform recursive crawl - - -f --filter Provide a string to filter the found .blend files - - -a, --ask If --ask is provided there will be no confirmation prompt before running script on .blend files. - - -p, --purge Run 'built-in function to purge data-blocks from all .blend files found in crawl.'. - - --exec EXEC If --exec user must provide blender executable path, OS default blender will not be used if found. - - -h, --help show the above help message and exit diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index d202fa7d..9b521e2e 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -37,6 +37,14 @@ parser.add_argument( ) parser.add_argument( + "-e", + "--exec", + help="If --exec user must provide blender executable path, OS default blender will not be used if found.", + type=str, +) + +parser.add_argument( + "-s", "--script", help="Path to blender python script(s) to execute inside .blend files during crawl. Execution is skipped if no script is provided", nargs='+', @@ -44,7 +52,7 @@ parser.add_argument( parser.add_argument( "-r", "--recursive", - help="If -R is provided in combination with a folder path will perform recursive crawl", + help="If -r is provided in combination with a folder path will perform recursive crawl", action="store_true", ) @@ -68,15 +76,12 @@ parser.add_argument( action="store_true", ) -parser.add_argument( - "--exec", - help="If --exec user must provide blender executable path, OS default blender will not be used if found.", - type=str, -) + def cancel_program(message: str): print(message) + print('Exiting blender_crawl.') sys.exit(0) @@ -219,7 +224,7 @@ def main() -> int: if not scripts: cancel_program( - "No valid script files were found. Exiting program." + "No script files were provided to execute." ) sys.exit(0) -- 2.30.2 From 739b2131447599147456bbdb9ac373565ce4f75c Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 10:39:09 -0400 Subject: [PATCH 27/34] [Blender-Crawl] Update Documentation --- scripts/blender-crawl/README.md | 42 ++++++++------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/scripts/blender-crawl/README.md b/scripts/blender-crawl/README.md index a537c0b9..668245bd 100644 --- a/scripts/blender-crawl/README.md +++ b/scripts/blender-crawl/README.md @@ -1,6 +1,5 @@ # blender_crawl -blender_crawl is a command line tools to purge orphan data of blend files via the console. - +`blender_crawl` is a command line tools to crawl directories for .blend files and execute a provied script. ## Table of Contents - [Prerequisite](#prerequisite) - [Installation](#installation) @@ -42,35 +41,14 @@ Run directly out of repo folder or follow above installation instructions. Give ## Usage Examples -### Basic Operation -Prints the names of .blends in Current Directory -> `python -m blender_crawl ./` - -### Recursive -Print the names of .blends Recursively -> `python -m blender_crawl /my-folder/ --recursive` - -### Find -Print only the names of .blends matching a provided string -> `python -m blender_crawl /my-folder/ --find string` - -### Purge -Run default 'Purge' script on .blends in Current Directory -> `python -m blender_crawl /my-folder/ --purge` - -### Script -Run custom script on all .blends in Current Directory -> `python -m blender_crawl /my-folder/ --script /my-directory/my-script.py` - -### Ask -Ask/Prompt before script execution -> `python -m blender_crawl /my-folder/ --script /my-directory/my-script.py --ask` - -### Exec -Run with a custom blender executable -> `python -m blender_crawl /my-folder/ --exec /path-to-blender-executable/blender` - - - +| Action | Command | +| ----------- | ----------- | +|Prints the names of .blends in Current Directory | `python -m blender_crawl ./` | +|Print the names of .blends Recursively | `python -m blender_crawl /my-folder/ --recursive` | +|Print only the names of .blends matching a provided string |`python -m blender_crawl /my-folder/ --find string`| +|Run default 'Purge' script on .blends in Current Directory |`python -m blender_crawl /my-folder/ --purge`| +|Run custom script on all .blends in Current Directory |`python -m blender_crawl /my-folder/ --script /my-directory/my-script.py`| +|Ask/Prompt before script execution|`python -m blender_crawl /my-folder/ --script /my-directory/my-script.py --ask`| +|Run with a custom blender executable|`python -m blender_crawl /my-folder/ --exec /path-to-blender-executable/blender`| -- 2.30.2 From f361f2ffe10ac265675ad61d79140dc9e73a8691 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 12:20:00 -0400 Subject: [PATCH 28/34] [Blender-Crawl] Remove 'python -m' from documenation --- scripts/blender-crawl/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/blender-crawl/README.md b/scripts/blender-crawl/README.md index 668245bd..2dfbe385 100644 --- a/scripts/blender-crawl/README.md +++ b/scripts/blender-crawl/README.md @@ -22,8 +22,8 @@ This script does the following (follow this if you want to do this manually or o 1. Clone this repository with `git clone https://projects.blender.org/studio/blender-studio-pipeline.git` 2. Run `cd blender-studio-pipeline/scripts/blender-crawl` to enter directory 3. Install with `python setup.py install` -4. Run with `sudo python -m blender_crawl /my-folder/` -5. Get help with `sudo python3 -m blender_crawl -h` +4. Run with `blender_crawl /my-folder/` +5. Get help with `blender_crawl -h` ## How to get started @@ -44,11 +44,11 @@ Run directly out of repo folder or follow above installation instructions. Give | Action | Command | | ----------- | ----------- | -|Prints the names of .blends in Current Directory | `python -m blender_crawl ./` | -|Print the names of .blends Recursively | `python -m blender_crawl /my-folder/ --recursive` | -|Print only the names of .blends matching a provided string |`python -m blender_crawl /my-folder/ --find string`| -|Run default 'Purge' script on .blends in Current Directory |`python -m blender_crawl /my-folder/ --purge`| -|Run custom script on all .blends in Current Directory |`python -m blender_crawl /my-folder/ --script /my-directory/my-script.py`| -|Ask/Prompt before script execution|`python -m blender_crawl /my-folder/ --script /my-directory/my-script.py --ask`| -|Run with a custom blender executable|`python -m blender_crawl /my-folder/ --exec /path-to-blender-executable/blender`| +|Prints the names of .blends in Current Directory | `blender_crawl ./` | +|Print the names of .blends Recursively | `blender_crawl /my-folder/ --recursive` | +|Print only the names of .blends matching a provided string |`blender_crawl /my-folder/ --find string`| +|Run default 'Purge' script on .blends in Current Directory |`blender_crawl /my-folder/ --purge`| +|Run custom script on all .blends in Current Directory |`blender_crawl /my-folder/ --script /my-directory/my-script.py`| +|Ask/Prompt before script execution|`blender_crawl /my-folder/ --script /my-directory/my-script.py --ask`| +|Run with a custom blender executable|`blender_crawl /my-folder/ --exec /path-to-blender-executable/blender`| -- 2.30.2 From 6a184b4e260317ff1bbeeebecfb9ad047481be99 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 12:31:27 -0400 Subject: [PATCH 29/34] [Blender-Crawl] Remove 'data_files' from setup.py --- scripts/blender-crawl/setup.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index 3436ebb4..e3045a96 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -43,7 +43,4 @@ setup( version="0.1.0", zip_safe=False, entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, - data_files=[ - ('default_purge', ['blender_crawl/default_scripts/purge.py']) - ] ) \ No newline at end of file -- 2.30.2 From eacef330ac108efa5027228f989d4279b3e7c145 Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 12:37:55 -0400 Subject: [PATCH 30/34] [Blender-Crawl] Remove No-Op Code from setup.py and clear TODO --- scripts/blender-crawl/setup.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index e3045a96..669c7ecc 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -1,21 +1,12 @@ #!/usr/bin/env python +"""The setup script for blender-crawl.""" -# TODO Put the default_scripts in /usr/share and adjust main Logic to accomodate - -"""The setup script.""" - -from setuptools import setup, find_packages +from setuptools import setup with open("README.md") as readme_file: readme = readme_file.read() -requirements = [] - -setup_requirements = [] - -test_requirements = [] - setup( author="Nick Alberelli", author_email="nick@blender.org", @@ -31,16 +22,11 @@ setup( "Programming Language :: Python :: 3.8", ], description="Command line tool to perform recursive crawl blend files from the console", - install_requires=requirements, long_description=readme, include_package_data=True, keywords="blender_crawl", name="blender_crawl", packages=["blender_crawl",], - setup_requires=setup_requirements, - test_suite="tests", - tests_require=test_requirements, version="0.1.0", - zip_safe=False, entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, ) \ No newline at end of file -- 2.30.2 From d128f19b45902ad885127c2d6d8e237958a2211f Mon Sep 17 00:00:00 2001 From: Nick Alberelli Date: Fri, 12 May 2023 12:51:13 -0400 Subject: [PATCH 31/34] [Blender-Crawl] restore 'package_data' to setup.py --- scripts/blender-crawl/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index 669c7ecc..e3022dec 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -29,4 +29,5 @@ setup( packages=["blender_crawl",], version="0.1.0", entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, + package_data={'default_purge': ['blender_crawl/default_scripts/purge.py']}, #TODO Verify this is working correctly after install ) \ No newline at end of file -- 2.30.2 From a2a3517696106f0a467635f20ef5d58289a8aa1a Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Mon, 15 May 2023 12:10:47 +0200 Subject: [PATCH 32/34] [Blender-Crawl] Fix setup.py not installing the bundled scripts --- scripts/blender-crawl/setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/blender-crawl/setup.py b/scripts/blender-crawl/setup.py index e3022dec..7d1f93c2 100644 --- a/scripts/blender-crawl/setup.py +++ b/scripts/blender-crawl/setup.py @@ -26,8 +26,8 @@ setup( include_package_data=True, keywords="blender_crawl", name="blender_crawl", - packages=["blender_crawl",], + packages=["blender_crawl", "blender_crawl.default_scripts",], version="0.1.0", entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]}, - package_data={'default_purge': ['blender_crawl/default_scripts/purge.py']}, #TODO Verify this is working correctly after install -) \ No newline at end of file + package_data={'blender_crawl.default_scripts': ['*']}, #TODO Verify this is working correctly after install +) -- 2.30.2 From 032da6d24866667ba6fd41b5c2d1bbafcbc91f52 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Mon, 15 May 2023 12:11:32 +0200 Subject: [PATCH 33/34] [Blender-Crawl] Remove trailing whitespace --- scripts/blender-crawl/blender_crawl/__main__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index 9b521e2e..d1c8ac62 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -59,7 +59,7 @@ parser.add_argument( parser.add_argument( "-f", "--filter", - help="Provide a string to filter the found .blend files", + help="Provide a string to filter the found .blend files", ) parser.add_argument( @@ -144,7 +144,7 @@ def main() -> int: import sys """Crawl blender files in a directory and run a provided scripts""" # Parse arguments. - args = parser.parse_args() + args = parser.parse_args() purge_path = get_purge_path(args.purge) recursive = args.recursive exec = args.exec @@ -158,13 +158,13 @@ def main() -> int: script_name = check_file_exists( script, "No --script was not provided as argument, printed found .blend files, exiting program.", - ) + ) scripts.append(script_name) - + # Purge is optional so it can be none if purge_path is not None: scripts.append(purge_path) - + if not exec: blender_exec = find_executable() else: -- 2.30.2 From d6a332265d733c8c220263768f0048a985afc3d0 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Mon, 15 May 2023 12:15:54 +0200 Subject: [PATCH 34/34] [Blender-Crawl] Remove superfluous "Exiting" message --- scripts/blender-crawl/blender_crawl/__main__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/blender-crawl/blender_crawl/__main__.py b/scripts/blender-crawl/blender_crawl/__main__.py index d1c8ac62..124e600f 100644 --- a/scripts/blender-crawl/blender_crawl/__main__.py +++ b/scripts/blender-crawl/blender_crawl/__main__.py @@ -81,7 +81,6 @@ parser.add_argument( def cancel_program(message: str): print(message) - print('Exiting blender_crawl.') sys.exit(0) -- 2.30.2