Пример #1
0
def printEvents():
    calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
    if not cal:
        return
    q = showDeleted = showHiddenInvitations = timeMin = \
        timeMax = timeZone = updatedMin = None
    toDrive = False
    titles = []
    csvRows = []
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'query':
            q = sys.argv[i + 1]
            i += 2
        elif myarg == 'includedeleted':
            showDeleted = True
            i += 1
        elif myarg == 'includehidden':
            showHiddenInvitations = True
            i += 1
        elif myarg == 'after':
            timeMin = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'before':
            timeMax = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'timezone':
            timeZone = sys.argv[i + 1]
            i += 2
        elif myarg == 'updated':
            updatedMin = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'todrive':
            toDrive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], 'gam calendar <email> printevents')
    page_message = gapi.got_total_items_msg(f'Events for {calendarId}', '')
    results = gapi.get_all_pages(cal.events(),
                                 'list',
                                 'items',
                                 page_message=page_message,
                                 calendarId=calendarId,
                                 q=q,
                                 showDeleted=showDeleted,
                                 showHiddenInvitations=showHiddenInvitations,
                                 timeMin=timeMin,
                                 timeMax=timeMax,
                                 timeZone=timeZone,
                                 updatedMin=updatedMin)
    for result in results:
        row = {'calendarId': calendarId}
        display.add_row_titles_to_csv_file(
            utils.flatten_json(result, flattened=row), csvRows, titles)
    display.sort_csv_titles(['calendarId', 'id', 'summary', 'status'], titles)
    display.write_csv_file(csvRows, titles, 'Calendar Events', toDrive)
Пример #2
0
 def _getRoleAndUsers():
     checkSuspended = None
     role = ROLE_MEMBER
     expireTime = None
     i = 5
     if sys.argv[i].lower() in GROUP_ROLES_MAP:
         role = GROUP_ROLES_MAP[sys.argv[i].lower()]
         i += 1
     if sys.argv[i].lower() in ['suspended', 'notsuspended']:
         checkSuspended = sys.argv[i].lower() == 'suspended'
         i += 1
     if sys.argv[i].lower() in ['expire', 'expires']:
         if role != ROLE_MEMBER:
             controlflow.invalid_argument_exit(sys.argv[i], f'role {role}')
         expireTime = utils.get_time_or_delta_from_now(sys.argv[i + 1])
         i += 2
     if sys.argv[i].lower() in usergroup_types:
         users_email = gam.getUsersToModify(entity_type=sys.argv[i].lower(),
                                            entity=sys.argv[i + 1],
                                            checkSuspended=checkSuspended,
                                            groupUserMembersOnly=False)
     else:
         users_email = [
             gam.normalizeEmailAddressOrUID(sys.argv[i],
                                            checkForCustomerId=True)
         ]
     return (role, expireTime, users_email)
Пример #3
0
def createtoken():
    cbcm = build()
    body = {'token_type': 'CHROME_BROWSER'}
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg in ['ou', 'orgunit', 'org']:
            body['org_unit_path'] = gapi_directory_orgunits.getOrgUnitItem(
                sys.argv[i + 1])
            i += 2
        elif myarg in ['expire', 'expires']:
            body['expire_time'] = utils.get_time_or_delta_from_now(sys.argv[i +
                                                                            1])
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam create browsertoken')
    browser = gapi.call(cbcm.enrollmentTokens(),
                        'create',
                        customer=GC_Values[GC_CUSTOMER_ID],
                        body=body)
    print(f'Created browser enrollment token {browser["token"]}')
Пример #4
0
def changeAttendees(users):
    do_it = True
    i = 5
    allevents = False
    start_date = end_date = None
    while len(sys.argv) > i:
        myarg = sys.argv[i].lower()
        if myarg == 'csv':
            csv_file = sys.argv[i + 1]
            i += 2
        elif myarg == 'dryrun':
            do_it = False
            i += 1
        elif myarg == 'start':
            start_date = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'end':
            end_date = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'allevents':
            allevents = True
            i += 1
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], 'gam <users> update calattendees')
    attendee_map = {}
    f = fileutils.open_file(csv_file)
    csvFile = csv.reader(f)
    for row in csvFile:
        attendee_map[row[0].lower()] = row[1].lower()
    fileutils.close_file(f)
    for user in users:
        sys.stdout.write(f'Checking user {user}\n')
        user, cal = buildCalendarGAPIObject(user)
        if not cal:
            continue
        page_token = None
        while True:
            events_page = gapi.call(cal.events(),
                                    'list',
                                    calendarId=user,
                                    pageToken=page_token,
                                    timeMin=start_date,
                                    timeMax=end_date,
                                    showDeleted=False,
                                    showHiddenInvitations=False)
            print(f'Got {len(events_page.get("items", []))}')
            for event in events_page.get('items', []):
                if event['status'] == 'cancelled':
                    # print u' skipping cancelled event'
                    continue
                try:
                    event_summary = event['summary']
                except (KeyError, UnicodeEncodeError, UnicodeDecodeError):
                    event_summary = event['id']
                try:
                    organizer = event['organizer']['email'].lower()
                    if not allevents and organizer != user:
                        #print(f' skipping not-my-event {event_summary}')
                        continue
                except KeyError:
                    pass  # no email for organizer
                needs_update = False
                try:
                    for attendee in event['attendees']:
                        try:
                            if attendee['email'].lower() in attendee_map:
                                old_email = attendee['email'].lower()
                                new_email = attendee_map[
                                    attendee['email'].lower()]
                                print(f' SWITCHING attendee {old_email} to ' \
                                    f'{new_email} for {event_summary}')
                                event['attendees'].remove(attendee)
                                event['attendees'].append({'email': new_email})
                                needs_update = True
                        except KeyError:  # no email for that attendee
                            pass
                except KeyError:
                    continue  # no attendees
                if needs_update:
                    body = {}
                    body['attendees'] = event['attendees']
                    print(f'UPDATING {event_summary}')
                    if do_it:
                        gapi.call(cal.events(),
                                  'patch',
                                  calendarId=user,
                                  eventId=event['id'],
                                  sendNotifications=False,
                                  body=body)
                    else:
                        print(' not pulling the trigger.')
                # else:
                #  print(f' no update needed for {event_summary}')
            try:
                page_token = events_page['nextPageToken']
            except KeyError:
                break
Пример #5
0
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'
    timeZone = None
    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'] = gam.getBoolean(
                sys.argv[i + 1], 'guestscaninviteothers')
            i += 2
        elif myarg == 'guestscantseeothers':
            body['guestsCanSeeOtherGuests'] = False
            i += 1
        elif myarg == 'guestscanseeothers':
            body['guestsCanSeeOtherGuests'] = gam.getBoolean(
                sys.argv[i + 1], 'guestscanseeothers')
            i += 2
        elif myarg == 'guestscanmodify':
            body['guestsCanModify'] = gam.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 = \
            gam.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'] = gam.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)
Пример #6
0
def showReport():
    rep = buildGAPIObject()
    throw_reasons = [gapi.errors.ErrorReason.INVALID]
    report = sys.argv[2].lower()
    report = REPORT_CHOICE_MAP.get(report.replace('_', ''), report)
    if report == 'usage':
        showUsage()
        return
    if report == 'usageparameters':
        showUsageParameters()
        return
    valid_apps = gapi.get_enum_values_minus_unspecified(
        rep._rootDesc['resources']['activities']['methods']['list']
        ['parameters']['applicationName']['enum']) + ['customer', 'user']
    if report not in valid_apps:
        controlflow.expected_argument_exit('report',
                                           ', '.join(sorted(valid_apps)),
                                           report)
    customerId = GC_Values[GC_CUSTOMER_ID]
    if customerId == MY_CUSTOMER:
        customerId = None
    filters = parameters = actorIpAddress = startTime = endTime = eventName = orgUnitId = None
    tryDate = datetime.date.today().strftime(YYYYMMDD_FORMAT)
    to_drive = False
    userKey = 'all'
    fullDataRequired = None
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if myarg == 'date':
            tryDate = utils.get_yyyymmdd(sys.argv[i + 1])
            i += 2
        elif myarg in ['orgunit', 'org', 'ou']:
            _, orgUnitId = gam.getOrgUnitId(sys.argv[i + 1])
            i += 2
        elif myarg == 'fulldatarequired':
            fullDataRequired = []
            fdr = sys.argv[i + 1].lower()
            if fdr and fdr == 'all':
                fullDataRequired = 'all'
            else:
                fullDataRequired = fdr.replace(',', ' ').split()
            i += 2
        elif myarg == 'start':
            startTime = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'end':
            endTime = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'event':
            eventName = sys.argv[i + 1]
            i += 2
        elif myarg == 'user':
            userKey = sys.argv[i + 1].lower()
            if userKey != 'all':
                userKey = gam.normalizeEmailAddressOrUID(sys.argv[i + 1])
            i += 2
        elif myarg in ['filter', 'filters']:
            filters = sys.argv[i + 1]
            i += 2
        elif myarg in ['fields', 'parameters']:
            parameters = sys.argv[i + 1]
            i += 2
        elif myarg == 'ip':
            actorIpAddress = sys.argv[i + 1]
            i += 2
        elif myarg == 'todrive':
            to_drive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i], 'gam report')
    if report == 'user':
        while True:
            try:
                one_page = gapi.call(rep.userUsageReport(),
                                     'get',
                                     throw_reasons=throw_reasons,
                                     date=tryDate,
                                     userKey=userKey,
                                     customerId=customerId,
                                     orgUnitID=orgUnitId,
                                     fields='warnings,usageReports',
                                     maxResults=1)
                warnings = one_page.get('warnings', [])
                has_reports = bool(one_page.get('usageReports'))
                fullData, tryDate = _check_full_data_available(
                    warnings, tryDate, fullDataRequired, has_reports)
                if fullData < 0:
                    print('No user report available.')
                    sys.exit(1)
                if fullData == 0:
                    continue
                page_message = gapi.got_total_items_msg('Users', '...\n')
                usage = gapi.get_all_pages(rep.userUsageReport(),
                                           'get',
                                           'usageReports',
                                           page_message=page_message,
                                           throw_reasons=throw_reasons,
                                           date=tryDate,
                                           userKey=userKey,
                                           customerId=customerId,
                                           orgUnitID=orgUnitId,
                                           filters=filters,
                                           parameters=parameters)
                break
            except gapi.errors.GapiInvalidError as e:
                tryDate = _adjust_date(str(e))
        if not usage:
            print('No user report available.')
            sys.exit(1)
        titles = ['email', 'date']
        csvRows = []
        for user_report in usage:
            if 'entity' not in user_report:
                continue
            row = {'email': user_report['entity']['userEmail'], 'date': tryDate}
            for item in user_report.get('parameters', []):
                if 'name' not in item:
                    continue
                name = item['name']
                if not name in titles:
                    titles.append(name)
                for ptype in REPORTS_PARAMETERS_SIMPLE_TYPES:
                    if ptype in item:
                        row[name] = item[ptype]
                        break
                else:
                    row[name] = ''
            csvRows.append(row)
        display.write_csv_file(csvRows, titles, f'User Reports - {tryDate}',
                               to_drive)
    elif report == 'customer':
        while True:
            try:
                first_page = gapi.call(rep.customerUsageReports(),
                                       'get',
                                       throw_reasons=throw_reasons,
                                       customerId=customerId,
                                       date=tryDate,
                                       fields='warnings,usageReports')
                warnings = first_page.get('warnings', [])
                has_reports = bool(first_page.get('usageReports'))
                fullData, tryDate = _check_full_data_available(
                    warnings, tryDate, fullDataRequired, has_reports)
                if fullData < 0:
                    print('No customer report available.')
                    sys.exit(1)
                if fullData == 0:
                    continue
                usage = gapi.get_all_pages(rep.customerUsageReports(),
                                           'get',
                                           'usageReports',
                                           throw_reasons=throw_reasons,
                                           customerId=customerId,
                                           date=tryDate,
                                           parameters=parameters)
                break
            except gapi.errors.GapiInvalidError as e:
                tryDate = _adjust_date(str(e))
        if not usage:
            print('No customer report available.')
            sys.exit(1)
        titles = ['name', 'value', 'client_id']
        csvRows = []
        auth_apps = list()
        for item in usage[0]['parameters']:
            if 'name' not in item:
                continue
            name = item['name']
            if 'intValue' in item:
                value = item['intValue']
            elif 'msgValue' in item:
                if name == 'accounts:authorized_apps':
                    for subitem in item['msgValue']:
                        app = {}
                        for an_item in subitem:
                            if an_item == 'client_name':
                                app['name'] = 'App: ' + \
                                    subitem[an_item].replace('\n', '\\n')
                            elif an_item == 'num_users':
                                app['value'] = f'{subitem[an_item]} users'
                            elif an_item == 'client_id':
                                app['client_id'] = subitem[an_item]
                        auth_apps.append(app)
                    continue
                values = []
                for subitem in item['msgValue']:
                    if 'count' in subitem:
                        mycount = myvalue = None
                        for key, value in list(subitem.items()):
                            if key == 'count':
                                mycount = value
                            else:
                                myvalue = value
                            if mycount and myvalue:
                                values.append(f'{myvalue}:{mycount}')
                        value = ' '.join(values)
                    elif 'version_number' in subitem \
                         and 'num_devices' in subitem:
                        values.append(f'{subitem["version_number"]}:'
                                      f'{subitem["num_devices"]}')
                    else:
                        continue
                    value = ' '.join(sorted(values, reverse=True))
            csvRows.append({'name': name, 'value': value})
        for app in auth_apps:  # put apps at bottom
            csvRows.append(app)
        display.write_csv_file(csvRows,
                               titles,
                               f'Customer Report - {tryDate}',
                               todrive=to_drive)
    else:
        page_message = gapi.got_total_items_msg('Activities', '...\n')
        activities = gapi.get_all_pages(rep.activities(),
                                        'list',
                                        'items',
                                        page_message=page_message,
                                        applicationName=report,
                                        userKey=userKey,
                                        customerId=customerId,
                                        actorIpAddress=actorIpAddress,
                                        startTime=startTime,
                                        endTime=endTime,
                                        eventName=eventName,
                                        filters=filters,
                                        orgUnitID=orgUnitId)
        if activities:
            titles = ['name']
            csvRows = []
            for activity in activities:
                events = activity['events']
                del activity['events']
                activity_row = utils.flatten_json(activity)
                purge_parameters = True
                for event in events:
                    for item in event.get('parameters', []):
                        if set(item) == set(['value', 'name']):
                            event[item['name']] = item['value']
                        elif set(item) == set(['intValue', 'name']):
                            if item['name'] in ['start_time', 'end_time']:
                                val = item.get('intValue')
                                if val is not None:
                                    val = int(val)
                                    if val >= 62135683200:
                                        event[item['name']] = \
                                            datetime.datetime.fromtimestamp(
                                                val-62135683200).isoformat()
                            else:
                                event[item['name']] = item['intValue']
                        elif set(item) == set(['boolValue', 'name']):
                            event[item['name']] = item['boolValue']
                        elif set(item) == set(['multiValue', 'name']):
                            event[item['name']] = ' '.join(item['multiValue'])
                        elif item['name'] == 'scope_data':
                            parts = {}
                            for message in item['multiMessageValue']:
                                for mess in message['parameter']:
                                    value = mess.get(
                                        'value',
                                        ' '.join(mess.get('multiValue', [])))
                                    parts[mess['name']] = parts.get(
                                        mess['name'], []) + [value]
                            for part, v in parts.items():
                                if part == 'scope_name':
                                    part = 'scope'
                                event[part] = ' '.join(v)
                        else:
                            purge_parameters = False
                    if purge_parameters:
                        event.pop('parameters', None)
                    row = utils.flatten_json(event)
                    row.update(activity_row)
                    for item in row:
                        if item not in titles:
                            titles.append(item)
                    csvRows.append(row)
            display.sort_csv_titles([
                'name',
            ], titles)
            display.write_csv_file(csvRows, titles,
                                   f'{report.capitalize()} Activity Report',
                                   to_drive)