Added option parentpathonly [<Boolean>]

This commit is contained in:
Ross Scroggs
2026-05-04 09:50:25 -07:00
parent b0b572a5b2
commit 760963889d
3 changed files with 45 additions and 27 deletions

View File

@@ -7032,7 +7032,7 @@ gam <UserTypeEntity> untrash drivefile <DriveFileEntity> [shortcutandtarget [<Bo
gam <UserTypeEntity> info drivefile <DriveFileEntity> gam <UserTypeEntity> info drivefile <DriveFileEntity>
[returnidonly] [returnidonly]
[filepath|fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [filepath|fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[includepermissionsforview published] [includepermissionsforview published]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
@@ -7513,7 +7513,7 @@ gam <UserTypeEntity> collect orphans
gam <UserTypeEntity> show fileinfo <DriveFileEntity> gam <UserTypeEntity> show fileinfo <DriveFileEntity>
[returnidonly] [returnidonly]
[filepath|fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [filepath|fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[includepermissionsforview published] [includepermissionsforview published]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
@@ -7527,12 +7527,12 @@ gam <UserTypeEntity> show filepath <DriveFileEntity>
[returnpathonly] [returnpathonly]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
[stripcrsfromname] [stripcrsfromname]
[fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
[followshortcuts [<Boolean>]] [followshortcuts [<Boolean>]]
gam <UserTypeEntity> print filepath <DriveFileEntity> [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print filepath <DriveFileEntity> [todrive <ToDriveAttribute>*]
(orderby <DriveFileOrderByFieldName> [ascending|descending])* (orderby <DriveFileOrderByFieldName> [ascending|descending])*
[stripcrsfromname] [oneitemperrow] [stripcrsfromname] [oneitemperrow]
[fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
[followshortcuts [<Boolean>]] [followshortcuts [<Boolean>]]
gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
@@ -7635,7 +7635,7 @@ gam <UserTypeEntity> print filelist [todrive <ToDriveAttribute>*]
[countsonly [summary none|only|plus] [summaryuser <String>] [countsonly [summary none|only|plus] [summaryuser <String>]
[showsource] [showsize] [showsizeunits] [showmimetypesize]] [showsource] [showsize] [showsizeunits] [showmimetypesize]]
[countsrowfilter] [countsrowfilter]
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree] [filepath|fullpath [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[showdrivename] [showshareddrivepermissions] [showdrivename] [showshareddrivepermissions]
[(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)] [(showlabels details|ids)|(includelabels <ClassificationLabelIDList>)]

View File

@@ -1,3 +1,14 @@
7.43.03
Added option `parentpathonly [<Boolean>]` to the following commands that causes GAM
to display only the parent folder names when displaying the path to a file.
```
gam <UserTypeEntity> info drivefile ... filepath|fullpath
gam <UserTypeEntity> show fileinfo ... filepath|fullpath
gam <UserTypeEntity> print|show filepath
gam <UserTypeEntity> print filelist ... filepath|fullpath
```
7.43.02 7.43.02
Added option `maxactivities <Number>` to `gam <UserTypeEntity> print driveactivity` to limit Added option `maxactivities <Number>` to `gam <UserTypeEntity> print driveactivity` to limit

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
""" """
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>' __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.43.02' __version__ = '7.43.03'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position # pylint: disable=wrong-import-position
@@ -57541,7 +57541,7 @@ def initFilePathInfo(delimiter):
return {'ids': {}, 'allPaths': {}, 'localPaths': None, 'delimiter': delimiter} return {'ids': {}, 'allPaths': {}, 'localPaths': None, 'delimiter': delimiter}
def getFilePaths(drive, fileTree, initialResult, filePathInfo, addParentsToTree=False, def getFilePaths(drive, fileTree, initialResult, filePathInfo, addParentsToTree=False,
fullpath=False, showDepth=False, folderPathOnly=False): fullpath=False, showDepth=False, folderPathOnly=False, parentPathOnly=False):
def _getParentName(result): def _getParentName(result):
if (result['mimeType'] == MIMETYPE_GA_FOLDER) and result.get('driveId') and (result['name'] == TEAM_DRIVE): if (result['mimeType'] == MIMETYPE_GA_FOLDER) and result.get('driveId') and (result['name'] == TEAM_DRIVE):
parentName = _getSharedDriveNameFromId(drive, result['driveId']) parentName = _getSharedDriveNameFromId(drive, result['driveId'])
@@ -57595,8 +57595,9 @@ def getFilePaths(drive, fileTree, initialResult, filePathInfo, addParentsToTree=
if depth > maxDepth: if depth > maxDepth:
maxDepth = depth-1 maxDepth = depth-1
fp.reverse() fp.reverse()
if initialMimeType == MIMETYPE_GA_FOLDER or not folderPathOnly: if not parentPathOnly:
fp.append(name) if initialMimeType == MIMETYPE_GA_FOLDER or not folderPathOnly:
fp.append(name)
filePaths.append(filePathInfo['delimiter'].join(fp)) filePaths.append(filePathInfo['delimiter'].join(fp))
else: else:
maxDepth = _makeFilePaths(v, fplist, filePaths, name, maxDepth) maxDepth = _makeFilePaths(v, fplist, filePaths, name, maxDepth)
@@ -58112,7 +58113,7 @@ def _formatFileDriveLabels(showLabels, labels, result, printMode, delimiter):
# gam <UserTypeEntity> info drivefile <DriveFileEntity> # gam <UserTypeEntity> info drivefile <DriveFileEntity>
# [returnidonly] # [returnidonly]
# [filepath|fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] # [filepath|fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
# [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [formatjson] # [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [formatjson]
# (orderby <DriveFileOrderByFieldName> [ascending|descending])* # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
# [showdrivename] [showshareddrivepermissions] # [showdrivename] [showshareddrivepermissions]
@@ -58122,7 +58123,7 @@ def _formatFileDriveLabels(showLabels, labels, result, printMode, delimiter):
# [stripcrsfromname] [formatjson] # [stripcrsfromname] [formatjson]
# gam <UserTypeEntity> show fileinfo <DriveFileEntity> # gam <UserTypeEntity> show fileinfo <DriveFileEntity>
# [returnidonly] # [returnidonly]
# [filepath|fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] # [filepath|fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
# [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [formatjson] # [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] [formatjson]
# (orderby <DriveFileOrderByFieldName> [ascending|descending])* # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
# [showdrivename] [showshareddrivepermissions] # [showdrivename] [showshareddrivepermissions]
@@ -58140,7 +58141,7 @@ def showFileInfo(users):
if followShortcuts: if followShortcuts:
_setSkipObjects(skipObjects, ['mimeType', 'shortcutDetails'], DFF.fieldsList) _setSkipObjects(skipObjects, ['mimeType', 'shortcutDetails'], DFF.fieldsList)
getPermissionsForSharedDrives = filepath = fullpath = folderPathOnly = followShortcuts = \ getPermissionsForSharedDrives = filepath = fullpath = folderPathOnly = parentPathOnly = followShortcuts = \
returnIdOnly = showParentsIdsAsList = showNoParents = stripCRsFromName = False returnIdOnly = showParentsIdsAsList = showNoParents = stripCRsFromName = False
pathDelimiter = '/' pathDelimiter = '/'
showLabels = None showLabels = None
@@ -58158,6 +58159,8 @@ def showFileInfo(users):
filepath = fullpath = True filepath = fullpath = True
elif myarg == 'folderpathonly': elif myarg == 'folderpathonly':
folderPathOnly = getBoolean() folderPathOnly = getBoolean()
elif myarg == 'parentpathonly':
parentPathOnly = getBoolean()
elif myarg == 'pathdelimiter': elif myarg == 'pathdelimiter':
pathDelimiter = getCharacter() pathDelimiter = getCharacter()
elif myarg == 'showparentsidsaslist': elif myarg == 'showparentsidsaslist':
@@ -58274,7 +58277,7 @@ def showFileInfo(users):
extendFileTreeParents(drive, fileTree, pathFields) extendFileTreeParents(drive, fileTree, pathFields)
if not FJQC.formatJSON: if not FJQC.formatJSON:
_, paths, _ = getFilePaths(drive, fileTree, result, filePathInfo, addParentsToTree=True, _, paths, _ = getFilePaths(drive, fileTree, result, filePathInfo, addParentsToTree=True,
fullpath=fullpath, folderPathOnly=folderPathOnly) fullpath=fullpath, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
kcount = len(paths) kcount = len(paths)
printKeyValueList(['paths', kcount]) printKeyValueList(['paths', kcount])
Ind.Increment() Ind.Increment()
@@ -58283,7 +58286,7 @@ def showFileInfo(users):
Ind.Decrement() Ind.Decrement()
else: else:
addFilePathsToInfo(drive, fileTree, result, filePathInfo, addFilePathsToInfo(drive, fileTree, result, filePathInfo,
addParentsToTree=True, folderPathOnly=folderPathOnly) addParentsToTree=True, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
if fullpath: if fullpath:
# Save simple parents list as mappings turn it into a list of dicts # Save simple parents list as mappings turn it into a list of dicts
fpparents = result['parents'][:] fpparents = result['parents'][:]
@@ -58960,9 +58963,9 @@ def buildFileTree(feed, drive):
return fileTree return fileTree
def addFilePathsToRow(drive, fileTree, fileEntryInfo, filePathInfo, csvPF, row, def addFilePathsToRow(drive, fileTree, fileEntryInfo, filePathInfo, csvPF, row,
fullpath=False, showDepth=False, folderPathOnly=False): fullpath=False, showDepth=False, folderPathOnly=False, parentPathOnly=False):
_, paths, maxDepth = getFilePaths(drive, fileTree, fileEntryInfo, filePathInfo, _, paths, maxDepth = getFilePaths(drive, fileTree, fileEntryInfo, filePathInfo,
fullpath=fullpath, showDepth=showDepth, folderPathOnly=folderPathOnly) fullpath=fullpath, showDepth=showDepth, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
kcount = len(paths) kcount = len(paths)
if showDepth: if showDepth:
row['depth'] = maxDepth row['depth'] = maxDepth
@@ -58977,9 +58980,9 @@ def addFilePathsToRow(drive, fileTree, fileEntryInfo, filePathInfo, csvPF, row,
row[key] = path row[key] = path
k += 1 k += 1
def addFilePathsToInfo(drive, fileTree, fileEntryInfo, filePathInfo, addParentsToTree=False, folderPathOnly=False): def addFilePathsToInfo(drive, fileTree, fileEntryInfo, filePathInfo, addParentsToTree=False, folderPathOnly=False, parentPathOnly=False):
_, paths, _ = getFilePaths(drive, fileTree, fileEntryInfo, filePathInfo, addParentsToTree=addParentsToTree, _, paths, _ = getFilePaths(drive, fileTree, fileEntryInfo, filePathInfo, addParentsToTree=addParentsToTree,
showDepth=False, folderPathOnly=folderPathOnly) showDepth=False, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
fileEntryInfo['paths'] = [] fileEntryInfo['paths'] = []
for path in sorted(paths): for path in sorted(paths):
if GC.Values[GC.CSV_OUTPUT_CONVERT_CR_NL] and (path.find('\n') >= 0 or path.find('\r') >= 0): if GC.Values[GC.CSV_OUTPUT_CONVERT_CR_NL] and (path.find('\n') >= 0 or path.find('\r') >= 0):
@@ -59572,7 +59575,7 @@ SIZE_FIELD_CHOICE_MAP = {
# [countsonly [summary none|only|plus] [summaryuser <String>] # [countsonly [summary none|only|plus] [summaryuser <String>]
# [showsource] [showsize] [showsizeunits] [showmimetypesize]] # [showsource] [showsize] [showsizeunits] [showmimetypesize]]
# [countsrowfilter] # [countsrowfilter]
# [filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree] # [filepath|fullpath [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
# [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)] # [allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
# [showdrivename] [showshareddrivepermissions] # [showdrivename] [showshareddrivepermissions]
# (showlabels details|ids)|(includelabels <DriveLabelIDList>)] # (showlabels details|ids)|(includelabels <DriveLabelIDList>)]
@@ -59676,9 +59679,9 @@ def printFileList(users):
if filepath: if filepath:
if not FJQC.formatJSON or not addPathsToJSON: if not FJQC.formatJSON or not addPathsToJSON:
addFilePathsToRow(drive, fileTree, fileInfo, filePathInfo, csvPF, row, addFilePathsToRow(drive, fileTree, fileInfo, filePathInfo, csvPF, row,
fullpath=fullpath, showDepth=showDepth, folderPathOnly=folderPathOnly) fullpath=fullpath, showDepth=showDepth, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
else: else:
addFilePathsToInfo(drive, fileTree, fileInfo, filePathInfo, folderPathOnly=folderPathOnly) addFilePathsToInfo(drive, fileTree, fileInfo, filePathInfo, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
_mapDriveInfo(fileInfo, DFF.parentsSubFields, showParentsIdsAsList) _mapDriveInfo(fileInfo, DFF.parentsSubFields, showParentsIdsAsList)
if showParentsIdsAsList and 'parentsIds' in fileInfo: if showParentsIdsAsList and 'parentsIds' in fileInfo:
fileInfo['parents'] = len(fileInfo['parentsIds']) fileInfo['parents'] = len(fileInfo['parentsIds'])
@@ -59812,7 +59815,7 @@ def printFileList(users):
csvPF = CSVPrintFile('Owner', indexedTitles=DRIVE_INDEXED_TITLES) csvPF = CSVPrintFile('Owner', indexedTitles=DRIVE_INDEXED_TITLES)
csvPFco = None csvPFco = None
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
addPathsToJSON = continueOnInvalidQuery = countsRowFilter = buildTree = countsOnly = filepath = fullpath = folderPathOnly = \ addPathsToJSON = continueOnInvalidQuery = countsRowFilter = buildTree = countsOnly = filepath = fullpath = folderPathOnly = parentPathOnly = \
getPermissionDetailsForMyDrive = getPermissionsForSharedDrives = mimeTypeInQuery = noRecursion = oneItemPerRow = stripCRsFromName = \ getPermissionDetailsForMyDrive = getPermissionsForSharedDrives = mimeTypeInQuery = noRecursion = oneItemPerRow = stripCRsFromName = \
showParentsIdsAsList = showDepth = showParent = showSize = showSizeUnits = showMimeTypeSize = showSource = False showParentsIdsAsList = showDepth = showParent = showSize = showSizeUnits = showMimeTypeSize = showSource = False
sizeField = 'quotaBytesUsed' sizeField = 'quotaBytesUsed'
@@ -59870,6 +59873,8 @@ def printFileList(users):
fullpath = myarg == 'fullpath' fullpath = myarg == 'fullpath'
elif myarg == 'folderpathonly': elif myarg == 'folderpathonly':
folderPathOnly = getBoolean() folderPathOnly = getBoolean()
elif myarg == 'parentpathonly':
parentPathOnly = getBoolean()
elif myarg == 'pathdelimiter': elif myarg == 'pathdelimiter':
pathDelimiter = getCharacter() pathDelimiter = getCharacter()
elif myarg == 'addpathstojson': elif myarg == 'addpathstojson':
@@ -60168,7 +60173,7 @@ def printFileList(users):
break break
if fullpath: if fullpath:
getFilePaths(drive, fileTree, fileEntryInfo, filePathInfo, addParentsToTree=True, getFilePaths(drive, fileTree, fileEntryInfo, filePathInfo, addParentsToTree=True,
fullpath=fullpath, showDepth=showDepth, folderPathOnly=folderPathOnly) fullpath=fullpath, showDepth=showDepth, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
if ((showParent and (fileEntryInfo['id'] not in {ORPHANS, SHARED_WITHME, SHARED_DRIVES})) or if ((showParent and (fileEntryInfo['id'] not in {ORPHANS, SHARED_WITHME, SHARED_DRIVES})) or
fileEntryInfo['mimeType'] != MIMETYPE_GA_FOLDER or noRecursion): fileEntryInfo['mimeType'] != MIMETYPE_GA_FOLDER or noRecursion):
if fileId not in filesPrinted: if fileId not in filesPrinted:
@@ -60463,18 +60468,18 @@ def printShowFileComments(users):
# gam <UserTypeEntity> print filepaths <DriveFileEntity> [todrive <ToDriveAttribute>*] # gam <UserTypeEntity> print filepaths <DriveFileEntity> [todrive <ToDriveAttribute>*]
# (orderby <DriveFileOrderByFieldName> [ascending|descending])* # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
# [stripcrsfromname] [oneitemperrow] # [stripcrsfromname] [oneitemperrow]
# [fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] # [fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
# [followshortcuts [<Boolean>]] # [followshortcuts [<Boolean>]]
# gam <UserTypeEntity> show filepaths <DriveFileEntity> # gam <UserTypeEntity> show filepaths <DriveFileEntity>
# [returnpathonly] # [returnpathonly]
# (orderby <DriveFileOrderByFieldName> [ascending|descending])* # (orderby <DriveFileOrderByFieldName> [ascending|descending])*
# [stripcrsfromname] # [stripcrsfromname]
# [fullpath] [folderpathonly [<Boolean>]] [pathdelimiter <Character>] # [fullpath] [folderpathonly|parentpathonly [<Boolean>]] [pathdelimiter <Character>]
# [followshortcuts [<Boolean>]] # [followshortcuts [<Boolean>]]
def printShowFilePaths(users): def printShowFilePaths(users):
csvPF = CSVPrintFile(['Owner', 'id', 'name', 'paths'], 'sortall', ['paths']) if Act.csvFormat() else None csvPF = CSVPrintFile(['Owner', 'id', 'name', 'paths'], 'sortall', ['paths']) if Act.csvFormat() else None
fileIdEntity = getDriveFileEntity() fileIdEntity = getDriveFileEntity()
fullpath = folderPathOnly = followShortcuts = oneItemPerRow = returnPathOnly = stripCRsFromName = False fullpath = folderPathOnly = parentPathOnly = followShortcuts = oneItemPerRow = returnPathOnly = stripCRsFromName = False
pathDelimiter = '/' pathDelimiter = '/'
OBY = OrderBy(DRIVEFILE_ORDERBY_CHOICE_MAP) OBY = OrderBy(DRIVEFILE_ORDERBY_CHOICE_MAP)
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
@@ -60485,6 +60490,8 @@ def printShowFilePaths(users):
fullpath = True fullpath = True
elif myarg == 'folderpathonly': elif myarg == 'folderpathonly':
folderPathOnly = getBoolean() folderPathOnly = getBoolean()
elif myarg == 'parentpathonly':
parentPathOnly = getBoolean()
elif myarg == 'pathdelimiter': elif myarg == 'pathdelimiter':
pathDelimiter = getCharacter() pathDelimiter = getCharacter()
elif myarg == 'stripcrsfromname': elif myarg == 'stripcrsfromname':
@@ -60556,7 +60563,7 @@ def printShowFilePaths(users):
extendFileTree(fileTree, [result], None, False) extendFileTree(fileTree, [result], None, False)
extendFileTreeParents(drive, fileTree, pathFields) extendFileTreeParents(drive, fileTree, pathFields)
entityType, paths, _ = getFilePaths(drive, fileTree, result, filePathInfo, addParentsToTree=True, entityType, paths, _ = getFilePaths(drive, fileTree, result, filePathInfo, addParentsToTree=True,
fullpath=fullpath, folderPathOnly=folderPathOnly) fullpath=fullpath, folderPathOnly=folderPathOnly, parentPathOnly=parentPathOnly)
if returnPathOnly: if returnPathOnly:
for path in paths: for path in paths:
writeStdout(f'{path}\n') writeStdout(f'{path}\n')