def invite_google(request): all_emails = [] if 'token' in request.GET: token = request.GET['token'] token_auth_login = AuthSubToken(token) query = ContactsQuery() query.max_results = MAX_RESULT client = ContactsClient(auth_token=token_auth_login) client.upgrade_token(token=token_auth_login) try: feed = client.GetContacts(q=query) while feed: next = feed.GetNextLink() for entry in feed.entry: try: email_address = entry.email[0].address #print email_address all_emails.append(email_address) except: pass feed = None if PAGING and next: feed = client.GetContacts(next.href, auth_token=token_auth_login, q=query) except: pass return render(request , 'pin/invite_google.html', {'login': GetAuthSubUrl(), 'all_emails':all_emails})
def create_contact_group(cls, credentials): auth_token = OAuth2TokenFromCredentials(credentials) gd_client = ContactsClient() auth_token.authorize(gd_client) new_group = gdata.contacts.data.GroupEntry(title=atom.data.Title( text='ioGrow Contacts')) created_group = gd_client.CreateGroup(new_group) return created_group.id.text
def __get_client(self): '''Login to Google and return a ContactsClient object. ''' if not self.__client: if not self.config.email or not self.password: print >> sys.stderr, "ERROR: Missing email or password" sys.exit(1) client = ContactsClient() client.ssl = True client.ClientLogin(email=self.config.email, password=self.password, service='cp', source='goobook') self.__client = client return self.__client
def list_google_contacts(cls, credentials): auth_token = OAuth2TokenFromCredentials(credentials) gd_client = ContactsClient() auth_token.authorize(gd_client) query = gdata.contacts.client.ContactsQuery() query.max_results = 10 feed = gd_client.GetContacts(q=query) for i, entry in enumerate(feed.entry): if entry.name: print '\n%s %s' % (i + 1, smart_str(entry.name.full_name.text)) try: contact_image = gd_client.GetPhoto(entry) except: print 'ERROR: not found'
def invite_google(request): all_emails = [] if 'token' in request.GET: token = request.GET['token'] token_auth_login = AuthSubToken(token) query = ContactsQuery() query.max_results = MAX_RESULT client = ContactsClient(auth_token=token_auth_login) client.upgrade_token(token=token_auth_login) try: feed = client.GetContacts(q=query) while feed: next = feed.GetNextLink() for entry in feed.entry: try: email_address = entry.email[0].address #print email_address all_emails.append(email_address) except: pass feed = None if PAGING and next: feed = client.GetContacts(next.href, auth_token=token_auth_login, q=query) except: pass return render(request, 'pin/invite_google.html', { 'login': GetAuthSubUrl(), 'all_emails': all_emails })
def _contacts_client(self): return ContactsClient(source="SchedUp", auth_token=ClientLoginToken( self.oauth.credentials.access_token))
def create_contact(cls, credentials, google_contact_schema): auth_token = OAuth2TokenFromCredentials(credentials) gd_client = ContactsClient() auth_token.authorize(gd_client) contact_entry = gd_client.CreateContact(google_contact_schema) return contact_entry.id.text
def __init__(self, account): # noinspection PyUnresolvedReferences def delegate(): """ Function to access as another account using server-side credentials. :return: Boolean, True if successful. """ try: self.dc = self.credentials.create_delegated(self.account) return True except Exception as e: logger.exception("Unexpected error when trying to get permission to access this account") return False # noinspection PyUnresolvedReferences def validate(): """ Function to validate your server-side credentials, generating an access token. :return: Boolean, True if successful. """ is_ok = False self.credentials = ServiceAccountCredentials.from_json_keyfile_name(self.json, scopes=self.scopes) try: if not self.credentials: logger.error('Problem when trying to validate your credentials.') elif self.credentials.invalid: logger.error("Access denied, invalid credentials") else: is_ok = True return is_ok except: logger.exception("Problem when trying to validate your credentials.") return is_ok self.credentials = None self.calendar_list = None self.dc = None # Load Google credentials self.json = 'credentials/google.json' # Load all the Application Scope used to handle Calendar and Contacts self.scopes = ['https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/contacts', 'https://www.google.com/m8/feeds/', 'https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.orgunit.readonly', 'https://www.googleapis.com/auth/admin.directory.orgunit', 'https://www.googleapis.com/auth/apps.groups.migration', 'https://www.googleapis.com/auth/gmail.insert', 'https://www.googleapis.com/auth/gmail.labels', 'https://mail.google.com/', 'https://www.googleapis.com/auth/gmail.modify'] # Stores the User Account self.account = str(account) # ERROR CODE FOR LOGGING self.error_code = {'delegate': '[' + self.account + '][DELEGATE] ', 'validate': '[' + self.account + '][VALIDATE] ', 'create_cal': '[' + self.account + '][CREATE_CALENDAR] ', 'rem_cal': '[' + self.account + '][REMOVE_CALENDAR] ', 'list_cals': '[' + self.account + '][LIST_CALENDARS] ', 'create_evt': '[' + self.account + '][CREATE_EVENT] ', 'g_events': '[' + self.account + '][GET_EVENTS] ', 'g_cts': '[' + self.account + '][GET_CONTACTS] ', 'rem_ct': '[' + self.account + '][REMOVE_CONTACT] ', 'create_ct': '[' + self.account + '][CREATE_CONTACT] ', 'list_cts': '[' + self.account + '][LIST_CONTACTS] ', 'create_grp': '[' + self.account + '][CREATE_GROUP] ', 'list_grp': '[' + self.account + '][LIST_GROUPS] ', 'rem_grp': '[' + self.account + '][REMOVE_GROUP] ', 'format_ct': '[' + self.account + '][FORMAT_CONTACT] ', 'format_evt': '[' + self.account + '][FORMAT_EVENT] ', 'convert_dlist': '[' + self.account + '][CONVERT_DLIST] ', 'br_grps': '[' + self.account + '][BATCH_REMOVE_GROUPS] ', 'br_cts': '[' + self.account + '][BATCH_REMOVE_CONTACTS] ', 'br_cals': '[' + self.account + '][BATCH_REMOVE_CALENDARS] ', 'br_evts': '[' + self.account + '][BATCH_REMOVE_EVENTS] ', 'bi_grps': '[' + self.account + '][BATCH_INSERT_GROUPS] ', 'bi_cts': '[' + self.account + '][BATCH_INSERT_CONTACTS] ', 'bi_cals': '[' + self.account + '][BATCH_INSERT_CALENDARS] ', 'bi_evts': '[' + self.account + '][BATCH_INSERT_EVENTS] ', 'usr_update': '[' + self.account + '][USER_UPDATE] ', 'list_orgs': '[' + self.account + '][LIST_ORGANIZATIONS] ', 'user_info': '[' + self.account + '][USER_INFO] ', 'clean_prim': '[' + self.account + '][CLEAN_PRIMARY_CAL] ', 'ins_msg': '[' + self.account + '][INSERT_MESSAGE] ', 'gmail_info': '[' + self.account + '][GMAIL_INFO] ', 'gmail_conn': '[' + self.account + '][GMAIL_CONN] ', 'gmail_senders': '[' + self.account + '][GMAIL_SENDERS] ', } self.is_ok = True # If has access to Google API if validate(): # To access this account we need to delegate access using Google API if delegate(): try: # Calendar Token self._service_calendar = build('calendar', 'v3', http=self.dc.authorize(Http()), cache_discovery=False) # Contacts Token self.service_contacs = ContactsClient(source='contacts_handler') self.auth_token = gauth.OAuth2TokenFromCredentials(self.dc) self.auth_token.authorize(self.service_contacs) self.feed = '' except: logger.exception('Problem when trying to access ' + self.account + ' account, check it in the logs later.') else: print ('Problem when trying to access ' + self.account + ' account, check it in the logs later.') self.is_ok = False else: print ('Problem when trying to validate your credentials, check it in the logs later.') self.is_ok = False
class Google: def __init__(self, account): # noinspection PyUnresolvedReferences def delegate(): """ Function to access as another account using server-side credentials. :return: Boolean, True if successful. """ try: self.dc = self.credentials.create_delegated(self.account) return True except Exception as e: logger.exception("Unexpected error when trying to get permission to access this account") return False # noinspection PyUnresolvedReferences def validate(): """ Function to validate your server-side credentials, generating an access token. :return: Boolean, True if successful. """ is_ok = False self.credentials = ServiceAccountCredentials.from_json_keyfile_name(self.json, scopes=self.scopes) try: if not self.credentials: logger.error('Problem when trying to validate your credentials.') elif self.credentials.invalid: logger.error("Access denied, invalid credentials") else: is_ok = True return is_ok except: logger.exception("Problem when trying to validate your credentials.") return is_ok self.credentials = None self.calendar_list = None self.dc = None # Load Google credentials self.json = 'credentials/google.json' # Load all the Application Scope used to handle Calendar and Contacts self.scopes = ['https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/contacts', 'https://www.google.com/m8/feeds/', 'https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.orgunit.readonly', 'https://www.googleapis.com/auth/admin.directory.orgunit', 'https://www.googleapis.com/auth/apps.groups.migration', 'https://www.googleapis.com/auth/gmail.insert', 'https://www.googleapis.com/auth/gmail.labels', 'https://mail.google.com/', 'https://www.googleapis.com/auth/gmail.modify'] # Stores the User Account self.account = str(account) # ERROR CODE FOR LOGGING self.error_code = {'delegate': '[' + self.account + '][DELEGATE] ', 'validate': '[' + self.account + '][VALIDATE] ', 'create_cal': '[' + self.account + '][CREATE_CALENDAR] ', 'rem_cal': '[' + self.account + '][REMOVE_CALENDAR] ', 'list_cals': '[' + self.account + '][LIST_CALENDARS] ', 'create_evt': '[' + self.account + '][CREATE_EVENT] ', 'g_events': '[' + self.account + '][GET_EVENTS] ', 'g_cts': '[' + self.account + '][GET_CONTACTS] ', 'rem_ct': '[' + self.account + '][REMOVE_CONTACT] ', 'create_ct': '[' + self.account + '][CREATE_CONTACT] ', 'list_cts': '[' + self.account + '][LIST_CONTACTS] ', 'create_grp': '[' + self.account + '][CREATE_GROUP] ', 'list_grp': '[' + self.account + '][LIST_GROUPS] ', 'rem_grp': '[' + self.account + '][REMOVE_GROUP] ', 'format_ct': '[' + self.account + '][FORMAT_CONTACT] ', 'format_evt': '[' + self.account + '][FORMAT_EVENT] ', 'convert_dlist': '[' + self.account + '][CONVERT_DLIST] ', 'br_grps': '[' + self.account + '][BATCH_REMOVE_GROUPS] ', 'br_cts': '[' + self.account + '][BATCH_REMOVE_CONTACTS] ', 'br_cals': '[' + self.account + '][BATCH_REMOVE_CALENDARS] ', 'br_evts': '[' + self.account + '][BATCH_REMOVE_EVENTS] ', 'bi_grps': '[' + self.account + '][BATCH_INSERT_GROUPS] ', 'bi_cts': '[' + self.account + '][BATCH_INSERT_CONTACTS] ', 'bi_cals': '[' + self.account + '][BATCH_INSERT_CALENDARS] ', 'bi_evts': '[' + self.account + '][BATCH_INSERT_EVENTS] ', 'usr_update': '[' + self.account + '][USER_UPDATE] ', 'list_orgs': '[' + self.account + '][LIST_ORGANIZATIONS] ', 'user_info': '[' + self.account + '][USER_INFO] ', 'clean_prim': '[' + self.account + '][CLEAN_PRIMARY_CAL] ', 'ins_msg': '[' + self.account + '][INSERT_MESSAGE] ', 'gmail_info': '[' + self.account + '][GMAIL_INFO] ', 'gmail_conn': '[' + self.account + '][GMAIL_CONN] ', 'gmail_senders': '[' + self.account + '][GMAIL_SENDERS] ', } self.is_ok = True # If has access to Google API if validate(): # To access this account we need to delegate access using Google API if delegate(): try: # Calendar Token self._service_calendar = build('calendar', 'v3', http=self.dc.authorize(Http()), cache_discovery=False) # Contacts Token self.service_contacs = ContactsClient(source='contacts_handler') self.auth_token = gauth.OAuth2TokenFromCredentials(self.dc) self.auth_token.authorize(self.service_contacs) self.feed = '' except: logger.exception('Problem when trying to access ' + self.account + ' account, check it in the logs later.') else: print ('Problem when trying to access ' + self.account + ' account, check it in the logs later.') self.is_ok = False else: print ('Problem when trying to validate your credentials, check it in the logs later.') self.is_ok = False def is_connected(self): return self.is_ok def format_event_zimbra_to_google(self, evt,evt_attendees, timezone): """ Function to convert a Zimbra Calendar event into a Google Calendar event. :param evt: Zimbra Calendar's Event to be converted :param timezone: Zimbra Timezone obtained from the user account :return: Google Calendar event object """ try: new_event = {'anyoneCanAddSelf': False, } if 'ATTENDEE' in evt: new_event['attendees'] = [] responseStatus = 'declined' for attendee in evt_attendees: if self.account in attendee['email']: #remove owner continue if attendee['PARTSTAT'] == u'NEEDS-ACTION': responseStatus = 'needsAction' elif attendee['PARTSTAT'] == u'ACCEPTED': responseStatus = 'accepted' new_event['attendees'].append({'email': attendee['email'], 'responseStatus': responseStatus}) if 'DESCRIPTION' in evt: new_event['description'] = evt['DESCRIPTION'] if evt['SUMMARY']: new_event['summary'] = evt['SUMMARY'] if evt['LOCATION']: new_event['location'] = evt['LOCATION'] if evt['X-ALT-DESC']: new_event['description'] = evt['X-ALT-DESC'] if evt['DTSTART']: new_event['start'] = {'dateTime': evt['DTSTART'], 'timeZone': timezone, } if evt['DTEND']: new_event['end'] = {'dateTime': evt['DTEND'], 'timeZone': timezone, } new_event['visibility'] = 'default' if evt['CLASS']: if evt['CLASS'] == 'PUBLIC': new_event['visibility'] = 'public' else: new_event['visibility'] = 'default' if evt['TRANSP']: if evt['TRANSP'] == 'TRANSPARENT': new_event['transparency'] = 'transparent' else: new_event['transparency'] = 'opaque' if evt['RRULE']: raw_rules = "RRULE:" # Convert rules to Google format raw_rules += str(evt['RRULE']).strip('vRecur(') \ .replace("u'", "'") \ .replace("'", "") \ .replace(":", "=") \ .replace(" [", "") \ .replace("{", "") \ .replace("}", "") \ .replace("], ", ";") \ .replace("])", "") \ .replace(", ", ",") lista_rules = raw_rules.split(";") final_rules = "" for elem in lista_rules: if "datetime.datetime" in elem: aux_elem = elem.replace("datetime.datetime(", "").split(",") res_elem = aux_elem[0] for n in range(1, 5): if n == 3: res_elem += "T" if int(aux_elem[n]) < 10: res_elem += "0" + aux_elem[n] else: res_elem += aux_elem[n] res_elem += "00Z" final_rules += res_elem + ";" else: final_rules += elem + ";" new_event['recurrence'] = [final_rules.rstrip(";")] return new_event except: logger.exception("format_event_zimbra_to_google") return None def format_contact(self, cnt_entry, group_id): """ Function to convert a Zimbra Contact into a Google Contact. :param cnt_entry: Zimbra Contact to be converted. :param group_id: AddressBook id, to insert contact into it. :return: Google Contact object """ def display_name(uq): """ Internal Function to built the display_name :param uq: :return: String with display_name """ if 'nickname' in uq and uq['nickname'] != '': dn = uq['nickname'] elif 'fullName' in uq and uq['fullName'] != '': dn = uq['fullName'] elif uq['firstName'] != '' or uq['lastName'] != '': dn = uq.get('firstName','') + ' ' + uq.get('middleName','') + ' ' + uq.get('lastName','') else: dn = uq['email'] return dn def full_name(uq): """ Internal Function to built the full_name :param uq: :return: String with display_name """ full_name = uq.get('firstName','') + ' ' + uq.get('middleName','') + ' ' + uq.get('lastName','').strip() full_name = uq.get('fullName',full_name).strip() if not full_name or len(full_name)<2: full_name = uq.get('nickname', uq['email']) return full_name try: # Constructor new_contact google_contact = gdata.contacts.data.ContactEntry() zimbra_contact_default = cnt_entry['google_fields'] zimbra_contact_custom_fields = cnt_entry['custom_fields'] # Set the contact's email addresses. if zimbra_contact_default.get('email','') != '': google_contact.email.append(data.Email(address=zimbra_contact_default['email'], rel=gdata.data.WORK_REL, primary='true', display_name=display_name(zimbra_contact_default))) """else: err_ct = 'Impossible to register a contact without an e-mail ' + str(zimbra_contact_default) logger.info(self.error_code['create_ct'] + err_ct) return None, False""" # Set the contact's name google_contact.name = data.Name( given_name=data.GivenName(text=zimbra_contact_default['firstName']), family_name=data.FamilyName(text=zimbra_contact_default['lastName']), full_name=data.FullName(text=full_name(zimbra_contact_default)), name_prefix=data.NamePrefix(text=zimbra_contact_default['namePrefix'])) google_contact.content = atom.data.Content(text=zimbra_contact_default['notes']) if zimbra_contact_default['nickname'] != '': google_contact.nickname = gdata.contacts.data.NickName(text=zimbra_contact_default['nickname']) if zimbra_contact_default['birthday'] != '' and '-' in zimbra_contact_default['birthday']: google_contact.birthday = gdata.contacts.data.Birthday(when=zimbra_contact_default['birthday']) google_contact.organization = gdata.data.Organization( name=gdata.data.OrgName(text=zimbra_contact_default['company']), title=gdata.data.OrgTitle(text=zimbra_contact_default['jobTitle']), department=gdata.data.OrgDepartment(text=zimbra_contact_default['department']), rel=gdata.data.WORK_REL) # Set the contact's phone numbers. if zimbra_contact_default['workPhone'] != '': google_contact.phone_number.append(gdata.data.PhoneNumber(text=zimbra_contact_default['workPhone'], rel=gdata.data.WORK_REL, primary='true')) if zimbra_contact_default['homePhone'] != '': google_contact.phone_number.append(gdata.data.PhoneNumber(text=zimbra_contact_default['homePhone'], rel=gdata.data.HOME_REL)) if zimbra_contact_default['mobilePhone'] != '': google_contact.phone_number.append(gdata.data.PhoneNumber(text=zimbra_contact_default['mobilePhone'], rel=gdata.data.MOBILE_REL)) elif zimbra_contact_default['homePhone'] != '': google_contact.phone_number.append(gdata.data.PhoneNumber(text=zimbra_contact_default['homePhone'], rel=gdata.data.HOME_REL, primary='true')) if zimbra_contact_default['mobilePhone'] != '': google_contact.phone_number.append(gdata.data.PhoneNumber(text=zimbra_contact_default['mobilePhone'], rel=gdata.data.MOBILE_REL)) elif zimbra_contact_default['mobilePhone'] != '': google_contact.phone_number.append(gdata.data.PhoneNumber(text=zimbra_contact_default['mobilePhone'], rel=gdata.data.MOBILE_REL, primary='true')) # Set the contact's postal address. if (zimbra_contact_default['workCity'] != '' or zimbra_contact_default['workStreet'] != '' or zimbra_contact_default['workState'] != '' or zimbra_contact_default['workCountry'] != '' or zimbra_contact_default['workPostalCode'] != ''): google_contact.structured_postal_address.append(gdata.data.StructuredPostalAddress( rel=gdata.data.WORK_REL, primary='true', street=gdata.data.Street(text=zimbra_contact_default['workStreet']), city=gdata.data.City(text=zimbra_contact_default['workCity']), region=gdata.data.Region(text=zimbra_contact_default['workState']), postcode=gdata.data.Postcode(text=zimbra_contact_default['workPostalCode']), country=gdata.data.Country(text=zimbra_contact_default['workCountry']))) if (zimbra_contact_default['homeCity'] != '' or zimbra_contact_default['homeStreet'] != '' or zimbra_contact_default['homeState'] != '' or zimbra_contact_default['homeCountry'] != '' or zimbra_contact_default['homePostalCode'] != ''): google_contact.structured_postal_address.append(gdata.data.StructuredPostalAddress( rel=gdata.data.HOME_REL, street=gdata.data.Street(text=zimbra_contact_default['homeStreet']), city=gdata.data.City(text=zimbra_contact_default['homeCity']), region=gdata.data.Region(text=zimbra_contact_default['homeState']), postcode=gdata.data.Postcode(text=zimbra_contact_default['homePostalCode']), country=gdata.data.Country(text=zimbra_contact_default['homeCountry']))) elif (zimbra_contact_default['homeCity'] != '' or zimbra_contact_default['homeStreet'] != '' or zimbra_contact_default['homeState'] != '' or zimbra_contact_default['homeCountry'] != '' or zimbra_contact_default['homePostalCode'] != ''): google_contact.structured_postal_address.append(gdata.data.StructuredPostalAddress( rel=gdata.data.HOME_REL, primary='true', street=gdata.data.Street(text=zimbra_contact_default['homeStreet']), city=gdata.data.City(text=zimbra_contact_default['homeCity']), region=gdata.data.Region(text=zimbra_contact_default['homeState']), postcode=gdata.data.Postcode(text=zimbra_contact_default['homePostalCode']), country=gdata.data.Country(text=zimbra_contact_default['homeCountry']))) for item in zimbra_contact_custom_fields: google_contact.user_defined_field.append( gdata.contacts.data.UserDefinedField(key=item,value=zimbra_contact_custom_fields[item])) google_contact.group_membership_info.append(gdata.contacts.data.GroupMembershipInfo(href=group_id)) return google_contact, True except Exception as stdErr: logger.error(self.error_code['format_ct'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return None, False def create_calendar(self, cal, timezone, del_on_exists=False): """ Function to create a new Google Calendar. :param cal: String with Calendar name :param timezone: Default Timezone :return: Google Calendar Id """ calendar = { 'summary': cal, 'timeZone': timezone } try: created_calendar = self._service_calendar.calendars().insert(body=calendar).execute() msg_success = 'Calendar {0} successful created into {1}'.format(cal,self.account) logger.debug( msg_success) return created_calendar['id'] except gdata.client.RequestError as e: # if e.status == 412: err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['create_cal'] + err_gdata) logger.error(str(e)) return None except Exception as stdErr: logger.error(self.error_code['create_cal'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return None def remove_calendar(self, cal_id): """ Function to remove a Google Calendar. :param cal_id: Google Calendar Id :return: Boolean, True if successful. """ try: self._service_calendar.calendars().delete(calendarId=cal_id).execute() logger.info('Calendar removed as requested. Calendar ID: ' + str(cal_id)) return True except Exception as stdErr: err_remcal = 'Unexpected Error when trying to remove the calendar ' + str(cal_id) + ': ' + str(stdErr) logger.error(self.error_code['rem_cal'] + err_remcal) logger.error(traceback.format_exc()) return False def list_calendars(self): """ Function to list all Calendars from an account. :return: List of Google Calendars """ calendar_list = {} try: while True: calendarlist = self._service_calendar.calendarList().list().execute() for entry in calendarlist['items']: calendar_list[entry['id']] = entry['summary'] return calendar_list except Exception as stdErr: logger.error(self.error_code['list_cals'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return {} def get_events(self, calendarId): try: events_result = self._service_calendar.events().list(calendarId=calendarId).execute() events = events_result.get('items', []) if events: return events else: return None except Exception: logger.error(traceback.format_exc()) return None def delete_event(self, calendarId, eventId): try: self._service_calendar.events().delete(calendarId=calendarId, eventId=eventId).execute() except Exception: logger.error(traceback.format_exc()) return None def delete_cal(self, calendarId): """ Function to clean all events in the Google Calendar. :return: Boolean, True if successful """ try: evts = self.get_events(calendarId=calendarId) if not evts is None: for evt in evts: self.delete_event(calendarId=calendarId, eventId=evt['id']) sleep(0.050) self._service_calendar.calendars().delete(calendarId=calendarId).execute() return True except errors.HttpError as err: if err.resp.status == 404: return True raise except Exception: logger.exception("Error deleting calendar id[{id}] account[{account}]").format(id=calendarId,account=self.account) return False def create_event(self, evt, cal_id): """ Function to create a new event in a given Google Calendar. :param evt: New event, in Google Calendar format :param cal_id: Google Calendar Id :return: Boolean, True if successful """ try: # print cal_id, evt if evt: self._service_calendar.events().insert(calendarId=cal_id, body=evt).execute() return True else: logger.warning(self.error_code['create_evt'] + 'Empty event given, check it later.') return False except googleapiclient.errors.HttpError as e: err_gdata = 'Status: ' + str(e) logger.error(self.error_code['create_evt'] + err_gdata) return False except gdata.client.RequestError as e: # if e.status == 412: err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['create_evt'] + err_gdata) logger.error(str(e)) return False except Exception as stdErr: logger.error(self.error_code['create_evt'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return False def get_contacts(self, start_index=1, max_results=10000): """ Function that returns all contacts from the account. :param start_index: Query Start position, default to 1 :param max_results: Limit the number of results, default to 10000 :return: List of contacts """ try: query = gdata.contacts.client.ContactsQuery() query.max_results = max_results query.start_index = start_index feed = self.service_contacs.GetContacts(q=query) return feed except gdata.client.RequestError as e: # if e.status == 412: err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['g_cts'] + err_gdata) logger.error(str(e)) return None except Exception as stdErr: logger.error(self.error_code['g_cts'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return None def remove_contact(self, contact_url): """ Function to remove a given contact. :param contact_url: Contact URL used as id :return: Boolean, True if successful """ # Retrieving the contact is required in order to get the Etag. contact = self.service_contacs.GetContact(contact_url) try: self.service_contacs.Delete(contact) logger.info(self.error_code['rem_ct'] + 'Contact removed as requested: ' + str(contact_url)) return True except gdata.client.RequestError as e: err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['rem_ct'] + err_gdata) logger.error(str(e)) return False except Exception as stdErr: logger.error(self.error_code['rem_ct'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return False def create_contact(self, contact): """ Function to create a new contact in Google Contacts :param contact: new contact in Google Format. :return: Contact Entry Id """ try: # Send the contact data to the server. contact_entry = self.service_contacs.CreateContact(contact) return contact_entry except gdata.client.RequestError as e: # if e.status == 412: if e.status == 520: sleep(30) err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['create_ct'] + err_gdata) logger.error(str(e)) return None except Exception as stdErr: logger.error(self.error_code['create_ct'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return None def create_contact_group(self, addrbook, named_as=''): """ Function to create a new Contact Group in Google Contacts. :param addrbook: String of the Address Book to be created :param named_as: String with a extra info to be added to this Group name :return: Created Group using Google format """ try: group_name = '' if named_as != '': group_name += named_as + '_' group_name += addrbook new_group = gdata.contacts.data.GroupEntry(title=atom.data.Title(text=group_name)) created_group = self.service_contacs.CreateGroup(new_group) return created_group except: logger.exception("create_contact_group") return None def list_groups(self, start_index=1, max_results=10000): """ Function to list all Contact Groups from a given account. :param start_index: Query Start position, default to 1 :param max_results: Limit the number of results, default to 10000 :return: List of groups """ try: query = gdata.contacts.client.ContactsQuery() query.max_results = max_results query.start_index = start_index feed = self.service_contacs.GetGroups(q=query) group_list = [] for entry in feed.entry: if 'System Group' not in entry.title.text: group_list.append(entry) return group_list except gdata.client.RequestError as e: logger.exception("list_groups") return None except Exception as stdErr: logger.exception("list_groups") return None def remove_group(self, cgu): """ Function to remove a Contact Groups. :param cgu: String with the Contact Group URL :return: Boolean, True if successfully removed. """ try: group = self.service_contacs.GetGroup(cgu) self.service_contacs.Delete(group) return True except errors.HttpError as err: if err.resp.status == 404: return True except gdata.client.RequestError as e: if e.status == 404: return True err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['rem_grp'] + err_gdata) logger.error(str(e)) return False except Exception as stdErr: logger.error(self.error_code['rem_grp'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return False def convert_dlist(self, cnt_entry): """ Function to convert a Zimbra DList Contact into a Contact Group (with contacts) in Google Contacts. :param cnt_entry: Contact in Zimbra format :return: Boolean, True if Contact Group was successfully created. """ try: unique = cnt_entry['unique'] aux = [] # Get all e-mails in Zimbra Group of Contacts List distro_list = unique['dlist'].split(',') # Create a list using the Group of Contacts name group = self.create_group(unique['nickname'], named_as='listaDist') # insert as the first element the Group ID aux.append(group.id.text) # For each email in the Group of Contacts List insert as a new contact in the list just created for email in distro_list: if email != '': nc = gdata.contacts.data.ContactEntry() # Use E-mail info as the name in the Contact Entry nc.name = data.Name(full_name=data.FullName(text=email)) # Register Notes nc.content = atom.data.Content(text=unique['notes']) # Register E-mail info nc.email.append(data.Email(address=email, rel=gdata.data.HOME_REL, primary='true', display_name=email)) # Add this contact to the list that we just created. nc.group_membership_info.append(gdata.contacts.data.GroupMembershipInfo(href=group.id.text)) # Create contact. ce = self.service_contacs.CreateContact(nc) # Insert each contact created to a list aux.append(ce.id.text) # print "List_" + unique['nickname'] + "Contact's ID: %s" % ce.id.text else: info_create = 'Invalid e-mail ' + email + ' when processing account ' + self.account logger.warning(self.error_code['convert_dlist'] + info_create) # if cnt_entry['unique']['type'] != '': return True except Exception as stdErr: logger.error(self.error_code['convert_dlist'] + 'Unexpected Error: ' + str(stdErr)) logger.error(traceback.format_exc()) return False def batch_insert_events(self, evts, cal_id): """ Function to insert a list of events in a given calendar using batch mode. :param evts: List of events in Google Calendar format :param cal_id: Calendar to register all the events :returns Boolean, True if successful; List of events that fail to be created. """ failed_processing = 0 ok_processing = 0 def batch_handler(request_id, response, exception): """ Function to handle batch mode :param request_id: :param response: :param exception: """ nonlocal failed_processing nonlocal ok_processing # if exception is not None: if exception: # print 'Fail', request_id, response, exception err_msg = self.error_code['bi_evts'] + 'Failed to process: ' + str(request_id) err_msg += ', Reason: ' + str(exception) + ' ' + str(response) logger.error(err_msg) failed_processing +=1 #failed_processing.append((request_id, response, exception)) else: ok_processing +=1 pass try: batch = self._service_calendar.new_batch_http_request(callback=batch_handler) for evt in evts: batch.add(self._service_calendar.events().insert(calendarId=cal_id, body=evt)) batch.execute() sleep(1) return True, ok_processing, failed_processing except: logger.exception("batch_insert_events") return False, ok_processing, failed_processing def batch_insert_contacts(self, cl): """ Function to insert a pre-formatted list of contacts using batch mode. :param cl: :returns Boolean, True if successful; Response Feed """ # Feed that holds the batch request entries. request_feed = gdata.contacts.data.ContactsFeed() response_feed = None try: count = 0 for create_contact in cl: request_feed.AddInsert(entry=create_contact, batch_id_string=str(count)) count += 1 response_feed = self.service_contacs.ExecuteBatch(request_feed, 'https://www.google.com/m8/feeds/contacts/default/full/batch') sleep(0.300) return True, response_feed except gdata.client.RequestError as e: if e.status == 520: sleep(30) logger.exception("batch_insert_contacts status = 520") return False, response_feed except: logger.exception("batch_insert_contacts") return False, response_feed def batch_remove_contacts(self, cl): """ Function to remove list of contacts using batch mode. :param cl: :returns Boolean, True if successful; Response Feed """ def patched_post(client, entry, uri, auth_token=None, converter=None, desired_class=None, **kwargs): if converter is None and desired_class is None: desired_class = entry.__class__ http_request = atom.http_core.HttpRequest() entry_string = entry.to_string(gdata.client.get_xml_version(client.api_version)) entry_string = entry_string.replace('ns1=', 'gd=').replace('ns1:', 'gd:') http_request.add_body_part(entry_string, 'application/atom+xml') return client.request(method='POST', uri=uri, auth_token=auth_token, http_request=http_request, converter=converter, desired_class=desired_class, **kwargs) # Feed that holds the batch request entries. request_feed = gdata.contacts.data.ContactsFeed() response_feed = None try: count = 0 for contact in cl: request_feed.AddDelete(entry=contact, batch_id_string=str(count)) count += 1 response_feed = patched_post(self.service_contacs, request_feed, 'https://www.google.com/m8/feeds/contacts/default/full/batch') return True, response_feed except gdata.client.RequestError as e: # if e.status == 412: if e.status == 520: sleep(30) err_gdata = 'Status: ' + str(e.status) logger.error(self.error_code['br_cts'] + err_gdata) logger.error(str(e)) return False, response_feed except: logger.exception("batch_remove_contacts") return False, response_feed