Unzip File Only If New in Google Apps Scripts

安稳与你 提交于 2020-04-17 20:05:13

问题


I have a folder (let's call it the source folder) on Google Drive that is updated from time to time with new zip files (underlying files are PDFs). I am trying to use Google Apps Script to unzip only the new zip files and place the underlying PDFs in another folder (let's call it the destination folder).

I am currently using the following code to unzip the files in the source folder, running on a time-based trigger. My current code does not differentiate between old and new zip files so I am getting a large number of duplicates accumulating in the destination folder. (I found this code on WeirdGeek: https://www.weirdgeek.com/2019/10/unzip-files-using-google-apps-script/)

function Unzip() {
  //Add folder ID to select the folder where zipped files are placed
  var SourceFolder = DriveApp.getFolderById("1KbyB2vTUfbwYdzBEyIwzTliXKjATbW8A")
  //Add folder ID to save the where unzipped files to be placed
  var DestinationFolder = DriveApp.getFolderById("1Z-iVlcROe5kVX8IkBlV9a98WKlvlfp3U")
  //Select the Zip files from source folder using the Mimetype of ZIP
  var ZIPFiles = SourceFolder.getFilesByType(MimeType.ZIP)

  //Loop over all the Zip files
  while (ZIPFiles.hasNext()){
   // Get the blob of all the zip files one by one
    var fileBlob = ZIPFiles.next().getBlob();
   //Use the Utilities Class to unzip the blob
    var unZippedfile = Utilities.unzip(fileBlob);
   //Unzip the file and save it on destination folder
    var newDriveFile = DestinationFolder.createFile(unZippedfile[0]);
    }
}

I initially thought to add some sort of time-based restriction to the function, but because the source folder is being synced (using MultCloud) with an sFTP site, I don't want to go that direction.

I ALSO found the following code is used to put a "replace" restriction on saving new spreadsheets but couldn't figure out how to integrate this with my code. (Code is from user Tainake)

function saveAsSpreadsheet() {
  var folderId = "0B8xnkPYxGFbUMktOWm14TVA3Yjg";
  var folder = DriveApp.getFolderById(folderId);
  var files = folder.getFilesByName(getFilename());
  if (files.hasNext()) {
    files.next().setTrashed(true);
  }
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  DriveApp.getFileById(sheet.getId()).makeCopy(getFilename(), folder);
}

Any ideas on how to solve this problem would be appreciated! I am a complete noob so I apologize in advance if this is a stupid question.

EDIT: I could not figure out how to unzip only "new" files in the source folder, and so my new code moves to trash all files in the destination folder, and then unzips all files in the source folder. Code is below:



function Unzip() {
  //Add folder ID to select the folder where zipped files are placed
  var SourceFolder = DriveApp.getFolderById("1KbyB2vTUfbwYdzBEyIwzTliXKjATbW8A")
  //Add folder ID to save the where unzipped files to be placed
  var DestinationFolder = DriveApp.getFolderById("1Z-iVlcROe5kVX8IkBlV9a98WKlvlfp3U")

 //Delete files from the destination folder
  //Get the files in the destination folder
    var files = DestinationFolder.getFiles();

    //Loop through the files in the destination folder
    while(files.hasNext()){

      //Get the individual file in the destination folder to process
      var file = files.next(); 

      //Trash that file
        file.setTrashed(true);
      }


  //Select the Zip files from source folder using the Mimetype of ZIP
  var ZIPFiles = SourceFolder.getFilesByType(MimeType.ZIP)

  //Loop over all the Zip files
  while (ZIPFiles.hasNext()){
   // Get the blob of all the zip files one by one
    var fileBlob = ZIPFiles.next().getBlob();
   //Use the Utilities Class to unzip the blob
    var unZippedfile = Utilities.unzip(fileBlob);
   //Unzip the file and save it on destination folder
    var newDriveFile = DestinationFolder.createFile(unZippedfile[0]);
    }
}

I could see how this may not be the best solution to this issue, but this allows me to have a MultCloud sync the zip files into my Google Drive, and then allows me to have those files unzipped with a function that runs from time to time. Anyone have a better idea how to accomplish the same thing without deleteing and recreating all the files every time?

EDIT 2: Thank you to Cameron, this question is answered. I am pasting the full code I am using below, for posterity / other newbies so that they don't have to piece it together:

function Unzip() {
  //Add folder ID to select the folder where zipped files are placed
  var SourceFolder = DriveApp.getFolderById("1KbyB2vTUfbwYdzBEyIwzTliXKjATbW8A")
  //Add folder ID to save the where unzipped files to be placed
  var DestinationFolder = DriveApp.getFolderById("1Z-iVlcROe5kVX8IkBlV9a98WKlvlfp3U")

  //Select the Zip files from source folder using the Mimetype of ZIP
  var ZIPFiles = SourceFolder.getFilesByType(MimeType.ZIP);

  var now = new Date(); //get current time after you fetch the file list from Drive.

  //Get script properties and check for stored "last_execution_time"
  var properties = PropertiesService.getScriptProperties();
  var cutoff_datetime = properties.getProperty('last_execution_time');

  //if we have last execution date, stored as a string, convert it to a Date object.
  if(cutoff_datetime)
     cutoff_datetime = new Date(cutoff_datetime);

  //Loop over all the Zip files
  while (ZIPFiles.hasNext()){
    var file = ZIPFiles.next();

    //if no stored last execution, or file is newer than last execution, process the file.
    if(!cutoff_datetime || file.getDateCreated() > cutoff_datetime){
        var fileBlob = file.getBlob();
       //Use the Utilities Class to unzip the blob
       var unZippedfile = Utilities.unzip(fileBlob);
       //Unzip the file and save it on destination folder
       var newDriveFile = DestinationFolder.createFile(unZippedfile[0]);
    }
  }

  //store "now" as last execution time as a string, to be referenced on next run.
  properties.setProperty('last_execution_time',now.toString());
}


回答1:


You can use the getDateCreated() function on a File object to determine when the file was created. By checking this value against a time limit, you should be able to determine if the file is new. If you are triggering your script with at least a few hours between executions, you could use a hardcoded cutoff time. So if you are triggering your script every six hours, you could ignore any files not created within the last 6 hours, for example.

However, a more robust approach would be to store the last successful execution time in a Script Property, so you could always process any files created since the last successful execution.

Note that this code will process all files currently in the folder the first time it runs, after that it will only process files created since the last run.

  var ZIPFiles = SourceFolder.getFilesByType(MimeType.ZIP);

  var now = new Date(); //get current time after you fetch the file list from Drive.

  //Get script properties and check for stored "last_execution_time"
  var properties = PropertiesService.getScriptProperties();
  var cutoff_datetime = properties.getProperty('last_execution_time');

  //if we have last execution date, stored as a string, convert it to a Date object.
  if(cutoff_datetime)
     cutoff_datetime = new Date(cutoff_datetime);

  //Loop over all the Zip files
  while (ZIPFiles.hasNext()){
    var file = ZIPFiles.next();

    //if no stored last execution, or file is newer than last execution, process the file.
    if(!cutoff_datetime || file.getDateCreated() > cutoff_datetime){
        var fileBlob = file.getBlob();
       //Use the Utilities Class to unzip the blob
       var unZippedfile = Utilities.unzip(fileBlob);
       //Unzip the file and save it on destination folder
       var newDriveFile = DestinationFolder.createFile(unZippedfile[0]);
    }
  }

  //store "now" as last execution time as a string, to be referenced on next run.
  properties.setProperty('last_execution_time',now.toString());


来源:https://stackoverflow.com/questions/60644572/unzip-file-only-if-new-in-google-apps-scripts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!