Skip to content

Commit

Permalink
✨ Changed Concept Of Syncing Calendars
Browse files Browse the repository at this point in the history
Massive changes in the way calendars are synced. This should have a noticable performance gain as a result.
  • Loading branch information
pauldev20 committed Jan 5, 2024
1 parent e701ef6 commit 03cab31
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 13 deletions.
46 changes: 33 additions & 13 deletions calsync/calsync.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from models.base import BaseCalDav, BaseCalendar
from models.base import BaseCalDav, BaseCalendar, BaseObjectResource
from datetime import datetime, timedelta
from typing import Union, List
import configparser
Expand Down Expand Up @@ -68,30 +68,50 @@ def sync(self, weeks_back: int, weeks_forward: int) -> None:
aggregations = self.__get_aggregation_calendars()
if aggregations == None or len(aggregations) == 0:
return
self.logger.info(f"Clearing Aggregation Calendar(s)")
for agg_calendar in aggregations:
agg_calendar.clear()

new_agg_events: List[BaseObjectResource] = []
for section in self.config.sections():
cldav = self.__get_cal_dav(section)
if cldav == None:
continue
self.logger.info(f"Syncing - \"{section}\"")

# --------------------------- Get Aggregated Events -------------------------- #
for calendar in self.config[section]["calendars"].split(","):
self.logger.info(f"Loading Events - \"{section}\" - \"{calendar}\"")
cldav_calendar = cldav.create_calendar(calendar)
for event in cldav_calendar.get_events(
datetime.now() - timedelta(weeks=weeks_back),
datetime.now() + timedelta(weeks=weeks_forward)
):
if not event.is_busy():
continue
for agg_calendar in aggregations:
agg_calendar.add_event(
event.get_start(),
event.get_end(),
"BUSY",
event.is_busy()
)
new_agg_events.append(event)

if len(self.config[section]["calendars"].split(",")) == 0:
self.logger.error(f"No Configured Calendars Found - \"{section}\"")
else:
self.logger.info(f"Finished Loading Events - \"{section}\"")

# ------------------------- Modify Aggregated Events ------------------------- #
for event in new_agg_events:
event.set_name(f"BUSY")

self.logger.info(f"Finished Syncing - \"{section}\"")
# --------------------------- Add Aggregated Events -------------------------- #
self.logger.info(f"Syncing Calendar(s)")
for agg_calendar in aggregations:
agg_events = agg_calendar.get_events(
datetime.now() - timedelta(weeks=weeks_back),
datetime.now() + timedelta(weeks=weeks_forward)
)

for evt in [event for event in agg_events if event not in new_agg_events]:
agg_calendar.remove_events_in_range(evt.get_start(), evt.get_end())

for evt in [event for event in new_agg_events if event not in agg_events]:
agg_calendar.add_event(
evt.get_start(),
evt.get_end(),
evt.get_name(),
evt.is_busy()
)
self.logger.info(f"Finished Syncing Calendar(s)")
26 changes: 26 additions & 0 deletions calsync/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ def get_name(self) -> str:
"""
return self.instance.vevent.summary.value

def set_name(self, name: str) -> None:
"""
The function `set_name` sets the value of the `summary` attribute of the event.
:param name: The `name` parameter is a string that represents the name of the
event.
:type name: str
"""
self.instance.vevent.summary.value = name

def get_start(self) -> datetime:
"""
The function returns the start datetime of an event.
Expand All @@ -44,6 +53,9 @@ def get_end(self) -> datetime:
def __str__(self) -> str:
return f"{self.get_name()} ({self.is_busy()}) - [{self.get_start()} - {self.get_end()}]"

def __eq__(self, other):
return self.get_name() == other.get_name() and self.get_start() == other.get_start() and self.get_end() == other.get_end()

# ---------------------------------------------------------------------------- #
# BaseCalendar #
# ---------------------------------------------------------------------------- #
Expand Down Expand Up @@ -108,6 +120,20 @@ def add_event(self, dtstart: datetime, dtend: datetime, summary: str, busy: bool
dtend=dtend,
transp="OPAQUE" if busy else "TRANSPARENT"
)

def remove_events_in_range(self, start: datetime, end: datetime) -> None:
"""
The function removes all events within a specified time range.
:param start: The start parameter is a datetime object that represents the
start date and time of the range for which you want to remove events
:type start: datetime
:param end: The "end" parameter is a datetime object that represents the end
time or date of the range for which you want to remove events
:type end: datetime
"""
for event in self.calendar.search(start=start, end=end, event=True):
event.delete()

# ---------------------------------------------------------------------------- #
# BaseCalDav #
Expand Down

0 comments on commit 03cab31

Please sign in to comment.