2020-02-02 Fred Gleason <fredg@paravelsystems.com>

* Added a 'MusicBrainz' CD metadata lookup method in 'RDMbLookup'.
This commit is contained in:
Fred Gleason 2020-02-01 10:59:58 -05:00
parent 3993732904
commit 1e207e7e0a
30 changed files with 793 additions and 112 deletions

View File

@ -19457,3 +19457,5 @@
class.
* Added a 'CUTS.TRACK_MBID' field to the database.
* Added a 'CUTS.RELEASE_MBID' field to the database.
2020-02-02 Fred Gleason <fredg@paravelsystems.com>
* Added a 'MusicBrainz' CD metadata lookup method in 'RDMbLookup'.

View File

@ -172,6 +172,7 @@ dist_librd_la_SOURCES = dbversion.h\
rdmarker_button.cpp rdmarker_button.h\
rdmarker_edit.cpp rdmarker_edit.h\
rdmatrix.cpp rdmatrix.h\
rdmblookup.cpp rdmblookup.h\
rdmeteraverage.cpp rdmeteraverage.h\
rdmixer.cpp rdmixer.h\
rdmonitor_config.cpp rdmonitor_config.h\
@ -307,6 +308,7 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\
moc_rdmacro_event.cpp\
moc_rdmarker_bar.cpp\
moc_rdmarker_edit.cpp\
moc_rdmblookup.cpp\
moc_rdmulticaster.cpp\
moc_rdoneshot.cpp\
moc_rdpanel_button.cpp\

View File

@ -124,6 +124,7 @@ SOURCES += rdmacro_event.cpp
SOURCES += rdmarker_button.cpp
SOURCES += rdmarker_edit.cpp
SOURCES += rdmatrix.cpp
SOURCES += rdmblookup.cpp
SOURCES += rdmonitor_config.cpp
SOURCES += rdnotification.cpp
SOURCES += rdoneshot.cpp
@ -261,6 +262,7 @@ HEADERS += rdmacro_event.h
HEADERS += rdmarker_button.h
HEADERS += rdmarker_edit.h
HEADERS += rdmatrix.h
HEADERS += rdmblookup.h
HEADERS += rdmonitor_config.h
HEADERS += rdnotification.h
HEADERS += rdoneshot.h

View File

@ -2408,6 +2408,45 @@ Bitte Kofiguration prüfen und erneut versuchen.</translation>
<translation type="obsolete">Tracker</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -2403,6 +2403,45 @@ Bitte Kofiguration prüfen und erneut versuchen.</translation>
<translation type="obsolete">Tracker</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -2393,6 +2393,45 @@ Do you still want to proceed?</source>
<translation type="obsolete">RDLogManager</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -1935,6 +1935,45 @@ Do you want to overwrite it?</source>
<translation type="obsolete">Panneau</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -2374,6 +2374,45 @@ Sjekk eksportoppsettet ditt og prøv att.</translation>
<translation type="obsolete">Sporleggjar</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -2374,6 +2374,45 @@ Sjekk eksportoppsettet ditt og prøv att.</translation>
<translation type="obsolete">Sporleggjar</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -2408,6 +2408,45 @@ Por Favor, cheque suas configurações e tenbte outra vez.</translation>
<translation type="obsolete">Busca</translation>
</message>
</context>
<context>
<name>RDMbLookup</name>
<message>
<source>Connection Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Result</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastHTTPCode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>LastErrorMessage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Timeout Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Authentication Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fetch Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Request Exception</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDPanelButton</name>
<message>

View File

@ -83,6 +83,7 @@ void RDCddbLookup::readyReadData()
char offset[256];
QStringList f0;
bool ok=false;
int index_line;
while(lookup_socket->canReadLine()) {
line=QString::fromUtf8(lookup_socket->readLine());
@ -100,7 +101,8 @@ void RDCddbLookup::readyReadData()
lookup_state=1;
}
else {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
}
break;
@ -110,25 +112,27 @@ void RDCddbLookup::readyReadData()
lookup_state=2;
}
else {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
}
break;
case 2: // Protocol Level Response
if(code==201) {
snprintf(buffer,2048,"cddb query %08x %d",
cddbRecord()->discId(),cddbRecord()->tracks());
for(int i=0;i<cddbRecord()->tracks();i++) {
snprintf(offset,256," %d",cddbRecord()->trackOffset(i));
discRecord()->discId(),discRecord()->tracks());
for(int i=0;i<discRecord()->tracks();i++) {
snprintf(offset,256," %d",discRecord()->trackOffset(i));
strcat(buffer,offset);
}
snprintf(offset,256," %d",cddbRecord()->discLength()/75);
snprintf(offset,256," %d",discRecord()->discLength()/75);
strcat(buffer,offset);
SendToServer(buffer);
lookup_state=3;
}
else {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
}
break;
@ -137,23 +141,25 @@ void RDCddbLookup::readyReadData()
case 200: // Exact Match
f0=line.split(" ");
if(f0.size()>=4) {
cddbRecord()->setDiscId(f0[2].toUInt(&ok,16));
discRecord()->setDiscId(f0[2].toUInt(&ok,16));
if(!ok) {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Invalid discid received from CDDB server");
}
cddbRecord()->setDiscGenre(f0[1]);
discRecord()->setDiscGenre(f0[1]);
f0.erase(f0.begin());
f0.erase(f0.begin());
f0.erase(f0.begin());
cddbRecord()->setDiscTitle(f0.join(" "));
discRecord()->setDiscTitle(f0.join(" "));
snprintf(buffer,2048,"cddb read %s %08x\n",
(const char *)cddbRecord()->discGenre().utf8(),
cddbRecord()->discId());
(const char *)discRecord()->discGenre().utf8(),
discRecord()->discId());
SendToServer(buffer);
lookup_state=5;
}
else {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
}
break;
@ -164,11 +170,12 @@ void RDCddbLookup::readyReadData()
break;
case 211: // Inexact Match
FinishCddbLookup(RDCddbLookup::PartialMatch);
FinishCddbLookup(RDCddbLookup::NoMatch,"OK");
break;
default:
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
break;
}
break;
@ -176,32 +183,33 @@ void RDCddbLookup::readyReadData()
case 4: // Process Multiple Matches
if(line.trimmed()==".") {
profile("Match list complete, showing chooser dialog...");
if(exec()) {
f0=titlesKey()->at(titlesBox()->currentItem()).
split(" ",QString::SkipEmptyParts);
if((index_line=exec())>=0) {
f0=titlesKey()->at(index_line).split(" ",QString::SkipEmptyParts);
if(f0.size()!=2) {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
}
cddbRecord()->setDiscId(f0.at(1).toUInt(&ok,16));
discRecord()->setDiscId(f0.at(1).toUInt(&ok,16));
if(!ok) {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Invalid discid received from CDDB server");
}
cddbRecord()->setDiscGenre(f0.at(0));
discRecord()->setDiscGenre(f0.at(0));
f0=titlesBox()->currentText().split("/");
if(f0.size()==2) {
cddbRecord()->setDiscTitle(f0.at(1).trimmed());
discRecord()->setDiscTitle(f0.at(1).trimmed());
}
else {
cddbRecord()->setDiscTitle(titlesBox()->currentText().trimmed());
discRecord()->setDiscTitle(titlesBox()->currentText().trimmed());
}
snprintf(buffer,2048,"cddb read %s %08x\n",
(const char *)cddbRecord()->discGenre().utf8(),
cddbRecord()->discId());
(const char *)discRecord()->discGenre().utf8(),
discRecord()->discId());
SendToServer(buffer);
lookup_state=5;
}
else {
FinishCddbLookup(RDCddbLookup::NoMatch);
FinishCddbLookup(RDCddbLookup::NoMatch,"OK");
}
}
else {
@ -220,37 +228,38 @@ void RDCddbLookup::readyReadData()
lookup_state=6;
}
else {
FinishCddbLookup(RDCddbLookup::ProtocolError);
FinishCddbLookup(RDCddbLookup::LookupError,
"Unexpected response from CDDB server");
}
break;
case 6: // Record Lines
if(line[0]!='#') { // Ignore Comments
if(line[0]=='.') { // Done
FinishCddbLookup(RDCddbLookup::ExactMatch);
FinishCddbLookup(RDCddbLookup::ExactMatch,"OK");
}
ParsePair(&line,&tag,&value,&index);
if(tag=="DTITLE") {
cddbRecord()->setDiscTitle(value.left(value.length()-1));
discRecord()->setDiscTitle(value.left(value.length()-1));
}
if(tag=="DYEAR") {
cddbRecord()->setDiscYear(value.toUInt());
discRecord()->setDiscYear(value.toUInt());
}
if(tag=="EXTD") {
cddbRecord()->
setDiscExtended(cddbRecord()->discExtended()+
discRecord()->
setDiscExtended(discRecord()->discExtended()+
DecodeString(value));
}
if(tag=="PLAYORDER") {
cddbRecord()->setDiscPlayOrder(value);
discRecord()->setDiscPlayOrder(value);
}
if((tag=="TTITLE")&&(index!=-1)) {
cddbRecord()->setTrackTitle(index,value.left(value.length()-1));
discRecord()->setTrackTitle(index,value.left(value.length()-1));
}
if((tag=="EXTT")&&(index!=-1)) {
cddbRecord()->
discRecord()->
setTrackExtended(index,
cddbRecord()->trackExtended(index)+value);
discRecord()->trackExtended(index)+value);
}
}
break;
@ -261,30 +270,35 @@ void RDCddbLookup::readyReadData()
void RDCddbLookup::errorData(QAbstractSocket::SocketError err)
{
QString err_msg="Network error";
switch(err) {
case QTcpSocket::ErrConnectionRefused:
printf("CDDB: Connection Refused!\n");
break;
case QTcpSocket::ErrHostNotFound:
printf("CDDB: Host Not Found!\n");
break;
case QTcpSocket::ErrSocketRead:
printf("CDDB: Socket Read Error!\n");
break;
default:
break;
case QTcpSocket::ErrConnectionRefused:
err_msg="Connection to \""+rda->libraryConf()->cddbServer()+"\" refused";
break;
case QTcpSocket::ErrHostNotFound:
err_msg="Host \""+rda->libraryConf()->cddbServer()+"\" not found";
break;
case QTcpSocket::ErrSocketRead:
err_msg="Socket read error";
break;
default:
break;
}
lookup_state=0;
emit done(RDCddbLookup::NetworkError);
emit lookupDone(RDCddbLookup::LookupError,err_msg);
}
void RDCddbLookup::FinishCddbLookup(RDCddbLookup::Result res)
void RDCddbLookup::FinishCddbLookup(RDCddbLookup::Result res,
const QString &err_msg)
{
SendToServer("quit");
lookup_socket->close();
lookup_state=0;
emit lookupDone(res);
emit lookupDone(res,err_msg);
profile("CDDB lookup finished");
}

View File

@ -55,7 +55,7 @@ class RDCddbLookup : public RDDiscLookup
void lookupRecord();
private:
void FinishCddbLookup(RDCddbLookup::Result res);
void FinishCddbLookup(RDCddbLookup::Result res,const QString &err_msg);
QString DecodeString(QString &str);
void ParsePair(QString *line,QString *tag,QString *value,int *index);
int GetIndex(QString *tag);

View File

@ -71,7 +71,7 @@ void RDDiscLookup::setCddbRecord(RDDiscRecord *rec)
void RDDiscLookup::lookup()
{
if(cddbRecord()->tracks()==0) {
if(discRecord()->tracks()==0) {
return;
}
@ -98,16 +98,16 @@ void RDDiscLookup::lookup()
return;
}
}
cddbRecord()->setDiscId(QString(discid_get_freedb_id(disc)).toUInt(NULL,16));
cddbRecord()->setMbId(discid_get_id(disc));
cddbRecord()->setMbSubmissionUrl(discid_get_submission_url(disc));
discRecord()->setDiscId(QString(discid_get_freedb_id(disc)).toUInt(NULL,16));
discRecord()->setDiscMbId(discid_get_id(disc));
discRecord()->setMbSubmissionUrl(discid_get_submission_url(disc));
if(rda->libraryConf()->readIsrc()) {
cddbRecord()->setMcn(discid_get_mcn(disc));
discRecord()->setMcn(discid_get_mcn(disc));
int first=discid_get_first_track_num(disc);
int last=discid_get_last_track_num(disc);
for(int i=first;i<=last;i++) {
if((i-first)<lookup_record->tracks()) {
cddbRecord()->setIsrc(i-first,
discRecord()->setIsrc(i-first,
RDDiscLookup::normalizedIsrc(discid_get_track_isrc(disc,i)));
}
}
@ -129,13 +129,13 @@ QString RDDiscLookup::caption()
void RDDiscLookup::okData()
{
done(true);
done(lookup_titles_box->currentIndex());
}
void RDDiscLookup::cancelData()
{
done(false);
done(-1);
}
@ -153,7 +153,7 @@ void RDDiscLookup::resizeEvent(QResizeEvent *e)
}
RDDiscRecord *RDDiscLookup::cddbRecord()
RDDiscRecord *RDDiscLookup::discRecord()
{
return lookup_record;
}

View File

@ -37,8 +37,7 @@ class RDDiscLookup : public RDDialog
{
Q_OBJECT
public:
enum Result {ExactMatch=0,PartialMatch=1,NoMatch=2,
ProtocolError=3,NetworkError=4};
enum Result {ExactMatch=0,NoMatch=1,LookupError=2};
RDDiscLookup(const QString &caption,FILE *profile_msgs,QWidget *parent=0);
QSize sizeHint() const;
virtual QString sourceName() const=0;
@ -49,7 +48,7 @@ class RDDiscLookup : public RDDialog
static QString normalizedIsrc(const QString &isrc,bool *ok=NULL);
signals:
void lookupDone(RDDiscLookup::Result);
void lookupDone(RDDiscLookup::Result,const QString &err_msg);
protected slots:
QString caption();
@ -59,7 +58,7 @@ class RDDiscLookup : public RDDialog
protected:
virtual void lookupRecord()=0;
void resizeEvent(QResizeEvent *e);
RDDiscRecord *cddbRecord();
RDDiscRecord *discRecord();
void profile(const QString &msg);
QComboBox *titlesBox();
QStringList *titlesKey();

View File

@ -20,8 +20,9 @@
//
#include "rdcddblookup.h"
#include "rddummylookup.h"
#include "rddisclookup_factory.h"
#include "rddummylookup.h"
#include "rdmblookup.h"
RDDiscLookup *RDDiscLookupFactory(RDLibraryConf::CdServerType type,
const QString &caption,
@ -39,6 +40,9 @@ RDDiscLookup *RDDiscLookupFactory(RDLibraryConf::CdServerType type,
break;
case RDLibraryConf::MusicBrainzType:
ret=new RDMbLookup(caption,profile_msgs,parent);
break;
case RDLibraryConf::LastType:
break;
}

View File

@ -97,15 +97,15 @@ void RDDiscRecord::setMcn(const QString &mcn)
}
QString RDDiscRecord::mbID() const
QString RDDiscRecord::discMbId() const
{
return disc_mb_id;
return disc_disc_mb_id;
}
void RDDiscRecord::setMbId(const QString &str)
void RDDiscRecord::setDiscMbId(const QString &str)
{
disc_mb_id=str;
disc_disc_mb_id=str;
}
@ -205,6 +205,18 @@ void RDDiscRecord::setDiscGenre(QString genre)
}
QString RDDiscRecord::discLabel() const
{
return disc_disc_label;
}
void RDDiscRecord::setDiscLabel(const QString &str)
{
disc_disc_label=str;
}
QString RDDiscRecord::discExtended() const
{
return disc_disc_extended;
@ -297,6 +309,18 @@ void RDDiscRecord::setTrackArtist(int track,QString artist)
}
QString RDDiscRecord::trackMbId(int track) const
{
return disc_track_mbid[track];
}
void RDDiscRecord::setTrackMbId(int track,const QString &str)
{
disc_track_mbid[track]=str;
}
QString RDDiscRecord::isrc(int track) const
{
if(track<CDROM_LEADOUT) {
@ -312,3 +336,35 @@ void RDDiscRecord::setIsrc(int track,QString isrc)
disc_track_isrc[track]=isrc;
}
}
QString RDDiscRecord::dump()
{
QString ret="RDDiscRecord::dump()\n";
ret+=QString().sprintf("tracks: %d\n",tracks());
ret+=QString().sprintf("discLength: %d\n",discLength());
ret+=QString().sprintf("discId: %08x\n",discId());
ret+="mcn: "+mcn()+"\n";
ret+="discMbId: "+discMbId()+"\n";
ret+="mbSubmissionUrl: "+mbSubmissionUrl()+"\n";
ret+="discTitle: "+discTitle()+"\n";
ret+="discArtist: "+discArtist()+"\n";
ret+="discAlbum: "+discAlbum()+"\n";
ret+="discAuthor: "+discAuthor()+"\n";
ret+=QString().sprintf("discYear: %u\n",discYear());
ret+="discGenre: "+discGenre()+"\n";
ret+="discLabel: "+discLabel()+"\n";
ret+="discExtended: "+discExtended()+"\n";
ret+="discPlayOrder: "+discPlayOrder()+"\n";
for(int i=0;i<tracks();i++) {
QString num=QString().sprintf("(%d): ",i+1);
ret+="trackOffset"+num+QString().sprintf("%u",trackOffset(i))+"\n";
ret+="trackTitle"+num+trackTitle(i)+"\n";
ret+="trackExtended"+num+trackExtended(i)+"\n";
ret+="trackMbId"+num+trackMbId(i)+"\n";
ret+="isrc"+num+isrc(i)+"\n";
}
return ret;
}

View File

@ -47,8 +47,8 @@ class RDDiscRecord
void setDiscId(unsigned id);
QString mcn() const;
void setMcn(const QString &mcn);
QString mbID() const;
void setMbId(const QString &str);
QString discMbId() const;
void setDiscMbId(const QString &str);
QString mbSubmissionUrl() const;
void setMbSubmissionUrl(const QString &url);
QString discTitle() const;
@ -63,6 +63,8 @@ class RDDiscRecord
void setDiscYear(unsigned year);
QString discGenre() const;
void setDiscGenre(QString genre);
QString discLabel() const;
void setDiscLabel(const QString &str);
QString discExtended() const;
void setDiscExtended(QString text);
QString discPlayOrder() const;
@ -75,14 +77,17 @@ class RDDiscRecord
void setTrackExtended(int track,QString text);
QString trackArtist(int track) const;
void setTrackArtist(int track,QString artist);
QString trackMbId(int track) const;
void setTrackMbId(int track,const QString &str);
QString isrc(int track) const;
void setIsrc(int track,QString isrc);
QString dump();
private:
int disc_tracks;
unsigned disc_disc_id;
QString disc_mcn;
QString disc_mb_id;
QString disc_disc_mb_id;
QString disc_mb_submission_url;
unsigned disc_disc_length;
QString disc_disc_title;
@ -91,11 +96,13 @@ class RDDiscRecord
QString disc_disc_author;
unsigned disc_disc_year;
QString disc_disc_genre;
QString disc_disc_label;
QString disc_disc_extended;
QString disc_disc_playorder;
QString disc_track_title[CDROM_LEADOUT];
QString disc_track_extended[CDROM_LEADOUT];
QString disc_track_artist[CDROM_LEADOUT];
QString disc_track_mbid[CDROM_LEADOUT];
QString disc_track_isrc[CDROM_LEADOUT];
unsigned disc_track_offset[CDROM_LEADOUT];
};

217
lib/rdmblookup.cpp Normal file
View File

@ -0,0 +1,217 @@
// rdmblookup.cpp
//
// RDDiscLookup instance class for MusicBrainz
//
// (C) Copyright 2003-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//
#include <musicbrainz5/Artist.h>
#include <musicbrainz5/ArtistCredit.h>
#include <musicbrainz5/Disc.h>
#include <musicbrainz5/HTTPFetch.h>
#include <musicbrainz5/Label.h>
#include <musicbrainz5/LabelInfo.h>
#include <musicbrainz5/Medium.h>
#include <musicbrainz5/NameCredit.h>
#include <musicbrainz5/NameCreditList.h>
#include <musicbrainz5/Query.h>
#include <musicbrainz5/Recording.h>
#include <musicbrainz5/ReleaseGroup.h>
#include <musicbrainz5/ReleaseGroupList.h>
#include <musicbrainz5/RelationList.h>
#include <musicbrainz5/RelationListList.h>
#include <musicbrainz5/Track.h>
#include <QMessageBox>
#include "rdmblookup.h"
QString err_str="OK";
RDDiscLookup::Result result_code=RDDiscLookup::ExactMatch;
RDMbLookup::RDMbLookup(const QString &caption,FILE *profile_msgs,
QWidget *parent)
: RDDiscLookup(caption,profile_msgs,parent)
{
setWindowTitle(caption+" - MusicBrainz "+tr("Lookup"));
}
QString RDMbLookup::sourceName() const
{
return QString("MusicBrainz");
}
void RDMbLookup::lookupRecord()
{
MusicBrainz5::CQuery
mbq((const char *)(QString("rivendell-")+VERSION).toUtf8(),
(const char *)rda->libraryConf()->mbServer().toUtf8());
try {
MusicBrainz5::CMetadata metadata=
mbq.Query("discid",(const char *)discRecord()->discMbId().toUtf8());
if(metadata.Disc()&&metadata.Disc()->ReleaseList()) {
MusicBrainz5::CReleaseList *releases=metadata.Disc()->ReleaseList();
if(releases->NumItems()==1) { // Exact Match
result_code=ProcessRelease(releases->Item(0));
}
if(releases->NumItems()>1) { // Multiple Matches
int index;
titlesKey()->clear();
titlesBox()->clear();
for(int i=0;i<releases->NumItems();i++) {
MusicBrainz5::CRelease *release=releases->Item(i);
titlesKey()->push_back(QString::fromUtf8(release->Title().c_str()));
titlesBox()->insertItem(titlesBox()->count(),
QString::fromUtf8(release->Title().c_str()));
}
if((index=exec())>=0) {
result_code=ProcessRelease(releases->Item(index));
}
else {
result_code=RDDiscLookup::NoMatch;
}
}
}
}
catch (MusicBrainz5::CConnectionError &err) {
err_str=" "+tr("Connection Exception")+"\n"+
" "+tr("Last Result")+": "+
QString().sprintf("%d",mbq.LastResult())+"\n"+
" "+tr("LastHTTPCode")+": "+
QString().sprintf("%d",mbq.LastHTTPCode())+"\n"+
" "+tr("LastErrorMessage")+": "+
QString::fromUtf8(mbq.LastErrorMessage().c_str());
result_code=RDDiscLookup::LookupError;
}
catch (MusicBrainz5::CTimeoutError &err) {
err_str=" "+tr("Timeout Exception")+"\n"+
" "+tr("Last Result")+": "+
QString().sprintf("%d",mbq.LastResult())+"\n"+
" "+tr("LastHTTPCode")+": "+
QString().sprintf("%d",mbq.LastHTTPCode())+"\n"+
" "+tr("LastErrorMessage")+": "+
QString::fromUtf8(mbq.LastErrorMessage().c_str());
result_code=RDDiscLookup::LookupError;
}
catch (MusicBrainz5::CAuthenticationError &err) {
err_str=" "+tr("Authentication Exception")+"\n"+
" "+tr("Last Result")+": "+
QString().sprintf("%d",mbq.LastResult())+"\n"+
" "+tr("LastHTTPCode")+": "+
QString().sprintf("%d",mbq.LastHTTPCode())+"\n"+
" "+tr("LastErrorMessage")+": "+
QString::fromUtf8(mbq.LastErrorMessage().c_str());
result_code=RDDiscLookup::LookupError;
}
catch (MusicBrainz5::CFetchError &err) {
err_str=" "+tr("Fetch Exception")+"\n"+
" "+tr("Last Result")+": "+
QString().sprintf("%d",mbq.LastResult())+"\n"+
" "+tr("LastHTTPCode")+": "+
QString().sprintf("%d",mbq.LastHTTPCode())+"\n"+
" "+tr("LastErrorMessage")+": "+
QString::fromUtf8(mbq.LastErrorMessage().c_str());
result_code=RDDiscLookup::LookupError;
}
catch (MusicBrainz5::CRequestError &err) {
err_str=" "+tr("Request Exception")+"\n"+
" "+tr("Last Result")+": "+\
QString().sprintf("%d",mbq.LastResult())+"\n"+
" "+tr("LastHTTPCode")+": "+
QString().sprintf("%d",mbq.LastHTTPCode())+"\n"+
" "+tr("LastErrorMessage")+": "+
QString::fromUtf8(mbq.LastErrorMessage().c_str());
result_code=RDDiscLookup::LookupError;
}
emit lookupDone(result_code,err_str);
}
RDDiscLookup::Result RDMbLookup::ProcessRelease(MusicBrainz5::CRelease *release)
{
MusicBrainz5::CQuery
mbq((const char *)(QString("rivendell-")+VERSION).toUtf8(),
(const char *)rda->libraryConf()->mbServer().toUtf8());
//
// Extract Basic Release Data
//
discRecord()->setDiscAlbum(QString::fromUtf8(release->Title().c_str()));
//discRecord()->setDiscGenre();
QStringList f0=QString::fromUtf8(release->Date().c_str()).split("-");
discRecord()->setDiscYear(f0.at(0).toInt());
//
// Extract Extended Release Data
//
MusicBrainz5::CQuery::tParamMap params;
params["inc"]="artists labels recordings";
MusicBrainz5::CMetadata metadata=mbq.Query("release",release->ID(),"",params);
if(metadata.Release()) {
//
// Get Artist(s)
//
MusicBrainz5::CNameCreditList *credits=
metadata.Release()->ArtistCredit()->NameCreditList();
if(credits) {
QString str="";
for(int j=0;j<credits->NumItems();j++) { // Amalgamate 'em!
str+=
QString::fromUtf8(credits->Item(j)->Artist()->Name().c_str());
str+=QString::fromUtf8(credits->Item(j)->JoinPhrase().c_str());
}
discRecord()->setDiscArtist(str);
}
//
// Get Labels
//
MusicBrainz5::CLabelInfoList *labels=
metadata.Release()->LabelInfoList();
if(labels) {
std::cout << *labels << std::endl;
discRecord()->
setDiscLabel(QString::fromUtf8(labels->Item(0)->
Label()->Name().c_str()));
}
//
// Get Per-Track Data
//
MusicBrainz5::CMediumList *media=metadata.Release()->MediumList();
if(media) {
for(int j=0;j<media->NumItems();j++) {
MusicBrainz5::CMedium *medium=media->Item(j);
MusicBrainz5::CTrackList *tracks=medium->TrackList();
for(int k=0;k<tracks->NumItems();k++) {
MusicBrainz5::CTrack *track=tracks->Item(k);
MusicBrainz5::CRecording *recording=track->Recording();
discRecord()->
setTrackTitle(k,QString::fromUtf8(recording->Title().c_str()));
discRecord()->
setTrackMbId(k,QString::fromUtf8(recording->ID().c_str()));
//std::cout << k << ": " << recording->Title() << std::endl;
}
}
}
}
return RDDiscLookup::ExactMatch;
}

43
lib/rdmblookup.h Normal file
View File

@ -0,0 +1,43 @@
// rdmblookup.h
//
// RDDiscLookup instance class for MusicBrainz
//
// (C) Copyright 2003-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//
#ifndef RDMBLOOKUP_H
#define RDMBLOOKUP_H
#include <musicbrainz5/Release.h>
#include <rddisclookup.h>
class RDMbLookup : public RDDiscLookup
{
Q_OBJECT
public:
RDMbLookup(const QString &caption,FILE *profile_msgs,QWidget *parent=0);
QString sourceName() const;
protected:
void lookupRecord();
private:
RDDiscLookup::Result ProcessRelease(MusicBrainz5::CRelease *release);
};
#endif // RDMBLOOKUP_H

View File

@ -86,8 +86,8 @@ CdRipper::CdRipper(QString cutname,RDDiscRecord *rec,RDLibraryConf *conf,
rip_disc_lookup=RDDiscLookupFactory(rda->libraryConf()->cdServerType(),
"RDLibrary",NULL,this);
}
connect(rip_disc_lookup,SIGNAL(lookupDone(RDDiscLookup::Result)),
this,SLOT(cddbDoneData(RDDiscLookup::Result)));
connect(rip_disc_lookup,SIGNAL(lookupDone(RDDiscLookup::Result,const QString &)),
this,SLOT(lookupDoneData(RDDiscLookup::Result,const QString &)));
//
// Title Selector
@ -567,7 +567,7 @@ void CdRipper::stoppedData()
}
void CdRipper::cddbDoneData(RDDiscLookup::Result result)
void CdRipper::lookupDoneData(RDDiscLookup::Result result,const QString &err_msg)
{
switch(result) {
case RDDiscLookup::ExactMatch:
@ -589,13 +589,14 @@ void CdRipper::cddbDoneData(RDDiscLookup::Result result)
trackSelectionChangedData();
break;
case RDDiscLookup::PartialMatch:
case RDDiscLookup::NoMatch:
rip_track[0]=-1;
rip_track[1]=-1;
printf("Partial Match!\n");
break;
default:
case RDDiscLookup::LookupError:
QMessageBox::warning(this,"RDLibrary - "+rip_disc_lookup->sourceName()+
" "+tr("Lookup Error"),err_msg);
rip_track[0]=-1;
rip_track[1]=-1;
break;

View File

@ -57,7 +57,7 @@ class CdRipper : public RDDialog
void mediaChangedData();
void playedData(int);
void stoppedData();
void cddbDoneData(RDDiscLookup::Result);
void lookupDoneData(RDDiscLookup::Result,const QString &err_msg);
void normalizeCheckData(bool);
void autotrimCheckData(bool);
void closeData();

View File

@ -83,8 +83,9 @@ DiskRipper::DiskRipper(QString *filter,QString *group,QString *schedcode,
rip_disc_lookup=RDDiscLookupFactory(rda->libraryConf()->cdServerType(),
"RDLibrary",NULL,this);
}
connect(rip_disc_lookup,SIGNAL(lookupDone(RDDiscLookup::Result)),
this,SLOT(cddbDoneData(RDDiscLookup::Result)));
connect(rip_disc_lookup,
SIGNAL(lookupDone(RDDiscLookup::Result,const QString &)),
this,SLOT(lookupDoneData(RDDiscLookup::Result,const QString &)));
//
// Artist Label
@ -780,36 +781,40 @@ void DiskRipper::stoppedData()
}
void DiskRipper::cddbDoneData(RDDiscLookup::Result result)
void DiskRipper::lookupDoneData(RDDiscLookup::Result result,
const QString &err_msg)
{
switch(result) {
case RDDiscLookup::ExactMatch:
if(rip_cdrom->status()!=RDCdPlayer::Ok) {
return;
}
rip_artist_edit->setText(rip_disc_record.discArtist());
rip_album_edit->setText(rip_disc_record.discAlbum());
rip_other_edit->setText(rip_disc_record.discExtended());
for(int i=0;i<rip_disc_record.tracks();i++) {
rip_track_list->findItem(QString().sprintf("%d",i+1),0)->
setText(2,rip_disc_record.trackTitle(i));
rip_track_list->findItem(QString().sprintf("%d",i+1),0)->
setText(3,rip_disc_record.trackExtended(i));
rip_wave_datas[i]->setTitle(rip_disc_record.trackTitle(i));
rip_wave_datas[i]->setArtist(rip_disc_record.discArtist());
rip_wave_datas[i]->setAlbum(rip_disc_record.discAlbum());
}
rip_apply_box->setChecked(true);
rip_apply_box->setEnabled(true);
rip_apply_label->setEnabled(true);
break;
case RDDiscLookup::PartialMatch:
rip_track=-1;
printf("Partial Match!\n");
break;
default:
rip_track=-1;
break;
case RDDiscLookup::ExactMatch:
if(rip_cdrom->status()!=RDCdPlayer::Ok) {
return;
}
rip_artist_edit->setText(rip_disc_record.discArtist());
rip_album_edit->setText(rip_disc_record.discAlbum());
rip_other_edit->setText(rip_disc_record.discExtended());
for(int i=0;i<rip_disc_record.tracks();i++) {
rip_track_list->findItem(QString().sprintf("%d",i+1),0)->
setText(2,rip_disc_record.trackTitle(i));
rip_track_list->findItem(QString().sprintf("%d",i+1),0)->
setText(3,rip_disc_record.trackExtended(i));
rip_wave_datas[i]->setTitle(rip_disc_record.trackTitle(i));
rip_wave_datas[i]->setArtist(rip_disc_record.discArtist());
rip_wave_datas[i]->setAlbum(rip_disc_record.discAlbum());
}
rip_apply_box->setChecked(true);
rip_apply_box->setEnabled(true);
rip_apply_label->setEnabled(true);
break;
case RDDiscLookup::NoMatch:
rip_track=-1;
break;
case RDDiscLookup::LookupError:
QMessageBox::warning(this,"RDLibrary - "+rip_disc_lookup->sourceName()+
" "+tr("Lookup Error"),err_msg);
rip_track=-1;
break;
}
}

View File

@ -57,7 +57,7 @@ class DiskRipper : public RDDialog
void mediaChangedData();
void playedData(int);
void stoppedData();
void cddbDoneData(RDDiscLookup::Result);
void lookupDoneData(RDDiscLookup::Result,const QString &err_msg);
void normalizeCheckData(bool);
void autotrimCheckData(bool);
void selectionChangedData();

View File

@ -468,6 +468,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -740,6 +744,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>

View File

@ -468,6 +468,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -739,6 +743,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>

View File

@ -468,6 +468,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -740,6 +744,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>

View File

@ -356,6 +356,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -568,6 +572,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>

View File

@ -458,6 +458,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -732,6 +736,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>

View File

@ -458,6 +458,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -732,6 +736,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>

View File

@ -459,6 +459,10 @@ Track</source>
<source>Values to Cart</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DiskGauge</name>
@ -733,6 +737,10 @@ Selection</source>
<source>Values to Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Lookup Error</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditCart</name>