From ba4474ed0661c74b0a5d35130da467daa0da9734 Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Mon, 7 Nov 2022 18:52:12 -0500 Subject: [PATCH 1/7] Import viewstate (watch history) from another database. Viewstate import - Development complete Developer initial testing complete. 1. Copy DB from Syno to Linux workstation 2. Setup empty PMS on Linux workstation 3. Add library section 4. Observe media all unwatched 5. import the DS418's database 6. Verify on Linux workstation -- all titles now marked played --- DBRepair.sh | 78 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/DBRepair.sh b/DBRepair.sh index 97754f1..731819d 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -338,7 +338,7 @@ HostConfig() { cat override.conf local.conf *.conf 2>/dev/null | grep "APPLICATION_SUPPORT_DIR" | head -1)" if [ "$NewSuppDir" != "" ]; then - NewSuppDir="$(sed -e 's/.*_DIR=//' | tr -d '"' | tr -d "'")" + NewSuppDir="$(echo $NewSuppDir | sed -e 's/.*_DIR=//' | tr -d '"' | tr -d "'")" if [ -d "$NewSuppDir" ]; then AppSuppDir="$NewSuppDir" @@ -520,8 +520,9 @@ do 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. Show logfile" - echo " 8. Exit" + echo " 7. Import Viewstate / Watch history from another PMS database" + echo " 8. Show logfile" + echo " 9. Exit" echo " " echo -n "Enter choice: " if [ "$1" != "" ]; then @@ -542,6 +543,8 @@ do [ "$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 @@ -899,7 +902,7 @@ do Dates=$(GetDates) # If no backups, error and exit - if [ "$Dates" == "" ] && [ $Damaged -eq 1 ]; then + 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" @@ -1050,20 +1053,79 @@ do WriteLog "Undo - Nothing to Undo." fi - # 7. - Show Logfile + # 7. - Get Viewstate/Watch history from another DB and import elif [ $Choice -eq 7 ]; then + echo -n "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 + + # Confirm our databases are intact + if ! CheckDatabases; then + Output "Error: PMS databases are damaged. Repair needed. Refusing to import." + continue + fi + + # Check the given database + if ! CheckDB "$Input" 2>1 >/dev/null; then + Output "Error: Given database is damaged. Repair needed. Database not trusted. Refusing to import." + continue + fi + + # Export viewstate from DB + Output "Exporting Viewstate / Watch history" + echo ".dump metadata_item_settings" | "$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" | cut -d " " -f 1) -lt 1 ]; then + Output "No viewstates found to import." + continue + fi + + # Make a working copy to import into + Output "Making backup copy of main database" + cp -p $CPPL.db "$TMPDIR/Viewstate.db-$TimeStamp" + + # Import viewstates into working copy + Output "Importing Viewstate data" + "$PLEX_SQLITE" $CPPL.db < "$TMPDIR/Viewstate.sql-$TimeStamp" + Result=$? + + # Make certain the resultant DB is OK + Output "Checking database following import" + if CheckDB $CPPL.db ; then + Output "Viewstate import successful." + WriteLog " Import - Import: $Input - PASS" + else + Output "Error $Result during import. Reverting to previous state." + Output " Viewstate history not imported." + mv -f "$TMPDIR/Viewstate.db-$TimeStamp" $CPPL.db + WriteLog " Import - Import: $Input - FAIL" + continue + fi + + # 8. - Show Logfile + elif [ $Choice -eq 8 ]; then + echo ================================================================================== cat "$LOGFILE" echo ================================================================================== - # 8. - Exit - elif [ $Choice -eq 8 ]; then + # 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 work files for this session?" ; then + if ConfirmYesNo "Ok to remove temporary databases/workfiles for this session?" ; then # Here it goes Output "Deleting all temporary work files." From 580ec279865eee4f8b4247a31c160b11b73da698 Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Tue, 8 Nov 2022 11:19:31 -0500 Subject: [PATCH 2/7] Replaced 'echo -n' with posix printf. --- DBRepair.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DBRepair.sh b/DBRepair.sh index 731819d..8965325 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -186,7 +186,7 @@ ConfirmYesNo() { Answer="" while [ "$Answer" = "" ] do - echo -n "$1 (Y/N) ? " + printf "$1 (Y/N) ? " read Input # EOF = No @@ -209,7 +209,7 @@ ConfirmYesNo() { Answer="" while [ "$Answer" = "" ] do - echo -n "Are you sure (Y/N) ? " + printf "Are you sure (Y/N) ? " read Input # EOF = No @@ -524,7 +524,7 @@ do echo " 8. Show logfile" echo " 9. Exit" echo " " - echo -n "Enter choice: " + printf "Enter choice: " if [ "$1" != "" ]; then Input="$1" echo "$1" @@ -746,7 +746,7 @@ do Owner="$(stat -c '%u:%g' $CPPL.db)" # Attempt to export main db to SQL file (Step 1) - echo -n 'Export: (main)..' + printf 'Export: (main)..' "$PLEX_SQLITE" $CPPL.db ".output '$TMPDIR/library.plexapp.sql-$TimeStamp'" .dump Result=$? if ! SQLiteOK $Result; then @@ -760,7 +760,7 @@ do fi # Attempt to export blobs db to SQL file - echo -n '(blobs)..' + printf '(blobs)..' "$PLEX_SQLITE" $CPPL.blobs.db ".output '$TMPDIR/blobs.plexapp.sql-$TimeStamp'" .dump Result=$? if ! SQLiteOK $Result; then @@ -787,7 +787,7 @@ do WriteLog "Repair - Export databases - PASS" # Library and blobs successfully exported, create new - echo -n 'Import: (main)..' + printf 'Import: (main)..' "$PLEX_SQLITE" $CPPL.db-$TimeStamp < "$TMPDIR/library.plexapp.sql-$TimeStamp" Result=$? if ! SQLiteOK $Result; then @@ -798,7 +798,7 @@ do continue fi - echo -n '(blobs)..' + printf '(blobs)..' "$PLEX_SQLITE" $CPPL.blobs.db-$TimeStamp < "$TMPDIR/blobs.plexapp.sql-$TimeStamp" Result=$? if ! SQLiteOK $Result ; then @@ -1075,7 +1075,7 @@ do fi # Check the given database - if ! CheckDB "$Input" 2>1 >/dev/null; then + if ! CheckDB "$Input"; then Output "Error: Given database is damaged. Repair needed. Database not trusted. Refusing to import." continue fi From 303cde633d30a57fd069bfa08d3b1e81711572d7 Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Wed, 9 Nov 2022 21:33:07 -0500 Subject: [PATCH 3/7] Timestamp changed, Add Undo to new code 1. To increase portability, changed the ':' in timestamo to '.' (MacOS problems) 2. Completed adding WriteLog and logic to support UNDO for importing Viewstate --- DBRepair.sh | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/DBRepair.sh b/DBRepair.sh index 8965325..8423463 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -548,7 +548,7 @@ do [ "$Choice" -eq 0 ] && echo " " && echo "'$Input' - Is invalid. Try again" # Update timestamp - TimeStamp="$(date "+%Y-%m-%d_%H:%M:%S")" + TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")" done # Spacing for legibility @@ -1068,18 +1068,34 @@ do continue fi + WriteLog "Import - Attempting to import watch history from '$Input' " + # Confirm our databases are intact if ! CheckDatabases; then Output "Error: PMS databases are damaged. Repair needed. Refusing to import." + WriteLog "Import - Verify main database - FAIL" continue fi # Check the given database if ! CheckDB "$Input"; then Output "Error: Given database is damaged. Repair needed. Database not trusted. Refusing to import." + WriteLog "Import - Verify '$Input' - FAIL" continue fi + # Make a backup + Output "Backing up databases" + if ! MakeBackups "Import "; then + Output "Error making backups. Cannot continue." + WriteLog "Import - MakeBackups - FAIL" + Fail=1 + continue + else + WriteLog "Import - MakeBackups - PASS" + fi + + # Export viewstate from DB Output "Exporting Viewstate / Watch history" echo ".dump metadata_item_settings" | "$PLEX_SQLITE" "$Input" | grep -v TABLE | grep -v INDEX > "$TMPDIR/Viewstate.sql-$TimeStamp" @@ -1101,17 +1117,24 @@ do # Make certain the resultant DB is OK Output "Checking database following import" - if CheckDB $CPPL.db ; then - Output "Viewstate import successful." - WriteLog " Import - Import: $Input - PASS" - else - Output "Error $Result during import. Reverting to previous state." - Output " Viewstate history not imported." - mv -f "$TMPDIR/Viewstate.db-$TimeStamp" $CPPL.db - WriteLog " Import - Import: $Input - FAIL" + if ! CheckDB $CPPL.db ; then + + Output "Error $Result during import. Import corrupted database." + Output " Undoing viewstate import." + + RestoreSaved "$LastTimestamp" + WriteLog "Import - Import: $Input - FAIL" continue fi + # We were successful + Output "Viewstate import successful." + WriteLog "Import - Import: $Input - PASS" + + # We were successful + SetLast "Import" "$TimeStamp" + + # 8. - Show Logfile elif [ $Choice -eq 8 ]; then From f45227abc482899a619730efc38ce67532ec1b26 Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Wed, 9 Nov 2022 21:38:24 -0500 Subject: [PATCH 4/7] Change 'cut' back to awk --- DBRepair.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DBRepair.sh b/DBRepair.sh index 8423463..d6fc7f4 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -1101,7 +1101,7 @@ do echo ".dump metadata_item_settings" | "$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" | cut -d " " -f 1) -lt 1 ]; then + if [ $(wc -l "$TMPDIR/Viewstate.sql-$TimeStamp" | awk '{print $1}') -lt 1 ]; then Output "No viewstates found to import." continue fi From aa296cf52dc0f203227f8621b9182cee3aac7296 Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Fri, 11 Nov 2022 13:57:15 -0500 Subject: [PATCH 5/7] use printf in new code. Reapply timestamp change --- DBRepair.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DBRepair.sh b/DBRepair.sh index d6fc7f4..d58f867 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -440,7 +440,7 @@ SetLast() { CPPL=com.plexapp.plugins.library # Initial timestamp -TimeStamp="$(date "+%Y-%m-%d_%H:%M:%S")" +TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")" # Initialize LastName LastTimestamp SetLast "" "" @@ -1056,7 +1056,7 @@ do # 7. - Get Viewstate/Watch history from another DB and import elif [ $Choice -eq 7 ]; then - echo -n "Pathname of database containing watch history to import: " + printf "Pathname of database containing watch history to import: " read Input # Did we get something? From b645e0f2059d261b09b1d17cfbdebe488d75c1f1 Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Sat, 12 Nov 2022 01:17:53 -0500 Subject: [PATCH 6/7] Viewstate import - Improve error checking and recovery --- DBRepair.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/DBRepair.sh b/DBRepair.sh index d58f867..f5f43f2 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -1112,17 +1112,16 @@ do # Import viewstates into working copy Output "Importing Viewstate data" - "$PLEX_SQLITE" $CPPL.db < "$TMPDIR/Viewstate.sql-$TimeStamp" - Result=$? + "$PLEX_SQLITE" $CPPL.db < "$TMPDIR/Viewstate.sql-$TimeStamp 2> /dev/null" # Make certain the resultant DB is OK Output "Checking database following import" - if ! CheckDB $CPPL.db ; then + if ! CheckDB $CPPL.db ; then Output "Error $Result during import. Import corrupted database." Output " Undoing viewstate import." - RestoreSaved "$LastTimestamp" + cp -p "$TMPDIR/Viewstate.db-$TimeStamp" $CPPL.db WriteLog "Import - Import: $Input - FAIL" continue fi From e30053be35eceaa0b699d23151a444448003414c Mon Sep 17 00:00:00 2001 From: ChuckPa Date: Sat, 12 Nov 2022 23:01:40 -0500 Subject: [PATCH 7/7] Fix misplaced quote --- DBRepair.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DBRepair.sh b/DBRepair.sh index f5f43f2..9b285d3 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -1112,7 +1112,7 @@ do # Import viewstates into working copy Output "Importing Viewstate data" - "$PLEX_SQLITE" $CPPL.db < "$TMPDIR/Viewstate.sql-$TimeStamp 2> /dev/null" + "$PLEX_SQLITE" $CPPL.db < "$TMPDIR/Viewstate.sql-$TimeStamp" 2> /dev/null # Make certain the resultant DB is OK Output "Checking database following import"