gam7 7.4.3__py3-none-any.whl → 7.5.0__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.04.03'
28
+ __version__ = '7.05.00'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -4710,7 +4710,7 @@ def getAPIService(api, httpObj):
4710
4710
 
4711
4711
  def getService(api, httpObj):
4712
4712
  ### Drive v3beta
4713
- mapDriveURL = api == API.DRIVE3 and GC.Values[GC.DRIVE_V3_BETA]
4713
+ # mapDriveURL = api == API.DRIVE3 and GC.Values[GC.DRIVE_V3_BETA]
4714
4714
  hasLocalJSON = API.hasLocalJSON(api)
4715
4715
  api, version, v2discovery = API.getVersion(api)
4716
4716
  if api in GM.Globals[GM.CURRENT_API_SERVICES] and version in GM.Globals[GM.CURRENT_API_SERVICES][api]:
@@ -4727,8 +4727,8 @@ def getService(api, httpObj):
4727
4727
  GM.Globals[GM.CURRENT_API_SERVICES].setdefault(api, {})
4728
4728
  GM.Globals[GM.CURRENT_API_SERVICES][api][version] = service._rootDesc.copy()
4729
4729
  ### Drive v3beta
4730
- if mapDriveURL:
4731
- setattr(service, '_baseUrl', getattr(service, '_baseUrl').replace('/v3/', '/v3beta/'))
4730
+ # if mapDriveURL:
4731
+ # setattr(service, '_baseUrl', getattr(service, '_baseUrl').replace('/v3/', '/v3beta/'))
4732
4732
  if GM.Globals[GM.CACHE_DISCOVERY_ONLY]:
4733
4733
  clearServiceCache(service)
4734
4734
  return service
@@ -5571,6 +5571,8 @@ def buildGAPIServiceObject(api, user, i=0, count=0, displayError=True):
5571
5571
  userEmail = getSaUser(user)
5572
5572
  httpObj = getHttpObj(cache=GM.Globals[GM.CACHE_DIR])
5573
5573
  service = getService(api, httpObj)
5574
+ if api == API.MEET_BETA:
5575
+ api = API.MEET
5574
5576
  credentials = getSvcAcctCredentials(api, userEmail)
5575
5577
  request = transportCreateRequest(httpObj)
5576
5578
  triesLimit = 3
@@ -7324,12 +7326,6 @@ def _getRawFields(requiredField=None):
7324
7326
  return rawFields
7325
7327
  return f'{requiredField},{rawFields}'
7326
7328
 
7327
- def _addInitialField(fieldsList, initialField):
7328
- if isinstance(initialField, list):
7329
- fieldsList.extend(initialField)
7330
- else:
7331
- fieldsList.append(initialField)
7332
-
7333
7329
  def CheckInputRowFilterHeaders(titlesList, rowFilter, rowDropFilter):
7334
7330
  status = True
7335
7331
  for filterVal in rowFilter:
@@ -7744,6 +7740,12 @@ def RowFilterMatch(row, titlesList, rowFilter, rowFilterModeAll, rowDropFilter,
7744
7740
  # }
7745
7741
  # fieldsList is the list of API fields
7746
7742
  def getFieldsList(myarg, fieldsChoiceMap, fieldsList, initialField=None, fieldsArg='fields', onlyFieldsArg=False):
7743
+ def addInitialField():
7744
+ if isinstance(initialField, list):
7745
+ fieldsList.extend(initialField)
7746
+ else:
7747
+ fieldsList.append(initialField)
7748
+
7747
7749
  def addMappedFields(mappedFields):
7748
7750
  if isinstance(mappedFields, list):
7749
7751
  fieldsList.extend(mappedFields)
@@ -7752,11 +7754,11 @@ def getFieldsList(myarg, fieldsChoiceMap, fieldsList, initialField=None, fieldsA
7752
7754
 
7753
7755
  if not onlyFieldsArg and myarg in fieldsChoiceMap:
7754
7756
  if not fieldsList and initialField is not None:
7755
- _addInitialField(fieldsList, initialField)
7757
+ addInitialField()
7756
7758
  addMappedFields(fieldsChoiceMap[myarg])
7757
7759
  elif myarg == fieldsArg:
7758
7760
  if not fieldsList and initialField is not None:
7759
- _addInitialField(fieldsList, initialField)
7761
+ addInitialField()
7760
7762
  for field in _getFieldsList():
7761
7763
  if field in fieldsChoiceMap:
7762
7764
  addMappedFields(fieldsChoiceMap[field])
@@ -7933,14 +7935,21 @@ class CSVPrintFile():
7933
7935
  fieldsList.append(fields)
7934
7936
  self.AddTitles(fields.replace('.', GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]))
7935
7937
 
7938
+ def addInitialField(self, initialField, fieldsChoiceMap, fieldsList):
7939
+ if isinstance(initialField, list):
7940
+ for field in initialField:
7941
+ self.AddField(field, fieldsChoiceMap, fieldsList)
7942
+ else:
7943
+ self.AddField(initialField, fieldsChoiceMap, fieldsList)
7944
+
7936
7945
  def GetFieldsListTitles(self, fieldName, fieldsChoiceMap, fieldsList, initialField=None):
7937
7946
  if fieldName in fieldsChoiceMap:
7938
7947
  if not fieldsList and initialField is not None:
7939
- _addInitialField(fieldsList, initialField)
7948
+ self.addInitialField(initialField, fieldsChoiceMap, fieldsList)
7940
7949
  self.AddField(fieldName, fieldsChoiceMap, fieldsList)
7941
7950
  elif fieldName == 'fields':
7942
7951
  if not fieldsList and initialField is not None:
7943
- _addInitialField(fieldsList, initialField)
7952
+ self.addInitialField(initialField, fieldsChoiceMap, fieldsList)
7944
7953
  for field in _getFieldsList():
7945
7954
  if field in fieldsChoiceMap:
7946
7955
  self.AddField(field, fieldsChoiceMap, fieldsList)
@@ -9833,7 +9842,7 @@ def MultiprocessGAMCommands(items, showCmds):
9833
9842
  if GM.Globals[GM.MULTIPROCESS_EXIT_CONDITION] is not None and checkChildProcessRC(result[1]):
9834
9843
  GM.Globals[GM.MULTIPROCESS_EXIT_PROCESSING] = True
9835
9844
 
9836
- def signal_handler(sig, frame):
9845
+ def signal_handler(*_):
9837
9846
  nonlocal controlC
9838
9847
  controlC = True
9839
9848
 
@@ -17247,7 +17256,7 @@ def checkOrgUnitPathExists(cd, orgUnitPath, i=0, count=0, showError=False):
17247
17256
  return (False, orgUnitPath, orgUnitPath)
17248
17257
 
17249
17258
  def _batchMoveCrOSesToOrgUnit(cd, orgUnitPath, orgUnitId, i, count, items, quickCrOSMove, fromOrgUnitPath=None):
17250
- def _callbackMoveCrOSesToOrgUnit(request_id, response, exception):
17259
+ def _callbackMoveCrOSesToOrgUnit(request_id, _, exception):
17251
17260
  ri = request_id.splitlines()
17252
17261
  if exception is None:
17253
17262
  if not fromOrgUnitPath:
@@ -17328,7 +17337,7 @@ def _batchMoveCrOSesToOrgUnit(cd, orgUnitPath, orgUnitId, i, count, items, quick
17328
17337
 
17329
17338
  def _batchMoveUsersToOrgUnit(cd, orgUnitPath, i, count, items, fromOrgUnitPath=None):
17330
17339
  _MOVE_USER_REASON_TO_MESSAGE_MAP = {GAPI.USER_NOT_FOUND: Msg.DOES_NOT_EXIST, GAPI.DOMAIN_NOT_FOUND: Msg.SERVICE_NOT_APPLICABLE, GAPI.FORBIDDEN: Msg.SERVICE_NOT_APPLICABLE}
17331
- def _callbackMoveUsersToOrgUnit(request_id, response, exception):
17340
+ def _callbackMoveUsersToOrgUnit(request_id, _, exception):
17332
17341
  ri = request_id.splitlines()
17333
17342
  if exception is None:
17334
17343
  if not fromOrgUnitPath:
@@ -27481,6 +27490,8 @@ def printShowChatEvents(users):
27481
27490
  csvPF.writeCSVfile('Chat Events')
27482
27491
 
27483
27492
  def buildMeetServiceObject(api=API.MEET, user=None, i=0, count=0, entityTypeList=None):
27493
+ if GC.Values[GC.MEET_V2_BETA]:
27494
+ api = API.MEET_BETA
27484
27495
  user, meet = buildGAPIServiceObject(api, user, i, count)
27485
27496
  kvList = [Ent.USER, user]
27486
27497
  if entityTypeList is not None:
@@ -27504,7 +27515,10 @@ MEET_SPACE_OPTIONS_MAP = {
27504
27515
  'reactionrestriction': 'reactionRestriction',
27505
27516
  'presentrestriction': 'presentRestriction',
27506
27517
  'defaultjoinasviewer': 'defaultJoinAsViewerType',
27507
- 'firstjoiner': 'firstJoinerType'
27518
+ 'firstjoiner': 'firstJoinerType',
27519
+ 'autorecording': 'recordingConfig',
27520
+ 'autosmartnotes': 'smartNotesConfig',
27521
+ 'autotranscription': 'transcriptionConfig',
27508
27522
  }
27509
27523
 
27510
27524
  MEET_SPACE_ACCESSTYPE_CHOICES = {'open', 'trusted', 'restricted'}
@@ -27518,9 +27532,15 @@ MEET_SPACE_RESTRICTIONS_CHOICES_MAP = {
27518
27532
  'norestriction': 'NO_RESTRICTION'
27519
27533
  }
27520
27534
 
27521
- MEET_SPACE_FIRSTJOINERTYPE_CHOICES_MAP = {
27522
- 'hostsonly': 'HOSTS_ONLY',
27523
- 'anyone': 'ANYONE'
27535
+ #MEET_SPACE_FIRSTJOINERTYPE_CHOICES_MAP = {
27536
+ # 'hostsonly': 'HOSTS_ONLY',
27537
+ # 'anyone': 'ANYONE'
27538
+ # }
27539
+
27540
+ MEET_SPACE_ARTIFACT_SUB_OPTIONS = {
27541
+ 'recordingConfig': 'autoRecordingGeneration',
27542
+ 'smartNotesConfig': 'autoSmartNotesGeneration',
27543
+ 'transcriptionConfig': 'autoTranscriptionGeneration'
27524
27544
  }
27525
27545
 
27526
27546
  # [accesstype open|trusted|restricted]
@@ -27531,7 +27551,10 @@ MEET_SPACE_FIRSTJOINERTYPE_CHOICES_MAP = {
27531
27551
  # [presentrestriction hostsonly|norestriction]
27532
27552
  # [defaultjoinasviewer <Boolean>]
27533
27553
  # [firstjoiner hostsonly|anyone]
27534
- def _getMeetSpaceParameters(myarg, body, updateMask):
27554
+ # [autorecording <Boolean>]
27555
+ # [autosmartnotes <Boolean>]
27556
+ # [autotranscription <Boolean>]
27557
+ def _getMeetSpaceParameters(myarg, body):
27535
27558
  option = MEET_SPACE_OPTIONS_MAP.get(myarg, None)
27536
27559
  if option is None:
27537
27560
  return False
@@ -27541,15 +27564,17 @@ def _getMeetSpaceParameters(myarg, body, updateMask):
27541
27564
  body['config'][option] = getChoice(MEET_SPACE_ENTRYPOINTACCESS_CHOICES_MAP, mapChoice=True)
27542
27565
  elif option == 'moderation':
27543
27566
  body['config'][option] = 'ON' if getBoolean() else 'OFF'
27544
- elif option in {'chatrestriction', 'reactionrestriction', 'presentrestriction'}:
27545
- body['config'].setdefault('moderationRestictions', {})
27567
+ elif option in {'chatRestriction', 'reactionRestriction', 'presentRestriction'}:
27568
+ body['config'].setdefault('moderationRestrictions', {})
27546
27569
  body['config']['moderationRestrictions'][option] = getChoice(MEET_SPACE_RESTRICTIONS_CHOICES_MAP, mapChoice=True)
27547
- option = f'moderationRestrictions.{option}'
27548
27570
  elif option == 'defaultJoinAsViewerType':
27549
27571
  body['config'][option] = 'ON' if getBoolean() else 'OFF'
27550
- elif option == 'firstJoinerType':
27551
- body['config'][option] = getChoice(MEET_SPACE_FIRSTJOINERTYPE_CHOICES_MAP, mapChoice=True)
27552
- updateMask.append(f'config.{option}')
27572
+ # elif option == 'firstJoinerType':
27573
+ # body['config'][option] = getChoice(MEET_SPACE_FIRSTJOINERTYPE_CHOICES_MAP, mapChoice=True)
27574
+ elif option in {'recordingConfig', 'transcriptionConfig', 'smartNotesConfig'}:
27575
+ body['config'].setdefault('artifactConfig', {})
27576
+ body['config']['artifactConfig'].setdefault(option, {})
27577
+ body['config']['artifactConfig'][option][MEET_SPACE_ARTIFACT_SUB_OPTIONS[option]] = 'ON' if getBoolean() else 'OFF'
27553
27578
  return True
27554
27579
 
27555
27580
  # gam <UserTypeEntity> create meetspace
@@ -27564,10 +27589,9 @@ def createMeetSpace(users):
27564
27589
  # 'firstJoinerType': 'ANYONE',
27565
27590
  }}
27566
27591
  returnIdOnly = False
27567
- updateMask = []
27568
27592
  while Cmd.ArgumentsRemaining():
27569
27593
  myarg = getArgument()
27570
- if _getMeetSpaceParameters(myarg, body, updateMask):
27594
+ if _getMeetSpaceParameters(myarg, body):
27571
27595
  pass
27572
27596
  elif myarg == 'returnidonly':
27573
27597
  returnIdOnly = True
@@ -27602,12 +27626,11 @@ def updateMeetSpace(users):
27602
27626
  FJQC = FormatJSONQuoteChar()
27603
27627
  name = None
27604
27628
  body = {'config': {}}
27605
- updateMask = []
27606
27629
  while Cmd.ArgumentsRemaining():
27607
27630
  myarg = getArgument()
27608
27631
  if (myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/')):
27609
27632
  name = getSpaceName(myarg)
27610
- elif _getMeetSpaceParameters(myarg, body, updateMask):
27633
+ elif _getMeetSpaceParameters(myarg, body):
27611
27634
  pass
27612
27635
  else:
27613
27636
  FJQC.GetFormatJSON(myarg)
@@ -27622,7 +27645,7 @@ def updateMeetSpace(users):
27622
27645
  try:
27623
27646
  space = callGAPI(meet.spaces(), 'patch',
27624
27647
  throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
27625
- name=name, updateMask=','.join(updateMask), body=body)
27648
+ name=name, updateMask='', body=body)
27626
27649
  if not FJQC.formatJSON:
27627
27650
  entityActionPerformed(kvList, i, count)
27628
27651
  Ind.Increment()
@@ -32000,7 +32023,7 @@ def doUpdateGroups():
32000
32023
  GAPI.INVALID_MEMBER: Msg.INVALID_MEMBER,
32001
32024
  GAPI.CYCLIC_MEMBERSHIPS_NOT_ALLOWED: Msg.WOULD_MAKE_MEMBERSHIP_CYCLE}
32002
32025
 
32003
- def _callbackAddGroupMembers(request_id, response, exception):
32026
+ def _callbackAddGroupMembers(request_id, _, exception):
32004
32027
  ri = request_id.splitlines()
32005
32028
  if exception is None:
32006
32029
  _showSuccess(ri[RI_ENTITY], ri[RI_ITEM], ri[RI_ROLE], ri[RI_OPTION], int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -32089,7 +32112,7 @@ def doUpdateGroups():
32089
32112
  GAPI.CONDITION_NOT_MET: f'{Msg.NOT_A} {Ent.Singular(Ent.MEMBER)}',
32090
32113
  GAPI.INVALID_MEMBER: Msg.DOES_NOT_EXIST}
32091
32114
 
32092
- def _callbackRemoveGroupMembers(request_id, response, exception):
32115
+ def _callbackRemoveGroupMembers(request_id, _, exception):
32093
32116
  ri = request_id.splitlines()
32094
32117
  if exception is None:
32095
32118
  _showSuccess(ri[RI_ENTITY], ri[RI_ITEM], ri[RI_ROLE], DELIVERY_SETTINGS_UNDEFINED, int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -32188,7 +32211,7 @@ def doUpdateGroups():
32188
32211
  except (GAPI.invalidMember, GAPI.resourceNotFound, GAPI.serviceNotAvailable) as e:
32189
32212
  _showFailure(group, member, role, str(e), j, jcount)
32190
32213
 
32191
- def _callbackUpdateGroupMembers(request_id, response, exception):
32214
+ def _callbackUpdateGroupMembers(request_id, _, exception):
32192
32215
  ri = request_id.splitlines()
32193
32216
  if exception is None:
32194
32217
  _showSuccess(ri[RI_ENTITY], ri[RI_ITEM], ri[RI_ROLE], ri[RI_OPTION], int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -33425,6 +33448,7 @@ PRINT_GROUPS_JSON_TITLES = ['email', 'JSON']
33425
33448
 
33426
33449
  # gam print groups [todrive <ToDriveAttribute>*]
33427
33450
  # [([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryUserList>)]))|
33451
+ # (group|group_ns|group_susp <GroupItem>)|
33428
33452
  # (select <GroupEntity>)]
33429
33453
  # [emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
33430
33454
  # [descriptionmatchpattern [not] <RegularExpression>] (matchsetting [not] <GroupAttribute>)*
@@ -33637,6 +33661,12 @@ def doPrintGroups():
33637
33661
  pass
33638
33662
  elif getGroupMatchPatterns(myarg, matchPatterns, False):
33639
33663
  pass
33664
+ elif myarg in {'group', 'groupns', 'groupsusp'}:
33665
+ entitySelection = [getString(Cmd.OB_EMAIL_ADDRESS)]
33666
+ if myarg == 'groupns':
33667
+ isSuspended = False
33668
+ elif myarg == 'groupsusp':
33669
+ isSuspended = True
33640
33670
  elif myarg == 'select':
33641
33671
  entitySelection = getEntityList(Cmd.OB_GROUP_ENTITY)
33642
33672
  elif myarg in SUSPENDED_ARGUMENTS:
@@ -34206,7 +34236,7 @@ def doPrintGroupMembers():
34206
34236
  pass
34207
34237
  elif getMemberMatchOptions(myarg, memberOptions):
34208
34238
  pass
34209
- elif csvPF.GetFieldsListTitles(myarg, GROUPMEMBERS_FIELDS_CHOICE_MAP, fieldsList):
34239
+ elif csvPF.GetFieldsListTitles(myarg, GROUPMEMBERS_FIELDS_CHOICE_MAP, fieldsList, initialField='email'):
34210
34240
  pass
34211
34241
  elif myarg == 'membernames':
34212
34242
  memberOptions[MEMBEROPTION_MEMBERNAMES] = True
@@ -36223,6 +36253,7 @@ CIGROUPMEMBERS_FIELDS_CHOICE_MAP = {
36223
36253
  'createtime': 'createTime',
36224
36254
  'delivery': 'deliverySetting',
36225
36255
  'deliverysettings': 'deliverySetting',
36256
+ 'email': 'preferredMemberKey',
36226
36257
  'expiretime': 'expireTime',
36227
36258
  'id': 'name',
36228
36259
  'memberkey': 'preferredMemberKey',
@@ -36309,7 +36340,7 @@ def doPrintCIGroupMembers():
36309
36340
  pass
36310
36341
  elif getMemberMatchOptions(myarg, memberOptions):
36311
36342
  pass
36312
- elif getFieldsList(myarg, CIGROUPMEMBERS_FIELDS_CHOICE_MAP, fieldsList):
36343
+ elif getFieldsList(myarg, CIGROUPMEMBERS_FIELDS_CHOICE_MAP, fieldsList, initialField='preferredMemberKey'):
36313
36344
  pass
36314
36345
  elif myarg == 'noduplicates':
36315
36346
  memberOptions[MEMBEROPTION_NODUPLICATES] = True
@@ -42323,7 +42354,7 @@ def doPrintVaultCounts():
42323
42354
  # gam [<UserTypeEntity>] print siteacls <SiteEntity> [todrive <ToDriveAttribute>*]
42324
42355
  # gam [<UserTypeEntity>] print siteactivity <SiteEntity> [todrive <ToDriveAttribute>*]
42325
42356
  # [startindex <Number>] [maxresults <Number>] [updated_min <Date>] [updated_max <Date>]
42326
- def deprecatedUserSites(users):
42357
+ def deprecatedUserSites(_):
42327
42358
  deprecatedCommandExit()
42328
42359
 
42329
42360
  def deprecatedDomainSites():
@@ -43645,7 +43676,7 @@ def waitForMailbox(entityList):
43645
43676
  Ind.Decrement()
43646
43677
 
43647
43678
  def getUserLicenses(lic, user, skus):
43648
- def _callbackGetLicense(request_id, response, exception):
43679
+ def _callbackGetLicense(_, response, exception):
43649
43680
  if exception is None:
43650
43681
  if response and 'skuId' in response:
43651
43682
  licenses.append(response['skuId'])
@@ -48151,7 +48182,7 @@ def _batchAddItemsToCourse(croom, courseId, i, count, addParticipants, role):
48151
48182
  _ADD_PART_REASON_TO_MESSAGE_MAP = {GAPI.NOT_FOUND: Msg.DOES_NOT_EXIST,
48152
48183
  GAPI.ALREADY_EXISTS: Msg.DUPLICATE,
48153
48184
  GAPI.FAILED_PRECONDITION: Msg.NOT_ALLOWED}
48154
- def _callbackAddItemsToCourse(request_id, response, exception):
48185
+ def _callbackAddItemsToCourse(request_id, _, exception):
48155
48186
  ri = request_id.splitlines()
48156
48187
  if exception is None:
48157
48188
  entityActionPerformed([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -48231,7 +48262,7 @@ def _batchRemoveItemsFromCourse(croom, courseId, i, count, removeParticipants, r
48231
48262
  _REMOVE_PART_REASON_TO_MESSAGE_MAP = {GAPI.NOT_FOUND: Msg.DOES_NOT_EXIST,
48232
48263
  GAPI.FORBIDDEN: Msg.FORBIDDEN,
48233
48264
  GAPI.PERMISSION_DENIED: Msg.PERMISSION_DENIED}
48234
- def _callbackRemoveItemsFromCourse(request_id, response, exception):
48265
+ def _callbackRemoveItemsFromCourse(request_id, _, exception):
48235
48266
  ri = request_id.splitlines()
48236
48267
  if exception is None:
48237
48268
  entityActionPerformed([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -48443,7 +48474,7 @@ def doCourseRemoveItems(courseIdList, getEntityListArg):
48443
48474
 
48444
48475
  # gam courses <CourseEntity> clear teachers|students
48445
48476
  # gam course <CourseID> clear teacher|student
48446
- def doCourseClearParticipants(courseIdList, getEntityListArg):
48477
+ def doCourseClearParticipants(courseIdList, _):
48447
48478
  croom = buildGAPIObject(API.CLASSROOM)
48448
48479
  role = getChoice(CLEAR_SYNC_PARTICIPANT_TYPES_MAP, mapChoice=True)
48449
48480
  checkForExtraneousArguments()
@@ -48459,7 +48490,7 @@ def doCourseClearParticipants(courseIdList, getEntityListArg):
48459
48490
  # gam course <CourseID> sync students [addonly|removeonly] <UserTypeEntity>
48460
48491
  # gam courses <CourseEntity> sync teachers [addonly|removeonly] [makefirstteacherowner] <UserTypeEntity>
48461
48492
  # gam course <CourseID> sync teachers [addonly|removeonly] [makefirstteacherowner] <UserTypeEntity>
48462
- def doCourseSyncParticipants(courseIdList, getEntityListArg):
48493
+ def doCourseSyncParticipants(courseIdList, _):
48463
48494
  croom = buildGAPIObject(API.CLASSROOM)
48464
48495
  role = getChoice(CLEAR_SYNC_PARTICIPANT_TYPES_MAP, mapChoice=True)
48465
48496
  if role == Ent.TEACHER:
@@ -58195,6 +58226,7 @@ def initCopyMoveOptions(copyCmd):
58195
58226
  'showPermissionMessages': False,
58196
58227
  'sendEmailIfRequired': False,
58197
58228
  'useDomainAdminAccess': False,
58229
+ 'enforceExpansiveAccess': False,
58198
58230
  'copiedShortcutsPointToCopiedFiles': True,
58199
58231
  'createShortcutsForNonmovableFiles': False,
58200
58232
  'duplicateFiles': DUPLICATE_FILE_OVERWRITE_OLDER,
@@ -58293,6 +58325,8 @@ def getCopyMoveOptions(myarg, copyMoveOptions):
58293
58325
  elif myarg == 'mappermissionsdomain':
58294
58326
  oldDomain = getString(Cmd.OB_DOMAIN_NAME).lower()
58295
58327
  copyMoveOptions['mapPermissionsDomains'][oldDomain] = getString(Cmd.OB_DOMAIN_NAME).lower()
58328
+ elif myarg == 'enforceexpansiveaccess':
58329
+ copyMoveOptions['enforceExpansiveAccess'] = getBoolean()
58296
58330
  else:
58297
58331
  # Move arguments
58298
58332
  if not copyMoveOptions['copyCmd']:
@@ -58564,6 +58598,9 @@ def _copyPermissions(drive, user, i, count, j, jcount,
58564
58598
  updateTargetPerms[permissionId].update(updatePerm)
58565
58599
  updateTargetPerms[permissionId]['updates'] = updatePerm
58566
58600
  copySourcePerms.pop(permissionId)
58601
+ deleteUpdateKwargs = {'useDomainAdminAccess': copyMoveOptions['useDomainAdminAccess']}
58602
+ if entityType != Ent.SHAREDDRIVE:
58603
+ deleteUpdateKwargs['enforceExpansiveAccess'] = copyMoveOptions['enforceExpansiveAccess']
58567
58604
  Ind.Increment()
58568
58605
  action = Act.Get()
58569
58606
  Act.Set(Act.COPY)
@@ -58582,8 +58619,9 @@ def _copyPermissions(drive, user, i, count, j, jcount,
58582
58619
  callGAPI(drive.permissions(), 'create',
58583
58620
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_CREATE_ACL_THROW_REASONS,
58584
58621
  # retryReasons=[GAPI.INVALID_SHARING_REQUEST],
58622
+ useDomainAdminAccess=copyMoveOptions['useDomainAdminAccess'],
58585
58623
  fileId=newFileId, sendNotificationEmail=sendNotificationEmail, emailMessage=None,
58586
- body=permission, fields='', useDomainAdminAccess=copyMoveOptions['useDomainAdminAccess'], supportsAllDrives=True)
58624
+ body=permission, fields='', supportsAllDrives=True)
58587
58625
  if copyMoveOptions['showPermissionMessages']:
58588
58626
  entityActionPerformed(kvList, k, kcount)
58589
58627
  break
@@ -58621,7 +58659,8 @@ def _copyPermissions(drive, user, i, count, j, jcount,
58621
58659
  try:
58622
58660
  callGAPI(drive.permissions(), 'delete',
58623
58661
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_DELETE_ACL_THROW_REASONS+[GAPI.FILE_NEVER_WRITABLE],
58624
- fileId=newFileId, permissionId=permissionId, useDomainAdminAccess=copyMoveOptions['useDomainAdminAccess'], supportsAllDrives=True)
58662
+ **deleteUpdateKwargs,
58663
+ fileId=newFileId, permissionId=permissionId, supportsAllDrives=True)
58625
58664
  if copyMoveOptions['showPermissionMessages']:
58626
58665
  entityActionPerformed(kvList, k, kcount)
58627
58666
  except (GAPI.notFound, GAPI.permissionNotFound,
@@ -58646,8 +58685,9 @@ def _copyPermissions(drive, user, i, count, j, jcount,
58646
58685
  callGAPI(drive.permissions(), 'update',
58647
58686
  bailOnInternalError=True,
58648
58687
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_UPDATE_ACL_THROW_REASONS+[GAPI.FILE_NEVER_WRITABLE],
58649
- fileId=newFileId, permissionId=permissionId, removeExpiration=removeExpiration,
58650
- body=permission['updates'], useDomainAdminAccess=copyMoveOptions['useDomainAdminAccess'], supportsAllDrives=True)
58688
+ removeExpiration=removeExpiration,
58689
+ **deleteUpdateKwargs,
58690
+ fileId=newFileId, permissionId=permissionId, body=permission['updates'], supportsAllDrives=True)
58651
58691
  if copyMoveOptions['showPermissionMessages']:
58652
58692
  entityActionPerformed(kvList, k, kcount)
58653
58693
  except (GAPI.notFound, GAPI.permissionNotFound,
@@ -58921,6 +58961,7 @@ copyReturnItemMap = {
58921
58961
  # [sendemailifrequired [<Boolean>]]
58922
58962
  # [suppressnotselectedmessages [<Boolean>]]
58923
58963
  # [verifyorganizer [<Boolean>]]
58964
+ # [enforceexpansiveaccess [<Boolean>]]
58924
58965
  def copyDriveFile(users):
58925
58966
  def _writeCSVData(user, oldName, oldId, newName, newId, mimeType):
58926
58967
  row = {'User': user, fileNameTitle: oldName, 'id': oldId,
@@ -59648,7 +59689,9 @@ def _updateMoveFilePermissions(drive, user, i, count,
59648
59689
  try:
59649
59690
  callGAPI(drive.permissions(), 'delete',
59650
59691
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_DELETE_ACL_THROW_REASONS+[GAPI.FILE_NEVER_WRITABLE],
59651
- fileId=fileId, permissionId=permissionId, useDomainAdminAccess=copyMoveOptions['useDomainAdminAccess'], supportsAllDrives=True)
59692
+ useDomainAdminAccess=copyMoveOptions['useDomainAdminAccess'],
59693
+ enforceExpansiveAccess=copyMoveOptions['enforceExpansiveAccess'],
59694
+ fileId=fileId, permissionId=permissionId, supportsAllDrives=True)
59652
59695
  if copyMoveOptions['showPermissionMessages']:
59653
59696
  entityActionPerformed(kvList, k, kcount)
59654
59697
  except (GAPI.notFound, GAPI.permissionNotFound,
@@ -59736,6 +59779,7 @@ def _updateMoveFilePermissions(drive, user, i, count,
59736
59779
  # [retainsourcefolders [<Boolean>]]
59737
59780
  # [sendemailifrequired [<Boolean>]]
59738
59781
  # [verifyorganizer [<Boolean>]]
59782
+ # [enforceexpansiveaccess [<Boolean>]]
59739
59783
  def moveDriveFile(users):
59740
59784
  def _cloneFolderMove(drive, user, i, count, j, jcount,
59741
59785
  source, targetChildren, newFolderName, newParentId, newParentName, mergeParentModifiedTime,
@@ -60079,9 +60123,8 @@ def moveDriveFile(users):
60079
60123
  parentBody = {}
60080
60124
  parentParms = initDriveFileAttributes()
60081
60125
  copyMoveOptions = initCopyMoveOptions(False)
60082
- newParentsSpecified = False
60126
+ newParentsSpecified = updateFilePermissions = False
60083
60127
  movedFiles = {}
60084
- updateFilePermissions = False
60085
60128
  verifyOrganizer = True
60086
60129
  while Cmd.ArgumentsRemaining():
60087
60130
  myarg = getArgument()
@@ -60970,6 +61013,7 @@ TRANSFER_DRIVEFILE_ACL_ROLES_MAP = {
60970
61013
  # [nonowner_retainrole reader|commenter|writer|editor|fileorganizer|current|none]
60971
61014
  # [nonowner_targetrole reader|commenter|writer|editor|fileorganizer|current|none|source]
60972
61015
  # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
61016
+ # [enforceexpansiveaccess [<Boolean>]]
60973
61017
  # [preview] [todrive <ToDriveAttribute>*]
60974
61018
  def transferDrive(users):
60975
61019
 
@@ -61156,6 +61200,7 @@ def transferDrive(users):
61156
61200
  callGAPI(sourceDrive.permissions(), 'update',
61157
61201
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.BAD_REQUEST, GAPI.INVALID_OWNERSHIP_TRANSFER,
61158
61202
  GAPI.PERMISSION_NOT_FOUND, GAPI.SHARING_RATE_LIMIT_EXCEEDED],
61203
+ enforceExpansiveAccess=enforceExpansiveAccess,
61159
61204
  fileId=childFileId, permissionId=targetPermissionId,
61160
61205
  transferOwnership=True, body={'role': 'owner'}, fields='')
61161
61206
  if removeSourceParents:
@@ -61344,6 +61389,7 @@ def transferDrive(users):
61344
61389
  if ownerRetainRoleBody['role'] != 'writer':
61345
61390
  callGAPI(targetDrive.permissions(), 'update',
61346
61391
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND, GAPI.BAD_REQUEST, GAPI.SHARING_RATE_LIMIT_EXCEEDED],
61392
+ enforceExpansiveAccess=enforceExpansiveAccess,
61347
61393
  fileId=childFileId, permissionId=sourcePermissionId, body=ownerRetainRoleBody, fields='')
61348
61394
  else:
61349
61395
  callGAPI(targetDrive.permissions(), 'delete',
@@ -61393,6 +61439,7 @@ def transferDrive(users):
61393
61439
  if nonOwnerRetainRoleBody['role'] != 'current':
61394
61440
  callGAPI(ownerDrive.permissions(), 'update',
61395
61441
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND, GAPI.BAD_REQUEST, GAPI.SHARING_RATE_LIMIT_EXCEEDED],
61442
+ enforceExpansiveAccess=enforceExpansiveAccess,
61396
61443
  fileId=childFileId, permissionId=sourcePermissionId, body=sourceUpdateRole, fields='')
61397
61444
  else:
61398
61445
  try:
@@ -61553,7 +61600,7 @@ def transferDrive(users):
61553
61600
  targetUserFolderPattern = '#user# old files'
61554
61601
  targetUserOrphansFolderPattern = '#user# orphaned files'
61555
61602
  targetIds = [None, None]
61556
- createShortcutsForNonmovableFiles = False
61603
+ createShortcutsForNonmovableFiles = enforceExpansiveAccess = False
61557
61604
  mergeWithTarget = False
61558
61605
  thirdPartyOwners = {}
61559
61606
  skipFileIdEntity = initDriveFileEntity()
@@ -61571,6 +61618,8 @@ def transferDrive(users):
61571
61618
  nonOwnerRetainRoleBody['role'] = 'current'
61572
61619
  elif myarg == 'nonownertargetrole':
61573
61620
  nonOwnerTargetRoleBody['role'] = getChoice(TRANSFER_DRIVEFILE_ACL_ROLES_MAP, mapChoice=True)
61621
+ elif myarg == 'enforceexpansiveaccess':
61622
+ enforceExpansiveAccess = getBoolean()
61574
61623
  elif myarg == 'noretentionmessages':
61575
61624
  showRetentionMessages = False
61576
61625
  elif myarg == 'orderby':
@@ -61808,6 +61857,7 @@ def getPermissionIdForEmail(user, i, count, email):
61808
61857
  # [<DriveFileParentAttribute>] [includetrashed] [norecursion [<Boolean>]]
61809
61858
  # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
61810
61859
  # [preview] [filepath] [pathdelimiter <Character>] [buildtree]
61860
+ # [enforceexpansiveaccess [<Boolean>]]
61811
61861
  # [todrive <ToDriveAttribute>*]
61812
61862
  def transferOwnership(users):
61813
61863
  def _identifyFilesToTransfer(fileEntry):
@@ -61856,7 +61906,7 @@ def transferOwnership(users):
61856
61906
  body = {}
61857
61907
  newOwner = getEmailAddress()
61858
61908
  OBY = OrderBy(DRIVEFILE_ORDERBY_CHOICE_MAP)
61859
- changeParents = filepath = includeTrashed = noRecursion = False
61909
+ changeParents = enforceExpansiveAccess = filepath = includeTrashed = noRecursion = False
61860
61910
  pathDelimiter = '/'
61861
61911
  csvPF = fileTree = None
61862
61912
  addParents = ''
@@ -61883,6 +61933,8 @@ def transferOwnership(users):
61883
61933
  csvPF.GetTodriveParameters()
61884
61934
  elif getDriveFileParentAttribute(myarg, parentParms):
61885
61935
  changeParents = True
61936
+ elif myarg == 'enforceexpansiveaccess':
61937
+ enforceExpansiveAccess = getBoolean()
61886
61938
  else:
61887
61939
  unknownArgumentExit()
61888
61940
  Act.Set(Act.TRANSFER_OWNERSHIP)
@@ -62000,6 +62052,7 @@ def transferOwnership(users):
62000
62052
  Act.Set(action)
62001
62053
  callGAPI(drive.permissions(), 'update',
62002
62054
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND],
62055
+ enforceExpansiveAccess=enforceExpansiveAccess,
62003
62056
  fileId=xferFileId, permissionId=permissionId, transferOwnership=True, body=body, fields='')
62004
62057
  entityModifierNewValueItemValueListActionPerformed(kvList, Act.MODIFIER_TO, None, [Ent.USER, newOwner], k, kcount)
62005
62058
  else:
@@ -62021,6 +62074,7 @@ def transferOwnership(users):
62021
62074
  fileId=xferFileId, sendNotificationEmail=False, body=bodyAdd, fields='')
62022
62075
  callGAPI(drive.permissions(), 'update',
62023
62076
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND],
62077
+ enforceExpansiveAccess=enforceExpansiveAccess,
62024
62078
  fileId=xferFileId, permissionId=permissionId, transferOwnership=True, body=body, fields='')
62025
62079
  entityModifierNewValueItemValueListActionPerformed(kvList, Act.MODIFIER_TO, None, [Ent.USER, newOwner], k, kcount)
62026
62080
  except GAPI.invalidSharingRequest as e:
@@ -62093,6 +62147,7 @@ def transferOwnership(users):
62093
62147
  # [keepuser | (retainrole reader|commenter|writer|editor|none)] [noretentionmessages]
62094
62148
  # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
62095
62149
  # [preview] [filepath] [pathdelimiter <Character>] [buildtree]
62150
+ # [enforceexpansiveaccess [<Boolean>]]
62096
62151
  # [todrive <ToDriveAttribute>*]
62097
62152
  def claimOwnership(users):
62098
62153
  def _identifyFilesToClaim(fileEntry):
@@ -62153,6 +62208,7 @@ def claimOwnership(users):
62153
62208
  if sourceRetainRoleBody['role'] != 'writer':
62154
62209
  callGAPI(sourceDrive.permissions(), 'update',
62155
62210
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND, GAPI.BAD_REQUEST],
62211
+ enforceExpansiveAccess=enforceExpansiveAccess,
62156
62212
  fileId=ofileId, permissionId=oldOwnerPermissionId, body=sourceRetainRoleBody, fields='')
62157
62213
  else:
62158
62214
  callGAPI(sourceDrive.permissions(), 'delete',
@@ -62176,7 +62232,7 @@ def claimOwnership(users):
62176
62232
  onlyOwners = set()
62177
62233
  skipOwners = set()
62178
62234
  subdomains = []
62179
- filepath = includeTrashed = False
62235
+ enforceExpansiveAccess = filepath = includeTrashed = False
62180
62236
  pathDelimiter = '/'
62181
62237
  addParents = ''
62182
62238
  parentBody = {}
@@ -62211,6 +62267,8 @@ def claimOwnership(users):
62211
62267
  includeTrashed = True
62212
62268
  elif myarg == 'orderby':
62213
62269
  OBY.GetChoice()
62270
+ elif myarg == 'enforceexpansiveaccess':
62271
+ enforceExpansiveAccess = getBoolean()
62214
62272
  elif myarg == 'restricted':
62215
62273
  bodyShare['copyRequiresWriterPermission'] = getBoolean()
62216
62274
  elif myarg == 'writerscanshare':
@@ -62381,6 +62439,7 @@ def claimOwnership(users):
62381
62439
  Act.Set(action)
62382
62440
  callGAPI(sourceDrive.permissions(), 'update',
62383
62441
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND],
62442
+ enforceExpansiveAccess=enforceExpansiveAccess,
62384
62443
  fileId=xferFileId, permissionId=permissionId, transferOwnership=True, body=body, fields='')
62385
62444
  kvList = [Ent.USER, user, entityType, fileDesc]
62386
62445
  entityModifierNewValueItemValueListActionPerformed(kvList, Act.MODIFIER_FROM, None, [Ent.USER, oldOwner], l, lcount)
@@ -62405,6 +62464,7 @@ def claimOwnership(users):
62405
62464
  fileId=xferFileId, sendNotificationEmail=False, body=bodyAdd, fields='')
62406
62465
  callGAPI(sourceDrive.permissions(), 'update',
62407
62466
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.PERMISSION_NOT_FOUND],
62467
+ enforceExpansiveAccess=enforceExpansiveAccess,
62408
62468
  fileId=xferFileId, permissionId=permissionId, transferOwnership=True, body=body, fields='')
62409
62469
  entityModifierNewValueItemValueListActionPerformed(kvList, Act.MODIFIER_FROM, None, [Ent.USER, oldOwner], l, lcount)
62410
62470
  _processRetainedRole(user, i, count, oldOwner, entityType, xferFileId, fileDesc, l, lcount)
@@ -62941,11 +63001,12 @@ def doCreateDriveFileACL():
62941
63001
 
62942
63002
  # gam [<UserTypeEntity>] update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> [asadmin]
62943
63003
  # (role <DriveFileACLRole>) [expiration <Time>] [removeexpiration [<Boolean>]]
62944
- # [updatesheetprotectedranges [<Boolean>]]
63004
+ # [updatesheetprotectedranges [<Boolean>]] [enforceexpansiveaccess [<Boolean>]]
62945
63005
  # [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
62946
63006
  def updateDriveFileACLs(users, useDomainAdminAccess=False):
62947
63007
  fileIdEntity = getDriveFileEntity()
62948
63008
  isEmail, permissionId = getPermissionId()
63009
+ enforceExpansiveAccess = None
62949
63010
  removeExpiration = showTitles = updateSheetProtectedRanges = False
62950
63011
  showDetails = True
62951
63012
  csvPF = None
@@ -62964,6 +63025,8 @@ def updateDriveFileACLs(users, useDomainAdminAccess=False):
62964
63025
  showTitles = True
62965
63026
  elif myarg == 'updatesheetprotectedranges':
62966
63027
  updateSheetProtectedRanges = getBoolean()
63028
+ elif myarg == 'enforceexpansiveaccess':
63029
+ enforceExpansiveAccess = getBoolean()
62967
63030
  elif myarg == 'nodetails':
62968
63031
  showDetails = False
62969
63032
  elif myarg == 'csv':
@@ -62981,6 +63044,9 @@ def updateDriveFileACLs(users, useDomainAdminAccess=False):
62981
63044
  _checkFileIdEntityDomainAccess(fileIdEntity, useDomainAdminAccess)
62982
63045
  if 'role' not in body:
62983
63046
  missingArgumentExit(f'role {formatChoiceList(DRIVEFILE_ACL_ROLES_MAP)}')
63047
+ updateKwargs = {'useDomainAdminAccess': useDomainAdminAccess}
63048
+ if enforceExpansiveAccess is not None:
63049
+ updateKwargs['enforceExpansiveAccess'] = enforceExpansiveAccess
62984
63050
  printKeys, timeObjects = _getDriveFileACLPrintKeysTimeObjects()
62985
63051
  if csvPF and showTitles:
62986
63052
  csvPF.AddTitles(fileNameTitle)
@@ -63018,7 +63084,7 @@ def updateDriveFileACLs(users, useDomainAdminAccess=False):
63018
63084
  permission = callGAPI(drive.permissions(), 'update',
63019
63085
  bailOnInternalError=True,
63020
63086
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_UPDATE_ACL_THROW_REASONS+[GAPI.FILE_NEVER_WRITABLE],
63021
- useDomainAdminAccess=useDomainAdminAccess,
63087
+ **updateKwargs,
63022
63088
  fileId=fileId, permissionId=permissionId, removeExpiration=removeExpiration,
63023
63089
  transferOwnership=body.get('role', '') == 'owner', body=body, fields='*', supportsAllDrives=True)
63024
63090
  if updateSheetProtectedRanges and mimeType == MIMETYPE_GA_SPREADSHEET:
@@ -63114,7 +63180,7 @@ def createDriveFilePermissions(users, useDomainAdminAccess=False):
63114
63180
  except ValueError:
63115
63181
  return None
63116
63182
 
63117
- def _callbackCreatePermission(request_id, response, exception):
63183
+ def _callbackCreatePermission(request_id, _, exception):
63118
63184
  ri = request_id.splitlines()
63119
63185
  if int(ri[RI_J]) == 1:
63120
63186
  entityPerformActionNumItems([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY]], int(ri[RI_JCOUNT]), Ent.PERMITTEE, int(ri[RI_I]), int(ri[RI_COUNT]))
@@ -63262,11 +63328,12 @@ def doCreatePermissions():
63262
63328
  createDriveFilePermissions([_getAdminEmail()], True)
63263
63329
 
63264
63330
  # gam [<UserTypeEntity>] delete drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail> [asadmin]
63265
- # [updatesheetprotectedranges [<Boolean>]]
63331
+ # [updatesheetprotectedranges [<Boolean>]] [enforceexpansiveaccess [<Boolean>]]
63266
63332
  # [showtitles]
63267
63333
  def deleteDriveFileACLs(users, useDomainAdminAccess=False):
63268
63334
  fileIdEntity = getDriveFileEntity()
63269
63335
  isEmail, permissionId = getPermissionId()
63336
+ enforceExpansiveAccess = None
63270
63337
  showTitles = updateSheetProtectedRanges = False
63271
63338
  while Cmd.ArgumentsRemaining():
63272
63339
  myarg = getArgument()
@@ -63274,11 +63341,16 @@ def deleteDriveFileACLs(users, useDomainAdminAccess=False):
63274
63341
  showTitles = getBoolean()
63275
63342
  elif myarg == 'updatesheetprotectedranges':
63276
63343
  updateSheetProtectedRanges = getBoolean()
63344
+ elif myarg == 'enforceexpansiveaccess':
63345
+ enforceExpansiveAccess = getBoolean()
63277
63346
  elif myarg in ADMIN_ACCESS_OPTIONS:
63278
63347
  useDomainAdminAccess = True
63279
63348
  else:
63280
63349
  unknownArgumentExit()
63281
63350
  _checkFileIdEntityDomainAccess(fileIdEntity, useDomainAdminAccess)
63351
+ deleteKwargs = {'useDomainAdminAccess': useDomainAdminAccess}
63352
+ if enforceExpansiveAccess is not None:
63353
+ deleteKwargs['enforceExpansiveAccess'] = enforceExpansiveAccess
63282
63354
  i, count, users = getEntityArgument(users)
63283
63355
  for user in users:
63284
63356
  i += 1
@@ -63311,7 +63383,8 @@ def deleteDriveFileACLs(users, useDomainAdminAccess=False):
63311
63383
  break
63312
63384
  callGAPI(drive.permissions(), 'delete',
63313
63385
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_DELETE_ACL_THROW_REASONS+[GAPI.FILE_NEVER_WRITABLE],
63314
- useDomainAdminAccess=useDomainAdminAccess, fileId=fileId, permissionId=permissionId, supportsAllDrives=True)
63386
+ **deleteKwargs,
63387
+ fileId=fileId, permissionId=permissionId, supportsAllDrives=True)
63315
63388
  entityActionPerformed([Ent.USER, user, entityType, fileName, Ent.PERMISSION_ID, permissionId], j, jcount)
63316
63389
  if updateSheetProtectedRanges and mimeType == MIMETYPE_GA_SPREADSHEET:
63317
63390
  _updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
@@ -63333,6 +63406,7 @@ def doDeleteDriveFileACLs():
63333
63406
 
63334
63407
  # gam [<UserTypeEntity>] delete permissions <DriveFileEntity> <DriveFilePermissionIDEntity> [asadmin]
63335
63408
  # <PermissionMatch>* [<PermissionMatchAction>]
63409
+ # [enforceexpansiveaccess [<Boolean>]]
63336
63410
  def deletePermissions(users, useDomainAdminAccess=False):
63337
63411
  def convertJSONPermissions(jsonPermissions):
63338
63412
  permissionIds = []
@@ -63342,7 +63416,7 @@ def deletePermissions(users, useDomainAdminAccess=False):
63342
63416
  permissionIds.append(permission['id'])
63343
63417
  return permissionIds
63344
63418
 
63345
- def _callbackDeletePermissionId(request_id, response, exception):
63419
+ def _callbackDeletePermissionId(request_id, _, exception):
63346
63420
  ri = request_id.splitlines()
63347
63421
  if int(ri[RI_J]) == 1:
63348
63422
  entityPerformActionNumItems([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY]], int(ri[RI_JCOUNT]), Ent.PERMISSION_ID, int(ri[RI_I]), int(ri[RI_COUNT]))
@@ -63367,7 +63441,8 @@ def deletePermissions(users, useDomainAdminAccess=False):
63367
63441
  callGAPI(drive.permissions(), 'delete',
63368
63442
  throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+GAPI.DRIVE3_DELETE_ACL_THROW_REASONS,
63369
63443
  retryReasons=[GAPI.SERVICE_LIMIT],
63370
- useDomainAdminAccess=useDomainAdminAccess, fileId=ri[RI_ENTITY], permissionId=ri[RI_ITEM], supportsAllDrives=True)
63444
+ useDomainAdminAccess=useDomainAdminAccess, enforceExpansiveAccess=enforceExpansiveAccess,
63445
+ fileId=ri[RI_ENTITY], permissionId=ri[RI_ITEM], supportsAllDrives=True)
63371
63446
  entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
63372
63447
  except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
63373
63448
  GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
@@ -63387,12 +63462,15 @@ def deletePermissions(users, useDomainAdminAccess=False):
63387
63462
  jsonData = getJSON([])
63388
63463
  PM = PermissionMatch()
63389
63464
  PM.SetDefaultMatch(False, {'role': 'owner'})
63465
+ enforceExpansiveAccess = False
63390
63466
  while Cmd.ArgumentsRemaining():
63391
63467
  myarg = getArgument()
63392
63468
  if myarg in ADMIN_ACCESS_OPTIONS:
63393
63469
  useDomainAdminAccess = True
63394
63470
  elif PM and PM.ProcessArgument(myarg):
63395
63471
  pass
63472
+ elif myarg == 'enforceexpansiveaccess':
63473
+ enforceExpansiveAccess = getBoolean()
63396
63474
  else:
63397
63475
  unknownArgumentExit()
63398
63476
  _checkFileIdEntityDomainAccess(fileIdEntity, useDomainAdminAccess)
@@ -68623,7 +68701,7 @@ def deleteLabels(users, labelEntity):
68623
68701
  http_status, reason, message = checkGAPIError(exception)
68624
68702
  entityActionFailedWarning([Ent.USER, ri[RI_ENTITY], Ent.LABEL, labelIdToNameMap[ri[RI_ITEM]]], formatHTTPError(http_status, reason, message), int(ri[RI_J]), int(ri[RI_JCOUNT]))
68625
68703
 
68626
- def _callbackDeleteLabel(request_id, response, exception):
68704
+ def _callbackDeleteLabel(request_id, _, exception):
68627
68705
  ri = request_id.splitlines()
68628
68706
  if exception is None:
68629
68707
  entityActionPerformed([Ent.USER, ri[RI_ENTITY], Ent.LABEL, labelIdToNameMap[ri[RI_ITEM]]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -69224,7 +69302,7 @@ def _processMessagesThreads(users, entityType):
69224
69302
  GAPI.INVALID_MESSAGE_ID: Msg.INVALID_MESSAGE_ID,
69225
69303
  GAPI.FAILED_PRECONDITION: Msg.FAILED_PRECONDITION}
69226
69304
 
69227
- def _callbackProcessMessage(request_id, response, exception):
69305
+ def _callbackProcessMessage(request_id, _, exception):
69228
69306
  ri = request_id.splitlines()
69229
69307
  if exception is None:
69230
69308
  if not csvPF: