Super Rename Tool

Features wanted...
SpiroC
Posts: 14
Joined: 01 Dec 2017 23:20

Re: Super Rename Tool

Post by SpiroC »

- msg tip - great thanks will try!
- Beyond Compare - Of course just use free/open alternatives (WinMerge?)
- The BC and confirmation are temporary for me. After a few runs of proving the expressions they are removed so one click does the lot. There are still other failsafe options - the XYplorer undo option which is working great, and the file _selectedfiles.txt remains until the next time the script is run. They could also be timestamped and squirreled away in a log folder too.
- Code tags. Yes forgot apologies
Last edited by SpiroC on 02 Dec 2017 13:26, edited 1 time in total.

SpiroC
Posts: 14
Joined: 01 Dec 2017 23:20

Re: Super Rename Tool

Post by SpiroC »

v0.2. Bugfix in call to substr()

Code: Select all

"Multi Rename"
  log("Main        ", "------------------------------");
  // Version 0.2
  global $gstartindex = 0, $gendindex = 0, $gnewname, $gnewnameslist;
  $selectedlist = get("SelectedItemsNames", "<crlf>");
  writefile("<xydata>\_selectedfiles.txt", $selectedlist);
  writefile("<xydata>\_newnames.txt", "", o);
  $count = 1;
  foreach($file, $selectedlist, "<crlf>") {
    $base = getpathcomponent($file, "base");
    $ext = getpathcomponent($file, "ext");

    // all rename operations done on variable $file or $base/$ext separately
    // ****************************************** 

    $base = regexreplace($base, "[_\.]+", " ");
    $base = trim($base, " ");
    $base = regexreplace($base, "  ", " ");
    $base = recase($base, "t");
    $base = regexreplace($base, "[sS](\d{2})[eE](\d{2}).*", "s$1e$2");
    $ext = recase($ext, "l");

    // ******************************************

    $file = "$base.$ext";
    writefile("<xydata>\_newnames.txt", "$file<crlf>", a);
    $count++;
  }

  //  Optional check and manual edit.  Remove when happy with above transforms
  //run '"C:\_Portable\_Beyond Compare\BCompare.exe" "_selectedfiles.txt" "_newnames.txt"', <xydata>, 2;
  //msg("Proceed with rename?", 1);

  $gnewnameslist = readfile("<xydata>\_newnames.txt");
  $selectedlistpaths = get("SelectedItemsPathNames", "<crlf>");
  foreach($filepath, $selectedlistpaths, "<crlf>") {
    findnextname();
    log("Main        ", "$filepath --> $gnewname");
    renameitem("$gnewname", "$filepath", 4);
  }

  function findnextname() {
    global $gstartindex, $gendindex, $gnewname, $gnewnameslist;
    $gendindex = strpos($gnewnameslist, "<crlf>", $gstartindex);
    $gnewname = substr($gnewnameslist, $gstartindex, $gendindex-$gstartindex);
    $gnewname = trim($gnewname, "<cr><lf><crlf>");
    $gstartindex = $gendindex+2;
    log("findnextname", "new name: $gnewname");
  }

  function log($fn, $str) {
    //writefile("<xydata>\_log.txt", "[$fn]: $str<crlf>", a);
  }

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Super Rename Tool

Post by highend »

Just as a mockup what could be done by invoking an external tool...

Ofc there is working code behind this example :mrgreen:
mockup_01.png
mockup_01.png (23.13 KiB) Viewed 1478 times
One of my scripts helped you out? Please donate via Paypal

SpiroC
Posts: 14
Joined: 01 Dec 2017 23:20

Re: Super Rename Tool

Post by SpiroC »

@highend. Preview. yes!! NICE
v0.3 - turns out <cr> and <lf> aren't a thing so "trim($gnewname, "<cr><lf><crlf>");" was giving: "abc.rar" --> "abc.ra". Shortened.

Code: Select all

"Multi Rename"
  log("Main        ", "------------------------------");
  // Version 0.3
  global $gstartindex = 0, $gendindex = 0, $gnewname, $gnewnameslist;
  $selectedlist = get("SelectedItemsNames", "<crlf>");
  writefile("<xydata>\_selectedfiles.txt", $selectedlist);
  writefile("<xydata>\_newnames.txt", "", o);
  $count = 1;
  foreach($file, $selectedlist, "<crlf>") {
    $base = getpathcomponent($file, "base");
    $ext = getpathcomponent($file, "ext");

    // all rename operations done on variable $file or $base/$ext separately
    // ******************************************

    $base = regexreplace($base, "[_\.]+", " ");
    $base = trim($base, " ");
    $base = regexreplace($base, "  ", " ");
    $base = recase($base, "t");
    $base = regexreplace($base, "[sS](\d{2})[eE](\d{2}).*", "s$1e$2");
    $ext = recase($ext, "l");

    // ******************************************

    $file = "$base.$ext";
    writefile("<xydata>\_newnames.txt", "$file<crlf>", a);
    $count++;
  }

  //  Optional check and manual edit.  Remove when happy with above transforms
  //run '"C:\_Portable\_Beyond Compare\BCompare.exe" "_selectedfiles.txt" "_newnames.txt"', <xydata>, 2;
  //msg("Proceed with rename?", 1);

  $gnewnameslist = readfile("<xydata>\_newnames.txt");
  $selectedlistpaths = get("SelectedItemsPathNames", "<crlf>");
  foreach($filepath, $selectedlistpaths, "<crlf>") {
    findnextname();
    log("Main        ", "$filepath --> $gnewname");
    renameitem("$gnewname", "$filepath", 4);
  }

  function findnextname() {
    global $gstartindex, $gendindex, $gnewname, $gnewnameslist;
    $gendindex = strpos($gnewnameslist, "<crlf>", $gstartindex);
    $gnewname = substr($gnewnameslist, $gstartindex, $gendindex-$gstartindex);
    $gnewname = trim($gnewname, "<crlf>");
    $gstartindex = $gendindex+2;
    log("findnextname", "new name: $gnewname");
  }

  function log($fn, $str) {
    //writefile("<xydata>\_log.txt", "[$fn]: $str<crlf>", a);
  }

SpiroC
Posts: 14
Joined: 01 Dec 2017 23:20

Re: Super Rename Tool

Post by SpiroC »

Here is a multi rename with preview using the Extra 5 tags column as well as tags Red and Green to show which files have changed. 3 scripts including an example rename scirpt (tolower). To try it out, select some files and run the Lowercase script. This should display the ext 5 column in the current Tab, rename it "New Filename" and populate it with new filenames but only if the filename has changed. It also applies a second tag Red/Green if the filename has changed. Individual new names can be edited in the usual way for Ext 5 (right click, "Edit Data"). When you are ready, you can either back out of the whole things by running "Remove tags without renaming", or proceed with the rename using "Rename files, remove tags".
Separate scrtipts to run rename, show preview, undo tags without making changes
Separate scrtipts to run rename, show preview, undo tags without making changes
Snap1.png (4.48 KiB) Viewed 1454 times
Column added, Red/Green highlighting added, after running Lowercase example
Column added, Red/Green highlighting added, after running Lowercase example
Snap2.png (61.73 KiB) Viewed 1454 times

Code: Select all

"Multi Rename (tags) - Rename files, remove tags"
  $selectedlistpaths = get("SelectedItemsPathNames", "<crlf>");
  foreach($filepath, $selectedlistpaths, "<crlf>") {
    $newname = tagitems(5,,$filepath,2);  // retrieve
    if ($newname != "") {
      renameitem($newname, $filepath, 4); 
    }
  }
  $selectedlistpaths = get("SelectedItemsPathNames", "<crlf>"); // Need to recreate due to filename changes
  tag "", $selectedlistpaths, 7; // clear
  tag "", $selectedlistpaths, 0; // clear
  extratag(5, "");
  setcolumns("Extra 5", 8);
  setcolumns("Label", 8);


"Multi Rename (tags) - Remove tags without renaming"
  $selectedlistpaths = get("SelectedItemsPathNames", "<crlf>");
  tag "", $selectedlistpaths, 7;  // clear
  tag "", $selectedlistpaths, 0;  // clear
  extratag(5, "");
  setcolumns("Extra 5", 8);

"Multi Rename (tags) - Lowercase"
  extratag(5, "New Filename");
  setcolumns("Name,Extra 5,Ext,Size,Type,Modified", 16);

  $selectedlistpaths = get("SelectedItemsPathNames", "<crlf>");

  $count = 1;
  foreach($filepath, $selectedlistpaths, "<crlf>") {
    $filename = getpathcomponent($filepath, "file");
    $base = getpathcomponent($filepath, "base");
    $ext = getpathcomponent($filepath, "ext");

    // all rename operations done on variables $base, $ext
    // ****************************************** 

    $base = recase($base, "l");
    //$base = $base$count;
    $ext = recase($ext, "l");

    // ******************************************

    if ($ext != "") {
      $filenamenew = "$base.$ext";
    }
    else
    {
      $filenamenew = "$base";
    }
    if ($filename != $filenamenew) {
      tag "Red", $filepath;
      tag $filenamenew, $filepath, 7; 
    }
    else {
      tag("Green", $filepath);
    }
    $count++;
  }
  setcolumns("Name,Extra 5,Ext,Size,Type,Modified", 16);  // autosize again after populated

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Super Rename Tool

Post by highend »

@SpiroC

While I like the idea behind it, now do this with 5k files selected (e.g. because you want to pre / suffix a larger collection of files)
If you want to get rid of the "no response" problem while XY is working, you should add a

Code: Select all

wait 1;
in your foreach loops. Anyway, this approach can only be (effectively) used for a low amount of selected files.

Btw, my little preview tool is invoked like this:

Code: Select all

    // Do some XY internal stuff to create two files, the
    // first contains all original names, the second all modified ones
    // Ofc there must be a one to one relationship!
    $exe = "<some path>\XY_Rename preview.exe";
    $result = runret("""$exe"" ""< file 1>"" ""< file 2 >""", , , 2);
    // Proceed because the rename button was clicked
    // (in all other cases the return value of the preview tool is != 0)
    if ($result == 0) {
        // Do something...
    }
So ofc you still need a script that does the renaming like you want it,
but acknowledging / denying the preview is only one key press away
and it's reasonable fast.
Reading in two files with 3284 entries each and populating the list icon gadgets
takes ~500ms (colorizing modified entries included)
One of my scripts helped you out? Please donate via Paypal

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Super Rename Tool

Post by highend »

Another mockup (this time as a gif)

Sync scrolling is enabled (either via mouse wheel, cursor up/down or dragging
the right scrollbar (I've disabled the left one). Conflict detection is included...
mockup.gif
mockup.gif (1.69 MiB) Viewed 1417 times
Or for easier readability:
background.png
background.png (32.37 KiB) Viewed 1399 times
One of my scripts helped you out? Please donate via Paypal

SpiroC
Posts: 14
Joined: 01 Dec 2017 23:20

Re: Super Rename Tool

Post by SpiroC »

@highend
I will try the "wait 1" thanks. I'll take the hit on scalability and use an external tool for more than 30-40 files. If you were really liking the external tool idea (like your very nice mockups) then I'd go all the way to WinMerge. It'll let you show all, show delta's, edit lines, etc. I'm liking that with this (albeit slow) integrated preview method, I can run 3 or 4 different rename scripts and preview them all before committing the changes at once, like a git staging area. I'd like to add checkboxes to the CTB menu allowing me toggle certain renames on/off, then run a sort of "meta rename" that runs through them and applies them one by one if checked. Hunting for the checkbox code. I can see from the help file that I can make a checked menu entry with:

Code: Select all

"Go D:|D:|2" goto "D:\";  //shown checked
but I can't find anyway to toggle the checked state. I saw some posts of yours in the forums that rewrite the entire toolbar. I was hoping for something a bit simpler!! Thanks for the feedback.

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Super Rename Tool

Post by highend »

You can't check / uncheck items on the fly in this kind of menu.

What you can do is something like this (and you are free to modify the script file
itself, use an external file that contains the menu entries or (as in my example)
use a permanent variable):

Code: Select all

    perm $menu;
    setting "AllowRecursion", 1;

    if (!$menu) {
        $menu = <<<>>>
Pattern 1 (*.*)|id_1||2
Pattern 2 [#.#]|id_2||0
Pattern 3 <bla>|id_3||2
-
Rename...|id_ren|:tsf|0
>>>;
    }
    $selection = popupmenu($menu, , , , , , <crlf>, "|");
    if ($selection) {
        if ($selection LikeI "id_ren") {
            // Get the states of all other menu entries
            // Apply their pattern (store a list with
            // patterns and their corresponding id_1, id_2, etc. before!)
        } else {
            // Find the line with the return data and toggle it's state
            $line = regexmatches($menu, "^.+\|$selection\|.*?(?=\r?\n|$)");
            // Now get it's state
            $state = gettoken($line, 4, "|");
            // State toggeling
            if (!$state) { $state = 2; }
            elseif ($state == 1 || $state = 2) { $state = 0; }
            // Set new state
            $newLine = substr($line, 0, -1) . $state;
            // Modify the $menu
            $menu = regexreplace($menu, regexreplace($line, "([\\.+*|?(){\[^$])", "\$1"), $newLine);
            load "*", , "s";
        }
    }
Easier? Nothing that I'm aware of...
One of my scripts helped you out? Please donate via Paypal

SpiroC
Posts: 14
Joined: 01 Dec 2017 23:20

Re: Super Rename Tool

Post by SpiroC »

Thanks I will try that immediately. I just sidestepped it for the moment with a perm variable:

Code: Select all

"RenameEnablePreview Toggle"
  perm $scRenameEnablePreview;
  if ($scRenameEnablePreview == "ON") {
    $scRenameEnablePreview = "OFF";
  } else {
    $scRenameEnablePreview = "ON";
  }
and on the button:

Code: Select all

"Rename Preview toggle, currently: $scRenameEnablePreview"
  #1456;
And that looks like:
Snap4.png
Snap4.png (3.05 KiB) Viewed 1367 times
and after toggle:
Snap5.png
Snap5.png (2.93 KiB) Viewed 1367 times
In this case I used it to turn off the preview columns. One click writes the new names immediately saving the second click to commit the changes. As I mentioned above, I'd like to enable/disable rename operations and then run a set of them with a single "meta rename" script.

Post Reply