1
/* This file is part of Clementine.
2
Copyright 2011, David Sansome <me@davidsansome.com>
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.
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.
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/>.
18
#ifndef GROOVESHARKSERVICE_H
19
#define GROOVESHARKSERVICE_H
21
#include "internetmodel.h"
22
#include "internetservice.h"
26
class GroovesharkUrlHandler;
27
class NetworkAccessManager;
30
class QSortFilterProxyModel;
31
class QNetworkRequest;
33
class GroovesharkService : public InternetService {
36
GroovesharkService(InternetModel *parent);
37
~GroovesharkService();
40
Type_SearchResults = InternetModel::TypeCount,
45
Role_UserPlaylistId = InternetModel::RoleCount,
50
UserPlaylist = Qt::UserRole,
51
// Favorites list is like a playlist, but we want to do special treatments
57
// Values are persisted - don't change.
59
LoginState_LoggedIn = 1,
60
LoginState_AuthFailed = 2,
61
LoginState_NoPremium = 3,
62
LoginState_OtherError = 4
65
// Internet Service methods
66
QStandardItem* CreateRootItem();
67
void LazyPopulate(QStandardItem *parent);
69
void ItemDoubleClicked(QStandardItem* item);
70
smart_playlists::GeneratorPtr CreateGenerator(QStandardItem* item);
71
void DropMimeData(const QMimeData* data, const QModelIndex& index);
72
QList<QAction*> playlistitem_actions(const Song& song);
73
void ShowContextMenu(const QModelIndex& index, const QPoint& global_pos);
75
void Search(const QString& text, Playlist* playlist, bool now = false);
76
// User should be logged in to be able to generate streaming urls
77
QUrl GetStreamingUrlFromSongId(const QString& song_id, const QString& artist_id,
78
QString* server_id, QString* stream_key,
79
qint64* length_nanosec);
80
void Login(const QString& username, const QString& password);
82
bool IsLoggedIn() const { return !session_id_.isEmpty(); }
83
void RetrieveUserPlaylists();
84
void RetrieveUserFavorites();
85
void RetrievePopularSongs();
86
void RetrievePopularSongsMonth();
87
void RetrievePopularSongsToday();
88
void RetrieveSubscribedPlaylists();
89
void RetrieveAutoplayTags();
90
void SetPlaylistSongs(int playlist_id, const QList<int>& songs_ids);
91
void RemoveFromPlaylist(int playlist_id, int song_id);
92
// Refresh playlist_id playlist , or create it if it doesn't exist
93
void RefreshPlaylist(int playlist_id);
94
void DeletePlaylist(int playlist_id);
95
void RenamePlaylist(int playlist_id);
96
void AddUserFavoriteSong(int song_id);
97
void RemoveFromFavorites(int song_id);
98
void GetSongUrlToShare(int song_id);
99
// Start autoplay for the given tag_id, fill the autoplay_state, returns a
100
// first song to play
101
Song StartAutoplayTag(int tag_id, QVariantMap& autoplay_state);
102
Song StartAutoplay(QVariantMap& autoplay_state);
103
// Get another autoplay song. autoplay_state is the autoplay_state received from StartAutoplayTag
104
Song GetAutoplaySong(QVariantMap& autoplay_state);
105
void MarkStreamKeyOver30Secs(const QString& stream_key, const QString& server_id);
106
void MarkSongComplete(const QString& song_id, const QString& stream_key, const QString& server_id);
108
// Persisted in the settings and updated on each Login().
109
LoginState login_state() const { return login_state_; }
110
const QString& session_id() { return session_id_; }
112
int SimpleSearch(const QString& query);
113
int SearchAlbums(const QString& query);
114
void FetchSongsForAlbum(int id, const QUrl& url);
115
void FetchSongsForAlbum(int id, quint64 album_id);
117
static const char* kServiceName;
118
static const char* kSettingsGroup;
121
void LoginFinished(bool success);
122
void SimpleSearchResults(int id, SongList songs);
123
void AlbumSearchResult(int id, SongList songs);
124
void AlbumSongsLoaded(int id, SongList songs);
130
QModelIndex GetCurrentIndex();
132
struct PlaylistInfo {
134
PlaylistInfo(int id, QString name, QStandardItem* item)
135
: id_(id), name_(name), item_(item) {}
139
QStandardItem* item_;
140
QList<int> songs_ids_;
144
void UpdateTotalSongCount(int count);
146
void SessionCreated();
147
void OpenSearchTab();
149
void SearchSongsFinished();
150
void SimpleSearchFinished();
151
void SearchAlbumsFinished(QNetworkReply* reply, int id);
152
void GetAlbumSongsFinished(QNetworkReply* reply, int id);
153
void Authenticated();
154
void UserPlaylistsRetrieved();
155
void UserFavoritesRetrieved(QNetworkReply* reply, int task_id);
156
void PopularSongsMonthRetrieved(QNetworkReply* reply);
157
void PopularSongsTodayRetrieved(QNetworkReply* reply);
158
void SubscribedPlaylistsRetrieved(QNetworkReply* reply);
159
void AutoplayTagsRetrieved(QNetworkReply* reply);
160
void PlaylistSongsRetrieved();
161
void PlaylistSongsSet(QNetworkReply* reply, int playlist_id, int task_id);
162
void CreateNewPlaylist();
163
void NewPlaylistCreated(QNetworkReply* reply, const QString& name);
164
void DeleteCurrentPlaylist();
165
void RenameCurrentPlaylist();
166
void PlaylistDeleted(QNetworkReply* reply, int playlist_id);
167
void PlaylistRenamed(QNetworkReply* reply, int playlist_id, const QString& new_name);
168
void AddCurrentSongToUserFavorites() { AddUserFavoriteSong(current_song_id_); }
169
void AddCurrentSongToPlaylist(QAction* action);
170
void UserFavoriteSongAdded(QNetworkReply* reply, int task_id);
171
void GetCurrentSongUrlToShare();
172
void SongUrlToShareReceived(QNetworkReply* reply);
173
void RemoveCurrentFromPlaylist();
174
void RemoveCurrentFromFavorites();
175
void SongRemovedFromFavorites(QNetworkReply* reply, int task_id);
177
void SongMarkedAsComplete();
179
void RequestSslErrors(const QList<QSslError>& errors);
182
// Refresh all Grooveshark's items, and re-fill them
186
void EnsureMenuCreated();
187
void EnsureItemsCreated();
189
void EnsureConnected();
191
// Create a playlist item, with data set as excepted. Doesn't fill the item
193
QStandardItem* CreatePlaylistItem(const QString& playlist_name, int playlist_id);
195
void AuthenticateSession();
198
// Create a request for the given method, with the given params.
199
// If need_authentication is true, add session_id to params.
200
// Returns the reply object created
201
QNetworkReply* CreateRequest(const QString& method_name, const QList<QPair<QString, QVariant> > params,
202
bool use_https = false);
203
// Convenient function which block until 'reply' replies, or timeout after 10
204
// seconds. Returns false if reply has timeouted
205
bool WaitForReply(QNetworkReply* reply);
206
// Convenient function for extracting result from reply
207
QVariantMap ExtractResult(QNetworkReply* reply);
208
// Convenient function for extracting songs from grooveshark result. result
209
// should be the "result" field of most Grooveshark replies
210
SongList ExtractSongs(const QVariantMap& result);
211
// Convenient function for extracting song from grooveshark result.
212
// result_song should be the song field ('song', 'nextSong', ...) of the
214
Song ExtractSong(const QVariantMap& result_song);
215
// Convenient functions for extracting Grooveshark songs ids
216
QList<int> ExtractSongsIds(const QVariantMap& result);
217
QList<int> ExtractSongsIds(const QList<QUrl>& urls);
218
int ExtractSongId(const QUrl& url); // Returns 0 if url is not a Grooveshark url
220
void ResetSessionId();
223
GroovesharkUrlHandler* url_handler_;
225
QString pending_search_;
226
Playlist* pending_search_playlist_;
228
int next_pending_search_id_;
229
QMap<QNetworkReply*, int> pending_searches_;
231
QMap<QNetworkReply*, int> pending_retrieve_playlists_;
233
QMap<int, PlaylistInfo> playlists_;
234
QMap<int, PlaylistInfo> subscribed_playlists_;
236
QStandardItem* root_;
237
QStandardItem* search_;
238
QStandardItem* popular_month_;
239
QStandardItem* popular_today_;
240
QStandardItem* stations_;
241
QStandardItem* grooveshark_radio_;
242
QStandardItem* favorites_;
243
QStandardItem* subscribed_playlists_divider_;
245
NetworkAccessManager* network_;
247
QMenu* context_menu_;
248
QModelIndex context_item_;
249
int current_song_id_;
251
QAction* create_playlist_;
252
QAction* delete_playlist_;
253
QAction* rename_playlist_;
254
QAction* remove_from_playlist_;
255
QAction* remove_from_favorites_;
256
QList<QAction*> playlistitem_actions_;
258
QTimer* search_delay_;
259
QNetworkReply* last_search_reply_;
262
QString password_; // In fact, password's md5 hash
265
QMap<QString, QVariant> country_;
266
// The last artists and songs ids th users has listened to. Used for autoplay
267
QList<int> last_artists_ids_;
268
QList<int> last_songs_ids_;
271
LoginState login_state_;
273
// Tasks' ids: we need to keep them in mind to be able to update task status
275
int task_popular_id_;
276
int task_playlists_id_;
279
static const char* kUrl;
280
static const char* kUrlCover;
281
static const char* kHomepage;
283
static const int kSongSearchLimit;
284
static const int kSongSimpleSearchLimit;
285
static const int kSearchDelayMsec;
287
static const char* kApiKey;
288
static const char* kApiSecret;
292
#endif // GROOVESHARKSERVICE_H