1

Unlike the DriveApp.getFilesByType() method that will only search for files in the immediate folder, i'm trying to also search for files inside the sub-folders.

Found this bloggpost about it, and that works as is. However my script needs to push the result into an Array. So far i can push files to the array but i'm not fetching the subfolder's files.

I have 3 functions:

trigger_GetDriveFiles

function trigger_GetDriveFiles(){
var folder = DriveApp.getFolderById("0B2XfBTL5aSGMZTNwTDlwT2JqNjg");
var filesJSObj = GetDriveFiles(folder);


   for(var i in filesJSObj){
    if(filesJSObj.hasOwnProperty(i)){
    Logger.log(bulkFile(i, filesJSObj[i]));
    } 
  }
}

GetDriveFiles (The out-commented section is where it fails)

function GetDriveFiles(folder) {
  var files = {};
  var fileIt = folder.getFiles();
  while (fileIt.hasNext()) {
    var f = fileIt.next();
    var owner = f.getOwner().getEmail();
    var id = f.getId();

    if (owner != "admin.fileshare@domain.com"){
      if (!files[owner]) {
        files[owner] = [];
      }

      // push the file to the owner's array
      files[owner].push(id);
    }

  }
  /*
  // Get all the sub-folders and iterate, This is the part not wokring!
  var folderIt = folder.getFolders();
  while(folderIt.hasNext()) {
    fs = GetDriveFiles(folderIt.next());
    for (var i = 0; i < fs.length; i++) {
      files.push(fs[i].id) 
    }
  }*/
  return files;
}

bulkFile

function bulkFile(ownerEmail, fileIds) {
  var ts = tokenService(ownerEmail);
  LibDrive.Init(ts);
  var dSA = LibDrive.ServiceAccount(ownerEmail);
 return dSA.batchPermissionChange(fileIds, "admin.fileshare@domain.com"); //<-- This is the user that recieves the folder/file
}
John Smith
  • 387
  • 2
  • 8
  • 24

1 Answers1

1

The problem is in inconsistent data structures. The commented part of code treats files as an array, using files.push. In the rest of the code it's an object with keys being owner emails.

Another problem with files being such an object is that the function would have to merge object properties, which is messy. I suggest changing the structure to files being an array of objects {id: id, file: file}. This is easy to concatenate, and after the work is done, the resulting array can be then converted to an object with keys being owners. I include the conversion bit convertToObj at the end.

function trigger_GetDriveFiles() {
  var folder = DriveApp.getFolderById('your_id');
  Logger.log(convertToObj(GetDriveFiles(folder)));
}

function GetDriveFiles(folder) {
  var files = [];
  var fileIt = folder.getFiles();
  while (fileIt.hasNext()) {
    var f = fileIt.next();
    var owner = f.getOwner().getEmail();
    var id = f.getId();
    if (owner != "admin.fileshare@domain.com"){
      files.push({'id': id, 'owner': owner});
    }
  }
  var folderIt = folder.getFolders();
  while (folderIt.hasNext()) {
    files = files.concat(GetDriveFiles(folderIt.next()));
  }
  return files;
}

The function convertToObj has nothing to do with Google Drive; it's just a manipulation with JS objects and arrays.

function convertToObj(files) {
  var filesObj = {};
  for (var i = 0; i < files.length; i++) {
    var owner = files[i].owner;
    if (!filesObj[owner]) {
      filesObj[owner] = [];
    }
    filesObj[owner].push(files[i].id);
  }
  return filesObj;
}
Community
  • 1
  • 1
  • Thank you for the comment, i included the batch/bulk function just to show that the approach you are suggesting isn't working, due to i need to pass it on like this "function bulkFile(ownerEmail, fileIds) ". – John Smith Apr 13 '16 at 11:36
  • The output looks like this now: [{owner=adam.aden@domain.com, id=1aYF62ynb8BYut7mbfrVFHC2GYfxhM0W8}, {owner=adam.aden@domain.com, id=1C5xhapMROPb3FZoSTRzcafDyZxYUWGpnh0}, {owner=adam.aden@domain.com, id=1UgGC9u2xxPlhbEQ4G1UIz1ktJxdDPqbzOvo}]. – John Smith Apr 13 '16 at 11:41
  • 1
    I wrote that the output can be converted from the array format to object format that you want. And now I included the function `convertToObj` that does that. –  Apr 13 '16 at 16:35