Page 1 of 1

Script for export to Kodi ( 15.x tested)

Posted: 2015-12-12 23:20:51
by Harald
What does this script:

Exports data to simple xml as filename.nfo for use in Kodi.
Exports Picture to filename-poster.ext for use in Kodi.

* filename comes from filed [FilePath].
if [FilePath] is empty then field [OriginalTitle] is used
and you'll be asked to enter a existing folder name to export to.
Folder must already exist.
If file not created , then foldername was not correct or not existing.


before import in Kodi make sure files match same name.
example: Superman.nfo
Superman-poster.jpg
Superman.mkv


Best way to use:

1 create new ant catalog.
2 use File-->import-->Media Files then field [FilePath] will exist.
3 add your data with ant-scripts by pressing F6.
4 press SHIFT-F6 and choose the AMC_to_Simple_Kodi script.

Succesfully tested for Kodi 15.x

script is based on AMC_to_XBMC_xml_Export.ifs thanks to 'dowiew' the author.(hope you did not mind) .

Hope you like it.
save all in code to : AMC_to_Simple_Kodi.ifs in the AMC-script folder.

Code: Select all

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

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

[Infos]
Authors=Harald
Title=AMC to Simple Kodi xml Export
Description=Export movie data  to  movie.nfo and Picture to movie-poster.jpg if FilePath exists in movie data else save to OriginalTitle.nfo and OriginalTitle-poster.ext asked folder
Site=
Language=EN
Version=1.0
Requires=3.5.0
Comments=Read source code comments!
License=This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
GetInfo=0
RequiresMovies=1

[Options]

[Parameters]

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

program AMCtoSimpleKodiXMLExport;
var

  sx: string;
  sl: TStringList;
  SFileName, SaveFileName, MovieNumber, XBOX_Movies_Path: string;
  i:integer;
  
procedure Ask(Msg: string; var TheStr: string);
begin
  if not Input('AMC to Simple Kodi xml Export', Msg, TheStr) then TheStr:='';
end;

begin
  sl := TStringList.Create;
  SaveFileName:= ChangeFileExt(GetField(fieldFilePath),'.nfo');

  if SaveFileName = '.nfo' then
  begin
    XBOX_Movies_Path:='';
    if XBOX_Movies_Path='' then XBOX_Movies_Path:='D:\Movie\';
    i := 0;
    Ask('Set Pathname to save your files if no FilePath-Field exists', XBOX_Movies_Path);
    while i = 0 do
    begin
      if not DirectoryExists(XBOX_Movies_Path) then
        begin

         Ask('Set Pathname to save your files if no FilePath-Field exists. Path must already exist!!', XBOX_Movies_Path);
        end
      else
        i := 1;
    end;
  end;

     

  if SaveFileName='' then EXIT;
  if Pos('.nfo', SaveFileName)+Pos('.NFO', SaveFileName)=0 then SaveFileName:=SaveFileName+'.nfo';

  sl.Append('<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>');

  sl.Append('<movie>');

  MovieNumber:=GetField(fieldNumber);
  sx:='';
  //Movie info ordered as it appears on XBMC screen.
  //The fields we don't have in AMC are commented-out. Leave blank or put other fields there.
  if GetField(fieldTranslatedTitle) <> '' then
    sx:=sx+'    <title>'           + GetField(fieldTranslatedTitle) + '</title>'+#13#10
  else
    sx:=sx+'    <title>'           + GetField(fieldOriginalTitle) + '</title>'+#13#10 ;
    
  sx:=sx+'    <director>'        + GetField(fieldDirector)        + '</director>'+#13#10;
//sx:=sx+'    <credits>'         + GetField(fieldRating)               + '</credits>'+#13#10;
  sx:=sx+'    <genre>'           + GetField(fieldCategory)        + '</genre>'+#13#10;
  sx:=sx+'    <year>'            + GetField(fieldYear)            + '</year>'+#13#10;
//sx:=sx+'    <tagline>'         + GetField(field )               + '</tagline>'+#13#10;
//sx:=sx+'    <outline>'         + GetField(field )               + '</outline>'+#13#10;
  sx:=sx+'    <rating>'          + GetField(fieldRating)          + '</rating>'+#13#10;
//sx:=sx+'    <votes>'           + GetField(field )               + '</votes>'+#13#10;
  sx:=sx+'    <runtime>'         + GetField(fieldLength)+' min'   + '</runtime>'+#13#10;
//sx:=sx+'    <mpaa>'            + GetField(field )               + '</mpaa>'+#13#10;
  sx:=sx+'    <plot>'            + GetField(fieldDescription)     + '</plot>'+#13#10;
//Original Title, not visible though:
  sx:=sx+'    <originaltitle>'   + GetField(fieldOriginalTitle)   + '</originaltitle>'+#13#10;

//Additional xml fields that can be left blank or assigned to whatever:

//sx:=sx+'    <top250>'          + GetField(field )               + '</top250>'+#13#10;
//sx:=sx+'    <season>'          + GetField(field )               + '</season>'+#13#10;
//sx:=sx+'    <episode>'         + GetField(field )               + '</episode>'+#13#10;
//sx:=sx+'    <thumb>'           + GetField(field )               + '</thumb>'+#13#10; // http://127.0.0.1/dummy.jpg
//sx:=sx+'    <watched>'         + GetField(field )               + '</watched>'+#13#10;
//sx:=sx+'    <searchstring>'    + GetField(field )               + '</searchstring>'+#13#10;
//sx:=sx+'    <file>'            + GetField(field )               + '</file>'+#13#10;
//sx:=sx+'    <path>'            + GetField(field )               + '</path>'+#13#10; // seems not needed
//sx:=sx+'    <premiered>'       + GetField(field )               + '</premiered>'+#13#10;
//sx:=sx+'    <status>'          + GetField(field )               + '</status>'+#13#10;
//sx:=sx+'    <code>'            + GetField(field )               + '</code>'+#13#10;
//sx:=sx+'    <aired>'           + GetField(field )               + '</aired>'+#13#10;



  sx:=sx+'  </movie>';
  sl.Append(UTF8Encode(sx));
  //save sl.savefilename
  if SaveFileName = '.nfo' then
  begin
    i:= 0;
    SaveFilename := GetField(fieldOriginalTitle);
    while i=0 do
      begin
      if Pos('<', SaveFileName) + Pos('>', SaveFileName)+ Pos(':', SaveFileName)+
           Pos('"', SaveFileName) + Pos('/', SaveFileName)+ Pos('\', SaveFileName)+
           Pos('|', SaveFileName) + Pos('?', SaveFileName)+ Pos('*', SaveFileName) >0 then
           Ask('Origintal title contains  < > : " / \ | ? *  ) , if other illegal characters.'+#13#10 +
                ' are used then files wil not be created ' + #13#10 + ' Please Correct filename!!', SaveFileName)
      else
        begin
          i:=1;
        end;

      end;
  SaveFileName := XBOX_Movies_Path + SaveFileName + '.nfo';
  end;

  SFilename := ChangeFileExt(SaveFileName,'-poster' + PictureExt);

  sl.SaveToFile(SaveFileName);
  sl.Free;
  ExportPicture(SFileName);
  

end.
[/code]

Nice...

Posted: 2017-05-15 04:10:24
by tiagoaquino
I found it really interesting and I'm trying to improve it.. But I ended up facing some difficulties, I hope this community is able to help.

In ANT, we can add multiple actors (or genres) by adding a comma (,) between them. In Kodi we must add them individually in their on tags. As I'm familiar with programming, I believe there is a way to read the field and keep adding tags until no comma is found, excluding spaces around them (a "for loop" "while", don't know).

Can someone help with that?

Posted: 2017-05-15 16:22:59
by antp
It should not be very difficult indeed, if you add a "uses StringUtils1;" at the top (after the "program" line) you can use a function "TextBefore" that can be useful for that.
e.g.: (there is probably cleaner way to do that, it is just quickly written code)

Code: Select all

var
  Actors, s: String;

Actors := GetField(fieldActors);
while Actors <> '' do
begin
  if Pos(',' Actors) = 0 then
  begin
    s := Actors;
    Actors := '';
  end
  else
  begin
    s := TextBefore(Actors, ',', '');
    Actors := RemainingText;
  end;
  /*
    here you have an actor name in the variable "s", that you can use to generate a new actor tag
  */
end;

Posted: 2017-05-15 17:40:37
by tiagoaquino
antp wrote:It should not be very difficult indeed, if you add a "uses StringUtils1;" at the top (after the "program" line) you can use a function "TextBefore" that can be useful for that.
e.g.: (there is probably cleaner way to do that, it is just quickly written code)

Code: Select all

var
  Actors, s: String;

Actors := GetField(fieldActors);
while Actors <> '' do
begin
  if Pos(',' Actors) = 0 then
  begin
    s := Actors;
    Actors := '';
  end
  else
  begin
    s := TextBefore(Actors, ',', '');
    Actors := RemainingText;
  end;
  /*
    here you have an actor name in the variable "s", that you can use to generate a new actor tag
  */
end;
We're almost there.. I've made some minor changes on your code due to compilation warnings. I ended up with this (also change variable names to use them more than once):

Code: Select all

TxtAux := GetField(fieldActors);
while TxtAux <> '' do
begin
  if Pos(',',TxtAux) = 0 then
  begin
    sAux := TxtAux;
    TxtAux := '';
  end
  else
  begin
    sAux := TextBefore(TxtAux, ',', '');
    TxtAux := RemainingText;
  end;
  sx:=sx+'    <actor>'+#13#10'        <name>'     + sAux          + '</name>'+#13#10'    </actors>'+#13#10;
  end;
Right now, the script is running, generating this output:

Code: Select all

    <actor>
        <name>Darryl Alan Reed</name>
    </actors>
    <actor>
        <name> Valente Rodriguez</name>
    </actors>
    <actor>
        <name> Yvette Nicole Brown</name>
    </actors>
    <actor>
        <name> Nicole Vicius</name>
    </actors>
As you can see, we're almost there. There is a blank space before the actor name. And depending on some case, there might be a space at the end. So.. is there a way to remove leading and trailing spaces?

Posted: 2017-05-15 17:55:33
by tiagoaquino
tiagoaquino wrote:is there a way to remove leading and trailing spaces?
fulltrim(sAux) does it! Done!

Posted: 2017-05-15 18:12:51
by tiagoaquino
Ok.. now how it came out:

Director, Country, Genre and Actors may be multiple values. There's also some Custom Fields on this script for SortTitle and Set tags (more info in Kodi documentation: http://kodi.wiki/view/NFO_files/Movies), if you don't use it, you leave it commented

Code: Select all

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

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

[Infos]
Authors=Harald
Title=AMC to Simple Kodi xml Export
Description=Export movie data  to  movie.nfo and Picture to movie-poster.jpg if FilePath exists in movie data else save to OriginalTitle.nfo and OriginalTitle-poster.ext asked folder
Site=
Language=EN
Version=1.0
Requires=3.5.0
Comments=Read source code comments!
License=This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
GetInfo=0
RequiresMovies=1

[Options]

[Parameters]

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

program AMCtoSimpleKodiXMLExport; uses StringUtils1;
var

  TxtAux: string;
  sAux: string;
  sx: string;
  sl: TStringList;
  SFileName, SaveFileName, MovieNumber, XBOX_Movies_Path: string;
  i:integer;

procedure Ask(Msg: string; var TheStr: string);
begin
  if not Input('AMC to Simple Kodi xml Export', Msg, TheStr) then TheStr:='';
end;

begin
  sl := TStringList.Create;
  SaveFileName:= ChangeFileExt(GetField(fieldFilePath),'.nfo');

  if SaveFileName = '.nfo' then
  begin
    XBOX_Movies_Path:='';
    if XBOX_Movies_Path='' then XBOX_Movies_Path:='D:\Movie\';
    i := 0;
    Ask('Set Pathname to save your files if no FilePath-Field exists', XBOX_Movies_Path);
    while i = 0 do
    begin
      if not DirectoryExists(XBOX_Movies_Path) then
        begin

         Ask('Set Pathname to save your files if no FilePath-Field exists. Path must already exist!!', XBOX_Movies_Path);
        end
      else
        i := 1;
    end;
  end;



  if SaveFileName='' then EXIT;
  if Pos('.nfo', SaveFileName)+Pos('.NFO', SaveFileName)=0 then SaveFileName:=SaveFileName+'.nfo';

  sl.Append('<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>');

  sl.Append('<movie>');

  MovieNumber:=GetField(fieldNumber);
  sx:='';
  if GetField(fieldTranslatedTitle) <> '' then
    sx:=sx+'    <title>'           + GetField(fieldTranslatedTitle) + '</title>'+#13#10
  else
    sx:=sx+'    <title>'           + GetField(fieldOriginalTitle) + '</title>'+#13#10 ;

TxtAux := GetField(fieldDirector);
while TxtAux <> '' do
begin
  if Pos(',',TxtAux) = 0 then
  begin
    sAux := TxtAux;
    TxtAux := '';
  end
  else
  begin
    sAux := TextBefore(TxtAux, ',', '');
    TxtAux := RemainingText;
  end;
  sx:=sx+'    <director>'        + fulltrim(sAux)        + '</director>'+#13#10;
end;
//sx:=sx+'    <credits>'         + GetField(field )               + '</credits>'+#13#10;
TxtAux := GetField(fieldCategory);
while TxtAux <> '' do
begin
  if Pos(',',TxtAux) = 0 then
  begin
    sAux := TxtAux;
    TxtAux := '';
  end
  else
  begin
    sAux := TextBefore(TxtAux, ',', '');
    TxtAux := RemainingText;
  end;
  sx:=sx+'    <genre>'           + fulltrim(sAux)        + '</genre>'+#13#10;
end;
  sx:=sx+'    <year>'            + GetField(fieldYear)            + '</year>'+#13#10;
//sx:=sx+'    <tagline>'         + GetField(field )               + '</tagline>'+#13#10;
//sx:=sx+'    <outline>'         + GetField(field )               + '</outline>'+#13#10;
  sx:=sx+'    <rating>'          + GetField(fieldRating)          + '</rating>'+#13#10;
//sx:=sx+'    <votes>'           + GetField(field )               + '</votes>'+#13#10;
  sx:=sx+'    <runtime>'         + GetField(fieldLength)          + '</runtime>'+#13#10;
//sx:=sx+'    <mpaa>'            + GetField(field )               + '</mpaa>'+#13#10;
  sx:=sx+'    <id>'              + GetField(fieldMedia)           + '</id>'+#13#10;
  sx:=sx+'    <plot>'            + GetField(fieldDescription)     + '</plot>'+#13#10;
TxtAux := GetField(fieldActors);
while TxtAux <> '' do
begin
  if Pos(',',TxtAux) = 0 then
  begin
    sAux := TxtAux;
    TxtAux := '';
  end
  else
  begin
    sAux := TextBefore(TxtAux, ',', '');
    TxtAux := RemainingText;
  end;
  sx:=sx+'    <actor>'+#13#10'        <name>'     + fulltrim(sAux)          + '</name>'+#13#10'    </actor>'+#13#10;
end;
TxtAux := GetField(fieldCountry);
while TxtAux <> '' do
begin
  if Pos(',',TxtAux) = 0 then
  begin
    sAux := TxtAux;
    TxtAux := '';
  end
  else
  begin
    sAux := TextBefore(TxtAux, ',', '');
    TxtAux := RemainingText;
  end;
  sx:=sx+'    <country>'         + fulltrim(sAux)         + '</country>'+#13#10;
end;
//  if GetCustomField('SortTitle') <> '' then
//  sx:=sx+'    <sorttitle>'       + GetCustomField('SortTitle')    + '</sorttitle>'+#13#10;
  
//  if GetCustomField('Set') <> '' then
//  sx:=sx+'    <set>'             + GetCustomField('Set')    + '</set>'+#13#10;


//Additional xml fields that can be left blank or assigned to whatever:

//sx:=sx+'    <top250>'          + GetField(field )               + '</top250>'+#13#10;
//sx:=sx+'    <season>'          + GetField(field )               + '</season>'+#13#10;
//sx:=sx+'    <episode>'         + GetField(field )               + '</episode>'+#13#10;
//sx:=sx+'    <thumb>'           + GetField(field )               + '</thumb>'+#13#10; // http://127.0.0.1/dummy.jpg
//sx:=sx+'    <watched>'         + GetField(field )               + '</watched>'+#13#10;
//sx:=sx+'    <searchstring>'    + GetField(field )               + '</searchstring>'+#13#10;
//sx:=sx+'    <file>'            + GetField(field )               + '</file>'+#13#10;
//sx:=sx+'    <path>'            + GetField(field )               + '</path>'+#13#10; // seems not needed
//sx:=sx+'    <premiered>'       + GetField(field )               + '</premiered>'+#13#10;
//sx:=sx+'    <status>'          + GetField(field )               + '</status>'+#13#10;
//sx:=sx+'    <code>'            + GetField(field )               + '</code>'+#13#10;
//sx:=sx+'    <aired>'           + GetField(field )               + '</aired>'+#13#10;



  sx:=sx+'  </movie>';
  sl.Append(UTF8Encode(sx));
  //save sl.savefilename
  if SaveFileName = '.nfo' then
  begin
    i:= 0;
    SaveFilename := GetField(fieldOriginalTitle);
    while i=0 do
      begin
      if Pos('<', SaveFileName) + Pos('>', SaveFileName)+ Pos(':', SaveFileName)+
           Pos('"', SaveFileName) + Pos('/', SaveFileName)+ Pos('\', SaveFileName)+
           Pos('|', SaveFileName) + Pos('?', SaveFileName)+ Pos('*', SaveFileName) >0 then
           Ask('Origintal title contains  < > : " / \ | ? *  ) , if other illegal characters.'+#13#10 +
                ' are used then files wil not be created ' + #13#10 + ' Please Correct filename!!', SaveFileName)
      else
        begin
          i:=1;
        end;

      end;
  SaveFileName := XBOX_Movies_Path + SaveFileName + '.nfo';
  end;

  SFilename := ChangeFileExt(SaveFileName,'-poster' + PictureExt);

  sl.SaveToFile(SaveFileName);
  sl.Free;
  ExportPicture(SFileName);


end.

Re: Script for export to Kodi ( 15.x tested)

Posted: 2019-05-04 17:55:17
by Madstorm
Hello,

I use Antmovie since > 10 years, great no doubt.

I've switched on XBMC - Kodi since 5, and export antmovie catalog to .nfo then import with local info in Kodi.
Works great...
BUT...one feature is not correctly handled in the .nfo file...the god dam <role> tag...

The reason is : In Kodi, if i want to get all movies available in my library with a particular actor, it doesn't work...and it is frustrating !!!

Example of what i need ! (the ActorsToXml function which is available in scripts section doesn't do the job !!!)

Actors field in antmovie :
Oskar Werner (Guy Montag), Julie Christie (Linda/Clarisse), Cyril Cusack (le capitaine), Anton Diffring (Fabian), Jeremy Spenser (l'homme avec les pommes), Bee Duffell (la dame aux livres), Michael Balfour (Machiavelli), Anna Palk (Jackie), Alex Scott (Book Person: 'The Life of Henry Brulard'), Ann Bell (Doris), Arthur Cox (Male Nurse), Frank Cox (Book Person: 'Prejudice').


I need something like that in the .nfo export with actor, name + role :

<actor>
<name>Oskar Werner</name>
<role>Guy Montag</role>
</actor>
....
....

in 2008, this guy seems to have post the solution
https://forum.kodi.tv/showthread.php?tid=31511&page=2
not active anymore...

Is there somebody with the solution ?

Thank you very much

Rgs
M