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,-]*
<TaskID> ::= <String>
<TaskListID> ::= <String>
<TaskListTitle> ::= tltitle:<String>
<TasklistIDTaskID> ::= <TasklistID>/<TaskID>
<ThreadID> ::= <String>
<TimeZone> ::= <String>

View File

@@ -332,8 +332,8 @@ Data fields identified in a `csvkmd` argument.
<SiteACLScopeList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<SiteEntity> ::=
<SiteList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<TasklistIDEntity> ::=
<TasklistIDList> | <FileSelector> | <CSVFileSelector>
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
<TasklistIDTaskIDEntity> ::=
<TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector>
<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.
### 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
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$ ./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.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>
Python 3.10.8 64-bit final
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>gam version
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>
Python 3.12.0 64-bit final
Windows-10-10.0.17134 AMD64

View File

@@ -93,6 +93,7 @@
<SharedDriveIDList> ::= "<SharedDriveID>(,<SharedDriveID>)*"
<StringList> ::= "<String>(,<String>)*"
<TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*"
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*"
<ThreadIDList> ::= "<ThreadID>(,<ThreadID>)*"
<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.
9. Manage user data
* 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)
9. 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.
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>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize]
[showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> show filecounts
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
(querytime<String> <Time>)*]
@@ -628,13 +629,16 @@ gam <UserTypeEntity> show filecounts
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[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).
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)
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>`.
### 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
```
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.
### 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
```
@@ -850,7 +930,7 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow]
[excludetrashed]
[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]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[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.
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.
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 `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.
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)
- [Display User Contact Groups](#display-user-contact-groups)
- [Display User People Profile](#display-user-people-profile)
- [Copy User Contacts to another User](#copy-user-contacts-to-another-user)
## Notes
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.
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.
## 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)
- [Notes](#notes)
- [Definitions](#definitions)
- [Specifying task lists](#specifying-task-lists)
- [Create Tasks](#create-tasks)
- [Update Tasks](#update-tasks)
- [Delete Tasks](#delete-tasks)
@@ -28,11 +29,13 @@ gam user user@domain.com check serviceaccount
```
<TaskID> ::= <String>
<TaskListID> ::= <String>
<TaskListTitle> ::= tltitle:<String>
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistIDTaskID> ::= <TasklistID>/<TaskID>
<TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*"
<TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*"
<TasklistIDEntity> ::=
<TasklistIDList> | <FileSelector> | <CSVFileSelector>
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<TasklistIDTaskIDEntity> ::=
<TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector>
@@ -47,9 +50,22 @@ gam user user@domain.com check serviceaccount
<TasklistAttribute> ::=
(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
```
gam <UserTypeEntity> create task <TasklistIDEntity>
gam <UserTypeEntity> create task <TasklistEntity>
<TaskAttribute>* [parent <TaskID>] [previous <TaskID>]
[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
```
gam <UserTypeEntity> show tasks [tasklists <TasklistIDEntity>]
gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
[completedmin <Time>] [completedmax <Time>]
[duemin <Time>] [duemax <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.
* `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>]
[duemin <Time>] [duemax <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
```
gam <UserTypeEntity> update tasklist <TasklistIDEntity>
gam <UserTypeEntity> update tasklist <TasklistEntity>
<TasklistAttribute>*
[formatjson]
```
@@ -167,19 +183,19 @@ By default, Gam displays the updated task list as an indented list of keys and v
## Delete Task Lists
```
gam <UserTypeEntity> delete tasklist <TasklistIDEntity>
gam <UserTypeEntity> delete tasklist <TasklistEntity>
```
## Clear 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 selected task lists
```
gam <UserTypeEntity> info tasklist <TasklistIDEntity>
gam <UserTypeEntity> info tasklist <TasklistEntity>
[formatjson]
```
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
```
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>
Python 3.12.0 64-bit final
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
```
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>
Python 3.12.0 64-bit final
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
```
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>
Python 3.12.0 64-bit final
MacOS Monterey 12.7 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.64.16
Latest: 6.65.01
echo $?
1
```
@@ -73,7 +73,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.64.16
6.65.01
```
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.64.16 - https://github.com/taers232c/GAMADV-XTD3
GAM 6.65.01 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64