fix: enhance database script with improved permission handling and error checks

- Added permission setting for backup and temporary database files to ensure proper access.
- Implemented checks for file readability and ownership adjustments to enhance robustness.
- Included detailed SQL commands to fix internationalization data in the database, improving data integrity.
This commit is contained in:
Hördle Bot
2025-12-01 17:06:07 +01:00
parent a80c14223b
commit a503edb220
3 changed files with 226 additions and 3 deletions

83
FIX_I18N.md Normal file
View File

@@ -0,0 +1,83 @@
# Fix für i18n-Daten (String → JSON Konvertierung)
## Problem
Die Datenbank hat Genre-/Special-/News-Namen als einfache Strings (`"Rock"`) statt JSON (`{"de": "Rock", "en": "Rock"}`) gespeichert, was zu `SyntaxError: "Rock" is not valid JSON` führt.
## Lösung: Manuell ausführen
Führe diese Befehle **direkt auf dem Server** aus:
```bash
cd ~/hoerdle
# 1. Backup erstellen
docker cp hoerdle:/app/data/prod.db ./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)
# 2. Kopiere DB lokal
docker cp hoerdle:/app/data/prod.db ./data/prod.db.tmp
# 3. Setze Berechtigungen
sudo chmod 666 ./data/prod.db.tmp
sudo chmod 775 ./data
# 4. Prüfe ob sqlite3 installiert ist
which sqlite3 || sudo apt-get install -y sqlite3
# 5. Fixe die Datenbank (kopiere diesen Block komplett)
sqlite3 ./data/prod.db.tmp << 'EOF'
UPDATE Genre SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
UPDATE Genre SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
UPDATE Special SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
UPDATE Special SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
UPDATE News SET title = json_object('de', title, 'en', title) WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
UPDATE News SET content = json_object('de', content, 'en', content) WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
SELECT '✅ Fertig!' as status;
EOF
# 6. Kopiere zurück
docker cp ./data/prod.db.tmp hoerdle:/app/data/prod.db
# 7. Aufräumen
rm ./data/prod.db.tmp
# 8. Container neu starten
docker compose restart hoerdle
# 9. Logs prüfen
docker logs hoerdle --tail=50
```
Falls Schritt 5 mit "permission denied" fehlschlägt, verwende `sudo`:
```bash
sudo sqlite3 ./data/prod.db.tmp << 'EOF'
[... SQL-Befehle wie oben ...]
EOF
```
## Automatisiertes Skript
Alternativ kannst du das automatische Skript verwenden:
```bash
./scripts/fix-i18n-easy.sh
```
Oder das lokale Skript:
```bash
./scripts/fix-i18n-local.sh
```
## Prüfen ob es funktioniert hat
Nach dem Neustart sollte die Seite wieder funktionieren:
```bash
# Prüfe Logs (sollte keine JSON-Fehler mehr zeigen)
docker logs hoerdle --tail=100 | grep -i "json\|error" || echo "✅ Keine JSON-Fehler gefunden"
# Teste die Seite
curl -s https://hoerdle.de/de | head -20
```

87
scripts/fix-i18n-easy.sh Executable file
View File

@@ -0,0 +1,87 @@
#!/bin/bash
# Einfaches Fix-Skript für i18n-Daten
set -e
echo "🔧 Fixe i18n-Daten..."
echo ""
# Prüfe ob Container läuft
if ! docker ps | grep -q hoerdle; then
echo "❌ Container 'hoerdle' läuft nicht!"
exit 1
fi
# Backup
BACKUP_FILE="./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)"
echo "💾 Erstelle Backup..."
docker cp hoerdle:/app/data/prod.db "$BACKUP_FILE" || {
echo "❌ Backup fehlgeschlagen!"
exit 1
}
echo "✅ Backup: $BACKUP_FILE"
echo ""
# Kopiere DB
echo "📥 Kopiere Datenbank lokal..."
DB_TMP="./data/prod.db.tmp"
docker cp hoerdle:/app/data/prod.db "$DB_TMP"
echo "✅ Datenbank kopiert"
echo ""
# Setze Berechtigungen
echo "🔐 Setze Berechtigungen..."
sudo chmod 666 "$DB_TMP" 2>/dev/null || chmod 666 "$DB_TMP" || {
echo "⚠️ Konnte Berechtigungen nicht setzen"
}
sudo chmod 775 ./data 2>/dev/null || chmod 775 ./data || true
echo ""
# Prüfe sqlite3
if ! command -v sqlite3 &> /dev/null; then
echo "❌ sqlite3 nicht gefunden! Installiere es:"
echo " sudo apt-get update && sudo apt-get install -y sqlite3"
exit 1
fi
# Fixe DB
echo "🔧 Führe SQL-Updates aus..."
sqlite3 "$DB_TMP" << 'SQL' || {
echo "⚠️ Normale Ausführung fehlgeschlagen, versuche mit sudo..."
sudo sqlite3 "$DB_TMP" << 'SQL2'
UPDATE Genre SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
UPDATE Genre SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
UPDATE Special SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
UPDATE Special SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
UPDATE News SET title = json_object('de', title, 'en', title) WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
UPDATE News SET content = json_object('de', content, 'en', content) WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
SQL2
}
UPDATE Genre SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
UPDATE Genre SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
UPDATE Special SET name = json_object('de', name, 'en', name) WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
UPDATE Special SET subtitle = json_object('de', subtitle, 'en', subtitle) WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
UPDATE News SET title = json_object('de', title, 'en', title) WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
UPDATE News SET content = json_object('de', content, 'en', content) WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
SELECT '✅ Fertig!' as status;
SQL
echo ""
echo "✅ Datenbank gefixt"
echo ""
# Kopiere zurück
echo "📤 Kopiere Datenbank zurück..."
docker cp "$DB_TMP" hoerdle:/app/data/prod.db
echo "✅ Zurück kopiert"
echo ""
# Aufräumen
rm -f "$DB_TMP"
echo "🔄 Starte Container neu..."
docker compose restart hoerdle
echo ""
echo "✅ Fertig! Prüfe Logs: docker logs hoerdle --tail=50"

View File

@@ -16,12 +16,20 @@ fi
BACKUP_FILE="./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)"
echo "💾 Erstelle Backup..."
docker cp hoerdle:/app/data/prod.db "$BACKUP_FILE"
# Setze Berechtigungen (kann root gehören)
sudo chmod 666 "$BACKUP_FILE" 2>/dev/null || chmod 666 "$BACKUP_FILE" 2>/dev/null || true
echo "✅ Backup erstellt: $BACKUP_FILE"
echo ""
# Kopiere DB lokal
echo "📥 Kopiere Datenbank lokal..."
docker cp hoerdle:/app/data/prod.db ./data/prod.db.tmp
# Setze Berechtigungen (Datei kann root gehören)
sudo chmod 666 ./data/prod.db.tmp 2>/dev/null || chmod 666 ./data/prod.db.tmp 2>/dev/null || {
echo "⚠️ Konnte Berechtigungen nicht setzen. Versuche mit sudo..."
sudo chmod 666 ./data/prod.db.tmp
}
chmod 775 ./data 2>/dev/null || sudo chmod 775 ./data 2>/dev/null || true
echo "✅ Datenbank kopiert"
echo ""
@@ -34,10 +42,18 @@ fi
# Fixe die Datenbank
echo "🔧 Fixe i18n-Daten..."
sqlite3 ./data/prod.db.tmp << 'SQL'
-- Backup innerhalb der DB
.backup ./data/prod.db.tmp.backup
# Stelle sicher, dass wir Schreibrechte haben (auch für WAL-Dateien)
chmod 666 ./data/prod.db.tmp 2>/dev/null || sudo chmod 666 ./data/prod.db.tmp
chmod 775 ./data 2>/dev/null || sudo chmod 775 ./data
# Prüfe ob wir die Datei lesen können
if [ ! -r "./data/prod.db.tmp" ]; then
echo "❌ Kann Datenbankdatei nicht lesen. Setze Besitzer..."
sudo chown $(whoami):$(whoami) ./data/prod.db.tmp || true
fi
# Führe SQL-Befehle aus (mit sudo falls nötig)
if [ -r "./data/prod.db.tmp" ] && [ -w "./data" ]; then
sqlite3 ./data/prod.db.tmp << 'SQL'
-- Fix Genre.name
UPDATE Genre
SET name = json_object('de', name, 'en', name)
@@ -70,6 +86,43 @@ WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
SELECT '✅ Alle i18n-Daten wurden gefixt!' as status;
SQL
else
echo "❌ Kann Datenbankdatei nicht lesen oder schreiben!"
echo " Versuche mit sudo..."
sudo sqlite3 ./data/prod.db.tmp << 'SQL'
-- Fix Genre.name
UPDATE Genre
SET name = json_object('de', name, 'en', name)
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
-- Fix Genre.subtitle
UPDATE Genre
SET subtitle = json_object('de', subtitle, 'en', subtitle)
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
-- Fix Special.name
UPDATE Special
SET name = json_object('de', name, 'en', name)
WHERE typeof(name) = 'text' AND name NOT LIKE '{%';
-- Fix Special.subtitle
UPDATE Special
SET subtitle = json_object('de', subtitle, 'en', subtitle)
WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%';
-- Fix News.title
UPDATE News
SET title = json_object('de', title, 'en', title)
WHERE typeof(title) = 'text' AND title NOT LIKE '{%';
-- Fix News.content
UPDATE News
SET content = json_object('de', content, 'en', content)
WHERE typeof(content) = 'text' AND content NOT LIKE '{%';
SELECT '✅ Alle i18n-Daten wurden gefixt!' as status;
SQL
fi
if [ $? -ne 0 ]; then
echo "❌ Fehler beim Fixen der Datenbank!"