News:

MultiCommander v16.6 is released!

Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - SpiroC

#1
Script / Rename file script
November 08, 2017, 01:10:51
Hi.  I couldn't find a way to launch MultiRename profiles on a button or menu, so I wrote a rename script which I am sharing here.  You can duplicate it, tweak it, then put it on a dedicated menu or button.
Pros:
- Can be put on a menu/button
- Can do some things that MultiRename dialog can't (obviously, because it's a programming environment), but it's harder to use.  Once you set it up on buttons though it's all good.
- Works for multiple files selected
- Works in branch view (different paths)

Cons:
- No regex grouping/capture.  So you can't replace (.*) with $1.  This is a big weakness. 
- I couldn't find any StrRegexReplace or any way of knowing how long the match is after StrIsRegExpMatch() returns with a successful find.  I used a messy guess and check iteration to find a match, but it's non-greedy and inflexible.  I'd really like a StrRegexReplace() library function.
- Inefficiency: scRegexExtract(), scRegexDelAfterMatch() and scRegexReplace() only vary slightly.  They should be consolidated into 1 routine.
- No undo.

Notes:
- A popup showing changes is presented giving you the chance to op-out before and filename changes are made.
- Top function MakeNewName() is called once per file.  There are examples in this function (including regex replace, proper case, base reversal, pre/app date).  Uncomment them to try them out.

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function MakeNewName($fbase, $fext)
{
   @var $now = GetTime();
   @var $date = FormatDate( "yyyy-MM-dd" , $now );
   @var $seasonepisode;

   // Regex replace base only
   //$fbase= scRegexReplace($fbase, "t.", "AAA", 0);

   // Regex replace global, base only
   //$fbase= scRegexReplaceGlobal($fbase, "(t|T).", "ZZZ", 0);

   // Regex replace, global, case insensitive, base only
   //$fbase= scRegexReplaceGlobal($fbase, ".", "_", 1);

   // Reverse string, base only
   //$fbase = scReverse($fbase);

   // Append date to base
   //$fbase = $fbase + " " + $date;

   // Prepend date to base
   $fbase = $date + " " + $fbase;

   // Regex delete after match case insensitive (base only)
   //$fbase = scRegexDelAfterMatch($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   // Proper case base only (Only capitalises.  You need to lowercase first manually.  See examples below)
   //$fbase = scProperCase($fbase);

   // TV Show filename cleanup 1 (Aggresive. Removes episode name and cleans up various things)
   //$fbase= scRegexReplaceGlobal($fbase, "_", " ", 0);
   //$fbase = StrTrim($fbase, " ");
   //$seasonepisode = scRegexExtract($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   //$fbase = scRegexDelAfterMatch($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   //$fbase = StrToLower($fbase);
   //$fbase = scProperCase($fbase, 7);
   //$fbase = scRegexReplace($fbase, "S[0-9][0-9]e[0-9][0-9]", $seasonepisode, 0);

   // TV Show filename Proper case (Soft. Preserves chars after sXXeXX.  For minor corrections)
   //$fbase = StrToLower($fbase);
   //$seasonepisode = scRegexExtract($fbase, "s[0-9][0-9]e[0-9][0-9]", 1);
   //$fbase = scProperCase($fbase, 0);
   //$fbase = scRegexReplace($fbase, "S[0-9][0-9]e[0-9][0-9]", $seasonepisode, 0);

   // Movie filename cleanup
   //$fbase= scRegexReplaceGlobal($fbase, "_", " ", 0);
   //$fbase= scRegexReplaceGlobal($fbase, "\.", " ", 0);
   //$fbase = scRegexDelAfterMatch($fbase, " (hd|dvd|br)rip", 1);
   //$fbase= scRegexReplaceGlobal($fbase, " (hd|dvd|br)rip", "", 1);
   //$fbase = scProperCase($fbase, 0);

   return $fbase + $fext;
}
function scProperCase($strInput, $ignoreNfromend)
{
   @var $i = 1;
   @var $newStr;
   @var $len = StrLen($strInput);
   @var $nextchar;
   @var $capitaliseflag = 0;
   @var $tail = "";
   if ($ignoreNfromend > 0)
   {
      $tail = StrSub($strInput, $len - $ignoreNfromend, -1);
      $len = $len - $ignoreNfromend;
   }
   $newStr = "";
   $newStr = StrToUpper(StrSub($strInput, 0, 1));
   while($i < $len)
   {
      $nextchar = StrSub($strInput, $i, 1);
      if ($capitaliseflag == 1)
      {
         $newStr = $newStr + StrToUpper($nextchar);
         $capitaliseflag = 0;
      }
      else
      {
         $newStr = $newStr + $nextchar
      }
      $i = $i + 1;
      if (StrIsEqual($nextchar, " "))
      {
         $capitaliseflag = 1;
      }
   }
   return $newStr + $tail;
}
function scRegexExtract($strInput, $strRe, $nocase)
{
   @var $firstpart;
   @var $matchpart;
   @var $matchlen;
   @var $matchcheck;
   @var $matchend;
   @var $lastpart;
   @var $lastpartidx;
   @var $inputlen;
   @var $matchpos;
   @var $result;
   @var $strInputOrig;
   $strInputOrig = $strInput;
   if ($nocase)
   {
      $strInput = StrToUpper($strInput);
      $strRe = StrToUpper($strRe);
   }
   $matchpos = StrRegExpFind($strInput , $strRe);
   $inputlen = StrLen($strInput);
   //Log(0, 10, "scRegexDelAfterMatch: testing regex:" + $strRe + " , string:" + $strInput);
   if ($matchpos == -1)
   {
      //Log(0, 10, "....scRegexDelAfterMatch: not found");
      return $strInputOrig;
   }
   else
   {
      //Log(0, 10, "....scRegexDelAfterMatch: found");
      $firstpart = StrSub($strInputOrig, 0, $matchpos);
      //Log(0, 10, "....scRegexDelAfterMatch: firstpart:" + $firstpart);
      $matchlen = 1;
      $matchpart = StrSub($strInput, $matchpos, $matchlen);
      $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
      //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      while (!$matchcheck)
      {
         $matchend = $matchpos + $matchlen;
         if ($matchend > $inputlen)
         {
            break;
         }
         $matchlen += 1;         
         $matchpart = StrSub($strInput, $matchpos, $matchlen);
         $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
         //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      }
      if ($matchcheck == 0)
      {
         //Log(0, 10, "....scRegexDelAfterMatch: matchcheck failure, returning original");
         return $strInputOrig;
      }
      $matchpart = StrSub($strInputOrig, $matchpos, $matchlen);
      $result = $matchpart;
      //Log(0, 10, "....scRegexDelAfterMatch: replace complete, returning:" + $result);
   }
   return $result;
}
function scRegexDelAfterMatch($strInput, $strRe, $nocase)
{
   @var $firstpart;
   @var $matchpart;
   @var $matchlen;
   @var $matchcheck;
   @var $matchend;
   @var $lastpart;
   @var $lastpartidx;
   @var $inputlen;
   @var $matchpos;
   @var $result;
   @var $strInputOrig;
   $strInputOrig = $strInput;
   if ($nocase)
   {
      $strInput = StrToUpper($strInput);
      $strRe = StrToUpper($strRe);
   }
   $matchpos = StrRegExpFind($strInput , $strRe);
   $inputlen = StrLen($strInput);
   //Log(0, 10, "scRegexDelAfterMatch: testing regex:" + $strRe + " , string:" + $strInput);
   if ($matchpos == -1)
   {
      //Log(0, 10, "....scRegexDelAfterMatch: not found");
      return $strInputOrig;
   }
   else
   {
      //Log(0, 10, "....scRegexDelAfterMatch: found");
      $firstpart = StrSub($strInputOrig, 0, $matchpos);
      //Log(0, 10, "....scRegexDelAfterMatch: firstpart:" + $firstpart);
      $matchlen = 1;
      $matchpart = StrSub($strInput, $matchpos, $matchlen);
      $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
      //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      while (!$matchcheck)
      {
         $matchend = $matchpos + $matchlen;
         if ($matchend > $inputlen)
         {
            break;
         }
         $matchlen += 1;         
         $matchpart = StrSub($strInput, $matchpos, $matchlen);
         $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
         //Log(0, 10, "........scRegexDelAfterMatch: matchcheck trying:" + $matchpart);
      }
      if ($matchcheck == 0)
      {
         //Log(0, 10, "....scRegexDelAfterMatch: matchcheck failure, returning original");
         return $strInputOrig;
      }
      $matchpart = StrSub($strInputOrig, $matchpos, $matchlen);
      $result = $firstpart + $matchpart;
      //Log(0, 10, "....scRegexDelAfterMatch: replace complete, returning:" + $result);
   }
   return $result;
}
function scReverse($strInput)
{
   @var $newStr;
   @var $len = StrLen($strInput) - 1;
   $newStr = "";
   while($len >= 0)
   {
      $newStr = $newStr + StrSub($strInput, $len, 1);
      $len = $len - 1;
   }
   return $newStr;
}
function scRegexReplaceGlobal($strInput, $strRe, $strRep, $nocase)
{
   @var $retstr;
   @var $maxloops = 20;
   @var $previousmatch = $strInput;
   @var $ismatch;
   $retstr = scRegexReplace($strInput, $strRe, $strRep, $nocase);
   $ismatch = StrIsEqual($retstr, $previousmatch);
   while (!$ismatch)
   {
      $previousmatch = $retstr;
      $maxloops = $maxloops - 1;
      if ($maxloops <= 0)
      {
         break;
      }
      $retstr = scRegexReplace($retstr, $strRe, $strRep, $nocase);
      $ismatch = StrIsEqual($retstr, $previousmatch);
   }
   return $retstr;
}
function scRegexReplace($strInput, $strRe, $strRep, $nocase)
{
   @var $firstpart;
   @var $matchpart;
   @var $matchlen;
   @var $matchcheck;
   @var $matchend;
   @var $lastpart;
   @var $lastpartidx;
   @var $inputlen;
   @var $matchpos;
   @var $result;
   @var $strInputOrig;
   $strInputOrig = $strInput;
   if ($nocase)
   {
      $strInput = StrToUpper($strInput);
      $strRe = StrToUpper($strRe);
   }
   $matchpos = StrRegExpFind($strInput , $strRe);
   $inputlen = StrLen($strInput);
   //Log(0, 10, "scRegexReplace: testing regex:" + $strRe + " , string:" + $strInput);
   if ($matchpos == -1)
   {
      //Log(0, 10, "....scRegexReplace: not found");
      return $strInputOrig;
   }
   else
   {
      //Log(0, 10, "....scRegexReplace: found");
      $firstpart = StrSub($strInputOrig, 0, $matchpos);
      //Log(0, 10, "....scRegexReplace: firstpart:" + $firstpart);
      $matchlen = 1;
      $matchpart = StrSub($strInput, $matchpos, $matchlen);
      $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
      //Log(0, 10, "........scRegexReplace: matchcheck trying:" + $matchpart);
      while (!$matchcheck)
      {
         $matchend = $matchpos + $matchlen;
         if ($matchend > $inputlen)
         {
            break;
         }
         $matchlen += 1;         
         $matchpart = StrSub($strInput, $matchpos, $matchlen);
         $matchcheck = StrIsRegExpMatch($matchpart, $strRe);
         //Log(0, 10, "........scRegexReplace: matchcheck trying:" + $matchpart);
      }
      if ($matchcheck == 0)
      {
         //Log(0, 10, "....scRegexReplace: matchcheck failure, returning original");
         return $strInputOrig;
      }
      $matchpart = StrSub($strInputOrig, $matchpos, $matchlen);
      $lastpartidx = $matchpos + $matchlen;
      if ($lastpartidx < $inputlen)
      {
         $lastpart = StrSub($strInputOrig, $lastpartidx , -1);
      }
      else
      {
         $lastpart = "";
      }
      $result = $firstpart + $strRep + $lastpart;
      //Log(0, 10, "....scRegexReplace: replace complete, returning:" + $result);
   }
   return $result;
}
function main()
{
   Log(0, 10, "-------------- Script Start --------------" );
   @var $logprefix = "scMultiRename: ";
   @var $i;
   @var $filebase;
   @var $fileext;
   @var $resultsstr = "";
   @var $resultsarr[];
   @var $arrfullpath = GetSelectedPaths();
   @var $arr = GetSourceSelectedFileNames();
   @var $count = arrayCount($arr);
   if ($count == 0)
   {
      Log(0, 10, $logprefix + "no files selected, exiting");
   }
   else
   {   
      for($i = 0; $i < $count; $i++)
      {
         //Log(0, 10, $logprefix + "Full path:" + $arrfullpath[$i]);
         @var $dotpos = StrRegExpFind($arr[$i] , "\....$" );
         if ($dotpos == -1)
         {
            $filebase = $arr[$i];
            $fileext = "";
         }
         else
         {
            $filebase = StrSub($arr[$i], 0, $dotpos);
            $fileext = StrSub($arr[$i], $dotpos, -1);
         }
         arrayAdd($resultsarr, MakeNewName($filebase, $fileext));
         //Log(0, 10, $logprefix + "\"" + $arr[$i] + "\" --> " + $resultsarr);
         $resultsstr = $resultsstr + $arr[$i] + " -->\r\n" + $resultsarr[$i] + "\r\n";
      }
      @var $msganswer = MessageBox("Proceed with rename?", $resultsstr, 1);
      if ($msganswer == 1)
      {
         Log(0, 10, $logprefix + "[Ok] renaming...");
         for($i = 0; $i < $count; $i++)
         {
            @var $newname = $resultsarr[$i];
            Log(0, 10, $logprefix + "Renaming:[" + $arrfullpath[$i] + "] to [" + $newname + "]");
            MC.Filesystem.Rename FILE="{$arrfullpath[$i]}" NEWNAME='{$newname}'
         }
      }
      else
      {
         Log(0, 10, $logprefix + "[Cancel] not renaming...");
      }
   }
   Log(0, 10, "-------------- Script Done --------------" );
}
main();
#2
Hi,
Any way to do this?  I have a few favorite profiles that I call regularly.  As a workaround, if I script my own rename sequence, can I put that on a toolbar button?  How about on a custom menu if I create say a RenameProfiles menu?
thanks,
SpiroC