7#include "musicbrainzlookup.h" 
   11#include <musicbrainz5/Query.h> 
   12#include <musicbrainz5/Medium.h> 
   13#include <musicbrainz5/Release.h> 
   14#include <musicbrainz5/ReleaseGroup.h> 
   15#include <musicbrainz5/Track.h> 
   16#include <musicbrainz5/Recording.h> 
   17#include <musicbrainz5/Disc.h> 
   18#include <musicbrainz5/HTTPFetch.h> 
   19#include <musicbrainz5/ArtistCredit.h> 
   20#include <musicbrainz5/Artist.h> 
   21#include <musicbrainz5/NameCredit.h> 
   22#include <musicbrainz5/SecondaryType.h> 
   24#include <QCryptographicHash> 
   26#include <QRegularExpression> 
   33  MusicBrainzLookup::MusicBrainzLookup()
 
   38  MusicBrainzLookup::~MusicBrainzLookup()
 
   43  Result MusicBrainzLookup::lookup( 
const QString &, uint, 
const TrackOffsetList & trackOffsetList )
 
   45    QString discId = calculateDiscId(trackOffsetList);
 
   47    qDebug() << 
"Should lookup " << discId;
 
   49    MusicBrainz5::CQuery Query(
"libkcddb-0.5");
 
   54      MusicBrainz5::CMetadata Metadata=Query.Query(
"discid",discId.
toLatin1().
constData());
 
   56      if (Metadata.Disc() && Metadata.Disc()->ReleaseList())
 
   58        MusicBrainz5::CReleaseList *ReleaseList=Metadata.Disc()->ReleaseList();
 
   59        qDebug() << 
"Found " << ReleaseList->NumItems() << 
" release(s)";
 
   63        for (
int i = 0; i < ReleaseList->NumItems(); i++)
 
   65          MusicBrainz5::CRelease* 
Release=ReleaseList->Item(i);
 
   69          MusicBrainz5::CQuery::tParamMap Params;
 
   70          Params[
"inc"]=
"artists labels recordings release-groups url-rels discids artist-credits";
 
   72          std::string ReleaseID=
Release->ID();
 
   74          MusicBrainz5::CMetadata Metadata2=Query.Query(
"release",ReleaseID,
"",Params);
 
   75          if (Metadata2.Release())
 
   77            MusicBrainz5::CRelease *FullRelease=Metadata2.Release();
 
   82            MusicBrainz5::CMediumList MediaList=FullRelease->MediaMatchingDiscID(discId.
toLatin1().
constData());
 
   84            if (MediaList.NumItems() > 0)
 
   91              qDebug() << 
"Found " << MediaList.NumItems() << 
" media item(s)";
 
   93              for (
int i=0; i < MediaList.NumItems(); i++)
 
   95                MusicBrainz5::CMedium* Medium= MediaList.Item(i);
 
  100                info.set(QLatin1String( 
"source" ), QLatin1String( 
"musicbrainz" ));
 
  105                  info.set(QLatin1String( 
"discid" ), discId);
 
  107                  info.set(QLatin1String( 
"discid" ), QVariant(discId+QLatin1String( 
"-" )+
QString::number(relnr)));
 
  111                if (FullRelease->MediumList()->NumItems() > 1)
 
  112                  title = 
i18n(
"%1 (disc %2)", title, Medium->Position());
 
  114                info.set(Title, title);
 
  115                info.set(Artist, artistFromCreditList(FullRelease->ArtistCredit()));
 
  118                const QRegularExpression yearRe(
QString::fromUtf8(
"^(\\d{4,4})(-\\d{1,2}-\\d{1,2})?$"));
 
  120                if (
const auto yearMatch = yearRe.match(date); yearMatch.hasMatch())
 
  122                  QString yearString = yearMatch.captured(1);
 
  124                  year=yearString.
toInt(&ok);
 
  128                info.set(Year, year);
 
  130                MusicBrainz5::CTrackList *TrackList=Medium->TrackList();
 
  133                  for (
int i=0; i < TrackList->NumItems(); i++)
 
  135                    MusicBrainz5::CTrack* Track=TrackList->Item(i);
 
  136                    MusicBrainz5::CRecording *Recording=Track->Recording();
 
  138                    TrackInfo& track = info.track(i);
 
  146                    if(Recording && Track->ArtistCredit() == 
nullptr)
 
  147                      track.set(Artist, artistFromCreditList(Recording->ArtistCredit()));
 
  149                      track.set(Artist, artistFromCreditList(Track->ArtistCredit()));
 
  151                    if(Recording && Track->Title().empty())
 
  166    catch (MusicBrainz5::CConnectionError& Error)
 
  168      qDebug() << 
"Connection Exception: '" << 
Error.what() << 
"'";
 
  169      qDebug() << 
"LastResult: " << Query.LastResult();
 
  170      qDebug() << 
"LastHTTPCode: " << Query.LastHTTPCode();
 
  171      qDebug() << 
"LastErrorMessage: " << 
QString::fromUtf8(Query.LastErrorMessage().c_str());
 
  176    catch (MusicBrainz5::CTimeoutError& Error)
 
  178      qDebug() << 
"Timeout Exception: '" << 
Error.what() << 
"'";
 
  179      qDebug() << 
"LastResult: " << Query.LastResult();
 
  180      qDebug() << 
"LastHTTPCode: " << Query.LastHTTPCode();
 
  181      qDebug() << 
"LastErrorMessage: " << 
QString::fromUtf8(Query.LastErrorMessage().c_str());
 
  186    catch (MusicBrainz5::CAuthenticationError& Error)
 
  188      qDebug() << 
"Authentication Exception: '" << 
Error.what() << 
"'";
 
  189      qDebug() << 
"LastResult: " << Query.LastResult();
 
  190      qDebug() << 
"LastHTTPCode: " << Query.LastHTTPCode();
 
  191      qDebug() << 
"LastErrorMessage: " << 
QString::fromUtf8(Query.LastErrorMessage().c_str());
 
  196    catch (MusicBrainz5::CFetchError& Error)
 
  198      qDebug() << 
"Fetch Exception: '" << 
Error.what() << 
"'";
 
  199      qDebug() << 
"LastResult: " << Query.LastResult();
 
  200      qDebug() << 
"LastHTTPCode: " << Query.LastHTTPCode();
 
  201      qDebug() << 
"LastErrorMessage: " << 
QString::fromUtf8(Query.LastErrorMessage().c_str());
 
  206    catch (MusicBrainz5::CRequestError& Error)
 
  208      qDebug() << 
"Request Exception: '" << 
Error.what() << 
"'";
 
  209      qDebug() << 
"LastResult: " << Query.LastResult();
 
  210      qDebug() << 
"LastHTTPCode: " << Query.LastHTTPCode();
 
  211      qDebug() << 
"LastErrorMessage: " << 
QString::fromUtf8(Query.LastErrorMessage().c_str());
 
  216    catch (MusicBrainz5::CResourceNotFoundError& Error)
 
  218      qDebug() << 
"ResourceNotFound Exception: '" << 
Error.what() << 
"'";
 
  219      qDebug() << 
"LastResult: " << Query.LastResult();
 
  220      qDebug() << 
"LastHTTPCode: " << Query.LastHTTPCode();
 
  221      qDebug() << 
"LastErrorMessage: " << 
QString::fromUtf8(Query.LastErrorMessage().c_str());
 
  226    if (cdInfoList_.isEmpty())
 
  228        qDebug() << 
"No record found";
 
  229        return NoRecordFound;
 
  232    qDebug() << 
"Query succeeded :-)";
 
  237  QString MusicBrainzLookup::calculateDiscId(
const TrackOffsetList & trackOffsetList )
 
  241    int numTracks = trackOffsetList.count()-1;
 
  248    int lastTrack = numTracks;
 
  250    sprintf(temp, 
"%02X", firstTrack);
 
  251    sha.addData(QByteArrayView(temp, strlen(temp)));
 
  253    sprintf(temp, 
"%02X", lastTrack);
 
  254    sha.addData(QByteArrayView(temp, strlen(temp)));
 
  256    for(
int i = 0; i < 100; i++)
 
  260        offset = trackOffsetList[numTracks];
 
  261      else if (i <= numTracks)
 
  262        offset = trackOffsetList[i-1];
 
  266      sprintf(temp, 
"%08lX", offset);
 
  267      sha.addData(QByteArrayView(temp, strlen(temp)));
 
  270    QByteArray base64 = sha.result().toBase64();
 
  278  CDInfoList MusicBrainzLookup::cacheFiles(
const TrackOffsetList &offsetList, 
const Config& c )
 
  281    QStringList cddbCacheDirs = c.cacheLocations();
 
  282    QString discid = calculateDiscId(offsetList);
 
  284    for (QStringList::const_iterator cddbCacheDir = cddbCacheDirs.
constBegin();
 
  285        cddbCacheDir != cddbCacheDirs.
constEnd(); ++cddbCacheDir)
 
  290      QDir 
dir(*cddbCacheDir+QLatin1String( 
"/musicbrainz/" ));
 
  291      dir.setNameFilters(QStringList(discid+QLatin1String( 
"*" )));
 
  293      QStringList files = 
dir.entryList();
 
  294      qDebug() << 
"Cache files found: " << files.
count();
 
  295      for (QStringList::iterator it = files.
begin(); it != files.
end(); ++it)
 
  297        QFile f( 
dir.filePath(*it) );
 
  301          QString cddbData = ts.readAll();
 
  305          info.set(QLatin1String( 
"source" ), QLatin1String( 
"musicbrainz" ));
 
  306          info.set(QLatin1String( 
"discid" ), discid);
 
  308          infoList.append( info );
 
  311          qDebug() << 
"Could not read file: " << f.fileName();
 
  318  QString MusicBrainzLookup::artistFromCreditList(MusicBrainz5::CArtistCredit * artistCredit )
 
  323    MusicBrainz5::CNameCreditList *ArtistList=artistCredit->NameCreditList();
 
  327      for (
int i=0; i < ArtistList->NumItems(); i++)
 
  329        MusicBrainz5::CNameCredit* Name=ArtistList->Item(i);
 
  330        MusicBrainz5::CArtist* 
Artist = Name->Artist();
 
  332        if (!Name->Name().empty())
 
  340      qDebug() << 
"Artist:" << artistName;
 
  348#include "moc_musicbrainzlookup.cpp" 
QString i18n(const char *text, const TYPE &arg...)
 
KIOCORE_EXPORT QString dir(const QString &fileClass)
 
const char * constData() const const
 
const_iterator constBegin() const const
 
const_iterator constEnd() const const
 
qsizetype count() const const
 
QString fromLatin1(QByteArrayView str)
 
QString fromUtf8(QByteArrayView str)
 
QString number(double n, char format, int precision)
 
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
 
int toInt(bool *ok, int base) const const
 
QByteArray toLatin1() const const