Home > Blockchain >  Is it possible to get the names of all the folders and create from each folder a custom script file
Is it possible to get the names of all the folders and create from each folder a custom script file

Time:01-25

I made a code that renames multiple files in Google Drive (taken from Here) and here is the content

function renamejpgs() {

  /* 
  // A given Goiogle Drive folder contains jpg files.
  // The files have a consistent naming structure:
  // "AA123_y.jpg, where y is a single or multi-digit sequence number.
  //
  // The function renames the files by removing the third, fourth, fifth and sixth characters of the file name and substituting a single"underscore"
  // For example, "AA123_1.jpg" -> "AA_1.jpg"
  */
   
  // set the mime type/file type to be renamed
  var mimetype = 'image/jpeg';
  // get the folder ID; note the id is a string
  var folderid = "<<insert your folder ID>>"
  
  // getFoldersById = Gets a specific folders in the user's Drive
  var folder = DriveApp.getFolderById(folderid)
 
  // get  files in this folder
  // myfiles is a File Iterator
  var myfiles = folder.getFiles();

  // loop through files in this folder
  while (myfiles.hasNext()) { 
  
    var myfile = myfiles.next();   
    var myname = myfile.getName();
    var ftype = myfile.getMimeType();
    // find the next file that matches the mime type
    var indexOfFirst = ftype.indexOf(mimetype);

    if (indexOfFirst != -1){ 
      // the next file was an image
    
      // edit the file name
      var fname = myname.replace("123_", "_");
      // update the file name
      myfile.setName(fname);       
 
    } //end if
  } // end while loop through main folder
  
  return false;
} 

My problem is that it only works on the root folder and not on subfolders I tried to ask in this place if subfolders could be included and they helped me change the name there. But then there was a problem of a longer time than the Google limit. My question is Is it possible to get the names of all the folders and create from each folder a custom script file for that folder in Google Drive

CodePudding user response:

function renamejpgs() {

  /* 
  // A given Goiogle Drive folder contains jpg files.
  // The files have a consistent naming structure:
  // "AA123_y.jpg, where y is a single or multi-digit sequence number.
  //
  // The function renames the files by removing the third, fourth, fifth and sixth characters of the file name and substituting a single"underscore"
  // For example, "AA123_1.jpg" -> "AA_1.jpg"
  */
   
  // set the mime type/file type to be renamed
  var mimetype = 'image/jpeg';
  // get the folder ID; note the id is a string
  var folderid = "<<insert your folder ID>>"
  
  // getFoldersById = Gets a specific folders in the user's Drive
  var folder = DriveApp.getFolderById(folderid)
 
  // get  files in this folder
  // myfiles is a File Iterator
  var myfiles = folder.getFiles();

  // loop through files in this folder
  while (myfiles.hasNext()) { 
  
    var myfile = myfiles.next();   
    var myname = myfile.getName();
    var ftype = myfile.getMimeType();
    // find the next file that matches the mime type
    var indexOfFirst = ftype.indexOf(mimetype);
    Utilities.sleep(10);
    if (indexOfFirst != -1){ 
      // the next file was an image
    
      // edit the file name
      var fname = myname.replace("123_", "_");
      // update the file name
      myfile.setName(fname);       
 
    } //end if
  } // end while loop through main folder
  
  return false;
}

I believe this will help stop the code from timing out.


I added a sleep function to pause it and stop it from exhaustion.


This is my basis of research for using the sleep function: https://webapps.stackexchange.com/questions/116041/how-to-set-up-delays-in-google-apps-script

CodePudding user response:

In this implementation, I've decided to use Drive API service on Apps Scripts in order to use the filter functionality (q parameter) of Drive API queries.

Given that, make sure to add Drive API on the service list on your Apps Scripts project.

The code below will "scan" for a file name that includes MATCH_PATTERN set on a given starting folder ID including sub-folders.

Make sure to customize the constants in the beginning to adapt to your use case. The function main() is a sample start point for this script.

Sample Code:

const MATCH_PATTERN = "[replace]"; //file name pattern to be renamed
const REPLACE_PATTERN = "[123456789]"; //pattern to replace MATCH_PATTERN from file name
const MIMETYPE_TARGET_FILES = "image/jpeg"; //mimetype of target files

function listFoldersIn(parentId = "root") {
  /**
   * Lists sub-folders in the user's Drive for a given folder ID.
   * Slightly modified script from https://developers.google.com/apps-script/advanced/drive#listing_folders
  */
  var query = '"'  parentId  '" in parents and trashed = false and '  
      'mimeType = "application/vnd.google-apps.folder"';
  var folders;
  var pageToken;

  var folderIdList = [];
  do {
    folders = Drive.Files.list({
      q: query,
      maxResults: 100,
      pageToken: pageToken
    });
    if (folders.items && folders.items.length > 0) {
      for (var i = 0; i < folders.items.length; i  ) {
        var folder = folders.items[i];
        folderIdList.push(folder.id);
      }
    }
    pageToken = folders.nextPageToken;
  } while (pageToken);
  
  return folderIdList;
};

function listTargetFilesForParent(parentId = "root", mime = MIMETYPE_TARGET_FILES) {
  /**
   * Lists files on a given folder ID matching the MIME type set.
   * Slightly modified script from https://developers.google.com/apps-script/advanced/drive#listing_folders
  */
  var query = '"'  parentId  '" in parents and trashed = false and '  
      'mimeType = "'  mime  '"';
  var files;
  var pageToken;

  var fileIdList = [];
  do {
    files = Drive.Files.list({
      q: query,
      maxResults: 100,
      pageToken: pageToken
    });
    if (files.items && files.items.length > 0) {
      for (var i = 0; i < files.items.length; i  ) {
        var file = files.items[i];
        fileIdList.push({title: file.title, id: file.id});
      }
    }
    pageToken = files.nextPageToken;
  } while (pageToken);
  
  return fileIdList;
};

function renameFilesInFolders(folderList) {
  if (folderList.length > 0) { //if folder ID list provided is empty, exit method;
    for (folder of folderList) { //loop for folder ID list provided.
      //Fetch target files in current folder
      var filesList = listTargetFilesForParent(parentId = folder);

      renameTargetFiles(filesList); // Rename files if applicable;

      //Check for sub folders
      var subFolders = listFoldersIn(folder);
      if (subFolders.length > 0) { //It has subfolders?
        renameFilesInFolders(subFolders); //call this same method recursively
      } else { //if current folder does not have sub-folders, then do nothing and continue loop;
        continue;
      }
    }
  } else {
    return;
  }
}

function renameTargetFiles(filesList){
  for (file of filesList) { //loop through file list provided
    if (file.title.includes(MATCH_PATTERN)) { //is current file applicable to be renamed? In other words, does the current file name contain the MATCH_PATTERN?
      var newName = file.title.replace(MATCH_PATTERN, REPLACE_PATTERN); //replace MATCH_PATTERN from file name for REPLACE_PATTERN
      Drive.Files.patch({title: newName}, file.id); //Call Drive API patch to modify file name. 
    }
  }
}

function main() {
  /**
   * Make sure to set up constants in the beginning of this file to adapt to your use case
   * When calling renameFilesInFolders() without passing parameters, it will scan starting from the root of My Drive.
   * Passing an array of a single Drive Folder ID, sets the root level for the scan
   */ 

  renameFilesInFolders(["<STARTING_FOLDER_ID>"]);
}
  •  Tags:  
  • Related