Hello,
I am new to this program and find it clutter free, fast and super customizable - I love it! Thank you for making it available!
I was wondering if there is a way to batch update selected extras (or even movies) with different values per extra?
To clarify, here is my scenario:
If I have a list of extras representing episodes that I initially added as place holders, I would like to be able to either update their thumbnail and/or URL with a list of files that I select (by the order I select them); I would like to keep everything else intact - description, titles etc.
And here is what I imagine it would be like:
An initial prompt asking what field you wish to update.
A file selection dialog where you select the files you wish to use to update the field you selected.
Upon confirmation the specified field is being updated with the selected files URLs.
*Another option is maybe use clipboard or a file with a list of items which might be more flexible in case you need to update the titles or description.
Does anyone have an idea how to achieve such a thing?
Any input would greatly appreciated - thank you in advance!
Batch update selected extras with selected files?
Re: Batch update selected extras with selected files?
Hi,
The part with the file selection dialog is too advanced for the script capabilities of the program, but for the rest it is maybe possible.
Many kinds of batch-update can be done with the script engine.
There is for example a script "Update Fields (FR-US).ifs" that was made for general changes, but that you can check for some help (though that its comments are in French...)
If you have some programming knowledge, it should not be too difficult to write your own script with that as basis. In the help file of the program there is the list of all available functions in the "Technical info" section (and some are made for handling Extras).
The part with the file selection dialog is too advanced for the script capabilities of the program, but for the rest it is maybe possible.
Many kinds of batch-update can be done with the script engine.
There is for example a script "Update Fields (FR-US).ifs" that was made for general changes, but that you can check for some help (though that its comments are in French...)
If you have some programming knowledge, it should not be too difficult to write your own script with that as basis. In the help file of the program there is the list of all available functions in the "Technical info" section (and some are made for handling Extras).
Re: Batch update selected extras with selected files?
Thank you for your reply!
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":
Thanks again!
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.
Re: Batch update selected extras with selected files?
For anyone who uses the script, I have updated it - I found some errors I overlooked