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);
+ }
+}