Added option showitemcountonly to various commands

This commit is contained in:
Ross Scroggs
2024-01-12 21:53:12 -08:00
parent 2dd810ba69
commit 64ed92692a
17 changed files with 303 additions and 20 deletions

View File

@@ -23,7 +23,7 @@
- [Print a header row and fields for selected CrOS devices](#print-a-header-row-and-fields-for-selected-cros-devices)
- [Print a header row and fields for specified CrOS devices](#print-a-header-row-and-fields-for-specified-cros-devices)
- [Display Examples](#display-examples)
- [Display CrOS device count](#display-cros-device-count)
- [Display CrOS device counts](#display-cros-device-counts)
- [Print ChromeOS device activity](#print-chromeos-device-activity)
- [Print a header row and activity for selected CrOS devices](#print-a-header-row-and-activity-for-selected-cros-devices)
- [Print a header row and activity for specified CrOS devices](#print-a-header-row-and-activity-for-specified-cros-devices)
@@ -683,10 +683,17 @@ Print information about CrOS devices synced between 45 days ago and 30 days ago:
gam print cros query "sync:#querytime1#..#querytime2#" querytime1 -45d querytime2 -30d
```
## Display CrOS device count
## Display CrOS device counts
Display the number of CrOS devices in an entity.
```
gam <CrOSTypeEntity> show count
gam <CrOSTypeEntity> print cros showitemcountonly
gam print cros select <CrOSTypeEntity> showitemcountonly
gam print cros
[(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
[(limittoou|cros_ou <OrgUnitItem>)|(cros_ou_and_children <OrgUnitItem>)|
(cros_ous <OrgUnitList>)|(cros_ous_and_children <OrgUnitList>)]]
showitemcountonly
```
## Print ChromeOS device activity

View File

@@ -10,6 +10,7 @@
- [Manage course aliases](#manage-course-aliases)
- [Manage course topics](#manage-course-topics)
- [Display courses](#display-courses)
- [Display course counts](#display-course-counts)
- [Display course announcements](#display-course-announcements)
- [Display course materials](#display-course-materials)
- [Display course topics](#display-course-topics)
@@ -432,6 +433,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display course counts
Display the number of courses.
```
gam print courses
(course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
[owneremailmatchpattern <RegularExpression>]
showitemcountonly
```
## Display course announcements
```
gam print course-announcements [todrive <ToDriveAttribute>*]

View File

@@ -6,6 +6,7 @@
- [Legacy manage membership](#legacy-manage-membership)
- [Bulk membership changes](#bulk-membership-changes)
- [Display course membership](#display-course-membership)
- [Display course membership counts](#display-course-membership-counts)
## API documentation
* https://developers.google.com/classroom/reference/rest/
@@ -131,3 +132,12 @@ the quote character itself, the column delimiter (comma by default) and new-line
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display course membership counts
Display the number of course participants.
```
gam print course-participants
(course|class <CourseID>)*|([teacher <UserItem>] [student <UserItem>]) [states <CourseStateList>]
[show all|students|teachers]
showitemcountonly
```

View File

@@ -9,11 +9,13 @@
- [Synchronize devices](#synchronize-devices)
- [Display devices](#display-devices)
- [Print devices](#print-devices)
- [Display device counts](#display-device-counts)
- [Approve or block device users](#approve-or-block-device-users)
- [Delete device users](#delete-device-users)
- [Wipe device users](#wipe-device-users)
- [Perform device user actions](#perform-device-user-actions)
- [Display device users](#display-device-users)
- [Display device user counts](#display-device-user-counts)
- [Print device users](#print-device-users)
- [Display device user client state](#display-device-user-client-state)
- [Update device user client state](#update-device-user-client-state)
@@ -225,6 +227,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display device counts
Display the number of devices.
```
gam print devices
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
[all|company|personal|nocompanydevices|nopersonaldevices]
showitemcountonly
```
## Approve or block device users
Approve or block user profiles on a device.
```
@@ -285,6 +296,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display device user counts
Display the number of device users.
```
gam print deviceusers [todrive <ToDriveAttribute>*]
[select <DeviceID>]
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
showitemcountonly
```
## Display device user client state
```
gam info deviceuserstate <DeviceUserEntity> [clientid <String>]

View File

@@ -9,6 +9,7 @@
- [Manage groups](#manage-groups)
- [Display information about individual groups](#display-information-about-individual-groups)
- [Display information about multiple groups](#display-information-about-multiple-groups)
- [Display group counts](#display-group-counts)
## API documentation
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups
@@ -376,3 +377,14 @@ gam print cigroups query "'cloudidentity.googleapis.com/groups.dynamic' in label
```
gam print cigroups query "'cloudidentity.googleapis.com/groups.security' in labels"
```
## Display group counts
Display the number of groups.
```
gam print cigroups
[(cimember|showownedby <UserItem>)|(select <GroupEntity>)|(query <String>)]
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
[descriptionmatchpattern [not] <RegularExpression>]
showitemcountonly
```

View File

@@ -11,6 +11,23 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
### 6.67.17
Added option `showitemcountonly` to various commands that causes GAM to display the
item count on stdout; no CSV file is written.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Groups#display-group-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Courses#display-course-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Membership#display-course-membership-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/ChromeOS-Devices#display-cros-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Groups#display-group-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Mobile-Devices#display-mobile-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Organizational-Units#display-organizational-unit-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Resources#display-resource-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#display-user-counts
### 6.67.16
By default, `gam print group-members membernames` displays `Unknown` for members whose names can not be determined.

View File

@@ -16,6 +16,7 @@
- [Display information about selected groups](#display-information-about-selected-groups)
- [Display a group and its parents](#Display-a-group-and-its-parents)
- [Examples](#Examples)
- [Display group counts](#display-group-counts)
## API documentation
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups
@@ -563,3 +564,14 @@ Group,Name,ParentsCount,Parents,ParentsName
testgroup2@domain.com,Test - Group 2,2,testgroup1@domain.com|testgroup@domain.com,Test Group1|Test Group Org
testgroup2@domain.com,Test - Group 2,1,testgroup@domain.net,Test Group Net
```
## Display group counts
Display the number of groups.
```
gam print groups
[([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryGroupList>)]))|
(select <GroupEntity>)]
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
[descriptionmatchpattern [not] <RegularExpression>] (matchsetting [not] <GroupAttribute>)*
[admincreatedmatch <Boolean>]
showitemcountonly
```

View File

@@ -334,7 +334,7 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.1 64-bit final
MacOS Sonoma 14.2.1 x86_64
@@ -1002,7 +1002,7 @@ writes the credentials into the file oauth2.txt.
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
C:\GAMADV-XTD3>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.1 64-bit final
Windows-10-10.0.17134 AMD64

View File

@@ -5,6 +5,7 @@
- [Manage mobile devices](#manage-mobile-devices)
- [Display mobile devices](#display-mobile-devices)
- [Print mobile devices](#print-mobile-devices)
- [Display mobile device counts](#display-mobile-device-counts)
## API documentation
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/mobiledevices
@@ -150,3 +151,10 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display mobile device counts
Display the number of mobile devices.
```
gam print mobile
[(query <QueryMobile>)|(queries <QueryMobileList>) (querytime<String> <Time>)*]
showitemcountonly
```

View File

@@ -13,6 +13,7 @@
- [Synchronize ChromeOS devices with an organizational unit](#synchronize-chromeos-devices-with-an-organizational-unit)
- [Display organizational units](#display-organizational-units)
- [Print organizational units](#print-organizational-units)
- [Display orgamizational unit counts](#display-organizational-unit-counts)
- [Display indented organizational unit tree](#display-indented-organizational-unit-tree)
- [Special case handling for large number of organizational units](#special-case-handling-for-large-number-of-organizational-units)
@@ -237,6 +238,14 @@ Get file count summaries by OU; top level selector is ou, sub level selectors ar
gam redirect csv ./TopLevelOUs.csv print ous showparent toplevelonly parentselector ou childselector ou_and_children fields orgunitpath
gam redirect csv ./FileCounts.csv multiprocess csv ./TopLevelOUs.csv gam "~orgUnitSelector" "~orgUnitPath" print filecounts excludetrashed summary only summaryuser "~orgUnitPath"
```
## Display organizational unit counts
Display the number of organizational units.
```
gam print orgs|ous
[fromparent <OrgUnitItem>] [showparent [Boolean>]] [toplevelonly]
showitemcountonly
```
## Display indented organizational unit tree
```
gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [<Boolean>]]

View File

@@ -8,6 +8,7 @@
- [Display features](#display-features)
- [Manage resources](#manage-resources)
- [Display resources](#display-resources)
- [Display resource counts](#display-resource-counts)
- [Manage resource calendar ACLs](#manage-resource-calendar-acls)
- [Display resource calendar ACLs](#display-resource-calendar-acls)
@@ -245,6 +246,14 @@ Print all resources and their owners.
gam config csv_output_row_filter "role:regex:owner" redirect csv Resource.csv print resources acls
```
## Display resource counts
Display the number of mobile devices.
```
gam print resources
[query <String>]
showitemcountonly
```
## Manage resource calendar ACLs
These commands operate on a single resource calendar.
```

View File

@@ -172,6 +172,7 @@
(gdoc|ghtml <UserGoogleDoc>)|
(gcsdoc|gcshtml <StorageBucketObjectName>)|
(emlfile <FileName> [charset <Charset>]))
```
## Message queries with dates
```
query <QueryGmail> [querytime<String> <Date>]*

View File

@@ -38,7 +38,7 @@
- [Print domain counts for users in a specific domain and/or selected by a query](#print-domain-counts-for-users-in-a-specific-domain-and-or-selected-by-a-query)
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-usertypeentity)
- [Print user list](#print-user-list)
- [Display user count](#display-user-count)
- [Display user counts](#display-user-counts)
## API documentation
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
@@ -1206,9 +1206,15 @@ $ more UsersList.csv
["testuser1@domain.org", "testuser2@domain.org", "testuser3@domain.org", "testuser4@domain.org"]
```
## Display user count
## Display user counts
Display the number of users in an entity.
```
gam <UserTypeEntity> show count
gam <UserTypeEntity> print users showitemcountonly
gam print users select <UserTypeEntity> showitemcountonly
gam print users
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])|[select <UserTypeEntity>]
[issuspended <Boolean>]
showitemcountonly
```

View File

@@ -4,7 +4,7 @@
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.1 64-bit final
MacOS Sonoma 14.2.1 x86_64
@@ -16,7 +16,7 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.1 64-bit final
MacOS Sonoma 14.2.1 x86_64
@@ -28,7 +28,7 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information
```
gam version extended
GAMADV-XTD3 6.67.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.67.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.1 64-bit final
MacOS Sonoma 14.2.1 x86_64
@@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Version Check:
Current: 5.35.08
Latest: 6.67.16
Latest: 6.67.17
echo $?
1
```
@@ -73,7 +73,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.67.16
6.67.17
```
In Linux/MacOS you can do:
```
@@ -83,7 +83,7 @@ echo $VER
Print the current version of Gam and address of this Wiki
```
gam help
GAM 6.67.16 - https://github.com/taers232c/GAMADV-XTD3
GAM 6.67.17 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.1 64-bit final
MacOS Sonoma 14.2.1 x86_64

View File

@@ -2295,6 +2295,7 @@ gam print cros [todrive <ToDriveAttribute>*]
[timerangeorder ascending|descending] [showdvrsfp]
[sortheaders]
[formatjson [quotechar <Character>]]
[showitemcountonly]
Print fields for specified CrOS devices.
@@ -2307,6 +2308,7 @@ gam print cros [todrive <ToDriveAttribute>*] select <CrOSTypeEntity>
[timerangeorder ascending|descending] [showdvrsfp]
[sortheaders]
[formatjson [quotechar <Character>]]
[showitemcountonly]
gam <CrOSTypeEntity> print cros [todrive <ToDriveAttribute>*]
[orderby <CrOSOrderByFieldName> [ascending|descending]]
@@ -2317,6 +2319,7 @@ gam <CrOSTypeEntity> print cros [todrive <ToDriveAttribute>*]
[timerangeorder ascending|descending] [showdvrsfp]
[sortheaders]
[formatjson [quotechar <Character>]]
[showitemcountonly]
The first column will always be deviceId; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
otherwise, the remaining field names will appear in the order specified.
@@ -2901,13 +2904,16 @@ gam print courses [todrive <ToDriveAttribute>*]
[owneremail] [owneremailmatchpattern <RegularExpression>]
[alias|aliases|aliasesincolumns [delimiter <Character>]]
[show all|students|teachers] [countsonly]
[timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
[fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>]
[formatjson [quotechar <Character>]]
[timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
[showitemcountonly]
gam print course-participants [todrive <ToDriveAttribute>*]
(course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
[show all|students|teachers]
[formatjson [quotechar <Character>]]
[showitemcountonly]
<CourseAnnouncementFieldName> ::=
alternatelink|
@@ -3616,6 +3622,7 @@ gam print groups [todrive <ToDriveAttribute>*]
[memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
[convertcrnl] [delimiter <Character>] [sortheaders]
[formatjson [quotechar <Character>]]
[showitemcountonly]
gam print grouptree <GroupEntity> [todrive <ToDriveAttribute>*]
[showparentsaslist [<Boolean>]] [delimiter <Character>]
@@ -3736,6 +3743,7 @@ gam print cigroups [todrive <ToDriveAttribute>*]
[memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
[convertcrnl] [delimiter <Character>]
[formatjson [quotechar <Character>]]
[showitemcountonly]
<CIGroupMembersFieldName> ::=
createtime
@@ -3860,6 +3868,7 @@ gam print devices [todrive <ToDriveAttribute>*]
[all|company|personal|nocompanydevices|nopersonaldevices]
[nodeviceusers]
[formatjson [quotechar <Character>]]
[showitemcountonly]
<DeviceUserAction> ::=
approve|
@@ -3883,6 +3892,7 @@ gam print deviceusers [todrive <ToDriveAttribute>*]
<DeviceUserFieldName>* [fields <DeviceUserFieldNameList>]
[orderby <DeviceOrderByFieldName> [ascending|descending]]
[formatjson [quotechar <Character>]]
[showitemcountonly]
gam info deviceuserstate <DeviceUserEntity> [clientid <String>]
gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
@@ -4025,6 +4035,7 @@ gam print mobile [todrive <ToDriveAttribute>*]
[basic|full|allfields] <MobileFieldName>* [fields <MobileFieldNameList>]
[delimiter <Character>] [appslimit <Number>] [oneappperrow] [listlimit <Number>]
[formatjson [quotechar <Character>]]
[showitemcountonly]
# Organizational Units
@@ -4067,6 +4078,7 @@ gam print orgs|ous [todrive <ToDriveAttribute>*]
[allfields|<OrgUnitFieldName>*|(fields <OrgUnitFieldNameList>)] [convertcrnl] [batchsuborgs [<Boolean>]]
[mincroscount <Number>] [maxcroscount <Number>]
[minusercount <Number>] [maxusercount <Number>]
[showitemcountonly]
gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [<Boolean>]]
# Printers
@@ -4360,6 +4372,7 @@ gam print resources [todrive <ToDriveAttribute>*] [allfields|<ResourceFieldName>
[query <String>]
[acls] [noselfowner] [calendar] [convertcrnl]
[formatjson [quotechar <Character>]]
[showitemcountonly]
<CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer|none
<CalendarACLScope> ::= <EmailAddress>|user:<EmailAdress>|group:<EmailAddress>|domain:<DomainName>|domain|default
@@ -5342,6 +5355,7 @@ gam print users [todrive <ToDriveAttribute>*]
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
[showitemcountonly]
Print fields for specified users.
@@ -5356,6 +5370,7 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
[showitemcountonly]
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
[orderby <UserOrderByFieldName> [ascending|descending]]
@@ -5368,6 +5383,7 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
[showitemcountonly]
The first column will always be primaryEmail; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
otherwise, the remaining field names will appear in the order specified.

View File

@@ -2,6 +2,23 @@
Merged GAM-Team version
6.67.17
Added option `showitemcountonly` to various commands that causes GAM to display the
item count on stdout; no CSV file is written.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Groups#display-group-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Courses#display-course-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Classroom-Membership#display-course-membership-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/ChromeOS-Devices#display-cros-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Devices#display-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Groups#display-group-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Mobile-Devices#display-mobile-device-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Organizational-Units#display-organizational-unit-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Resources#display-resource-counts
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#display-user-counts
6.67.16
By default, `gam print group-members membernames` displays `Unknown` for members whose names can not be determined.

View File

@@ -17148,6 +17148,7 @@ def getOrgUnitIdToPathMap(cd=None):
# [allfields|<OrgUnitFieldName>*|(fields <OrgUnitFieldNameList>)] [convertcrnl] [batchsuborgs [<Boolean>]]
# [mincroscount <Number>] [maxcroscount <Number>]
# [minusercount <Number>] [maxusercount <Number>]
# [showitemcountonly]
def doPrintOrgs():
cd = buildGAPIObject(API.DIRECTORY)
convertCRNL = GC.Values[GC.CSV_OUTPUT_CONVERT_CR_NL]
@@ -17160,6 +17161,7 @@ def doPrintOrgs():
minCrOSCounts = maxCrOSCounts = minUserCounts = maxUserCounts = -1
crosCounts = {}
userCounts = {}
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -17203,6 +17205,8 @@ def doPrintOrgs():
invalidChoiceExit(field, list(ORG_ARGUMENT_TO_FIELD_MAP), True)
elif myarg in {'convertcrnl', 'converttextnl'}:
convertCRNL = True
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
unknownArgumentExit()
if childSelector:
@@ -17216,6 +17220,9 @@ def doPrintOrgs():
for field in PRINT_ORGS_DEFAULT_FIELDS:
csvPF.AddField(field, ORG_ARGUMENT_TO_FIELD_MAP, fieldsList)
orgUnits = _getOrgUnits(cd, orgUnitPath, fieldsList, listType, showParent, batchSubOrgs, childSelector, parentSelector)
if showItemCountOnly:
writeStdout(f'{0 if orgUnits is None else (len(orgUnits))}\n')
return
if orgUnits is None:
return
if showUserCounts:
@@ -23463,6 +23470,7 @@ CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
# [(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
# [(limittoou|cros_ou <OrgUnitItem>)|(cros_ou_and_children <OrgUnitItem>)|
# (cros_ous <OrgUnitList>)|(cros_ous_and_children <OrgUnitList>)]]
# [showitemcountonly]
# gam print cros [todrive <ToDriveAttribute>*] select <CrOSTypeEntity>
# gam <CrOSTypeEntity> print cros [todrive <ToDriveAttribute>*]
# [orderby <CrOSOrderByFieldName> [ascending|descending]]
@@ -23473,6 +23481,7 @@ CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
# [timerangeorder ascending|descending] [showdvrsfp]
# [sortheaders]
# [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintCrOSDevices(entityList=None):
def _printCrOS(cros):
checkTPMVulnerability(cros)
@@ -23607,6 +23616,7 @@ def doPrintCrOSDevices(entityList=None):
selectionAllowed = False
allFields = noLists = oneRow = showDVRstorageFreePercentage = sortHeaders = False
activeTimeRangesOrder = 'ASCENDING'
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -23676,6 +23686,8 @@ def doPrintCrOSDevices(entityList=None):
invalidChoiceExit(field, CROS_LIST_FIELDS_CHOICE_MAP, True)
elif myarg == 'showdvrsfp':
showDVRstorageFreePercentage = True
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
if selectedLists:
@@ -23716,8 +23728,9 @@ def doPrintCrOSDevices(entityList=None):
tokenRetries = 0
pageToken, totalItems = _processGAPIpagesResult(feed, 'chromeosdevices', None, totalItems, pageMessage, None, Ent.CROS_DEVICE)
if feed:
for cros in feed.get('chromeosdevices', []):
_printCrOS(cros)
if not showItemCountOnly:
for cros in feed.get('chromeosdevices', []):
_printCrOS(cros)
del feed
if not pageToken:
_finalizeGAPIpagesResult(pageMessage)
@@ -23742,7 +23755,13 @@ def doPrintCrOSDevices(entityList=None):
return
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
accessErrorExit(cd)
if showItemCountOnly:
writeStdout(f'{totalItems}\n')
return
else:
if showItemCountOnly:
writeStdout(f'{len(entityList)}\n')
return
sortRows = True
if allFields or len(set(fieldsList)) > 1:
jcount = len(entityList)
@@ -25202,7 +25221,7 @@ def _getChatMemberEmail(cd, member):
if 'member' in member:
if member['member']['type'] == 'HUMAN':
_, memberUid = member['member']['name'].split('/')
member['member']['email'], status = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, emailTypes=['user'])
member['member']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, emailTypes=['user'])
elif 'groupMember' in member:
_, memberUid = member['groupMember']['name'].split('/')
member['groupMember']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, emailTypes=['group'])
@@ -27348,6 +27367,7 @@ DEVICE_ORDERBY_CHOICE_MAP = {
# [all|company|personal|nocompanydevices|nopersonaldevices]
# [nodeviceusers]
# [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintCIDevices():
ci = buildGAPICIDeviceServiceObject()
customer = _getCustomersCustomerIdNoC()
@@ -27361,6 +27381,7 @@ def doPrintCIDevices():
queries = [None]
view, entityType = DEVICE_VIEW_CHOICE_MAP['all']
getDeviceUsers = True
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -27381,11 +27402,14 @@ def doPrintCIDevices():
pass
elif myarg == 'sortheaders':
pass
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
fields = getItemFieldsFromFieldsList('devices', fieldsList)
userFields = getItemFieldsFromFieldsList('deviceUsers', userFieldsList)
substituteQueryTimes(queries, queryTimes)
itemCount = 0
for query in queries:
printGettingAllAccountEntities(entityType, query)
pageMessage = getPageMessage()
@@ -27396,6 +27420,9 @@ def doPrintCIDevices():
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
customer=customer, filter=query,
orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100)
if showItemCountOnly:
itemCount += len(devices)
continue
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
entityActionFailedWarning([entityType, None], str(e))
continue
@@ -27430,6 +27457,9 @@ def doPrintCIDevices():
csvPF.WriteRowNoFilter({'name': device['name'],
'JSON': json.dumps(cleanJSON(device, timeObjects=DEVICE_TIME_OBJECTS),
ensure_ascii=False, sort_keys=True)})
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
csvPF.writeCSVfile('Devices')
DEVICE_USER_ACTION_CHOICES = {'approve', 'block', 'cancelwipe', 'wipe'}
@@ -27533,6 +27563,7 @@ def doInfoCIDeviceUser():
# <DeviceUserFieldName>* [fields <DevieUserFieldNameList>]
# [orderby <DeviceOrderByFieldName> [ascending|descending]]
# [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintCIDeviceUsers():
ci = buildGAPICIDeviceServiceObject()
customer = _getCustomersCustomerIdNoC()
@@ -27543,6 +27574,7 @@ def doPrintCIDeviceUsers():
queryTimes = {}
queries = [None]
parent = 'devices/-'
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -27561,10 +27593,13 @@ def doPrintCIDeviceUsers():
pass
elif myarg == 'sortheaders':
pass
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
userFields = getItemFieldsFromFieldsList('deviceUsers', userFieldsList)
substituteQueryTimes(queries, queryTimes)
itemCount = 0
for query in queries:
printGettingAllAccountEntities(Ent.DEVICE_USER, query)
pageMessage = getPageMessage()
@@ -27575,6 +27610,9 @@ def doPrintCIDeviceUsers():
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
customer=customer, filter=query,
orderBy=OBY.orderBy, parent=parent, fields=userFields, pageSize=20)
if showItemCountOnly:
itemCount += len(deviceUsers)
continue
for deviceUser in deviceUsers:
row = flattenJSON(deviceUser, timeObjects=DEVICE_TIME_OBJECTS)
if not FJQC.formatJSON:
@@ -27586,6 +27624,9 @@ def doPrintCIDeviceUsers():
except (GAPI.invalid, GAPI.permissionDenied) as e:
entityActionFailedWarning([Ent.DEVICE_USER, None], str(e))
break
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
csvPF.writeCSVfile('Device Users')
DEVICE_USER_COMPLIANCE_STATE_CHOICE_MAP = {
@@ -29319,6 +29360,7 @@ MOBILE_ORDERBY_CHOICE_MAP = {
# [basic|full|allfields] <MobileFieldName>* [fields <MobileFieldNameList>]
# [delimiter <Character>] [appslimit <Number>] [oneappperrow] [listlimit <Number>]
# [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintMobileDevices():
def _appDetails(app):
appDetails = []
@@ -29389,6 +29431,7 @@ def doPrintMobileDevices():
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
listLimit = 1
appsLimit = -1
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -29409,6 +29452,8 @@ def doPrintMobileDevices():
oneAppPerRow = True
elif _getMobileFieldsArguments(myarg, parameters):
pass
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
if not FJQC.formatJSON:
@@ -29417,6 +29462,7 @@ def doPrintMobileDevices():
parameters['projection'] = 'FULL'
fields = getItemFieldsFromFieldsList('mobiledevices', parameters['fieldsList'])
substituteQueryTimes(queries, queryTimes)
itemCount = 0
for query in queries:
printGettingAllAccountEntities(Ent.MOBILE_DEVICE, query)
pageMessage = getPageMessage()
@@ -29428,8 +29474,11 @@ def doPrintMobileDevices():
customerId=GC.Values[GC.CUSTOMER_ID], query=query, projection=parameters['projection'],
orderBy=orderBy, sortOrder=sortOrder, fields=fields, maxResults=GC.Values[GC.MOBILE_MAX_RESULTS])
for mobiles in feed:
totalItems += len(mobiles)
if showItemCountOnly:
itemCount += len(mobiles)
continue
for mobile in mobiles:
totalItems += 1
_printMobile(mobile)
printGotAccountEntities(totalItems)
except GAPI.invalidInput:
@@ -29437,6 +29486,9 @@ def doPrintMobileDevices():
return
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
accessErrorExit(cd)
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
csvPF.writeCSVfile('Mobile')
GROUP_DISCOVER_CHOICES = {
@@ -31352,8 +31404,10 @@ PRINT_GROUPS_JSON_TITLES = ['email', 'JSON']
# [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
# [convertcrnl] [delimiter <Character>] [sortheaders]
# [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintGroups():
def _printGroupRow(groupEntity, groupSettings, groupMembers):
nonlocal itemCount
row = {}
if matchSettings:
if not isinstance(groupSettings, dict):
@@ -31366,6 +31420,9 @@ def doPrintGroups():
return
if showOwnedBy and not checkGroupShowOwnedBy(showOwnedBy, groupMembers):
return
if showItemCountOnly:
itemCount += 1
return
if deprecatedAttributesSet and isinstance(groupSettings, dict):
deprecatedKeys = []
for key in groupSettings:
@@ -31533,6 +31590,7 @@ def doPrintGroups():
matchSettings = {}
deprecatedAttributesSet = set()
ciGroups = {}
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -31613,6 +31671,8 @@ def doPrintGroups():
pass
elif myarg == 'includederivedmembership':
memberOptions[MEMBEROPTION_INCLUDEDERIVEDMEMBERSHIP] = True
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
if not typesSet:
@@ -31751,6 +31811,7 @@ def doPrintGroups():
gsbatch = gs.new_batch_http_request(callback=_callbackProcessGroupSettings)
gsbcount = 0
groupData = {}
itemCount = 0
i = 0
count = len(entityList)
for groupEntity in entityList:
@@ -31793,6 +31854,9 @@ def doPrintGroups():
if getSettings and gsbcount > 0:
gsbatch.execute()
_writeCompleteRows()
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
if sortHeaders:
sortTitles = ['email']+GROUP_INFO_PRINT_ORDER+['aliases', 'nonEditableAliases']
if getSettings:
@@ -33413,12 +33477,17 @@ PRINT_CIGROUPS_JSON_TITLES = ['email', 'JSON']
# [memberemaildisplaypattern|memberemailskippattern <RegularExpression>]
# [convertcrnl] [delimiter <Character>]
# [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintCIGroups():
def _printGroupRow(groupEntity, groupMembers):
nonlocal itemCount
for member in groupMembers:
getCIGroupMemberRoleFixType(member)
if showOwnedBy and not checkCIGroupShowOwnedBy(showOwnedBy, groupMembers):
return
if showItemCountOnly:
itemCount += 1
return
if not keepName:
groupEntity.pop('name', None)
row = {}
@@ -33458,6 +33527,7 @@ def doPrintCIGroups():
memberOptions = initMemberOptions()
entitySelection = groupMembers = memberQuery = query = showOwnedBy = None
matchPatterns = {}
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -33508,6 +33578,8 @@ def doPrintCIGroups():
pass
elif myarg == 'memberrestrictions':
memberRestrictions = True
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
if not typesSet:
@@ -33601,6 +33673,7 @@ def doPrintCIGroups():
GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
GAPI.systemError, GAPI.permissionDenied, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning([Ent.CLOUD_IDENTITY_GROUP, groupEmail], str(e), i, count)
itemCount = 0
i = 0
count = len(entityList)
for groupEntity in entityList:
@@ -33644,6 +33717,9 @@ def doPrintCIGroups():
GAPI.systemError, GAPI.permissionDenied, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning([Ent.CLOUD_IDENTITY_GROUP, groupEmail], str(e), i, count)
_printGroupRow(groupEntity, groupMembers)
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
if sortHeaders:
sortTitles = ['email']+CIGROUP_PRINT_ORDER
if rolesSet:
@@ -35214,6 +35290,7 @@ RESOURCE_FIELDS_CHOICE_MAP = {
# [allfields|<ResourceFieldName>*|(fields <ResourceFieldNameList>)]
# [query <String>]
# [acls] [noselfowner] [calendar] [convertcrnl] [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintShowResourceCalendars():
cd = buildGAPIObject(API.DIRECTORY)
convertCRNL = GC.Values[GC.CSV_OUTPUT_CONVERT_CR_NL]
@@ -35222,6 +35299,7 @@ def doPrintShowResourceCalendars():
fieldsList = []
csvPF = CSVPrintFile() if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF)
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -35254,6 +35332,8 @@ def doPrintShowResourceCalendars():
invalidChoiceExit(field, RESOURCE_FIELDS_CHOICE_MAP, True)
elif myarg in {'convertcrnl', 'converttextnl'}:
convertCRNL = True
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
if not fieldsList:
@@ -35286,8 +35366,11 @@ def doPrintShowResourceCalendars():
except GAPI.invalidInput as e:
entityActionFailedWarning([Ent.RESOURCE_CALENDAR, ''], str(e))
return
i = 0
count = len(resources)
if showItemCountOnly:
writeStdout(f'{count}\n')
return
i = 0
for resource in resources:
i += 1
if getCalSettings or getCalPermissions:
@@ -42487,6 +42570,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
# [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
# [showitemcountonly]
#
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
# [groups|groupsincolumns]
@@ -42497,16 +42581,19 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
# [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
# [showitemcountonly]
#
# gam print users [todrive <ToDriveAttribute>*]
# ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
# [limittoou <OrgUnitItem>] [deleted_only|only_deleted])|[select <UserTypeEntity>]
# [formatjson [quotechar <Character>]] [countonly]
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
# [showitemcountonly]
#
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
# [formatjson [quotechar <Character>]] [countonly]
# [issuspended <Boolean>]
# [showitemcountonly]
def doPrintUsers(entityList=None):
def _printUser(userEntity, i, count):
if isSuspended is None or isSuspended == userEntity.get('suspended', isSuspended):
@@ -42632,6 +42719,7 @@ def doPrintUsers(entityList=None):
aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
viewType = 'admin_view'
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -42704,6 +42792,8 @@ def doPrintUsers(entityList=None):
maxResults = getInteger(minVal=1, maxVal=500)
elif myarg == 'quoteplusphonenumbers':
quotePlusPhoneNumbers = True
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
_, _, entityList = getEntityArgument(entityList)
@@ -42739,6 +42829,7 @@ def doPrintUsers(entityList=None):
if orgUnitPath is not None and fieldsList:
fieldsList.append('orgUnitPath')
fields = getItemFieldsFromFieldsList('users', fieldsList)
itemCount = 0
for kwargsQuery in makeUserGroupDomainQueryFilters(kwargsDict):
kwargs = kwargsQuery[0]
query = kwargsQuery[1]
@@ -42754,6 +42845,9 @@ def doPrintUsers(entityList=None):
showDeleted=showDeleted, orderBy=orderBy, sortOrder=sortOrder, viewType=viewType,
projection=projection, customFieldMask=customFieldMask, maxResults=maxResults, **kwargs)
for users in feed:
if showItemCountOnly:
itemCount += len(users)
continue
if orgUnitPath is None:
if not printOptions['countOnly']:
for user in users:
@@ -42785,7 +42879,13 @@ def doPrintUsers(entityList=None):
continue
except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
accessErrorExit(cd)
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
else:
if showItemCountOnly:
writeStdout(f'{len(entityList)}\n')
return
sortRows = True
# If no individual fields were specified (allfields, basic, full) or individual fields other than primaryEmail were specified, look up each user
if isSuspended is not None:
@@ -45057,6 +45157,7 @@ def _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties, getO
# [show none|all|students|teachers] [countsonly]
# [fields <CourseFieldNameList>] [skipfields <CourseFieldNameList>] [formatjson [quotechar <Character>]]
# [timefilter creationtime|updatetime] [start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>]
# [showitemcountonly]
def doPrintCourses():
def _saveParticipants(course, participants, role, rtitles):
jcount = len(participants)
@@ -45097,6 +45198,7 @@ def doPrintCourses():
courseShowProperties = _initCourseShowProperties()
ownerEmails = {}
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -45109,6 +45211,8 @@ def doPrintCourses():
delimiter = getCharacter()
elif _getCourseShowProperties(myarg, courseShowProperties):
pass
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
applyCourseItemFilter = _setApplyCourseItemFilter(courseItemFilter, None)
@@ -45117,6 +45221,8 @@ def doPrintCourses():
courseShowProperties['fields'].append(courseItemFilter['timefilter'])
coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
if coursesInfo is None:
if showItemCountOnly:
writeStdout('0\n')
return
if courseShowProperties['aliases']:
if FJQC.formatJSON:
@@ -45142,6 +45248,7 @@ def doPrintCourses():
studentsFields = 'nextPageToken,students(profile)'
else:
teachersFields = studentsFields = None
itemCount = 0
count = len(coursesInfo)
i = 0
for course in coursesInfo:
@@ -45156,6 +45263,9 @@ def doPrintCourses():
[Ent.COURSE, courseId, Ent.OWNER_ID, course['ownerId']], i, count)
if courseShowProperties['ownerEmailMatchPattern'] and not courseShowProperties['ownerEmailMatchPattern'].match(course['ownerEmail']):
continue
if showItemCountOnly:
itemCount += 1
continue
aliases, teachers, students = _getCourseAliasesMembers(croom, courseId, courseShowProperties, teachersFields, studentsFields, True, i, count)
if courseShowProperties['aliases']:
if not courseShowProperties['aliasesInColumns']:
@@ -45187,6 +45297,9 @@ def doPrintCourses():
else:
row['JSON-students'] = json.dumps(len(students))
csvPF.WriteRowNoFilter(row)
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
if not FJQC.formatJSON:
if courseShowProperties['aliases']:
csvPF.AddTitles('Aliases')
@@ -45853,6 +45966,7 @@ COURSE_PARTICIPANTS_SORT_TITLES = ['courseId', 'courseName', 'userRole', 'userId
# gam print course-participants [todrive <ToDriveAttribute>*]
# (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
# [show all|students|teachers] [formatjson [quotechar <Character>]]
# [showitemcountonly]
def doPrintCourseParticipants():
croom = buildGAPIObject(API.CLASSROOM)
csvPF = CSVPrintFile(['courseId', 'courseName'])
@@ -45860,6 +45974,7 @@ def doPrintCourseParticipants():
courseSelectionParameters = _initCourseSelectionParameters()
courseShowProperties = _initCourseShowProperties(['name'])
courseShowProperties['members'] = 'all'
showItemCountOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -45868,10 +45983,14 @@ def doPrintCourseParticipants():
pass
elif myarg == 'show':
courseShowProperties['members'] = getChoice(COURSE_MEMBER_ARGUMENTS)
elif myarg == 'showitemcountonly':
showItemCountOnly = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, False)
coursesInfo = _getCoursesInfo(croom, courseSelectionParameters, courseShowProperties)
if coursesInfo is None:
if showItemCountOnly:
writeStdout('0\n')
return
if courseShowProperties['members'] != 'none':
if courseShowProperties['members'] != 'students':
@@ -45884,12 +46003,19 @@ def doPrintCourseParticipants():
studentsFields = 'nextPageToken,students(userId,profile)'
else:
teachersFields = studentsFields = None
i = 0
itemCount = 0
count = len(coursesInfo)
i = 0
for course in coursesInfo:
i += 1
courseId = course['id']
_, teachers, students = _getCourseAliasesMembers(croom, courseId, courseShowProperties, teachersFields, studentsFields, True, i, count)
if showItemCountOnly:
if courseShowProperties['members'] != 'students':
itemCount += len(teachers)
if courseShowProperties['members'] != 'teachers':
itemCount += len(students)
continue
if not FJQC.formatJSON:
if courseShowProperties['members'] != 'none':
if courseShowProperties['members'] != 'students':
@@ -45906,6 +46032,9 @@ def doPrintCourseParticipants():
if courseShowProperties['members'] != 'teachers':
row['JSON-students'] = json.dumps(list(students))
csvPF.WriteRowNoFilter(row)
if showItemCountOnly:
writeStdout(f'{itemCount}\n')
return
if not FJQC.formatJSON:
csvPF.SetSortTitles(COURSE_PARTICIPANTS_SORT_TITLES)
csvPF.writeCSVfile('Course Participants')