google-apps-scriptflysystem-google-drive

Is there a way to Archive files and folders to a specific folder in Google Drive and keep folder path?


I'm using Google Drive and I'd like to Archive all the files synced with my computer which are older than a certain amount of time. As a result, the archived files will disappear from my computer on the next sync.

I've found several scripts to perform the file moving but it seems challenging to move the file and keep the path structure as if it was moved using a robocopy/powershell command locally on the computer.

any idea if such feature is possible with Google Apps Scripts?

So far, I haven't integrated yet the copy/remove function. I'm retrieving the folder path and I guess there must be a way to check if path already exists in destination and if not, create subfolders?

function FilesModifiedLastWeek(){

// Find files modified last week

  var today     = new Date();
  var oneDayAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);  
  var startTime = oneDayAgo.toISOString();

  // The magic search expression
  var search = '(trashed = true or trashed = false) and (modifiedDate > "' + startTime + '")';
  var files  = DriveApp.searchFiles(search);

  // Loop through all the files in the search results
  while( files.hasNext() ) {

    var file = files.next();

    var fileName    = file.getName();
    var parentFolder = file.getParents();
    folders = [];

    //Get full path
    while (parentFolder.hasNext()) {
      parentFolder = parentFolder.next();
      var title = parentFolder.getName();
      folders.push(parentFolder.getName());
      parentFolder = parentFolder.getParents();
    }
    var fileURL     = file.getUrl();
    var dateCreated =  Utilities.formatDate(file.getDateCreated(), "Europe/Zurich", "yyyy-MM-dd HH:mm");
    Logger.log("Filename: " + fileName + " Folder path: " + folders.reverse().join("/") + " File creation date:" + dateCreated);
  }
}

Additional point, is it a way to exclude the Archive folder from the search? :)


Solution

  • You can achieve this with the Advanced Drive Services and one extra function in your code.

    We will be using the Patch command to add and remove parent folders.

    Optional query parameters

    addParents string A comma-separated list of parent IDs to add.

    removeParents string A comma-separated list of parent IDs to remove.

    The code is like this:

    function placeFileInFolders(file, folders) {
      var archiveFolder = DriveApp.getFoldersByName("Archive Folder").next();
      
      var lastFolder = archiveFolder;
      for (var i=0; i<folders.length; i++) {
        if (lastFolder.getFoldersByName(folders[i]).hasNext()) {
          lastFolder = lastFolder.getFoldersByName(folders[i]).next();
        } else {
          lastFolder = lastFolder.createFolder(folders[i]);
        }
      }
      var newFile = Drive.Files.patch({}, file.getId(), {
        addParents: lastFolder.getId(),
        removeParents: file.getParents().next().getId()
      });
    }
    

    And you can use it like this:

        //...
        Logger.log("Filename: " + fileName + " Folder path: " + folders.reverse().join("/") + " File creation date:" + dateCreated);
        placeFileInFolders(file, folders.reverse());
        //...
    

    Improvements

    Shared with Me

    I've also added one extra case where your code will be able to handle files "Shared With Me".

        //...
        if (!parentFolder.hasNext()) {
          folders.push("Shared With Me");
        }
        while (parentFolder.hasNext()) {
        //...
    

    Delete empty folders

    This script does not remove folders that have all their contents moved to the Archive.