Personal Video Database
English => Support => Topic started by: afrocuban on November 16, 2024, 11:17:53 am
-
Hello again, Ivek. I'm further customizing your script. I've got that custom director's field, but I will not post the script until some point when I will be satisfied with the level of customization.
Now I'm working on a possibility to import more than one poster at once from the site (let's say, IMDb site). Do you by any chance know if database or PVD itself allows that, so with the proper script coding, multiple posters would be parsed and populated to poster field?
-
To add further questions, so you could answer in one post:
If you have a definitive answer (yes or no), how do you know that, is it your experience?
If it's not experience, is there any resource on this forum that I am able to see and find, but I can't succeed to find such info?
If there's some resource out of this forum, or here but I don't have access to it, and which would provide me to analyze capabilities of database and PVD itself, but you have an access to such resource I'd highly appreciate if you could, would or are allowed and be willing to share it with me.
Thank you in advance.
-
Hello again, Ivek. I'm further customizing your script. I've got that custom director's field, but I will not post the script until some point when I will be satisfied with the level of customization.
Now I'm working on a possibility to import more than one poster at once from the site (let's say, IMDb site). Do you by any chance know if database or PVD itself allows that, so with the proper script coding, multiple posters would be parsed and populated to poster field?
Hi afrocuban,
PVD can handle multiple images for the same type (poster, disk cover, etc..) but from scripts I have never been able to upload more than 1 per type.
-
Hi afrocuban,
PVD can handle multiple images for the same type (poster, disk cover, etc..) but from scripts I have never been able to upload more than 1 per type.
Hmmm, yes, me too. I'm trying but what ever I try, script won't compile, and it should. For example, this:
type
TPosterInfo = record
ImageURL: string;
Caption: string;
Height: Integer; // Included height in the record for clarity
end;
Function ParsePage_IMDBMovieBASE(HTML: String): Cardinal; //BlockOpen
//Returns:
// Result:=prFinished; Script has finished gathering data
// Result:=prError; If ¿any big problem? with exit;
// Retrieve: ~title~, ~year~, ~origtitle~, ~poster~ / ~imdbrating~, ~IMDB_Votes~ (Custom Field) / ~TOP_250~ (Custom Field) /
// If Not(GET_FULL_CREDIT): ~crew~ ctDirectors, ctWriters, ctComposers, ctProducers (Not in base page), ctActors
// ~description~ / ~category~ "keywords" / ~tagline~ / ~genre~
// If Not(GET_FULL_MPAA) ~mpaa~
// ~country~ / ~rdate~ in contry provider local IP geolocation
// If Not(GET_FULL_AKA) ~aka~.
// ~budget~ / ~money~ / ~studio~ "Production Co"
Var
curPos, endPos, index, debug_pos1: Integer;
StartPos, Hours, Minutes: Integer;
ItemValue, ItemValue0, ItemValue1, ItemValue2, ItemValue99, ItemList, ImageFile: String;
MovieURL, titleValue, yearValue, yearsValue: String;
Name, Role, PersonURL: String;
ItemList2, ItemList12, day_s, month_s, year_s: String;
ItemList1, ItemList11: String;
ItemArray: TWideArray;
Posters: array of TPosterInfo; // Declared Posters here
PosterURL, TempURL: String; // Added for poster handling
TempHeight: Integer; // Added for poster handling
Begin
LogMessage('Function ParsePage_IMDBMovieBASE BEGIN======================|');
Result := prFinished; // It will change to prError if any big problem with exit;
//Because the script doesn't retrieve the data in order, a token search for the first curPos position or block select is mandatory
//Get ~title~, ~year~, ~origtitle~, ~poster~
//Get all "raw" title summary (in raw because we need the hidden links, we avoid "complete" token in strings which opens/closes) // (* *)
//Get ~MID ID:~ and ~NUM ID::~
AddCustomFieldValueByName('MID ID:', GetFieldValueXML('mid'));
LogMessage(' ** Movie MID ID: ' + GetFieldValueXML('mid') + ' **');
if GetFieldValueXML('num') <> '0' then AddCustomFieldValueByName('NUM ID:', GetFieldValueXML('num'));
if GetFieldValueXML('num') <> '0' then LogMessage(' * Movie NUM ID: ' + GetFieldValueXML('num') + ' ||');
//Get ~script info~
//Get ~rdate~ in country provider local IP geolocation. See: http://sobizarre-en.blogspot.fr/2014/12/how-to-easily-defeat-imdb-geolocation.html
//Get ~imdbrating~, ~IMDB_Votes~ (Two tries)
ItemList := TextBetWeenFirst(HTML, '<script type="application/ld+json"', '}</script>'); //WEB_SPECIFIC.
//LogMessage(' Parse results (' + IntToStr(curPos) + ',' + IntToStr(endPos) + ') complex ItemList: ' + '<script type="application/ld+json"' + ItemList + '}</script>' + '||');
If (Length(ItemList) > 0) Then Begin
//Get ~IMDb Url~
//MovieURL:='http://www.imdb.com' + TextBetWeenFirst(ItemList, '","url":"', '","name":"');
MovieURL := TextBetWeenFirst(ItemList, '","url":"', '","name":"');
MovieURL := StringReplace(MovieURL, 'https://', 'http://', True, False, True);
AddFieldValueXML('url', MovieURL);
LogMessage(' * Get result url 1:' + MovieURL + ' ||');
LogMessage(' * Get result MovieURL: ' + MovieURL);
// IMDB_FIELD = 'IMDB';
if PosFrom('imdb', MovieURL, 1) > 0 then AddCustomFieldValueByName(IMDB_FIELD, '-1');
//Get ~title~
titleValue := TextBetWeenFirst(ItemList, '","name":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
If titleValue = '0' then titleValue := '';
//If titleValue = '' then titleValue := TextBetWeenFirst(ItemList, '<h1 class="long">', '<'); //Strings which opens/closes the data. WEB_SPECIFIC
if GET_ORIGINAL_TITLE then AddFieldValueXML('title', titleValue);
AddCustomFieldValueByName('Title', titleValue);
AddCustomFieldValueByName('Localized title', titleValue);
LogMessage(' Get result title:' + titleValue + '||');
//Get ~origtitle~
ItemValue := TextBetWeenFirst(ItemList, '","name":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
If (Length(ItemValue) = 0) Then ItemValue := titleValue; //Provider hides the original title if same as title. WEB_SPECIFIC
AddFieldValueXML('origtitle', ItemValue);
AddCustomFieldValueByName('Origtitle', ItemValue);
LogMessage(' Get result origtitle:' + ItemValue + '||');
//Get ~alternatetitle~
ItemValue := TextBetWeenFirst(ItemList, '","alternateName":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
AddCustomFieldValueByName('Localized title', ItemValue);
if GET_LOCAL_TITLE then AddFieldValueXML('title', ItemValue);
if ItemValue <> '' then LogMessage(' Get result alternatetitle:' + ItemValue + '||');
If ItemValue <> '' then AddCustomFieldValueByName('Imdb_Title', ItemValue + #13 + titleValue + ' (original title)')
Else AddCustomFieldValueByName('Imdb_Title', titleValue);
//Get ~IMDB_Movietype~
ItemValue := TextBetWeenFirst(ItemList, '","@type":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
MediaType := ItemValue;
MediaType := StringReplace(MediaType, 'TVEpisode', 'TV Episode', True, False, True);
MediaType := StringReplace(MediaType, 'TVSeries', 'TV Series', True, False, True);
AddCustomFieldValueByName('IMDB_Movietype', MediaType);
AddCustomFieldValueByName('Tv 0', MediaType);
if ItemValue <> '' then LogMessage(' Get result MediaType (CF~IMDB_Movietype~):' + MediaType + '||');
//Get ~IMDB_MPAA~
ItemValue := TextBetWeenFirst(ItemList, ',"contentRating":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
AddCustomFieldValueByName('IMDB_MPAA', ItemValue);
if ItemValue <> '' then LogMessage(' Get result ContentRating (CF~IMDB_MPAA~):' + ItemValue + '||');
// Start of the new poster-related code
procedure AddPoster(const URL: string; Height: Integer);
begin
SetLength(Posters, Length(Posters) + 1);
Posters[High(Posters)].ImageURL := URL;
Posters[High(Posters)].Caption := 'Poster'; // Adjust this as needed
Posters[High(Posters)].Height := Height; // Added to ensure height is stored
end;
repeat
PosterURL := TextBetWeenFirst(ItemList, BASE_URL_IMAGE_PRE_TRUE, '.'); // Adjust this to match actual URLs
if PosterURL <> '' then
begin
TempURL := BASE_URL_IMAGE_PRE_TRUE + PosterURL + '.jpg';
TempHeight := StrToIntDef(TextBetWeenFirst(PosterURL, '_V1_UY', '_'), 0);
AddPoster(TempURL, TempHeight);
end;
until (PosterURL = '');
// Import the posters up to the specified limit
PosterCount := Min(5, Length(Posters)); // Up to 5 posters
for index := 0 to PosterCount - 1 do
begin
ImageFile := GetAppPath + 'Scripts\' + BASE_DOWNLOAD_FILE_IMAGE_NAME + '-Poster-' + IntToStr(index + 1) + '.jpg';
if (1 = DownloadImage(Posters[index].ImageURL + '._V1_UY' + IntToStr(Posters[index].Height) + '_.jpg', ImageFile)) then
begin
AddImageURL(itPoster, ImageFile);
LogMessage('Imported poster: ' + Posters[index].ImageURL + '._V1_UY' + IntToStr(Posters[index].Height) + '_.jpg' + ' || Height: ' + IntToStr(Posters[index].Height));
end
else if (1 = DownloadImage(Posters[index].ImageURL + '.jpg', ImageFile)) then
begin
AddImageURL(itPoster, ImageFile);
LogMessage('Imported poster: ' + Posters[index].ImageURL + '.jpg' + ' || Height: ' + IntToStr(Posters[index].Height));
end;
end;
// End of the new poster-related code
End;
Begin
LoadPosters;
// Additional code to integrate with PVD if needed
End.
//~description~
The log complains with this
(11/16/2024 1:17:20 PM) Could not compile script: IMDB_2c_afro-Custom Cast + more.psf
[Error] (731:5): Identifier expected
Line 731 is procedure AddPoster(const URL: string; Height: Integer);
-
Hello again, Ivek. I'm further customizing your script. I've got that custom director's field, but I will not post the script until some point when I will be satisfied with the level of customization.
Now I'm working on a possibility to import more than one poster at once from the site (let's say, IMDb site). Do you by any chance know if database or PVD itself allows that, so with the proper script coding, multiple posters would be parsed and populated to poster field?
Hi afrocuban,
PVD can handle multiple images for the same type (poster, disk cover, etc..) but from scripts I have never been able to upload more than 1 per type.
NetworkShark user has already written the correct findings regarding the number of adding posters and other images to the PVD database using scripts. VVV_Easy_Programin user and author of the mod versions also found that it was not possible to add more than one screenShot for each movie from the website to the database. Also all 1.x.x versions allow the transfer of only one type (poster, disk cover, etc..).
However, there is a manual solution for adding multiple types (poster, disk cover, etc..). The easiest way is to add manually in edit mode. It is not bad if you also have an imagelist added to the skin, as in the code added below. <tab shape="true" space="1">
<caption>&Images</caption>
<color>$E0ECFE</color>
<row>
<column valign="top" space="1">
<imagelist valign="top" halign="left" cheight="100" cwidth="75" autosize="true" space="7">
<border shape="none" />
<color>$CCDDEE</color>
</imagelist>
</column>
</row>
</tab>
-
Hi afrocuban,
PVD can handle multiple images for the same type (poster, disk cover, etc..) but from scripts I have never been able to upload more than 1 per type.
Hmmm, yes, me too. I'm trying but what ever I try, script won't compile, and it should. For example, this:
type
TPosterInfo = record
ImageURL: string;
Caption: string;
Height: Integer; // Included height in the record for clarity
end;
Function ParsePage_IMDBMovieBASE(HTML: String): Cardinal; //BlockOpen
//Returns:
// Result:=prFinished; Script has finished gathering data
// Result:=prError; If ¿any big problem? with exit;
// Retrieve: ~title~, ~year~, ~origtitle~, ~poster~ / ~imdbrating~, ~IMDB_Votes~ (Custom Field) / ~TOP_250~ (Custom Field) /
// If Not(GET_FULL_CREDIT): ~crew~ ctDirectors, ctWriters, ctComposers, ctProducers (Not in base page), ctActors
// ~description~ / ~category~ "keywords" / ~tagline~ / ~genre~
// If Not(GET_FULL_MPAA) ~mpaa~
// ~country~ / ~rdate~ in contry provider local IP geolocation
// If Not(GET_FULL_AKA) ~aka~.
// ~budget~ / ~money~ / ~studio~ "Production Co"
Var
curPos, endPos, index, debug_pos1: Integer;
StartPos, Hours, Minutes: Integer;
ItemValue, ItemValue0, ItemValue1, ItemValue2, ItemValue99, ItemList, ImageFile: String;
MovieURL, titleValue, yearValue, yearsValue: String;
Name, Role, PersonURL: String;
ItemList2, ItemList12, day_s, month_s, year_s: String;
ItemList1, ItemList11: String;
ItemArray: TWideArray;
Posters: array of TPosterInfo; // Declared Posters here
PosterURL, TempURL: String; // Added for poster handling
TempHeight: Integer; // Added for poster handling
Begin
LogMessage('Function ParsePage_IMDBMovieBASE BEGIN======================|');
Result := prFinished; // It will change to prError if any big problem with exit;
//Because the script doesn't retrieve the data in order, a token search for the first curPos position or block select is mandatory
//Get ~title~, ~year~, ~origtitle~, ~poster~
//Get all "raw" title summary (in raw because we need the hidden links, we avoid "complete" token in strings which opens/closes) // (* *)
//Get ~MID ID:~ and ~NUM ID::~
AddCustomFieldValueByName('MID ID:', GetFieldValueXML('mid'));
LogMessage(' ** Movie MID ID: ' + GetFieldValueXML('mid') + ' **');
if GetFieldValueXML('num') <> '0' then AddCustomFieldValueByName('NUM ID:', GetFieldValueXML('num'));
if GetFieldValueXML('num') <> '0' then LogMessage(' * Movie NUM ID: ' + GetFieldValueXML('num') + ' ||');
//Get ~script info~
//Get ~rdate~ in country provider local IP geolocation. See: http://sobizarre-en.blogspot.fr/2014/12/how-to-easily-defeat-imdb-geolocation.html
//Get ~imdbrating~, ~IMDB_Votes~ (Two tries)
ItemList := TextBetWeenFirst(HTML, '<script type="application/ld+json"', '}</script>'); //WEB_SPECIFIC.
//LogMessage(' Parse results (' + IntToStr(curPos) + ',' + IntToStr(endPos) + ') complex ItemList: ' + '<script type="application/ld+json"' + ItemList + '}</script>' + '||');
If (Length(ItemList) > 0) Then Begin
//Get ~IMDb Url~
//MovieURL:='http://www.imdb.com' + TextBetWeenFirst(ItemList, '","url":"', '","name":"');
MovieURL := TextBetWeenFirst(ItemList, '","url":"', '","name":"');
MovieURL := StringReplace(MovieURL, 'https://', 'http://', True, False, True);
AddFieldValueXML('url', MovieURL);
LogMessage(' * Get result url 1:' + MovieURL + ' ||');
LogMessage(' * Get result MovieURL: ' + MovieURL);
// IMDB_FIELD = 'IMDB';
if PosFrom('imdb', MovieURL, 1) > 0 then AddCustomFieldValueByName(IMDB_FIELD, '-1');
//Get ~title~
titleValue := TextBetWeenFirst(ItemList, '","name":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
If titleValue = '0' then titleValue := '';
//If titleValue = '' then titleValue := TextBetWeenFirst(ItemList, '<h1 class="long">', '<'); //Strings which opens/closes the data. WEB_SPECIFIC
if GET_ORIGINAL_TITLE then AddFieldValueXML('title', titleValue);
AddCustomFieldValueByName('Title', titleValue);
AddCustomFieldValueByName('Localized title', titleValue);
LogMessage(' Get result title:' + titleValue + '||');
//Get ~origtitle~
ItemValue := TextBetWeenFirst(ItemList, '","name":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
If (Length(ItemValue) = 0) Then ItemValue := titleValue; //Provider hides the original title if same as title. WEB_SPECIFIC
AddFieldValueXML('origtitle', ItemValue);
AddCustomFieldValueByName('Origtitle', ItemValue);
LogMessage(' Get result origtitle:' + ItemValue + '||');
//Get ~alternatetitle~
ItemValue := TextBetWeenFirst(ItemList, '","alternateName":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
AddCustomFieldValueByName('Localized title', ItemValue);
if GET_LOCAL_TITLE then AddFieldValueXML('title', ItemValue);
if ItemValue <> '' then LogMessage(' Get result alternatetitle:' + ItemValue + '||');
If ItemValue <> '' then AddCustomFieldValueByName('Imdb_Title', ItemValue + #13 + titleValue + ' (original title)')
Else AddCustomFieldValueByName('Imdb_Title', titleValue);
//Get ~IMDB_Movietype~
ItemValue := TextBetWeenFirst(ItemList, '","@type":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
MediaType := ItemValue;
MediaType := StringReplace(MediaType, 'TVEpisode', 'TV Episode', True, False, True);
MediaType := StringReplace(MediaType, 'TVSeries', 'TV Series', True, False, True);
AddCustomFieldValueByName('IMDB_Movietype', MediaType);
AddCustomFieldValueByName('Tv 0', MediaType);
if ItemValue <> '' then LogMessage(' Get result MediaType (CF~IMDB_Movietype~):' + MediaType + '||');
//Get ~IMDB_MPAA~
ItemValue := TextBetWeenFirst(ItemList, ',"contentRating":"', '","'); //Strings which opens/closes the data. WEB_SPECIFIC
AddCustomFieldValueByName('IMDB_MPAA', ItemValue);
if ItemValue <> '' then LogMessage(' Get result ContentRating (CF~IMDB_MPAA~):' + ItemValue + '||');
// Start of the new poster-related code
procedure AddPoster(const URL: string; Height: Integer);
begin
SetLength(Posters, Length(Posters) + 1);
Posters[High(Posters)].ImageURL := URL;
Posters[High(Posters)].Caption := 'Poster'; // Adjust this as needed
Posters[High(Posters)].Height := Height; // Added to ensure height is stored
end;
repeat
PosterURL := TextBetWeenFirst(ItemList, BASE_URL_IMAGE_PRE_TRUE, '.'); // Adjust this to match actual URLs
if PosterURL <> '' then
begin
TempURL := BASE_URL_IMAGE_PRE_TRUE + PosterURL + '.jpg';
TempHeight := StrToIntDef(TextBetWeenFirst(PosterURL, '_V1_UY', '_'), 0);
AddPoster(TempURL, TempHeight);
end;
until (PosterURL = '');
// Import the posters up to the specified limit
PosterCount := Min(5, Length(Posters)); // Up to 5 posters
for index := 0 to PosterCount - 1 do
begin
ImageFile := GetAppPath + 'Scripts\' + BASE_DOWNLOAD_FILE_IMAGE_NAME + '-Poster-' + IntToStr(index + 1) + '.jpg';
if (1 = DownloadImage(Posters[index].ImageURL + '._V1_UY' + IntToStr(Posters[index].Height) + '_.jpg', ImageFile)) then
begin
AddImageURL(itPoster, ImageFile);
LogMessage('Imported poster: ' + Posters[index].ImageURL + '._V1_UY' + IntToStr(Posters[index].Height) + '_.jpg' + ' || Height: ' + IntToStr(Posters[index].Height));
end
else if (1 = DownloadImage(Posters[index].ImageURL + '.jpg', ImageFile)) then
begin
AddImageURL(itPoster, ImageFile);
LogMessage('Imported poster: ' + Posters[index].ImageURL + '.jpg' + ' || Height: ' + IntToStr(Posters[index].Height));
end;
end;
// End of the new poster-related code
End;
Begin
LoadPosters;
// Additional code to integrate with PVD if needed
End.
//~description~
The log complains with this
(11/16/2024 1:17:20 PM) Could not compile script: IMDB_2c_afro-Custom Cast + more.psf
[Error] (731:5): Identifier expected
Line 731 is procedure AddPoster(const URL: string; Height: Integer);
procedure AddPoster(const URL: string; Height: Integer);
Of course, this doesn't work, it reports an error, because this AddPoster procedure must be added separately to the script, just like, for example, Function TextBetWeenFirst, so that the script will then show the errors that need to be fixed.
It will immediately report an error for
SetLength or somewhere else that needs to be added.
And this.
As you now have the code for posters, you will not be able to download the nebene downimage-BIN-Poster image to the Tmp folder because you are missing part of the code for DownloadImage
And this advice.
It is also necessary to edit the code for transferring to the Tmp folder so that there are more downimage-BIN-Poster images in the folder, only then will it be possible to add more poster types to the database.
-
Thanks for the responses. We could probably achieve this by mimicking nextposterbtn clicking after each import. That would also need to rewrite ahk autioit script, and all of that would be way to over headed
-
And then, I thought that maybe multiple posters can be imported by the script at once to imagelist field, beside poster which is not in imagelist? For this we would need probably something like multiple-downpage-UTF8_NO_BOM.htm and the rest to be defined...