Sometimes I happen not to be able to extract informations about an album from allmusic.com.
Maybe the name I wrote is wrong (too much or too few spaces, strange symbols in the name etc) but using discography I see that the abum exists, what can I do?
My first answer is to write a script that extracts informations from the specified page.
Simply write the URL in related field of my AMC catalog and use the script that follows:
Code: Select all
(***************************************************
Ant Movie Catalog importation script
www.antp.be/software/moviecatalog/
[Infos]
Authors=Fulvio53s03 - based on Frenchfrog2 and sracer works
Title=AllMusic IT extract from URL
Description=import data from a specified URL
Site=http://www.allmusic.com
Language=IT
Version=1.0
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
[Options]
AlbumOpt=2|2|1=search for artist|2=search for album|3=search for song
TypeSearch=1|1|1=search for exact expression|2=search for any word
Mode=0|0|0=normal mode|1=batch mode (url)
***************************************************)
// needs the following units
// StringUtils1.pas, StringUtils7552.pas
//
program AllMusic;
uses
StringUtils7552;
const
AllMusicUrl = 'http://www.allmusic.com'; // base url
batchlogfic = 'c:\amc_AllGame_batchlog.txt'; // log for batch mode
debug = false; // debug mode on/off
debugrep = 'd:\data\disk1\temp'; // directory where to save files
var
Credit_address: String;
AlbumName, dfltAlbumc, firstcall, abort, name: String;
Releases, Commento, save_value, indirizzo_pagina, valore_ricerca: String;
value, sw_serie, StartDelimiter, endDelimiter : string;
CharNormal, CharAbNormal: string;
BatchMode, dfltAlbum, Tipo_Ricerca: Integer;
len_dopo, len_prima, num_char: Integer;
CharCut, NumChar: integer;
min_albName, min_alb, dopo, prima: String;
batchlog, confbatch, memo: TstringList;
albumok: boolean;
//------------------------------------------------------------------------------
// list of albums or artist
//------------------------------------------------------------------------------
procedure GetList;
var
Address, Table, Line, Page, urlmusic, year, album, albumtest, label, genre, Linet: String;
Relevance: String;
ValRelev: integer;
found: boolean;
i: integer;
begin
Address := AlbumName;
Credit_address := Address + '~t2'; // credits page
AnalyzeMusicPage(Address); // Album page
AnalyzeCreditsPage;
end;
//------------------------------------------------------------------------------
// ANALYZE MUSIC PAGE
//------------------------------------------------------------------------------
procedure AnalyzeMusicPage(Address: string);
var
Page, Line, Linet, urlmusic, artisturl, cover, Track, Lenght, Minu, Seco, Pays, usastates: String;
Autore: String;
i, TMinu, TSeco: Integer;
j: Real;
begin
Page := GetPage(Address);
if debug then
DumpPage(debugrep+'AllMusicPageDetail.txt', Page); // debug
if Pos('Artist', Page) = 0 then // may be this test is OK?
Begin
LogMessage('Error while reading album page');
exit;
end;
SetField(fieldURL, Address);
SetField(fieldDate, DateToStr(Date));
albumok := True;
//*** artist url
urlmusic := 'href="/cg/amg.dll'; // url to search (first occurence)
Value := TextBetween(Page, '<span class="title">', 'class="subtitle');
artisturl := AllMusicUrl+TranslateSpecial(TextBetween(Value, '<a href="', ' "'));
//*** artist name (=TranslatedTitle)
//*** artist name (=Director) - sracer
Value := TextBetween(Page, 'class="subtitle">', '</a>');
SetField(fieldOriginalTitle, FormatText(Value));
//*** album title (=originalTitle)
Value := TextBetween(Page, '<span class="title">', '</span>');
SetField(fieldTranslatedTitle, FormatText(Value));
//*** rating (<img src="/img/stars/st_rX.gif" with X = rating: 1=1 star to 9=5 stars)
// X=1 (1) x=2 (1.5) ... x=9 (5) ==> rating = (x+1) for 0 to 10
Value := TextBetween(Page, '<img src="/i/pages/site/stars/st_r', '.gif"');
if Value <> '' then
begin
i := StrToInt(Value, 0);
j := (i + 1); // rating from 0 to 10
// uncomment next line if you want a rating from 0 to 5 (by half point)
// j := (i + 1) /2;
SetField(fieldRating, FloatToStr(j));
end;
//*** release date (year only) ('month year' 'month day, year' or 'year')
Value := TextBetween(Page, '<span>Release Date</span>', '</table>');
Value := FormatText(Value);
i := LastPos(' ', Value); // extract year only
if i > 0 then Value := Copy(Value, i+1, length(Value));
SetField(fieldYear, Value);
//*** label (= director)
// Value := TextBetween(Page,'<span>Label</span>', '</table>');
// SetField(fieldDirector, FormatText(Value));
//*** type (= country)
Value := FormatText(TextBetween(Page, '<span>Type</span>', '</table>'));
// if Value = '' then
// SetField(fieldCountry,'Standard');
// if Value <> '' then
// SetField(fieldCountry, Value);
// if Value = 'Explicit Lyrics' then
// SetField(fieldCountry,'Standard');
//*** genre (= category)
Value := TextBetween(Page, '<span>Styles</span>', '</li>');
SetField(fieldCategory, FormatText(Value));
//*** cover
cover := TextBetween(Page, '<!--Begin Album Photo-->', '</table>');
cover := TextBetween(cover, 'img src="', '"');
if CanSetPicture then
GetPicture(cover);
//*** album review (= comments)
Value := FormatText(TextBetween(Page, '<!--Begin Center Content-->', '</table>'));
Value := TextAfter(Value, 'Reviewby');
if Value = '' then
SetField(fieldComments, 'No Review Available');
if Value <> '' then
SetField(fieldComments, 'Review by'+Value);
//*** tracks list (= description)
//*** tracks list (= artist) - sracer
Value := TextBetween(Page, '<!--Begin Center Content-->', '<!--End Center Content-->');
if debug then
DumpPage(debugrep+'AllMusicPagetracks.txt', Value); // debug
Value := TextAfter(Value, '>Time');
Value := TextAfter(Value, '</table>');
Value := TextAfter(Value, '</TD>');
Value := TextAfter(Value, '</TD>');
Value := StringReplace(Value, crlf, ''); // separate lines
memo := TStringList.Create;
memo.Text := StringReplace(Value, '</tr>', crlf); // separate lines
if debug then
begin
Linet := StringReplace(Value, '</tr>', crlf);
DumpPage(debugrep+'AllMusicPageDetailList.txt', Linet); // debug
end;
Value := '';
Minu := '';
Seco := '';
TMinu := 0;
TSeco := 0;
for i := 0 to memo.Count-1 do // list of tracks
begin
Line := memo.GetString(i); // extract current line
Line := TextAfter(Line, '<TD class="cell">');
Line := StringReplace(Line, '</TD>', sepchar1); // separate fields with </TD>
Track := Trim(TextBefore(Line, sepchar1, ''));
if Track <> '' then
begin
Value := Value+Track; // number of track
Line := RemainingText;
// ******************************++ aggiunte qui
Autore := Line;
// Autore := textbetween(Autore, '<td class="cell">', '<td align="right" class="cell">');
Autore := textbetween(Autore, '<TD class="cell">', sepchar1);
HTMLDecode(Autore); // Clean description from HTML codes (if some exist)
HTMLRemoveTags(Autore);
// Value := FullTrim(Autore); // Clean title from HTML tags (if some exist)
Autore := ' (' + Autore + ') ';
// fine aggiunte *********************************
Value := Value+'. '+FormatText(Trim(TextBefore(Line, sepchar1, ''))); // title of track
Line := RemainingText;
Line := TextAfter(Line, sepchar1); // not usefull info
Lenght := FormatText(Trim(TextBefore(Line, sepchar1, ''))); // lenght of track
Minu := Trim(TextBefore(Lenght, ':', ''));
Seco := Trim(TextAfter(Lenght, ':'));
TMinu := TMinu + StrToInt(Minu, 0); // extract the minutes
TSeco := TSeco + StrToInt(Seco, 0); // extract the seconds
if TSeco > 60 then
begin
TMinu := TMinu + 1;
TSeco := TSeco - 60;
end;
Value := Value + autore + ' (' + Lenght + ')';
Value := Value+crlf;
end;
end;
Releases := textBetween(Page, '<tr class="visible">', '</table>');
SetField(fieldDescription, Value);
GetReleases;
Value := Value + crlf + 'Releases:' + crlf + Releases;
SetField(fieldDescription, Value);
//*** length (only show the minutes)
if TSeco > 30 then
TMinu := Tminu + 1;
SetField(fieldLength, IntToStr(TMinu));
//*** media name (= artist - title) default setting
// SetField(fieldMedia, GetField(fieldTranslatedTitle)+' - '+GetField(fieldOriginalTitle));
// SetField(fieldMedia, GetField(fieldDirector)+' - '+GetField(fieldOriginalTitle));
//*** media type (= JewelCase) default setting
//*** media type (= CD) default setting - sracer
SetField(fieldMediaType, 'CD');
//*** audio format (= VideoFormat = CD) default setting
// SetField(fieldVideoFormat, 'CD');
//*** source (= AudioFormat = Achat) default setting
SetField(fieldAudioFormat, 'CD Audio');
//*** number of disks (= VideoBitrate = 1) default setting
// SetField(fieldVideoBitrate, '1');
//*** country of the artist
Page := GetPage(artisturl);
if debug then
DumpPage(debugrep+'AllMusicArtistDetail.txt', Page); // debug
if pos('<!--Begin Formed-->', Page) > 0 then
Value := TextBetween(Page, '<!--Begin Formed-->', '<!--End Formed-->');
if pos('<!--Begin Born-->', Page) > 0 then
Value := TextBetween(Page, '<!--Begin Born-->', '<!--End Born-->');
if debug then
DumpPage(debugrep+'AllMusicArtistDetailshort.txt', Value); // debug
Value := TextAfter(Value, '<a href=');
Value := TextAfter(Value, '<a href=');
Value := TextBetween(Value, '>', '<');
Pays := TextAfter(Value, ', ');
// SetField(fieldSource, Pays);
// SetField(fieldProducer, 'English');
// if Pays = 'France' then SetField(fieldProducer, 'French');
// if Pays = 'Spain' then SetField(fieldProducer, 'Spanish');
// if Pays = 'Italia' then SetField(fieldProducer, 'Italian');
usastates :='WA,MT,ND,MN,WI,MI,YT,NH,ME,NY,RI,MA,CT,NJ,DE,MD,DC,PA,OH,IN,IL,IA,SD,NE,WY,ID,OR,CA,NV,UT,AZ,CO,NM,KS,OK,TX,MO,AR,LA,KY,TN,MS,AL,FL,GA,SC,NC,VA,WV,HI,AK';
// if pos(Pays,usastates) > 0 then
// begin
// SetField(fieldSource, 'United States Of America');
// SetField(fieldProducer, 'English');
// end;
end;
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6
procedure GetReleases;
var
Riga_Commento, trovato: String;
Begin
Save_Value := '';
trovato := 'si';
Riga_Commento := '* ';
StartDelimiter := '<TD';
EndDelimiter := '</TD>';
While trovato = 'si' do
begin
Riga_commento := '';
trovato := 'no';
CharCut := Pos(StartDelimiter, Releases);
Commento := TextBetween(Releases, StartDelimiter, EndDelimiter); // estrae anno
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Releases, 1, CharCut);
Commento := StartDelimiter + Commento;
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
if commento <> '' then
begin
Riga_Commento := commento + ' ';
trovato := 'si';
end
if commento = '' then
begin
Riga_Commento := ' ' + ' ';
end
CharCut := Pos(StartDelimiter, Releases);
Commento := TextBetween(Releases, StartDelimiter, EndDelimiter); // estrae supporto
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Releases, 1, CharCut);
Commento := StartDelimiter + Commento;
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
if commento <> '' then
begin
Riga_Commento := Riga_Commento + commento + ' - ';
trovato := 'si';
end
if commento = '' then
begin
Riga_Commento := Riga_Commento + ' ' + ' - ';
end
CharCut := Pos(StartDelimiter, Releases);
Commento := TextBetween(Releases, StartDelimiter, EndDelimiter); // estrae supporto
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Releases, 1, CharCut);
Commento := StartDelimiter + Commento;
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
if commento <> '' then
begin
Riga_Commento := Riga_Commento + commento + ' ';
trovato := 'si';
end
CharCut := Pos(StartDelimiter, Releases);
Commento := TextBetween(Releases, StartDelimiter, EndDelimiter); // estrae supporto
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Releases, 1, CharCut);
Commento := StartDelimiter + Commento;
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
if commento <> '' then
begin
Riga_Commento := Riga_Commento + commento;
trovato := 'si';
end
If Trovato = 'si' then
Save_value := save_value + Riga_commento + crlf;
end;
Releases := Save_value;
end;
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6
//------------------------------------------------------------------------------
// ANALYZE Credits PAGE
//------------------------------------------------------------------------------
procedure AnalyzeCreditsPage;
var
Page, Line, Linet, urlmusic, artisturl, cover, Track, Lenght: String;
i: Integer;
j: Real;
begin
Page := GetPage(Credit_address);
NumChar := length(Page);
if debug then
DumpPage(debugrep+'AllMusicPageDetail.txt', Page); // debug
if Pos('Credits', Page) = 0 then // may be this test is OK?
Begin
LogMessage('Error while reading credits page');
exit;
end;
// SetField(fieldURL, Credit_address);
albumok := True;
// delete(Page, 1, 11320);
//*** artist url ********************** unuseful?????
// urlmusic := 'href="/cg/amg.dll'; // url to search (first occurence)
// artisturl := AllMusicUrl+TranslateSpecial(TextBetween(Value, '<a href="', ' "'));
// ***************************** estrae i credits (copiato dalle tracce) ***********************************+
// Value := TextBetween(Page, '<div id="tabcontent_2">', '<div id="tabcontent_3">');
Value := TextAfter(Page, '<div id="tabcontent_2">');
NumChar := length(Value);
Value := TextBefore(Value, '<div id="tabcontent_3">', '');
NumChar := length(Value);
Normalizza_Page;
Getcredits;
// ************************ fine estrae i credits (copiato dalle tracce) ***********************************+
SetField(fieldActors, Save_value);
end;
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6
procedure GetCredits;
Begin
Save_Value := '';
Commento := '* ';
While Commento <> '' do
begin
StartDelimiter := '<td class="sorted-cell';
CharCut := Pos(StartDelimiter, Value);
EndDelimiter := '</td>';
Commento := TextBetween(Value, StartDelimiter, EndDelimiter); // estrae nome
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Value, 1, CharCut);
Commento := StartDelimiter + Commento;
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
Save_Value := Save_value + commento;
if commento <> '' then
Save_Value := Save_value + ': ';
StartDelimiter := '<td class="cell">';
CharCut := Pos(StartDelimiter, Value);
EndDelimiter := '</td>';
Commento := TextBetween(Value, StartDelimiter, EndDelimiter); // estrae strumento
CharCut := CharCut + length(StartDelimiter) + length(Commento) + length(EndDelimiter);
delete(Value, 1, CharCut);
HTMLRemoveTags(Commento);
HTMLDecode(Commento);
Commento := trim(Commento);
if commento <> '' then
Save_Value := Save_value + commento + ';' + crlf;
end;
Value := Save_value;
end;
Procedure Normalizza_page; // elimina i crlf, trasforma delimiters maiuscoli in minuscoli
begin
CharAbNormal := crlf;
CharNormal := ' ';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '<B';
CharNormal := '<b';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '</B';
CharNormal := '</b';
Value := StringReplace(Value, CharAbNormal, CharNormal);
// CharAbNormal := ' ';
// CharNormal := ' ';
// Value := StringReplace(Page, CharAbNormal, CharNormal);
CharAbNormal := '<FONT';
CharNormal := '<font';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '</FONT';
CharNormal := '</font';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '<TD';
CharNormal := '<td';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '</TD';
CharNormal := '</td';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '<DIV';
CharNormal := '<div';
Value := StringReplace(Value, CharAbNormal, CharNormal);
CharAbNormal := '</DIV';
CharNormal := '</div';
Value := StringReplace(Value, CharAbNormal, CharNormal);
end;
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//------------------------------------------------------------------------------
// extract 'various infos'
//------------------------------------------------------------------------------
function ExtrInfo(str1, str2: string) :string;
begin
str1 := FormatText(TextBetween(str1, str2, '</table>'));
if str1 <> '' then str1 := crlf+str2+': '+str1;
result := str1;
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(fieldTranslatedTitle); // 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;
if dfltAlbum = 1 then
begin
LogMessage('Sorry this functionality is not operational for now');
// dfltAlbumc := '1';
// AlbumName := GetField(fieldTranslatedTitle); // get artist name
// repeat
// if not Input('AllMusic.com Import', 'Enter the name of the artist :', AlbumName) or (AlbumName = '') then exit;
// GetList;
// until albumok;
end;
if dfltAlbum = 2 then
begin
dfltAlbumc := '2';
AlbumName := GetField(fieldurl); // get album link
repeat
if not Input('AllMusic.com Import', 'Enter the name of the album :', AlbumName) or (AlbumName = '') then exit;
GetList;
until albumok;
end;
if dfltAlbum = 3 then
begin
LogMessage('Sorry this functionality is not operational for now');
// dfltAlbumc := '3';
// AlbumName := GetField(fieldOriginalTitle); // get song name
// repeat
// if not Input('AllMusic.com Import', 'Enter the name of the song :', AlbumName) or (AlbumName = '') then exit;
// GetList;
// until albumok;
end;
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)
dfltAlbum := GetOption('AlbumOpt');
BatchMode := GetOption('Mode');
Tipo_ricerca := GetOption('TypeSearch');
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('Have you saved your database?');
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.