diff --git a/bitbylaw/motia-workbench.json b/bitbylaw/motia-workbench.json index e874d1f2..bab792d2 100644 --- a/bitbylaw/motia-workbench.json +++ b/bitbylaw/motia-workbench.json @@ -88,6 +88,18 @@ "steps/advoware_proxy/advoware_api_proxy_delete_step.py": { "x": 600, "y": 0 + }, + "steps/advoware_cal_sync/calendar_sync_event_step.py": { + "x": 395, + "y": 893 + }, + "steps/advoware_cal_sync/calendar_sync_cron_step.py": { + "x": -78, + "y": 768 + }, + "steps/advoware_cal_sync/calendar_sync_api_step.py": { + "x": -77, + "y": 990 } } } diff --git a/bitbylaw/steps/advoware_cal_sync/audit_calendar_sync.py b/bitbylaw/steps/advoware_cal_sync/audit_calendar_sync.py index 4fe9e9b9..235cf4f3 100644 --- a/bitbylaw/steps/advoware_cal_sync/audit_calendar_sync.py +++ b/bitbylaw/steps/advoware_cal_sync/audit_calendar_sync.py @@ -286,22 +286,70 @@ async def audit_calendar_sync(employee_kuerzel, check_system, delete_orphaned_go finally: await conn.close() +async def delete_google_calendar(service, employee_kuerzel): + """Delete Google Calendar for employee if it exists.""" + calendar_name = f"AW-{employee_kuerzel}" + try: + calendar_list = service.calendarList().list().execute() + for calendar in calendar_list.get('items', []): + if calendar['summary'] == calendar_name: + calendar_id = calendar['id'] + primary = calendar.get('primary', False) + if primary: + logger.warning(f"Cannot delete primary calendar: {calendar_name}") + return False + try: + service.calendars().delete(calendarId=calendar_id).execute() + logger.info(f"Deleted Google calendar: {calendar_name} (ID: {calendar_id})") + return True + except HttpError as e: + logger.error(f"Failed to delete Google calendar {calendar_name}: {e}") + return False + except Exception as e: + logger.error(f"Error deleting Google calendar {calendar_name}: {e}") + return False + logger.info(f"Google calendar {calendar_name} does not exist, nothing to delete") + return False + except HttpError as e: + logger.error(f"Google API error checking calendar {employee_kuerzel}: {e}") + raise + except Exception as e: + logger.error(f"Failed to check/delete Google calendar for {employee_kuerzel}: {e}") + raise + async def main(): - if len(sys.argv) < 3 or len(sys.argv) > 4: - print("Usage: python audit_calendar_sync.py [--delete-orphaned-google]") + if len(sys.argv) < 3 or len(sys.argv) > 5: + print("Usage: python audit_calendar_sync.py [--delete-orphaned-google] [--delete-calendar]") print(" --delete-orphaned-google: Delete Google events that exist in Google but not in the DB") + print(" --delete-calendar: Delete the Google calendar for the employee") print("Example: python audit_calendar_sync.py SB google --delete-orphaned-google") + print("Example: python audit_calendar_sync.py SB google --delete-calendar") sys.exit(1) employee_kuerzel = sys.argv[1].upper() check_system = sys.argv[2].lower() - delete_orphaned_google = len(sys.argv) == 4 and sys.argv[3] == '--delete-orphaned-google' + delete_orphaned_google = '--delete-orphaned-google' in sys.argv + delete_calendar = '--delete-calendar' in sys.argv - try: - await audit_calendar_sync(employee_kuerzel, check_system, delete_orphaned_google) - except Exception as e: - logger.error(f"Audit failed: {e}") - sys.exit(1) + if delete_calendar: + # Delete calendar mode + try: + service = await get_google_service() + deleted = await delete_google_calendar(service, employee_kuerzel) + if deleted: + print(f"Successfully deleted Google calendar for {employee_kuerzel}") + else: + print(f"No calendar deleted for {employee_kuerzel}") + except Exception as e: + logger.error(f"Failed to delete calendar: {e}") + sys.exit(1) + else: + # Audit mode + try: + await audit_calendar_sync(employee_kuerzel, check_system, delete_orphaned_google) + except Exception as e: + logger.error(f"Audit failed: {e}") + sys.exit(1) if __name__ == "__main__": asyncio.run(main()) \ No newline at end of file