~ubuntu-branches/ubuntu/natty/kdemultimedia/natty-proposed

« back to all changes in this revision

Viewing changes to libkcddb/musicbrainz/musicbrainzlookup.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Debian Qt/KDE Maintainers
  • Date: 2011-05-26 02:41:36 UTC
  • mfrom: (0.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 108.
  • Revision ID: james.westby@ubuntu.com-20110526024136-jjwsigfy402jhupm
Tags: upstream-4.6.3
ImportĀ upstreamĀ versionĀ 4.6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <qcryptographichash.h>
26
26
#include <cstdio>
27
27
#include <cstring>
28
 
#include <musicbrainz/musicbrainz.h>
29
 
 
30
 
// Added in libmusicbrainz 2.1.3
31
 
#ifndef MBE_AlbumGetAlbumArtistName
32
 
#define MBE_AlbumGetAlbumArtistName \
33
 
  "http://purl.org/dc/elements/1.1/creator http://purl.org/dc/elements/1.1/title"
34
 
#endif
 
28
#include <musicbrainz3/musicbrainz.h>
 
29
#include <musicbrainz3/query.h>
 
30
#include <musicbrainz3/release.h>
 
31
#include <musicbrainz3/filters.h>
35
32
 
36
33
namespace KCDDB
37
34
{
44
41
  {
45
42
 
46
43
  }
47
 
  
 
44
 
48
45
  Result MusicBrainzLookup::lookup( const QString &, uint, const TrackOffsetList & trackOffsetList )
49
46
  {
50
47
    QString discId = calculateDiscId(trackOffsetList);
51
 
    
 
48
 
52
49
    kDebug() << "Should lookup " << discId;
53
50
 
54
 
    ::MusicBrainz mb;
55
 
 
56
 
    mb.UseUTF8(true);
57
 
    mb.SetDepth(4);
58
 
 
59
 
    vector<string> args;
60
 
    args.insert(args.begin(), discId.toLatin1().data());
61
 
 
62
 
    if (!mb.Query(MBQ_GetCDInfoFromCDIndexId, &args))
63
 
    {
64
 
      string error;
65
 
      
66
 
      mb.GetQueryError(error);
67
 
      kDebug() << "Query failed: " << error.c_str();
68
 
      
69
 
      return UnknownError;
70
 
    }
71
 
 
72
 
    int nrAlbums = mb.DataInt(MBE_GetNumAlbums);
73
 
 
74
 
    if (nrAlbums < 1)
75
 
    {
76
 
      kDebug() << "No CD Found";
77
 
 
78
 
      return UnknownError;
79
 
    }
80
 
 
81
 
    for (int i=1; i <= nrAlbums; i++)
82
 
    {
83
 
      mb.Select(MBS_SelectAlbum, i);
84
 
 
85
 
      CDInfo info;
86
 
      info.set("source", "musicbrainz");
87
 
      // FIXME Could have different discid than the one above?
88
 
      // Will break cache if several entries have same discid
89
 
      info.set("discid", discId);
90
 
 
91
 
      info.set(Title, QString::fromUtf8(mb.Data(MBE_AlbumGetAlbumName).c_str()));
92
 
      info.set(Artist, QString::fromUtf8(mb.Data(MBE_AlbumGetAlbumArtistName).c_str()));
93
 
 
94
 
      int numTracks = trackOffsetList.count()-1;
95
 
 
96
 
      for (int i=1; i <= numTracks; i++)
97
 
      {
98
 
        TrackInfo& track = info.track(i-1);
99
 
        track.set(Artist, QString::fromUtf8(mb.Data(MBE_AlbumGetArtistName, i).c_str()));
100
 
        track.set(Title, QString::fromUtf8(mb.Data(MBE_AlbumGetTrackName, i).c_str()));
101
 
      }
102
 
 
103
 
      cdInfoList_ << info;
 
51
    MusicBrainz::Query q;
 
52
    MusicBrainz::ReleaseResultList results;
 
53
 
 
54
    try {
 
55
        MusicBrainz::ReleaseFilter f = MusicBrainz::ReleaseFilter().discId(std::string(discId.toAscii()));
 
56
        results = q.getReleases(&f);
 
57
    }
 
58
                // FIXME Doesn't seem to get caught, why?
 
59
    // catch (MusicBrainz::WebServiceError &e)
 
60
    catch (...)
 
61
    {
 
62
        kDebug() << "Query failed"; //<< e.what();
 
63
        return UnknownError;
 
64
    }
 
65
 
 
66
    int relnr=1;
 
67
    for (MusicBrainz::ReleaseResultList::iterator i = results.begin(); i != results.end(); i++) {
 
68
        MusicBrainz::ReleaseResult *result = *i;
 
69
        MusicBrainz::Release *release;
 
70
        try {
 
71
            release = q.getReleaseById(result->getRelease()->getId(), &MusicBrainz::ReleaseIncludes().tracks().artist());
 
72
        }
 
73
        catch (MusicBrainz::WebServiceError &e) {
 
74
            kDebug() << "Error: " << e.what();
 
75
            continue;
 
76
        }
 
77
        CDInfo info;
 
78
        info.set(QLatin1String( "source" ), QLatin1String( "musicbrainz" ));
 
79
        // Uses musicbrainz discid for the first release,
 
80
        // then discid-2, discid-3 and so on, to
 
81
        // allow multiple releases with the same discid
 
82
        if (relnr == 1)
 
83
          info.set(QLatin1String( "discid" ), discId);
 
84
        else
 
85
          info.set(QLatin1String( "discid" ), discId+QLatin1String( "-" )+QString::number(relnr));
 
86
 
 
87
        info.set(Title, QString::fromUtf8(release->getTitle().c_str()));
 
88
        info.set(Artist, QString::fromUtf8(release->getArtist()->getName().c_str()));
 
89
 
 
90
        int trackno = 0;
 
91
        for (MusicBrainz::TrackList::iterator j = release->getTracks().begin(); j != release->getTracks().end(); j++) {
 
92
            MusicBrainz::Track *mb_track = *j;
 
93
            MusicBrainz::Artist *artist = mb_track->getArtist();
 
94
            if (!artist)
 
95
              artist = release->getArtist();
 
96
            TrackInfo& track = info.track(trackno);
 
97
            track.set(Artist, QString::fromUtf8(artist->getName().c_str()));
 
98
            track.set(Title, QString::fromUtf8(mb_track->getTitle().c_str()));
 
99
            trackno++;
 
100
        }
 
101
        delete result;
 
102
 
 
103
        cdInfoList_ << info;
 
104
        relnr++;
 
105
    }
 
106
 
 
107
    if (cdInfoList_.isEmpty())
 
108
    {
 
109
        kDebug() << "No record found";
 
110
        return NoRecordFound;
104
111
    }
105
112
 
106
113
    kDebug() << "Query succeeded :-)";
107
114
 
108
115
    return Success;
109
116
  }
110
 
  
 
117
 
111
118
  QString MusicBrainzLookup::calculateDiscId(const TrackOffsetList & trackOffsetList )
112
119
  {
113
120
    // Code based on libmusicbrainz/lib/diskid.cpp
114
 
    
 
121
 
115
122
    int numTracks = trackOffsetList.count()-1;
116
123
 
117
124
    QCryptographicHash sha(QCryptographicHash::Sha1);
140
147
      sprintf(temp, "%08lX", offset);
141
148
      sha.addData(temp, strlen(temp));
142
149
    }
143
 
    
 
150
 
144
151
    QByteArray base64 = sha.result().toBase64();
145
152
 
146
153
    // '/' '+' and '=' replaced for MusicBrainz
147
 
    QString res = QString::fromLatin1(base64).replace('/',"_").replace('+',".").replace('=',"-");
148
 
    
 
154
    QString res = QString::fromLatin1(base64).replace(QLatin1Char( '/' ),QLatin1String( "_" )).replace(QLatin1Char( '+' ),QLatin1String( "." )).replace(QLatin1Char( '=' ),QLatin1String( "-" ));
 
155
 
149
156
    return res;
150
157
  }
151
158
 
158
165
    for (QStringList::const_iterator cddbCacheDir = cddbCacheDirs.constBegin();
159
166
        cddbCacheDir != cddbCacheDirs.constEnd(); ++cddbCacheDir)
160
167
    {
161
 
      QString fileName = *cddbCacheDir + "/musicbrainz/" + discid;
 
168
      // Looks for all files in cddbdir/musicbrainz/discid*
 
169
      // Several files can correspond to the same discid,
 
170
      // then they are named discid, discid-2, discid-3 and so on
 
171
      QDir dir(*cddbCacheDir+QLatin1String( "/musicbrainz/" ));
 
172
      dir.setNameFilters(QStringList(discid+QLatin1String( "*" )));
162
173
 
163
 
      QFile f( fileName );
164
 
      if ( f.exists() && f.open(QIODevice::ReadOnly) )
 
174
      QStringList files = dir.entryList();
 
175
      kDebug() << "Cache files found: " << files.count();
 
176
      for (QStringList::iterator it = files.begin(); it != files.end(); ++it)
165
177
      {
166
 
        QTextStream ts(&f);
167
 
        ts.setCodec("UTF-8");
168
 
        QString cddbData = ts.readAll();
169
 
        f.close();
170
 
        CDInfo info;
171
 
        info.load(cddbData);
172
 
        info.set("source", "musicbrainz");
173
 
        info.set("discid", discid);
 
178
        QFile f( dir.filePath(*it) );
 
179
        if ( f.exists() && f.open(QIODevice::ReadOnly) )
 
180
        {
 
181
          QTextStream ts(&f);
 
182
          ts.setCodec("UTF-8");
 
183
          QString cddbData = ts.readAll();
 
184
          f.close();
 
185
          CDInfo info;
 
186
          info.load(cddbData);
 
187
          info.set(QLatin1String( "source" ), QLatin1String( "musicbrainz" ));
 
188
          info.set(QLatin1String( "discid" ), discid);
174
189
 
175
 
        infoList.append( info );
 
190
          infoList.append( info );
 
191
        }
 
192
        else
 
193
          kDebug() << "Could not read file: " << f.fileName();
176
194
      }
177
195
    }
178
196