Page 1 of 1

[REL] Gracenote's CDDB for Audio CDs' script

Posted: 2005-02-08 23:49:10
by ABNormal
This script has been a personal test in the search of understanding scripts.
I used DinoLib's script (based on Pivello's ones) trying to capture infos from internet.
Gracenote has a easy search pages, info pages (few pictures, near only the CD's informations...) and i tried. Now, with a LITTLE help from my friend ANTP, this script works.
So, if you want to have a catalogue for your music you can use this script.
---HOW TO USE & HOW TO READ---
1) Add a new empty "movie" record (Add+Ins) and
2) both... or write into "ORIGINAL TITLE" or directly go in my script and write band - album (example: The Cure - Disintegration).
Script, as usual, try to find the right result. If more than one it asks a choice.
3) Resulting Datas:
Director=Band
Translated Title= Album
Description= Track Titles
Year=Year :) (Not always present)
Producer= Label (Not always present)

That's all
now the code:

Code: Select all

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

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

[Infos]
Authors=Pivello, DinoLib, ABNormal
Title=CDDB
Description=Get movie info from CDDB
Site=www.GRACENOTE.COM/MUSIC
Language=EN
Version=08.02.2005
Requires=3.5.0
Comments=Modified by: 08.02.2005 ABNormal;
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

//[Options]
//LargePicture=1|1|0=Get a small picture|1=Try to get the big picture

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

program CDDb;

const
  UrlBase = 'http://www.gracenote.com';
  QueryBase = UrlBase + '/music/search.html?f=artist&f=disc&x=0&y=0&n=100&q=';
  cStartId = 'ENDREL --><A HREF="'; // ID start marker
  cEndId = '.html" ';           // ID end marker
  cStartDirector = '<b>';               // Director start marker
  cEndDirector = ' /';                         // Director end marker
  cStartTitle = '>';                      // Title start marker
  cEndTitle = '</A><!';                     // Title end marker
  cStartTranslTitle = ' ';     // Translated title start marker
  cEndTranslTitle = '</b>';                   // Translated title end marker
  cStartProd = 'Label: ';                         // Image end marker
  cEndProd = '<br>';
  cStartYear = 'Year: ';
  cEndYear = '<';                        // Generic field marker
  cStartTrack = 'class=num width=40 align=right>';
  cEndTrack = '</td><td';
  cStartCast = ' width=62%>';                   // Actor start marker
  cEndCast = '</td><td align=';                             // Actor end marker
var
  Page: TStringList;
  MovieUrl, MovieName, OriginalStr, TranslatedStr, PageStr:  string;

// ---------------------------------------------
// PAGE PACKING (remove extra spaces, tabs & CR)
// IN:  page Url     (string)
// OUT: compact page (string)
// ---------------------------------------------
function RemoveExtraChars(Url: string): string;
var
  Temp: string;
  PackedPage: string;
  CharPos: Integer;
  n: Integer;
begin
  Page.Text := GetPage(Url);
  for n:=0 to Page.Count-1 do
   PackedPage := PackedPage + ' ' + Page.GetString(n);
  repeat
   CharPos := pos('  ', PackedPage);
   if CharPos = 0 then
    CharPos := pos(#9, PackedPage);
   if CharPos <> 0 then
    begin
     Temp := copy(PackedPage, 1, CharPos -1);
     Delete(PackedPage, 1, CharPos);
     PackedPage := Temp + PackedPage;
    end;
  until((pos('  ', PackedPage) = 0) and (pos(#9, PackedPage) = 0));
  result := PackedPage;
end;

// ---------------------------------
// GET FIELD VALUES FROM PACKED PAGE
// IN:  Start marker     (String)
//      End marker       (string)
//      Cut Start Marker (bool)
//      Cut End Marker   (bool)
// OUT: value            (string)
// ---------------------------------
function GetValue(StartMarker, EndMarker: string; CutStartMarker, CutEndMarker: boolean): string;
var
  StartPos: integer;
  EndPos: integer;
  Value: string;
begin
  Value := '';
  StartPos := pos(StartMarker, PageStr);
  if (StartPos > 0) then
   Delete(PageStr, 1, StartPos-1);
  StartPos := pos(StartMarker, PageStr);
  EndPos := pos(EndMarker, PageStr);
  if ((StartPos > 0)and(EndPos > 0)) then
   begin
    if CutStartMarker then
     StartPos := StartPos + length(StartMarker);
    if not CutEndMarker then
     EndPos := EndPos + length(EndMarker);
    Value := copy(PageStr, StartPos, EndPos-Startpos);
    Delete(PageStr, 1, EndPos);
   end;
  result := Value;
end;

// -----------------------
// ANALYZE MOVIE DATA PAGE
// IN:  none
// OUT: set Ant fields
// -----------------------
procedure AnalyzeMoviePage;
var
  i, h, m: integer;
  Duration, Description, Cast, TempTrackNo, TempStr, TempImg, hh, mm: string;
begin
  // Get packed title main page
  PageStr := RemoveExtraChars(MovieUrl);

  SetField(fieldDirector, getValue(cStartDirector, cEndDirector, true, true)); // BAND (Director)
  SetField(fieldTranslatedTitle, getValue(cStartTranslTitle, cEndTranslTitle, true, true));  // ALBUM (Translated Title)
  SetField(fieldProducer, getValue(cStartProd, cEndProd, true, true));  // LABEL (Producer)
  SetField(fieldYear, getValue(cStartYear, cEndYear, true, true));  // YEAR (Year)

  // TRACKS (Description)
  Cast := '';
  repeat
  TempTrackNo := getValue(cStartTrack, cEndTrack, true, true);
  TempStr := getValue(cStartCast, cEndCast, true, true);
  if ((Cast<>'') and (TempStr<>'')) then
  Cast := Cast + #13#10;
  Cast := Cast + TempTrackNo + ' ' + TempStr;
  until((TempStr='')or(Length(TempStr)>40));
  SetField(fieldDescription, Cast);
 
  SetField(fieldURL, MovieUrl); //Album Web Page
end;

// ------------------------------------------------------------------
// FILL PICKTREE CONTROL WITH LINKS & TITLES or RETURN ONE PAGE LINK
// if flag true return Film Id else populate PickTree
// IN:  OneFilm flag (bool)
// OUT: one page ID  (string)
// ------------------------------------------------------------------
function PopulatePickTree(OneFilm: boolean): string;
var
  TempIdFilm: string;
  TempTitle: string;
  StartPos: integer;
  EndPos: integer;
begin
  if OneFilm then
   begin
    StartPos := pos(cStartId, PageStr);
    EndPos := pos(cEndId, PageStr);
    StartPos := StartPos + Length(cStartId);
    TempIdFilm := copy(PageStr, StartPos, EndPos-Startpos); // Get ID
    result := UrlBase + TempIdFilm + '.html';
   end
  else
   begin
    PickTreeClear;
    repeat
     StartPos := pos(cStartId, PageStr);
     EndPos := pos(cEndId, PageStr);
     if StartPos > 0 then
      begin
       StartPos := StartPos + Length(cStartId);
       TempIdFilm := copy(PageStr, StartPos, EndPos-Startpos);  // Get ID
       Delete(PageStr, 1, EndPos);
       StartPos := pos(cStartTitle, PageStr);
       EndPos := pos(cEndTitle, PageStr);
       StartPos := StartPos + Length(cStartTitle);
       TempTitle := copy(PageStr, StartPos, EndPos-Startpos); // Get Title
       PickTreeAdd(TempTitle, UrlBase + TempIdFilm + '.html');
      end;
    until(StartPos = 0);
    result := '';
   end
end;

// ---------------------------------
// ANALYZE FIRST SEARCH RESULT PAGE:
// IN:  page Url (string)
// OUT: none
// ---------------------------------
procedure AnalyzeSearchPage(Url: string);
var
  FilmId: string;
begin
  PageStr := RemoveExtraChars(Url);
  if pos('We were unable', PageStr) > 0 then ShowMessage('Title not found / Nessun film trovato.')
  else 
    if pos('Si è verificato un errore',PageStr) > 0 then ShowMessage('Server not available, try later / Server non disponibile, prova più tardi')
    else
      begin
       if pos('Displaying Disc', PageStr) > 0 then
       begin
       PopulatePickTree(false);           
       if not PickTreeExec(MovieUrl) then
       exit;
      end;
    AnalyzeMoviePage;
   end;
end;

// ----------
// MAIN:
// IN:  none
// OUT: none
// ----------
begin
  if CheckVersion(3,5,0) then
   begin
    TranslatedStr := GetField(fieldOriginalTitle);
    OriginalStr := GetField(fieldTranslatedTitle);
    if (TranslatedStr <> '') then MovieName := TranslatedStr else MovieName := OriginalStr;
    if (Input('Gracenote''s CDDB - By ABN+Pivello', 'Enter the title of the movie / Inserire titolo del film:', MovieName)) then
     begin
      Page := TStringList.Create;
      MovieUrl := QueryBase + UrlEncode(MovieName);
      AnalyzeSearchPage(MovieUrl);
      Page.Free;
     end;
   end
  else
   ShowMessage('This script requires a newer version of Ant Movie Catalog (at least the version 3.5.0)');
end. 
I don't know if someone will use it, but i'm happy to have reached my goal: a working script.
Bye
ABN

Posted: 2005-02-11 13:52:41
by -xD-
senx a looot!!!!
but can you add in you script to add in
Original Title like this
2Pac - Thug Life - Volume 1
atrist album
please!
and add a picture import from amazon or else! its very important for me

Posted: 2005-02-11 14:57:44
by ABNormal
I'm glad you've apreciate my script.
For my limited knowledge in these scripts, now i can satisfy you for your 1st request: OriginalTitle will be Director (Band) - TranslatedTitle (Album)
so, if u start with
2Pac - Thug
and u choose 1st volume of Thug LIFE:
Director= 2pac (R.I.P.)
TranslatedTitle= Thug Life Vol.1
and, at last
OriginalTitle changes into 2Pac - Thug Life Vol.1 .
Script now is:

Code: Select all

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

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

[Infos]
Authors=Pivello, DinoLib, ABNormal
Title=CDDB
Description=Get movie info from CDDB
Site=www.GRACENOTE.COM/MUSIC
Language=EN
Version=08.02.2005
Requires=3.5.0
Comments=Modified by: 08.02.2005 ABNormal;
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

[Options]
//LargePicture=1|1|0=Get a small picture|1=Try to get the big picture

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

program CDDb;

const
  UrlBase = 'http://www.gracenote.com';
  QueryBase = UrlBase + '/music/search.html?f=artist&f=disc&x=0&y=0&n=100&q=';
  cStartId = 'ENDREL --><A HREF="'; // ID start marker
  cEndId = '.html" ';           // ID end marker
  cStartDirector = '<b>';               // Director start marker
  cEndDirector = ' /';                         // Director end marker
  cStartTitle = '>';                      // Title start marker
  cEndTitle = '</A><!';                     // Title end marker
  cStartTranslTitle = ' ';     // Translated title start marker
  cEndTranslTitle = '</b>';                   // Translated title end marker
  cStartProd = 'Label: ';                         // Image end marker
  cEndProd = '<br>';
  cStartYear = 'Year: ';
  cEndYear = '<';                        // Generic field marker
  cStartTrack = 'class=num width=40 align=right>';
  cEndTrack = '</td><td';
  cStartCast = ' width=62%>';                   // Actor start marker
  cEndCast = '</td><td align=';                             // Actor end marker
var
  Page: TStringList;
  MovieUrl, MovieName, OriginalStr, TranslatedStr, PageStr:  string;

// ---------------------------------------------
// PAGE PACKING (remove extra spaces, tabs & CR)
// IN:  page Url     (string)
// OUT: compact page (string)
// ---------------------------------------------
function RemoveExtraChars(Url: string): string;
var
  Temp: string;
  PackedPage: string;
  CharPos: Integer;
  n: Integer;
begin
  Page.Text := GetPage(Url);
  for n:=0 to Page.Count-1 do
   PackedPage := PackedPage + ' ' + Page.GetString(n);
  repeat
   CharPos := pos('  ', PackedPage);
   if CharPos = 0 then
    CharPos := pos(#9, PackedPage);
   if CharPos <> 0 then
    begin
     Temp := copy(PackedPage, 1, CharPos -1);
     Delete(PackedPage, 1, CharPos);
     PackedPage := Temp + PackedPage;
    end;
  until((pos('  ', PackedPage) = 0) and (pos(#9, PackedPage) = 0));
  result := PackedPage;
end;

// ---------------------------------
// GET FIELD VALUES FROM PACKED PAGE
// IN:  Start marker     (String)
//      End marker       (string)
//      Cut Start Marker (bool)
//      Cut End Marker   (bool)
// OUT: value            (string)
// ---------------------------------
function GetValue(StartMarker, EndMarker: string; CutStartMarker, CutEndMarker: boolean): string;
var
  StartPos: integer;
  EndPos: integer;
  Value: string;
begin
  Value := '';
  StartPos := pos(StartMarker, PageStr);
  if (StartPos > 0) then
   Delete(PageStr, 1, StartPos-1);
  StartPos := pos(StartMarker, PageStr);
  EndPos := pos(EndMarker, PageStr);
  if ((StartPos > 0)and(EndPos > 0)) then
   begin
    if CutStartMarker then
     StartPos := StartPos + length(StartMarker);
    if not CutEndMarker then
     EndPos := EndPos + length(EndMarker);
    Value := copy(PageStr, StartPos, EndPos-Startpos);
    Delete(PageStr, 1, EndPos);
   end;
  result := Value;
end;

// -----------------------
// ANALYZE MOVIE DATA PAGE
// IN:  none
// OUT: set Ant fields
// -----------------------
procedure AnalyzeMoviePage;
var
  i, h, m: integer;
  Duration, Description, Cast, TempTrackNo, OrigTit, TempStr, TempImg, hh, mm: string;
begin
  // Get packed title main page
  PageStr := RemoveExtraChars(MovieUrl);

  SetField(fieldDirector, getValue(cStartDirector, cEndDirector, true, true)); // BAND (Director)
  SetField(fieldTranslatedTitle, getValue(cStartTranslTitle, cEndTranslTitle, true, true));  // ALBUM (Translated Title)
  SetField(fieldProducer, getValue(cStartProd, cEndProd, true, true));  // LABEL (Producer)
  SetField(fieldYear, getValue(cStartYear, cEndYear, true, true));  // YEAR (Year)
OrigTit := GetField(fieldDirector) + ' - ' + GetField(fieldTranslatedTitle);
SetField(fieldOriginalTitle, OrigTit);
  // TRACKS (Description)
  Cast := '';
  repeat
  TempTrackNo := getValue(cStartTrack, cEndTrack, true, true);
  TempStr := getValue(cStartCast, cEndCast, true, true);
  if ((Cast<>'') and (TempStr<>'')) then
  Cast := Cast + #13#10;
  Cast := Cast + TempTrackNo + ' ' + TempStr;
  until((TempStr='')or(Length(TempStr)>40));
  SetField(fieldDescription, Cast);
 
  SetField(fieldURL, MovieUrl); //Album Web Page
end;

// ------------------------------------------------------------------
// FILL PICKTREE CONTROL WITH LINKS & TITLES or RETURN ONE PAGE LINK
// if flag true return Film Id else populate PickTree
// IN:  OneFilm flag (bool)
// OUT: one page ID  (string)
// ------------------------------------------------------------------
function PopulatePickTree(OneFilm: boolean): string;
var
  TempIdFilm: string;
  TempTitle: string;
  StartPos: integer;
  EndPos: integer;
begin
  if OneFilm then
   begin
    StartPos := pos(cStartId, PageStr);
    EndPos := pos(cEndId, PageStr);
    StartPos := StartPos + Length(cStartId);
    TempIdFilm := copy(PageStr, StartPos, EndPos-Startpos); // Get ID
    result := UrlBase + TempIdFilm + '.html';
   end
  else
   begin
    PickTreeClear;
    repeat
     StartPos := pos(cStartId, PageStr);
     EndPos := pos(cEndId, PageStr);
     if StartPos > 0 then
      begin
       StartPos := StartPos + Length(cStartId);
       TempIdFilm := copy(PageStr, StartPos, EndPos-Startpos);  // Get ID
       Delete(PageStr, 1, EndPos);
       StartPos := pos(cStartTitle, PageStr);
       EndPos := pos(cEndTitle, PageStr);
       StartPos := StartPos + Length(cStartTitle);
       TempTitle := copy(PageStr, StartPos, EndPos-Startpos); // Get Title
       PickTreeAdd(TempTitle, UrlBase + TempIdFilm + '.html');
      end;
    until(StartPos = 0);
    result := '';
   end
end;

// ---------------------------------
// ANALYZE FIRST SEARCH RESULT PAGE:
// IN:  page Url (string)
// OUT: none
// ---------------------------------
procedure AnalyzeSearchPage(Url: string);
var
  FilmId: string;
begin
  PageStr := RemoveExtraChars(Url);
  if pos('We were unable', PageStr) > 0 then ShowMessage('Title not found / Nessun film trovato.')
  else 
    if pos('Si è verificato un errore',PageStr) > 0 then ShowMessage('Server not available, try later / Server non disponibile, prova più tardi')
    else
      begin
       if pos('Displaying Disc', PageStr) > 0 then
       begin
       PopulatePickTree(false);           
       if not PickTreeExec(MovieUrl) then
       exit;
      end;
    AnalyzeMoviePage;
   end;
end;

// ----------
// MAIN:
// IN:  none
// OUT: none
// ----------
begin
  if CheckVersion(3,5,0) then
   begin
    TranslatedStr := GetField(fieldOriginalTitle);
    OriginalStr := GetField(fieldTranslatedTitle);
    if (TranslatedStr <> '') then MovieName := TranslatedStr else MovieName := OriginalStr;
    if (Input('Gracenote''s CDDB - By ABN+Pivello', 'Enter the title of the movie / Inserire titolo del film:', MovieName)) then
     begin
      Page := TStringList.Create;
      MovieUrl := QueryBase + UrlEncode(MovieName);
      AnalyzeSearchPage(MovieUrl);
      Page.Free;
     end;
   end
  else
   ShowMessage('This script requires a newer version of Ant Movie Catalog (at least the version 3.5.0)');
end. 
For images i'm trying to learn how to create a script.
In 2nd moment i'll try to understand how to mix this script with the other one.
I hope for now my script will be btw usefull for you

ciao
ABN

Posted: 2005-02-11 19:03:20
by -xD-
senx
and can you make a script to remake all my base data like this
orig title = artist - album

from base (not go in internet)
take data from

director -> artist
producer -> album


and 2.
this script dont take data of track list 4 some albums
but on site its all ok
script or dont get data or get but not full (take 1 - 6 track from 18)

Posted: 2005-02-11 19:08:54
by -xD-
and i store all data in base like this

Source - Lable
Original Title - Atrist - Albim
Director - Artist
Prodicer - Album
Actors - Track List
Year - Year
Discription - Review

Posted: 2005-02-11 22:44:46
by ABNormal
-xD- wrote: this script dont take data of track list 4 some albums
but on site its all ok
script or dont get data or get but not full (take 1 - 6 track from 18)
nice thing. :)
may you give me a list of these albums (i'll try to understand what happens)? thx
senx
and can you make a script to remake all my base data like this
orig title = artist - album
Source - Lable
Original Title - Atrist - Albim
Director - Artist
Prodicer - Album
Actors - Track List
Year - Year
Discription - Review
mmmm dont know.. i think should be easy.... where easy is a term for who knows what it's doing... i hope for me too.
i'll try a script tomorrow (maybe) not now... too drunk and it's too late :)

btw if you prefear to keep your actual settings (label in source.....) you could easily change destination fields in my source (change: fieldCast where, in my script, now is written fieldDescription so you'll keep description for reviews .......)

ciao

Posted: 2006-04-19 11:19:13
by pollewops
is this script still valid...
Is it possible to query time/length of the tracks as well and display them in the program ?

Posted: 2006-04-26 21:52:47
by ocean1909
Thanks for the script ! I was looking for something like this for long time.
However, I have a weird thing that I don't know if I should address this to the creator of the script or to the author of AMC. The file does not display in the script list. I named it CDDB_Gracenote.ifs and put it to Script folder, but it seems to be invisible in the list. Each time I add an Audio CD, I have to load the file and run it. The script works great but this problem bothers me somehow.
Thanks again !

Posted: 2006-04-27 12:49:24
by pollewops
I have the same problem.
I thought it was just me that have that problem....thus not !

Posted: 2006-04-27 15:12:26
by antp
Are you sure that there is not an hidden extra extension after it ?
e.g. it would be .ifs.txt but if extensions are hidden by Windows you may only see .ifs

Posted: 2006-04-27 15:42:42
by ocean1909
I'm sure of it because I always leave visible file extension. The file is visible as .ifs in the Script folder with the others but it's not displayed in the script list of the AMC. Weird !

Posted: 2006-04-27 18:39:03
by pollewops
Hummm...i think i was looking wrong.
The script is normal visible :-)

Sorry.

Posted: 2006-04-28 12:36:57
by ocean1909
You might be but I don't think I am. because it's not the 1st time it happened to me, then it appeared again. That's why I call it 'weird'.