It can be used in 2 ways:
- Batch mode: in URL field you must supply album/CD page information link (i.e. http://www.allmusic.com/album/hanno-ucc ... 0002386981) (mode=1)
- Normal mode: supply only Album/CD title. (mode=0)
Code: Select all
(***************************************************
Ant Movie Catalog importation script
www.antp.be/software/moviecatalog/
[Infos]
Authors=Fulvio53s03
Title=AllMusic
Description=import album
Site=http://www.allmusic.com
Language=IT, EN
Version=2.1
Requires=3.5.0
Comments=this script is based on the script AllGame from Scorpion7552.
License=* The source code of the script can be used in |* another program only if full credits to |* script
GetInfo=1
RequiresMovies=1
[Options]
Mode=0|0|0=normal mode|1=batch mode (url)
[Parameters]
***************************************************)
// TypeSearch=1|1|1=search for exact expression|2=search for any word
// TypeOrder=3|3|1=order by Artist|2=order by Album Title|3=order by relevance
// needs the following units
// StringUtils7552.pas
//
program AllMusic;
uses
StringUtils7552;
const
AllMusicUrl = 'http://www.allmusic.com'; // base url
AllAlbumUrl = 'http://www.allmusic.com'; // base url
batchlogfic = 'c:\amc_Album_searchlog.txt'; // log for batch mode
debug = false; // debug mode on/off
debugrep = 'c:\'; // directory where to save files
CRLF3 = CRLF + ' ' + CRLF + ' ' + CRLF;
CRLF2 = CRLF + ' ';
CRLFCRLF = CRLF + CRLF;
// CRLF_blank = CRLF + ' ';
var
Credit_address, Readdress, Page: String;
AlbumName, firstcall, abort, name, Dati_traccia, autori: String;
Releases: String;
Commento, save_value, indirizzo_pagina, ordine_lista, Salva_autore: String;
value, sw_serie, StartDelimiter, endDelimiter : string;
CharNormal, CharAbNormal: string;
Album_ok: boolean;
BatchMode, index: Integer;
len_dopo, len_prima, num_char, num_linee, lungo, lgth_Pag_ricerca: Integer;
CharCut, NumChar: integer;
min_albName, min_alb, dopo, prima, brani, Track, newtrack, old_track, datitrack: String;
titolo_e_autore, titolo, autore: String;
batchlog, confbatch, memo: TstringList;
pag_ricerca, save_pag, dati_album, artist, initchar, endchar: string;
sw_giri, year: string;
albumok: boolean;
contatore: integer;
//------------------------------------------------------------------------------
// list of albums
//------------------------------------------------------------------------------
procedure GetList;
var
Address, Line, urlmusic, album, albumtest, label, genre: String;
Save_address, Title_album, indir_album: String;
Editore: string;
Relevance: String;
ctr_loop, ValRelev: integer;
found: boolean;
i, lgth_dati_album: integer;
begin
PickTreeClear; // clear list
indirizzo_pagina := AllMusicUrl+'/search/';
Address := AllMusicUrl + '/search/album/' + UrlEncode(AlbumName) + ordine_lista; //fs
Page := GetPage(Address);
Save_address := Address;
SetField(fieldURL, Address);
found := False;
PickTreeAdd('List of albums found for' + '"' + AlbumName + '"', '');
if debug then
DumpPage(debugrep+'AllMusicList.txt', Page); // debug
if Pos('album search results for', Page) = 0 then
begin
LogMessage('Error while reading selection page - no results found');
exit;
end;
initchar := '<ul class="search-results">';
endchar := '</ul>';
pag_ricerca := initchar + TextBetween(Page, '<ul class="search-results">', '</ul>') + endchar; //elenco titoli richiesti
Normalizza_Page(pag_ricerca);
save_pag := pag_ricerca;
if debug then
DumpPage(debugrep+'AllMusicSavePag.txt', save_pag); // debug
initchar := '<h4>Album</h4>';
endchar := '<h4>Album</h4>';
dati_album := TextBetween (pag_ricerca, initchar, endchar) + endchar; //dati_album contiene recursivamente i dati degli album
if debug then
DumpPage(debugrep+'AllMusicAlbum.txt', dati_album); // debug
delete(Pag_ricerca, 1, length(dati_album) - length(initchar));
ctr_loop := 0;
lungo := (Length(initchar) + length(endchar));
lgth_dati_album := length(Dati_album);
while (Length(Dati_Album) > Lungo) and (ctr_loop < 20) do //estraggo al massimo 20 titoli
begin
ctr_loop := ctr_loop + 1;
initchar := '<div class="title">';
endchar := '</div>';
indir_album := textBetween(dati_album, initchar, endchar);
initchar := '<a href="http://';
endchar := '"';
Address := textBetween(indir_album,initchar, endchar); //indirizzo album
initchar := '>';
endchar := '</a>';
Title_album := textBetween(indir_album,initchar, endchar); //titolo dell'album //Fs fino qui $$$$$$$$$$$$$$$$$$$$
initchar := '<div class="artist">';
endchar := '</div>';
artist := textbetween(dati_album, initchar, endchar);
artist := textbetween(artist, '>', '<');
initchar := '<div class="year">';
endchar := '</div>';
year := textbetween(Dati_album, initchar, endchar);
year := fulltrim(year);
Title_Album := Title_Album + ' (' + artist + ', ' + year + ')';
Address := 'http://' + Address;
PickTreeAdd(Title_Album, Address);
found := True;
initchar := '<h4>Album</h4>';
endchar := '<h4>Album</h4>';
dati_album := TextBetween (pag_ricerca, initchar, endchar) + endchar; //dati_album contiene recursivamente i dati degli album
lgth_dati_album := length(Dati_album);
delete(Pag_ricerca, 1, lgth_dati_album);
end;
if not found then
begin
LogMessage('No album found for '+AlbumName);
exit;
end;
if PickTreeExec(Address) then
begin
AnalyzeMusicPage(Address); // Album page
end
else
LogMessage('No album selected');
end;
//------------------------------------------------------------------------------
// ANALYZE MUSIC PAGE
//------------------------------------------------------------------------------
procedure AnalyzeMusicPage(Address: string);
var
Line, urlmusic, cover, Lenght, Pays: String;
Autore, Commenti, str_min: String;
minu, minuti, ore, lgth_comm, save_lgth_comm: integer;
i: Integer;
j: Real;
begin
Page := GetPage(Address);
Page := UTF8decode(Page);
// if debug then
// DumpPage(debugrep+'AllMusicPageDetail.txt', Page); // debug
Readdress := '';
Readdress := textbetween(Page, '<meta property="og:url" content="', '">');
if length(Readdress) > 0 then
Address := Readdress;
if Pos('class="album-artist"', Page) = 0 then
Begin
LogMessage('Error while reading album page');
exit;
end;
SetField(fieldURL, Address);
SetField(fieldDate, DateToStr(Date));
Normalizza_Page(Page);
albumok := True;
if debug then
DumpPage(debugrep+'AllMusicPageDetail.txt', Page); // debug
//titolo tradotto
Value := TextBetween(Page, '<h2 class="album-title" itemprop="name">', '</h2>');
SetField(fieldTranslatedTitle, FormatText(Value));
//Allmusic Rating
Value := TextBetween(Page, 'itemprop="ratingValue">', '<');
SetField(fieldRating, FormatText(Value));
//*** artist url
urlmusic := 'href="/cg/amg.dll'; // url to search (first occurence)
Value := TextBetween(Page, '<span class="title">', 'class="subtitle');
//*** artist name (=OriginalTitle)
Value := TextBetween(Page, '<h4>', '</h4>');
Value := TextBetween(Value, 'title="', ' Discography');
SetField(fieldDirector, FormatText(Value));
SetField(fieldOriginalTitle, FormatText(Value));
Salva_autore :=FormatText(Value);
//*** release date (year only) ('month year' 'month day, year' or 'year')
Value := TextBetween(Page, '<div class="release-date">', '</div>');
value := textbetween(Value, '<span>', '</span>');
Value := FormatText(Value);
i := LastPos(' ', Value); // extract year only
if i > 0 then Value := Copy(Value, i+1, length(Value));
SetField(fieldYear, Value);
//*** duration
Value := TextBetween(Page, ' <div class="duration">', '</div>');
value := textbetween (Value, '<span>', '</span>');
// setfield(fieldlength, value);
ore := strtoint(TextBefore (Value, ':', ''), 0);
str_min := TextBetween (Value, ':', ':');
minuti := strtoint(str_min, 0);
if minuti > 0 then
Minu := ore*60 + Minuti;
if minuti = 0 then
Minu := ore;
str_min := inttostr(Minu);
SetField(fieldLength, str_Min);
//*** genre (= category)
if debug then
DumpPage(debugrep+'AllMusicPage.txt', Page); // debug
Value := TextBetween(Page, '<div class="genre">', '<div class="styles">');
Value := TextBetween(Value, '<div>', '</div>');
SetField(fieldCategory, FormatText(Value));
//*** cover
cover := TextBetween(Page, '<div class="album-cover">', '</div>');
cover := TextBetween(cover, '<img src="', '"');
if CanSetPicture then
GetPicture(cover);
//*** label
Value := FormatText(TextBetween(Page, '<h3>Label</h3>', '</p>'));
if Value = '' then
SetField(fieldProducer, 'No label');
if Value <> '' then
SetField(fieldProducer, Value);
//*** album review (= comments)
initchar := '<section class="review read-more"';
endchar := '</section>';
Value := TextBetween(Page, initchar, endchar);
Value := initchar + Value + endchar;
HTMLRemovetags(Value);
Value := stringreplace (Value, ('Review' + CRLF), 'Review ');
Value := FormatText(Value);
if Value = '' then
Commenti := '--- No Review Available ---'
else
Commenti := Value;
// GetReleases;
Value := TextBetween(Page, '<div id="releases">', '</div>');
// GetReleases; //fs2015.01.03
Commenti := UTF8decode(Commenti) + CRLF + UTF8decode(Releases);
lgth_comm := length(commenti);
save_lgth_comm := length(commenti);
repeat
save_lgth_comm := lgth_comm;
commenti := StringReplace(commenti, CRLF2, CRLF);
commenti := StringReplace(commenti, CRLFCRLF, CRLF);
lgth_comm := length(commenti);
until save_lgth_comm = lgth_comm;
Commenti := stringreplace(Commenti, '.', '. ');
Setfield(FieldComments, commenti);
Value := Page;
pag_ricerca := TextBetween(Value, ' <section class="track-listing">', '</section'); //fs 2015.01.02
Value := TextBetween(Value, '<tbody>', '</tbody>');
delete(Page, 1, length(Value));
brani := '';
estrazione_tracce;
HTMLRemoveTags(brani);
SetField(fieldDescription, brani);
Credit_address := Address + '/credits';
AnalyzeCreditsPage;
end;
procedure GetReleases;
var
Dato_Release: String;
begin
CharAbNormal := '<td class="cell">'; //elimino i dati inutili
CharNormal := '';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '</td>';
CharNormal := ' ';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := CRLF;
CharNormal := '';
Value := StringReplace(Value, CharAbNormal, CharNormal);
StartDelimiter := '<tr class="visible">'; //mi posiziono su inizio dati significativi
EndDelimiter := '</tr>';
lungo := length(textbefore(Value, StartDelimiter, ''));
delete(Value, 1, lungo);
Lungo := (Length(StartDelimiter) + length(EndDelimiter));
Dato_release := StartDelimiter + TextBetween(Value, StartDelimiter, EndDelimiter) + EndDelimiter;
delete(Value, 1, length(Dato_release));
Dato_release := Trim(TextBetween(Value, StartDelimiter, EndDelimiter));
Releases := '--- Releases ---' + CRLF + Dato_release;
while Length(Dato_Release) > Lungo do
begin
Dato_release := StartDelimiter + TextBetween(Value, StartDelimiter, EndDelimiter) + EndDelimiter;
delete(Value, 1, length(Dato_release));
// Dato_release := FormatText(Dato_release);
Dato_release := Trim(TextBetween(Value, StartDelimiter, EndDelimiter));
Releases := Releases + CRLF + Dato_release;
end;
end;
//
Procedure estrazione_tracce;
Begin
//fs 2015.01.02 pag_ricerca := value;
if debug then
DumpPage(debugrep+'AllMusicList_pag_ricerca.txt', pag_ricerca); // debug
initchar := '<tr class="track';
endchar := '<tr class="track';
lungo := (Length(initchar) + length(endchar));
Dati_traccia := initchar + TextBetween(Pag_ricerca, initchar, endchar) + endchar;
delete(Pag_ricerca, 1, length(Dati_traccia));
while Length(Dati_traccia) > Lungo do //esegui se trovato qualcosa
begin
datitrack := '';
track := '';
initchar := '<td class="tracknum">';
endchar := '</td>';
track := textbetween(dati_traccia, initchar, endchar); //n.d'ordine
track := StringReplace(track, CRLF, '');
track := Fulltrim(track);
// datitrack := datitrack + track;
if length(track) > 0 then
brani := brani + track + ' ';
delete(Dati_traccia, 1, (pos(Initchar, dati_traccia) + length(track) + length(initchar) + length(endchar)));
initchar := '<td class="title-composer">';
endchar := '</td>';
track := textbetween(dati_traccia, initchar, endchar); //titolo brano e compositore
titolo := Textbetween(track, 'itemprop="url">', '</a>'); //fs20141115 titolo
autore := Textbetween(track, '<div class="composer">', '</a>'); //fs20141115
autore := FormatText(autore); //fs20141115
if length(autore) = 0 then
begin
initchar := '<span itemprop="name">';
endchar := '</a>';
track := Textbetween(dati_traccia, '<span itemprop="name">', '</a>'); //fs20141115
autore := FormatText(track); //fs20141115
end
titolo_e_autore := titolo + ' (' + autore + ')'; //fs20141115 titolo + autore
datitrack := datitrack + ' ' + titolo_e_autore; //fs20141115
if datitrack = old_track then
datitrack := ''
else
datitrack := datitrack + CRLF;
old_track := datitrack;
datitrack := StringReplace(datitrack, CRLF2, ' '); //fs 2012.10.28
//fs2015-01-03
index := length(datitrack);
//fs2015-01-03 while index < 42 do
while index < 0 do //fs2015-01-03
begin
datitrack := datitrack + ' ';
index := index +1;
end;
datitrack := fulltrim(datitrack);
if length(datitrack) > 3 then
brani := brani + datitrack + CRLF; //fs 2014.11.15
// reimposto l'area su cui loopare
initchar := '<tr';
endchar := '</tr>';
lungo := (Length(initchar) + length(endchar));
dati_traccia := initchar + TextBetween (pag_ricerca, initchar, endchar) + endchar; //dati_album contiene i dati dell'album
delete(Pag_ricerca, 1, length(Dati_traccia));
lgth_Pag_ricerca := length(Pag_ricerca); //fs 2012.03.25 debug
lgth_Pag_ricerca := length(Pag_ricerca); //fs 2012.03.25 debug
end;
end;
//fs ********************* fine nuova estrazione tracce *****************************************
//------------------------------------------------------------------------------
// ANALYZE Credits PAGE
//------------------------------------------------------------------------------
procedure AnalyzeCreditsPage;
var
Line, urlmusic, cover, Lenght: String;
i: Integer;
j: Real;
begin
Page := GetPage(Credit_address);
Page := UTF8decode(Page);
Normalizza_Page(Page);
NumChar := length(Page);
if debug then
DumpPage(debugrep+'AllMusicCreditDetail.txt', Page); // debug
if Pos('Credits', Page) = 0 then // may be this test is OK?
Begin
LogMessage('Error while reading credits page');
exit;
end;
albumok := True;
// ***************************** estrae i credits ***********************************************
Value := TextBetween(Page, '<section class="credits">', '</section>');
NumChar := length(Value);
Getcredits;
// ************************ fine estrae i credits (copiato dalle tracce) ************************
Save_value := '"' + Salva_autore + '":' + CRLF + Save_Value;
// Save_value := UTF8Decode(Save_value); //fs 2012.03.24
Save_value := RemoveHTML(Save_value);
SetField(fieldActors, Save_value);
end;
procedure GetCredits;
Begin
Save_Value := '';
Commento := '* ';
if debug then
DumpPage(debugrep+'AllMusicCreditDetailExtract.txt', Value); // debug
While Commento <> '' do
begin
StartDelimiter := '<a href="http://www.allmusic.com/';
CharCut := Pos(StartDelimiter, Value);
EndDelimiter := '</a>';
Commento := TextBetween(Value, StartDelimiter, EndDelimiter); // estrae nome
Commento := TextAfter(Commento, '>');
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Value, 1, CharCut);
Save_Value := Save_value + commento;
if commento <> '' then
Save_Value := Save_value + ': ';
StartDelimiter := '<td class="credit"';
CharCut := Pos(StartDelimiter, Value);
EndDelimiter := '</td>';
Commento := StartDelimiter + TextBetween(Value, StartDelimiter, EndDelimiter); // estrae strumento
CharCut := CharCut + length(Commento) + length(EndDelimiter);
delete(Value, 1, CharCut);
Commento := stringreplace(Commento, CRLF, '');
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
if commento <> '' then
//fs 2012.03.23 Save_Value := Save_value + commento + ';' + crlf;
Save_Value := Save_value + commento + ';' + ' - '; //fs 2012.03.23
end;
Save_value := copy(Save_value, 1, length(Save_value) - 6); // tolgo ultimo separatore
end;
Procedure Normalizza_page(Pagina: string); // elimina i crlf, trasforma delimiters maiuscoli in minuscoli
begin
CharAbNormal := crlf;
CharNormal := ' ';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '<B';
CharNormal := '<b';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '</B';
CharNormal := '</b';
pagina := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '<FONT';
CharNormal := '<font';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '</FONT';
CharNormal := '</font';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '<TR';
CharNormal := '<tr';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '</TR';
CharNormal := '</tr';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '<TD';
CharNormal := '<td';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '</TD';
CharNormal := '</td';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '<DIV';
CharNormal := '<div';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
CharAbNormal := '</DIV';
CharNormal := '</div';
pagina := StringReplace(pagina, CharAbNormal, CharNormal);
end;
//------------------------------------------------------------------------------
// set show warning (normal mode) or add to log (batch mode)
//------------------------------------------------------------------------------
procedure LogMessage(m: string);
begin
if BatchMode > 0 then
AddToLog('item '+GetField(fieldNumber)+': '+m)
else
ShowWarning(m);
end;
//------------------------------------------------------------------------------
// add a message in the batch log and save to disk
// (because I don't know when it's finished...)
//------------------------------------------------------------------------------
procedure AddToLog(m: string);
begin
batchlog.Add(m);
batchlog.SaveToFile(batchlogfic);
end;
//------------------------------------------------------------------------------
// process batch mode
//------------------------------------------------------------------------------
procedure AllMusicBatch;
begin
AlbumName := GetField(fieldUrl); // if no url or another site then ignore
if (AlbumName <> '') and (Pos(AllAlbumUrl, AlbumName) > 0) then
AnalyzeMusicPage(AlbumName)
else
LogMessage('ignored url="'+AlbumName+'"');
end;
//------------------------------------------------------------------------------
// process normal mode
//------------------------------------------------------------------------------
procedure AllMusicNorm;
begin
albumok := False;
AlbumName := GetField(fieldTranslatedTitle); // get album name
value := getField(fieldTranslatedTitle);
repeat
if not Input('AllMusic - ' + Value, 'Enter the name of the album :' + crlf, AlbumName) or (AlbumName = '') then exit;
GetList;
until albumok;
end;
//------------------------------------------------------------------------------
// start here
//------------------------------------------------------------------------------
begin
if abort = 'o' then exit; // batch mode aborted
if firstcall <> 'done' then
begin // 1st call: init parameters
firstcall := 'done';
if not CheckVersion(3,5,0) then
begin
ShowMessage('This script requires a newer version of Ant Movie Catalog (at least the version 3.5.0)');
abort := 'o';
exit;
end;
// get user's parms (used more than once)
BatchMode := GetOption('Mode');
if BatchMode > 0 then // batch mode: confirm the choice
begin
batchlog := TStringList.Create; // init batch log
batchlog.Add('starting batch mode');
batchlog.Add(StringOfChar('*',80));
batchlog.SaveToFile(batchlogfic);
// confirmation message
confbatch := TStringList.Create;
confbatch.Add('You have selected the batch mode:');
confbatch.Add('Did you save your database?');
confbatch.Add('*** Address to extract must be supplied in Field Url ***');
confbatch.Add('');
confbatch.Add('At the end of treatement:');
confbatch.Add('- look at the file ' + batchlogfic + ' for errors/infos');
confbatch.Add('- the albums found will be checked, the others not (for the selection)');
confbatch.Add(' (see: Tools/Preferences/Movie list/checkboxes)');
confbatch.Add('');
confbatch.Add('confirm your choice');
if not ShowWarning(confbatch.Text) then
begin
AddToLog('batch mode aborted'); // batch mode not confirmed = abort
abort := 'o';
exit;
end;
end;
end;
// let's go
if BatchMode = 0 then
AllMusicNorm
else
AllMusicBatch;
end.