// v0.1 - 2016.04.19 // - initial version // TABS feature only (select equal items in src/dst tabs) derived from: // "Compare tabs" -> http://resource.dopus.com/viewtopic.php?f=35&t=21126 // - optional and new comparison method based on md5 hash instead of item names // v0.2 // - Select EXACT // - works with folders // - tested to work in flatview mode // v0.2.1 - 2016.04.21 // - new/changed TABS argument options "by-name", "by-md5" // - options "by-name", "by-md5" define how duplicates are being searched for // - options "name,md5,size,created,modified" define additional "need2match" criterias // v0.2.2 - 2016.04.22 // - more robust comparison in flatview mode // v0.2.3 - 2016.04.22 // - typo fixed // v0.2.4 - 2016.10.03 // - support for ftp locations // v0.2.5 - 2018.07.02 // - add "ignorepaths" option, to compare content in flatviewed tab with subfolders // and regular "flat list of files"-tab containing files without subfolders /////////////////////////////////////////////////////////////////////////////// var template = "" + "TABS/O[,by-md5,name,md5,size,created,modified,invert]," + //shared misc "DESELECTNOMATCH/S,"+ "NOFAIL/S,NODESELECT/S,"+ "XLOG/O[off,xit,error,warning,info,,trace,dump,all]"; /////////////////////////////////////////////////////////////////////////////// function OnInit(data) { //thread url added via script wizard (required for updating) var url = "https://www.haage-partner.de/forum/viewtopic.php?f=45&t=4956"; //uid added via script wizard (do not change after publishing this script) var uid = "E3B155F8-6E8C-4E4F-A466-3381F30EED3C"; data.name = "Command.Generic: CompareEx"; data.desc = "Extended compare functionality."; data.copyright = "tbone"; data.version = "0.2.5"; data.default_enable = true; var cmd = data.AddCommand(); cmd.name = "CompareEx"; cmd.method = "Command_CompareEx"; cmd.label = data.name = "CompareEx"; cmd.desc = data.desc; cmd.template = template; /////////////////////////////////////////////////////////////////////////// function ConfigHelper(data){ //v1.2 var t=this; t.d=data; t.c=data.config; t.cd=DOpus.Create.Map(); t.add=function(name, val, des){ t.l={n:name,ln:name. toLowerCase()}; return t.val(val).des(des);} t.des=function(des){ if (!des) return t; if (t.cd.empty) t.d.config_desc=t.cd; t.cd(t.l.n)=des; return t;} t.val=function(val){ var l=t.l; if (l.v!==l.x&&typeof l.v=="object") l.v.push_back(val);else l.v=t.c[l.n]=val;return t;} t.trn=function(){return t.des(t("script.config."+t.l.ln));}} var cfg = new ConfigHelper(data); /////////////////////////////////////////////////////////////////////////// var cfg = new ConfigHelper(data); cfg.add('XLog', DOpus.Create.Vector()). val(5).val("Off").val("Exception").val("Error").val("Warning").val("Info").val("Normal").val("Trace").val("Dump").val("All"). des('Console output level. The higher, the more output will be visible in the console window. '); } /////////////////////////////////////////////////////////////////////////////// var COMMAND_FAILURE = true; var COMMAND_USERABORT = true; var COMMAND_BADPARAMS = true; var COMMAND_SUCCESS = false; /////////////////////////////////////////////////////////////////////////////// function Command_CompareEx(data) { var args = ArgsMagic(data, null, template), result = null; //DumpObject(args); //return; if (args["XLOG"].exists){ XLog = args["XLOG"].value; } Log("CmdLine: " + data.cmdline,"D"); if (args["NODESELECT"].exists) data.func.command.deselect = false; if (args["NOFAIL"].exists) COMMAND_FAILURE = COMMAND_SUCCESS; if (0); else if (args["TABS"].exists) return CompareEx_TABS(data.func.command, data.func.sourcetab, data.func.desttab, args); if (result===null){ Log("Bad/incomplete params.","X"); return COMMAND_BADPARAMS; } return result; } /////////////////////////////////////////////////////////////////////////////// function CompareItem(doItem, tab, args){ var md5 = args["TABS"].options["by-md5"] || args["TABS"].options["md5"]; var ignorePaths = args["TABS"].options["ignorepaths"]; //todo: ein bisschen sehr holprig dieser Part mit relativem Pfad ja/nein und Case-Sensitive ja/nein.. this.name = doItem.name; //weird looking lowercase conversion, but required to make things work in flat view (iirc) var relativeFilePath = (""+doItem.realpath).replace(tab.path+"\\",""); if ((tab.path+"").search(/^ftp:\/\//i)!=-1) //ftp path, different slash at end relativeFilePath = (""+doItem.realpath).replace(tab.path+"/",""); //todo: fix nameLC property being used for a relative file path this.nameLC = relativeFilePath.toLowerCase(); if (ignorePaths) this.nameLC = (this.name+"").toLowerCase(); Log("NameLC: " + this.nameLC); this.realpath = ""+doItem.realpath; this.size = doItem.size.cy*10000; this.modified = 1*doItem.modify_utc; this.created = 1*doItem.create_utc; this.isDir = doItem.is_dir; this.hashMD5 = md5 && !doItem.is_dir ? DOpus.FSUtil.Hash(doItem.realpath) : null; this.hasDuplicate = false; } /////////////////////////////////////////////////////////////////////////////// function CompareEx_TABS(cmd, sourcetab, desttab, args){ Log("CompareEx_TABS():", "t", 1); if (!desttab){ Log("No destination tab, aborting.", "e"); Log("-", "t", -1); return COMMAND_FAILURE; } if (!args["TABS"].options["by-name"] && !args["TABS"].options["by-md5"]) args["TABS"].options["by-name"] = true; var src = [], srcIndexed = [], dst = [], dstIndexed = [], srcMD5 = [], dstMD5 = []; Log("Collecting item data in source (please wait).."); for(var i=0;i"); if (parts.length>1) opValue = parts.slice(1).join(""); this.options[opName] = opValue; } if (!(!this.value && subOpsTemplate)) return; if (!(match = subOpsTemplate.match(/\<(.+?)\>/))) return; this.options[match[1]] = true; this.value = match[1]; } /////////////////////////////////////////////////////////////////////////// var types = {s:"switch",k:"keyword",o:"optional",n:"numeric",m:"multiple",r:"raw"}; var names = template.replace(/\/(.)\,/g,"/$1;").replace(/\]\,/g,"];").split(";"), args = []; for(arg in names) { var parts = names[arg].split("/"); var name=parts[0].toUpperCase(), subOpsTemplate=null; var parts2 = parts[1].split("["); var type=parts2[0].toLowerCase(); if (parts2.length>1) subOpsTemplate = parts2[1].substring(0,parts2[1].length-1); var exists=(data&&data.func.args.got_arg[name])||(jsonData&&(jsonData[name]!=undefined))||false; var value = (data && data.func.args[name]) || (jsonData && jsonData[name]) || undefined; args.push( args[name] = new Arg(name, types[type], exists, value, subOpsTemplate )); } /////////////////////////////////////////////////////////////////////////// args.Get = function( argName, configName, noneValue){ var arg = this[argName = argName.toUpperCase()]; if (!arg) throw new Error(0, "Unknown parameter ["+argName+"]"); if (arg.exists) return arg.value; //DOpus.Output("argName: " + argName); //DOpus.Output("configName: " + configName); if (!configName) return noneValue; if (typeof Script.config[configName] == "string") return new String(""+Script.config[configName]); return Script.config[configName]; } return args; } /////////////////////////////////////////////////////////////////////////////// function Log(text, lvl, ind){ //XLog v0.41 var u,lvs={o:0,x:1,e:2,w:3,i:4,n:5,t:6,d:7,a:8},i=["","X","E","W","I","","","",""]; if (typeof XLog==(u="undefined")){var v=DOpus.Vars; if (v.Exists("XLog") && typeof XLogForce==u) {XLog=v.Get("XLog"); }} if (typeof XLog==u){var c=Script.Config; if(typeof c!="undefined" && typeof c.XLog!=u){ XLog=c.XLog; }} if (typeof XLog==u){XLog="normal";} if(XLog.paused===undefined){ if(XLog===true) var L=5; else if(!isNaN(parseInt(XLog,10))) var L=XLog*1; else var L=lvs[(""+XLog).substring(0,1)]; XLog={paused:false,I:0,L:L};} lvl=(lvl==undefined?5:lvs[lvl.substring(0,1).toLowerCase()]); if (!(lvl && XLog.L && !XLog.paused && (lvl<=XLog.L))){ return;} var pad = (XLog.I==0?"":new Array(XLog.I+1).join(" ")); if (i[lvl])pad = i[lvl]+(!pad?" ":pad.substring(1)); if (text!="-"){ var d=DOpus; if (d.Version.AtLeast("11.13.1")) d.Output(pad+text,((lvl==1||lvl==2)?1:0)); else d.Output(pad+text);} ind=(ind!==undefined?ind:0);XLog.I+=ind;if(XLog.I<0)throw new Error("XLog indent went sub-zero."); } /////////////////////////////////////////////////////////////////////////////// function OnAboutScript(data){ //v0.1 var cmd = DOpus.Create.Command(); if (!cmd.Commandlist('s').exists("ScriptWizard")){ if (DOpus.Dlg.Request("The 'ScriptWizard' add-in has not been found.\n\n"+ "Install 'ScriptWizard' from [resource.dopus.com].\nThe add-in enables this dialog and also offers "+ "easy updating of scripts and many more.","Yes, take me there!|Cancel", "No About.. ", data.window)) cmd.RunCommand('http://resource.dopus.com/viewtopic.php?f=35&t=23179');} else cmd.RunCommand('ScriptWizard ABOUT WIN='+data.window+' FILE="'+Script.File+'"'); } //MD5 = "757b7f01bc1d7274902a7f36ea6c1be6"; DATE = "2018.07.02 - 15:37:09"