Files
PlexDBRepair/DBRepair-Windows.bat
2024-05-05 17:57:54 -07:00

315 lines
11 KiB
Batchfile

@echo off
REM PlexDBRepair.bat - Database maintenance / rebuild tool for Windows.
REM
REM This tool currently works as a "full shot" service, outside of PhotoTranscoder pruning.
REM - everything is done without need to interact.
REM
REM -- WARNNING -- WARNING -- WARNING
REM
REM This is stable working software but not "Released" software. Development will continue.
setlocal enabledelayedexpansion
goto :Begin
:Help
echo PlexDBRepair.bat - Database maintenance / rebuild tool for Windows.
echo.
echo Usage: PlexDBRepair.bat [OPTION]...
echo.
echo -prune Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder
echo in addition to standard database maintenance tasks.
echo -cacheAge [age] Set the date cutoff for pruned images. Defaults to pruning images
echo over 30 days old.
echo -skipDB Don't perform database maintenance.
echo.
echo -- WARNNING -- WARNING -- WARNING
echo.
echo This is stable working software but not "Released" software. Development will continue.
goto :EOF
:Begin
REM ### Create Timestamp
set Hour=%time:~0,2%
set Min=%time:~3,2%
set Sec=%time:~6,2%
REM ## Remove spaces from Hour ##
set Hour=%Hour: =%
REM ## Set TimeStamp ##
set TimeStamp=%Hour%-%Min%-%Sec%
REM Parse arguments
set PruneCache=0
set CacheAge=30
set SkipDBMaintenance=0
:ParseArgs
if "%1" == "" goto :ParseArgsDone
for %%a in (prune -prune) do if /i "%1" == "%%a" ( set PruneCache=1 ) & shift & goto :ParseArgs
for %%a in (cacheage -cacheage) do if /i "%1" == "%%a" ( set "CacheAge=%2" & shift ) & shift & goto :ParseArgs
for %%a in (skipdb -skipdb) do if /i "%1" == "%%a" ( set SkipDBMaintenance=1 ) & shift & goto :ParseArgs
for %%a in (help -help /? -?) do if /i "%1" == "%%a" goto :Help
:ParseArgsDone
if not "%1" == "" (
echo Unknown option "%1"
echo.
goto :Help
)
REM Find PMS data directory
for /F "tokens=2* skip=2" %%a in ('REG.EXE QUERY "HKCU\Software\Plex, Inc.\Plex Media Server" /v "LocalAppDataPath" 2^> nul') do set "AppSupDir=%%b\Plex Media Server"
if not exist "%AppSupDir%" (
if exist "%LOCALAPPDATA%\Plex Media Server" (
set "%AppSupDir%=%LOCALAPPDATA%\Plex Media Server"
) else (
echo Could not determine Plex data directory.
echo Normally "%LOCALAPPDATA%\Plex Media Server"
echo.
goto :EOF
)
)
REM Find PMS database location
set "PlexData=%AppSupDir%\Plug-in Support\Databases"
if not exist "%PlexData%" (
echo Could not determine Plex database path.
echo Normally %AppSupDir%\Plug-in Support\Databases
echo.
goto :EOF
)
REM Find PMS cache dir
set "PlexCache=%AppSupDir%\Cache\PhotoTranscoder"
if %PruneCache% == 1 (
if not exist "%PlexCache%" (
echo Could not determine Plex photo cache path, cannot prune images.
echo Normally "%PlexCache%"
echo.
goto :EOF
)
)
REM Find PMS installation location.
for /F "tokens=2* skip=2" %%a in ('REG.EXE QUERY "HKCU\Software\Plex, Inc.\Plex Media Server" /v "InstallFolder" 2^> nul') do set "PlexSQL=%%b\Plex SQLite.exe"
if not exist "%PlexSQL%" (
REM InstallFolder might be set under HKLM, not HKCU
for /F "tokens=2* skip=2" %%a in ('REG.EXE QUERY "HKLM\Software\Plex, Inc.\Plex Media Server" /v "InstallFolder" 2^> nul') do set "PlexSQL=%%b\Plex SQLite.exe"
)
REM If InstallFolder wasn't set, or the resulting file doesn't exist, iterate through the
REM PROGRAMFILES variables looking for it. If we still can't find it, ask the user to provide it.
if not exist "%PlexSQL%" (
if exist "%PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite.exe" (
set "PlexSQL=%PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite.exe"
) else (
if exist "%PROGRAMFILES(X86)%\Plex\Plex Media Server\Plex SQLite.exe" (
echo NOTE: 32-bit version of PMS detected on a 64-bit version of Windows. Updating to the 64-bit release of PMS is recommended.
set "PlexSQL=%PROGRAMFILES(X86)%\Plex\Plex Media Server\Plex SQLite.exe"
) else (
echo Could not determine SQLite path. Please provide it below
echo Normally %PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite.exe
echo.
REM Last ditch effort, ask the user for the full path to Plex SQLite.exe
set /p "PlexSQL=Path to Plex SQLite.exe: "
if not exist "!PlexSQL!" (
echo "!PlexSQL!" could not be found. Cannot continue.
goto :EOF
)
)
)
)
REM Set temporary file locations
set "DBtmp=%PlexData%\dbtmp"
set "TmpFile=%DBtmp%\results.tmp"
REM Time now.
echo %time% -- ====== Session begins. (%date%) ======
echo %time% -- ====== Session begins. (%date%) ====== >> "%PlexData%\PlexDBRepair.log"
REM Make certain Plex is NOT running.
tasklist | find /I "Plex Media Server.exe" >NUL
if %ERRORLEVEL%==0 (
echo %time% -- Plex is running. Please stop Plex Media Server and try again.
echo %time% -- Plex is running. Please stop Plex Media Server and try again. >> "%PlexData%\PlexDBRepair.log"
exit /B 1
)
set "CDSave=%cd%"
if %SkipDBMaintenance% == 1 (
goto :PruneStart
)
cd "%PlexData%"
md "%PlexData%\dbtmp" 2>NUL
del "%TmpFile%" 2>NUL
echo %time% -- Exporting Main DB
echo %time% -- Exporting Main DB >> "%PlexData%\PlexDBRepair.log"
echo .dump | "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db" > "%DBtmp%\library.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot export Main DB. Aborting.
exit /b 2
)
echo %time% -- Exporting Blobs DB
echo %time% -- Exporting Blobs DB >> "%PlexData%\PlexDBRepair.log"
echo .dump | "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db" > "%DBtmp%\blobs.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot export Blobs DB. Aborting.
)
REM Now create new databases from SQL statements
echo %time% -- Exporting Complete.
echo %time% -- Exporting Complete. >> "%PlexData%\PlexDBRepair.log"
echo %time% -- Creating Main DB
echo %time% -- Creating Main DB >> "%PlexData%\PlexDBRepair.log"
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" < "%DBtmp%\library.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot create Main DB. Aborting.
echo %time% -- ERROR: Cannot create Main DB. Aborting. >> "%PlexData%\PlexDBRepair.log"
exit /b 3
)
echo %time% -- Verifying Main DB
echo %time% -- Verifying Main DB >> "%PlexData%\PlexDBRepair.log"
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "PRAGMA integrity_check(1)" >"%TmpFile%"
set /p Result= < "%TmpFile%"
del "%TmpFile%"
echo %time% -- Main DB verification check is: %Result%
echo %time% -- Main DB verification check is: %Result% >> "%PlexData%\PlexDBRepair.log"
if not "%Result%" == "ok" (
echo %time% -- ERROR: Main DB verificaion failed. Exiting.
echo %time% -- ERROR: Main DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log"
exit /B 4
)
echo %time% -- Main DB verification successful.
echo %time% -- Main DB verification successful. >> "%PlexData%\PlexDBRepair.log"
echo %time% -- Creating Blobs DB
echo %time% -- Creating Blobs DB >> "%PlexData%\PlexDBRepair.log"
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" < "%DBtmp%\blobs.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot create Blobs DB. Aborting.
echo %time% -- ERROR: Cannot create Blobs DB. Aborting. >> "%PlexData%\PlexDBRepair.log"
exit /b 5
)
echo %time% -- Verifying Blobs DB
echo %time% -- Verifying Blobs DB >> "%PlexData%\PlexDBRepair.log"
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "PRAGMA integrity_check(1)" > "%TmpFile%"
set /p Result= < "%TmpFile%"
del "%TmpFile%"
echo %time% -- Blobs DB verification check is: %Result%
echo %time% -- Blobs DB verification check is: %Result% >> "%PlexData%\PlexDBRepair.log"
if not "%Result%" == "ok" (
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting.
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log"
exit /B 6
)
echo %time% -- Blobs DB verification successful.
echo %time% -- Blobs DB verification successful. >> "%PlexData%\PlexDBRepair.log"
echo %time% -- Import and verification complete.
echo %time% -- Import and verification complete. >> "%PlexData%\PlexDBRepair.log"
REM Import complete, now reindex
echo %time% -- Reindexing Main DB
echo %time% -- Reindexing Main DB >> "%PlexData%\PlexDBRepair.log"
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "REINDEX;"
echo %time% -- Reindexing Blobs DB
echo %time% -- Reindexing Blobs DB >> "%PlexData%\PlexDBRepair.log"
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "REINDEX;"
REM Index complete, make active
echo %time% -- Reindexing complete.
echo %time% -- Reindexing complete. >> "%PlexData%\PlexDBRepair.log"
echo %time% -- Moving current DBs to DBTMP and making new databases active
echo %time% -- Moving current DBs to DBTMP and making new databases active >> "%PlexData%\PlexDBRepair.log"
move "%PlexData%\com.plexapp.plugins.library.db" "%PlexData%\dbtmp\com.plexapp.plugins.library.db_%TimeStamp%"
move "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "%PlexData%\com.plexapp.plugins.library.db"
move "%PlexData%\com.plexapp.plugins.library.blobs.db" "%PlexData%\dbtmp\com.plexapp.plugins.library.blobs.db_%TimeStamp%"
move "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "%PlexData%\com.plexapp.plugins.library.blobs.db"
echo %time% -- Database repair/rebuild/reindex completed.
echo %time% -- Database repair/rebuild/reindex completed. >> "%PlexData%\PlexDBRepair.log"
:PruneStart
if %PruneCache% neq 1 (
goto :Done
)
REM Restore working directory
cd %CDSave%
echo %time% -- Prune - START
echo %time% -- Prune - START >> "%PlexData%\PlexDBRepair.log"
REM Validate cache age parameter
echo %CacheAge%|findstr /r /c:"^[1-9][0-9]*$" >nul
if errorlevel 1 (
goto :PruneAgeError
) else (
set /a "checkZero=%CacheAge%"
if "%checkZero%" == 0 (
goto :PruneAgeError
)
)
goto :Prune
:PruneAgeError
echo %time% -- Prune - ERROR: Cache age %CacheAge% is not a valid value
echo %time% -- Prune - ERROR: Cache age %CacheAge% is not a valid value >> "%PlexData%\PlexDBRepair.log"
goto :Done
:Prune
set i=0
for /f "delims=" %%a in ('powershell .\CleanPhotoCache-Windows.ps1 -cacheDir '%PlexCache%' -cacheAge %CacheAge%') do (
set PSReturn[!i!]=%%a
set /a i += 1
)
set TotalFiles=%PSReturn[0]%
set DeletedFiles=%PSReturn[1]%
set FreedBytes=%PSReturn[2]%
echo %time% -- Prune - Removing %DeletedFiles% files over %CacheAge% days old (out of %TotalFiles% files), freeing %FreedBytes%
echo %time% -- Prune - Removing %DeletedFiles% files over %CacheAge% days old (out of %TotalFiles% files), freeing %FreedBytes% >> "%PlexData%\PlexDBRepair.log"
echo %time% -- Prune - PASS
echo %time% -- Prune - PASS >> "%PlexData%\PlexDBRepair.log"
:Done
echo %time% -- ====== Session completed. ======
echo %time% -- ====== Session completed. ====== >> "%PlexData%\PlexDBRepair.log"
exit /b
REM #### Functions
REM Output - Write text to the console and the log file
:Output
echo %time% %~1
echo %time% %~1 >> "%PlexData%\PlexDBRepair.log"
exit /B