color coded cli output!

This commit is contained in:
2026-03-22 12:58:19 -06:00
parent a8205447e3
commit 53430f768f
4 changed files with 565 additions and 96 deletions
@@ -9364,3 +9364,446 @@ To clear locked @eaDir on Hydra: ssh in first, then run:
```
So you **`ssh Hydra`** (or your usual host) in one step, then paste **`sudo rm -rf "…"`** in that shell. The path is still built from **`NASPATH`**, with **double quotes** for any spaces in names.
---
_**User**_
color code all the output print
---
_**Agent (composer-2-fast)**_
<think><details><summary>Thought Process</summary>
**Colorizing batch output**
I'm implementing ANSI escape codes for colored output in autoThumbs.bat. I'll use PowerShell's `Write-Host` for colored output since it's more reliable across Windows versions than enabling ANSI in cmd. I'm implementing the ESC character setup using delayed expansion for consistent color support across Windows versions. I'm switching to using PowerShell's Write-Host with ForegroundColor for consistent coloring across Windows versions. I'm adding ANSI escape code support and refactoring echo calls to use a colorized subroutine. I'm implementing ANSI color codes for batch output using PowerShell to generate ESC characters.
I'm adding ANSI color codes to batch output, categorizing errors in red, debug in cyan, success in green, and headers in yellow. I'll use PowerShell's Write-Host for cleaner ANSI color support instead of batch registry hacks. I'm implementing a hybrid approach using PowerShell subroutines for colorized output. </details></think>
_**Agent (composer-2-fast)**_
Reading `autoThumbs.bat` to add ANSI colors (with a small helper) across all echoed output.
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: C:\Users\Nathan\Desktop\synology-thumbgen\autoThumbs.bat</summary>
</details>
</tool-use>
<tool-use data-tool-type="read" data-tool-name="read_file_v2"><details>
<summary>Tool use: **read_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<think><details><summary>Thought Process</summary>
**Adding ANSI support**
I'm implementing ANSI color support using ESC variable with PowerShell command. I'm refactoring the batch cecho function to handle messages with spaces using `%*` instead of `%2`.
I'm implementing ANSI support by creating a PowerShell helper function for colored output. I'm switching from PowerShell helpers to ANSI escape codes for colored terminal output. I'm implementing ANSI escape code constants for terminal colors in batch script.
**Handling delayed expansion**
I'm using delayed expansion with !RED! for ANSI colors inside blocks to avoid premature expansion. I'm adding ESC and color variables after setlocal to enable ANSI colors. I'm implementing color-coded output for menu elements and error messages using ANSI escape sequences. I'm implementing color-coded output using ANSI escape sequences with special handling for batch file syntax and variable expansion.
I'm implementing color-coded output with ANSI escape sequences, handling batch file syntax and variable expansion with special cases for echo commands. I'm adding color-coded output for Hydra clear commands using ANSI escapes. I'm implementing full file with colored output using ANSI escapes for Hydra commands. </details></think>
_**Agent (composer-2-fast)**_
Adding ANSI color variables (via PowerShell to obtain ESC) and applying them to all batch `echo` output. Enabling VT when possible so colors render in `cmd.exe`.
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="write" data-tool-name="edit_file_v2">
<details><summary>Tool use: **edit_file_v2** • Edit file: C:\Users\Nathan\Desktop\synology-thumbgen\autoThumbs.bat</summary>
</details>
</tool-use>
<tool-use data-tool-type="write" data-tool-name="edit_file_v2"><details>
<summary>Tool use: **edit_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<think><details><summary>Thought Process</summary>
**Fixing pause command**
I'm adjusting the pause command to properly handle user input with parentheses in the set /p prompt. I'm correcting the pause command to escape parentheses in user input with caret syntax. I'm addressing potential ANSI color code rendering issues in the pause command's prompt.
I'm correcting the Windows path prompt to properly escape parentheses with carets. I'm fixing the Windows path prompt to properly escape parentheses with carets. I'm escaping parentheses in the Windows path prompt using carets. </details></think>
_**Agent (composer-2-fast)**_
Fixing `set /p` prompts: escaping parentheses and removing the registry tweak (optional).
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="write" data-tool-name="edit_file_v2">
<details><summary>Tool use: **edit_file_v2** • Edit file: C:\Users\Nathan\Desktop\synology-thumbgen\autoThumbs.bat</summary>
</details>
</tool-use>
<tool-use data-tool-type="write" data-tool-name="edit_file_v2"><details>
<summary>Tool use: **edit_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="write" data-tool-name="edit_file_v2">
<details><summary>Tool use: **edit_file_v2** • Edit file: C:\Users\Nathan\Desktop\synology-thumbgen\autoThumbs.bat</summary>
</details>
</tool-use>
<tool-use data-tool-type="write" data-tool-name="edit_file_v2"><details>
<summary>Tool use: **edit_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="write" data-tool-name="edit_file_v2">
<details><summary>Tool use: **edit_file_v2** • Edit file: C:\Users\Nathan\Desktop\synology-thumbgen\autoThumbs.bat</summary>
</details>
</tool-use>
<tool-use data-tool-type="write" data-tool-name="edit_file_v2"><details>
<summary>Tool use: **edit_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="write" data-tool-name="edit_file_v2">
<details><summary>Tool use: **edit_file_v2** • Edit file: C:\Users\Nathan\Desktop\synology-thumbgen\autoThumbs.bat</summary>
</details>
</tool-use>
<tool-use data-tool-type="write" data-tool-name="edit_file_v2"><details>
<summary>Tool use: **edit_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
Heres what was added:
### Mechanics
- **`ESC`** from PowerShell (`[char]0x1b`), then standard **ANSI SGR** prefixes (`91``97`, bold, dim, reset).
- **No registry writes** (removed the VT registry line so the script doesnt touch `HKCU\Console` every run). **Windows Terminal** and recent **conhost** usually support ANSI already.
### Color usage
| Use | Color |
|-----|--------|
| Menu title | **Bold yellow** |
| Menu items / steps | **Cyan** |
| `DEBUG:` | **Gray** |
| Progress (“Uploading…”) | **Green** |
| `ERROR:` | **Bright red** |
| Warnings / “Keeping eaDir_tmp…” | **Yellow** |
| Hydra `sudo` hint | **Magenta** + **bold yellow** for the command |
| OneDrive banner | **Bold magenta** |
| Body text there | **White** / **gray** bullets |
| “Press any key…” | **Dim** + `pause >nul` so you dont get a second unstyled line |
### Prompts
- **`set /p`** prompts use the same codes; **parentheses** are escaped with **`^`** so **`(1-4)`**, **`(e.g., …)`**, **`(y/n)`** dont break parsing.
If anything still looks uncolored, open the batch in **Windows Terminal** or enable **“Use legacy console”** off so VT/ANSI applies.
---
_**User**_
make icaros cache prints blue, and fallback to ffmpeg green.
---
_**Agent (composer-2-fast)**_
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="unknown" data-tool-name="ripgrep_raw_search">
<details>
<summary>Tool use: **ripgrep_raw_search**</summary>
Parameters:
```json
{
"caseInsensitive": false,
"path": "C:\\Users\\Nathan\\Desktop\\synology-thumbgen\\psthumbgen.py",
"pattern": "Icaros|FFmpeg|ffmpeg|icaros"
}
```
Additional data:
```json
{
"isPruned": true,
"outputMode": "content",
"path": "C:\\Users\\Nathan\\Desktop\\synology-thumbgen\\psthumbgen.py",
"pattern": "Icaros|FFmpeg|ffmpeg|icaros",
"topFiles": [
{
"matchCount": 66,
"uri": "psthumbgen.py"
}
],
"totalFiles": 1,
"totalMatches": 66
}
```
Status: **completed**
</details>
</tool-use>
<tool-use data-tool-type="unknown" data-tool-name="ripgrep_raw_search"><details>
<summary>Tool use: **ripgrep_raw_search**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<think><details><summary>Thought Process</summary>
**Adding color constants**
I'm adding color constants and helper functions for Icaros vs FFmpeg print statements. I'm implementing ANSI color code support for Windows terminals with fallback options. </details></think>
_**Agent (composer-2-fast)**_
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: C:\Users\Nathan\Desktop\synology-thumbgen\psthumbgen.py</summary>
</details>
</tool-use>
<tool-use data-tool-type="read" data-tool-name="read_file_v2"><details>
<summary>Tool use: **read_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: C:\Users\Nathan\Desktop\synology-thumbgen\psthumbgen.py</summary>
</details>
</tool-use>
<tool-use data-tool-type="read" data-tool-name="read_file_v2"><details>
<summary>Tool use: **read_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: C:\Users\Nathan\Desktop\synology-thumbgen\psthumbgen.py</summary>
</details>
</tool-use>
<tool-use data-tool-type="read" data-tool-name="read_file_v2"><details>
<summary>Tool use: **read_file_v2**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<think><details><summary>Thought Process</summary>
**Color-coding prints**
I'm adding color-coded print functions for Icaros cache and FFmpeg fallback messages. I'm replacing print statements in extract_icaros_thumbnail and _build_icaros_index_map with color-coded _print_icaros functions for consistency.
I'm using blue coloring for 'Icaros' messages and _print_icaros for FFmpeg and Icaros tier prints. </details></think>
_**Agent (composer-2-fast)**_
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="unknown" data-tool-name="ripgrep_raw_search">
<details>
<summary>Tool use: **ripgrep_raw_search**</summary>
Parameters:
```json
{
"caseInsensitive": false,
"path": "C:\\Users\\Nathan\\Desktop\\synology-thumbgen\\psthumbgen.py",
"pattern": "print\\(.*[Ii]caros|print\\(.*Icaros|print\\(.*FFmpeg|print\\(.*ffmpeg"
}
```
Additional data:
```json
{
"isPruned": true,
"outputMode": "content",
"path": "C:\\Users\\Nathan\\Desktop\\synology-thumbgen\\psthumbgen.py",
"pattern": "print\\(.*[Ii]caros|print\\(.*Icaros|print\\(.*FFmpeg|print\\(.*ffmpeg",
"topFiles": [
{
"matchCount": 17,
"uri": "psthumbgen.py"
}
],
"totalFiles": 1,
"totalMatches": 17
}
```
Status: **completed**
</details>
</tool-use>
<tool-use data-tool-type="unknown" data-tool-name="ripgrep_raw_search"><details>
<summary>Tool use: **ripgrep_raw_search**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="unknown" data-tool-name="ripgrep_raw_search">
<details>
<summary>Tool use: **ripgrep_raw_search**</summary>
Parameters:
```json
{
"caseInsensitive": false,
"glob": "*.py",
"path": "C:\\Users\\Nathan\\Desktop\\synology-thumbgen\\psthumbgen.py",
"pattern": "print\\(f?[\\\"'].*-\u003e"
}
```
Additional data:
```json
{
"isPruned": true,
"outputMode": "content",
"path": "C:\\Users\\Nathan\\Desktop\\synology-thumbgen\\psthumbgen.py",
"pattern": "print\\(f?[\\\"'].*-\u003e",
"topFiles": [
{
"matchCount": 66,
"uri": "psthumbgen.py"
}
],
"totalFiles": 1,
"totalMatches": 66
}
```
Status: **completed**
</details>
</tool-use>
<tool-use data-tool-type="unknown" data-tool-name="ripgrep_raw_search"><details>
<summary>Tool use: **ripgrep_raw_search**</summary>
</details></tool-use>
_**Agent (composer-2-fast)**_
<think><details><summary>Thought Process</summary>
**Adding color helpers**
I'm adding ANSI helper functions to colorize Icaros and FFmpeg output.
**Colorizing icaros prints**
I'm colorizing Icaros-specific print statements in blue, including those from `extract_from_icdb_database` and related helpers. </details></think>
_**Agent (composer-2-fast)**_
_**Agent (composer-2-fast)**_
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: C:\Users\Nathan\Desktop\synology-thumbgen\psthumbgen.py</summary>
</details>
</tool-use>
<tool-use data-tool-type="read" data-tool-name="read_file_v2"><details>
<summary>Tool use: **read_file_v2**</summary>
</details></tool-use>
+4 -4
View File
@@ -46,13 +46,13 @@
"last_updated": "2026-03-22T18:11:22Z"
},
"88555ca4-9c88-4bcf-825f-dd19b19b7145": {
"user_message_count": 41,
"agent_message_count": 396,
"user_message_count": 43,
"agent_message_count": 425,
"start_timestamp": "2026-03-21T13:01:32-06:00",
"end_timestamp": "2026-03-21T13:01:32-06:00",
"markdown_size_bytes": 335861,
"markdown_size_bytes": 348634,
"provider": "cursoride",
"last_updated": "2026-03-22T18:45:49Z"
"last_updated": "2026-03-22T18:56:15Z"
},
"8a226504-a2e0-4b10-b083-a609486034c7": {
"user_message_count": 9,
+72 -58
View File
@@ -1,31 +1,44 @@
@echo off
setlocal
setlocal EnableExtensions
REM ANSI colors (needs Windows 10+ console VT or Windows Terminal)
for /f %%a in ('powershell -nop -c "[char]0x1b"') do set "ESC=%%a"
set "RST=%ESC%[0m"
set "BLD=%ESC%[1m"
set "DIM=%ESC%[2m"
set "RED=%ESC%[91m"
set "GRN=%ESC%[92m"
set "YLW=%ESC%[93m"
set "BLU=%ESC%[94m"
set "MAG=%ESC%[95m"
set "CYN=%ESC%[96m"
set "GRY=%ESC%[90m"
set "WHT=%ESC%[97m"
REM Always use 'nathan' as NAS username
set NASUSER=nathan
REM Menu for operation selection
echo.
echo Select operation:
echo 1. Generate thumbnails only
echo 2. SSH cleanup only
echo 3. Both (generate thumbnails + SSH cleanup)
echo 4. Fix OneDrive thumbnail override (NEW!)
echo %BLD%%YLW%Select operation:%RST%
echo %CYN%1.%RST% Generate thumbnails only
echo %CYN%2.%RST% SSH cleanup only
echo %CYN%3.%RST% Both (generate thumbnails + SSH cleanup)
echo %CYN%4.%RST% Fix OneDrive thumbnail override %DIM%(NEW^)%RST%
echo.
set /p CHOICE=Enter your choice (1-4):
set /p CHOICE=%CYN%Enter your choice ^(1-4^): %RST%
if "%CHOICE%"=="1" goto THUMBS_ONLY
if "%CHOICE%"=="2" goto SSH_ONLY
if "%CHOICE%"=="3" goto BOTH
if "%CHOICE%"=="4" goto FIX_ONEDRIVE
echo Invalid choice. Exiting.
echo %RED%Invalid choice. Exiting.%RST%
exit /b
:THUMBS_ONLY
REM Prompt for Windows path
set /p WINPATH=Enter the full Windows path to your NAS directory (e.g., R:\YouTube\Streams\MixerTwitch):
set /p WINPATH=%CYN%Enter the full Windows path to your NAS directory ^(e.g., R:\YouTube\Streams\MixerTwitch^): %RST%
if "%WINPATH%"=="" (
echo No path provided. Exiting.
echo %RED%No path provided. Exiting.%RST%
exit /b
)
@@ -34,9 +47,9 @@ set "RELPATH=%WINPATH:~3%"
set "RELPATH=%RELPATH:\=/%"
set "NASPATH=/volume1/Hydra/%RELPATH%"
echo Uploading extract_eadir_to_tmp.sh to NAS and seeding...
echo %GRN%Uploading extract_eadir_to_tmp.sh to NAS and seeding...%RST%
if not exist "%~dp0extract_eadir_to_tmp.sh" (
echo ERROR: extract_eadir_to_tmp.sh not found next to this batch file.
echo %RED%ERROR: extract_eadir_to_tmp.sh not found next to this batch file.%RST%
goto END
)
ssh Hydra "cat > ~/extract_eadir_to_tmp.sh" < "%~dp0extract_eadir_to_tmp.sh"
@@ -48,9 +61,9 @@ goto END
:SSH_ONLY
REM Prompt for Windows path
set /p WINPATH=Enter the full Windows path to your NAS directory (e.g., R:\YouTube\Streams\MixerTwitch):
set /p WINPATH=%CYN%Enter the full Windows path to your NAS directory ^(e.g., R:\YouTube\Streams\MixerTwitch^): %RST%
if "%WINPATH%"=="" (
echo No path provided. Exiting.
echo %RED%No path provided. Exiting.%RST%
exit /b
)
@@ -59,22 +72,22 @@ set "RELPATH=%WINPATH:~3%"
set "RELPATH=%RELPATH:\=/%"
set "NASPATH=/volume1/Hydra/%RELPATH%"
echo DEBUG: WINPATH = %WINPATH%
echo DEBUG: RELPATH = %RELPATH%
echo DEBUG: NASPATH = %NASPATH%
echo %GRY%DEBUG: WINPATH = %WINPATH%%RST%
echo %GRY%DEBUG: RELPATH = %RELPATH%%RST%
echo %GRY%DEBUG: NASPATH = %NASPATH%%RST%
echo.
call :WIN_REMOVE_LOCAL_EADIR
REM Ensure nascleanup.sh exists on NAS (upload + fix line endings), then run it
echo Uploading nascleanup.sh to NAS and running cleanup...
echo %GRN%Uploading nascleanup.sh to NAS and running cleanup...%RST%
if not exist "%~dp0nascleanup.sh" (
echo ERROR: nascleanup.sh not found next to this batch file.
echo %RED%ERROR: nascleanup.sh not found next to this batch file.%RST%
goto END
)
ssh Hydra "cat > ~/nascleanup.sh" < "%~dp0nascleanup.sh"
ssh Hydra "bash -lc 'if command -v dos2unix >/dev/null 2>&1; then dos2unix -f ~/nascleanup.sh; else tr -d \"\r\" < ~/nascleanup.sh > ~/nascleanup.sh.tmp && mv ~/nascleanup.sh.tmp ~/nascleanup.sh; fi; chmod +x ~/nascleanup.sh; ~/nascleanup.sh \"%NASPATH%\"'"
if errorlevel 1 (
echo ERROR: nascleanup failed on NAS - check promote ^(eaDir_tmp -^> @eaDir^) messages above.
echo Keeping eaDir_tmp on the share so you can retry without re-running FFmpeg.
echo %RED%ERROR: nascleanup failed on NAS - check promote ^(eaDir_tmp -^> @eaDir^) messages above.%RST%
echo %YLW%Keeping eaDir_tmp on the share so you can retry without re-running FFmpeg.%RST%
call :PRINT_HYDRA_CLEAR_EADIR
) else (
call :WIN_REMOVE_LOCAL_EADIR_TMP
@@ -83,9 +96,9 @@ goto END
:BOTH
REM Prompt for Windows path
set /p WINPATH=Enter the full Windows path to your NAS directory (e.g., R:\YouTube\Streams\MixerTwitch):
set /p WINPATH=%CYN%Enter the full Windows path to your NAS directory ^(e.g., R:\YouTube\Streams\MixerTwitch^): %RST%
if "%WINPATH%"=="" (
echo No path provided. Exiting.
echo %RED%No path provided. Exiting.%RST%
exit /b
)
@@ -94,15 +107,15 @@ set "RELPATH=%WINPATH:~3%"
set "RELPATH=%RELPATH:\=/%"
set "NASPATH=/volume1/Hydra/%RELPATH%"
echo DEBUG: WINPATH = %WINPATH%
echo DEBUG: RELPATH = %RELPATH%
echo DEBUG: NASPATH = %NASPATH%
echo %GRY%DEBUG: WINPATH = %WINPATH%%RST%
echo %GRY%DEBUG: RELPATH = %RELPATH%%RST%
echo %GRY%DEBUG: NASPATH = %NASPATH%%RST%
echo.
REM Pre-seed eaDir_tmp from @eaDir on NAS before generation
echo Uploading extract_eadir_to_tmp.sh to NAS and seeding...
echo %GRN%Uploading extract_eadir_to_tmp.sh to NAS and seeding...%RST%
if not exist "%~dp0extract_eadir_to_tmp.sh" (
echo ERROR: extract_eadir_to_tmp.sh not found next to this batch file.
echo %RED%ERROR: extract_eadir_to_tmp.sh not found next to this batch file.%RST%
goto END
)
ssh Hydra "cat > ~/extract_eadir_to_tmp.sh" < "%~dp0extract_eadir_to_tmp.sh"
@@ -116,16 +129,16 @@ call :WIN_REMOVE_LOCAL_EADIR
REM SSH cleanup commands (run separately)
REM Ensure nascleanup.sh exists on NAS (upload + fix line endings), then run it
echo Uploading nascleanup.sh to NAS and running cleanup...
echo %GRN%Uploading nascleanup.sh to NAS and running cleanup...%RST%
if not exist "%~dp0nascleanup.sh" (
echo ERROR: nascleanup.sh not found next to this batch file.
echo %RED%ERROR: nascleanup.sh not found next to this batch file.%RST%
goto END
)
ssh Hydra "cat > ~/nascleanup.sh" < "%~dp0nascleanup.sh"
ssh Hydra "bash -lc 'if command -v dos2unix >/dev/null 2>&1; then dos2unix -f ~/nascleanup.sh; else tr -d \"\r\" < ~/nascleanup.sh > ~/nascleanup.sh.tmp && mv ~/nascleanup.sh.tmp ~/nascleanup.sh; fi; chmod +x ~/nascleanup.sh; ~/nascleanup.sh \"%NASPATH%\"'"
if errorlevel 1 (
echo ERROR: nascleanup failed on NAS - check promote ^(eaDir_tmp -^> @eaDir^) messages above.
echo Keeping eaDir_tmp on the share so you can retry without re-running FFmpeg.
echo %RED%ERROR: nascleanup failed on NAS - check promote ^(eaDir_tmp -^> @eaDir^) messages above.%RST%
echo %YLW%Keeping eaDir_tmp on the share so you can retry without re-running FFmpeg.%RST%
call :PRINT_HYDRA_CLEAR_EADIR
) else (
call :WIN_REMOVE_LOCAL_EADIR_TMP
@@ -134,29 +147,29 @@ goto END
:FIX_ONEDRIVE
echo.
echo =================================================================
echo FIX ONEDRIVE THUMBNAIL OVERRIDE
echo =================================================================
echo %BLD%%MAG%=================================================================%RST%
echo %BLD%%MAG% FIX ONEDRIVE THUMBNAIL OVERRIDE %RST%
echo %BLD%%MAG%=================================================================%RST%
echo.
echo This will fix OneDrive overriding your custom thumbnails with
echo generic file icons for unsupported formats like .blend files.
echo %WHT%This will fix OneDrive overriding your custom thumbnails with%RST%
echo %WHT%generic file icons for unsupported formats like .blend files.%RST%
echo.
echo What this does:
echo - Disables OneDrive cloud thumbnail providers
echo - Restores local thumbnail priority
echo - Prevents future thumbnail cache deletion
echo %CYN%What this does:%RST%
echo %GRY% - Disables OneDrive cloud thumbnail providers%RST%
echo %GRY% - Restores local thumbnail priority%RST%
echo %GRY% - Prevents future thumbnail cache deletion%RST%
echo.
set /p CONFIRM=Continue? (y/n):
set /p CONFIRM=%YLW%Continue? ^(y/n^): %RST%
if /i not "%CONFIRM%"=="y" goto END
echo.
echo Running PowerShell script to fix OneDrive thumbnail override...
echo %GRN%Running PowerShell script to fix OneDrive thumbnail override...%RST%
echo.
REM Check if PowerShell script exists
if not exist "fix_thumbnail_override.ps1" (
echo ERROR: fix_thumbnail_override.ps1 not found in current directory.
echo Please ensure the PowerShell script is in the same folder as this batch file.
echo %RED%ERROR: fix_thumbnail_override.ps1 not found in current directory.%RST%
echo %YLW%Please ensure the PowerShell script is in the same folder as this batch file.%RST%
pause
goto END
)
@@ -165,31 +178,31 @@ REM Run PowerShell script as administrator
powershell -ExecutionPolicy Bypass -Command "Start-Process PowerShell -ArgumentList '-ExecutionPolicy Bypass -File \"%~dp0fix_thumbnail_override.ps1\"' -Verb RunAs"
echo.
echo OneDrive thumbnail override fix initiated.
echo Please check the PowerShell window for progress and results.
echo %GRN%OneDrive thumbnail override fix initiated.%RST%
echo %GRY%Please check the PowerShell window for progress and results.%RST%
echo.
echo After the fix completes:
echo 1. Restart your computer
echo 2. Re-run your thumbnail generation process
echo 3. Your custom thumbnails should now have priority!
echo %CYN%After the fix completes:%RST%
echo %GRY% 1. Restart your computer%RST%
echo %GRY% 2. Re-run your thumbnail generation process%RST%
echo %GRY% 3. Your custom thumbnails should now have priority!%RST%
echo.
goto END
REM Print ssh Hydra command to wipe @eaDir when NAS cleanup failed (matches NASPATH from pasted R:\ path).
:PRINT_HYDRA_CLEAR_EADIR
if "%NASPATH%"=="" goto :eof
echo To clear locked @eaDir on Hydra: ssh in first, then run:
echo sudo rm -rf "%NASPATH%/@eaDir"
echo %MAG%To clear locked @eaDir on Hydra: ssh in first, then run:%RST%
echo %BLD%%YLW% sudo rm -rf "%NASPATH%/@eaDir"%RST%
goto :eof
REM Remove folder-level @eaDir on the pasted Windows path (same files as NAS over SMB).
:WIN_REMOVE_LOCAL_EADIR
if "%WINPATH%"=="" goto :eof
if exist "%WINPATH%\@eaDir" (
echo Removing "%WINPATH%\@eaDir" via Windows ^(SMB share^)...
echo %CYN%Removing "%WINPATH%\@eaDir" via Windows ^(SMB share^)...%RST%
rd /s /q "%WINPATH%\@eaDir" 2>nul
if exist "%WINPATH%\@eaDir" (
echo WARNING: Could not remove @eaDir; try PowerShell as admin or delete in Explorer.
echo %YLW%WARNING: Could not remove @eaDir; try PowerShell as admin or delete in Explorer.%RST%
)
)
goto :eof
@@ -197,13 +210,14 @@ goto :eof
REM Remove every eaDir_tmp under pasted path (including subfolders e.g. gameplay\eaDir_tmp).
:WIN_REMOVE_LOCAL_EADIR_TMP
if "%WINPATH%"=="" goto :eof
echo Removing all eaDir_tmp folders under "%WINPATH%" ^(recursive, SMB^)...
echo %CYN%Removing all eaDir_tmp folders under "%WINPATH%" ^(recursive, SMB^)...%RST%
if not exist "%~dp0remove_eadir_tmp_recursive.ps1" (
echo ERROR: remove_eadir_tmp_recursive.ps1 not found next to this batch file.
echo %RED%ERROR: remove_eadir_tmp_recursive.ps1 not found next to this batch file.%RST%
goto :eof
)
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0remove_eadir_tmp_recursive.ps1" "%WINPATH%"
goto :eof
:END
pause
echo %DIM%Press any key to continue . . .%RST%
pause >nul
+46 -34
View File
@@ -72,6 +72,18 @@ def _ffmpeg_enabled():
return False
_ANSI_BLUE = "\033[94m"
_ANSI_GREEN = "\033[92m"
_ANSI_RST = "\033[0m"
def _print_icaros(msg):
print(f"{_ANSI_BLUE}{msg}{_ANSI_RST}")
def _print_ffmpeg(msg):
print(f"{_ANSI_GREEN}{msg}{_ANSI_RST}")
def find_files(dir):
# Only process formats that Synology doesn't handle well
@@ -136,13 +148,13 @@ def create_video_thumbnails(source_path, dest_dir):
# Try Windows thumbnail extraction first (leverages Icaros provider when present)
windows_thumb = extract_windows_thumbnail(source_path)
if windows_thumb:
print(f" -> SUCCESS: Using Windows/Icaros provider")
_print_icaros(f" -> SUCCESS: Using Windows/Icaros provider")
generate_synology_thumbnails(windows_thumb, dest_dir, include_video_screenshot=True)
return
# Optionally fall back to FFmpeg (disabled by default)
if _ffmpeg_enabled():
print(f"Windows/Icaros extraction failed for {source_path}, using FFmpeg...")
_print_ffmpeg(f"Windows/Icaros extraction failed for {source_path}, using FFmpeg...")
create_video_thumbnails_ffmpeg(source_path, dest_dir)
else:
print(f"Windows/Icaros extraction failed for {source_path}, FFmpeg disabled (THUMBGEN_ENABLE_FFMPEG=0). Skipping.")
@@ -175,15 +187,15 @@ def create_video_thumbnails_ffmpeg(source_path, dest_dir):
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Warning: FFmpeg failed for {source_path}: {result.stderr}")
_print_ffmpeg(f"Warning: FFmpeg failed for {source_path}: {result.stderr}")
continue
except FileNotFoundError:
print("Warning: FFmpeg not found. Video thumbnails will be skipped.")
print("Install FFmpeg: https://ffmpeg.org/download.html")
_print_ffmpeg("Warning: FFmpeg not found. Video thumbnails will be skipped.")
_print_ffmpeg("Install FFmpeg: https://ffmpeg.org/download.html")
break
except Exception as e:
print(f"Error processing video {source_path}: {e}")
_print_ffmpeg(f"Error processing video {source_path}: {e}")
def create_psd_thumbnails(source_path, dest_dir):
@@ -315,15 +327,15 @@ def extract_windows_thumbnail(file_path):
# Tier 3: Try Icaros cache extraction
try:
print(f" -> Trying Icaros cache extraction...")
_print_icaros(f" -> Trying Icaros cache extraction...")
icaros_thumb = extract_icaros_thumbnail(file_path)
if icaros_thumb:
print(f" -> Found thumbnail in Icaros cache for {filename}")
_print_icaros(f" -> Found thumbnail in Icaros cache for {filename}")
return icaros_thumb
else:
print(f" -> No thumbnail in Icaros cache for {filename}")
_print_icaros(f" -> No thumbnail in Icaros cache for {filename}")
except Exception as e:
print(f" -> Icaros cache extraction failed: {e}")
_print_icaros(f" -> Icaros cache extraction failed: {e}")
print(f" -> Windows thumbnail extraction failed for {filename}")
return None
@@ -679,28 +691,28 @@ def extract_icaros_thumbnail(file_path):
# Locate Icaros cache directory
icaros_cache_dir = _get_icaros_cache_dir()
if not icaros_cache_dir:
print(f" -> No Icaros cache directory found")
_print_icaros(f" -> No Icaros cache directory found")
return None
# Debug: Show cache directory contents (all files)
try:
cache_files = os.listdir(icaros_cache_dir)
print(f" -> Icaros cache has {len(cache_files)} files")
_print_icaros(f" -> Icaros cache has {len(cache_files)} files")
if len(cache_files) > 0:
print(f" -> All cache files: {cache_files}")
_print_icaros(f" -> All cache files: {cache_files}")
except Exception:
pass
# Discover .icdb databases by size preference
icdb_paths = _list_icdb_databases(icaros_cache_dir)
if not icdb_paths:
print(f" -> No .icdb database files found")
_print_icaros(f" -> No .icdb database files found")
return None
# Lookup a precise index for this file from Icaros_idx.icdb (SQLite or binary)
mapped_index, preferred_db = _lookup_icaros_index(icaros_cache_dir, file_path)
if mapped_index is None:
print(f" -> No exact Icaros index entry for this file; skipping Icaros")
_print_icaros(f" -> No exact Icaros index entry for this file; skipping Icaros")
return None
# Try preferred DB first if provided
@@ -711,16 +723,16 @@ def extract_icaros_thumbnail(file_path):
for icdb_path in ordered_dbs:
img = extract_from_icdb_database(icdb_path, file_path, forced_index=mapped_index)
if img:
print(f" -> Found thumbnail in {os.path.basename(icdb_path)} via mapped index")
_print_icaros(f" -> Found thumbnail in {os.path.basename(icdb_path)} via mapped index")
return img
print(f" -> Mapped index did not resolve a thumbnail in any DB")
_print_icaros(f" -> Mapped index did not resolve a thumbnail in any DB")
return None
except ImportError:
print(f" -> Required modules not available for .icdb extraction")
_print_icaros(f" -> Required modules not available for .icdb extraction")
return None
except Exception as e:
print(f" -> Icaros cache extraction error: {e}")
_print_icaros(f" -> Icaros cache extraction error: {e}")
return None
@@ -814,12 +826,12 @@ def _build_icaros_index_map(cache_dir):
conn.close()
_ICAROS_INDEX_CACHE = mapping
if mapping:
print(f" -> Loaded Icaros index map for {len(mapping)} files")
_print_icaros(f" -> Loaded Icaros index map for {len(mapping)} files")
else:
print(f" -> Icaros index database present but no usable mapping found")
_print_icaros(f" -> Icaros index database present but no usable mapping found")
return _ICAROS_INDEX_CACHE
except Exception as e:
print(f" -> Failed to read Icaros index: {e}")
_print_icaros(f" -> Failed to read Icaros index: {e}")
_ICAROS_INDEX_CACHE = {}
return _ICAROS_INDEX_CACHE
@@ -988,7 +1000,7 @@ def extract_from_icdb_database(icdb_path, file_path, forced_index=None):
# Verify ICDB signature
if not data.startswith(b'ICDB'):
print(f" -> Invalid ICDB signature in {icdb_path}")
_print_icaros(f" -> Invalid ICDB signature in {icdb_path}")
return None
# Search for JPEG images in the file
@@ -1002,10 +1014,10 @@ def extract_from_icdb_database(icdb_path, file_path, forced_index=None):
pos += 1
if not jpeg_positions:
print(f" -> No JPEG images found in {icdb_path}")
_print_icaros(f" -> No JPEG images found in {icdb_path}")
return None
print(f" -> Found {len(jpeg_positions)} JPEG images in {icdb_path}")
_print_icaros(f" -> Found {len(jpeg_positions)} JPEG images in {icdb_path}")
# If we have a mapped index, try it directly first
if isinstance(forced_index, int) and len(jpeg_positions) > 0:
@@ -1021,11 +1033,11 @@ def extract_from_icdb_database(icdb_path, file_path, forced_index=None):
jpeg_data = data[jpeg_start:jpeg_end]
try:
img = Image.open(io.BytesIO(jpeg_data))
print(f" -> Used mapped index {pos_index} from {os.path.basename(icdb_path)}")
_print_icaros(f" -> Used mapped index {pos_index} from {os.path.basename(icdb_path)}")
return img.copy()
except Exception:
# If mapped position invalid, continue to heuristic
print(f" -> Mapped index {pos_index} invalid; falling back to heuristic")
_print_icaros(f" -> Mapped index {pos_index} invalid; falling back to heuristic")
# Heuristic alphabetical mapping (fallback)
def get_alphabetical_position(target_file_path):
@@ -1079,10 +1091,10 @@ def extract_from_icdb_database(icdb_path, file_path, forced_index=None):
try:
position = all_files.index(target_rel_path)
print(f" -> Alphabetical position estimate: {position} for {target_filename}")
_print_icaros(f" -> Alphabetical position estimate: {position} for {target_filename}")
return position
except ValueError:
print(f" -> File {target_filename} not found in current monitored directories")
_print_icaros(f" -> File {target_filename} not found in current monitored directories")
# Return a reasonable fallback position
return len(all_files) // 2 # Middle position as fallback
@@ -1093,16 +1105,16 @@ def extract_from_icdb_database(icdb_path, file_path, forced_index=None):
if cache_position >= len(jpeg_positions):
# Use modulo to wrap around (cache might be from larger file set)
cache_position = cache_position % len(jpeg_positions)
print(f" -> Wrapped position to {cache_position} (cache has {len(jpeg_positions)} entries)")
_print_icaros(f" -> Wrapped position to {cache_position} (cache has {len(jpeg_positions)} entries)")
jpeg_start = jpeg_positions[cache_position]
print(f" -> Alphabetical mapping -> JPEG {cache_position} for {os.path.basename(file_path)}")
_print_icaros(f" -> Alphabetical mapping -> JPEG {cache_position} for {os.path.basename(file_path)}")
# Find the end of the JPEG (FF D9 marker)
jpeg_end = data.find(b'\xff\xd9', jpeg_start)
if jpeg_end == -1:
print(f" -> Could not find JPEG end marker")
_print_icaros(f" -> Could not find JPEG end marker")
return None
jpeg_end += 2 # Include the end marker
@@ -1110,11 +1122,11 @@ def extract_from_icdb_database(icdb_path, file_path, forced_index=None):
# Try to create PIL Image from the JPEG data
img = Image.open(io.BytesIO(jpeg_data))
print(f" -> Successfully extracted {img.size[0]}x{img.size[1]} JPEG from {icdb_path}")
_print_icaros(f" -> Successfully extracted {img.size[0]}x{img.size[1]} JPEG from {icdb_path}")
return img.copy()
except Exception as e:
print(f" -> Error reading ICDB file {icdb_path}: {e}")
_print_icaros(f" -> Error reading ICDB file {icdb_path}: {e}")
return None