I have created a script to be used with the Event Scripter extension of JDownloader 2. There are many requests around the web for how to automatically call Filebot when a download is finished in JD2. However I have never come across a satisfying solution, so I created one myself.
It relies on JD2 to extract archives (beaucse of the built in password "cracker") and then runs the AMC script on the extracted files. If it detects nested archives, it will skip processing until the actually relevant files are extracted. After successful renaming, the cleaner script will be called on the base directory of the package, to get rid of empty folders higher up in the hierarchy. It kind of relies on you downloading your stuff into separate folders for each package, but it should work either way.
There are a few options at the top of the script you need to customize and then you should be good to go. Just set up a script to be triggered on the "Archive Extraction Finished" event in JD2 and paste the code:
Code: Select all
var command = "filebot"; // Change this if filebot isn't on your path
var logfile = "C:/log/jdownloader-eventscripter.log"; // File this script logs to. Use forward slashes as path separators!
var filebotLogfile = "C:/log/filebot.log"; // File that filebot will log to. Use forward slashes as path separators!
var downloadBase = "D:\\Downloads"; // Base folder under which your download packages reside. Use escaped backslashes as path separators!
var archiveExtensions = /(\.(zip|rar|7z|par\d+|part\d+|r\d+|t\d+|\d{3}))$/; // Regex to test for nested archives in extracted files
// Parameters for the scripts to run
var params = {
"rename" : {
"options" : {
"-script": "fn:amc",
"--log-file": filebotLogfile,
"--action": "move",
"--conflict": "auto"
},
"defs" : {
"plex": "ZEUS",
"unsorted": "y",
"skipExtract": "y",
"clean": "y",
"minFileSize": "104857600",
"excludeList": "C:/Util/amc-input.txt",
"seriesFormat": "D:/Serien/{n}/{'Season '+s}/{n} - {s00e00} - {t}",
"movieFormat": "D:/Filme/{n} ({y}) [{vf}]/{n} ({y}) [{vf}]"
},
"switches" : [
"-non-strict"
]
},
"cleaner" : {
"options" : {
"-script": "fn:cleaner",
"--log-file": filebotLogfile
},
"defs" : {
"root" : "y"
},
"switches" : []
}
}
var logBuf = "";
function log(message) {
logBuf += new Date().toISOString().slice(0, 19) + " - " + message + "\r\n";
}
function logArray(message, arr) {
log("\t" + message);
if (arr == null) {
log("\t\tnone");
return;
}
for (var i = 0; i < arr.length; i++) {
log("\t\t" + arr[i]);
}
}
function logSpacer() {
log("++++++++++++++++++++++++++++++");
}
function flushLog() {
// Comment out the next two lines to prevent log from being written to file
writeFile(logfile, logBuf, true);
logBuf = "";
}
function quoteIfNecessary(value) {
return (value != null && value.indexOf("\"") < 0) ? '"' + value + '"' : value;
}
function quoteArrayElements(input) {
var result = [];
for (var i = 0; i < input.length; i++) {
result[result.length] = quoteIfNecessary(input[i]);
}
return result;
}
function reduce(map, joinChar) {
var keyValuePairs = [];
for (var key in map) {
keyValuePairs[keyValuePairs.length] = key + joinChar + map[key];
}
return keyValuePairs;
}
function mapToArray(map) {
var array = [];
for (var key in map) {
array[array.length] = key;
array[array.length] = map[key];
}
return array;
}
function createArgumentArray(parameters, inputs) {
var options = mapToArray(parameters["options"]);
var switches = parameters["switches"];
var defs = reduce(parameters["defs"], "=");
return [command].concat(options).concat(switches).concat(inputs).concat(["--def"]).concat(defs);
}
function isArchiveFile(filename) {
return archiveExtensions.test(filename);
}
function containsNestedArchive(extractedFiles) {
for (var i = 0; i < extractedFiles.length; i++) {
if (isArchiveFile(extractedFiles[i])) {
return true;
}
}
return false;
}
function getPackageRoot(folder) {
return folder.substring(0, folder.indexOf("\\", downloadBase.length + 1));
}
var archiveFolder = archive.getFolder();
var archiveName = archive.getName();
var archiveType = archive.getArchiveType();
var extractedFiles = archive.getExtractedFiles();
var archiveUID = archiveFolder + "\\" + archiveName;
var packageRoot = getPackageRoot(archiveFolder);
logSpacer();
log("FINISHED EXTRACTION - " + archiveUID);
log("\tType: " + archiveType);
log("\tPackage root: " + packageRoot);
logArray("Extracted files:", extractedFiles);
if (extractedFiles == null || extractedFiles.length == 0) {
log("SKIPPING - No files extracted.");
} else if (containsNestedArchive(extractedFiles)) {
log("SKIPPING - Nested archive detected.");
} else {
var renameInputs = quoteArrayElements(extractedFiles);
var renameArgs = createArgumentArray(params["rename"], renameInputs);
log("RUNNING SCRIPT - " + archiveUID);
callAsync(
function(exitCode, stdOut, errOut) {
if (exitCode == 0) {
log("SUCCESS - " + archiveUID);
var cleanerArgs = createArgumentArray(params["cleaner"], packageRoot);
log("CLEANING - " + packageRoot);
callAsync(
function(exitCode, stdOut, errOut) {
if(exitCode == 0) {
log("ALL CLEAN - " + packageRoot);
} else {
log("STILL DIRTY - " + packageRoot);
}
flushLog();
},
cleanerArgs
);
} else {
log("ERROR - " + archiveUID + " - Code " + exitCode);
}
flushLog();
},
renameArgs
);
}
logSpacer();
flushLog();
I hope this script helps some of you people, it certainly worked like a charm for me
