gam7 7.23.3__py3-none-any.whl → 7.23.5__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.23.03'
28
+ __version__ = '7.23.05'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -7868,6 +7868,13 @@ class CSVPrintFile():
7868
7868
  if title not in self.titlesSet:
7869
7869
  self.AddTitle(title)
7870
7870
 
7871
+ def InsertTitles(self, position, titles):
7872
+ for title in titles if isinstance(titles, list) else [titles]:
7873
+ if title not in self.titlesSet:
7874
+ self.titlesSet.add(title)
7875
+ self.titlesList.insert(position, title)
7876
+ position += 1
7877
+
7871
7878
  def SetTitles(self, titles):
7872
7879
  self.titlesSet = set()
7873
7880
  self.titlesList = []
@@ -16988,16 +16995,17 @@ ASSIGNEE_EMAILTYPE_TOFIELD_MAP = {
16988
16995
  'group': 'assignedToGroup',
16989
16996
  'serviceaccount': 'assignedToServiceAccount',
16990
16997
  }
16991
- PRINT_ADMIN_FIELDS = ['roleAssignmentId', 'roleId', 'assignedTo', 'scopeType', 'orgUnitId']
16998
+ PRINT_ADMIN_FIELDS = ['roleAssignmentId', 'roleId', 'assignedTo', 'scopeType', 'orgUnitId', 'assigneeType']
16992
16999
  PRINT_ADMIN_TITLES = ['roleAssignmentId', 'roleId', 'role',
16993
17000
  'assignedTo', 'assignedToUser', 'assignedToGroup', 'assignedToServiceAccount', 'assignedToUnknown',
16994
17001
  'scopeType', 'orgUnitId', 'orgUnit']
16995
17002
 
16996
17003
  # gam print admins [todrive <ToDriveAttribute>*]
16997
- # [user|group <EmailAddress>|<UniqueID>] [role <RoleItem>] [condition]
16998
- # [privileges] [oneitemperrow]
17004
+ # [user|group <EmailAddress>|<UniqueID>] [role <RoleItem>]
17005
+ # [recursive] [condition] [privileges] [oneitemperrow]
16999
17006
  # gam show admins
17000
- # [user|group <EmailAddress>|<UniqueID>] [role <RoleItem>] [condition] [privileges]
17007
+ # [user|group <EmailAddress>|<UniqueID>] [role <RoleItem>]
17008
+ # [recursive] [condition] [privileges]
17001
17009
  def doPrintShowAdmins():
17002
17010
  def _getPrivileges(admin):
17003
17011
  if showPrivileges:
@@ -17024,15 +17032,12 @@ def doPrintShowAdmins():
17024
17032
  def _setNamesFromIds(admin, privileges):
17025
17033
  admin['role'] = role_from_roleid(admin['roleId'])
17026
17034
  assignedTo = admin['assignedTo']
17027
- admin['assignedToUnknown'] = False
17028
17035
  if assignedTo not in assignedToIdEmailMap:
17029
- assigneeType = admin.get('assigneeType')
17030
- assignedToField = ASSIGNEE_EMAILTYPE_TOFIELD_MAP.get(assigneeType, None)
17031
17036
  assigneeEmail, assigneeType = convertUIDtoEmailAddressWithType(f'uid:{assignedTo}', cd, sal,
17032
- emailTypes=list(ASSIGNEE_EMAILTYPE_TOFIELD_MAP.keys()))
17033
- if not assignedToField and assigneeType in ASSIGNEE_EMAILTYPE_TOFIELD_MAP:
17037
+ emailTypes=allAssigneeTypes if admin.get('assigneeType') != 'group' else ['group'])
17038
+ if assigneeType in ASSIGNEE_EMAILTYPE_TOFIELD_MAP:
17034
17039
  assignedToField = ASSIGNEE_EMAILTYPE_TOFIELD_MAP[assigneeType]
17035
- if assigneeType == 'unknown':
17040
+ else:
17036
17041
  assignedToField = 'assignedToUnknown'
17037
17042
  assigneeEmail = True
17038
17043
  assignedToIdEmailMap[assignedTo] = {'assignedToField': assignedToField, 'assigneeEmail': assigneeEmail}
@@ -17052,11 +17057,12 @@ def doPrintShowAdmins():
17052
17057
  csvPF = CSVPrintFile(PRINT_ADMIN_TITLES) if Act.csvFormat() else None
17053
17058
  roleId = None
17054
17059
  userKey = None
17055
- oneItemPerRow = showPrivileges = False
17060
+ oneItemPerRow = recursive = showPrivileges = False
17056
17061
  kwargs = {}
17057
17062
  rolePrivileges = {}
17058
17063
  fieldsList = PRINT_ADMIN_FIELDS
17059
17064
  assignedToIdEmailMap = {}
17065
+ allAssigneeTypes = list(ASSIGNEE_EMAILTYPE_TOFIELD_MAP.keys())
17060
17066
  while Cmd.ArgumentsRemaining():
17061
17067
  myarg = getArgument()
17062
17068
  if csvPF and myarg == 'todrive':
@@ -17065,6 +17071,15 @@ def doPrintShowAdmins():
17065
17071
  userKey = kwargs['userKey'] = getEmailAddress()
17066
17072
  elif myarg == 'role':
17067
17073
  _, roleId = getRoleId()
17074
+ elif myarg == 'recursive':
17075
+ recursive = True
17076
+ allGroupRoles = ','.join(sorted(ALL_GROUP_ROLES))
17077
+ memberOptions = initMemberOptions()
17078
+ memberOptions[MEMBEROPTION_INCLUDEDERIVEDMEMBERSHIP] = True
17079
+ memberOptions[MEMBEROPTION_DISPLAYMATCH] = False
17080
+ memberDisplayOptions = initIPSGMGroupMemberDisplayOptions()
17081
+ for role in [Ent.ROLE_MEMBER, Ent.ROLE_MANAGER, Ent.ROLE_OWNER]:
17082
+ memberDisplayOptions[role]['show'] = True
17068
17083
  elif myarg == 'condition':
17069
17084
  fieldsList.append('condition')
17070
17085
  if csvPF:
@@ -17084,7 +17099,7 @@ def doPrintShowAdmins():
17084
17099
  admins = callGAPIpages(cd.roleAssignments(), 'list', 'items',
17085
17100
  pageMessage=getPageMessage(),
17086
17101
  throwReasons=[GAPI.INVALID, GAPI.USER_NOT_FOUND,
17087
- GAPI.FORBIDDEN, GAPI.SERVICE_NOT_AVAILABLE,
17102
+ GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.SERVICE_NOT_AVAILABLE,
17088
17103
  GAPI.BAD_REQUEST, GAPI.CUSTOMER_NOT_FOUND,
17089
17104
  GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED],
17090
17105
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
@@ -17092,39 +17107,72 @@ def doPrintShowAdmins():
17092
17107
  except (GAPI.invalid, GAPI.userNotFound):
17093
17108
  entityUnknownWarning(Ent.ADMINISTRATOR, userKey)
17094
17109
  return
17095
- except (GAPI.serviceNotAvailable) as e:
17096
- entityActionFailedExit([Ent.ADMINISTRATOR, userKey, Ent.ADMIN_ROLE, roleId], str(e))
17110
+ except GAPI.notFound as e:
17111
+ entityActionFailedExit([Ent.ADMIN_ROLE, kwargs['roleId']], str(e))
17112
+ except (GAPI.forbidden, GAPI.serviceNotAvailable) as e:
17113
+ entityActionFailedExit([Ent.ADMINISTRATOR, userKey], str(e))
17097
17114
  except (GAPI.badRequest, GAPI.customerNotFound):
17098
17115
  accessErrorExit(cd)
17099
17116
  except (GAPI.forbidden, GAPI.permissionDenied) as e:
17100
17117
  ClientAPIAccessDeniedExit(str(e))
17118
+ count = len(admins)
17119
+ groupMembers = {}
17120
+ expandedAdmins = []
17121
+ i = 0
17122
+ for admin in admins:
17123
+ i += 1
17124
+ if roleId and roleId != admin['roleId']:
17125
+ continue
17126
+ if admin['assigneeType'] != 'group' or not recursive:
17127
+ _setNamesFromIds(admin, _getPrivileges(admin))
17128
+ expandedAdmins.append(admin)
17129
+ continue
17130
+ assignedTo = admin['assignedTo']
17131
+ if assignedTo not in groupMembers:
17132
+ membersList = []
17133
+ membersSet = set()
17134
+ level = 0
17135
+ getGroupMembers(cd, assignedTo, allGroupRoles, membersList, membersSet, i, count,
17136
+ memberOptions, memberDisplayOptions, level, {Ent.TYPE_USER})
17137
+ groupMembers[assignedTo] = membersList[:]
17138
+ _setNamesFromIds(admin, _getPrivileges(admin))
17139
+ if not groupMembers[assignedTo]:
17140
+ expandedAdmins.append(admin)
17141
+ continue
17142
+ admin['assigneeType'] = 'user'
17143
+ admin['assignedToGroup'] = assignedToIdEmailMap[assignedTo]['assigneeEmail']
17144
+ for member in groupMembers[assignedTo]:
17145
+ userAdmin = admin.copy()
17146
+ userAdmin['assignedTo'] = member['id']
17147
+ _setNamesFromIds(userAdmin, _getPrivileges(admin))
17148
+ expandedAdmins.append(userAdmin)
17149
+ admins = expandedAdmins
17150
+ count = len(expandedAdmins)
17101
17151
  if not csvPF:
17102
- count = len(admins)
17103
17152
  performActionNumItems(count, Ent.ADMIN_ROLE_ASSIGNMENT)
17104
17153
  Ind.Increment()
17105
17154
  i = 0
17106
- for admin in admins:
17155
+ for admin in expandedAdmins:
17107
17156
  i += 1
17108
- if roleId and roleId != admin['roleId']:
17109
- continue
17110
- _setNamesFromIds(admin, _getPrivileges(admin))
17111
17157
  printEntity([Ent.ADMIN_ROLE_ASSIGNMENT, admin['roleAssignmentId']], i, count)
17112
17158
  Ind.Increment()
17113
17159
  for field in PRINT_ADMIN_TITLES:
17114
17160
  if field in admin:
17115
17161
  if field == 'roleAssignmentId':
17116
17162
  continue
17117
- if field != 'rolePrivileges':
17118
- printKeyValueList([field, admin[field]])
17119
- else:
17120
- showJSON(None, admin[field])
17163
+ printKeyValueList([field, admin[field]])
17164
+ if showPrivileges:
17165
+ rolePrivileges = admin.get('rolePrivileges', [])
17166
+ jcount = len(rolePrivileges)
17167
+ if jcount > 0:
17168
+ printKeyValueList(['rolePrivileges', jcount])
17169
+ Ind.Increment()
17170
+ showJSON(None, rolePrivileges)
17171
+ Ind.Decrement()
17121
17172
  Ind.Decrement()
17122
17173
  Ind.Decrement()
17123
17174
  else:
17124
- for admin in admins:
17125
- if roleId and roleId != admin['roleId']:
17126
- continue
17127
- _setNamesFromIds(admin, _getPrivileges(admin))
17175
+ for admin in expandedAdmins:
17128
17176
  if not oneItemPerRow or 'rolePrivileges' not in admin:
17129
17177
  csvPF.WriteRowTitles(flattenJSON(admin))
17130
17178
  else:
@@ -22429,12 +22477,12 @@ def infoUserPeopleContacts(users):
22429
22477
 
22430
22478
  # gam <UserTypeEntity> print contacts [todrive <ToDriveAttribute>*] <PeoplePrintShowUserContactSelection>
22431
22479
  # [showgroups|showgroupnameslist] [orderby firstname|lastname|(lastmodified ascending)|(lastnodified descending)
22432
- # [countsonly|allfields|fields <PeopleFieldNameList>] [showmetadata]
22433
- # [formatjson [quotechar <Character>]]
22480
+ # [allfields|fields <PeopleFieldNameList>] [showmetadata]
22481
+ # [countsonly|(formatjson [quotechar <Character>])]
22434
22482
  # gam <UserTypeEntity> show contacts <PeoplePrintShowUserContactSelection>
22435
22483
  # [showgroups] [orderby firstname|lastname|(lastmodified ascending)|(lastnodified descending)
22436
- # [countsonly|allfields|(fields <PeopleFieldNameList>)] [showmetadata]
22437
- # [formatjson]
22484
+ # [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
22485
+ # [countsonly|formatjson]
22438
22486
  def printShowUserPeopleContacts(users):
22439
22487
  entityType = Ent.USER
22440
22488
  entityTypeName = Ent.Singular(entityType)
@@ -22473,6 +22521,8 @@ def printShowUserPeopleContacts(users):
22473
22521
  else:
22474
22522
  FJQC.GetFormatJSONQuoteChar(myarg, True)
22475
22523
  if countsOnly:
22524
+ if csvPF:
22525
+ csvPF.SetFormatJSON(False)
22476
22526
  fieldsList = ['emailAddresses']
22477
22527
  if contactQuery['mainContacts']:
22478
22528
  fields = _getPersonFields(PEOPLE_FIELDS_CHOICE_MAP, PEOPLE_CONTACTS_DEFAULT_FIELDS, fieldsList, parameters)
@@ -22710,11 +22760,11 @@ def processUserPeopleOtherContacts(users):
22710
22760
  Ind.Decrement()
22711
22761
 
22712
22762
  # gam <UserTypeEntity> print othercontacts [todrive <ToDriveAttribute>*] <OtherContactSelection>
22713
- # [countsonly|allfields|(fields <OtherContactFieldNameList>)] [showmetadata]
22714
- # [formatjson [quotechar <Character>]]
22763
+ # [allfields|(fields <OtherContactFieldNameList>)] [showmetadata]
22764
+ # [countsonly|(formatjson [quotechar <Character>])]
22715
22765
  # gam <UserTypeEntity> show othercontacts <OtherContactSelection>
22716
- # [countsonly|allfields|(fields <OtherContactFieldNameList>)] [showmetadata]
22717
- # [formatjson]
22766
+ # [allfields|(fields <OtherContactFieldNameList>)] [showmetadata]
22767
+ # [countsonly|formatjson]
22718
22768
  def printShowUserPeopleOtherContacts(users):
22719
22769
  entityType = Ent.USER
22720
22770
  entityTypeName = Ent.Singular(entityType)
@@ -22744,6 +22794,8 @@ def printShowUserPeopleOtherContacts(users):
22744
22794
  else:
22745
22795
  FJQC.GetFormatJSONQuoteChar(myarg, True)
22746
22796
  if countsOnly:
22797
+ if csvPF:
22798
+ csvPF.SetFormatJSON(False)
22747
22799
  fieldsList = ['emailAddresses']
22748
22800
  fields = _getPersonFields(PEOPLE_OTHER_CONTACTS_FIELDS_CHOICE_MAP, PEOPLE_CONTACTS_DEFAULT_FIELDS, fieldsList, parameters)
22749
22801
  i, count, users = getEntityArgument(users)
@@ -22813,6 +22865,8 @@ def _printShowPeople(source):
22813
22865
  function = 'searchDirectoryPeople'
22814
22866
  else:
22815
22867
  FJQC.GetFormatJSONQuoteChar(myarg, True)
22868
+ if countsOnly and csvPF:
22869
+ csvPF.SetFormatJSON(False)
22816
22870
  fields = _getPersonFields(PEOPLE_FIELDS_CHOICE_MAP, PEOPLE_CONTACTS_DEFAULT_FIELDS, fieldsList, parameters)
22817
22871
  printGettingAllEntityItemsForWhom(peopleEntityType, GC.Values[GC.DOMAIN], query=kwargs.get('query'))
22818
22872
  try:
@@ -22850,29 +22904,24 @@ def doInfoDomainPeopleContacts():
22850
22904
  # gam print people|peopleprofile [todrive <ToDriveAttribute>*]
22851
22905
  # [query <String>]
22852
22906
  # [mergesources <PeopleMergeSourceName>]
22853
- # [countsonly]
22854
22907
  # [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
22855
- # [formatjson [quotechar <Character>]]
22908
+ # [countsonly|(formatjson [quotechar <Character>])]
22856
22909
  # gam show people|peopleprofile
22857
22910
  # [query <String>]
22858
22911
  # [mergesources <PeopleMergeSourceName>]
22859
- # [countsonly]
22860
22912
  # [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
22861
- # [formatjson]
22913
+ # [countsonlyformatjson]
22862
22914
  # gam print domaincontacts|peoplecontacts [todrive <ToDriveAttribute>*]
22863
22915
  # [sources <PeopleSourceName>]
22864
22916
  # [query <String>]
22865
22917
  # [mergesources <PeopleMergeSourceName>]
22866
- # [countsonly]
22867
22918
  # [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
22868
- # [formatjson [quotechar <Character>]]
22919
+ # [countsonly|(formatjson [quotechar <Character>])]
22869
22920
  # gam show domaincontacts|peoplecontacts
22870
22921
  # [sources <PeopleSourceName>]
22871
22922
  # [query <String>]
22872
22923
  # [mergesources <PeopleMergeSourceName>]
22873
- # [countsonly]
22874
- # [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
22875
- # [formatjson]
22924
+ # [countsonlyformatjson]
22876
22925
  def doPrintShowDomainPeopleProfiles():
22877
22926
  _printShowPeople('profile')
22878
22927
 
@@ -40125,7 +40174,7 @@ def _createCalendarEvents(user, origCal, function, calIds, count, body, paramete
40125
40174
  else:
40126
40175
  if parameters['showDayOfWeek']:
40127
40176
  _getEventDaysOfWeek(event)
40128
- _printCalendarEvent(user, calId, event, parameters['csvPF'], parameters['FJQC'])
40177
+ _printCalendarEvent(user, calId, event, parameters['csvPF'], parameters['FJQC'], {})
40129
40178
  except (GAPI.invalid, GAPI.required, GAPI.timeRangeEmpty, GAPI.eventDurationExceedsLimit,
40130
40179
  GAPI.requiredAccessLevel, GAPI.participantIsNeitherOrganizerNorAttendee,
40131
40180
  GAPI.malformedWorkingLocationEvent, GAPI.badRequest) as e:
@@ -40229,7 +40278,7 @@ def _updateCalendarEvents(origUser, user, origCal, calIds, count, calendarEventE
40229
40278
  else:
40230
40279
  if parameters['showDayOfWeek']:
40231
40280
  _getEventDaysOfWeek(event)
40232
- _printCalendarEvent(user, calId, event, parameters['csvPF'], parameters['FJQC'])
40281
+ _printCalendarEvent(user, calId, event, parameters['csvPF'], parameters['FJQC'], {})
40233
40282
  except (GAPI.notFound, GAPI.deleted) as e:
40234
40283
  if not checkCalendarExists(cal, calId, j, jcount):
40235
40284
  entityUnknownWarning(Ent.CALENDAR, calId, j, jcount)
@@ -40526,10 +40575,12 @@ def _showCalendarEvent(primaryEmail, calId, eventEntityType, event, k, kcount, F
40526
40575
  showJSON(None, event, skipObjects)
40527
40576
  Ind.Decrement()
40528
40577
 
40529
- def _printCalendarEvent(user, calId, event, csvPF, FJQC):
40578
+ def _printCalendarEvent(user, calId, event, csvPF, FJQC, addCSVData):
40530
40579
  row = {'calendarId': calId, 'id': event['id']}
40531
40580
  if user:
40532
40581
  row['primaryEmail'] = user
40582
+ if addCSVData:
40583
+ row.update(addCSVData)
40533
40584
  flattenJSON(event, flattened=row, timeObjects=EVENT_TIME_OBJECTS)
40534
40585
  if not FJQC.formatJSON:
40535
40586
  csvPF.WriteRowTitles(row)
@@ -40542,7 +40593,7 @@ def _printCalendarEvent(user, calId, event, csvPF, FJQC):
40542
40593
  csvPF.WriteRowNoFilter(row)
40543
40594
 
40544
40595
  def _printShowCalendarEvents(origUser, user, origCal, calIds, count, calendarEventEntity,
40545
- csvPF, FJQC, fieldsList):
40596
+ csvPF, FJQC, fieldsList, addCSVData):
40546
40597
  i = 0
40547
40598
  for calId in calIds:
40548
40599
  i += 1
@@ -40568,7 +40619,7 @@ def _printShowCalendarEvents(origUser, user, origCal, calIds, count, calendarEve
40568
40619
  for event in events:
40569
40620
  if calendarEventEntity['showDayOfWeek']:
40570
40621
  _getEventDaysOfWeek(event)
40571
- _printCalendarEvent(user, calId, event, csvPF, FJQC)
40622
+ _printCalendarEvent(user, calId, event, csvPF, FJQC, addCSVData)
40572
40623
  elif GC.Values[GC.CSV_OUTPUT_USERS_AUDIT] and user:
40573
40624
  csvPF.WriteRowNoFilter({'calendarId': calId, 'primaryEmail': user, 'id': ''})
40574
40625
  else:
@@ -40586,6 +40637,8 @@ def _printShowCalendarEvents(origUser, user, origCal, calIds, count, calendarEve
40586
40637
  row = {'calendarId': calId}
40587
40638
  if user:
40588
40639
  row['primaryEmail'] = user
40640
+ if addCSVData:
40641
+ row.update(addCSVData)
40589
40642
  row['events'] = jcount
40590
40643
  if not calendarEventEntity['eventRowFilter']:
40591
40644
  csvPF.WriteRow(row)
@@ -40816,6 +40869,8 @@ def _getCalendarPrintShowEventOptions(calendarEventEntity, entityType):
40816
40869
  csvPF = CSVPrintFile(['primaryEmail', 'calendarId', 'id'] if entityType == Ent.USER else ['calendarId', 'id'], 'sortall', indexedTitles=EVENT_INDEXED_TITLES) if Act.csvFormat() else None
40817
40870
  FJQC = FormatJSONQuoteChar(csvPF)
40818
40871
  fieldsList = []
40872
+ addCSVData = {}
40873
+ addCSVDataLoc = 2 if entityType == Ent.USER else 1
40819
40874
  while Cmd.ArgumentsRemaining():
40820
40875
  myarg = getArgument()
40821
40876
  if csvPF and myarg == 'todrive':
@@ -40824,6 +40879,9 @@ def _getCalendarPrintShowEventOptions(calendarEventEntity, entityType):
40824
40879
  pass
40825
40880
  elif myarg == 'fields':
40826
40881
  _getEventFields(fieldsList)
40882
+ elif csvPF and myarg == 'addcsvdata':
40883
+ k = getString(Cmd.OB_STRING)
40884
+ addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
40827
40885
  elif myarg == 'countsonly':
40828
40886
  calendarEventEntity['countsOnly'] = True
40829
40887
  elif myarg == 'showdayofweek':
@@ -40836,27 +40894,35 @@ def _getCalendarPrintShowEventOptions(calendarEventEntity, entityType):
40836
40894
  fieldsList = ['id']
40837
40895
  if csvPF:
40838
40896
  if calendarEventEntity['countsOnly']:
40897
+ csvPF.SetFormatJSON(False)
40839
40898
  csvPF.RemoveTitles(['id'])
40899
+ if addCSVData:
40900
+ csvPF.InsertTitles(addCSVDataLoc, sorted(addCSVData.keys()))
40840
40901
  csvPF.AddTitles(['events'])
40902
+ csvPF.SetSortAllTitles()
40841
40903
  calendarEventEntity['countsOnlyTitles'] = csvPF.titlesList[:]
40842
- elif not FJQC.formatJSON and not fieldsList:
40843
- csvPF.AddSortTitles(EVENT_PRINT_ORDER)
40904
+ else:
40905
+ if addCSVData:
40906
+ csvPF.InsertTitles(addCSVDataLoc, sorted(addCSVData.keys()))
40907
+ if not FJQC.formatJSON and not fieldsList:
40908
+ csvPF.AddTitles(EVENT_PRINT_ORDER)
40909
+ csvPF.SetSortAllTitles()
40844
40910
  _addEventEntitySelectFields(calendarEventEntity, fieldsList)
40845
- return (csvPF, FJQC, fieldsList)
40911
+ return (csvPF, FJQC, fieldsList, addCSVData)
40846
40912
 
40847
40913
  # gam calendars <CalendarEntity> print events <EventEntity> <EventDisplayProperties>*
40848
40914
  # [fields <EventFieldNameList>] [showdayofweek]
40849
- # [countsonly [eventrowfilter]]
40850
- # [formatjson [quotechar <Character>]] [todrive <ToDriveAttribute>*]
40915
+ # (addcsvdata <FieldName> <String>)*
40916
+ # [eventrowfilter]
40917
+ # [countsonly|(formatjson [quotechar <Character>])] [todrive <ToDriveAttribute>*]
40851
40918
  # gam calendars <CalendarEntity> show events <EventEntity> <EventDisplayProperties>*
40852
40919
  # [fields <EventFieldNameList>] [showdayofweek]
40853
- # [countsonly]
40854
- # [formatjson]
40920
+ # [countsonly|formatjson]
40855
40921
  def doCalendarsPrintShowEvents(calIds):
40856
40922
  calendarEventEntity = getCalendarEventEntity()
40857
- csvPF, FJQC, fieldsList = _getCalendarPrintShowEventOptions(calendarEventEntity, Ent.CALENDAR)
40923
+ csvPF, FJQC, fieldsList, addCSVData = _getCalendarPrintShowEventOptions(calendarEventEntity, Ent.CALENDAR)
40858
40924
  _printShowCalendarEvents(None, None, None, calIds, len(calIds), calendarEventEntity,
40859
- csvPF, FJQC, fieldsList)
40925
+ csvPF, FJQC, fieldsList, addCSVData)
40860
40926
  if csvPF:
40861
40927
  if calendarEventEntity['countsOnly'] and calendarEventEntity['eventRowFilter']:
40862
40928
  csvPF.SetTitles(calendarEventEntity['countsOnlyTitles'])
@@ -48863,13 +48929,15 @@ def _doInfoCourses(courseIdList):
48863
48929
 
48864
48930
  # gam info courses <CourseEntity> [owneraccess]
48865
48931
  # [owneremail] [alias|aliases] [show none|all|students|teachers] [countsonly]
48866
- # [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>] [formatjson]
48932
+ # [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
48933
+ # [formatjson]
48867
48934
  def doInfoCourses():
48868
48935
  _doInfoCourses(getEntityList(Cmd.OB_COURSE_ENTITY, shlexSplit=True))
48869
48936
 
48870
48937
  # gam info course <CourseID> [owneraccess]
48871
48938
  # [owneremail] [alias|aliases] [show none|all|students|teachers] [countsonly]
48872
- # [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>] [formatjson]
48939
+ # [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
48940
+ # [formatjson]
48873
48941
  def doInfoCourse():
48874
48942
  _doInfoCourses(getStringReturnInList(Cmd.OB_COURSE_ID))
48875
48943
 
@@ -49187,7 +49255,7 @@ COURSE_ANNOUNCEMENTS_INDEXED_TITLES = ['materials']
49187
49255
  # (orderby <CourseAnnouncementOrderByFieldName> [ascending|descending])*)
49188
49256
  # [showcreatoremails|creatoremail] [fields <CourseAnnouncementFieldNameList>]
49189
49257
  # [timefilter creationtime|updatetime|scheduledtime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
49190
- # [countsonly] [formatjson [quotechar <Character>]]
49258
+ # [countsonly|(formatjson [quotechar <Character>])]
49191
49259
  def doPrintCourseAnnouncements():
49192
49260
  def _printCourseAnnouncement(course, courseAnnouncement, i, count):
49193
49261
  if applyCourseItemFilter and not _courseItemPassesFilter(courseAnnouncement, courseItemFilter):
@@ -49243,6 +49311,8 @@ def doPrintCourseAnnouncements():
49243
49311
  coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
49244
49312
  if coursesInfo is None:
49245
49313
  return
49314
+ if countsOnly:
49315
+ csvPF.SetFormatJSON(False)
49246
49316
  applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, fieldsList)
49247
49317
  if showCreatorEmail and fieldsList:
49248
49318
  fieldsList.append('creatorUserId')
@@ -49299,7 +49369,7 @@ COURSE_TOPICS_SORT_TITLES = ['courseId', 'courseName', 'topicId', 'name', 'updat
49299
49369
  # (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] states <CourseStateList>])
49300
49370
  # [topicids <CourseTopicIDEntity>]
49301
49371
  # [timefilter updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
49302
- # [countsonly] [formatjson [quotechar <Character>]]
49372
+ # [countsonly|(formatjson [quotechar <Character>])]
49303
49373
  def doPrintCourseTopics():
49304
49374
  def _printCourseTopic(course, courseTopic):
49305
49375
  if applyCourseItemFilter and not _courseItemPassesFilter(courseTopic, courseItemFilter):
@@ -49340,6 +49410,8 @@ def doPrintCourseTopics():
49340
49410
  coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
49341
49411
  if coursesInfo is None:
49342
49412
  return
49413
+ if countsOnly:
49414
+ csvPF.SetFormatJSON(False)
49343
49415
  applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, fieldsList)
49344
49416
  courseTopicIdsLists = courseTopicIds if isinstance(courseTopicIds, dict) else None
49345
49417
  i = 0
@@ -49584,6 +49656,8 @@ def doPrintCourseWM(entityIDType, entityStateType):
49584
49656
  coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
49585
49657
  if coursesInfo is None:
49586
49658
  return
49659
+ if countsOnly:
49660
+ csvPF.SetFormatJSON(False)
49587
49661
  applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, fieldsList)
49588
49662
  courseWMIds = courseWMSelectionParameters['courseWMIds']
49589
49663
  courseWMIdsLists = courseWMIds if isinstance(courseWMIds, dict) else {}
@@ -49639,7 +49713,7 @@ def doPrintCourseWM(entityIDType, entityStateType):
49639
49713
  # [showcreatoremails|creatoremail] [showtopicnames] [fields <CourseMaterialFieldNameList>]
49640
49714
  # [timefilter creationtime|updatetime|scheduledtime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
49641
49715
  # [oneitemperrow]
49642
- # [countsonly] [formatjson [quotechar <Character>]]
49716
+ # [countsonly|(formatjson [quotechar <Character>])]
49643
49717
  def doPrintCourseMaterials():
49644
49718
  doPrintCourseWM(Ent.COURSE_MATERIAL_ID, Ent.COURSE_MATERIAL_STATE)
49645
49719
 
@@ -49651,7 +49725,7 @@ def doPrintCourseMaterials():
49651
49725
  # [showstudentsaslist [<Boolean>]] [delimiter <Character>]
49652
49726
  # [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
49653
49727
  # [oneitemperrow]
49654
- # [countsonly] [formatjson [quotechar <Character>]]
49728
+ # [countsonly|(formatjson [quotechar <Character>])]
49655
49729
  def doPrintCourseWork():
49656
49730
  doPrintCourseWM(Ent.COURSE_WORK_ID, Ent.COURSE_WORK_STATE)
49657
49731
 
@@ -49695,7 +49769,7 @@ def _gettingCourseSubmissionQuery(courseSubmissionStates, late, userId):
49695
49769
  # (submissionids <CourseSubmissionIDEntity>)|((submissionstates <CourseSubmissionStateList>)*) [late|notlate]
49696
49770
  # [fields <CourseSubmissionFieldNameList>] [showuserprofile]
49697
49771
  # [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
49698
- # [countsonly] [formatjson [quotechar <Character>]]
49772
+ # [countsonly|(formatjson [quotechar <Character>])]
49699
49773
  def doPrintCourseSubmissions():
49700
49774
  def _printCourseSubmission(course, courseSubmission):
49701
49775
  if applyCourseItemFilter and not _courseItemPassesFilter(courseSubmission, courseItemFilter):
@@ -49777,6 +49851,8 @@ def doPrintCourseSubmissions():
49777
49851
  coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties, getOwnerId=True)
49778
49852
  if coursesInfo is None:
49779
49853
  return
49854
+ if countsOnly:
49855
+ csvPF.SetFormatJSON(False)
49780
49856
  applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, fieldsList)
49781
49857
  courseWorkIds = courseWMSelectionParameters['courseWMIds']
49782
49858
  courseWorkIdsLists = courseWorkIds if isinstance(courseWorkIds, dict) else {}
@@ -53523,16 +53599,16 @@ def infoCalendarEvents(users):
53523
53599
 
53524
53600
  # gam <UserTypeEntity> print events <UserCalendarEntity> <EventEntity> <EventDisplayProperties>*
53525
53601
  # [fields <EventFieldNameList>] [showdayofweek]
53526
- # [countsonly [eventrowfilter]]
53527
- # [formatjson [quotechar <Character>]] [todrive <ToDriveAttribute>*]
53602
+ # (addcsvdata <FieldName> <String>)*
53603
+ # [eventrowfilter]
53604
+ # [countsonly|(formatjson [quotechar <Character>])] [todrive <ToDriveAttribute>*]
53528
53605
  # gam <UserTypeEntity> show events <UserCalendarEntity> <EventEntity> <EventDisplayProperties>*
53529
53606
  # [fields <EventFieldNameList>] [showdayofweek]
53530
- # [countsonly]]
53531
- # [formatjson]
53607
+ # ~[countsonly|formatjson]
53532
53608
  def printShowCalendarEvents(users):
53533
53609
  calendarEntity = getUserCalendarEntity()
53534
53610
  calendarEventEntity = getCalendarEventEntity()
53535
- csvPF, FJQC, fieldsList = _getCalendarPrintShowEventOptions(calendarEventEntity, Ent.USER)
53611
+ csvPF, FJQC, fieldsList, addCSVData = _getCalendarPrintShowEventOptions(calendarEventEntity, Ent.USER)
53536
53612
  i, count, users = getEntityArgument(users)
53537
53613
  for user in users:
53538
53614
  i += 1
@@ -53543,7 +53619,7 @@ def printShowCalendarEvents(users):
53543
53619
  continue
53544
53620
  Ind.Increment()
53545
53621
  _printShowCalendarEvents(origUser, user, cal, calIds, jcount, calendarEventEntity,
53546
- csvPF, FJQC, fieldsList)
53622
+ csvPF, FJQC, fieldsList, addCSVData)
53547
53623
  Ind.Decrement()
53548
53624
  if csvPF:
53549
53625
  if calendarEventEntity['countsOnly'] and calendarEventEntity['eventRowFilter']:
@@ -53987,7 +54063,7 @@ def printShowStatusEvent(users, eventType):
53987
54063
  for event in events:
53988
54064
  if showDayOfWeek:
53989
54065
  _getEventDaysOfWeek(event)
53990
- _printCalendarEvent(user, calId, event, csvPF, FJQC)
54066
+ _printCalendarEvent(user, calId, event, csvPF, FJQC, {})
53991
54067
  if 'pdelta' in wlDate:
53992
54068
  first = first.shift(**wlDate['pdelta'])
53993
54069
  last = last.shift(**wlDate['pdelta'])
@@ -77238,7 +77314,7 @@ TASK_QUERY_STATE_MAP = {
77238
77314
  # [updatedmin <Time>]
77239
77315
  # [showcompleted [<Boolean>]] [showdeleted [<Boolean>]] [showhidden [<Boolean>]] [showall]
77240
77316
  # [orderby completed|due|updated]
77241
- # [countsonly | (formatjson [quotechar <Character>])]
77317
+ # [countsonly|(formatjson [quotechar <Character>])]
77242
77318
  def printShowTasks(users):
77243
77319
  def _showTaskAndChildren(tasklist, taskId, k, compact):
77244
77320
  if taskId in taskParentsProcessed:
@@ -77305,8 +77381,11 @@ def printShowTasks(users):
77305
77381
  csvPF.SetTitles(['User', CSVTitle])
77306
77382
  else:
77307
77383
  FJQC.GetFormatJSONQuoteChar(myarg, False)
77308
- if csvPF and FJQC.formatJSON:
77309
- csvPF.SetJSONTitles(['User', 'tasklistId', 'id', 'taskId', 'title', 'JSON'])
77384
+ if csvPF:
77385
+ if countsOnly:
77386
+ csvPF.SetFormatJSON(False)
77387
+ elif FJQC.formatJSON:
77388
+ csvPF.SetJSONTitles(['User', 'tasklistId', 'id', 'taskId', 'title', 'JSON'])
77310
77389
  i, count, users = getEntityArgument(users)
77311
77390
  for user in users:
77312
77391
  i += 1
@@ -77505,7 +77584,7 @@ def processTasklists(users):
77505
77584
  # gam <UserTypeEntity> show tasklists
77506
77585
  # [countsonly|formatjson]
77507
77586
  # gam <UserTypeEntity> print tasklists [todrive <ToDriveAttribute>*]
77508
- # [countsonly | (formatjson [quotechar <Character>])]
77587
+ # [countsonly|(formatjson [quotechar <Character>])]
77509
77588
  def printShowTasklists(users):
77510
77589
  csvPF = CSVPrintFile(['User', 'id', 'title']) if Act.csvFormat() else None
77511
77590
  if csvPF:
@@ -77523,6 +77602,8 @@ def printShowTasklists(users):
77523
77602
  csvPF.SetTitles(['User', CSVTitle])
77524
77603
  else:
77525
77604
  FJQC.GetFormatJSONQuoteChar(myarg, True)
77605
+ if countsOnly and csvPF:
77606
+ csvPF.SetFormatJSON(False)
77526
77607
  i, count, users = getEntityArgument(users)
77527
77608
  for user in users:
77528
77609
  i += 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.23.3
3
+ Version: 7.23.5
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=dsuX4wazwrCSeB0f4J_CsvPREAC7MCb42Q7raQSmcKE,3619223
1
+ gam/__init__.py,sha256=azObku-kchg7drgmBFc3imztILTag7nTTt2PSx-l-Cs,3622295
2
2
  gam/__main__.py,sha256=amz0-959ph6zkZKqjaar4n60yho-T37w6qWI36qx0CA,1049
3
3
  gam/cacerts.pem,sha256=DUsVo2XlFYwfkhe3gnxa-Km4Z4noz74hSApXwTT-nQE,44344
4
4
  gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
@@ -47,8 +47,8 @@ gam/gdata/apps/audit/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrK
47
47
  gam/gdata/apps/audit/service.py,sha256=Z1eueThcNeVUMWP1DRWc_DGHrJCiJI8W_xj6L-cqu-Q,9658
48
48
  gam/gdata/apps/contacts/__init__.py,sha256=Um6zgIkiahZns7yAEuC3pxHSMD8iciZ_EoynSLoYPfU,30463
49
49
  gam/gdata/apps/contacts/service.py,sha256=5lNb-Ii1Gyek6ePFji3kyoYtCBc8CuJTwagx2BL2o14,15684
50
- gam7-7.23.3.dist-info/METADATA,sha256=wRQiwmYiklHDgb-mai-U8MVEtymKJrjK18xpCV12Ong,3092
51
- gam7-7.23.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
- gam7-7.23.3.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
53
- gam7-7.23.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
- gam7-7.23.3.dist-info/RECORD,,
50
+ gam7-7.23.5.dist-info/METADATA,sha256=4fCdZBo8CEvLYKB3C5MxtUIMeqGHc4DZCPHUN3oPdh8,3092
51
+ gam7-7.23.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
+ gam7-7.23.5.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
53
+ gam7-7.23.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
+ gam7-7.23.5.dist-info/RECORD,,
File without changes