begin develop configloader
This commit is contained in:
File diff suppressed because one or more lines are too long
24
CONFIG.md
Normal file
24
CONFIG.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# ProjectStructure Configuration
|
||||
|
||||
The repository reads user preferences from `config.json` in the ProjectStructure
|
||||
root (copied alongside helper batches when they are deployed to projects).
|
||||
|
||||
## Keys
|
||||
|
||||
| Key | Type | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `dailyFormat` | bool | `true` → daily folders named `YYYY-MM-DD`; `false` → `daily_*` style. |
|
||||
| `structDir` | string | Absolute or relative path to the canonical ProjectStructure directory. Blank values default to the folder containing `config.json`. |
|
||||
| `projectsRoot` | string (optional) | Override for the root directory scanned by `UpgradeSeqBatches.ps1`. Defaults to the parent of `structDir`. |
|
||||
| `zipper` | bool | `true` → use 7‑Zip (if available); `false` → use Python’s built-in zipfile module. |
|
||||
| `compression` | int | Compression level `0-9` (0 = store only, 9 = max). Applies to both zipfile and 7‑Zip. |
|
||||
|
||||
## Notes
|
||||
|
||||
- `UpgradeSeqBatches.ps1` copies `config.json` and `ConfigLoader.ps1` to every
|
||||
target folder so the helper `.bat` launchers can resolve script locations.
|
||||
- When `zipper` is `true`, the tool searches for `7z`/`7za` on `PATH`. If neither
|
||||
is found it logs a warning and falls back to `zipfile`.
|
||||
- Leaving `structDir` empty is safe—the scripts fall back to the directory that
|
||||
contains `config.json`.
|
||||
|
||||
113
ConfigLoader.ps1
Normal file
113
ConfigLoader.ps1
Normal file
@@ -0,0 +1,113 @@
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$script:LoaderRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$script:ConfigPath = Join-Path -Path $script:LoaderRoot -ChildPath 'config.json'
|
||||
$script:ConfigCache = $null
|
||||
|
||||
function Get-ProjectStructureConfig {
|
||||
if ($null -ne $script:ConfigCache) {
|
||||
return $script:ConfigCache
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $script:ConfigPath) {
|
||||
try {
|
||||
$raw = Get-Content -LiteralPath $script:ConfigPath -Raw -ErrorAction Stop
|
||||
if ($raw.Trim().Length -gt 0) {
|
||||
$script:ConfigCache = $raw | ConvertFrom-Json
|
||||
return $script:ConfigCache
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to parse config.json: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
$script:ConfigCache = [pscustomobject]@{}
|
||||
return $script:ConfigCache
|
||||
}
|
||||
|
||||
function Get-ConfigValue {
|
||||
param(
|
||||
[Parameter(Mandatory)] [string]$Name,
|
||||
$Default = $null
|
||||
)
|
||||
|
||||
$config = Get-ProjectStructureConfig
|
||||
if ($config.PSObject.Properties.Name -contains $Name) {
|
||||
$value = $config.$Name
|
||||
if ($null -ne $value -and ($value -isnot [string] -or $value.Trim().Length -gt 0)) {
|
||||
return $value
|
||||
}
|
||||
}
|
||||
|
||||
return $Default
|
||||
}
|
||||
|
||||
function Get-StructDirectory {
|
||||
$value = Get-ConfigValue -Name 'structDir'
|
||||
if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {
|
||||
return $script:LoaderRoot
|
||||
}
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($value)) {
|
||||
$resolved = Resolve-Path -LiteralPath $value -ErrorAction SilentlyContinue
|
||||
if ($null -ne $resolved) { return $resolved.Path }
|
||||
return $value
|
||||
}
|
||||
|
||||
$candidate = Join-Path -Path $script:LoaderRoot -ChildPath $value
|
||||
$resolvedCandidate = Resolve-Path -LiteralPath $candidate -ErrorAction SilentlyContinue
|
||||
if ($null -ne $resolvedCandidate) { return $resolvedCandidate.Path }
|
||||
return $candidate
|
||||
}
|
||||
|
||||
function Get-ProjectsRoot {
|
||||
$value = Get-ConfigValue -Name 'projectsRoot'
|
||||
if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {
|
||||
$structDir = Get-StructDirectory
|
||||
$parent = Split-Path -Parent $structDir
|
||||
if ($null -eq $parent -or $parent.Length -eq 0 -or $parent -eq $structDir) {
|
||||
return $structDir
|
||||
}
|
||||
return $parent
|
||||
}
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($value)) {
|
||||
$resolved = Resolve-Path -LiteralPath $value -ErrorAction SilentlyContinue
|
||||
if ($null -ne $resolved) { return $resolved.Path }
|
||||
return $value
|
||||
}
|
||||
|
||||
$candidate = Join-Path -Path $script:LoaderRoot -ChildPath $value
|
||||
$resolvedCandidate = Resolve-Path -LiteralPath $candidate -ErrorAction SilentlyContinue
|
||||
if ($null -ne $resolvedCandidate) { return $resolvedCandidate.Path }
|
||||
return $candidate
|
||||
}
|
||||
|
||||
function Use-IsoDailyFormat {
|
||||
$dailyFormat = Get-ConfigValue -Name 'dailyFormat' -Default $true
|
||||
return [bool]$dailyFormat
|
||||
}
|
||||
|
||||
function Use-7Zip {
|
||||
$zipper = Get-ConfigValue -Name 'zipper' -Default $true
|
||||
return [bool]$zipper
|
||||
}
|
||||
|
||||
function Get-ZipCompressionLevel {
|
||||
$value = Get-ConfigValue -Name 'compression' -Default 9
|
||||
if ($value -is [string]) {
|
||||
$parsed = 0
|
||||
if ([int]::TryParse($value, [ref]$parsed)) {
|
||||
$value = $parsed
|
||||
}
|
||||
}
|
||||
|
||||
if ($value -isnot [int]) {
|
||||
return 9
|
||||
}
|
||||
|
||||
return [Math]::Min(9, [Math]::Max(0, $value))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
@echo off
|
||||
setlocal
|
||||
setlocal EnableExtensions
|
||||
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
set "CONFIG_LOADER=%SCRIPT_DIR%ConfigLoader.ps1"
|
||||
set "CONFIG_PATH=%SCRIPT_DIR%config.json"
|
||||
|
||||
if not exist "%CONFIG_LOADER%" (
|
||||
echo [ERROR] ConfigLoader.ps1 not found next to NewProject.bat.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%CONFIG_PATH%" (
|
||||
echo [ERROR] config.json not found next to NewProject.bat.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; Write-Output (Get-StructDirectory)"`) do set "STRUCT_DIR=%%I"
|
||||
|
||||
if not defined STRUCT_DIR (
|
||||
echo [ERROR] Unable to resolve ProjectStructure directory from config.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: Get current date in YYYY-MM-DD format
|
||||
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (
|
||||
@@ -20,7 +42,7 @@ mkdir "%projectRoot%"
|
||||
|
||||
:: Create Assets structure
|
||||
mkdir "%projectRoot%\Assets\ElevenLabs"
|
||||
if exist "A:\1 Amazon_Active_Projects\3 ProjectStructure\NewDaily.bat" copy /Y "A:\1 Amazon_Active_Projects\3 ProjectStructure\NewDaily.bat" "%projectRoot%\Assets\ElevenLabs\NewDaily.bat" >nul
|
||||
if exist "%STRUCT_DIR%\NewDaily.bat" copy /Y "%STRUCT_DIR%\NewDaily.bat" "%projectRoot%\Assets\ElevenLabs\NewDaily.bat" >nul
|
||||
mkdir "%projectRoot%\Assets\Blends"
|
||||
mkdir "%projectRoot%\Assets\Mocap"
|
||||
mkdir "%projectRoot%\Assets\VO"
|
||||
@@ -40,11 +62,10 @@ mkdir "%projectRoot%\Pr\RnR\RIFE"
|
||||
if not exist "%projectRoot%\Renders" mkdir "%projectRoot%\Renders"
|
||||
|
||||
:: Place helper scripts into Renders
|
||||
set "templateRoot=%~dp0"
|
||||
if not exist "%templateRoot%ZipSeqArchv.bat" set "templateRoot=A:\1 Amazon_Active_Projects\3 ProjectStructure\"
|
||||
if exist "%templateRoot%UpdateSequences.bat" copy /Y "%templateRoot%UpdateSequences.bat" "%projectRoot%\Renders\UpdateSequences.bat" >nul
|
||||
if exist "%templateRoot%ZipSeqArchv.bat" copy /Y "%templateRoot%ZipSeqArchv.bat" "%projectRoot%\Renders\ZipSeqArchv.bat" >nul
|
||||
if exist "%templateRoot%UnzipSeqArchv.bat" copy /Y "%templateRoot%UnzipSeqArchv.bat" "%projectRoot%\Renders\UnzipSeqArchv.bat" >nul
|
||||
set "templateRoot=%STRUCT_DIR%"
|
||||
for %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat ConfigLoader.ps1 config.json) do (
|
||||
if exist "%templateRoot%\%%F" copy /Y "%templateRoot%\%%F" "%projectRoot%\Renders\%%F" >nul
|
||||
)
|
||||
|
||||
:: Use repo-provided templates for git config files
|
||||
if exist "%~dp0components\gitignore" copy /Y "%~dp0components\gitignore" "%projectRoot%\.gitignore" >nul
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
@echo off
|
||||
setlocal
|
||||
setlocal EnableExtensions
|
||||
|
||||
set "REN_DIR=%~dp0"
|
||||
for %%I in ("%REN_DIR%..") do set "PROJ_ROOT=%%~fI"
|
||||
set "PY_SCRIPT=A:\1 Amazon_Active_Projects\3 ProjectStructure\zip_sequences.py"
|
||||
|
||||
if not exist "%PY_SCRIPT%" (
|
||||
echo Missing %PY_SCRIPT%
|
||||
set "CONFIG_LOADER=%REN_DIR%ConfigLoader.ps1"
|
||||
set "CONFIG_PATH=%REN_DIR%config.json"
|
||||
|
||||
if not exist "%CONFIG_LOADER%" (
|
||||
echo [ERROR] ConfigLoader.ps1 not found next to UnzipSeqArchv.bat.
|
||||
echo Please run UpgradeSeqBatches.ps1 to refresh helper files.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%CONFIG_PATH%" (
|
||||
echo [ERROR] config.json not found next to UnzipSeqArchv.bat.
|
||||
echo Please run UpgradeSeqBatches.ps1 to refresh helper files.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; $pyPath = Join-Path (Get-StructDirectory) 'zip_sequences.py'; if (-not (Test-Path -LiteralPath $pyPath)) { throw \"zip_sequences.py not found at $pyPath\" }; Write-Output $pyPath"`) do set "PY_SCRIPT=%%I"
|
||||
|
||||
if not defined PY_SCRIPT (
|
||||
echo [ERROR] Unable to resolve zip_sequences.py path from config.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,30 @@
|
||||
@echo off
|
||||
setlocal EnableExtensions
|
||||
|
||||
set "ps1=A:\1 Amazon_Active_Projects\3 ProjectStructure\UpdateSequences.ps1"
|
||||
set "script_dir=%~dp0"
|
||||
set "config_loader=%script_dir%ConfigLoader.ps1"
|
||||
set "config_path=%script_dir%config.json"
|
||||
|
||||
if not exist "%config_loader%" (
|
||||
echo [ERROR] ConfigLoader.ps1 not found next to UpdateSequences.bat.
|
||||
echo Please run UpgradeSeqBatches.ps1 to refresh helper files.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%config_path%" (
|
||||
echo [ERROR] config.json not found next to UpdateSequences.bat.
|
||||
echo Please run UpgradeSeqBatches.ps1 to refresh helper files.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%config_loader%' -ErrorAction Stop; . $loader.Path; $ps1Path = Join-Path (Get-StructDirectory) 'UpdateSequences.ps1'; if (-not (Test-Path -LiteralPath $ps1Path)) { throw \"UpdateSequences.ps1 not found at $ps1Path\" }; Write-Output $ps1Path"`) do set "ps1=%%I"
|
||||
|
||||
if not defined ps1 (
|
||||
echo [ERROR] Unable to resolve UpdateSequences.ps1 path from config.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Running PowerShell update script...
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%ps1%"
|
||||
set "rc=%errorlevel%"
|
||||
|
||||
@@ -6,6 +6,18 @@ param(
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $PSScriptRoot) {
|
||||
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
}
|
||||
|
||||
$configLoader = Join-Path -Path $PSScriptRoot -ChildPath 'ConfigLoader.ps1'
|
||||
if (-not (Test-Path -LiteralPath $configLoader)) {
|
||||
throw "Missing ConfigLoader.ps1 in $PSScriptRoot"
|
||||
}
|
||||
. $configLoader
|
||||
|
||||
$useIsoDailyFormat = Use-IsoDailyFormat
|
||||
|
||||
function Sync-SequenceFilenames {
|
||||
param(
|
||||
[Parameter(Mandatory)] [string]$SequenceFolderPath,
|
||||
@@ -191,9 +203,12 @@ try {
|
||||
|
||||
$sequenceMap = @{}
|
||||
|
||||
$dailyDirs = Get-ChildItem -LiteralPath $root -Directory -Filter 'daily_*' -ErrorAction SilentlyContinue |
|
||||
$primaryPattern = if ($useIsoDailyFormat) { '????-??-??' } else { 'daily_*' }
|
||||
$secondaryPattern = if ($useIsoDailyFormat) { 'daily_*' } else { '????-??-??' }
|
||||
|
||||
$primaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $primaryPattern -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -ne '_archive' }
|
||||
foreach ($d in $dailyDirs) {
|
||||
foreach ($d in $primaryDirs) {
|
||||
$seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne '_archive' })
|
||||
if ($seqDirs.Count -eq 0) {
|
||||
Add-SequenceFolder -Directory $d -Map $sequenceMap
|
||||
@@ -204,10 +219,9 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
# Scan for YYYY-MM-DD format folders (home convention)
|
||||
$dailyDirsHome = Get-ChildItem -LiteralPath $root -Directory -Filter '????-??-??' -ErrorAction SilentlyContinue |
|
||||
$secondaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $secondaryPattern -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -ne '_archive' }
|
||||
foreach ($d in $dailyDirsHome) {
|
||||
foreach ($d in $secondaryDirs) {
|
||||
$seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne '_archive' })
|
||||
if ($seqDirs.Count -eq 0) {
|
||||
Add-SequenceFolder -Directory $d -Map $sequenceMap
|
||||
@@ -218,9 +232,12 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
# Scan for direct sequence folders (not in daily_* or YYYY-MM-DD folders)
|
||||
$directSeqs = Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -ne '_archive' -and $_.Name -notlike 'daily_*' -and $_.Name -notmatch '^\d{4}-\d{2}-\d{2}$' }
|
||||
Where-Object {
|
||||
$_.Name -ne '_archive' -and
|
||||
$_.Name -notlike 'daily_*' -and
|
||||
$_.Name -notmatch '^\d{4}-\d{2}-\d{2}$'
|
||||
}
|
||||
foreach ($seq in $directSeqs) {
|
||||
Add-SequenceFolder -Directory $seq -Map $sequenceMap
|
||||
}
|
||||
|
||||
@@ -1,28 +1,59 @@
|
||||
# Update subfolders with the latest UpdateSequences and UpdateAllSequences scripts
|
||||
|
||||
$sourceBat = "R:\Creative\artsy\maya\0 ProjectStructure\UpdateSequences.bat"
|
||||
$sourceAllBat = "R:\Creative\artsy\maya\0 ProjectStructure\UpdateAllSequences.bat"
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path $sourceBat)) { Write-Error "Source file not found: $sourceBat"; exit 1 }
|
||||
if (-not (Test-Path $sourceAllBat)) { Write-Error "Source file not found: $sourceAllBat"; exit 1 }
|
||||
if (-not $PSScriptRoot) {
|
||||
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
}
|
||||
|
||||
$root = "R:\Creative\artsy\maya"
|
||||
$configLoader = Join-Path -Path $PSScriptRoot -ChildPath 'ConfigLoader.ps1'
|
||||
if (-not (Test-Path -LiteralPath $configLoader)) {
|
||||
throw "Missing ConfigLoader.ps1 in $PSScriptRoot"
|
||||
}
|
||||
. $configLoader
|
||||
|
||||
$structDir = Get-StructDirectory
|
||||
$projectsRoot = Get-ProjectsRoot
|
||||
|
||||
$sourceBat = Join-Path -Path $structDir -ChildPath 'UpdateSequences.bat'
|
||||
$sourceAllBat = Join-Path -Path $structDir -ChildPath 'UpdateAllSequences.bat'
|
||||
$sourceZipBat = Join-Path -Path $structDir -ChildPath 'ZipSeqArchv.bat'
|
||||
$sourceUnzipBat = Join-Path -Path $structDir -ChildPath 'UnzipSeqArchv.bat'
|
||||
$configLoaderSource = Join-Path -Path $structDir -ChildPath 'ConfigLoader.ps1'
|
||||
$configJsonSource = Join-Path -Path $structDir -ChildPath 'config.json'
|
||||
|
||||
if (-not (Test-Path -LiteralPath $sourceBat)) { Write-Error "Source file not found: $sourceBat"; exit 1 }
|
||||
if (-not (Test-Path -LiteralPath $sourceAllBat)) { Write-Error "Source file not found: $sourceAllBat"; exit 1 }
|
||||
if (-not (Test-Path -LiteralPath $sourceZipBat)) { Write-Error "Source file not found: $sourceZipBat"; exit 1 }
|
||||
if (-not (Test-Path -LiteralPath $sourceUnzipBat)) { Write-Error "Source file not found: $sourceUnzipBat"; exit 1 }
|
||||
if (-not (Test-Path -LiteralPath $configLoaderSource)) { Write-Error "Config loader not found: $configLoaderSource"; exit 1 }
|
||||
if (-not (Test-Path -LiteralPath $configJsonSource)) { Write-Error "Config file not found: $configJsonSource"; exit 1 }
|
||||
|
||||
$specs = @(
|
||||
@{ Name = "UpdateSequences.bat"; Source = $sourceBat },
|
||||
@{ Name = "UpdateAllSequences.bat"; Source = $sourceAllBat }
|
||||
@{ Name = "UpdateAllSequences.bat"; Source = $sourceAllBat },
|
||||
@{ Name = "ZipSeqArchv.bat"; Source = $sourceZipBat },
|
||||
@{ Name = "UnzipSeqArchv.bat"; Source = $sourceUnzipBat }
|
||||
)
|
||||
|
||||
$sharedAssets = @(
|
||||
@{ Name = 'ConfigLoader.ps1'; Source = $configLoaderSource },
|
||||
@{ Name = 'config.json'; Source = $configJsonSource }
|
||||
)
|
||||
|
||||
$grandTotal = 0
|
||||
$grandUpdated = 0
|
||||
$grandFailed = 0
|
||||
$touchedDirs = @{}
|
||||
|
||||
foreach ($spec in $specs) {
|
||||
Write-Host "=== Updating $($spec.Name) files ===" -ForegroundColor Cyan
|
||||
Write-Host "Source: $($spec.Source)" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
$targets = Get-ChildItem -Path $root -Recurse -Filter $spec.Name | Where-Object { $_.FullName -ne $spec.Source }
|
||||
$targets = Get-ChildItem -LiteralPath $projectsRoot -Recurse -Filter $spec.Name -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -ne $spec.Source }
|
||||
Write-Host "Found $($targets.Count) target files to update:" -ForegroundColor Yellow
|
||||
foreach ($t in $targets) { Write-Host " - $($t.FullName)" -ForegroundColor Gray }
|
||||
Write-Host ""
|
||||
@@ -30,10 +61,24 @@ foreach ($spec in $specs) {
|
||||
$updated = 0
|
||||
$failed = 0
|
||||
foreach ($t in $targets) {
|
||||
$targetDir = $t.Directory.FullName
|
||||
try {
|
||||
Copy-Item -Path $spec.Source -Destination $t.FullName -Force
|
||||
Write-Host "✓ Updated: $($t.FullName)" -ForegroundColor Green
|
||||
$updated++
|
||||
|
||||
if (-not $touchedDirs.ContainsKey($targetDir)) {
|
||||
foreach ($asset in $sharedAssets) {
|
||||
try {
|
||||
Copy-Item -Path $asset.Source -Destination (Join-Path -Path $targetDir -ChildPath $asset.Name) -Force
|
||||
}
|
||||
catch {
|
||||
Write-Host "✗ Failed to copy $($asset.Name) to $targetDir" -ForegroundColor Red
|
||||
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
$touchedDirs[$targetDir] = $true
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "✗ Failed to update: $($t.FullName)" -ForegroundColor Red
|
||||
|
||||
@@ -56,6 +56,18 @@ for %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat) do (
|
||||
)
|
||||
)
|
||||
|
||||
for %%F in (ConfigLoader.ps1 config.json) do (
|
||||
if exist "%scriptDir%%%F" (
|
||||
if "%DRY%"=="1" (
|
||||
echo [DRY] copy "%scriptDir%%%F" "%rendersDir%\%%F"
|
||||
) else (
|
||||
copy /Y "%scriptDir%%%F" "%rendersDir%\%%F" >nul
|
||||
)
|
||||
) else (
|
||||
echo [WARN] Missing template: "%scriptDir%%%F"
|
||||
)
|
||||
)
|
||||
|
||||
:: -----------------------------
|
||||
:: Merge .gitignore and .gitattributes from templates
|
||||
:: -----------------------------
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
@echo off
|
||||
setlocal
|
||||
setlocal EnableExtensions
|
||||
|
||||
set "REN_DIR=%~dp0"
|
||||
for %%I in ("%REN_DIR%..") do set "PROJ_ROOT=%%~fI"
|
||||
set "PY_SCRIPT=A:\1 Amazon_Active_Projects\3 ProjectStructure\zip_sequences.py"
|
||||
|
||||
if not exist "%PY_SCRIPT%" (
|
||||
echo Missing %PY_SCRIPT%
|
||||
set "CONFIG_LOADER=%REN_DIR%ConfigLoader.ps1"
|
||||
set "CONFIG_PATH=%REN_DIR%config.json"
|
||||
|
||||
if not exist "%CONFIG_LOADER%" (
|
||||
echo [ERROR] ConfigLoader.ps1 not found next to ZipSeqArchv.bat.
|
||||
echo Please run UpgradeSeqBatches.ps1 to refresh helper files.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if not exist "%CONFIG_PATH%" (
|
||||
echo [ERROR] config.json not found next to ZipSeqArchv.bat.
|
||||
echo Please run UpgradeSeqBatches.ps1 to refresh helper files.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
for /f "usebackq delims=" %%I in (`powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; $pyPath = Join-Path (Get-StructDirectory) 'zip_sequences.py'; if (-not (Test-Path -LiteralPath $pyPath)) { throw \"zip_sequences.py not found at $pyPath\" }; Write-Output $pyPath"`) do set "PY_SCRIPT=%%I"
|
||||
|
||||
if not defined PY_SCRIPT (
|
||||
echo [ERROR] Unable to resolve zip_sequences.py path from config.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
|
||||
7
config.json
Normal file
7
config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dailyFormat": true,
|
||||
"structDir": "D:\\ProjectStructure",
|
||||
"zipper": true,
|
||||
"compression": 9
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
@@ -30,6 +31,52 @@ SEQUENCE_EXTENSIONS = {
|
||||
".exr",
|
||||
}
|
||||
STATE_SUFFIX = ".meta.json"
|
||||
CONFIG_PATH = Path(__file__).resolve().with_name("config.json")
|
||||
DEFAULT_CONFIG = {
|
||||
"zipper": True,
|
||||
"compression": 9,
|
||||
}
|
||||
|
||||
|
||||
def load_config() -> dict:
|
||||
try:
|
||||
text = CONFIG_PATH.read_text(encoding="utf-8")
|
||||
except FileNotFoundError:
|
||||
return DEFAULT_CONFIG.copy()
|
||||
except OSError:
|
||||
return DEFAULT_CONFIG.copy()
|
||||
|
||||
try:
|
||||
data = json.loads(text)
|
||||
except json.JSONDecodeError:
|
||||
return DEFAULT_CONFIG.copy()
|
||||
|
||||
if not isinstance(data, dict):
|
||||
return DEFAULT_CONFIG.copy()
|
||||
|
||||
merged = DEFAULT_CONFIG.copy()
|
||||
merged.update(data)
|
||||
return merged
|
||||
|
||||
|
||||
CONFIG = load_config()
|
||||
USE_7Z = bool(CONFIG.get("zipper", True))
|
||||
COMPRESSION_LEVEL = CONFIG.get("compression", 9)
|
||||
if isinstance(COMPRESSION_LEVEL, str):
|
||||
try:
|
||||
COMPRESSION_LEVEL = int(COMPRESSION_LEVEL)
|
||||
except ValueError:
|
||||
COMPRESSION_LEVEL = 9
|
||||
if not isinstance(COMPRESSION_LEVEL, int):
|
||||
COMPRESSION_LEVEL = 9
|
||||
COMPRESSION_LEVEL = max(0, min(9, COMPRESSION_LEVEL))
|
||||
|
||||
SEVEN_Z_EXE: str | None = None
|
||||
if USE_7Z:
|
||||
SEVEN_Z_EXE = shutil.which("7z") or shutil.which("7za")
|
||||
if SEVEN_Z_EXE is None:
|
||||
print("[zip] Requested 7z compression but no 7z executable was found; falling back to zipfile.", file=sys.stderr)
|
||||
USE_7Z = False
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
@@ -138,24 +185,55 @@ def state_path_for(zip_path: Path) -> Path:
|
||||
|
||||
|
||||
def zip_sequence(seq_dir: Path, zip_path: Path) -> None:
|
||||
from zipfile import ZIP_STORED, ZipFile
|
||||
if USE_7Z and SEVEN_Z_EXE:
|
||||
zip_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
cmd = [
|
||||
SEVEN_Z_EXE,
|
||||
"a",
|
||||
"-y",
|
||||
f"-mx={COMPRESSION_LEVEL}",
|
||||
"-tzip",
|
||||
str(zip_path),
|
||||
".\\*",
|
||||
]
|
||||
subprocess.run(cmd, cwd=seq_dir, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
return
|
||||
|
||||
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
||||
|
||||
zip_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with ZipFile(zip_path, "w", compression=ZIP_STORED) as archive:
|
||||
if COMPRESSION_LEVEL <= 0:
|
||||
compression = ZIP_STORED
|
||||
zip_kwargs = {}
|
||||
else:
|
||||
compression = ZIP_DEFLATED
|
||||
zip_kwargs = {"compresslevel": COMPRESSION_LEVEL}
|
||||
|
||||
with ZipFile(zip_path, "w", compression=compression, **zip_kwargs) as archive:
|
||||
for file_path in iter_sequence_files(seq_dir):
|
||||
archive.write(file_path, arcname=file_path.relative_to(seq_dir).as_posix())
|
||||
|
||||
|
||||
def expand_sequence(zip_path: Path, seq_state: dict) -> None:
|
||||
from zipfile import ZipFile
|
||||
|
||||
target_dir = sequence_dir_for(zip_path)
|
||||
if target_dir.exists():
|
||||
shutil.rmtree(target_dir)
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with ZipFile(zip_path, "r") as archive:
|
||||
archive.extractall(target_dir)
|
||||
if USE_7Z and SEVEN_Z_EXE:
|
||||
cmd = [
|
||||
SEVEN_Z_EXE,
|
||||
"x",
|
||||
"-y",
|
||||
str(zip_path),
|
||||
f"-o{target_dir}",
|
||||
]
|
||||
subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
else:
|
||||
from zipfile import ZipFile
|
||||
|
||||
with ZipFile(zip_path, "r") as archive:
|
||||
archive.extractall(target_dir)
|
||||
|
||||
for entry in seq_state.get("files", []):
|
||||
file_path = target_dir / entry["path"]
|
||||
|
||||
Reference in New Issue
Block a user