From 5a335fb57bb56e04ee428e21eed5c2abf0c45ec6 Mon Sep 17 00:00:00 2001 From: Ross Scroggs Date: Wed, 29 May 2024 10:49:31 -0700 Subject: [PATCH] Updated `` to allow schema fields --- docs/Basic-Items.md | 5 + docs/GamUpdates.md | 6 + docs/How-to-Upgrade-from-Standard-GAM.md | 4 +- docs/List-Items.md | 2 +- docs/Users.md | 19 ++- docs/Version-and-Help.md | 12 +- src/GamCommands.txt | 19 +-- src/GamUpdate.txt | 6 + src/gam/__init__.py | 172 ++++++++++++++--------- 9 files changed, 153 insertions(+), 92 deletions(-) diff --git a/docs/Basic-Items.md b/docs/Basic-Items.md index d7ccbad9..a84b86c9 100644 --- a/docs/Basic-Items.md +++ b/docs/Basic-Items.md @@ -457,6 +457,7 @@ ::= ::= ::= + ::= .
::= ::= (sig|signature|htmlsig )| @@ -513,6 +514,7 @@ ::= <String> <ToDriveAttribute> ::= (tdaddsheet [<Boolean>])| + (tdalert <EmailAddress>)*| (tdbackupsheet (id:<Number>)|<String>)| (tdcellnumberformat text|number)| (tdcellwrap clip|overflow|wrap)| @@ -520,17 +522,20 @@ (tdcopysheet (id:<Number>)|<String>)| (tddescription <String>)| (tdfileid <DriveFileID>)| + (tdfrom <EmailAddress>)| (tdlocalcopy [<Boolean>])| (tdlocale <Locale>)| (tdnobrowser [<Boolean>])| (tdnoemail [<Boolean>])| (tdnoescapechar [<Boolean>])| + (tdnotify [<Boolean>])| (tdparent (id:<DriveFolderID>)|<DriveFolderName>)| (tdretaintitle [<Boolean>])| (tdshare <EmailAddress> commenter|reader|writer)*| (tdsheet (id:<Number>)|<String>)| (tdsheettimestamp [<Boolean>] [tdsheettimeformat <String>]) (tdsheettitle <String>)| + (tdsubject <String>)| ([tdsheetdaysoffset <Number>] [tdsheethoursoffset <Number>])| (tdtimestamp [<Boolean>] [tdtimeformat <String>] [tddaysoffset <Number>] [tdhoursoffset <Number>])| diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index 6f58c6f9..4c501222 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,12 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation +### 6.76.08 + +Updated `<SchemaNameList>` to `"<SchemaName>|<SchemaFieldName>(,<SchemaName>|<SchemaFieldName>)*"` +that allows `schemas <SchemaNameList>` in `gam info user` and `gam print users` to display all fields or selected fields +of the specified custom schemas. + ### 6.76.07 Fixed bug where control-C was not recognized when GAM had processed all rows in a CSV file diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index 37d4998b..1a85fdcb 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.md @@ -335,7 +335,7 @@ writes the credentials into the file oauth2.txt. admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found -GAMADV-XTD3 6.76.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.76.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs <ross.scroggs@gmail.com> Python 3.12.3 64-bit final MacOS Sonoma 14.4.1 x86_64 @@ -1009,7 +1009,7 @@ writes the credentials into the file oauth2.txt. C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt C:\GAMADV-XTD3>gam version WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found -GAMADV-XTD3 6.76.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.76.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs <ross.scroggs@gmail.com> Python 3.12.3 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/List-Items.md b/docs/List-Items.md index 5b98cdaa..436145fd 100644 --- a/docs/List-Items.md +++ b/docs/List-Items.md @@ -85,7 +85,7 @@ <QueryMobileList> ::= "<QueryMobile>(,<QueryMobile>)*" <QueryUserList> ::= "<QueryUser>(,<QueryUser>)*" <ResourceIDList> ::= "<ResourceID>(,<ResourceID>)*" -<SchemaNameList> ::= "<SchemaName>(,<SchemaName>)*" +<SchemaNameList> ::= "<SchemaName>|<SchemaFieldName>(,<SchemaName>|<SchemaFieldName>)*" <SerialNumberList> ::= "<SerialNumber>(,<SerialNumber>)*" <ServiceAccountKeyList> ::= "<ServiceAccountKey>(,<ServiceAccountKey>)*" <SiteACLScopeList> ::= "<SiteACLScope>(,<SiteACLScope>)*" diff --git a/docs/Users.md b/docs/Users.md index 3449df98..f3924d02 100644 --- a/docs/Users.md +++ b/docs/Users.md @@ -110,6 +110,11 @@ queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Stude <QueryUser> ::= <String> See: https://developers.google.com/admin-sdk/directory/v1/guides/search-users +<FieldName> ::= <String> +<SchemaName> ::= <String> +<SchemaNameField> ::= <SchemaName>.<FieldName> +<SchemaNameList> ::= "<SchemaName>|<SchemaFieldName>(,<SchemaName>|<SchemaFieldName>)*" + <StorageBucketName> ::= <String> <StorageObjectName> ::= <String> <StorageBucketObjectName> ::= @@ -488,7 +493,7 @@ clearschema <SchemaName> ``` Clear a specific field in a schema: ``` -clearschema <SchemaName>.<FieldName> +clearschema <SchemaNameField> ``` ## Create a user @@ -614,7 +619,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>* [updateoufromgroup <FileName> [charset <Charset>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] - [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] + [clearschema <SchemaName>|<SchemaNameField>] [createifnotfound] [notfoundpassword random|<Password>] (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* [alias|aliases <EmailAddressList>] @@ -635,7 +640,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>* [updateoufromgroup <FileName> [charset <Charset>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] - [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] + [clearschema <SchemaName>|<SchemaNameField>] [createifnotfound] [notfoundpassword random|<Password>] (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* [alias|aliases <EmailAddressList>] @@ -656,7 +661,7 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>* [updateoufromgroup <FileName> [charset <Charset>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] - [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] + [clearschema <SchemaName>|<SchemaNameField>] [createifnotfound] [notfoundpassword random|<Password>] (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* [alias|aliases <EmailAddressList>] @@ -954,7 +959,7 @@ Starting in version `5.23.01`, the variable `quick_info_user` was added to `gam. These existing options enable the display of additional information. * `(products|product <ProductIDList>)|(skus|sku <SKUIDList>)` - Display license information for a selected list of products/SKUs. -* `schemas|custom|customschemas <SchemaNameList>` - Display the specified custom schemas +* `schemas|custom|customschemas <SchemaNameList>` - Display all fields or selected fields of the specified custom schemas By default, Gam displays fields that only an adminstrator can view. * `userview` - Only display fields that other users in the domain can view. @@ -1064,8 +1069,8 @@ By default, Gam displays only the primary email address for each user. * `allfields|basic` - Display all non custom schema fields for each user. * `full` - Display all fields including all custom schema fields for each user. * `<UserFieldName>* [fields <UserFieldNameList>]` - Only display selected fields. -* `schemas|custom all` - Get custom schema information for all schemas. -* `schemas|custom <SchemaNameList>` - Get custom schema information for a selected list of schemas. +* `schemas|custom all` - Display custom schema information for all schemas. +* `schemas|custom <SchemaNameList>` - Display all fields or selected fields of the specified custom schemas By default, when aliases are displayed, all aliases are displayed. Use `aliasmatchpattern <RegularExpression>` to limit the display of aliases to those that match `<RegularExpression>`. diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 34324378..f1f2fe0e 100644 --- a/docs/Version-and-Help.md +++ b/docs/Version-and-Help.md @@ -3,7 +3,7 @@ Print the current version of Gam with details ``` gam version -GAMADV-XTD3 6.76.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.76.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs <ross.scroggs@gmail.com> Python 3.12.3 64-bit final MacOS Sonoma 14.4.1 x86_64 @@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00 Print the current version of Gam with details and time offset information ``` gam version timeoffset -GAMADV-XTD3 6.76.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.76.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs <ross.scroggs@gmail.com> Python 3.12.3 64-bit final MacOS Sonoma 14.4.1 x86_64 @@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second Print the current version of Gam with extended details and SSL information ``` gam version extended -GAMADV-XTD3 6.76.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.76.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs <ross.scroggs@gmail.com> Python 3.12.3 64-bit final MacOS Sonoma 14.4.1 x86_64 @@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64 Path: /Users/Admin/bin/gamadv-xtd3 Version Check: Current: 5.35.08 - Latest: 6.76.07 + Latest: 6.76.08 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -6.76.07 +6.76.08 ``` In Linux/MacOS you can do: ``` @@ -82,7 +82,7 @@ echo $VER Print the current version of Gam and address of this Wiki ``` gam help -GAM 6.76.07 - https://github.com/taers232c/GAMADV-XTD3 +GAM 6.76.08 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs <ross.scroggs@gmail.com> Python 3.12.3 64-bit final MacOS Sonoma 14.4.1 x86_64 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 16374088..1db02ee1 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -546,6 +546,7 @@ If an item contains spaces, it should be surrounded by ". <ResellerID> ::= <String> <ResourceID> ::= <String> <SchemaName> ::= <String> +<SchemaNameField> ::= <SchemaName>.<FieldName> <Section> ::= <String> <SendAsContent> ::= (sig|signature|htmlsig <String>)| @@ -626,7 +627,7 @@ If an item contains spaces, it should be surrounded by ". (tdsubject <String>)| ([tdsheetdaysoffset <Number>] [tdsheethoursoffset <Number>])| (tdtimestamp [<Boolean>] [tdtimeformat <String>] - ([tddaysoffset <Number>] [tdhoursoffset <Number>])| + [tddaysoffset <Number>] [tdhoursoffset <Number>])| (tdtimezone <TimeZone>)| (tdtitle <String>)| (tdupdatesheet [<Boolean>])| @@ -725,7 +726,7 @@ If an item contains spaces, it should be surrounded by ". <QueryMobileList> ::= "<QueryMobile>(,<QueryMobile>)*" <QueryUserList> ::= "<QueryUser>(,<QueryUser>)*" <ResourceIDList> ::= "<ResourceID>(,<ResourceID>)*" -<SchemaNameList> ::= "<SchemaName>(,<SchemaName>)*" +<SchemaNameList> ::= "<SchemaName>|<SchemaFieldName>(,<SchemaName>|<SchemaFieldName>)*" <SerialNumberList> ::= "<SerialNumber>(,<SerialNumber>)*" <ServiceAccountKeyList> ::= "<ServiceAccountKey>(,<ServiceAccountKey>)*" <SiteACLScopeList> ::= "<SiteACLScope>(,<SiteACLScope>)*" @@ -4991,7 +4992,7 @@ gam <UserTypeEntity> show teamdriveacls (field:<UserReplacementField>)| (field:<UserReplacementFieldSubfield>)| (field:<UserReplacementFieldSubfieldMatchSubfield>)| - (schema:<SchemaName>.<FieldName>)| + (schema:<SchemaNameField>)| <String> # Vault/Takeout @@ -5256,9 +5257,9 @@ gam download storagefile <StorageBucketObjectName> (recoveryemail <EmailAddress>)| (recoveryphone <string>)| (suspend|suspended <Boolean>)| - (<SchemaName>.<FieldName> [scalarnonempty| - [multivalued|multivalue|value|multinonempty [type home|other|work|(custom <String>)]]] - <String>) + (<SchemaNameField> [scalarnonempty| + [multivalued|multivalue|value|multinonempty [type home|other|work|(custom <String>)]]] + <String>) <UserMultiAttribute> ::= (address type home|other|work|(custom <String>) @@ -5347,7 +5348,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>* [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] [immutableous <OrgUnitEntity>]| - [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] + [clearschema <SchemaName> | <SchemaNameField>] [createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>] (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* [alias|aliases <EmailAddressList>] @@ -5382,7 +5383,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>* [updateoufromgroup <FileName> [charset <CharSet>] [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>] [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]] - [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] + [clearschema <SchemaName>|<SchemaNameField>] [createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>] (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* [alias|aliases <EmailAddressList>] @@ -5415,7 +5416,7 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>* [verifynotinvitable] [noactionifalias] [updateprimaryemail <RegularExpression> <EmailReplacement>] [updateoufromgroup <CSVFileInput> [keyfield <FieldName>] [datafield <FieldName>]] - [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] + [clearschema <SchemaName> | <SchemaNameField>] [createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>] (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* [alias|aliases <EmailAddressList>] diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index 6b49bec5..6bbb6ef5 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -2,6 +2,12 @@ Merged GAM-Team version +6.76.08 + +Updated `<SchemaNameList>` to `"<SchemaName>|<SchemaFieldName>(,<SchemaName>|<SchemaFieldName>)*"` +that allows `schemas <SchemaNameList>` in `gam info user` and `gam print users` to display all fields or selected fields +of the specified custom schemas. + 6.76.07 Fixed bug where control-C was not recognized when GAM had processed all rows in a CSV file diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 7ac5c07c..3bcb9e7b 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -41917,7 +41917,7 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count): # [updateprimaryemail <RegularExpression> <EmailReplacement>] # [updateoufromgroup <CSVFileInput> [keyfield <FieldName>] [datafield <FieldName>]] # [immutableous <OrgUnitEntity>]| -# [clearschema <SchemaName>] [clearschema <SchemaName>.<FieldName>] +# [clearschema <SchemaName>|<SchemaNameField>] # [createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>] # (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)* # [alias|aliases <EmailAddressList>] @@ -42523,6 +42523,44 @@ def _formatLanguagesList(propertyValue, delimiter): languages.append(lang) return delimiter.join(languages) +def _initSchemaParms(projection): + return {'projection': projection, 'customFieldMask': None, 'selectedSchemaFields': {}} + +def _getSchemaNameList(schemaParms): + customFieldMask = getString(Cmd.OB_SCHEMA_NAME_LIST).replace(' ', ',') + if customFieldMask.lower() == 'all': + schemaParms['projection'] = 'full' + schemaParms['customFieldMask'] = None + schemaParms['selectedSchemaFields'] = {} + else: + schemaParms['projection'] = 'custom' + customFieldMaskList = [] + for schemaField in customFieldMask.split(','): + if schemaField.find('.') == -1: + customFieldMaskList.append(schemaField) + else: + schemaName, fieldName = schemaField.split('.', 1) + customFieldMaskList.append(schemaName) + schemaParms['selectedSchemaFields'] .setdefault(schemaName, set()) + schemaParms['selectedSchemaFields'][schemaName].add(fieldName) + schemaParms['customFieldMask'] = ','.join(customFieldMaskList) + +def _filterSchemaFields(userEntity, schemaParms): + schemas = userEntity.pop('customSchemas', None) + if schemas is None: + return + customSchemas = {} + for schema in sorted(schemas): + if schema in schemaParms['selectedSchemaFields']: + for field, value in sorted(iter(schemas[schema].items())): + if field not in schemaParms['selectedSchemaFields'][schema]: + continue + customSchemas.setdefault(schema, {}) + customSchemas[schema][field] = value + else: + customSchemas[schema] = schemas[schema] + userEntity['customSchemas'] = customSchemas + def infoUsers(entityList): def printUserCIGroupMap(parent, group_name_mappings, seen_group_count, edges, direction): for a_parent, a_child in edges: @@ -42558,8 +42596,7 @@ def infoUsers(entityList): getAliases = getBuildingNames = getCIGroupsTree = getGroups = getLicenses = getSchemas = not GC.Values[GC.QUICK_INFO_USER] getGroupsTree = False FJQC = FormatJSONQuoteChar() - projection = 'full' - customFieldMask = None + schemaParms = _initSchemaParms('full') viewType = 'admin_view' fieldsList = [] groups = [] @@ -42582,19 +42619,13 @@ def infoUsers(entityList): getLicenses = myarg in {'licenses', 'licences'} elif myarg == 'noschemas': getSchemas = False - projection = 'basic' + schemaParms = _initSchemaParms('basic') elif myarg == 'allschemas': getSchemas = True - projection = 'full' + schemaParms = _initSchemaParms('full') elif myarg in {'custom', 'schemas', 'customschemas'}: getSchemas = True - customFieldMask = getString(Cmd.OB_SCHEMA_NAME_LIST).replace(' ', ',') - if customFieldMask.lower() == 'all': - customFieldMask = None - projection = 'full' - else: - projection = 'custom' - fieldsList.append('customSchemas') + _getSchemaNameList(schemaParms) elif myarg in {'products', 'product'}: skus = SKU.convertProductListToSKUList(getGoogleProductList()) elif myarg in {'sku', 'skus'}: @@ -42611,6 +42642,8 @@ def infoUsers(entityList): FJQC.GetFormatJSON(myarg) if fieldsList: fieldsList.append('primaryEmail') + if getSchemas: + fieldsList.append('customSchemas') if getAliases: fieldsList.extend(['aliases', 'nonEditableAliases']) fields = getFieldsFromFieldsList(fieldsList) @@ -42627,7 +42660,8 @@ def infoUsers(entityList): try: user = callGAPI(cd.users(), 'get', throwReasons=GAPI.USER_GET_THROW_REASONS+[GAPI.INVALID_INPUT, GAPI.RESOURCE_NOT_FOUND], - userKey=userEmail, projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields) + userKey=userEmail, projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'], + viewType=viewType, fields=fields) groups = [] memberships = [] if getGroups or getGroupsTree: @@ -42859,25 +42893,29 @@ def infoUsers(entityList): typeKey = userProperty[UProp.TYPE_KEYWORDS][UProp.PTKW_ATTR_TYPE_KEYWORD] typeCustomValue = userProperty[UProp.TYPE_KEYWORDS][UProp.PTKW_ATTR_TYPE_CUSTOM_VALUE] customTypeKey = userProperty[UProp.TYPE_KEYWORDS][UProp.PTKW_ATTR_CUSTOMTYPE_KEYWORD] - printKeyValueList([UProp.PROPERTIES[up][UProp.TITLE], None]) - Ind.Increment() - for schema in sorted(propertyValue): - printKeyValueList(['Schema', schema]) + if schemaParms['selectedSchemaFields']: + _filterSchemaFields(user, schemaParms) + propertyValue = user[up] + if propertyValue: + printKeyValueList([UProp.PROPERTIES[up][UProp.TITLE], None]) Ind.Increment() - for field in propertyValue[schema]: - if isinstance(propertyValue[schema][field], list): - printKeyValueList([field]) - Ind.Increment() - for an_item in propertyValue[schema][field]: - _showType(an_item, typeKey, typeCustomValue, customTypeKey, defaultType='work') + for schema in sorted(propertyValue): + printKeyValueList(['Schema', schema]) + Ind.Increment() + for field in propertyValue[schema]: + if isinstance(propertyValue[schema][field], list): + printKeyValueList([field]) Ind.Increment() - printKeyValueList(['value', an_item['value']]) + for an_item in propertyValue[schema][field]: + _showType(an_item, typeKey, typeCustomValue, customTypeKey, defaultType='work') + Ind.Increment() + printKeyValueList(['value', an_item['value']]) + Ind.Decrement() Ind.Decrement() - Ind.Decrement() - else: - printKeyValueList([field, propertyValue[schema][field]]) + else: + printKeyValueList([field, propertyValue[schema][field]]) + Ind.Decrement() Ind.Decrement() - Ind.Decrement() if getAliases: for up in ['aliases', 'nonEditableAliases']: propertyValue = user.get(up, []) @@ -42942,8 +42980,8 @@ def infoUsers(entityList): GAPI.badRequest, GAPI.backendError, GAPI.systemError) as e: entityActionFailedWarning([Ent.USER, userEmail], str(e), i, count) except (GAPI.invalidInput, GAPI.invalidMember) as e: - if customFieldMask: - entityActionFailedWarning([Ent.USER, userEmail], invalidUserSchema(customFieldMask), i, count) + if schemaParms['customFieldMask']: + entityActionFailedWarning([Ent.USER, userEmail], invalidUserSchema(schemaParms['customFieldMask']), i, count) else: entityActionFailedWarning([Ent.USER, userEmail], str(e), i, count) @@ -43058,6 +43096,8 @@ def doPrintUsers(entityList=None): phoneNumber = phone.get('value', '') if phoneNumber.startswith('+'): phone['value'] = "'"+phoneNumber + if schemaParms['selectedSchemaFields']: + _filterSchemaFields(userEntity, schemaParms) if printOptions['getGroupFeed']: printGettingAllEntityItemsForWhom(Ent.GROUP_MEMBERSHIP, userEmail, i, count) try: @@ -43128,8 +43168,8 @@ def doPrintUsers(entityList=None): entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT])) else: _writeUserEntity({'primaryEmail': ri[RI_ITEM], showValidColumn: False}) - elif (reason == GAPI.INVALID_INPUT) and customFieldMask: - entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(customFieldMask), int(ri[RI_J]), int(ri[RI_JCOUNT])) + elif (reason == GAPI.INVALID_INPUT) and schemaParms['customFieldMask']: + entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(schemaParms['customFieldMask']), int(ri[RI_J]), int(ri[RI_JCOUNT])) elif reason not in GAPI.DEFAULT_RETRY_REASONS: errMsg = getHTTPError(_PRINT_USER_REASON_TO_MESSAGE_MAP, http_status, reason, message) printKeyValueList([ERROR, errMsg]) @@ -43138,7 +43178,8 @@ def doPrintUsers(entityList=None): try: user = callGAPI(cd.users(), 'get', throwReasons=GAPI.USER_GET_THROW_REASONS+[GAPI.INVALID_INPUT, GAPI.RESOURCE_NOT_FOUND, GAPI.RATE_LIMIT_EXCEEDED], - userKey=ri[RI_ITEM], projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields) + userKey=ri[RI_ITEM], projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'], + viewType=viewType, fields=fields) _printUser(user, int(ri[RI_J]), int(ri[RI_JCOUNT])) except (GAPI.userNotFound, GAPI.resourceNotFound): if not showValidColumn: @@ -43149,8 +43190,8 @@ def doPrintUsers(entityList=None): GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e: entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT])) except GAPI.invalidInput as e: - if customFieldMask: - entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(customFieldMask), int(ri[RI_J]), int(ri[RI_JCOUNT])) + if schemaParms['customFieldMask']: + entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(schemaParms['customFieldMask']), int(ri[RI_J]), int(ri[RI_JCOUNT])) else: entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT])) @@ -43174,9 +43215,8 @@ def doPrintUsers(entityList=None): lic = None skus = None maxResults = GC.Values[GC.USER_MAX_RESULTS] - projection = 'basic' + schemaParms = _initSchemaParms('basic') projectionSet = False - customFieldMask = None oneLicensePerRow = quotePlusPhoneNumbers = showDeleted = False aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None viewType = 'admin_view' @@ -43203,27 +43243,22 @@ def doPrintUsers(entityList=None): orderBy, sortOrder = getOrderBySortOrder(USERS_ORDERBY_CHOICE_MAP) elif myarg == 'userview': viewType = 'domain_public' + elif myarg in {'allfields', 'basic'}: + schemaParms = _initSchemaParms('basic') + projectionSet = printOptions['sortHeaders'] = True + fieldsList = [] + elif myarg == 'full': + if schemaParms['projection'] != 'custom': + schemaParms = _initSchemaParms(myarg) + projectionSet = printOptions['sortHeaders'] = True + fieldsList = [] elif myarg in {'custom', 'schemas', 'customschemas'}: - if not fieldsList: - fieldsList = ['primaryEmail'] - fieldsList.append('customSchemas') - customFieldMask = getString(Cmd.OB_SCHEMA_NAME_LIST).replace(' ', ',') - if customFieldMask.lower() == 'all': - customFieldMask = None - projection = 'full' - else: - projection = 'custom' projectionSet = True + _getSchemaNameList(schemaParms) + if fieldsList: + fieldsList.append('customSchemas') elif myarg == 'delimiter': delimiter = getCharacter() - elif myarg in PROJECTION_CHOICE_MAP: - projection = myarg - projectionSet = printOptions['sortHeaders'] = True - fieldsList = [] - elif myarg == 'allfields': - projection = 'basic' - projectionSet = printOptions['sortHeaders'] = True - fieldsList = [] elif myarg == 'sortheaders': printOptions['sortHeaders'] = getBoolean() elif myarg == 'scalarsfirst': @@ -43326,7 +43361,8 @@ def doPrintUsers(entityList=None): GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN], query=query, fields=fields, showDeleted=showDeleted, orderBy=orderBy, sortOrder=sortOrder, viewType=viewType, - projection=projection, customFieldMask=customFieldMask, maxResults=maxResults, **kwargs) + projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'], + maxResults=maxResults, **kwargs) for users in feed: if showItemCountOnly: itemCount += len(users) @@ -43351,12 +43387,12 @@ def doPrintUsers(entityList=None): entityActionFailedWarning([Ent.USER, None, Ent.DOMAIN, kwargs['domain']], Msg.NOT_FOUND) continue except (GAPI.invalidOrgunit, GAPI.invalidInput) as e: - if query and not customFieldMask: + if query and not schemaParms['customFieldMask']: entityActionFailedWarning([Ent.USER, None], invalidQuery(query)) - elif customFieldMask and not query: - entityActionFailedWarning([Ent.USER, None], invalidUserSchema(customFieldMask)) - elif query and customFieldMask: - entityActionFailedWarning([Ent.USER, None], f'{invalidQuery(query)} or {invalidUserSchema(customFieldMask)}') + elif schemaParms['customFieldMask'] and not query: + entityActionFailedWarning([Ent.USER, None], invalidUserSchema(schemaParms['customFieldMask'])) + elif query and schemaParms['customFieldMask']: + entityActionFailedWarning([Ent.USER, None], f'{invalidQuery(query)} or {invalidUserSchema(schemaParms['customFieldMask'])}') else: entityActionFailedWarning([Ent.USER, None], str(e)) continue @@ -43377,7 +43413,9 @@ def doPrintUsers(entityList=None): jcount = len(entityList) fields = getFieldsFromFieldsList(fieldsList) if GC.Values[GC.BATCH_SIZE] > 1 and jcount > 1: - svcargs = dict([('userKey', None), ('fields', fields), ('projection', projection), ('customFieldMask', customFieldMask), ('viewType', viewType)]+GM.Globals[GM.EXTRA_ARGS_LIST]) + svcargs = dict([('userKey', None), ('fields', fields), + ('projection', schemaParms['projection']), ('customFieldMask', schemaParms['customFieldMask']), + ('viewType', viewType)]+GM.Globals[GM.EXTRA_ARGS_LIST]) method = getattr(cd.users(), 'get') dbatch = cd.new_batch_http_request(callback=_callbackPrintUser) bcount = 0 @@ -43402,7 +43440,8 @@ def doPrintUsers(entityList=None): try: user = callGAPI(cd.users(), 'get', throwReasons=GAPI.USER_GET_THROW_REASONS+[GAPI.INVALID_INPUT, GAPI.RESOURCE_NOT_FOUND, GAPI.RATE_LIMIT_EXCEEDED], - userKey=userEmail, projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields) + userKey=userEmail, projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'], + viewType=viewType, fields=fields) _printUser(user, j, jcount) except (GAPI.userNotFound, GAPI.resourceNotFound): if not showValidColumn: @@ -43413,8 +43452,8 @@ def doPrintUsers(entityList=None): GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e: entityActionFailedWarning([Ent.USER, userEmail], str(e), j, jcount) except GAPI.invalidInput as e: - if customFieldMask: - entityActionFailedWarning([Ent.USER, userEmail], invalidUserSchema(customFieldMask), j, jcount) + if schemaParms['customFieldMask']: + entityActionFailedWarning([Ent.USER, userEmail], invalidUserSchema(schemaParms['customFieldMask']), j, jcount) else: entityActionFailedWarning([Ent.USER, userEmail], str(e), j, jcount) # The only field specified was primaryEmail, just list the users/count the domains @@ -53951,10 +53990,9 @@ def printFileList(users): showParent = getBoolean() elif myarg == 'nodataheaders': nodataFields = getString(Cmd.OB_FIELD_NAME_LIST).replace('_', '').replace(',', ' ').split() - elif myarg == 'filepath': + elif myarg in {'filepath', 'fullpath'}: filepath = True - elif myarg == 'fullpath': - filepath = fullpath = True + fullpath = myarg == 'fullpath' elif myarg == 'folderpathonly': folderPathOnly = getBoolean() elif myarg == 'pathdelimiter':