~ubuntu-branches/ubuntu/saucy/clementine/saucy

« back to all changes in this revision

Viewing changes to src/musicbrainz/musicbrainzclient.cpp

  • Committer: Package Import Robot
  • Author(s): Thomas PIERSON
  • Date: 2012-01-01 20:43:39 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120101204339-lsb6nndwhfy05sde
Tags: 1.0.1+dfsg-1
New upstream release. (Closes: #653926, #651611, #657391)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
*/
17
17
 
18
18
#include "musicbrainzclient.h"
 
19
#include "core/logging.h"
19
20
#include "core/network.h"
 
21
#include "core/utilities.h"
20
22
 
21
23
#include <QCoreApplication>
22
24
#include <QNetworkReply>
 
25
#include <QSet>
23
26
#include <QXmlStreamReader>
24
27
#include <QtDebug>
25
28
 
26
 
const char* MusicBrainzClient::kUrl = "http://musicbrainz.org/ws/1/track/";
 
29
const char* MusicBrainzClient::kTrackUrl = "http://musicbrainz.org/ws/2/recording/";
 
30
const char* MusicBrainzClient::kDiscUrl = "http://musicbrainz.org/ws/1/release/";
 
31
const char* MusicBrainzClient::kDateRegex = "^[12]\\d{3}";
27
32
const int MusicBrainzClient::kDefaultTimeout = 5000; // msec
28
33
 
29
34
MusicBrainzClient::MusicBrainzClient(QObject* parent)
33
38
{
34
39
}
35
40
 
36
 
void MusicBrainzClient::Start(int id, const QString& puid) {
 
41
void MusicBrainzClient::Start(int id, const QString& mbid) {
37
42
  typedef QPair<QString, QString> Param;
38
43
 
39
44
  QList<Param> parameters;
40
 
  parameters << Param("type", "xml")
41
 
             << Param("puid", puid);
 
45
  parameters << Param("inc", "artists+releases+media");
42
46
 
43
 
  QUrl url(kUrl);
 
47
  QUrl url(kTrackUrl + mbid);
44
48
  url.setQueryItems(parameters);
45
49
  QNetworkRequest req(url);
46
50
 
51
55
  timeouts_->AddReply(reply);
52
56
}
53
57
 
 
58
void MusicBrainzClient::StartDiscIdRequest(const QString& discid) {
 
59
  typedef QPair<QString, QString> Param;
 
60
 
 
61
  QList<Param> parameters;
 
62
  parameters << Param("type", "xml")
 
63
             << Param("discid", discid);
 
64
 
 
65
  QUrl url(kDiscUrl);
 
66
  url.setQueryItems(parameters);
 
67
  QNetworkRequest req(url);
 
68
 
 
69
  QNetworkReply* reply = network_->get(req);
 
70
  connect(reply, SIGNAL(finished()), SLOT(DiscIdRequestFinished()));
 
71
  //requests_[reply] = id;
 
72
 
 
73
  timeouts_->AddReply(reply);
 
74
}
 
75
 
54
76
void MusicBrainzClient::Cancel(int id) {
55
77
  QNetworkReply* reply = requests_.key(id);
56
78
  requests_.remove(reply);
62
84
  requests_.clear();
63
85
}
64
86
 
 
87
void MusicBrainzClient::DiscIdRequestFinished() {
 
88
  QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
 
89
  if (!reply)
 
90
    return;
 
91
  reply->deleteLater();
 
92
 
 
93
  ResultList ret;
 
94
  QString artist;
 
95
  QString album;
 
96
 
 
97
  if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
 
98
    emit Finished(artist, album, ret);
 
99
    return;
 
100
  }
 
101
 
 
102
  // Parse xml result:
 
103
  // -get title
 
104
  // -get artist
 
105
  // -get all the tracks' tags
 
106
  QXmlStreamReader reader(reply);
 
107
  while (!reader.atEnd()) {
 
108
    QXmlStreamReader::TokenType type = reader.readNext();
 
109
    if (type == QXmlStreamReader::StartElement) {
 
110
      QStringRef name = reader.name();
 
111
      if (name == "title") {
 
112
        album = reader.readElementText();
 
113
      } else if (name == "artist") {
 
114
        ParseArtist(&reader, &artist);
 
115
      } else if (name == "track-list") {
 
116
        break;
 
117
      }
 
118
    }
 
119
  }
 
120
 
 
121
  while (!reader.atEnd()) {
 
122
    QXmlStreamReader::TokenType token = reader.readNext();
 
123
    if (token == QXmlStreamReader::StartElement && reader.name() == "track") {
 
124
      ResultList tracks = ParseTrack(&reader);
 
125
      foreach (const Result& track, tracks) {
 
126
        if (!track.title_.isEmpty()) {
 
127
          ret << track;
 
128
        }
 
129
      }
 
130
    } else if (token == QXmlStreamReader::EndElement && reader.name() == "track-list") {
 
131
      break;
 
132
    }
 
133
  }
 
134
 
 
135
  emit Finished(artist, album, UniqueResults(ret));
 
136
}
 
137
 
 
138
 
65
139
void MusicBrainzClient::RequestFinished() {
66
140
  QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
67
141
  if (!reply)
81
155
 
82
156
  QXmlStreamReader reader(reply);
83
157
  while (!reader.atEnd()) {
84
 
    if (reader.readNext() == QXmlStreamReader::StartElement && reader.name() == "track") {
85
 
      Result track = ParseTrack(&reader);
86
 
      if (!track.title_.isEmpty()) {
87
 
        ret << track;
 
158
    if (reader.readNext() == QXmlStreamReader::StartElement && reader.name() == "recording") {
 
159
      ResultList tracks = ParseTrack(&reader);
 
160
      foreach (const Result& track, tracks) {
 
161
        if (!track.title_.isEmpty()) {
 
162
          ret << track;
 
163
        }
88
164
      }
89
165
    }
90
166
  }
91
167
 
92
 
  emit Finished(id, ret);
 
168
  emit Finished(id, UniqueResults(ret));
93
169
}
94
170
 
95
 
MusicBrainzClient::Result MusicBrainzClient::ParseTrack(QXmlStreamReader* reader) {
96
 
  Result ret;
 
171
MusicBrainzClient::ResultList MusicBrainzClient::ParseTrack(QXmlStreamReader* reader) {
 
172
  Result result;
 
173
  QList<Release> releases;
97
174
 
98
175
  while (!reader->atEnd()) {
99
176
    QXmlStreamReader::TokenType type = reader->readNext();
102
179
      QStringRef name = reader->name();
103
180
 
104
181
      if (name == "title") {
105
 
        ret.title_ = reader->readElementText();
106
 
      } else if (name == "duration") {
107
 
        ret.duration_msec_ = reader->readElementText().toInt();
 
182
        result.title_ = reader->readElementText();
 
183
      } else if (name == "length") {
 
184
        result.duration_msec_ = reader->readElementText().toInt();
108
185
      } else if (name == "artist") {
109
 
        ParseArtist(reader, &ret.artist_);
 
186
        ParseArtist(reader, &result.artist_);
110
187
      } else if (name == "release") {
111
 
        ParseAlbum(reader, &ret.album_, &ret.track_);
 
188
        releases << ParseRelease(reader);
112
189
      }
113
190
    }
114
191
 
115
 
    if (type == QXmlStreamReader::EndElement && reader->name() == "track") {
 
192
    if (type == QXmlStreamReader::EndElement && reader->name() == "recording") {
116
193
      break;
117
194
    }
118
195
  }
119
196
 
 
197
  ResultList ret;
 
198
  foreach (const Release& release, releases) {
 
199
    ret << release.CopyAndMergeInto(result);
 
200
  }
120
201
  return ret;
121
202
}
122
203
 
134
215
  }
135
216
}
136
217
 
137
 
void MusicBrainzClient::ParseAlbum(QXmlStreamReader* reader, QString* album, int* track) {
 
218
MusicBrainzClient::Release MusicBrainzClient::ParseRelease(QXmlStreamReader* reader) {
 
219
  Release ret;
 
220
 
138
221
  while (!reader->atEnd()) {
139
222
    QXmlStreamReader::TokenType type = reader->readNext();
140
223
 
141
224
    if (type == QXmlStreamReader::StartElement) {
142
225
      QStringRef name = reader->name();
143
226
      if (name == "title") {
144
 
        *album = reader->readElementText();
 
227
        ret.album_ = reader->readElementText();
 
228
      } else if (name == "date") {
 
229
        QRegExp regex(kDateRegex);
 
230
        if (regex.indexIn(reader->readElementText()) == 0) {
 
231
          ret.year_ = regex.cap(0).toInt();
 
232
        }
145
233
      } else if (name == "track-list") {
146
 
        *track = reader->attributes().value("offset").toString().toInt() + 1;
 
234
        ret.track_ = reader->attributes().value("offset").toString().toInt() + 1;
 
235
        Utilities::ConsumeCurrentElement(reader);
147
236
      }
148
237
    }
149
238
 
150
239
    if (type == QXmlStreamReader::EndElement && reader->name() == "release") {
151
 
      return;
 
240
      break;
152
241
    }
153
242
  }
 
243
 
 
244
  return ret;
 
245
}
 
246
 
 
247
MusicBrainzClient::ResultList MusicBrainzClient::UniqueResults(const ResultList& results) {
 
248
  ResultList ret = QSet<Result>::fromList(results).toList();
 
249
  qSort(ret);
 
250
  return ret;
154
251
}