TDIing out loud, ok SDIing as well

Ramblings on the paradigm-shift that is TDI.

Saturday, February 22, 2025

Couple of handy functions to share

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: