From 34a2c840cd211e6eaadff0b700f4f6d135623462 Mon Sep 17 00:00:00 2001 From: Kevin Alberts Date: Thu, 12 Nov 2020 13:28:39 +0100 Subject: [PATCH] Do not re-upload events if they aren't changed. --- davinci/caldav/models.py | 28 ++++++++++++++----- .../management/commands/gcal_sync.py | 4 +-- .../management/commands/ical_sync.py | 4 +-- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/davinci/caldav/models.py b/davinci/caldav/models.py index 677fd7b..ad0ef46 100644 --- a/davinci/caldav/models.py +++ b/davinci/caldav/models.py @@ -65,7 +65,7 @@ class CalDAVCalendar(models.Model): return cal return None - def upload_events(self, events: List[Event], purge: bool = True, ignore_invalid_recurring: bool = False) -> Tuple[int, int, int]: + def upload_events(self, events: List[Event], purge: bool = True, ignore_invalid_recurring: bool = False) -> Tuple[int, int, int, int]: """ Upload events to this calendar. If purge is True, all old events will be removed. :param events: The events to upload @@ -74,8 +74,8 @@ class CalDAVCalendar(models.Model): :type purge: bool :param ignore_invalid_recurring: Whether to ignore errors when adding invalid recurring events (GCalendar does this) :type ignore_invalid_recurring: bool - :return Amount of events added, updated, and deleted - :rtype Tuple[int, int, int] + :return Amount of events added, updated, unchanged, and deleted + :rtype Tuple[int, int, int, int] """ logger = logging.getLogger("davinci.icalendar.CalDAVCalendar.upload_events") calendar = self.get_calendar() @@ -88,6 +88,7 @@ class CalDAVCalendar(models.Model): updated = 0 added = 0 + unchanged = 0 # Import events for event in events: @@ -102,8 +103,22 @@ class CalDAVCalendar(models.Model): # Need to overwrite try: cevent = calendar.event_by_uid(event.uid) - cevent.data = vcal.fix(ev) - cevent.save() + + replace = False + + # If a sequence number is available, only overwrite if it is higher in the ICS event. + if hasattr(cevent.vobject_instance.vevent, 'sequence') and any([x.name == "SEQUENCE" for x in event.extra]): + ics_sequence = [x.value for x in event.extra if x.name == "SEQUENCE"][0] + dav_sequence = cevent.vobject_instance.vevent.sequence.value + if int(ics_sequence) > int(dav_sequence): + replace = True + + if replace: + cevent.data = vcal.fix(ev) + cevent.save() + updated += 1 + else: + unchanged += 1 except Exception as e: if ignore_invalid_recurring and len([x for x in event.extra if x.name == "RECURRENCE-ID"]) > 0: # Recurring event from GCal, ignore @@ -113,7 +128,6 @@ class CalDAVCalendar(models.Model): logger.error(f"======EVENT======\n{ev}\n=================") purge_uids.remove(event.uid) - updated += 1 else: try: @@ -131,4 +145,4 @@ class CalDAVCalendar(models.Model): else: deleted = 0 - return added, updated, deleted + return added, updated, unchanged, deleted diff --git a/davinci/gcalendar/management/commands/gcal_sync.py b/davinci/gcalendar/management/commands/gcal_sync.py index d2308b8..7096219 100644 --- a/davinci/gcalendar/management/commands/gcal_sync.py +++ b/davinci/gcalendar/management/commands/gcal_sync.py @@ -21,10 +21,10 @@ class Command(BaseCommand): logger.debug(f"Synchronizing {sync.name}...") events = sync.get_events() - added, existing, deleted = sync.target.upload_events(events, purge=sync.purge, ignore_invalid_recurring=True) + added, existing, unchanged, deleted = sync.target.upload_events(events, purge=sync.purge, ignore_invalid_recurring=True) sync.last_sync = timezone.now() sync.save() - logger.debug(f"Sync for {sync.name} done! {added} events added, {existing} updated, and {deleted} purged.") + logger.debug(f"Sync for {sync.name} done! {added} events added, {existing} updated, {unchanged} unchanged, and {deleted} purged.") logger.debug("iCal sync complete!") diff --git a/davinci/icalendar/management/commands/ical_sync.py b/davinci/icalendar/management/commands/ical_sync.py index f3000eb..b3bc44b 100644 --- a/davinci/icalendar/management/commands/ical_sync.py +++ b/davinci/icalendar/management/commands/ical_sync.py @@ -21,10 +21,10 @@ class Command(BaseCommand): logger.debug(f"Synchronizing {sync.name}...") events = sync.get_events() - added, existing, deleted = sync.target.upload_events(events, purge=sync.purge) + added, existing, unchanged, deleted = sync.target.upload_events(events, purge=sync.purge) sync.last_sync = timezone.now() sync.save() - logger.debug(f"Sync for {sync.name} done! {added} events added, {existing} updated, and {deleted} purged.") + logger.debug(f"Sync for {sync.name} done! {added} events added, {existing} updated. {unchanged} unchanged, and {deleted} purged.") logger.debug("iCal sync complete!")