Commit 57902715 authored by Richard Lärkäng's avatar Richard Lärkäng
Browse files

Update libkcddb to use libmusicbrainz-4.0,

which uses the new api from last year,
fixing lookup for releases with multiple discs.
Kscd still uses 3.0, so the libmusicbrainz-3 cmake
files are still left.

Also, enable Musicbrainz lookup by default,
don't know why I haven't done that earlier.

svn path=/trunk/KDE/kdemultimedia/libkcddb/; revision=1282268
parent eb06a67f
......@@ -3,19 +3,19 @@ project(libkcddb)
add_subdirectory( test )
add_subdirectory( kcmcddb )
if(MUSICBRAINZ3_FOUND)
set(HAVE_MUSICBRAINZ3 1)
include_directories(${MUSICBRAINZ3_INCLUDE_DIR})
if(MUSICBRAINZ4_FOUND)
set(HAVE_MUSICBRAINZ4 1)
include_directories(${MUSICBRAINZ4_INCLUDE_DIR})
set(libmusicbrainz_SRCS ${libmusicbrainz_SRCS}
musicbrainz/musicbrainzlookup.cpp
musicbrainz/asyncmusicbrainzlookup.cpp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
else(MUSICBRAINZ3_FOUND)
set(HAVE_MUSICBRAINZ3 0)
else(MUSICBRAINZ4_FOUND)
set(HAVE_MUSICBRAINZ4 0)
set(libmusicbrainz_SRCS)
endif(MUSICBRAINZ3_FOUND)
endif(MUSICBRAINZ4_FOUND)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-musicbrainz.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-musicbrainz.h )
......@@ -58,9 +58,9 @@ kde4_add_kcfg_files(kcddb_LIB_SRCS configbase.kcfgc )
kde4_add_library(kcddb SHARED ${kcddb_LIB_SRCS})
target_link_libraries(kcddb ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS})
if(MUSICBRAINZ3_FOUND)
target_link_libraries(kcddb ${MUSICBRAINZ3_LIBRARIES})
endif(MUSICBRAINZ3_FOUND)
if(MUSICBRAINZ4_FOUND)
target_link_libraries(kcddb ${MUSICBRAINZ4_LIBRARIES})
endif(MUSICBRAINZ4_FOUND)
set_target_properties(kcddb PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} )
install(TARGETS kcddb ${INSTALL_TARGETS_DEFAULT_ARGS} )
......
......@@ -26,7 +26,7 @@
#include "cddb.h"
#include "config-musicbrainz.h"
#ifdef HAVE_MUSICBRAINZ3
#ifdef HAVE_MUSICBRAINZ4
#include "musicbrainz/musicbrainzlookup.h"
#endif
......@@ -49,7 +49,7 @@ namespace KCDDB
CDInfoList infoList;
infoList << CDDB::cacheFiles(offsetList, c);
#ifdef HAVE_MUSICBRAINZ3
#ifdef HAVE_MUSICBRAINZ4
infoList << MusicBrainzLookup::cacheFiles(offsetList, c);
#endif
......
......@@ -39,7 +39,7 @@ namespace KCDDB
static QString trackOffsetListToId( const TrackOffsetList & );
static QString clientName() { return QLatin1String("libkcddb"); }
static QString clientVersion() { return QLatin1String("0.4"); }
static QString clientVersion() { return QLatin1String("0.5"); }
static uint statusCode( const QString & );
......
......@@ -443,13 +443,30 @@ namespace KCDDB
else
s += d->createLine(QLatin1String( "DGENRE" ),get(Genre).toString());
bool isSampler = false;
for (int i = 0; i < d->trackInfoList.count(); ++i){
QString trackArtist = d->trackInfoList[i].get(Artist).toString();
if (!trackArtist.isEmpty() && trackArtist != artist)
{
isSampler = true;
break;
}
}
for (int i = 0; i < d->trackInfoList.count(); ++i){
QString trackTitle = d->trackInfoList[i].get(Title).toString();
QString trackArtist = d->trackInfoList[i].get(Artist).toString();
if(trackArtist != artist && !trackArtist.isEmpty())
if (isSampler)
{
if (trackArtist.isEmpty())
s += d->createLine(QString::fromLatin1("TTITLE%1").arg(i), QString::fromLatin1("%1 / %2").arg(artist).arg(trackTitle));
else
s += d->createLine(QString::fromLatin1("TTITLE%1").arg(i), QString::fromLatin1("%1 / %2").arg(trackArtist).arg(trackTitle));
}
else
{
s += d->createLine(QString::fromLatin1("TTITLE%1").arg(i), trackTitle);
}
}
s += d->createLine(QLatin1String("EXTD"), get(Comment).toString());
......
......@@ -33,7 +33,7 @@
#include "lookup.h"
#include "config-musicbrainz.h"
#ifdef HAVE_MUSICBRAINZ3
#ifdef HAVE_MUSICBRAINZ4
#include "musicbrainz/musicbrainzlookup.h"
#include "musicbrainz/asyncmusicbrainzlookup.h"
#endif
......@@ -138,7 +138,7 @@ namespace KCDDB
if ( blockingMode() )
{
#ifdef HAVE_MUSICBRAINZ3
#ifdef HAVE_MUSICBRAINZ4
if ( d->config.musicBrainzLookupEnabled() )
{
d->cdInfoLookup = new MusicBrainzLookup();
......@@ -186,7 +186,7 @@ namespace KCDDB
}
else
{
#ifdef HAVE_MUSICBRAINZ3
#ifdef HAVE_MUSICBRAINZ4
if ( d->config.musicBrainzLookupEnabled() )
{
AsyncMusicBrainzLookup* lookup = new AsyncMusicBrainzLookup();
......
/* have MusicBrainz */
#cmakedefine HAVE_MUSICBRAINZ3 1
#cmakedefine HAVE_MUSICBRAINZ4 1
......@@ -51,8 +51,8 @@ namespace KCDDB
header += QLatin1String( "Category: " ) + cdInfo.get(Category).toString() + QLatin1Char( '\n' );
header += QLatin1String( "Discid: " ) + cdInfo.get(QLatin1String( "discid" )).toString() + QLatin1Char( '\n' );
header += QLatin1String( "User-Email: " ) + from_ + QLatin1Char( '\n' );
// Change to sumbit
header += QLatin1String( "Submit-Mode: test\n" );
//header += QLatin1String( "Submit-Mode: test\n" );
header += QLatin1String( "Submit-Mode: submit\n" );
header += QLatin1String( "Charset: UTF-8" );
job->addMetaData(QLatin1String( "customHTTPHeader" ), header);
......
......@@ -46,7 +46,7 @@ CDDBConfigWidget::CDDBConfigWidget(QWidget * parent)
{
setupUi(this);
#ifndef HAVE_MUSICBRAINZ3
#ifndef HAVE_MUSICBRAINZ4
kcfg_MusicBrainzLookupEnabled->hide();
#endif
......
......@@ -13,7 +13,7 @@
<default>80</default>
</entry>
<entry name="MusicBrainzLookupEnabled" type="Bool">
<default>false</default>
<default>true</default>
</entry>
<entry name="FreedbLookupEnabled" type="Bool">
<default>true</default>
......@@ -61,7 +61,7 @@
<entry name="smtpHostname" type="String">
</entry>
<entry name="submitAddress" type="String">
<default>test-submit@freedb.org</default>
<default>freedb-submit@freedb.org</default>
</entry>
</group>
</kcfg>
......@@ -22,13 +22,21 @@
#include <kdebug.h>
#include <kcodecs.h>
#include <klocale.h>
#include <qcryptographichash.h>
#include <cstdio>
#include <cstring>
#include <musicbrainz3/musicbrainz.h>
#include <musicbrainz3/query.h>
#include <musicbrainz3/release.h>
#include <musicbrainz3/filters.h>
#include <musicbrainz4/Query.h>
#include "musicbrainz4/Medium.h"
#include "musicbrainz4/Release.h"
#include "musicbrainz4/ReleaseGroup.h"
#include "musicbrainz4/Track.h"
#include "musicbrainz4/Recording.h"
#include "musicbrainz4/Disc.h"
#include "musicbrainz4/HTTPFetch.h"
#include "musicbrainz4/ArtistCredit.h"
#include "musicbrainz4/Artist.h"
#include "musicbrainz4/NameCredit.h"
namespace KCDDB
{
......@@ -48,60 +56,166 @@ namespace KCDDB
kDebug() << "Should lookup " << discId;
MusicBrainz::Query q;
MusicBrainz::ReleaseResultList results;
MusicBrainz4::CQuery Query("libkcddb-0.5");
// Code adapted from libmusicbrainz/examples/cdlookup.cc
try {
MusicBrainz::ReleaseFilter f = MusicBrainz::ReleaseFilter().discId(std::string(discId.toAscii()));
results = q.getReleases(&f);
MusicBrainz4::CMetadata Metadata=Query.Query("discid",discId.toAscii().constData());
if (Metadata.Disc() && Metadata.Disc()->ReleaseList())
{
MusicBrainz4::CReleaseList *ReleaseList=Metadata.Disc()->ReleaseList();
kDebug() << "Found " << ReleaseList->NumItems() << " release(s)";
int relnr=1;
for (int i = 0; i < ReleaseList->NumItems(); i++)
{
MusicBrainz4::CRelease* Release=ReleaseList->Item(i);
//The releases returned from LookupDiscID don't contain full information
MusicBrainz4::CQuery::tParamMap Params;
Params["inc"]="artists labels recordings release-groups url-rels discids artist-credits";
std::string ReleaseID=Release->ID();
MusicBrainz4::CMetadata Metadata2=Query.Query("release",ReleaseID,"",Params);
if (Metadata2.Release())
{
MusicBrainz4::CRelease *FullRelease=Metadata2.Release();
//However, these releases will include information for all media in the release
//So we need to filter out the only the media we want.
MusicBrainz4::CMediumList MediaList=FullRelease->MediaMatchingDiscID(discId.toAscii().constData());
if (MediaList.NumItems() > 0)
{
/*if (FullRelease->ReleaseGroup())
kDebug() << "Release group title: " << FullRelease->ReleaseGroup()->Title();
else
kDebug() << "No release group for this release";*/
kDebug() << "Found " << MediaList.NumItems() << " media item(s)";
for (int i=0; i < MediaList.NumItems(); i++)
{
MusicBrainz4::CMedium* Medium= MediaList.Item(i);
/*kDebug() << "Found media: '" << Medium.Title() << "', position " << Medium.Position();*/
CDInfo info;
info.set(QLatin1String( "source" ), QLatin1String( "musicbrainz" ));
// Uses musicbrainz discid for the first release,
// then discid-2, discid-3 and so on, to
// allow multiple releases with the same discid
if (relnr == 1)
info.set(QLatin1String( "discid" ), discId);
else
info.set(QLatin1String( "discid" ), discId+QLatin1String( "-" )+QString::number(relnr));
QString title = QString::fromUtf8(FullRelease->Title().c_str());
if (FullRelease->MediumList()->NumItems() > 1)
title = i18n("%1 (disc %2)", title, Medium->Position());
info.set(Title, title);
info.set(Artist, artistFromCreditList(FullRelease->ArtistCredit()));
MusicBrainz4::CTrackList *TrackList=Medium->TrackList();
if (TrackList)
{
for (int i=0; i < TrackList->NumItems(); i++)
{
MusicBrainz4::CTrack* Track=TrackList->Item(i);
MusicBrainz4::CRecording *Recording=Track->Recording();
/*if (Recording)
kDebug() << "Track: " << Track.Position() << " - '" << Recording->Title() << "'";
else
kDebug() << "Track: " << Track.Position() << " - '" << Track.Title() << "'";*/
TrackInfo& track = info.track(i);
if (Recording)
{
track.set(Artist, artistFromCreditList(Recording->ArtistCredit()));
track.set(Title, QString::fromUtf8(Recording->Title().c_str()));
}
else
{
track.set(Artist, artistFromCreditList(Track->ArtistCredit()));
track.set(Title, QString::fromUtf8(Track->Title().c_str()));
}
}
}
cdInfoList_ << info;
relnr++;
}
}
}
}
}
}
// FIXME Doesn't seem to get caught, why?
// catch (MusicBrainz::WebServiceError &e)
catch (...)
catch (MusicBrainz4::CConnectionError& Error)
{
kDebug() << "Query failed"; //<< e.what();
return UnknownError;
kDebug() << "Connection Exception: '" << Error.what() << "'";
kDebug() << "LastResult: " << Query.LastResult();
kDebug() << "LastHTTPCode: " << Query.LastHTTPCode();
kDebug() << "LastErrorMessage: " << QString::fromUtf8(Query.LastErrorMessage().c_str());
return ServerError;
}
int relnr=1;
for (MusicBrainz::ReleaseResultList::iterator i = results.begin(); i != results.end(); i++) {
MusicBrainz::ReleaseResult *result = *i;
MusicBrainz::Release *release;
try {
release = q.getReleaseById(result->getRelease()->getId(), &MusicBrainz::ReleaseIncludes().tracks().artist());
}
catch (MusicBrainz::WebServiceError &e) {
kDebug() << "Error: " << e.what();
continue;
}
CDInfo info;
info.set(QLatin1String( "source" ), QLatin1String( "musicbrainz" ));
// Uses musicbrainz discid for the first release,
// then discid-2, discid-3 and so on, to
// allow multiple releases with the same discid
if (relnr == 1)
info.set(QLatin1String( "discid" ), discId);
else
info.set(QLatin1String( "discid" ), discId+QLatin1String( "-" )+QString::number(relnr));
info.set(Title, QString::fromUtf8(release->getTitle().c_str()));
info.set(Artist, QString::fromUtf8(release->getArtist()->getName().c_str()));
int trackno = 0;
for (MusicBrainz::TrackList::iterator j = release->getTracks().begin(); j != release->getTracks().end(); j++) {
MusicBrainz::Track *mb_track = *j;
MusicBrainz::Artist *artist = mb_track->getArtist();
if (!artist)
artist = release->getArtist();
TrackInfo& track = info.track(trackno);
track.set(Artist, QString::fromUtf8(artist->getName().c_str()));
track.set(Title, QString::fromUtf8(mb_track->getTitle().c_str()));
trackno++;
}
delete result;
catch (MusicBrainz4::CTimeoutError& Error)
{
kDebug() << "Timeout Exception: '" << Error.what() << "'";
kDebug() << "LastResult: " << Query.LastResult();
kDebug() << "LastHTTPCode: " << Query.LastHTTPCode();
kDebug() << "LastErrorMessage: " << QString::fromUtf8(Query.LastErrorMessage().c_str());
return ServerError;
}
catch (MusicBrainz4::CAuthenticationError& Error)
{
kDebug() << "Authentication Exception: '" << Error.what() << "'";
kDebug() << "LastResult: " << Query.LastResult();
kDebug() << "LastHTTPCode: " << Query.LastHTTPCode();
kDebug() << "LastErrorMessage: " << QString::fromUtf8(Query.LastErrorMessage().c_str());
return ServerError;
}
catch (MusicBrainz4::CFetchError& Error)
{
kDebug() << "Fetch Exception: '" << Error.what() << "'";
kDebug() << "LastResult: " << Query.LastResult();
kDebug() << "LastHTTPCode: " << Query.LastHTTPCode();
kDebug() << "LastErrorMessage: " << QString::fromUtf8(Query.LastErrorMessage().c_str());
cdInfoList_ << info;
relnr++;
return ServerError;
}
catch (MusicBrainz4::CRequestError& Error)
{
kDebug() << "Request Exception: '" << Error.what() << "'";
kDebug() << "LastResult: " << Query.LastResult();
kDebug() << "LastHTTPCode: " << Query.LastHTTPCode();
kDebug() << "LastErrorMessage: " << QString::fromUtf8(Query.LastErrorMessage().c_str());
return ServerError;
}
catch (MusicBrainz4::CResourceNotFoundError& Error)
{
kDebug() << "ResourceNotFound Exception: '" << Error.what() << "'";
kDebug() << "LastResult: " << Query.LastResult();
kDebug() << "LastHTTPCode: " << Query.LastHTTPCode();
kDebug() << "LastErrorMessage: " << QString::fromUtf8(Query.LastErrorMessage().c_str());
return ServerError;
}
if (cdInfoList_.isEmpty())
......@@ -196,6 +310,35 @@ namespace KCDDB
return infoList;
}
QString MusicBrainzLookup::artistFromCreditList(MusicBrainz4::CArtistCredit * artistCredit )
{
kDebug() << k_funcinfo;
QString artistName;
MusicBrainz4::CNameCreditList *ArtistList=artistCredit->NameCreditList();
if (ArtistList)
{
for (int i=0; i < ArtistList->NumItems(); i++)
{
MusicBrainz4::CNameCredit* Name=ArtistList->Item(i);
MusicBrainz4::CArtist* Artist = Name->Artist();
if (!Name->Name().empty())
artistName += QString::fromUtf8(Name->Name().c_str());
else
artistName += QString::fromUtf8(Artist->Name().c_str());
artistName += QString::fromUtf8(Name->JoinPhrase().c_str());
}
kDebug() << "Artist:" << artistName;
}
return artistName;
}
}
// vim:tabstop=2:shiftwidth=2:expandtab:cinoptions=(s,U1,m1
......
......@@ -25,6 +25,11 @@
#include "../kcddb.h"
#include "../kcddbconfig.h"
namespace MusicBrainz4
{
class CArtistCredit;
}
namespace KCDDB
{
class MusicBrainzLookup : public Lookup
......@@ -44,6 +49,7 @@ namespace KCDDB
private:
static QString calculateDiscId(const TrackOffsetList & );
static QString artistFromCreditList(MusicBrainz4::CArtistCredit * );
} ;
}
......
......@@ -27,6 +27,7 @@ KCDDB_UNIT_TESTS(
asyncmusicbrainztest
cdinfotest
cachetest
musicbrainztest-severaldiscs
)
KCDDB_EXECUTABLE_TESTS(
......
......@@ -28,7 +28,7 @@ void AsyncMusicBrainzTest::testLookup()
{
using namespace KCDDB;
#ifndef HAVE_MUSICBRAINZ3
#ifndef HAVE_MUSICBRAINZ4
QSKIP("This test requires libmusicbrainz", SkipAll);
#endif
......@@ -78,14 +78,14 @@ void AsyncMusicBrainzTest::testLookup()
QCOMPARE(m_info.get(Genre).toString(),QString());
QCOMPARE(m_info.get(Year).toInt(),0);
QCOMPARE(m_info.track(0).get(Title).toString(),QString::fromUtf8("Uphill Struggle"));
QCOMPARE(m_info.track(1).get(Title).toString(),QString::fromUtf8("Vill du bli miljonär?"));
QCOMPARE(m_info.track(1).get(Title).toString(),QString::fromUtf8("Vill du bli miljonär"));
QCOMPARE(m_info.track(2).get(Title).toString(),QString::fromUtf8("Här är jag"));
QCOMPARE(m_info.track(3).get(Title).toString(),QString::fromUtf8("Århundradets fest"));
QCOMPARE(m_info.track(4).get(Title).toString(),QString::fromUtf8("Vem valde mittemellan"));
QCOMPARE(m_info.track(5).get(Title).toString(),QString::fromUtf8("Hippieambulansen"));
QCOMPARE(m_info.track(6).get(Title).toString(),QString::fromUtf8("Jonsson"));
QCOMPARE(m_info.track(7).get(Title).toString(),QString::fromUtf8("Jag lämnar filmen"));
QCOMPARE(m_info.track(8).get(Title).toString(),QString::fromUtf8("39 Steg"));
QCOMPARE(m_info.track(8).get(Title).toString(),QString::fromUtf8("39 steg"));
QCOMPARE(m_info.track(9).get(Title).toString(),QString::fromUtf8("Lyckliga land"));
QCOMPARE(m_info.track(10).get(Title).toString(),QString::fromUtf8("Helpless"));
QCOMPARE(m_info.track(11).get(Title).toString(),QString::fromUtf8("Tunna skivor"));
......
/*
Copyright (C) 2006 Richard Lärkäng <nouseforaname@home.se>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <qtest_kde.h>
#include "musicbrainztest-severaldiscs.h"
#include "libkcddb/client.h"
#include "libkcddb/cache.h"
#include "libkcddb/lookup.h"
#include "config-musicbrainz.h"
void MusicBrainzTestSeveralDiscs::testLookup()
{
using namespace KCDDB;
#ifndef HAVE_MUSICBRAINZ4
QSKIP("This test requires libmusicbrainz", SkipAll);
#endif
Client c;
c.config().setCacheLookupEnabled(false);
c.config().setFreedbLookupEnabled(false);
c.config().setMusicBrainzLookupEnabled(true);
TrackOffsetList list;
list <<
150 <<
17272 <<
36395 <<
47954 <<
63638 <<
77928 <<
95029 <<
112094 <<
130540 <<
145938 <<
160463 <<
180364 <<
195549 <<
203821 <<
222410 <<
230367 <<
249241 <<
273944 <<
287584 <<
309904 <<
325124;
Result r = c.lookup(list);
QVERIFY(r == Success);
kDebug() << "Client::lookup gave : " << resultToString(r);
CDInfoList response = c.lookupResponse();
kDebug() << "Client::lookup returned : " << response.count() << " entries"
<< endl;
QVERIFY(response.count() > 0);
// See http://musicbrainz.org/tracklist/165651 for changes
CDInfo i(response.first());
QCOMPARE(i.numberOfTracks(),20);
QCOMPARE(i.get(Artist).toString(),QString("Billy Bragg"));
QCOMPARE(i.get(Title).toString(),QString("Must I Paint You a Picture? The Essential Billy Bragg (disc 2)"));
// genre and year not really supported for musicbrainz
QCOMPARE(i.get(Genre).toString(),QString());
QCOMPARE(i.get(Year).toInt(),0);
QCOMPARE(i.track(0).get(Title).toString(),QString("Sexuality"));
QCOMPARE(i.track(1).get(Title).toString(),QString("Cindy of 1000 Lives"));
QCOMPARE(i.track(2).get(Title).toString(),QString("Moving the Goalposts"));
QCOMPARE(i.track(3).get(Title).toString(),QString("Tank Park Salute"));
QCOMPARE(i.track(4).get(Title).toString(),QString("You Woke Up My Neighbourhood"));
QCOMPARE(i.track(5).get(Title).toString(),QString("Accident Waiting to Happen (Red Stars version)"));
QCOMPARE(i.track(6).get(Title).toString(),QString("Sulk"));
QCOMPARE(i.track(7).get(Title).toString(),QString("Upfield"));
QCOMPARE(i.track(8).get(Title).toString(),QString("The Fourteenth of February"));
QCOMPARE(i.track(9).get(Title).toString(),QString("Brickbat"));
QCOMPARE(i.track(10).get(Title).toString(),QString("The Space Race Is Over"));
QCOMPARE(i.track(11).get(Title).toString(),QString("The Boy Done Good"));
QCOMPARE(i.track(12).get(Title).toString(),QString("Ingrid Bergman"));
QCOMPARE(i.track(13).get(Title).toString(),QString("Way Over Yonder in the Minor Key"));
QCOMPARE(i.track(14).get(Title).toString(),QString("My Flying Saucer"));
QCOMPARE(i.track(15).get(Title).toString(),QString("All You Fascists Bound to Lose (Blokes version)"));
QCOMPARE(i.track(16).get(Title).toString(),QString("NPWA"));