If the spotify blob isn't installed, try to download it from the Clementine website. Also, make the blob separate from the core Spotify code in Clementine so you can build the core code without building the blob

This commit is contained in:
David Sansome 2011-04-29 19:44:51 +00:00
parent a1e06e6596
commit 3deb371537
23 changed files with 432 additions and 74 deletions

View File

@ -7,6 +7,7 @@ include(cmake/Version.cmake)
include(cmake/Deb.cmake)
include(cmake/Rpm.cmake)
include(cmake/SipBindings.cmake)
include(cmake/SpotifyVersion.cmake)
if (UNIX AND NOT APPLE)
set(LINUX 1)
@ -137,6 +138,16 @@ if(${CMAKE_BUILD_TYPE} MATCHES "Release")
add_definitions(-DQT_NO_DEBUG_OUTPUT)
endif(${CMAKE_BUILD_TYPE} MATCHES "Release")
# Use protobuf-lite if it's available
find_library(PROTOBUF_LITE_LIBRARY protobuf-lite)
if(NOT PROTOBUF_LITE_LIBRARY)
# Lucid doesn't have a .so symlink
find_file(PROTOBUF_LITE_LIBRARY
NAMES libprotobuf-lite.so.5
PATH_SUFFIXES lib
)
endif(NOT PROTOBUF_LITE_LIBRARY)
# Set up definitions and paths
add_definitions(${QT_DEFINITIONS})
link_directories(${TAGLIB_LIBRARY_DIRS})
@ -188,7 +199,8 @@ option(ENABLE_SCRIPTING_ARCHIVES "Enable support for loading scripts from archiv
option(ENABLE_SCRIPTING_PYTHON "Enable python scripting" ON)
option(ENABLE_REMOTE "Enable support for using remote controls with Clementine" OFF)
option(ENABLE_BREAKPAD "Enable crash reporting" OFF)
option(ENABLE_SPOTIFY "Enable spotify support" OFF)
option(ENABLE_SPOTIFY_BLOB "Build the spotify non-GPL binary" ON)
option(ENABLE_SPOTIFY "Enable spotify support" ON)
if(WIN32)
option(ENABLE_WIN32_CONSOLE "Show the windows console even outside Debug mode" OFF)
@ -234,9 +246,13 @@ if(ENABLE_BREAKPAD)
set(HAVE_BREAKPAD ON)
endif(ENABLE_BREAKPAD)
if(ENABLE_SPOTIFY AND SPOTIFY_FOUND AND PROTOBUF_FOUND)
if(ENABLE_SPOTIFY AND PROTOBUF_FOUND)
set(HAVE_SPOTIFY ON)
endif(ENABLE_SPOTIFY AND SPOTIFY_FOUND AND PROTOBUF_FOUND)
endif(ENABLE_SPOTIFY AND PROTOBUF_FOUND)
if(ENABLE_SPOTIFY_BLOB AND PROTOBUF_FOUND AND SPOTIFY_FOUND)
set(HAVE_SPOTIFY_BLOB ON)
endif(ENABLE_SPOTIFY_BLOB AND PROTOBUF_FOUND AND SPOTIFY_FOUND)
if(ENABLE_VISUALISATIONS)
@ -375,9 +391,13 @@ if(HAVE_BREAKPAD)
endif(HAVE_BREAKPAD)
if(HAVE_SPOTIFY)
add_subdirectory(spotifyblob)
add_subdirectory(spotifyblob/common)
endif(HAVE_SPOTIFY)
if(HAVE_SPOTIFY_BLOB)
add_subdirectory(spotifyblob/blob)
endif(HAVE_SPOTIFY_BLOB)
# Uninstall support
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
@ -388,20 +408,21 @@ add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
# Show a summary of what we have enabled
summary_add("devices: DeviceKit backend" HAVE_DEVICEKIT)
summary_add("devices: iPod classic support" HAVE_LIBGPOD)
summary_add("devices: iPod Touch, iPhone, iPad support" HAVE_IMOBILEDEVICE)
summary_add("devices: MTP support" HAVE_LIBMTP)
summary_add("devices: GIO backend" HAVE_GIO)
summary_add("D-Bus support" HAVE_DBUS)
summary_add("Gnome sound menu integration" HAVE_LIBINDICATE)
summary_add("Wiimote support" HAVE_WIIMOTEDEV)
summary_add("Visualisations" ENABLE_VISUALISATIONS)
summary_add("Last.fm support" HAVE_LIBLASTFM)
summary_add("Crash reporting" HAVE_BREAKPAD)
summary_add("D-Bus support" HAVE_DBUS)
summary_add("Devices: DeviceKit backend" HAVE_DEVICEKIT)
summary_add("Devices: iPod classic support" HAVE_LIBGPOD)
summary_add("Devices: iPod Touch, iPhone, iPad support" HAVE_IMOBILEDEVICE)
summary_add("Devices: MTP support" HAVE_LIBMTP)
summary_add("Devices: GIO backend" HAVE_GIO)
summary_add("Gnome sound menu integration" HAVE_LIBINDICATE)
summary_add("Last.fm support" HAVE_LIBLASTFM)
summary_add("Scripting support: loading archives" HAVE_LIBARCHIVE)
summary_add("Scripting support: Python" HAVE_SCRIPTING_PYTHON)
summary_add("Spotify support: core code" HAVE_SPOTIFY)
summary_add("Spotify support: non-GPL binary helper" HAVE_SPOTIFY_BLOB)
summary_add("Visualisations" ENABLE_VISUALISATIONS)
summary_add("Wiimote support" HAVE_WIIMOTEDEV)
summary_add("(Mac OS X) Sparkle integration" HAVE_SPARKLE)
summary_add("(unstable) Remote control support" HAVE_REMOTE)
summary_add("(unstable) Spotify support" HAVE_SPOTIFY)
summary_show()

View File

@ -0,0 +1,2 @@
# Increment this whenever the user needs to download a new blob
set(SPOTIFY_BLOB_VERSION 1)

View File

@ -0,0 +1,54 @@
include_directories(${SPOTIFY_INCLUDE_DIRS})
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_SOURCE_DIR}/src)
link_directories(${SPOTIFY_LIBRARY_DIRS})
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(SOURCES
main.cpp
spotifyclient.cpp
${CMAKE_SOURCE_DIR}/src/core/logging.cpp
)
set(HEADERS
spotifyclient.h
)
qt4_wrap_cpp(MOC ${HEADERS})
add_executable(clementine-spotifyblob
${SOURCES}
${MOC}
)
target_link_libraries(clementine-spotifyblob
${SPOTIFY_LIBRARIES}
${QT_QTCORE_LIBRARY}
${QT_QTNETWORK_LIBRARY}
clementine-spotifyblob-messages
)
install(TARGETS clementine-spotifyblob
RUNTIME DESTINATION bin
)
if(LINUX)
# Versioned name of the blob
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(SPOTIFY_BLOB_ARCH 32)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(SPOTIFY_BLOB_ARCH 64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
install(
FILES ${CMAKE_BINARY_DIR}/clementine-spotifyblob
DESTINATION ${CMAKE_BINARY_DIR}/spotify/version${SPOTIFY_BLOB_VERSION}-${SPOTIFY_BLOB_ARCH}bit/blob
RENAME ${SPOTIFY_BLOB_NAME}
)
endif(LINUX)

View File

@ -1,12 +1,9 @@
include_directories(${SPOTIFY_INCLUDE_DIRS})
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR}/src)
link_directories(${SPOTIFY_LIBRARY_DIRS})
set(EXECUTABLE_OUTPUT_PATH ..)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/blobversion.h.in
${CMAKE_CURRENT_BINARY_DIR}/blobversion.h)
set(COMMON_SOURCES
spotifymessagehandler.cpp
@ -29,32 +26,15 @@ add_library(clementine-spotifyblob-messages STATIC
${PROTO_SOURCES}
)
# Use protobuf-lite if it's available
if(PROTOBUF_LITE_LIBRARY)
set(protobuf ${PROTOBUF_LITE_LIBRARY})
else(PROTOBUF_LITE_LIBRARY)
set(protobuf ${PROTOBUF_LIBRARY})
endif(PROTOBUF_LITE_LIBRARY)
target_link_libraries(clementine-spotifyblob-messages
${PROTOBUF_LIBRARY}
${protobuf}
${CMAKE_THREAD_LIBS_INIT}
)
set(SOURCES
main.cpp
spotifyclient.cpp
../src/core/logging.cpp
)
set(HEADERS
spotifyclient.h
)
qt4_wrap_cpp(MOC ${HEADERS})
add_executable(clementine-spotifyblob
${SOURCES}
${MOC}
)
target_link_libraries(clementine-spotifyblob
${SPOTIFY_LIBRARIES}
${QT_LIBRARIES}
clementine-spotifyblob-messages
)

View File

@ -0,0 +1,23 @@
/* This file is part of Clementine.
Copyright 2010, 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 SPOTIFY_BLOBVERSION_H_IN
#define SPOTIFY_BLOBVERSION_H_IN
#define SPOTIFY_BLOB_VERSION ${SPOTIFY_BLOB_VERSION}
#endif // SPOTIFY_BLOBVERSION_H_IN

View File

@ -58,7 +58,6 @@ void SpotifyMessageHandler::DeviceReadyRead() {
return;
}
qLog(Debug) << message.DebugString().c_str();
emit MessageArrived(message);
// Clear the buffer
@ -71,8 +70,6 @@ void SpotifyMessageHandler::DeviceReadyRead() {
}
void SpotifyMessageHandler::SendMessage(const protobuf::SpotifyMessage& message) {
qLog(Debug) << message.DebugString().c_str();
std::string data(message.SerializeAsString());
QDataStream s(device_);

View File

@ -21,6 +21,9 @@
package protobuf;
option optimize_for = LITE_RUNTIME;
message LoginRequest {
required string username = 1;
required string password = 2;

View File

@ -624,6 +624,7 @@ endif(HAVE_LIBLASTFM)
if(HAVE_SPOTIFY)
list(APPEND SOURCES
radio/spotifyblobdownloader.cpp
radio/spotifyconfig.cpp
radio/spotifyserver.cpp
radio/spotifyservice.cpp
@ -631,6 +632,7 @@ if(HAVE_SPOTIFY)
radio/spotifyurlhandler.cpp
)
list(APPEND HEADERS
radio/spotifyblobdownloader.h
radio/spotifyconfig.h
radio/spotifyserver.h
radio/spotifyservice.h
@ -1023,8 +1025,6 @@ endif(HAVE_BREAKPAD)
if(HAVE_SPOTIFY)
target_link_libraries(clementine_lib clementine-spotifyblob-messages)
add_dependencies(clementine_lib
clementine-spotifyblob)
endif(HAVE_SPOTIFY)
if (APPLE)

View File

@ -18,6 +18,7 @@
#define CONFIG_H_IN
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
#define CMAKE_EXECUTABLE_SUFFIX "${CMAKE_EXECUTABLE_SUFFIX}"
#cmakedefine ENABLE_VISUALISATIONS
#cmakedefine HAVE_BREAKPAD

View File

@ -34,7 +34,7 @@ static Level sDefaultLevel = Level_Debug;
static QMap<QString, Level>* sClassLevels = NULL;
static QIODevice* sNullDevice = NULL;
const char* kDefaultLogLevels = "GstEnginePipeline:2,SpotifyMessageHandler:2,*:3";
const char* kDefaultLogLevels = "GstEnginePipeline:2,*:3";
static const char* kMessageHandlerMagic = "__logging_message__";
static const int kMessageHandlerMagicLength = strlen(kMessageHandlerMagic);

View File

@ -273,6 +273,9 @@ QString GetConfigPath(ConfigPath config) {
return QDir::homePath();
#endif
case Path_LocalSpotifyBlob:
return GetConfigPath(Path_Root) + "/spotifyblob";
default:
qFatal("%s", Q_FUNC_INFO);
return QString::null;

View File

@ -55,6 +55,7 @@ namespace Utilities {
Path_GstreamerRegistry,
Path_DefaultMusicLibrary,
Path_Scripts,
Path_LocalSpotifyBlob,
};
QString GetConfigPath(ConfigPath config);
}

View File

@ -0,0 +1,137 @@
/* This file is part of Clementine.
Copyright 2010, 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 "spotifyblobdownloader.h"
#include "spotifyservice.h"
#include "core/logging.h"
#include "core/network.h"
#include <QDir>
#include <QMessageBox>
#include <QNetworkReply>
#include <QProgressDialog>
SpotifyBlobDownloader::SpotifyBlobDownloader(
const QString& version, const QString& path, QObject* parent)
: QObject(parent),
version_(version),
path_(path),
network_(new NetworkAccessManager(this)),
progress_(new QProgressDialog(tr("Downloading Spotify plugin"), tr("Cancel"), 0, 0))
{
progress_->setWindowTitle(QCoreApplication::applicationName());
connect(progress_, SIGNAL(canceled()), SLOT(Cancel()));
}
SpotifyBlobDownloader::~SpotifyBlobDownloader() {
qDeleteAll(replies_);
replies_.clear();
delete progress_;
}
void SpotifyBlobDownloader::Start() {
qDeleteAll(replies_);
replies_.clear();
const QStringList filenames = QStringList() << "blob" << "libspotify.so.7";
foreach (const QString& filename, filenames) {
const QUrl url(SpotifyService::kBlobDownloadUrl + version_ + "/" + filename);
qLog(Info) << "Downloading" << url;
QNetworkReply* reply = network_->get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), SLOT(ReplyFinished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(ReplyProgress()));
replies_ << reply;
}
progress_->show();
}
void SpotifyBlobDownloader::ReplyFinished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if (reply->error() != QNetworkReply::NoError) {
// Handle network errors
ShowError(reply->errorString());
return;
}
// Is everything finished?
foreach (QNetworkReply* reply, replies_) {
if (!reply->isFinished()) {
return;
}
}
// Make the destination directory and write the files into it
QDir().mkpath(path_);
foreach (QNetworkReply* reply, replies_) {
const QString filename = reply->url().path().section('/', -1, -1);
const QString path = path_ + "/" + filename;
qLog(Info) << "Saving file" << path;
QFile file(path);
if (!file.open(QIODevice::WriteOnly)) {
ShowError("Failed to open file for writing: " + path);
return;
}
file.setPermissions(QFile::Permissions(0x7755));
file.write(reply->readAll());
}
EmitFinished();
}
void SpotifyBlobDownloader::ReplyProgress() {
int progress = 0;
int total = 0;
foreach (QNetworkReply* reply, replies_) {
progress += reply->bytesAvailable();
total += reply->rawHeader("Content-Length").toInt();
}
progress_->setMaximum(total);
progress_->setValue(progress);
}
void SpotifyBlobDownloader::Cancel() {
deleteLater();
}
void SpotifyBlobDownloader::ShowError(const QString& message) {
// Stop any remaining replies before showing the dialog so they don't
// carry on in the background
foreach (QNetworkReply* reply, replies_) {
disconnect(reply, 0, this, 0);
reply->abort();
}
qLog(Warning) << message;
QMessageBox::warning(NULL, tr("Error downloading Spotify plugin"), message,
QMessageBox::Close);
deleteLater();
}
void SpotifyBlobDownloader::EmitFinished() {
emit Finished();
deleteLater();
}

View File

@ -0,0 +1,59 @@
/* This file is part of Clementine.
Copyright 2010, 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 SPOTIFYBLOBDOWNLOADER_H
#define SPOTIFYBLOBDOWNLOADER_H
#include <QObject>
class QNetworkAccessManager;
class QNetworkReply;
class QProgressDialog;
class SpotifyBlobDownloader : public QObject {
Q_OBJECT
public:
SpotifyBlobDownloader(const QString& version, const QString& path,
QObject* parent = 0);
~SpotifyBlobDownloader();
void Start();
signals:
void Finished();
private slots:
void ReplyFinished();
void ReplyProgress();
void Cancel();
private:
void ShowError(const QString& message);
void EmitFinished();
private:
QString version_;
QString path_;
QNetworkAccessManager* network_;
QList<QNetworkReply*> replies_;
QProgressDialog* progress_;
};
#endif // SPOTIFYBLOBDOWNLOADER_H

View File

@ -18,8 +18,8 @@
#include "spotifyserver.h"
#include "core/logging.h"
#include "spotifyblob/spotifymessages.pb.h"
#include "spotifyblob/spotifymessagehandler.h"
#include "spotifyblob/common/spotifymessages.pb.h"
#include "spotifyblob/common/spotifymessagehandler.h"
#include <QTcpServer>
#include <QTcpSocket>

View File

@ -18,7 +18,7 @@
#ifndef SPOTIFYSERVER_H
#define SPOTIFYSERVER_H
#include "spotifyblob/spotifymessages.pb.h"
#include "spotifyblob/common/spotifymessages.pb.h"
#include <QImage>
#include <QObject>

View File

@ -1,4 +1,6 @@
#include "config.h"
#include "radiomodel.h"
#include "spotifyblobdownloader.h"
#include "spotifyserver.h"
#include "spotifyservice.h"
#include "spotifysearchplaylisttype.h"
@ -7,20 +9,26 @@
#include "core/logging.h"
#include "core/player.h"
#include "core/taskmanager.h"
#include "core/utilities.h"
#include "playlist/playlist.h"
#include "playlist/playlistcontainer.h"
#include "playlist/playlistmanager.h"
#include "spotifyblob/spotifymessagehandler.h"
#include "spotifyblob/common/blobversion.h"
#include "spotifyblob/common/spotifymessagehandler.h"
#include "widgets/didyoumean.h"
#include "ui/iconloader.h"
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QMenu>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
const char* SpotifyService::kServiceName = "Spotify";
const char* SpotifyService::kSettingsGroup = "Spotify";
const char* SpotifyService::kBlobDownloadUrl = "http://spotify.clementine-player.org/";
const int SpotifyService::kSearchDelayMsec = 400;
SpotifyService::SpotifyService(RadioModel* parent)
@ -35,12 +43,18 @@ SpotifyService::SpotifyService(RadioModel* parent)
pending_search_playlist_(NULL),
context_menu_(NULL),
search_delay_(new QTimer(this)) {
#ifdef Q_OS_DARWIN
blob_path_ = QCoreApplication::applicationDirPath() + "/../PlugIns/clementine-spotifyblob";
#else
blob_path_ = QCoreApplication::applicationFilePath() + "-spotifyblob";
#endif
qLog(Debug) << "Loading spotify blob from:" << blob_path_;
// Build the search path for the binary blob.
// Look for one distributed alongside clementine first, then check in the
// user's home directory for any that have been downloaded.
blob_path_ << QCoreApplication::applicationFilePath() + "-spotifyblob" CMAKE_EXECUTABLE_SUFFIX
<< QCoreApplication::applicationDirPath() + "/../PlugIns/clementine-spotifyblob" CMAKE_EXECUTABLE_SUFFIX;
local_blob_version_ = QString("version%1-%2bit").arg(SPOTIFY_BLOB_VERSION).arg(sizeof(void*) * 8);
local_blob_path_ = Utilities::GetConfigPath(Utilities::Path_LocalSpotifyBlob) +
"/" + local_blob_version_ + "/blob";
qLog(Debug) << "Spotify blob search path:" << blob_path_;
qLog(Debug) << "Spotify local blob path:" << local_blob_path_;
model()->player()->RegisterUrlHandler(url_handler_);
model()->player()->playlists()->RegisterSpecialPlaylistType(
@ -115,19 +129,18 @@ void SpotifyService::LoginCompleted(bool success) {
void SpotifyService::BlobProcessError(QProcess::ProcessError error) {
qLog(Error) << "Spotify blob process failed:" << error;
blob_process_->deleteLater();
blob_process_ = NULL;
}
void SpotifyService::EnsureServerCreated(const QString& username,
const QString& password) {
if (server_) {
if (server_ && blob_process_) {
return;
}
qLog(Debug) << Q_FUNC_INFO;
delete server_;
server_ = new SpotifyServer(this);
blob_process_ = new QProcess(this);
blob_process_->setProcessChannelMode(QProcess::ForwardedChannels);
connect(server_, SIGNAL(LoginCompleted(bool)), SLOT(LoginCompleted(bool)));
connect(server_, SIGNAL(PlaylistsUpdated(protobuf::Playlists)),
@ -145,13 +158,7 @@ void SpotifyService::EnsureServerCreated(const QString& username,
connect(server_, SIGNAL(ImageLoaded(QString,QImage)),
SLOT(ImageLoaded(QString,QImage)));
connect(blob_process_,
SIGNAL(error(QProcess::ProcessError)),
SLOT(BlobProcessError(QProcess::ProcessError)));
server_->Init();
blob_process_->start(
blob_path_, QStringList() << QString::number(server_->server_port()));
login_task_id_ = model()->task_manager()->StartTask(tr("Connecting to Spotify"));
@ -163,6 +170,71 @@ void SpotifyService::EnsureServerCreated(const QString& username,
} else {
server_->Login(username, password);
}
StartBlobProcess();
}
void SpotifyService::StartBlobProcess() {
// Try to find an executable to run
QString blob_path;
QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
// Look in the system search path first
foreach (const QString& path, blob_path_) {
if (QFile::exists(path)) {
blob_path = path;
break;
}
}
// Next look in the local path
const QString local_blob_dir = QFileInfo(local_blob_path_).path();
if (blob_path.isEmpty()) {
if (QFile::exists(local_blob_path_)) {
blob_path = local_blob_path_;
env.insert("LD_LIBRARY_PATH", local_blob_dir);
}
}
if (blob_path.isEmpty()) {
// If the blob still wasn't found then we'll prompt the user to download one
if (login_task_id_) {
model()->task_manager()->SetTaskFinished(login_task_id_);
}
#ifdef Q_OS_LINUX
QMessageBox::StandardButton ret = QMessageBox::question(NULL,
tr("Spotify plugin not installed"),
tr("An additional plugin is required to use Spotify in Clementine. Would you like to download and install it now?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (ret == QMessageBox::Yes) {
// The downloader deletes itself when it finishes
SpotifyBlobDownloader* downloader = new SpotifyBlobDownloader(
local_blob_version_, local_blob_dir, this);
connect(downloader, SIGNAL(Finished()), SLOT(BlobDownloadFinished()));
downloader->Start();
}
#endif
return;
}
delete blob_process_;
blob_process_ = new QProcess(this);
blob_process_->setProcessChannelMode(QProcess::ForwardedChannels);
connect(blob_process_,
SIGNAL(error(QProcess::ProcessError)),
SLOT(BlobProcessError(QProcess::ProcessError)));
qLog(Info) << "Starting" << blob_path;
blob_process_->start(
blob_path, QStringList() << QString::number(server_->server_port()));
}
void SpotifyService::BlobDownloadFinished() {
EnsureServerCreated();
}
void SpotifyService::PlaylistsUpdated(const protobuf::Playlists& response) {

View File

@ -3,7 +3,7 @@
#include "radiomodel.h"
#include "radioservice.h"
#include "spotifyblob/spotifymessages.pb.h"
#include "spotifyblob/common/spotifymessages.pb.h"
#include <QProcess>
#include <QTimer>
@ -37,6 +37,7 @@ public:
static const char* kServiceName;
static const char* kSettingsGroup;
static const char* kBlobDownloadUrl;
static const int kSearchDelayMsec;
QStandardItem* CreateRootItem();
@ -61,6 +62,7 @@ protected:
private:
void EnsureServerCreated(const QString& username = QString(),
const QString& password = QString());
void StartBlobProcess();
void FillPlaylist(QStandardItem* item, const protobuf::LoadPlaylistResponse& response);
void SongFromProtobuf(const protobuf::Track& track, Song* song) const;
void EnsureMenuCreated();
@ -82,12 +84,15 @@ private slots:
void DoSearch();
void ShowConfig();
void BlobDownloadFinished();
private:
SpotifyServer* server_;
SpotifyUrlHandler* url_handler_;
QString blob_path_;
QString local_blob_version_;
QString local_blob_path_;
QStringList blob_path_;
QProcess* blob_process_;
QStandardItem* root_;