6 Replies Latest reply on Jan 25, 2017 7:33 AM by Kasyan Servetsky

    Batch process script

    damijanl

      Hello,

       

      I came across this Batch process scripts and i am simply loving it. But after a while i came across one big problem, as script run breaks if choosen file is opened or not accessible. How could i get around this, so if file is already opened/not accessible script would simply wait 5 x 10 seconds and than continue trough other files in folder that were left to it. Offcourse if file is within this 50s closed/accessible script would simply continue foward like it was never in a loop / paused.

       

      Any help or point in right direction would be highly appriciated.

       

      Thanks a lot!

        • 1. Re: Batch process script
          Kasyan Servetsky Level 5

          Hi there,

           

          Try to add 'try-catch' block like so:

          function ProcessAllInddDocs(inddFiles) {
              startTime = new Date();
              if (set.log) {
                  arr.push(GetDate());
                  if (set.rbScope == 2) arr.push("Book name: " + app.activeBook.name);
              }
          
              progressWin.show();
              var pbCounter = 0;
              progressBar.minvalue = 0;
              progressBar.maxvalue = inddFiles.length;
              
              for (var i = 0; i < inddFiles.length; i++) {
                  try {
                      inddFile = inddFiles[i];
                      progressBar.value = pbCounter++;
                      progressTxt.text = "Processing file - " + inddFile.displayName;
                      
                      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
                      doc = app.open(inddFile);
                      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
                      ProcessDocument(doc, subFolders);
                      doc.close(SaveOptions.YES);
                  }
              }
              catch(err) {
                  $.writeln(err.message + ", line: " + err.line);
              }
          }
          

           

          I wrote it at home so didn't encounter such a situation. I'll test it later today at work against some files open open by other users on a network drive.

          Thanks for pointing this out.

           

          — Kas

          1 person found this helpful
          • 2. Re: Batch process script
            damijanl Level 1

            Basically this is not bug, but just something i came across in my workflow. I am on-the-go at the moment, but basically i get error when ever file is already opened over network drive by some other user and i am trying to run script over that file.

             

            I think one solution would be (if possible) some kind of check box "Wait for opened files to close" of some sort, and when checked, script would wait/loop till file is accessible over network again and then properly continue from there.

             

            Thank a lot!

            • 3. Re: Batch process script
              Kasyan Servetsky Level 5

              I am sorry, I made a stupid mistake in my post 1. I was in a hurry getting ready to my work.

              Here's a new version:

              /* Copyright 2016, Kasyan Servetsky
              November 24, 2016
              Written by Kasyan Servetsky
              http://www.kasyan.ho.com.ua
              e-mail: askoldich@yahoo.com
              */
              //======================================================================================
              
              var set, doc, subFolders, progressWin, progressBar, progressTxt, startTime, scriptFile, scriptFolder,
              scriptName = "Batch process scripts - 1.2",
              count = 0,
              arr = [];
              
              CreateDialog();
              
              //===================================== FUNCTIONS  ======================================
              function Main() {
                  var inddFolder, inddFiles, inddFiles;
              
                  CreateProgressBar();
                  
                  if (set.rbScope == 0 || set.rbScope == 1) {
                      startTime = new Date();
                      if (set.log) arr.push(GetDate());
                      progressWin.show();
                      if (set.rbScope == 0) { // active document
                          doc = app.activeDocument;
                          progressWin.show();
                          ProcessDocument(doc);
                      }
                      else if (set.rbScope == 1) { // all open documents
                          for (var d = 0; d < app.documents.length; d++) {
                              doc = app.documents[d];
                              ProcessDocument(doc);
                          }
                      }
                  }
                  else if (set.rbScope == 2) { // active book
                      inddFiles = GetFilesFromBook();
                      if (inddFiles.length == 0) ErrorExit("Found no InDesign documents in the active book.", true);
                      ProcessAllInddDocs(inddFiles);
                  }
                  else if (set.rbScope == 3 || set.rbScope == 4) {
                      inddFolder = Folder.selectDialog("Choose a folder with InDesign documents.");
                      if (inddFolder == null) exit();
              
                      if (set.rbScope == 3) { // folder
                          inddFiles = inddFolder.getFiles("*.indd");
                      }
                      else if (set.rbScope == 4) { // folder and subfolders
                          inddFiles = GetAllInddFiles(inddFolder);
                      }
                  
                      if (inddFiles.length == 0) ErrorExit("Found no InDesign documents in the selected folder.", true);
                      ProcessAllInddDocs(inddFiles);
                  }
                  
                  progressWin.close();
                  var endTime = new Date();
                  var duration = GetDuration(startTime, endTime);
                  var report = count + ((count == 1) ? " document was" : " documents were") + " processed.\n(time elapsed: " + duration + ")";
              
                  if (set.log) {
                      arr.push("\r=========================================================\r" + report + "\r=========================================================\r\r\r");
                      var text = arr.join("\r");
                      WriteToFile(text);
                  }
                  
                  alert("Finished. " + report, scriptName);
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function ProcessAllInddDocs(inddFiles) {
                  startTime = new Date();
                  if (set.log) {
                      arr.push(GetDate());
                      if (set.rbScope == 2) arr.push("Book name: " + app.activeBook.name);
                  }
              
                  progressWin.show();
                  var pbCounter = 0;
                  progressBar.minvalue = 0;
                  progressBar.maxvalue = inddFiles.length;
                  
                  for (var i = 0; i < inddFiles.length; i++) {
                      try {
                      inddFile = inddFiles[i];
                      progressBar.value = pbCounter++;
                      progressTxt.text = "Processing file - " + inddFile.displayName;
                      
                      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
                      doc = app.open(inddFile);
                      app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
                      ProcessDocument(doc, subFolders);
                      doc.close(SaveOptions.YES);
                      }  
                      catch(err) {  
                          $.writeln(err.message + ", line: " + err.line);  
                      } 
                  }
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function ProcessDocument(doc) {
                  if (doc.name.match(/^Backup_/) != null) return; // Skip backups    
                  if (set.log) arr.push("\r------------------------------------------\rDocument name: " + doc.name + "\rDocument path: " + File(doc.filePath).fsName + "\r");
              
                  if (set.backUp) { // Create a backup copy
                      var file = new File(doc.filePath.absoluteURI + "/Backup_" + doc.name);
                      if (file.exists) { // Don't overwrite existing files
                          var increment = 1;
                          while (file.exists) {
                              file = new File(doc.filePath.absoluteURI + "/Backup_" + increment++ + "_" + doc.name);
                          }
                      }
                      doc.fullName.copy(file.fsName);
                  }
              
                  count++;
                  RunScripts();
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function RunScripts() {
                  var jsxFile;
                  
                  if (set.rbScript == 0) {
                      app.doScript(scriptFile, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "\"" + scriptName + "\" Script");
                      if (set.log) arr.push("Script: " + scriptFile.displayName);
                  }
                  else {
                      var jsxFiles = scriptFolder.getFiles("*.jsx");
                      if (set.log) arr.push("Scripts:");
                      
                      for (var i = 0; i < jsxFiles.length; i++) {
                          jsxFile = jsxFiles[i];
                          app.doScript(jsxFile, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "\"" + scriptName + "\" Script");
              
                          if (set.log) arr.push("  " + jsxFile.displayName);
                      }
                  }
              
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetAllInddFiles(folder) {
                  var files = [],
                  fileList = folder.getFiles(),
                  i, file;
                  
                  for (i = 0; i < fileList.length; i++) {
                      file = fileList[i];
                      if (file instanceof Folder) {
                          files = files.concat(GetAllInddFiles(file));
                      }
                      else if (file instanceof File && file.name.match(/\.indd$/i)) {
                          files.push(file);
                      }
                  }
              
                  return files;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetSubFolders(folder) {
                  var file,
                  fileList = folder.getFiles();
                  
                  for (var i = 0; i < fileList.length; i++) {
                      file = fileList[i];
                      
                      if (file instanceof Folder) {
                          subFolders.push(file.fsName);
                          GetSubFolders(file);
                      }
                  }
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetArrayIndex(arr, val) {
                  for (var i = 0; i < arr.length; i++) {
                      if (arr[i] == val) {
                          return i;
                      }
                  }
                  return -1;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetFilesFromBook() {
                  var bookContent, file,
                  activeBook = app.activeBook,
                  files = [];
                  
                  for (var i = 0; i < activeBook.bookContents.length; i++) {
                      bookContent = activeBook.bookContents[i];
                      if (bookContent.status != BookContentStatus.MISSING_DOCUMENT) {
                          file = new File(bookContent.fullName);
                          files.push(file);
                      }
                  }
                  
                  return files;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function CreateDialog() {
                  var jsxFiles;
              //~     app.insertLabel("Kas_" + scriptName, "");
                  GetDialogSettings();
                  var isFile = (set.rbScript == 0) ? true : false; // file, or set of scripts in the folder
                  if (scriptFolder != null) {
                      jsxFiles = scriptFolder.getFiles("*.jsx");
                  }
              
                  var w = new Window("dialog", scriptName);
                  
                  w.p1 = w.add("panel", undefined, "Process:");
                  w.p1.orientation = "column";
                  w.p1.alignment = "fill";
                  w.p1.alignChildren = "left";
                  
                  // Scope
                  w.p1.rb0 = w.p1.add("radiobutton", undefined, "active document");
                  if (app.documents.length == 0) w.p1.rb0.enabled = false;
                  w.p1.rb1 = w.p1.add("radiobutton", undefined, "all open documents");
                  if (app.documents.length < 2) w.p1.rb1.enabled = false;
                  w.p1.rb2 = w.p1.add("radiobutton", undefined, "active book");
                  if (app.books.length == 0) w.p1.rb2.enabled = false;
                  w.p1.rb3 = w.p1.add("radiobutton", undefined, "documents in the selected folder");
                  w.p1.rb4 = w.p1.add("radiobutton", undefined, "documents in the selected folder and its subfolders");
              
                  
                  if (set.rbScope == 0 && app.documents.length != 0) { // active document
                      w.p1.rb0.value = true;
                  }
                  else if (set.rbScope == 1 && app.documents.length > 1) { // all open documents
                      w.p1.rb1.value = true;
                  }
                  else if (set.rbScope == 2 && app.books.length != 0) { // active book
                      w.p1.rb2.value = true;
                  }
                  else if (set.rbScope == 3) { // documents in the selected folder
                      w.p1.rb3.value = true;
                  }
                  else  { // documents in the selected folder and its subfolders
                      w.p1.rb4.value = true;
                  }
              
                  // What to run
                  w.p3 = w.add("panel", undefined, "What to run:");
                  w.p3.alignChildren = "left";
                  w.p3.alignment = "fill";
                  w.p3.rb0 = w.p3.add("radiobutton", undefined, "single script");
                  w.p3.rb0.onClick = UpdatePanel;
                  w.p3.rb1 = w.p3.add("radiobutton", undefined, "set of scripts");
                  w.p3.rb1.onClick = UpdatePanel;
              
                  function UpdatePanel() { // clicking a radio button switches between "scipt" and "set of scripts"
                      var fileObj;
              
                      if (this.text == "single script") {
                          isFile = true;
                          fileObj = scriptFile;
                          w.p4.text = "Script:";
                          
                          if (fileObj == undefined || !fileObj.exists) {
                              w.p4.st.text = "No file has been selected";
                          }
                      }
                      else {
                          isFile = false;
                          fileObj = scriptFolder;
                          w.p4.text = "Folder with scripts:";
                          
                          if (fileObj == undefined || !fileObj.exists) {
                              w.p4.st.text = "No folder has been selected";
                          }
                      }
                      
                      UpdateWindow(fileObj);
                  }
                  
                  if (isFile) {
                      w.p3.rb0.value = true;
                  }
                  else  {
                      w.p3.rb1.value = true;
                  }
                  
                  var fileObj = (isFile) ? scriptFile : scriptFolder;
                  
                  // Scripts folder or a script panel
                  w.p4 = w.add("panel", undefined, ((isFile) ? "Script:": "Folder with scripts:"));
                  w.p4.alignment = "fill";
                  w.p4.st = w.p4.add("statictext");
                  if (fileObj == undefined || !fileObj.exists) {
                      w.p4.st.text = "No " + ((isFile) ? "file": "folder") + " has been selected";
                  }
                  else {
                      w.p4.st.text = TrimPath(fileObj.fsName);
                      w.p4.st.helpTip = fileObj.fsName;
                  }
              
                  w.p4.bt = w.p4.add("button", undefined, "Select...");
                  w.p4.bt.onClick = Select;
                  
                  function Select() {
                      if (isFile) {
                          scriptFile = File.openDialog("Pick a script", "*.jsx");
                          if (scriptFile != null) {
                              UpdateWindow(scriptFile);
                          }
                      }
                      else {
                          scriptFolder = Folder.selectDialog("Pick a folder with scripts");
                          
                          if (scriptFolder != null) {
                              jsxFiles = scriptFolder.getFiles("*.jsx");
                              if (jsxFiles.length == 0) {
                                  alert("There are no scripts in the selected folder.", scriptName, true);
                                  scriptFolder = undefined;
                                  w.p4.st.text = "No " + ((isFile) ? "file": "folder") + " has been selected";
                              }
                              else {
                                  UpdateWindow(scriptFolder);
                              }
                          }
                      }
                  }
              
                  function UpdateWindow(fileObj) {
                      if (fileObj != null && fileObj.exists) {
                          w.p4.remove(w.p4.st);
                          w.p4.remove(w.p4.bt);
                          w.p4.st = w.p4.add("statictext");
                          w.p4.st.text = TrimPath(fileObj.fsName);
                          w.p4.st.helpTip = fileObj.fsName;
                          w.p4.bt = w.p4.add("button", undefined, "Select...");
                          w.p4.bt.onClick = Select;
                          w.layout.layout(true);
                      }
                  }
              
                  w.p2 = w.add("panel", undefined, "Settings:");
                  w.p2.alignChildren = "left";
                  w.p2.alignment = "fill";
                  
                  // Checkboxes
                  w.p2.cb1 = w.p2.add("checkbox", undefined, "Create log file on the desktop");
                  w.p2.cb1.alignment = "left";
                  w.p2.cb1.value = set.log;
                  
                  w.p2.cb3 = w.p2.add("checkbox", undefined, "Backup original InDesign documents");
                  w.p2.cb3.alignment = "left";
                  w.p2.cb3.value = set.backUp;
                  
                  // Buttons
                  w.buttons = w.add("group");
                  w.buttons.orientation = "row";   
                  w.buttons.alignment = "center";
                  w.buttons.ok = w.buttons.add("button", undefined, "OK", {name:"ok" });
                  w.buttons.cancel = w.buttons.add("button", undefined, "Cancel", {name:"cancel"});
                  
                  var showDialog = w.show();
                  
                  if (showDialog == 1) {
                      set.log = w.p2.cb1.value;
                      set.backUp = w.p2.cb3.value;
                      
                      if (w.p1.rb0.value == true) {
                          set.rbScope = 0;
                      }
                      else if (w.p1.rb1.value == true) {
                          set.rbScope = 1;
                      }
                      else if (w.p1.rb2.value == true) {
                          set.rbScope = 2;
                      }
                      else if (w.p1.rb3.value == true) {
                          set.rbScope = 3;
                      }
                      else if (w.p1.rb4.value == true) {
                          set.rbScope = 4;
                      }
                  
                      if (w.p3.rb0.value == true) {
                          set.rbScript = 0;
                      }
                      else if (w.p3.rb1.value == true) {
                          set.rbScript = 1;
                      }
                      
                      if (isFile) { // File
                          if (scriptFile == undefined) ErrorExit("No script has been selected", scriptName, true);
                          if (!scriptFile.exists) ErrorExit("Script '" + scriptFile.displayName + "' doesn't exist.", scriptName, true);
                          
                          if (scriptFile instanceof File) {
                              set.scriptFilePath = scriptFile.fsName;
                          }
                          else {
                              set.scriptFilePath = null;
                          }
                      }
                      else { // Folder
                          if (scriptFolder == undefined) ErrorExit("No  folder with scripts has been selected", scriptName, true);
                          if (!scriptFolder.exists) ErrorExit("Folder '" + scriptFolder.displayName + "' doesn't exist.", scriptName, true);
                          if (jsxFiles == undefined || jsxFiles.length == 0) ErrorExit("There are no scripts in the scripts folder.", scriptName, true);
                          
                          if (scriptFolder instanceof Folder) {
                              set.scriptFolderPath = scriptFolder.fsName;
                          }
                          else {
                              set.scriptFilePath = null;
                          }            
                      }
              
                      app.insertLabel("Kas_" + scriptName, set.toSource());
                      
                      Main();
                  }
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetDialogSettings() {
                  set = eval(app.extractLabel("Kas_" + scriptName));
                  
                  if (set == undefined) {
                      set = { rbScope: 0, rbScript: 0, log: true, backUp: true };
                  }
                  else {
                      scriptFile = new Folder(set.scriptFilePath);
                      scriptFolder = new Folder(set.scriptFolderPath);
                  }
              
                  var tmp = set;
                  return set;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function CreateProgressBar() {
                  progressWin = new Window("window", scriptName); // global
                  progressBar = progressWin.add("progressbar", [12, 12, 350, 24], 0, undefined); // global
                  progressTxt = progressWin.add("statictext"); // global
                  progressTxt.bounds = [0, 0, 340, 20];
                  progressTxt.alignment = "left";
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetDuration(startTime, endTime) {
                  var str;
                  var duration = (endTime - startTime)/1000;
                  duration = Math.round(duration);
                  if (duration >= 60) {
                      var minutes = Math.floor(duration/60);
                      var seconds = duration - (minutes * 60);
                      str = minutes + ((minutes != 1) ? " minutes, " :  " minute, ") + seconds + ((seconds != 1) ? " seconds" : " second");
                      if (minutes >= 60) {
                          var hours = Math.floor(minutes/60);
                          minutes = minutes - (hours * 60);
                          str = hours + ((hours != 1) ? " hours, " : " hour, ") + minutes + ((minutes != 1) ? " minutes, " :  " minute, ") + seconds + ((seconds != 1) ? " seconds" : " second");
                      }
                  }
                  else {
                      str = duration + ((duration != 1) ? " seconds" : " second");
                  }
              
                  return str;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function GetDate() {
                  var date = new Date();
                  if ((date.getYear() - 100) < 10) {
                      var year = "0" + new String((date.getYear() - 100));
                  }
                  else {
                      var year = new String((date.getYear() - 100));
                  }
                  var dateString = (date.getMonth() + 1) + "/" + date.getDate() + "/" + year + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
                  return dateString;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function TrimPath(path) {
                  var theFile = new File(path);
                  if (File.fs == "Macintosh") {
                      var trimPath = "..." + theFile.fsName.split("/").splice(-3).join("/");
                  }
                  else if (File.fs == "Windows" ) {
                      var trimPath = ((theFile.fsName.split("\\").length > 3) ? "...\\" : "") + theFile.fsName.split("\\").splice(-3).join("\\");
                  }
                  return trimPath;
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function WriteToFile(text) {
                  var file = new File("~/Desktop/" + scriptName + ".txt");
                  file.encoding = "UTF-8";
                  if (file.exists) {
                      file.open("e");
                      file.seek(0, 2);
                  }
                  else {
                      file.open("w");
                  }
                  file.write(text); 
                  file.close();
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              function ErrorExit(error, icon) {
                  alert(error, scriptName, icon);
                  exit();
              }
              //--------------------------------------------------------------------------------------------------------------------------------------------------------
              
              1 person found this helpful
              • 4. Re: Batch process script
                Kasyan Servetsky Level 5

                The forum software is misbehaving, or maybe my previous post was too long.

                I just tested the new version using a folder with 5 files located on a network drive: two of them are open on another machine.

                 

                Before

                I used the three sample 'clean-up' script for testing

                Screenshot 2016-11-24 18.00.47.png

                Screenshot 2016-11-24 18.08.00.png

                After

                Screenshot 2016-11-24 18.01.44.png

                Screenshot 2016-11-24 18.03.31.png

                This is not the final version yet. I have some ideas on improving it: e.g. maybe it makes sense to add an error logging feature so that the user would know why some document weren't processed, like so:

                Cannot open the document “TEST:_Today:Test:Q_1239_005.indd”. You may not have permission or the document may be open already.

                 

                When I make a new version, I'll update it on my site.

                I'm open to suggestions and new ideas: feel free to post them here in this thread.

                 

                — Kas

                • 5. Re: Batch process script
                  damijanl Level 1

                  WOW! This works like charm once error occurs within processing of scripts!

                   

                  One part of my main problem was that once error occured, script will still continue to go ahead not looking back which files it missed processing. I was trying to customize your script with some sleep function of my own, but was not successful to the point of usability.

                   

                  However, i had in mind some upgrade/function in form of check box "Wait for opened files to close" of some sort, and when checked, script would wait/loop till individual file is accessible over network again - and offcourse then properly continue from where it stoped/looped.

                   

                  Offcourse this is problem only when a lot of files and scripts are in question, as it would be very hard to follow which scripts were procesed and on which files. Eventually i will get there with my knowledge/learning, but as always any help is appreciated in this direction till then.

                   

                  Thanks a lot!

                  • 6. Re: Batch process script
                    Kasyan Servetsky Level 5

                    I've made a new version of the batch processor script. It's a major update: eliminated a potential of clashing global variables, added new features. I left a couple of global variables which can be accessed from the scripts executed by the batch processor:

                    1. gEventLog — for events (non-error) messages
                    2. gErrorLog — for error messages

                    Both are arrays of text elements and you can 'push' into them your own messages from your scripts. These messages will appear in the log file on the desktop. See the 'Package' sample script here. I commented out these variables so that the script could be used as a stand alone one. If you outcomment them, you'll see the messages sent from the 'internal' script in the log. In this way, the script should keep working despite whatever error occurs along the way, but you'll be able to track down what and when went wrong in the log.

                     

                    —Kas