要复制整个Google云端硬盘文件结构的Google Apps脚本;如何避免超时?

时间:2015-03-24 16:40:39

标签: recursion google-apps-script google-drive-api session-timeout

我的组织正在切换到Google Business帐户,每个人都需要将其Drive文件转移到新帐户。云端硬盘不允许在这些帐户之间转让所有权,因此我创建了一个脚本,用于将文件和文件夹从旧帐户复制到新帐户。 (旧帐户的内容已移至与新帐户共享的文件夹中。)

这是我到目前为止所拥有的:

function copyDrive() {
  var originFolder = DriveApp.getFolderById(originFolderID);
  var destination = DriveApp.getFolderById(destinationID);
  copyFiles(originFolder, destination);

};

function copyFiles(passedFolder, targetFolder) {
  var fileContents = passedFolder.getFiles();
  var file;
  var fileName;

  while(fileContents.hasNext()) {
    file = fileContents.next();
    fileName = file.getName();
    file.makeCopy(fileName, targetFolder);
  }
  copySubFolders(passedFolder, targetFolder);
};

function copySubFolders(passedFolder, targetFolder) {
  var folderContents = passedFolder.getFolders();
  var folder;
  var folderName;

  while(folderContents.hasNext()) {
    folder = folderContents.next();
    folderName = folder.getName();
    var subFolderCopy = targetFolder.createFolder(folderName);
    copyFiles(folder, subFolderCopy);
  }
};

请原谅任何不雅;我是新来的。该脚本实际上工作得很好并保留了文件夹结构,但在复制~150个文件和文件夹后它会超时。我一直在研究如何使用延续令牌,并且我已经仔细阅读了this post。我认为我陷入了概念层面,因为我不确定延续令牌如何与我设置的递归函数相互作用。看起来我最终会得到一堆copySubFolders函数,他们每个人都需要自己的延续令牌。当然它们都为迭代器使用相同的变量名,所以我真的不知道如何设置它。

有什么想法?很抱歉发布这样一个无助的新手问题;我希望这对某人来说至少是一个有趣的问题。

3 个答案:

答案 0 :(得分:3)

我认为我已经解决了概念问题,但我得到了

  

很抱歉,发生了服务器错误。请稍等一下再试一次。 (第9行,文件"代码")

当我尝试执行它时。

基本上,我将其设置为仅尝试一次复制一个顶级文件夹,并且每个文件夹使用我之前使用的递归函数。它应该保存第一级文件夹和根文件夹中的任何文件的连续令牌,以便它可以在下一次执行时从中断处获取。这样,令牌不会涉及我的递归函数堆栈。

function copyDrive() {


  var originFolder = DriveApp.getFolderById(originFolderID);
  var destination = DriveApp.getFolderById(destinationID);

  var scriptProperties = PropertiesService.getScriptProperties();
  var fileContinuationToken = scriptProperties.getProperty('FILE_CONTINUATION_TOKEN');
  var fileIterator = fileContinuationToken == null ?
    originFolder.getFiles() : DriveApp.continueFileIterator(fileContinuationToken);
  var folderContinuationToken = scriptProperties.getProperty('FOLDER_CONTINUATION_TOKEN');
  var folderIterator = folderContinuationToken == null ?
    originFolder.getFolders() : DriveApp.continueFolderIterator(folderContinuationToken);

  try {
    var rootFileName;
    while(fileIterator.hasNext()) {
      var rootFile = fileIterator.next();
      rootFileName = rootFile.getName();
      rootFile.makeCopy(rootFileName, destination);
      }

    var folder = folderIterator.next();
    var folderName = folder.getName();
    var folderCopy = folder.makeCopy(folderName, destination);


    copyFiles(folder, folderCopy);

  } catch(err) {
    Logger.log(err);
  }

  if(fileIterator.hasNext()) {
    scriptProperties.setProperty('FILE_CONTINUATION_TOKEN', fileIterator.getContinuationToken());
  } else {
    scriptProperties.deleteProperty('FILE_CONTINUATION_TOKEN');
  }
  if(folderIterator.hasNext()) {
    scriptProperties.setProperty('FOLDER_CONTINUATION_TOKEN', folderIterator.getContinuationToken());
  } else {
    scriptProperties.deleteProperty('FOLDER_CONTINUATION_TOKEN');
  }

};

function copyFiles(passedFolder, targetFolder) {
  var fileContents = passedFolder.getFiles();
  var file;
  var fileName;

  while(fileContents.hasNext()) {
    file = fileContents.next();
    fileName = file.getName();
    file.makeCopy(fileName, targetFolder);
  }
  copySubFolders(passedFolder, targetFolder);
};

function copySubFolders(passedFolder, targetFolder) {
  var subFolderContents = passedFolder.getFolders();
  var subFolder;
  var subFolderName;

  while(folderContents.hasNext()) {
    subFolder = subFolderContents.next();
    subFolderName = subFolder.getName();
    var subFolderCopy = targetFolder.createFolder(folderName);
    copyFiles(subFolder, subFolderCopy);
  }
};

答案 1 :(得分:1)

我知道您希望以简单,程序化的方式执行此操作,但最简单的方法是安装Google Drive for Desktop并对其进行右键单击,复制和粘贴。

这个想法:

  1. 创建一个文件夹,用户可以在其中放置其云端硬盘的每个项目。 (我看你已经这样做了。)
  2. 与新帐户共享该文件夹。 (我知道你已经这样做了。)
  3. 使用云端硬盘桌面登录新帐户。
  4. 复制Drive for Desktop中的文件夹并将其重新粘贴回来。所有权将转移到新帐户。
  5. 只是一个想法。

答案 2 :(得分:0)

您将需要存储一个文件夹迭代器和文件迭代器数组,因为每个文件夹都可能具有嵌套的文件夹数组。如果您要重新使用与接受的解决方案相同的文件夹迭代器,则将无法在更多顶级文件夹上继续使用。

在此处查看my answer的模板,您可以使用该模板以递归方式迭代内置有恢复功能的驱动器中的所有文件。