Esempio n. 1
0
    def save(self, *args, **kwargs):
        if self.name is None:
            self.name = ""
        self.name = self.name[:150].encode('utf-8').strip()

        if self.description is None:
            self.description = ""
        self.description = self.description[:20000]

        # Validate the color_index field, correct if necessary
        if self.color_index is None or self.color_index == '':
            self.color_index = self.EVENT_COLORS_KEYS[0]
        try:
            assert int(self.color_index) in range(len(self.EVENT_COLORS_KEYS))
        except (ValueError, AssertionError):
            self.color_index = self.EVENT_COLORS_KEYS[0]

        made_aware = False
        if timezone.is_naive(self.start):
            made_aware = True

        self.start = ensure_timezone_awareness(self.start, self.timezone)
        self.end = ensure_timezone_awareness(self.end, self.timezone)

        super(GEvent, self).save(*args, **kwargs)

        if made_aware and settings.VERBOSE_PRINT:
            print "Made datetime timezone aware for GEvent {} with id {}".format(
                self.name, self.id)
Esempio n. 2
0
    def save(self, *args, **kwargs):
        if self.name is None:
            self.name = ""
        self.name = self.name[:150]

        if self.description is None:
            self.description = ""
        self.description = self.description[:20000]

        # Validate the color_index field, correct if necessary
        if self.color_index is None or self.color_index == '':
            self.color_index = self.EVENT_COLORS_KEYS[0]
        try:
            assert int(self.color_index) in range(len(self.EVENT_COLORS_KEYS))
        except (ValueError, AssertionError):
            self.color_index = self.EVENT_COLORS_KEYS[0]

        made_aware = False
        if timezone.is_naive(self.start):
            made_aware = True

        self.start = ensure_timezone_awareness(self.start, self.timezone)
        self.end = ensure_timezone_awareness(self.end, self.timezone)

        super(GEvent, self).save(*args, **kwargs)

        if made_aware:
            print "Made datetime timezone aware for GEvent {} with id {}".format(self.name, self.id)
Esempio n. 3
0
    def save(self, *args, **kwargs):

        self.start = ensure_timezone_awareness(self.start)
        self.end = ensure_timezone_awareness(self.end)

        return super(GRecurrence, self).save(*args, **kwargs)
Esempio n. 4
0
    def sync(self, full_sync=False):
        """
        Syncs this calendar.
        Assumes that the list of calendars for this profile is correct
        """

        print "Syncing calendar {}".format(
            self.summary.encode('utf-8').strip())
        result = None
        creds = self.user.googlecredentials
        service = creds.get_service()

        default_list_args = {
            'calendarId': self.calendar_id,
            'singleEvents': True,
            'maxResults': 2500,
        }
        list_args_with_constraints = {
            # Only sync up to two months in the future
            'timeMax':
            ensure_timezone_awareness(datetime.now() +
                                      timedelta(days=60)).isoformat(),
        }
        list_args_with_constraints.update(default_list_args)

        next_page_token = None
        if full_sync:
            # Full sync - initial request without sync token or page token
            result = service.events().list(
                **list_args_with_constraints).execute()
            old_events = GEvent.objects.filter(calendar=self)
            for event in old_events:
                event.delete()
            # Delete the DeletedEvents and get a fresh copy from Google
            deleted_events = DeletedEvent.objects.filter(calendar=self)
            for event in deleted_events:
                event.delete()
        else:
            # Incremental sync, initial request needs syncToken
            try:
                # Google API doesn't accept constraints for the first request in incremental sync
                result = service.events().list(syncToken=self.next_sync_token,
                                               **default_list_args).execute()
            except Exception as e:
                t, v, tb = sys.exc_info()
                if hasattr(e, 'resp') and e.resp.status == 410:
                    # Sync token is no longer valid, perform full sync
                    print "Sync token is no longer valid, perform full sync for calendar {}".format(
                        self.summary.encode('utf-8').strip())
                    result = service.events().list(
                        **list_args_with_constraints).execute()
                else:
                    raise t, v, tb

        # Run the first iteration, for the first request
        for item in result['items']:
            self.api_event_to_gevent(item)

        # Paginate through the rest, if applicable
        while True:
            next_page_token = result.get('nextPageToken')

            if not next_page_token:
                # We've reached the last page. Store the sync token.
                self.next_sync_token = result['nextSyncToken']
                self.save()
                break

            result = service.events().list(
                pageToken=next_page_token,
                **list_args_with_constraints).execute()

            # Assume at this point it's a correctly formatted event
            for item in result['items']:
                self.api_event_to_gevent(item)

        # Make this calendar consistent with existing DeletedEvents
        deleted_events = DeletedEvent.objects.filter(calendar=self)
        for d_event in deleted_events:
            d_event.apply()

        print "Successfully synced calendar {}".format(
            self.summary.encode('utf-8').strip())

        # Some additional sanity checks
        # Check for non-duplicate events with the same recurring_event_id
        start_times = {}
        for recurrence in GEvent.objects.filter(calendar=self).exclude(
                recurrence=''):
            if recurrence.start in start_times.get(
                    recurrence.recurring_event_id, set()):
                print "Error: Multiple GEvents found with the same start and recurring_event_id"
                dupe_ids = [
                    str(dupe.id) for dupe in GEvent.objects.filter(
                        recurring_event_id=recurrence.recurring_event_id,
                        start=recurrence.start)
                ]
                print "IDs are {} at time {}".format(", ".join(dupe_ids),
                                                     recurrence.start)

            if not start_times.get(recurrence.recurring_event_id, None):
                start_times[recurrence.recurring_event_id] = set()
            start_times[recurrence.recurring_event_id].add(recurrence.start)
Esempio n. 5
0
    def save(self, *args, **kwargs):

        self.start = ensure_timezone_awareness(self.start)
        self.end = ensure_timezone_awareness(self.end)

        return super(GRecurrence, self).save(*args, **kwargs)
Esempio n. 6
0
    def sync(self, full_sync=False):
        result = None
        creds = self.user.googlecredentials
        service = creds.get_service()

        default_list_args = {
                'calendarId': self.calendar_id,
                'singleEvents': True,
                'maxResults': 2500,
                }
        list_args_with_constraints = {
                # Only sync up to two months in the future
                'timeMax': ensure_timezone_awareness(datetime.now() + timedelta(days=60)).isoformat(),
                }
        list_args_with_constraints.update(default_list_args)

        next_page_token = None
        if full_sync:
            # Full sync - initial request without sync token or page token
            result = service.events().list(**list_args_with_constraints).execute()
            old_events = GEvent.objects.filter(calendar=self)
            for event in old_events:
                event.delete()
            # Delete the DeletedEvents and get a fresh copy from Google
            deleted_events = DeletedEvent.objects.filter(calendar=self)
            for event in deleted_events:
                event.delete()
        else:
            # Incremental sync, initial request needs syncToken
            try:
                # Google API doesn't accept constraints for the first request in incremental sync
                result = service.events().list(syncToken=creds.next_sync_token, **default_list_args).execute()
            except Exception as e:
                t, v, tb = sys.exc_info()
                if hasattr(e, 'resp') and e.resp.status == 410:
                    # Sync token is no longer valid, perform full sync
                    result = service.events().list(**list_args_with_constraints).execute()
                else:
                    raise t, v, tb

        # Run the first iteration, for the first request
        for item in result['items']:
            self.api_event_to_gevent(item)

        # Paginate through the rest, if applicable
        while True:
            next_page_token = result.get('nextPageToken')

            if not next_page_token:
                # We've reached the last page. Store the sync token.
                creds.next_sync_token = result['nextSyncToken']
                creds.save()
                break

            result = service.events().list(pageToken=next_page_token, **list_args_with_constraints).execute()

            # Assume at this point it's a correctly formatted event
            for item in result['items']:
                self.api_event_to_gevent(item)

        # Make this calendar consistent with existing DeletedEvents
        deleted_events = DeletedEvent.objects.filter(calendar=self)
        for d_event in deleted_events:
            d_event.apply()

        print "Successfully synced calendar."

        # Some additional sanity checks
        # Check for non-duplicate events with the same recurring_event_id
        start_times = {}
        for recurrence in GEvent.objects.filter(calendar=self).exclude(recurrence=''):
            if recurrence.start in start_times.get(recurrence.recurring_event_id, set()):
                print "Error: Multiple GEvents found with the same start and recurring_event_id"
                dupe_ids = [str(dupe.id) for dupe in GEvent.objects.filter(recurring_event_id=recurrence.recurring_event_id,
                                                                start=recurrence.start)]
                print "IDs are {} at time {}".format(", ".join(dupe_ids), recurrence.start)

            if not start_times.get(recurrence.recurring_event_id, None):
                start_times[recurrence.recurring_event_id] = set()
            start_times[recurrence.recurring_event_id].add(recurrence.start)