Here is something I made (it was not fully tested but just enough) - first time scripting in Pascal so apologies in advance if some things are a "no-no":
Code: Select all
(***************************************************
Ant Movie Catalog importation script
www.antp.be/software/moviecatalog/
[Infos]
Authors=Ethan Phoenix
Title=Update Selected Extras
Description=Update selected Extras specified field with a list of item wither from folder or a text file.
Site=
Language=Tools
Version=1.0 (1/6/2025)
Requires=4.2.0
Comments=
License=
GetInfo=0
RequiresMovies=1
[Options]
File Mask=0|0|0=Prompt|1=Movies|2=Images
Restore Defaults=0|0|0=No|1=Yes
Enable Warnings=1|1|0=No|1=Yes
Picture Import Method=5|0|0=Prompt|1=Store picture in catalog|2=Copy picture to catalog folder|3=Ccopy picture to pictures folder of catalog|4=Link to picture with absolute link|5=Link to picture with relative link if possible
[Parameters]
***************************************************)
program UpdateSelectedExtras;
var
  extrasFieldSelection, sourcePath, sourceType, itemSelection, mask, picImportMethod, maskSelection : string;
  iSourceItem, iExtras, totalExtras, iExtrasFields, iSelectionID, maskParam : Integer;
  selectedExtrasList, extrasFieldsList, itemsList: TStringList;
// TextBefore function
function TextBefore(wholeText: string; searchText: string): string;
  var
  	foundPos: Integer;
  begin
  	Result := '';
  	foundPos := Pos(searchText, wholeText);
  	if foundPos = 0 then
  		Exit;
  	Result := Copy(wholeText, 0, foundPos-1);
  end;
// SplitString function
function SplitString(InputStr: string; Delimiter: Char): TStringList;
  var
    DelimPos, i: Integer;
    SubStr: string;
  begin
    Result := TStringList.Create; // Create a new TStringList instance
      // Find the first delimiter
    DelimPos := Pos(Delimiter, InputStr);
    // Loop while there are delimiters found
    while DelimPos > 0 do
    begin
      // Extract substring from start position to delimiter position
      SubStr := Copy(InputStr, 0, DelimPos-1);
      Result.Add(SubStr); // Add substring to the TStringList
      Delete(InputStr, 1, DelimPos);
      // Find the next delimiter
      DelimPos := Pos(Delimiter, InputStr);
    end;
    Result.Add(InputStr); // Add substring to the TStringList
    // REMOVING DUPLICATES, JUST IN CASE
    Result.Sort;
    // Iterate backwards through the list
    for i := Result.Count - 1 downto 1 do
    begin
      // Compare the current string with the previous one
      if Result.GetString(i) = Result.GetString(i - 1) then
        Result.Delete(i); // Remove if it's a duplicate
    end;
  end;
// GetItemsList function
function  GetItemsList(sourcePathA: string; maskA: string): TStringList;
  var
    tempItemsList : String;
    i: Integer;
    maskList: TStringList;
  begin
    tempItemsList := '';
    Result := TStringList.Create; // Create a new TStringList instance
    maskList := SplitString(maskA, ';');
    for i := 0 to maskList.Count do
      begin
     		tempItemsList := tempItemsList + ListDirectory(sourcePathA, maskList.GetString(i));
      end;
      Result.Text := tempItemsList;
      Result.Sort;
      maskList.Free;
  end;
// CleanItemsList function
function CleanItemsList(itemsListA: TStringList): TStringList;
  var
    iSourceItem : Integer;
  begin
    Result := TStringList.Create; // Create a new TStringList instance
    for iSourceItem := 0 to itemsListA.Count - 1 do
      Result.Add(TextBefore(itemsListA.GetString(iSourceItem), #9))
		if (Result.GetString(1) = '..') then
      Result.Delete(1)
 		if (Result.GetString(0) = '.') then
      Result.Delete(0)
  end;
// MAIN SCRIPT BEGINS
begin
  // IS RESTORE DEFAULTS SET?
  if (  GetOption('Restore Defaults') = 1) then
    begin
      SetOption('Restore Defaults', 0);
      SetOption('File Mask', 0);
      SetOption('Enable Warnings', 1);
      SetOption('Picture Import Method', 0);
      if (ShowConfirmation('All options restored to their default settings.' + #13#10 +
                           'Do you wish to proceed with the script?') = False) then
        Exit;
    end;
  // MORE THAN ONE MOVIE SELECTED
  if (GetIterationCount <> 1) Then
    begin
      ShowError('This script works on one movie at a time.' + #13#10#13#10 +
      'You can do so by making sure only one movie is selected and selecting "Selected" in the "Script Limitation"' +
      'selection box that can be found at the bottom right area of the Scripting window.');
      Exit;
    end;
  // THERE ARE NO EXTRAS FOR THE SELECTED MOVIE
  if (GetExtraCount = 0) Then
    begin
      ShowError('There are no Extras for the selected movie.' + #13#10#13#10 +
      'This script works with exisiting Extras.');
      Exit;
    end;
  // THERE ARE NO EXTRAS SELECTED
	selectedExtrasList := TStringList.Create;
  totalExtras := GetExtraCount;
  for iExtras := 0 to totalExtras - 1 do
    begin
      if (IsExtraSelected(iExtras) = True) then
        begin
          selectedExtrasList.Add(IntToStr(iExtras));
        end;
    end;
  if (selectedExtrasList.Count = 0) Then
    begin
      ShowError('There are no selected Extras.' + #13#10#13#10 +
      'In order to use this script, please make sure to select at least one Extra.');
      Exit;
    end;
  // SELECTING WHICH EXTRA FIELD TO EDIT
  extrasFieldSelection := '';
	extrasFieldsList := TStringList.Create;
  PickTreeClear;
  PickTreeTitle('Extras Field Selection');
  for iExtrasFields := 0 to GetExtraFieldCount - 1 do
    begin
      if ((GetExtraFieldType(iExtrasFields) = 'ftString') OR
         (GetExtraFieldType(iExtrasFields) = 'ftList') OR
         (GetExtraFieldType(iExtrasFields) = 'ftText') OR
         (GetExtraFieldType(iExtrasFields) = 'ftUrl')) AND
         (iExtrasFields <> ePictureStatus) Then
            PickTreeAdd(GetExtraFieldName(iExtrasFields)+' ('+GetExtraFieldType(iExtrasFields)+')', IntToStr(iExtrasFields));
    end;
    PickTreeAdd('Picture', 'Picture');
    PickTreeSort;
    if (PickTreeExec3('Select from the list below which Extras field you wish to update:', extrasFieldSelection) = False) OR
       (extrasFieldSelection = '') then
        begin
          ShowError('You must select which Extra field you wish to update.');
          Exit;
        end;
  // IF PICTURE, ASK HOW AND/OR SET THE METHOD
  picImportMethod := IntToStr(picImportLinkRel);
  if GetOption('Picture Import Method') = 0 then //Prompt
    begin
      picImportMethod := '-1';
      while (picImportMethod = '-1') do
        begin
          PickTreeClear;
          PickTreeTitle('Pictures Handling Selection');
          PickTreeAdd('Store picture in catalog', IntToStr(picImportStore));
          PickTreeAdd('Copy picture to catalog folder', IntToStr(picImportCopyInCatDir));
          PickTreeAdd('Ccopy picture to pictures folder of catalog', IntToStr(picImportCopyInPicDir));
          PickTreeAdd('Link to picture with absolute link', IntToStr(picImportLinkAbs));
          PickTreeAdd('Link to picture with relative link if possible', IntToStr(picImportLinkRel));
          if (PickTreeExec3('Please select from the list below the method you wish to handle the pictures:', picImportMethod) = False) then
            Exit;
        end
    end
  else if (GetOption('Picture Import Method') = 1) then // picImportStore (store picture into catalog)
    picImportMethod := IntToStr(picImportStore)
  else if (GetOption('Picture Import Method') = 2) then // picImportCopyInCatDir (copy picture into catalog folder)
    picImportMethod := IntToStr(picImportCopyInCatDir)
  else if (GetOption('Picture Import Method') = 3) then // picImportCopyInPicDir (copy picture into pictures folder of catalog)
    picImportMethod := IntToStr(picImportCopyInPicDir)
  else if (GetOption('Picture Import Method') = 4) then // picImportLinkAbs (only link picture with absolute link)
    picImportMethod := IntToStr(picImportLinkAbs)
//  else if (GetOption('Picture Import Method') = 5) then // picImportLinkRel (only link picture with relative link if possible)
//    picImportMethod := IntToStr(picImportLinkRel)
  // ASK FOR SOURCE - FILE OR PATH
  sourcePath := '';
  while (DirectoryExists(sourcePath) <> True) AND (FileExists(sourcePath) <> True) do
    if (Input('Source', 'Please enter a path or a path to a file list you wish to use as a source:', sourcePath) = False) then
      Exit;
  sourceType := '';
  if (DirectoryExists(sourcePath) = True) then
    begin
      sourceType := 'Dir';
      // PROMPT FOR MASK OR TAKE FROM PARAMS
      mask := '';
      maskSelection := '';
      maskParam := GetOption('File Mask');
      if (maskParam = 0) and (extrasFieldSelection <> 'Picture') then
        begin
          PickTreeClear;
          PickTreeTitle('Mask Selection');
          PickTreeAdd('Image Files', '2');
          PickTreeAdd('Video Files', '1');
          PickTreeAdd('Custom', '0');
          if (PickTreeExec3('Select a file mask from the options below to filter the files in the given folder:', maskSelection) = False) then
            Exit
          else
          begin
            if (maskSelection = '0') then
              maskParam := 0
            else if (maskSelection = '1') then
              maskParam := 1
            else if (maskSelection = '2') then
              maskParam := 2;
          end;
        end;
      if (extrasFieldSelection = 'Picture') or (maskParam = 2) then // Images
        mask := '*.bmp;*.gif;*.jpe;*.jpeg;*.jpg;*.png'
      else if (maskParam = 1) then // Movies
        mask := '*.3gp;*.asf;*.avi;*.divx;*.evo;*.flv;*.ifo;*.m2p;*.m2ts;*.m4v;*.mkv;*.mov;*.mp4;*.mpe;*.mpeg;*.mpeg2;*.mpg;*.ogm;*.rm;*.rmvb;*.rv9;*.ts;*.vob;*.wmv;*.xvid'
      else if (maskParam = 0) then // Prompt
        begin
          while (mask = '') do
            Input('Source Mask', 'Please enter a valid mask for the file type(s) you wish to search for (use ; to separate multiple):', mask);
        end;
      itemsList := GetItemsList(sourcePath, mask);
      itemsList := CleanItemsList(itemsList);
    end
  else if (FileExists(sourcePath) = True) then
    begin
      sourceType := 'File';
      itemsList := TStringList.Create;
      itemsList.LoadFromFile(sourcePath);
    end
  else  // WE SHOULDN'T BE HERE BUT JUST IN CASE
    begin
      ShowError('You must select the source you wish to use for updating the selected Extras field.');
      Exit;
    end;
  iSourceItem := 0;
  iSelectionID := -1;
  itemSelection := '';
  while (iSelectionID <> 0) AND (itemsList.Count > 0) do
    begin
      PickTreeClear;
      PickTreeTitle('Source Items Preview:');
      PickTreeAdd('Continue...', '-1');
      for iSourceItem := 0 to itemsList.Count - 1 do
      PickTreeAdd(itemsList.GetString(iSourceItem), IntToStr(iSourceItem));
      if (PickTreeExec4('Select an item below if you wish to remove it, otherwise select "Continue..."', itemSelection, iSelectionID) = True) AND (iSelectionID <> 0) then
        itemsList.Delete(iSelectionID-1)
    end;
    // LET'S CHECK IF THE LIST ISN'T EMPTY
    if (itemsList.Count = 0) then
      begin
        ShowError('The items list is empty, there is nothing that can be assigned to the selected field.');
        Exit;
      end;
  // LET'S CHECK IF THERE IS DISCREPANCY BETWEEN EXTRAS AND ITEMS COUNTS AND PROMPT WARNING
  if (itemsList.Count <> selectedExtrasList.Count) AND (GetOption('Enable Warnings') = 1 )then
      if (ShowWarning('There is a discrepancy between the numbers of selected extras ('+IntToStr(selectedExtrasList.Count)+') and the number of items ('+IntToStr(itemsList.Count)+').'  + #13#10 +
                      'Only the available ones will be assigned, while the excess will be disregarded.' + #13#10#13#10 +
                      'You can disable future messages like this in the Options area of the script under Enable Warnings.') = False) then
                        Exit;
  // WE ARE NOW READY TO UPDATE THE SELECTED FIELD
  for iExtras := 0 to selectedExtrasList.Count - 1 do
    begin
      if extrasFieldSelection = 'Picture' then
        begin
          if (FileExists(IncludeTrailingPathDelimiter(sourcePath)+itemsList.GetString(iExtras)) = True) then
            ImportExtraPicture2(StrToInt(selectedExtrasList.GetString(iExtras),0), IncludeTrailingPathDelimiter(sourcePath)+itemsList.GetString(iExtras), StrToInt(picImportMethod,0))
          else
            if (ShowWarning('Could not locate:'+#13#10+IncludeTrailingPathDelimiter(sourcePath)+itemsList.GetString(iExtras)) = False) then
              Exit;
        end
      else
        begin
          if sourceType = 'File' then
            SetExtraField(StrToInt(selectedExtrasList.GetString(iExtras),0), StrToInt(extrasFieldSelection, 0), itemsList.GetString(iExtras))
          else
            SetExtraField(StrToInt(selectedExtrasList.GetString(iExtras),0), StrToInt(extrasFieldSelection, 0), IncludeTrailingPathDelimiter(sourcePath)+itemsList.GetString(iExtras))
        end;
    end;
  selectedExtrasList.Free;
  extrasFieldsList.Free;
  itemsList.Free;
end.