Update and fix

Fixed bug in `gam <UserTypeEntity> print diskusage` that caused a trap.

Added a command the print the parent tree of file/folder.
This commit is contained in:
Ross Scroggs
2023-12-06 14:18:33 -08:00
parent d639e8e728
commit 59dd01f1e8
9 changed files with 161 additions and 20 deletions

View File

@@ -10,6 +10,19 @@ 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.66.07
Fixed bug in `gam <UserTypeEntity> print diskusage` that caused a trap.
### 6.66.06
Added a command the print the parent tree of file/folder.
```
gam <UserTypeEntity> print fileparenttree <DriveFileEntity> [todrive <ToDriveAttribute>*]
[stripcrsfromname]
```
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Files-Display#display-file-parent-tree
### 6.66.05
Added column `space.name` to `gam <UserTypeEntity> print chatmembers`.

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.66.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.66.07 - 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.66.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.66.07 - 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

@@ -24,6 +24,7 @@
- [Display file share counts](#display-file-share-counts)
- [Display file tree](#display-file-tree)
- [File selection starting point for Display file tree](#file-selection-starting-point-for-display-file-tree)
- [Display file parent tree](#display-file-parent-tree)
- [Display file list](#display-file-list)
- [File selection by name and entity shortcuts for Display file list](#file-selection-by-name-and-entity-shortcuts-for-display-file-list)
- [File selection starting point for Display file list](#file-selection-starting-point-for-display-file-list)
@@ -946,6 +947,40 @@ Show file tree starting at the folder named "Middle Folder" and 2 levels deeper
```
gam user testuser show filetree select drivefilename "Middle Folder" depth 2
```
## Display file parent tree
Print the parent tree of file/folder.
```
gam <UserTypeEntity> print fileparenttree <DriveFileEntity> [todrive <ToDriveAttribute>*]
[stripcrsfromname]
```
### Examples
```
# My Drive file
$ gam user user@domain.com print fileparenttree 1tDGtnaBXc1qx_9NjBSZOUUNZ7FoRc2u6
User: user@domain.com, Print 1 File Parent Tree
Owner,id,name,parentId,depth,isRoot
user@domain.com,1tDGtnaBXc1qx_9NjBSZOUUNZ7FoRc2u6,Bottom Folder,1HvAJtmQ2KZrKJhzY8aeZVScHhZ3HBJLp,4,False
user@domain.com,1HvAJtmQ2KZrKJhzY8aeZVScHhZ3HBJLp,Middle Folder,1CVqOJJLNQtxX4QEPdpDfbkjiq1oUsxne,3,False
user@domain.com,1CVqOJJLNQtxX4QEPdpDfbkjiq1oUsxne,TopCopy,0AHYenC8f12ALUk9PVA,2,False
user@domain.com,0AHYenC8f12ALUk9PVA,My Drive,,1,True
# Shared Drive file
$ gam user user@domain.com print fileparenttree 1kAHa7Q801KXRF1DfoofNlW05UWDzddhVP_u_L2xGfFQ
User: user@domain.com, Print 1 File Parent Tree
Owner,id,name,parentId,depth,isRoot
user@domain.com,1kAHa7Q801KXRF1DfoofNlW05UWDzddhVP_u_L2xGfFQ,Middle Doc,1DShPJ6iG1TnNsgiBn-Oy1OVE2BahYlPr,4,False
user@domain.com,1DShPJ6iG1TnNsgiBn-Oy1OVE2BahYlPr,Middle Folder,1s3g64uWfuQrpXRPf82B-bWCB5VuyrOmQ,3,False
user@domain.com,1s3g64uWfuQrpXRPf82B-bWCB5VuyrOmQ,Top Folder,0AL5LiIe4dqxZUk9PVA,2,False
user@domain.com,0AL5LiIe4dqxZUk9PVA,TS Shared Drive 1,,1,True
# Shared with Me file
$ gam user user@domain.com print fileparenttree 1S2D97pyG1vAil4hgNnGGLD2ldCwTOzXUM9D7XbeUv0s
User: user@domain.com, Print 1 File Parent Tree
Owner,id,name,parentId,depth,isRoot
user@domain.com,1S2D97pyG1vAil4hgNnGGLD2ldCwTOzXUM9D7XbeUv0s,GooGoo,0B0NlVEBUkz-hfjVudlF4VHlYYWlmOEdCUUxDaHdLdXhJTF84YWQwbmpRWmZ3Qm0wZnpHSGs,2,False
user@domain.com,0B0NlVEBUkz-hfjVudlF4VHlYYWlmOEdCUUxDaHdLdXhJTF84YWQwbmpRWmZ3Qm0wZnpHSGs,FooBar,,1,False
```
## Display file list
Display a list of file/folder details in CSV format.
```

View File

@@ -1,10 +1,10 @@
\
# Version and Help
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.66.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.66.07 - 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.66.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.66.07 - 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.66.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.66.07 - 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.66.05
Latest: 6.66.07
echo $?
1
```
@@ -73,7 +73,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.66.05
6.66.07
```
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.66.05 - https://github.com/taers232c/GAMADV-XTD3
GAM 6.66.07 - 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

View File

@@ -6608,6 +6608,9 @@ gam <UserTypeEntity> show filetree
(orderby <DriveFileOrderByFieldName> [ascending|descending])* [delimiter <Character>]
[stripcrsfromname]
gam <UserTypeEntity> print fileparenttree <DriveFileEntity> [todrive <ToDriveAttribute>*]
[stripcrsfromname]
gam <UserTypeEntity> print filelist [todrive <ToDriveAttribute>*]
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
(querytime<String> <Time>)*]

View File

@@ -2,6 +2,19 @@
Merged GAM-Team version
6.66.07
Fixed bug in `gam <UserTypeEntity> print diskusage` that caused a trap.
6.66.06
Added a command the print the parent tree of file/folder.
```
gam <UserTypeEntity> print fileparenttree <DriveFileEntity> [todrive <ToDriveAttribute>*]
[stripcrsfromname]
```
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Files-Display#display-file-parent-tree
6.66.05
Added column `space.name` to `gam <UserTypeEntity> print chatmembers`.

View File

@@ -25170,7 +25170,7 @@ def createChatMember(users):
try:
member = callGAPI(chat.spaces().members(), 'create',
bailOnInternalError=True,
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
parent=parent, body=body)
if role != 'ROLE_MEMBER':
member = callGAPI(chat.spaces().members(), 'patch',
@@ -25187,7 +25187,7 @@ def createChatMember(users):
Ind.Decrement()
else:
writeStdout(f'{member["name"]}\n')
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
except (GAPI.alreadyExists, GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
entityActionFailedWarning(kvList, str(e))
Ind.Decrement()
@@ -25235,13 +25235,13 @@ def createChatMember(users):
i, count, users = getEntityArgument(users)
for user in users:
i += 1
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count, [Ent.CHAT_SPACE, parent, Ent.CHAT_MEMBER, ''])
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count, [Ent.CHAT_SPACE, parent])
if not chat:
continue
if userMembers:
addMembers(userMembers, 'member', Ent.USER, i, count)
addMembers(userMembers, 'member', Ent.CHAT_MEMBER_USER, i, count)
if groupMembers:
addMembers(groupMembers, 'groupMember', Ent.GROUP, i, count)
addMembers(groupMembers, 'groupMember', Ent.CHAT_MEMBER_GROUP, i, count)
def _deleteChatMembers(chat, kvList, jcount, memberNames, i, count):
j = 0
@@ -25383,7 +25383,7 @@ def syncChatMembers(users):
try:
callGAPI(chat.spaces().members(), 'create',
bailOnInternalError=True,
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
parent=parent, body=body)
if role != 'ROLE_MEMBER':
callGAPI(chat.spaces().members(), 'patch',
@@ -25391,7 +25391,7 @@ def syncChatMembers(users):
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
name=memberName, updateMask='role', body={'role': role})
entityActionPerformed(kvList, j, jcount)
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
except (GAPI.alreadyExists, GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
entityActionFailedWarning(kvList, str(e), j, jcount)
Ind.Decrement()
del kvList[-2:]
@@ -25491,15 +25491,15 @@ def syncChatMembers(users):
if syncOperation != 'addonly':
Act.Set([Act.REMOVE, Act.REMOVE_PREVIEW][preview])
if usersSpecified:
deleteMembers(currentUsersSet-syncUsersSet, Ent.USER, i, count)
deleteMembers(currentUsersSet-syncUsersSet, Ent.CHAT_MEMBER_USER, i, count)
if groupsSpecified:
deleteMembers(currentGroupsSet-syncGroupsSet, Ent.GROUP, i, count)
deleteMembers(currentGroupsSet-syncGroupsSet, Ent.CHAT_MEMBER_GROUP, i, count)
if syncOperation != 'removeonly':
Act.Set([Act.ADD, Act.ADD_PREVIEW][preview])
if usersSpecified:
addMembers(syncUsersSet-currentUsersSet, userMembers, Ent.USER, i, count)
addMembers(syncUsersSet-currentUsersSet, userMembers, Ent.CHAT_MEMBER_USER, i, count)
if groupsSpecified:
addMembers(syncGroupsSet-currentGroupsSet, groupMembers, Ent.GROUP, i, count)
addMembers(syncGroupsSet-currentGroupsSet, groupMembers, Ent.CHAT_MEMBER_GROUP, i, count)
if csvPF:
csvPF.writeCSVfile('Chat Member Updates')
@@ -53340,6 +53340,73 @@ def printShowFilePaths(users):
if csvPF:
csvPF.writeCSVfile('Drive File Paths')
# gam <UserTypeEntity> print fileparenttree <DriveFileEntity> [todrive <ToDriveAttribute>*]
# [stripcrsfromname]
def printFileParentTree(users):
fileNameTitle = 'title' if not GC.Values[GC.DRIVE_V3_NATIVE_NAMES] else 'name'
csvPF = CSVPrintFile(['Owner', 'id', fileNameTitle, 'parentId', 'depth', 'isRoot'], 'sortall')
fileIdEntity = getDriveFileEntity()
stripCRsFromName = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
csvPF.GetTodriveParameters()
elif myarg == 'stripcrsfromname':
stripCRsFromName = True
else:
unknownArgumentExit()
i, count, users = getEntityArgument(users)
for user in users:
i += 1
user, drive, jcount = _validateUserGetFileIDs(user, i, count, fileIdEntity, entityType=Ent.FILE_PARENT_TREE)
if jcount == 0:
continue
try:
rootId = callGAPI(drive.files(), 'get',
throwReasons=GAPI.DRIVE_USER_THROW_REASONS,
fileId=ROOT, fields='id')['id']
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
continue
j = 0
for fileId in fileIdEntity['list']:
j += 1
fileList = []
while True:
try:
result = callGAPI(drive.files(), 'get',
throwReasons=GAPI.DRIVE_GET_THROW_REASONS,
fileId=fileId, fields='id,name,mimeType,parents,driveId', supportsAllDrives=True)
if stripCRsFromName:
result['name'] = _stripControlCharsFromName(result['name'])
result['isRoot'] = False
if not result.get('parents', []):
if fileId == rootId:
result['isRoot'] = True
else:
driveId = result.get('driveId')
if driveId:
if result['mimeType'] == MIMETYPE_GA_FOLDER and result['name'] == TEAM_DRIVE:
result['name'] = _getSharedDriveNameFromId(drive, driveId)
result['isRoot'] = True
result['parents'] = ['']
fileList.append(result)
break
fileList.append(result)
fileId = result['parents'][0]
except GAPI.fileNotFound:
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER_ID, fileId], Msg.DOES_NOT_EXIST, j, jcount)
break
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
break
kcount = len(fileList)
for result in fileList:
csvPF.WriteRow({'Owner': user, 'id': result['id'], fileNameTitle: result['name'], 'parentId': result['parents'][0],
'depth': kcount, 'isRoot': result['isRoot']})
kcount -= 1
csvPF.writeCSVfile('Drive File Parent Tree')
# gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
# [((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) (querytime<String> <Time>)*]
# [corpora <CorporaAttribute>]
@@ -53592,6 +53659,7 @@ def printDiskUsage(users):
if stripCRsFromName:
childEntryInfo['name'] = _stripControlCharsFromName(childEntryInfo['name'])
childEntryInfo['path'] = fileEntry['path']+pathDelimiter+childEntryInfo['name']
childEntryInfo.pop(sizeField, None)
foldersList.append(childEntryInfo)
_getChildDriveFolderInfo(drive, childEntryInfo, user, i, count)
fileEntry['totalFileCount'] += childEntryInfo['totalFileCount']
@@ -53714,6 +53782,7 @@ def printDiskUsage(users):
topFolder.pop('ownedByMe', None)
topFolder.pop('parents', None)
topFolder.update(zeroFolderInfo)
topFolder.pop(sizeField, None)
foldersList.append(topFolder)
_getChildDriveFolderInfo(drive, topFolder, user, i, count)
except GAPI.fileNotFound:
@@ -71852,6 +71921,7 @@ USER_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_NOTE: printShowNotes,
Cmd.ARG_OTHERCONTACT: printShowUserPeopleOtherContacts,
Cmd.ARG_OUTOFOFFICE: printShowOutOfOffice,
Cmd.ARG_FILEPARENTTREE: printFileParentTree,
Cmd.ARG_PEOPLECONTACT: printShowUserPeopleContacts,
Cmd.ARG_PEOPLECONTACTGROUP: printShowUserPeopleContactGroups,
Cmd.ARG_PEOPLEPROFILE: printShowUserPeopleProfiles,

View File

@@ -577,6 +577,7 @@ class GamCLArgs():
ARG_FILEDRIVELABELS = 'filedrivelabels'
ARG_FILEINFO = 'fileinfo'
ARG_FILELIST = 'filelist'
ARG_FILEPARENTTREE = 'fileparenttree'
ARG_FILEPATH = 'filepath'
ARG_FILEPATHS = 'filepaths'
ARG_FILEREVISION = 'filerevision'

View File

@@ -85,6 +85,8 @@ class GamEntity():
CHANNEL_SKU = 'chsk'
CHAT_BOT = 'chbo'
CHAT_MEMBER = 'chme'
CHAT_MEMBER_GROUP = 'chmg'
CHAT_MEMBER_USER = 'chmu'
CHAT_MESSAGE = 'chms'
CHAT_MESSAGE_ID = 'chmi'
CHAT_SPACE = 'chsp'
@@ -207,6 +209,7 @@ class GamEntity():
FEATURE = 'feat'
FIELD = 'fiel'
FILE = 'file'
FILE_PARENT_TREE = 'fptr'
FILTER = 'filt'
FORM = 'form'
FORM_RESPONSE = 'frmr'
@@ -416,6 +419,8 @@ class GamEntity():
CHAT_MESSAGE: ['Chat Messages', 'Chat Message'],
CHAT_MESSAGE_ID: ['Chat Message IDs', 'Chat Message ID'],
CHAT_MEMBER: ['Chat Members', 'Chat Member'],
CHAT_MEMBER_GROUP: ['Chat Group Members', 'Chat Group Member'],
CHAT_MEMBER_USER: ['Chat User Members', 'Chat User Member'],
CHAT_SPACE: ['Chat Spaces', 'Chat Space'],
CHAT_THREAD: ['Chat Threads', 'Chat Thread'],
CHROME_APP: ['Chrome Applications', 'Chrome Application'],
@@ -536,6 +541,7 @@ class GamEntity():
FEATURE: ['Features', 'Feature'],
FIELD: ['Fields', 'Field'],
FILE: ['Files', 'File'],
FILE_PARENT_TREE: ['File Parent Trees', 'File Parent Tree'],
FILTER: ['Filters', 'Filter'],
FORM: ['Forms', 'Form'],
FORM_RESPONSE: ['Form Responses', 'Form Response'],