Recent Posts

Pages: 1 [2] 3 4 5 6 7 ... 10
11
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Custom Fields
« Last post by Ivek23 on March 29, 2025, 03:15:49 pm »
ParsePage_IMDBMovieREFERENCE

PVD custom field for Type/Comments in Preferences/Movies/Custom Items:
  • Reference (Memo)
  • Year (Multiselect list)
  • Title (Memo)
  • Localized title (Memo)
  • Title1 (Long Text)
  • Origtitle (Memo)
  • Original Title (Memo)
  • Imdb_Title (Memo)
  • Imdb Title 1 (Memo)
  • Imdb Title (Memo)
  • IMDB Rating or IMDBRating (Rating)
  • IMDB Votes or IMDB Votes:', (Number)
  • IMDB Release Date (Short Text)
  • TOP_250 or Top 250: (Number)
  • TOP_250TV (Number)
  • Bottom 100 (Number)
  • IMDb Studio2 (Memo)
  • Distributors (Memo)
  • IMDbAwards1(Memo) or (Long Text)
  • IMDb_Reviews_Summary (Memo)
  • IMDB Plot Summary (Memo)
  • Description (Memo)
  • IMDB_Tagline (Memo)
  • Sound Mix (Multiselect list)
  • IMDB - Sound Mix (Multiselect list)
  • Run time 1 (Short Text)
  • Imdb Runtime 1 (Long Text)
  • ProductionBudget (Long Text)
  • Language: (Multiselect list)
  • IMDb_Filming_Locations (Memo)
  • Color : (Multiselect list)
  • Imdb Color : (Multiselect list)
  • Certification: (Memo)
  • Imdb Aka (Memo)
  • IMDbCountryAKA (Memo)
12
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 29, 2025, 12:58:31 pm »
Function ParsePage_IMDBMovieBASE

Minor code correction.

Quote
   If Not (ReferencePageDownloaded) Then Begin
      If Not (USE_SAVED_PVDCONFIG And (ConfigOptions[19] = '0')) Then Begin
         // Get ~budget~
         //curPos := Pos('<span class="ipc-metadata-list-item__label" aria-disabled="false">Budget</span>', HTML); // WEB_SPECIFIC
         curPos := Pos('<span class="ipc-metadata-list-item__label ipc-btn--not-interactable" aria-disabled="false">Budget</span>', HTML); // WEB_SPECIFIC
         If 0 < curPos Then Begin
            ItemValue := TextBetWeen(HTML, '<span class="ipc-metadata-list-item__label ipc-btn--not-interactable" aria-disabled="false">Budget</span><div class="ipc-metadata-list-item__content-container"><ul class="ipc-inline-list ipc-inline-list--show-dividers ipc-inline-list--inline ipc-metadata-list-item__list-content base" role="presentation"><li role="presentation" class="ipc-inline-list__item"><span class="ipc-metadata-list-item__list-content-item ipc-btn--not-interactable" aria-disabled="false">', '</span></li></ul>', false, curPos); // Strings which opens/closes the data. WEB_SPECIFIC
            ItemValue := StringReplace(ItemValue, ' (estimated)', '', True, True, False); // Eliminate '(estimated)' if exists
            if ItemValue <> '' then AddCustomFieldValueByName('ProductionBudget', ItemValue);
            ItemValue := StringReplace(ItemValue, 'EUR', '', True, True, False); // Eliminate 'EUR' if exists
            ItemValue := StringReplace(ItemValue, #36, '', True, True, False); // Eliminate '$' if exists
            ItemValue := StringReplace(ItemValue, '€', '', True, True, False); // Eliminate '€' if exists
            ItemValue := StringReplace(ItemValue, ',', '', True, True, False); // Eliminate ',' if exists
            AddFieldValueXML('budget', ItemValue);
            if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE - ParsePage_IMDBMovieBASE - Get results ~budget~: ' + ItemValue + ' | |');
         End;
      End;
   End;   //If Not (ReferencePageDownloaded) Then Begin should end here
   
      //Get (CF~Domestic~) Gross US & Canada
      //curPos:=Pos('<span class="ipc-metadata-list-item__label" aria-disabled="false">Gross US & Canada</span>',HTML);      //WEB_SPECIFIC
      curPos:=Pos('<span class="ipc-metadata-list-item__label ipc-btn--not-interactable" aria-disabled="false">Gross US & Canada</span>',HTML);      //WEB_SPECIFIC
      If 0<curPos Then Begin       
         ItemValue:=TextBetWeen(HTML,'<span class="ipc-metadata-list-item__label ipc-btn--not-interactable" aria-disabled="false">Gross US & Canada</span>','</li></ul>',false,curPos);      //Strings which opens/closes the data. WEB_SPECIFIC
         //LogMessage('Function ParsePage_IMDBMovieBASE -      Get results BoxOffice Gross US & Canada:'+ItemValue+'||');
         if ItemValue <> '' then AddCustomFieldValueByName('Domestic',ItemValue);      
         ItemValue:=StringReplace(ItemValue,#36,'',True,True,False);        //Eliminate '$' if exists 
         ItemValue:=StringReplace(ItemValue,'€','',True,True,False);        //Eliminate '€' if exists         
         ItemValue:=StringReplace(ItemValue,',','',True,True,False);        //Eliminate ',' if exists       
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get results Box Office Gross US & Canada  (CF~Domestic~):'+ItemValue+'||');
      End;   
   
      If Not (USE_SAVED_PVDCONFIG And (ConfigOptions[20] = '0')) Then Begin
         // Get ~money~ +  (CF~Worldwide~) Box Office worldwide
         //curPos := Pos('<span class="ipc-metadata-list-item__label" aria-disabled="false">Gross worldwide</span>', HTML); // WEB_SPECIFIC
         curPos := Pos('<span class="ipc-metadata-list-item__label ipc-btn--not-interactable" aria-disabled="false">Gross worldwide</span>', HTML); // WEB_SPECIFIC
         If 0 < curPos Then Begin
            ItemValue := TextBetWeen(HTML, '<span class="ipc-metadata-list-item__label ipc-btn--not-interactable" aria-disabled="false">Gross worldwide</span><div class="ipc-metadata-list-item__content-container"><ul class="ipc-inline-list ipc-inline-list--show-dividers ipc-inline-list--inline ipc-metadata-list-item__list-content base" role="presentation"><li role="presentation" class="ipc-inline-list__item"><span class="ipc-metadata-list-item__list-content-item ipc-btn--not-interactable" aria-disabled="false">', '</span></li></ul>', false, curPos); // Strings which opens/closes the data. WEB_SPECIFIC
            LogMessage('Function ParsePage_IMDBMovieBASE -      Get results BoxOffice worldwide: ' + ItemValue + ' | |');

            // Process the monetary value for XML
            MoneyValue := ItemValue;
            MoneyValue := StringReplace(MoneyValue, #36, '', True, True, False); // Eliminate '$' if exists
            MoneyValue := StringReplace(MoneyValue, '€', '', True, True, False); // Eliminate '€' if exists
            MoneyValue := StringReplace(MoneyValue, ',', '', True, True, False); // Eliminate ',' if exists
            LogMessage('Function ParsePage_IMDBMovieBASE - Processed Box Office value for "money" PVD field: ' + MoneyValue);
            AddFieldValueXML('money', MoneyValue);

            // Add the Worldwide value with currency symbol
            If ItemValue <> '' Then AddCustomFieldValueByName('Worldwide', ItemValue);

            If MoneyValue <> '' Then LogMessage('Function ParsePage_IMDBMovieBASE - Get results Box Office worldwide ~money~ +  (CF~Worldwide~): ' + MoneyValue + ' | |');
         End;
      End;
      
13
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 29, 2025, 12:46:57 pm »
Function ParsePage_IMDBMovieMPAA

Fix part of the code.

Quote
    mpaaValue := '';
   
   // Get (CF~IMDbmpaaSummary~)
      curPos := Pos('<select id="jump-to"', HTML);
      If curPos > 0 Then
      Begin
        // Extract the relevant section for categories
        curPos := PosFrom('<option', HTML, curPos);
        endPos := PosFrom('</select>', HTML, curPos);
        mpaaSection := Copy(HTML, curPos, endPos - curPos);
        //LogMessage('Function ParsePage_IMDBMovieMPAA - Extracted Category section for (CF~IMDbmpaaSummary~): ' + mpaaSection);

        // Parse the options and category names
        curPos := 1;
        mpaaContent := '';
        While PosFrom('<option', mpaaSection, curPos) > 0 Do
        Begin
         curPos := PosFrom('<option', mpaaSection, curPos) + Length('<option');
         optionValue := TextBetween(mpaaSection, 'value="', '">', False, curPos);
         categoryName := TextBetween(mpaaSection, '">', '</option>', False, curPos);

         // Format the category link
         mpaaContent := mpaaContent + '<link url="' + MovieURL + optionValue + '">' + categoryName + '</link>    ';

         // Move to the next position
         curPos := PosFrom('</option>', mpaaSection, curPos) + Length('</option>');
        End;

        // Remove the trailing "   •   " if it exists and keep the last </link> intact
        If Copy(mpaaContent, Length(mpaaContent) - 13, 7) = '   •   ' Then
        Begin
         mpaaContent := Copy(mpaaContent, 1, Length(mpaaContent) - 14) + '</link>';
        End;

        // Combine and format the final result 
        mpaaContent := '<link url="' + MovieURL + '#contentRating' + '">Content Ratings Summary:</link>     •     ' + mpaaContent;
       
        // Store the result in the custom field
        AddCustomFieldValueByName('IMDbmpaaSummary', mpaaContent);
        LogMessage('Function ParsePage_IMDBMovieMPAA - Stored result for (CF~IMDbmpaaSummary~)');
      End
      Else
      Begin
        LogMessage('Function ParsePage_IMDBMovieMPAA - Content Rating section for (CF~IMDbmpaaSummary~) not found');
        Result := prError; // Set to error if content rating section is not found
      End;
      
      
Custom field to remove.

Quote
      AddFieldValueXML('mpaa', mpaaValue);
      //AddCustomFieldValueByName('IMDB_MPAA', mpaaValue);
      LogMessage('Function ParsePage_IMDBMovieMPAA - Final ~mpaa~ Result: ' + mpaaValue + ' | |');

   // Get "Certification" (CF~Certification~) info


14
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Custom Fields
« Last post by Ivek23 on March 28, 2025, 08:00:33 pm »
Function ParsePage_IMDBMovieAKA

PVD custom field for Type/Comments in Preferences/Movies/Custom Items:

  • Release infos (Memo)
  • Imdb Aka (Memo)
  • IMDbCountryAKA (Memo)
  • IMDbPremiereDates (Memo)

Function ParsePage_IMDBMovieCREDIT

PVD custom field for Type/Comments in Preferences/Movies/Custom Items:

  • Cinema (Memo)
  • Cinema1 (Memo)
  • IMDb Directed by: (Memo)
  • IMDb Cast (Memo)
  • Thank (Memo)


Function ParsePage_IMDBMovieMPAA

PVD custom field for Type/Comments in Preferences/Movies/Custom Items:

  • IMDbmpaaSummary (Memo)
  • IMDbmpaaDetails (Memo)
  • Certification (Memo)
15
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 28, 2025, 05:27:31 pm »
Function ParsePage_IMDBMovieBASE

Quote
// Get ~User Reviews~

This part of the code is added here.

Quote
FullReview := StringReplace(FullReview, '; - )', '', True, False, True);

The whole code is now like this.

Quote
      // Get ~User Reviews~
   curPos := Pos('<section data-testid="UserReviews"', HTML); // Start of the User Reviews section
   If 0 < curPos Then Begin
      // Loop through multiple reviews if needed
      While 0 < curPos Do Begin
         // Find the review subject start
         curPos := PosFrom('data-testid="review-summary"><a href="', HTML, curPos);
         If 0 < curPos Then Begin
            curPos := PosFrom(' class="ipc-title-link-wrapper" tabindex="0"><h3 class="ipc-title__text">', HTML, curPos) + Length(' class="ipc-title-link-wrapper" tabindex="0"><h3 class="ipc-title__text">');
            EndPos := PosFrom('<svg', HTML, curPos);
            ItemValue := Copy(HTML, curPos, EndPos - curPos);
            ItemValue := Trim(ItemValue); // Clean up leading/trailing whitespace
            curPos := EndPos;

            // Find the review content start
            curPos := PosFrom('<div class="ipc-overflowText--children"><div class="ipc-html-content ipc-html-content--base" role="presentation"><div class="ipc-html-content-inner-div" role="presentation">', HTML, curPos) + Length('<div class="ipc-overflowText--children"><div class="ipc-html-content ipc-html-content--base" role="presentation"><div class="ipc-html-content-inner-div" role="presentation">');
            EndPos := PosFrom('</div></div></div></div></div><div class="ipc-list-card__actions">', HTML, curPos);
            ReviewContent := Copy(HTML, curPos, EndPos - curPos);
            ReviewContent := Trim(ReviewContent); // Clean up leading/trailing whitespace

            // Combine review subject and content
            FullReview := ItemValue + #13#10 + '-------------------------------------------' + #13#10 + ReviewContent; // Add new line between subject and content

            // Clean up unnecessary parts of the review content
            FullReview := StringReplace(FullReview, '; - )', '', True, False, True);
            FullReview := StringReplace(FullReview, ':)', '', True, False, True);
            FullReview := StringReplace(FullReview, '=)', '', True, False, True);

            // Add the review to custom fields
            AddCustomFieldValueByName('User Reviews', FullReview);
            AddCustomFieldValueByName('User Comments', FullReview);

            // Log the review
            If FullReview <> '' Then LogMessage('Function ParsePage_IMDBMovieBASE - Get result User Reviews (CF~User Reviews~) (CF~User Comments~): <br>' + FullReview + ' | |');

            // Move to the next review
            curPos := PosFrom('<section data-testid="UserReviews"', HTML, curPos);
         End Else Break;
      End;
   End;

In Function ParsePage_IMDBMovieBASE, everything would be there.
16
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 28, 2025, 05:22:09 pm »
Function ParsePage_IMDBMovieBASE

Cleaned part of the code and Custom field name changes.

Quote
//LogMessage('Function ParsePage_IMDBMovieBASE -      Get results ItemList before If  GET_MINI_FEATURES Then Begin: ' + ItemList + ' | |');
         If  GET_MINI_FEATURES Then Begin
      If Not(TechnicalPageDownloaded) then Begin
      //Get ~features~ (multiline) GET_FULL_FEATURES = False only the info from the main movie page..
            ItemList := '';
            // Get the original "Runtime" (in minutes) as ~length~ (in seconds) instead of the duration of the user movie copy
            curPos := Pos('<span class="ipc-metadata-list-item__label" aria-disabled="false">Runtime</span>', HTML);
            if curPos > 0 then begin
               Hours := StrToInt(HTMLValue(HTML, curPos, 0, '<div class="ipc-metadata-list-item__content-container">', '<!-- --> <!-- -->hour'));
               LogMessage('Function ParsePage_IMDBMovieBASE - Get result Original Runtime: ' + IntToStr(Hours) + ' | |');
               If (Pos('hour<!-- --> <!-- -->', HTML) <> 0) Then
                  Minutes := StrToInt(HTMLValue(HTML, curPos, 0, 'hour<!-- --> <!-- -->', '<!-- --> <!-- -->minutes'))
               Else Minutes := StrToInt(HTMLValue(HTML, curPos, 0, 'hours<!-- --> <!-- -->', '<!-- --> <!-- -->minutes'));
               ItemValue := IntToStr(Hours * 60 + Minutes);
               If ItemValue = '0' then ItemValue := '';
               If ItemValue = '' then Minutes := StrToInt(HTMLValue(HTML, curPos, 0, '<div class="ipc-metadata-list-item__content-container">', '<!-- --> <!-- -->minutes'));
               ItemValue := IntToStr(Hours * 60 + Minutes);
               LogMessage('Function ParsePage_IMDBMovieBASE - duration: ' + ItemValue);
               if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE - Get result Original Runtime: ' + ItemValue + ' | |');
               AddCustomFieldValueByName('Imdb Runtime1', IntToStr(Hours) + 'h' + ' ' + IntToStr(Minutes) + 'm (' + ItemValue + ' minutes)');
               ItemList := 'Runtime: ' + ItemList + IntToStr(Hours) + 'h' + ' ' + IntToStr(Minutes) + 'm (' + ItemValue + ' minutes)' + '<br>';            
               AddFieldValueXML('length', IntToStr(60 * StrToInt(ItemValue))); //~length~ Value in seconds.
               if ItemValue <> '' then AddCustomFieldValueByName('Run time1', ItemValue);
//               AddCustomFieldValueByName('Run time', ItemValue);
               if ItemValue <> '' then Begin
               LogMessage('Function ParsePage_IMDBMovieBASE - Get result "Runtime" (in minutes) as ~length~: ' + ItemValue + ' | |');
               end else
               LogMessage('Function ParsePage_IMDBMovieBASE - duration/length not found');

      //Get "Color" (CF~Color~), (CF~Imdb Color~) (multiple values in a comma separated list)
            curPos := Pos('<span class="ipc-metadata-list-item__label" aria-disabled="false">Color</span>', HTML);
               //LogMessage('Function ParsePage_IMDBMovieBASE - Get result curPos (CF~Color~) & (CF~Imdb Color~): ' + IntToStr(curPos) + ' | |');
            if 0<curPos then begin
               EndPos := curPos;
               ItemValue := HTMLValues2(HTML, '<span class="ipc-metadata-list-item__label" aria-disabled="false">Color</span>', '</ul>', '<li role="presentation" class="ipc-inline-list__item">', '</li>', ', ', EndPos);
               //LogMessage('Function ParsePage_IMDBMovieBASE -       Get result ItemValue after HTMLValues2 (CF~Color~) & (CF~Imdb Color~): ' + ItemValue + ' | |');
               //ItemValue := StringReplace(ItemValue, '|        ', ', ', True, True, False);    //WEB_SPECIFIC.
               ItemValue := StringReplace(ItemValue, '(', ' (', True, True, False);          //WEB_SPECIFIC.
               if ItemValue <> '' then ItemList := ItemList + 'Color: ' + ItemValue + '<br>';
               if ItemValue <> '' then AddCustomFieldValueByName('Color:', ItemValue);
               if ItemValue <> '' then AddCustomFieldValueByName('Imdb Color', ItemValue);
               if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -       Get result (CF~Color~), (CF~Imdb Color~), (CF~Imdb_Color~) and (CF~Imdb Color:~): ' + ItemValue + ' | |');
            End;
         End;   //If Not(TechnicalPageDownloaded) then Begin should end here
         
      If Not(TechnicalPageDownloaded) And Not(ReferencePageDownloaded) then Begin
      //Get "Sound Mix" info (CF~SILENT_FIELD~), (CF~Sound Mix:~)  (multiple values in a comma separated list)
            curPos := Pos('<span class="ipc-metadata-list-item__label" aria-disabled="false">Sound mix</span>', HTML);
            if 0<curPos then begin
            EndPos := curPos;
               ItemValue := HTMLValues(HTML,
               '<span class="ipc-metadata-list-item__label" aria-disabled="false">Sound mix</span>', '</ul>', '<li role="presentation" class="ipc-inline-list__item">', '</li>', ', ', EndPos);
               //ItemValue := StringReplace(ItemValue, '|        ', ', ', True, True, False);   //WEB_SPECIFIC.
               ItemValue := StringReplace(ItemValue, '(', ' (', True, True, False);          //WEB_SPECIFIC.
               if ItemValue <> '' then ItemList := ItemList + 'Sound Mix: ' + ItemValue + '<br>';
               //LogMessage('Function ParsePage_IMDBMovieBASE -      Get result ItemList After Sound Mix for ~features~: ' + ItemList + ' | |');
               //  SILENT_FIELD       = 'Silent';
               if PosFrom('Silent', ItemValue, 1)>0 then AddCustomFieldValueByName(SILENT_FIELD, '-1');
               if ItemValue <> '' then AddCustomFieldValueByName('Sound Mix:', RemoveTagsEx0(ItemValue));
               if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result (CF~Sound Mix:~): ' + ItemValue + ' | |');
            End;
         End;   //      If Not(TechnicalPageDownloaded) And Not(ReferencePageDownloaded) then Begin should end here
            
      If Not(TechnicalPageDownloaded) then Begin   
      //Get "Aspect Ratio" (CF~Aspect Ratio: ~) multiple values in a comma separated list)
            curPos := Pos('">Aspect ratio</span>', HTML);
            if 0<curPos then begin
            //EndPos := curPos;
               ItemValue := HTMLValues(HTML,
               '">Aspect ratio</span>', '</ul></div></li>', '<li role="presentation" class="ipc-inline-list__item">', '</li>', ', ', endPos);
               if ItemValue <> '' then ItemList := ItemList + 'Aspect Ratio: ' + ItemValue + '<br>';
               //LogMessage('Function ParsePage_IMDBMovieBASE -      Get result ItemList After Aspect Ratio for ~features~: ' + ItemList + ' | |');
               ItemValue := StringReplace(ItemValue, '/ (high definition)', ' HD', True, False, True);
               ItemValue := StringReplace(ItemValue, '16:9 HD', '16 : 9  HD', True, False, True);
               ItemValue := StringReplace(ItemValue, '4:3', '4 : 3', True, False, True);
               ItemValue := StringReplace(ItemValue, '2.55: 1', '2.55 : 1', True, False, True);
               ItemValue := StringReplace(ItemValue, '2.39: 1', '2.39 : 1', True, False, True);
               ItemValue := StringReplace(ItemValue, '2.40:1', '2.40 : 1', True, False, True);
               //ItemValue := StringReplace(ItemValue, '1.78 : 1 / (high definition)', '1.78 : 1 (hd)', True, False, True);
               if ItemValue <> '' then AddCustomFieldValueByName('Aspect Ratio:', ItemValue);
               if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result  (CF~Aspect Ratio: ~): ' + ItemValue + ' | |');
            End;
            //(*
            if (Length(ItemList)>0) then begin
               AddCustomFieldValueByName('Imdb-TechSpecs', ItemList);
               if GET_FEATURES then
               AddFieldValueXML('features', ItemList);
               LogMessage('Function ParsePage_IMDBMovieBASE -       Get result ~features~: ' + ItemList + ' | |');
            End;
            //*)
         End;
        End;   //If Not(TechnicalPageDownloaded) then Begin should end here

Need to remove this part of the code because it no longer displays Followed By in the Connections area on the main page.

Quote
      (*

      // Go to "Connections" (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~)
         // Initialize the string to collect all entries
         allItemValues := '';
         
         StartPos := Pos('>Connections<', HTML);
         If StartPos > 0 Then Begin
            // Define the end marker for the "Connections" section
            EndPos := PosFrom('a class="ipc-metadata-list-item__icon-link" tabindex="0" aria-label="See more" ', HTML, StartPos);
            If EndPos > StartPos Then Begin
               // Extract the relevant HTML section
               ItemValue := Copy(HTML, StartPos, EndPos - StartPos);
               //LogMessage('Function ParsePage_IMDBMovieBASE - Get result ItemValue for (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~) : ' + #13 + ItemValue + ' | |' + #13);

               // Initialize connections container
               Connections := '';

               // Define connection types
               connectionTypes := ['Featured in', 'Follows', 'Followed by', 'Referenced in', 'Remade as', 'Remake of', 'Spin-off', 'Spoofed in', 'Edited into', 'Edited from', 'Version of', 'Features', 'References', 'Spoofs', 'Spin-off from'];

               // Iterate through each type of connection using an indexed loop
               For i := Low(connectionTypes) To High(connectionTypes) Do Begin
                  connType := connectionTypes;
                  connStartPos := PosFrom(connType, ItemValue, 1);
                  While connStartPos > 0 Do Begin
                     connEndPos := PosFrom('</a>', ItemValue, connStartPos) + Length('</a>') - 1;
                     If connEndPos > connStartPos Then Begin
                        connHTML := Copy(ItemValue, connStartPos, connEndPos - connStartPos + 1);
                        //LogMessage('Function ParsePage_IMDBMovieBASE - Get result connHTML for (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~) : ' + connHTML + ' | |');

                        // Extract the link URL
                        linkStartPos := PosFrom(' href="', connHTML, 1) + Length(' href="');
                        linkEndPos := PosFrom('?ref', connHTML, linkStartPos);
                        linkURL := Copy(connHTML, linkStartPos, linkEndPos - linkStartPos);
                        //LogMessage('Function ParsePage_IMDBMovieBASE - Get result linkURL for (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~) : ' + linkURL + ' | |');

                        // Extract the link text
                        textStartPos := PosFrom('">', connHTML, linkStartPos) + Length('">');
                        textEndPos := PosFrom('</a', connHTML, textStartPos);
                        yearStartPos := PosFrom('</a>', ItemValue, textStartPos) + Length('</a>');
                        yearEndPos := PosFrom('</div>', ItemValue, yearStartPos);
                        yearValue := Copy(ItemValue, yearStartPos, yearEndPos - yearStartPos);
                        linkText := Copy(connHTML, textStartPos, textEndPos - textStartPos);
                        (*
                        linkText := HTMLValues2(connHTML, linkStartPos, '</div><a class=',  linkEndPos, linkStartPos);
                        //*)
                        (*
                        //LogMessage('Function ParsePage_IMDBMovieBASE - Get result linkText for (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~): ' + linkText + ' | |');
                        //LogMessage('Function ParsePage_IMDBMovieBASE - Get result yearValue for (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~): ' + yearValue + ' | |');

                        // Build the custom format
                        connHTML := connType + ' <link url="https://www.imdb.com' + linkURL + '">' + linkText + yearValue + '</link>';
                        //LogMessage('Function ParsePage_IMDBMovieBASE - Get result final connHTML for (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~) : ' + connHTML + ' | |');

                        // Append to connections container
                        If Length(Connections) > 0 Then
                           Connections := Connections + ', ' + connHTML
                        Else
                           Connections := connHTML;
                     End;
                     connStartPos := PosFrom(connType, ItemValue, connStartPos + Length(connHTML));
                  End;
               End;

               LogMessage('Function ParsePage_IMDBMovieBASE - Final processed Connections: ' + Connections + ' | |' + #13);

                Add custom field values
               //AddCustomFieldValueByName('Conect', Connections);
               //AddCustomFieldValueByName('MiniConnections', Connections);

               // Add condition to check "Followed By" presence and add custom field value
               If PosFrom('Followed By', Connections, 1) > 0 Then
                  AddCustomFieldValueByName(FOLLOWEDBY_FIELD, '-1');
            End;
         End Else
            LogMessage('Function ParsePage_IMDBMovieBASE - (CF~Conect~) (CF~MiniConnections~) (CF~FOLLOWEDBY_FIELD~) not found');

      *)
17
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 28, 2025, 04:57:18 pm »
Removed unused parts of Function RemoveTagsEx code and added new and more efficient parts of Function RemoveTagsEx code.

Quote
Function RemoveTagsEx0(AText:String): String; //BlockOpen
    //Ivek23 function for get faster the script
Var
   B, E:Integer;
Begin
   Result := AText;
   B := PosFrom('<', Result, 1);
   E := PosFrom('>', Result, B);
   While (B>0) AND (B<E) Do Begin
      Delete(Result, B, E-B + 1);
      B := Pos('<', Result);
      E := Pos('>', Result);
   End;
End; //BlockClose

Function RemoveTagsEx(AText:String): String; //BlockOpen
    //Ivek23 function for get faster the PLOTKEYWORDS script
Var
   B, E:Integer;
Begin
   Result := AText;
   B := PosFrom('(', Result, 1);
   E := PosFrom(')', Result, B);
   While (B>0) AND (B<E) Do Begin
      Delete(Result, B, E-B + 1);
      B := Pos('(', Result);
      E := Pos(')', Result);
   End;
End; //BlockClose

function RemoveTagsEx_1(AText:String): String; //BlockOpen
    //Ivek23 function for get faster the script
Var
   B, E:Integer;
Begin
   Result := AText;
   B := PosFrom('<', Result, 1);
   E := PosFrom('>', Result, B);
   While (B>0) AND (B<E) Do Begin
      Delete(Result, B, E-B + 1);
      B := Pos('<', Result);
      E := Pos('>', Result);
   End;
End; //BlockClose

function RemoveTagsEx_2(AText:String): String; //BlockOpen
    //Ivek23 function for get faster the script
Var
   B, E:Integer;
Begin
   Result := AText;
   B := PosFrom('<h3 class="', Result, 1);
   E := PosFrom('div">', Result, B);
   //E := PosFrom('</h3>', Result, B);
   While (B>0) AND (B<E) Do Begin
      //Delete(Result, B, E-B + 5);
      Delete(Result, B, E-B + 5);
      B := Pos('<h3 class="', Result);
      E := Pos('div">', Result);
   End;
End; //BlockClose

function RemoveTagsEx0_10(AText:String):String; //BlockOpen
Var
  B,E:Integer;
  TagToRemove: String;
Begin
  Result := AText;
  TagToRemove := '<a class="ipc-link ipc-link--baseAlt ipc-link--inherit-color" tabindex="0" aria-disabled="false" href="';
 
  B := Pos(TagToRemove, Result);
  While B > 0 Do Begin
    E := PosFrom('>', Result, B);
    If (E > B) Then
      Delete(Result, B, E - B + 1)
    Else
      Delete(Result, B, Length(TagToRemove));

    B := Pos(TagToRemove, Result);
  End;
End; //BlockClose

function HTMLValue(HTML: String;StartPos, EndPos:Integer;StartValue, EndValue:String): String; //BlockOpen

Function ParsePage_IMDBMovieBASE

Cleaned up part of code and used new Function RemoveTagsEx code.

Quote
         AddCustomFieldValueByName('IMDB Year', yearValue);
         if yearValue <> '' then LogMessage('ParsePage_IMDBMovieBASE -      Get result Tv Mode (CF~IMDB_year~) + : ' + yearValue);

            ItemValue1 := HTMLValues(HTML, '<h1 textlength="', '</ul>', '"ipc-inline-list__item', '</', '  •  ', StartPos);
            if ItemValue1 <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Tv Mode2a: ' + #13 + ItemValue1 + ' | |' + #13);
            debug_pos1 := Pos('<a class="ipc-metadata', ItemValue1);
            if debug_pos1 >0 then ItemValue1 := Copy(ItemValue1, 0, debug_pos1-1);
            ItemValue1 := RemoveTagsEx0_10(ItemValue1);
            ItemValue1 := StringReplace(ItemValue1, '">', '', True, False, True);
            AddCustomFieldValueByName('Tv2', ItemValue1);
            if ItemValue1 <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Tv Mode2 (CF~Tv2~): ' + #13 + ItemValue1 + ' | |' + #13);
         end else
            LogMessage('Function ParsePage_IMDBMovieBASE - Tv/Tv 2 - metadata not found');

Cleaned part of the code.


Quote
[   //Get ~Metascore~
      EndPos := Pos('</span></span><span class="label"><span class="metacritic-score-label">Metascore</span></span></span></a></li></ul>', HTML);
      if EndPos>0 then begin
         curPos := PrevPos('">', HTML, EndPos) + Length('">');
         EndPos := PosFrom('</span></span><span class="label"><span class="metacritic-score-label">Metascore</span></span></span></a></li></ul>', HTML, curPos) + 2;
         //ItemValue := RemoveTags(Copy(HTML, curPos, endPos-curPos), false);
         ItemValue := Copy(HTML, curPos, endPos-curPos);
         LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Metascore original: ' + ItemValue + ' | |');
         ItemValue := CustomStringReplace(ItemValue, ['0</', '1</', '2</', '3</', '4</', '5</', '6</', '7</', '8</', '9</'], [',0', ',1', ',2', ',3', ',4', ',5', ',6', ',7', ',8', ',9']);
         //curPos := Pos('var ue_t0=ue_t0', ItemValue);                               //WEB_SPECIFIC.
         //If 0<curPos then ItemValue := Copy(ItemValue, 0, curPos-1);
         if ItemValue <> '' then AddCustomFieldValueByName('Metascore', FloatToStr((StrToFloat(ItemValue) * 1)));
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Metascore in PVD format (CF~Metascore~): ' + ItemValue + ' | |');
      End;

Custom field name changes.

Quote
         //LogMessage('Function ParsePage_IMDBMovieBASE -  Value of ReferencePageDownloaded for Studio: ' + BoolToStr(ReferencePageDownloaded));
      If Not(ReferencePageDownloaded) Then Begin
         // Get ~studio~ "Production Co" (multiple values in a comma separated list)
         curPos := Pos('">Production compan', HTML); // WEB_SPECIFIC.
         If 0 < curPos Then Begin
            EndPos := curPos;
            ItemValue := HTMLValues(HTML, '">Production compan', '</ul>', '<li role="presentation" class="ipc-inline-list__item">', '</li>', ', ', endPos);
            LogMessage('Function ParsePage_IMDBMovieBASE - Get ItemValue Studio/Production Co multiple: ' + ItemValue + ' | |');
            AddFieldValueXML('studio', ItemValue);
            // Custom field: IMDb Studio2 (formatted as "STUDIO RELEASE BY\n[ItemValue]")
            If ItemValue <> '' Then Begin
               ItemValue := 'STUDIO RELEASE BY' + #13#10 + ItemValue;
               AddCustomFieldValueByName('IMDbStudio2', ItemValue);
               //AddCustomFieldValueByName('IMDb Studio2', ItemValue);
               LogMessage('Function ParsePage_IMDBMovieBASE - Get results Studio/Production Co multiple: ' + ItemValue + ' | |');
            End;
         End;
      End;   //If Not(ReferencePageDownloaded) Then Begin should end here
18
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 28, 2025, 01:38:22 pm »
Function ParsePage_IMDBMovieBASE

Cleaned part of the code.

Quote
   If Not (ReferencePageDownloaded) Then Begin
   //Get ~IMDB_Votes~
         ItemValue := TextBetWeenFirst(ItemList,'","ratingCount":',',"');   //Strings which opens/closes the data. WEB_SPECIFIC
         AddCustomFieldValueByName('IMDB_Votes', ItemValue);
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result ratingCount (CF~IMDB_Votes~): ' + ItemValue + ' | |');
         
         //Get ~imdbrating~~IMDB Rating~~IMDBRating~
         ItemValue := TextBetWeenFirst(ItemList,'"worstRating":1,"ratingValue":','},"');   //Strings which opens/closes the data. WEB_SPECIFIC
         //ItemValue := FloatToStr((StrToFloat(ItemValue) * 1));
         AddFieldValueXML('imdbrating',ItemValue);
         AddCustomFieldValueByName('IMDB Rating',ItemValue);
         AddCustomFieldValueByName('IMDBRating',ItemValue);
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result ratingValue ~imdbrating~ (CF~IMDB Rating~~IMDBRating~): ' + ItemValue + ' | |');
      End;   //If Not (ReferencePageDownloaded) Then Begin should end here
   End;   //If (Length(ItemList)>0) Then Beginshould end here


Custom field name changes.

Quote
      If Not (USE_SAVED_PVDCONFIG And (ConfigOptions[4] = '0')) Then Begin
         // Go to "Tv Mode"
         // Get ~year~ ~yearsValue~
         StartPos := Pos('<h1 textlength="', HTML);
         if StartPos > 0 then begin
            yearsValue := TextBetWeen(HTML, 'releaseinfo/?ref_=tt_ov_rdat">', '</a></li>', false, StartPos);
            LogMessage('Function ParsePage_IMDBMovieBASE - Get result year (yearsValue): ' + yearsValue + ' | |');
            debug_pos1 := Pos('–', yearsValue);
            if debug_pos1 > 0 then yearsValue := Copy(yearsValue, 0, debug_pos1 - 1);
            AddFieldValueXML('year', yearsValue);
            If Not (ReferencePageDownloaded) Then Begin
            AddCustomFieldValueByName('Imdb_Title_1', titleValue + ' (' + yearsValue + ')');
            end else
            if yearsValue <> '' Then LogMessage('Function ParsePage_IMDBMovieBASE - Get result added year yearsValue: ' + yearsValue + ' | |');
         end else
            LogMessage('Function ParsePage_IMDBMovieBASE - year-metadata not found');
      End;

Fix part of the code.

Quote
   // Go to "Tv Mode"
      StartPos := Pos('<h1 textlength="', HTML);
      if StartPos > 0 then begin
         ItemValue:=HTMLValue(HTML,StartPos,0,'</h1>','releaseinfo/?ref_=tt_ov_rdat">');
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Tv Mode1a: ' + ItemValue + ' | |');
         debug_pos1 := Pos('<a href="', ItemValue);
         if debug_pos1 > 0 then ItemValue := Copy(ItemValue, 0, debug_pos1 - 1);
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Tv Mode1b: ' + ItemValue + ' | |');
         debug_pos1 := Pos('<a class="', ItemValue);
         if debug_pos1 > 0 then ItemValue := Copy(ItemValue, 0, debug_pos1 - 1);
         debug_pos1 := Pos('Original title: ', ItemValue);
         if debug_pos1 > 0 then ItemValue := Copy(ItemValue, 0, debug_pos1 - 1);
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Tv Mode1: ' + ItemValue + ' | |');
         AddCustomFieldValueByName('Tv', ItemValue);
         if ItemValue <> '' then LogMessage('Function ParsePage_IMDBMovieBASE -      Get result Tv Mode (CF~Tv~): ' + ItemValue);
         yearValue:=HTMLValue(HTML,StartPos,0,'releaseinfo/?ref_=tt_ov_rdat">','</a></li><li role="presentation" class="ipc-inline-list__item"><a class="');         
         AddCustomFieldValueByName('IMDB Year', yearValue);
         if yearValue <> '' then LogMessage('ParsePage_IMDBMovieBASE -      Get result Tv Mode (CF~IMDB_year~) + : ' + yearValue);
19
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Custom Fields
« Last post by Ivek23 on March 28, 2025, 12:46:19 pm »
Function ParsePage_IMDBMovieBASE

PVD custom field for Type/Comments in Preferences/Movies/Custom Items:
  • MID ID: (Number)
  • NUM ID: (Number)
  • MicroIMDbInfo (Memo)
  • Title (Memo)
  • Origtitle (Memo)
  • Original Title (Memo)
  • Localized title (Memo)
  • Imdb_Title (Memo)
  • IMDB_Movietype (Multiselect list)
  • Tv 0 (Short Text)
  • IMDB_Tagline (Memo)
  • IMDB_MPAA (Multiselect list)
  • Description (Memo)
  • IMDb_Sub-Genres (Multiselect list)
  • IMDB Release Date (Short Text)
  • IMDB Release Dates (Short Text)
  • IMDB_Votes (Number)
  • IMDB Rating or IMDBRating (Rating)
  • Imdb_Title_1 (Memo)
  • Tv (Multiselect list)
  • IMDB Year (Multiselect list)
  • Tv2 (Long Text)
  • TOP_250 (Number)
  • Metascore (Rating)
  • IMDb Directed by: (Memo)
  • IMDb Cast (Memo)
  • IMDB Plot Summary (Memo)
  • Imdb Aka (Memo)
  • ProductionBudget (Long Text)
  • Domestic (Long Text)
  • Worldwide (Long Text)
  • IMDbStudio2 (Memo)
  • IMDb_Filming_Locations (Memo)
  • Language: (Multiselect list)
  • Run time1 (Short Text)
  • Imdb Runtime1 (Multiselect list)
  • Color: (Multiselect list)
  • Imdb Color (Memo)
  • Sound Mix: (Multiselect list)
  • Aspect Ratio: (Multiselect list)
  • Imdb-TechSpecs (Memo)
  • MiniSoundtracks (Memo)
  • User Reviews or User Comments(Memo)
  • IMDbAwards1(Memo) or (Long Text)
20
PVD Python Scripts / Re: PVD Selenium MOD v4 IMDb Movie Script Confusion
« Last post by Ivek23 on March 28, 2025, 06:26:56 am »
Notice:

These two Function ConfDate1 and Function ConfDate2 below are not used in the script because if there is no complete date (day, month, year) or if the day or month is missing, PVD will freeze.


Quote
Function ConfDate1(OrigDate:String): String; //BlockOpen
Var
   i, rNum:Integer;
   d, m, y: String;
   TabMonths, TabFullMonths:Array of string;
   TabDate:TwideArray;
begin
   TabMonths := ['Null', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
   TabFullMonths := ['Null', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
   rNum := ExplodeString(OrigDate, TabDate, '/');
   // LogMessage('* Function ConfDate1 => rNum: ' + IntToStr(rNum));
   if (rNum <= 1) then begin
      rNum := ExplodeString(OrigDate, TabDate, ' ');
      // LogMessage('* Function ConfDate1 => rNum: ' + IntToStr(rNum));
   end;
   if (rNum > 0) then begin
      // LogMessage('** Function ConfDate1 => TabDate 0: ' + TabDate[0]);
      // LogMessage('** Function ConfDate1 => TabDate 1: ' + TabDate[1]);
      // LogMessage('** Function ConfDate1 => TabDate 2: ' + TabDate[2]);
      if (Length(TabDate[0]) > 0) then begin
         if (Length(TabDate[0]) > 2) then begin
            m := TabDate[0];
            for i := 1 to 12 do begin
               if ((m = TabMonths) or (m = TabFullMonths)) then begin
                  m := IntToStr(i);
                  break;
               end;
            end;
            LogMessage('* Function ConfDate1 => Months: ' + m);
            // d := Copy(TabDate[1], 1, Length(TabDate[1])-1);
            d := TabDate[1];
            If Copy(TabDate[1], 1, 1) = '0' then
               d:= Copy(TabDate[1], 2, 1);
            y := TabDate[2];
         end else if (Length(TabDate[1]) > 0) then begin
            y:= TabDate[2];
            m:= TabDate[1];
               For i := 1 to 12 do begin
                  If ((m = TabMonths) or (m = TabFullMonths)) then begin
                     m := IntToStr(i);
                     break;
                  end;
               end;
            d:= TabDate[0];
            If Copy(TabDate[0], 1, 1) = '0' then
               d:= Copy(TabDate[0], 2, 1);
            LogMessage('* Function ConfDate1 => Year: ' + y + ' month: ' + m + ' day: ' + d);
         end else begin
            y := '';
            m := '';
            d := '';
         end;
      end else begin
         ExplodeString(OrigDate, TabDate, '/');
         y := Copy(OrigDate, 7, 4);
         m := Copy(OrigDate, 3, 3);
            For i := 1 to 12 do begin
               If m = Copy(TabMonths, 1, 3) then begin
                  m := IntToStr(i);
                  break;
               end;
            end;
         d := Copy(OrigDate, 1, 2);
            If Copy(TabDate[0], 1, Length(TabDate[0])-1) = '0' then d:= Copy(TabDate[0], 2, Length(TabDate[0])-1);
         LogMessage('* Function ConfDate1 - Year: ' + y + ' month: ' + m + ' day: ' + d);
      end;
      Result := d + '.' + m + '.' + y;
   end;
End; //BlockClose

Function ConfDate2(OrigDate:String): String; //BlockOpen
Var
    i, rNum:Integer;
    d, m, y: String;
    TabMonths, TabFullMonths:Array of string;
    TabDate:TwideArray;
begin
    TabMonths := ['Null', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    TabFullMonths := ['Null', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
    rNum := ExplodeString(OrigDate, TabDate, '/');
    // LogMessage('* Function ConfDate2 => rNum: ' + IntToStr(rNum));
    if (rNum <= 1) then begin
        rNum := ExplodeString(OrigDate, TabDate, ' ');
        // LogMessage('* Function ConfDate2 => rNum: ' + IntToStr(rNum));
    end;
    if (rNum > 0) then begin
        // LogMessage('** Function ConfDate2 => TabDate 0: ' + TabDate[0]);
        // LogMessage('** Function ConfDate2 => TabDate 1: ' + TabDate[1]);
        // LogMessage('** Function ConfDate2 => TabDate 2: ' + TabDate[2]);
        if (Length(TabDate[0]) > 0) then begin
            if (Length(TabDate[0]) > 2) then begin
                m := TabDate[0];
                for i := 1 to 12 do begin
                    if ((m = TabMonths) or (m = TabFullMonths)) then begin
                        m := IntToStr(i);
                        break;
                    end;
                end;
                if Length(m) = 1 then m := '0' + m; // Ensure month has two digits
                LogMessage('* Function ConfDate2 => Months: ' + m);
                d := TabDate[1];
                If Copy(TabDate[1], 1, 1) = '0' then
                    d := Copy(TabDate[1], 2, 1);
                if Length(d) = 1 then d := '0' + d; // Ensure day has two digits
                y := TabDate[2];
            end else if (Length(TabDate[1]) > 0) then begin
                y := TabDate[2];
                m := TabDate[1];
                For i := 1 to 12 do begin
                    If ((m = TabMonths) or (m = TabFullMonths)) then begin
                        m := IntToStr(i);
                        break;
                    end;
                end;
                if Length(m) = 1 then m := '0' + m; // Ensure month has two digits
                d := TabDate[0];
                If Copy(TabDate[0], 1, 1) = '0' then
                    d := Copy(TabDate[0], 2, 1);
                if Length(d) = 1 then d := '0' + d; // Ensure day has two digits
                LogMessage('* Function ConfDate2 => Year: ' + y + ' month: ' + m + ' day: ' + d);
            end else begin
                y := '';
                m := '';
                d := '';
            end;
        end else begin
            ExplodeString(OrigDate, TabDate, '/');
            y := Copy(OrigDate, 7, 4);
            m := Copy(OrigDate, 3, 3);
            For i := 1 to 12 do begin
                If m = Copy(TabMonths, 1, 3) then begin
                    m := IntToStr(i);
                    break;
                end;
            end;
            if Length(m) = 1 then m := '0' + m; // Ensure month has two digits
            d := Copy(OrigDate, 1, 2);
            If Copy(TabDate[0], 1, Length(TabDate[0])-1) = '0' then
                d := Copy(TabDate[0], 2, Length(TabDate[0])-1);
            if Length(d) = 1 then d := '0' + d; // Ensure day has two digits
            LogMessage('Function ConfDate2 - Year: ' + y + ' month: ' + m + ' day: ' + d);
        end;
        // Format the date as yyyy-mm-dd
        Result := y + '-' + m + '-' + d;
    end;
End; //BlockClose
Pages: 1 [2] 3 4 5 6 7 ... 10