Copy link to clipboard
Copied
Hey y'all,
I'd like to start by acknowledging that using ExtendScript for data collection might not be ideal, but it's currently my only option. My task is to gather metadata labeled "Plates" from Adobe files. Previously, the process involved manually copying and pasting details from over 50,000 files. Thankfully, I've managed to reduce this to a 22-hour task using the script below. However, I'm encountering an issue while the script runs. An unrelated error message keeps popping up during the script's execution, requiring manual confirmation by clicking 'OK' each time. As a temporary workaround, we've resorted to keeping the Enter key pressed down, but obviously, we're looking for a more efficient solution for our next round of data collection.
Does anyone have any suggestions? I was exploring the possibility of using 'app.preferences.setBooleanPreference' to bypass this, but haven't found a way to make it effective. Any advice would be greatly appreciated.
// Main function to control the flow of operations
function main() {
processFilesInFolder('D:/files','~/Downloads/Plates Metadata.txt','.pdf');
}
// Function to extract and save plate names from the document's XMP metadata
function extractAndSavePlateNames(logLoc) {
try {
if (app.documents.length === 0) {
throw new Error("No document open");
}
var doc = app.activeDocument;
var xmpString = doc.XMPString;
var xmpXML = new XML(xmpString);
var plateNamesXML = xmpXML..*::PlateNames.*::Seq.*::li;
if (plateNamesXML.length() === 0) {
throw new Error("No plate names found in the document's XMP metadata.");
}
var excludePlates = {"Cyan": true, "Magenta": true, "Yellow": true, "Black": true};
var plateNames = [];
for each (var plateName in plateNamesXML) {
var name = plateName.text().toString();
if (!excludePlates[name]) {
plateNames.push(name);
}
}
var file = new File(logLoc);
file.open(file.exists ? "a" : "w");
file.write(plateNames.join("\n"));
file.write("\n");
file.close();
} catch (e) {
alert("Error in extractAndSavePlateNames function: " + e.message);
}
}
// Function to process each file in the specified folder
function processFilesInFolder(fileLoc, logLoc, filetype) {
try {
var folderPath = fileLoc;
var folder = new Folder(folderPath);
if (!folder) {
throw new Error("No folder selected");
}
var files = folder.getFiles("*" + filetype);
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file instanceof File) {
var doc = app.open(file);
extractAndSavePlateNames(logLoc);
doc.close(SaveOptions.DONOTSAVECHANGES);
}
}
alert("Done!","Keaton wuz here");
} catch (e) {
alert("Error in processFilesInFolder function: " + e.message);
}
}
// Run the main function
main();
Add this line at the very beginning of your script:
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
You can undo this by adding this line after your main() function:
app.userInteractionLevel = UserInteractionLevel.DISPLAYALERTS;
GNDGN's way is sufficient as a solution.
More to the point, there is no need to open the file in the Illustrator GUI to read the metadata; you can read it directly from the file by loading a library called AdobeXMPScript.
Adobe Bridge's JavaScript also makes it relatively easy to read metadata without opening the file in Illustrator.
Copy link to clipboard
Copied
Add this line at the very beginning of your script:
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
You can undo this by adding this line after your main() function:
app.userInteractionLevel = UserInteractionLevel.DISPLAYALERTS;
Copy link to clipboard
Copied
Thank you!
Copy link to clipboard
Copied
GNDGN's way is sufficient as a solution.
More to the point, there is no need to open the file in the Illustrator GUI to read the metadata; you can read it directly from the file by loading a library called AdobeXMPScript.
Adobe Bridge's JavaScript also makes it relatively easy to read metadata without opening the file in Illustrator.
Copy link to clipboard
Copied
This is the route I took! Thank you for leading me down this path!
Here is the code I used:
// Load the XMPScript library
if (ExternalObject.AdobeXMPScript === undefined) {
ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
}
// Main function to control the flow of operations
function main() {
var sourceFolder = new Folder("D:/files");
var targetFile = new File("~/Downloads/Plates_Metadata.txt");
processFilesInFolder(sourceFolder, targetFile);
}
// Function to process each file in the specified folder
function processFilesInFolder(folder, outputFile) {
var files = folder.getFiles();
var unwantedColors = ["Cyan", "Magenta", "Yellow", "Black"];
outputFile.open('w');
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file instanceof File) {
var xmpFile = new XMPFile(file.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_READ);
var xmpPackets = xmpFile.getXMP();
var xmpData = new XMPMeta(xmpPackets.serialize());
var xmpXML = new XML(xmpData.serialize());
var plateNamesXML = xmpXML..*::PlateNames.*::Seq.*::li;
var plateNames = [];
for each (var plateName in plateNamesXML) {
plateNames.push(plateName.toString());
}
var filteredPlateNames = [];
for (var j = 0; j < plateNames.length; j++) {
var isUnwanted = false;
for (var k = 0; k < unwantedColors.length; k++) {
if (plateNames[j] === unwantedColors[k]) {
isUnwanted = true;
break;
}
}
if (!isUnwanted) {
filteredPlateNames.push(plateNames[j]);
}
}
if (filteredPlateNames.length > 0) {
for (var l = 0; l < filteredPlateNames.length; l++) {
outputFile.writeln(filteredPlateNames[l]);
}
}
}
}
outputFile.close();
alert("Metadata extraction complete.");
}
main();
Copy link to clipboard
Copied
That's amazing. What an improvement so quickly.
Copy link to clipboard
Copied
This was able to get the process down to 25 min from 27 days!