gam7 7.5.21__py3-none-any.whl → 7.5.22__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of gam7 might be problematic. Click here for more details.

gam/__init__.py CHANGED
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
25
25
  """
26
26
 
27
27
  __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
28
- __version__ = '7.05.21'
28
+ __version__ = '7.05.22'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -1723,16 +1723,19 @@ def getREPattern(flags=0):
1723
1723
  return validateREPattern(patstr, flags)
1724
1724
  missingArgumentExit(Cmd.OB_RE_PATTERN)
1725
1725
 
1726
- def getREPatternReplacement(flags=0):
1727
- pattern = getREPattern(flags)
1728
- replacement = getString(Cmd.OB_STRING, minLen=0)
1726
+ def validateREPatternSubstitution(pattern, replacement):
1729
1727
  try:
1730
1728
  re.sub(pattern, replacement, '')
1731
1729
  return (pattern, replacement)
1732
1730
  except re.error as e:
1733
1731
  Cmd.Backup()
1734
- usageErrorExit(f'{Cmd.OB_RE_REPLACEMENT} {Msg.ERROR}: {e}')
1735
-
1732
+ usageErrorExit(f'{Cmd.OB_RE_SUBSTITUTION} {Msg.ERROR}: {e}')
1733
+
1734
+ def getREPatternSubstitution(flags=0):
1735
+ pattern = getREPattern(flags)
1736
+ replacement = getString(Cmd.OB_RE_SUBSTITUTION, minLen=0)
1737
+ return validateREPatternSubstitution(pattern, replacement)
1738
+
1736
1739
  def getSheetEntity(allowBlankSheet):
1737
1740
  if Cmd.ArgumentsRemaining():
1738
1741
  sheet = Cmd.Current()
@@ -6816,9 +6819,9 @@ def getEntitiesFromCSVFile(shlexSplit, returnSet=False):
6816
6819
  return entityList if not returnSet else entitySet
6817
6820
 
6818
6821
  # <CSVFileSelector>
6819
- # keyfield <FieldName> [keypattern <RegularExpression>] [keyvalue <String>] [delimiter <Character>]
6820
- # subkeyfield <FieldName> [keypattern <RegularExpression>] [keyvalue <String>] [delimiter <Character>]
6821
- # (matchfield|skipfield <FieldName> <RegularExpression>)*
6822
+ # keyfield <FieldName> [keypattern <RESearchPattern>] [keyvalue <RESubstitution>] [delimiter <Character>]
6823
+ # subkeyfield <FieldName> [keypattern <RESearchPattern>] [keyvalue <RESubstitution>] [delimiter <Character>]
6824
+ # (matchfield|skipfield <FieldName> <RESearchPattern>)*
6822
6825
  # [datafield <FieldName>(:<FieldName>)* [delimiter <Character>]]
6823
6826
  def getEntitiesFromCSVbyField():
6824
6827
 
@@ -10339,7 +10342,7 @@ def processSubFields(GAM_argv, row, subFields):
10339
10342
 
10340
10343
  # gam csv <CSVLoopContent> [warnifnodata]
10341
10344
  # [columndelimiter <Character>] [quotechar <Character>] [fields <FieldNameList>]
10342
- # (matchfield|skipfield <FieldName> <RegularExpression>)* [showcmds [<Boolean>]]
10345
+ # (matchfield|skipfield <FieldName> <RESearchPattern>)* [showcmds [<Boolean>]]
10343
10346
  # [skiprows <Integer>] [maxrows <Integer>]
10344
10347
  # gam <GAM argument list>
10345
10348
  def doCSV(testMode=False):
@@ -10395,7 +10398,7 @@ def doCSVTest():
10395
10398
 
10396
10399
  # gam loop <CSVLoopContent> [warnifnodata]
10397
10400
  # [columndelimiter <Character>] [quotechar <Character>] [fields <FieldNameList>]
10398
- # (matchfield|skipfield <FieldName> <RegularExpression>)* [showcmds [<Boolean>]]
10401
+ # (matchfield|skipfield <FieldName> <RESearchPattern>)* [showcmds [<Boolean>]]
10399
10402
  # [skiprows <Integer>] [maxrows <Integer>]
10400
10403
  # gam <GAM argument list>
10401
10404
  def doLoop(loopCmd):
@@ -14531,7 +14534,7 @@ def _getTagReplacement(myarg, tagReplacements, allowSubs):
14531
14534
  if myarg == 'replace':
14532
14535
  trregex = None
14533
14536
  elif myarg == 'replaceregex':
14534
- trregex = getREPatternReplacement(re.IGNORECASE)
14537
+ trregex = getREPatternSubstitution(re.IGNORECASE)
14535
14538
  else:
14536
14539
  return False
14537
14540
  matchTag = getString(Cmd.OB_TAG)
@@ -14950,7 +14953,7 @@ def getRecipients():
14950
14953
  # [subject <String>]
14951
14954
  # [<MessageContent>]
14952
14955
  # (replace <Tag> <String>)*
14953
- # (replaceregex <RegularExpression> <String> <Tag> <String>)*
14956
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
14954
14957
  # [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
14955
14958
  # (embedimage <FileName> <String>)*
14956
14959
  # [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
@@ -14960,7 +14963,7 @@ def getRecipients():
14960
14963
  # [subject <String>]
14961
14964
  # [<MessageContent>]
14962
14965
  # (replace <Tag> <String>)*
14963
- # (replaceregex <RegularExpression> <String> <Tag> <String>)*
14966
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
14964
14967
  # [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
14965
14968
  # (embedimage <FileName> <String>)*
14966
14969
  # [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
@@ -14970,7 +14973,7 @@ def getRecipients():
14970
14973
  # [subject <String>]
14971
14974
  # [<MessageContent>]
14972
14975
  # (replace <Tag> <String>)*
14973
- # (replaceregex <RegularExpression> <String> <Tag> <String>)*
14976
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
14974
14977
  # [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
14975
14978
  # (embedimage <FileName> <String>)*
14976
14979
  # [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
@@ -18644,7 +18647,7 @@ def userFilters(kwargs, query, orgUnitPath, isSuspended):
18644
18647
  # [limittoou <OrgUnitItem>])
18645
18648
  # [user|users <EmailAddressList>] [group|groups <EmailAddressList>]
18646
18649
  # [select <UserTypeEntity>]
18647
- # [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
18650
+ # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
18648
18651
  # [shownoneditable] [nogroups] [nousers]
18649
18652
  # [onerowpertarget] [delimiter <Character>]
18650
18653
  # [suppressnoaliasrows]
@@ -20111,7 +20114,7 @@ def _clearUpdateContacts(updateContacts):
20111
20114
  Ind.Decrement()
20112
20115
 
20113
20116
  # gam clear contacts <ContactEntity>|<ContactSelection>
20114
- # [clearmatchpattern <RegularExpression>] [clearmatchtype work|home|other|<String>]
20117
+ # [clearmatchpattern <REMatchPattern>] [clearmatchtype work|home|other|<String>]
20115
20118
  # [deleteclearedcontactswithnoemails]
20116
20119
  def doClearDomainContacts():
20117
20120
  _clearUpdateContacts(False)
@@ -21676,7 +21679,7 @@ def _clearUpdatePeopleContacts(users, updateContacts):
21676
21679
  Ind.Decrement()
21677
21680
 
21678
21681
  # gam <UserTypeEntity> clear contacts <PeopleResourceNameEntity>|<PeopleUserContactSelection>
21679
- # [emailclearpattern <RegularExpression>] [emailcleartype work|home|other|<String>]
21682
+ # [emailclearpattern <REMatchPattern>] [emailcleartype work|home|other|<String>]
21680
21683
  # [deleteclearedcontactswithnoemails]
21681
21684
  def clearUserPeopleContacts(users):
21682
21685
  _clearUpdatePeopleContacts(users, False)
@@ -31956,7 +31959,7 @@ GROUP_PREVIEW_TITLES = ['group', 'email', 'role', 'action', 'message']
31956
31959
  # gam update groups <GroupEntity> clear [member] [manager] [owner]
31957
31960
  # [usersonly|groupsonly]
31958
31961
  # [notsuspended|suspended] [notarchived|archived]
31959
- # [emailclearpattern|emailretainpattern <RegularExpression>]
31962
+ # [emailclearpattern|emailretainpattern <REMatchPattern>]
31960
31963
  # [removedomainnostatusmembers]
31961
31964
  # [preview] [actioncsv]
31962
31965
  def doUpdateGroups():
@@ -33305,7 +33308,7 @@ def infoGroups(entityList):
33305
33308
  # [internal] [internaldomains <DomainList>] [external]
33306
33309
  # [notsuspended|suspended] [notarchived|archived]
33307
33310
  # [types <GroupMemberTypeList>]
33308
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
33311
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
33309
33312
  # [formatjson]
33310
33313
  def doInfoGroups():
33311
33314
  infoGroups(getEntityList(Cmd.OB_GROUP_ENTITY))
@@ -33516,8 +33519,8 @@ PRINT_GROUPS_JSON_TITLES = ['email', 'JSON']
33516
33519
  # [([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryUserList>)]))|
33517
33520
  # (group|group_ns|group_susp <GroupItem>)|
33518
33521
  # (select <GroupEntity>)]
33519
- # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
33520
- # [descriptionmatchpattern [not] <RegularExpression>] (matchsetting [not] <GroupAttribute>)*
33522
+ # [emailmatchpattern [not] <REMatchPattern>] [namematchpattern [not] <REMatchPattern>]
33523
+ # [descriptionmatchpattern [not] <REMatchPattern>] (matchsetting [not] <GroupAttribute>)*
33521
33524
  # [admincreatedmatch <Boolean>]
33522
33525
  # [maxresults <Number>]
33523
33526
  # [allfields|([basic] [settings] <GroupFieldName>* [fields <GroupFieldNameList>])]
@@ -33529,7 +33532,7 @@ PRINT_GROUPS_JSON_TITLES = ['email', 'JSON']
33529
33532
  # [includederivedmembership]
33530
33533
  # [notsuspended|suspended] [notarchived|archived]
33531
33534
  # [types <GroupMemberTypeList>]
33532
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
33535
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
33533
33536
  # [convertcrnl] [delimiter <Character>] [sortheaders]
33534
33537
  # [formatjson [quotechar <Character>]]
33535
33538
  # [showitemcountonly]
@@ -34218,13 +34221,13 @@ GROUPMEMBERS_DEFAULT_FIELDS = ['group', 'type', 'role', 'id', 'status', 'email']
34218
34221
  # [([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryUserList>)]))|
34219
34222
  # (group|group_ns|group_susp <GroupItem>)|
34220
34223
  # (select <GroupEntity>)]
34221
- # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
34222
- # [descriptionmatchpattern [not] <RegularExpression>]
34224
+ # [emailmatchpattern [not] <REMatchPattern>] [namematchpattern [not] <REMatchPattern>]
34225
+ # [descriptionmatchpattern [not] <REMatchPattern>]
34223
34226
  # [roles <GroupRoleList>] [members] [managers] [owners]
34224
34227
  # [internal] [internaldomains <DomainList>] [external]
34225
34228
  # [notsuspended|suspended] [notarchived|archived]
34226
34229
  # [types <GroupMemberTypeList>]
34227
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
34230
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
34228
34231
  # [membernames] [showdeliverysettings]
34229
34232
  # <MembersFieldName>* [fields <MembersFieldNameList>]
34230
34233
  # [userfields <UserFieldNameList>]
@@ -34518,13 +34521,13 @@ def doPrintGroupMembers():
34518
34521
  # [([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryUserList>)]))|
34519
34522
  # (group|group_ns|group_susp <GroupItem>)|
34520
34523
  # (select <GroupEntity>)]
34521
- # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
34522
- # [descriptionmatchpattern [not] <RegularExpression>]
34524
+ # [emailmatchpattern [not] <REMatchPattern>] [namematchpattern [not] <REMatchPattern>]
34525
+ # [descriptionmatchpattern [not] <REMatchPattern>]
34523
34526
  # [roles <GroupRoleList>] [members] [managers] [owners] [depth <Number>]
34524
34527
  # [internal] [internaldomains <DomainList>] [external]
34525
34528
  # [notsuspended|suspended] [notarchived|archived]
34526
34529
  # [types <GroupMemberTypeList>]
34527
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
34530
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
34528
34531
  # [includederivedmembership]
34529
34532
  def doShowGroupMembers():
34530
34533
  def _roleOrder(key):
@@ -34783,7 +34786,7 @@ def doCreateCIGroup():
34783
34786
  # <UserTypeEntity>
34784
34787
  # gam update cigroups <GroupEntity> clear [member] [manager] [owner]
34785
34788
  # [usersonly|groupsonly]
34786
- # [emailclearpattern|emailretainpattern <RegularExpression>]
34789
+ # [emailclearpattern|emailretainpattern <REMatchPattern>]
34787
34790
  # [preview] [actioncsv]
34788
34791
  def doUpdateCIGroups():
34789
34792
 
@@ -35505,7 +35508,7 @@ def getCIGroupMemberTypes(myarg, typesSet):
35505
35508
  # [roles <GroupRoleList>] [members] [managers] [owners]
35506
35509
  # [internal] [internaldomains <DomainList>] [external]
35507
35510
  # [types <CIGroupMemberTypeList>]
35508
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
35511
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
35509
35512
  # [formatjson]
35510
35513
  def doInfoCIGroups():
35511
35514
  def printCIGroupMemberTree(group_id, showRole):
@@ -35842,11 +35845,11 @@ def doInfoCIPolicies():
35842
35845
 
35843
35846
  # gam print policies [todrive <ToDriveAttribute>*]
35844
35847
  # [filter <String>] [nowarnings] [noappnames]
35845
- # [group <RegularExpression>] [ou|org|orgunit <RegularExpression>]
35848
+ # [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
35846
35849
  # [formatjson [quotechar <Character>]]
35847
35850
  # gam show policies
35848
35851
  # [filter <String>] [nowarnings] [noappnames]
35849
- # [group <RegularExpression>] [ou|org|orgunit <RegularExpression>]
35852
+ # [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
35850
35853
  # [formatjson]
35851
35854
  def doPrintShowCIPolicies():
35852
35855
 
@@ -35906,14 +35909,14 @@ PRINT_CIGROUPS_JSON_TITLES = ['email', 'JSON']
35906
35909
  # gam print cigroups [todrive <ToDriveAttribute>*]
35907
35910
  # [(cimember|ciowner <UserItem>)|(select <GroupEntity>)|(query <String>)]
35908
35911
  # [showownedby <UserItem>]
35909
- # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
35910
- # [descriptionmatchpattern [not] <RegularExpression>]
35912
+ # [emailmatchpattern [not] <REMatchPattern>] [namematchpattern [not] <REMatchPattern>]
35913
+ # [descriptionmatchpattern [not] <REMatchPattern>]
35911
35914
  # [basic|allfields|(<CIGroupFieldName>* [fields <CIGroupFieldNameList>])]
35912
35915
  # [roles <GroupRoleList>] [memberrestrictions]
35913
35916
  # [members|memberscount] [managers|managerscount] [owners|ownerscount] [totalcount] [countsonly]
35914
35917
  # [internal] [internaldomains <DomainList>] [external]
35915
35918
  # [types <CIGroupMemberTypeList>]
35916
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
35919
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
35917
35920
  # [convertcrnl] [delimiter <Character>]
35918
35921
  # [formatjson [quotechar <Character>]]
35919
35922
  # [showitemcountonly]
@@ -36360,11 +36363,11 @@ def _getCIListGroupMembersArgs(listView):
36360
36363
  # gam print cigroup-members [todrive <ToDriveAttribute>*]
36361
36364
  # [(cimember|ciowner <UserItem>)|(cigroup <GroupItem>)|(select <GroupEntity>)]
36362
36365
  # [showownedby <UserItem>]
36363
- # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
36364
- # [descriptionmatchpattern [not] <RegularExpression>]
36366
+ # [emailmatchpattern [not] <REMatchPattern>] [namematchpattern [not] <REMatchPattern>]
36367
+ # [descriptionmatchpattern [not] <REMatchPattern>]
36365
36368
  # [roles <GroupRoleList>] [members] [managers] [owners]
36366
36369
  # [types <CIGroupMemberTypeList>]
36367
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
36370
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
36368
36371
  # <CIGroupMembersFieldName>* [fields <CIGroupMembersFieldNameList>]
36369
36372
  # [minimal|basic|full]
36370
36373
  # [(recursive [noduplicates])|includederivedmembership] [nogroupeemail]
@@ -36531,12 +36534,12 @@ def doPrintCIGroupMembers():
36531
36534
  # gam show cigroup-members
36532
36535
  # [(cimember|ciowner <UserItem>)|(cigroup <GroupItem>)|(select <GroupEntity>)]
36533
36536
  # [showownedby <UserItem>]
36534
- # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
36535
- # [descriptionmatchpattern [not] <RegularExpression>]
36537
+ # [emailmatchpattern [not] <REMatchPattern>] [namematchpattern [not] <REMatchPattern>]
36538
+ # [descriptionmatchpattern [not] <REMatchPattern>]
36536
36539
  # [roles <GroupRoleList>] [members] [managers] [owners]
36537
36540
  # [internal] [internaldomains <DomainList>] [external]
36538
36541
  # [types <CIGroupMemberTypeList>]
36539
- # [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
36542
+ # [memberemaildisplaypattern|memberemailskippattern <REMatchPattern>]
36540
36543
  # [minimal|basic|full]
36541
36544
  # [(depth <Number>) | includederivedmembership]
36542
36545
  def doShowCIGroupMembers():
@@ -38564,7 +38567,7 @@ def _getCalendarEventAttribute(myarg, body, parameters, function):
38564
38567
  elif myarg == 'description':
38565
38568
  body['description'] = getStringWithCRsNLs()
38566
38569
  elif function == 'update' and myarg == 'replacedescription':
38567
- parameters['replaceDescription'].append(getREPatternReplacement(re.IGNORECASE))
38570
+ parameters['replaceDescription'].append(getREPatternSubstitution(re.IGNORECASE))
38568
38571
  elif myarg == 'location':
38569
38572
  body['location'] = getString(Cmd.OB_STRING, minLen=0)
38570
38573
  elif myarg == 'source':
@@ -41089,11 +41092,11 @@ def md5MatchesFile(filename, expected_md5, j=0, jcount=0):
41089
41092
 
41090
41093
  # gam copy vaultexport|export <ExportItem> matter <MatterItem>
41091
41094
  # [targetbucket <String>] [targetprefix <String>]
41092
- # [bucketmatchpattern <RegularExpression>] [objectmatchpattern <RegularExpression>]
41095
+ # [bucketmatchpattern <REMatchPattern>] [objectmatchpattern <REMatchPattern>]
41093
41096
  # [copyattempts <Integer>] [retryinterval <Integer>]
41094
41097
  # gam copy vaultexport|export <MatterItem> <ExportItem>
41095
41098
  # [targetbucket <String>] [targetprefix <String>]
41096
- # [bucketmatchpattern <RegularExpression>] [objectmatchpattern <RegularExpression>]
41099
+ # [bucketmatchpattern <REMatchPattern>] [objectmatchpattern <REMatchPattern>]
41097
41100
  # [copyattempts <Integer>] [retryinterval <Integer>]
41098
41101
  def doCopyVaultExport():
41099
41102
  v = buildGAPIObject(API.VAULT)
@@ -41158,11 +41161,11 @@ ZIP_EXTENSION_PATTERN = re.compile(r'^.*\.zip$', re.IGNORECASE)
41158
41161
 
41159
41162
  # gam download vaultexport|export <ExportItem> matter <MatterItem>
41160
41163
  # [targetfolder <FilePath>] [targetname <FileName>] [noverify] [noextract] [ziptostdout]
41161
- # [bucketmatchpattern <RegularExpression>] [objectmatchpattern <RegularExpression>]
41164
+ # [bucketmatchpattern <REMatchPattern>] [objectmatchpattern <REMatchPattern>]
41162
41165
  # [downloadattempts <Integer>] [retryinterval <Integer>]
41163
41166
  # gam download vaultexport|export <MatterItem> <ExportItem>
41164
41167
  # [targetfolder <FilePath>] [targetname <FileName>] [noverify] [noextract] [ziptostdout]
41165
- # [bucketmatchpattern <RegularExpression>] [objectmatchpattern <RegularExpression>]
41168
+ # [bucketmatchpattern <REMatchPattern>] [objectmatchpattern <REMatchPattern>]
41166
41169
  # [downloadattempts <Integer>] [retryinterval <Integer>]
41167
41170
  def doDownloadVaultExport():
41168
41171
  def extract_nested_zip(zippedFile):
@@ -42904,18 +42907,7 @@ def getUserAttributes(cd, updateCmd, noUid=False):
42904
42907
  elif updateCmd and myarg == 'updateoufromgroup':
42905
42908
  groupOrgUnitMap = _getGroupOrgUnitMap()
42906
42909
  elif updateCmd and myarg == 'updateprimaryemail':
42907
- search = getString(Cmd.OB_RE_PATTERN)
42908
- pattern = validateREPattern(search, re.IGNORECASE)
42909
- replace = getString(Cmd.OB_EMAIL_REPLACEMENT)
42910
- patternGroups = pattern.groups
42911
- replSubs = REPLACE_GROUP_PATTERN.findall(replace)
42912
- for replSub in replSubs:
42913
- if int(replSub) > patternGroups:
42914
- Cmd.Backup()
42915
- usageErrorExit(Msg.MISMATCH_RE_SEARCH_REPLACE_SUBFIELDS.format(pattern.groups, search, int(replSub), replace))
42916
- updatePrimaryEmail['search'] = search
42917
- updatePrimaryEmail['pattern'] = pattern
42918
- updatePrimaryEmail['replace'] = replace
42910
+ updatePrimaryEmail = getREPatternSubstitution(re.IGNORECASE)
42919
42911
  elif myarg == 'json':
42920
42912
  body.update(getJSON(USER_JSON_SKIP_FIELDS))
42921
42913
  if 'name' in body and 'fullName' in body['name']:
@@ -43286,7 +43278,7 @@ def createUserAddAliases(cd, user, aliasList, i, count):
43286
43278
  # [replyto <EmailAaddress>]
43287
43279
  # [<NotifyMessageContent>]
43288
43280
  # (replace <Tag> <UserReplacement>)*
43289
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
43281
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
43290
43282
  # [logpassword <FileName>] [ignorenullpassword]
43291
43283
  # [addnumericsuffixonduplicate <Number>]
43292
43284
  def doCreateUser():
@@ -43374,7 +43366,7 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
43374
43366
 
43375
43367
  # gam <UserTypeEntity> update user <UserAttribute>*
43376
43368
  # [verifynotinvitable|alwaysevict] [noactionifalias]
43377
- # [updateprimaryemail <RegularExpression> <EmailReplacement>]
43369
+ # [updateprimaryemail <RESEarchPattern> <RESubstitution>]
43378
43370
  # [updateoufromgroup <CSVFileInput> [keyfield <FieldName>] [datafield <FieldName>]]
43379
43371
  # [immutableous <OrgUnitEntity>]|
43380
43372
  # [clearschema <SchemaName>|<SchemaNameField>]
@@ -43388,7 +43380,7 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
43388
43380
  # [replyto <EmailAaddress>]
43389
43381
  # [<NotifyMessageContent>
43390
43382
  # (replace <Tag> <UserReplacement>)*
43391
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
43383
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
43392
43384
  # [notifyonupdate [<Boolean>]]
43393
43385
  # [logpassword <FileName>] [ignorenullpassword]
43394
43386
  def updateUsers(entityList):
@@ -43431,12 +43423,12 @@ def updateUsers(entityList):
43431
43423
  'customType': 'former_employee',
43432
43424
  'primary': False, 'address': userPrimary}]
43433
43425
  elif updatePrimaryEmail:
43434
- if updatePrimaryEmail['pattern'].search(user) is not None:
43435
- body['primaryEmail'] = updatePrimaryEmail['pattern'].sub(updatePrimaryEmail['replace'], user)
43426
+ if updatePrimaryEmail[0].search(user) is not None:
43427
+ body['primaryEmail'] = re.sub(updatePrimaryEmail[0], updatePrimaryEmail[1], user)
43436
43428
  else:
43437
43429
  body.pop('primaryEmail', None)
43438
43430
  if not body:
43439
- entityActionNotPerformedWarning([Ent.USER, user], Msg.PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN.format(updatePrimaryEmail['search']), i, count)
43431
+ entityActionNotPerformedWarning([Ent.USER, user], Msg.PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN.format(updatePrimaryEmail[0].pattern), i, count)
43440
43432
  if groupOrgUnitMap:
43441
43433
  try:
43442
43434
  groups = callGAPIpages(cd.groups(), 'list', 'groups',
@@ -44518,7 +44510,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
44518
44510
  # [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
44519
44511
  # [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
44520
44512
  # [convertcrnl]
44521
- # [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
44513
+ # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
44522
44514
  # [showitemcountonly]
44523
44515
  # [showvalidcolumn] (addcsvdata <FieldName> <String>)*
44524
44516
  #
@@ -44531,7 +44523,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
44531
44523
  # [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
44532
44524
  # [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
44533
44525
  # [convertcrnl]
44534
- # [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
44526
+ # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
44535
44527
  # [showitemcountonly]
44536
44528
  # [showvalidcolumn] (addcsvdata <FieldName> <String>)*
44537
44529
  #
@@ -44539,7 +44531,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
44539
44531
  # ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
44540
44532
  # [limittoou <OrgUnitItem>] [deleted_only|only_deleted])|[select <UserTypeEntity>]
44541
44533
  # [formatjson [quotechar <Character>]] [countonly]
44542
- # [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
44534
+ # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
44543
44535
  # [showitemcountonly]
44544
44536
  # [showvalidcolumn] (addcsvdata <FieldName> <String>)*
44545
44537
  #
@@ -47328,7 +47320,7 @@ def _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties, getO
47328
47320
  return coursesInfo
47329
47321
 
47330
47322
  # gam print courses [todrive <ToDriveAttribute>*] (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
47331
- # [owneremail] [owneremailmatchpattern <RegularExpression>]
47323
+ # [owneremail] [owneremailmatchpattern <REMatchPattern>]
47332
47324
  # [alias|aliases|aliasesincolumns [delimiter <Character>]]
47333
47325
  # [show none|all|students|teachers] [countsonly]
47334
47326
  # [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
@@ -52836,7 +52828,7 @@ def getDriveFileAttribute(myarg, body, parameters, updateCmd):
52836
52828
  elif myarg =='stripnameprefix':
52837
52829
  parameters[DFA_STRIPNAMEPREFIX] = getString(Cmd.OB_STRING, minLen=0)
52838
52830
  elif myarg == 'replacefilename':
52839
- parameters[DFA_REPLACEFILENAME].append(getREPatternReplacement(re.IGNORECASE))
52831
+ parameters[DFA_REPLACEFILENAME].append(getREPatternSubstitution(re.IGNORECASE))
52840
52832
  elif myarg in {'convert', 'ocr'}:
52841
52833
  deprecatedArgument(myarg)
52842
52834
  stderrWarningMsg(Msg.USE_MIMETYPE_TO_SPECIFY_GOOGLE_FORMAT)
@@ -55354,6 +55346,12 @@ class DriveListParameters():
55354
55346
  def GetFileMatchingPermission(self, fileInfo):
55355
55347
  return self.PM.GetMatchingPermissions(fileInfo.get('permissions', []))
55356
55348
 
55349
+ def _getGettingEntity(user, fileIdEntity):
55350
+ driveId = fileIdEntity.get('shareddrive', {}).get('driveId', None)
55351
+ if not driveId:
55352
+ return user
55353
+ return f"{user} on {Ent.Singular(Ent.SHAREDDRIVE_ID)}: {driveId}"
55354
+
55357
55355
  OWNED_BY_ME_FIELDS_TITLES = ['ownedByMe']
55358
55356
  FILELIST_FIELDS_TITLES = ['id', 'name', 'mimeType', 'parents']
55359
55357
  DRIVE_INDEXED_TITLES = ['parents', 'path', 'permissions']
@@ -55384,7 +55382,7 @@ SIZE_FIELD_CHOICE_MAP = {
55384
55382
  # [anyowner|(showownedby any|me|others)]
55385
55383
  # [showmimetype [not] <MimeTypeList>] [showmimetype category <MimeTypeNameList>] [mimetypeinquery [<Boolean>]]
55386
55384
  # [sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
55387
- # [filenamematchpattern <RegularExpression>]
55385
+ # [filenamematchpattern <REMatchPattern>]
55388
55386
  # <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow]
55389
55387
  # [excludetrashed]
55390
55388
  # [maxfiles <Integer>] [nodataheaders <String>]
@@ -55882,7 +55880,8 @@ def printFileList(users):
55882
55880
  mimeTypeInfo = {}
55883
55881
  getSharedDriveACLsCount = 0
55884
55882
  if buildTree:
55885
- printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query'])
55883
+ gettingEntity = _getGettingEntity(user, fileIdEntity)
55884
+ printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count, query=DLP.fileIdEntity['query'])
55886
55885
  if not incrementalPrint:
55887
55886
  fileTree, status = initFileTree(drive, fileIdEntity.get('shareddrive'), DLP, shareddriveFields, showParent, user, i, count)
55888
55887
  if not status:
@@ -56483,7 +56482,7 @@ def printFileParentTree(users):
56483
56482
  # [anyowner|(showownedby any|me|others)]
56484
56483
  # [showmimetype [not] <MimeTypeList>] [showmimetype category <MimeTypeNameList>]
56485
56484
  # [sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
56486
- # [filenamematchpattern <RegularExpression>]
56485
+ # [filenamematchpattern <REMatchPattern>]
56487
56486
  # <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
56488
56487
  # [excludetrashed] (addcsvdata <FieldName> <String>)*
56489
56488
  # [showsize] [showmimetypesize] [showlastmodification]
@@ -56497,7 +56496,7 @@ def printFileParentTree(users):
56497
56496
  # [anyowner|(showownedby any|me|others)]
56498
56497
  # [showmimetype [not] <MimeTypeList>] [showmimetype category <MimeTypeNameList>]
56499
56498
  # [sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
56500
- # [filenamematchpattern <RegularExpression>]
56499
+ # [filenamematchpattern <REMatchPattern>]
56501
56500
  # <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
56502
56501
  # [excludetrashed]
56503
56502
  # [showsize] [showmimetypesize] [showlastmodification]
@@ -56656,7 +56655,8 @@ def printShowFileCounts(users):
56656
56655
  userLastModification = {
56657
56656
  'lastModifiedFileId': '', 'lastModifiedFileName': '',
56658
56657
  'lastModifyingUser': '', 'lastModifiedTime': NEVER_TIME}
56659
- printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query'])
56658
+ gettingEntity = _getGettingEntity(user, fileIdEntity)
56659
+ printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count, query=DLP.fileIdEntity['query'])
56660
56660
  try:
56661
56661
  feed = yieldGAPIpages(drive.files(), 'list', 'files',
56662
56662
  pageMessage=getPageMessageForWhom(),
@@ -57015,7 +57015,8 @@ def printShowFileShareCounts(users):
57015
57015
  if not drive:
57016
57016
  continue
57017
57017
  userShareCounts = FILESHARECOUNTS_ZEROCOUNTS.copy()
57018
- printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=query)
57018
+ gettingEntity = _getGettingEntity(user, fileIdEntity)
57019
+ printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count, query=query)
57019
57020
  try:
57020
57021
  feed = yieldGAPIpages(drive.files(), 'list', 'files',
57021
57022
  pageMessage=getPageMessageForWhom(),
@@ -57078,7 +57079,7 @@ FILETREE_FIELDS_PRINT_ORDER = ['id', 'parents', 'owners', 'mimeType', 'size', 'e
57078
57079
  # [anyowner|(showownedby any|me|others)]
57079
57080
  # [showmimetype [not] <MimeTypeList>] [showmimetype category <MimeTypeNameList>]
57080
57081
  # [sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
57081
- # [filenamematchpattern <RegularExpression>]
57082
+ # [filenamematchpattern <REMatchPattern>]
57082
57083
  # <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
57083
57084
  # [excludetrashed]
57084
57085
  # [fields <FileTreeFieldNameList>]
@@ -57089,7 +57090,7 @@ FILETREE_FIELDS_PRINT_ORDER = ['id', 'parents', 'owners', 'mimeType', 'size', 'e
57089
57090
  # [anyowner|(showownedby any|me|others)]
57090
57091
  # [showmimetype [not] <MimeTypeList>] [showmimetype category <MimeTypeNameList>]
57091
57092
  # [sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
57092
- # [filenamematchpattern <RegularExpression>]
57093
+ # [filenamematchpattern <REMatchPattern>]
57093
57094
  # <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
57094
57095
  # [excludetrashed]
57095
57096
  # [fields <FileTreeFieldNameList>]
@@ -57279,7 +57280,8 @@ def printShowFileTree(users):
57279
57280
  fileTree, status = initFileTree(drive, fileIdEntity.get('shareddrive'), DLP, shareddriveFields, True, user, i, count)
57280
57281
  if not status:
57281
57282
  continue
57282
- printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query'])
57283
+ gettingEntity = _getGettingEntity(user, fileIdEntity)
57284
+ printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count, query=DLP.fileIdEntity['query'])
57283
57285
  try:
57284
57286
  feed = yieldGAPIpages(drive.files(), 'list', 'files',
57285
57287
  pageMessage=getPageMessageForWhom(),
@@ -57316,6 +57318,9 @@ def printShowFileTree(users):
57316
57318
  fileEntryInfo = callGAPI(drive.files(), 'get',
57317
57319
  throwReasons=GAPI.DRIVE_GET_THROW_REASONS,
57318
57320
  fileId=fileId, fields=fields, supportsAllDrives=True)
57321
+ if (fileEntryInfo['mimeType'] == MIMETYPE_GA_FOLDER and fileEntryInfo.get('driveId') and
57322
+ fileEntryInfo['name'] == TEAM_DRIVE and not fileEntryInfo.get('parents', [])):
57323
+ fileEntryInfo['name'] = f"{SHARED_DRIVES}/{_getSharedDriveNameFromId(fileId)}"
57319
57324
  if stripCRsFromName:
57320
57325
  fileEntryInfo['name'] = _stripControlCharsFromName(fileEntryInfo['name'])
57321
57326
  if buildTree:
@@ -57400,7 +57405,7 @@ createReturnItemMap = {
57400
57405
 
57401
57406
  # gam <UserTypeEntity> create drivefile
57402
57407
  # [(localfile <FileName>|-)|(url <URL>)]
57403
- # [(drivefilename|newfilename <DriveFileName>) | (replacefilename <RegularExpression> <String>)*]
57408
+ # [(drivefilename|newfilename <DriveFileName>) | (replacefilename <REMatchPattern> <RESubstitution>)*]
57404
57409
  # [stripnameprefix <String>]
57405
57410
  # [timestamp <Boolean>]] [timeformat <String>]
57406
57411
  # <DriveFileCreateAttribute>* [noduplicate]
@@ -57928,7 +57933,7 @@ def checkDriveFileShortcut(users):
57928
57933
 
57929
57934
  # gam <UserTypeEntity> update drivefile <DriveFileEntity> [copy] [returnidonly|returnlinkonly]
57930
57935
  # [(localfile <FileName>|-)|(url <URL>)]
57931
- # [retainname | (newfilename <DriveFileName>) | (replacefilename <RegularExpression> <String>)*]
57936
+ # [retainname | (newfilename <DriveFileName>) | (replacefilename <REMatchPattern> <RESubstitution>)*]
57932
57937
  # [stripnameprefix <String>]
57933
57938
  # [timestamp <Boolean>]] [timeformat <String>]
57934
57939
  # <DriveFileUpdateAttribute>*
@@ -58393,7 +58398,7 @@ def getCopyMoveOptions(myarg, copyMoveOptions):
58393
58398
  elif myarg =='stripnameprefix':
58394
58399
  copyMoveOptions['stripNamePrefix'] = getString(Cmd.OB_STRING, minLen=0)
58395
58400
  elif myarg == 'replacefilename':
58396
- copyMoveOptions['replaceFilename'].append(getREPatternReplacement(re.IGNORECASE))
58401
+ copyMoveOptions['replaceFilename'].append(getREPatternSubstitution(re.IGNORECASE))
58397
58402
  elif myarg == 'showpermissionmessages':
58398
58403
  copyMoveOptions['showPermissionMessages'] = getBoolean()
58399
58404
  elif myarg == 'sendemailifrequired':
@@ -59033,7 +59038,7 @@ copyReturnItemMap = {
59033
59038
  }
59034
59039
 
59035
59040
  # gam <UserTypeEntity> copy drivefile <DriveFileEntity>
59036
- # [newfilename <DriveFileName>] (replacefilename <RegularExpression> <String>)*
59041
+ # [newfilename <DriveFileName>] (replacefilename <REMatchPattern> <RESubstitution>)*
59037
59042
  # [stripnameprefix <String>]
59038
59043
  # [excludetrashed]
59039
59044
  # [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*)) |
@@ -59043,9 +59048,9 @@ copyReturnItemMap = {
59043
59048
  # [mergewithparent [<Boolean>]] [recursive [depth <Number>]]
59044
59049
  # <DriveFileCopyAttribute>*
59045
59050
  # [skipids <DriveFileEntity>]
59046
- # [copysubfiles [<Boolean>]] [filenamematchpattern <RegularExpression>] [filemimetype [not] <MimeTypeList>]
59047
- # [copysubfolders [<Boolean>]] [foldernamematchpattern <RegularExpression>]
59048
- # [copysubshortcuts [<Boolean>]] [shortcutnamematchpattern <RegularExpression>]
59051
+ # [copysubfiles [<Boolean>]] [filenamematchpattern <REMatchPattern>] [filemimetype [not] <MimeTypeList>]
59052
+ # [copysubfolders [<Boolean>]] [foldernamematchpattern <REMatchPattern>]
59053
+ # [copysubshortcuts [<Boolean>]] [shortcutnamematchpattern <REMatchPattern>]
59049
59054
  # [duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip]
59050
59055
  # [duplicatefolders merge|duplicatename|uniquename|skip]
59051
59056
  # [copiedshortcutspointtocopiedfiles [<Boolean>]]
@@ -65073,13 +65078,13 @@ SHAREDDRIVE_ACL_ROLES_MAP = {
65073
65078
 
65074
65079
  # gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*]
65075
65080
  # [asadmin [shareddriveadminquery|query <QuerySharedDrive>]]
65076
- # [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
65081
+ # [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
65077
65082
  # (role|roles <SharedDriveACLRoleList>)*
65078
65083
  # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
65079
65084
  # [guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
65080
65085
  # gam <UserTypeEntity> show shareddrives
65081
65086
  # [asadmin [shareddriveadminquery|query <QuerySharedDrive>]]
65082
- # [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
65087
+ # [matchname <REMatchPattrn>] [orgunit|org|ou <OrgUnitPath>]
65083
65088
  # (role|roles <SharedDriveACLRoleLIst>)*
65084
65089
  # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
65085
65090
  # [guiroles [<Boolean>]] [formatjson]
@@ -65373,7 +65378,7 @@ SHOW_NO_PERMISSIONS_DRIVES_CHOICE_MAP = {
65373
65378
 
65374
65379
  # gam [<UserTypeEntity>] print shareddriveacls [todrive <ToDriveAttribute>*]
65375
65380
  # [asadmin] [shareddriveadminquery|query <QuerySharedDrive>]
65376
- # [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
65381
+ # [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
65377
65382
  # [user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)*
65378
65383
  # <PermissionMatch>* [<PermissionMatchAction>] [pmselect]
65379
65384
  # [oneitemperrow] [maxitems <Integer>]
@@ -65383,7 +65388,7 @@ SHOW_NO_PERMISSIONS_DRIVES_CHOICE_MAP = {
65383
65388
  # [formatjson [quotechar <Character>]]
65384
65389
  # gam [<UserTypeEntity>] show shareddriveacls
65385
65390
  # [asadmin] [shareddriveadminquery|query <QuerySharedDrive>]
65386
- # [matchname <RegularExpression>] [orgunit|org|ou <OrgUnitPath>]
65391
+ # [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
65387
65392
  # [user|group <EmailAddress> [checkgroups]] (role|roles <SharedDriveACLRoleList>)*
65388
65393
  # <PermissionMatch>* [<PermissionMatchAction>] [pmselect]
65389
65394
  # [oneitemperrow] [maxitems <Integer>]
@@ -66143,7 +66148,7 @@ def checkUserGroupMatchPattern(groupEmail, matchPattern):
66143
66148
 
66144
66149
  # gam <UserTypeEntity> delete group|groups
66145
66150
  # [(domain <DomainName>)|(customerid <CustomerID>)|
66146
- # (emailmatchpattern [not] <RegularExpression>)|<GroupEntity>]
66151
+ # (emailmatchpattern [not] <REMatchPattern>)|<GroupEntity>]
66147
66152
  def deleteUserFromGroups(users):
66148
66153
  cd = buildGAPIObject(API.DIRECTORY)
66149
66154
  groupKeys = None
@@ -68683,7 +68688,8 @@ def cleanLabelQuery(labelQuery):
68683
68688
  labelQuery = labelQuery.replace(ch, '-')
68684
68689
  return labelQuery.lower()
68685
68690
 
68686
- # gam <UserTypeEntity> update label|labels [search <RegularExpression>] [replace <LabelReplacement>] [merge [keepoldlabel]]
68691
+ # gam <UserTypeEntity> update label|labels
68692
+ # [search <REMatchPattern>] [replace <RESubstitution>] [merge [keepoldlabel]]
68687
68693
  # search defaults to '^Inbox/(.*)$' which will find all labels in the Inbox
68688
68694
  # replace defaults to '%s'
68689
68695
  def updateLabels(users):
@@ -68698,7 +68704,7 @@ def updateLabels(users):
68698
68704
  pattern = validateREPattern(search, re.IGNORECASE)
68699
68705
  elif myarg == 'replace':
68700
68706
  replaceLocation = Cmd.Location()
68701
- replace = getString(Cmd.OB_LABEL_REPLACEMENT)
68707
+ replace = getString(Cmd.OB_RE_SUBSTITUTION)
68702
68708
  elif myarg == 'merge':
68703
68709
  merge = True
68704
68710
  elif myarg == 'keepoldlabel':
@@ -68708,12 +68714,8 @@ def updateLabels(users):
68708
68714
  # Validate that number of substitions in replace matches the number of groups in pattern
68709
68715
  useRegexSub = replace.find('%s') == -1
68710
68716
  if useRegexSub:
68711
- patternGroups = pattern.groups
68712
- replSubs = REPLACE_GROUP_PATTERN.findall(replace)
68713
- for replSub in replSubs:
68714
- if int(replSub) > patternGroups:
68715
- Cmd.SetLocation(replaceLocation)
68716
- usageErrorExit(Msg.MISMATCH_RE_SEARCH_REPLACE_SUBFIELDS.format(pattern.groups, search, int(replSub), replace))
68717
+ Cmd.SetLocation(replaceLocation)
68718
+ validateREPatternSubstitution(pattern, replace)
68717
68719
  else:
68718
68720
  if pattern.groups != replace.count('%s'):
68719
68721
  Cmd.SetLocation(replaceLocation)
@@ -68735,7 +68737,10 @@ def updateLabels(users):
68735
68737
  match_result = pattern.match(label['name'])
68736
68738
  if match_result is not None:
68737
68739
  labelMatches += 1
68738
- newLabelName = pattern.sub(replace, label['name']) if useRegexSub else replace % match_result.groups()
68740
+ if useRegexSub:
68741
+ newLabelName = pattern.sub(replace, label['name'])
68742
+ else:
68743
+ newLabelName = replace % match_result.groups()
68739
68744
  newLabelNameLower = newLabelName.lower()
68740
68745
  try:
68741
68746
  Act.Set(Act.RENAME)
@@ -68868,7 +68873,7 @@ def deleteLabels(users, labelEntity):
68868
68873
  except (GAPI.serviceNotAvailable, GAPI.badRequest):
68869
68874
  userGmailServiceNotEnabledWarning(user, i, count)
68870
68875
 
68871
- # gam <UserTypeEntity> delete label|labels <LabelName>|regex:<RegularExpression>
68876
+ # gam <UserTypeEntity> delete label|labels <LabelName>|regex:<REMatchPattern>
68872
68877
  def deleteLabel(users):
68873
68878
  deleteLabels(users, getStringReturnInList(Cmd.OB_LABEL_NAME))
68874
68879
 
@@ -70162,7 +70167,7 @@ def _draftImportInsertMessage(users, operation):
70162
70167
  # gam <UserTypeEntity> draft message
70163
70168
  # <MessageContent>
70164
70169
  # (replace <Tag> <UserReplacement>)*
70165
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
70170
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*
70166
70171
  # (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
70167
70172
  # (attach <FileName> [charset <CharSet>])*
70168
70173
  # (embedimage <FileName> <String>)*
@@ -70172,7 +70177,7 @@ def draftMessage(users):
70172
70177
  # gam <UserTypeEntity> import message
70173
70178
  # <MessageContent>
70174
70179
  # (replace <Tag> <UserReplacement>)*
70175
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
70180
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*
70176
70181
  # (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
70177
70182
  # (addlabel <LabelName>)* [labels <LabelNameList>]
70178
70183
  # (attach <FileName> [charset <CharSet>])*
@@ -70184,7 +70189,7 @@ def importMessage(users):
70184
70189
  # gam <UserTypeEntity> insert message
70185
70190
  # <MessageContent>
70186
70191
  # (replace <Tag> <UserReplacement>)*
70187
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
70192
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*
70188
70193
  # (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
70189
70194
  # (addlabel <LabelName>)* [labels <LabelNameList>]
70190
70195
  # (attach <FileName> [charset <CharSet>])*
@@ -70994,21 +70999,21 @@ def printShowMessagesThreads(users, entityType):
70994
70999
 
70995
71000
  # gam <UserTypeEntity> print message|messages [todrive <ToDriveAttribute>*]
70996
71001
  # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
70997
- # [labelmatchpattern <RegularExpression>] [sendermatchpattern <RegularExpression>]
71002
+ # [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
70998
71003
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
70999
71004
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
71000
71005
  # [convertcrnl] [delimiter <Character>]
71001
71006
  # [countsonly|positivecountsonly] [useronly]
71002
- # [[attachmentnamepattern <RegularExpression>]
71007
+ # [[attachmentnamepattern <REMatchPattern>]
71003
71008
  # [showattachments [noshowtextplain]]]
71004
71009
  # (addcsvdata <FieldName> <String>)*
71005
71010
  # gam <UserTypeEntity> show message|messages
71006
71011
  # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
71007
- # [labelmatchpattern <RegularExpression>] [sendermatchpattern <RegularExpression>]
71012
+ # [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
71008
71013
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
71009
71014
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
71010
71015
  # [countsonly|positivecountsonly] [useronly]
71011
- # [[attachmentnamepattern <RegularExpression>]
71016
+ # [[attachmentnamepattern <REMatchPattern>]
71012
71017
  # [showattachments [noshowtextplain]]
71013
71018
  # [saveattachments [targetfolder <FilePath>] [overwrite [<Boolean>]]]
71014
71019
  # [uploadattachments [<DriveFileParentAttribute>]]]
@@ -71017,21 +71022,21 @@ def printShowMessages(users):
71017
71022
 
71018
71023
  # gam <UserTypeEntity> print thread|threads [todrive <ToDriveAttribute>*]
71019
71024
  # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
71020
- # [labelmatchpattern <RegularExpression>]
71025
+ # [labelmatchpattern <REMatchPattern>]
71021
71026
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
71022
71027
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
71023
71028
  # [convertcrnl] [delimiter <Character>]
71024
71029
  # [countsonly|positivecountsonly] [useronly]
71025
- # [[attachmentnamepattern <RegularExpression>]
71030
+ # [[attachmentnamepattern <REMatchPattern>]
71026
71031
  # [showattachments [noshowtextplain]]]
71027
71032
  # (addcsvdata <FieldName> <String>)*
71028
71033
  # gam <UserTypeEntity> show thread|threads
71029
71034
  # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
71030
- # [labelmatchpattern <RegularExpression>]
71035
+ # [labelmatchpattern <REMatchPattern>]
71031
71036
  # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
71032
71037
  # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
71033
71038
  # [countsonly|positivecountsonly] [useronly]
71034
- # [[attachmentnamepattern <RegularExpression>]
71039
+ # [[attachmentnamepattern <REMatchPattern>]
71035
71040
  # [showattachments [noshowtextplain]]
71036
71041
  # [saveattachments [targetfolder <FilePath>] [overwrite [<Boolean>]]]
71037
71042
  # [uploadattachments [<DriveFileParentAttribute>]]]
@@ -72493,7 +72498,7 @@ SMTPMSA_REQUIRED_FIELDS = ['host', 'port', 'username', 'password']
72493
72498
  # gam <UserTypeEntity> [create] sendas <EmailAddress> [name] <String>
72494
72499
  # [<SendAsContent>
72495
72500
  # (replace <Tag> <UserReplacement>)*
72496
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
72501
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
72497
72502
  # [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
72498
72503
  # [smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
72499
72504
  # smtpmsa.username <UserName> smtpmsa.password <Password>
@@ -72501,7 +72506,7 @@ SMTPMSA_REQUIRED_FIELDS = ['host', 'port', 'username', 'password']
72501
72506
  # gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
72502
72507
  # [<SendAsContent>
72503
72508
  # (replace <Tag> <UserReplacement>)*
72504
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
72509
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
72505
72510
  # [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
72506
72511
  def createUpdateSendAs(users):
72507
72512
  updateCmd = Act.Get() == Act.UPDATE
@@ -73338,7 +73343,7 @@ def printShowCSEKeyPairs(users):
73338
73343
  # gam <UserTypeEntity> signature|sig
73339
73344
  # <SignatureContent>
73340
73345
  # (replace <Tag> <String>)*
73341
- # (replaceregex <RegularExpression> <String> <Tag> <String>)*
73346
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
73342
73347
  # [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
73343
73348
  # [name <String>]
73344
73349
  # [primary]
@@ -73434,7 +73439,7 @@ def _showVacation(user, i, count, result, showDisabled, sigReplyFormat):
73434
73439
  # gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
73435
73440
  # [<VacationMessageContent>
73436
73441
  # (replace <Tag> <UserReplacement>)*
73437
- # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
73442
+ # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
73438
73443
  # [html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
73439
73444
  # [start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
73440
73445
  def setVacation(users):
gam/gamlib/glclargs.py CHANGED
@@ -952,7 +952,6 @@ class GamCLArgs():
952
952
  OB_LABEL_ID_LIST = 'LabelIDLIst'
953
953
  OB_LABEL_NAME = 'LabelName'
954
954
  OB_LABEL_NAME_LIST = 'LabelNameList'
955
- OB_LABEL_REPLACEMENT = 'LabelReplacement'
956
955
  OB_LANGUAGE_LIST = 'LanguageList'
957
956
  OB_LOOKERSTUDIO_PERMISSION_ENTITY = 'LookerStudioPermissionEntity'
958
957
  OB_MATTER_ITEM = 'MatterItem'
@@ -991,7 +990,7 @@ class GamCLArgs():
991
990
  OB_RESOURCE_ENTITY = 'ResourceEntity'
992
991
  OB_RESOURCE_ID = 'ResourceID'
993
992
  OB_RE_PATTERN = 'REPattern'
994
- OB_RE_REPLACEMENT = 'REReplacement'
993
+ OB_RE_SUBSTITUTION = 'RESubstitution'
995
994
  OB_ROLE_ASSIGNMENT_ID = 'RoleAssignmentID'
996
995
  OB_ROLE_ITEM = 'RoleItem'
997
996
  OB_ROLE_LIST = 'RoleList'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.5.21
3
+ Version: 7.5.22
4
4
  Summary: CLI tool to manage Google Workspace
5
5
  Project-URL: Homepage, https://github.com/GAM-team/GAM
6
6
  Project-URL: Issues, https://github.com/GAM-team/GAM/issues
@@ -1,4 +1,4 @@
1
- gam/__init__.py,sha256=VBXU9NxJVzPLYR2ySONCwtzSN1bpmJ40EFsdlgJRs1Q,3484729
1
+ gam/__init__.py,sha256=8RlQ9HrG7vrPGTkXqMVmKI-zqgFE7YzqxrOTLkBlRKo,3484762
2
2
  gam/__main__.py,sha256=amz0-959ph6zkZKqjaar4n60yho-T37w6qWI36qx0CA,1049
3
3
  gam/cacerts.pem,sha256=nJuWha0xm5dHw_5ptGphwRoO-r36Ccpqiww9pCEDbSc,67484
4
4
  gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
@@ -25,7 +25,7 @@ gam/gamlib/__init__.py,sha256=z5mF-y0j8pm-YNFBaiuxB4M_GAUPG-cXWwrhYwrVReM,679
25
25
  gam/gamlib/glaction.py,sha256=1Il_HrChVnPkzZwiZs5au4mFQVtq4K1Z42uIuR6qdnI,9419
26
26
  gam/gamlib/glapi.py,sha256=EAQXkaM13t6jjh9vL4eHJqIZRI5kmzeneiFs5xcWXfg,34304
27
27
  gam/gamlib/glcfg.py,sha256=cV011FpIWge4oi5_dJrdof66vUqX6UCvTGWWTNVmYEg,28055
28
- gam/gamlib/glclargs.py,sha256=Dg7xs3Hca8uK_UimbYtp7eVQJcBZwoE1HD7aJr0lEk8,42238
28
+ gam/gamlib/glclargs.py,sha256=jQoPUJoENvoAe8-MjKfcW1gvLnvoxMbvWWYvtQZynfU,42196
29
29
  gam/gamlib/glentity.py,sha256=ZLbyMl9NhN-MBf9Rxmho2dBYeS4SNLMctpeaKFZSbQ4,33801
30
30
  gam/gamlib/glgapi.py,sha256=49PPbxiW6EpPE4E8fAlLMx1mSMcQra1zwi-CSXPa7rk,38473
31
31
  gam/gamlib/glgdata.py,sha256=weRppttWm6uRyqtBoGPKoHiNZ2h28nhfUV4J_mbCszY,2707
@@ -65,8 +65,8 @@ gam/googleapiclient/discovery_cache/base.py,sha256=yCDPtxnbNN-p5_9fzBacC6P3wcUPl
65
65
  gam/googleapiclient/discovery_cache/file_cache.py,sha256=sim3Mg4HgRYo3vX75jvcKy_aV568EvIrtBfvfbw-044,4774
66
66
  gam/iso8601/__init__.py,sha256=Z2PsYbXgAH5a5xzUvgczCboPzqWpm65kRcIngCnhViU,1218
67
67
  gam/iso8601/iso8601.py,sha256=Li2FHZ4sBTWuthuQhyCvmvj0j6At8JbGzkSv2fc2RHU,4384
68
- gam7-7.5.21.dist-info/METADATA,sha256=OsXbB8rZlHdu_Cew6vd_WE_md6KeIygLaYhZ1Yz7rm8,2889
69
- gam7-7.5.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
- gam7-7.5.21.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
71
- gam7-7.5.21.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
- gam7-7.5.21.dist-info/RECORD,,
68
+ gam7-7.5.22.dist-info/METADATA,sha256=0Lzj8QF1Z5vT6EfdcY2vOvfr0kipHS9jsqGPzOSyDrI,2889
69
+ gam7-7.5.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
+ gam7-7.5.22.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
71
+ gam7-7.5.22.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
+ gam7-7.5.22.dist-info/RECORD,,
File without changes