From 9eb90ba7d7beda774b09a6e2bd9245ca0ec69a2c Mon Sep 17 00:00:00 2001 From: Ross Scroggs Date: Tue, 23 Oct 2018 07:49:49 -0700 Subject: [PATCH] Add Jay's changes group member delivery settings, check max sheet bytes on CSV upload --- src/GamCommands.txt | 7 ++-- src/gam.py | 89 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 66ad1315..4df007aa 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -962,13 +962,14 @@ gam print mobile [todrive] [(query )|(queries )] [ gam create group * gam update group [admincreated ] [email ] * -gam update group add [owner|manager|member] [notsuspended|suspended] +gam update group add [owner|manager|member] [notsuspended|suspended] [delivery allmail|daily|digest|none|noemail] gam update group delete|remove [owner|manager|member] -gam update group sync [owner|manager|member] [notsuspended|suspended] -gam update group update [owner|manager|member] +gam update group sync [owner|manager|member] [notsuspended|suspended] [delivery allmail|daily|digest|none|noemail] +gam update group update [owner|manager|member] [delivery allmail|daily|digest|none|noemail] gam update group clear [member] [manager] [owner] [notsuspended|suspended] gam delete group gam info group [nousers] [noaliases] [groups] +gam info member gam print groups [todrive] ([domain ] ([member ]|[query ]) [maxresults ] [allfields|([settings] * [fields ])] diff --git a/src/gam.py b/src/gam.py index fe1807a0..f8e9d1d9 100755 --- a/src/gam.py +++ b/src/gam.py @@ -8412,7 +8412,10 @@ GROUP_ROLES_MAP = { u'manager': ROLE_MANAGER, u'managers': ROLE_MANAGER, u'member': ROLE_MEMBER, u'members': ROLE_MEMBER, } - +MEMBER_DELIVERY_MAP = { + u'allmail': u'ALL_MAIL', u'digest': u'DIGEST', u'daily': u'DAILY', + u'abridged': u'DAILY', u'nomail': u'NONE', u'none': u'NONE' + } def doUpdateGroup(): # Convert foo@googlemail.com to foo@gmail.com; eliminate periods in name for foo.bar@gmail.com @@ -8428,7 +8431,8 @@ def doUpdateGroup(): def _getRoleAndUsers(): checkSuspended = None - role = ROLE_MEMBER + role = None + delivery = None i = 5 if sys.argv[i].lower() in GROUP_ROLES_MAP: role = GROUP_ROLES_MAP[sys.argv[i].lower()] @@ -8436,11 +8440,14 @@ def doUpdateGroup(): if sys.argv[i].lower() in [u'suspended', u'notsuspended']: checkSuspended = sys.argv[i].lower() == u'suspended' i += 1 + if sys.argv[i].lower().replace(u'_', u'') in MEMBER_DELIVERY_MAP: + delivery = MEMBER_DELIVERY_MAP[sys.argv[i].lower()] + i += 1 if sys.argv[i].lower() in usergroup_types: users_email = getUsersToModify(entity_type=sys.argv[i].lower(), entity=sys.argv[i+1], checkSuspended=checkSuspended, groupUserMembersOnly=False) else: users_email = [normalizeEmailAddressOrUID(sys.argv[i], checkForCustomerId=True)] - return (role, users_email) + return (role, users_email, delivery) cd = buildGAPIObject(u'directory') group = sys.argv[3] @@ -8449,27 +8456,37 @@ def doUpdateGroup(): if myarg in UPDATE_GROUP_SUBCMDS: group = normalizeEmailAddressOrUID(group) if myarg == u'add': - role, users_email = _getRoleAndUsers() + role, users_email, delivery = _getRoleAndUsers() + if not role: + role = ROLE_MEMBER if not checkGroupExists(cd, group): return if len(users_email) > 1: sys.stderr.write(u'Group: {0}, Will add {1} {2}s.\n'.format(group, len(users_email), role)) for user_email in users_email: - items.append(['gam', 'update', 'group', group, 'add', role, user_email]) + item = ['gam', 'update', 'group', group, 'add', role] + if delivery: + item.append(delivery) + item.append(user_email) + items.append(item) else: body = {u'role': role, u'email': users_email[0]} + add_text = [u'as %s' % role] + if delivery: + body[u'delivery_settings'] = delivery + add_text.append(u'delivery %s' % delivery) for i in range(2): try: callGAPI(cd.members(), u'insert', throw_reasons=[GAPI_DUPLICATE, GAPI_MEMBER_NOT_FOUND, GAPI_RESOURCE_NOT_FOUND, GAPI_INVALID_MEMBER, GAPI_CYCLIC_MEMBERSHIPS_NOT_ALLOWED], groupKey=group, body=body) - print u' Group: {0}, {1} Added as {2}'.format(group, users_email[0], role) + print u' Group: {0}, {1} Added {2}'.format(group, users_email[0], u' '.join(add_text)) break except GAPI_duplicate as e: # check if user is a full member, not pending try: result = callGAPI(cd.members(), u'get', throw_reasons=[GAPI_MEMBER_NOT_FOUND], memberKey=users_email[0], groupKey=group, fields=u'role') - print u' Group: {0}, {1} Add as {2} Failed: Duplicate, already a {3}'.format(group, users_email[0], role, result[u'role']) + print u' Group: {0}, {1} Add {2} Failed: Duplicate, already a {3}'.format(group, users_email[0], u' '.join(add_text), result[u'role']) break # if get succeeds, user is a full member and we throw duplicate error except GAPI_memberNotFound: # insert fails on duplicate and get fails on not found, user is pending @@ -8477,12 +8494,12 @@ def doUpdateGroup(): callGAPI(cd.members(), u'delete', memberKey=users_email[0], groupKey=group) continue # 2nd insert should succeed now that pending is clear except (GAPI_memberNotFound, GAPI_resourceNotFound, GAPI_invalidMember, GAPI_cyclicMembershipsNotAllowed) as e: - print u' Group: {0}, {1} Add as {2} Failed: {3}'.format(group, users_email[0], role, str(e)) + print u' Group: {0}, {1} Add {2} Failed: {3}'.format(group, users_email[0], u' '.join(add_text), str(e)) break elif myarg == u'sync': syncMembersSet = set() syncMembersMap = {} - role, users_email = _getRoleAndUsers() + role, users_email, delivery = _getRoleAndUsers() for user_email in users_email: if user_email == u'*' or user_email == GC_Values[GC_CUSTOMER_ID]: syncMembersSet.add(GC_Values[GC_CUSTOMER_ID]) @@ -8502,15 +8519,21 @@ def doUpdateGroup(): to_remove = [currentMembersMap.get(emailAddress, emailAddress) for emailAddress in currentMembersSet-syncMembersSet] sys.stderr.write(u'Group: {0}, Will add {1} and remove {2} {3}s.\n'.format(group, len(to_add), len(to_remove), role)) for user in to_add: - items.append([u'gam', u'update', u'group', group, u'add', role, user]) + item = [u'gam', u'update', u'group', group, u'add'] + if role: + item.append(role) + if delivery: + item.append(delivery) + item.append(user) + items.append(item) for user in to_remove: items.append([u'gam', u'update', u'group', group, u'remove', user]) elif myarg in [u'delete', u'remove']: - role, users_email = _getRoleAndUsers() + _, users_email, _ = _getRoleAndUsers() if not checkGroupExists(cd, group): return if len(users_email) > 1: - sys.stderr.write(u'Group: {0}, Will remove {1} {2}s.\n'.format(group, len(users_email), role)) + sys.stderr.write(u'Group: {0}, Will remove {1} emails.\n'.format(group, len(users_email))) for user_email in users_email: items.append(['gam', 'update', 'group', group, 'remove', user_email]) else: @@ -8522,20 +8545,33 @@ def doUpdateGroup(): except (GAPI_memberNotFound, GAPI_invalidMember) as e: print u' Group: {0}, {1} Remove Failed: {2}'.format(group, users_email[0], str(e)) elif myarg == u'update': - role, users_email = _getRoleAndUsers() + role, users_email, delivery = _getRoleAndUsers() group = checkGroupExists(cd, group) if group: if len(users_email) > 1: sys.stderr.write(u'Group: {0}, Will update {1} {2}s.\n'.format(group, len(users_email), role)) for user_email in users_email: - items.append(['gam', 'update', 'group', group, 'update', role, user_email]) + item = ['gam', 'update', 'group', group, 'update'] + if role: + item.append(role) + if delivery: + item.append(delivery) + item.append(user_email) + items.append(item) else: - body = {u'role': role} + body = {} + update_text = [] + if role: + body[u'role'] = role + update_text.append(u'to %s' % role) + if delivery: + body[u'delivery_settings'] = delivery + update_text.append(u'delivery %s' % delivery) try: callGAPI(cd.members(), u'update', throw_reasons=[GAPI_MEMBER_NOT_FOUND, GAPI_INVALID_MEMBER], groupKey=group, memberKey=users_email[0], body=body) - print u' Group: {0}, {1} Updated to {2}'.format(group, users_email[0], role) + print u' Group: {0}, {1} Updated {2}'.format(group, users_email[0], u' '.join(update_text)) except (GAPI_memberNotFound, GAPI_invalidMember) as e: print u' Group: {0}, {1} Update to {2} Failed: {3}'.format(group, users_email[0], role, str(e)) else: # clear @@ -8568,6 +8604,9 @@ def doUpdateGroup(): page_message=page_message, throw_reasons=GAPI_MEMBERS_THROW_REASONS, groupKey=group, roles=listRoles, fields=listFields, maxResults=GC_Values[GC_MEMBER_MAX_RESULTS]) + if not result: + print u'Group already has 0 members' + return if checkSuspended is None: users_email = [member.get(u'email', member[u'id']) for member in result if not validRoles or member.get(u'role', ROLE_MEMBER) in validRoles] elif checkSuspended: @@ -9012,6 +9051,13 @@ def _getValueFromOAuth(field, credentials=None): credentials = credentials if credentials is not None else getValidOauth2TxtCredentials() return credentials.id_token.get(field, u'Unknown') +def doGetMemberInfo(): + cd = buildGAPIObject(u'directory') + memberKey = normalizeEmailAddressOrUID(sys.argv[3]) + groupKey = normalizeEmailAddressOrUID(sys.argv[4]) + info = callGAPI(cd.members(), u'get', memberKey=memberKey, groupKey=groupKey) + print_json(None, info) + def doGetUserInfo(user_email=None): def user_lic_result(request_id, response, exception): @@ -10275,13 +10321,11 @@ def writeCSVfile(csvRows, titles, list_type, todrive): except IOError as e: systemErrorExit(6, e) if todrive: + data_size = string_file.len columns = len(titles) rows = len(csvRows) cell_count = rows * columns mimeType = u'application/vnd.google-apps.spreadsheet' - if cell_count > 2000000 or columns > 256: - print u'{0}{1}'.format(WARNING_PREFIX, MESSAGE_RESULTS_TOO_LARGE_FOR_GOOGLE_SPREADSHEET) - mimeType = u'text/csv' admin_email = _getValueFromOAuth(u'email') _, drive = buildDrive3GAPIObject(admin_email) if not drive: @@ -10291,6 +10335,11 @@ gam user %s check serviceaccount and follow recommend steps to authorize GAM for Drive access.''' % (admin_email) sys.exit(5) + result = callGAPI(drive.about(), u'get', fields=u'maxImportSizes') + max_sheet_bytes = int(result[u'maxImportSizes'][u'application/vnd.google-apps.spreadsheet']) + if cell_count > 2000000 or columns > 256 or data_size > max_sheet_bytes: + print u'{0}{1}'.format(WARNING_PREFIX, MESSAGE_RESULTS_TOO_LARGE_FOR_GOOGLE_SPREADSHEET) + mimeType = u'text/csv' body = {u'description': u' '.join(sys.argv), u'name': u'%s - %s' % (GC_Values[GC_DOMAIN], list_type), u'mimeType': mimeType} @@ -12584,6 +12633,8 @@ def ProcessGAMCommand(args): doGetUserInfo() elif argument == u'group': doGetGroupInfo() + elif argument == u'member': + doGetMemberInfo() elif argument in [u'nickname', u'alias']: doGetAliasInfo() elif argument == u'instance':