diff --git a/clementine-liblastfm1-compatibility.patch b/clementine-liblastfm1-compatibility.patch new file mode 100644 index 0000000..bbfd45e --- /dev/null +++ b/clementine-liblastfm1-compatibility.patch @@ -0,0 +1,485 @@ +diff -rupN clementine-1.0.1.old/src/core/song.cpp clementine-1.0.1/src/core/song.cpp +--- clementine-1.0.1.old/src/core/song.cpp 2012-01-22 07:43:26.000000000 -0500 ++++ clementine-1.0.1/src/core/song.cpp 2012-07-03 22:12:08.548375178 -0400 +@@ -49,7 +49,7 @@ + + #ifdef HAVE_LIBLASTFM + #include "internet/fixlastfm.h" +- #include ++ #include + #endif + + #include +diff -rupN clementine-1.0.1.old/src/covers/lastfmcoverprovider.cpp clementine-1.0.1/src/covers/lastfmcoverprovider.cpp +--- clementine-1.0.1.old/src/covers/lastfmcoverprovider.cpp 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/src/covers/lastfmcoverprovider.cpp 2012-07-03 22:12:08.549375174 -0400 +@@ -19,8 +19,8 @@ + #include "coverprovider.h" + #include "lastfmcoverprovider.h" + +-#include +-#include ++#include ++#include + #include + + #include +@@ -52,14 +52,8 @@ void LastFmCoverProvider::QueryFinished( + + CoverSearchResults results; + +- try { +- lastfm::XmlQuery query(lastfm::ws::parse(reply)); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) { +- throw std::runtime_error(""); +- } +-#endif +- ++ lastfm::XmlQuery query; ++ if (query.parse(reply->readAll())) { + // parse the list of search results + QList elements = query["results"]["albummatches"].children("album"); + +@@ -69,7 +63,7 @@ void LastFmCoverProvider::QueryFinished( + result.image_url = element["image size=extralarge"].text(); + results << result; + } +- } catch(std::runtime_error&) { ++ } else { + // Drop through and emit an empty list of results. + } + +diff -rupN clementine-1.0.1.old/src/internet/lastfmservice.cpp clementine-1.0.1/src/internet/lastfmservice.cpp +--- clementine-1.0.1.old/src/internet/lastfmservice.cpp 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/src/internet/lastfmservice.cpp 2012-07-03 22:12:08.556375146 -0400 +@@ -33,20 +33,18 @@ + + #include + +-#include ++#include + #include +-#include +-#include +-#include +-#include ++#include ++#include ++#include + #include +-#include ++#include + + #include + #include + + using boost::scoped_ptr; +-using lastfm::Scrobble; + using lastfm::XmlQuery; + + uint qHash(const lastfm::Track& track) { +@@ -300,13 +298,8 @@ void LastFMService::AuthenticateReplyFin + reply->deleteLater(); + + // Parse the reply +- try { +- lastfm::XmlQuery const lfm = lastfm::ws::parse(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- ++ lastfm::XmlQuery lfm; ++ if (lfm.parse(reply->readAll())) { + lastfm::ws::Username = lfm["session"]["name"].text(); + lastfm::ws::SessionKey = lfm["session"]["key"].text(); + QString subscribed = lfm["session"]["subscriber"].text(); +@@ -318,8 +311,8 @@ void LastFMService::AuthenticateReplyFin + settings.setValue("Username", lastfm::ws::Username); + settings.setValue("Session", lastfm::ws::SessionKey); + settings.setValue("Subscriber", is_subscriber); +- } catch (std::runtime_error& e) { +- qLog(Error) << e.what(); ++ } else { ++ qLog(Error) << lfm.parseError().message(); + emit AuthenticationComplete(false); + return; + } +@@ -347,13 +340,8 @@ void LastFMService::UpdateSubscriberStat + + bool is_subscriber = false; + +- try { +- const lastfm::XmlQuery lfm = lastfm::ws::parse(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- ++ lastfm::XmlQuery lfm; ++ if (lfm.parse(reply->readAll())) { + connection_problems_ = false; + QString subscriber = lfm["user"]["subscriber"].text(); + is_subscriber = (subscriber.toInt() == 1); +@@ -362,11 +350,9 @@ void LastFMService::UpdateSubscriberStat + settings.beginGroup(kSettingsGroup); + settings.setValue("Subscriber", is_subscriber); + qLog(Info) << lastfm::ws::Username << "Subscriber status:" << is_subscriber; +- } catch (lastfm::ws::ParseError e) { +- qLog(Error) << "Last.fm parse error: " << e.enumValue(); +- connection_problems_ = e.enumValue() == lastfm::ws::MalformedResponse; +- } catch (std::runtime_error& e) { +- qLog(Error) << e.what(); ++ } else { ++ qLog(Error) << "Last.fm parse error: " << lfm.parseError().message(); ++ connection_problems_ = lfm.parseError().enumValue() == lastfm::ws::MalformedResponse; + } + + emit UpdatedSubscriberStatus(is_subscriber); +@@ -469,7 +455,8 @@ bool LastFMService::InitScrobbler() { + scrobbler_ = new lastfm::Audioscrobbler(kAudioscrobblerClientId); + + //reemit the signal since the sender is private +- connect(scrobbler_, SIGNAL(status(int)), SIGNAL(ScrobblerStatus(int))); ++ connect(scrobbler_, SIGNAL(scrobblesSubmitted(QList)), SIGNAL(ScrobbleSubmitted())); ++ connect(scrobbler_, SIGNAL(nowPlayingError(int,QString)), SIGNAL(ScrobbleError(int))); + return true; + } + +@@ -497,7 +484,7 @@ void LastFMService::NowPlaying(const Son + if (!last_track_.isNull() && + last_track_.source() == lastfm::Track::NonPersonalisedBroadcast) { + const int duration_secs = last_track_.timestamp().secsTo(QDateTime::currentDateTime()); +- if (duration_secs >= ScrobblePoint::kScrobbleMinLength) { ++ if (duration_secs >= lastfm::ScrobblePoint::scrobbleTimeMin()) { + lastfm::MutableTrack mtrack(last_track_); + mtrack.setDuration(duration_secs); + +@@ -514,14 +501,16 @@ void LastFMService::NowPlaying(const Son + already_scrobbled_ = false; + last_track_ = mtrack; + +- //check immediately if the song is valid +- Scrobble::Invalidity invalidity; +- +- if (!lastfm::Scrobble(last_track_).isValid( &invalidity )) { +- //for now just notify this, we can also see the cause +- emit ScrobblerStatus(-1); +- return; +- } ++// TODO: validity was removed from liblastfm1 but might reappear, it should have ++// no impact as we get a different error when actually trying to scrobble. ++// //check immediately if the song is valid ++// Scrobble::Invalidity invalidity; ++// ++// if (!lastfm::Scrobble(last_track_).isValid( &invalidity )) { ++// //for now just notify this, we can also see the cause ++// emit ScrobbleError(-1); ++// return; ++// } + + scrobbler_->nowPlaying(mtrack); + } +@@ -530,12 +519,12 @@ void LastFMService::Scrobble() { + if (!InitScrobbler()) + return; + +- ScrobbleCache cache(lastfm::ws::Username); ++ lastfm::ScrobbleCache cache(lastfm::ws::Username); + qLog(Debug) << "There are" << cache.tracks().count() << "tracks in the last.fm cache."; + scrobbler_->cache(last_track_); + + // Let's mark a track as cached, useful when the connection is down +- emit ScrobblerStatus(30); ++ emit ScrobbleError(30); + scrobbler_->submit(); + + already_scrobbled_ = true; +@@ -640,7 +629,7 @@ void LastFMService::RefreshFriends(bool + return; + } + +- lastfm::AuthenticatedUser user; ++ lastfm::User user; + QNetworkReply* reply = user.getFriends(); + connect(reply, SIGNAL(finished()), SLOT(RefreshFriendsFinished())); + } +@@ -649,7 +638,7 @@ void LastFMService::RefreshNeighbours() + if (!neighbours_list_ || !IsAuthenticated()) + return; + +- lastfm::AuthenticatedUser user; ++ lastfm::User user; + QNetworkReply* reply = user.getNeighbours(); + connect(reply, SIGNAL(finished()), SLOT(RefreshNeighboursFinished())); + } +@@ -661,14 +650,11 @@ void LastFMService::RefreshFriendsFinish + + QList friends; + +- try { +- friends = lastfm::User::list(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- } catch (std::runtime_error& e) { +- qLog(Error) << e.what(); ++ lastfm::XmlQuery lfm; ++ if (lfm.parse(reply->readAll())) { ++ friends = lastfm::UserList(lfm).users(); ++ } else { ++ qLog(Error) << lfm.parseError().message(); + return; + } + +@@ -708,14 +694,11 @@ void LastFMService::RefreshNeighboursFin + + QList neighbours; + +- try { +- neighbours = lastfm::User::list(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- } catch (std::runtime_error& e) { +- qLog(Error) << e.what(); ++ lastfm::XmlQuery lfm; ++ if (lfm.parse(reply->readAll())) { ++ neighbours = lastfm::UserList(lfm).users(); ++ } else { ++ qLog(Error) << lfm.parseError().message(); + return; + } + +@@ -869,13 +852,8 @@ void LastFMService::FetchMoreTracksFinis + model()->task_manager()->SetTaskFinished(tune_task_id_); + tune_task_id_ = 0; + +- try { +- const XmlQuery& query = lastfm::ws::parse(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- ++ XmlQuery query; ++ if (query.parse(reply->readAll())) { + const XmlQuery& playlist = query["playlist"]; + foreach (const XmlQuery& q, playlist["trackList"].children("track")) { + lastfm::MutableTrack t; +@@ -890,17 +868,9 @@ void LastFMService::FetchMoreTracksFinis + art_urls_[t] = q["image"].text(); + playlist_ << t; + } +- } catch (std::runtime_error& e) { +- // For some reason a catch block that takes a lastfm::ws::ParseError& +- // doesn't get called, even when a lastfm::ws::ParseError is thrown... +- // Hacks like this remind me of Java... +- if (QString(typeid(e).name()).contains("ParseError")) { +- // dynamic_cast throws a std::bad_cast ... *boggle* ++ } else { + emit StreamError(tr("Couldn't load the last.fm radio station") +- .arg(e.what())); +- } else { +- emit StreamError(tr("An unknown last.fm error occurred: %1").arg(e.what())); +- } ++ .arg(query.parseError().message())); + return; + } + +@@ -913,7 +883,7 @@ void LastFMService::Tune(const QUrl& url + + last_url_ = url; + initial_tune_ = true; +- const lastfm::RadioStation station(FixupUrl(url)); ++ const lastfm::RadioStation station(FixupUrl(url).toString()); + + playlist_.clear(); + +diff -rupN clementine-1.0.1.old/src/internet/lastfmservice.h clementine-1.0.1/src/internet/lastfmservice.h +--- clementine-1.0.1.old/src/internet/lastfmservice.h 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/src/internet/lastfmservice.h 2012-07-03 22:15:35.723550539 -0400 +@@ -27,7 +27,8 @@ class Track; + uint qHash(const lastfm::Track& track); + + #include "fixlastfm.h" +-#include ++#include ++#include + #include + + #include "internetmodel.h" +@@ -132,7 +133,8 @@ class LastFMService : public InternetSer + void ScrobblingEnabledChanged(bool value); + void ButtonVisibilityChanged(bool value); + void ScrobbleButtonVisibilityChanged(bool value); +- void ScrobblerStatus(int value); ++ void ScrobbleSubmitted(); ++ void ScrobbleError(int value); + void UpdatedSubscriberStatus(bool is_subscriber); + void ScrobbledRadioStream(); + +diff -rupN clementine-1.0.1.old/src/songinfo/lastfmtrackinfoprovider.cpp clementine-1.0.1/src/songinfo/lastfmtrackinfoprovider.cpp +--- clementine-1.0.1.old/src/songinfo/lastfmtrackinfoprovider.cpp 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/src/songinfo/lastfmtrackinfoprovider.cpp 2012-07-03 22:12:08.558375138 -0400 +@@ -22,7 +22,7 @@ + #include "ui/iconloader.h" + + #include +-#include ++#include + + void LastfmTrackInfoProvider::FetchInfo(int id, const Song& metadata) { + QMap params; +@@ -50,18 +50,12 @@ void LastfmTrackInfoProvider::RequestFin + return; + } + +- try { +- lastfm::XmlQuery query = lastfm::ws::parse(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- ++ lastfm::XmlQuery query; ++ if (query.parse(reply->readAll())) { + GetPlayCounts(id, query); + GetWiki(id, query); + GetTags(id, query); + +- } catch (std::runtime_error&) { + } + emit Finished(id); + } +diff -rupN clementine-1.0.1.old/src/suggesters/lastfmsuggester.cpp clementine-1.0.1/src/suggesters/lastfmsuggester.cpp +--- clementine-1.0.1.old/src/suggesters/lastfmsuggester.cpp 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/src/suggesters/lastfmsuggester.cpp 2012-07-03 22:12:08.576375068 -0400 +@@ -1,6 +1,6 @@ + #include "lastfmsuggester.h" + +-#include ++#include + + #include "core/logging.h" + #include "core/timeconstants.h" +@@ -39,13 +39,8 @@ void LastFMSuggester::RequestFinished() + int id = it.value(); + replies_.erase(it); + +- try { +- lastfm::XmlQuery const lfm = lastfm::ws::parse(reply); +-#ifdef Q_OS_WIN32 +- if (lastfm::ws::last_parse_error != lastfm::ws::NoError) +- throw std::runtime_error(""); +-#endif +- ++ lastfm::XmlQuery lfm; ++ if (lfm.parse(reply->readAll())) { + const QList tracks = lfm["similartracks"].children("track"); + SongList songs; + foreach (const XmlQuery& q, tracks) { +@@ -59,8 +54,8 @@ void LastFMSuggester::RequestFinished() + } + qLog(Debug) << songs.length() << "suggested songs from Last.fm"; + emit SuggestSongsFinished(id, songs); +- } catch (std::runtime_error& e) { +- qLog(Error) << e.what(); ++ } else { ++ qLog(Error) << lfm.parseError().message(); + emit SuggestSongsFinished(id, SongList()); + } + } +diff -rupN clementine-1.0.1.old/src/ui/mainwindow.cpp clementine-1.0.1/src/ui/mainwindow.cpp +--- clementine-1.0.1.old/src/ui/mainwindow.cpp 2012-01-22 07:43:26.000000000 -0500 ++++ clementine-1.0.1/src/ui/mainwindow.cpp 2012-07-03 22:36:24.578550926 -0400 +@@ -700,7 +700,8 @@ MainWindow::MainWindow( + connect(player_->playlists()->sequence(), SIGNAL(ShuffleModeChanged(PlaylistSequence::ShuffleMode)), osd_, SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode))); + + #ifdef HAVE_LIBLASTFM +- connect(InternetModel::Service(), SIGNAL(ScrobblerStatus(int)), SLOT(ScrobblerStatus(int))); ++ connect(InternetModel::Service(), SIGNAL(ScrobbleSubmitted()), SLOT(ScrobbleSubmitted())); ++ connect(InternetModel::Service(), SIGNAL(ScrobbleError(int)), SLOT(ScrobbleError(int))); + + LastFMButtonVisibilityChanged(internet_model_->InternetModel::Service()->AreButtonsVisible()); + ScrobbleButtonVisibilityChanged(internet_model_->InternetModel::Service()->IsScrobbleButtonVisible()); +@@ -2201,30 +2202,26 @@ void MainWindow::SetToggleScrobblingIcon + } + + #ifdef HAVE_LIBLASTFM +-void MainWindow::ScrobblerStatus(int value) { ++void MainWindow::ScrobbleSubmitted() { + const LastFMService* lastfm_service = InternetModel::Service(); + const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() && + lastfm_service->IsScrobblingEnabled() && + lastfm_service->IsAuthenticated(); + ++ playlists_->active()->set_lastfm_status(Playlist::LastFM_Scrobbled); ++ // update the button icon ++ if (last_fm_enabled) ++ ui_->action_toggle_scrobbling->setIcon(QIcon(":/last.fm/as.png")); ++} ++ ++void MainWindow::ScrobbleError(int value) { ++ + switch (value) { + case -1: + // custom error value got from initial validity check + playlists_->active()->set_lastfm_status(Playlist::LastFM_Invalid); + break; + +- case 2: +- case 3: +- // we should get 3 for a correct scrobbling, but I just get 2 for +- // mysterious reasons +- // seems to scrobble fine though, so for now we accept it as correct +- playlists_->active()->set_lastfm_status(Playlist::LastFM_Scrobbled); +- +- // update the button icon +- if (last_fm_enabled) +- ui_->action_toggle_scrobbling->setIcon(QIcon(":/last.fm/as.png")); +- break; +- + case 30: + // Hack: when offline, liblastfm doesn't inform us, so set the status + // as queued; in this way we won't try to scrobble again, it will be done automatically +diff -rupN clementine-1.0.1.old/src/ui/mainwindow.h clementine-1.0.1/src/ui/mainwindow.h +--- clementine-1.0.1.old/src/ui/mainwindow.h 2011-12-27 13:16:09.000000000 -0500 ++++ clementine-1.0.1/src/ui/mainwindow.h 2012-07-03 22:12:08.582375044 -0400 +@@ -224,7 +224,8 @@ class MainWindow : public QMainWindow, p + + void ShowCoverManager(); + #ifdef HAVE_LIBLASTFM +- void ScrobblerStatus(int value); ++ void ScrobbleSubmitted(); ++ void ScrobbleError(int value); + #endif + void ShowAboutDialog(); + void ShowTranscodeDialog(); +diff -rupN clementine-1.0.1.old/tests/mpris1_test.cpp clementine-1.0.1/tests/mpris1_test.cpp +--- clementine-1.0.1.old/tests/mpris1_test.cpp 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/tests/mpris1_test.cpp 2012-07-03 22:12:08.583375040 -0400 +@@ -22,7 +22,7 @@ + #include "playlist/playlistsequence.h" + #ifdef HAVE_LIBLASTFM + #include "internet/fixlastfm.h" +-#include ++#include + #endif + + #include "gmock/gmock.h" +diff -rupN clementine-1.0.1.old/tests/song_test.cpp clementine-1.0.1/tests/song_test.cpp +--- clementine-1.0.1.old/tests/song_test.cpp 2011-12-02 16:24:44.000000000 -0500 ++++ clementine-1.0.1/tests/song_test.cpp 2012-07-03 22:12:08.584375036 -0400 +@@ -20,7 +20,7 @@ + #include "core/song.h" + #ifdef HAVE_LIBLASTFM + #include "internet/fixlastfm.h" +-#include ++#include + #endif + + #include "gmock/gmock.h" diff --git a/clementine.spec b/clementine.spec index cc01770..a40c75b 100644 --- a/clementine.spec +++ b/clementine.spec @@ -1,6 +1,6 @@ Name: clementine Version: 1.0.1 -Release: 7%{?dist} +Release: 8%{?dist} Summary: A music player and library organizer Group: Applications/Multimedia @@ -22,7 +22,8 @@ Patch2: clementine-fresh-start.patch Patch3: clementine-fix-albumcoverfetch-crash.patch # Upstream patch for libimobiledevice Patch4: imobiledevice.patch - +# Compatibility patch with liblastfm1. Backported from upstream trunk +Patch5: clementine-liblastfm1-compatibility.patch BuildRequires: boost-devel BuildRequires: cmake BuildRequires: desktop-file-utils @@ -78,6 +79,9 @@ music. %patch2 -p1 %patch3 -p1 %patch4 -p1 -b .imobile +%if 0%{?fedora} > 17 +%patch5 -p1 -b .liblastfm1 +%endif # Remove all 3rdparty libraries exceph universalchardet # as it is not available as a separate library. @@ -151,6 +155,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %endif %changelog +* Tue Jul 03 2012 Orcan Ogetbil - 1.0.1-8 +- liblastfm1 compatibility fix + * Tue Jul 03 2012 Rex Dieter 1.0.1-7 - rebuild (liblastfm)