#1 2023-01-31 03:50

visusys
Member
Registered: 2021-10-16
Posts: 20

PascalScript - Serialize Duplicates and Renaming the first dupliicate

Hi,

I am trying to use PascalScript to serialize duplicates, while also renaming the first duplicate file. Consider the following filename:

SPCYCLIC Beats 130 IDMModular Drums.wav

I want all duplicates to be renamed as well as the first file.

So if there are five files with the same name as above, I want the following result:

SPCYCLIC Beats 130 IDMModular Drums 1.wav
SPCYCLIC Beats 130 IDMModular Drums 2.wav
SPCYCLIC Beats 130 IDMModular Drums 3.wav
SPCYCLIC Beats 130 IDMModular Drums 4.wav
SPCYCLIC Beats 130 IDMModular Drums 5.wav

This is the script I'm using:

var
  Files: TWideStringArray;

procedure Add(const S: WideString);
begin
  SetLength(Files, Length(Files)+1);
  Files[Length(Files)-1] := S;
end;

function Exists(const S: WideString): Boolean;
var I: Integer;
begin
  Result := False;
  for I:=0 to Length(Files)-1 do
    if WideSameText(Files[I], S) then
      begin Result := True; Break; end;
end;

var
  NewFileName: WideString;
  Counter: Integer;

begin
  Counter := 2;
  NewFileName := FileName;
  while Exists(NewFileName) do
    begin
    NewFileName :=
      WideExtractBaseName(FileName) +
      ' ' + IntToStr(Counter) +
      WideExtractFileExt(FileName);
    Counter := Counter + 1;
    end;
  FileName := NewFileName;
  Add(FileName);
end.

It partially works, but it doesn't rename the first file. This is because "while Exists(NewFileName)" will always evaluate to false for the first member of a duplicate set.

How can I accomplish my goal here? Is this even possible?

Edit: I just wanted to specify that only files in a set of duplicates should be renamed. If the file doesn't have existing duplicates, it should not be renamed at all. So the default state is no serialization suffix. All examples on the wiki either only rename the duplicate files, or rename all files. Hopefully this is clear enough.

Any help at all would be greatly appreciated.

Last edited by visusys (2023-01-31 04:54)

Offline

#2 2023-01-31 06:26

visusys
Member
Registered: 2021-10-16
Posts: 20

Re: PascalScript - Serialize Duplicates and Renaming the first dupliicate

Just wanted to add that I found the solution from another forum post (Thanks to SafetyCar).

Here's the final script for my use:

var
  NamesDB: TStringsArray;
  NamesTXT: WideString;
  I, Count: Integer;
  Initialized, EmptyVars: Boolean;

  Files: TStringsArray;
  NewFileName: WideString;
  Counter: Integer;

procedure Add(const S: WideString);
begin
  SetLength(Files, Length(Files)+1);
  Files[Length(Files)-1] := S;
end;

function Exists(const S: WideString): Boolean;
var I: Integer;
begin
  Result := False;
  for I:=0 to Length(Files)-1 do
    if WideSameText(Files[i], S) then
      begin Result := True; Break; end;
end;

begin
  NamesTXT := WideGetTempPath + '\~temp_vars_names.txt';

  FileName :=  ReplaceRegEx(WideExtractBaseName(FileName), ' *(\(\d+\)|-\d+)$', '', False, False) + WideExtractFileExt(FileName);

  If not Initialized then
    begin
      If not WideFileExists(NamesTXT) then FileWriteContent(NamesTXT, '');
      If FileReadContent(NamesTXT)='' then EmptyVars:=True else EmptyVars:=False;
    end;

  If EmptyVars then
    begin
      FileAppendContent(NamesTXT, FileName + #13#10);
      FileName := ':: Please do the Preview again ::';
    end
  else
    begin
      If not Initialized then
      begin
        NamesDB := WideSplitString(FileReadContent(NamesTXT), #13#10);
        WideDeleteFile(NamesTXT);
      end;

      Count:=0
      For I:=0 to length(NamesDB)-1 do
      begin
        If WideSameText(FileName, NamesDB[i]) then Count := Count + 1;
      end;

      If Count>1 then
      begin
        Counter := 1;
        NewFileName := FileName;
        If not Exists(FileName) then Add(FileName);
        while Exists(NewFileName) do
          begin
          NewFileName :=
            WideExtractBaseName(FileName) +
            ' ' + IntToStr(Counter) +
            WideExtractFileExt(FileName);
          Counter := Counter + 1;
          end;
        FileName := NewFileName;
        Add(FileName);
      end;
    end;

  Initialized := True;
end.

Offline

#3 2023-02-07 17:31

jogiwer
Member
From: Germany
Registered: 2022-11-05
Posts: 66

Re: PascalScript - Serialize Duplicates and Renaming the first dupliicate

You might get rid of the need for two runs as well as the usage of an external file.

If you make use of GetMarkedFiles you'll get all full qualified filenames. By calling GetMarkedFiles you'll have dismissed the path parts.

And: if you hold the filenames as WideStrings you should store them in a TWideStringArray
Just an untested scratch:

var
  NamesDB: TWideStringArray;
  I, Count: Integer;
  Initialized: Boolean;

  Files: TWideStringArray;
  NewFileName: WideString;
  Counter: Integer;

procedure Add(const S: WideString);
begin
  SetLength(Files, Length(Files)+1);
  Files[Length(Files)-1] := S;
end;

function Exists(const S: WideString): Boolean;
var
  I: Integer;
begin
  Result := False;
  for I:=0 to Length(Files)-1 do
    if WideSameText(Files[i], S) then
      begin
        Result := True;
        Break;
    end;
end;

begin
  If not Initialized then
  begin
    NamesDB := GetMarkedFiles();
    For I:=0 to length(NamesDB)-1 do
    begin
      NamesDB[i] := WideExtractFileName(NamesDB[i]);
    end;

    Initialized := True;
  end;

  FileName :=  ReplaceRegEx(WideExtractBaseName(FileName), ' *(\(\d+\)|-\d+)$', '', False, False) + WideExtractFileExt(FileName);
  Count:=0
  For I:=0 to length(NamesDB)-1 do
  begin
    If WideSameText(FileName, NamesDB[i]) then Count := Count + 1;
  end;

  If Count > 1 then
  begin
    Counter := 1;
    NewFileName := FileName;
    If not Exists(FileName) then Add(FileName);
    while Exists(NewFileName) do
    begin
      NewFileName :=
        WideExtractBaseName(FileName) +
        ' ' + IntToStr(Counter) +
        WideExtractFileExt(FileName);
      Counter := Counter + 1;
    end;
    FileName := NewFileName;
    Add(FileName);
  end;
end.

Some more notes:

  • You are assuming incoming filename with number at the end which you are cutting in advance. But the numbers are either in brackets ' (001)' or following space and dash ' -02'

  • Seeking won't work in NamesDB if you want these cut off to lead to some grouping. So 'abc (01)' and 'abc (02)' will both be changed to 'abc' but no group is recognized.

  • To resolve this NamesDB has to be cleaned with the same replacement.

Offline

#4 2023-02-08 02:52

visusys
Member
Registered: 2021-10-16
Posts: 20

Re: PascalScript - Serialize Duplicates and Renaming the first dupliicate

While very clever, the problem with your approach is that I'm doing this serialization after a lot of filename manipulation. The names on disk will be different than the "current" new name. Sometimes during the normal processing of this preset, it generates a duplicate filename when there was none before. So I'm not too keen on going down the GetMarkedFiles rabbit hole, and this is also the reason why I posted about adding two new functions to ReNamer here.

There is one option I want to explore, but I'm a bit unsure if it will work. I'm wondering if I can split this into two PascalScript rules:

Rule 1: Create a temporary file and fill it with all of the current filenames.
Rule 2: Read the temporary file and perform serialization, then delete the file.

This might let me avoid having to preview twice. But I'm not sure if the temporary file is created exactly when Rule 1 is executed and before Rule 2 is executed. I.E. Will Rule 2 really be able to read the file during the preview process?

You are assuming incoming filename with number at the end which you are cutting in advance. But the numbers are either in brackets ' (001)' or following space and dash ' -02'

I'm not quite sure I follow what you're saying here, but I am not operating on files that have brackets or "space and dash" formatting. I am just adding a number (serializing) exactly duplicate filenames.

Thanks for all your suggestions!

Offline

#5 2023-02-08 04:48

jogiwer
Member
From: Germany
Registered: 2022-11-05
Posts: 66

Re: PascalScript - Serialize Duplicates and Renaming the first dupliicate

visusys wrote:

You are assuming incoming filename with number at the end which you are cutting in advance. But the numbers are either in brackets ' (001)' or following space and dash ' -02'

I'm not quite sure I follow what you're saying here, but I am not operating on files that have brackets or "space and dash" formatting. I am just adding a number (serializing) exactly duplicate filenames.

I just was wondering why this is done:

FileName :=  ReplaceRegEx(WideExtractBaseName(FileName), ' *(\(\d+\)|-\d+)$', '', False, False) + WideExtractFileExt(FileName);

As I read the regexp there are digits in brackets or digits following a dash - and in front of this there might be none, one or some spaces ...

Offline

#6 2023-02-09 04:18

jogiwer
Member
From: Germany
Registered: 2022-11-05
Posts: 66

Re: PascalScript - Serialize Duplicates and Renaming the first dupliicate

I didn't know that these filenames have been changed already before building groups. In that case it seems impossible to forecast how the next filename wil llook like.

So two runs might be the only possible approach. Instead of using a file you could store the information (like array of names) inside the GlobalVars ...

Offline

Board footer

Powered by FluxBB