Разархивировать файл, только если он новый в скриптах Google Apps - PullRequest
0 голосов
/ 12 марта 2020

У меня есть папка (назовем ее папкой с исходными файлами) на Google Диске, которая время от времени обновляется новыми zip-файлами (основными файлами являются PDF-файлы). Я пытаюсь использовать Google Apps Script, чтобы распаковать только новые zip-файлы и поместить соответствующие PDF-файлы в другую папку (назовем ее папкой назначения).

В настоящее время я использую следующий код, чтобы разархивировать файлы в исходной папке, работая по триггеру на основе времени. Мой текущий код не различает старые и новые zip-файлы, поэтому я получаю большое количество дубликатов, накапливающихся в папке назначения. (Я нашел этот код на 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]);
    }
}

Сначала я думал добавить какое-то временное ограничение к функции, но поскольку исходная папка находится в процессе синхронизируется (используя MultCloud) с сайтом sFTP, я не хочу go в этом направлении.

Я также обнаружил, что следующий код используется для наложения ограничения на замену при сохранении новых электронных таблиц, но не смог понять, как интегрировать это с моим кодом. (Код от пользователя 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);
}

Любые идеи о том, как решить эту проблему, будут оценены! Я полный нуб, поэтому заранее прошу прощения, если это глупый вопрос.

РЕДАКТИРОВАТЬ: я не мог понять, как распаковать только "новые" файлы в исходной папке, и поэтому мой новый код перемещается в tra sh всех файлов в папке назначения, а затем распаковывает все файлы в исходной папке. Код ниже:



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]);
    }
}

Я мог видеть, что это может быть не лучшим решением этой проблемы, но это позволяет мне иметь MultCloud syn c zip-файлы в моем Google Диске, а затем позволяет мне разархивировать эти файлы с помощью функции, которая запускается время от времени. У кого-нибудь есть идея, как выполнить sh одно и то же без удаления и повторного создания всех файлов каждый раз?

РЕДАКТИРОВАТЬ 2: Спасибо Кэмерон, на этот вопрос дан ответ. Я вставляю полный код, который я использую ниже, для потомков / других новичков, чтобы им не приходилось собирать его вместе:

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 Ответ

0 голосов
/ 12 марта 2020

Вы можете использовать функцию getDateCreated () для объекта File, чтобы определить, когда был создан файл. Сравнив это значение с ограничением по времени, вы сможете определить, является ли файл новым. Если вы запускаете свой сценарий по крайней мере с несколькими часами между выполнениями, вы можете использовать жестко заданное время отключения. Поэтому, если вы запускаете свой сценарий каждые шесть часов, вы можете игнорировать любые файлы, например, не созданные в течение последних 6 часов.

Однако более надежный подход заключается в сохранении времени последнего успешного выполнения в Свойство сценария , поэтому вы всегда можете обработать любые файлы, созданные с момента последнего успешного выполнения.

Обратите внимание, что этот код будет обрабатывать все файлы, находящиеся в папке в данный момент, при первом запуске, после чего он будет обрабатывать только файлы, созданные с момента последнего запуска.

  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());
...