Skip to content

Instantly share code, notes, and snippets.

@matt17r
Last active February 5, 2021 07:53
Show Gist options
  • Save matt17r/6b3095c9f7bc450d83b72c1d29c2dee4 to your computer and use it in GitHub Desktop.
Save matt17r/6b3095c9f7bc450d83b72c1d29c2dee4 to your computer and use it in GitHub Desktop.
Generate a tree view of Google Shared Drives in Markdown format
/**
* Generate trees for all (if less than 100) Shared Drives in the domain (requires domain admin permissions)
*/
function generateSharedDriveTrees() {
// Get (first 100) Shared Drives for domain
const drives = Drive.Drives.list({useDomainAdminAccess: true, maxResults: 100}).items;
drives.forEach(drive => generateSharedDriveTree(drive));
}
/**
* Lists Shared Drive name, URL and file count then generates tree for all children (if permissions allow)
* @param {Drives} drive The [drives Resource](https://developers.google.com/drive/api/v3/reference/drives#resource) to iterate
*/
function generateSharedDriveTree(drive) {
try {
var result = [];
const query = "trashed = false and '" + drive.id + "' in parents and mimeType != 'application/vnd.google-apps.folder'";
const filesInFolder = Drive.Files.list({q: query, includeItemsFromAllDrives: true, supportsAllDrives: true});
result.push("# [" + drive.name + "](https://drive.google.com/drive/folders/" + drive.id + ")" + "\n");
if (filesInFolder.items.length > 0) {
result.push("Number of files in root of Shared drive: " + filesInFolder.items.length + "\n");
} else {
result.push("*If this file is empty you may not have permission to view the contents of this Shared Drive*\n")
}
getChildFolders(result, drive.id); // use getChildFolders(result, drive.id, 1, 5) to override maxDepth to 5
outputFile = DriveApp.createFile('Map of ' + drive.name + '.md', result.join("\n"));
DriveApp.addFile(outputFile);
} catch (e) {
Logger.log(e.toString());
}
}
/**
* Recursively lists folder names, URLs and file counts
* @param {array} result Result array to populate
* @param {string} parent Parent folder ID
* @param {number} currentDepth Current depth of tree, defaults to 1, must be between 1 and maxDepth inclusive
* @param {number} maxDepth Maximum depth of tree, defaults to 3, must be between 1 and 10
*/
function getChildFolders(result, parent, currentDepth = 1, maxDepth = 3) {
if (currentDepth > maxDepth || currentDepth < 1 || maxDepth < 1 || maxDepth > 10) {
return result;
}
const folderQuery = "trashed = false and '" + parent + "' in parents and mimeType = 'application/vnd.google-apps.folder'";
const childFolders = Drive.Files.list({q: folderQuery, includeItemsFromAllDrives: true, supportsAllDrives: true}).items;
for (const childFolder of childFolders) {
const fileQuery = "trashed = false and '" + childFolder.getId() + "' in parents and mimeType != 'application/vnd.google-apps.folder'";
const filesInFolder = Drive.Files.list({q: fileQuery, includeItemsFromAllDrives: true, supportsAllDrives: true});
const countString = filesInFolder.items.length > 0 ? " (" + filesInFolder.items.length + " files)" : ""
result.push("\t".repeat(currentDepth - 1) + "- [" + childFolder.title + "](" + childFolder.alternateLink + ")" + countString);
// Recursive call for any sub-folders (unless we've already reached maxDepth)
if (currentDepth < maxDepth) {
getChildFolders(result, childFolder.id, currentDepth + 1, maxDepth);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment