feat: add core modules (config, state, diff, apply, health)
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import logging
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from typing import Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _extract_uid(ical_data: bytes) -> str:
|
||||
for line in ical_data.decode("utf-8", errors="replace").split("\r\n"):
|
||||
if line.upper().startswith("UID:"):
|
||||
return line[4:].strip()
|
||||
return ""
|
||||
|
||||
|
||||
def _find_event_by_uid(calendar: Any, uid: str) -> Any | None:
|
||||
try:
|
||||
for event in calendar.events():
|
||||
content = event.data.decode("utf-8", errors="replace")
|
||||
for line in content.split("\r\n"):
|
||||
if line.upper().startswith("UID:"):
|
||||
if line[4:].strip() == uid:
|
||||
return event
|
||||
except Exception as exc:
|
||||
logger.error("Error scanning events for UID %s: %s", uid, exc)
|
||||
return None
|
||||
|
||||
|
||||
def _add_event(calendar: Any, uid: str, ical_data: bytes) -> bool:
|
||||
try:
|
||||
calendar.add_event(ical_data)
|
||||
return True
|
||||
except Exception as exc:
|
||||
logger.error("Failed to add event %s: %s", uid, exc)
|
||||
return False
|
||||
|
||||
|
||||
def _delete_event(calendar: Any, uid: str) -> bool:
|
||||
try:
|
||||
event = _find_event_by_uid(calendar, uid)
|
||||
if event:
|
||||
event.delete()
|
||||
return True
|
||||
logger.error("Event with UID %s not found", uid)
|
||||
return False
|
||||
except Exception as exc:
|
||||
logger.error("Failed to delete event %s: %s", uid, exc)
|
||||
return False
|
||||
|
||||
|
||||
def _update_event(calendar: Any, uid: str, ical_data: bytes) -> bool:
|
||||
if not _delete_event(calendar, uid):
|
||||
return False
|
||||
return _add_event(calendar, uid, ical_data)
|
||||
|
||||
|
||||
def apply_adds(calendar: Any, events: dict[str, bytes], max_workers: int = 10) -> tuple[int, int]:
|
||||
success = 0
|
||||
errors = 0
|
||||
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
futures = {
|
||||
executor.submit(_add_event, calendar, uid, data): uid
|
||||
for uid, data in events.items()
|
||||
}
|
||||
for future in as_completed(futures):
|
||||
if future.result():
|
||||
success += 1
|
||||
else:
|
||||
errors += 1
|
||||
|
||||
return success, errors
|
||||
|
||||
|
||||
def apply_updates(calendar: Any, events: dict[str, bytes], max_workers: int = 10) -> tuple[int, int]:
|
||||
success = 0
|
||||
errors = 0
|
||||
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
futures = {
|
||||
executor.submit(_update_event, calendar, uid, data): uid
|
||||
for uid, data in events.items()
|
||||
}
|
||||
for future in as_completed(futures):
|
||||
if future.result():
|
||||
success += 1
|
||||
else:
|
||||
errors += 1
|
||||
|
||||
return success, errors
|
||||
|
||||
|
||||
def apply_deletes(calendar: Any, uids: list[str], max_workers: int = 10) -> tuple[int, int]:
|
||||
success = 0
|
||||
errors = 0
|
||||
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
futures = {
|
||||
executor.submit(_delete_event, calendar, uid): uid
|
||||
for uid in uids
|
||||
}
|
||||
for future in as_completed(futures):
|
||||
if future.result():
|
||||
success += 1
|
||||
else:
|
||||
errors += 1
|
||||
|
||||
return success, errors
|
||||
Reference in New Issue
Block a user