Add showmimetypesize to print filelist/filecounts

This commit is contained in:
Ross Scroggs
2023-10-20 14:35:45 -07:00
parent 55298f0134
commit 4934809b88
13 changed files with 268 additions and 110 deletions

View File

@@ -571,6 +571,7 @@
<TakeoutBucketName> ::= takeout-export-[a-f,0-9,-]* <TakeoutBucketName> ::= takeout-export-[a-f,0-9,-]*
<TaskID> ::= <String> <TaskID> ::= <String>
<TaskListID> ::= <String> <TaskListID> ::= <String>
<TaskListTitle> ::= tltitle:<String>
<TasklistIDTaskID> ::= <TasklistID>/<TaskID> <TasklistIDTaskID> ::= <TasklistID>/<TaskID>
<ThreadID> ::= <String> <ThreadID> ::= <String>
<TimeZone> ::= <String> <TimeZone> ::= <String>

View File

@@ -332,8 +332,8 @@ Data fields identified in a `csvkmd` argument.
<SiteACLScopeList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector> <SiteACLScopeList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<SiteEntity> ::= <SiteEntity> ::=
<SiteList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector> <SiteList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<TasklistIDEntity> ::= <TasklistEntity> ::=
<TasklistIDList> | <FileSelector> | <CSVFileSelector> <TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
<TasklistIDTaskIDEntity> ::= <TasklistIDTaskIDEntity> ::=
<TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector> <TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector>
<ThreadIDEntity> ::= <ThreadIDEntity> ::=

View File

@@ -10,6 +10,37 @@ 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. See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation.
### 6.65.01
Added option `showmimetypesize` to `gam <UserTypeEntity> print|show filecounts` and
`gam <UserTypeEntity> print filelist countsonly` that displays the total file size for each MIME type.
### 6.65.00
Fixed bug in `gam <UserTypeEntity> create contact <JSONData>` that caused a trap when
contacts were being copied from one user to another.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-People-Contacts-Profiles#copy-user-contacts-to-another-user
Updated the following commands to allow specification of a task list by its title.
```
<TaskListTitle> ::= tltitle:<String>
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
gam <UserTypeEntity> create task <TasklistEntity>
gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
gam <UserTypeEntity> print tasks [tasklists <TasklistEntity>]
gam <UserTypeEntity> update tasklist <TasklistEntity>
gam <UserTypeEntity> delete tasklist <TasklistEntity>
gam <UserTypeEntity> clear tasklist <TasklistEntity>
gam <UserTypeEntity> info tasklist <TasklistEntity>
```
Note the quoting in `<TasklistTitleList>`; the entire list should be enclosed in `"` and
each `tltitle:<String>` must be enclosed in `'` if `<String>` contains a space.
### 6.64.16 ### 6.64.16
Fixed bug in `gam <UserTypeEntity> create task <TasklistIDEntity>` that caused a trap Fixed bug in `gam <UserTypeEntity> create task <TasklistIDEntity>` that caused a trap

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$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version 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 WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAMADV-XTD3 6.64.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource GAMADV-XTD3 6.65.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com> Ross Scroggs <ross.scroggs@gmail.com>
Python 3.10.8 64-bit final Python 3.10.8 64-bit final
MacOS High Sierra 10.13.6 x86_64 MacOS High Sierra 10.13.6 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>del C:\GAMConfig\oauth2.txt
C:\GAMADV-XTD3>gam version C:\GAMADV-XTD3>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAMADV-XTD3 6.64.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource GAMADV-XTD3 6.65.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com> Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.0 64-bit final Python 3.12.0 64-bit final
Windows-10-10.0.17134 AMD64 Windows-10-10.0.17134 AMD64

View File

@@ -93,6 +93,7 @@
<SharedDriveIDList> ::= "<SharedDriveID>(,<SharedDriveID>)*" <SharedDriveIDList> ::= "<SharedDriveID>(,<SharedDriveID>)*"
<StringList> ::= "<String>(,<String>)*" <StringList> ::= "<String>(,<String>)*"
<TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*" <TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*"
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*" <TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*"
<ThreadIDList> ::= "<ThreadID>(,<ThreadID>)*" <ThreadIDList> ::= "<ThreadID>(,<ThreadID>)*"
<TimeList> ::= "<Time>(,<Time>)*" <TimeList> ::= "<Time>(,<Time>)*"

View File

@@ -55,8 +55,8 @@ gam enable apis
``` ```
You are given the option to enable them automatically or manually. Automatic enablement will ask you to authenticate to GAMADV-XTD3. You should authenticate as a user with rights to manage project APIs, probably a project owner. If you are not the project owner you can choose manual enablement and GAMADV-XTD3 will provide two or more URLs which you can send to the project owner. When the owner opens these URLs, they'll be prompted to enable all the APIs GAMADV-XTD3 needs. You are given the option to enable them automatically or manually. Automatic enablement will ask you to authenticate to GAMADV-XTD3. You should authenticate as a user with rights to manage project APIs, probably a project owner. If you are not the project owner you can choose manual enablement and GAMADV-XTD3 will provide two or more URLs which you can send to the project owner. When the owner opens these URLs, they'll be prompted to enable all the APIs GAMADV-XTD3 needs.
9. Manage user data 9. Perform admin actions (manage users, groups, orgunits, Chrome devices, etc)
* Run ```gam user user@domain.com check serviceaccount``` and follow the instructions to perform domain-wide delegation.
10. Perform admin actions (manage users, groups, orgunits, Chrome devices, etc)
* [Configure delegated admin service account (DASA)](https://github.com/taers232c/GAMADV-XTD3/wiki/Using-GAMADV-XTD3-with-a-delegated-admin-service-account); start at step 4. * [Configure delegated admin service account (DASA)](https://github.com/taers232c/GAMADV-XTD3/wiki/Using-GAMADV-XTD3-with-a-delegated-admin-service-account); start at step 4.
10. Manage user data
* Run ```gam user user@domain.com check serviceaccount``` and follow the instructions to perform domain-wide delegation.

View File

@@ -617,7 +617,8 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[filenamematchpattern <RegularExpression>] [filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize] [showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> show filecounts gam <UserTypeEntity> show filecounts
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) [((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
(querytime<String> <Time>)*] (querytime<String> <Time>)*]
@@ -628,13 +629,16 @@ gam <UserTypeEntity> show filecounts
[filenamematchpattern <RegularExpression>] [filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize] [showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
``` ```
By default, print filecounts displays counts of all files owned by the specified [`<UserTypeEntity>`](Collections-of-Users). By default, print filecounts displays counts of all files owned by the specified [`<UserTypeEntity>`](Collections-of-Users).
The `showsize` option displays the total size (in bytes) of the files counted. The `showsize` option displays the total size (in bytes) of the files counted.
The showmimetypesize' displays the total size (in bytes) of each MIME type counted.
See [Select files for Display file counts, list, tree](#select-files-for-display-file-counts-list-tree) See [Select files for Display file counts, list, tree](#select-files-for-display-file-counts-list-tree)
Use the `excludetrashed` option to suppress counting files in the trash. Use the `excludetrashed` option to suppress counting files in the trash.
@@ -647,7 +651,83 @@ that can display a summarization of file counts across all users specified in th
The `summaryuser <String>` option replaces the default summary user `Summary` with `<String>`. The `summaryuser <String>` option replaces the default summary user `Summary` with `<String>`.
### Example ### Examples
Show file counts for a user.
```
$ gam user testuser@domain.com show filecounts showsize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User: testuser@domain.com, Drive Files/Folders: 261, Size: 13822521
application/octet-stream: 8
application/pdf: 1
application/vnd.google-apps.document: 98
application/vnd.google-apps.drawing: 2
application/vnd.google-apps.drive-sdk.423565144751: 1
application/vnd.google-apps.folder: 68
application/vnd.google-apps.form: 3
application/vnd.google-apps.jam: 1
application/vnd.google-apps.presentation: 1
application/vnd.google-apps.shortcut: 14
application/vnd.google-apps.site: 1
application/vnd.google-apps.spreadsheet: 24
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: 1
application/vnd.openxmlformats-officedocument.wordprocessingml.document: 3
application/vnd.openxmlformats-officedocument.wordprocessingml.template: 1
application/x-gzip: 4
application/zip: 2
image/jpeg: 8
image/vnd.adobe.photoshop: 1
text/csv: 2
text/plain: 13
text/rtf: 3
text/x-sh: 1
```
Show file counts for a user including sizes for each MIME type.
```
$ gam user testuser@domain.com show filecounts showmimetypesize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User: testuser@domain.com, Drive Files/Folders: 261, Size: 13822521
application/octet-stream: 8, 17
application/pdf: 1, 9879
application/vnd.google-apps.document: 98, 52858
application/vnd.google-apps.drawing: 2, 2048
application/vnd.google-apps.drive-sdk.423565144751: 1, 0
application/vnd.google-apps.folder: 68, 0
application/vnd.google-apps.form: 3, 0
application/vnd.google-apps.jam: 1, 1024
application/vnd.google-apps.presentation: 1, 0
application/vnd.google-apps.shortcut: 14, 0
application/vnd.google-apps.site: 1, 0
application/vnd.google-apps.spreadsheet: 24, 11264
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: 1, 8157
application/vnd.openxmlformats-officedocument.wordprocessingml.document: 3, 34407
application/vnd.openxmlformats-officedocument.wordprocessingml.template: 1, 25906
application/x-gzip: 4, 2768
application/zip: 2, 765
image/jpeg: 8, 16498
image/vnd.adobe.photoshop: 1, 13613198
text/csv: 2, 397
text/plain: 13, 41461
text/rtf: 3, 1738
text/x-sh: 1, 136
```
Print file counts for a user.
```
$ gam user testuser@domain,com print filecounts showsize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User,Total,Size,application/octet-stream,application/pdf,application/vnd.google-apps.document,application/vnd.google-apps.drawing,application/vnd.google-apps.drive-sdk.423565144751,application/vnd.google-apps.folder,application/vnd.google-apps.form,application/vnd.google-apps.jam,application/vnd.google-apps.presentation,application/vnd.google-apps.shortcut,application/vnd.google-apps.site,application/vnd.google-apps.spreadsheet,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.wordprocessingml.template,application/x-gzip,application/zip,image/jpeg,image/vnd.adobe.photoshop,text/csv,text/plain,text/rtf,text/x-sh
testuser@domain.com,261,13822521,8,1,98,2,1,68,3,1,1,14,1,24,1,3,1,4,2,8,1,2,13,3,1
```
Print file counts for a user including sizes for each MIME type.
```
$ gam user testuser@domain.com print filecounts showmimetypesize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User,Total,Size,application/octet-stream,application/octet-stream-size,application/pdf,application/pdf-size,application/vnd.google-apps.document,application/vnd.google-apps.document-size,application/vnd.google-apps.drawing,application/vnd.google-apps.drawing-size,application/vnd.google-apps.drive-sdk.423565144751,application/vnd.google-apps.drive-sdk.423565144751-size,application/vnd.google-apps.folder,application/vnd.google-apps.folder-size,application/vnd.google-apps.form,application/vnd.google-apps.form-size,application/vnd.google-apps.jam,application/vnd.google-apps.jam-size,application/vnd.google-apps.presentation,application/vnd.google-apps.presentation-size,application/vnd.google-apps.shortcut,application/vnd.google-apps.shortcut-size,application/vnd.google-apps.site,application/vnd.google-apps.site-size,application/vnd.google-apps.spreadsheet,application/vnd.google-apps.spreadsheet-size,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet-size,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.wordprocessingml.document-size,application/vnd.openxmlformats-officedocument.wordprocessingml.template,application/vnd.openxmlformats-officedocument.wordprocessingml.template-size,application/x-gzip,application/x-gzip-size,application/zip,application/zip-size,image/jpeg,image/jpeg-size,image/vnd.adobe.photoshop,image/vnd.adobe.photoshop-size,text/csv,text/csv-size,text/plain,text/plain-size,text/rtf,text/rtf-size,text/x-sh,text/x-sh-size
testuser@domain.com,261,13822521,8,17,1,9879,98,52858,2,2048,1,0,68,0,3,0,1,1024,1,0,14,0,1,0,24,11264,1,8157,3,34407,1,25906,4,2768,2,765,8,16498,1,13613198,2,397,13,41461,3,1738,1,136
```
Get file count summaries by OU; top level selector is ou, sub level selectors are ou_and_children Get file count summaries by OU; top level selector is ou, sub level selectors are ou_and_children
``` ```
gam redirect csv ./TopLevelOUs.csv print ous showparent toplevelonly parentselector ou childselector ou_and_children fields orgunitpath gam redirect csv ./TopLevelOUs.csv print ous showparent toplevelonly parentselector ou childselector ou_and_children fields orgunitpath
@@ -826,7 +906,7 @@ The `stripcrsfromname` option strips nulls, carriage returns and linefeeds from
This option is special purpose and will not generally be used. This option is special purpose and will not generally be used.
### Examples ### Examples
Show full file tree including the file id and mimetype: Show full file tree including the file id and MIME type:
``` ```
gam user testuser show filetree fields id,mimetype gam user testuser show filetree fields id,mimetype
``` ```
@@ -850,7 +930,7 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow]
[excludetrashed] [excludetrashed]
[maxfiles <Integer>] [nodataheaders <String>] [maxfiles <Integer>] [nodataheaders <String>]
[countsonly [summary none|only|plus] [summaryuser <String>] [showsource] [showsize]] [countsrowfilter] [countsonly [summary none|only|plus] [summaryuser <String>] [showsource] [showsize] [showmimetypesize]] [countsrowfilter]
[filepath|fullpath [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree] [filepath|fullpath [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[showdrivename] [showshareddrivepermissions] [showdrivename] [showshareddrivepermissions]
@@ -1022,7 +1102,7 @@ By default, all ACLs are displayed with the other file fields on a single row.
* `oneitemperrow` - Display each of a files ACls on a separate row with all of the other file fields. * `oneitemperrow` - Display each of a files ACls on a separate row with all of the other file fields.
This produces a CSV file that can be used in subsequent commands without further script processing. This produces a CSV file that can be used in subsequent commands without further script processing.
The `countsonly` option doesn't display any indididual file data, it lists the total number of files that the use can access The `countsonly` option doesn't display any indididual file data, it lists the total number of files that the user can access
and the mumber of files by MIME type. and the mumber of files by MIME type.
The `countsonly` suboption `summary none|only|plus` specifies display of a summarization of file counts across all users specified in the command. The `countsonly` suboption `summary none|only|plus` specifies display of a summarization of file counts across all users specified in the command.
@@ -1036,6 +1116,8 @@ The `countsonly` suboption `showsource` adds additional columns `Source` and `Na
The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row. The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row.
The `countsonly` suboption `showmimetypesize` adds additional columns `<MimeType>:Size` that indicate the total size (in bytes) of each MIME type.
By default, when `countsonly` is specified, GAM applies `config csv_output_row_filter` to the file details to select which files are counted. By default, when `countsonly` is specified, GAM applies `config csv_output_row_filter` to the file details to select which files are counted.
Use the `countsrowfilter` option to have GAM to apply `config csv_output_row_filter` to the file counts rather than the file details. Use the `countsrowfilter` option to have GAM to apply `config csv_output_row_filter` to the file counts rather than the file details.

View File

@@ -21,6 +21,7 @@
- [Manage User Contact Groups](#manage-user-contact-groups) - [Manage User Contact Groups](#manage-user-contact-groups)
- [Display User Contact Groups](#display-user-contact-groups) - [Display User Contact Groups](#display-user-contact-groups)
- [Display User People Profile](#display-user-people-profile) - [Display User People Profile](#display-user-people-profile)
- [Copy User Contacts to another User](#copy-user-contacts-to-another-user)
## Notes ## Notes
As of version `6.08.00`, GAM uses the People API to manage user contacts rather than the Contacts API. As of version `6.08.00`, GAM uses the People API to manage user contacts rather than the Contacts API.
@@ -651,3 +652,16 @@ 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. 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. 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. `quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Copy User Contacts to another User
To copy one user's contacts to another user perform the following steps.
```
# Copy contact groups
gam redirect csv ./ContactGroups.csv user sourceuser@domain.com print contactgroups formatjson
gam redirect stdout ./CopyContactGroups.txt multiprocess redirect stderr stdout csv ContactGroups.csv gam user targetuser@domain.com create contactgroup json "~JSON"
# Copy contacts
gam redirect csv ./Contacts.csv user sourceuser@domain.com print contacts selectmaincontacts allfields showgroups formatjson
gam redirect stdout ./CopyContacts.txt multiprocess redirect stderr stdout csv Contacts.csv gam user targetuser@domain.com create contact json "~JSON"
```

View File

@@ -2,6 +2,7 @@
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Notes](#notes) - [Notes](#notes)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Specifying task lists](#specifying-task-lists)
- [Create Tasks](#create-tasks) - [Create Tasks](#create-tasks)
- [Update Tasks](#update-tasks) - [Update Tasks](#update-tasks)
- [Delete Tasks](#delete-tasks) - [Delete Tasks](#delete-tasks)
@@ -28,11 +29,13 @@ gam user user@domain.com check serviceaccount
``` ```
<TaskID> ::= <String> <TaskID> ::= <String>
<TaskListID> ::= <String> <TaskListID> ::= <String>
<TaskListTitle> ::= tltitle:<String>
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistIDTaskID> ::= <TasklistID>/<TaskID> <TasklistIDTaskID> ::= <TasklistID>/<TaskID>
<TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*" <TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*"
<TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*" <TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*"
<TasklistIDEntity> ::= <TasklistEntity> ::=
<TasklistIDList> | <FileSelector> | <CSVFileSelector> <TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<TasklistIDTaskIDEntity> ::= <TasklistIDTaskIDEntity> ::=
<TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector> <TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector>
@@ -47,9 +50,22 @@ gam user user@domain.com check serviceaccount
<TasklistAttribute> ::= <TasklistAttribute> ::=
(title <String>) (title <String>)
``` ```
## Specifying task lists
The Tasks API requires that a task list be specified by its ID; GAM allows specification of a task list
by its title and makes an additional API call to convert the title to an ID.
Note the quoting in `<TasklistTitleList>`; the entire list should be enclosed in `"` and
each `tltitle:<String>` must be enclosed in `'` if `<String>` contains a space.
```
gam user user@domain.com create task "'tltitle:My Tasks'" title "Task title" notes "Task Notes"
gam user user@domain.com info tasklist "'tltitle:My Tasks'"
```
## Create Tasks ## Create Tasks
``` ```
gam <UserTypeEntity> create task <TasklistIDEntity> gam <UserTypeEntity> create task <TasklistEntity>
<TaskAttribute>* [parent <TaskID>] [previous <TaskID>] <TaskAttribute>* [parent <TaskID>] [previous <TaskID>]
[compact|formatjson|returnidonly] [compact|formatjson|returnidonly]
``` ```
@@ -95,7 +111,7 @@ By default, Gam displays the tasks as an indented list of keys and values; the t
### Display all tasks ### Display all tasks
``` ```
gam <UserTypeEntity> show tasks [tasklists <TasklistIDEntity>] gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
[completedmin <Time>] [completedmax <Time>] [completedmin <Time>] [completedmax <Time>]
[duemin <Time>] [duemax <Time>] [duemin <Time>] [duemax <Time>]
[updatedmin <Time>] [updatedmin <Time>]
@@ -118,7 +134,7 @@ By default, only tasks with status `needsAction` are displayed.
* `showcompleted` - Add completed tasks to the display. `showHidden` must also be True to show tasks completed in first party clients, such as the web UI and Google's mobile apps. * `showcompleted` - Add completed tasks to the display. `showHidden` must also be True to show tasks completed in first party clients, such as the web UI and Google's mobile apps.
* `showall` - Equivalent to `showdeleted` `showhidden` `showcompleted` * `showall` - Equivalent to `showdeleted` `showhidden` `showcompleted`
``` ```
gam <UserTypeEntity> print tasks [tasklists <TasklistIDEntity>] [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print tasks [tasklists <TasklistEntity>] [todrive <ToDriveAttribute>*]
[completedmin <Time>] [completedmax <Time>] [completedmin <Time>] [completedmax <Time>]
[duemin <Time>] [duemax <Time>] [duemin <Time>] [duemax <Time>]
[updatedmin <Time>] [updatedmin <Time>]
@@ -158,7 +174,7 @@ By default, Gam displays the created task list as an indented list of keys and v
## Update Task Lists ## Update Task Lists
``` ```
gam <UserTypeEntity> update tasklist <TasklistIDEntity> gam <UserTypeEntity> update tasklist <TasklistEntity>
<TasklistAttribute>* <TasklistAttribute>*
[formatjson] [formatjson]
``` ```
@@ -167,19 +183,19 @@ By default, Gam displays the updated task list as an indented list of keys and v
## Delete Task Lists ## Delete Task Lists
``` ```
gam <UserTypeEntity> delete tasklist <TasklistIDEntity> gam <UserTypeEntity> delete tasklist <TasklistEntity>
``` ```
## Clear Task Lists ## Clear Task Lists
Clears all completed tasks from the specified task lists. Clears all completed tasks from the specified task lists.
``` ```
gam <UserTypeEntity> clear tasklist <TasklistIDEntity> gam <UserTypeEntity> clear tasklist <TasklistEntity>
``` ```
## Display Task Lists ## Display Task Lists
### Display selected task lists ### Display selected task lists
``` ```
gam <UserTypeEntity> info tasklist <TasklistIDEntity> gam <UserTypeEntity> info tasklist <TasklistEntity>
[formatjson] [formatjson]
``` ```
By default, Gam displays the task lists as an indented list of keys and values. By default, Gam displays the task lists as an indented list of keys and values.

View File

@@ -4,7 +4,7 @@
Print the current version of Gam with details Print the current version of Gam with details
``` ```
gam version gam version
GAMADV-XTD3 6.64.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource GAMADV-XTD3 6.65.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com> Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.0 64-bit final Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64 MacOS Monterey 12.7 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 Print the current version of Gam with details and time offset information
``` ```
gam version timeoffset gam version timeoffset
GAMADV-XTD3 6.64.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource GAMADV-XTD3 6.65.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com> Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.0 64-bit final Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64 MacOS Monterey 12.7 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 Print the current version of Gam with extended details and SSL information
``` ```
gam version extended gam version extended
GAMADV-XTD3 6.64.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource GAMADV-XTD3 6.65.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com> Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.0 64-bit final Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64 MacOS Monterey 12.7 x86_64
@@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3 Path: /Users/Admin/bin/gamadv-xtd3
Version Check: Version Check:
Current: 5.35.08 Current: 5.35.08
Latest: 6.64.16 Latest: 6.65.01
echo $? echo $?
1 1
``` ```
@@ -73,7 +73,7 @@ echo $?
Print the current version number without details Print the current version number without details
``` ```
gam version simple gam version simple
6.64.16 6.65.01
``` ```
In Linux/MacOS you can do: In Linux/MacOS you can do:
``` ```
@@ -83,7 +83,7 @@ echo $VER
Print the current version of Gam and address of this Wiki Print the current version of Gam and address of this Wiki
``` ```
gam help gam help
GAM 6.64.16 - https://github.com/taers232c/GAMADV-XTD3 GAM 6.65.01 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com> Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.0 64-bit final Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64 MacOS Monterey 12.7 x86_64

View File

@@ -6483,7 +6483,8 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[filenamematchpattern <RegularExpression>] [filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize] [showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> show filecounts gam <UserTypeEntity> show filecounts
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) [((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
(querytime<String> <Time>)*] (querytime<String> <Time>)*]
@@ -6494,7 +6495,8 @@ gam <UserTypeEntity> show filecounts
[filenamematchpattern <RegularExpression>] [filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed] [excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize] [showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> print filesharecounts [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print filesharecounts [todrive <ToDriveAttribute>*]
[excludetrashed] [excludetrashed]
@@ -6552,7 +6554,7 @@ gam <UserTypeEntity> print filelist [todrive <ToDriveAttribute>*]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow] <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow]
[excludetrashed] [excludetrashed]
[maxfiles <Integer>] [nodataheaders <String>] [maxfiles <Integer>] [nodataheaders <String>]
[countsonly [summary none|only|plus] [summaryuser <String>] [showsource] [showsize]] [countsrowfilter] [countsonly [summary none|only|plus] [summaryuser <String>] [showsource] [showsize] [showmimetypesize]] [countsrowfilter]
[filepath|fullpath [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree] [filepath|fullpath [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[showdrivename] [showshareddrivepermissions] [showdrivename] [showshareddrivepermissions]

View File

@@ -2,6 +2,11 @@
Merged GAM-Team version Merged GAM-Team version
6.65.01
Added option `showmimetypesize` to `gam <UserTypeEntity> print|show filecounts` and
`gam <UserTypeEntity> print filelist countsonly` that displays the total file size for each MIME type.
6.65.00 6.65.00
Fixed bug in `gam <UserTypeEntity> create contact <JSONData>` that caused a trap when Fixed bug in `gam <UserTypeEntity> create contact <JSONData>` that caused a trap when

View File

@@ -8222,13 +8222,14 @@ class CSVPrintFile():
self.AddTitle(title) self.AddTitle(title)
return RowFilterMatch(row, self.titlesList, self.rowFilter, self.rowFilterMode, self.rowDropFilter, self.rowDropFilterMode) return RowFilterMatch(row, self.titlesList, self.rowFilter, self.rowFilterMode, self.rowDropFilter, self.rowDropFilterMode)
def UpdateMimeTypeCounts(self, row, mimeTypeCounts): def UpdateMimeTypeCounts(self, row, mimeTypeInfo):
for title in row: for title in row:
if title not in self.titlesSet: if title not in self.titlesSet:
self.AddTitle(title) self.AddTitle(title)
if RowFilterMatch(row, self.titlesList, self.rowFilter, self.rowFilterMode, self.rowDropFilter, self.rowDropFilterMode): if RowFilterMatch(row, self.titlesList, self.rowFilter, self.rowFilterMode, self.rowDropFilter, self.rowDropFilterMode):
mimeTypeCounts.setdefault(row['mimeType'], 0) mimeTypeInfo.setdefault(row['mimeType'], {'count': 0, 'size': 0})
mimeTypeCounts[row['mimeType']] += 1 mimeTypeInfo[row['mimeType']]['count'] += 1
mimeTypeInfo[row['mimeType']]['size'] += int(row.get('size', '0'))
def SetZeroBlankMimeTypeCounts(self, zeroBlankMimeTypeCounts): def SetZeroBlankMimeTypeCounts(self, zeroBlankMimeTypeCounts):
self.zeroBlankMimeTypeCounts = zeroBlankMimeTypeCounts self.zeroBlankMimeTypeCounts = zeroBlankMimeTypeCounts
@@ -22183,6 +22184,8 @@ def printShowUserPeopleContactGroups(users):
entityType = Ent.USER entityType = Ent.USER
entityTypeName = Ent.Singular(entityType) entityTypeName = Ent.Singular(entityType)
csvPF = CSVPrintFile([entityTypeName, 'resourceName'], 'sortall') if Act.csvFormat() else None csvPF = CSVPrintFile([entityTypeName, 'resourceName'], 'sortall') if Act.csvFormat() else None
if csvPF:
csvPF.SetEscapeChar(None)
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
fieldsList = [] fieldsList = []
parameters = _initPersonMetadataParameters() parameters = _initPersonMetadataParameters()
@@ -52225,14 +52228,13 @@ def printFileList(users):
ensure_ascii=False, sort_keys=True) ensure_ascii=False, sort_keys=True)
csvPF.WriteRowTitlesJSONNoFilter(row) csvPF.WriteRowTitlesJSONNoFilter(row)
else: else:
if showSize:
sizeTotals['User'] += int(fileInfo.get('size', '0'))
if not countsRowFilter: if not countsRowFilter:
csvPF.UpdateMimeTypeCounts(flattenJSON(fileInfo, flattened=row, skipObjects=skipObjects, timeObjects=timeObjects, csvPF.UpdateMimeTypeCounts(flattenJSON(fileInfo, flattened=row, skipObjects=skipObjects, timeObjects=timeObjects,
simpleLists=simpleLists, delimiter=delimiter), mimeTypeCounts) simpleLists=simpleLists, delimiter=delimiter), mimeTypeInfo)
else: else:
mimeTypeCounts.setdefault(fileInfo['mimeType'], 0) mimeTypeInfo.setdefault(fileInfo['mimeType'], {'count': 0, 'size': 0})
mimeTypeCounts[fileInfo['mimeType']] += 1 mimeTypeInfo[fileInfo['mimeType']['count']] += 1
mimeTypeInfo[fileInfo['mimeType']['size']] += int(fileInfo.get('size', '0'))
def _printChildDriveFolderContents(drive, fileEntry, user, i, count, depth): def _printChildDriveFolderContents(drive, fileEntry, user, i, count, depth):
parentFileEntry = fileTree.get(fileEntry['id']) parentFileEntry = fileTree.get(fileEntry['id'])
@@ -52286,11 +52288,12 @@ def printFileList(users):
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count) userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
def writeMimeTypeCountsRow(user, sourceId, sourceName, mimeTypeCounts, sizeTotal): def writeMimeTypeCountsRow(user, sourceId, sourceName, mimeTypeInfo):
total = 0 countTotal = sizeTotal = 0
for mimeTypeCount in iter(mimeTypeCounts.values()): for mtinfo in iter(mimeTypeInfo.values()):
total += mimeTypeCount countTotal += mtinfo['count']
row = {'Owner': user, 'Total': total} sizeTotal += mtinfo['size']
row = {'Owner': user, 'Total': countTotal}
if showSource: if showSource:
row['Source'] = sourceId row['Source'] = sourceId
row['Name'] = sourceName row['Name'] = sourceName
@@ -52298,20 +52301,20 @@ def printFileList(users):
row['Size'] = sizeTotal row['Size'] = sizeTotal
if addCSVData: if addCSVData:
row.update(addCSVData) row.update(addCSVData)
row.update(mimeTypeCounts) for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
row[f'{mimeType}'] = mtinfo['count']
if showMimeTypeSize:
row[f'{mimeType}:Size'] = mtinfo['size']
if not countsRowFilter: if not countsRowFilter:
csvPFco.WriteRowTitlesNoFilter(row) csvPFco.WriteRowTitlesNoFilter(row)
else: else:
csvPFco.WriteRowTitles(row) csvPFco.WriteRowTitles(row)
def incrementSizeSummary():
sizeTotals['Summary'] += sizeTotals['User']
sizeTotals['User'] = 0
csvPF = CSVPrintFile('Owner', indexedTitles=DRIVE_INDEXED_TITLES) csvPF = CSVPrintFile('Owner', indexedTitles=DRIVE_INDEXED_TITLES)
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
addPathsToJSON = countsRowFilter = buildTree = countsOnly = filepath = fullpath = getPermissionsForSharedDrives = \ addPathsToJSON = countsRowFilter = buildTree = countsOnly = filepath = fullpath = getPermissionsForSharedDrives = \
noRecursion = oneItemPerRow = showParentsIdsAsList = showDepth = showParent = showSize = showSource = stripCRsFromName = False noRecursion = oneItemPerRow = stripCRsFromName = \
showParentsIdsAsList = showDepth = showParent = showSize = showMimeTypeSize = showSource = False
pathDelimiter = '/' pathDelimiter = '/'
pmselect = True pmselect = True
showLabels = None showLabels = None
@@ -52328,7 +52331,7 @@ def printFileList(users):
DFF = DriveFileFields() DFF = DriveFileFields()
summary = FILECOUNT_SUMMARY_NONE summary = FILECOUNT_SUMMARY_NONE
summaryUser = FILECOUNT_SUMMARY_USER summaryUser = FILECOUNT_SUMMARY_USER
summaryMimeTypeCounts = {} summaryMimeTypeInfo = {}
addCSVData = {} addCSVData = {}
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -52383,16 +52386,18 @@ def printFileList(users):
if not showSize: if not showSize:
csvPFco.SetTitles(['Owner', 'Source', 'Name', 'Total']) csvPFco.SetTitles(['Owner', 'Source', 'Name', 'Total'])
else: else:
csvPFco.SetTitles(['Owner', 'Source', 'Name', 'Size', 'Total']) csvPFco.SetTitles(['Owner', 'Source', 'Name', 'Total', 'Size'])
csvPFco.SetSortAllTitles() csvPFco.SetSortAllTitles()
elif myarg == 'showsize': elif myarg in {'showsize', 'showmimetypesize'}:
showSize = True showSize = True
if countsOnly: if countsOnly:
if not showSource: if not showSource:
csvPFco.SetTitles(['Owner', 'Size', 'Total']) csvPFco.SetTitles(['Owner', 'Total', 'Size'])
else: else:
csvPFco.SetTitles(['Owner', 'Source', 'Name', 'Size', 'Total']) csvPFco.SetTitles(['Owner', 'Source', 'Name', 'Total', 'Size'])
csvPFco.SetSortAllTitles() csvPFco.SetSortAllTitles()
if myarg == 'showmimetypesize':
showMimeTypeSize = True
elif myarg == 'delimiter': elif myarg == 'delimiter':
delimiter = getCharacter() delimiter = getCharacter()
elif myarg == 'showparentsidsaslist': elif myarg == 'showparentsidsaslist':
@@ -52516,7 +52521,6 @@ def printFileList(users):
else: else:
csvPF.SetNodataFields(False, nodataFields, None, None, False) csvPF.SetNodataFields(False, nodataFields, None, None, False)
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
sizeTotals = {'User': 0, 'Summary': 0}
for user in users: for user in users:
i += 1 i += 1
origUser = user origUser = user
@@ -52550,7 +52554,7 @@ def printFileList(users):
if filepath: if filepath:
filePathInfo = initFilePathInfo(pathDelimiter) filePathInfo = initFilePathInfo(pathDelimiter)
filesPrinted = set() filesPrinted = set()
mimeTypeCounts = {} mimeTypeInfo = {}
if buildTree: if buildTree:
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query']) printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query'])
if not incrementalPrint: if not incrementalPrint:
@@ -52583,12 +52587,12 @@ def printFileList(users):
if incrementalPrint: if incrementalPrint:
if countsOnly: if countsOnly:
if summary != FILECOUNT_SUMMARY_NONE: if summary != FILECOUNT_SUMMARY_NONE:
for mimeType, mtcount in iter(mimeTypeCounts.items()): for mimeType, mtinfo in iter(mimeTypeInfo.items()):
summaryMimeTypeCounts.setdefault(mimeType, 0) summaryMimeTypeInfo.setdefault(mimeType, {'count': 0, 'size': 0})
summaryMimeTypeCounts[mimeType] += mtcount summaryMimeTypeInfo[mimeType]['count'] += mtinfo['count']
summaryMimeTypeInfo[mimeType]['size'] += mtinfo['size']
if summary != FILECOUNT_SUMMARY_ONLY: if summary != FILECOUNT_SUMMARY_ONLY:
writeMimeTypeCountsRow(user, rootFolderId, rootFolderName, mimeTypeCounts, sizeTotals['User']) writeMimeTypeCountsRow(user, rootFolderId, rootFolderName, mimeTypeInfo)
incrementSizeSummary()
continue continue
extendFileTreeParents(drive, fileTree, fields) extendFileTreeParents(drive, fileTree, fields)
DLP.GetLocationFileIdsFromTree(fileTree, fileIdEntity) DLP.GetLocationFileIdsFromTree(fileTree, fileIdEntity)
@@ -52613,7 +52617,7 @@ def printFileList(users):
for fileId in fileIdEntity['list']: for fileId in fileIdEntity['list']:
j += 1 j += 1
if showSource: if showSource:
mimeTypeCounts = {} mimeTypeInfo = {}
fileEntry = fileTree.get(fileId) fileEntry = fileTree.get(fileId)
if fileEntry: if fileEntry:
fileEntryInfo = fileEntry['info'] fileEntryInfo = fileEntry['info']
@@ -52655,21 +52659,21 @@ def printFileList(users):
if countsOnly: if countsOnly:
if showSource: if showSource:
if summary != FILECOUNT_SUMMARY_NONE: if summary != FILECOUNT_SUMMARY_NONE:
for mimeType, mtcount in iter(mimeTypeCounts.items()): for mimeType, mtinfo in iter(mimeTypeInfo.items()):
summaryMimeTypeCounts.setdefault(mimeType, 0) summaryMimeTypeInfo.setdefault(mimeType, {'count': 0, 'size': 0})
summaryMimeTypeCounts[mimeType] += mtcount summaryMimeTypeInfo[mimeType]['count'] += mtinfo['count']
summaryMimeTypeInfo[mimeType]['size'] += mtinfo['size']
if summary != FILECOUNT_SUMMARY_ONLY: if summary != FILECOUNT_SUMMARY_ONLY:
writeMimeTypeCountsRow(user, fileId, fileEntryInfo['name'], mimeTypeCounts, sizeTotals['User']) writeMimeTypeCountsRow(user, fileId, fileEntryInfo['name'], mimeTypeInfo)
incrementSizeSummary()
if countsOnly: if countsOnly:
if not showSource: if not showSource:
if summary != FILECOUNT_SUMMARY_NONE: if summary != FILECOUNT_SUMMARY_NONE:
for mimeType, mtcount in iter(mimeTypeCounts.items()): for mimeType, mtinfo in iter(mimeTypeInfo.items()):
summaryMimeTypeCounts.setdefault(mimeType, 0) summaryMimeTypeInfo.setdefault(mimeType, {'count': 0, 'size': 0})
summaryMimeTypeCounts[mimeType] += mtcount summaryMimeTypeInfo[mimeType]['count'] += mtinfo['count']
summaryMimeTypeInfo[mimeType]['size'] += mtinfo['size']
if summary != FILECOUNT_SUMMARY_ONLY: if summary != FILECOUNT_SUMMARY_ONLY:
writeMimeTypeCountsRow(user, 'Various', 'Various', mimeTypeCounts, sizeTotals['User']) writeMimeTypeCountsRow(user, 'Various', 'Various', mimeTypeInfo)
incrementSizeSummary()
if not countsOnly: if not countsOnly:
if not csvPF.rows: if not csvPF.rows:
setSysExitRC(NO_ENTITIES_FOUND_RC) setSysExitRC(NO_ENTITIES_FOUND_RC)
@@ -52686,7 +52690,7 @@ def printFileList(users):
if not csvPFco.rows: if not csvPFco.rows:
setSysExitRC(NO_ENTITIES_FOUND_RC) setSysExitRC(NO_ENTITIES_FOUND_RC)
if summary != FILECOUNT_SUMMARY_NONE: if summary != FILECOUNT_SUMMARY_NONE:
writeMimeTypeCountsRow(summaryUser, 'Various', 'Various', summaryMimeTypeCounts, sizeTotals['Summary']) writeMimeTypeCountsRow(summaryUser, 'Various', 'Various', summaryMimeTypeInfo)
csvPFco.todrive = csvPF.todrive csvPFco.todrive = csvPF.todrive
if not countsRowFilter: if not countsRowFilter:
csvPFco.SetRowFilter([], GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE]) csvPFco.SetRowFilter([], GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE])
@@ -52842,46 +52846,48 @@ def printShowFileCounts(users):
if DLP.onlySharedDrives or getPermissionsForSharedDrives: if DLP.onlySharedDrives or getPermissionsForSharedDrives:
fieldsList.append('driveId') fieldsList.append('driveId')
def incrementSizeSummary(): def showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, i, count):
sizeTotals['Summary'] += sizeTotals['User']
sizeTotals['User'] = 0
def showMimeTypeCounts(user, mimeTypeCounts, sizeTotal, sharedDriveId, sharedDriveName, i, count):
total = 0
for mimeTypeCount in iter(mimeTypeCounts.values()):
total += mimeTypeCount
if summary != FILECOUNT_SUMMARY_NONE: if summary != FILECOUNT_SUMMARY_NONE:
if user != summaryUser: if user != summaryUser:
for mimeType, mtcount in iter(mimeTypeCounts.items()): for mimeType, mtinfo in iter(mimeTypeInfo.items()):
summaryMimeTypeCounts.setdefault(mimeType, 0) summaryMimeTypeInfo.setdefault(mimeType, {'count': 0, 'size': 0})
summaryMimeTypeCounts[mimeType] += mtcount summaryMimeTypeInfo[mimeType]['count'] += mtinfo['count']
summaryMimeTypeInfo[mimeType]['size'] += mtinfo['size']
if summary == FILECOUNT_SUMMARY_ONLY: if summary == FILECOUNT_SUMMARY_ONLY:
return return
countTotal = sizeTotal = 0
for mtinfo in iter(mimeTypeInfo.values()):
countTotal += mtinfo['count']
sizeTotal += mtinfo['size']
if not csvPF: if not csvPF:
if sharedDriveId: if sharedDriveId:
kvList = [Ent.USER, user, Ent.SHAREDDRIVE, f'{sharedDriveName} ({sharedDriveId})'] kvList = [Ent.USER, user, Ent.SHAREDDRIVE, f'{sharedDriveName} ({sharedDriveId})']
else: else:
kvList = [Ent.USER, user] kvList = [Ent.USER, user]
dataList = [Ent.Choose(Ent.DRIVE_FILE_OR_FOLDER, countTotal), countTotal]
if showSize: if showSize:
dataList = [Ent.Singular(Ent.SIZE), sizeTotal] dataList.extend([Ent.Singular(Ent.SIZE), sizeTotal])
else:
dataList = []
dataList.extend([Ent.Choose(Ent.DRIVE_FILE_OR_FOLDER, total), total])
if sharedDriveId: if sharedDriveId:
dataList.extend(['Item cap', f"{total/SHARED_DRIVE_MAX_FILES_FOLDERS:.2%}"]) dataList.extend(['Item cap', f"{countTotal/SHARED_DRIVE_MAX_FILES_FOLDERS:.2%}"])
printEntityKVList(kvList, dataList, i, count) printEntityKVList(kvList, dataList, i, count)
Ind.Increment() Ind.Increment()
for mimeType, mimeTypeCount in sorted(iter(mimeTypeCounts.items())): for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
printKeyValueList([mimeType, mimeTypeCount]) if not showMimeTypeSize:
printKeyValueList([mimeType, mtinfo['count']])
else:
printKeyValueList([mimeType, f"{mtinfo['count']}, {mtinfo['size']}"])
Ind.Decrement() Ind.Decrement()
else: else:
if sharedDriveId: if sharedDriveId:
row = {'User': user, 'id': sharedDriveId, 'name': sharedDriveName, 'Total': total, 'Item cap': f"{total/SHARED_DRIVE_MAX_FILES_FOLDERS:.2%}"} row = {'User': user, 'id': sharedDriveId, 'name': sharedDriveName, 'Total': sizeTotal, 'Item cap': f"{sizeTotal/SHARED_DRIVE_MAX_FILES_FOLDERS:.2%}"}
else: else:
row = {'User': user, 'Total': total} row = {'User': user, 'Total': countTotal}
if showSize: if showSize:
row['Size'] = sizeTotal row['Size'] = sizeTotal
row.update(mimeTypeCounts) for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
row[f'{mimeType}'] = mtinfo['count']
if showMimeTypeSize:
row[f'{mimeType}:Size'] = mtinfo['size']
csvPF.WriteRowTitles(row) csvPF.WriteRowTitles(row)
csvPF = CSVPrintFile() if Act.csvFormat() else None csvPF = CSVPrintFile() if Act.csvFormat() else None
@@ -52890,10 +52896,10 @@ def printShowFileCounts(users):
fieldsList = ['mimeType'] fieldsList = ['mimeType']
DLP = DriveListParameters({'allowChoose': False, 'allowCorpora': True, 'allowQuery': True, 'mimeTypeInQuery': True}) DLP = DriveListParameters({'allowChoose': False, 'allowCorpora': True, 'allowQuery': True, 'mimeTypeInQuery': True})
sharedDriveId = sharedDriveName = '' sharedDriveId = sharedDriveName = ''
showSize = False showSize = showMimeTypeSize = False
summary = FILECOUNT_SUMMARY_NONE summary = FILECOUNT_SUMMARY_NONE
summaryUser = FILECOUNT_SUMMARY_USER summaryUser = FILECOUNT_SUMMARY_USER
summaryMimeTypeCounts = {} summaryMimeTypeInfo = {}
fileIdEntity = {} fileIdEntity = {}
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -52907,6 +52913,8 @@ def printShowFileCounts(users):
fileIdEntity = getSharedDriveEntity() fileIdEntity = getSharedDriveEntity()
elif myarg == 'showsize': elif myarg == 'showsize':
showSize = True showSize = True
elif myarg == 'showmimetypesize':
showMimeTypeSize = showSize = True
elif myarg == 'summary': elif myarg == 'summary':
summary = getChoice(FILECOUNT_SUMMARY_CHOICE_MAP, mapChoice=True) summary = getChoice(FILECOUNT_SUMMARY_CHOICE_MAP, mapChoice=True)
elif myarg == 'summaryuser': elif myarg == 'summaryuser':
@@ -52930,12 +52938,11 @@ def printShowFileCounts(users):
if csvPF: if csvPF:
sortTitles = ['User', 'id', 'name', 'Total', 'Item cap'] if fileIdEntity.get('shareddrive') else ['User', 'Total'] sortTitles = ['User', 'id', 'name', 'Total', 'Item cap'] if fileIdEntity.get('shareddrive') else ['User', 'Total']
if showSize: if showSize:
sortTitles.insert(-2, 'Size') sortTitles.insert(sortTitles.index('Total')+1, 'Size')
csvPF.SetTitles(sortTitles) csvPF.SetTitles(sortTitles)
csvPF.SetSortAllTitles() csvPF.SetSortAllTitles()
pagesFields = getItemFieldsFromFieldsList('files', fieldsList) pagesFields = getItemFieldsFromFieldsList('files', fieldsList)
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
sizeTotals = {'User': 0, 'Summary': 0}
for user in users: for user in users:
i += 1 i += 1
user, drive = _validateUserSharedDrive(user, i, count, fileIdEntity) user, drive = _validateUserSharedDrive(user, i, count, fileIdEntity)
@@ -52946,7 +52953,7 @@ def printShowFileCounts(users):
sharedDriveName = _getSharedDriveNameFromId(drive, sharedDriveId) sharedDriveName = _getSharedDriveNameFromId(drive, sharedDriveId)
else: else:
sharedDriveName = '' sharedDriveName = ''
mimeTypeCounts = {} mimeTypeInfo = {}
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query']) printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query'])
try: try:
feed = yieldGAPIpages(drive.files(), 'list', 'files', feed = yieldGAPIpages(drive.files(), 'list', 'files',
@@ -52984,12 +52991,11 @@ def printShowFileCounts(users):
GAPI.unknownError, GAPI.invalid, GAPI.badRequest, GAPI.unknownError, GAPI.invalid, GAPI.badRequest,
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy): GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy):
continue continue
mimeTypeCounts.setdefault(f_file['mimeType'], 0) fileSize = int(f_file.get('size', '0'))
mimeTypeCounts[f_file['mimeType']] += 1 mimeTypeInfo.setdefault(f_file['mimeType'], {'count': 0, 'size': 0})
if showSize: mimeTypeInfo[f_file['mimeType']]['count'] += 1
sizeTotals['User'] += int(f_file.get('size', '0')) mimeTypeInfo[f_file['mimeType']]['size'] += fileSize
showMimeTypeCounts(user, mimeTypeCounts, sizeTotals['User'], sharedDriveId, sharedDriveName, i, count) showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, i, count)
incrementSizeSummary()
except (GAPI.invalidQuery, GAPI.invalid, GAPI.badRequest): except (GAPI.invalidQuery, GAPI.invalid, GAPI.badRequest):
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], invalidQuery(DLP.fileIdEntity['query']), i, count) entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], invalidQuery(DLP.fileIdEntity['query']), i, count)
break break
@@ -53001,8 +53007,8 @@ def printShowFileCounts(users):
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count) userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
continue continue
if summary != FILECOUNT_SUMMARY_NONE: if summary != FILECOUNT_SUMMARY_NONE:
showMimeTypeCounts(summaryUser, summaryMimeTypeCounts, sizeTotals['Summary'], showMimeTypeInfo(summaryUser, summaryMimeTypeInfo,
'' if count > 1 else sharedDriveId, '' if count > 1 else sharedDriveName, 0, 0) '' if count > 1 else sharedDriveId, '' if count > 1 else sharedDriveName, 0, 0)
if csvPF: if csvPF:
csvPF.writeCSVfile('Drive File Counts') csvPF.writeCSVfile('Drive File Counts')
@@ -69572,7 +69578,7 @@ def importTasklist(users):
cleanTasklist['items'].append(cleanTask.copy()) cleanTasklist['items'].append(cleanTask.copy())
cleanData['items'].append(cleanTasklist.copy()) cleanData['items'].append(cleanTasklist.copy())
if not cleanData['items']: if not cleanData['items']:
print('No tasks to import') writeStdout('No tasks to import\n')
return return
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users: