def _sync_google2odoo(self, google_events: GoogleEvent, default_reminders=()): """Synchronize Google recurrences in Odoo. Creates new recurrences, updates existing ones. :param google_recurrences: Google recurrences to synchronize in Odoo :return: synchronized odoo recurrences """ existing = google_events.exists(self.env) new = google_events - existing - google_events.cancelled() odoo_values = [ dict(self._odoo_values(e, default_reminders), need_sync=False) for e in new ] new_odoo = self.create(odoo_values) cancelled = existing.cancelled() cancelled_odoo = self.browse(cancelled.odoo_ids(self.env)) cancelled_odoo._cancel() synced_records = new_odoo + cancelled_odoo for gevent in existing - cancelled: # Last updated wins. # This could be dangerous if google server time and odoo server time are different updated = parse(gevent.updated) odoo_record = self.browse(gevent.odoo_id(self.env)) if updated >= pytz.utc.localize(odoo_record.write_date): vals = dict(self._odoo_values(gevent, default_reminders), need_sync=False) odoo_record.write(vals) synced_records |= odoo_record return synced_records
def _sync_google2odoo(self, google_events: GoogleEvent, default_reminders=()): """Synchronize Google recurrences in Odoo. Creates new recurrences, updates existing ones. :param google_recurrences: Google recurrences to synchronize in Odoo :return: synchronized odoo recurrences """ existing = google_events.exists(self.env) new = google_events - existing - google_events.cancelled() odoo_values = [ dict(self._odoo_values(e, default_reminders), need_sync=False) for e in new ] new_odoo = self.with_context(dont_notify=True)._create_from_google(new, odoo_values) # Synced recurrences attendees will be notified once _apply_recurrence is called. if not self._context.get("dont_notify") and all(not e.is_recurrence() for e in google_events): new_odoo._notify_attendees() cancelled = existing.cancelled() cancelled_odoo = self.browse(cancelled.odoo_ids(self.env)) cancelled_odoo._cancel() synced_records = (new_odoo + cancelled_odoo).with_context(dont_notify=self._context.get("dont_notify", False)) for gevent in existing - cancelled: # Last updated wins. # This could be dangerous if google server time and odoo server time are different updated = parse(gevent.updated) odoo_record = self.browse(gevent.odoo_id(self.env)) # Migration from 13.4 does not fill write_date. Therefore, we force the update from Google. if not odoo_record.write_date or updated >= pytz.utc.localize(odoo_record.write_date): vals = dict(self._odoo_values(gevent, default_reminders), need_sync=False) odoo_record._write_from_google(gevent, vals) synced_records |= odoo_record return synced_records
def get_events(self, sync_token=None, token=None, timeout=TIMEOUT): url = "/calendar/v3/calendars/primary/events" headers = {'Content-type': 'application/json'} params = {'access_token': token} if sync_token: params['syncToken'] = sync_token else: # full sync, limit to a range of 1y in past to 1y in the futur by default ICP = self.google_service.env['ir.config_parameter'].sudo() day_range = int(ICP.get_param('google_calendar.sync.range_days', default=365)) _logger.info("Full cal sync, restricting to %s days range", day_range) lower_bound = fields.Datetime.subtract(fields.Datetime.now(), days=day_range) upper_bound = fields.Datetime.add(fields.Datetime.now(), days=day_range) params['timeMin'] = lower_bound.isoformat() + 'Z' # Z = UTC (RFC3339) params['timeMax'] = upper_bound.isoformat() + 'Z' # Z = UTC (RFC3339) try: status, data, time = self.google_service._do_request(url, params, headers, method='GET', timeout=timeout) except requests.HTTPError as e: if e.response.status_code == 410 and 'fullSyncRequired' in str(e.response.content): raise InvalidSyncToken("Invalid sync token. Full sync required") raise e events = data.get('items', []) next_page_token = data.get('nextPageToken') while next_page_token: params = {'access_token': token, 'pageToken': next_page_token} status, data, time = self.google_service._do_request(url, params, headers, method='GET', timeout=timeout) next_page_token = data.get('nextPageToken') events += data.get('items', []) next_sync_token = data.get('nextSyncToken') default_reminders = data.get('defaultReminders') return GoogleEvent(events), next_sync_token, default_reminders
def get_events(self, sync_token=None, token=None, timeout=TIMEOUT): url = "/calendar/v3/calendars/primary/events" headers = {'Content-type': 'application/json'} params = {'access_token': token} if sync_token: params['syncToken'] = sync_token try: status, data, time = self.google_service._do_request(url, params, headers, method='GET', timeout=timeout) except requests.HTTPError as e: if e.response.status_code == 410 and 'fullSyncRequired' in str(e.response.content): raise InvalidSyncToken("Invalid sync token. Full sync required") raise e events = data.get('items', []) next_page_token = data.get('nextPageToken') while next_page_token: params = {'access_token': token, 'pageToken': next_page_token} status, data, time = self.google_service._do_request(url, params, headers, method='GET', timeout=timeout) next_page_token = data.get('nextPageToken') events += data.get('items', []) next_sync_token = data.get('nextSyncToken') default_reminders = data.get('defaultReminders') return GoogleEvent(events), next_sync_token, default_reminders