--- src/core/song.cpp +++ src/core/song.cpp @@ -49,7 +49,7 @@ #ifdef HAVE_LIBLASTFM #include "internet/fixlastfm.h" - #include + #include #endif #include --- src/covers/lastfmcoverprovider.cpp +++ src/covers/lastfmcoverprovider.cpp @@ -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. } --- src/internet/lastfmservice.cpp +++ src/internet/lastfmservice.cpp @@ -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(); --- src/internet/lastfmservice.h +++ src/internet/lastfmservice.h @@ -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(); --- src/songinfo/lastfmtrackinfoprovider.cpp +++ src/songinfo/lastfmtrackinfoprovider.cpp @@ -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); } --- src/suggesters/lastfmsuggester.cpp +++ src/suggesters/lastfmsuggester.cpp @@ -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()); } } --- src/ui/mainwindow.cpp +++ src/ui/mainwindow.cpp @@ -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 --- src/ui/mainwindow.h +++ src/ui/mainwindow.h @@ -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(); --- tests/mpris1_test.cpp +++ tests/mpris1_test.cpp @@ -22,7 +22,7 @@ #include "playlist/playlistsequence.h" #ifdef HAVE_LIBLASTFM #include "internet/fixlastfm.h" -#include +#include #endif #include "gmock/gmock.h" --- tests/song_test.cpp +++ tests/song_test.cpp @@ -20,7 +20,7 @@ #include "core/song.h" #ifdef HAVE_LIBLASTFM #include "internet/fixlastfm.h" -#include +#include #endif #include "gmock/gmock.h"