TDIing out loud, ok SDIing as well

Ramblings on the paradigm-shift that is TDI.

Thursday, February 27, 2025

Finalized solution

 Here comes my (til now) final solution for scanning folders recursive and setting the create date for files found. Let me know if you see any problems :) And let me know in the comments if you'd like more.

---

// 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);

}


var supportedExtentions = {

dv: true,

jpg: true,

avi: true, 

mpg: true,

mp4: true,

psd: true

}

function supportedType(fileName) {

var parts = system.splitString(fileName, ".");

if (parts.length <= 1) return true;

for (var ext in supportedExtentions) {

if (ext.equalsIgnoreCase(parts[parts.length-1].trim())) return true

}

return false

}


// 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 (supportedType(fileName)) {

var dateString = system.formatDate(new java.util.Date(), "YYYYMMDD HH:mm:ss.SSSZ");

fileListObject[file.getPath()] = {

date: dateString,

name: fileName,

folder: folderName

}

}

}

}


return fileListObject

}


function setCreateDate(fromPath) {

var regexForDates = /(\d{4})\D(\d{2})\D(\d{2})(?:_(\d{4})\D(\d{2})\D(\d{2}))?/;

var regexForSingleDate = /(\d{4})\D(\d{2})$/;

var filesObj = getFiles(fromPath, {});

var Runtime = java.lang.Runtime;

// First count the files in each folder, saving this total

var fileCount = {};

var filesAL = new java.util.ArrayList();

for (var fullPath in filesObj) {

var file = filesObj[fullPath];

fileCount[file.folder] = (fileCount[file.folder] || 0) + 1

filesAL.add(fullPath);

}

var sortedFullPaths = filesAL.toArray();

java.util.Arrays.sort(sortedFullPaths);

var filesHandled = {};

var match = null;

var lastFolder = "";

for (var fullPath in sortedFullPaths) {

var file = filesObj[fullPath];


match = file.folder.match(regexForDates);

if (!match) { // Try just looking for yyyy-MM

match = file.folder.match(regexForSingleDate)

}

if (!match) continue; // No date found

// Increment the file count for this folder

filesHandled[file.folder] = (filesHandled[file.folder] || 0) + 1;


// Parse out the dates matched in the folder name

var dates = makeDates(match)

/*

task.logmsg(LJ(file.folder,25) + " -> " 

+ LJ(system.formatDate(dates.first, "YYYY.MM.dd"), 10) + "  _  " 

+ system.formatDate(dates.second, "YYYY.MM.dd"));

*/

var dateCreated = calcDate(dates.first, dates.second, filesHandled[file.folder], fileCount[file.folder], file.folder);


// Construct PowerShell command

var psCommand = 'powershell.exe -Command "Set-ItemProperty -Path \'' + fullPath + '\' -Name CreationTime -Value \'' + dateCreated + '\'"';


// Execute the command using Java Runtime

var process = Runtime.getRuntime().exec(psCommand);

// Wait for the process to complete

process.waitFor();

// Log the output

if (file.folder != lastFolder) {

task.logmsg("");

lastFolder = file.folder

}

task.logmsg("    >" + psCommand);

//task.logmsg("DateCreated set for: " + LJ(fullPath, 80) + " to " + dateCreated);

}

}


// Calculate the date between the first and second passed, based on total/index*100 (pct)

function calcDate(firstDate, secondDate, index, total, folder) {

    var pct = index / total;

    var diff = secondDate.getTime() - firstDate.getTime();

    var retDate;


    if (index == 1) {

        retDate = firstDate; // First index = firstDate

    } else if (index == total) {

        retDate = secondDate; // Last index = secondDate

    } else {

        retDate = new java.util.Date(firstDate.getTime() + (diff * pct));

    }

/*


if (index == 1) task.logmsg("");

task.logmsg("-----------------> " + LJ(folder, 25) + "   "

+ LJ(index + "/" + total, 10) + LJ(Math.round(pct*100) + "%", 8)

+ "   --   " + LJ(firstDate.toString(), 8) + " <<  " 

+ LJ(retDate.toString(), 8)

+ " << " + LJ(secondDate.toString(), 8));

*/

    return retDate;

}


// Left justified text

function LJ(txt, len) {

txt = txt || "";

len = len || txt.length;

return (txt + "                                                                                                       ").substring(0, len)

}


// Converts string to an int

function toInt(str, defVal) {

var intVal;

try {

intVal = system.toInt(str)

} catch (notAnIntException) {

intVal = defVal

}

return intVal

}


// The mc argument is the array resulting from doing a regex .match against the folder name

// It expects 1 date string in the format YYYY.MM.DD, possibly a second 

// In the first case, match will have a length of 4. If two are found, the length will be 7

function makeDate(mc, whichOne) {

var offset = (whichOne == 1) ? 0 : 3;


var year = toInt(mc[1 + offset] || mc[1]);

var month = toInt(mc[2 + offset] || mc[2] || 1);

var day = toInt(mc[3 + offset] || mc[3] || 15)


var cal = java.util.Calendar.getInstance();


cal.set(year, month - 1, day);

return cal.getTime()

}


// Returns an object with first and second date properties

// The mc argument is the array resulting from doing a regex .match against the folder name

function makeDates(mc) {

return {

first: makeDate(mc, 1),

second: makeDate(mc, 2)

}

}