cleanup
This commit is contained in:
176
bitbylaw/scripts/calendar_sync/README.md
Normal file
176
bitbylaw/scripts/calendar_sync/README.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# Calendar Sync Utility Scripts
|
||||
|
||||
---
|
||||
title: Calendar Sync Utilities
|
||||
description: Helper-Scripts für Google Calendar Synchronisation - Wartung, Debugging und Cleanup
|
||||
date: 2026-02-07
|
||||
category: utilities
|
||||
---
|
||||
|
||||
## Übersicht
|
||||
|
||||
Dieses Verzeichnis enthält Utility-Scripts für Wartung und Debugging der Calendar-Sync-Funktionalität.
|
||||
|
||||
---
|
||||
|
||||
## Scripts
|
||||
|
||||
### delete_all_calendars.py
|
||||
|
||||
**Zweck**: Löscht alle (nicht-primären) Kalender aus dem Google Calendar Service Account.
|
||||
|
||||
**Use Case**:
|
||||
- Reset bei fehlerhafter Synchronisation
|
||||
- Cleanup nach Tests
|
||||
- Bereinigung von Duplikaten
|
||||
|
||||
**Ausführung**:
|
||||
```bash
|
||||
cd /opt/motia-app/bitbylaw
|
||||
python3 scripts/calendar_sync/delete_all_calendars.py
|
||||
```
|
||||
|
||||
**Funktionsweise**:
|
||||
1. Authentifizierung mit Google Service Account
|
||||
2. Abruf aller Kalender via `calendarList().list()`
|
||||
3. Iteration durch alle Kalender
|
||||
4. Überspringen des Primary Calendar (Schutz)
|
||||
5. Löschen aller anderen Kalender via `calendars().delete()`
|
||||
|
||||
**Sicherheit**:
|
||||
- ⚠️ **WARNUNG**: Löscht unwiderruflich alle Kalender!
|
||||
- Primary Calendar wird automatisch übersprungen
|
||||
- Manuelle Bestätigung erforderlich (TODO: Confirmation Prompt)
|
||||
|
||||
**Abhängigkeiten**:
|
||||
- `steps.advoware_cal_sync.calendar_sync_event_step.get_google_service`
|
||||
- Google Calendar API Access
|
||||
- Service Account Credentials
|
||||
|
||||
**Output-Beispiel**:
|
||||
```
|
||||
Fetching calendar list...
|
||||
Found 15 calendars to delete:
|
||||
- Max Mustermann (ID: max@example.com, Primary: False)
|
||||
✓ Deleted calendar: Max Mustermann
|
||||
- Primary (ID: service@project.iam.gserviceaccount.com, Primary: True)
|
||||
Skipping primary calendar: Primary
|
||||
...
|
||||
All non-primary calendars have been deleted.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### delete_employee_locks.py
|
||||
|
||||
**Zweck**: Löscht alle Employee-Locks aus Redis für Calendar Sync.
|
||||
|
||||
**Use Case**:
|
||||
- Cleanup nach abgestürztem Sync-Prozess
|
||||
- Manueller Reset bei "hanging" Locks
|
||||
- Debugging von Lock-Problemen
|
||||
|
||||
**Ausführung**:
|
||||
```bash
|
||||
cd /opt/motia-app/bitbylaw
|
||||
python3 scripts/calendar_sync/delete_employee_locks.py
|
||||
```
|
||||
|
||||
**Funktionsweise**:
|
||||
1. Verbindung zu Redis DB 2 (`REDIS_DB_CALENDAR_SYNC`)
|
||||
2. Suche nach allen Keys mit Pattern `calendar_sync_lock_*`
|
||||
3. Löschen aller gefundenen Lock-Keys
|
||||
|
||||
**Redis Key Pattern**:
|
||||
```
|
||||
calendar_sync_lock_{employee_id}
|
||||
```
|
||||
|
||||
**Sicherheit**:
|
||||
- ⚠️ Kann zu Race Conditions führen, wenn Sync läuft
|
||||
- Empfehlung: Nur ausführen, wenn kein Sync-Prozess aktiv ist
|
||||
|
||||
**Abhängigkeiten**:
|
||||
- `config.Config` (Redis-Konfiguration)
|
||||
- Redis DB 2 (Calendar Sync State)
|
||||
|
||||
**Output-Beispiel**:
|
||||
```
|
||||
Deleted 12 employee lock keys.
|
||||
```
|
||||
|
||||
**Oder bei leerer DB**:
|
||||
```
|
||||
No employee lock keys found.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow: Kompletter Reset
|
||||
|
||||
Bei schwerwiegenden Sync-Problemen:
|
||||
|
||||
```bash
|
||||
cd /opt/motia-app/bitbylaw
|
||||
|
||||
# 1. Stoppe Motia Service (verhindert neue Syncs)
|
||||
sudo systemctl stop motia
|
||||
|
||||
# 2. Lösche alle Redis Locks
|
||||
python3 scripts/calendar_sync/delete_employee_locks.py
|
||||
|
||||
# 3. Lösche alle Google Kalender (optional, nur bei Bedarf!)
|
||||
python3 scripts/calendar_sync/delete_all_calendars.py
|
||||
|
||||
# 4. Starte Motia Service neu
|
||||
sudo systemctl start motia
|
||||
|
||||
# 5. Triggere Full-Sync
|
||||
curl -X POST http://localhost:3000/api/calendar/sync/all
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Vor Ausführung
|
||||
|
||||
1. **Backup prüfen**: Sicherstellen, dass Advoware-Daten konsistent sind
|
||||
2. **Service Status**: `systemctl status motia` prüfen
|
||||
3. **Redis Dump**: `redis-cli -n 2 BGSAVE` (optional)
|
||||
|
||||
### Nach Ausführung
|
||||
|
||||
1. **Logs prüfen**: `journalctl -u motia -n 100 --no-pager`
|
||||
2. **Sync triggern**: Via API oder Cron
|
||||
3. **Verifizierung**: Google Calendar auf korrekte Kalender prüfen
|
||||
|
||||
---
|
||||
|
||||
## Zukünftige Scripts (TODO)
|
||||
|
||||
### audit_calendar_sync.py
|
||||
|
||||
**Zweck**: Vergleicht Advoware-Termine mit Google Calendar
|
||||
|
||||
**Features**:
|
||||
- Diff-Anzeige zwischen Advoware und Google
|
||||
- Erkennung von Orphaned Calendars
|
||||
- Report-Generierung
|
||||
|
||||
### repair_calendar_sync.py
|
||||
|
||||
**Zweck**: Automatische Reparatur bei Inkonsistenzen
|
||||
|
||||
**Features**:
|
||||
- Auto-Sync bei fehlenden Terminen
|
||||
- Löschen von Duplikaten
|
||||
- Lock-Cleanup mit Safety-Checks
|
||||
|
||||
---
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [Calendar Sync Architecture](../../docs/ARCHITECTURE.md#2-calendar-sync-pipeline)
|
||||
- [Calendar Sync Cron Step](../../steps/advoware_cal_sync/calendar_sync_cron_step.md)
|
||||
- [Troubleshooting Guide](../../docs/TROUBLESHOOTING.md)
|
||||
52
bitbylaw/scripts/calendar_sync/delete_all_calendars.py
Normal file
52
bitbylaw/scripts/calendar_sync/delete_all_calendars.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script to delete all calendars from Google Calendar account
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
sys.path.append('.')
|
||||
|
||||
from steps.advoware_cal_sync.calendar_sync_event_step import get_google_service
|
||||
|
||||
async def delete_all_calendars():
|
||||
"""Delete all calendars from the Google account"""
|
||||
try:
|
||||
service = await get_google_service()
|
||||
|
||||
# Get all calendars
|
||||
print("Fetching calendar list...")
|
||||
calendars_result = service.calendarList().list().execute()
|
||||
calendars = calendars_result.get('items', [])
|
||||
|
||||
print(f"Raw calendars result: {calendars_result}")
|
||||
print(f"Calendars list: {calendars}")
|
||||
|
||||
print(f"Found {len(calendars)} calendars to delete:")
|
||||
|
||||
for calendar in calendars:
|
||||
calendar_id = calendar['id']
|
||||
summary = calendar.get('summary', 'No summary')
|
||||
primary = calendar.get('primary', False)
|
||||
|
||||
print(f" - {summary} (ID: {calendar_id}, Primary: {primary})")
|
||||
|
||||
# Skip primary calendar if you want to keep it
|
||||
if primary:
|
||||
print(f" Skipping primary calendar: {summary}")
|
||||
continue
|
||||
|
||||
try:
|
||||
# Delete the calendar
|
||||
service.calendars().delete(calendarId=calendar_id).execute()
|
||||
print(f" ✓ Deleted calendar: {summary}")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed to delete calendar {summary}: {e}")
|
||||
|
||||
print("\nAll non-primary calendars have been deleted.")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(delete_all_calendars())
|
||||
21
bitbylaw/scripts/calendar_sync/delete_employee_locks.py
Normal file
21
bitbylaw/scripts/calendar_sync/delete_employee_locks.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import redis
|
||||
from config import Config
|
||||
|
||||
def main():
|
||||
redis_client = redis.Redis(
|
||||
host=Config.REDIS_HOST,
|
||||
port=int(Config.REDIS_PORT),
|
||||
db=int(Config.REDIS_DB_CALENDAR_SYNC),
|
||||
socket_timeout=Config.REDIS_TIMEOUT_SECONDS
|
||||
)
|
||||
|
||||
# Find all lock keys
|
||||
lock_keys = redis_client.keys('calendar_sync_lock_*')
|
||||
if lock_keys:
|
||||
deleted_count = redis_client.delete(*lock_keys)
|
||||
print(f"Deleted {deleted_count} employee lock keys.")
|
||||
else:
|
||||
print("No employee lock keys found.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user