mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 01:10:12 -08:00
feat: Add cleanup script for temporary and corrupted Plex database files
This commit is contained in:
@@ -307,6 +307,36 @@ $ ./check-plex-builtin-backups.sh
|
|||||||
./plex-recent-additions.sh # Generate recent additions report
|
./plex-recent-additions.sh # Generate recent additions report
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `cleanup-plex-databases.sh` ⭐ **NEW**
|
||||||
|
**Safe cleanup of temporary and corrupted database files**
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Removes temporary files, recovery files, and corrupted directories
|
||||||
|
- Preserves active databases and legitimate backups
|
||||||
|
- Dry-run mode for safe preview
|
||||||
|
- Comprehensive safety checks and validation
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
./cleanup-plex-databases.sh --dry-run # Preview what will be removed
|
||||||
|
sudo ./cleanup-plex-databases.sh # Perform actual cleanup
|
||||||
|
./cleanup-plex-databases.sh --help # Show all options
|
||||||
|
```
|
||||||
|
|
||||||
|
**What it removes:**
|
||||||
|
- Temporary files (`*-tmp`, `*-2025-*-tmp`)
|
||||||
|
- MD5 checksum files (`*.md5`)
|
||||||
|
- Recovery files (`*recovery*`)
|
||||||
|
- Repaired files (`*repaired*`)
|
||||||
|
- Empty backup files (`*empty-backup*`)
|
||||||
|
- Repair log files (`DBRepair.log`)
|
||||||
|
- Corrupted database directories (`corrupted-*`)
|
||||||
|
|
||||||
|
**What it preserves:**
|
||||||
|
- Active database files (`*.db`, `*.db-shm`, `*.db-wal`)
|
||||||
|
- Plex built-in backups (`*.backup.*`)
|
||||||
|
- Historical dated backups (`*.db.YYYYMMDD`)
|
||||||
|
- EPG databases (`tv.plex.providers.epg.cloud-*.db`)
|
||||||
### 🧪 Testing & Integration
|
### 🧪 Testing & Integration
|
||||||
|
|
||||||
#### `test-plex-backup.sh`
|
#### `test-plex-backup.sh`
|
||||||
|
|||||||
310
plex/cleanup-plex-databases.sh
Executable file
310
plex/cleanup-plex-databases.sh
Executable file
@@ -0,0 +1,310 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Plex Database Directory Cleanup Script
|
||||||
|
# Author: Peter Wood <peter@peterwood.dev>
|
||||||
|
# Created: June 21, 2025
|
||||||
|
#
|
||||||
|
# This script safely removes temporary, recovery, and corrupted files
|
||||||
|
# from the Plex databases directory while preserving active databases
|
||||||
|
# and legitimate Plex built-in backups.
|
||||||
|
|
||||||
|
# Don't exit on errors, we want to continue processing all files
|
||||||
|
set +e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
PLEX_DB_DIR="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases"
|
||||||
|
DRY_RUN=false
|
||||||
|
VERBOSE=false
|
||||||
|
|
||||||
|
# Usage function
|
||||||
|
show_usage() {
|
||||||
|
cat << EOF
|
||||||
|
Usage: $0 [OPTIONS]
|
||||||
|
|
||||||
|
Clean up temporary, recovery, and corrupted files from Plex databases directory.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--dry-run Show what would be removed without actually removing
|
||||||
|
--verbose Show detailed output
|
||||||
|
--help Show this help message
|
||||||
|
|
||||||
|
DESCRIPTION:
|
||||||
|
This script removes:
|
||||||
|
- Temporary files (*-tmp, *-2025-*-tmp)
|
||||||
|
- MD5 checksum files (*.md5)
|
||||||
|
- Recovery files (*recovery*)
|
||||||
|
- Repaired files (*repaired*)
|
||||||
|
- Empty backup files (*empty-backup*)
|
||||||
|
- DBRepair.log files
|
||||||
|
- Corrupted database directories (corrupted-*)
|
||||||
|
|
||||||
|
This script preserves:
|
||||||
|
- Active database files (*.db, *.db-shm, *.db-wal)
|
||||||
|
- Plex built-in backups (*.backup.*)
|
||||||
|
- Legitimate dated backups (*.db.YYYYMMDD)
|
||||||
|
- EPG databases (tv.plex.providers.epg.cloud-*.db)
|
||||||
|
|
||||||
|
EXAMPLES:
|
||||||
|
$0 --dry-run # Preview what would be removed
|
||||||
|
$0 --verbose # Remove files with detailed output
|
||||||
|
sudo $0 # Remove files (requires root for some files)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse command line arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--dry-run)
|
||||||
|
DRY_RUN=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--verbose)
|
||||||
|
VERBOSE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--help)
|
||||||
|
show_usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${RED}Error: Unknown option '$1'${NC}"
|
||||||
|
show_usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Function to log messages
|
||||||
|
log_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_verbose() {
|
||||||
|
if [[ "$VERBOSE" == "true" ]]; then
|
||||||
|
echo -e "${BLUE}[VERBOSE]${NC} $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to safely remove files/directories
|
||||||
|
safe_remove() {
|
||||||
|
local item="$1"
|
||||||
|
local item_type="$2" # "file" or "directory"
|
||||||
|
|
||||||
|
if [[ ! -e "$item" ]]; then
|
||||||
|
log_verbose "Skipping $item (does not exist)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo -e "${YELLOW}[DRY-RUN]${NC} Would remove $item_type: $(basename "$item")"
|
||||||
|
if [[ "$item_type" == "directory" ]]; then
|
||||||
|
echo -e "${YELLOW} ${NC} Contents: $(ls -la "$item" 2>/dev/null | wc -l) items"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW} ${NC} Size: $(ls -lah "$item" 2>/dev/null | awk '{print $5}')"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_verbose "Removing $item_type: $(basename "$item")"
|
||||||
|
if [[ "$item_type" == "directory" ]]; then
|
||||||
|
if rm -rf "$item" 2>/dev/null; then
|
||||||
|
log_success "Removed directory: $(basename "$item")"
|
||||||
|
else
|
||||||
|
log_error "Failed to remove directory: $(basename "$item")"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if rm -f "$item" 2>/dev/null; then
|
||||||
|
log_success "Removed file: $(basename "$item")"
|
||||||
|
else
|
||||||
|
log_error "Failed to remove file: $(basename "$item")"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main cleanup function
|
||||||
|
cleanup_databases() {
|
||||||
|
log_info "Starting Plex database directory cleanup..."
|
||||||
|
|
||||||
|
if [[ ! -d "$PLEX_DB_DIR" ]]; then
|
||||||
|
log_error "Plex databases directory not found: $PLEX_DB_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$PLEX_DB_DIR" || {
|
||||||
|
log_error "Cannot access Plex databases directory: $PLEX_DB_DIR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
local files_removed=0
|
||||||
|
local dirs_removed=0
|
||||||
|
local total_size_removed=0
|
||||||
|
|
||||||
|
log_info "Scanning directory: $PLEX_DB_DIR"
|
||||||
|
|
||||||
|
# Remove temporary files
|
||||||
|
log_info "Cleaning up temporary files..."
|
||||||
|
for file in *-tmp *-2025-*-tmp; do
|
||||||
|
if [[ -f "$file" && "$file" != "*-tmp" && "$file" != "*-2025-*-tmp" ]]; then
|
||||||
|
safe_remove "$file" "file"
|
||||||
|
((files_removed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove MD5 checksum files
|
||||||
|
log_info "Cleaning up MD5 checksum files..."
|
||||||
|
for file in *.md5; do
|
||||||
|
if [[ -f "$file" && "$file" != "*.md5" ]]; then
|
||||||
|
safe_remove "$file" "file"
|
||||||
|
((files_removed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove recovery files
|
||||||
|
log_info "Cleaning up recovery files..."
|
||||||
|
for file in *recovery*; do
|
||||||
|
if [[ -f "$file" && "$file" != "*recovery*" ]]; then
|
||||||
|
safe_remove "$file" "file"
|
||||||
|
((files_removed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove repaired files
|
||||||
|
log_info "Cleaning up repaired files..."
|
||||||
|
for file in *repaired*; do
|
||||||
|
if [[ -f "$file" && "$file" != "*repaired*" ]]; then
|
||||||
|
safe_remove "$file" "file"
|
||||||
|
((files_removed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove empty backup files
|
||||||
|
log_info "Cleaning up empty backup files..."
|
||||||
|
for file in *empty-backup*; do
|
||||||
|
if [[ -f "$file" && "$file" != "*empty-backup*" ]]; then
|
||||||
|
safe_remove "$file" "file"
|
||||||
|
((files_removed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove DBRepair.log
|
||||||
|
log_info "Cleaning up repair log files..."
|
||||||
|
if [[ -f "DBRepair.log" ]]; then
|
||||||
|
safe_remove "DBRepair.log" "file"
|
||||||
|
((files_removed++))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove corrupted directories
|
||||||
|
log_info "Cleaning up corrupted database directories..."
|
||||||
|
for dir in corrupted-*; do
|
||||||
|
if [[ -d "$dir" && "$dir" != "corrupted-*" ]]; then
|
||||||
|
safe_remove "$dir" "directory"
|
||||||
|
((dirs_removed++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo
|
||||||
|
log_info "=== Cleanup Summary ==="
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo -e "${YELLOW}[DRY-RUN]${NC} Files that would be removed: $files_removed"
|
||||||
|
echo -e "${YELLOW}[DRY-RUN]${NC} Directories that would be removed: $dirs_removed"
|
||||||
|
else
|
||||||
|
log_success "Files removed: $files_removed"
|
||||||
|
log_success "Directories removed: $dirs_removed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show what remains
|
||||||
|
echo
|
||||||
|
log_info "=== Remaining Files ==="
|
||||||
|
echo -e "${GREEN}Active database files:${NC}"
|
||||||
|
ls -lah *.db *.db-shm *.db-wal 2>/dev/null | grep -E "\.(db|db-shm|db-wal)$" || echo " None found"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}Backup files:${NC}"
|
||||||
|
ls -lah *.backup.* 2>/dev/null || echo " None found"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}Historical backups:${NC}"
|
||||||
|
ls -lah *.db.2[0-9][0-9][0-9][0-9][0-9][0-9][0-9] 2>/dev/null || echo " None found"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${GREEN}Other database files:${NC}"
|
||||||
|
ls -lah tv.plex.providers.*.db 2>/dev/null || echo " None found"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pre-flight checks
|
||||||
|
preflight_checks() {
|
||||||
|
log_info "Performing pre-flight checks..."
|
||||||
|
|
||||||
|
# Check if Plex is running
|
||||||
|
if pgrep -f "Plex Media Server" > /dev/null; then
|
||||||
|
log_warning "Plex Media Server is currently running!"
|
||||||
|
log_warning "For safety, consider stopping Plex before cleanup:"
|
||||||
|
log_warning " sudo systemctl stop plexmediaserver"
|
||||||
|
echo
|
||||||
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
log_info "Cleanup cancelled by user"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check permissions
|
||||||
|
if [[ ! -w "$PLEX_DB_DIR" ]]; then
|
||||||
|
log_warning "You may not have write permissions to the databases directory"
|
||||||
|
log_warning "Consider running with sudo if you encounter permission errors"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check disk space
|
||||||
|
local available_space=$(df -h "$PLEX_DB_DIR" | awk 'NR==2 {print $4}')
|
||||||
|
log_info "Available disk space: $available_space"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
main() {
|
||||||
|
echo -e "${BLUE}+================================================================+${NC}"
|
||||||
|
echo -e "${BLUE}| PLEX DATABASE CLEANUP TOOL |${NC}"
|
||||||
|
echo -e "${BLUE}+================================================================+${NC}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
log_warning "DRY-RUN MODE: No files will actually be removed"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
preflight_checks
|
||||||
|
cleanup_databases
|
||||||
|
|
||||||
|
echo
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
log_info "Dry-run completed. Run without --dry-run to actually remove files."
|
||||||
|
else
|
||||||
|
log_success "Database cleanup completed successfully!"
|
||||||
|
log_info "You can now restart Plex Media Server if it was stopped."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute main function
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user