Copy link to clipboard
Copied
Hello once again,
Below you can find a link to my previous script issue. This post will provide some background information on our situation.
What we are now looking for, is a script which can find EPS and AI files within a sub-folder and put them into a new sub-sub-folder with a specific name.
The name the sub-sub-folder is similar to the main folder, except that we want to add "_download" at the end of the folder name.
For example: the folder structure looks like this at the moment:
folder > image folder > EPS/AI files
and we want the new folder structure to look like this:
Folder > image folder > image folder_download > EPS/AI files
this script needs to be performed on thousands of sub-folders within the main image folder.
i hope this makes sense and hope that it's possibility.
thanks in advance for any and all your help.
DJ
Copy link to clipboard
Copied
this is more of a shell script project than an illustrator script project.
In illustrator, scripts don't have access to the file system this way. we can't just move and rearrange files as far as i know (and if we could, it's still probably not the right environment for this task). We can create folders and we can save files into those folders. But as far as i know that's pretty much it.
Copy link to clipboard
Copied
I'd definitly use Node or CLI instead but technically you can write and execute BAT and other CLI syntax files from scripting. At the point you're doing this though, you may as well just execute the file from somewhere else, but if it's necessary as some step within a pre-existing script I can understand why there's a need:
var text = """echo You can execute batch files from JSX
pause""";
var file = File(Folder.desktop + "/test.bat");
file.open("w");
file.write(text);
file.close();
var result = file.execute();
alert(result); // Returns true if successful
When you run this, a BAT file is written to desktop and then scripting will execute it (or simulate a double-click action, so if it doesn't work via double-click you need to set up file associations), you should see a terminal window pop up and you can run shell commands this way. An issue with doing this is that the terminal will inherit OS focus -- Illustrator loses focus. Even if the last line is "exit" to close the terminal window, you still tend to lose program focus (that may not be an issue for you but it's an important distinction because it means you can't easily sandwich shell commands into normal scripts with seamless transitions).
Copy link to clipboard
Copied
Though now that I'm thinking about it, you could probably do this through a combination of Folder.getFiles() and File.changePath() without needing a shell command at all.
Copy link to clipboard
Copied
I thought this would be easy but for some reason I can't get the filepath change working. I can't actually find any example of File.changePath() online -- it says a string, but it doesn't say if it needs encodeURI or as a File Object, as plaintext, etc. I've tried all of these and the method returns "true" which it only should if there are no errors (nothing in try/catch either), so the below doesn't work but this would be relatively close once you can figure out the File.changePath part:
var ROOT_STR = Folder.desktop + "/image folder"
var TARGET_STR = Folder.desktop + "/image folder/image folder_download";
var ROOT = Folder(ROOT_STR);
var TARGET = Folder(TARGET_STR);
TARGET.create();
var children = ROOT.getFiles(/.(svg|ai)$/);
for (var i = 0; i < children.length; i++) {
var child = children[i];
var newPath = decodeURI(child).replace(ROOT_STR, TARGET_STR);
var result = File(child).changePath(newPath);
alert(result) // Returns true, but incorrectly! Files never move.
}
Copy link to clipboard
Copied
So I've sat here for 10 minutes, trying every variation I can think of including a ton of relative filepath syntax variations. I've noticed that File.changePath always returns true but never actually works.
I'm tempted to say that it's a broken method in the API, but I might still be using it incorrectly. Can someone confirm or correct me here?
Copy link to clipboard
Copied
https://aenhancers.com/viewtopic.php?t=1328
try this. changePath doesn't do what you think it's supposed to do (though i don't fully understand what it is supposed to do either).
Copy link to clipboard
Copied
Hmmm, okay. Yeah that doesn't seem nearly as useful as the description implies and I'm clearly not the only one who read it as a Node fs.rename() equivalent to move a file from one path to another, but does give working results.
This is only for one folder but you'd be able to apply this logic to some root folder, then perform this snippet on each descendent folder (though I include hard-coded strings here, you'd just concatenate "_download" to the parent):
// Designate paths to root folder and the folder we want to collect inside
var ROOT_STR = Folder.desktop + "/image folder"
var TARGET_STR = Folder.desktop + "/image folder/image folder_download";
// Create native Classes and the subfolder
var ROOT = Folder(ROOT_STR);
var TARGET = Folder(TARGET_STR);
TARGET.create();
// Grab all svg and ai files via regex mask
var children = ROOT.getFiles(/\.(svg|ai)$/);
// Iterate through all valid matches
for (var i = 0; i < children.length; i++) {
// Create a file Class specific to this match
var child = File(children[i]);
// Copy the file to a new location
child.copy(
encodeURI(
decodeURI(children[i]).replace(ROOT_STR, TARGET_STR)
)
);
// Then remove the file from the original location
child.remove();
};
Can't say I'd trust AI to do this very efficiently with 1k folders in scripting to begin with to be honest, I'd expect it to crash the app.
Copy link to clipboard
Copied
I agree, changePath is false advertising hahaha, it drove me nuts when I needed to used it. I ended up doing what you guys posted above.
here's changePath() usage for posterity
// changePath() usage
var mainFolder = Folder("~/desktop/image folder");
mainFolder.create();
var ref1 = Folder(mainFolder + "/subfolder1");
ref1.create();
var ref2 = Folder(mainFolder + "/subfolder2")
ref2.create();
$.writeln(ref1.fullName); // ~/desktop/image folder/subfolder1
ref1.changePath (ref2.fullName); // this changes the Referenced Folder's path (or Variable's path) not the actual folder
$.writeln(ref1.fullName); // ~/desktop/image folder/subfolder2
ref1.remove(); // remove ref1 which now points to subfolder2
$.writeln(ref1.fullName); // ~/desktop/image folder/subfolder2
$.writeln(ref1.exists); // false, ref1 does not point to subfolder1 anymore
Copy link to clipboard
Copied
what's the use case and/or benefits of this method? Does this do anything different than just saying
ref1 = Folder("some/path/");
ref2 = Folder("some/other/path");
ref1 = Folder(ref2.fullName);
?
Copy link to clipboard
Copied
I don't see the purpose of it honestly.
Copy link to clipboard
Copied
it's more characters to type "changePath" than "Folder" and the argument is the same. i wonder if there's some deeper memory related reason why it's better to not overwrite the variable? certainly wouldn't be the first memory related script issue.
Copy link to clipboard
Copied
The only use case I can think of for this is if you have a specific File or Folder object that you need to duplicate then change the original reference path of the duplicate, but I don't think I've ever needed that before.
Copy link to clipboard
Copied
me neither, I always use the same variable name, I just update the folder reference by building a new path and re assigning it to the variable I need.
The only time I've wanted to use changePath() is when I thought it would move a file to a different folder, which it didn't.
Copy link to clipboard
Copied
Hi Guys,
I just thought of a possible solution to this issue. What if we use the previous script and add this extra steps to the end? Could the script create the new folder and export the EPS/AI file into this file? Or is all this too much?
function main() {
var inputFolder = Folder.selectDialog("Select a folder to process")
if (inputFolder != null){
var fileandfolderAr = scanSubFolders(inputFolder, /\.(ai|eps)$/i);
var fileList = fileandfolderAr[0];
}
for (var i = fileList.length-1; i >= 0; i--) {
app.open(fileList[i]);
var doc = app.activeDocument;
try {
var docLayers = doc.layers;
var n = docLayers.length;
docLayers[n-1].visible = true;
docLayers[n-1].locked = false;
docLayers[n-1].remove();
doc.save();
doc.close(SaveOptions.NO);
} catch (e) {
}
}
}
main()
function scanSubFolders(tFolder, myAI) {
var sFolders = [];
var allFiles = [];
sFolders[0] = tFolder;
for (var j = 0; j < sFolders.length; j++) {
var procFiles = sFolders[j].getFiles();
for (var i = 0; i < procFiles.length; i++) {
if (procFiles[i] instanceof File) {
if(myAI == undefined) {
allFiles.push(procFiles);
}
if (procFiles[i].fullName.search(myAI) != -1) {
allFiles.push(procFiles[i]);
}
}
else if (procFiles[i] instanceof Folder) {
sFolders.push(procFiles[i]);
scanSubFolders(procFiles[i], myAI);
}
}
}
return [allFiles, sFolders];
}