initial
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================
|
||||
# install.sh — OpenClaw mailbox.org Kalender + Aufgaben
|
||||
# Zielplattform: Raspberry Pi (Raspberry Pi OS / Ubuntu ARM)
|
||||
# Ausführen als: pi-Nutzer (sudo-Rechte erforderlich)
|
||||
# =============================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
ENV_FILE="$REPO_ROOT/.env"
|
||||
|
||||
# --- Farben ---
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
|
||||
|
||||
# =============================================================
|
||||
# 1. .env laden
|
||||
# =============================================================
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
warn ".env nicht gefunden — kopiere .env.example nach .env"
|
||||
cp "$REPO_ROOT/assets/.env.example" "$ENV_FILE"
|
||||
error "Bitte .env mit deinen mailbox.org-Zugangsdaten befüllen und install.sh erneut ausführen."
|
||||
fi
|
||||
# shellcheck source=/dev/null
|
||||
# set -a exportiert alle Variablen; $HOME wird durch die Shell expandiert
|
||||
set -a
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
info ".env geladen (Benutzer: ${MAILBOX_USER:-NICHT GESETZT})"
|
||||
|
||||
[[ -z "${MAILBOX_USER:-}" ]] && error "MAILBOX_USER in .env nicht gesetzt!"
|
||||
[[ -z "${MAILBOX_PASS:-}" ]] && error "MAILBOX_PASS in .env nicht gesetzt!"
|
||||
|
||||
# @ im URL-Pfad muss als %40 kodiert sein (mailbox.org CalDAV-Anforderung)
|
||||
export MAILBOX_USER_ENCODED="${MAILBOX_USER/@/%40}"
|
||||
info "URL-kodierter Benutzername: ${MAILBOX_USER_ENCODED}"
|
||||
|
||||
# =============================================================
|
||||
# 2. Systempakete installieren
|
||||
# =============================================================
|
||||
info "Installiere Systempakete..."
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
vdirsyncer \
|
||||
khal \
|
||||
todoman \
|
||||
pass \
|
||||
python3-keyring \
|
||||
gettext-base \
|
||||
curl \
|
||||
jq \
|
||||
python3-pip \
|
||||
python3-venv
|
||||
|
||||
# Locale sicherstellen
|
||||
sudo locale-gen de_AT.UTF-8 2>/dev/null || true
|
||||
info "Pakete installiert."
|
||||
|
||||
# =============================================================
|
||||
# 3. Verzeichnisse anlegen
|
||||
# =============================================================
|
||||
info "Lege Verzeichnisse an..."
|
||||
|
||||
VDIR_BASE="${VDIR_BASE_DIR:-$HOME/.local/share/vdirsyncer}"
|
||||
mkdir -p "$VDIR_BASE/status"
|
||||
mkdir -p "$VDIR_BASE/calendars"
|
||||
mkdir -p "$VDIR_BASE/tasks"
|
||||
mkdir -p "${KHAL_DB_PATH:-$HOME/.local/share/khal}"
|
||||
mkdir -p "$HOME/.config/vdirsyncer"
|
||||
mkdir -p "$HOME/.config/khal"
|
||||
mkdir -p "$HOME/.config/todoman"
|
||||
# Log + .env-Zielverzeichnis im Home (kein sudo nötig, passt zu systemd %h-Specifier)
|
||||
mkdir -p "$HOME/.local/share/openclaw-mailbox-cal"
|
||||
mkdir -p "$HOME/.config/openclaw-mailbox-cal"
|
||||
|
||||
# .env auch nach ~/.config/openclaw-mailbox-cal/.env kopieren
|
||||
# (dort erwartet es die systemd EnvironmentFile-Direktive via %h)
|
||||
cp "$ENV_FILE" "$HOME/.config/openclaw-mailbox-cal/.env"
|
||||
chmod 600 "$HOME/.config/openclaw-mailbox-cal/.env"
|
||||
info ".env nach ~/.config/openclaw-mailbox-cal/.env deployt"
|
||||
|
||||
# =============================================================
|
||||
# 4. Konfigurationsdateien deployen (envsubst für Variablen)
|
||||
# =============================================================
|
||||
info "Deploye Konfigurationsdateien..."
|
||||
|
||||
# vdirsyncer config — Variablen ersetzen
|
||||
export MAILBOX_USER MAILBOX_USER_ENCODED MAILBOX_PASS
|
||||
envsubst '${MAILBOX_USER} ${MAILBOX_USER_ENCODED} ${MAILBOX_PASS}' \
|
||||
< "$REPO_ROOT/config/vdirsyncer.conf" \
|
||||
> "$HOME/.config/vdirsyncer/config"
|
||||
chmod 600 "$HOME/.config/vdirsyncer/config"
|
||||
info " → ~/.config/vdirsyncer/config"
|
||||
|
||||
# khal config
|
||||
cp "$REPO_ROOT/config/khal.conf" "$HOME/.config/khal/config"
|
||||
info " → ~/.config/khal/config"
|
||||
|
||||
# todoman config
|
||||
cp "$REPO_ROOT/config/todoman.conf" "$HOME/.config/todoman/config.cfg"
|
||||
info " → ~/.config/todoman/config.cfg"
|
||||
|
||||
# =============================================================
|
||||
# 5. systemd Units installieren (User-Session)
|
||||
# =============================================================
|
||||
info "Installiere systemd Units (User-Session)..."
|
||||
|
||||
SYSTEMD_USER_DIR="$HOME/.config/systemd/user"
|
||||
mkdir -p "$SYSTEMD_USER_DIR"
|
||||
|
||||
# Variablen in systemd-Units ersetzen
|
||||
for unit_file in "$REPO_ROOT/systemd/"*.{service,timer}; do
|
||||
[[ -f "$unit_file" ]] || continue
|
||||
unit_name="$(basename "$unit_file")"
|
||||
envsubst '${SYNC_INTERVAL}' < "$unit_file" > "$SYSTEMD_USER_DIR/$unit_name"
|
||||
info " → $SYSTEMD_USER_DIR/$unit_name"
|
||||
done
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now vdirsyncer-sync.timer
|
||||
info "systemd Timer aktiviert."
|
||||
|
||||
# Lingering aktivieren (damit User-Units ohne Login laufen)
|
||||
loginctl enable-linger "$USER" 2>/dev/null || \
|
||||
warn "loginctl enable-linger fehlgeschlagen — bitte manuell ausführen: sudo loginctl enable-linger $USER"
|
||||
|
||||
# =============================================================
|
||||
# 6. Erst-Synchronisation
|
||||
# =============================================================
|
||||
info "Führe initialen vdirsyncer discover + sync durch..."
|
||||
vdirsyncer discover calendars || warn "discover calendars hatte Warnungen — prüfe Ausgabe"
|
||||
vdirsyncer discover tasks || warn "discover tasks hatte Warnungen — prüfe Ausgabe"
|
||||
vdirsyncer sync || warn "sync hatte Warnungen — prüfe Ausgabe"
|
||||
info "Erst-Sync abgeschlossen."
|
||||
|
||||
# =============================================================
|
||||
# 7. khal-Index aufbauen
|
||||
# =============================================================
|
||||
info "Baue khal-Index auf..."
|
||||
khal --config "$HOME/.config/khal/config" rebuild-cache || true
|
||||
|
||||
# =============================================================
|
||||
# 8. OpenClaw Skill-Verknüpfung
|
||||
# =============================================================
|
||||
OPENCLAW_SKILLS_DIR="${OPENCLAW_SKILLS_DIR:-$HOME/.config/openclaw/skills}"
|
||||
if [[ -d "$OPENCLAW_SKILLS_DIR" ]]; then
|
||||
info "Verknüpfe OpenClaw Skill..."
|
||||
ln -sf "$REPO_ROOT" "$OPENCLAW_SKILLS_DIR/mailbox-cal" 2>/dev/null || true
|
||||
info " → $OPENCLAW_SKILLS_DIR/mailbox-cal"
|
||||
else
|
||||
warn "OpenClaw Skills-Verzeichnis nicht gefunden ($OPENCLAW_SKILLS_DIR)."
|
||||
warn "Bitte Skill manuell in OpenClaw registrieren (siehe README.md)."
|
||||
fi
|
||||
|
||||
# =============================================================
|
||||
# Fertig
|
||||
# =============================================================
|
||||
echo ""
|
||||
echo -e "${GREEN}╔══════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Installation abgeschlossen! ║${NC}"
|
||||
echo -e "${GREEN}╚══════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo " Nächste Schritte:"
|
||||
echo " 1. khal agenda # Termine anzeigen"
|
||||
echo " 2. todo list # Aufgaben anzeigen"
|
||||
echo " 3. systemctl --user status vdirsyncer-sync.timer"
|
||||
echo " 4. tail -f ~/.local/share/openclaw-mailbox-cal/sync.log"
|
||||
echo ""
|
||||
@@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================
|
||||
# test_setup.sh — Überprüft die Installation Schritt für Schritt
|
||||
# Ausführen nach install.sh: bash scripts/test_setup.sh
|
||||
# =============================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Farben
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
ok() { echo -e "${GREEN} [✓] $*${NC}"; }
|
||||
fail() { echo -e "${RED} [✗] $*${NC}"; FAILED=$((FAILED+1)); }
|
||||
info() { echo -e "${CYAN} [i] $*${NC}"; }
|
||||
|
||||
FAILED=0
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
echo -e "${CYAN} OpenClaw mailbox.org Kalender+Aufgaben — Selbsttest${NC}"
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
# --- 1. Binaries vorhanden? ---
|
||||
echo "▶ 1. Programm-Verfügbarkeit"
|
||||
for bin in vdirsyncer khal todo python3; do
|
||||
if command -v "$bin" &>/dev/null; then
|
||||
ok "$bin → $(command -v $bin)"
|
||||
else
|
||||
fail "$bin nicht gefunden — install.sh ausführen"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 2. Konfigurationsdateien ---
|
||||
echo ""
|
||||
echo "▶ 2. Konfigurationsdateien"
|
||||
declare -A CONFIGS=(
|
||||
["vdirsyncer"]="$HOME/.config/vdirsyncer/config"
|
||||
["khal"]="$HOME/.config/khal/config"
|
||||
["todoman"]="$HOME/.config/todoman/config.cfg"
|
||||
)
|
||||
for name in "${!CONFIGS[@]}"; do
|
||||
path="${CONFIGS[$name]}"
|
||||
if [[ -f "$path" ]]; then
|
||||
ok "$name → $path"
|
||||
else
|
||||
fail "$name-Config fehlt: $path"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 3. Berechtigungen vdirsyncer-Config (enthält Passwort) ---
|
||||
echo ""
|
||||
echo "▶ 3. Sicherheit"
|
||||
VDIR_CONF="$HOME/.config/vdirsyncer/config"
|
||||
if [[ -f "$VDIR_CONF" ]]; then
|
||||
PERMS=$(stat -c "%a" "$VDIR_CONF")
|
||||
if [[ "$PERMS" == "600" ]]; then
|
||||
ok "vdirsyncer config Berechtigungen: $PERMS (korrekt)"
|
||||
else
|
||||
fail "vdirsyncer config Berechtigungen: $PERMS (sollte 600 sein) → chmod 600 $VDIR_CONF"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prüfe ob Klartext-Passwort in Config steht
|
||||
if grep -q 'password.*=.*"[^$]' "$VDIR_CONF" 2>/dev/null; then
|
||||
info "Passwort in Plaintext erkannt — Erwäge pass(1) oder python-keyring als Alternative"
|
||||
fi
|
||||
|
||||
# --- 4. Sync-Verzeichnisse ---
|
||||
echo ""
|
||||
echo "▶ 4. Sync-Verzeichnisse"
|
||||
for dir in \
|
||||
"$HOME/.local/share/vdirsyncer/status" \
|
||||
"$HOME/.local/share/vdirsyncer/calendars" \
|
||||
"$HOME/.local/share/vdirsyncer/tasks"; do
|
||||
if [[ -d "$dir" ]]; then
|
||||
COUNT=$(find "$dir" -name "*.ics" 2>/dev/null | wc -l)
|
||||
ok "$dir (${COUNT} .ics Dateien)"
|
||||
else
|
||||
fail "Verzeichnis fehlt: $dir"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 5. vdirsyncer Verbindungstest ---
|
||||
echo ""
|
||||
echo "▶ 5. vdirsyncer — Verbindungstest"
|
||||
|
||||
# Prüfen ob discover bereits gelaufen ist (Status-Dateien vorhanden)
|
||||
STATUS_DIR="$HOME/.local/share/vdirsyncer/status"
|
||||
if [[ -z "$(ls -A "$STATUS_DIR" 2>/dev/null)" ]]; then
|
||||
info "Kein discover-Status gefunden — führe 'vdirsyncer discover' zuerst aus..."
|
||||
if timeout 60 vdirsyncer discover calendars 2>&1 | tail -3 && \
|
||||
timeout 60 vdirsyncer discover tasks 2>&1 | tail -3; then
|
||||
ok "vdirsyncer discover erfolgreich"
|
||||
else
|
||||
fail "vdirsyncer discover fehlgeschlagen — Zugangsdaten und Netzwerk prüfen"
|
||||
fi
|
||||
else
|
||||
info "discover-Status vorhanden — überspringe discover"
|
||||
fi
|
||||
|
||||
info "Führe 'vdirsyncer sync' aus (Timeout: 60s)..."
|
||||
SYNC_OUT=$(timeout 60 vdirsyncer sync 2>&1)
|
||||
SYNC_RC=$?
|
||||
echo "$SYNC_OUT" | tail -8
|
||||
|
||||
# Erfolg prüfen: Kopier-Aktivität oder kein Fehler = OK
|
||||
if [[ $SYNC_RC -eq 0 ]]; then
|
||||
ok "vdirsyncer sync erfolgreich"
|
||||
elif echo "$SYNC_OUT" | grep -qE "^Copying|^Deleting|Nothing to do"; then
|
||||
# Sync hat Daten übertragen trotz non-zero exit (häufig bei teilweisem discover)
|
||||
ok "vdirsyncer sync erfolgreich (Daten wurden übertragen)"
|
||||
if echo "$SYNC_OUT" | grep -q "discover"; then
|
||||
warn "Hinweis: 'vdirsyncer discover tasks' noch ausführen um alle Pairs zu aktivieren"
|
||||
fi
|
||||
elif echo "$SYNC_OUT" | grep -q "discover"; then
|
||||
fail "vdirsyncer sync: discover noch nicht vollständig — starte: vdirsyncer discover tasks"
|
||||
else
|
||||
fail "vdirsyncer sync fehlgeschlagen — siehe Ausgabe oben"
|
||||
fi
|
||||
|
||||
# --- 6. khal-Test ---
|
||||
echo ""
|
||||
echo "▶ 6. khal — Termine heute"
|
||||
KHAL_OUT=$(khal list --format "{start-time} {title}" today today 2>&1)
|
||||
KHAL_RC=$?
|
||||
if [[ $KHAL_RC -eq 0 ]]; then
|
||||
ok "khal list ausgeführt"
|
||||
[[ -n "$KHAL_OUT" ]] && echo "$KHAL_OUT" | sed 's/^/ /'
|
||||
else
|
||||
fail "khal list fehlgeschlagen:"
|
||||
echo "$KHAL_OUT" | sed 's/^/ /'
|
||||
info "Tipp: khal rebuild-cache ausführen"
|
||||
fi
|
||||
|
||||
# --- 7. todoman-Test ---
|
||||
echo ""
|
||||
echo "▶ 7. todoman — Aufgabenliste"
|
||||
TODO_OUT=$(todo list 2>&1)
|
||||
TODO_RC=$?
|
||||
if [[ $TODO_RC -eq 0 ]]; then
|
||||
ok "todo list ausgeführt"
|
||||
[[ -n "$TODO_OUT" ]] && echo "$TODO_OUT" | sed 's/^/ /'
|
||||
else
|
||||
fail "todo list fehlgeschlagen:"
|
||||
echo "$TODO_OUT" | sed 's/^/ /'
|
||||
info "Tipp: Pfad in ~/.config/todoman/config.cfg prüfen, 'vdirsyncer discover tasks' ausführen"
|
||||
fi
|
||||
|
||||
# --- 8. systemd-Timer ---
|
||||
echo ""
|
||||
echo "▶ 8. systemd Timer"
|
||||
if systemctl --user is-active vdirsyncer-sync.timer &>/dev/null; then
|
||||
ok "vdirsyncer-sync.timer: aktiv"
|
||||
NEXT=$(systemctl --user list-timers vdirsyncer-sync.timer --no-legend 2>/dev/null | awk '{print $1, $2}')
|
||||
info "Nächster Sync: $NEXT"
|
||||
else
|
||||
fail "vdirsyncer-sync.timer nicht aktiv → systemctl --user enable --now vdirsyncer-sync.timer"
|
||||
fi
|
||||
|
||||
# --- 9. Log-Datei ---
|
||||
echo ""
|
||||
echo "▶ 9. Log-Datei"
|
||||
LOG="$HOME/.local/share/openclaw-mailbox-cal/sync.log"
|
||||
if [[ -f "$LOG" ]]; then
|
||||
SIZE=$(du -sh "$LOG" | cut -f1)
|
||||
ok "Log vorhanden: $LOG ($SIZE)"
|
||||
info "Letzte 5 Zeilen:"
|
||||
tail -5 "$LOG" | sed 's/^/ /'
|
||||
else
|
||||
info "Log noch nicht vorhanden (wird beim ersten Sync erstellt)"
|
||||
fi
|
||||
|
||||
# --- Zusammenfassung ---
|
||||
echo ""
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
if [[ $FAILED -eq 0 ]]; then
|
||||
echo -e "${GREEN} Alle Tests bestanden! Setup ist korrekt.${NC}"
|
||||
else
|
||||
echo -e "${RED} $FAILED Test(s) fehlgeschlagen — siehe Details oben.${NC}"
|
||||
fi
|
||||
echo -e "${CYAN}══════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
exit $FAILED
|
||||
Reference in New Issue
Block a user