diff --git a/ChangeLog b/ChangeLog index 88c53a6c..137e48e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19440,3 +19440,6 @@ * Added a 'readcd_test' test harness. 2020-01-29 Fred Gleason * Moved MCN to extended attributes in the 'readcd_test' harness. +2020-01-29 Fred Gleason + * Refactored the 'RDCddbLookup' class into 'RDCddbLookup' and + 'RDDiscLookup'. diff --git a/lib/Makefile.am b/lib/Makefile.am index ae6b3351..0af3581c 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -111,6 +111,7 @@ dist_librd_la_SOURCES = dbversion.h\ rddeck.cpp rddeck.h\ rddelete.cpp rddelete.h\ rddialog.cpp rddialog.h\ + rddisclookup.cpp rddisclookup.h\ rddownload.cpp rddownload.h\ rddropbox.cpp rddropbox.h\ rdedit_audio.cpp rdedit_audio.h\ @@ -272,6 +273,7 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\ moc_rddbheartbeat.cpp\ moc_rddelete.cpp\ moc_rddialog.cpp\ + moc_rddisclookup.cpp\ moc_rddownload.cpp\ moc_rdedit_audio.cpp\ moc_rdedit_panel_name.cpp\ diff --git a/lib/librd_cs.ts b/lib/librd_cs.ts index fceca301..7458c8f7 100644 --- a/lib/librd_cs.ts +++ b/lib/librd_cs.ts @@ -1232,17 +1232,13 @@ ze &souboru CDDB Query - - Multiple Matches Found! - - OK - OK + OK Cancel - Zrušit + Zrušit diff --git a/lib/librd_de.ts b/lib/librd_de.ts index 21c78e67..56a0b0ff 100644 --- a/lib/librd_de.ts +++ b/lib/librd_de.ts @@ -1223,17 +1223,13 @@ senden CDDB Query - - Multiple Matches Found! - - OK - OK + OK Cancel - Abbrechen + Abbrechen diff --git a/lib/librd_es.ts b/lib/librd_es.ts index 812522a9..a58e1917 100644 --- a/lib/librd_es.ts +++ b/lib/librd_es.ts @@ -1223,17 +1223,9 @@ Color CDDB Query - - Multiple Matches Found! - - - - OK - - Cancel - Cancelar + Cancelar diff --git a/lib/librd_fr.ts b/lib/librd_fr.ts index 4bd62ef5..947a2a40 100644 --- a/lib/librd_fr.ts +++ b/lib/librd_fr.ts @@ -1073,18 +1073,6 @@ La Couleur CDDB Query - - Multiple Matches Found! - - - - OK - - - - Cancel - - RDCueEdit diff --git a/lib/librd_nb.ts b/lib/librd_nb.ts index d468e38f..6b4f5b11 100644 --- a/lib/librd_nb.ts +++ b/lib/librd_nb.ts @@ -1222,17 +1222,9 @@ farge CDDB Query - - Multiple Matches Found! - - OK - OK - - - Cancel - + OK diff --git a/lib/librd_nn.ts b/lib/librd_nn.ts index d468e38f..6b4f5b11 100644 --- a/lib/librd_nn.ts +++ b/lib/librd_nn.ts @@ -1222,17 +1222,9 @@ farge CDDB Query - - Multiple Matches Found! - - OK - OK - - - Cancel - + OK diff --git a/lib/librd_pt_BR.ts b/lib/librd_pt_BR.ts index 3d5d3dd4..4743d63e 100644 --- a/lib/librd_pt_BR.ts +++ b/lib/librd_pt_BR.ts @@ -1223,17 +1223,13 @@ Cor CDDB Query - - Multiple Matches Found! - - OK - OK + OK Cancel - Cancelar + Cancelar diff --git a/lib/rdcddblookup.cpp b/lib/rdcddblookup.cpp index cd43b04b..db369b2e 100644 --- a/lib/rdcddblookup.cpp +++ b/lib/rdcddblookup.cpp @@ -2,7 +2,7 @@ // // A Qt class for accessing the FreeDB CD Database. // -// (C) Copyright 2003-2019 Fred Gleason +// (C) Copyright 2003-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License @@ -26,42 +26,18 @@ #include #include -#include -#include +#include "rdapplication.h" +#include "rdcddblookup.h" +#include "rdprofile.h" RDCddbLookup::RDCddbLookup(const QString &caption,FILE *profile_msgs, QWidget *parent) - : RDDialog(parent) + : RDDiscLookup(caption,profile_msgs,parent) { lookup_state=0; - lookup_profile_msgs=profile_msgs; - - // - // Get the Hostname - // - if(getenv("HOSTNAME")==NULL) { - lookup_hostname=RDCDDBLOOKUP_DEFAULT_HOSTNAME; - } - else { - lookup_hostname=getenv("HOSTNAME"); - } setWindowTitle(caption+" - "+tr("CDDB Query")); - lookup_titles_label=new QLabel(tr("Multiple Matches Found!"),this); - lookup_titles_label->setAlignment(Qt::AlignCenter|Qt::AlignVCenter); - lookup_titles_label->setFont(labelFont()); - - lookup_titles_box=new QComboBox(this); - - lookup_ok_button=new QPushButton(tr("OK"),this); - lookup_ok_button->setFont(buttonFont()); - connect(lookup_ok_button,SIGNAL(clicked()),this,SLOT(okData())); - - lookup_cancel_button=new QPushButton(tr("Cancel"),this); - lookup_cancel_button->setFont(buttonFont()); - connect(lookup_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData())); - // // Socket // @@ -78,72 +54,19 @@ RDCddbLookup::~RDCddbLookup() } -QSize RDCddbLookup::sizeHint() const +void RDCddbLookup::lookupRecord() { - return QSize(400,120); -} - - -void RDCddbLookup::setCddbRecord(RDCddbRecord *rec) -{ - lookup_record=rec; -} - - -void RDCddbLookup::lookupRecord(const QString &cdda_dir,const QString &cdda_dev, - const QString &hostname,Q_UINT16 port, - const QString &username,const QString &appname, - const QString &appver) -{ - if(lookup_record->tracks()==0) { + if(cddbRecord()->tracks()==0) { return; } - lookup_username=username; - lookup_appname=appname; - lookup_appver=appver; + lookup_username=rda->user()->name(); + lookup_hostname=rda->libraryConf()->cddbServer(); + lookup_appname="rivendell"; + lookup_appver=VERSION; - Profile("starting CD-TEXT lookup"); - if(!cdda_dir.isEmpty()) { - if(ReadCdText(cdda_dir,cdda_dev)) { - emit done(RDCddbLookup::ExactMatch); - Profile("CD-TEXT lookup success"); - return; - } - } - Profile("CD-TEXT lookup failure"); - - Profile("starting CDDB lookup"); - if(!hostname.isEmpty()) { - // - // Set Up Default User - // - if(lookup_username.isEmpty()) { - if(getenv("USER")==NULL) { - lookup_username=RDCDDBLOOKUP_DEFAULT_USER; - } - else { - lookup_username=getenv("USER"); - } - } - - // - // Get the Hostname - // - if(getenv("HOSTNAME")==NULL) { - lookup_hostname=RDCDDBLOOKUP_DEFAULT_HOSTNAME; - } - else { - lookup_hostname=getenv("HOSTNAME"); - } - lookup_socket->connectToHost(hostname,port); - } -} - - -bool RDCddbLookup::readIsrc(const QString &cdda_dir,const QString &cdda_dev) -{ - return ReadIsrcs(cdda_dir,cdda_dev); + profile("starting CDDB lookup"); + lookup_socket->connectToHost(lookup_hostname,RDCDDBLOOKUP_DEFAULT_PORT); } @@ -161,7 +84,7 @@ void RDCddbLookup::readyReadData() while(lookup_socket->canReadLine()) { line=QString::fromUtf8(lookup_socket->readLine()); - Profile("recevied from server: \""+line+"\""); + profile("recevied from server: \""+line+"\""); code=line.split(" ").at(0).toInt(); switch(lookup_state) { case 0: // Login Banner @@ -192,12 +115,12 @@ void RDCddbLookup::readyReadData() case 2: // Protocol Level Response if(code==201) { snprintf(buffer,2048,"cddb query %08x %d", - lookup_record->discId(),lookup_record->tracks()); - for(int i=0;itracks();i++) { - snprintf(offset,256," %d",lookup_record->trackOffset(i)); + cddbRecord()->discId(),cddbRecord()->tracks()); + for(int i=0;itracks();i++) { + snprintf(offset,256," %d",cddbRecord()->trackOffset(i)); strcat(buffer,offset); } - snprintf(offset,256," %d",lookup_record->discLength()/75); + snprintf(offset,256," %d",cddbRecord()->discLength()/75); strcat(buffer,offset); SendToServer(buffer); lookup_state=3; @@ -212,18 +135,18 @@ void RDCddbLookup::readyReadData() case 200: // Exact Match f0=line.split(" "); if(f0.size()>=4) { - lookup_record->setDiscId(f0[2].toUInt(&ok,16)); + cddbRecord()->setDiscId(f0[2].toUInt(&ok,16)); if(!ok) { FinishCddbLookup(RDCddbLookup::ProtocolError); } - lookup_record->setDiscGenre(f0[1]); + cddbRecord()->setDiscGenre(f0[1]); f0.erase(f0.begin()); f0.erase(f0.begin()); f0.erase(f0.begin()); - lookup_record->setDiscTitle(f0.join(" ")); + cddbRecord()->setDiscTitle(f0.join(" ")); snprintf(buffer,2048,"cddb read %s %08x\n", - (const char *)lookup_record->discGenre().utf8(), - lookup_record->discId()); + (const char *)cddbRecord()->discGenre().utf8(), + cddbRecord()->discId()); SendToServer(buffer); lookup_state=5; } @@ -233,8 +156,8 @@ void RDCddbLookup::readyReadData() break; case 210: // Multiple Exact Matches - lookup_titles_box->clear(); - lookup_titles_key.clear(); + titlesBox()->clear(); + titlesKey()->clear(); lookup_state=4; break; @@ -250,28 +173,28 @@ void RDCddbLookup::readyReadData() case 4: // Process Multiple Matches if(line.trimmed()==".") { - Profile("Match list complete, showing chooser dialog..."); + profile("Match list complete, showing chooser dialog..."); if(exec()) { - f0=lookup_titles_key.at(lookup_titles_box->currentItem()). + f0=titlesKey()->at(titlesBox()->currentItem()). split(" ",QString::SkipEmptyParts); if(f0.size()!=2) { FinishCddbLookup(RDCddbLookup::ProtocolError); } - lookup_record->setDiscId(f0.at(1).toUInt(&ok,16)); + cddbRecord()->setDiscId(f0.at(1).toUInt(&ok,16)); if(!ok) { FinishCddbLookup(RDCddbLookup::ProtocolError); } - lookup_record->setDiscGenre(f0.at(0)); - f0=lookup_titles_box->currentText().split("/"); + cddbRecord()->setDiscGenre(f0.at(0)); + f0=titlesBox()->currentText().split("/"); if(f0.size()==2) { - lookup_record->setDiscTitle(f0.at(1).trimmed()); + cddbRecord()->setDiscTitle(f0.at(1).trimmed()); } else { - lookup_record->setDiscTitle(lookup_titles_box->currentText().trimmed()); + cddbRecord()->setDiscTitle(titlesBox()->currentText().trimmed()); } snprintf(buffer,2048,"cddb read %s %08x\n", - (const char *)lookup_record->discGenre().utf8(), - lookup_record->discId()); + (const char *)cddbRecord()->discGenre().utf8(), + cddbRecord()->discId()); SendToServer(buffer); lookup_state=5; } @@ -282,11 +205,11 @@ void RDCddbLookup::readyReadData() else { f0.clear(); f0=line.split(" "); - lookup_titles_key.push_back(f0.at(0).trimmed()+" "+ + titlesKey()->push_back(f0.at(0).trimmed()+" "+ f0.at(1).trimmed()); f0.removeFirst(); f0.removeFirst(); - lookup_titles_box->insertItem(lookup_titles_box->count(),f0.join(" ").trimmed()); + titlesBox()->insertItem(titlesBox()->count(),f0.join(" ").trimmed()); } break; @@ -306,26 +229,26 @@ void RDCddbLookup::readyReadData() } ParsePair(&line,&tag,&value,&index); if(tag=="DTITLE") { - lookup_record->setDiscTitle(value.left(value.length()-1)); + cddbRecord()->setDiscTitle(value.left(value.length()-1)); } if(tag=="DYEAR") { - lookup_record->setDiscYear(value.toUInt()); + cddbRecord()->setDiscYear(value.toUInt()); } if(tag=="EXTD") { - lookup_record-> - setDiscExtended(lookup_record->discExtended()+ + cddbRecord()-> + setDiscExtended(cddbRecord()->discExtended()+ DecodeString(value)); } if(tag=="PLAYORDER") { - lookup_record->setDiscPlayOrder(value); + cddbRecord()->setDiscPlayOrder(value); } if((tag=="TTITLE")&&(index!=-1)) { - lookup_record->setTrackTitle(index,value.left(value.length()-1)); + cddbRecord()->setTrackTitle(index,value.left(value.length()-1)); } if((tag=="EXTT")&&(index!=-1)) { - lookup_record-> + cddbRecord()-> setTrackExtended(index, - lookup_record->trackExtended(index)+value); + cddbRecord()->trackExtended(index)+value); } } break; @@ -354,39 +277,13 @@ void RDCddbLookup::errorData(QAbstractSocket::SocketError err) } -void RDCddbLookup::okData() -{ - done(true); -} - - -void RDCddbLookup::cancelData() -{ - done(false); -} - - -void RDCddbLookup::resizeEvent(QResizeEvent *e) -{ - int w=size().width(); - int h=size().height(); - - lookup_titles_label->setGeometry(15,2,w-30,20); - - lookup_titles_box->setGeometry(10,24,w-20,20); - - lookup_ok_button->setGeometry(w-180,h-60,80,50); - lookup_cancel_button->setGeometry(w-90,h-60,80,50); -} - - void RDCddbLookup::FinishCddbLookup(RDCddbLookup::Result res) { SendToServer("quit"); lookup_socket->close(); lookup_state=0; emit lookupDone(res); - Profile("CDDB lookup finished"); + profile("CDDB lookup finished"); } @@ -438,133 +335,8 @@ int RDCddbLookup::GetIndex(QString *tag) } -bool RDCddbLookup::ReadCdText(const QString &cdda_dir,const QString &cdda_dev) -{ - RDProfile *title_profile=new RDProfile(); - bool ret=false; - QString str; - QString cmd; - - // - // Write the Track Title Data to a Temp File - // - QByteArray output; - Q3Process *proc=new Q3Process(this); - proc->addArgument("cdda2wav"); - proc->addArgument("-D"); - proc->addArgument(cdda_dev); - proc->addArgument("--info-only"); - proc->addArgument("-v"); - proc->addArgument("titles"); - proc->setWorkingDirectory(cdda_dir); - if(!proc->start()) { - delete proc; - return false; - } - while(proc->isRunning()) { - output=proc->readStderr(); - if(output.size()>0) { // Work around icedax(1)'s idiotic user prompt - if(strncmp(output,"load cdrom please and press enter",33)==0) { - proc->kill(); - delete proc; - return false; - } - } - } - if((!proc->normalExit())||(proc->exitStatus()!=0)) { - delete proc; - return false; - } - delete proc; - - // - // Read the Track Title Data File - // - for(int i=0;itracks();i++) { - title_profile->setSource(cdda_dir+QString().sprintf("/audio_%02d.inf",i+1)); - str=title_profile->stringValue("","Albumtitle",""); - str.remove("'"); - if((!str.isEmpty())&&(str!="''")) { - lookup_record->setDiscTitle(str); - ret=true; - } - - str=title_profile->stringValue("","Albumperformer",""); - str.remove("'"); - if((!str.isEmpty())&&(str!="''")) { - lookup_record->setDiscArtist(str); - ret=true; - } - - str=title_profile->stringValue("","Tracktitle",""); - str.remove("'"); - if((!str.isEmpty())&&(str!="''")) { - lookup_record->setTrackTitle(i,str); - ret=true; - } - - str=title_profile->stringValue("","Performer",""); - str.remove("'"); - if((!str.isEmpty())&&(str!="''")) { - lookup_record->setTrackArtist(i,str); - ret=true; - } - } - return ret; -} - - -bool RDCddbLookup::ReadIsrcs(const QString &cdda_dir,const QString &cdda_dev) -{ - int err=0; - RDProfile *title_profile=new RDProfile(); - RDProfile *isrc_profile=new RDProfile(); - bool ret=false; - QString str; - QString cmd; - - // - // Write the ISRC Data to a Temp File - // - cmd=QString("CURDIR=`pwd`;cd ")+ - cdda_dir+";cdda2wav -D "+cdda_dev+ - " --info-only -v trackid 2> /dev/null;cd $CURDIR"; - if((err=system(cmd))!=0) { - return false; - } - - // - // Read the ISRC Data File - // - for(int i=0;itracks();i++) { - isrc_profile->setSource(cdda_dir+QString().sprintf("/audio_%02d.inf",i+1)); - str=isrc_profile->stringValue("","ISRC",""); - str.remove("'"); - str.remove("-"); - if((!str.isEmpty())&&(str!="''")) { - lookup_record->setIsrc(i,str); - ret=true; - } - } - delete title_profile; - delete isrc_profile; - - return ret; -} - - void RDCddbLookup::SendToServer(const QString &msg) { lookup_socket->writeBlock(msg+"\n",msg.length()+1); - Profile("sent to server: \""+msg+"\""); -} - - -void RDCddbLookup::Profile(const QString &msg) -{ - if(lookup_profile_msgs!=NULL) { - printf("%s | RDCddbLookup::%s\n", - (const char *)QTime::currentTime().toString("hh:mm:ss.zzz"), - (const char *)msg.toUtf8()); - } + profile("sent to server: \""+msg+"\""); } diff --git a/lib/rdcddblookup.h b/lib/rdcddblookup.h index 94d26cb2..794806f7 100644 --- a/lib/rdcddblookup.h +++ b/lib/rdcddblookup.h @@ -30,76 +30,39 @@ #include #include +#include #include #include // -// Default Settings +// FreeDB Service Settings // #define RDCDDBLOOKUP_DEFAULT_PORT 8880 -#define RDCDDBLOOKUP_DEFAULT_USER "libradio" -#define RDCDDBLOOKUP_DEFAULT_HOSTNAME "linux" -/** - * @short Lookup CD Data from the FreeDB CD Database - * @author Fred Gleason - * - * This class implements an object for accessing a remote FreeDB CD - * database server. - **/ - -class RDCddbLookup : public RDDialog +class RDCddbLookup : public RDDiscLookup { Q_OBJECT public: - enum Result {ExactMatch=0,PartialMatch=1,NoMatch=2, - ProtocolError=3,NetworkError=4}; RDCddbLookup(const QString &caption,FILE *profile_msgs,QWidget *parent=0); ~RDCddbLookup(); - QSize sizeHint() const; - void setCddbRecord(RDCddbRecord *); - void lookupRecord(const QString &cdda_dir,const QString &cdda_dev, - const QString &hostname, - Q_UINT16 port=RDCDDBLOOKUP_DEFAULT_PORT, - const QString &username="", - const QString &appname=PACKAGE_NAME, - const QString &ver=VERSION); - bool readIsrc(const QString &cdda_dir,const QString &cdda_dev); + void lookupRecord(); private slots: void readyReadData(); void errorData(QAbstractSocket::SocketError); - void okData(); - void cancelData(); - - signals: - void lookupDone(RDCddbLookup::Result); - - protected: - void resizeEvent(QResizeEvent *e); private: void FinishCddbLookup(RDCddbLookup::Result res); QString DecodeString(QString &str); void ParsePair(QString *line,QString *tag,QString *value,int *index); int GetIndex(QString *tag); - bool ReadCdText(const QString &cdda_dir,const QString &cdda_dev); - bool ReadIsrcs(const QString &cdda_dir,const QString &cdda_dev); void SendToServer(const QString &msg); - void Profile(const QString &msg); - QLabel *lookup_titles_label; - QComboBox *lookup_titles_box; - QStringList lookup_titles_key; - QPushButton *lookup_ok_button; - QPushButton *lookup_cancel_button; - RDCddbRecord *lookup_record; QTcpSocket *lookup_socket; int lookup_state; QString lookup_username; QString lookup_appname; QString lookup_appver; QString lookup_hostname; - FILE *lookup_profile_msgs; }; #endif // RDCDDBLOOKUP_H diff --git a/lib/rddisclookup.cpp b/lib/rddisclookup.cpp new file mode 100644 index 00000000..928a282d --- /dev/null +++ b/lib/rddisclookup.cpp @@ -0,0 +1,296 @@ +// rddisclookup.cpp +// +// Base class for CD metadata lookup methods +// +// (C) Copyright 2003-2020 Fred Gleason +// +// 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 +#include + +#include +#include +#include +#include +#include + +#include "rdtempdirectory.h" +#include "rddisclookup.h" +#include "rdprofile.h" + +RDDiscLookup::RDDiscLookup(const QString &caption,FILE *profile_msgs, + QWidget *parent) + : RDDialog(parent) +{ + lookup_profile_msgs=profile_msgs; + + lookup_titles_label=new QLabel(tr("Multiple Matches Found!"),this); + lookup_titles_label->setAlignment(Qt::AlignCenter|Qt::AlignVCenter); + lookup_titles_label->setFont(labelFont()); + + lookup_titles_box=new QComboBox(this); + + lookup_ok_button=new QPushButton(tr("OK"),this); + lookup_ok_button->setFont(buttonFont()); + connect(lookup_ok_button,SIGNAL(clicked()),this,SLOT(okData())); + + lookup_cancel_button=new QPushButton(tr("Cancel"),this); + lookup_cancel_button->setFont(buttonFont()); + connect(lookup_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData())); + + // + // Create Temporary Directory + // + char path[PATH_MAX]; + strncpy(path,RDTempDirectory::basePath(),PATH_MAX); + strcat(path,"/XXXXXX"); + if(mkdtemp(path)==NULL) { + QMessageBox::warning(this,caption+" - "+tr("Ripper Error"), + tr("Unable to create temporary directory!")); + } + else { + lookup_cdda_dir.setPath(path); + } + profile("created temp directory \""+lookup_cdda_dir.path()+"\""); +} + + +RDDiscLookup::~RDDiscLookup() +{ + QStringList files=lookup_cdda_dir.entryList(); + for(int i=0;ilibraryConf()->ripperDevice())) { + emit lookupDone(RDDiscLookup::ExactMatch); + profile("CD-TEXT lookup success"); + return; + } + profile("CD-TEXT lookup failure"); + + lookupRecord(); +} + + +bool RDDiscLookup::readIsrc() +{ + return ReadIsrcs(lookup_cdda_dir.path(),rda->libraryConf()->ripperDevice()); +} + + +void RDDiscLookup::okData() +{ + done(true); +} + + +void RDDiscLookup::cancelData() +{ + done(false); +} + + +void RDDiscLookup::resizeEvent(QResizeEvent *e) +{ + int w=size().width(); + int h=size().height(); + + lookup_titles_label->setGeometry(15,2,w-30,20); + + lookup_titles_box->setGeometry(10,24,w-20,20); + + lookup_ok_button->setGeometry(w-180,h-60,80,50); + lookup_cancel_button->setGeometry(w-90,h-60,80,50); +} + + +RDCddbRecord *RDDiscLookup::cddbRecord() +{ + return lookup_record; +} + + +void RDDiscLookup::profile(const QString &msg) +{ + if(lookup_profile_msgs!=NULL) { + printf("%s | RDDiscLookup::%s\n", + (const char *)QTime::currentTime().toString("hh:mm:ss.zzz"), + (const char *)msg.toUtf8()); + } +} + + +QComboBox *RDDiscLookup::titlesBox() +{ + return lookup_titles_box; +} + + +QStringList *RDDiscLookup::titlesKey() +{ + return &lookup_titles_key; +} + + +bool RDDiscLookup::ReadCdText(const QString &cdda_dir,const QString &cdda_dev) +{ + RDProfile *title_profile=new RDProfile(); + bool ret=false; + QString str; + QString cmd; + + // + // Write the Track Title Data to a Temp File + // + QByteArray output; + Q3Process *proc=new Q3Process(this); + proc->addArgument("cdda2wav"); + proc->addArgument("-D"); + proc->addArgument(cdda_dev); + proc->addArgument("--info-only"); + proc->addArgument("-v"); + proc->addArgument("titles"); + proc->setWorkingDirectory(cdda_dir); + if(!proc->start()) { + delete proc; + profile("cdda2wav failed to start!"); + return false; + } + while(proc->isRunning()) { + output=proc->readStderr(); + if(output.size()>0) { // Work around icedax(1)'s idiotic user prompt + if(strncmp(output,"load cdrom please and press enter",33)==0) { + proc->kill(); + delete proc; + profile("cdda2wav returned \""+output+"\", killing it!"); + return false; + } + } + } + if(!proc->normalExit()) { + profile("cdda2wav crashed!"); + delete proc; + return false; + } + if(proc->exitStatus()!=0) { + profile("cdda2wav return exit code "+ + QString().sprintf("%d",proc->exitStatus())); + delete proc; + return false; + } + delete proc; + + // + // Read the Track Title Data File + // + for(int i=0;itracks();i++) { + title_profile->setSource(cdda_dir+QString().sprintf("/audio_%02d.inf",i+1)); + str=title_profile->stringValue("","Albumtitle",""); + str.remove("'"); + if((!str.isEmpty())&&(str!="''")) { + lookup_record->setDiscTitle(str); + profile("setting DiscTitle to \""+str+"\""); + ret=true; + } + + str=title_profile->stringValue("","Albumperformer",""); + str.remove("'"); + if((!str.isEmpty())&&(str!="''")) { + lookup_record->setDiscArtist(str); + profile("setting DiscArtist to \""+str+"\""); + ret=true; + } + + str=title_profile->stringValue("","Tracktitle",""); + str.remove("'"); + if((!str.isEmpty())&&(str!="''")) { + lookup_record->setTrackTitle(i,str); + profile("setting TrackTitle "+QString().sprintf("%d",i+1)+" to \""+str+"\""); + ret=true; + } + + str=title_profile->stringValue("","Performer",""); + str.remove("'"); + if((!str.isEmpty())&&(str!="''")) { + lookup_record->setTrackArtist(i,str); + profile("setting TrackArtist "+QString().sprintf("%d",i+1)+" to \""+str+"\""); + ret=true; + } + } + return ret; +} + + +bool RDDiscLookup::ReadIsrcs(const QString &cdda_dir,const QString &cdda_dev) +{ + int err=0; + RDProfile *title_profile=new RDProfile(); + RDProfile *isrc_profile=new RDProfile(); + bool ret=false; + QString str; + QString cmd; + + // + // Write the ISRC Data to a Temp File + // + cmd=QString("CURDIR=`pwd`;cd ")+ + cdda_dir+";cdda2wav -D "+cdda_dev+ + " --info-only -v trackid 2> /dev/null;cd $CURDIR"; + if((err=system(cmd))!=0) { + return false; + } + + // + // Read the ISRC Data File + // + for(int i=0;itracks();i++) { + isrc_profile->setSource(cdda_dir+QString().sprintf("/audio_%02d.inf",i+1)); + str=isrc_profile->stringValue("","ISRC",""); + str.remove("'"); + str.remove("-"); + if((!str.isEmpty())&&(str!="''")) { + lookup_record->setIsrc(i,str); + ret=true; + } + } + delete title_profile; + delete isrc_profile; + + return ret; +} diff --git a/lib/rddisclookup.h b/lib/rddisclookup.h new file mode 100644 index 00000000..ba010da4 --- /dev/null +++ b/lib/rddisclookup.h @@ -0,0 +1,84 @@ +// rddisclookup.h +// +// Base class for CD metadata lookup methods +// +// (C) Copyright 2003-2020 Fred Gleason +// +// 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 RDDISCLOOKUP_H +#define RDDISCLOOKUP_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +class RDDiscLookup : public RDDialog +{ + Q_OBJECT + public: + enum Result {ExactMatch=0,PartialMatch=1,NoMatch=2, + ProtocolError=3,NetworkError=4}; + RDDiscLookup(const QString &caption,FILE *profile_msgs,QWidget *parent=0); + ~RDDiscLookup(); + QSize sizeHint() const; + void setCddbRecord(RDCddbRecord *); + void lookup(); + bool readIsrc(); + + signals: + void lookupDone(RDDiscLookup::Result); + + protected slots: + virtual void lookupRecord()=0; + void okData(); + void cancelData(); + + protected: + void resizeEvent(QResizeEvent *e); + RDCddbRecord *cddbRecord(); + void profile(const QString &msg); + QComboBox *titlesBox(); + QStringList *titlesKey(); + + private: + bool ReadCdText(const QString &cdda_dir,const QString &cdda_dev); + bool ReadIsrcs(const QString &cdda_dir,const QString &cdda_dev); + QLabel *lookup_titles_label; + QComboBox *lookup_titles_box; + QStringList lookup_titles_key; + QPushButton *lookup_ok_button; + QPushButton *lookup_cancel_button; + RDCddbRecord *lookup_record; + QTcpSocket *lookup_socket; + int lookup_state; + QString lookup_username; + QString lookup_appname; + QString lookup_appver; + QString lookup_hostname; + QDir lookup_cdda_dir; + FILE *lookup_profile_msgs; +}; + +#endif // RDDISCLOOKUP_H diff --git a/rdlibrary/cdripper.cpp b/rdlibrary/cdripper.cpp index a106eabd..51e53476 100644 --- a/rdlibrary/cdripper.cpp +++ b/rdlibrary/cdripper.cpp @@ -53,20 +53,6 @@ CdRipper::CdRipper(QString cutname,RDCddbRecord *rec,RDLibraryConf *conf, // setMinimumSize(sizeHint()); - // - // Create Temporary Directory - // - char path[PATH_MAX]; - strncpy(path,RDTempDirectory::basePath(),PATH_MAX); - strcat(path,"/XXXXXX"); - if(mkdtemp(path)==NULL) { - QMessageBox::warning(this,"RDLibrary - "+tr("Ripper Error"), - tr("Unable to create temporary directory!")); - } - else { - rip_cdda_dir.setPath(path); - } - // // Target Cut // @@ -97,8 +83,8 @@ CdRipper::CdRipper(QString cutname,RDCddbRecord *rec,RDLibraryConf *conf, else { rip_cddb_lookup=new RDCddbLookup("RDLibrary",NULL,this); } - connect(rip_cddb_lookup,SIGNAL(lookupDone(RDCddbLookup::Result)), - this,SLOT(cddbDoneData(RDCddbLookup::Result))); + connect(rip_cddb_lookup,SIGNAL(lookupDone(RDDiscLookup::Result)), + this,SLOT(cddbDoneData(RDDiscLookup::Result))); // // Title Selector @@ -278,14 +264,6 @@ CdRipper::CdRipper(QString cutname,RDCddbRecord *rec,RDLibraryConf *conf, CdRipper::~CdRipper() { - QStringList files=rip_cdda_dir.entryList(); - for(int i=0;iclose(); delete rip_cdrom; delete rip_track_list; @@ -434,7 +412,7 @@ void CdRipper::ripTrackButtonData() // if(!rip_isrc_read) { if(rda->libraryConf()->readIsrc()) { - rip_cddb_lookup->readIsrc(rip_cdda_dir.path(),rip_conf->ripperDevice()); + rip_cddb_lookup->readIsrc(); } rip_isrc_read=true; } @@ -575,9 +553,7 @@ void CdRipper::mediaChangedData() rip_cdrom->setCddbRecord(rip_cddb_record); rip_cddb_lookup->setCddbRecord(rip_cddb_record); Profile("starting metadata lookup"); - rip_cddb_lookup->lookupRecord(rip_cdda_dir.path(),rip_conf->ripperDevice(), - rip_conf->cddbServer(),8880, - RIPPER_CDDB_USER,PACKAGE_NAME,VERSION); + rip_cddb_lookup->lookup(); Profile("metadata lookup finished"); } @@ -596,10 +572,10 @@ void CdRipper::stoppedData() } -void CdRipper::cddbDoneData(RDCddbLookup::Result result) +void CdRipper::cddbDoneData(RDDiscLookup::Result result) { switch(result) { - case RDCddbLookup::ExactMatch: + case RDDiscLookup::ExactMatch: if(rip_cdrom->status()!=RDCdPlayer::Ok) { return; } @@ -618,7 +594,7 @@ void CdRipper::cddbDoneData(RDCddbLookup::Result result) trackSelectionChangedData(); break; - case RDCddbLookup::PartialMatch: + case RDDiscLookup::PartialMatch: rip_track[0]=-1; rip_track[1]=-1; printf("Partial Match!\n"); diff --git a/rdlibrary/cdripper.h b/rdlibrary/cdripper.h index 5cb1338e..f26d18e7 100644 --- a/rdlibrary/cdripper.h +++ b/rdlibrary/cdripper.h @@ -2,7 +2,7 @@ // // CD Ripper Dialog for Rivendell // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -57,7 +57,7 @@ class CdRipper : public RDDialog void mediaChangedData(); void playedData(int); void stoppedData(); - void cddbDoneData(RDCddbLookup::Result); + void cddbDoneData(RDDiscLookup::Result); void normalizeCheckData(bool); void autotrimCheckData(bool); void closeData(); @@ -110,7 +110,6 @@ class CdRipper : public RDDialog QLabel *rip_autotrim_unit; bool rip_done; bool rip_profile_rip; - QDir rip_cdda_dir; bool rip_isrc_read; }; diff --git a/rdlibrary/disk_ripper.cpp b/rdlibrary/disk_ripper.cpp index ba9f6abf..805e6355 100644 --- a/rdlibrary/disk_ripper.cpp +++ b/rdlibrary/disk_ripper.cpp @@ -2,7 +2,7 @@ // // CD Disk Ripper Dialog for Rivendell. // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -55,20 +55,6 @@ DiskRipper::DiskRipper(QString *filter,QString *group,QString *schedcode, // rip_wavedata_dialog=new RDWaveDataDialog("RDLibrary",this); - // - // Create Temporary Directory - // - char path[PATH_MAX]; - strncpy(path,RDTempDirectory::basePath(),PATH_MAX); - strcat(path,"/XXXXXX"); - if(mkdtemp(path)==NULL) { - QMessageBox::warning(this,"RDLibrary - "+tr("Ripper Error"), - tr("Unable to create temporary directory!")); - } - else { - rip_cdda_dir.setPath(path); - } - // // The CDROM Drive // @@ -94,8 +80,8 @@ DiskRipper::DiskRipper(QString *filter,QString *group,QString *schedcode, else { rip_cddb_lookup=new RDCddbLookup("RDLibrary",NULL,this); } - connect(rip_cddb_lookup,SIGNAL(lookupDone(RDCddbLookup::Result)), - this,SLOT(cddbDoneData(RDCddbLookup::Result))); + connect(rip_cddb_lookup,SIGNAL(lookupDone(RDDiscLookup::Result)), + this,SLOT(cddbDoneData(RDDiscLookup::Result))); // // Artist Label @@ -326,14 +312,6 @@ DiskRipper::DiskRipper(QString *filter,QString *group,QString *schedcode, DiskRipper::~DiskRipper() { - QStringList files=rip_cdda_dir.entryList(); - for(int i=0;iclose(); delete rip_cdrom; delete rip_track_list; @@ -407,8 +385,7 @@ void DiskRipper::ripDiskButtonData() // if(!rip_isrc_read) { if(rda->libraryConf()->readIsrc()) { - rip_cddb_lookup-> - readIsrc(rip_cdda_dir.path(),rda->libraryConf()->ripperDevice()); + rip_cddb_lookup->readIsrc(); } rip_isrc_read=true; } @@ -477,8 +454,6 @@ void DiskRipper::ripDiskButtonData() item=(RDListViewItem *)item->nextSibling(); } -// rip_cdrom->eject(); - if(rip_aborting) { QMessageBox::information(this,tr("Rip Complete"),tr("Rip aborted!")); } @@ -789,10 +764,7 @@ void DiskRipper::mediaChangedData() rip_cddb_record.clear(); rip_cdrom->setCddbRecord(&rip_cddb_record); rip_cddb_lookup->setCddbRecord(&rip_cddb_record); - rip_cddb_lookup-> - lookupRecord(rip_cdda_dir.path(),rda->libraryConf()->ripperDevice(), - rda->libraryConf()->cddbServer(),8880, - RIPPER_CDDB_USER,PACKAGE_NAME,VERSION); + rip_cddb_lookup->lookup(); QApplication::restoreOverrideCursor(); } @@ -812,10 +784,10 @@ void DiskRipper::stoppedData() } -void DiskRipper::cddbDoneData(RDCddbLookup::Result result) +void DiskRipper::cddbDoneData(RDDiscLookup::Result result) { switch(result) { - case RDCddbLookup::ExactMatch: + case RDDiscLookup::ExactMatch: if(rip_cdrom->status()!=RDCdPlayer::Ok) { return; } @@ -835,7 +807,7 @@ void DiskRipper::cddbDoneData(RDCddbLookup::Result result) rip_apply_box->setEnabled(true); rip_apply_label->setEnabled(true); break; - case RDCddbLookup::PartialMatch: + case RDDiscLookup::PartialMatch: rip_track=-1; printf("Partial Match!\n"); break; diff --git a/rdlibrary/disk_ripper.h b/rdlibrary/disk_ripper.h index c18b2f88..ca3520cd 100644 --- a/rdlibrary/disk_ripper.h +++ b/rdlibrary/disk_ripper.h @@ -2,7 +2,7 @@ // // CD Disk Ripper Dialog for Rivendell // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -57,7 +57,7 @@ class DiskRipper : public RDDialog void mediaChangedData(); void playedData(int); void stoppedData(); - void cddbDoneData(RDCddbLookup::Result); + void cddbDoneData(RDDiscLookup::Result); void normalizeCheckData(bool); void autotrimCheckData(bool); void selectionChangedData(); @@ -125,7 +125,6 @@ class DiskRipper : public RDDialog std::vector rip_wave_datas; bool rip_aborting; bool rip_profile_rip; - QDir rip_cdda_dir; bool rip_isrc_read; RDWaveDataDialog *rip_wavedata_dialog; }; diff --git a/rdlibrary/rdlibrary_cs.ts b/rdlibrary/rdlibrary_cs.ts index b9e92869..81d7c532 100644 --- a/rdlibrary/rdlibrary_cs.ts +++ b/rdlibrary/rdlibrary_cs.ts @@ -451,14 +451,6 @@ vytahování [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD Vytáhnout z CD @@ -687,14 +679,6 @@ z CD Vytažení zrušeno! - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/rdlibrary/rdlibrary_de.ts b/rdlibrary/rdlibrary_de.ts index 933ec58c..c059a7b1 100644 --- a/rdlibrary/rdlibrary_de.ts +++ b/rdlibrary/rdlibrary_de.ts @@ -451,14 +451,6 @@ abbrechen [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD CD rippen @@ -686,14 +678,6 @@ Rippen Rip aborted! Rip abgebrochen! - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/rdlibrary/rdlibrary_es.ts b/rdlibrary/rdlibrary_es.ts index e91ea47f..7761adfe 100644 --- a/rdlibrary/rdlibrary_es.ts +++ b/rdlibrary/rdlibrary_es.ts @@ -451,14 +451,6 @@ Lectura [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD Leer CD @@ -687,14 +679,6 @@ Disco ¡Lectura Abortada! - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/rdlibrary/rdlibrary_fr.ts b/rdlibrary/rdlibrary_fr.ts index 4886a13d..e0841354 100644 --- a/rdlibrary/rdlibrary_fr.ts +++ b/rdlibrary/rdlibrary_fr.ts @@ -343,14 +343,6 @@ Rip [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD @@ -523,14 +515,6 @@ Disk Rip aborted! - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/rdlibrary/rdlibrary_nb.ts b/rdlibrary/rdlibrary_nb.ts index 131b637a..4669bc42 100644 --- a/rdlibrary/rdlibrary_nb.ts +++ b/rdlibrary/rdlibrary_nb.ts @@ -441,14 +441,6 @@ Rip [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD Ripp CD @@ -679,14 +671,6 @@ Disk Rip aborted! - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/rdlibrary/rdlibrary_nn.ts b/rdlibrary/rdlibrary_nn.ts index 131b637a..4669bc42 100644 --- a/rdlibrary/rdlibrary_nn.ts +++ b/rdlibrary/rdlibrary_nn.ts @@ -441,14 +441,6 @@ Rip [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD Ripp CD @@ -679,14 +671,6 @@ Disk Rip aborted! - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/rdlibrary/rdlibrary_pt_BR.ts b/rdlibrary/rdlibrary_pt_BR.ts index 410c47a5..a2bcc9ca 100644 --- a/rdlibrary/rdlibrary_pt_BR.ts +++ b/rdlibrary/rdlibrary_pt_BR.ts @@ -442,14 +442,6 @@ Rip [none] - - Ripper Error - - - - Unable to create temporary directory! - - Rip CD Extrair CD @@ -680,14 +672,6 @@ Disk RDLibrary - Ripper Error - - Ripper Error - - - - Unable to create temporary directory! - - Track diff --git a/tests/mblookup_test.cpp b/tests/mblookup_test.cpp new file mode 100644 index 00000000..e69de29b diff --git a/tests/mblookup_test.h b/tests/mblookup_test.h new file mode 100644 index 00000000..e69de29b