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)
}
}