Blender Crawl: Improvements based on User Feedback #53
@ -1,4 +1,4 @@
|
||||
# blender_crawl
|
||||
# Blender Crawl
|
||||
`blender_crawl` is a command line tools to crawl directories for .blend files and execute a provied script.
|
||||
## Table of Contents
|
||||
- [Prerequisite](#prerequisite)
|
||||
@ -10,32 +10,39 @@ In order to use this tool you need:
|
||||
- Python 3.5+
|
||||
|
||||
## Run without Installation
|
||||
This folder contains a command line tool that doesn't require installation to use properly. This tool doesn't require installation to be run. To run `blender-crawl` without installation follow the steps below.
|
||||
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.
|
||||
|
||||
## Installation (OPTIONAL)
|
||||
Download or clone this repository. This repository is a command line tool that can be installed with the python packaging manager. Installation is an optional step only intended for advanced users.
|
||||
This script does the following (follow this if you want to do this manually or on another platform):
|
||||
Steps 3 and 5 are specific to linux, similar steps to gain root/administration privileges are avaliable to [Windows](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/jj717276(v=ws.11)) and [Mac](https://support.apple.com/en-ca/guide/terminal/apd5b0b6259-a7d4-4435-947d-0dff528912ba/mac) users.
|
||||
|
||||
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 `blender_crawl /my-folder/`
|
||||
5. Get help with `blender_crawl -h`
|
||||
3. Gain root access with `su` or equivalent command to grant permission to modify the system.
|
||||
4. Install with `pip install .`
|
||||
5. Type `exit` to log out of root user or equivalent command.
|
||||
5. Run with `blender_crawl /my-folder/`
|
||||
6. Get help with `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, 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.
|
||||
|
||||
If a script is provided, `blender_crawl` will automatically save after execution of the script, without saving any backups aka [save versions](https://docs.blender.org/manual/en/latest/editors/preferences/save_load.html#:~:text=of%20using%20characters.-,Save%20Versions,-Number%20of%20versions). If you already have saving logic in your provided script, skip this step using the "--nosave" flag.
|
||||
|
||||
| Command | Description |
|
||||
| ----------- | ----------- |
|
||||
| --script| Path to blender python script(s) to execute inside .blend files during crawl.|
|
||||
| -n, --nosave|Don't save .blend after script execution.|
|
||||
| -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.'.|
|
||||
| -a, --ask| If provided there will be a prompt for confirmation before running script on .blend files.|
|
||||
| -p, --purge| Run 'built-in function to purge data-blocks from all .blend files found in crawl, and saves them.|
|
||||
| --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|
|
||||
|
||||
@ -50,5 +57,6 @@ Run directly out of repo folder or follow above installation instructions. Give
|
||||
|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 script on .blends without saving |`blender_crawl /my-folder/ --script /my-directory/my-script.py --nosave` |
|
||||
|Run with a custom blender executable|`blender_crawl /my-folder/ --exec /path-to-blender-executable/blender`|
|
||||
|
||||
|
@ -27,12 +27,14 @@ import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import tempfile
|
||||
import uuid
|
||||
|
||||
# Command line arguments.
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"path",
|
||||
help="Path to a file(s) or folder(s) on which to perform crawl",
|
||||
help="Path to a file(s) or folder(s) on which to perform crawl.",
|
||||
nargs='+'
|
||||
)
|
||||
|
||||
@ -46,33 +48,39 @@ parser.add_argument(
|
||||
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",
|
||||
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(
|
||||
"-n",
|
||||
"--nosave",
|
||||
help="Don't save .blend after script execution.",
|
||||
action="store_true",
|
||||
)
|
||||
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",
|
||||
)
|
||||
|
||||
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(
|
||||
"-a",
|
||||
"--ask",
|
||||
help="If --ask is provided there will be no confirmation prompt before running script on .blend files.",
|
||||
help="If --ask is provided there will be a prompt for confirmation 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.'.",
|
||||
help="Run 'built-in function to purge data-blocks from all .blend files found in crawl, and saves them.",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
@ -120,7 +128,7 @@ def is_filepath_blend(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) -> Path:
|
||||
if file_path_str is None:
|
||||
return
|
||||
file_path = Path(file_path_str).absolute()
|
||||
@ -129,22 +137,39 @@ def check_file_exists(file_path_str: str, error_msg: str):
|
||||
else:
|
||||
cancel_program(error_msg)
|
||||
|
||||
def script_append_save(script: Path, skip_save:bool):
|
||||
if skip_save:
|
||||
return script
|
||||
save_script = get_default_script("save.py", True)
|
||||
# Reading data from file1
|
||||
with open(script) as script_file:
|
||||
script_data = script_file.read()
|
||||
# Reading data from file2
|
||||
with open(save_script) as save_file:
|
||||
save_data = save_file.read()
|
||||
script_data += "\n"
|
||||
script_data += save_data
|
||||
temp_dir = Path(tempfile.TemporaryDirectory().name).parent
|
||||
new_temp_file = Path.joinpath(Path(temp_dir), f"blender_crawl_{uuid.uuid4()}.py")
|
||||
with open(new_temp_file, "w") as new_file:
|
||||
new_file.write(script_data)
|
||||
return new_temp_file
|
||||
|
||||
def get_purge_path(purge: bool):
|
||||
|
||||
def get_default_script(file_name:str, purge: bool):
|
||||
# Cancel function if user has not supplied purge arg
|
||||
if not purge:
|
||||
return
|
||||
scripts_directory = Path((os.path.dirname(__file__))).joinpath("default_scripts/")
|
||||
purge_script = os.path.join(scripts_directory.resolve(), "purge.py")
|
||||
purge_script = os.path.join(scripts_directory.resolve(), file_name)
|
||||
return check_file_exists(str(purge_script), "Default scripts location may be invalid")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
import sys
|
||||
"""Crawl blender files in a directory and run a provided scripts"""
|
||||
# Parse arguments.
|
||||
args = parser.parse_args()
|
||||
purge_path = get_purge_path(args.purge)
|
||||
purge_path = get_default_script("purge.py", args.purge)
|
||||
recursive = args.recursive
|
||||
exec = args.exec
|
||||
regex = args.filter
|
||||
@ -154,15 +179,15 @@ def main() -> int:
|
||||
scripts = []
|
||||
if script_input:
|
||||
for script in script_input:
|
||||
script_name = check_file_exists(
|
||||
script_path = check_file_exists(
|
||||
script,
|
||||
"No --script was not provided as argument, printed found .blend files, exiting program.",
|
||||
)
|
||||
scripts.append(script_name)
|
||||
scripts.append(script_append_save(script_path, args.nosave))
|
||||
|
||||
# Purge is optional so it can be none
|
||||
if purge_path is not None:
|
||||
scripts.append(purge_path)
|
||||
scripts.append(script_append_save(purge_path, args.nosave))
|
||||
|
||||
if not exec:
|
||||
blender_exec = find_executable()
|
||||
@ -227,7 +252,6 @@ def main() -> int:
|
||||
)
|
||||
sys.exit(0)
|
||||
|
||||
# crawl each file two times.
|
||||
for blend_file in files:
|
||||
for script in scripts:
|
||||
cmd_list = (
|
||||
|
@ -20,18 +20,5 @@
|
||||
# (c) 2021, Blender Foundation
|
||||
|
||||
import bpy
|
||||
|
||||
# Setup prefs.
|
||||
bpy.context.preferences.filepaths.save_version = 0 #TODO Figure out why this is here
|
||||
|
||||
# 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()
|
||||
print("Saved file: %s", bpy.data.filepath)
|
||||
|
||||
# Quit.
|
||||
print("Closing File")
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
20
scripts/blender-crawl/blender_crawl/default_scripts/save.py
Normal file
20
scripts/blender-crawl/blender_crawl/default_scripts/save.py
Normal file
@ -0,0 +1,20 @@
|
||||
import bpy
|
||||
import contextlib
|
||||
|
||||
@contextlib.contextmanager
|
||||
def override_save_version():
|
||||
"""Overrides the save version settings"""
|
||||
save_version = bpy.context.preferences.filepaths.save_version
|
||||
|
||||
try:
|
||||
bpy.context.preferences.filepaths.save_version = 0
|
||||
yield
|
||||
|
||||
finally:
|
||||
bpy.context.preferences.filepaths.save_version = save_version
|
||||
|
||||
|
||||
with override_save_version():
|
||||
bpy.ops.wm.save_mainfile()
|
||||
print(f"Saved file: '{bpy.data.filepath}'")
|
||||
bpy.ops.wm.quit_blender()
|
@ -27,7 +27,7 @@ setup(
|
||||
keywords="blender_crawl",
|
||||
name="blender_crawl",
|
||||
packages=["blender_crawl", "blender_crawl.default_scripts",],
|
||||
version="0.1.0",
|
||||
version="0.1.1",
|
||||
entry_points={"console_scripts": ["blender_crawl = blender_crawl.__main__:main"]},
|
||||
package_data={'blender_crawl.default_scripts': ['*']}, #TODO Verify this is working correctly after install
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user