'Synchronze events with google calendar : fetching, creating, updating, deleting, ...'

def update_events(self, lastSync=False):

    CalendarEvent = self.env['calendar.event']
    CalendarAttendee = self.env['calendar.attendee']
    my_partner_id = self.env.user.partner_id.id
    context_novirtual = self.get_context_no_virtual()
    if lastSync:
        try:
            all_event_from_google = self.get_event_synchro_dict(lastSync=lastSync)
        except urllib2.HTTPError as e:
            if (e.code == 410):
                self.env.cr.rollback()
                self.env.user.write({'google_calendar_last_sync_date': False})
                self.env.cr.commit()
            error_key = json.loads(str(e))
            error_key = error_key.get('error', {}).get('message', 'nc')
            error_msg = (_('Google    is    lost...    the    next    synchro    will    be    a    full    synchro.    \n\n    %s') % error_key)
            raise self.env['res.config.settings'].get_config_warning(error_msg)
        my_google_attendees = CalendarAttendee.with_context(context_novirtual).search([('partner_id', '=', my_partner_id), ('google_internal_event_id', 'in', all_event_from_google.keys())])
        my_google_att_ids = my_google_attendees.ids
        my_odoo_attendees = CalendarAttendee.with_context(context_novirtual).search([('partner_id', '=', my_partner_id), ('event_id.oe_update_date', '>', ((lastSync and fields.Datetime.to_string(lastSync)) or self.get_minTime().fields.Datetime.to_string())), ('google_internal_event_id', '!=', False)])
        my_odoo_googleinternal_records = my_odoo_attendees.read(['google_internal_event_id', 'event_id'])
        if self.get_print_log():
            _logger.info('Calendar    Synchro    -        \n\nUPDATE    IN    GOOGLE\n%s\n\nRETRIEVE    FROM    OE\n%s\n\nUPDATE    IN    OE\n%s\n\nRETRIEVE    FROM    GG\n%s\n\n', all_event_from_google, my_google_att_ids, my_odoo_attendees.ids, my_odoo_googleinternal_records)
        for gi_record in my_odoo_googleinternal_records:
            active = True
            if gi_record.get('event_id'):
                active = CalendarEvent.with_context(context_novirtual).browse(int(gi_record.get('event_id')[0])).active
            if (gi_record.get('google_internal_event_id') and (not all_event_from_google.get(gi_record.get('google_internal_event_id'))) and active):
                one_event = self.get_one_event_synchro(gi_record.get('google_internal_event_id'))
                if one_event:
                    all_event_from_google[one_event['id']] = one_event
        my_attendees = (my_google_attendees | my_odoo_attendees)
    else:
        domain = [('partner_id', '=', my_partner_id), ('google_internal_event_id', '!=', False), '|', ('event_id.stop', '>', fields.Datetime.to_string(self.get_minTime())), ('event_id.final_date', '>', fields.Datetime.to_string(self.get_minTime()))]
        my_attendees = CalendarAttendee.with_context(context_novirtual).search(domain)
        all_event_from_google = self.get_event_synchro_dict(lastSync=False)
    event_to_synchronize = {}
    for att in my_attendees:
        event = att.event_id
        base_event_id = att.google_internal_event_id.rsplit('_', 1)[0]
        if (base_event_id not in event_to_synchronize):
            event_to_synchronize[base_event_id] = {}
        if (att.google_internal_event_id not in event_to_synchronize[base_event_id]):
            event_to_synchronize[base_event_id][att.google_internal_event_id] = SyncEvent()
        ev_to_sync = event_to_synchronize[base_event_id][att.google_internal_event_id]
        ev_to_sync.OE.attendee_id = att.id
        ev_to_sync.OE.event = event
        ev_to_sync.OE.found = True
        ev_to_sync.OE.event_id = event.id
        ev_to_sync.OE.isRecurrence = event.recurrency
        ev_to_sync.OE.isInstance = bool((event.recurrent_id and (event.recurrent_id > 0)))
        ev_to_sync.OE.update = event.oe_update_date
        ev_to_sync.OE.status = event.active
        ev_to_sync.OE.synchro = att.oe_synchro_date
    for event in all_event_from_google.values():
        event_id = event.get('id')
        base_event_id = event_id.rsplit('_', 1)[0]
        if (base_event_id not in event_to_synchronize):
            event_to_synchronize[base_event_id] = {}
        if (event_id not in event_to_synchronize[base_event_id]):
            event_to_synchronize[base_event_id][event_id] = SyncEvent()
        ev_to_sync = event_to_synchronize[base_event_id][event_id]
        ev_to_sync.GG.event = event
        ev_to_sync.GG.found = True
        ev_to_sync.GG.isRecurrence = bool(event.get('recurrence', ''))
        ev_to_sync.GG.isInstance = bool(event.get('recurringEventId', 0))
        ev_to_sync.GG.update = event.get('updated', None)
        if ev_to_sync.GG.update:
            ev_to_sync.GG.update = ev_to_sync.GG.update.replace('T', '    ').replace('Z', '')
        ev_to_sync.GG.status = (event.get('status') != 'cancelled')
    for base_event in event_to_synchronize:
        for current_event in event_to_synchronize[base_event]:
            event_to_synchronize[base_event][current_event].compute_OP(modeFull=(not lastSync))
        if self.get_print_log():
            if (not isinstance(event_to_synchronize[base_event][current_event].OP, NothingToDo)):
                _logger.info(event_to_synchronize[base_event])
    for base_event in event_to_synchronize:
        event_to_synchronize[base_event] = sorted(event_to_synchronize[base_event].iteritems(), key=operator.itemgetter(0))
        for current_event in event_to_synchronize[base_event]:
            self.env.cr.commit()
            event = current_event[1]
            actToDo = event.OP
            actSrc = event.OP.src
            recs = self.with_context(curr_attendee=event.OE.attendee_id)
            if isinstance(actToDo, NothingToDo):
                continue
            elif isinstance(actToDo, Create):
                if (actSrc == 'GG'):
                    self.create_from_google(event, my_partner_id)
                elif (actSrc == 'OE'):
                    raise 'Should    be    never    here,    creation    for    OE    is    done    before    update    !'
            elif isinstance(actToDo, Update):
                if (actSrc == 'GG'):
                    recs.update_from_google(event.OE.event, event.GG.event, 'write')
                elif (actSrc == 'OE'):
                    recs.update_to_google(event.OE.event, event.GG.event)
            elif isinstance(actToDo, Exclude):
                if (actSrc == 'OE'):
                    recs.delete_an_event(current_event[0])
                elif (actSrc == 'GG'):
                    new_google_event_id = event.GG.event['id'].rsplit('_', 1)[1]
                    if ('T' in new_google_event_id):
                        new_google_event_id = new_google_event_id.replace('T', '')[:(-1)]
                    else:
                        new_google_event_id = (new_google_event_id + '000000')
                    if event.GG.status:
                        parent_event = {}
                        if (not event_to_synchronize[base_event][0][1].OE.event_id):
                            main_ev = CalendarAttendee.with_context(context_novirtual).search([('google_internal_event_id', '=', event.GG.event['id'].rsplit('_', 1)[0])], limit=1)
                            event_to_synchronize[base_event][0][1].OE.event_id = main_ev.event_id.id
                        if event_to_synchronize[base_event][0][1].OE.event_id:
                            parent_event['id'] = ('%s-%s' % (event_to_synchronize[base_event][0][1].OE.event_id, new_google_event_id))
                            res = recs.update_from_google(parent_event, event.GG.event, 'copy')
                        else:
                            recs.create_from_google(event, my_partner_id)
                    else:
                        parent_oe_id = event_to_synchronize[base_event][0][1].OE.event_id
                        if parent_oe_id:
                            CalendarEvent.browse(('%s-%s' % (parent_oe_id, new_google_event_id))).with_context(curr_attendee=event.OE.attendee_id).unlink(can_be_deleted=True)
            elif isinstance(actToDo, Delete):
                if (actSrc == 'GG'):
                    try:
                        recs.delete_an_event(current_event[0])
                    except Exception as e:
                        if (e.code in (401, 410)):
                            pass
                        else:
                            raise e
                elif (actSrc == 'OE'):
                    CalendarEvent.browse(event.OE.event_id).unlink(can_be_deleted=False)
    return True
