mirror of
https://github.com/ChuckPa/PlexDBRepair.git
synced 2025-11-06 03:08:55 -05:00
Added informative output and correct issue selecting final available backup. Added binhex (Arch) docker support Updated READMEmd Add support for all Docker variants Change detection to use cgroup Add BINHEX support, Update README.md
1257 lines
37 KiB
Bash
Executable File
1257 lines
37 KiB
Bash
Executable File
#!/bin/sh
|
|
#########################################################################
|
|
# Plex Media Server database check and repair utility script. #
|
|
# Maintainer: ChuckPa #
|
|
#########################################################################
|
|
|
|
# Flag when temp files are to be retained
|
|
Retain=0
|
|
|
|
# Have the databases passed integrity checks
|
|
CheckedDB=0
|
|
|
|
# Universal output function
|
|
Output() {
|
|
echo "$@"
|
|
$LOG_TOOL "$@"
|
|
}
|
|
|
|
# Write to Repair Tool log
|
|
WriteLog() {
|
|
|
|
# Write given message into tool log file with TimeStamp
|
|
echo "$(date "+%Y-%m-%d %H.%M.%S") - $*" >> "$LOGFILE"
|
|
return 0
|
|
}
|
|
|
|
# Check given database file integrity
|
|
CheckDB() {
|
|
|
|
# Confirm the DB exists
|
|
[ ! -f "$1" ] && Output "ERROR: $1 does not exist." && return 1
|
|
|
|
# Now check database for corruption
|
|
Result="$("$PLEX_SQLITE" "$1" "PRAGMA integrity_check(1)")"
|
|
if [ "$Result" = "ok" ]; then
|
|
return 0
|
|
else
|
|
SQLerror="$(echo $Result | sed -e 's/.*code //')"
|
|
return 1
|
|
fi
|
|
|
|
}
|
|
|
|
# Check all databases
|
|
CheckDatabases() {
|
|
|
|
# Arg1 = calling function
|
|
# Arg2 = 'force' if present
|
|
|
|
# Check each of the databases. If all pass, set the 'CheckedDB' flag
|
|
# Only force recheck if flag given
|
|
|
|
# Check if not checked or forced
|
|
NeedCheck=0
|
|
[ $CheckedDB -eq 0 ] && NeedCheck=1
|
|
[ $CheckedDB -eq 1 ] && [ "$2" = "force" ] && NeedCheck=1
|
|
|
|
# Do we need to check
|
|
if [ $NeedCheck -eq 1 ]; then
|
|
|
|
# Clear Damaged flag
|
|
Damaged=0
|
|
CheckedDB=0
|
|
|
|
# Info
|
|
Output "Checking the PMS databases"
|
|
|
|
# Check main DB
|
|
if CheckDB $CPPL.db ; then
|
|
Output "Check complete. PMS main database is OK."
|
|
WriteLog "$1"" - Check $CPPL.db - PASS"
|
|
else
|
|
Output "Check complete. PMS main database is damaged."
|
|
WriteLog "$1"" - Check $CPPL.db - FAIL ($SQLerror)"
|
|
Damaged=1
|
|
fi
|
|
|
|
# Check blobs DB
|
|
if CheckDB $CPPL.blobs.db ; then
|
|
Output "Check complete. PMS blobs database is OK."
|
|
WriteLog "$1"" - Check $CPPL.blobs.db - PASS"
|
|
else
|
|
Output "Check complete. PMS blobs database is damaged."
|
|
WriteLog "$1"" - Check $CPPL.blobs.db - FAIL ($SQLerror)"
|
|
Damaged=1
|
|
fi
|
|
fi
|
|
|
|
[ $Damaged -eq 0 ] && CheckedDB=1
|
|
|
|
# return status
|
|
return $Damaged
|
|
}
|
|
|
|
# Return list of database backup dates for consideration in replace action
|
|
GetDates(){
|
|
|
|
Dates=""
|
|
Tempfile="/tmp/DBRepairTool.$$.tmp"
|
|
touch "$Tempfile"
|
|
|
|
for i in $(find . -name 'com.plexapp.plugins.library.db-????-??-??' | sort -r)
|
|
do
|
|
# echo Date - "${i//[^.]*db-/}"
|
|
Date="$(echo $i | sed -e 's/.*.db-//')"
|
|
|
|
# Only add if companion blobs DB exists
|
|
[ -e $CPPL.blobs.db-$Date ] && echo $Date >> "$Tempfile"
|
|
|
|
done
|
|
|
|
# Reload dates in sorted order
|
|
Dates="$(sort -r <$Tempfile)"
|
|
|
|
# Remove tempfile
|
|
rm -f "$Tempfile"
|
|
|
|
# Give results
|
|
echo $Dates
|
|
return
|
|
}
|
|
|
|
# Non-fatal SQLite error code check
|
|
SQLiteOK() {
|
|
|
|
# Global error variable
|
|
SQLerror=0
|
|
|
|
# Quick exit- known OK
|
|
[ $1 -eq 0 ] && return 0
|
|
|
|
# Put list of acceptable error codes here
|
|
Codes="19 28"
|
|
|
|
# By default assume the given code is an error
|
|
CodeError=1
|
|
|
|
for i in $Codes
|
|
do
|
|
if [ $i -eq $1 ]; then
|
|
CodeError=0
|
|
SQLerror=$i
|
|
break
|
|
fi
|
|
done
|
|
return $CodeError
|
|
}
|
|
|
|
# Perform the actual copying for MakeBackup()
|
|
DoBackup() {
|
|
|
|
if [ -e $2 ]; then
|
|
cp -p "$2" "$3"
|
|
Result=$?
|
|
if [ $Result -ne 0 ]; then
|
|
Output "Error $Result while backing up '$2'. Cannot continue."
|
|
WriteLog "$1 - MakeBackup $2 - FAIL"
|
|
|
|
# Remove partial copied file and return
|
|
rm -f "$3"
|
|
return 1
|
|
else
|
|
WriteLog "$1 - MakeBackup $2 - PASS"
|
|
return 0
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Make a backup of the current database files and tag with TimeStamp
|
|
MakeBackups() {
|
|
|
|
Output "Backup current databases with '-ORIG-$TimeStamp' timestamp."
|
|
|
|
for i in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm"
|
|
do
|
|
DoBackup "$1" "${CPPL}.${i}" "$DBTMP/${CPPL}.${i}-ORIG-$TimeStamp"
|
|
Result=$?
|
|
done
|
|
|
|
return $Result
|
|
|
|
}
|
|
|
|
ConfirmYesNo() {
|
|
|
|
Answer=""
|
|
while [ "$Answer" = "" ]
|
|
do
|
|
printf "$1 (Y/N) ? "
|
|
read Input
|
|
|
|
# EOF = No
|
|
[ "$Input" = "" ] && Answer=N ; [ "$Input" = "n" ] && Answer=N ; [ "$Input" = "N" ] && Answer=N
|
|
[ "$Input" = "y" ] && Answer=Y ; [ "$Input" = "Y" ] && Answer=Y
|
|
|
|
# Unrecognized
|
|
if [ "$Answer" != "Y" ] && [ "$Answer" != "N" ]; then
|
|
echo "$Input" was not a valid reply. Please try again.
|
|
continue
|
|
fi
|
|
done
|
|
|
|
# If no, done.
|
|
if [ "$Answer" = "N" ]; then
|
|
return 1
|
|
fi
|
|
|
|
# User said Yes. Be 100% certain
|
|
Answer=""
|
|
while [ "$Answer" = "" ]
|
|
do
|
|
printf "Are you sure (Y/N) ? "
|
|
read Input
|
|
|
|
# EOF = No
|
|
[ "$Input" = "" ] && Answer=N ; [ "$Input" = "n" ] && Answer=N ; [ "$Input" = "N" ] && Answer=N
|
|
[ "$Input" = "y" ] && Answer=Y ; [ "$Input" = "Y" ] && Answer=Y
|
|
|
|
# Unrecognized
|
|
if [ "$Answer" != "Y" ] && [ "$Answer" != "N" ]; then
|
|
echo "$Input" was not a valid reply. Please try again.
|
|
continue
|
|
fi
|
|
done
|
|
|
|
if [ "$Answer" = "Y" ]; then
|
|
# Confirmed Yes
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Restore previously saved DB from given TimeStamp
|
|
RestoreSaved() {
|
|
|
|
T="$1"
|
|
|
|
for i in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm"
|
|
do
|
|
[ -e "${CPPL}.${i}" ] && rm -f "${CPPL}.${i}"
|
|
[ -e "$DBTMP/${CPPL}.${i}-ORIG-$T" ] && mv "$DBTMP/${CPPL}.${i}-ORIG-$T" "${CPPL}.${i}"
|
|
done
|
|
}
|
|
|
|
# Get the size of the given DB in MB
|
|
GetSize() {
|
|
|
|
Size=$(stat $STATFMT $STATBYTES "$1")
|
|
Size=$(expr $Size / 1048576)
|
|
[ $Size -eq 0 ] && Size=1
|
|
echo $Size
|
|
}
|
|
|
|
# Determine which host we are running on and set variables
|
|
HostConfig() {
|
|
|
|
# On all hosts except Mac
|
|
PIDOF="pidof"
|
|
STATFMT="-c"
|
|
STATBYTES="%s"
|
|
|
|
# Synology (DSM 7)
|
|
if [ -d /var/packages/PlexMediaServer ] && \
|
|
[ -d "/var/packages/PlexMediaServer/shares/PlexMediaServer/AppData/Plex Media Server" ]; then
|
|
|
|
# Where is the software
|
|
PKGDIR="/var/packages/PlexMediaServer/target"
|
|
PLEX_SQLITE="$PKGDIR/Plex SQLite"
|
|
LOG_TOOL="logger"
|
|
|
|
# Where is the data
|
|
AppSuppDir="/var/packages/PlexMediaServer/shares/PlexMediaServer/AppData"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
|
|
# We are done
|
|
HostType="Synology (DSM 7)"
|
|
return 0
|
|
|
|
# Synology (DSM 6)
|
|
elif [ -d "/var/packages/Plex Media Server" ] && \
|
|
[ -f "/usr/syno/sbin/synoshare" ]; then
|
|
|
|
# Where is the software
|
|
PKGDIR="/var/packages/Plex Media Server/target"
|
|
PLEX_SQLITE="$PKGDIR/Plex SQLite"
|
|
LOG_TOOL="logger"
|
|
|
|
# Get shared folder path
|
|
AppSuppDir="$(synoshare --get Plex | grep Path | awk -F\[ '{print $2}' | awk -F\] '{print $1}')"
|
|
|
|
# Where is the data
|
|
AppSuppDir="$AppSuppDir/Library/Application Support"
|
|
if [ -d "$AppSuppDir/Plex Media Server" ]; then
|
|
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
|
|
HostType="Synology (DSM 6)"
|
|
return 0
|
|
fi
|
|
|
|
# QNAP (QTS & QuTS)
|
|
elif [ -f /etc/config/qpkg.conf ]; then
|
|
|
|
# Where is the software
|
|
PKGDIR="$(getcfg -f /etc/config/qpkg.conf PlexMediaServer Install_path)"
|
|
PLEX_SQLITE="$PKGDIR/Plex SQLite"
|
|
LOG_TOOL="/sbin/log_tool -t 0 -a"
|
|
|
|
# Where is the data
|
|
AppSuppDir="$PKGDIR/Library"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
|
|
HostType="QNAP"
|
|
return 0
|
|
|
|
# Standard configuration Linux host
|
|
elif [ -f /etc/os-release ] && \
|
|
[ -d /usr/lib/plexmediaserver ] && \
|
|
[ -d /var/lib/plexmediaserver ]; then
|
|
|
|
# Where is the software
|
|
PKGDIR="/usr/lib/plexmediaserver"
|
|
PLEX_SQLITE="$PKGDIR/Plex SQLite"
|
|
LOG_TOOL="logger"
|
|
|
|
# Where is the data
|
|
AppSuppDir="/var/lib/plexmediaserver/Library/Application Support"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
|
|
# Find the metadata dir if customized
|
|
if [ -e /etc/systemd/system/plexmediaserver.service.d ]; then
|
|
|
|
# Glob up all 'conf files' found
|
|
NewSuppDir="$(cd /etc/systemd/system/plexmediaserver.service.d ; \
|
|
cat override.conf local.conf *.conf 2>/dev/null | grep "APPLICATION_SUPPORT_DIR" | head -1)"
|
|
|
|
if [ "$NewSuppDir" != "" ]; then
|
|
NewSuppDir="$(echo $NewSuppDir | sed -e 's/.*_DIR=//' | tr -d '"' | tr -d "'")"
|
|
|
|
if [ -d "$NewSuppDir" ]; then
|
|
AppSuppDir="$NewSuppDir"
|
|
else
|
|
echo "Given application support directory override specified does not exist: '$NewSuppDir'". Ignoring.
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
|
|
HostType="$(grep ^PRETTY_NAME= /etc/os-release | sed -e 's/PRETTY_NAME=//' | sed -e 's/"//g')"
|
|
return 0
|
|
|
|
# Netgear ReadyNAS
|
|
elif [ -e /etc/os-release ] && [ "$(cat /etc/os-release | grep ReadyNASOS)" != "" ]; then
|
|
|
|
# Find PMS
|
|
if [ "$(echo /apps/plexmediaserver*)" != "/apps/plexmediaserver*" ]; then
|
|
|
|
PKGDIR="$(echo /apps/plexmediaserver*)"
|
|
|
|
# Where is the code
|
|
PLEX_SQLITE="$PKGDIR/Binaries/Plex SQLite"
|
|
AppSuppDir="$PKGDIR/MediaLibrary"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
LOG_TOOL="logger"
|
|
|
|
HostType="Netgear ReadyNAS"
|
|
return 0
|
|
fi
|
|
|
|
# ASUSTOR
|
|
elif [ -f /etc/nas.conf ] && grep ASUSTOR /etc/nas.conf >/dev/null && \
|
|
[ -d "/volume1/Plex/Library/Plex Media Server" ]; then
|
|
|
|
# Where are things
|
|
PLEX_SQLITE="/volume1/.@plugins/AppCentral/plexmediaserver/Plex SQLite"
|
|
AppSuppDir="/volume1/Plex/Library"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
LOG_TOOL="logger"
|
|
|
|
HostType="ASUSTOR"
|
|
return 0
|
|
|
|
|
|
# Docker (All main docker variants except binhex)
|
|
elif [ "$(grep docker /proc/1/cgroup | wc -l)" -gt 0 ] && [ -d "/config/Library/Application Support" ]; then
|
|
|
|
PLEX_SQLITE="/usr/lib/plexmediaserver/Plex SQLite"
|
|
AppSuppDir="/config/Library/Application Support"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
LOG_TOOL="logger"
|
|
|
|
HostType="Docker"
|
|
return 0
|
|
|
|
# BINHEX Plex container
|
|
elif [ "$(grep docker /proc/1/cgroup | wc -l)" -gt 0 ] && [ -d "/config/Plex Media Server" ]; then
|
|
|
|
PLEX_SQLITE="/usr/lib/plexmediaserver/Plex SQLite"
|
|
AppSuppDir="/config"
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
LOG_TOOL="logger"
|
|
|
|
HostType="BINHEX"
|
|
return 0
|
|
|
|
# Western Digital (OS5)
|
|
elif [ -f /etc/system.conf ] && [ -d /mnt/HD/HD_a2/Nas_Prog/plexmediaserver ] && \
|
|
grep "Western Digital Corp" /etc/system.conf >/dev/null; then
|
|
|
|
# Where things are
|
|
PLEX_SQLITE="/mnt/HD/HD_a2/Nas_Prog/plexmediaserver/binaries/Plex SQLite"
|
|
AppSuppDir=/mnt/HD/HD*/Nas_Prog/plex_conf
|
|
PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
LOG_TOOL="logger"
|
|
|
|
HostType="Western Digital"
|
|
return 0
|
|
|
|
# Apple Mac
|
|
elif [ -d "/Applications/Plex Media Server.app" ] && \
|
|
[ -d "$HOME/Library/Application Support/Plex Media Server" ]; then
|
|
|
|
# Where is the software
|
|
PLEX_SQLITE="/Applications/Plex Media Server.app/Contents/MacOS/Plex SQLite"
|
|
AppSuppDir="$HOME/Library/Application Support"
|
|
DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases"
|
|
PID_FILE="$DBDIR/dbtmp/plexmediaserver.pid"
|
|
LOGFILE="$DBDIR/DBRepair.log"
|
|
LOG_TOOL="logger"
|
|
|
|
# MacOS uses pgrep and uses different stat options
|
|
PIDOF="pgrep"
|
|
STATFMT="-f"
|
|
STATBYTES="%z"
|
|
|
|
# make the TMP directory in advance to store plexmediaserver.pid
|
|
mkdir -p "$DBDIR/dbtmp"
|
|
|
|
# Remove stale PID file if it exists
|
|
[ -f "$PID_FILE" ] && rm "$PID_FILE"
|
|
|
|
# If PMS is running create plexmediaserver.pid
|
|
PIDVALUE=$($PIDOF "Plex Media Server")
|
|
[ $PIDVALUE ] && echo $PIDVALUE > "$PID_FILE"
|
|
|
|
HostType="Mac"
|
|
return 0
|
|
fi
|
|
|
|
# Unknown / currently unsupported host
|
|
return 1
|
|
}
|
|
|
|
# Simple function to set variables
|
|
SetLast() {
|
|
|
|
LastName="$1"
|
|
LastTimestamp="$2"
|
|
return 0
|
|
}
|
|
#############################################################
|
|
# Main utility begins here #
|
|
#############################################################
|
|
|
|
# Global variable - main database
|
|
CPPL=com.plexapp.plugins.library
|
|
|
|
# Initial timestamp
|
|
TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")"
|
|
|
|
# Initialize LastName LastTimestamp
|
|
SetLast "" ""
|
|
|
|
# Identify this host
|
|
HostType="" ; LOG_TOOL="echo"
|
|
if ! HostConfig; then
|
|
Output 'Error: Unknown host. Currently supported hosts are: QNAP, Synology, Netgear, Mac, ASUSTOR, WD (OS5) and Linux Workstation/Server'
|
|
exit 1
|
|
fi
|
|
|
|
# Is PMS already running?
|
|
if $PIDOF 'Plex Media Server' > /dev/null ; then
|
|
Output "Plex Media Server is currently running, cannot continue."
|
|
Output "Please stop Plex Media Server and restart this utility."
|
|
WriteLog "PMS running. Could not continue."
|
|
exit 1
|
|
fi
|
|
|
|
echo " "
|
|
# echo Detected Host: $HostType
|
|
WriteLog "============================================================"
|
|
WriteLog "Session start: Host is $HostType"
|
|
|
|
# Make sure we have a logfile
|
|
touch "$LOGFILE"
|
|
|
|
# Basic checks; PMS installed
|
|
if [ ! -f "$PLEX_SQLITE" ] ; then
|
|
Output "PMS is not installed. Cannot continue. Exiting."
|
|
WriteLog "Attempt to run utility without PMS installed."
|
|
exit 1
|
|
fi
|
|
|
|
# Can I write to the Databases directory ?
|
|
if [ ! -w "$DBDIR" ]; then
|
|
Output "ERROR: Cannot write to the Databases directory. Insufficient privilege or wrong UID. Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
# Databases exist or Backups exist to restore from
|
|
if [ ! -f "$DBDIR/$CPPL.db" ] && \
|
|
[ ! -f "$DBDIR/$CPPL.blobs.db" ] && \
|
|
[ "$(echo com.plexapp.plugins.*-????-??-??)" = "com.plexapp.plugins.*-????-??-??" ]; then
|
|
|
|
Output "Cannot locate databases. Cannot continue. Exiting."
|
|
WriteLog "No databases or backups found."
|
|
exit 1
|
|
fi
|
|
|
|
# Set tmp dir so we don't use RAM when in DBDIR
|
|
DBTMP="./dbtmp"
|
|
mkdir -p "$DBDIR/$DBTMP"
|
|
export TMPDIR="$DBTMP"
|
|
export TMP="$DBTMP"
|
|
|
|
# Work in the Databases directory
|
|
cd "$DBDIR"
|
|
|
|
# Get the owning UID/GID before we proceed so we can restore
|
|
Owner="$(stat $STATFMT '%u:%g' $CPPL.db)"
|
|
|
|
# Run entire utility in a loop until all arguments used, EOF on input, or commanded to exit
|
|
while true
|
|
do
|
|
|
|
# Main menu loop
|
|
Choice=0; Exit=0
|
|
while [ $Choice -eq 0 ]
|
|
do
|
|
echo " "
|
|
echo " "
|
|
echo " Plex Media Server Database Repair Utility ($HostType)"
|
|
echo " "
|
|
echo "Select"
|
|
echo " "
|
|
echo " 1. Check database"
|
|
echo " 2. Vacuum database"
|
|
echo " 3. Reindex database"
|
|
echo " 4. Attempt database repair"
|
|
echo " 5. Replace current database with newest usable backup copy"
|
|
echo " 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace)"
|
|
echo " 7. Import Viewstate / Watch history from another PMS database"
|
|
echo " 8. Show logfile"
|
|
echo " 9. Exit"
|
|
echo " "
|
|
printf "Enter choice: "
|
|
if [ "$1" != "" ]; then
|
|
Input="$1"
|
|
echo "$1"
|
|
shift
|
|
else
|
|
read Input
|
|
|
|
# Handle EOF/forced exit
|
|
[ "$Input" = "" ] && Input=8 && Exit=1
|
|
fi
|
|
[ "$Input" = "1" ] && Choice=1
|
|
[ "$Input" = "2" ] && Choice=2
|
|
[ "$Input" = "3" ] && Choice=3
|
|
[ "$Input" = "4" ] && Choice=4
|
|
[ "$Input" = "5" ] && Choice=5
|
|
[ "$Input" = "6" ] && Choice=6
|
|
[ "$Input" = "7" ] && Choice=7
|
|
[ "$Input" = "8" ] && Choice=8
|
|
[ "$Input" = "9" ] && Choice=9
|
|
|
|
[ "$Choice" -eq 0 ] && echo " " && echo "'$Input' - Is invalid. Try again"
|
|
|
|
# Update timestamp
|
|
TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")"
|
|
done
|
|
|
|
# Don't get caught; Is PMS already running?
|
|
if $PIDOF 'Plex Media Server' > /dev/null ; then
|
|
if [ $Choice -lt 8 ]; then
|
|
Output "Plex Media Server is currently running, cannot continue."
|
|
Output "Please stop Plex Media Server and restart this utility."
|
|
WriteLog "PMS running. Could not continue."
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Spacing for legibility
|
|
echo ' '
|
|
|
|
# 1. - Check database
|
|
if [ $Choice -eq 1 ]; then
|
|
|
|
# CHECK DBs
|
|
if CheckDatabases "Check " force ; then
|
|
WriteLog "Check - PASS"
|
|
CheckedDB=1
|
|
else
|
|
WriteLog "Check - FAIL"
|
|
CheckedDB=0
|
|
fi
|
|
|
|
# 2. Vacuum DB
|
|
elif [ $Choice -eq 2 ]; then
|
|
|
|
# Clear flags
|
|
Fail=0
|
|
Damaged=0
|
|
|
|
# Check databases before Indexing if not previously checked
|
|
if ! CheckDatabases "Vacuum " ; then
|
|
Damaged=1
|
|
Fail=1
|
|
fi
|
|
|
|
# If damaged, exit
|
|
if [ $Damaged -eq 1 ]; then
|
|
Output "Databases are damaged. Vacuum operation not available. Please repair or replace first."
|
|
WriteLog "Vacuum - Databases damaged."
|
|
continue
|
|
fi
|
|
|
|
|
|
# Make a backup
|
|
Output "Backing up databases"
|
|
if ! MakeBackups "Vacuum "; then
|
|
Output "Error making backups. Cannot continue."
|
|
WriteLog "Vacuum - MakeBackups - FAIL"
|
|
Fail=1
|
|
continue
|
|
else
|
|
WriteLog "Vacuum - MakeBackups - PASS"
|
|
fi
|
|
|
|
# Start vacuuming
|
|
Output "Vacuuming main database"
|
|
SizeStart=$(GetSize $CPPL.db)
|
|
|
|
# Vacuum it
|
|
"$PLEX_SQLITE" $CPPL.db 'VACUUM;'
|
|
Result=$?
|
|
|
|
if SQLiteOK $Result; then
|
|
SizeFinish=$(GetSize $CPPL.db)
|
|
Output "Vacuuming main database successful (Size: ${SizeStart}MB/${SizeFinish}MB)."
|
|
WriteLog "Vacuum - Vacuum main database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)."
|
|
else
|
|
Output "Vaccuming main database failed. Error code $Result from Plex SQLite"
|
|
WriteLog "Vacuum - Vacuum main database - FAIL ($Result)"
|
|
Fail=1
|
|
fi
|
|
|
|
Output "Vacuuming blobs database"
|
|
SizeStart=$(GetSize $CPPL.blobs.db)
|
|
|
|
# Vacuum it
|
|
"$PLEX_SQLITE" $CPPL.blobs.db 'VACUUM;'
|
|
Result=$?
|
|
|
|
if SQLiteOK $Result; then
|
|
SizeFinish=$(GetSize $CPPL.blobs.db)
|
|
Output "Vacuuming blobs database successful (Size: ${SizeStart}MB/${SizeFinish}MB)."
|
|
WriteLog "Vacuum - Vacuum blobs database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)."
|
|
else
|
|
Output "Vaccuming blobs database failed. Error code $Result from Plex SQLite"
|
|
WriteLog "Vacuum - Vacuum blobs database - FAIL ($Result)"
|
|
Fail=1
|
|
fi
|
|
|
|
if [ $Fail -eq 0 ]; then
|
|
Output "Vacuum complete."
|
|
WriteLog "Vacuum - PASS"
|
|
SetLast "Vacuum" "$TimeStamp"
|
|
else
|
|
Output "Vacuum failed."
|
|
WriteLog "Vacuum - FAIL"
|
|
RestoreSaved "$TimeStamp"
|
|
fi
|
|
continue
|
|
|
|
# 3. Reindex DB
|
|
elif [ $Choice -eq 3 ]; then
|
|
|
|
# Clear flag
|
|
Damaged=0
|
|
Fail=0
|
|
# Check databases before Indexing if not previously checked
|
|
if ! CheckDatabases "Reindex" ; then
|
|
Damaged=1
|
|
Fail=1
|
|
fi
|
|
|
|
|
|
# If damaged, exit
|
|
if [ $Damaged -eq 1 ]; then
|
|
Output "Databases are damaged. Reindex operation not available. Please repair or replace first."
|
|
continue
|
|
fi
|
|
|
|
# Databases are OK, Make a backup
|
|
Output "Backing up of databases"
|
|
MakeBackups "Reindex"
|
|
Result=$?
|
|
if [ $Result -eq 0 ]; then
|
|
WriteLog "Reindex - MakeBackup - PASS"
|
|
else
|
|
Output "Error making backups. Cannot continue."
|
|
WriteLog "Reindex - MakeBackup - FAIL ($Result)"
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
# Databases are OK, Start reindexing
|
|
Output "Reindexing main database"
|
|
"$PLEX_SQLITE" $CPPL.db 'REINDEX;'
|
|
Result=$?
|
|
if SQLiteOK $Result; then
|
|
Output "Reindexing main database successful."
|
|
WriteLog "Reindex - Reindex: $CPPL.db - PASS"
|
|
else
|
|
Output "Reindexing main database failed. Error code $Result from Plex SQLite"
|
|
WriteLog "Reindex - Reindex: $CPPL.db - FAIL ($Result)"
|
|
Fail=1
|
|
fi
|
|
|
|
Output "Reindexing blobs database"
|
|
"$PLEX_SQLITE" $CPPL.blobs.db 'REINDEX;'
|
|
Result=$?
|
|
if SQLiteOK $Result; then
|
|
Output "Reindexing blobs database successful."
|
|
WriteLog "Reindex - Reindex: $CPPL.blobs.db - PASS"
|
|
else
|
|
Output "Reindexing blobs database failed. Error code $Result from Plex SQLite"
|
|
WriteLog "Reindex - Reindex: $CPPL.blobs.db - FAIL ($Result)"
|
|
Fail=1
|
|
fi
|
|
|
|
Output "Reindex complete."
|
|
|
|
if [ $Fail -eq 0 ]; then
|
|
SetLast "Reindex" "$TimeStamp"
|
|
WriteLog "Reindex - PASS"
|
|
else
|
|
RestoreSaved "$TimeStamp"
|
|
WriteLog "Reindex - FAIL"
|
|
fi
|
|
continue
|
|
|
|
|
|
# 4. - Attempt DB repair
|
|
elif [ $Choice -eq 4 ]; then
|
|
|
|
Damaged=0
|
|
Fail=0
|
|
|
|
# Verify DBs are here
|
|
if [ ! -e $CPPL.db ]; then
|
|
Output "No main Plex database exists to repair. Exiting."
|
|
WriteLog "Repair - No main database - FAIL"
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
# Check size
|
|
Size=$(stat $STATFMT $STATBYTES $CPPL.db)
|
|
|
|
# Exit if not valid
|
|
if [ $Size -lt 300000 ]; then
|
|
Output "Main database is too small/truncated, repair is not possible. Please try restoring a backup. "
|
|
WriteLog "Repair - Main databse too small - FAIL"
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
# Continue
|
|
Output "Exporting current databases using timestamp: $TimeStamp"
|
|
Fail=0
|
|
|
|
# Get the owning UID/GID before we proceed so we can restore
|
|
Owner="$(stat $STATFMT '%u:%g' $CPPL.db)"
|
|
|
|
# Attempt to export main db to SQL file (Step 1)
|
|
printf 'Export: (main)..'
|
|
"$PLEX_SQLITE" $CPPL.db ".output '$TMPDIR/library.plexapp.sql-$TimeStamp'" .dump
|
|
Result=$?
|
|
if ! SQLiteOK $Result; then
|
|
|
|
# Cannot dump file
|
|
Output "Error $Result from Plex SQLite while exporting $CPPL.db"
|
|
Output "Could not successfully export the main database to repair it. Please try restoring a backup."
|
|
WriteLog "Repair - Cannot recover main database to '$TMPDIR/library.plexapp.sql-$TimeStamp' - FAIL ($Result)"
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
# Attempt to export blobs db to SQL file
|
|
printf '(blobs)..'
|
|
"$PLEX_SQLITE" $CPPL.blobs.db ".output '$TMPDIR/blobs.plexapp.sql-$TimeStamp'" .dump
|
|
Result=$?
|
|
if ! SQLiteOK $Result; then
|
|
|
|
# Cannot dump file
|
|
Output "Error $Result from Plex SQLite while exporting $CPPL.blobs.db"
|
|
Output "Could not successfully export the blobs database to repair it. Please try restoring a backup."
|
|
WriteLog "Repair - Cannot recover blobs database to '$TMPDIR/blobs.plexapp.sql-$TimeStamp' - FAIL ($Result)"
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
# Edit the .SQL files if all OK
|
|
if [ $Fail -eq 0 ]; then
|
|
|
|
# Edit
|
|
sed -i -e 's/ROLLBACK;/COMMIT;/' "$TMPDIR/library.plexapp.sql-$TimeStamp"
|
|
sed -i -e 's/ROLLBACK;/COMMIT;/' "$TMPDIR/blobs.plexapp.sql-$TimeStamp"
|
|
fi
|
|
|
|
# Inform user
|
|
echo done.
|
|
Output "Successfully exported the main and blobs databases. Proceeding to import into new databases."
|
|
WriteLog "Repair - Export databases - PASS"
|
|
|
|
# Library and blobs successfully exported, create new
|
|
printf 'Import: (main)..'
|
|
"$PLEX_SQLITE" $CPPL.db-$TimeStamp < "$TMPDIR/library.plexapp.sql-$TimeStamp"
|
|
Result=$?
|
|
if ! SQLiteOK $Result; then
|
|
Output "Error $Result from Plex SQLite while importing from '$TMPDIR/library.plexapp.sql-$TimeStamp'"
|
|
WriteLog "Repair - Cannot import main database from '$TMPDIR/library.plexapp.sql-$TimeStamp' - FAIL ($Result)"
|
|
Output "Cannot continue."
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
printf '(blobs)..'
|
|
"$PLEX_SQLITE" $CPPL.blobs.db-$TimeStamp < "$TMPDIR/blobs.plexapp.sql-$TimeStamp"
|
|
Result=$?
|
|
if ! SQLiteOK $Result ; then
|
|
Output "Error $Result from Plex SQLite while importing from '$TMPDIR/blobs.plexapp.sql-$TimeStamp'"
|
|
WriteLog "Repair - Cannot import blobs database from '$TMPDIR/blobs.plexapp.sql-$TimeStamp' - FAIL ($Result)"
|
|
Output "Cannot continue."
|
|
Fail=1
|
|
continue
|
|
fi
|
|
|
|
# Made it to here, now verify
|
|
echo done.
|
|
Output "Successfully imported data from exported SQL files."
|
|
WriteLog "Repair - Import - PASS"
|
|
|
|
# Verify databases are intact and pass testing
|
|
Output "Verifying databases integrity after importing."
|
|
|
|
# Check main DB
|
|
if CheckDB $CPPL.db-$TimeStamp ; then
|
|
SizeStart=$(GetSize $CPPL.db)
|
|
SizeFinish=$(GetSize $CPPL.db-$TimeStamp)
|
|
Output "Verification complete. PMS main database is OK."
|
|
WriteLog "Repair - Verify main database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)."
|
|
else
|
|
Output "Verification complete. PMS main database import failed."
|
|
WriteLog "Repair - Verify main database - FAIL ($SQLerror)"
|
|
Fail=1
|
|
fi
|
|
|
|
# Check blobs DB
|
|
if CheckDB $CPPL.blobs.db-$TimeStamp ; then
|
|
SizeStart=$(GetSize $CPPL.blobs.db)
|
|
SizeFinish=$(GetSize $CPPL.blobs.db-$TimeStamp)
|
|
Output "Verification complete. PMS blobs database is OK."
|
|
WriteLog "Repair - Verify blobs database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)."
|
|
else
|
|
Output "Verification complete. PMS blobs database import failed."
|
|
WriteLog "Repair - Verify main database - FAIL ($SQLerror)"
|
|
Fail=1
|
|
fi
|
|
|
|
# If not failed, move files normally
|
|
if [ $Fail -eq 0 ]; then
|
|
|
|
Output "Saving current databases with '-ORIG-$TimeStamp'"
|
|
[ -e $CPPL.db ] && mv $CPPL.db "$TMPDIR/$CPPL.db-ORIG-$TimeStamp"
|
|
[ -e $CPPL.blobs.db ] && mv $CPPL.blobs.db "$TMPDIR/$CPPL.blobs.db-ORIG-$TimeStamp"
|
|
|
|
Output "Making imported databases active"
|
|
mv $CPPL.db-$TimeStamp $CPPL.db
|
|
mv $CPPL.blobs.db-$TimeStamp $CPPL.blobs.db
|
|
|
|
Output "Import complete. Please check your library settings and contents for completeness."
|
|
Output "Recommend: Scan Files and Refresh all metadata for each library section."
|
|
|
|
# Remove .sql temp files from $TMPDIR
|
|
# rm -f "$TMPDIR"/*.sql-*
|
|
|
|
# Ensure WAL and SHM are gone
|
|
[ -e $CPPL.blobs.db-wal ] && rm -f $CPPL.blobs.db-wal
|
|
[ -e $CPPL.blobs.db-shm ] && rm -f $CPPL.blobs.db-shm
|
|
[ -e $CPPL.db-wal ] && rm -f $CPPL.db-wal
|
|
[ -e $CPPL.db-shm ] && rm -f $CPPL.db-shm
|
|
|
|
# Set ownership on new files
|
|
chown $Owner $CPPL.db $CPPL.blobs.db
|
|
|
|
# We didn't fail, set CheckedDB status true (passed above checks)
|
|
CheckedDB=1
|
|
|
|
WriteLog "Repair - Move files - PASS"
|
|
WriteLog "Repair - PASS"
|
|
|
|
SetLast "Repair" "$TimeStamp"
|
|
else
|
|
|
|
rm -f $CPPL.db-$TimeStamp
|
|
rm -f $CPPL.blobs.db-$TimeStamp
|
|
|
|
Output "Repair has failed. No files changed"
|
|
WriteLog "Repair - $TimeStamp - FAIL"
|
|
Retain=1
|
|
fi
|
|
continue
|
|
|
|
# 5. Replace database from backup copy
|
|
elif [ $Choice -eq 5 ]; then
|
|
|
|
# If Databases already checked, confirm the user really wants to do this
|
|
Confirmed=0
|
|
Fail=0
|
|
if CheckDatabases "Replace"; then
|
|
if ConfirmYesNo "Are you sure you want to restore a previous database backup"; then
|
|
Confirmed=1
|
|
fi
|
|
fi
|
|
|
|
if [ $Damaged -eq 1 ] || [ $Confirmed -eq 1 ]; then
|
|
# Get list of dates to use
|
|
Dates=$(GetDates)
|
|
|
|
# If no backups, error and exit
|
|
if [ "$Dates" = "" ] && [ $Damaged -eq 1 ]; then
|
|
Output "Database is damaged and no backups avaiable."
|
|
Output "Only available option is Repair."
|
|
WriteLog "Replace - Scan for usable candidates - FAIL"
|
|
continue
|
|
fi
|
|
|
|
Output "Checking for a usable backup."
|
|
Candidate=""
|
|
|
|
Output "Database backups available are: $Dates"
|
|
for i in $Dates
|
|
do
|
|
|
|
# Check candidate
|
|
if [ -e $CPPL.db-$i ] && \
|
|
[ -e $CPPL.blobs.db-$i ] && \
|
|
Output "Checking database $i" && \
|
|
CheckDB $CPPL.db-$i && \
|
|
CheckDB $CPPL.blobs.db-$i ; then
|
|
|
|
Output "Found valid database backup date: $i"
|
|
Candidate=$i
|
|
|
|
UseThis=0
|
|
if ConfirmYesNo "Use backup '$Candidate' ?"; then
|
|
UseThis=1
|
|
fi
|
|
|
|
# OK, use this one
|
|
if [ $UseThis -eq 1 ]; then
|
|
|
|
# Move database, wal, and shm (keep safe) with timestamp
|
|
Output "Saving current databases with timestamp: '-ORIG-$TimeStamp'"
|
|
|
|
for j in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm"
|
|
do
|
|
[ -e $CPPL.$j ] && mv -f $CPPL.$j "$TMPDIR/$CPPL.$j-ORIG-$TimeStamp"
|
|
done
|
|
WriteLog "Replace - Move Files - PASS"
|
|
|
|
# Copy this backup into position as primary
|
|
Output "Copying backup database $Candidate to use as new database."
|
|
|
|
cp -p $CPPL.db-$Candidate $CPPL.db-$TimeStamp
|
|
Result=$?
|
|
|
|
if [ $Result -ne 0 ]; then
|
|
Output "Error $Result while copying $CPPL.db"
|
|
Output "Database file is incomplete. Please resolve manually."
|
|
WriteLog "Replace - Copy $CPPL.db-$Candidate - FAIL"
|
|
Fail=1
|
|
else
|
|
WriteLog "Replace - Copy $CPPL.db-$i - PASS"
|
|
fi
|
|
|
|
cp -p $CPPL.blobs.db-$Candidate $CPPL.blobs.db-$TimeStamp
|
|
Result=$?
|
|
|
|
if [ $Result -ne 0 ]; then
|
|
Output "Error $Result while copying $CPPL.blobs.db"
|
|
Output "Database file is incomplete. Please resolve manually."
|
|
WriteLog "Replace - Copy $CPPL.blobs.db-$Candidate - FAIL"
|
|
Fail=1
|
|
else
|
|
WriteLog "Replace - Copy $CPPL.blobs.db-$Candidate - PASS"
|
|
fi
|
|
|
|
# If no failure copying, check and make active
|
|
if [ $Fail -eq 0 ]; then
|
|
# Final checks
|
|
Output "Copy complete. Performing final check"
|
|
|
|
if CheckDB $CPPL.db-$TimeStamp && \
|
|
CheckDB $CPPL.blobs.db-$TimeStamp ; then
|
|
|
|
# Move into position as active
|
|
mv $CPPL.db-$TimeStamp $CPPL.db
|
|
mv $CPPL.blobs.db-$TimeStamp $CPPL.blobs.db
|
|
|
|
# done
|
|
Output "Database recovery and verification complete."
|
|
WriteLog "Replace - Verify databases - PASS"
|
|
|
|
else
|
|
|
|
# DB did not verify after copy -- Something wrong
|
|
|
|
rm -f $CPPL.db-$TimeStamp $CPPL.blobs.db-$TimeStamp
|
|
Output "Final check failed. Keeping existing databases"
|
|
WriteLog "Replace - Verify databases - FAIL"
|
|
WriteLog "Replace - Failed Databses - REMOVED"
|
|
fi
|
|
else
|
|
|
|
Output "Could not copy backup databases. Out of disk space?"
|
|
Output "Restoring original databases"
|
|
|
|
for k in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm"
|
|
do
|
|
[ -e "$TMPDIR/$CPPL.$k-ORIG-$TimeStamp" ] && mv -f "$TMPDIR/$CPPL.$k-ORIG-$TimeStamp" $CPPL.$k
|
|
done
|
|
WriteLog "Replace - Verify databases - FAIL"
|
|
Fail=1
|
|
fi
|
|
|
|
# If successful, save
|
|
[ $Fail -eq 0 ] && SetLast "Replace" "$TimeStamp"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Error check if no Candidate found
|
|
if [ "$Candidate" = "" ]; then
|
|
Output "Error. No valid matching main and blobs database pairs. Cannot replace."
|
|
WriteLog "Replace - Select candidate - FAIL"
|
|
fi
|
|
fi
|
|
|
|
# 6. - Undo last successful action
|
|
elif [ $Choice -eq 6 ]; then
|
|
|
|
|
|
# Confirm there is something to undo
|
|
if [ "$LastTimestamp" != "" ]; then
|
|
|
|
# Educate user
|
|
echo " "
|
|
echo "'Undo' restores the databases to the state prior to the last SUCCESSFUL action."
|
|
echo "If any action fails before it completes, that action is automatically undone for you."
|
|
echo "Be advised: Undo restores the databases to their state PRIOR TO the last action of 'Vacuum', 'Reindex', or 'Replace'"
|
|
echo "WARNING: Once Undo completes, there will be nothing more to Undo untl another successful action is completed"
|
|
echo " "
|
|
|
|
if ConfirmYesNo "Undo '$LastName' performed at timestamp '$LastTimestamp' ? "; then
|
|
|
|
Output "Undoing $LastName ($LastTimestamp)"
|
|
for j in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm"
|
|
do
|
|
[ -e "$TMPDIR/$CPPL.$j-ORIG-$LastTimestamp" ] && mv -f "$TMPDIR/$CPPL.$j-ORIG-$LastTimestamp" $CPPL.$j
|
|
done
|
|
|
|
Output "Undo complete."
|
|
WriteLog "Undo - Undo ${LastName}, TimeStamp $LastTimestamp"
|
|
SetLast "Undo" ""
|
|
fi
|
|
|
|
else
|
|
Output "Nothing to undo."
|
|
WriteLog "Undo - Nothing to Undo."
|
|
fi
|
|
|
|
# 7. - Get Viewstate/Watch history from another DB and import
|
|
elif [ $Choice -eq 7 ]; then
|
|
|
|
printf "Pathname of database containing watch history to import: "
|
|
read Input
|
|
|
|
# Did we get something?
|
|
[ "$Input" = "" ] && continue
|
|
|
|
# Go see if it's a valid database
|
|
if [ ! -f "$Input" ]; then
|
|
Output "'$Input' does not exist."
|
|
continue
|
|
fi
|
|
|
|
Output " "
|
|
WriteLog "Import - Attempting to import watch history from '$Input' "
|
|
|
|
# Confirm our databases are intact
|
|
if ! CheckDatabases "Import "; then
|
|
Output "Error: PMS databases are damaged. Repair needed. Refusing to import."
|
|
WriteLog "Import - Verify main database - FAIL"
|
|
continue
|
|
fi
|
|
|
|
# Check the given database
|
|
Output "Checking database '$Input'"
|
|
if ! CheckDB "$Input"; then
|
|
Output "Error: Given database '$Input' is damaged. Repair needed. Database not trusted. Refusing to import."
|
|
WriteLog "Import - Verify '$Input' - FAIL"
|
|
continue
|
|
fi
|
|
WriteLog "Import - Verify '$Input' - PASS"
|
|
Output "Check complete. '$Input' is OK."
|
|
|
|
|
|
# Make a backup
|
|
Output "Backing up PMS databases"
|
|
if ! MakeBackups "Import "; then
|
|
Output "Error making backups. Cannot continue."
|
|
WriteLog "Import - MakeBackups - FAIL"
|
|
Fail=1
|
|
continue
|
|
fi
|
|
WriteLog "Import - MakeBackups - PASS"
|
|
|
|
|
|
# Export viewstate from DB
|
|
Output "Exporting Viewstate & Watch history"
|
|
echo ".dump metadata_item_settings metadata_item_views " | "$PLEX_SQLITE" "$Input" | grep -v TABLE | grep -v INDEX > "$TMPDIR/Viewstate.sql-$TimeStamp"
|
|
|
|
# Make certain we got something usable
|
|
if [ $(wc -l "$TMPDIR/Viewstate.sql-$TimeStamp" | awk '{print $1}') -lt 1 ]; then
|
|
Output "No viewstates or history found to import."
|
|
WriteLog "Import - Nothing to import - FAIL"
|
|
continue
|
|
fi
|
|
|
|
# Make a working copy to import into
|
|
Output "Preparing to import Viewstate and History data"
|
|
cp -p $CPPL.db $CPPL.db-$TimeStamp
|
|
Result=$?
|
|
|
|
if [ $Result -ne 0 ]; then
|
|
Output "Error $Result while making a working copy of the PMS main database."
|
|
Output " File permissions? Disk full?"
|
|
WriteLog "Import - Prepare: Make working copy - FAIL"
|
|
continue
|
|
fi
|
|
|
|
# Import viewstates into working copy
|
|
printf 'Importing Viewstate & History data...'
|
|
"$PLEX_SQLITE" $CPPL.db-$TimeStamp < "$TMPDIR/Viewstate.sql-$TimeStamp" 2> /dev/null
|
|
|
|
# Make certain the resultant DB is OK
|
|
Output " done."
|
|
Output "Checking database following import"
|
|
|
|
if ! CheckDB $CPPL.db-$TimeStamp ; then
|
|
|
|
# Import failed discard
|
|
Output "Error: Error code $Result during import. Import corrupted database."
|
|
Output " Discarding import attempt."
|
|
|
|
rm -f $CPPL.db-$TimeStamp
|
|
|
|
WriteLog "Import - Import: $Input - FAIL"
|
|
continue
|
|
fi
|
|
|
|
# Import successful; switch to new DB
|
|
Output "PMS main database is OK. Making imported database active"
|
|
WriteLog "Import - Import: Making imported database active"
|
|
|
|
# Move from tmp to active
|
|
mv $CPPL.db-$TimeStamp $CPPL.db
|
|
|
|
# We were successful
|
|
Output "Viewstate import successful."
|
|
WriteLog "Import - Import: $Input - PASS"
|
|
|
|
# We were successful
|
|
SetLast "Import" "$TimeStamp"
|
|
continue
|
|
|
|
# 8. - Show Logfile
|
|
elif [ $Choice -eq 8 ]; then
|
|
|
|
echo ==================================================================================
|
|
cat "$LOGFILE"
|
|
echo ==================================================================================
|
|
|
|
# 9. - Exit
|
|
elif [ $Choice -eq 9 ]; then
|
|
|
|
# Ask questions on graceful exit
|
|
if [ $Exit -eq 0 ]; then
|
|
# Ask if the user wants to remove the DBTMP directory and all backups thus far
|
|
if ConfirmYesNo "Ok to remove temporary databases/workfiles for this session?" ; then
|
|
|
|
# Here it goes
|
|
Output "Deleting all temporary work files."
|
|
WriteLog "Exit - Delete temp files."
|
|
rm -rf "$TMPDIR"
|
|
else
|
|
Output "Retaining all temporary work files."
|
|
WriteLog "Exit - Retain temp files."
|
|
fi
|
|
else
|
|
Output "Unexpected exit command. Keeping all temporary work files."
|
|
WriteLog "EOFExit - Retain temp files."
|
|
fi
|
|
|
|
WriteLog "Session end."
|
|
WriteLog "============================================================"
|
|
exit 0
|
|
fi
|
|
done
|
|
exit 0
|