[REL] [ES] Filmaffinity 5.0

If you made a script you can offer it to the others here, or ask help to improve it. You can also report here bugs & problems with existing scripts.
Post Reply
Radagast
Posts: 81
Joined: 2016-04-22 16:07:15

[REL] [ES] Filmaffinity 5.0

Post by Radagast »

Lanzamiento de nueva versión del script FilmAffinity (ES).ifs versión 5.0 para adaptarlo al nuevo sistema de protección de FilmAffinity. Creado y adaptado por MrObama2022 y Garada.

Ejecutar el script UPDATE_SCRIPTS para actualizar o descargar de https://update.antp.be/amc/scripts/ y sobrescribir el antiguo en la carpeta scripts de AMC.
Para el funcionamiento del script son necesarios los archivos ExternalCurlHandler.pas, StringUtils7552.pas y StringUtils1.pas que también tienen que estar ubicados en la carpeta scripts de AMC. Actualizar o descargar mediante mismos métodos que el script.

NOVEDADES
-Búsqueda estándar o avanzada. Seleccionable mediante la opción AdvancedSearch
-Listado ordenado por relevancia o por año. Seleccionable mediante la opción SortByYear
-----------------------------------------------------------------------------------------------------------------
El script ahora hace uso de ExternalCurlHandler.pas como intermediario para las peticiones a FilmAffinity. En la mayoría de casos funcionará bien con los parámetros por defecto, en casos especiales se puede modificar el comportamiento de ExternalCurlHandler.pas editando el archivo con un editor de texto.

OPCIONES/PARAMETROS de ExternalCurlHandler.pas
-UseVBS
Permite deshabilitar el uso de Visual Basic si no se quiere o no se puede usar Visual Basic
-curlPath
Permite especificar la ruta a cURL.exe en el caso de utilizar sistemas anteriores a Windows10 o Linux. Previamente se tendrá que descargar e instalar cURL (https://curl.se/)
-tmpDir
Permite especificar un directorio para los archivos temporales si no se quiere utilizar la carpeta SCRIPTS
-delayBetweenRequest
Permite especificar un retardo en ms entre las peticiones a FilmAffinity para evitar posibles bloqueos por peticiones muy seguidas
-TimeOut
Tiempo máximo de espera de las peticiones a FilmAffinity, en caso de superarse dará error
-curlUserAgent
UserAgent comunicado por el script en las peticiones a FilmAffinity
jesalo
Posts: 5
Joined: 2025-11-05 10:15:58

Re: [REL] [ES] Filmaffinity 5.0

Post by jesalo »

No consigo que funcione.
Garada
Posts: 46
Joined: 2025-08-10 12:39:21

Re: [REL] [ES] Filmaffinity 5.0

Post by Garada »

jesalo wrote: 2025-11-05 10:24:17 No consigo que funcione.
¿Puedes dar más información?
Mensajes de error, sistema operativo que usas, comportamiento del script,...
jesalo
Posts: 5
Joined: 2025-11-05 10:15:58

Re: [REL] [ES] Filmaffinity 5.0

Post by jesalo »

Hola, de nuevo
Gracias por tu trabajo
El script no me funciona. Uso windows 11 y el error lo puedes ver en la siguiente imagen
[https://postimg.cc/f3pqgsvSrl]
jesalo
Posts: 5
Joined: 2025-11-05 10:15:58

Re: [REL] [ES] Filmaffinity 5.0

Post by jesalo »

Me parece que así no se puede ver. lo pongo manual

Error downloading page
http://www.filmaffinity.com/es/search.p ... type=title
ExitCode:35
ErrorMsg: schannel:next InitializeSecurityContext failed:
CRYPT_E_NO_REVOCATION_CHECK (0x80092012) - La función de revocación
no puede comprobar la revocación para el certificado.
ResponseCode; 000[/b][/b]


Esto ocurre para cualquier pelicula qur busque (en este caso es AMAL.

Muchas gracias
Garada
Posts: 46
Joined: 2025-08-10 12:39:21

Re: [REL] [ES] Filmaffinity 5.0

Post by Garada »

He mirado el código de error y puede ser por un antivirus que tengas instalado.

En todo caso se podría solucionar si haces un cambio en el código del archivo ExternalCurlHandler.pas
Ábrelo con un bloc de notas y busca las líneas:

Code: Select all

 // Download page and save to file
    sCommand := sCommand + ' -L --output "' + InstallerPath + curlOutput + '" --url "' + address + '" ' + '-H "Accept: text/html, */*" -H "Accept-Language: it" -H "DNT: 1" -H "Priority: u=0, i" -H "Sec-Ch-Ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"Windows\"" -H "Sec-Fetch-Dest: Document" -H "Sec-Fetch-Mode: Navigate" -H "Sec-Fetch-Site: None" -H "Sec-Fetch-User: ?1" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: ' + curlUserAgent + '"';
y añade --ssl-no-revoke como indico a continuación:

Code: Select all

 // Download page and save to file
    sCommand := sCommand + ' --ssl-no-revoke -L --output "' + InstallerPath + curlOutput + '" --url "' + address + '" ' + '-H "Accept: text/html, */*" -H "Accept-Language: it" -H "DNT: 1" -H "Priority: u=0, i" -H "Sec-Ch-Ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"Windows\"" -H "Sec-Fetch-Dest: Document" -H "Sec-Fetch-Mode: Navigate" -H "Sec-Fetch-Site: None" -H "Sec-Fetch-User: ?1" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: ' + curlUserAgent + '"';
Cuidado con los espacios
jesalo
Posts: 5
Joined: 2025-11-05 10:15:58

Re: [REL] [ES] Filmaffinity 5.0

Post by jesalo »

Gracias por tu ayuda.
He hecho el cambio como me has indicado pero el mensaje de error se repite solo que la final pone
ResponseCode; 000--ssl-no-revoke
Garada
Posts: 46
Joined: 2025-08-10 12:39:21

Re: [REL] [ES] Filmaffinity 5.0

Post by Garada »

Creo que no has dejado un espacio antes de --ssl-no-revoke, revisa que tengas un espacio entre la comilla simple (') y el primer guion (-)

Code: Select all

sCommand := sCommand + ' --ssl-no-revoke -L .......
                        ^
                        |
jesalo
Posts: 5
Joined: 2025-11-05 10:15:58

Re: [REL] [ES] Filmaffinity 5.0

Post by jesalo »

Efectivamente. Ahora todo correcto.
Millones de gracias. :clapping:
i42poloj
Posts: 3
Joined: 2025-11-11 10:11:58

Re: [REL] [ES] Filmaffinity 5.0

Post by i42poloj »

Hola.
Llevo tiempo siguiendo el hilo desde que dejó de funcionar el script hace unos meses. Ahora parece que va bien a mucha gente, pero a mí me da error.
Una vez actualizado y guardados los ficheros .pas en la carpeta scripts, cuando le doy al F6 y doble click al script de filmaffinity, me da un error:

Error de script en "FILMAFFINITY": unit is not found en la línea 2

Y luego me sale un editor en el que se ve el contenido del script, marcando en rojo la línea 2, donde dice:
uses ExternalCurlHandler;

¿Hay solución a esto? Gracias.
antp
Site Admin
Posts: 9784
Joined: 2002-05-30 10:13:07
Location: Brussels
Contact:

Re: [REL] [ES] Filmaffinity 5.0

Post by antp »

You need to add the file ExternalCurlHandler.pas to the scripts folder.
Either by running "Update scripts" or manually via https://update.antp.be/amc/scripts/
i42poloj
Posts: 3
Joined: 2025-11-11 10:11:58

Re: [REL] [ES] Filmaffinity 5.0

Post by i42poloj »

Ya tengo los ficheros .pas en la carpeta de scripts. Los 3 necesarios.
antp
Site Admin
Posts: 9784
Joined: 2002-05-30 10:13:07
Location: Brussels
Contact:

Re: [REL] [ES] Filmaffinity 5.0

Post by antp »

If it is in the same folder as the FilmAffinity script it shoud work.
Otherwise you can try getting the latest install of AMC which includes that file too.
Garada
Posts: 46
Joined: 2025-08-10 12:39:21

Re: [REL] [ES] Filmaffinity 5.0

Post by Garada »

i42poloj wrote: 2025-11-11 10:32:42 Ya tengo los ficheros .pas en la carpeta de scripts. Los 3 necesarios.
Si lo hiciste a mano mejor usa la utilidad de actualizar los scripts como te comenta antp para asegurarte que tienen los nombres correctos:
Image
i42poloj
Posts: 3
Joined: 2025-11-11 10:11:58

Re: [REL] [ES] Filmaffinity 5.0

Post by i42poloj »

¡¡Con eso sí funciona!!
Muchísimas gracias a todos por vuestra ayuda y esperemos que el script aguante mucho tiempo más funcionando.
Y si no es así, ya sé dónde acudir para resolverlo.
Es que hay un mundo entre catalogar por script o manualmente, sobre todo los que catalogamos una infinidad de películas como yo.
Lo dicho, muchas gracias.
kadmon
Posts: 5
Joined: 2019-09-30 08:30:06

Re: [REL] [ES] Filmaffinity 5.0

Post by kadmon »

Comparto las gracias que da i42poloj más arriba, llevo muchos años usando este script.

Dicho esto, a mi me da error cuando tengo la opción del script "DontWantExtras" puesta en 0, el error es en la lína 687,que dice " AnalyzeExtras(Page,Address); " y el error que me da es: "Error de Script en "FILMAFFINITY": unknown identifier: ADDRESS en la línea 687"

El error se "soluciona" poniendo el DontWantExtras en 1, así que tampoco me parece tan grave.

De cualquier forma, muchas gracias y esperemos que el script aguante mucho tiempo.
Radagast
Posts: 81
Joined: 2016-04-22 16:07:15

Re: [REL] [ES] Filmaffinity 5.0

Post by Radagast »

kadmon wrote: 2025-11-16 17:42:45 Comparto las gracias que da i42poloj más arriba, llevo muchos años usando este script.

Dicho esto, a mi me da error cuando tengo la opción del script "DontWantExtras" puesta en 0, el error es en la lína 687,que dice " AnalyzeExtras(Page,Address); " y el error que me da es: "Error de Script en "FILMAFFINITY": unknown identifier: ADDRESS en la línea 687"

El error se "soluciona" poniendo el DontWantExtras en 1, así que tampoco me parece tan grave.

De cualquier forma, muchas gracias y esperemos que el script aguante mucho tiempo.
Pues si, confirmado.
Al ponerlo a cero le decimos al script que queremos que recopile extras como enlaces, trailers, fotos, etc...
La verdad es que nunca lo he tenido a 0 así que no se si es un error que ya viene de antes o que se ha producido al tener que utilizar ExternalCurlHandler. Quizás para las páginas de extras no esté utilizando ExternalCurlHandler y por eso falla.
Esto escapa a mis conocimientos, a ver si alguien que entienda más le puede echar un vistazo y tiene fácil solución.
Garada
Posts: 46
Joined: 2025-08-10 12:39:21

Re: [REL] [ES] Filmaffinity 5.0

Post by Garada »

La verdad que la opción de extras nunca la he usado, me bastaba con la URL de la página de FA y así no sobrecargaba la base de películas.

Pongo aquí con el script corregido para que baje los extras (críticas, imágenes y trailers) para que lo prueben por si falla algo.
Arreglé la llamada a la captura de extras y también cambié la descarga de la información de los trailers que no funcionaba, lo demás está sin tocar.

Code: Select all

(***************************************************

Ant Movie Catalog importation script
www.antp.be/software/moviecatalog/

[Infos]
Authors=aviloria (aviloria@yahoo.com) modded by: rodpedja (rodpedja@gmail.com), kreti (bisoft@hotmail.com), MrK, gilistico, juliojs, Albher, Arturo, jacqlittle, AgustinG, Fulvio53s03, MrObama2022, Garada
Title=FilmAffinity (ES)
Description=Movie importation script for FilmAffinity Spain
Site=https://www.filmaffinity.com
Language=ES
Version=5.0
Requires=4.2.3.3
Comments=Adaptation for compatibility with 4.2 version. |Added Extras capture. |Changed Charset ISO-> utf8 - new search page structure. |Added cURL compatibility, need ExternalCurlHandler.pas (MrObama2022)|Optional standard or advanced search mode. (Thanks to Radagast for testing and suggestions) (Garada)
License=The source code of the script can be used in another program only if full credits to script author and a link to Ant Movie Catalog website are given in the About box or in the documentation of the program.
GetInfo=1
RequiresMovies=1

[Options]
AdvancedSearch=0|1|0=Desactivada, usa búsqueda estándar|1=Activada, usa búsqueda avanzada
DontAsk=0|0|1=Método rápido: No te pregunta el titulo al principio, ni te pide confirmar si sólo hay un resultado|0=Método lento: Confirmas la información manualmente
ActorsInALine=0|0|1=Actores separados por comas|0=Actores en lineas independientes
Force350=0|0|1=force the behavior of 3.5.0 version|0=Version auto
DontWantExtras=0|1|1=No se recopilan extras|0=Se recopilan extras: enlaces, imágenes
GroupImages=1|1|1=Agrupa todas las imagenes en una misnma categoría 'Imagenes'|0=Divide las imágenes por categorias
SortByYear=0|0|1=Ordena lista de busqueda por año|0=Ordena lista de busqueda por relevancia
SearchByFromToYears=0|0|0=No buscar por año|1=Buscar dentro de un período de años
SearchByTitle=1|1|0=No buscar por título|1=Buscar por título
SearchByDirector=0|0|0=No buscar por director|1=Buscar por director
SearchByCast=0|0|0=No buscar por reparto|1=Buscar por reparto
SearchByScript=0|0|0=No buscar por guión|1=Buscar por guión
SearchByPhoto=0|0|0=No buscar por fotografía|1=Buscar por fotografía
SearchByMusic=0|0|0=No buscar por música|1=Buscar por música
SearchByProducer=0|0|0=No buscar por productor|1=Buscar por productor

[Parameters]
ExtraCriticsLimit=5|99|Límite de criticas en Extras
ExtraImagesLimit=5|99|Límite de imágenes en Extras
ExtraTrailersLimit=5|99|Límite de Trailers en Extras

***************************************************)

program FilmAffinity;
uses ExternalCurlHandler;
//uses StringUtils7552;


const
  BaseURL = 'https://www.filmaffinity.com';
  folder  = 'c:\temp\';
  debug_search = False;
  debug_movie = false;
var
  DUMMY, initchar, endchar : string;
  MovieName    : string;
  MovieURL     : string;
  MovieYear    : string;

  YearFrom     : string;
  YearTo       : string;

  AdvQuery     : string;

//------------------------------------------------------------------------------------

function LineDecode(S: string):string;
begin
  S:= UTF8Decode(S);
  HTMLDecode(S);
  Result := S;
end;

//------------------------------------------------------------------------------------

//
//  ConvertAlphaNum: Quita todo menos letras (mayusculas y minusculas) y numeros
//

Function ConvertAlphaNum(s: string) : string;
var
  i: Integer;
  s2, ch: string;
begin
  s2 := '';
  For i := 1 To Length(s) do
  begin
    ch := copy(s, i, 1);
    if ((ch >= 'a') and (ch <= 'z')) or ((ch >= '0') and (ch <= '9')) or ((ch >= 'A') and (ch <= 'Z'))  then
    s2 := s2 + ch;
  end;
  result := s2;
end;

//------------------------------------------------------------------------------------

function DeleteTags(S: string): string;
var
  n, len, tag: Integer;
  c, p: char;
begin
  len    := Length(S);
  tag    := 0;
  p      := ' ';
  Result := '';
  for n := 1 to len do
  begin
    c := Copy(S,n,1);

      // Eliminamos los tabuladores
    if c = #9 then c := ' ';

      // Los espacios redundantes no se procesan
    if (c <> ' ') or (p <> ' ') then
    begin
         // Eliminamos los tags de HTML
      if tag = 0 then
      begin
        if c <> '<' then
        begin
          Result := Result + c;
          p := c;
        end
        else tag := 1;
      end
      else if c = '>' then tag := 0;
    end;
  end
  if p = ' ' then Result := Copy(Result, 1, Length(Result) - 1);
end;
//------------------------------------------------------------------------------------

function Occurrences(Subtext: string; Text: string): integer;
var
  offset: Integer;
begin
  result := 0;
  while true do
  begin
    offset := Pos(Subtext, Text);
    if offset = 0 then break;
    Result := Result + 1;
    Text := TextAfter(Text, Subtext);
  end;
end;
//------------------------------------------------------------------------------------

procedure AnalyzeAdvPage(Busqueda: string);
var
  Page: TStringList;
  Pagestr, Blockestr, Linestr : string;             //fs2025
  BeginChar, LastChar : string;
  LineNr,LineNrax,NextPageNr,Pages: Integer;
  Line, PageNr: string;
  Count: Integer;
  MoviesList, MovieTitle, MovieAddress, MovieDirector: string;
  MovieYear, PagSig:String;
  PickMessaggio2, PickMessaggio3 : string;
  Numpage: Integer;  // Indica el numero de pagina. Raulsara. 22/02/25.
  Finalpaginas: Integer; // Indica cuando acaban todas las paginas encontradas. Raulsara. 22/02/25
  Address: string;
begin
  Numpage:= 1;
  Finalpaginas:=0;
  Address := (BaseUrl + '/es/advsearch.php' + '?page=1&stext=' + Busqueda); // Inicialmente pone la pagina num. 1, después, si hay mas
                                                                            // ira sumando 1 a la pagina. Raulsara. 22/02/25
  repeat
    PickTreeClear;
    PickTreeTitle('Resultados Filmaffinity(ES) para "' + UrlDecode(MovieName) + '"');
    
    Count := 0;
    Page  := TStringList.Create;
    pagestr := GetPage5Advanced(Address, '', '', '', '');
    Page.Text := pagestr;
    if debug_search then
       DumpPage(folder + 'Filmaffinity_search.html', pagestr);                //fs2025.01.30

    Count := 0;

    initchar := '<div class="fa-card">';
    endchar := '<div class="text-center mt-3">';

    Blockestr := initchar + TextBetween(Pagestr, initchar, endchar) + endchar;                   //fs2025.02.01 elenco dei film trovati
    if debug_search then
       DumpPage(folder + 'Filmaffinity_search_' + intToStr(count) + '.html', blockestr);                //fs2025.01.30


    repeat
       initchar := '<a class="d-none d-md-inline-block" ';
       endchar  := '</a>';
       Linestr  := initchar + textbetween(Blockestr, initchar, endchar) + endchar;        //first movie title found
       
       MovieTitle := textbetween(Linestr,'>', endchar);
       MovieTitle := LineDecode(MovieTitle);
       if MovieTitle <> '' then
       begin
         MovieAddress := textbetween(Linestr,'href="', '"');
    //     BlockEstr := StringReplace(BlockEstr, Linestr, '');
         BlockEstr := textafter(BlockEstr, Linestr);

         initchar := '<span class="mc-year ms-1">';
         endchar  := '</span>';
         MovieYear := initchar + textbetween(Blockestr, initchar, endchar) + endchar;       // movie year
    //     BlockEstr := StringReplace(BlockEstr, MovieYear, '');
         BlockEstr := TextAfter(BlockEstr, MovieYear);

         HTMLremovetags(MovieYear);

         initchar := '<div class="mt-2 mc-director">';
         endchar  := '<div class="mt-2 mc-cast">';
         MovieDirector  := initchar + textbetween(Blockestr, initchar, endchar) + endchar;  // movie director
    //     BlockEstr := StringReplace(BlockEstr, MovieDirector, '');
         BlockEstr := TextAfter(BlockEstr, MovieDirector);

         HTMLremovetags(MovieDirector);
         MovieDirector := LineDecode(MovieDirector);
         MovieDirector := fulltrim(MovieDirector);

         PickMessaggio2 := MovieTitle + ' (' + MovieYear + ') ' + MovieDirector;
         PickTreeAdd(PickMessaggio2, MovieAddress);
         Count := Count + 1;
       end;
       DUMMY := DUMMY;
       if debug_search then
          DumpPage(folder + 'Filmaffinity_search_' + intToStr(count) + '.html', blockestr);     //2025.01.30

    until MovieTitle = '';

  // Buscamos la linea donde estan los caracteres ">>" que indican que hay mas paginas, si hay mas paginas
  // sumamos 1 a la pagina y formamos la url con el numero de pagina correspondiente y analizamos la pagina. Si ya no esta ">>" es
  // que es la ultima pagina y acabamos. Ponemos un 1 en el campo Finalpaginas y acabamos el bucle (repeat/until). Raulsara. 22/02/25

    LineNr := FindLine('fa-regular fa-chevrons-right', Page, 0);    //si no lo encuentra es que es la ultima pagina. Raulsara. 22/02/2025
    if LineNr > 0 then
    begin
      Numpage := Numpage+1;
      Address := (BaseUrl + '/es/advsearch.php' + '?page=' + intTostr (Numpage)+ '&stext=' + Busqueda);// Crea la url sumandole 1 a la pagina para su analisis. Raulsara. 22/02/25
    end
    else
    begin
      Finalpaginas := 1; // Pone el campo Finalpaginas a 1 cuando ya no hay mas paginas y acaba el bucle. Raulsara. 22/02/2025
      Address := '';
    end;

    // muestra selección
    if Count = 0  then
    begin
      if Pos('<meta name="description" content="Too many request">', Page.Text) > 0 then
        ShowMessage('Demasiadas búsquedas en poco tiempo'#13'FilmAffinity te ha bloqueado por un tiempo')
      else
        ShowMessage ('No hay resultados');
        
      Finalpaginas := 1;
    end
    else if ((Count = 1) and (GetOption('DontAsk') = 1)) then
    begin
      AnalyzeMoviePageURL(MovieAddress)
      Finalpaginas := 1;
    end
    else
    begin
      PickTreeMoreLink(Address);
      LineNr := 2;
      PickTreeExec2(MovieAddress, LineNr);
      
      case LineNr of
        -2: FinalPaginas := 0; // buscar mas
        -1: FinalPaginas := 1;// cancelar
        else // selección
        begin
          AnalyzeMoviePageURL(MovieAddress);
          FinalPaginas := 1;
        end;
      end;
    end;
  until Finalpaginas = 1;
  
  DUMMY := DUMMY;

  Page.Free;
end;

//------------------------------------------------
// Analiza los resultados de una búsqueda estándar
//------------------------------------------------

procedure AnalyzeStdPage(Busqueda: string);
var
  PageStr, BlockStr, LineStr : string;
  BeginTag, EndTag: string;
  MovieTitle, MovieAddress, MovieDirector, MovieYear: string;
  Count: Integer;
//  Numpage: Integer;
  FinalPaginas: Boolean;
  Address: string;
  ItemSel: Integer;
begin
  Address := BaseUrl + '/es/search.php?stext=' + Busqueda;

  FinalPaginas := False;
  while not FinalPaginas do
  begin
    PickTreeClear;
    PickTreeTitle('Resultados Filmaffinity(ES) para "' + UrlDecode(MovieName) + '"');

    PageStr := GetPage5Advanced(Address, '', '', '', '');
    if debug_search then
       DumpPage(folder + 'Filmaffinity_search.html', PageStr);
       
    if Pos('<meta name="description" content="Too many request">', PageStr) > 0 then
    begin
      ShowMessage('Demasiadas búsquedas en poco tiempo'#13'FilmAffinity te ha bloqueado por un tiempo')
      Exit;
    end;

    if Pos('<div class="z-movie">', PageStr) > 0 then // 1 resultado, página de la película
    begin
      if GetOption('DontAsk') = 1 then // no preguntar, ir al resultado
      begin
        AnalyzeMoviePageContent(PageStr);
        Exit;
      end
      else // mostrar el resultado para confirmarlo
      begin
        // enlace
        MovieAddress := TextBetween(PageStr, '<link rel="canonical" href="', '"');
      
        // Titulo
        MovieTitle := TextBetween(PageStr, '<h1 id="main-title">' , '</h1>');
        MovieTitle := TextBetween(MovieTitle, '<span itemprop="name">' , '</span>');
        MovieTitle := LineDecode(MovieTitle);
        
        // Año
        MovieYear := TextBetween(PageStr, '<dd itemprop="datePublished">', '</dd>');
        
        // Director(es)
        MovieDirector := TextBetween(PageStr, '<dd class="directors">', '</dd>');
        HTMLremoveTags(MovieDirector);
        MovieDirector := LineDecode(MovieDirector);
        MovieDirector := FullTrim(MovieDirector);

        PickTreeAdd(MovieTitle + ' (' + MovieYear + ') ' + MovieDirector, MovieAddress);

        Address := '';
        Count := 1;
        FinalPaginas := True;
      end;
    end
    else // resultados de búsqueda
    begin
      BeginTag := '<div class="item-search">';
      EndTag := '</li>';
      BlockStr := TextBetween(PageStr, BeginTag, EndTag);
      Count := 0;
      while BlockStr <> '' do
      begin
        if debug_search then
          DumpPage(folder + 'Filmaffinity_search_' + intToStr(Count) + '.html', BlockStr);

        PageStr := TextAfter(PageStr, BeginTag);

        // Titulo y enlace
        LineStr  := TextBetween(BlockStr, '<a class="d-none d-md-inline-block"', '</a>');
        MovieAddress := TextBetween(LineStr,'href="', '"');
        MovieTitle := TextAfter(Linestr,'>');
        MovieTitle := LineDecode(MovieTitle);

        // Año
        MovieYear := TextBetween(BlockStr, '<span class="mc-year ms-1">', '</span>');
        HTMLremovetags(MovieYear);

        // Director
        MovieDirector := TextBetween(BlockStr, '<div class="mt-2 mc-director">', '</div>');
        HTMLremoveTags(MovieDirector);
        MovieDirector := LineDecode(MovieDirector);
        MovieDirector := FullTrim(MovieDirector);

        PickTreeAdd(MovieTitle + ' (' + MovieYear + ') ' + MovieDirector, MovieAddress);

        BlockStr := TextBetween(PageStr, BeginTag, EndTag);
        Count := Count + 1;
      end;

      // Mas resultados?
      BlockStr  := TextBetween(PageStr, '<div class="d-flex justify-content-center">', '</div>');
      if Pos('>>', BlockStr) > 0 then
      begin
        Address := BaseUrl + '/es/' + TextBetween(BlockStr, 'href="', '"');
        Address := StringReplace2(Address, '&amp;', '&', True, True);
      end
      else
        Address := '';
    end;

    // muestra selección
    if Count = 0  then
    begin
      ShowMessage ('No hay resultados');
      FinalPaginas := True;
    end
    else if (Count = 1) and (GetOption('DontAsk') = 1) then
    begin
      AnalyzeMoviePageURL(MovieAddress)
      FinalPaginas := True;
    end
    else
    begin
      PickTreeMoreLink(Address);
      PickTreeExec2(MovieAddress, ItemSel);

      case ItemSel of
        -2: FinalPaginas := False; // buscar mas
        -1: FinalPaginas := True;// cancelar
        else // selección
        begin
          AnalyzeMoviePageURL(MovieAddress);
          FinalPaginas := True;
        end;
      end;
    end;
  end;
end;

//-----------------------------------------------------------------------------------------------------
// Analiza la pagina seleccionada para extraer toda la informacion y pasarla alos campos de la pelicula
// Dos versiones: pasando l aURL o el contanido descargado
//-----------------------------------------------------------------------------------------------------
procedure AnalyzeMoviePageURL(Address: string);
begin
  AnalyzeMoviePageContent(GetPage5Advanced(Address, '', '', '', ''));
end;

procedure AnalyzeMoviePageContent(PageContent: string);
var
  Page: TStringList;
  LineNr, LineInc: Integer;
  sinossi : string;
  Line: string;
  Item: string;
  Comments: string;
  CharStar: string;
  auxItem: string;
  Address: string;
begin
  Comments := '';

  Page := TStringList.Create;
  Page.Text := PageContent;
  
  // URL
  Address := TextBetween(PageContent, '<link rel="canonical" href="', '"');
  SetField(fieldURL, Address);

   // Translated Title
  LineNr := FindLine('<h1 id="main-title">', Page, 0);
  Line   := Page.GetString(LineNr+1);
  Item   := DeleteTags(TextBetween(Line, '<span itemprop="name">', '</span>'));
  Item   := LineDecode(Item);
  SetField(fieldTranslatedTitle, Item);

   // Picture
  LineNr := FindLine('href="https://pics.filmaffinity.com/', Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr);
    Item := TextBetween(Line, '<a class="lightbox" style="display: block;" href="', '" title="');
    if Length(Item) = 0 then
    Item := TextBetween(Line, '" src="', '"></a>');
    GetPicture(Item);
  end;

   // Rating
  LineNr := FindLine('<div id="movie-rat-avg" itemprop="ratingValue"', Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := DeleteTags(Line);
    Item := LineDecode(Item);
    SetField(fieldRating, StringReplace(Item, ',', '.'));
  end;

   // Original Title
  LineNr := FindLine(UTF8Encode('<dt>Título original</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);

      // Eliminar aka
    if Pos('>aka <',Line) <>0 then
    Line:= StringReplace(Line,'>aka <','');

    Item := DeleteTags(TextBetween(Line, '<dd>', '</dd>'));
    Item := LineDecode(Item);
    if Length(Item) = 0 then
    begin
      Line := Page.GetString(LineNr + 2);

      // Eliminar aka
      if Pos('>aka <',Line) <>0 then
      Line:= StringReplace(Line,'>aka <','');

      Item := DeleteTags(Line);
      Item := LineDecode(Item);
    end;
    SetField(fieldOriginalTitle, Item);
  end;

   // Year
  LineNr := FindLine(UTF8Encode('<dt>Año</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := DeleteTags(TextBetween(Line, '">', '</dd>'));
    Item := LineDecode(Item);
    SetField(fieldYear, Item);
  end;

   // Length, si no la tiene...
  if GetField(fieldLength) = '' then
  begin
    LineNr := FindLine(UTF8Encode('<dt>Duración</dt>'), Page, LineNr);
    if LineNr <> -1 then
    begin
      Line := Page.GetString(LineNr + 1);
      Item := DeleteTags(TextBetween(Line, 'duration">', 'min.</dd>'));
      Item := LineDecode(Item);
      SetField(fieldLength, Item);
    end;
  end;

   // Country
  LineNr := FindLine(UTF8Encode('<dt>País</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := DeleteTags(TextBetween(Line, 'alt="', '"></span'));
    Item := LineDecode(Item);
    SetField(fieldCountry, Item);
  end;

   // Director
  LineNr := FindLine(UTF8Encode('class="directors">'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := TextBetween(Line, '<span itemprop="name">', '</div>');
    Item := LineDecode(Item);
    Item := DeleteTags(Item);
    SetField(fieldDirector, Item);
  end;

   // Script writer
  LineNr := FindLine(UTF8Encode('<dt>Guion</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := TextBetween(Line, '<span class="nb">', '</div>');
    Item := LineDecode(Item);
    Item := DeleteTags(Item);
    if ((CheckVersion(4,2,0) = true) and (GetOption('Force350') = 0)) then SetField(fieldWriter, Item)
    else   Comments := Comments + 'Guión: ' + Item + #13#10 + #13#10;
  end;

   // Actors
  LineNr := FindLine(UTF8Encode('<div class="cast-wrapper">'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := LineDecode(Line);
    Item := StringReplace(Item, '</li>', ', ');
    Item := DeleteTags(Item);
    Item := Trim(StringReplace(Item, ' Ver todos los créditos', ''));
    while StrGet(Item, Length(Item)) = ',' do
    begin
      Item := Copy(Item, 1, Length(Item) - 1);
    end;
    if GetOption('ActorsInALine') = 0 then
      Item := StringReplace(Item, ', ', ', '#13#10);
    SetField(fieldActors, Item);
  end;

   // Composer
  LineNr := FindLine(UTF8Encode('<dt>Música</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := TextBetween(Line, '<span class="nb">', '</div>');
    Item := LineDecode(Item);
    Item := DeleteTags(Item);
    if ((CheckVersion(4,2,0) = true) and (GetOption('Force350') = 0)) then SetField(fieldComposer, Item)
    else Comments := Comments + 'Música: ' + Item + #13#10 + #13#10;
  end;

   // Photography
  LineNr := FindLine(UTF8Encode('<dt>Fotografía</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := TextBetween(Line, '<span class="nb">', '</div>');
    Item := LineDecode(Item);
    Item := DeleteTags(Item);
    Comments := Comments + 'Fotograf&iacute;a: ' + Item + #13#10 + #13#10;
  end;

// Productor
  LineNr := FindLine(UTF8Encode('<dt>Compañías</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 2);
    Item := TextBetween(Line, '<span class="nb">', '</div>');
    Item := LineDecode(Item);
    Item := DeleteTags(Item);
    SetField(fieldProducer, Item);
  end;

   // Category
  LineNr := FindLine(UTF8Encode('<dt>Género</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 2);
    Item := DeleteTags(Line);
    Item := LineDecode(Item);
    Item := StringReplace(Item, ' | ', ', ');
    Item := StringReplace(Item, '. ', ', ');
    SetField(fieldCategory, Item);
  end;

   // Official Webpage
  LineNr := FindLine(UTF8Encode('<dt>Web oficial</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr + 1);
    Item := DeleteTags(TextBetween(Line, ' href="', '">'));
    Item := LineDecode(Item);
    Comments := Comments + 'Web oficial: ' + Item + #13#10 + #13#10;
  end;

   // Synopsis
  LineNr := FindLine(UTF8Encode('<dt>Sinopsis</dt>'), Page, LineNr);
  if LineNr <> -1 then
//2025.02.09 inizio fulvio53s03
  begin
  initchar := '<dt>Sinopsis</dt>';
  endchar :=  '</dd>';
  sinossi :=  textbetween(PageContent, initchar, endchar) + endchar;
  sinossi := DeleteTags(sinossi);
  sinossi := LineDecode(sinossi);
  sinossi := fulltrim(sinossi);
  if Copy(sinossi, Length(sinossi) - 13, 14) = '(FILMAFFINITY)' then
    sinossi := FullTrim(Copy(sinossi, 1, Length(sinossi) - 14));
  SetField(fieldDescription, sinossi);
  end;
//2025.02.09 fine fulvio53s03

{
    Line := Page.GetString(LineNr + 1);
    if debug_movie then
       DumpPage(folder + 'Filmaffinity_sinopsis1.html', line);             //fs2025.02.09

    Item := DeleteTags(Line);
    Item := LineDecode(Item);
    SetField(fieldDescription, Item);
  end;
}

   // Awards
  LineNr := FindLine(UTF8Encode('<dt>Premios</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
    LineNr   := LineNr + 1;
    Line     := Page.GetString(LineNr);
    Comments := Comments + 'Premios: ' + #13#10;
    while Pos ('</dd>', Line) = 0 do
    begin
      if Pos ('<span id="show-all-awards">', Line) = 0 then
      begin
        Item := DeleteTags(Line);
        Item := LineDecode(Item);
        if (Length(Item) <> 0) then
        begin
          Comments := Comments + '  - ' + Item + #13#10;
        end;
      end;
      LineNr := LineNr + 1;
      Line   := Page.GetString(LineNr);
    end;
    Comments := Comments + #13#10;
  end;

   // Critic
  LineNr := FindLine(UTF8Encode('<dt>Críticas</dt>'), Page, LineNr);
  if LineNr <> -1 then
  begin
      // El unico objeto de esta linea es poder presentar en el foro el listado
      // del script sin que se produzca la conversión del caracter estrella

    CharStar       := '&'+'#9733;';
    Comments := Comments + 'Críticas: ' + #13#10 + #13#10;
    LineNr := FindLine('<div class="pro-review"', Page, LineNr + 1);
    while LineNr <> -1 do
    begin
      LineNr := LineNr + 2;
      Line := Page.GetString(LineNr);
      if Pos (UTF8Encode('<a title="Leer crítica completa" href='), Line) <> 0 then
      begin
        LineNr := LineNr + 1;
        Line := Page.GetString(LineNr);
      end;
      Line:= StringReplace(Line, CharStar, '*');
      Item := DeleteTags(Line);
      Item := LineDecode(Item);
      if (Length(Item) <> 0) then
      begin
        Comments := Comments + Item + #13#10;
        LineNr := FindLine('div class="pro-crit-med"', Page, LineNr + 1);
        Line := Page.GetString(LineNr);
        Item := DeleteTags(TextBetween(Line, ' itemprop="author">', '<i'));
        Item := LineDecode(Item);
        if (Length(Item) <> 0) then
        begin
          Comments := Comments + Item + #13#10;
        end;
        Comments := Comments + '________________________________________' + #13#10 + #13#10;
      end;
      LineNr := FindLine('<div class="pro-review"', Page, LineNr + 1)
    end;
  end;

  HTMLDecode(Comments);
  SetField(fieldComments, Comments);
  if GetOption('DontWantExtras') = 0 then
    AnalyzeExtras(Page, Address);
end;

//------------------------------------------------------------------------------------
// Extras
procedure AnalyzeExtras(Page: TStringList; Address: string);
var
  LineNr,NumImages,NumTrailers, i,CountC: Integer;
  Line: string;
  TrailersAddress: string;
  ImagesAddress: string;
  ImageTitle: string;
  ExtraIndex: Integer;
  ExtraString: string;
  ExtraURL: string;
  ExtraTagBase: string;
  LimitImages,LimitTrailers,LimitCritics: Integer;
begin
  ExtraTagBase :=  'FA'+TextBetween(Address, '/film', '.html');
  ClearExtrasOfScript;
  LimitImages := StrtoInt (GetParam('ExtraImagesLimit'),0);
  if LimitImages < 0 then LimitImages := 0;
  LimitTrailers := StrtoInt (GetParam('ExtraTrailersLimit'),0);
  if LimitTrailers < 0 then LimitTrailers := 0;
  LimitCritics := StrtoInt (GetParam('ExtraCriticsLimit'),0);
  if LimitCritics < 0 then LimitCritics := 0;

// Enlaces a Criticas
  LineNr := FindLine(UTF8Encode('<dt>Críticas</dt>'), Page, LineNr);
  CountC := 0;
  if LineNr <> -1 then
  begin
    LineNr := FindLine('<div class="pro-review"', Page, LineNr + 1);
    while LineNr <> -1 do
    begin
      LineNr := LineNr + 2;
      Line := Page.GetString(LineNr);
      if Pos (UTF8Encode('<a title="Leer crítica completa" href='), Line) <> 0 then
      begin
        Line := Page.GetString(LineNr);
        ExtraURL:= TextBetween(Line, 'href="', '" ');
        if (Length(ExtraURL))>0 then
        begin
          ExtraIndex := AddExtra();
          SetExtraField(ExtraIndex, extraFieldURL, ExtraURL);
          SetExtraField(ExtraIndex, extraFieldCategory, 'Críticas');
          SetExtraField(ExtraIndex, extraFieldTitle, TextBetween(ExtraURL, '//', '/'));
          SetExtraField(ExtraIndex, extraFieldTag, ExtraTagBase+'C'+IntToStr(ExtraIndex));
        end;
        LineNr := LineNr + 1;
        Line := Page.GetString(LineNr);

        CountC := CountC+1;
        if CountC = LimitCritics then
          break;
      end;
      LineNr := FindLine('<div class="pro-review"', Page, LineNr + 1);
    end;
  end;

   // Imágenes  y Trailers
  NumTrailers := 0;
  NumImages := 0;

  LineNr := FindLine(UTF8Encode('>Tráilers&nbsp;<em>'), Page, 0);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr);
    NumTrailers := StrToInt(TextBetween(Line, '<em>[', ']</em>'),0);
    TrailersAddress := TextBetween(Line, 'href="', '"');
  end

  LineNr := FindLine(UTF8Encode('>Imágenes&nbsp;<em>'), Page, LineNr+1);
  if LineNr <> -1 then
  begin
    Line := Page.GetString(LineNr);
    NumImages := StrToInt(TextBetween(Line, '<em>[', ']</em>'),0);
    ImagesAddress := TextBetween(Line, 'href="', '"');
  end

   // Imágenes
  If NumImages > LimitImages then NumImages := LimitImages;
  if NumImages >0 then
  begin
    Page.Text := GetPage5Advanced(ImagesAddress, '', '', '', '');
    LineNr := FindLine(UTF8Encode('<span>Posters</span>'), Page,0);
    if LineNr = -1 then
    LineNr := FindLine(UTF8Encode('<span>Movie Posters</span>'), Page,0);
    if LineNr =-1 then
    LineNr := FindLine(UTF8Encode('<span>Fotogramas</span>'), Page,0);
    if LineNr =-1 then
    LineNr := FindLine(UTF8Encode('span>Otros</span>'), Page,0);
    if LineNr <> -1 then
    begin
      Line := Page.GetString(LineNr);
      for i := 1 to NumImages do
      begin
        LineNr := FindLine('<a href="', Page, LineNr + 1);
        if LineNr <> -1 then
        begin
          Line := Page.GetString(LineNr);
          ExtraString := TextBetween(Line, 'href="', '"');
          ImageTitle := TextBetween(Line, 'Tipo: </strong>', '</div>');
          ExtraIndex := AddExtra();
          if GetOption('GroupImages') = 1 then
          begin
            SetExtraField(ExtraIndex, extraFieldCategory, 'Imágenes');
            SetExtraField(ExtraIndex, extraFieldTitle, ImageTitle);
          end
          else
          begin
            SetExtraField(ExtraIndex, extraFieldCategory, ImageTitle);
            SetExtraField(ExtraIndex, extraFieldTitle, 'Imágenes')
          end;

          SetExtraField(ExtraIndex, extraFieldTag, ExtraTagBase+'I'+IntToStr(ExtraIndex));
          GetExtraPicture(ExtraIndex, ExtraString);
        end;
      end;
    end;
  end;

  If NumTrailers > LimitTrailers then NumTrailers := LimitTrailers;
  if NumTrailers > 0 then
  begin
    Page.Text := GetPage5Advanced(TrailersAddress, '', '', '', '');
    
    LineNr := 0;
    for i:= 1 to NumTrailers do
    begin
      LineNr := FindLine('<div id="divvid' + InttoStr(i), Page, LineNr);
      if LineNr <> -1 then
      begin
        LineNr := FindLine('<iframe', Page, LineNr + 1);
        Line := Page.GetString(LineNr);
        
        ExtraString := TextBetween(Line, 'src="', '"');
        ExtraURL := TextAfter(ExtraString, '//');
        ExtraIndex := AddExtra();
        SetExtraField(ExtraIndex, extraFieldURL, ExtraURL);
        SetExtraField(ExtraIndex, extraFieldCategory, 'Trailers');
        SetExtraField(ExtraIndex, extraFieldTitle, TextBetween(ExtraString, '//', '/'))
        SetExtraField(ExtraIndex, extraFieldTag, ExtraTagBase+'T'+IntToStr(ExtraIndex));
      end;
    end;
  end;
end;


//------------------------------------------------------------------------------------

begin
  if (CheckVersion(4,2,3) = false) then
  begin
    if ShowWarning('This script requires a newer version of Ant Movie Catalog, at least the version 4.2.3.3 - do you wish to open the link to download it?)') = true then
    begin
      Launch('https://www.antp.be/software/moviecatalog/download', '');
    end;
    exit;
  end;

  MovieName     := GetField(fieldOriginalTitle);
  MovieYear     := GetField(fieldYear);

  YearFrom      := MovieYear;
  YearTo        := MovieYear;

  if Length(MovieName) = 0 then
  MovieName := GetField(fieldTranslatedTitle);

  if (GetOption('DontAsk') = 0) or (MovieName = '') then
    Input('FilmAffinity (ES)', 'Título: ' + GetField(fieldFilePath), MovieName);

  if Pos('filmaffinity.com', MovieName) > 0 then
    AnalyzeMoviePageURL(MovieName)
  else if GetOption('AdvancedSearch') = 1 then
  begin
    AdvQuery := UrlEncode(MovieName);
    if GetOption('SearchByFromToYears') = 1 then
    begin
      if GetOption('DontAsk') = 0 then
      begin
        Input('FilmAffinity (ES)', 'Desde el año: ', YearFrom);
        Input('FilmAffinity (ES)', 'Hasta el año: ', YearTo);
      end;
      AdvQuery := AdvQuery + '&fromyear=' + YearFrom;
      AdvQuery := AdvQuery + '&toyear=' + YearTo;
    end;

    {
    stype[]=title         Título
    stype[]=director      Director
    stype[]=cast          Reparto
    stype[]=script        Guión
    stype[]=photo         Fotografía
    stype[]=music         Música
    stype[]=producer      Productor
    }

    if GetOption('SearchByTitle') = 1 then
    AdvQuery := AdvQuery + '&stype[]=title';

    if GetOption('SearchByDirector') = 1 then
    AdvQuery := AdvQuery + '&stype[]=director';

    if GetOption('SearchByCast') = 1 then
    AdvQuery := AdvQuery + '&stype[]=cast';

    if GetOption('SearchByScript') = 1 then
    AdvQuery := AdvQuery + '&stype[]=script';

    if GetOption('SearchByPhoto') = 1 then
    AdvQuery := AdvQuery + '&stype[]=photo';

    if GetOption('SearchByMusic') = 1 then
    AdvQuery := AdvQuery + '&stype[]=music';

    if GetOption('SearchByProducer') = 1 then
    AdvQuery := AdvQuery + '&stype[]=producer';

    if GetOption('SortByYear') = 1 then
    AdvQuery := AdvQuery + '&orderby=year';

    AnalyzeAdvPage(AdvQuery);
  end
  else
  begin
    AdvQuery := UrlEncode(MovieName);

    if GetOption('SearchByTitle') = 1 then
    AdvQuery := AdvQuery + '&stype=title';

    if GetOption('SearchByCast') = 1 then
    AdvQuery := AdvQuery + '&stype=cast';

    if GetOption('SortByYear') = 1 then
    AdvQuery := AdvQuery + '&orderby=year';

    AnalyzeStdPage(AdvQuery);
  end;
end.
Post Reply