First, I wanted to scan a folder and all sub-folders and return a JS object that reflected files found. The reason I often use JS objects to carry data is that they work beautifully and simply with the Javascript for-loop.
Here's what I got working:
// Recursive function to spin through a folder (java.io.File or String)
// and sub-folders and return a JS fileListObject. Each property of the object
// is a sub-object with its property name being the path to the file,
// ensuring uniqueness for property names. Each object has the following three properties:
//
// "\\FilesToFix\\Clip 08.dv": {
// "folder": "FilesToFix",
// "name": "Clip 08.dv",
// "date": "20021224 18:34:18.953+0100"
// }
//
// JS Objects are handy carriers of objects, and can be any primitive
// Ecmascript 3 type or a Java object, like an Entry, Attribute or java.util.HashMap.
//
function getFiles(folder, fileListObjectArg) {
// Initialize the object if not passed in
var fileListObject = fileListObjectArg || {};
// If the folder name pass passed in, convert it to a File object
if (typeof(folder == "string")) {
var useFolder = new java.io.File(folder);
if (!useFolder) throw "Cannot open folder: " + folder;
folder = useFolder
}
// Get the folder name and list of files in it
var folderName = folder.getName();
var fileList = folder.listFiles();
// If any files found, run through the returned list of java.io.File objects
if (fileList) {
for (file in fileList) {
var fileName = file.getName();
// If it's a directory then call this function recursively,
// passing in the current state of the fileListObject
if (file.isDirectory()) {
getFiles(file, fileListObject);
} else
if (fileName.trim().toLowerCase().endsWith(".dv")) {
var dateString = system.formatDate(new Date(),
"YYYYMMDD HH:mm:ss.SSSZ");
fileListObject[file.getPath()] = {
date: dateString,
name: fileName,
folder: folderName
}
}
}
}
return fileListObject
}
I am able to use a JS Object as a data carrier (think Entry holding Attributes, just lighter) as long as each property that I add has a unique name, and using the filepath as the property's name ensures that.
To easily check the results of this function, I translated a nice Java example that I found on Stacktrace for beautifying JSON, and viĆ³la:
// Pass in JSON string or JS Object, it is returned as beautified JSON
//
function prettyJSON(jsonString) {
// If object is passed, convert it to a jsonString
if (typeof(jsonString) == "object") {
jsonString = toJson(jsonString)
}
// Import Java classes
var ObjectMapper = new Packages.com.fasterxml.jackson.databind.ObjectMapper;
// Now get an Object Mapper
var objectMapper = new ObjectMapper();
// Need to use ObjectMapper to create our JS Object here
var jsonObject = objectMapper.readValue(jsonString, java.lang.Object);
// Return the beautified code
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject);
}
The reason I am doing all this is that I have gigabytes of old pictures and movies that I (thankfully) sorted into folders and with date info captured in the folder names.
Now, I would like to run through my gigabytes of files and set the Date Created metadata value based on the date encoded in the enclosing folder's name. Then I can more easily import them into my main photos library and they will get sorted into the timeline correctly.
My testing code looks like this:
var filesListObj = getFiles("\\FilesToFix", {});
task.logmsg(prettyJSON(filesObj));
// Run through the filesListObj
for (var fileName in filesListObj) {
var file = filesListObj[fileName];
task.logmsg("--> " + fileName
+ " date: " + file.date
+ " folder: " + file.folder
+ " name: " + file.name)
I'll stop here for now and starting thinking about how to set the Date Created metadata for each file I process. Maybe the TDI LabJam GPT has suggestions.
Until next time.
No comments:
Post a Comment