def addACL(function): calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2]) if not cal: return myarg = sys.argv[4].lower().replace('_', '') if myarg not in CALENDAR_ACL_ROLES_MAP: controlflow.expected_argument_exit("Role", ", ".join(CALENDAR_ACL_ROLES_MAP), myarg) body = {'role': CALENDAR_ACL_ROLES_MAP[myarg]} i = _getCalendarACLScope(5, body) sendNotifications = True while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'sendnotifications': sendNotifications = __main__.getBoolean(sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit( sys.argv[i], f"gam calendar <email> {function.lower()}") print(f'Calendar: {calendarId}, {function} ACL: {formatACLRule(body)}') gapi.call(cal.acl(), 'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications)
def transferSecCals(users): target_user = sys.argv[5] remove_source_user = sendNotifications = True i = 6 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'keepuser': remove_source_user = False i += 1 elif myarg == 'sendnotifications': sendNotifications = __main__.getBoolean(sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], "gam <users> transfer seccals") if remove_source_user: target_user, target_cal = buildCalendarGAPIObject(target_user) if not target_cal: return for user in users: user, source_cal = buildCalendarGAPIObject(user) if not source_cal: continue calendars = gapi.get_all_pages(source_cal.calendarList(), 'list', 'items', soft_errors=True, minAccessRole='owner', showHidden=True, fields='items(id),nextPageToken') for calendar in calendars: calendarId = calendar['id'] if calendarId.find('@group.calendar.google.com') != -1: body = { 'role': 'owner', 'scope': { 'type': 'user', 'value': target_user } } gapi.call(source_cal.acl(), 'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications) if remove_source_user: body = { 'role': 'none', 'scope': { 'type': 'user', 'value': user } } gapi.call(target_cal.acl(), 'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications)
def getSendUpdates(myarg, i, cal): if myarg == 'notifyattendees': sendUpdates = 'all' i += 1 elif myarg == 'sendnotifications': sendUpdates = 'all' if __main__.getBoolean(sys.argv[i+1], myarg) else 'none' i += 2 else: # 'sendupdates': sendUpdatesMap = {} for val in cal._rootDesc['resources']['events']['methods']['delete'][ 'parameters']['sendUpdates']['enum']: sendUpdatesMap[val.lower()] = val sendUpdates = sendUpdatesMap.get(sys.argv[i+1].lower(), False) if not sendUpdates: controlflow.expected_argument_exit( "sendupdates", ", ".join(sendUpdatesMap), sys.argv[i+1]) i += 2 return (sendUpdates, i)
def getCalendarAttributes(i, body, function): colorRgbFormat = False while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'selected': body['selected'] = __main__.getBoolean(sys.argv[i + 1], myarg) i += 2 elif myarg == 'hidden': body['hidden'] = __main__.getBoolean(sys.argv[i + 1], myarg) i += 2 elif myarg == 'summary': body['summaryOverride'] = sys.argv[i + 1] i += 2 elif myarg == 'colorindex': body['colorId'] = __main__.getInteger( sys.argv[i + 1], myarg, minVal=CALENDAR_MIN_COLOR_INDEX, maxVal=CALENDAR_MAX_COLOR_INDEX) i += 2 elif myarg == 'backgroundcolor': body['backgroundColor'] = __main__.getColor(sys.argv[i + 1]) colorRgbFormat = True i += 2 elif myarg == 'foregroundcolor': body['foregroundColor'] = __main__.getColor(sys.argv[i + 1]) colorRgbFormat = True i += 2 elif myarg == 'reminder': body.setdefault('defaultReminders', []) method = sys.argv[i + 1].lower() if method not in CLEAR_NONE_ARGUMENT: if method not in CALENDAR_REMINDER_METHODS: controlflow.expected_argument_exit( "Method", ", ".join(CALENDAR_REMINDER_METHODS + CLEAR_NONE_ARGUMENT), method) minutes = __main__.getInteger( sys.argv[i + 2], myarg, minVal=0, maxVal=CALENDAR_REMINDER_MAX_MINUTES) body['defaultReminders'].append({ 'method': method, 'minutes': minutes }) i += 3 else: i += 2 elif myarg == 'notification': body.setdefault('notificationSettings', {'notifications': []}) method = sys.argv[i + 1].lower() if method not in CLEAR_NONE_ARGUMENT: if method not in CALENDAR_NOTIFICATION_METHODS: controlflow.expected_argument_exit( "Method", ", ".join(CALENDAR_NOTIFICATION_METHODS + CLEAR_NONE_ARGUMENT), method) eventType = sys.argv[i + 2].lower() if eventType not in CALENDAR_NOTIFICATION_TYPES_MAP: controlflow.expected_argument_exit( "Event", ", ".join(CALENDAR_NOTIFICATION_TYPES_MAP), eventType) notice = { 'method': method, 'type': CALENDAR_NOTIFICATION_TYPES_MAP[eventType] } body['notificationSettings']['notifications'].append(notice) i += 3 else: i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], f"gam {function} calendar") return colorRgbFormat
def getEventAttributes(i, calendarId, cal, body, action): # Default to external only so non-Google # calendars are notified of changes sendUpdates = 'externalOnly' action = 'update' if body else 'add' while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg in ['notifyattendees', 'sendnotifications', 'sendupdates']: sendUpdates, i = getSendUpdates(myarg, i, cal) elif myarg == 'attendee': body.setdefault('attendees', []) body['attendees'].append({'email': sys.argv[i + 1]}) i += 2 elif myarg == 'removeattendee' and action == 'update': remove_email = sys.argv[i + 1].lower() if 'attendees' in body: body['attendees'] = _remove_attendee(body['attendees'], remove_email) i += 2 elif myarg == 'optionalattendee': body.setdefault('attendees', []) body['attendees'].append({ 'email': sys.argv[i + 1], 'optional': True }) i += 2 elif myarg == 'anyonecanaddself': body['anyoneCanAddSelf'] = True i += 1 elif myarg == 'description': body['description'] = sys.argv[i + 1].replace('\\n', '\n') i += 2 elif myarg == 'replacedescription' and action == 'update': search = sys.argv[i + 1] replace = sys.argv[i + 2] if 'description' in body: body['description'] = re.sub(search, replace, body['description']) i += 3 elif myarg == 'start': if sys.argv[i + 1].lower() == 'allday': body['start'] = {'date': utils.get_yyyymmdd(sys.argv[i + 2])} i += 3 else: start_time = utils.get_time_or_delta_from_now(sys.argv[i + 1]) body['start'] = {'dateTime': start_time} i += 2 elif myarg == 'end': if sys.argv[i + 1].lower() == 'allday': body['end'] = {'date': utils.get_yyyymmdd(sys.argv[i + 2])} i += 3 else: end_time = utils.get_time_or_delta_from_now(sys.argv[i + 1]) body['end'] = {'dateTime': end_time} i += 2 elif myarg == 'guestscantinviteothers': body['guestsCanInviteOthers'] = False i += 1 elif myarg == 'guestscaninviteothers': body['guestsCanInviteTohters'] = __main__.getBoolean( sys.argv[i + 1], 'guestscaninviteothers') i += 2 elif myarg == 'guestscantseeothers': body['guestsCanSeeOtherGuests'] = False i += 1 elif myarg == 'guestscanseeothers': body['guestsCanSeeOtherGuests'] = __main__.getBoolean( sys.argv[i + 1], 'guestscanseeothers') i += 2 elif myarg == 'guestscanmodify': body['guestsCanModify'] = __main__.getBoolean( sys.argv[i + 1], 'guestscanmodify') i += 2 elif myarg == 'id': if action == 'update': controlflow.invalid_argument_exit( 'id', 'gam calendar <calendar> updateevent') body['id'] = sys.argv[i + 1] i += 2 elif myarg == 'summary': body['summary'] = sys.argv[i + 1] i += 2 elif myarg == 'location': body['location'] = sys.argv[i + 1] i += 2 elif myarg == 'available': body['transparency'] = 'transparent' i += 1 elif myarg == 'transparency': validTransparency = ['opaque', 'transparent'] if sys.argv[i + 1].lower() in validTransparency: body['transparency'] = sys.argv[i + 1].lower() else: controlflow.expected_argument_exit( 'transparency', ", ".join(validTransparency), sys.argv[i + 1]) i += 2 elif myarg == 'visibility': validVisibility = ['default', 'public', 'private'] if sys.argv[i + 1].lower() in validVisibility: body['visibility'] = sys.argv[i + 1].lower() else: controlflow.expected_argument_exit("visibility", ", ".join(validVisibility), sys.argv[i + 1]) i += 2 elif myarg == 'tentative': body['status'] = 'tentative' i += 1 elif myarg == 'status': validStatus = ['confirmed', 'tentative', 'cancelled'] if sys.argv[i + 1].lower() in validStatus: body['status'] = sys.argv[i + 1].lower() else: controlflow.expected_argument_exit('visibility', ', '.join(validStatus), sys.argv[i + 1]) i += 2 elif myarg == 'source': body['source'] = {'title': sys.argv[i + 1], 'url': sys.argv[i + 2]} i += 3 elif myarg == 'noreminders': body['reminders'] = {'useDefault': False} i += 1 elif myarg == 'reminder': minutes = \ __main__.getInteger(sys.argv[i+1], myarg, minVal=0, maxVal=CALENDAR_REMINDER_MAX_MINUTES) reminder = {'minutes': minutes, 'method': sys.argv[i + 2]} body.setdefault('reminders', { 'overrides': [], 'useDefault': False }) body['reminders']['overrides'].append(reminder) i += 3 elif myarg == 'recurrence': body.setdefault('recurrence', []) body['recurrence'].append(sys.argv[i + 1]) i += 2 elif myarg == 'timezone': timeZone = sys.argv[i + 1] i += 2 elif myarg == 'privateproperty': if 'extendedProperties' not in body: body['extendedProperties'] = {'private': {}, 'shared': {}} body['extendedProperties']['private'][sys.argv[i + 1]] = sys.argv[i + 2] i += 3 elif myarg == 'sharedproperty': if 'extendedProperties' not in body: body['extendedProperties'] = {'private': {}, 'shared': {}} body['extendedProperties']['shared'][sys.argv[i + 1]] = sys.argv[i + 2] i += 3 elif myarg == 'colorindex': body['colorId'] = __main__.getInteger( sys.argv[i + 1], myarg, CALENDAR_EVENT_MIN_COLOR_INDEX, CALENDAR_EVENT_MAX_COLOR_INDEX) i += 2 elif myarg == 'hangoutsmeet': body['conferenceData'] = { 'createRequest': { 'requestId': f'{str(uuid.uuid4())}' } } i += 1 else: controlflow.invalid_argument_exit( sys.argv[i], f'gam calendar <email> {action}event') if ('recurrence' in body) and (('start' in body) or ('end' in body)): if not timeZone: timeZone = gapi.call(cal.calendars(), 'get', calendarId=calendarId, fields='timeZone')['timeZone'] if 'start' in body: body['start']['timeZone'] = timeZone if 'end' in body: body['end']['timeZone'] = timeZone return (sendUpdates, body)
def createExport(): v = buildGAPIObject() allowed_corpuses = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['Query']['properties']['corpus']['enum']) allowed_scopes = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['Query']['properties']['dataScope']['enum']) allowed_formats = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['MailExportOptions']['properties'] ['exportFormat']['enum']) export_format = 'MBOX' showConfidentialModeContent = None # default to not even set matterId = None body = {'query': {'dataScope': 'ALL_DATA'}, 'exportOptions': {}} i = 3 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'matter': matterId = getMatterItem(v, sys.argv[i+1]) body['matterId'] = matterId i += 2 elif myarg == 'name': body['name'] = sys.argv[i+1] i += 2 elif myarg == 'corpus': body['query']['corpus'] = sys.argv[i+1].upper() if body['query']['corpus'] not in allowed_corpuses: controlflow.expected_argument_exit( "corpus", ", ".join(allowed_corpuses), sys.argv[i+1]) i += 2 elif myarg in VAULT_SEARCH_METHODS_MAP: if body['query'].get('searchMethod'): message = f'Multiple search methods ' \ f'({", ".join(VAULT_SEARCH_METHODS_LIST)})' \ f'specified, only one is allowed' controlflow.system_error_exit(3, message) searchMethod = VAULT_SEARCH_METHODS_MAP[myarg] body['query']['searchMethod'] = searchMethod if searchMethod == 'ACCOUNT': body['query']['accountInfo'] = { 'emails': sys.argv[i+1].split(',')} i += 2 elif searchMethod == 'ORG_UNIT': body['query']['orgUnitInfo'] = { 'orgUnitId': __main__.getOrgUnitId(sys.argv[i+1])[1]} i += 2 elif searchMethod == 'SHARED_DRIVE': body['query']['sharedDriveInfo'] = { 'sharedDriveIds': sys.argv[i+1].split(',')} i += 2 elif searchMethod == 'ROOM': body['query']['hangoutsChatInfo'] = { 'roomId': sys.argv[i+1].split(',')} i += 2 else: i += 1 elif myarg == 'scope': body['query']['dataScope'] = sys.argv[i+1].upper() if body['query']['dataScope'] not in allowed_scopes: controlflow.expected_argument_exit( "scope", ", ".join(allowed_scopes), sys.argv[i+1]) i += 2 elif myarg in ['terms']: body['query']['terms'] = sys.argv[i+1] i += 2 elif myarg in ['start', 'starttime']: body['query']['startTime'] = utils.get_date_zero_time_or_full_time( sys.argv[i+1]) i += 2 elif myarg in ['end', 'endtime']: body['query']['endTime'] = utils.get_date_zero_time_or_full_time( sys.argv[i+1]) i += 2 elif myarg in ['timezone']: body['query']['timeZone'] = sys.argv[i+1] i += 2 elif myarg in ['excludedrafts']: body['query']['mailOptions'] = { 'excludeDrafts': __main__.getBoolean(sys.argv[i+1], myarg)} i += 2 elif myarg in ['driveversiondate']: body['query'].setdefault('driveOptions', {})['versionDate'] = \ utils.get_date_zero_time_or_full_time(sys.argv[i+1]) i += 2 elif myarg in ['includeshareddrives', 'includeteamdrives']: body['query'].setdefault('driveOptions', {})[ 'includeSharedDrives'] = __main__.getBoolean(sys.argv[i+1], myarg) i += 2 elif myarg in ['includerooms']: body['query']['hangoutsChatOptions'] = { 'includeRooms': __main__.getBoolean(sys.argv[i+1], myarg)} i += 2 elif myarg in ['format']: export_format = sys.argv[i+1].upper() if export_format not in allowed_formats: controlflow.expected_argument_exit( "export format", ", ".join(allowed_formats), export_format) i += 2 elif myarg in ['showconfidentialmodecontent']: showConfidentialModeContent = __main__.getBoolean(sys.argv[i+1], myarg) i += 2 elif myarg in ['region']: allowed_regions = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['ExportOptions']['properties'][ 'region']['enum']) body['exportOptions']['region'] = sys.argv[i+1].upper() if body['exportOptions']['region'] not in allowed_regions: controlflow.expected_argument_exit("region", ", ".join( allowed_regions), body['exportOptions']['region']) i += 2 elif myarg in ['includeaccessinfo']: body['exportOptions'].setdefault('driveOptions', {})[ 'includeAccessInfo'] = __main__.getBoolean(sys.argv[i+1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], "gam create export") if not matterId: controlflow.system_error_exit( 3, 'you must specify a matter for the new export.') if 'corpus' not in body['query']: controlflow.system_error_exit(3, f'you must specify a corpus for the ' \ f'new export. Choose one of {", ".join(allowed_corpuses)}') if 'searchMethod' not in body['query']: controlflow.system_error_exit(3, f'you must specify a search method ' \ 'for the new export. Choose one of ' \ f'{", ".join(VAULT_SEARCH_METHODS_LIST)}') if 'name' not in body: corpus_name = body["query"]["corpus"] corpus_date = datetime.datetime.now() body['name'] = f'GAM {corpus_name} export - {corpus_date}' options_field = None if body['query']['corpus'] == 'MAIL': options_field = 'mailOptions' elif body['query']['corpus'] == 'GROUPS': options_field = 'groupsOptions' elif body['query']['corpus'] == 'HANGOUTS_CHAT': options_field = 'hangoutsChatOptions' if options_field: body['exportOptions'].pop('driveOptions', None) body['exportOptions'][options_field] = {'exportFormat': export_format} if showConfidentialModeContent is not None: body['exportOptions'][options_field][ 'showConfidentialModeContent'] = showConfidentialModeContent results = gapi.call(v.matters().exports(), 'create', matterId=matterId, body=body) print(f'Created export {results["id"]}') display.print_json(results)