summaryrefslogtreecommitdiffstats
path: root/libk3b/cddb
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-03 02:15:56 +0000
commit50b48aec6ddd451a6d1709c0942477b503457663 (patch)
treea9ece53ec06fd0a2819de7a2a6de997193566626 /libk3b/cddb
downloadk3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz
k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libk3b/cddb')
-rw-r--r--libk3b/cddb/Makefile.am9
-rw-r--r--libk3b/cddb/k3bcddb.cpp280
-rw-r--r--libk3b/cddb/k3bcddb.h103
-rw-r--r--libk3b/cddb/k3bcddbhttpquery.cpp233
-rw-r--r--libk3b/cddb/k3bcddbhttpquery.h64
-rw-r--r--libk3b/cddb/k3bcddblocalquery.cpp129
-rw-r--r--libk3b/cddb/k3bcddblocalquery.h48
-rw-r--r--libk3b/cddb/k3bcddblocalsubmit.cpp102
-rw-r--r--libk3b/cddb/k3bcddblocalsubmit.h43
-rw-r--r--libk3b/cddb/k3bcddbmultientriesdialog.cpp74
-rw-r--r--libk3b/cddb/k3bcddbmultientriesdialog.h48
-rw-r--r--libk3b/cddb/k3bcddbpquery.cpp278
-rw-r--r--libk3b/cddb/k3bcddbpquery.h62
-rw-r--r--libk3b/cddb/k3bcddbquery.cpp275
-rw-r--r--libk3b/cddb/k3bcddbquery.h115
-rw-r--r--libk3b/cddb/k3bcddbresult.cpp49
-rw-r--r--libk3b/cddb/k3bcddbresult.h79
-rw-r--r--libk3b/cddb/k3bcddbsubmit.cpp84
-rw-r--r--libk3b/cddb/k3bcddbsubmit.h60
19 files changed, 2135 insertions, 0 deletions
diff --git a/libk3b/cddb/Makefile.am b/libk3b/cddb/Makefile.am
new file mode 100644
index 0000000..e73c5ce
--- /dev/null
+++ b/libk3b/cddb/Makefile.am
@@ -0,0 +1,9 @@
+AM_CPPFLAGS = -I$(srcdir)/../core -I$(srcdir)/../../libk3bdevice -I$(srcdir)/../../src $(all_includes)
+
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libcddb.la
+
+libcddb_la_SOURCES = k3bcddbquery.cpp k3bcddb.cpp k3bcddbresult.cpp k3bcddbhttpquery.cpp k3bcddbpquery.cpp k3bcddblocalquery.cpp k3bcddbsubmit.cpp k3bcddblocalsubmit.cpp k3bcddbmultientriesdialog.cpp
+
+include_HEADERS = k3bcddb.h k3bcddbresult.h
diff --git a/libk3b/cddb/k3bcddb.cpp b/libk3b/cddb/k3bcddb.cpp
new file mode 100644
index 0000000..a0e4fe1
--- /dev/null
+++ b/libk3b/cddb/k3bcddb.cpp
@@ -0,0 +1,280 @@
+/*
+ *
+ * $Id: k3bcddb.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kdeversion.h>
+
+#include "k3bcddb.h"
+#include "k3bcddbhttpquery.h"
+#include "k3bcddbpquery.h"
+#include "k3bcddblocalquery.h"
+#include "k3bcddblocalsubmit.h"
+
+#include <k3btoc.h>
+#include <k3btrack.h>
+#include "k3bcddbmultientriesdialog.h"
+
+
+K3bCddb::K3bCddb( QObject* parent, const char* name )
+ : QObject( parent, name )
+{
+ m_httpQuery = 0;
+ m_cddbpQuery = 0;
+ m_localQuery = 0;
+ m_localSubmit = 0;
+
+ m_lastUsedQuery = 0;
+}
+
+
+K3bCddb::~K3bCddb()
+{
+}
+
+
+void K3bCddb::readConfig( KConfig* c )
+{
+ c->setGroup( "Cddb" );
+
+ m_bRemoteCddbQuery = c->readBoolEntry( "use remote cddb", true );
+ m_bLocalCddbQuery = c->readBoolEntry( "use local cddb query", false );
+
+ // old config <= 0.7.3
+ QStringList cddbpServer = c->readListEntry( "cddbp server" );
+ QStringList httpServer = c->readListEntry( "http server" );
+
+ // new config
+ m_cddbServer = c->readListEntry( "cddb server" );
+
+ m_localCddbDirs = c->readPathListEntry( "local cddb dirs" );
+
+ m_bUseManualCgiPath = c->readBoolEntry( "use manual cgi path", false );
+ m_cgiPath = c->readEntry( "cgi path", "/~cddb/cddb.cgi" );
+
+ if( m_localCddbDirs.isEmpty() )
+ m_localCddbDirs.append( "~/.cddb/" );
+
+ // old config <= 0.7.3
+ if( !httpServer.isEmpty() ) {
+ for( QStringList::iterator it = httpServer.begin(); it != httpServer.end(); ++it ) {
+ m_cddbServer.append( "Http " + *it );
+ }
+ }
+ if( !cddbpServer.isEmpty() ) {
+ for( QStringList::iterator it = cddbpServer.begin(); it != cddbpServer.end(); ++it ) {
+ m_cddbServer.append( "Cddbp " + *it );
+ }
+ }
+
+ if( m_cddbServer.isEmpty() )
+ m_cddbServer.append( "Http freedb2.org:80" );
+}
+
+
+void K3bCddb::query( const K3bDevice::Toc& toc )
+{
+ m_toc = toc;
+
+ if( m_bLocalCddbQuery ) {
+ m_iCurrentQueriedLocalDir = 0;
+ QTimer::singleShot( 0, this, SLOT(localQuery()) );
+ }
+ else if( m_bRemoteCddbQuery ) {
+ m_iCurrentQueriedServer = 0;
+ QTimer::singleShot( 0, this, SLOT(remoteQuery()) );
+ }
+ else {
+ QTimer::singleShot( 0, this, SLOT(slotNoEntry()) );
+ }
+}
+
+
+void K3bCddb::slotNoEntry()
+{
+ emit queryFinished( K3bCddbQuery::NO_ENTRY_FOUND );
+}
+
+
+void K3bCddb::remoteQuery()
+{
+ K3bCddbQuery* q = getQuery( m_cddbServer[m_iCurrentQueriedServer] );
+ q->query(m_toc);
+}
+
+
+void K3bCddb::slotMultibleMatches( K3bCddbQuery* query )
+{
+ K3bCddbResultHeader hdr = K3bCddbMultiEntriesDialog::selectCddbEntry( query, 0 );
+ if( !hdr.discid.isEmpty() )
+ query->queryMatch( hdr );
+ else
+ emit queryFinished( K3bCddbQuery::CANCELED );
+}
+
+
+void K3bCddb::slotQueryFinished( K3bCddbQuery* query )
+{
+ m_lastUsedQuery = query;
+
+ if( query->error() == K3bCddbQuery::SUCCESS ) {
+ m_lastResult = m_lastUsedQuery->result();
+
+ // make sure the result has the requested discid since otherwise local saving does not make much sense
+ m_lastResult.discid = QString::number( m_toc.discId(), 16 ).rightJustify( 8, '0' );
+
+ emit queryFinished( K3bCddbQuery::SUCCESS );
+ }
+ else if( query == m_localQuery ) {
+ m_iCurrentQueriedLocalDir++;
+ if( m_iCurrentQueriedLocalDir < m_localCddbDirs.size() )
+ localQuery();
+ else if( m_bRemoteCddbQuery ) {
+ m_iCurrentQueriedServer = 0;
+ remoteQuery();
+ }
+ else {
+ emit queryFinished( query->error() );
+ }
+ }
+ else {
+ m_iCurrentQueriedServer++;
+ if( m_iCurrentQueriedServer < m_cddbServer.size() ) {
+ remoteQuery();
+ }
+ else {
+ emit queryFinished( query->error() );
+ }
+ }
+}
+
+
+K3bCddbQuery* K3bCddb::getQuery( const QString& s )
+{
+ QStringList buf = QStringList::split( ":", s.mid( s.find(" ")+1 ) );
+ QString server = buf[0];
+ int port = buf[1].toInt();
+
+ if( s.startsWith("Http") ) {
+ if( !m_httpQuery ) {
+ m_httpQuery = new K3bCddbHttpQuery( this );
+ connect( m_httpQuery, SIGNAL(infoMessage(const QString&)),
+ this, SIGNAL(infoMessage(const QString&)) );
+ connect( m_httpQuery, SIGNAL(queryFinished(K3bCddbQuery*)),
+ this, SLOT(slotQueryFinished(K3bCddbQuery*)) );
+ connect( m_httpQuery, SIGNAL(inexactMatches(K3bCddbQuery*)),
+ this, SLOT(slotMultibleMatches(K3bCddbQuery*)) );
+ }
+
+ m_httpQuery->setServer( server, port );
+ m_httpQuery->setCgiPath( m_bUseManualCgiPath ? m_cgiPath : QString::fromLatin1("/~cddb/cddb.cgi") );
+
+ return m_httpQuery;
+ }
+ else {
+ if( !m_cddbpQuery ) {
+ m_cddbpQuery = new K3bCddbpQuery( this );
+ connect( m_cddbpQuery, SIGNAL(infoMessage(const QString&)),
+ this, SIGNAL(infoMessage(const QString&)) );
+ connect( m_cddbpQuery, SIGNAL(queryFinished(K3bCddbQuery*)),
+ this, SLOT(slotQueryFinished(K3bCddbQuery*)) );
+ connect( m_cddbpQuery, SIGNAL(inexactMatches(K3bCddbQuery*)),
+ this, SLOT(slotMultibleMatches(K3bCddbQuery*)) );
+ }
+
+ m_cddbpQuery->setServer( server, port );
+
+ return m_cddbpQuery;
+ }
+}
+
+
+void K3bCddb::localQuery()
+{
+ if( !m_localQuery ) {
+ m_localQuery = new K3bCddbLocalQuery( this );
+ connect( m_localQuery, SIGNAL(infoMessage(const QString&)),
+ this, SIGNAL(infoMessage(const QString&)) );
+ connect( m_localQuery, SIGNAL(queryFinished(K3bCddbQuery*)),
+ this, SLOT(slotQueryFinished(K3bCddbQuery*)) );
+ connect( m_localQuery, SIGNAL(inexactMatches(K3bCddbQuery*)),
+ this, SLOT(slotMultibleMatches(K3bCddbQuery*)) );
+ }
+
+ m_localQuery->setCddbDir( m_localCddbDirs[m_iCurrentQueriedLocalDir] );
+
+ m_localQuery->query( m_toc );
+}
+
+
+QString K3bCddb::errorString() const
+{
+ if( !m_lastUsedQuery )
+ return "no query";
+
+ switch( m_lastUsedQuery->error() ) {
+ case K3bCddbQuery::SUCCESS:
+ return i18n("Found freedb entry.");
+ case K3bCddbQuery::NO_ENTRY_FOUND:
+ return i18n("No entry found");
+ case K3bCddbQuery::CONNECTION_ERROR:
+ return i18n("Error while connecting to host.");
+ case K3bCddbQuery::WORKING:
+ return i18n("Working...");
+ case K3bCddbQuery::QUERY_ERROR:
+ case K3bCddbQuery::READ_ERROR:
+ case K3bCddbQuery::FAILURE:
+ default:
+ return i18n("Communication error.");
+ }
+}
+
+
+const K3bCddbResultEntry& K3bCddb::result() const
+{
+ // return m_lastUsedQuery->result();
+ return m_lastResult;
+}
+
+
+void K3bCddb::saveEntry( const K3bCddbResultEntry& entry )
+{
+ if( !m_localSubmit ) {
+ m_localSubmit = new K3bCddbLocalSubmit( this );
+ connect( m_localSubmit, SIGNAL(submitFinished(K3bCddbSubmit*)),
+ this, SLOT(slotSubmitFinished(K3bCddbSubmit*)) );
+ }
+
+ m_localSubmit->setCddbDir( m_localCddbDirs[0] );
+
+ m_localSubmit->submit( entry );
+}
+
+
+void K3bCddb::slotSubmitFinished( K3bCddbSubmit* s )
+{
+ emit submitFinished( s->error() == K3bCddbSubmit::SUCCESS );
+}
+
+#include "k3bcddb.moc"
+
diff --git a/libk3b/cddb/k3bcddb.h b/libk3b/cddb/k3bcddb.h
new file mode 100644
index 0000000..86b67c5
--- /dev/null
+++ b/libk3b/cddb/k3bcddb.h
@@ -0,0 +1,103 @@
+/*
+ *
+ * $Id: k3bcddb.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDB_H
+#define K3BCDDB_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qobject.h>
+
+#include <k3btoc.h>
+
+#include "k3bcddbresult.h"
+#include "k3b_export.h"
+
+class KConfig;
+class K3bCddbQuery;
+class K3bCddbHttpQuery;
+class K3bCddbpQuery;
+class K3bCddbLocalQuery;
+class K3bCddbSubmit;
+class K3bCddbLocalSubmit;
+
+
+class LIBK3B_EXPORT K3bCddb : public QObject
+{
+ Q_OBJECT
+
+ public:
+ K3bCddb( QObject* parent = 0, const char* name = 0 );
+ ~K3bCddb();
+
+ QString errorString() const;
+
+ /**
+ * Do NOT call this before queryResult has
+ * been emitted
+ */
+ const K3bCddbResultEntry& result() const;
+
+ public slots:
+ /** query a cd and connect to the queryFinished signal */
+ void query( const K3bDevice::Toc& );
+ void readConfig( KConfig* c );
+ void saveEntry( const K3bCddbResultEntry& );
+
+ signals:
+ void queryFinished( int error );
+ void submitFinished( bool success );
+ void infoMessage( const QString& );
+
+ private slots:
+ void localQuery();
+ void remoteQuery();
+ void slotQueryFinished( K3bCddbQuery* );
+ void slotSubmitFinished( K3bCddbSubmit* );
+ void slotMultibleMatches( K3bCddbQuery* );
+ void slotNoEntry();
+
+ private:
+ K3bCddbQuery* getQuery( const QString& );
+
+ K3bCddbHttpQuery* m_httpQuery;
+ K3bCddbpQuery* m_cddbpQuery;
+ K3bCddbLocalQuery* m_localQuery;
+ K3bCddbLocalSubmit* m_localSubmit;
+
+ K3bDevice::Toc m_toc;
+ unsigned int m_iCurrentQueriedServer;
+ unsigned int m_iCurrentQueriedLocalDir;
+
+ const K3bCddbQuery* m_lastUsedQuery;
+ K3bCddbResultEntry m_lastResult;
+
+ // config
+ QStringList m_cddbServer;
+ QString m_proxyServer;
+ int m_proxyPort;
+ QString m_cgiPath;
+ bool m_bUseProxyServer;
+ bool m_bUseKdeSettings;
+ QStringList m_localCddbDirs;
+ bool m_bSaveCddbEntriesLocally;
+ bool m_bUseManualCgiPath;
+ bool m_bRemoteCddbQuery;
+ bool m_bLocalCddbQuery;
+};
+
+
+#endif
diff --git a/libk3b/cddb/k3bcddbhttpquery.cpp b/libk3b/cddb/k3bcddbhttpquery.cpp
new file mode 100644
index 0000000..a453c3e
--- /dev/null
+++ b/libk3b/cddb/k3bcddbhttpquery.cpp
@@ -0,0 +1,233 @@
+/*
+ *
+ * $Id: k3bcddbhttpquery.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#include "k3bcddbhttpquery.h"
+
+#include "k3bcddbresult.h"
+
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kio/global.h>
+#include <kio/job.h>
+
+
+K3bCddbHttpQuery::K3bCddbHttpQuery( QObject* parent, const char* name )
+ : K3bCddbQuery( parent, name )
+{
+ m_server = "freedb.org";
+ m_port = 80;
+ m_cgiPath = "/~cddb/cddb.cgi";
+}
+
+
+K3bCddbHttpQuery::~K3bCddbHttpQuery()
+{
+}
+
+
+void K3bCddbHttpQuery::doQuery()
+{
+ setError( WORKING );
+ m_state = QUERY;
+
+ performCommand( queryString() );
+}
+
+
+void K3bCddbHttpQuery::doMatchQuery()
+{
+ setError( WORKING );
+ m_state = READ;
+ m_parsingBuffer.truncate(0);
+
+ performCommand( QString( "cddb read %1 %2").arg( header().category ).arg( header().discid ) );
+}
+
+
+void K3bCddbHttpQuery::performCommand( const QString& cmd )
+{
+ KURL url;
+ url.setProtocol( "http" );
+ url.setHost( m_server );
+ url.setPort( m_port );
+ url.setPath( m_cgiPath );
+
+ url.addQueryItem( "cmd", cmd );
+ url.addQueryItem( "hello", handshakeString() );
+ url.addQueryItem( "proto", "6" );
+
+ m_data.truncate(0);
+
+ kdDebug() << "(K3bCddbHttpQuery) getting url: " << url.prettyURL() << endl;
+
+ KIO::TransferJob* job = KIO::get( url, false, false );
+
+ if( !job ) {
+ setError( CONNECTION_ERROR );
+ emit infoMessage( i18n("Could not connect to host %1").arg(m_server) );
+ emitQueryFinished();
+ return;
+ }
+
+ connect( job, SIGNAL(data(KIO::Job*, const QByteArray&)),
+ SLOT(slotData(KIO::Job*, const QByteArray&)) );
+ connect( job, SIGNAL(result(KIO::Job*)),
+ SLOT(slotResult(KIO::Job*)) );
+}
+
+
+
+void K3bCddbHttpQuery::slotData( KIO::Job*, const QByteArray& data )
+{
+ if( data.size() ) {
+ QDataStream stream( m_data, IO_WriteOnly | IO_Append );
+ stream.writeRawBytes( data.data(), data.size() );
+ }
+}
+
+
+void K3bCddbHttpQuery::slotResult( KIO::Job* job )
+{
+ if( job->error() ) {
+ emit infoMessage( job->errorString() );
+ setError( CONNECTION_ERROR );
+ emitQueryFinished();
+ return;
+ }
+
+ QStringList lines = QStringList::split( "\n", QString::fromUtf8( m_data.data(), m_data.size() ) );
+
+ for( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it ) {
+ QString line = *it;
+
+ // kdDebug() << "(K3bCddbHttpQuery) line: " << line << endl;
+
+ switch( m_state ) {
+
+ case QUERY:
+ if( getCode( line ) == 200 ) {
+ // parse exact match and send a read command
+ K3bCddbResultHeader header;
+ parseMatchHeader( line.mid(4), header );
+
+ queryMatch( header );
+ }
+
+ else if( getCode( line ) == 210 ) {
+ // TODO: perhaps add an "exact" field to K3bCddbEntry
+ kdDebug() << "(K3bCddbHttpQuery) Found multiple exact matches" << endl;
+
+ emit infoMessage( i18n("Found multiple exact matches") );
+
+ m_state = QUERY_DATA;
+ }
+
+ else if( getCode( line ) == 211 ) {
+ kdDebug() << "(K3bCddbHttpQuery) Found inexact matches" << endl;
+
+ emit infoMessage( i18n("Found inexact matches") );
+
+ m_state = QUERY_DATA;
+ }
+
+ else if( getCode( line ) == 202 ) {
+ kdDebug() << "(K3bCddbHttpQuery) no match found" << endl;
+ emit infoMessage( i18n("No match found") );
+ setError(NO_ENTRY_FOUND);
+ m_state = FINISHED;
+ emitQueryFinished();
+ return;
+ }
+
+ else {
+ kdDebug() << "(K3bCddbHttpQuery) Error while querying: " << line << endl;
+ emit infoMessage( i18n("Error while querying") );
+ setError(QUERY_ERROR);
+ m_state = FINISHED;
+ emitQueryFinished();
+ return;
+ }
+ break;
+
+ case QUERY_DATA:
+ if( line.startsWith( "." ) ) {
+ // finished query
+ // go on reading
+
+
+ // here we have the inexact matches headers and should emit the
+ // inexactMatches signal
+ emit inexactMatches( this );
+ }
+ else {
+ kdDebug() << "(K3bCddbHttpQuery) inexact match: " << line << endl;
+
+ // create a new resultHeader
+ K3bCddbResultHeader header;
+ parseMatchHeader( line, header );
+ m_inexactMatches.append(header);
+ }
+ break;
+
+ case READ:
+ if( getCode( line ) == 210 ) {
+
+ // we just start parsing the read data
+ m_state = READ_DATA;
+ }
+
+ else {
+ emit infoMessage( i18n("Could not read match") );
+ setError(READ_ERROR);
+ m_state = FINISHED;
+ emitQueryFinished();
+ return;
+ }
+ break;
+
+
+ case READ_DATA:
+
+ // kdDebug() << "parsing line: " << line << endl;
+
+ if( line.startsWith( "." ) ) {
+
+ kdDebug() << "(K3bCddbHttpQuery query finished." << endl;
+
+ QTextStream strStream( m_parsingBuffer, IO_ReadOnly );
+ parseEntry( strStream, result() );
+
+ setError(SUCCESS);
+ m_state = FINISHED;
+ emitQueryFinished();
+ return;
+ }
+
+ else {
+ m_parsingBuffer.append(line + "\n");
+ }
+ break;
+ }
+ }
+}
+
+
+#include "k3bcddbhttpquery.moc"
diff --git a/libk3b/cddb/k3bcddbhttpquery.h b/libk3b/cddb/k3bcddbhttpquery.h
new file mode 100644
index 0000000..b1e544e
--- /dev/null
+++ b/libk3b/cddb/k3bcddbhttpquery.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * $Id: k3bcddbhttpquery.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDB_HTTP_QUERY_H
+#define K3BCDDB_HTTP_QUERY_H
+
+#include "k3bcddbquery.h"
+#include "k3bcddbresult.h"
+
+#include <qvaluelist.h>
+
+namespace KIO {
+ class Job;
+}
+
+class K3bCddbHttpQuery : public K3bCddbQuery
+{
+ Q_OBJECT
+
+ public:
+ K3bCddbHttpQuery( QObject* parent = 0, const char* name = 0 );
+ ~K3bCddbHttpQuery();
+
+ public slots:
+ void setServer( const QString& s, int port = 80 ) { m_server = s; m_port = port; }
+ void setCgiPath( const QString& p ) { m_cgiPath = p; }
+
+ protected slots:
+ void doQuery();
+ void doMatchQuery();
+ void slotResult( KIO::Job* );
+ void slotData( KIO::Job*, const QByteArray& data );
+
+ private:
+ void performCommand( const QString& );
+
+ enum State { QUERY, QUERY_DATA, READ, READ_DATA, FINISHED };
+
+ int m_state;
+ QString m_server;
+ int m_port;
+ QString m_cgiPath;
+
+ QString m_currentlyConnectingServer;
+
+ QByteArray m_data;
+ QString m_parsingBuffer;
+};
+
+#endif
+
diff --git a/libk3b/cddb/k3bcddblocalquery.cpp b/libk3b/cddb/k3bcddblocalquery.cpp
new file mode 100644
index 0000000..b3a1264
--- /dev/null
+++ b/libk3b/cddb/k3bcddblocalquery.cpp
@@ -0,0 +1,129 @@
+/*
+ *
+ * $Id: k3bcddblocalquery.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bcddblocalquery.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+
+K3bCddbLocalQuery::K3bCddbLocalQuery( QObject* parent , const char* name )
+ : K3bCddbQuery( parent, name )
+{
+}
+
+
+K3bCddbLocalQuery::~K3bCddbLocalQuery()
+{
+}
+
+
+void K3bCddbLocalQuery::doQuery()
+{
+ emit infoMessage( i18n("Searching entry in %1").arg( m_cddbDir ) );
+ kapp->processEvents(); //BAD!
+
+ QString path = preparePath( m_cddbDir );
+
+ kdDebug() << "(K3bCddbLocalQuery) searching in dir " << path << " for "
+ << QString::number( toc().discId(), 16 ).rightJustify( 8, '0' ) << endl;
+
+ for( QStringList::const_iterator it = categories().begin();
+ it != categories().end(); ++it ) {
+
+ QString file = path + *it + "/" + QString::number( toc().discId(), 16 ).rightJustify( 8, '0' );
+
+ if( QFile::exists( file ) ) {
+ // found file
+
+ QFile f( file );
+ if( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "(K3bCddbLocalQuery) Could not open file" << endl;
+ }
+ else {
+ QTextStream t( &f );
+
+ K3bCddbResultEntry entry;
+ parseEntry( t, entry );
+ K3bCddbResultHeader header;
+ header.discid = QString::number( toc().discId(), 16 ).rightJustify( 8, '0' );
+ header.category = *it;
+ header.title = entry.cdTitle;
+ header.artist = entry.cdArtist;
+ m_inexactMatches.append(header);
+ }
+ }
+ else {
+ kdDebug() << "(K3bCddbLocalQuery) Could not find local entry in category " << *it << endl;
+ }
+ }
+
+ if( m_inexactMatches.count() > 0 ) {
+ setError( SUCCESS );
+ if( m_inexactMatches.count() == 1 ) {
+ queryMatch( m_inexactMatches.first() );
+ }
+ else {
+ emit inexactMatches( this );
+ }
+ }
+ else {
+ setError( NO_ENTRY_FOUND );
+ emit queryFinished( this );
+ }
+}
+
+
+void K3bCddbLocalQuery::doMatchQuery()
+{
+ QString path = preparePath( m_cddbDir ) + header().category + "/" + header().discid;
+
+ QFile f( path );
+ if( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "(K3bCddbLocalQuery) Could not open file" << endl;
+ setError( READ_ERROR );
+ }
+ else {
+ QTextStream t( &f );
+
+ parseEntry( t, result() );
+ result().discid = header().discid;
+ result().category = header().category;
+ setError( SUCCESS );
+ }
+ emit queryFinished( this );
+}
+
+
+QString K3bCddbLocalQuery::preparePath( const QString& p )
+{
+ QString path = p;
+ if( path.startsWith( "~" ) )
+ path.replace( 0, 1, QDir::homeDirPath() );
+ else if( !path.startsWith( "/" ) )
+ path.prepend( QDir::homeDirPath() );
+ if( path[path.length()-1] != '/' )
+ path.append( "/" );
+
+ return path;
+}
+
+#include "k3bcddblocalquery.moc"
diff --git a/libk3b/cddb/k3bcddblocalquery.h b/libk3b/cddb/k3bcddblocalquery.h
new file mode 100644
index 0000000..d68d379
--- /dev/null
+++ b/libk3b/cddb/k3bcddblocalquery.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * $Id: k3bcddblocalquery.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#ifndef K3BCDDB_LOCAL_QUERY_H
+#define K3BCDDB_LOCAL_QUERY_H
+
+#include "k3bcddbquery.h"
+#include "k3bcddbresult.h"
+
+#include <qstring.h>
+
+
+class K3bCddbLocalQuery : public K3bCddbQuery
+{
+ Q_OBJECT
+
+ public:
+ K3bCddbLocalQuery( QObject* parent = 0, const char* name = 0 );
+ ~K3bCddbLocalQuery();
+
+ public slots:
+ void setCddbDir( const QString& dir ) { m_cddbDir = dir; }
+
+ protected:
+ void doQuery();
+ void doMatchQuery();
+
+ private:
+ QString preparePath( const QString& p );
+
+ QString m_cddbDir;
+};
+
+#endif
diff --git a/libk3b/cddb/k3bcddblocalsubmit.cpp b/libk3b/cddb/k3bcddblocalsubmit.cpp
new file mode 100644
index 0000000..f2d1e69
--- /dev/null
+++ b/libk3b/cddb/k3bcddblocalsubmit.cpp
@@ -0,0 +1,102 @@
+/*
+ *
+ * $Id: k3bcddblocalsubmit.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#include "k3bcddblocalsubmit.h"
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+
+K3bCddbLocalSubmit::K3bCddbLocalSubmit( QObject* parent, const char* name )
+ : K3bCddbSubmit( parent, name )
+{
+}
+
+
+K3bCddbLocalSubmit::~K3bCddbLocalSubmit()
+{
+}
+
+
+void K3bCddbLocalSubmit::doSubmit()
+{
+ QString path = m_cddbDir;
+ if( path.startsWith( "~" ) )
+ path.replace( 0, 1, QDir::homeDirPath() + "/" );
+ else if( !path.startsWith( "/" ) )
+ path.prepend( QDir::homeDirPath() + "/" );
+ if( path[path.length()-1] != '/' )
+ path.append( "/" );
+
+ if( !QFile::exists( path ) && !QDir().mkdir( path ) ) {
+ kdDebug() << "(K3bCddbLocalSubmit) could not create directory: " << path << endl;
+ setError( IO_ERROR );
+ emit submitFinished( this );
+ return;
+ }
+
+ if( QFile::exists( path ) ) {
+ // if the category dir does not exists
+ // create it
+
+ path += resultEntry().category;
+
+ if( !QFile::exists( path ) ) {
+ if( !QDir().mkdir( path ) ) {
+ kdDebug() << "(K3bCddbLocalSubmit) could not create directory: " << path << endl;
+ setError( IO_ERROR );
+ emit submitFinished( this );
+ return;
+ }
+ }
+
+ // we always overwrite existing entries
+ path += "/" + resultEntry().discid;
+ QFile entryFile( path );
+ if( entryFile.exists() ) {
+ kdDebug() << "(K3bCddbLocalSubmit) file already exists: " << path << endl;
+ }
+
+ if( !entryFile.open( IO_WriteOnly ) ) {
+ kdDebug() << "(K3bCddbLocalSubmit) could not create file: " << path << endl;
+ setError( IO_ERROR );
+ emit submitFinished( this );
+ }
+ else {
+ kdDebug() << "(K3bCddbLocalSubmit) creating file: " << path << endl;
+ QTextStream entryStream( &entryFile );
+ entryStream.setEncoding( QTextStream::UnicodeUTF8 );
+ entryStream << resultEntry().rawData;
+ entryFile.close();
+
+ setError( SUCCESS );
+ emit submitFinished( this );
+ }
+ }
+ else {
+ kdDebug() << "(K3bCddbLocalSubmit) could not find directory: " << path << endl;
+ setError( IO_ERROR );
+ emit infoMessage( i18n("Could not find directory: %1").arg(path) );
+ emit submitFinished( this );
+ }
+}
+
+#include "k3bcddblocalsubmit.moc"
diff --git a/libk3b/cddb/k3bcddblocalsubmit.h b/libk3b/cddb/k3bcddblocalsubmit.h
new file mode 100644
index 0000000..8b7ea91
--- /dev/null
+++ b/libk3b/cddb/k3bcddblocalsubmit.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * $Id: k3bcddblocalsubmit.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDB_LOCAL_SUBMIT_H
+#define K3BCDDB_LOCAL_SUBMIT_H
+
+#include "k3bcddbsubmit.h"
+
+#include <qstring.h>
+
+
+class K3bCddbLocalSubmit : public K3bCddbSubmit
+{
+ Q_OBJECT
+
+ public:
+ K3bCddbLocalSubmit( QObject* parent = 0, const char* name = 0 );
+ ~K3bCddbLocalSubmit();
+
+ public slots:
+ void setCddbDir( const QString& dir ) { m_cddbDir = dir; }
+
+ protected slots:
+ void doSubmit();
+
+ private:
+ QString m_cddbDir;
+};
+
+#endif
diff --git a/libk3b/cddb/k3bcddbmultientriesdialog.cpp b/libk3b/cddb/k3bcddbmultientriesdialog.cpp
new file mode 100644
index 0000000..094176a
--- /dev/null
+++ b/libk3b/cddb/k3bcddbmultientriesdialog.cpp
@@ -0,0 +1,74 @@
+/*
+ *
+ * $Id: k3bcddbmultientriesdialog.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bcddbmultientriesdialog.h"
+
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+
+#include <klistbox.h>
+#include <klocale.h>
+
+
+
+K3bCddbMultiEntriesDialog::K3bCddbMultiEntriesDialog( QWidget* parent, const char* name )
+ : KDialogBase( Plain, i18n("CDDB Database Entry"), Ok|Cancel, Ok, parent, name )
+{
+ QFrame* frame = plainPage();
+ QVBoxLayout* layout = new QVBoxLayout( frame );
+ layout->setAutoAdd( true );
+ layout->setSpacing( spacingHint() );
+ layout->setMargin( 0 );
+
+ QLabel* infoLabel = new QLabel( i18n("K3b found multiple inexact CDDB entries. Please select one."), frame );
+ infoLabel->setAlignment( WordBreak );
+
+ m_listBox = new KListBox( frame, "list_box");
+
+ setMinimumSize( 280, 200 );
+}
+
+K3bCddbResultHeader K3bCddbMultiEntriesDialog::selectCddbEntry( K3bCddbQuery* query, QWidget* parent )
+{
+ K3bCddbMultiEntriesDialog d( parent );
+
+ const QValueList<K3bCddbResultHeader> headers = query->getInexactMatches();
+
+ int i = 1;
+ for( QValueListConstIterator<K3bCddbResultHeader> it = headers.begin();
+ it != headers.end(); ++it ) {
+ d.m_listBox->insertItem( QString::number(i) + " " +
+ (*it).artist + " - " +
+ (*it).title + " (" +
+ (*it).category + ")" );
+ ++i;
+ }
+
+ d.m_listBox->setSelected( 0, true );
+
+ if( d.exec() == QDialog::Accepted )
+ return headers[ d.m_listBox->currentItem() >= 0 ? d.m_listBox->currentItem() : 0 ];
+ else
+ return K3bCddbResultHeader();
+}
+
+
+K3bCddbMultiEntriesDialog::~K3bCddbMultiEntriesDialog(){
+}
+
+
+#include "k3bcddbmultientriesdialog.moc"
diff --git a/libk3b/cddb/k3bcddbmultientriesdialog.h b/libk3b/cddb/k3bcddbmultientriesdialog.h
new file mode 100644
index 0000000..15cc6f8
--- /dev/null
+++ b/libk3b/cddb/k3bcddbmultientriesdialog.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * $Id: k3bcddbmultientriesdialog.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDBMULTIENTRIESDIALOG_H
+#define K3BCDDBMULTIENTRIESDIALOG_H
+
+#include <kdialogbase.h>
+
+#include "k3bcddbquery.h"
+#include "k3bcddbresult.h"
+
+
+class QStringList;
+class KListBox;
+
+/**
+ *@author Sebastian Trueg
+ */
+class K3bCddbMultiEntriesDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ ~K3bCddbMultiEntriesDialog();
+
+ static K3bCddbResultHeader selectCddbEntry( K3bCddbQuery* query, QWidget* parent = 0 );
+
+ protected:
+ K3bCddbMultiEntriesDialog( QWidget* parent = 0, const char* name = 0);
+
+ private:
+ KListBox *m_listBox;
+};
+
+#endif
diff --git a/libk3b/cddb/k3bcddbpquery.cpp b/libk3b/cddb/k3bcddbpquery.cpp
new file mode 100644
index 0000000..fefc8e4
--- /dev/null
+++ b/libk3b/cddb/k3bcddbpquery.cpp
@@ -0,0 +1,278 @@
+/*
+ *
+ * $Id: k3bcddbpquery.cpp 619556 2007-01-03 17:38:12Z trueg $
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bcddbpquery.h"
+
+#include <qstringlist.h>
+#include <qsocket.h>
+#include <qtextstream.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+
+
+
+
+K3bCddbpQuery::K3bCddbpQuery( QObject* parent, const char* name )
+ :K3bCddbQuery( parent, name )
+{
+ m_socket = new QSocket( this );
+ m_stream.setDevice( m_socket );
+ m_stream.setEncoding( QTextStream::UnicodeUTF8 );
+
+ connect( m_socket, SIGNAL(connected()), this, SLOT(slotConnected()) );
+ connect( m_socket, SIGNAL(hostFound()), this, SLOT(slotHostFound()) );
+ connect( m_socket, SIGNAL(connectionClosed()), this, SLOT(slotConnectionClosed()) );
+ connect( m_socket, SIGNAL(error(int)), this, SLOT(slotError(int)) );
+ connect( m_socket, SIGNAL(readyRead()), this, SLOT(slotReadyRead()) );
+}
+
+
+K3bCddbpQuery::~K3bCddbpQuery()
+{
+ delete m_socket;
+}
+
+void K3bCddbpQuery::doQuery()
+{
+ setError( WORKING );
+
+ m_state = GREETING;
+
+ // connect to the server
+
+ m_socket->connectToHost( m_server, m_port );
+ emit infoMessage( i18n("Searching %1 on port %2").arg(m_server).arg(m_port) );
+}
+
+
+void K3bCddbpQuery::doMatchQuery()
+{
+ // we should still be connected
+ // TODO: check this
+
+ QString read = QString( "cddb read %1 %2").arg( header().category ).arg( header().discid );
+
+ m_state = READ;
+ m_parsingBuffer = "";
+
+ kdDebug() << "(K3bCddbpQuery) Read: " << read << endl;
+
+ m_stream << read << endl << flush;
+}
+
+
+void K3bCddbpQuery::slotHostFound()
+{
+ emit infoMessage( i18n("Host found") );
+}
+
+
+void K3bCddbpQuery::slotConnected()
+{
+ emit infoMessage( i18n("Connected") );
+}
+
+
+void K3bCddbpQuery::slotConnectionClosed()
+{
+ emit infoMessage( i18n("Connection closed") );
+ emitQueryFinished();
+}
+
+
+void K3bCddbpQuery::cddbpQuit()
+{
+ m_state = QUIT;
+ m_stream << "quit" << endl << flush;
+}
+
+
+void K3bCddbpQuery::slotReadyRead()
+{
+ while( m_socket->canReadLine() ) {
+ QString line = m_stream.readLine();
+
+ // kdDebug() << "(K3bCddbpQuery) line: " << line << endl;
+
+ switch( m_state ) {
+ case GREETING:
+ if( getCode( line ) == 200 || getCode( line ) == 201) {
+ emit infoMessage( i18n("OK, read access") );
+ m_state = HANDSHAKE;
+
+ m_stream << "cddb hello " << handshakeString() << endl << flush;
+ }
+
+ else {
+ emit infoMessage( i18n("Connection refused") );
+ setError( CONNECTION_ERROR );
+ m_socket->close();
+ }
+ break;
+
+ case HANDSHAKE:
+ if( getCode( line ) == 200 ) {
+ emit infoMessage( i18n("Handshake successful") );
+
+ m_state = PROTO;
+
+ m_stream << "proto 6" << endl << flush;
+ }
+
+ else {
+ emit infoMessage( i18n("Handshake failed") ); // server closes connection
+ setError( CONNECTION_ERROR );
+ m_socket->close(); // just to be sure
+ }
+ break;
+
+ case PROTO:
+ {
+ if( getCode( line ) == 501 ) {
+ kdDebug() << "(K3bCddbpQuery) illigal protocol level!" << endl;
+ }
+
+ // just ignore the reply since it's not important for the functionality
+ m_state = QUERY;
+
+ m_stream << queryString() << endl << flush;
+ break;
+ }
+
+ case QUERY:
+ if( getCode( line ) == 200 ) {
+ // parse exact match and send a read command
+ K3bCddbResultHeader header;
+ parseMatchHeader( line.mid( 4 ), header );
+
+ emit infoMessage( i18n("Found exact match") );
+
+ queryMatch( header );
+ }
+
+ else if( getCode( line ) == 210 ) {
+ // TODO: perhaps add an "exact" field to K3bCddbEntry
+ kdDebug() << "(K3bCddbpQuery) Found multiple exact matches" << endl;
+
+ emit infoMessage( i18n("Found multiple exact matches") );
+
+ m_state = QUERY_DATA;
+ }
+
+ else if( getCode( line ) == 211 ) {
+ kdDebug() << "(K3bCddbpQuery) Found inexact matches" << endl;
+
+ emit infoMessage( i18n("Found inexact matches") );
+
+ m_state = QUERY_DATA;
+ }
+
+ else if( getCode( line ) == 202 ) {
+ kdDebug() << "(K3bCddbpQuery) no match found" << endl;
+ emit infoMessage( i18n("No match found") );
+ setError( NO_ENTRY_FOUND );
+ cddbpQuit();
+ }
+
+ else {
+ kdDebug() << "(K3bCddbpQuery) Error while querying: " << line << endl;
+ emit infoMessage( i18n("Error while querying") );
+ setError( QUERY_ERROR );
+ cddbpQuit();
+ }
+ break;
+
+ case QUERY_DATA:
+ if( line.startsWith( "." ) ) {
+ // finished query
+ // go on reading
+
+ emit inexactMatches( this );
+ return;
+ }
+ else {
+ kdDebug() << "(K3bCddbpQuery) inexact match: " << line << endl;
+ K3bCddbResultHeader header;
+ parseMatchHeader( line, header );
+ m_inexactMatches.append( header );
+ }
+ break;
+
+ case READ:
+ if( getCode( line ) == 210 ) {
+
+ // we just start parsing the read data
+ m_state = READ_DATA;
+ }
+
+ else {
+ emit infoMessage( i18n("Could not read match") );
+ setError( READ_ERROR );
+ cddbpQuit();
+ }
+ break;
+
+
+ case READ_DATA:
+
+ // kdDebug() << "(K3bCddbpQuery) parsing line: " << line << endl;
+
+ if( line.startsWith( "." ) ) {
+
+ kdDebug() << "(K3bCddbpQuery) query finished." << endl;
+
+ QTextStream strStream( m_parsingBuffer, IO_ReadOnly );
+ parseEntry( strStream, result() );
+
+ setError( SUCCESS );
+ cddbpQuit();
+ }
+
+ else {
+ m_parsingBuffer.append(line + "\n");
+ }
+ break;
+
+ case QUIT:
+ // no parsing needed
+ break;
+ }
+ }
+}
+
+
+void K3bCddbpQuery::slotError( int e )
+{
+ switch(e) {
+ case QSocket::ErrConnectionRefused:
+ kdDebug() << i18n("Connection to %1 refused").arg( m_server ) << endl;
+ emit infoMessage( i18n("Connection to %1 refused").arg( m_server ) );
+ break;
+ case QSocket::ErrHostNotFound:
+ kdDebug() << i18n("Could not find host %1").arg( m_server ) << endl;
+ emit infoMessage( i18n("Could not find host %1").arg( m_server ) );
+ break;
+ case QSocket::ErrSocketRead:
+ kdDebug() << i18n("Error while reading from %1").arg( m_server ) << endl;
+ emit infoMessage( i18n("Error while reading from %1").arg( m_server ) );
+ break;
+ }
+
+ m_socket->close();
+ emitQueryFinished();
+}
+
+#include "k3bcddbpquery.moc"
diff --git a/libk3b/cddb/k3bcddbpquery.h b/libk3b/cddb/k3bcddbpquery.h
new file mode 100644
index 0000000..78fe5df
--- /dev/null
+++ b/libk3b/cddb/k3bcddbpquery.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * $Id: k3bcddbpquery.h 619556 2007-01-03 17:38:12Z trueg $
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDBP_QUERY_H
+#define K3BCDDBP_QUERY_H
+
+#include "k3bcddbquery.h"
+#include "k3bcddbresult.h"
+
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <qtextstream.h>
+
+class QSocket;
+
+class K3bCddbpQuery : public K3bCddbQuery
+{
+ Q_OBJECT
+
+ public:
+ K3bCddbpQuery( QObject* parent = 0, const char* name = 0 );
+ ~K3bCddbpQuery();
+
+ public slots:
+ void setServer( const QString& s, int port = 8080 ) { m_server = s; m_port = port; }
+
+ protected slots:
+ void slotHostFound();
+ void slotConnected();
+ void slotConnectionClosed();
+ void slotReadyRead();
+ void slotError( int e );
+ void doQuery();
+ void doMatchQuery();
+
+ private:
+ void cddbpQuit();
+ enum State { GREETING, HANDSHAKE, PROTO, QUERY, QUERY_DATA, READ, READ_DATA, QUIT };
+
+ int m_state;
+ QString m_server;
+ int m_port;
+
+ QSocket* m_socket;
+ QTextStream m_stream;
+
+ QString m_parsingBuffer;
+};
+
+#endif
diff --git a/libk3b/cddb/k3bcddbquery.cpp b/libk3b/cddb/k3bcddbquery.cpp
new file mode 100644
index 0000000..783f9a4
--- /dev/null
+++ b/libk3b/cddb/k3bcddbquery.cpp
@@ -0,0 +1,275 @@
+/*
+ *
+ * $Id: k3bcddbquery.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#include "k3bcddbquery.h"
+
+#include "k3bcddbresult.h"
+
+#include <kdebug.h>
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+
+
+#include <qtextstream.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qtimer.h>
+
+#include <stdlib.h>
+
+
+
+
+K3bCddbQuery::K3bCddbQuery( QObject* parent, const char* name )
+ : QObject(parent, name)
+{
+ m_bQueryFinishedEmited = false;
+}
+
+
+K3bCddbQuery::~K3bCddbQuery()
+{
+}
+
+
+void K3bCddbQuery::query( const K3bDevice::Toc& toc )
+{
+ m_bQueryFinishedEmited = false;
+ m_toc = toc;
+ m_inexactMatches.clear();
+
+ QTimer::singleShot( 0, this, SLOT(doQuery()) );
+}
+
+
+void K3bCddbQuery::queryMatch( const K3bCddbResultHeader& header )
+{
+ m_header = header;
+ m_result = K3bCddbResultEntry();
+ m_result.category = header.category;
+ m_result.discid = header.discid;
+
+ QTimer::singleShot( 0, this, SLOT(doMatchQuery()) );
+}
+
+
+const QStringList& K3bCddbQuery::categories()
+{
+ static QStringList s_cat = QStringList::split( ",", "rock,blues,misc,classical,"
+ "country,data,folk,jazz,newage,reggae,soundtrack" );
+ return s_cat;
+}
+
+
+bool K3bCddbQuery::parseEntry( QTextStream& stream, K3bCddbResultEntry& entry )
+{
+ entry.rawData = "";
+
+ stream.setEncoding( QTextStream::UnicodeUTF8 );
+
+ // parse data
+ QString line;
+ while( !(line = stream.readLine()).isNull() ) {
+ entry.rawData.append(line + "\n");
+
+ // !all fields may be splitted into several lines!
+
+ if( line.startsWith( "DISCID" ) ) {
+ // TODO: this could be several discids separated by comma!
+ }
+
+ else if( line.startsWith( "DYEAR" ) ) {
+ QString year = line.mid( 6 );
+ if( year.length() == 4 )
+ entry.year = year.toInt();
+ }
+
+ else if( line.startsWith( "DGENRE" ) ) {
+ entry.genre = line.mid( 7 );
+ }
+
+ else if( line.startsWith( "DTITLE" ) ) {
+ entry.cdTitle += line.mid( 7 );
+ }
+
+ else if( line.startsWith( "TTITLE" ) ) {
+ int eqSgnPos = line.find( "=" );
+ bool ok;
+ uint trackNum = (uint)line.mid( 6, eqSgnPos - 6 ).toInt( &ok );
+ if( !ok )
+ kdDebug() << "(K3bCddbQuery) !!! PARSE ERROR: " << line << endl;
+ else {
+ // kdDebug() << "(K3bCddbQuery) Track title for track " << trackNum << endl;
+
+ // make sure the list is big enough
+ while( entry.titles.count() <= trackNum )
+ entry.titles.append( "" );
+
+ entry.titles[trackNum] += line.mid( eqSgnPos+1 );
+ }
+ }
+
+ else if( line.startsWith( "EXTD" ) ) {
+ entry.cdExtInfo += line.mid( 5 );
+ }
+
+ else if( line.startsWith( "EXTT" ) ) {
+ int eqSgnPos = line.find( "=" );
+ bool ok;
+ uint trackNum = (uint)line.mid( 4, eqSgnPos - 4 ).toInt( &ok );
+ if( !ok )
+ kdDebug() << "(K3bCddbQuery) !!! PARSE ERROR: " << line << endl;
+ else {
+ // kdDebug() << "(K3bCddbQuery) Track extr track " << trackNum << endl;
+
+ // make sure the list is big enough
+ while( entry.extInfos.count() <= trackNum )
+ entry.extInfos.append( "" );
+
+ entry.extInfos[trackNum] += line.mid( eqSgnPos+1 );
+ }
+ }
+
+ else if( line.startsWith( "#" ) ) {
+ // kdDebug() << "(K3bCddbQuery) comment: " << line << endl;
+ }
+
+ else {
+ kdDebug() << "(K3bCddbQuery) Unknown field: " << line << endl;
+ }
+ }
+
+ // now split the titles in the last added match
+ // if no " / " delimiter is present title and artist are the same
+ // -------------------------------------------------------------------
+ QString fullTitle = entry.cdTitle;
+ int splitPos = fullTitle.find( " / " );
+ if( splitPos < 0 )
+ entry.cdArtist = fullTitle;
+ else {
+ // split
+ entry.cdTitle = fullTitle.mid( splitPos + 3 );
+ entry.cdArtist = fullTitle.left( splitPos );
+ }
+
+
+ for( QStringList::iterator it = entry.titles.begin();
+ it != entry.titles.end(); ++it ) {
+ QString fullTitle = *it;
+ int splitPos = fullTitle.find( " / " );
+ if( splitPos < 0 )
+ entry.artists.append( entry.cdArtist );
+ else {
+ // split
+ *it = fullTitle.mid( splitPos + 3 );
+ entry.artists.append( fullTitle.left( splitPos ) );
+ }
+ }
+
+
+ // replace all "\\n" with "\n"
+ for( QStringList::iterator it = entry.titles.begin();
+ it != entry.titles.end(); ++it ) {
+ (*it).replace( "\\\\\\\\n", "\\n" );
+ }
+
+ for( QStringList::iterator it = entry.artists.begin();
+ it != entry.artists.end(); ++it ) {
+ (*it).replace( "\\\\\\\\n", "\\n" );
+ }
+
+ for( QStringList::iterator it = entry.extInfos.begin();
+ it != entry.extInfos.end(); ++it ) {
+ (*it).replace( "\\\\\\\\n", "\\n" );
+ }
+
+ entry.cdTitle.replace( "\\\\\\\\n", "\\n" );
+ entry.cdArtist.replace( "\\\\\\\\n", "\\n" );
+ entry.cdExtInfo.replace( "\\\\\\\\n", "\\n" );
+ entry.genre.replace( "\\\\\\\\n", "\\n" );
+
+ return true;
+}
+
+
+int K3bCddbQuery::getCode( const QString& line )
+{
+ bool ok;
+ int code = line.left( 3 ).toInt( &ok );
+ if( !ok )
+ code = -1;
+ return code;
+}
+
+
+QString K3bCddbQuery::handshakeString() const
+{
+ QString user( getenv("USER") );
+ QString host( getenv("HOST") );
+ if( user.isEmpty() )
+ user = "kde-user";
+ if( host.isEmpty() )
+ host = "kde-host";
+
+ return QString("%1 %2 K3b %3").arg(user).arg(host).arg(kapp->aboutData()->version());
+}
+
+
+QString K3bCddbQuery::queryString() const
+{
+ QString query = "cddb query "
+ + QString::number( m_toc.discId(), 16 ).rightJustify( 8, '0' )
+ + " "
+ + QString::number( (unsigned int)m_toc.count() );
+
+ for( K3bDevice::Toc::const_iterator it = m_toc.begin(); it != m_toc.end(); ++it ) {
+ query.append( QString( " %1" ).arg( (*it).firstSector().lba() ) );
+ }
+
+ query.append( QString( " %1" ).arg( m_toc.length().lba() / 75 ) );
+
+ return query;
+}
+
+
+bool K3bCddbQuery::parseMatchHeader( const QString& line, K3bCddbResultHeader& header )
+{
+ // format: category id title
+ // where title could be artist and title splitted with a /
+ header.category = line.section( ' ', 0, 0 );
+ header.discid = line.section( ' ', 1, 1 );
+ header.title = line.mid( header.category.length() + header.discid.length() + 2 );
+ int slashPos = header.title.find( "/" );
+ if( slashPos > 0 ) {
+ header.artist = header.title.left(slashPos).stripWhiteSpace();
+ header.title = header.title.mid( slashPos+1 ).stripWhiteSpace();
+ }
+ return true;
+}
+
+
+void K3bCddbQuery::emitQueryFinished()
+{
+ if( !m_bQueryFinishedEmited ) {
+ m_bQueryFinishedEmited = true;
+ emit queryFinished( this );
+ }
+}
+
+
+#include "k3bcddbquery.moc"
diff --git a/libk3b/cddb/k3bcddbquery.h b/libk3b/cddb/k3bcddbquery.h
new file mode 100644
index 0000000..569e882
--- /dev/null
+++ b/libk3b/cddb/k3bcddbquery.h
@@ -0,0 +1,115 @@
+/*
+ *
+ * $Id: k3bcddbquery.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDB_QUERY_H
+#define K3BCDDB_QUERY_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qtextstream.h>
+
+#include "k3bcddbresult.h"
+
+#include <k3btoc.h>
+#include "k3b_export.h"
+
+
+class LIBK3B_EXPORT K3bCddbQuery : public QObject
+{
+ Q_OBJECT
+
+ public:
+ K3bCddbQuery( QObject* parent = 0, const char* name = 0 );
+ virtual ~K3bCddbQuery();
+
+ void query( const K3bDevice::Toc& );
+
+ /**
+ * Use this if the query returned multiple matches
+ */
+ void queryMatch( const K3bCddbResultHeader& );
+
+ const K3bCddbResultEntry& result() const { return m_result; }
+
+ /**
+ * After emitting the signal inexactMatches one has to choose one
+ * of these entries and query it with queryInexactMatch
+ */
+ const QValueList<K3bCddbResultHeader>& getInexactMatches() const { return m_inexactMatches; }
+
+ static const QStringList& categories();
+
+ enum Error { SUCCESS = 0,
+ CANCELED,
+ NO_ENTRY_FOUND,
+ CONNECTION_ERROR,
+ QUERY_ERROR,
+ READ_ERROR,
+ FAILURE,
+ WORKING };
+
+ int error() const { return m_error; }
+
+ signals:
+ /**
+ * This gets emitted if a single entry has been found or
+ * no entry has been found.
+ */
+ void queryFinished( K3bCddbQuery* );
+
+ /**
+ * This gets emitted if multiple entries have been found.
+ * Call queryInexactMatch() after receiving it.
+ */
+ void inexactMatches( K3bCddbQuery* );
+
+ void infoMessage( const QString& );
+
+ protected slots:
+ virtual void doQuery() = 0;
+ virtual void doMatchQuery() = 0;
+
+ protected:
+ const K3bDevice::Toc& toc() const { return m_toc; }
+ K3bCddbResultHeader& header() { return m_header; }
+ K3bCddbResultEntry& result() { return m_result; }
+ void setError( int e ) { m_error = e; }
+
+ bool parseEntry( QTextStream&, K3bCddbResultEntry& );
+ int getCode( const QString& );
+ QString handshakeString() const;
+ QString queryString() const;
+ bool parseMatchHeader( const QString& line, K3bCddbResultHeader& header );
+
+ /**
+ * since I'm not quite sure when the socket will emit connectionClosed
+ * this method makes sure the queryFinished signal
+ * gets emited only once.
+ */
+ void emitQueryFinished();
+
+ QValueList<K3bCddbResultHeader> m_inexactMatches;
+
+ private:
+ K3bDevice::Toc m_toc;
+ K3bCddbResultEntry m_result;
+ K3bCddbResultHeader m_header;
+ int m_error;
+
+ bool m_bQueryFinishedEmited;
+};
+
+#endif
diff --git a/libk3b/cddb/k3bcddbresult.cpp b/libk3b/cddb/k3bcddbresult.cpp
new file mode 100644
index 0000000..b33b16e
--- /dev/null
+++ b/libk3b/cddb/k3bcddbresult.cpp
@@ -0,0 +1,49 @@
+/*
+ *
+ * $Id: k3bcddbresult.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#include "k3bcddbresult.h"
+
+
+K3bCddbResult::K3bCddbResult()
+{
+}
+
+
+void K3bCddbResult::clear()
+{
+ m_entries.clear();
+}
+
+
+int K3bCddbResult::foundEntries() const
+{
+ return m_entries.count();
+}
+
+const K3bCddbResultEntry& K3bCddbResult::entry( unsigned int number ) const
+{
+ if( number >= m_entries.count() )
+ return m_emptyEntry;
+
+ return m_entries[number];
+}
+
+
+void K3bCddbResult::addEntry( const K3bCddbResultEntry& entry )
+{
+ m_entries.append( entry );
+}
diff --git a/libk3b/cddb/k3bcddbresult.h b/libk3b/cddb/k3bcddbresult.h
new file mode 100644
index 0000000..46dcb9a
--- /dev/null
+++ b/libk3b/cddb/k3bcddbresult.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * $Id: k3bcddbresult.h 768492 2008-01-30 08:39:42Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+
+#ifndef K3B_CDDB_RESULT_H
+#define K3B_CDDB_RESULT_H
+
+
+#include <qstringlist.h>
+#include "k3b_export.h"
+
+
+class LIBK3B_EXPORT K3bCddbResultHeader
+{
+ public:
+ QString category;
+ QString title;
+ QString artist;
+ QString discid;
+};
+
+
+class LIBK3B_EXPORT K3bCddbResultEntry
+{
+ public:
+ // just to set a default
+ K3bCddbResultEntry()
+ : category("misc"),
+ year(0) {
+ }
+
+ QStringList titles;
+ QStringList artists;
+ QStringList extInfos;
+
+ QString cdTitle;
+ QString cdArtist;
+ QString cdExtInfo;
+
+ QString genre;
+ QString category;
+ int year;
+ QString discid;
+
+ QString rawData;
+};
+
+
+class LIBK3B_EXPORT K3bCddbResult
+{
+ public:
+ K3bCddbResult();
+ // K3bCddbQuery( const K3bCddbQuery& );
+
+ void clear();
+ void addEntry( const K3bCddbResultEntry& = K3bCddbResultEntry() );
+ const K3bCddbResultEntry& entry( unsigned int number = 0 ) const;
+ int foundEntries() const;
+
+ private:
+ QValueList<K3bCddbResultEntry> m_entries;
+
+ K3bCddbResultEntry m_emptyEntry;
+};
+
+#endif
diff --git a/libk3b/cddb/k3bcddbsubmit.cpp b/libk3b/cddb/k3bcddbsubmit.cpp
new file mode 100644
index 0000000..a04dbcb
--- /dev/null
+++ b/libk3b/cddb/k3bcddbsubmit.cpp
@@ -0,0 +1,84 @@
+/*
+ *
+ * $Id: k3bcddbsubmit.cpp 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#include "k3bcddbsubmit.h"
+
+#include <qtimer.h>
+
+
+K3bCddbSubmit::K3bCddbSubmit( QObject* parent, const char* name )
+ : QObject( parent, name )
+{
+}
+
+
+K3bCddbSubmit::~K3bCddbSubmit()
+{
+}
+
+
+void K3bCddbSubmit::submit( const K3bCddbResultEntry& entry )
+{
+ m_resultEntry = entry;
+
+ if( m_resultEntry.rawData.isEmpty() )
+ createDataStream( m_resultEntry );
+
+ QTimer::singleShot( 0, this, SLOT(doSubmit()) );
+}
+
+
+void K3bCddbSubmit::createDataStream( K3bCddbResultEntry& entry )
+{
+ entry.rawData.truncate(0);
+
+ QTextStream ts( &entry.rawData, IO_WriteOnly );
+
+ ts << "#" << endl
+ << "# Submitted via: K3b" << endl
+ << "#" << endl;
+
+ ts << "DISCID=" << entry.discid << endl
+ << "DTITLE=" << entry.cdArtist << " / " << entry.cdTitle << endl
+ << "DYEAR=";
+ if( entry.year > 0 )
+ ts << entry.year;
+ ts << endl;
+ ts << "DGENRE=" << entry.genre << endl;
+
+ bool allEqualArtist = true;
+ for( unsigned int i = 0; i < entry.artists.count(); ++i )
+ if( entry.artists[i] != entry.cdArtist &&
+ !entry.artists[i].isEmpty() ) {
+ allEqualArtist = false;
+ break;
+ }
+
+ for( unsigned int i = 0; i < entry.titles.count(); ++i ) {
+ ts << "TTITLE" << i << "=";
+ if( !allEqualArtist )
+ ts << entry.artists[i] << " / ";
+ ts << entry.titles[i] << endl;
+ }
+
+ ts << "EXTD=" << entry.cdExtInfo << endl;
+
+ for( unsigned int i = 0; i < entry.titles.count(); ++i ) {
+ ts << "EXTT" << i << "=" << entry.extInfos[i] << endl;
+ }
+}
+
+#include "k3bcddbsubmit.moc"
diff --git a/libk3b/cddb/k3bcddbsubmit.h b/libk3b/cddb/k3bcddbsubmit.h
new file mode 100644
index 0000000..ff57101
--- /dev/null
+++ b/libk3b/cddb/k3bcddbsubmit.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * $Id: k3bcddbsubmit.h 619556 2007-01-03 17:38:12Z trueg $
+ * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+
+#ifndef K3BCDDB_SUBMIT_H
+#define K3BCDDB_SUBMIT_H
+
+#include <qobject.h>
+#include <qstring.h>
+
+#include "k3bcddbresult.h"
+
+
+
+class K3bCddbSubmit : public QObject
+{
+ Q_OBJECT
+
+ public:
+ K3bCddbSubmit( QObject* parent = 0, const char* name = 0 );
+ virtual ~K3bCddbSubmit();
+
+ int error() const { return m_error; }
+
+ enum State { SUCCESS, WORKING, IO_ERROR, CONNECTION_ERROR };
+
+ public slots:
+ void submit( const K3bCddbResultEntry& );
+
+ signals:
+ void infoMessage( const QString& );
+ void submitFinished( K3bCddbSubmit* );
+
+ protected slots:
+ virtual void doSubmit() = 0;
+ void setError( int e ) { m_error = e; }
+
+ protected:
+ K3bCddbResultEntry& resultEntry() { return m_resultEntry; }
+
+ private:
+ void createDataStream( K3bCddbResultEntry& entry );
+
+ int m_error;
+ K3bCddbResultEntry m_resultEntry;
+};
+
+#endif