diff --git a/scripts/backup-database.sh b/scripts/backup-database.sh index eedec3e..c75d533 100755 --- a/scripts/backup-database.sh +++ b/scripts/backup-database.sh @@ -73,6 +73,24 @@ POSTGRES_USER="${POSTGRES_USER:-translate}" POSTGRES_DB="${POSTGRES_DB:-translate_db}" POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-}" +# Resolve Python command for SQLite backups +PYTHON_CMD="python" +if [ -f "${SCRIPT_DIR}/../.venv/bin/python" ]; then + PYTHON_CMD="${SCRIPT_DIR}/../.venv/bin/python" +elif [ -f "${SCRIPT_DIR}/../.venv/Scripts/python" ]; then + PYTHON_CMD="${SCRIPT_DIR}/../.venv/Scripts/python" +elif [ -f "${SCRIPT_DIR}/../.venv/Scripts/python.exe" ]; then + PYTHON_CMD="${SCRIPT_DIR}/../.venv/Scripts/python.exe" +elif command -v python3 &>/dev/null; then + PYTHON_CMD="python3" +elif command -v python &>/dev/null; then + PYTHON_CMD="python" +elif command -v py &>/dev/null; then + PYTHON_CMD="py" +else + log_warning "Could not find a Python installation on PATH or in .venv. SQLite backups may fail." +fi + # ============================================================================== # 2. VALIDATION AND PREPARATION # ============================================================================== @@ -151,19 +169,27 @@ create_backup() { # Safe online backup using Python local temp_db="${BACKUP_DIR}/daily/temp_${TIMESTAMP}.db" - if ! python -c " -import sqlite3, sys + if ! "${PYTHON_CMD}" -c " +import sqlite3, sys, os, re try: - src = sqlite3.connect(r'${SQLITE_PATH}') - dst = sqlite3.connect(r'${temp_db}') + src_raw, dst_raw = sys.argv[1], sys.argv[2] + if sys.platform == 'win32': + m_src = re.match(r'^/(?:mnt/)?([a-zA-Z])/(.*)', src_raw) + if m_src: + src_raw = m_src.group(1) + ':/' + m_src.group(2) + m_dst = re.match(r'^/(?:mnt/)?([a-zA-Z])/(.*)', dst_raw) + if m_dst: + dst_raw = m_dst.group(1) + ':/' + m_dst.group(2) + src = sqlite3.connect(os.path.abspath(src_raw)) + dst = sqlite3.connect(os.path.abspath(dst_raw)) with dst: src.backup(dst) src.close() dst.close() except Exception as e: - print(e, file=sys.stderr) + print(f'Python SQLite error: {e}', file=sys.stderr) sys.exit(1) -" 2>/dev/null; then +" "${SQLITE_PATH}" "${temp_db}"; then log_error "SQLite online backup failed! Checking if DB is locked." send_notification "Wordly DB Backup FAILED: SQLite online backup script error." exit 1 @@ -348,19 +374,27 @@ restore_backup() { gunzip -c "${archive_path}" > "${temp_restore_db}" # Overwrite database safely using Python (ensures open handles or locks are respected) - if ! python -c " -import sqlite3, sys + if ! "${PYTHON_CMD}" -c " +import sqlite3, sys, os, re try: - src = sqlite3.connect(r'${temp_restore_db}') - dst = sqlite3.connect(r'${SQLITE_PATH}') + src_raw, dst_raw = sys.argv[1], sys.argv[2] + if sys.platform == 'win32': + m_src = re.match(r'^/(?:mnt/)?([a-zA-Z])/(.*)', src_raw) + if m_src: + src_raw = m_src.group(1) + ':/' + m_src.group(2) + m_dst = re.match(r'^/(?:mnt/)?([a-zA-Z])/(.*)', dst_raw) + if m_dst: + dst_raw = m_dst.group(1) + ':/' + m_dst.group(2) + src = sqlite3.connect(os.path.abspath(src_raw)) + dst = sqlite3.connect(os.path.abspath(dst_raw)) with dst: src.backup(dst) src.close() dst.close() except Exception as e: - print(e, file=sys.stderr) + print(f'Python SQLite restore error: {e}', file=sys.stderr) sys.exit(1) -" 2>/dev/null; then +" "${temp_restore_db}" "${SQLITE_PATH}"; then log_error "SQLite restore swap operation failed!" rm -f "${temp_restore_db}" exit 1