Improve info|print users #1890

This commit is contained in:
Ross Scroggs
2026-03-11 15:13:21 -07:00
parent 9a981bf02e
commit 9d01e3fa27
3 changed files with 108 additions and 5 deletions

View File

@@ -5803,12 +5803,12 @@ gam download storagefile <StorageBucketObjectName>
<UserClearAttribute> ::=
(address clear)|
(otheremail clear)|
(externalid clear)|
(im clear)|
(keyword clear)|
(location clear)|
(organization clear)|
(otheremail clear)|
(phone clear)|
(posix clear)|
(relation clear)|
@@ -5821,6 +5821,18 @@ gam download storagefile <StorageBucketObjectName>
<UserMultiAttribute>|
<UserClearAttribute>
<UserMultiAttributeFilterName> ::=
address|addresses|
externalid|externalids|
im|ims|
keyword|keywords|
location|locations|
orgainzation|organizations|
otheremail|otheremails|
phone|phones|
relation|relations|
website|websites
gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable|alwaysevict]
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
@@ -5875,6 +5887,8 @@ gam info user [<UserItem>]
[nolicenses|nolicences|licenses|licences]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[formatjson]
@@ -5911,6 +5925,8 @@ gam info users <UserTypeEntity>
[nolicenses|nolicences|licenses|licences]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[formatjson]
@@ -5947,6 +5963,8 @@ gam <UserTypeEntity> info users
[nolicenses|nolicences|licenses|licences]
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
[userview] <UserFieldName>* [fields <UserFieldNameList>]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
[formatjson]
@@ -5966,6 +5984,8 @@ gam print users [todrive <ToDriveAttribute>*]
[schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -5983,6 +6003,8 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
[schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
@@ -5998,6 +6020,8 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
[schemas|custom|customschemas all|<SchemaNameList>]
[emailpart|emailparts|username]
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]

View File

@@ -1,7 +1,28 @@
7.35.04
7.36.00
Fixed bug in `gam create feature name <Name>` where the result was incorrectly shown as
`Building: <Name>, Added` instead of `Feature: <Name>, Added`.
Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and
`gam print users` that support filtering `<UserMultiAttribute>` display based on `type` or `customType`.
```
<UserMultiAttributeFilterName> ::=
address|addresses|
externalid|externalids|
im|ims|
keyword|keywords|
location|locations|
orgainzation|organizations|
otheremail|otheremails|
phone|phones|
relation|relations|
website|websites
```
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
```
gam info user user@domain.com quick filtermultiattrtype organizations work filtermultiattrcustom phones private
```
7.35.03

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.35.04'
__version__ = '7.36.00'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position
@@ -46726,10 +46726,58 @@ USER_FIELDS_CHOICE_MAP = {
'websites': 'websites',
}
USER_MULTI_ATTR_FILTER_CHOICE_MAP = {
'address': 'addresses',
'addresses': 'addresses',
'email': 'emails',
'emails': 'emails',
'externalid': 'externalIds',
'externalids': 'externalIds',
'im': 'ims',
'ims': 'ims',
'keyword': 'keywords',
'keywords': 'keywords',
'location': 'locations',
'locations': 'locations',
'organization': 'organizations',
'organizations': 'organizations',
'organisation': 'organizations',
'organisations': 'organizations',
'otheremail': 'emails',
'otheremails': 'emails',
'phone': 'phones',
'phones': 'phones',
'relation': 'relations',
'relations': 'relations',
'website': 'websites',
'websites': 'websites',
}
INFO_USER_OPTIONS = {'noaliases', 'nobuildingnames', 'nogroups', 'nolicenses', 'nolicences', 'noschemas', 'schemas', 'userview'}
USER_SKIP_OBJECTS = {'thumbnailPhotoEtag'}
USER_TIME_OBJECTS = {'creationTime', 'deletionTime', 'lastLoginTime'}
def _getUserMultiAttributeFilters(myarg, userMultiAttributeFilters):
up = getChoice(USER_MULTI_ATTR_FILTER_CHOICE_MAP, mapChoice=True)
filterValue = getString(Cmd.OB_STRING)
userMultiAttributeFilters.setdefault(up, [])
if myarg == 'filtermultiattrtype':
userMultiAttributeFilters[up].append({'type': filterValue})
else: #elif myarg == 'filtermultiattrcustom':
userMultiAttributeFilters[up].append({'customType': filterValue})
def _filterUserMultiAttributes(user, userMultiAttributeFilters):
for up, upTypes in userMultiAttributeFilters.items():
if up in user:
filterAttrList = []
for userAttr in user.pop(up):
for upType in upTypes:
if ((userAttr.get('type', None) == upType.get('type', '')) or
(userAttr.get('customType', None) == upType.get('customType', ''))):
filterAttrList.append(userAttr)
break
user[up] = filterAttrList
def _formatLanguagesList(propertyValue, delimiter):
languages = []
for language in propertyValue:
@@ -46824,6 +46872,7 @@ def infoUsers(entityList):
fieldsList = []
groups = []
memberships = []
userMultiAttributeFilters = {}
skus = SKU.getAllSKUs() if not GM.Globals[GM.LICENSE_SKUS] else GM.Globals[GM.LICENSE_SKUS]
while Cmd.ArgumentsRemaining():
myarg = getArgument()
@@ -46858,6 +46907,8 @@ def infoUsers(entityList):
getGroups = getLicenses = False
elif getFieldsList(myarg, USER_FIELDS_CHOICE_MAP, fieldsList):
pass
elif myarg in {'filtermultiattrtype', 'filtermultiattrcustom'}:
_getUserMultiAttributeFilters(myarg, userMultiAttributeFilters)
# Ignore info group arguments that may have come from whatis
elif myarg in INFO_GROUP_OPTIONS:
pass
@@ -46885,6 +46936,8 @@ def infoUsers(entityList):
throwReasons=GAPI.USER_GET_THROW_REASONS+[GAPI.INVALID_INPUT, GAPI.RESOURCE_NOT_FOUND],
userKey=userEmail, projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'],
viewType=viewType, fields=fields)
if userMultiAttributeFilters:
_filterUserMultiAttributes(user, userMultiAttributeFilters)
groups = []
memberships = []
if getGroups or getGroupsTree:
@@ -47322,6 +47375,8 @@ def doPrintUsers(entityList=None):
return
if showValidColumn:
userEntity[showValidColumn] = True
if userMultiAttributeFilters:
_filterUserMultiAttributes(userEntity, userMultiAttributeFilters)
userEmail = userEntity['primaryEmail']
if printOptions['emailParts']:
if userEmail.find('@') != -1:
@@ -47464,6 +47519,7 @@ def doPrintUsers(entityList=None):
showItemCountOnly = False
addCSVData = {}
includeCSVDataInJSON = False
userMultiAttributeFilters = {}
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -47543,6 +47599,8 @@ def doPrintUsers(entityList=None):
getAddCSVData(addCSVData)
elif myarg == 'includecsvdatainjson':
includeCSVDataInJSON = getBoolean()
elif myarg in {'filtermultiattrtype', 'filtermultiattrcustom'}:
_getUserMultiAttributeFilters(myarg, userMultiAttributeFilters)
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
_, _, entityList = getEntityArgument(entityList)