File migrate-to-musicbrainz5.patch of Package kscd

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e8915067529df072ecde3a0bb5e54a870cd2621a..2939563dd6f4bae8a43826a76dd9bc0f2ad8f33c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,13 +8,15 @@ include_directories(${QT_INCLUDES} ${KDE4_INCLUDES})
 include(MacroLibrary)
 include_directories(${QT_INCLUDES} ${KDE4_INCLUDES})
 
-find_package(MusicBrainz3 REQUIRED)
+find_package(MusicBrainz5 REQUIRED)
+find_package(DiscId REQUIRED)
 
 include_directories(
                 ${CMAKE_CURRENT_SOURCE_DIR}/gui
 		${CMAKE_CURRENT_SOURCE_DIR}
 		${CMAKE_CURRENT_BINARY_DIR}
-		${MUSICBRAINZ3_INCLUDE_DIR}
+		${MUSICBRAINZ5_INCLUDE_DIR}
+		${DISCID_INCLUDE_DIR}
 		)
 add_subdirectory(tests)
 ########### next target ###############
@@ -112,7 +114,8 @@ target_link_libraries(kscd
     ${KDE4_KIO_LIBS}
     ${KDE4_SOLID_LIBS}
     ${KDE4_PHONON_LIBS}
-    ${MUSICBRAINZ3_LIBRARIES}
+    ${MUSICBRAINZ5_LIBRARIES}
+    ${DISCID_LIBRARIES}
     )
 
 ########### install files ###############
diff --git a/cmake/FindDiscId.cmake b/cmake/FindDiscId.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3759056c59fb4e219e3dd05d6d11c1387f137180
--- /dev/null
+++ b/cmake/FindDiscId.cmake
@@ -0,0 +1,40 @@
+# Module to find the discid library
+#
+# It defines
+#  DISCID_INCLUDE_DIR - the include dir
+#  DISCID_LIBRARIES - the required libraries
+#  DISCID_FOUND - true if both of the above have been found
+
+# Copyright (c) 2006,2007 Laurent Montel, <montel@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+if(DISCID_INCLUDE_DIR AND DISCID_LIBRARIES)
+   set(DISCID_FIND_QUIETLY TRUE)
+endif(DISCID_INCLUDE_DIR AND DISCID_LIBRARIES)
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig)
+pkg_check_modules(PC_LIBDISCID QUIET discid)
+
+FIND_PATH(DISCID_INCLUDE_DIR discid/discid.h
+          HINTS
+          ${PC_LIBDISCID_INCLUDEDIR}
+          ${PC_LIBDISCID_INCLUDE_DIRS}
+)
+
+FIND_LIBRARY( DISCID_LIBRARIES NAMES discid
+              HINTS
+              ${PC_LIBDISCID_LIBDIR}
+              ${PC_LIBDISCID_LIB_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args( DiscId DEFAULT_MSG
+                                   DISCID_INCLUDE_DIR DISCID_LIBRARIES)
+
+MARK_AS_ADVANCED(DISCID_INCLUDE_DIR DISCID_LIBRARIES)
+
+
diff --git a/cmake/FindMusicBrainz5.cmake b/cmake/FindMusicBrainz5.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..81923f26423468a7ed55ad900bc48ef18f910ffd
--- /dev/null
+++ b/cmake/FindMusicBrainz5.cmake
@@ -0,0 +1,40 @@
+# Module to find the musicbrainz-5 library
+#
+# It defines
+#  MUSICBRAINZ5_INCLUDE_DIR - the include dir
+#  MUSICBRAINZ5_LIBRARIES - the required libraries
+#  MUSICBRAINZ5_FOUND - true if both of the above have been found
+
+# Copyright (c) 2006,2007 Laurent Montel, <montel@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+if(MUSICBRAINZ5_INCLUDE_DIR AND MUSICBRAINZ5_LIBRARIES)
+   set(MUSICBRAINZ5_FIND_QUIETLY TRUE)
+endif(MUSICBRAINZ5_INCLUDE_DIR AND MUSICBRAINZ5_LIBRARIES)
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig)
+pkg_check_modules(PC_LIBMUSICBRAINZ5 QUIET libmusicbrainz5cc libmusicbrainz5)
+
+FIND_PATH(MUSICBRAINZ5_INCLUDE_DIR musicbrainz5/Query.h
+          HINTS
+          ${PC_LIBMUSICBRAINZ5_INCLUDEDIR}
+          ${PC_LIBMUSICBRAINZ5_INCLUDE_DIRS}
+)
+
+FIND_LIBRARY( MUSICBRAINZ5_LIBRARIES NAMES musicbrainz5cc musicbrainz5
+              HINTS
+              ${PC_LIBMUSICBRAINZ5_LIBDIR}
+              ${PC_LIBMUSICBRAINZ5_LIB_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args( MusicBrainz5 DEFAULT_MSG
+                                   MUSICBRAINZ5_INCLUDE_DIR MUSICBRAINZ5_LIBRARIES)
+
+MARK_AS_ADVANCED(MUSICBRAINZ5_INCLUDE_DIR MUSICBRAINZ5_LIBRARIES)
+
+
diff --git a/kscd.h b/kscd.h
index dcbdd57b1f5f18dc369ea8babd66fc4340553b31..84c1c012179436ccc781b55f23e97cc1c0e2695b 100644
--- a/kscd.h
+++ b/kscd.h
@@ -130,6 +130,7 @@ public slots:
 	void configureKeys();
 
 	void discLookup();
+	void discUpload();
 	void discLookupFinished();
 
 private:
diff --git a/kscd.cpp b/kscd.cpp
index 3bcb8f664fa76143f33ef69cd28fa7116ee475ea..2c6d1a4519a928528099b8a25c541a72b2f2d038 100644
--- a/kscd.cpp
+++ b/kscd.cpp
@@ -114,7 +114,7 @@ void KSCD::setupActions()
 	m_uploadAction = m_actions->addAction( QLatin1String( "Upload Info" ));
 	m_uploadAction->setText(i18n("Upload Info"));
 	addAction(m_uploadAction);
-	connect(m_uploadAction, SIGNAL(triggered()), m_MBManager, SLOT(discUpload()));
+	connect(m_uploadAction, SIGNAL(triggered()), this, SLOT(discUpload()));
 
 	//play/pause
 	m_playPauseAction = m_actions->addAction( QLatin1String( "Play/Pause" ));
@@ -248,6 +248,11 @@ void KSCD::discLookup()
 	m_MBManager->discLookup(devices->getMedia()->currentSource().deviceName());
 }
 
+void KSCD::discUpload()
+{
+	m_MBManager->discUpload(devices->getMedia()->currentSource().deviceName());
+}
+
 void KSCD::discLookupFinished()
 {
 	// If the track dialog is open, refresh it
diff --git a/mbmanager.h b/mbmanager.h
index 6b07e951adf12a34e4c946367b2708c73dd59fcf..ea0415341598a447264ecd43f2718ad12f0d871a 100644
--- a/mbmanager.h
+++ b/mbmanager.h
@@ -42,6 +42,9 @@
 #include <qstring.h>
 #include <qlist.h>
 
+// musicbrainz discid
+#include <discid/discid.h>
+
 struct DiscInfo
 {
 	QString Title;
@@ -64,6 +67,7 @@ private:
 	QList <MBTrackInfo> m_trackList;	/// List of tracks information
 
 	bool m_validInfo;					/// Tells whether the lookup query succeeded
+	DiscId *m_discid;
 
 public:
 	MBManager();
@@ -82,11 +86,11 @@ public slots:
 	void discLookup(const QString& device);
 
 	/** Uploads information */
-	void discUpload();
+	void discUpload(const QString& device=QString());
 
 signals:
 	void showArtistLabel(QString&);
-	
+
 	void discLookupFinished();
 };
 
diff --git a/mbmanager.cpp b/mbmanager.cpp
index 4df3803afb13c788b9e0c0d49dbe7c20f00f3fd6..3f702d4238a8b14e0ee4a033562d6f2b1bfa0f07 100644
--- a/mbmanager.cpp
+++ b/mbmanager.cpp
@@ -34,162 +34,244 @@
 
 #include <ktoolinvocation.h>
 
-#include <musicbrainz3/musicbrainz.h>
-#include <musicbrainz3/query.h>
+#include <musicbrainz5/Query.h>
+#include <musicbrainz5/Artist.h>
+#include <musicbrainz5/ArtistCredit.h>
+#include <musicbrainz5/Disc.h>
+#include <musicbrainz5/HTTPFetch.h>
+#include <musicbrainz5/Medium.h>
+#include <musicbrainz5/NameCredit.h>
+#include <musicbrainz5/NameCreditList.h>
+#include <musicbrainz5/Recording.h>
+#include <musicbrainz5/Release.h>
+#include <musicbrainz5/Track.h>
 
 MBManager::MBManager():m_validInfo(true)
 {
-
+	m_discid = discid_new();
 }
 
 MBManager::~MBManager()
 {
+	discid_free(m_discid);
+}
+
+static QString getTitle(MusicBrainz5::CRelease *release, MusicBrainz5::CMedium *medium)
+{
+    QString title;
+    if (! release) return title;
 
+    title = QString::fromUtf8(release->Title().c_str());
+    if (medium && release->MediumList()->NumItems() > 1) {
+	title = i18n("%1 (disc %2)", title, medium->Position());
+    }
+
+    return title;
 }
 
-void MBManager::discLookup(const QString &device)
+static QString getArtistFromArtistCredit(MusicBrainz5::CArtistCredit *artistCredit)
 {
-	m_validInfo = true;
+    QString artist;
+    MusicBrainz5::CNameCreditList *artistList = artistCredit->NameCreditList();
 
-	MusicBrainz::WebService* ws = new MusicBrainz::WebService();
+    if (! artistList) return artist;
 
-	// Set the proper server to use. Defaults to mm.musicbrainz.org:80
-	if (!qgetenv("MB_SERVER").isNull())
-	{
-		std::string server(qgetenv("MB_SERVER"));
-		ws->setHost(server);
-		//kDebug() << "!! set server !!" ;
-	}
+    for (int i = 0; i < artistList->NumItems(); i++) {
+	MusicBrainz5::CNameCredit* name = artistList->Item(i);
+	MusicBrainz5::CArtist* itemArtist = name->Artist();
+
+	if (!name->Name().empty())
+	    artist += QString::fromUtf8(name->Name().c_str());
 	else
-	{
-		//kDebug() << "no server";
-	}
+	    artist += QString::fromUtf8(itemArtist->Name().c_str());
 
-	// If you need to use a proxy, uncomment/edit the following line
-	// as appropriate
-	//ws->setProxyHost("proxy.mydomain.com");
-	//ws->setProxyPort(80);
+	artist += QString::fromUtf8(name->JoinPhrase().c_str());
+    }
 
-	try
-	{
-		MusicBrainz::Disc *disc = MusicBrainz::readDisc(qPrintable(device));
-
-		MusicBrainz::Query q(ws);
-		MusicBrainz::ReleaseResultList results;
-
-		try
-		{
-		MusicBrainz::ReleaseFilter f = MusicBrainz::ReleaseFilter().discId(disc->getId());
-			results = q.getReleases(&f);
-
-			// Check to see how many items were returned from the server
-			if (!results.empty())
-			{
-				// TODO if multiple entries found
-				if (results.size() > 1)
-				{
-					kDebug() << results.size() << " entries found";
-				}
-
-				MusicBrainz::ReleaseResult *result = results.front();
-				MusicBrainz::Release *release = q.getReleaseById(result->getRelease()->getId(),
-								&MusicBrainz::ReleaseIncludes().tracks().artist());
-				// Sets info
-				m_discInfo.Title = QString::fromUtf8(release->getTitle().c_str());
-				m_discInfo.Artist = QString::fromUtf8(release->getArtist()->getName().c_str());
-
-				m_trackList.clear();
-				MBTrackInfo track;
-				for (MusicBrainz::TrackList::iterator j = release->getTracks().begin();
-								j != release->getTracks().end(); j++)
-				{
-					MusicBrainz::Track *t = *j;
-					MusicBrainz::Artist *artist = t->getArtist();
-					if (!artist)
-						artist = release->getArtist();
-
-					track.Title = QString::fromUtf8(t->getTitle().c_str());
-					track.Artist = QString::fromUtf8(artist->getName().c_str());
-					track.Duration = t->getDuration();
-
-					m_trackList << track;
-				}
-			}
-			else
-			{
-				kDebug() << "This CD was not found.";
-				m_validInfo = false;
-			}
-
-
-		}
-		catch (const MusicBrainz::WebServiceError &e)
-                {
-			kDebug() << "Error: " << e.what();
-			m_validInfo = false;
-                }
-		catch (...)
-		{
-			kDebug() << "Caught Unknown Exception:";
-			m_validInfo = false;
-		}
-
-		if (!m_validInfo)
-		{
-			// If invalid data, fill the information with something
-			// Sets info
-			m_discInfo.Title = i18n("Unknown album");
-			m_discInfo.Artist = i18n("Unknown artist");
-
-			m_trackList.clear();
-			MBTrackInfo track;
-			for (MusicBrainz::Disc::TrackList::iterator j = disc->getTracks().begin(); j != disc->getTracks().end(); j++)
-			{
-				track.Title = i18n("Unknown title");
-				track.Artist = m_discInfo.Artist;
-				// time from mb library in sectors, 75 sectors = 1 second
-				track.Duration = (*j).second*1000/75;
-
-				m_trackList << track;
-			}
-		}
-		delete disc;
-	}
-        // FIXME Doesn't seem to get caught, why?
-        catch (const MusicBrainz::DiscError &e)
-        {
-		kDebug() << "Error: " << e.what();
-		m_discInfo.Title = i18n("Unknown album");
-		m_discInfo.Artist = i18n("Unknown artist");
-		m_discInfo.Artist = i18n( "No Disc" );
-		m_trackList.clear();
-        }
-	catch(...)
-	{
-		m_discInfo.Title = i18n("Unknown album");
-		m_discInfo.Artist = i18n("Unknown artist");
-		m_discInfo.Artist = i18n( "No Disc" );
-		m_trackList.clear();
-	}
-	
-	emit discLookupFinished();
+    return artist;
 }
 
-void MBManager::discUpload()
+static QString getArtist(MusicBrainz5::CRelease *release)
 {
-	showArtistLabel(m_discInfo.Artist);
+    QString artist;
+    if (! release) return artist;
+
+    MusicBrainz5::CArtistCredit *artistCredit = release->ArtistCredit();
+    return getArtistFromArtistCredit(artistCredit);
+}
+
+static QList<MBTrackInfo> unknownTracks(QString &discArtist, DiscId *m_discid)
+{
+    QList<MBTrackInfo> tracks;
+    MBTrackInfo track;
+    for (int j = 1; j < discid_get_first_track_num(m_discid); j++) {
+	track.Title = i18n("Unknown title");
+	track.Artist = discArtist;
+	// Not an audio track
+	track.Duration = 0;
+
+	tracks << track;
+    }
+    for (int j = discid_get_first_track_num(m_discid); j <= discid_get_last_track_num(m_discid); j++)
+    {
+	track.Title = i18n("Unknown title");
+	track.Artist = discArtist;
+	// time from mb library in sectors, 75 sectors = 1 second
+	track.Duration = discid_get_track_length(m_discid, j) * 1000 / 75;
+
+	tracks << track;
+    }
+
+    return tracks;
+}
+
+static QList<MBTrackInfo> getTracks(MusicBrainz5::CMedium *medium, QString &discArtist, DiscId *m_discid)
+{
+    QList<MBTrackInfo> tracks;
+    if (! medium) return tracks;
+
+    MusicBrainz5::CTrackList *trackList = medium->TrackList();
+    if (! trackList) return unknownTracks(discArtist, m_discid);
+
+    MBTrackInfo track;
+    for (int i = 0; i < trackList->NumItems(); i++) {
+	MusicBrainz5::CTrack *itemTrack = trackList->Item(i);
+	MusicBrainz5::CRecording *recording = itemTrack->Recording();
+	if (recording && !itemTrack->ArtistCredit())
+	    track.Artist = getArtistFromArtistCredit(recording->ArtistCredit());
+	else
+	    track.Artist = getArtistFromArtistCredit(itemTrack->ArtistCredit());
+
+	if(recording && itemTrack->Title().empty())
+	    track.Title = QString::fromUtf8(recording->Title().c_str());
+	else
+	    track.Title = QString::fromUtf8(itemTrack->Title().c_str());
+
+	track.Duration = itemTrack->Length();
 
+	tracks << track;
+    }
+
+    return tracks;
+}
+
+static MusicBrainz5::CRelease *getRelease(MusicBrainz5::CQuery &query, std::string &discId, MusicBrainz5::CMetadata &metadata, MusicBrainz5::CMetadata &fullMetadata)
+{
+    metadata = query.Query("discid", discId);
+    // Check to see how many items were returned from the server
+    if (! metadata.Disc() || ! metadata.Disc()->ReleaseList()) return 0;
+
+    MusicBrainz5::CReleaseList *results = metadata.Disc()->ReleaseList();
+
+    // TODO if multiple entries found
+    if (results->NumItems() > 1)
+    {
+	kDebug() << results->NumItems() << " entries found";
+    }
+
+    MusicBrainz5::CRelease *release;
+    for (int i = 0; i < results->NumItems(); i++) {
+	MusicBrainz5::CRelease *result = results->Item(i);
+	MusicBrainz5::CQuery::tParamMap params;
+	params["inc"] = "artists labels recordings release-groups url-rels "
+	                "discids artist-credits";
+	fullMetadata = query.Query("release", result->ID(), "", params);
+
+	release = fullMetadata.Release();
+	if (release) break;
+    }
+
+    return release;
+}
+
+static MusicBrainz5::CMedium *getMedium(MusicBrainz5::CRelease *release,
+	                                std::string &discId,
+					MusicBrainz5::CMediumList &mediaList)
+{
+    if (! release) return 0;
+
+    // Find the specific media in the release
+    mediaList = release->MediaMatchingDiscID(discId);
+    MusicBrainz5::CMedium* medium = 0;
+
+    for (int i = 0; i < mediaList.NumItems(); i++) {
+	medium = mediaList.Item(i);
+	if (medium) break;
+    }
+
+    return medium;
+}
+
+void MBManager::discLookup(const QString &device)
+{
+    m_validInfo = true;
+    MusicBrainz5::CQuery query("kscd");
+    int discid_ok = discid_read_sparse(m_discid, qPrintable(device), 0);
+    if (discid_ok) {
+	std::string discId(discid_get_id(m_discid));
 	try
 	{
-		MusicBrainz::Disc *disc = MusicBrainz::readDisc();
-		std::string url = MusicBrainz::getSubmissionUrl(disc);
-		delete disc;
+	    MusicBrainz5::CMetadata metadata, fullMetadata;
+	    MusicBrainz5::CMediumList mediaList;
+	    MusicBrainz5::CRelease *release = getRelease(query, discId, metadata, fullMetadata);
+	    MusicBrainz5::CMedium *medium = getMedium(release, discId, mediaList);
+
+	    if (release && medium) {
+		// Sets info
+		m_discInfo.Title = getTitle(release, medium);
+		m_discInfo.Artist = getArtist(release);
+
+		m_trackList = getTracks(medium, m_discInfo.Artist, m_discid);
+	    } else {
+		kDebug() << "This CD was not found.";
+		m_validInfo = false;
+	    }
+
+	}
+	catch (MusicBrainz5::CExceptionBase& error)
+	{
+	    kDebug() << "Connection Exception: '" << error.what() << "'";
+	    kDebug() << "LastResult: " << query.LastResult();
+	    kDebug() << "LastHTTPCode: " << query.LastHTTPCode();
+	    kDebug() << "LastErrorMessage: " << QString::fromUtf8(query.LastErrorMessage().c_str());
 
-		KToolInvocation::invokeBrowser(QString::fromUtf8(url.c_str()));
+	    m_validInfo = false;
 	}
-	catch (MusicBrainz::DiscError &e)
+	catch (...)
 	{
-		kDebug() << "Error: " << e.what();
+	    kDebug() << "Caught Unknown Exception:";
+	    m_validInfo = false;
 	}
+    } else {
+	m_validInfo = false;
+    }
+
+    if (!m_validInfo)
+    {
+	// If invalid data, fill the information with something
+	// Sets info
+	m_discInfo.Title = i18n("Unknown album");
+	m_discInfo.Artist = i18n("Unknown artist");
+
+	m_trackList.clear();
+	if (discid_ok) {
+	    m_trackList = unknownTracks(m_discInfo.Artist, m_discid);
+	}
+    }
+
+    emit discLookupFinished();
 }
 
+void MBManager::discUpload(const QString &device)
+{
+    showArtistLabel(m_discInfo.Artist);
+    const char *discid_device = device.isEmpty()? NULL : qPrintable(device);
+
+    int ok = discid_read_sparse(m_discid, discid_device, 0);
+    if (ok) {
+	QString url = QString::fromUtf8(discid_get_submission_url(m_discid));
+	KToolInvocation::invokeBrowser(url);
+    } else {
+	kDebug() << "Error: " << discid_get_error_msg(m_discid);
+    }
+}
openSUSE Build Service is sponsored by