Vars are awesome (global/lister/tab/etc)

Two rename scripts scenarios (jscript):

  • 2 files selected - rename one file to another files name. I make a choice by extensions, eg: rename .nfo file to the name of .mkv file.
  • I want to rename selected files by reading a JSON file in the same folder, which has information that I am gonna use to build new filenames.

Questions:

  1. How can I get access to the Tab, and this way to the selected files inside the rename script, to be able to rename one file by another's name, for scenario 1? Also, using Tab I could get to and read the JSON file, for scenario 2. Is it possible? Or maybe there is a better solution?
  2. Can I have and use global variables in rename scripts? For scenario two, I would like to read the JSON file only once, and re-use the info in some global variable.

Thanks in advance for any help.


Edit.
Changed title from non-descriptive to (hopefully) helpful.
@wowbagger made 1st script even better:

It's probably easier to solve this independently from the Rename dialog. The two selected files are clickData.func.sourcetab.selected_files(0) and (1). Based on their extensions a Rename command can be put together and started via RunCommand.

Regarding the second question: interesting topic! JSON.parse() can probably be used, but I haven't done that myself.

@lxp, I did actually had an idea how to maybe do both of them. :smile:
Working on it now...

Script 1 - done (rename to other file's name, by extension).

Well, almost done. Solved using global tab variable. The only problem is the order the files are processed. If the source file gets processed first - then everythings a OK. If target file gets processed first - not so much. Need to run re-load the profile a second time, or re-run the script.

  • Can the order, in which the selected files are being renamed, be controlled from the script or some other way (programmatically, not manually)?

As it stands now, the sure way for this script to work is use the rename dialog and sort the files appropriately. But was hoping to use this in a button to make things faster...

function OnGetNewName(getNewNameData) {
	var tab = GetTab();
	var extension = getNewNameData.item.ext;
	var filename = getNewNameData.item.name_stem_m;
	if (extension === ".nfo") {
		return tab.Vars.Get("filename") + extension;
	} else {
		tab.Vars.Set("filename", filename);
		return true;
	}
}

function GetTab() {
	for (var i = 0; i < DOpus.listers.Count; i++) {
		if (DOpus.listers(i).lastactive === true) {
			return DOpus.listers(i).activetab;
		}
	}
}

Edit:

Script 2 - done (rename by reading a JSON file in the source folder).

This one is working perfectly. And it was so easy, it's embarrassing. Pretty much DOpus object to the rescue in both scripts.
Damn, it always takes me quite a while to "remember" and "get back into" things, when it comes to DOpus scripting.

function OnGetNewName(getNewNameData) {
	var jsonObj = ReadJsonToVariable();
	var filename = getNewNameData.item.name;
	for (var i = 0; i < jsonObj.length; i++) {
		if (jsonObj[i].Name === filename) {
			return jsonObj[i].Whatever.Crazy["json-you-have"][0].name;
		}
	}
}

function ReadJsonToVariable() {
	var tab = GetTab();
	var jsonFile = tab.path + "\\rename.json";
	var doFsu = DOpus.FSUtil;
	if (!doFsu.Exists(jsonFile)) {
		DOpus.Output("Error: Can't find json File, Path: " + jsonFile);
		return;
	}
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var fileStream = fso.openTextFile(jsonFile);
	var fileData = fileStream.readAll();
	fileStream.Close();
	return JSON.parse(fileData);
}

function GetTab() {
	for (var i = 0; i < DOpus.listers.Count; i++) {
		if (DOpus.listers(i).lastactive === true) {
			return DOpus.listers(i).activetab;
		}
	}
}

How cool would be to have DOpus scripting intellisense in VS Code? :wink:

1 Like

Nice idea for a script.

Can you should some before and after screen shots so i understand what you are trying to achieve?
Are you only selecting two file at a time, or would you like to select, multiple sets at once?

There's nothing too special about it. I simply select only 2 files, and rename one of them to another's name, so they match.
I will mostly use it to match nfo files to the video (mkv) files. Regular Kodi/Plex/Emby stuff. I simply have tens of TBs of old hard drives to sort out, and am too lazy to write a special app for 100% automation. I am too lazy to copy paste the names, when I come up on missmatched ones from time to time :wink:
Anyway, I am almost always happier to loose a couple of hours writing a small script to help me save maybe an hour in the long run. It's just fun. A more sophisticated app would not be worth a waste of time for my situation.

Given this for script 1 you might be able to remove the order issue you mentioned using the tab.selected property.

  1. In the rename function, check if the current file is the one to be renamed (if its not .nfo, skip).
  2. Get the list of selected files from the tab.selected property.
  3. Confirm only 2 file are selected (just in case :slight_smile: )
  4. Loop the selected files to find the one to copy the name from.

This would mean you don't need to store the file name in the var and thus would not care about the order.
Would make a pretty handy script.

I hear you :wink: That being said, using the 80/20 rule. Would be pretty easy to make a Powershell script that checked all folders for any that contain only 1 video and one nfo file. If it did to update that one nfo to the video name. This should get a lot of the updated pretty quickly.

TBH, I'm not that good at powershell or bash. I could do it 5 times faster in node, or better still 10 times faster in c#.
Come to think of it, I already have written a WPF app for exactly this about 5 years ago, I just cannot remember where I put it. All I could find was a lonely screenshot. :crazy_face:

It was(is) pretty powerfull, though. It could handle pretty much all the metadata files and any mess you can imagine. The only rule - movies need to be in individual folders.

Although, being me, if I'll find it, I'm pretty sure, I'm gonna start re-writing it in some shape or form.
Just look at that awesome green :slight_smile:

try this

//Incase InGroup("Movies") does not cover type
//videoFilesPattern = ".*\.(m4v|3gp|nsv|ts|ty|strm|rm|rmvb|ifo|mov|qt|divx|xvid|bivx|vob|nrg|wmv|asf|asx|ogm|m2v|avi|dat|dvr-ms|mpg|mpeg|mp4|mkv|avc|vp3|svq3|nuv|viv|dv|fli|flv)$";
textFilesPattern = ".*\.(nfo|txt)$";

function OnGetNewName(getNewNameData) {
	if(!getNewNameData.item.name.match(textFilesPattern))
	{
		DOpus.Output("Returning for " + getNewNameData.item);
		return true; //true = skip
	}
	
	var tab = GetTab();
	if(!tab.selected.Count == 2)
	{
		DOpus.Output("Returning cos not 2 files");
		return true; //true = skip
	}

	for (var i = 0; i < tab.selected.Count; i++) {
		var item = tab.selected(i);
		if(item.InGroup("Movies"))
		{
			DOpus.Output("rename to " + item.name_stem_m + getNewNameData.item.ext);
			return item.name_stem_m + getNewNameData.item.ext;
		}
	}
}

function GetTab() {
	for (var i = 0; i < DOpus.listers.Count; i++) {
		if (DOpus.listers(i).lastactive === true) {
			return DOpus.listers(i).activetab;
		}
	}
}
1 Like

Awesome, yours works perfectly.
Thank You.