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

« back to all changes in this revision

Viewing changes to src/internet/jamendodynamicplaylist.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:
 
1
/* This file is part of Clementine.
 
2
   Copyright 2011, David Sansome <me@davidsansome.com>
 
3
 
 
4
   Clementine is free software: you can redistribute it and/or modify
 
5
   it under the terms of the GNU General Public License as published by
 
6
   the Free Software Foundation, either version 3 of the License, or
 
7
   (at your option) any later version.
 
8
 
 
9
   Clementine is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
   GNU General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU General Public License
 
15
   along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
 
16
*/
 
17
 
 
18
#include "jamendodynamicplaylist.h"
 
19
 
 
20
#include "jamendoplaylistitem.h"
 
21
#include "jamendoservice.h"
 
22
 
 
23
#include <QEventLoop>
 
24
#include <QHttp>
 
25
#include <QHttpRequestHeader>
 
26
#include <QtDebug>
 
27
 
 
28
#include "core/logging.h"
 
29
#include "core/network.h"
 
30
#include "library/librarybackend.h"
 
31
 
 
32
const char* JamendoDynamicPlaylist::kUrl =
 
33
    "http://api.jamendo.com/get2/id/track/plain/";
 
34
 
 
35
JamendoDynamicPlaylist::JamendoDynamicPlaylist()
 
36
  : order_by_(OrderBy_Rating),
 
37
    order_direction_(Order_Descending),
 
38
    current_page_(0),
 
39
    current_index_(0) {
 
40
}
 
41
 
 
42
JamendoDynamicPlaylist::JamendoDynamicPlaylist(const QString& name, OrderBy order_by)
 
43
  : order_by_(order_by),
 
44
    order_direction_(Order_Descending),
 
45
    current_page_(0),
 
46
    current_index_(0) {
 
47
  set_name(name);
 
48
}
 
49
 
 
50
void JamendoDynamicPlaylist::Load(const QByteArray& data) {
 
51
  QDataStream s(data);
 
52
  s >> *this;
 
53
}
 
54
 
 
55
void JamendoDynamicPlaylist::Load(OrderBy order_by, OrderDirection order_direction) {
 
56
  order_by_ = order_by;
 
57
  order_direction_ = order_direction;
 
58
}
 
59
 
 
60
QByteArray JamendoDynamicPlaylist::Save() const {
 
61
  QByteArray ret;
 
62
  QDataStream s(&ret, QIODevice::WriteOnly);
 
63
  s << *this;
 
64
 
 
65
  return ret;
 
66
}
 
67
 
 
68
PlaylistItemList JamendoDynamicPlaylist::Generate() {
 
69
  return GenerateMore(20);
 
70
}
 
71
 
 
72
PlaylistItemList JamendoDynamicPlaylist::GenerateMore(int count) {
 
73
  int tries = 0;
 
74
 
 
75
  PlaylistItemList items;
 
76
  while (items.size() < count && tries++ < kApiRetryLimit) {
 
77
    // Add items from current list.
 
78
    if (current_index_ < current_items_.size()) {
 
79
      PlaylistItemList more_items = current_items_.mid(current_index_, count);
 
80
      items << more_items;
 
81
      current_index_ += more_items.size();
 
82
    } else {
 
83
      // We need more songs!
 
84
      Fetch();
 
85
    }
 
86
  }
 
87
 
 
88
  return items;
 
89
}
 
90
 
 
91
QString JamendoDynamicPlaylist::OrderSpec(OrderBy by, OrderDirection dir) {
 
92
  QString ret;
 
93
  switch (by) {
 
94
    case OrderBy_Listened:    ret += "listened";    break;
 
95
    case OrderBy_Rating:      ret += "rating";      break;
 
96
    case OrderBy_RatingMonth: ret += "ratingmonth"; break;
 
97
    case OrderBy_RatingWeek:  ret += "ratingweek";  break;
 
98
  }
 
99
  switch (dir) {
 
100
    case Order_Ascending:     ret += "_asc";        break;
 
101
    case Order_Descending:    ret += "_desc";       break;
 
102
  }
 
103
  return ret;
 
104
}
 
105
 
 
106
void JamendoDynamicPlaylist::Fetch() {
 
107
  QUrl url(kUrl);
 
108
  url.addQueryItem("pn", QString::number(current_page_++));
 
109
  url.addQueryItem("n", QString::number(kPageSize));
 
110
  url.addQueryItem("order", OrderSpec(order_by_, order_direction_));
 
111
 
 
112
  // We have to use QHttp here because there's no way to disable Keep-Alive
 
113
  // with QNetworkManager.
 
114
  QHttpRequestHeader header("GET", url.encodedPath() + "?" + url.encodedQuery());
 
115
  header.setValue("Host", url.encodedHost());
 
116
 
 
117
  QHttp http(url.host());
 
118
  http.request(header);
 
119
 
 
120
  // Wait for the reply
 
121
  {
 
122
    QEventLoop event_loop;
 
123
    connect(&http, SIGNAL(requestFinished(int,bool)), &event_loop, SLOT(quit()));
 
124
    event_loop.exec();
 
125
  }
 
126
 
 
127
  if (http.error() != QHttp::NoError) {
 
128
    qLog(Warning) << "HTTP error returned from Jamendo:" << http.errorString()
 
129
               << ", url:" << url.toString();
 
130
    return;
 
131
  }
 
132
 
 
133
  // The reply will contain one track ID per line
 
134
  QStringList lines = QString::fromAscii(http.readAll()).split('\n');
 
135
 
 
136
  // Get the songs from the database
 
137
  SongList songs = backend_->GetSongsByForeignId(
 
138
        lines, JamendoService::kTrackIdsTable, JamendoService::kTrackIdsColumn);
 
139
 
 
140
  if (songs.empty()) {
 
141
    qLog(Warning) << "No songs returned from Jamendo:"
 
142
               << url.toString();
 
143
    return;
 
144
  }
 
145
 
 
146
  current_items_.clear();
 
147
  foreach (const Song& song, songs) {
 
148
    if (song.is_valid())
 
149
      current_items_ << PlaylistItemPtr(new JamendoPlaylistItem(song));
 
150
  }
 
151
  current_index_ = 0;
 
152
}
 
153
 
 
154
QDataStream& operator <<(QDataStream& s, const JamendoDynamicPlaylist& p) {
 
155
  s << quint8(p.order_by_) << quint8(p.order_direction_);
 
156
  return s;
 
157
}
 
158
 
 
159
QDataStream& operator >>(QDataStream& s, JamendoDynamicPlaylist& p) {
 
160
  quint8 order_by, order_direction;
 
161
  s >> order_by >> order_direction;
 
162
  p.order_by_ = JamendoDynamicPlaylist::OrderBy(order_by);
 
163
  p.order_direction_ = JamendoDynamicPlaylist::OrderDirection(order_direction);
 
164
  return s;
 
165
}