javascriptgoogle-apps-scriptgoogle-drive-apigoogle-drive-picker

how to calculate the size of a folder google script with google picker api


Yo, I would like to create a script where the user can choose a folder and then by getting the id of the folder I display the size of the folder. I manage to retrieve the ID but I don't know how from this id I can calculate the size and display it. here is the code to show the picker google drive :

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
  <script type="text/javascript">
    var DIALOG_DIMENSIONS = {
        width: 600,
        height: 425
    };
    var pickerApiLoaded = false;

    function onApiLoad() {
        gapi.load('picker', {
            'callback': function() {
                pickerApiLoaded = true;
            }
        });
        google.script.run.withSuccessHandler(createPicker)
            .withFailureHandler(showError).getOAuthToken();
    }

    function createPicker(token) {

        if (pickerApiLoaded && token) {

            var docsView = new google.picker.DocsView()
                .setIncludeFolders(true)
                .setMimeTypes('application/vnd.google-apps.folder')
                .setSelectFolderEnabled(true);

            var picker = new google.picker.PickerBuilder()
                .addView(docsView)
                .enableFeature(google.picker.Feature.NAV_HIDDEN)
                .hideTitleBar()
                .setSize(DIALOG_DIMENSIONS.width - 2, DIALOG_DIMENSIONS.height - 2)
                .setOAuthToken(token)
                .setCallback(pickerCallback)
                .setOrigin('https://docs.google.com')
                .build();

            picker.setVisible(true);

        } else {
            showError('Unable to load the file picker.');
        }
    }

    /**
     * A callback function that extracts the chosen document's metadata from the
     * response object. For details on the response object, see
     * https://developers.google.com/picker/docs/result
     *
     * @param {object} data The response object.
     */
    function pickerCallback(data) {
        var action = data[google.picker.Response.ACTION];
        if (action == google.picker.Action.PICKED) {
            var doc = data[google.picker.Response.DOCUMENTS][0];
            var id = doc[google.picker.Document.ID];
            // Show the ID of the Google Drive folder
            document.getElementById('result').innerHTML = id;



        } else if (action == google.picker.Action.CANCEL) {
            google.script.host.close();
        }
    }

    function showError(message) {
        document.getElementById('result').innerHTML = 'Error: ' + message;
    }


            



  </script>
</head>

<body>
    <div>
        <p id='result'></p>
    </div>
    <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>

function onOpen() {
 SpreadsheetApp.getUi().createMenu('Google Picker')
     .addItem('Choose Folder', 'showPicker')
     .addToUi();
}

/**
* Displays an HTML-service dialog in Google Sheets that contains client-side
* JavaScript code for the Google Picker API.
*/
function showPicker() {
 var html = HtmlService.createHtmlOutputFromFile('Picker.html')
     .setWidth(600)
     .setHeight(425)
     .setSandboxMode(HtmlService.SandboxMode.IFRAME);
 SpreadsheetApp.getUi().showModalDialog(html, 'Select Folder');
}

function getOAuthToken() {
 DriveApp.getRootFolder();
 return ScriptApp.getOAuthToken();
}



I would like to merge the two code.gs file with the id of picker.html


function test(){
  var root = DriveApp.getFolderById("1fl7XeqwelnlJJnSQjjvDmdxYudfCwQAR");
  var list = [];

  var list = recurseFolder(root, list);
  //Logger.log(JSON.stringify(list));

  //This is just how I am testing the outputed list. You can do what you need.
  var sheet = SpreadsheetApp.getActiveSheet();
  //list.forEach(function (row){
  // sheet.appendRow(row); 
  //});
  Logger.log("test !\n")

}
var fileCounter = folderCounter = fileSize = 0;

function recurseFolder(folder, list){
  
  
  var files = folder.getFiles();  
  var subfolders = folder.getFolders();

  while (files.hasNext()){ //add all the files to our list first.
    var file = files.next();
    var row = [];
    fileCounter++;
    fileSize+=file.getSize();
    //Logger.log("File: " + folder.getName());
    //row.push(folder.getName(),file.getName(),file.getId(),file.getUrl(),file.getSize(),file.getDateCreated(),file.getLastUpdated())
    //list.push(row);
  }


  while (subfolders.hasNext()){   //Recurse through child folders.
    subfolder = subfolders.next(); 
    folderCounter++;
    //Logger.log("Folder: " + subfolder.getName());
    list = recurseFolder(subfolder, list); //Past the original list in so it stays a 2D Array suitible for inserting into a range.
  }  

  Logger.log ("file : " + fileCounter + " folderCounter : " + folderCounter + " fileSize : " +  fileSize);  

}


Solution

  • You can use gapi to use the Drive API and use it to do the exact same logic as you did in Apps Script. You can read the official quickstart and modify it to query the size of files instead of simply listing the names.

    Note that you'll have to load auth, client, and picker. Also you'll have to integrate the picker with it.

    References