From f5a8de28b86c2c838a28e79aa54f8b4c3fbd869e Mon Sep 17 00:00:00 2001
From: root
Date: Thu, 31 May 2012 16:24:59 +0000
Subject: Thu May 31 16:24:59 UTC 2012
---
.../remove-and-disable-spotify.patch | 3268 ++++++++++++++++++++
1 file changed, 3268 insertions(+)
create mode 100644 libre/clementine-libre/remove-and-disable-spotify.patch
(limited to 'libre/clementine-libre/remove-and-disable-spotify.patch')
diff --git a/libre/clementine-libre/remove-and-disable-spotify.patch b/libre/clementine-libre/remove-and-disable-spotify.patch
new file mode 100644
index 000000000..9cfc3092a
--- /dev/null
+++ b/libre/clementine-libre/remove-and-disable-spotify.patch
@@ -0,0 +1,3268 @@
+diff -rauN clementine-1.0.1/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m clementine-libre-1.0.1/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m
+--- clementine-1.0.1/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m 2011-12-02 19:24:43.000000000 -0200
++++ clementine-libre-1.0.1/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m 2012-05-28 17:19:14.612750904 -0300
+@@ -98,7 +98,6 @@
+ {
+ return [NSArray arrayWithObjects:
+ [[NSBundle mainBundle] bundleIdentifier], // your app
+- @"com.spotify.client",
+ @"com.apple.iTunes",
+ @"com.apple.QuickTimePlayerX",
+ @"com.apple.quicktimeplayer",
+diff -rauN clementine-1.0.1/Changelog clementine-libre-1.0.1/Changelog
+--- clementine-1.0.1/Changelog 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/Changelog 2012-05-28 13:50:10.422664725 -0300
+@@ -1,3 +1,7 @@
++Version 1.0.1 (libre version):
++ Major features:
++ * Disabled and removed Spotify.
++
+ Version 1.0.1:
+ Bugfixes:
+ * Use Chromaprinter and Acoustid instead of Echoprint and MusicDNS.
+diff -rauN clementine-1.0.1/cmake/SpotifyVersion.cmake /dev/null
+--- clementine-1.0.1/cmake/SpotifyVersion.cmake 2011-12-02 19:24:43.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,3 +0,0 @@
+-# Increment this whenever the user needs to download a new blob
+-# Remember to upload and sign the new version of the blob.
+-set(SPOTIFY_BLOB_VERSION 11)
+diff -rauN clementine-1.0.1/CMakeLists.txt clementine-libre-1.0.1/CMakeLists.txt
+--- clementine-1.0.1/CMakeLists.txt 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/CMakeLists.txt 2012-05-28 17:32:48.690568781 -0300
+@@ -6,7 +6,6 @@
+ include(cmake/Version.cmake)
+ include(cmake/Deb.cmake)
+ include(cmake/Rpm.cmake)
+-include(cmake/SpotifyVersion.cmake)
+ include(cmake/OptionalSource.cmake)
+
+ if (UNIX AND NOT APPLE)
+@@ -66,7 +65,6 @@
+ pkg_check_modules(USBMUXD libusbmuxd)
+ pkg_check_modules(LIBMTP libmtp>=1.0)
+ pkg_check_modules(INDICATEQT indicate-qt)
+-pkg_check_modules(SPOTIFY libspotify>=10.1.16)
+ pkg_check_modules(CDIO libcdio)
+ pkg_check_modules(QCA qca2)
+ pkg_check_modules(CHROMAPRINT libchromaprint)
+@@ -90,13 +88,6 @@
+ set(HAVE_SPARKLE ON)
+ endif (ENABLE_SPARKLE AND SPARKLE)
+
+- find_library(SPOTIFY libspotify)
+- if (SPOTIFY)
+- set (SPOTIFY_FOUND ON)
+- set (SPOTIFY_INCLUDE_DIRS ${SPOTIFY})
+- set (SPOTIFY_LIBRARIES ${SPOTIFY})
+- endif (SPOTIFY)
+-
+ add_subdirectory(3rdparty/SPMediaKeyTap)
+ set(SPMEDIAKEYTAP_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/SPMediaKeyTap)
+ set(SPMEDIAKEYTAP_LIBRARIES SPMediaKeyTap)
+@@ -191,8 +182,8 @@
+ option(ENABLE_LIBLASTFM "Use liblastfm for fetching song info, scrobbling and radio streams" ON)
+ option(ENABLE_REMOTE "Enable support for using remote controls with Clementine" OFF)
+ option(ENABLE_BREAKPAD "Enable crash reporting" OFF)
+-option(ENABLE_SPOTIFY_BLOB "Build the spotify non-GPL binary" ON)
+-option(ENABLE_SPOTIFY "Enable spotify support" ON)
++option(ENABLE_SPOTIFY_BLOB "Build the spotify non-GPL binary" OFF)
++option(ENABLE_SPOTIFY "Enable spotify support" OFF)
+ option(ENABLE_PLASMARUNNER "Enable plasma krunner global search" OFF)
+
+ if(WIN32)
+@@ -235,24 +226,6 @@
+ set(HAVE_BREAKPAD ON)
+ endif(ENABLE_BREAKPAD)
+
+-if(ENABLE_SPOTIFY AND PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE)
+- set(HAVE_SPOTIFY ON)
+-endif(ENABLE_SPOTIFY AND PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE)
+-
+-if(ENABLE_SPOTIFY_BLOB AND PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE AND SPOTIFY_FOUND)
+- set(HAVE_SPOTIFY_BLOB ON)
+-endif(ENABLE_SPOTIFY_BLOB AND PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE AND SPOTIFY_FOUND)
+-
+-if((NOT HAVE_SPOTIFY_BLOB) AND (NOT QCA_FOUND))
+- # If we're not bundling the spotify blob then we must ensure QCA is available
+- # so we can verify the blob we download at runtime.
+- unset(HAVE_SPOTIFY)
+-endif((NOT HAVE_SPOTIFY_BLOB) AND (NOT QCA_FOUND))
+-
+-if(QCA_FOUND AND HAVE_SPOTIFY)
+- set(HAVE_QCA ON)
+-endif(QCA_FOUND AND HAVE_SPOTIFY)
+-
+
+ if(ENABLE_VISUALISATIONS)
+ # When/if upstream accepts our patches then these options can be used to link
+@@ -391,14 +364,6 @@
+ add_subdirectory(3rdparty/google-breakpad)
+ endif(HAVE_BREAKPAD)
+
+-if(HAVE_SPOTIFY)
+- add_subdirectory(spotifyblob/common)
+-endif(HAVE_SPOTIFY)
+-
+-if(HAVE_SPOTIFY_BLOB)
+- add_subdirectory(spotifyblob/blob)
+-endif(HAVE_SPOTIFY_BLOB)
+-
+ # This goes after everything else because KDE fucks everything else up with its
+ # cmake includes.
+ find_package(KDE4 4.3.60)
+@@ -430,8 +395,6 @@
+ summary_add("Devices: GIO backend" HAVE_GIO)
+ summary_add("Gnome sound menu integration" HAVE_LIBINDICATE)
+ summary_add("Last.fm support" HAVE_LIBLASTFM)
+-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("(KDE) Plasma global search" HAVE_PLASMARUNNER)
+diff -rauN clementine-1.0.1/data/data.qrc clementine-libre-1.0.1/data/data.qrc
+--- clementine-1.0.1/data/data.qrc 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/data/data.qrc 2012-05-28 17:50:22.768352061 -0300
+@@ -49,9 +49,6 @@
+ providers/magnatune.png
+ schema/schema-8.sql
+ schema/schema-9.sql
+- icons/22x22/spotify.png
+- icons/32x32/spotify.png
+- icons/48x48/spotify.png
+ icons/22x22/application-exit.png
+ icons/22x22/applications-internet.png
+ icons/22x22/configure.png
+@@ -320,7 +317,6 @@
+ icons/32x32/edit-find.png
+ icons/48x48/edit-find.png
+ schema/schema-33.sql
+- spotify-core-logo-128x128.png
+ icons/22x22/dialog-warning.png
+ icons/22x22/dialog-ok-apply.png
+ schema/schema-34.sql
+@@ -331,7 +327,6 @@
+ providers/grooveshark.png
+ allthethings.png
+ globalsearch.css
+- clementine-spotify-public.pem
+ icons/22x22/user-away.png
+ icons/32x32/search.png
+ schema/schema-35.sql
+diff -rauN clementine-1.0.1/data/icons/svg/spotify.svg /dev/null
+--- clementine-1.0.1/data/icons/svg/spotify.svg 2011-12-02 19:24:43.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,285 +0,0 @@
+-
+-
+-
+diff -rauN clementine-1.0.1/data/schema/schema-30.sql clementine-libre-1.0.1/data/schema/schema-30.sql
+--- clementine-1.0.1/data/schema/schema-30.sql 2011-12-02 19:24:43.000000000 -0200
++++ clementine-libre-1.0.1/data/schema/schema-30.sql 2012-05-28 17:55:40.840489308 -0300
+@@ -1,45 +1 @@
+-CREATE TABLE spotify_search_songs (
+- title TEXT,
+- album TEXT,
+- artist TEXT,
+- albumartist TEXT,
+- composer TEXT,
+- track INTEGER,
+- disc INTEGER,
+- bpm REAL,
+- year INTEGER,
+- genre TEXT,
+- comment TEXT,
+- compilation INTEGER,
+-
+- length INTEGER,
+- bitrate INTEGER,
+- samplerate INTEGER,
+-
+- directory INTEGER NOT NULL,
+- filename TEXT NOT NULL,
+- mtime INTEGER NOT NULL,
+- ctime INTEGER NOT NULL,
+- filesize INTEGER NOT NULL,
+- sampler INTEGER NOT NULL DEFAULT 0,
+- art_automatic TEXT,
+- art_manual TEXT,
+- filetype INTEGER NOT NULL DEFAULT 0,
+- playcount INTEGER NOT NULL DEFAULT 0,
+- lastplayed INTEGER,
+- rating INTEGER,
+- forced_compilation_on INTEGER NOT NULL DEFAULT 0,
+- forced_compilation_off INTEGER NOT NULL DEFAULT 0,
+- effective_compilation NOT NULL DEFAULT 0,
+- skipcount INTEGER NOT NULL DEFAULT 0,
+- score INTEGER NOT NULL DEFAULT 0,
+- beginning INTEGER NOT NULL DEFAULT 0,
+- cue_path TEXT
+-);
+-
+-CREATE VIRTUAL TABLE spotify_search_songs_fts USING fts3 (
+- ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsgenre, ftscomment,
+- tokenize=unicode
+-);
+-
+ UPDATE schema_version SET version=30;
+diff -rauN clementine-1.0.1/dist/macdeploy.py clementine-libre-1.0.1/dist/macdeploy.py
+--- clementine-1.0.1/dist/macdeploy.py 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/dist/macdeploy.py 2012-05-28 17:58:29.937662793 -0300
+@@ -367,11 +367,6 @@
+
+ FixPlugin(FindGstreamerPlugin('gst-plugin-scanner'), '.')
+
+-try:
+- FixPlugin('clementine-spotifyblob', '.')
+-except:
+- print 'Failed to find spotify blob'
+-
+ for plugin in QT_PLUGINS:
+ FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
+
+diff -rauN clementine-1.0.1/dist/windows/clementine.nsi clementine-libre-1.0.1/dist/windows/clementine.nsi
+--- clementine-1.0.1/dist/windows/clementine.nsi 2012-01-22 10:43:46.000000000 -0200
++++ clementine-libre-1.0.1/dist/windows/clementine.nsi 2012-05-28 18:06:56.812551755 -0300
+@@ -95,7 +95,6 @@
+ Delete "$INSTDIR\gstreamer-plugins\libgstsoup.dll"
+
+ ; 1.0 prerelease
+- Delete "$INSTDIR\spotify.dll"
+
+ ; 1.0
+ Delete "$INSTDIR\libofa.dll"
+@@ -109,7 +108,6 @@
+ File "avformat-52.dll"
+ File "avutil-50.dll"
+ File "clementine.exe"
+- File "clementine-spotifyblob.exe"
+ File "clementine.ico"
+ File "glew32.dll"
+ File "intl.dll"
+@@ -163,7 +161,6 @@
+ File "libqjson.dll"
+ File "libsoup-2.4-1.dll"
+ File "libspeex-1.dll"
+- File "libspotify.dll"
+ File "libtag.dll"
+ File "libtasn1-3.dll"
+ File "libusbmuxd.dll"
+@@ -949,7 +946,6 @@
+ Delete "$INSTDIR\avutil-50.dll"
+ Delete "$INSTDIR\clementine.ico"
+ Delete "$INSTDIR\clementine.exe"
+- Delete "$INSTDIR\clementine-spotifyblob.exe"
+ Delete "$INSTDIR\glew32.dll"
+ Delete "$INSTDIR\intl.dll"
+ Delete "$INSTDIR\libcdio-12.dll"
+@@ -1002,7 +998,6 @@
+ Delete "$INSTDIR\libqjson.dll"
+ Delete "$INSTDIR\libsoup-2.4-1.dll"
+ Delete "$INSTDIR\libspeex-1.dll"
+- Delete "$INSTDIR\libspotify.dll"
+ Delete "$INSTDIR\libtag.dll"
+ Delete "$INSTDIR\libtasn1-3.dll"
+ Delete "$INSTDIR\libusbmuxd.dll"
+diff -rauN clementine-1.0.1/dist/windows/clementine.nsi.in clementine-libre-1.0.1/dist/windows/clementine.nsi.in
+--- clementine-1.0.1/dist/windows/clementine.nsi.in 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/dist/windows/clementine.nsi.in 2012-05-28 18:09:14.664818947 -0300
+@@ -95,7 +95,6 @@
+ Delete "$INSTDIR\gstreamer-plugins\libgstsoup.dll"
+
+ ; 1.0 prerelease
+- Delete "$INSTDIR\spotify.dll"
+
+ ; 1.0
+ Delete "$INSTDIR\libofa.dll"
+@@ -109,7 +108,6 @@
+ File "avformat-52.dll"
+ File "avutil-50.dll"
+ File "clementine.exe"
+- File "clementine-spotifyblob.exe"
+ File "clementine.ico"
+ File "glew32.dll"
+ File "intl.dll"
+@@ -163,7 +161,6 @@
+ File "libqjson.dll"
+ File "libsoup-2.4-1.dll"
+ File "libspeex-1.dll"
+- File "libspotify.dll"
+ File "libtag.dll"
+ File "libtasn1-3.dll"
+ File "libusbmuxd.dll"
+@@ -949,7 +946,6 @@
+ Delete "$INSTDIR\avutil-50.dll"
+ Delete "$INSTDIR\clementine.ico"
+ Delete "$INSTDIR\clementine.exe"
+- Delete "$INSTDIR\clementine-spotifyblob.exe"
+ Delete "$INSTDIR\glew32.dll"
+ Delete "$INSTDIR\intl.dll"
+ Delete "$INSTDIR\libcdio-12.dll"
+@@ -1002,7 +998,6 @@
+ Delete "$INSTDIR\libqjson.dll"
+ Delete "$INSTDIR\libsoup-2.4-1.dll"
+ Delete "$INSTDIR\libspeex-1.dll"
+- Delete "$INSTDIR\libspotify.dll"
+ Delete "$INSTDIR\libtag.dll"
+ Delete "$INSTDIR\libtasn1-3.dll"
+ Delete "$INSTDIR\libusbmuxd.dll"
+diff -rauN clementine-1.0.1/src/CMakeLists.txt clementine-libre-1.0.1/src/CMakeLists.txt
+--- clementine-1.0.1/src/CMakeLists.txt 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/src/CMakeLists.txt 2012-05-30 02:50:15.725755468 -0300
+@@ -552,7 +552,6 @@
+ internet/internetviewcontainer.ui
+ internet/magnatunedownloaddialog.ui
+ internet/magnatunesettingspage.ui
+- internet/spotifysettingspage.ui
+
+ library/groupbydialog.ui
+ library/libraryfilterwidget.ui
+@@ -690,23 +689,6 @@
+ internet/lastfmstationdialog.ui
+ )
+
+-# Spotify
+-optional_source(HAVE_SPOTIFY
+- SOURCES
+- globalsearch/spotifysearchprovider.cpp
+- internet/spotifyblobdownloader.cpp
+- internet/spotifysearchplaylisttype.cpp
+- internet/spotifyserver.cpp
+- internet/spotifyservice.cpp
+- internet/spotifysettingspage.cpp
+- HEADERS
+- globalsearch/spotifysearchprovider.h
+- internet/spotifyblobdownloader.h
+- internet/spotifyserver.h
+- internet/spotifyservice.h
+- internet/spotifysettingspage.h
+-)
+-
+ optional_source(HAVE_QCA INCLUDE_DIRECTORIES ${QCA_INCLUDE_DIRS})
+
+ # Platform specific - OS X
+@@ -1037,14 +1019,6 @@
+ endif (LINUX)
+ endif(HAVE_BREAKPAD)
+
+-if(HAVE_SPOTIFY)
+- target_link_libraries(clementine_lib
+- clementine-spotifyblob-messages
+- ${QCA_LIBRARIES}
+- )
+- link_directories(${QCA_LIBRARY_DIRS})
+-endif(HAVE_SPOTIFY)
+-
+ if (APPLE)
+ target_link_libraries(clementine_lib
+ ${GROWL}
+@@ -1118,11 +1092,6 @@
+ clementine_lib
+ )
+
+-# macdeploy.py relies on the blob being built first.
+-if(HAVE_SPOTIFY_BLOB)
+- add_dependencies(clementine clementine-spotifyblob)
+-endif(HAVE_SPOTIFY_BLOB)
+-
+ set_target_properties(clementine PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "../dist/Info.plist"
+ )
+diff -rauN clementine-1.0.1/src/config.h.in clementine-libre-1.0.1/src/config.h.in
+--- clementine-1.0.1/src/config.h.in 2011-12-02 19:24:43.000000000 -0200
++++ clementine-libre-1.0.1/src/config.h.in 2012-05-28 18:17:13.027993639 -0300
+@@ -35,7 +35,6 @@
+ #cmakedefine HAVE_QCA
+ #cmakedefine HAVE_REMOTE
+ #cmakedefine HAVE_SPARKLE
+-#cmakedefine HAVE_SPOTIFY
+ #cmakedefine HAVE_STATIC_SQLITE
+ #cmakedefine HAVE_WIIMOTEDEV
+ #cmakedefine LEOPARD
+diff -rauN clementine-1.0.1/src/core/utilities.cpp clementine-libre-1.0.1/src/core/utilities.cpp
+--- clementine-1.0.1/src/core/utilities.cpp 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/src/core/utilities.cpp 2012-05-28 18:25:43.252728803 -0300
+@@ -277,9 +277,6 @@
+ return QDir::homePath();
+ #endif
+
+- case Path_LocalSpotifyBlob:
+- return GetConfigPath(Path_Root) + "/spotifyblob";
+-
+ default:
+ qFatal("%s", Q_FUNC_INFO);
+ return QString::null;
+diff -rauN clementine-1.0.1/src/core/utilities.h clementine-libre-1.0.1/src/core/utilities.h
+--- clementine-1.0.1/src/core/utilities.h 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/src/core/utilities.h 2012-05-28 18:27:31.686659381 -0300
+@@ -88,7 +88,6 @@
+ Path_NetworkCache,
+ Path_GstreamerRegistry,
+ Path_DefaultMusicLibrary,
+- Path_LocalSpotifyBlob,
+ };
+ QString GetConfigPath(ConfigPath config);
+
+diff -rauN clementine-1.0.1/src/covers/albumcoverloader.cpp clementine-libre-1.0.1/src/covers/albumcoverloader.cpp
+--- clementine-1.0.1/src/covers/albumcoverloader.cpp 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/covers/albumcoverloader.cpp 2012-05-28 18:34:26.543457483 -0300
+@@ -28,10 +28,6 @@
+ #include
+ #include
+
+-#ifdef HAVE_SPOTIFY
+-# include "internet/spotifyservice.h"
+-#endif
+-
+
+ AlbumCoverLoader::AlbumCoverLoader(QObject* parent)
+ : QObject(parent),
+@@ -40,8 +36,7 @@
+ scale_(true),
+ padding_(true),
+ next_id_(0),
+- network_(new NetworkAccessManager(this)),
+- connected_spotify_(false)
++ network_(new NetworkAccessManager(this))
+ {
+ }
+
+@@ -148,46 +143,12 @@
+
+ remote_tasks_.insert(reply, task);
+ return TryLoadResult(true, false, QImage());
+- } else if (filename.toLower().startsWith("spotify://image/")) {
+- // HACK: we should add generic image URL handlers
+- #ifdef HAVE_SPOTIFY
+- SpotifyService* spotify = InternetModel::Service();
+-
+- if (!connected_spotify_) {
+- connect(spotify, SIGNAL(ImageLoaded(QString,QImage)),
+- SLOT(SpotifyImageLoaded(QString,QImage)));
+- connected_spotify_ = true;
+- }
+-
+- QString id = QUrl(filename).path();
+- if (id.startsWith('/')) {
+- id.remove(0, 1);
+- }
+- remote_spotify_tasks_.insert(id, task);
+-
+- // Need to schedule this in the spotify service's thread
+- QMetaObject::invokeMethod(spotify, "LoadImage", Qt::QueuedConnection,
+- Q_ARG(QString, id));
+- return TryLoadResult(true, false, QImage());
+- #else
+- return TryLoadResult(false, false, QImage());
+- #endif
+ }
+
+ QImage image(filename);
+ return TryLoadResult(false, !image.isNull(), image.isNull() ? default_ : image);
+ }
+
+-void AlbumCoverLoader::SpotifyImageLoaded(const QString& id, const QImage& image) {
+- if (!remote_spotify_tasks_.contains(id))
+- return;
+-
+- Task task = remote_spotify_tasks_.take(id);
+- QImage scaled = ScaleAndPad(image);
+- emit ImageLoaded(task.id, scaled);
+- emit ImageLoaded(task.id, scaled, image);
+-}
+-
+ void AlbumCoverLoader::RemoteFetchFinished() {
+ QNetworkReply* reply = qobject_cast(sender());
+ if (!reply)
+diff -rauN clementine-1.0.1/src/covers/albumcoverloader.h clementine-libre-1.0.1/src/covers/albumcoverloader.h
+--- clementine-1.0.1/src/covers/albumcoverloader.h 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/covers/albumcoverloader.h 2012-05-28 18:38:03.228006474 -0300
+@@ -65,7 +65,6 @@
+ protected slots:
+ void ProcessTasks();
+ void RemoteFetchFinished();
+- void SpotifyImageLoaded(const QString& url, const QImage& image);
+
+ protected:
+ enum State {
+@@ -108,13 +107,10 @@
+ QMutex mutex_;
+ QQueue tasks_;
+ QMap remote_tasks_;
+- QMap remote_spotify_tasks_;
+ quint64 next_id_;
+
+ NetworkAccessManager* network_;
+
+- bool connected_spotify_;
+-
+ static const int kMaxRedirects = 3;
+ };
+
+diff -rauN clementine-1.0.1/src/engines/gstenginepipeline.cpp clementine-libre-1.0.1/src/engines/gstenginepipeline.cpp
+--- clementine-1.0.1/src/engines/gstenginepipeline.cpp 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/engines/gstenginepipeline.cpp 2012-05-28 18:51:35.779395089 -0300
+@@ -26,11 +26,6 @@
+ #include "core/utilities.h"
+ #include "internet/internetmodel.h"
+
+-#ifdef HAVE_SPOTIFY
+-# include "internet/spotifyserver.h"
+-# include "internet/spotifyservice.h"
+-#endif
+-
+ #include
+
+ const int GstEnginePipeline::kGstStateTimeoutNanosecs = 10000000;
+@@ -131,36 +126,6 @@
+ bool GstEnginePipeline::ReplaceDecodeBin(const QUrl& url) {
+ GstElement* new_bin = NULL;
+
+- if (url.scheme() == "spotify") {
+- #ifdef HAVE_SPOTIFY
+- new_bin = gst_bin_new("spotify_bin");
+-
+- // Create elements
+- GstElement* src = engine_->CreateElement("tcpserversrc", new_bin);
+- GstElement* gdp = engine_->CreateElement("gdpdepay", new_bin);
+- if (!src || !gdp)
+- return false;
+-
+- // Pick a port number
+- const int port = Utilities::PickUnusedPort();
+- g_object_set(G_OBJECT(src), "host", "127.0.0.1", NULL);
+- g_object_set(G_OBJECT(src), "port", port, NULL);
+-
+- // Link the elements
+- gst_element_link(src, gdp);
+-
+- // Add a ghost pad
+- GstPad* pad = gst_element_get_static_pad(gdp, "src");
+- gst_element_add_pad(GST_ELEMENT(new_bin), gst_ghost_pad_new("src", pad));
+- gst_object_unref(GST_OBJECT(pad));
+-
+- // Tell spotify to start sending data to us.
+- InternetModel::Service()->server()->StartPlaybackLater(url.toString(), port);
+- #else // HAVE_SPOTIFY
+- qLog(Error) << "Tried to play a spotify:// url, but spotify support is not compiled in";
+- return false;
+- #endif
+- } else {
+ new_bin = engine_->CreateElement("uridecodebin");
+ g_object_set(G_OBJECT(new_bin), "uri", url.toEncoded().constData(), NULL);
+ g_object_set(G_OBJECT(new_bin), "buffer-duration", buffer_duration_nanosec_, NULL);
+@@ -169,7 +134,6 @@
+ g_signal_connect(G_OBJECT(new_bin), "drained", G_CALLBACK(SourceDrainedCallback), this);
+ g_signal_connect(G_OBJECT(new_bin), "pad-added", G_CALLBACK(NewPadCallback), this);
+ g_signal_connect(G_OBJECT(new_bin), "notify::source", G_CALLBACK(SourceSetupCallback), this);
+- }
+
+ return ReplaceDecodeBin(new_bin);
+ }
+diff -rauN clementine-1.0.1/src/globalsearch/spotifysearchprovider.cpp /dev/null
+--- clementine-1.0.1/src/globalsearch/spotifysearchprovider.cpp 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,208 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#include "spotifysearchprovider.h"
+-#include "core/logging.h"
+-#include "internet/internetmodel.h"
+-#include "internet/spotifyserver.h"
+-#include "internet/spotifyservice.h"
+-#include "playlist/songmimedata.h"
+-#include "spotifyblob/common/spotifymessagehandler.h"
+-
+-SpotifySearchProvider::SpotifySearchProvider(QObject* parent)
+- : SearchProvider(parent),
+- server_(NULL),
+- service_(NULL)
+-{
+- Init("Spotify", "spotify", QIcon(":icons/32x32/spotify.png"),
+- WantsDelayedQueries | WantsSerialisedArtQueries | ArtIsProbablyRemote |
+- CanShowConfig);
+-}
+-
+-SpotifyServer* SpotifySearchProvider::server() {
+- if (server_)
+- return server_;
+-
+- if (!service_)
+- service_ = InternetModel::Service();
+-
+- if (service_->login_state() != SpotifyService::LoginState_LoggedIn)
+- return NULL;
+-
+- server_ = service_->server();
+- connect(server_, SIGNAL(SearchResults(spotify_pb::SearchResponse)),
+- SLOT(SearchFinishedSlot(spotify_pb::SearchResponse)));
+- connect(server_, SIGNAL(ImageLoaded(QString,QImage)),
+- SLOT(ArtLoadedSlot(QString,QImage)));
+- connect(server_, SIGNAL(AlbumBrowseResults(spotify_pb::BrowseAlbumResponse)),
+- SLOT(AlbumBrowseResponse(spotify_pb::BrowseAlbumResponse)));
+- connect(server_, SIGNAL(destroyed()), SLOT(ServerDestroyed()));
+-
+- return server_;
+-}
+-
+-void SpotifySearchProvider::ServerDestroyed() {
+- server_ = NULL;
+-}
+-
+-void SpotifySearchProvider::SearchAsync(int id, const QString& query) {
+- SpotifyServer* s = server();
+- if (!s) {
+- emit SearchFinished(id);
+- return;
+- }
+-
+- PendingState state;
+- state.orig_id_ = id;
+- state.tokens_ = TokenizeQuery(query);
+-
+- const QString query_string = state.tokens_.join(" ");
+- s->Search(query_string, 5, 5);
+- queries_[query_string] = state;
+-}
+-
+-void SpotifySearchProvider::SearchFinishedSlot(const spotify_pb::SearchResponse& response) {
+- QString query_string = QString::fromUtf8(response.request().query().c_str());
+- QMap::iterator it = queries_.find(query_string);
+- if (it == queries_.end())
+- return;
+-
+- PendingState state = it.value();
+- queries_.erase(it);
+-
+- ResultList ret;
+- for (int i=0; i < response.result_size() ; ++i) {
+- const spotify_pb::Track& track = response.result(i);
+-
+- Result result(this);
+- result.type_ = globalsearch::Type_Track;
+- SpotifyService::SongFromProtobuf(track, &result.metadata_);
+- result.match_quality_ = MatchQuality(state.tokens_, result.metadata_.title());
+-
+- ret << result;
+- }
+-
+- for (int i=0 ; iLoadImage(image_id);
+-}
+-
+-void SpotifySearchProvider::ArtLoadedSlot(const QString& id, const QImage& image) {
+- QMap::iterator it = pending_art_.find(id);
+- if (it == pending_art_.end())
+- return;
+-
+- const int orig_id = it.value();
+- pending_art_.erase(it);
+-
+- emit ArtLoaded(orig_id, ScaleAndPad(image));
+-}
+-
+-void SpotifySearchProvider::LoadTracksAsync(int id, const Result& result) {
+- switch (result.type_) {
+- case globalsearch::Type_Track: {
+- SongMimeData* mime_data = new SongMimeData;
+- mime_data->songs = SongList() << result.metadata_;
+- emit TracksLoaded(id, mime_data);
+- break;
+- }
+-
+- case globalsearch::Type_Album: {
+- SpotifyServer* s = server();
+- if (!s) {
+- emit TracksLoaded(id, NULL);
+- return;
+- }
+-
+- QString uri = result.metadata_.url().toString();
+-
+- pending_tracks_[uri] = id;
+- s->AlbumBrowse(uri);
+- break;
+- }
+-
+- default:
+- break;
+- }
+-}
+-
+-void SpotifySearchProvider::AlbumBrowseResponse(const spotify_pb::BrowseAlbumResponse& response) {
+- QString uri = QStringFromStdString(response.uri());
+- QMap::iterator it = pending_tracks_.find(uri);
+- if (it == pending_tracks_.end())
+- return;
+-
+- const int orig_id = it.value();
+- pending_tracks_.erase(it);
+-
+- SongMimeData* mime_data = new SongMimeData;
+-
+- for (int i=0 ; isongs << song;
+- }
+-
+- emit TracksLoaded(orig_id, mime_data);
+-}
+-
+-bool SpotifySearchProvider::IsLoggedIn() {
+- if (server()) {
+- return service_->IsLoggedIn();
+- }
+- return false;
+-}
+-
+-void SpotifySearchProvider::ShowConfig() {
+- if (service_) {
+- return service_->ShowConfig();
+- }
+-}
+diff -rauN clementine-1.0.1/src/globalsearch/spotifysearchprovider.h /dev/null
+--- clementine-1.0.1/src/globalsearch/spotifysearchprovider.h 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,60 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#ifndef SPOTIFYSEARCHPROVIDER_H
+-#define SPOTIFYSEARCHPROVIDER_H
+-
+-#include "searchprovider.h"
+-#include "spotifyblob/common/spotifymessages.pb.h"
+-
+-class SpotifyServer;
+-class SpotifyService;
+-
+-
+-class SpotifySearchProvider : public SearchProvider {
+- Q_OBJECT
+-
+-public:
+- SpotifySearchProvider(QObject* parent = 0);
+-
+- void SearchAsync(int id, const QString& query);
+- void LoadArtAsync(int id, const Result& result);
+- void LoadTracksAsync(int id, const Result& result);
+-
+- bool IsLoggedIn();
+- void ShowConfig();
+-
+-private slots:
+- void ServerDestroyed();
+- void SearchFinishedSlot(const spotify_pb::SearchResponse& response);
+- void ArtLoadedSlot(const QString& id, const QImage& image);
+-
+- void AlbumBrowseResponse(const spotify_pb::BrowseAlbumResponse& response);
+-
+-private:
+- SpotifyServer* server();
+-
+-private:
+- SpotifyServer* server_;
+- SpotifyService* service_;
+-
+- QMap queries_;
+- QMap pending_art_;
+- QMap pending_tracks_;
+-};
+-
+-#endif // SPOTIFYSEARCHPROVIDER_H
+diff -rauN clementine-1.0.1/src/internet/internetmodel.cpp clementine-libre-1.0.1/src/internet/internetmodel.cpp
+--- clementine-1.0.1/src/internet/internetmodel.cpp 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/internet/internetmodel.cpp 2012-05-28 18:56:58.934758916 -0300
+@@ -32,9 +32,6 @@
+ #ifdef HAVE_LIBLASTFM
+ #include "lastfmservice.h"
+ #endif
+-#ifdef HAVE_SPOTIFY
+- #include "spotifyservice.h"
+-#endif
+
+ #include
+ #include
+@@ -75,9 +72,6 @@
+ AddService(new SavedRadio(this));
+ AddService(new SkyFmService(this));
+ AddService(new SomaFMService(this));
+-#ifdef HAVE_SPOTIFY
+- AddService(new SpotifyService(this));
+-#endif
+ }
+
+ void InternetModel::AddService(InternetService *service) {
+diff -rauN clementine-1.0.1/src/internet/spotifyblobdownloader.cpp /dev/null
+--- clementine-1.0.1/src/internet/spotifyblobdownloader.cpp 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,222 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#include "config.h"
+-#include "spotifyblobdownloader.h"
+-#include "spotifyservice.h"
+-#include "core/logging.h"
+-#include "core/network.h"
+-#include "core/utilities.h"
+-
+-#include
+-#include
+-#include
+-#include
+-
+-#ifdef HAVE_QCA
+- #include
+-#endif // HAVE_QCA
+-
+-const char* SpotifyBlobDownloader::kSignatureSuffix = ".sha1";
+-
+-
+-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_;
+-}
+-
+-bool SpotifyBlobDownloader::Prompt() {
+- 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);
+- return ret == QMessageBox::Yes;
+-}
+-
+-void SpotifyBlobDownloader::Start() {
+- qDeleteAll(replies_);
+- replies_.clear();
+-
+- const QStringList filenames = QStringList()
+- << "blob"
+- << "blob" + QString(kSignatureSuffix)
+- << "libspotify.so.10.1.16"
+- << "libspotify.so.10.1.16" + QString(kSignatureSuffix);
+-
+- 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(sender());
+- if (reply->error() != QNetworkReply::NoError) {
+- // Handle network errors
+- ShowError(reply->errorString());
+- return;
+- }
+-
+- // Is everything finished?
+- foreach (QNetworkReply* reply, replies_) {
+- if (!reply->isFinished()) {
+- return;
+- }
+- }
+-
+- // Read files into memory first.
+- QMap file_data;
+- QStringList signature_filenames;
+-
+- foreach (QNetworkReply* reply, replies_) {
+- const QString filename = reply->url().path().section('/', -1, -1);
+-
+- if (filename.endsWith(kSignatureSuffix)) {
+- signature_filenames << filename;
+- }
+-
+- file_data[filename] = reply->readAll();
+- }
+-
+-#ifdef HAVE_QCA
+- // Load the public key
+- QCA::ConvertResult conversion_result;
+- QCA::PublicKey key = QCA::PublicKey::fromPEMFile(":/clementine-spotify-public.pem",
+- &conversion_result);
+- if (QCA::ConvertGood != conversion_result) {
+- ShowError("Failed to load Spotify public key");
+- return;
+- }
+-
+- // Verify signatures
+- foreach (const QString& signature_filename, signature_filenames) {
+- QString actual_filename = signature_filename;
+- actual_filename.remove(kSignatureSuffix);
+-
+- qLog(Debug) << "Verifying" << actual_filename << "against" << signature_filename;
+-
+- if (!key.verifyMessage(file_data[actual_filename],
+- file_data[signature_filename],
+- QCA::EMSA3_SHA1)) {
+- ShowError("Invalid signature: " + actual_filename);
+- return;
+- }
+- }
+-#endif // HAVE_QCA
+-
+- // Make the destination directory and write the files into it
+- QDir().mkpath(path_);
+-
+- foreach (const QString& filename, file_data.keys()) {
+- const QString dest_path = path_ + "/" + filename;
+-
+- if (filename.endsWith(kSignatureSuffix))
+- continue;
+-
+- qLog(Info) << "Writing" << dest_path;
+-
+- QFile file(dest_path);
+- if (!file.open(QIODevice::WriteOnly)) {
+- ShowError("Failed to open " + dest_path + " for writing");
+- return;
+- }
+-
+- file.write(file_data[filename]);
+- file.close();
+- file.setPermissions(QFile::Permissions(0x7755));
+-
+-#ifdef Q_OS_UNIX
+- const int so_pos = filename.lastIndexOf(".so.");
+- if (so_pos != -1) {
+- QString link_path = path_ + "/" + filename.left(so_pos + 3);
+- QStringList version_parts = filename.mid(so_pos + 4).split('.');
+-
+- while (!version_parts.isEmpty()) {
+- qLog(Debug) << "Linking" << dest_path << "to" << link_path;
+- int ret = symlink(dest_path.toLocal8Bit().constData(),
+- link_path.toLocal8Bit().constData());
+-
+- if (ret != 0) {
+- qLog(Warning) << "Creating symlink failed with return code" << ret;
+- }
+-
+- link_path += "." + version_parts.takeFirst();
+- }
+- }
+-#endif // Q_OS_UNIX
+- }
+-
+- 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();
+-}
+diff -rauN clementine-1.0.1/src/internet/spotifyblobdownloader.h /dev/null
+--- clementine-1.0.1/src/internet/spotifyblobdownloader.h 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,63 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#ifndef SPOTIFYBLOBDOWNLOADER_H
+-#define SPOTIFYBLOBDOWNLOADER_H
+-
+-#include
+-
+-class QNetworkAccessManager;
+-class QNetworkReply;
+-class QProgressDialog;
+-
+-class SpotifyBlobDownloader : public QObject {
+- Q_OBJECT
+-
+-public:
+- SpotifyBlobDownloader(const QString& version, const QString& path,
+- QObject* parent = 0);
+- ~SpotifyBlobDownloader();
+-
+- static const char* kSignatureSuffix;
+-
+- static bool Prompt();
+-
+- 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 replies_;
+-
+- QProgressDialog* progress_;
+-};
+-
+-#endif // SPOTIFYBLOBDOWNLOADER_H
+diff -rauN clementine-1.0.1/src/internet/spotifysearchplaylisttype.cpp /dev/null
+--- clementine-1.0.1/src/internet/spotifysearchplaylisttype.cpp 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,49 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#include "spotifysearchplaylisttype.h"
+-#include "spotifyservice.h"
+-
+-const char* SpotifySearchPlaylistType::kName = "spotify-search";
+-
+-SpotifySearchPlaylistType::SpotifySearchPlaylistType(SpotifyService* service)
+- : service_(service) {
+-}
+-
+-QIcon SpotifySearchPlaylistType::icon(Playlist* playlist) const {
+- return QIcon(":icons/32x32/spotify.png");
+-}
+-
+-QString SpotifySearchPlaylistType::search_hint_text(Playlist* playlist) const {
+- return QObject::tr("Search Spotify");
+-}
+-
+-QString SpotifySearchPlaylistType::empty_playlist_text(Playlist* playlist) const {
+- return QObject::tr("Start typing in the search box above to find music on %1.").arg("Spotify");
+-}
+-
+-bool SpotifySearchPlaylistType::has_special_search_behaviour(Playlist* playlist) const {
+- return true;
+-}
+-
+-void SpotifySearchPlaylistType::Search(const QString& text, Playlist* playlist) {
+- service_->Search(text, playlist);
+-}
+-
+-void SpotifySearchPlaylistType::DidYouMeanClicked(const QString& text, Playlist* playlist) {
+- service_->Search(text, playlist, true);
+-}
+diff -rauN clementine-1.0.1/src/internet/spotifysearchplaylisttype.h /dev/null
+--- clementine-1.0.1/src/internet/spotifysearchplaylisttype.h 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,44 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#ifndef SPOTIFYSEARCHPLAYLISTTYPE_H
+-#define SPOTIFYSEARCHPLAYLISTTYPE_H
+-
+-#include "playlist/specialplaylisttype.h"
+-
+-class SpotifyService;
+-
+-class SpotifySearchPlaylistType : public SpecialPlaylistType {
+-public:
+- SpotifySearchPlaylistType(SpotifyService* service);
+-
+- static const char* kName;
+- virtual QString name() const { return kName; }
+-
+- virtual QIcon icon(Playlist* playlist) const;
+- virtual QString search_hint_text(Playlist* playlist) const;
+- virtual QString empty_playlist_text(Playlist* playlist) const;
+-
+- virtual bool has_special_search_behaviour(Playlist* playlist) const;
+- virtual void Search(const QString& text, Playlist* playlist);
+- virtual void DidYouMeanClicked(const QString& text, Playlist* playlist);
+-
+-private:
+- SpotifyService* service_;
+-};
+-
+-#endif // SPOTIFYSEARCHPLAYLISTTYPE_H
+diff -rauN clementine-1.0.1/src/internet/spotifyserver.cpp /dev/null
+--- clementine-1.0.1/src/internet/spotifyserver.cpp 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,261 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#include "spotifyserver.h"
+-#include "core/closure.h"
+-#include "core/logging.h"
+-
+-#include "spotifyblob/common/spotifymessages.pb.h"
+-#include "spotifyblob/common/spotifymessagehandler.h"
+-
+-#include
+-#include
+-#include
+-
+-SpotifyServer::SpotifyServer(QObject* parent)
+- : QObject(parent),
+- server_(new QTcpServer(this)),
+- protocol_socket_(NULL),
+- handler_(NULL),
+- logged_in_(false)
+-{
+- connect(server_, SIGNAL(newConnection()), SLOT(NewConnection()));
+-}
+-
+-void SpotifyServer::Init() {
+- if (!server_->listen(QHostAddress::LocalHost)) {
+- qLog(Error) << "Couldn't open server socket" << server_->errorString();
+- }
+-}
+-
+-int SpotifyServer::server_port() const {
+- return server_->serverPort();
+-}
+-
+-void SpotifyServer::NewConnection() {
+- delete protocol_socket_;
+- delete handler_;
+-
+- protocol_socket_ = server_->nextPendingConnection();
+- handler_ = new SpotifyMessageHandler(protocol_socket_, this);
+- connect(handler_, SIGNAL(MessageArrived(spotify_pb::SpotifyMessage)),
+- SLOT(HandleMessage(spotify_pb::SpotifyMessage)));
+-
+- qLog(Info) << "Connection from port" << protocol_socket_->peerPort();
+-
+- // Send any login messages that were queued before the client connected
+- foreach (const spotify_pb::SpotifyMessage& message, queued_login_messages_) {
+- SendMessage(message);
+- }
+- queued_login_messages_.clear();
+-}
+-
+-void SpotifyServer::SendMessage(const spotify_pb::SpotifyMessage& message) {
+- const bool is_login_message = message.has_login_request();
+-
+- QList* queue =
+- is_login_message ? &queued_login_messages_ : &queued_messages_;
+-
+- if (!protocol_socket_ || (!is_login_message && !logged_in_)) {
+- queue->append(message);
+- } else {
+- handler_->SendMessage(message);
+- }
+-}
+-
+-void SpotifyServer::Login(const QString& username, const QString& password,
+- spotify_pb::Bitrate bitrate, bool volume_normalisation) {
+- spotify_pb::SpotifyMessage message;
+-
+- spotify_pb::LoginRequest* request = message.mutable_login_request();
+- request->set_username(DataCommaSizeFromQString(username));
+- if (!password.isEmpty()) {
+- request->set_password(DataCommaSizeFromQString(password));
+- }
+- request->mutable_playback_settings()->set_bitrate(bitrate);
+- request->mutable_playback_settings()->set_volume_normalisation(volume_normalisation);
+-
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::SetPlaybackSettings(spotify_pb::Bitrate bitrate, bool volume_normalisation) {
+- spotify_pb::SpotifyMessage message;
+-
+- spotify_pb::PlaybackSettings* request = message.mutable_set_playback_settings_request();
+- request->set_bitrate(bitrate);
+- request->set_volume_normalisation(volume_normalisation);
+-
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::HandleMessage(const spotify_pb::SpotifyMessage& message) {
+- if (message.has_login_response()) {
+- const spotify_pb::LoginResponse& response = message.login_response();
+- logged_in_ = response.success();
+-
+- if (response.success()) {
+- // Send any messages that were queued before the client logged in
+- foreach (const spotify_pb::SpotifyMessage& message, queued_messages_) {
+- SendMessage(message);
+- }
+- queued_messages_.clear();
+- }
+-
+- emit LoginCompleted(response.success(), QStringFromStdString(response.error()),
+- response.error_code());
+- } else if (message.has_playlists_updated()) {
+- emit PlaylistsUpdated(message.playlists_updated());
+- } else if (message.has_load_playlist_response()) {
+- const spotify_pb::LoadPlaylistResponse& response = message.load_playlist_response();
+-
+- switch (response.request().type()) {
+- case spotify_pb::Inbox:
+- emit InboxLoaded(response);
+- break;
+-
+- case spotify_pb::Starred:
+- emit StarredLoaded(response);
+- break;
+-
+- case spotify_pb::UserPlaylist:
+- emit UserPlaylistLoaded(response);
+- break;
+- }
+- } else if (message.has_playback_error()) {
+- emit PlaybackError(QStringFromStdString(message.playback_error().error()));
+- } else if (message.has_search_response()) {
+- emit SearchResults(message.search_response());
+- } else if (message.has_image_response()) {
+- const spotify_pb::ImageResponse& response = message.image_response();
+- const QString id = QStringFromStdString(response.id());
+-
+- if (response.has_data()) {
+- emit ImageLoaded(id, QImage::fromData(QByteArray(
+- response.data().data(), response.data().size())));
+- } else {
+- emit ImageLoaded(id, QImage());
+- }
+- } else if (message.has_sync_playlist_progress()) {
+- emit SyncPlaylistProgress(message.sync_playlist_progress());
+- } else if (message.has_browse_album_response()) {
+- emit AlbumBrowseResults(message.browse_album_response());
+- }
+-}
+-
+-void SpotifyServer::LoadPlaylist(spotify_pb::PlaylistType type, int index) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::LoadPlaylistRequest* req = message.mutable_load_playlist_request();
+-
+- req->set_type(type);
+- if (index != -1) {
+- req->set_user_playlist_index(index);
+- }
+-
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::SyncPlaylist(
+- spotify_pb::PlaylistType type, int index, bool offline) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::SyncPlaylistRequest* req = message.mutable_sync_playlist_request();
+- req->mutable_request()->set_type(type);
+- if (index != -1) {
+- req->mutable_request()->set_user_playlist_index(index);
+- }
+- req->set_offline_sync(offline);
+-
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::SyncInbox() {
+- SyncPlaylist(spotify_pb::Inbox, -1, true);
+-}
+-
+-void SpotifyServer::SyncStarred() {
+- SyncPlaylist(spotify_pb::Starred, -1, true);
+-}
+-
+-void SpotifyServer::SyncUserPlaylist(int index) {
+- Q_ASSERT(index >= 0);
+- SyncPlaylist(spotify_pb::UserPlaylist, index, true);
+-}
+-
+-void SpotifyServer::LoadInbox() {
+- LoadPlaylist(spotify_pb::Inbox);
+-}
+-
+-void SpotifyServer::LoadStarred() {
+- LoadPlaylist(spotify_pb::Starred);
+-}
+-
+-void SpotifyServer::LoadUserPlaylist(int index) {
+- Q_ASSERT(index >= 0);
+- LoadPlaylist(spotify_pb::UserPlaylist, index);
+-}
+-
+-void SpotifyServer::StartPlaybackLater(const QString& uri, quint16 port) {
+- QTimer* timer = new QTimer(this);
+- connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()));
+-
+- timer->start(100); // lol
+- NewClosure(timer, SIGNAL(timeout()),
+- this, SLOT(StartPlayback(QString,quint16)),
+- uri, port);
+-}
+-
+-void SpotifyServer::StartPlayback(const QString& uri, quint16 port) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::PlaybackRequest* req = message.mutable_playback_request();
+-
+- req->set_track_uri(DataCommaSizeFromQString(uri));
+- req->set_media_port(port);
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::Seek(qint64 offset_bytes) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::SeekRequest* req = message.mutable_seek_request();
+-
+- req->set_offset_bytes(offset_bytes);
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::Search(const QString& text, int limit, int limit_album) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::SearchRequest* req = message.mutable_search_request();
+-
+- req->set_query(DataCommaSizeFromQString(text));
+- req->set_limit(limit);
+- req->set_limit_album(limit_album);
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::LoadImage(const QString& id) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::ImageRequest* req = message.mutable_image_request();
+-
+- req->set_id(DataCommaSizeFromQString(id));
+- SendMessage(message);
+-}
+-
+-void SpotifyServer::AlbumBrowse(const QString& uri) {
+- spotify_pb::SpotifyMessage message;
+- spotify_pb::BrowseAlbumRequest* req = message.mutable_browse_album_request();
+-
+- req->set_uri(DataCommaSizeFromQString(uri));
+- SendMessage(message);
+-}
+diff -rauN clementine-1.0.1/src/internet/spotifyserver.h /dev/null
+--- clementine-1.0.1/src/internet/spotifyserver.h 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,91 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#ifndef SPOTIFYSERVER_H
+-#define SPOTIFYSERVER_H
+-
+-#include "spotifyblob/common/spotifymessages.pb.h"
+-
+-#include
+-#include
+-
+-class SpotifyMessageHandler;
+-
+-class QTcpServer;
+-class QTcpSocket;
+-
+-class SpotifyServer : public QObject {
+- Q_OBJECT
+-
+-public:
+- SpotifyServer(QObject* parent = 0);
+-
+- void Init();
+- void Login(const QString& username, const QString& password,
+- spotify_pb::Bitrate bitrate, bool volume_normalisation);
+-
+- void LoadStarred();
+- void SyncStarred();
+- void LoadInbox();
+- void SyncInbox();
+- void LoadUserPlaylist(int index);
+- void SyncUserPlaylist(int index);
+- void StartPlaybackLater(const QString& uri, quint16 port);
+- void Search(const QString& text, int limit, int limit_album = 0);
+- void LoadImage(const QString& id);
+- void AlbumBrowse(const QString& uri);
+- void SetPlaybackSettings(spotify_pb::Bitrate bitrate, bool volume_normalisation);
+-
+- int server_port() const;
+-
+-public slots:
+- void StartPlayback(const QString& uri, quint16 port);
+- void Seek(qint64 offset_bytes);
+-
+-signals:
+- void LoginCompleted(bool success, const QString& error,
+- spotify_pb::LoginResponse_Error error_code);
+- void PlaylistsUpdated(const spotify_pb::Playlists& playlists);
+-
+- void StarredLoaded(const spotify_pb::LoadPlaylistResponse& response);
+- void InboxLoaded(const spotify_pb::LoadPlaylistResponse& response);
+- void UserPlaylistLoaded(const spotify_pb::LoadPlaylistResponse& response);
+- void PlaybackError(const QString& message);
+- void SearchResults(const spotify_pb::SearchResponse& response);
+- void ImageLoaded(const QString& id, const QImage& image);
+- void SyncPlaylistProgress(const spotify_pb::SyncPlaylistProgress& progress);
+- void AlbumBrowseResults(const spotify_pb::BrowseAlbumResponse& response);
+-
+-private slots:
+- void NewConnection();
+- void HandleMessage(const spotify_pb::SpotifyMessage& message);
+-
+-private:
+- void LoadPlaylist(spotify_pb::PlaylistType type, int index = -1);
+- void SyncPlaylist(spotify_pb::PlaylistType type, int index, bool offline);
+- void SendMessage(const spotify_pb::SpotifyMessage& message);
+-
+- QTcpServer* server_;
+- QTcpSocket* protocol_socket_;
+- SpotifyMessageHandler* handler_;
+- bool logged_in_;
+-
+- QList queued_login_messages_;
+- QList queued_messages_;
+-};
+-
+-#endif // SPOTIFYSERVER_H
+diff -rauN clementine-1.0.1/src/internet/spotifyservice.cpp /dev/null
+--- clementine-1.0.1/src/internet/spotifyservice.cpp 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,669 +0,0 @@
+-#include "config.h"
+-#include "internetmodel.h"
+-#include "spotifyblobdownloader.h"
+-#include "spotifyserver.h"
+-#include "spotifyservice.h"
+-#include "spotifysearchplaylisttype.h"
+-#include "core/database.h"
+-#include "core/logging.h"
+-#include "core/player.h"
+-#include "core/taskmanager.h"
+-#include "core/timeconstants.h"
+-#include "core/utilities.h"
+-#include "globalsearch/globalsearch.h"
+-#include "globalsearch/spotifysearchprovider.h"
+-#include "playlist/playlist.h"
+-#include "playlist/playlistcontainer.h"
+-#include "playlist/playlistmanager.h"
+-#include "spotifyblob/common/blobversion.h"
+-#include "spotifyblob/common/spotifymessagehandler.h"
+-#include "widgets/didyoumean.h"
+-#include "ui/iconloader.h"
+-
+-#include
+-#include
+-#include
+-#include
+-#include
+-#include
+-#include
+-#include
+-
+-Q_DECLARE_METATYPE(QStandardItem*);
+-
+-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(InternetModel* parent)
+- : InternetService(kServiceName, parent, parent),
+- server_(NULL),
+- blob_process_(NULL),
+- root_(NULL),
+- search_(NULL),
+- starred_(NULL),
+- inbox_(NULL),
+- login_task_id_(0),
+- pending_search_playlist_(NULL),
+- context_menu_(NULL),
+- search_delay_(new QTimer(this)),
+- login_state_(LoginState_OtherError),
+- bitrate_(spotify_pb::Bitrate320k),
+- volume_normalisation_(false)
+-{
+- // 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.
+-#ifdef Q_OS_MAC
+- system_blob_path_ = QCoreApplication::applicationDirPath() +
+- "/../PlugIns/clementine-spotifyblob";
+-#else
+- system_blob_path_ = QCoreApplication::applicationDirPath() +
+- "/clementine-spotifyblob" CMAKE_EXECUTABLE_SUFFIX;
+-#endif
+-
+- 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 system blob path:" << system_blob_path_;
+- qLog(Debug) << "Spotify local blob path:" << local_blob_path_;
+-
+- model()->player()->playlists()->RegisterSpecialPlaylistType(
+- new SpotifySearchPlaylistType(this));
+-
+- model()->global_search()->AddProvider(new SpotifySearchProvider(this));
+-
+- search_delay_->setInterval(kSearchDelayMsec);
+- search_delay_->setSingleShot(true);
+- connect(search_delay_, SIGNAL(timeout()), SLOT(DoSearch()));
+-}
+-
+-SpotifyService::~SpotifyService() {
+- if (blob_process_ && blob_process_->state() == QProcess::Running) {
+- qLog(Info) << "Terminating blob process...";
+- blob_process_->terminate();
+- blob_process_->waitForFinished(1000);
+- }
+-}
+-
+-QStandardItem* SpotifyService::CreateRootItem() {
+- root_ = new QStandardItem(QIcon(":icons/22x22/spotify.png"), kServiceName);
+- root_->setData(true, InternetModel::Role_CanLazyLoad);
+- return root_;
+-}
+-
+-void SpotifyService::LazyPopulate(QStandardItem* item) {
+- switch (item->data(InternetModel::Role_Type).toInt()) {
+- case InternetModel::Type_Service:
+- EnsureServerCreated();
+- break;
+-
+- case Type_SearchResults:
+- break;
+-
+- case Type_InboxPlaylist:
+- EnsureServerCreated();
+- server_->LoadInbox();
+- break;
+-
+- case Type_StarredPlaylist:
+- EnsureServerCreated();
+- server_->LoadStarred();
+- break;
+-
+- case InternetModel::Type_UserPlaylist:
+- EnsureServerCreated();
+- server_->LoadUserPlaylist(item->data(Role_UserPlaylistIndex).toInt());
+- break;
+-
+- default:
+- break;
+- }
+-
+- return;
+-}
+-
+-QModelIndex SpotifyService::GetCurrentIndex() {
+- return QModelIndex();
+-}
+-
+-void SpotifyService::Login(const QString& username, const QString& password) {
+- Logout();
+- EnsureServerCreated(username, password);
+-}
+-
+-void SpotifyService::LoginCompleted(bool success, const QString& error,
+- spotify_pb::LoginResponse_Error error_code) {
+- if (login_task_id_) {
+- model()->task_manager()->SetTaskFinished(login_task_id_);
+- login_task_id_ = 0;
+- }
+-
+- if (!success) {
+- bool show_error_dialog = true;
+- QString error_copy(error);
+-
+- switch (error_code) {
+- case spotify_pb::LoginResponse_Error_BadUsernameOrPassword:
+- login_state_ = LoginState_BadCredentials;
+- break;
+-
+- case spotify_pb::LoginResponse_Error_UserBanned:
+- login_state_ = LoginState_Banned;
+- break;
+-
+- case spotify_pb::LoginResponse_Error_UserNeedsPremium:
+- login_state_ = LoginState_NoPremium;
+- break;
+-
+- case spotify_pb::LoginResponse_Error_ReloginFailed:
+- if (login_state_ == LoginState_LoggedIn) {
+- // This is the first time the relogin has failed - show a message this
+- // time only.
+- error_copy = tr("You have been logged out of Spotify, please re-enter your password in the Settings dialog.");
+- } else {
+- show_error_dialog = false;
+- }
+-
+- login_state_ = LoginState_ReloginFailed;
+- break;
+-
+- default:
+- login_state_ = LoginState_OtherError;
+- break;
+- }
+-
+- if (show_error_dialog) {
+- QMessageBox::warning(NULL, tr("Spotify login error"), error_copy, QMessageBox::Close);
+- }
+- } else {
+- login_state_ = LoginState_LoggedIn;
+- }
+-
+- QSettings s;
+- s.beginGroup(kSettingsGroup);
+- s.setValue("login_state", login_state_);
+-
+- emit LoginFinished(success);
+-}
+-
+-void SpotifyService::BlobProcessError(QProcess::ProcessError error) {
+- qLog(Error) << "Spotify blob process failed:" << error;
+- blob_process_->deleteLater();
+- blob_process_ = NULL;
+-
+- if (login_task_id_) {
+- model()->task_manager()->SetTaskFinished(login_task_id_);
+- }
+-}
+-
+-void SpotifyService::ReloadSettings() {
+- QSettings s;
+- s.beginGroup(kSettingsGroup);
+-
+- login_state_ = LoginState(s.value("login_state", LoginState_OtherError).toInt());
+- bitrate_ = static_cast(
+- s.value("bitrate", spotify_pb::Bitrate320k).toInt());
+- volume_normalisation_ = s.value("volume_normalisation", false).toBool();
+-
+- if (server_ && blob_process_) {
+- server_->SetPlaybackSettings(bitrate_, volume_normalisation_);
+- }
+-}
+-
+-void SpotifyService::EnsureServerCreated(const QString& username,
+- const QString& password) {
+- if (server_ && blob_process_) {
+- return;
+- }
+-
+- delete server_;
+- server_ = new SpotifyServer(this);
+-
+- connect(server_, SIGNAL(LoginCompleted(bool,QString,spotify_pb::LoginResponse_Error)),
+- SLOT(LoginCompleted(bool,QString,spotify_pb::LoginResponse_Error)));
+- connect(server_, SIGNAL(PlaylistsUpdated(spotify_pb::Playlists)),
+- SLOT(PlaylistsUpdated(spotify_pb::Playlists)));
+- connect(server_, SIGNAL(InboxLoaded(spotify_pb::LoadPlaylistResponse)),
+- SLOT(InboxLoaded(spotify_pb::LoadPlaylistResponse)));
+- connect(server_, SIGNAL(StarredLoaded(spotify_pb::LoadPlaylistResponse)),
+- SLOT(StarredLoaded(spotify_pb::LoadPlaylistResponse)));
+- connect(server_, SIGNAL(UserPlaylistLoaded(spotify_pb::LoadPlaylistResponse)),
+- SLOT(UserPlaylistLoaded(spotify_pb::LoadPlaylistResponse)));
+- connect(server_, SIGNAL(PlaybackError(QString)),
+- SIGNAL(StreamError(QString)));
+- connect(server_, SIGNAL(SearchResults(spotify_pb::SearchResponse)),
+- SLOT(SearchResults(spotify_pb::SearchResponse)));
+- connect(server_, SIGNAL(ImageLoaded(QString,QImage)),
+- SIGNAL(ImageLoaded(QString,QImage)));
+- connect(server_, SIGNAL(SyncPlaylistProgress(spotify_pb::SyncPlaylistProgress)),
+- SLOT(SyncPlaylistProgress(spotify_pb::SyncPlaylistProgress)));
+-
+- server_->Init();
+-
+- login_task_id_ = model()->task_manager()->StartTask(tr("Connecting to Spotify"));
+-
+- QString login_username = username;
+- QString login_password = password;
+-
+- if (username.isEmpty()) {
+- QSettings s;
+- s.beginGroup(kSettingsGroup);
+-
+- login_username = s.value("username").toString();
+- login_password = QString();
+- }
+-
+- server_->Login(login_username, login_password, bitrate_, volume_normalisation_);
+-
+- 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
+- if (QFile::exists(system_blob_path_)) {
+- blob_path = system_blob_path_;
+- }
+-
+- // Next look in the local path
+- if (blob_path.isEmpty()) {
+- if (QFile::exists(local_blob_path_)) {
+- blob_path = local_blob_path_;
+- env.insert("LD_LIBRARY_PATH", QFileInfo(local_blob_path_).path());
+- }
+- }
+-
+- 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
+- if (SpotifyBlobDownloader::Prompt()) {
+- InstallBlob();
+- }
+- #endif
+-
+- return;
+- }
+-
+- delete blob_process_;
+- blob_process_ = new QProcess(this);
+- blob_process_->setProcessChannelMode(QProcess::ForwardedChannels);
+- blob_process_->setProcessEnvironment(env);
+-
+- 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()));
+-}
+-
+-bool SpotifyService::IsBlobInstalled() const {
+- return QFile::exists(system_blob_path_) ||
+- QFile::exists(local_blob_path_);
+-}
+-
+-void SpotifyService::InstallBlob() {
+- // The downloader deletes itself when it finishes
+- SpotifyBlobDownloader* downloader = new SpotifyBlobDownloader(
+- local_blob_version_, QFileInfo(local_blob_path_).path(), this);
+- connect(downloader, SIGNAL(Finished()), SLOT(BlobDownloadFinished()));
+- connect(downloader, SIGNAL(Finished()), SIGNAL(BlobStateChanged()));
+- downloader->Start();
+-}
+-
+-void SpotifyService::BlobDownloadFinished() {
+- EnsureServerCreated();
+-}
+-
+-void SpotifyService::PlaylistsUpdated(const spotify_pb::Playlists& response) {
+- if (login_task_id_) {
+- model()->task_manager()->SetTaskFinished(login_task_id_);
+- login_task_id_ = 0;
+- }
+-
+- // Create starred and inbox playlists if they're not here already
+- if (!search_) {
+- search_ = new QStandardItem(IconLoader::Load("edit-find"),
+- tr("Search Spotify (opens a new tab)"));
+- search_->setData(Type_SearchResults, InternetModel::Role_Type);
+- search_->setData(InternetModel::PlayBehaviour_DoubleClickAction,
+- InternetModel::Role_PlayBehaviour);
+-
+- starred_ = new QStandardItem(QIcon(":/star-on.png"), tr("Starred"));
+- starred_->setData(Type_StarredPlaylist, InternetModel::Role_Type);
+- starred_->setData(true, InternetModel::Role_CanLazyLoad);
+-
+- inbox_ = new QStandardItem(IconLoader::Load("mail-message"), tr("Inbox"));
+- inbox_->setData(Type_InboxPlaylist, InternetModel::Role_Type);
+- inbox_->setData(true, InternetModel::Role_CanLazyLoad);
+-
+- root_->appendRow(search_);
+- root_->appendRow(starred_);
+- root_->appendRow(inbox_);
+- }
+-
+- // Don't do anything if the playlists haven't changed since last time.
+- if (!DoPlaylistsDiffer(response)) {
+- qLog(Debug) << "Playlists haven't changed - not updating";
+- return;
+- }
+-
+- // Remove and recreate the other playlists
+- foreach (QStandardItem* item, playlists_) {
+- item->parent()->removeRow(item->row());
+- }
+- playlists_.clear();
+-
+- for (int i=0 ; isetData(InternetModel::Type_UserPlaylist, InternetModel::Role_Type);
+- item->setData(true, InternetModel::Role_CanLazyLoad);
+- item->setData(msg.index(), Role_UserPlaylistIndex);
+- item->setData(InternetModel::PlayBehaviour_SingleItem, InternetModel::Role_PlayBehaviour);
+-
+- root_->appendRow(item);
+- playlists_ << item;
+-
+- // Preload the playlist items so that drag & drop works immediately.
+- LazyPopulate(item);
+- }
+-}
+-
+-bool SpotifyService::DoPlaylistsDiffer(const spotify_pb::Playlists& response) const {
+- if (playlists_.count() != response.playlist_size()) {
+- return true;
+- }
+-
+- for (int i=0 ; itext()) {
+- return true;
+- }
+- }
+-
+- return false;
+-}
+-
+-void SpotifyService::InboxLoaded(const spotify_pb::LoadPlaylistResponse& response) {
+- FillPlaylist(inbox_, response);
+-}
+-
+-void SpotifyService::StarredLoaded(const spotify_pb::LoadPlaylistResponse& response) {
+- FillPlaylist(starred_, response);
+-}
+-
+-QStandardItem* SpotifyService::PlaylistBySpotifyIndex(int index) const {
+- foreach (QStandardItem* item, playlists_) {
+- if (item->data(Role_UserPlaylistIndex).toInt() == index) {
+- return item;
+- }
+- }
+- return NULL;
+-}
+-
+-void SpotifyService::UserPlaylistLoaded(const spotify_pb::LoadPlaylistResponse& response) {
+- // Find a playlist with this index
+- QStandardItem* item = PlaylistBySpotifyIndex(response.request().user_playlist_index());
+- if (item) {
+- FillPlaylist(item, response);
+- }
+-}
+-
+-void SpotifyService::FillPlaylist(QStandardItem* item, const spotify_pb::LoadPlaylistResponse& response) {
+- qLog(Debug) << "Filling playlist:" << item->text();
+- if (item->hasChildren())
+- item->removeRows(0, item->rowCount());
+-
+- for (int i=0 ; isetData(Type_Track, InternetModel::Role_Type);
+- child->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
+- child->setData(InternetModel::PlayBehaviour_SingleItem, InternetModel::Role_PlayBehaviour);
+- child->setData(song.url(), InternetModel::Role_Url);
+-
+- item->appendRow(child);
+- }
+-}
+-
+-void SpotifyService::SongFromProtobuf(const spotify_pb::Track& track, Song* song) {
+- song->set_rating(track.starred() ? 1.0 : 0.0);
+- song->set_title(QStringFromStdString(track.title()));
+- song->set_album(QStringFromStdString(track.album()));
+- song->set_length_nanosec(track.duration_msec() * kNsecPerMsec);
+- song->set_score(track.popularity());
+- song->set_disc(track.disc());
+- song->set_track(track.track());
+- song->set_year(track.year());
+- song->set_url(QUrl(QStringFromStdString(track.uri())));
+- song->set_art_automatic("spotify://image/" + QStringFromStdString(track.album_art_id()));
+-
+- QStringList artists;
+- for (int i=0 ; iset_artist(artists.join(", "));
+-
+- song->set_filetype(Song::Type_Stream);
+- song->set_valid(true);
+- song->set_directory_id(0);
+- song->set_mtime(0);
+- song->set_ctime(0);
+- song->set_filesize(0);
+-}
+-
+-PlaylistItem::Options SpotifyService::playlistitem_options() const {
+- return PlaylistItem::PauseDisabled | PlaylistItem::SeekDisabled;
+-}
+-
+-void SpotifyService::EnsureMenuCreated() {
+- if (context_menu_)
+- return;
+-
+- context_menu_ = new QMenu;
+-
+- context_menu_->addActions(GetPlaylistActions());
+- context_menu_->addSeparator();
+- context_menu_->addAction(IconLoader::Load("edit-find"), tr("Search Spotify (opens a new tab)..."), this, SLOT(OpenSearchTab()));
+- context_menu_->addSeparator();
+- context_menu_->addAction(IconLoader::Load("configure"), tr("Configure Spotify..."), this, SLOT(ShowConfig()));
+-
+- playlist_context_menu_ = new QMenu;
+- playlist_sync_action_ = playlist_context_menu_->addAction(
+- IconLoader::Load("view-refresh"),
+- tr("Make playlist available offline"),
+- this,
+- SLOT(SyncPlaylist()));
+-}
+-
+-void SpotifyService::SyncPlaylist() {
+- QStandardItem* item = playlist_sync_action_->data().value();
+- Q_ASSERT(item);
+-
+- switch (item->data(InternetModel::Role_Type).toInt()) {
+- case InternetModel::Type_UserPlaylist: {
+- int index = item->data(Role_UserPlaylistIndex).toInt();
+- server_->SyncUserPlaylist(index);
+- playlist_sync_ids_[index] =
+- model()->task_manager()->StartTask(tr("Syncing Spotify playlist"));
+- break;
+- }
+- case Type_InboxPlaylist:
+- server_->SyncInbox();
+- inbox_sync_id_ = model()->task_manager()->StartTask(tr("Syncing Spotify inbox"));
+- break;
+- case Type_StarredPlaylist:
+- server_->SyncStarred();
+- starred_sync_id_ = model()->task_manager()->StartTask(tr("Syncing Spotify starred tracks"));
+- break;
+- default:
+- break;
+- }
+-}
+-
+-void SpotifyService::Search(const QString& text, Playlist* playlist, bool now) {
+- EnsureServerCreated();
+-
+- pending_search_ = text;
+- pending_search_playlist_ = playlist;
+-
+- if (now) {
+- search_delay_->stop();
+- DoSearch();
+- } else {
+- search_delay_->start();
+- }
+-}
+-
+-void SpotifyService::DoSearch() {
+- if (!pending_search_.isEmpty()) {
+- server_->Search(pending_search_, 200);
+- }
+-}
+-
+-void SpotifyService::SearchResults(const spotify_pb::SearchResponse& response) {
+- if (QStringFromStdString(response.request().query()) != pending_search_) {
+- qLog(Debug) << "Old search result for"
+- << QStringFromStdString(response.request().query())
+- << "expecting" << pending_search_;
+- return;
+- }
+- pending_search_.clear();
+-
+- SongList songs;
+- for (int i=0 ; iClear();
+- pending_search_playlist_->InsertSongs(songs);
+-
+- const QString did_you_mean = QStringFromStdString(response.did_you_mean());
+- if (!did_you_mean.isEmpty()) {
+- model()->player()->playlists()->playlist_container()->did_you_mean()->Show(did_you_mean);
+- }
+-}
+-
+-SpotifyServer* SpotifyService::server() const {
+- SpotifyService* nonconst_this = const_cast(this);
+-
+- if (QThread::currentThread() != thread()) {
+- metaObject()->invokeMethod(nonconst_this, "EnsureServerCreated",
+- Qt::BlockingQueuedConnection);
+- } else {
+- nonconst_this->EnsureServerCreated();
+- }
+-
+- return server_;
+-}
+-
+-void SpotifyService::ShowContextMenu(const QModelIndex& index, const QPoint& global_pos) {
+- EnsureMenuCreated();
+- QStandardItem* item = model()->itemFromIndex(index);
+- if (item) {
+- int type = item->data(InternetModel::Role_Type).toInt();
+- if (type == Type_InboxPlaylist ||
+- type == Type_StarredPlaylist ||
+- type == InternetModel::Type_UserPlaylist) {
+- playlist_sync_action_->setData(qVariantFromValue(item));
+- playlist_context_menu_->popup(global_pos);
+- return;
+- }
+- }
+-
+- context_menu_->popup(global_pos);
+-}
+-
+-void SpotifyService::OpenSearchTab() {
+- model()->player()->playlists()->New(tr("Search Spotify"), SongList(),
+- SpotifySearchPlaylistType::kName);
+-}
+-
+-void SpotifyService::ItemDoubleClicked(QStandardItem* item) {
+- if (item == search_) {
+- OpenSearchTab();
+- }
+-}
+-
+-void SpotifyService::LoadImage(const QString& id) {
+- EnsureServerCreated();
+- server_->LoadImage(id);
+-}
+-
+-void SpotifyService::SyncPlaylistProgress(
+- const spotify_pb::SyncPlaylistProgress& progress) {
+- qLog(Debug) << "Sync progress:" << progress.sync_progress();
+- int task_id = -1;
+- switch (progress.request().type()) {
+- case spotify_pb::Inbox:
+- task_id = inbox_sync_id_;
+- break;
+- case spotify_pb::Starred:
+- task_id = starred_sync_id_;
+- break;
+- case spotify_pb::UserPlaylist: {
+- QMap::const_iterator it = playlist_sync_ids_.constFind(
+- progress.request().user_playlist_index());
+- if (it != playlist_sync_ids_.constEnd()) {
+- task_id = it.value();
+- }
+- break;
+- }
+- default:
+- break;
+- }
+- if (task_id == -1) {
+- qLog(Warning) << "Received sync progress for unknown playlist";
+- return;
+- }
+- model()->task_manager()->SetTaskProgress(task_id, progress.sync_progress(), 100);
+- if (progress.sync_progress() == 100) {
+- model()->task_manager()->SetTaskFinished(task_id);
+- if (progress.request().type() == spotify_pb::UserPlaylist) {
+- playlist_sync_ids_.remove(task_id);
+- }
+- }
+-}
+-
+-void SpotifyService::ShowConfig() {
+- emit OpenSettingsAtPage(SettingsDialog::Page_Spotify);
+-}
+-
+-void SpotifyService::Logout() {
+- delete server_;
+- delete blob_process_;
+- server_ = NULL;
+- blob_process_ = NULL;
+-
+- login_state_ = LoginState_OtherError;
+-
+- QSettings s;
+- s.beginGroup(kSettingsGroup);
+- s.setValue("login_state", login_state_);
+-}
+diff -rauN clementine-1.0.1/src/internet/spotifyservice.h /dev/null
+--- clementine-1.0.1/src/internet/spotifyservice.h 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,147 +0,0 @@
+-#ifndef SPOTIFYSERVICE_H
+-#define SPOTIFYSERVICE_H
+-
+-#include "internetmodel.h"
+-#include "internetservice.h"
+-#include "spotifyblob/common/spotifymessages.pb.h"
+-
+-#include
+-#include
+-
+-#include
+-
+-class Playlist;
+-class SpotifyServer;
+-
+-class QMenu;
+-
+-class SpotifyService : public InternetService {
+- Q_OBJECT
+-
+-public:
+- SpotifyService(InternetModel* parent);
+- ~SpotifyService();
+-
+- enum Type {
+- Type_SearchResults = InternetModel::TypeCount,
+- Type_StarredPlaylist,
+- Type_InboxPlaylist,
+- Type_Track,
+- };
+-
+- enum Role {
+- Role_UserPlaylistIndex = InternetModel::RoleCount,
+- };
+-
+- // Values are persisted - don't change.
+- enum LoginState {
+- LoginState_LoggedIn = 1,
+- LoginState_Banned = 2,
+- LoginState_BadCredentials = 3,
+- LoginState_NoPremium = 4,
+- LoginState_OtherError = 5,
+- LoginState_ReloginFailed = 6
+- };
+-
+- static const char* kServiceName;
+- static const char* kSettingsGroup;
+- static const char* kBlobDownloadUrl;
+- static const int kSearchDelayMsec;
+-
+- void ReloadSettings();
+-
+- QStandardItem* CreateRootItem();
+- void LazyPopulate(QStandardItem* parent);
+- void ShowContextMenu(const QModelIndex& index, const QPoint& global_pos);
+- void ItemDoubleClicked(QStandardItem* item);
+- PlaylistItem::Options playlistitem_options() const;
+-
+- void Logout();
+- void Login(const QString& username, const QString& password);
+- void Search(const QString& text, Playlist* playlist, bool now = false);
+- Q_INVOKABLE void LoadImage(const QString& id);
+-
+- SpotifyServer* server() const;
+-
+- bool IsBlobInstalled() const;
+- void InstallBlob();
+-
+- // Persisted in the settings and updated on each Login().
+- LoginState login_state() const { return login_state_; }
+- bool IsLoggedIn() const { return login_state_ == LoginState_LoggedIn; }
+-
+- static void SongFromProtobuf(const spotify_pb::Track& track, Song* song);
+-
+-signals:
+- void BlobStateChanged();
+- void LoginFinished(bool success);
+- void ImageLoaded(const QString& id, const QImage& image);
+-
+-public slots:
+- void ShowConfig();
+-
+-protected:
+- virtual QModelIndex GetCurrentIndex();
+-
+-private:
+- void StartBlobProcess();
+- void FillPlaylist(QStandardItem* item, const spotify_pb::LoadPlaylistResponse& response);
+- void EnsureMenuCreated();
+-
+- QStandardItem* PlaylistBySpotifyIndex(int index) const;
+- bool DoPlaylistsDiffer(const spotify_pb::Playlists& response) const;
+-
+-private slots:
+- void EnsureServerCreated(const QString& username = QString(),
+- const QString& password = QString());
+- void BlobProcessError(QProcess::ProcessError error);
+- void LoginCompleted(bool success, const QString& error,
+- spotify_pb::LoginResponse_Error error_code);
+- void PlaylistsUpdated(const spotify_pb::Playlists& response);
+- void InboxLoaded(const spotify_pb::LoadPlaylistResponse& response);
+- void StarredLoaded(const spotify_pb::LoadPlaylistResponse& response);
+- void UserPlaylistLoaded(const spotify_pb::LoadPlaylistResponse& response);
+- void SearchResults(const spotify_pb::SearchResponse& response);
+- void SyncPlaylistProgress(const spotify_pb::SyncPlaylistProgress& progress);
+-
+- void OpenSearchTab();
+- void DoSearch();
+-
+- void SyncPlaylist();
+- void BlobDownloadFinished();
+-
+-private:
+- SpotifyServer* server_;
+-
+- QString system_blob_path_;
+- QString local_blob_version_;
+- QString local_blob_path_;
+- QProcess* blob_process_;
+-
+- QStandardItem* root_;
+- QStandardItem* search_;
+- QStandardItem* starred_;
+- QStandardItem* inbox_;
+- QList playlists_;
+-
+- int login_task_id_;
+- QString pending_search_;
+- Playlist* pending_search_playlist_;
+-
+- QMenu* context_menu_;
+- QMenu* playlist_context_menu_;
+- QAction* playlist_sync_action_;
+- QModelIndex context_item_;
+-
+- QTimer* search_delay_;
+-
+- int inbox_sync_id_;
+- int starred_sync_id_;
+- QMap playlist_sync_ids_;
+-
+- LoginState login_state_;
+- spotify_pb::Bitrate bitrate_;
+- bool volume_normalisation_;
+-};
+-
+-#endif
+diff -rauN clementine-1.0.1/src/internet/spotifysettingspage.cpp /dev/null
+--- clementine-1.0.1/src/internet/spotifysettingspage.cpp 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,172 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#include "spotifysettingspage.h"
+-
+-#include "spotifyservice.h"
+-#include "internetmodel.h"
+-#include "ui_spotifysettingspage.h"
+-#include "core/network.h"
+-#include "spotifyblob/common/spotifymessages.pb.h"
+-#include "ui/iconloader.h"
+-
+-#include
+-#include
+-#include
+-#include
+-#include
+-
+-SpotifySettingsPage::SpotifySettingsPage(SettingsDialog* dialog)
+- : SettingsPage(dialog),
+- network_(new NetworkAccessManager(this)),
+- ui_(new Ui_SpotifySettingsPage),
+- service_(InternetModel::Service()),
+- validated_(false)
+-{
+- ui_->setupUi(this);
+-
+- setWindowIcon(QIcon(":/icons/48x48/spotify.png"));
+-
+- QFont bold_font(font());
+- bold_font.setBold(true);
+- ui_->blob_status->setFont(bold_font);
+-
+- connect(ui_->download_blob, SIGNAL(clicked()), SLOT(DownloadBlob()));
+- 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)));
+- connect(service_, SIGNAL(BlobStateChanged()), SLOT(BlobStateChanged()));
+-
+- ui_->login_state->AddCredentialField(ui_->username);
+- ui_->login_state->AddCredentialField(ui_->password);
+- ui_->login_state->AddCredentialGroup(ui_->account_group);
+-
+- ui_->bitrate->addItem("96 " + tr("kbps"), spotify_pb::Bitrate96k);
+- ui_->bitrate->addItem("160 " + tr("kbps"), spotify_pb::Bitrate160k);
+- ui_->bitrate->addItem("320 " + tr("kbps"), spotify_pb::Bitrate320k);
+-
+- BlobStateChanged();
+-}
+-
+-SpotifySettingsPage::~SpotifySettingsPage() {
+- delete ui_;
+-}
+-
+-void SpotifySettingsPage::BlobStateChanged() {
+- const bool installed = service_->IsBlobInstalled();
+-
+- ui_->account_group->setEnabled(installed);
+- ui_->blob_status->setText(installed ? tr("Installed") : tr("Not installed"));
+-
+-#ifdef Q_OS_LINUX
+- ui_->download_blob->setEnabled(!installed);
+-#else
+- ui_->download_blob->setEnabled(false);
+-#endif
+-}
+-
+-void SpotifySettingsPage::DownloadBlob() {
+- service_->InstallBlob();
+-}
+-
+-void SpotifySettingsPage::Login() {
+- if (!service_->IsBlobInstalled()) {
+- return;
+- }
+-
+- if (ui_->username->text() == original_username_ &&
+- ui_->password->text() == original_password_ &&
+- service_->login_state() == SpotifyService::LoginState_LoggedIn) {
+- return;
+- }
+-
+- ui_->login_state->SetLoggedIn(LoginStateWidget::LoginInProgress);
+- service_->Login(ui_->username->text(), ui_->password->text());
+-}
+-
+-void SpotifySettingsPage::Load() {
+- QSettings s;
+- s.beginGroup(SpotifyService::kSettingsGroup);
+-
+- original_username_ = s.value("username").toString();
+-
+- ui_->username->setText(original_username_);
+- validated_ = false;
+-
+- ui_->bitrate->setCurrentIndex(ui_->bitrate->findData(
+- s.value("bitrate", spotify_pb::Bitrate320k).toInt()));
+- ui_->volume_normalisation->setChecked(
+- s.value("volume_normalisation", false).toBool());
+-
+- UpdateLoginState();
+-}
+-
+-void SpotifySettingsPage::Save() {
+- QSettings s;
+- s.beginGroup(SpotifyService::kSettingsGroup);
+-
+- s.setValue("username", ui_->username->text());
+- s.setValue("password", ui_->password->text());
+-
+- s.setValue("bitrate", ui_->bitrate->itemData(ui_->bitrate->currentIndex()).toInt());
+- s.setValue("volume_normalisation", ui_->volume_normalisation->isChecked());
+-}
+-
+-void SpotifySettingsPage::LoginFinished(bool success) {
+- validated_ = success;
+-
+- Save();
+- UpdateLoginState();
+-}
+-
+-void SpotifySettingsPage::UpdateLoginState() {
+- const bool logged_in =
+- service_->login_state() == SpotifyService::LoginState_LoggedIn;
+-
+- ui_->login_state->SetLoggedIn(logged_in ? LoginStateWidget::LoggedIn
+- : LoginStateWidget::LoggedOut,
+- ui_->username->text());
+- ui_->login_state->SetAccountTypeVisible(!logged_in);
+-
+- switch (service_->login_state()) {
+- case SpotifyService::LoginState_NoPremium:
+- ui_->login_state->SetAccountTypeText(tr("You do not have a Spotify Premium account."));
+- break;
+-
+- case SpotifyService::LoginState_Banned:
+- case SpotifyService::LoginState_BadCredentials:
+- ui_->login_state->SetAccountTypeText(tr("Your username or password was incorrect."));
+- break;
+-
+- case SpotifyService::LoginState_ReloginFailed:
+- ui_->login_state->SetAccountTypeText(tr("You have been logged out of Spotify, please re-enter your password."));
+- break;
+-
+- default:
+- ui_->login_state->SetAccountTypeText(tr("A Spotify Premium account is required."));
+- break;
+- }
+-}
+-
+-void SpotifySettingsPage::Logout() {
+- service_->Logout();
+- UpdateLoginState();
+-
+- ui_->username->clear();
+-}
+diff -rauN clementine-1.0.1/src/internet/spotifysettingspage.h /dev/null
+--- clementine-1.0.1/src/internet/spotifysettingspage.h 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,59 +0,0 @@
+-/* This file is part of Clementine.
+- Copyright 2010, David Sansome
+-
+- 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 .
+-*/
+-
+-#ifndef SPOTIFYSETTINGSPAGE_H
+-#define SPOTIFYSETTINGSPAGE_H
+-
+-#include "ui/settingspage.h"
+-
+-class NetworkAccessManager;
+-class Ui_SpotifySettingsPage;
+-class SpotifyService;
+-
+-class SpotifySettingsPage : public SettingsPage {
+- Q_OBJECT
+-
+-public:
+- SpotifySettingsPage(SettingsDialog* dialog);
+- ~SpotifySettingsPage();
+-
+- void Load();
+- void Save();
+-
+-public slots:
+- void BlobStateChanged();
+- void DownloadBlob();
+-
+-private slots:
+- void Login();
+- void LoginFinished(bool success);
+- void Logout();
+-
+-private:
+- void UpdateLoginState();
+-
+-private:
+- NetworkAccessManager* network_;
+- Ui_SpotifySettingsPage* ui_;
+- SpotifyService* service_;
+-
+- bool validated_;
+- QString original_username_;
+- QString original_password_;
+-};
+-
+-#endif // SPOTIFYSETTINGSPAGE_H
+diff -rauN clementine-1.0.1/src/internet/spotifysettingspage.ui /dev/null
+--- clementine-1.0.1/src/internet/spotifysettingspage.ui 2011-12-02 19:24:44.000000000 -0200
++++ /dev/null 2012-05-28 12:50:04.796939473 -0300
+@@ -1,214 +0,0 @@
+-
+-
+- SpotifySettingsPage
+-
+-
+-
+- 0
+- 0
+- 545
+- 458
+-
+-
+-
+- Spotify
+-
+-
+-
+-
+-
+-
+-
+-
+- Account details
+-
+-
+-
+-
+-
+- true
+-
+-
+-
+- 0
+-
+-
+-
+-
+- Username
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Password
+-
+-
+-
+-
+-
+-
+- QLineEdit::Password
+-
+-
+-
+-
+-
+-
+- Login
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Spotify plugin
+-
+-
+-
+-
+-
+- For licensing reasons Spotify support is in a separate plugin.
+-
+-
+-
+-
+-
+-
+-
+-
+- Plugin status:
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Qt::Horizontal
+-
+-
+-
+- 40
+- 20
+-
+-
+-
+-
+-
+-
+-
+- Download...
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Preferences
+-
+-
+-
+-
+-
+- Preferred bitrate
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Use volume normalisation
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Qt::Vertical
+-
+-
+-
+- 20
+- 30
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- Qt::Horizontal
+-
+-
+-
+- 40
+- 20
+-
+-
+-
+-
+-
+-
+-
+-
+- 64
+- 64
+-
+-
+-
+-
+- 64
+- 64
+-
+-
+-
+- :/spotify-core-logo-128x128.png
+-
+-
+- true
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- LoginStateWidget
+- QWidget
+- widgets/loginstatewidget.h
+- 1
+-
+-
+-
+-
+-
+-
+-
+diff -rauN clementine-1.0.1/src/ui/about.cpp clementine-libre-1.0.1/src/ui/about.cpp
+--- clementine-1.0.1/src/ui/about.cpp 2012-01-22 10:43:26.000000000 -0200
++++ clementine-libre-1.0.1/src/ui/about.cpp 2012-05-28 19:44:38.760244927 -0300
+@@ -79,12 +79,6 @@
+ ret += QString(" Scott Smitelli");
+ ret += QString(" Allie Brosh
");
+
+-#ifdef HAVE_SPOTIFY
+- ret += "
This product uses SPOTIFY(R) CORE but is not endorsed, certified "
+- "or otherwise approved in any way by Spotify. Spotify is the "
+- "registered trade mark of the Spotify Group.
";
+-#endif // HAVE_SPOTIFY
+-
+ return ret;
+ }
+
+diff -rauN clementine-1.0.1/src/ui/settingsdialog.cpp clementine-libre-1.0.1/src/ui/settingsdialog.cpp
+--- clementine-1.0.1/src/ui/settingsdialog.cpp 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/ui/settingsdialog.cpp 2012-05-28 19:46:49.506369764 -0300
+@@ -55,10 +55,6 @@
+ # include "remote/remotesettingspage.h"
+ #endif
+
+-#ifdef HAVE_SPOTIFY
+-# include "internet/spotifysettingspage.h"
+-#endif
+-
+ #include
+ #include
+ #include
+@@ -140,10 +136,6 @@
+
+ AddPage(Page_Grooveshark, new GroovesharkSettingsPage(this), providers);
+
+-#ifdef HAVE_SPOTIFY
+- AddPage(Page_Spotify, new SpotifySettingsPage(this), providers);
+-#endif
+-
+ AddPage(Page_Magnatune, new MagnatuneSettingsPage(this), providers);
+ AddPage(Page_DigitallyImported, new DigitallyImportedSettingsPage(this), providers);
+ AddPage(Page_BackgroundStreams, new BackgroundStreamsSettingsPage(this), providers);
+diff -rauN clementine-1.0.1/src/ui/settingsdialog.h clementine-libre-1.0.1/src/ui/settingsdialog.h
+--- clementine-1.0.1/src/ui/settingsdialog.h 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/ui/settingsdialog.h 2012-05-28 19:48:55.399426104 -0300
+@@ -65,7 +65,6 @@
+ Page_Library,
+ Page_Lastfm,
+ Page_Grooveshark,
+- Page_Spotify,
+ Page_Magnatune,
+ Page_DigitallyImported,
+ Page_BackgroundStreams,
+--- clementine-1.0.1/src/core/logging.cpp 2011-12-02 19:24:43.000000000 -0200
++++ clementine-libre-1.0.1/src/core/logging.cpp 2012-05-30 03:09:25.554790760 -0300
+@@ -14,10 +14,6 @@
+ limitations under the License.
+ */
+
+-// Note: this file is licensed under the Apache License instead of GPL because
+-// it is used by the Spotify blob which links against libspotify and is not GPL
+-// compatible.
+-
+
+ #include
+ #include
+--- clementine-1.0.1/src/core/logging.h 2011-12-02 19:24:43.000000000 -0200
++++ clementine-libre-1.0.1/src/core/logging.h 2012-05-30 03:09:44.390404481 -0300
+@@ -14,10 +14,6 @@
+ limitations under the License.
+ */
+
+-// Note: this file is licensed under the Apache License instead of GPL because
+-// it is used by the Spotify blob which links against libspotify and is not GPL
+-// compatible.
+-
+
+ #ifndef LOGGING_H
+ #define LOGGING_H
+--- clementine-1.0.1/src/core/timeconstants.h 2011-12-02 19:24:44.000000000 -0200
++++ clementine-libre-1.0.1/src/core/timeconstants.h 2012-05-30 03:10:10.338953893 -0300
+@@ -14,10 +14,6 @@
+ limitations under the License.
+ */
+
+-// Note: this file is licensed under the Apache License instead of GPL because
+-// it is used by the Spotify blob which links against libspotify and is not GPL
+-// compatible.
+-
+ #ifndef TIMECONSTANTS_H
+ #define TIMECONSTANTS_H
+
--
cgit v1.2.3-54-g00ecf