Remove Grooveshark support.
Well that was nice while it lasted.
This commit is contained in:
parent
c0cf5e1220
commit
e1ea116bfb
@ -9,7 +9,6 @@
|
||||
<file>currenttrack_pause.png</file>
|
||||
<file>currenttrack_play.png</file>
|
||||
<file>globalsearch.css</file>
|
||||
<file>grooveshark-valicert-ca.pem</file>
|
||||
<file>hypnotoad.gif</file>
|
||||
<file>icon_large_grey.png</file>
|
||||
<file>icon_large.png</file>
|
||||
@ -320,7 +319,6 @@
|
||||
<file>providers/dropbox.png</file>
|
||||
<file>providers/echonest.png</file>
|
||||
<file>providers/googledrive.png</file>
|
||||
<file>providers/grooveshark.png</file>
|
||||
<file>providers/itunes.png</file>
|
||||
<file>providers/jamendo.png</file>
|
||||
<file>providers/jazzradio.png</file>
|
||||
|
@ -1,43 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
|
||||
IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
|
||||
BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
|
||||
aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
|
||||
9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
|
||||
NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
|
||||
azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
|
||||
YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
|
||||
Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
|
||||
cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
|
||||
dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
|
||||
WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
|
||||
v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
|
||||
UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
|
||||
IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
|
||||
W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
|
||||
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
|
||||
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
|
||||
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
|
||||
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
|
||||
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
|
||||
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
|
||||
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
|
||||
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
|
||||
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
|
||||
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
|
||||
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
|
||||
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
|
||||
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
|
||||
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
|
||||
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
|
||||
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
|
||||
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
|
||||
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
|
||||
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
|
||||
ReYNnyicsbkqWletNw+vHX/bvZ8=
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB |
@ -147,7 +147,6 @@ set(SOURCES
|
||||
globalsearch/globalsearchsettingspage.cpp
|
||||
globalsearch/globalsearchsortmodel.cpp
|
||||
globalsearch/globalsearchview.cpp
|
||||
globalsearch/groovesharksearchprovider.cpp
|
||||
globalsearch/icecastsearchprovider.cpp
|
||||
globalsearch/librarysearchprovider.cpp
|
||||
globalsearch/savedradiosearchprovider.cpp
|
||||
@ -167,10 +166,6 @@ set(SOURCES
|
||||
internet/digitally/digitallyimportedsettingspage.cpp
|
||||
internet/digitally/digitallyimportedurlhandler.cpp
|
||||
internet/core/geolocator.cpp
|
||||
internet/grooveshark/groovesharkradio.cpp
|
||||
internet/grooveshark/groovesharkservice.cpp
|
||||
internet/grooveshark/groovesharksettingspage.cpp
|
||||
internet/grooveshark/groovesharkurlhandler.cpp
|
||||
internet/icecast/icecastbackend.cpp
|
||||
internet/icecast/icecastfilterwidget.cpp
|
||||
internet/icecast/icecastmodel.cpp
|
||||
@ -464,7 +459,6 @@ set(HEADERS
|
||||
globalsearch/globalsearchmodel.h
|
||||
globalsearch/globalsearchsettingspage.h
|
||||
globalsearch/globalsearchview.h
|
||||
globalsearch/groovesharksearchprovider.h
|
||||
globalsearch/searchprovider.h
|
||||
globalsearch/simplesearchprovider.h
|
||||
globalsearch/soundcloudsearchprovider.h
|
||||
@ -476,9 +470,6 @@ set(HEADERS
|
||||
internet/digitally/digitallyimportedservicebase.h
|
||||
internet/digitally/digitallyimportedsettingspage.h
|
||||
internet/core/geolocator.h
|
||||
internet/grooveshark/groovesharkservice.h
|
||||
internet/grooveshark/groovesharksettingspage.h
|
||||
internet/grooveshark/groovesharkurlhandler.h
|
||||
internet/icecast/icecastbackend.h
|
||||
internet/icecast/icecastfilterwidget.h
|
||||
internet/icecast/icecastmodel.h
|
||||
@ -694,7 +685,6 @@ set(UI
|
||||
globalsearch/suggestionwidget.ui
|
||||
|
||||
internet/digitally/digitallyimportedsettingspage.ui
|
||||
internet/grooveshark/groovesharksettingspage.ui
|
||||
internet/icecast/icecastfilterwidget.ui
|
||||
internet/core/internetshowsettingspage.ui
|
||||
internet/core/internetviewcontainer.ui
|
||||
|
@ -890,19 +890,6 @@ void GstEnginePipeline::SourceSetupCallback(GstURIDecodeBin* bin,
|
||||
g_object_set(element, "device",
|
||||
instance->source_device().toLocal8Bit().constData(), nullptr);
|
||||
}
|
||||
if (g_object_class_find_property(G_OBJECT_GET_CLASS(element),
|
||||
"extra-headers") &&
|
||||
instance->url().host().contains("grooveshark")) {
|
||||
// Grooveshark streaming servers will answer with a 400 error 'Bad request'
|
||||
// if we don't specify 'Range' field in HTTP header.
|
||||
// Maybe it could be useful in some other cases, but for now, I prefer to
|
||||
// keep this grooveshark specific.
|
||||
GstStructure* headers;
|
||||
headers = gst_structure_new("extra-headers", "Range", G_TYPE_STRING,
|
||||
"bytes=0-", nullptr);
|
||||
g_object_set(element, "extra-headers", headers, nullptr);
|
||||
gst_structure_free(headers);
|
||||
}
|
||||
if (g_object_class_find_property(G_OBJECT_GET_CLASS(element),
|
||||
"extra-headers") &&
|
||||
instance->url().host().contains("amazonaws.com")) {
|
||||
|
@ -1,132 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "groovesharksearchprovider.h"
|
||||
|
||||
#include <QIcon>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "covers/albumcoverloader.h"
|
||||
#include "internet/grooveshark/groovesharkservice.h"
|
||||
|
||||
GroovesharkSearchProvider::GroovesharkSearchProvider(Application* app,
|
||||
QObject* parent)
|
||||
: SearchProvider(app, parent), service_(nullptr) {}
|
||||
|
||||
void GroovesharkSearchProvider::Init(GroovesharkService* service) {
|
||||
service_ = service;
|
||||
SearchProvider::Init(
|
||||
"Grooveshark", "grooveshark", QIcon(":providers/grooveshark.png"),
|
||||
WantsDelayedQueries | ArtIsProbablyRemote | CanShowConfig);
|
||||
|
||||
connect(service_, SIGNAL(SimpleSearchResults(int, SongList)),
|
||||
SLOT(SearchDone(int, SongList)));
|
||||
connect(service_, SIGNAL(AlbumSearchResult(int, QList<quint64>)),
|
||||
SLOT(AlbumSearchResult(int, QList<quint64>)));
|
||||
connect(service_, SIGNAL(AlbumSongsLoaded(quint64, SongList)),
|
||||
SLOT(AlbumSongsLoaded(quint64, SongList)));
|
||||
|
||||
cover_loader_options_.desired_height_ = kArtHeight;
|
||||
cover_loader_options_.pad_output_image_ = true;
|
||||
cover_loader_options_.scale_output_image_ = true;
|
||||
|
||||
connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QImage)),
|
||||
SLOT(AlbumArtLoaded(quint64, QImage)));
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::SearchAsync(int id, const QString& query) {
|
||||
const int service_id = service_->SimpleSearch(query);
|
||||
pending_searches_[service_id] = PendingState(id, TokenizeQuery(query));
|
||||
;
|
||||
|
||||
const int album_id = service_->SearchAlbums(query);
|
||||
pending_searches_[album_id] = PendingState(id, TokenizeQuery(query));
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::SearchDone(int id, const SongList& songs) {
|
||||
// Map back to the original id.
|
||||
const PendingState state = pending_searches_.take(id);
|
||||
const int global_search_id = state.orig_id_;
|
||||
|
||||
ResultList ret;
|
||||
for (const Song& song : songs) {
|
||||
Result result(this);
|
||||
result.metadata_ = song;
|
||||
|
||||
ret << result;
|
||||
}
|
||||
|
||||
emit ResultsAvailable(global_search_id, ret);
|
||||
MaybeSearchFinished(global_search_id);
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::AlbumSearchResult(
|
||||
int id, const QList<quint64>& albums_ids) {
|
||||
// Map back to the original id.
|
||||
const PendingState state = pending_searches_.take(id);
|
||||
const int global_search_id = state.orig_id_;
|
||||
if (albums_ids.isEmpty()) {
|
||||
MaybeSearchFinished(global_search_id);
|
||||
return;
|
||||
}
|
||||
for (const quint64 album_id : albums_ids) {
|
||||
pending_searches_[album_id] = PendingState(global_search_id, QStringList());
|
||||
}
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::MaybeSearchFinished(int id) {
|
||||
if (pending_searches_.keys(PendingState(id, QStringList())).isEmpty()) {
|
||||
emit SearchFinished(id);
|
||||
}
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::LoadArtAsync(int id, const Result& result) {
|
||||
quint64 loader_id = app_->album_cover_loader()->LoadImageAsync(
|
||||
cover_loader_options_, result.metadata_);
|
||||
cover_loader_tasks_[loader_id] = id;
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::AlbumArtLoaded(quint64 id,
|
||||
const QImage& image) {
|
||||
if (!cover_loader_tasks_.contains(id)) {
|
||||
return;
|
||||
}
|
||||
int original_id = cover_loader_tasks_.take(id);
|
||||
emit ArtLoaded(original_id, image);
|
||||
}
|
||||
|
||||
bool GroovesharkSearchProvider::IsLoggedIn() {
|
||||
return (service_ && service_->IsLoggedIn());
|
||||
}
|
||||
|
||||
void GroovesharkSearchProvider::ShowConfig() { service_->ShowConfig(); }
|
||||
|
||||
void GroovesharkSearchProvider::AlbumSongsLoaded(quint64 id,
|
||||
const SongList& songs) {
|
||||
const PendingState state = pending_searches_.take(id);
|
||||
const int global_search_id = state.orig_id_;
|
||||
ResultList ret;
|
||||
for (const Song& s : songs) {
|
||||
Result result(this);
|
||||
result.metadata_ = s;
|
||||
ret << result;
|
||||
}
|
||||
|
||||
emit ResultsAvailable(global_search_id, ret);
|
||||
MaybeSearchFinished(global_search_id);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GROOVESHARKSEARCHPROVIDER_H
|
||||
#define GROOVESHARKSEARCHPROVIDER_H
|
||||
|
||||
#include "searchprovider.h"
|
||||
#include "covers/albumcoverloaderoptions.h"
|
||||
#include "internet/grooveshark/groovesharkservice.h"
|
||||
|
||||
class AlbumCoverLoader;
|
||||
|
||||
class GroovesharkSearchProvider : public SearchProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GroovesharkSearchProvider(Application* app, QObject* parent = nullptr);
|
||||
void Init(GroovesharkService* service);
|
||||
|
||||
// SearchProvider
|
||||
void SearchAsync(int id, const QString& query) override;
|
||||
void LoadArtAsync(int id, const Result& result) override;
|
||||
bool IsLoggedIn() override;
|
||||
void ShowConfig() override;
|
||||
InternetService* internet_service() override { return service_; }
|
||||
|
||||
private slots:
|
||||
void SearchDone(int id, const SongList& songs);
|
||||
void AlbumSearchResult(int id, const QList<quint64>& albums_ids);
|
||||
void AlbumArtLoaded(quint64 id, const QImage& image);
|
||||
void AlbumSongsLoaded(quint64 id, const SongList& songs);
|
||||
|
||||
private:
|
||||
void MaybeSearchFinished(int id);
|
||||
|
||||
GroovesharkService* service_;
|
||||
QMap<int, PendingState> pending_searches_;
|
||||
|
||||
AlbumCoverLoaderOptions cover_loader_options_;
|
||||
QMap<quint64, int> cover_loader_tasks_;
|
||||
};
|
||||
|
||||
#endif
|
@ -29,7 +29,6 @@
|
||||
#include <QtDebug>
|
||||
|
||||
#include "internet/digitally/digitallyimportedservicebase.h"
|
||||
#include "internet/grooveshark/groovesharkservice.h"
|
||||
#include "internet/icecast/icecastservice.h"
|
||||
#include "internet/core/internetmimedata.h"
|
||||
#include "internet/core/internetservice.h"
|
||||
@ -90,7 +89,6 @@ InternetModel::InternetModel(Application* app, QObject* parent)
|
||||
AddService(new DigitallyImportedService(app, this));
|
||||
AddService(new IcecastService(app, this));
|
||||
AddService(new JamendoService(app, this));
|
||||
AddService(new GroovesharkService(app, this));
|
||||
AddService(new JazzRadioService(app, this));
|
||||
AddService(new MagnatuneService(app, this));
|
||||
AddService(new PodcastService(app, this));
|
||||
|
@ -1,62 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
Copyright 2014, John Maguire <john.maguire@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "groovesharkradio.h"
|
||||
|
||||
#include "groovesharkservice.h"
|
||||
#include "core/logging.h"
|
||||
#include "internet/core/internetplaylistitem.h"
|
||||
|
||||
GroovesharkRadio::GroovesharkRadio(GroovesharkService* service)
|
||||
: service_(service), tag_id_(0), use_tag_(false), first_time_(true) {}
|
||||
|
||||
GroovesharkRadio::GroovesharkRadio(GroovesharkService* service, int tag_id)
|
||||
: service_(service), tag_id_(tag_id), use_tag_(true), first_time_(true) {}
|
||||
|
||||
void GroovesharkRadio::Load(const QByteArray& data) {}
|
||||
|
||||
QByteArray GroovesharkRadio::Save() const { return QByteArray(); }
|
||||
|
||||
PlaylistItemList GroovesharkRadio::Generate() {
|
||||
PlaylistItemList items;
|
||||
if (first_time_) {
|
||||
Song song;
|
||||
if (use_tag_) {
|
||||
song = service_->StartAutoplayTag(tag_id_, autoplay_state_);
|
||||
} else {
|
||||
song = service_->StartAutoplay(autoplay_state_);
|
||||
}
|
||||
// If the song url isn't valid, stop here
|
||||
if (!song.is_valid()) {
|
||||
return items;
|
||||
}
|
||||
PlaylistItemPtr playlist_item =
|
||||
PlaylistItemPtr(new InternetPlaylistItem(service_, song));
|
||||
items << playlist_item;
|
||||
first_time_ = false;
|
||||
}
|
||||
Song song = service_->GetAutoplaySong(autoplay_state_);
|
||||
if (!song.is_valid()) {
|
||||
return items;
|
||||
}
|
||||
PlaylistItemPtr playlist_item =
|
||||
PlaylistItemPtr(new InternetPlaylistItem(service_, song));
|
||||
items << playlist_item;
|
||||
return items;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
Copyright 2014, John Maguire <john.maguire@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INTERNET_GROOVESHARK_GROOVESHARKRADIO_H_
|
||||
#define INTERNET_GROOVESHARK_GROOVESHARKRADIO_H_
|
||||
|
||||
#include "smartplaylists/generator.h"
|
||||
|
||||
class GroovesharkService;
|
||||
|
||||
class GroovesharkRadio : public smart_playlists::Generator {
|
||||
public:
|
||||
// Start Grooveshark radio for a particular type of music
|
||||
GroovesharkRadio(GroovesharkService* service, int tag_id);
|
||||
// Start Grooveshark radio based on last artists and songs you listen to
|
||||
explicit GroovesharkRadio(GroovesharkService* service);
|
||||
|
||||
QString type() const { return "Grooveshark"; }
|
||||
void Load(const QByteArray& data);
|
||||
QByteArray Save() const;
|
||||
PlaylistItemList Generate();
|
||||
PlaylistItemList GenerateMore(int count) { return Generate(); }
|
||||
bool is_dynamic() const { return true; }
|
||||
|
||||
private:
|
||||
GroovesharkService* service_;
|
||||
int tag_id_;
|
||||
// Boolean to specify if we should use tag. If not, we will used autoplay
|
||||
// without tag
|
||||
bool use_tag_;
|
||||
// For Generate: indicates if it's the first time we generate songs
|
||||
bool first_time_;
|
||||
QVariantMap autoplay_state_;
|
||||
};
|
||||
|
||||
#endif // INTERNET_GROOVESHARK_GROOVESHARKRADIO_H_
|
File diff suppressed because it is too large
Load Diff
@ -1,338 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011-2014, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2011-2012, 2014, John Maguire <john.maguire@gmail.com>
|
||||
Copyright 2012, David Sansome <me@davidsansome.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INTERNET_GROOVESHARK_GROOVESHARKSERVICE_H_
|
||||
#define INTERNET_GROOVESHARK_GROOVESHARKSERVICE_H_
|
||||
|
||||
#include "internet/core/internetmodel.h"
|
||||
#include "internet/core/internetservice.h"
|
||||
|
||||
#include <QSslError>
|
||||
|
||||
class GroovesharkUrlHandler;
|
||||
class NetworkAccessManager;
|
||||
class Playlist;
|
||||
class SearchBoxWidget;
|
||||
|
||||
class QMenu;
|
||||
class QNetworkReply;
|
||||
class QNetworkRequest;
|
||||
class QSortFilterProxyModel;
|
||||
|
||||
class GroovesharkService : public InternetService {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GroovesharkService(Application* app, InternetModel* parent);
|
||||
~GroovesharkService();
|
||||
|
||||
enum Role {
|
||||
Role_UserPlaylistId = InternetModel::RoleCount,
|
||||
Role_PlaylistType
|
||||
};
|
||||
|
||||
enum PlaylistType {
|
||||
UserPlaylist = Qt::UserRole,
|
||||
// Favorites and Library list are like playlists, but we want to do special
|
||||
// treatments in some cases
|
||||
UserFavorites,
|
||||
UserLibrary,
|
||||
SubscribedPlaylist
|
||||
};
|
||||
|
||||
// Values are persisted - don't change.
|
||||
enum LoginState {
|
||||
LoginState_LoggedIn = 1,
|
||||
LoginState_AuthFailed = 2,
|
||||
LoginState_NoPremium = 3,
|
||||
LoginState_OtherError = 4
|
||||
};
|
||||
|
||||
// Internet Service methods
|
||||
QStandardItem* CreateRootItem();
|
||||
void LazyPopulate(QStandardItem* parent);
|
||||
|
||||
void ItemDoubleClicked(QStandardItem* item);
|
||||
smart_playlists::GeneratorPtr CreateGenerator(QStandardItem* item);
|
||||
void DropMimeData(const QMimeData* data, const QModelIndex& index);
|
||||
QList<QAction*> playlistitem_actions(const Song& song);
|
||||
void ShowContextMenu(const QPoint& global_pos);
|
||||
QWidget* HeaderWidget() const;
|
||||
|
||||
// User should be logged in to be able to generate streaming urls
|
||||
QUrl GetStreamingUrlFromSongId(const QString& song_id,
|
||||
const QString& artist_id, QString* server_id,
|
||||
QString* stream_key, qint64* length_nanosec);
|
||||
void Login(const QString& username, const QString& password);
|
||||
void Logout();
|
||||
bool IsLoggedIn() const { return !session_id_.isEmpty(); }
|
||||
void RetrieveUserPlaylists();
|
||||
void RetrieveUserFavorites();
|
||||
void RetrieveUserLibrarySongs();
|
||||
void RetrievePopularSongs();
|
||||
void RetrievePopularSongsMonth();
|
||||
void RetrievePopularSongsToday();
|
||||
void RetrieveSubscribedPlaylists();
|
||||
void RetrieveAutoplayTags();
|
||||
void SetPlaylistSongs(int playlist_id, const QList<int>& songs_ids);
|
||||
void RemoveFromPlaylist(int playlist_id,
|
||||
const QList<int>& songs_ids_to_remove);
|
||||
// Refresh playlist_id playlist , or create it if it doesn't exist
|
||||
void RefreshPlaylist(int playlist_id);
|
||||
void DeletePlaylist(int playlist_id);
|
||||
void RenamePlaylist(int playlist_id);
|
||||
void AddUserFavoriteSong(int song_id);
|
||||
void RemoveFromFavorites(const QList<int>& songs_ids_to_remove);
|
||||
void AddUserLibrarySongs(const QList<int>& songs_ids);
|
||||
void RemoveFromLibrary(const QList<int>& songs_ids_to_remove);
|
||||
void GetSongUrlToShare(int song_id);
|
||||
void GetPlaylistUrlToShare(int playlist_id);
|
||||
// Start autoplay for the given tag_id, fill the autoplay_state, returns a
|
||||
// first song to play
|
||||
Song StartAutoplayTag(int tag_id, QVariantMap& autoplay_state);
|
||||
Song StartAutoplay(QVariantMap& autoplay_state);
|
||||
// Get another autoplay song. autoplay_state is the autoplay_state received
|
||||
// from StartAutoplayTag
|
||||
Song GetAutoplaySong(QVariantMap& autoplay_state);
|
||||
void MarkStreamKeyOver30Secs(const QString& stream_key,
|
||||
const QString& server_id);
|
||||
void MarkSongComplete(const QString& song_id, const QString& stream_key,
|
||||
const QString& server_id);
|
||||
|
||||
// Persisted in the settings and updated on each Login().
|
||||
LoginState login_state() const { return login_state_; }
|
||||
const QString& session_id() { return session_id_; }
|
||||
|
||||
int SimpleSearch(const QString& query);
|
||||
int SearchAlbums(const QString& query);
|
||||
void GetAlbumSongs(quint64 album_id);
|
||||
|
||||
static const char* kServiceName;
|
||||
static const char* kSettingsGroup;
|
||||
|
||||
signals:
|
||||
void LoginFinished(bool success);
|
||||
void SimpleSearchResults(int id, SongList songs);
|
||||
// AlbumSearchResult emits the search id and the Grooveshark ids of the
|
||||
// albums found. Albums' songs will be loaded asynchronously and
|
||||
// AlbumSongsLoaded will be emitted, containing the actual Albums' songs.
|
||||
void AlbumSearchResult(int id, QList<quint64> albums_ids);
|
||||
void AlbumSongsLoaded(quint64 id, SongList songs);
|
||||
|
||||
public slots:
|
||||
void Search(const QString& text, bool now = false);
|
||||
void ShowConfig();
|
||||
// Refresh all Grooveshark's items, and re-fill them
|
||||
void RefreshItems();
|
||||
|
||||
protected:
|
||||
struct PlaylistInfo {
|
||||
PlaylistInfo() {}
|
||||
PlaylistInfo(int id, QString name, QStandardItem* item = nullptr)
|
||||
: id_(id), name_(name), item_(item) {}
|
||||
|
||||
bool operator<(const PlaylistInfo other) const {
|
||||
return name_.localeAwareCompare(other.name_) < 0;
|
||||
}
|
||||
|
||||
int id_;
|
||||
QString name_;
|
||||
QStandardItem* item_;
|
||||
QList<int> songs_ids_;
|
||||
};
|
||||
|
||||
private slots:
|
||||
void SessionCreated(QNetworkReply* reply);
|
||||
void DoSearch();
|
||||
void SearchSongsFinished(QNetworkReply* reply);
|
||||
void SimpleSearchFinished(QNetworkReply* reply, int id);
|
||||
void SearchAlbumsFinished(QNetworkReply* reply, int id);
|
||||
void GetAlbumSongsFinished(QNetworkReply* reply, quint64 album_id);
|
||||
void Authenticated(QNetworkReply* reply);
|
||||
void UserPlaylistsRetrieved(QNetworkReply* reply);
|
||||
void UserFavoritesRetrieved(QNetworkReply* reply, int task_id);
|
||||
void UserLibrarySongsRetrieved(QNetworkReply* reply, int task_id);
|
||||
void PopularSongsMonthRetrieved(QNetworkReply* reply);
|
||||
void PopularSongsTodayRetrieved(QNetworkReply* reply);
|
||||
void SubscribedPlaylistsRetrieved(QNetworkReply* reply);
|
||||
void AutoplayTagsRetrieved(QNetworkReply* reply);
|
||||
void PlaylistSongsRetrieved(QNetworkReply* reply, int playlist_id, int request_id);
|
||||
void PlaylistSongsSet(QNetworkReply* reply, int playlist_id, int task_id);
|
||||
void CreateNewPlaylist();
|
||||
void NewPlaylistCreated(QNetworkReply* reply, const QString& name);
|
||||
void DeleteCurrentPlaylist();
|
||||
void RenameCurrentPlaylist();
|
||||
void PlaylistDeleted(QNetworkReply* reply, int playlist_id);
|
||||
void PlaylistRenamed(QNetworkReply* reply, int playlist_id,
|
||||
const QString& new_name);
|
||||
void AddCurrentSongToUserFavorites() {
|
||||
AddUserFavoriteSong(current_song_id_);
|
||||
}
|
||||
void AddCurrentSongToUserLibrary() {
|
||||
AddUserLibrarySongs(QList<int>() << current_song_id_);
|
||||
}
|
||||
void AddCurrentSongToPlaylist(QAction* action);
|
||||
void UserFavoriteSongAdded(QNetworkReply* reply, int task_id);
|
||||
void UserLibrarySongAdded(QNetworkReply* reply, int task_id);
|
||||
void GetCurrentSongUrlToShare();
|
||||
void SongUrlToShareReceived(QNetworkReply* reply);
|
||||
void GetCurrentPlaylistUrlToShare();
|
||||
void PlaylistUrlToShareReceived(QNetworkReply* reply);
|
||||
void RemoveCurrentFromPlaylist();
|
||||
void RemoveCurrentFromFavorites();
|
||||
void RemoveCurrentFromLibrary();
|
||||
void SongsRemovedFromFavorites(QNetworkReply* reply, int task_id);
|
||||
void SongsRemovedFromLibrary(QNetworkReply* reply, int task_id);
|
||||
void StreamMarked(QNetworkReply* reply);
|
||||
void SongMarkedAsComplete(QNetworkReply* reply);
|
||||
|
||||
void RequestSslErrors(const QList<QSslError>& errors);
|
||||
|
||||
void Homepage();
|
||||
|
||||
private:
|
||||
void EnsureMenuCreated();
|
||||
void EnsureItemsCreated();
|
||||
void RemoveItems();
|
||||
void EnsureConnected();
|
||||
void ClearSearchResults();
|
||||
|
||||
// Create a playlist item, with data set as excepted. Doesn't fill the item
|
||||
// with songs rows.
|
||||
QStandardItem* CreatePlaylistItem(const QString& playlist_name,
|
||||
int playlist_id);
|
||||
|
||||
void AuthenticateSession();
|
||||
void InitCountry();
|
||||
|
||||
// Create a request for the given method, with the given params.
|
||||
// If need_authentication is true, add session_id to params.
|
||||
// Returns the reply object created
|
||||
QNetworkReply* CreateRequest(const QString& method_name,
|
||||
const QList<QPair<QString, QVariant>>& params,
|
||||
bool use_https = false);
|
||||
// Convenient function which block until 'reply' replies, or timeout after 10
|
||||
// seconds. Returns false if reply has timeouted
|
||||
bool WaitForReply(QNetworkReply* reply);
|
||||
// Convenient function for extracting result from reply
|
||||
QVariantMap ExtractResult(QNetworkReply* reply);
|
||||
// Convenient function for extracting songs from grooveshark result. result
|
||||
// should be the "result" field of most Grooveshark replies
|
||||
SongList ExtractSongs(const QVariantMap& result);
|
||||
// Convenient function for extracting song from grooveshark result.
|
||||
// result_song should be the song field ('song', 'nextSong', ...) of the
|
||||
// Grooveshark reply
|
||||
Song ExtractSong(const QVariantMap& result_song);
|
||||
// Convenient functions for extracting Grooveshark songs ids
|
||||
QList<int> ExtractSongsIds(const QVariantMap& result);
|
||||
QList<int> ExtractSongsIds(const QList<QUrl>& urls);
|
||||
int ExtractSongId(
|
||||
const QUrl& url); // Returns 0 if url is not a Grooveshark url
|
||||
// Convenient function for extracting basic playlist info (only 'id' and
|
||||
// 'name': QStandardItem still need to be created), and sort them by name
|
||||
QList<PlaylistInfo> ExtractPlaylistInfo(const QVariantMap& result);
|
||||
|
||||
void ResetSessionId();
|
||||
|
||||
// Sort songs alphabetically only if the "sort_alphabetically" option has been
|
||||
// checked in the preferences settings.
|
||||
void SortSongsAlphabeticallyIfNeeded(SongList* songs) const;
|
||||
|
||||
GroovesharkUrlHandler* url_handler_;
|
||||
|
||||
QString pending_search_;
|
||||
|
||||
int next_pending_search_id_;
|
||||
int next_pending_playlist_retrieve_id_;
|
||||
|
||||
QSet<int> pending_retrieve_playlists_;
|
||||
|
||||
QMap<int, PlaylistInfo> playlists_;
|
||||
QMap<int, PlaylistInfo> subscribed_playlists_;
|
||||
|
||||
QStandardItem* root_;
|
||||
QStandardItem* search_;
|
||||
QStandardItem* popular_month_;
|
||||
QStandardItem* popular_today_;
|
||||
QStandardItem* stations_;
|
||||
QStandardItem* grooveshark_radio_;
|
||||
QStandardItem* favorites_;
|
||||
// Grooveshark Library (corresponds to Grooveshark 'MyMusic' actually, but
|
||||
// called 'Library' in the API).
|
||||
// Nothing to do with Clementine's local library
|
||||
QStandardItem* library_;
|
||||
QStandardItem* playlists_parent_;
|
||||
QStandardItem* subscribed_playlists_parent_;
|
||||
|
||||
NetworkAccessManager* network_;
|
||||
|
||||
QMenu* context_menu_;
|
||||
// IDs kept when showing menu, to know what the user has clicked on, to be
|
||||
// able to perform actions on corresponding items
|
||||
int current_song_id_;
|
||||
int current_playlist_id_;
|
||||
|
||||
QAction* create_playlist_;
|
||||
QAction* delete_playlist_;
|
||||
QAction* rename_playlist_;
|
||||
QAction* remove_from_playlist_;
|
||||
QAction* remove_from_favorites_;
|
||||
QAction* remove_from_library_;
|
||||
QAction* get_url_to_share_song_;
|
||||
QAction* get_url_to_share_playlist_;
|
||||
QList<QAction*> playlistitem_actions_;
|
||||
|
||||
SearchBoxWidget* search_box_;
|
||||
|
||||
QTimer* search_delay_;
|
||||
QNetworkReply* last_search_reply_;
|
||||
|
||||
QString username_;
|
||||
QString password_; // In fact, password's md5 hash
|
||||
QString user_id_;
|
||||
QString session_id_;
|
||||
QMap<QString, QVariant> country_;
|
||||
// The last artists and songs ids th users has listened to. Used for autoplay
|
||||
QList<int> last_artists_ids_;
|
||||
QList<int> last_songs_ids_;
|
||||
QByteArray api_key_;
|
||||
|
||||
LoginState login_state_;
|
||||
|
||||
// Tasks' ids: we need to keep them in mind to be able to update task status
|
||||
// on each step
|
||||
int task_popular_id_;
|
||||
int task_playlists_id_;
|
||||
int task_search_id_;
|
||||
|
||||
static const char* kUrl;
|
||||
static const char* kUrlCover;
|
||||
static const char* kHomepage;
|
||||
|
||||
static const int kSongSearchLimit;
|
||||
static const int kSongSimpleSearchLimit;
|
||||
static const int kAlbumSearchLimit;
|
||||
static const int kSearchDelayMsec;
|
||||
|
||||
static const char* kApiKey;
|
||||
static const char* kApiSecret;
|
||||
};
|
||||
|
||||
#endif // INTERNET_GROOVESHARK_GROOVESHARKSERVICE_H_
|
@ -1,131 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, 2014, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2011, David Sansome <me@davidsansome.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
Copyright 2014, John Maguire <john.maguire@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "groovesharksettingspage.h"
|
||||
#include "ui_groovesharksettingspage.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QSettings>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "groovesharkservice.h"
|
||||
#include "internet/core/internetmodel.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/network.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
GroovesharkSettingsPage::GroovesharkSettingsPage(SettingsDialog* dialog)
|
||||
: SettingsPage(dialog),
|
||||
ui_(new Ui_GroovesharkSettingsPage),
|
||||
service_(InternetModel::Service<GroovesharkService>()),
|
||||
validated_(false) {
|
||||
ui_->setupUi(this);
|
||||
|
||||
setWindowIcon(QIcon(":/providers/grooveshark.png"));
|
||||
|
||||
connect(ui_->login, SIGNAL(clicked()), SLOT(Login()));
|
||||
connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout()));
|
||||
connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(Login()));
|
||||
|
||||
connect(service_, SIGNAL(LoginFinished(bool)), SLOT(LoginFinished(bool)));
|
||||
|
||||
ui_->login_state->AddCredentialField(ui_->username);
|
||||
ui_->login_state->AddCredentialField(ui_->password);
|
||||
ui_->login_state->AddCredentialGroup(ui_->account_group);
|
||||
}
|
||||
|
||||
GroovesharkSettingsPage::~GroovesharkSettingsPage() { delete ui_; }
|
||||
|
||||
void GroovesharkSettingsPage::Login() {
|
||||
if (service_->IsLoggedIn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui_->login_state->SetLoggedIn(LoginStateWidget::LoginInProgress);
|
||||
service_->Login(ui_->username->text(), ui_->password->text());
|
||||
}
|
||||
|
||||
void GroovesharkSettingsPage::Load() {
|
||||
QSettings s;
|
||||
s.beginGroup(GroovesharkService::kSettingsGroup);
|
||||
|
||||
original_username_ = s.value("username").toString();
|
||||
|
||||
ui_->username->setText(original_username_);
|
||||
validated_ = false;
|
||||
|
||||
UpdateLoginState();
|
||||
|
||||
ui_->sort_alphabetically->setChecked(s.value("sort_alphabetically").toBool());
|
||||
}
|
||||
|
||||
void GroovesharkSettingsPage::Save() {
|
||||
QSettings s;
|
||||
s.beginGroup(GroovesharkService::kSettingsGroup);
|
||||
|
||||
s.setValue("username", ui_->username->text());
|
||||
s.setValue("sessionid", service_->session_id());
|
||||
const bool old_sort_value = s.value("sort_alphabetically").toBool();
|
||||
const bool new_sort_value = ui_->sort_alphabetically->isChecked();
|
||||
if (old_sort_value != new_sort_value) {
|
||||
s.setValue("sort_alphabetically", new_sort_value);
|
||||
service_->RefreshItems();
|
||||
}
|
||||
}
|
||||
|
||||
void GroovesharkSettingsPage::LoginFinished(bool success) {
|
||||
validated_ = success;
|
||||
|
||||
Save();
|
||||
UpdateLoginState();
|
||||
}
|
||||
|
||||
void GroovesharkSettingsPage::UpdateLoginState() {
|
||||
const bool logged_in = service_->IsLoggedIn();
|
||||
|
||||
ui_->login_state->SetLoggedIn(
|
||||
logged_in ? LoginStateWidget::LoggedIn : LoginStateWidget::LoggedOut,
|
||||
ui_->username->text());
|
||||
ui_->login_state->SetAccountTypeVisible(!logged_in);
|
||||
|
||||
switch (service_->login_state()) {
|
||||
case GroovesharkService::LoginState_NoPremium:
|
||||
ui_->login_state->SetAccountTypeText(
|
||||
tr("You do not have a Grooveshark Anywhere account."));
|
||||
break;
|
||||
|
||||
case GroovesharkService::LoginState_AuthFailed:
|
||||
ui_->login_state->SetAccountTypeText(
|
||||
tr("Your username or password was incorrect."));
|
||||
break;
|
||||
|
||||
default:
|
||||
ui_->login_state->SetAccountTypeText(
|
||||
tr("A Grooveshark Anywhere account is required."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GroovesharkSettingsPage::Logout() {
|
||||
service_->Logout();
|
||||
UpdateLoginState();
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
Copyright 2014, John Maguire <john.maguire@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INTERNET_GROOVESHARK_GROOVESHARKSETTINGSPAGE_H_
|
||||
#define INTERNET_GROOVESHARK_GROOVESHARKSETTINGSPAGE_H_
|
||||
|
||||
#include "ui/settingspage.h"
|
||||
|
||||
class NetworkAccessManager;
|
||||
class Ui_GroovesharkSettingsPage;
|
||||
class GroovesharkService;
|
||||
|
||||
class GroovesharkSettingsPage : public SettingsPage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GroovesharkSettingsPage(SettingsDialog* dialog);
|
||||
~GroovesharkSettingsPage();
|
||||
|
||||
void Load();
|
||||
void Save();
|
||||
|
||||
private slots:
|
||||
void Login();
|
||||
void LoginFinished(bool success);
|
||||
void Logout();
|
||||
|
||||
private:
|
||||
void UpdateLoginState();
|
||||
|
||||
private:
|
||||
Ui_GroovesharkSettingsPage* ui_;
|
||||
GroovesharkService* service_;
|
||||
|
||||
bool validated_;
|
||||
QString original_username_;
|
||||
QString original_password_;
|
||||
};
|
||||
|
||||
#endif // INTERNET_GROOVESHARK_GROOVESHARKSETTINGSPAGE_H_
|
@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GroovesharkSettingsPage</class>
|
||||
<widget class="QWidget" name="GroovesharkSettingsPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>480</width>
|
||||
<height>184</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Grooveshark</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>By default, Grooveshark sorts songs on date added</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="LoginStateWidget" name="login_state" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="account_group">
|
||||
<property name="title">
|
||||
<string>Account details</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QWidget" name="login_container" native="true">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="username_label">
|
||||
<property name="text">
|
||||
<string>Username</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="username"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="password_label">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="password">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="login">
|
||||
<property name="text">
|
||||
<string>Login</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="preferences_group">
|
||||
<property name="title">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="sort_alphabetically">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sort playlists songs alphabetically</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LoginStateWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/loginstatewidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../data/data.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,82 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
Copyright 2014, John Maguire <john.maguire@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "groovesharkurlhandler.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#include "groovesharkservice.h"
|
||||
#include "core/logging.h"
|
||||
|
||||
GroovesharkUrlHandler::GroovesharkUrlHandler(GroovesharkService* service,
|
||||
QObject* parent)
|
||||
: UrlHandler(parent),
|
||||
service_(service),
|
||||
timer_mark_stream_key_(new QTimer(this)) {
|
||||
// We have to warn Grooveshark when user has listened for more than 30
|
||||
// seconds of a song, and when it ends. I guess this is used by Grooveshark
|
||||
// for statistics and user history.
|
||||
// To do this, we have TrackAboutToEnd method, and timer_mark_stream_key_
|
||||
// timer.
|
||||
// It is not perfect, as we may call Grooveshark MarkStreamKeyOver30Secs even
|
||||
// if user hasn't actually listen to 30 seconds (e.g. stream set to pause
|
||||
// state) but this is not a big deal and it should be accurate enough anyway.
|
||||
timer_mark_stream_key_->setInterval(30000);
|
||||
timer_mark_stream_key_->setSingleShot(true);
|
||||
connect(timer_mark_stream_key_, SIGNAL(timeout()),
|
||||
SLOT(MarkStreamKeyOver30Secs()));
|
||||
}
|
||||
|
||||
UrlHandler::LoadResult GroovesharkUrlHandler::StartLoading(const QUrl& url) {
|
||||
qint64 length_nanosec = 0;
|
||||
QUrl streaming_url;
|
||||
QStringList ids = url.toString().remove("grooveshark://").split("/");
|
||||
if (ids.size() < 3) {
|
||||
qLog(Error) << "Invalid grooveshark URL: " << url.toString();
|
||||
qLog(Error) << "Should be grooveshark://artist_id/album_id/song_id";
|
||||
} else {
|
||||
last_artist_id_ = ids[0];
|
||||
last_album_id_ = ids[1];
|
||||
last_song_id_ = ids[2];
|
||||
|
||||
streaming_url = service_->GetStreamingUrlFromSongId(
|
||||
last_song_id_, last_artist_id_, &last_server_id_, &last_stream_key_,
|
||||
&length_nanosec);
|
||||
qLog(Debug) << "Grooveshark Streaming URL: " << streaming_url;
|
||||
|
||||
timer_mark_stream_key_->start();
|
||||
}
|
||||
|
||||
return LoadResult(url, LoadResult::TrackAvailable, streaming_url,
|
||||
length_nanosec);
|
||||
}
|
||||
|
||||
void GroovesharkUrlHandler::TrackAboutToEnd() {
|
||||
if (timer_mark_stream_key_->isActive()) {
|
||||
timer_mark_stream_key_->stop();
|
||||
return;
|
||||
}
|
||||
service_->MarkSongComplete(last_song_id_, last_stream_key_, last_server_id_);
|
||||
}
|
||||
|
||||
void GroovesharkUrlHandler::TrackSkipped() { timer_mark_stream_key_->stop(); }
|
||||
|
||||
void GroovesharkUrlHandler::MarkStreamKeyOver30Secs() {
|
||||
service_->MarkStreamKeyOver30Secs(last_stream_key_, last_server_id_);
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, Arnaud Bienner <arnaud.bienner@gmail.com>
|
||||
Copyright 2012, 2014, John Maguire <john.maguire@gmail.com>
|
||||
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INTERNET_GROOVESHARK_GROOVESHARKURLHANDLER_H_
|
||||
#define INTERNET_GROOVESHARK_GROOVESHARKURLHANDLER_H_
|
||||
|
||||
#include "core/urlhandler.h"
|
||||
|
||||
class GroovesharkService;
|
||||
class QTimer;
|
||||
|
||||
class GroovesharkUrlHandler : public UrlHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GroovesharkUrlHandler(GroovesharkService* service, QObject* parent);
|
||||
|
||||
QString scheme() const { return "grooveshark"; }
|
||||
QIcon icon() const { return QIcon(":providers/grooveshark.png"); }
|
||||
LoadResult StartLoading(const QUrl& url);
|
||||
void TrackAboutToEnd();
|
||||
void TrackSkipped();
|
||||
|
||||
private slots:
|
||||
void MarkStreamKeyOver30Secs();
|
||||
|
||||
private:
|
||||
GroovesharkService* service_;
|
||||
QTimer* timer_mark_stream_key_;
|
||||
QString last_artist_id_;
|
||||
QString last_album_id_;
|
||||
QString last_song_id_;
|
||||
QString last_server_id_;
|
||||
QString last_stream_key_;
|
||||
};
|
||||
|
||||
#endif // INTERNET_GROOVESHARK_GROOVESHARKURLHANDLER_H_
|
10
src/main.cpp
10
src/main.cpp
@ -398,15 +398,7 @@ int main(int argc, char* argv[]) {
|
||||
Q_INIT_RESOURCE(data);
|
||||
Q_INIT_RESOURCE(translations);
|
||||
|
||||
// Grooveshark uses GoDaddy to sign its SSL certificates, which are in turn
|
||||
// signed by a ValiCert CA. This CA certificate isn't installed by default
|
||||
// in Windows, it's only added by windows update, or manually browsing to a
|
||||
// website with a certificate signed by ValiCert. Here we explicitly add
|
||||
// that CA to the default list used by QSslSocket, so it always works in
|
||||
// Clementine.
|
||||
QSslSocket::addDefaultCaCertificates(
|
||||
QSslCertificate::fromPath(":/grooveshark-valicert-ca.pem", QSsl::Pem));
|
||||
// Do the same for SoundCloud, whose certificate is missing on OS X.
|
||||
// Add root CA cert for SoundCloud, whose certificate is missing on OS X.
|
||||
QSslSocket::addDefaultCaCertificates(
|
||||
QSslCertificate::fromPath(":/soundcloud-ca.pem", QSsl::Pem));
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "engines/gstengine.h"
|
||||
#include "globalsearch/globalsearchsettingspage.h"
|
||||
#include "internet/digitally/digitallyimportedsettingspage.h"
|
||||
#include "internet/grooveshark/groovesharksettingspage.h"
|
||||
#include "internet/core/internetshowsettingspage.h"
|
||||
#include "internet/magnatune/magnatunesettingspage.h"
|
||||
#include "internet/soundcloud/soundcloudsettingspage.h"
|
||||
@ -168,8 +167,6 @@ SettingsDialog::SettingsDialog(Application* app, BackgroundStreams* streams,
|
||||
AddPage(Page_Lastfm, new LastFMSettingsPage(this), providers);
|
||||
#endif
|
||||
|
||||
AddPage(Page_Grooveshark, new GroovesharkSettingsPage(this), providers);
|
||||
|
||||
#ifdef HAVE_GOOGLE_DRIVE
|
||||
AddPage(Page_GoogleDrive, new GoogleDriveSettingsPage(this), providers);
|
||||
#endif
|
||||
|
@ -68,7 +68,6 @@ class SettingsDialog : public QDialog {
|
||||
Page_Notifications,
|
||||
Page_Library,
|
||||
Page_Lastfm,
|
||||
Page_Grooveshark,
|
||||
Page_SoundCloud,
|
||||
Page_Spotify,
|
||||
Page_Magnatune,
|
||||
|
Loading…
x
Reference in New Issue
Block a user