2010-03-24 00:11:46 +01:00
/* This file is part of Clementine.
2014-12-17 19:02:21 +01:00
Copyright 2009 - 2013 , David Sansome < me @ davidsansome . com >
Copyright 2010 - 2012 , 2014 , John Maguire < john . maguire @ gmail . com >
Copyright 2011 , Andrea Decorte < adecorte @ gmail . com >
Copyright 2012 , Arnaud Bienner < arnaud . bienner @ gmail . com >
Copyright 2012 , Kacper " mattrick " Banasik < mattrick @ jabster . pl >
Copyright 2012 , Harald Sitter < sitter @ kde . org >
Copyright 2014 , Krzysztof Sobiecki < sobkas @ gmail . com >
2010-03-24 00:11:46 +01:00
Clementine is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Clementine is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Clementine . If not , see < http : //www.gnu.org/licenses/>.
*/
2014-02-07 16:34:20 +01:00
// StringBuilder is activated to speed-up QString concatenation. As explained
// here:
2012-02-19 14:44:33 +01:00
// http://labs.qt.nokia.com/2011/06/13/string-concatenation-with-qstringbuilder/
// this cause some compilation errors in some cases. As Lasfm library inlines
// some functions in their includes files, which aren't compatible with
// QStringBuilder, we undef it here
# include <QtGlobal>
2014-02-07 16:34:20 +01:00
# undef QT_USE_QSTRINGBUILDER
2012-02-19 14:44:33 +01:00
2009-12-26 16:13:38 +01:00
# include "lastfmservice.h"
2012-06-28 18:41:51 +02:00
2018-10-05 17:19:05 +02:00
# include <algorithm>
2017-08-24 20:32:14 +02:00
# include <QCryptographicHash>
# include <QDesktopServices>
2012-10-12 14:31:31 +02:00
# include <QMenu>
2017-08-24 20:32:14 +02:00
# include <QMessageBox>
2012-10-12 14:31:31 +02:00
# include <QSettings>
2018-02-01 09:50:42 +01:00
# include <QUrlQuery>
2012-10-12 14:31:31 +02:00
# ifdef HAVE_LIBLASTFM1
2015-06-16 15:36:14 +02:00
# include <lastfm5/RadioStation.h>
2012-10-12 14:31:31 +02:00
# else
2015-06-16 15:36:14 +02:00
# include <lastfm5/RadioStation>
2012-10-12 14:31:31 +02:00
# endif
2012-06-28 18:41:51 +02:00
# include "lastfmcompat.h"
2012-02-12 14:41:50 +01:00
# include "core/application.h"
2012-10-12 14:31:31 +02:00
# include "core/closure.h"
2011-04-22 18:50:29 +02:00
# include "core/logging.h"
2017-08-24 20:32:14 +02:00
# include "core/network.h"
2011-04-28 17:10:28 +02:00
# include "core/player.h"
2010-05-10 23:50:31 +02:00
# include "core/song.h"
2010-06-23 15:21:30 +02:00
# include "core/taskmanager.h"
2017-08-24 20:32:14 +02:00
# include "internet/core/internetmodel.h"
# include "internet/core/internetplaylistitem.h"
# include "internet/core/localredirectserver.h"
2011-06-20 01:15:51 +02:00
# include "covers/coverproviders.h"
# include "covers/lastfmcoverprovider.h"
2010-05-19 17:45:29 +02:00
# include "ui/iconloader.h"
2010-06-09 00:56:31 +02:00
# include "ui/settingsdialog.h"
2009-12-26 16:13:38 +01:00
2010-02-25 01:18:32 +01:00
using lastfm : : XmlQuery ;
uint qHash ( const lastfm : : Track & track ) {
2014-02-07 16:34:20 +01:00
return qHash ( track . title ( ) ) ^ qHash ( track . artist ( ) . name ( ) ) ^
2010-02-25 01:18:32 +01:00
qHash ( track . album ( ) . title ( ) ) ;
}
2009-12-29 20:22:02 +01:00
const char * LastFMService : : kServiceName = " Last.fm " ;
2009-12-26 18:19:14 +01:00
const char * LastFMService : : kSettingsGroup = " Last.fm " ;
2009-12-29 20:22:02 +01:00
const char * LastFMService : : kAudioscrobblerClientId = " tng " ;
const char * LastFMService : : kApiKey = " 75d20fb472be99275392aefa2760ea09 " ;
const char * LastFMService : : kSecret = " d3072b60ae626be12be69448f5c46e70 " ;
2016-02-04 18:12:42 +01:00
const char * LastFMService : : kAuthLoginUrl =
" https://www.last.fm/api/auth/?api_key=%1&token=%2 " ;
2009-12-26 18:19:14 +01:00
2014-03-27 18:55:58 +01:00
LastFMService : : LastFMService ( Application * app , QObject * parent )
: Scrobbler ( parent ) ,
2014-02-07 16:34:20 +01:00
scrobbling_enabled_ ( false ) ,
2014-03-27 18:55:58 +01:00
connection_problems_ ( false ) ,
2017-08-24 20:32:14 +02:00
app_ ( app ) ,
network_ ( new NetworkAccessManager ) {
2016-02-09 16:17:20 +01:00
# ifdef HAVE_LIBLASTFM1
2016-02-09 12:52:04 +01:00
lastfm : : ws : : setScheme ( lastfm : : ws : : Https ) ;
2016-02-09 16:17:20 +01:00
# endif
2016-02-09 12:52:04 +01:00
2011-11-08 19:35:33 +01:00
ReloadSettings ( ) ;
2014-02-07 16:34:20 +01:00
// we emit the signal the first time to be sure the buttons are in the right
// state
2011-04-07 18:25:52 +02:00
emit ScrobblingEnabledChanged ( scrobbling_enabled_ ) ;
2009-12-26 18:19:14 +01:00
}
2014-02-07 16:34:20 +01:00
LastFMService : : ~ LastFMService ( ) { }
2009-12-26 16:13:38 +01:00
2010-02-03 19:32:48 +01:00
void LastFMService : : ReloadSettings ( ) {
2011-04-07 18:25:52 +02:00
bool scrobbling_enabled_old = scrobbling_enabled_ ;
2010-02-03 19:32:48 +01:00
QSettings settings ;
settings . beginGroup ( kSettingsGroup ) ;
lastfm : : ws : : Username = settings . value ( " Username " ) . toString ( ) ;
lastfm : : ws : : SessionKey = settings . value ( " Session " ) . toString ( ) ;
scrobbling_enabled_ = settings . value ( " ScrobblingEnabled " , true ) . toBool ( ) ;
2010-04-07 21:26:49 +02:00
buttons_visible_ = settings . value ( " ShowLoveBanButtons " , true ) . toBool ( ) ;
2014-02-07 16:34:20 +01:00
scrobble_button_visible_ =
settings . value ( " ShowScrobbleButton " , true ) . toBool ( ) ;
2012-05-13 17:04:55 +02:00
prefer_albumartist_ = settings . value ( " PreferAlbumArtist " , false ) . toBool ( ) ;
2011-09-24 14:48:14 +02:00
2014-02-07 16:34:20 +01:00
// avoid emitting signal if it's not changed
if ( scrobbling_enabled_old ! = scrobbling_enabled_ )
2011-04-07 18:25:52 +02:00
emit ScrobblingEnabledChanged ( scrobbling_enabled_ ) ;
2010-04-07 21:26:49 +02:00
emit ButtonVisibilityChanged ( buttons_visible_ ) ;
2011-04-07 18:25:52 +02:00
emit ScrobbleButtonVisibilityChanged ( scrobble_button_visible_ ) ;
2012-05-13 17:04:55 +02:00
emit PreferAlbumArtistChanged ( prefer_albumartist_ ) ;
2009-12-29 20:22:02 +01:00
}
2010-02-03 19:32:48 +01:00
void LastFMService : : ShowConfig ( ) {
2012-12-05 10:36:22 +01:00
app_ - > OpenSettingsDialogAtPage ( SettingsDialog : : Page_Lastfm ) ;
2010-02-03 19:32:48 +01:00
}
2009-12-29 21:48:50 +01:00
2010-02-03 19:32:48 +01:00
bool LastFMService : : IsAuthenticated ( ) const {
return ! lastfm : : ws : : SessionKey . isEmpty ( ) ;
2009-12-29 21:48:50 +01:00
}
2011-04-13 17:54:15 +02:00
bool LastFMService : : IsSubscriber ( ) const {
QSettings settings ;
settings . beginGroup ( kSettingsGroup ) ;
return settings . value ( " Subscriber " , false ) . toBool ( ) ;
}
2017-08-24 20:32:14 +02:00
namespace {
QByteArray SignApiRequest ( QList < QPair < QString , QString > > params ) {
2018-10-05 17:19:05 +02:00
std : : sort ( params . begin ( ) , params . end ( ) ) ;
2017-08-24 20:32:14 +02:00
QString to_sign ;
for ( const auto & p : params ) {
to_sign + = p . first ;
to_sign + = p . second ;
}
to_sign + = LastFMService : : kSecret ;
return QCryptographicHash : : hash ( to_sign . toUtf8 ( ) , QCryptographicHash : : Md5 ) . toHex ( ) ;
2009-12-26 18:19:14 +01:00
}
2017-08-24 20:32:14 +02:00
} // namespace
2009-12-26 18:19:14 +01:00
2017-08-24 20:32:14 +02:00
void LastFMService : : Authenticate ( ) {
QUrl url ( " https://www.last.fm/api/auth/ " ) ;
2010-04-07 21:26:49 +02:00
2017-08-24 20:32:14 +02:00
LocalRedirectServer * server = new LocalRedirectServer ( this ) ;
server - > Listen ( ) ;
2011-09-24 18:01:18 +02:00
2018-02-19 08:41:41 +01:00
QUrlQuery url_query ;
url_query . addQueryItem ( " api_key " , kApiKey ) ;
2018-02-01 09:50:42 +01:00
url_query . addQueryItem ( " cb " , server - > url ( ) . toString ( ) ) ;
2018-02-19 08:41:41 +01:00
url . setQuery ( url_query ) ;
2016-02-03 15:33:46 +01:00
2017-08-24 20:32:14 +02:00
NewClosure ( server , SIGNAL ( Finished ( ) ) , [ this , server ] ( ) {
server - > deleteLater ( ) ;
2016-02-03 15:33:46 +01:00
2017-08-24 20:32:14 +02:00
const QUrl & url = server - > request_url ( ) ;
2018-02-01 09:50:42 +01:00
QString token = QUrlQuery ( url ) . queryItemValue ( " token " ) ;
2017-08-24 20:32:14 +02:00
QUrl session_url ( " https://ws.audioscrobbler.com/2.0/ " ) ;
2018-02-01 09:50:42 +01:00
QUrlQuery session_url_query ;
session_url_query . addQueryItem ( " api_key " , kApiKey ) ;
session_url_query . addQueryItem ( " method " , " auth.getSession " ) ;
session_url_query . addQueryItem ( " token " , token ) ;
session_url_query . addQueryItem ( " api_sig " , SignApiRequest ( session_url_query . queryItems ( ) ) ) ;
session_url . setQuery ( session_url_query ) ;
2017-08-24 20:32:14 +02:00
QNetworkReply * reply = network_ - > get ( QNetworkRequest ( session_url ) ) ;
NewClosure ( reply , SIGNAL ( finished ( ) ) , this , SLOT ( AuthenticateReplyFinished ( QNetworkReply * ) ) , reply ) ;
} ) ;
if ( ! QDesktopServices : : openUrl ( url ) ) {
2017-08-28 23:03:49 +02:00
QMessageBox box ( QMessageBox : : NoIcon , tr ( " Last.fm Authentication " ) , tr ( " Please open this URL in your browser: <a href= \" %1 \" >%1</a> " ) . arg ( url . toString ( ) ) , QMessageBox : : Ok ) ;
2017-08-24 20:32:14 +02:00
box . setTextFormat ( Qt : : RichText ) ;
qLog ( Debug ) < < " Last.fm authentication URL: " < < url . toString ( ) ;
box . exec ( ) ;
}
2010-04-07 21:26:49 +02:00
}
2012-10-12 14:31:31 +02:00
void LastFMService : : AuthenticateReplyFinished ( QNetworkReply * reply ) {
2011-04-14 13:11:34 +02:00
reply - > deleteLater ( ) ;
2009-12-26 18:19:14 +01:00
// Parse the reply
2012-06-28 18:41:51 +02:00
lastfm : : XmlQuery lfm ( lastfm : : compat : : EmptyXmlQuery ( ) ) ;
if ( lastfm : : compat : : ParseQuery ( reply - > readAll ( ) , & lfm ) ) {
2009-12-26 18:19:14 +01:00
lastfm : : ws : : Username = lfm [ " session " ] [ " name " ] . text ( ) ;
lastfm : : ws : : SessionKey = lfm [ " session " ] [ " key " ] . text ( ) ;
2011-04-13 17:54:15 +02:00
QString subscribed = lfm [ " session " ] [ " subscriber " ] . text ( ) ;
const bool is_subscriber = ( subscribed . toInt ( ) = = 1 ) ;
// Save the session key
QSettings settings ;
settings . beginGroup ( kSettingsGroup ) ;
settings . setValue ( " Username " , lastfm : : ws : : Username ) ;
settings . setValue ( " Session " , lastfm : : ws : : SessionKey ) ;
settings . setValue ( " Subscriber " , is_subscriber ) ;
2012-06-25 12:30:53 +02:00
} else {
2017-08-24 20:32:14 +02:00
emit AuthenticationComplete ( false ) ;
2009-12-26 18:19:14 +01:00
return ;
}
2009-12-29 20:22:02 +01:00
// Invalidate the scrobbler - it will get recreated later
2016-02-04 18:13:01 +01:00
scrobbler_ . reset ( nullptr ) ;
2009-12-29 20:22:02 +01:00
2017-08-24 20:32:14 +02:00
emit AuthenticationComplete ( true ) ;
2009-12-26 18:19:14 +01:00
}
2009-12-26 22:35:45 +01:00
2016-02-03 15:33:46 +01:00
void LastFMService : : SignOut ( ) {
lastfm : : ws : : Username . clear ( ) ;
lastfm : : ws : : SessionKey . clear ( ) ;
QSettings settings ;
settings . beginGroup ( kSettingsGroup ) ;
settings . setValue ( " Username " , QString ( ) ) ;
settings . setValue ( " Session " , QString ( ) ) ;
}
2011-04-14 13:11:34 +02:00
void LastFMService : : UpdateSubscriberStatus ( ) {
QMap < QString , QString > params ;
params [ " method " ] = " user.getInfo " ;
params [ " user " ] = lastfm : : ws : : Username ;
QNetworkReply * reply = lastfm : : ws : : post ( params ) ;
2012-10-12 14:31:31 +02:00
NewClosure ( reply , SIGNAL ( finished ( ) ) , this ,
SLOT ( UpdateSubscriberStatusFinished ( QNetworkReply * ) ) , reply ) ;
2011-04-14 13:11:34 +02:00
}
2012-10-12 14:31:31 +02:00
void LastFMService : : UpdateSubscriberStatusFinished ( QNetworkReply * reply ) {
2011-04-14 13:11:34 +02:00
reply - > deleteLater ( ) ;
2011-08-27 23:01:28 +02:00
bool is_subscriber = false ;
2012-06-28 18:41:51 +02:00
lastfm : : XmlQuery lfm ( lastfm : : compat : : EmptyXmlQuery ( ) ) ;
2014-02-07 16:34:20 +01:00
if ( lastfm : : compat : : ParseQuery ( reply - > readAll ( ) , & lfm ,
& connection_problems_ ) ) {
2011-04-14 13:11:34 +02:00
QString subscriber = lfm [ " user " ] [ " subscriber " ] . text ( ) ;
2011-08-27 23:01:28 +02:00
is_subscriber = ( subscriber . toInt ( ) = = 1 ) ;
2011-04-28 12:32:56 +02:00
2011-04-14 13:11:34 +02:00
QSettings settings ;
settings . beginGroup ( kSettingsGroup ) ;
settings . setValue ( " Subscriber " , is_subscriber ) ;
2011-04-22 18:50:29 +02:00
qLog ( Info ) < < lastfm : : ws : : Username < < " Subscriber status: " < < is_subscriber ;
2011-04-14 13:11:34 +02:00
}
2011-08-27 23:01:28 +02:00
emit UpdatedSubscriberStatus ( is_subscriber ) ;
2011-04-14 13:11:34 +02:00
}
2011-01-09 19:27:41 +01:00
QUrl LastFMService : : FixupUrl ( const QUrl & url ) {
QUrl ret ;
2015-04-15 18:26:09 +02:00
ret . setUrl ( url . toEncoded ( ) . replace (
2011-01-09 19:27:41 +01:00
" USERNAME " , QUrl : : toPercentEncoding ( lastfm : : ws : : Username ) ) ) ;
return ret ;
2009-12-26 22:35:45 +01:00
}
QString LastFMService : : ErrorString ( lastfm : : ws : : Error error ) const {
switch ( error ) {
2014-02-07 16:34:20 +01:00
case lastfm : : ws : : InvalidService :
return tr ( " Invalid service " ) ;
case lastfm : : ws : : InvalidMethod :
return tr ( " Invalid method " ) ;
case lastfm : : ws : : AuthenticationFailed :
return tr ( " Authentication failed " ) ;
case lastfm : : ws : : InvalidFormat :
return tr ( " Invalid format " ) ;
case lastfm : : ws : : InvalidParameters :
return tr ( " Invalid parameters " ) ;
case lastfm : : ws : : InvalidResourceSpecified :
return tr ( " Invalid resource specified " ) ;
case lastfm : : ws : : OperationFailed :
return tr ( " Operation failed " ) ;
case lastfm : : ws : : InvalidSessionKey :
return tr ( " Invalid session key " ) ;
case lastfm : : ws : : InvalidApiKey :
return tr ( " Invalid API key " ) ;
case lastfm : : ws : : ServiceOffline :
return tr ( " Service offline " ) ;
case lastfm : : ws : : SubscribersOnly :
return tr ( " This stream is for paid subscribers only " ) ;
case lastfm : : ws : : TryAgainLater :
return tr ( " Last.fm is currently busy, please try again in a few minutes " ) ;
case lastfm : : ws : : NotEnoughContent :
return tr ( " Not enough content " ) ;
case lastfm : : ws : : NotEnoughMembers :
return tr ( " Not enough members " ) ;
case lastfm : : ws : : NotEnoughFans :
return tr ( " Not enough fans " ) ;
case lastfm : : ws : : NotEnoughNeighbours :
return tr ( " Not enough neighbors " ) ;
case lastfm : : ws : : MalformedResponse :
return tr ( " Malformed response " ) ;
2009-12-26 22:35:45 +01:00
case lastfm : : ws : : UnknownError :
default :
2010-02-23 19:33:09 +01:00
return tr ( " Unknown error " ) ;
2009-12-26 22:35:45 +01:00
}
}
2009-12-29 20:22:02 +01:00
bool LastFMService : : InitScrobbler ( ) {
2014-02-07 16:34:20 +01:00
if ( ! IsAuthenticated ( ) | | ! IsScrobblingEnabled ( ) ) return false ;
2009-12-29 20:22:02 +01:00
2009-12-29 20:57:33 +01:00
if ( ! scrobbler_ )
2016-02-04 18:13:01 +01:00
scrobbler_ . reset ( new lastfm : : Audioscrobbler ( kAudioscrobblerClientId ) ) ;
2009-12-29 20:22:02 +01:00
2014-02-07 16:34:20 +01:00
// reemit the signal since the sender is private
2012-06-28 18:41:51 +02:00
# ifdef HAVE_LIBLASTFM1
2016-02-04 18:13:01 +01:00
connect ( scrobbler_ . get ( ) , SIGNAL ( scrobblesSubmitted ( QList < lastfm : : Track > ) ) ,
2014-02-07 16:34:20 +01:00
SIGNAL ( ScrobbleSubmitted ( ) ) ) ;
2016-02-04 18:13:01 +01:00
connect ( scrobbler_ . get ( ) , SIGNAL ( nowPlayingError ( int , QString ) ) ,
2014-02-07 16:34:20 +01:00
SIGNAL ( ScrobbleError ( int ) ) ) ;
2012-06-28 18:41:51 +02:00
# else
2016-02-04 18:13:01 +01:00
connect ( scrobbler_ . get ( ) , SIGNAL ( status ( int ) ) , SLOT ( ScrobblerStatus ( int ) ) ) ;
2012-06-28 18:41:51 +02:00
# endif
2009-12-29 20:22:02 +01:00
return true ;
}
2012-06-28 18:41:51 +02:00
void LastFMService : : ScrobblerStatus ( int value ) {
switch ( value ) {
2014-02-07 16:34:20 +01:00
case 2 :
case 3 :
2014-01-18 23:13:23 +01:00
emit CachedToScrobble ( ) ;
2014-02-07 16:34:20 +01:00
break ;
default :
emit ScrobbleError ( value ) ;
break ;
2012-06-28 18:41:51 +02:00
}
}
2014-02-07 16:34:20 +01:00
lastfm : : Track LastFMService : : TrackFromSong ( const Song & song ) const {
2009-12-29 20:22:02 +01:00
if ( song . title ( ) = = last_track_ . title ( ) & &
song . artist ( ) = = last_track_ . artist ( ) & &
song . album ( ) = = last_track_ . album ( ) )
return last_track_ ;
lastfm : : Track ret ;
2012-05-13 17:04:55 +02:00
song . ToLastFM ( & ret , PreferAlbumArtist ( ) ) ;
2009-12-29 20:22:02 +01:00
return ret ;
}
2014-02-07 16:34:20 +01:00
void LastFMService : : NowPlaying ( const Song & song ) {
if ( ! InitScrobbler ( ) ) return ;
2009-12-29 20:22:02 +01:00
2011-04-16 17:13:53 +02:00
// Scrobbling streams is difficult if we don't have length of each individual
// part. In Song::ToLastFm we set the Track's source to
// NonPersonalisedBroadcast if it's such a stream, so we have to scrobble it
// when we change to a different track, but only if enough time has elapsed
// since it started playing.
if ( ! last_track_ . isNull ( ) & &
last_track_ . source ( ) = = lastfm : : Track : : NonPersonalisedBroadcast ) {
2014-02-07 16:34:20 +01:00
const int duration_secs =
last_track_ . timestamp ( ) . secsTo ( QDateTime : : currentDateTime ( ) ) ;
2012-06-28 18:41:51 +02:00
if ( duration_secs > = lastfm : : compat : : ScrobbleTimeMin ( ) ) {
2011-04-16 17:13:53 +02:00
lastfm : : MutableTrack mtrack ( last_track_ ) ;
mtrack . setDuration ( duration_secs ) ;
2014-02-07 16:34:20 +01:00
qLog ( Info ) < < " Scrobbling stream track " < < mtrack . title ( ) < < " length "
< < duration_secs ;
2011-04-16 17:13:53 +02:00
scrobbler_ - > cache ( mtrack ) ;
scrobbler_ - > submit ( ) ;
2011-04-16 17:27:34 +02:00
emit ScrobbledRadioStream ( ) ;
2011-04-16 17:13:53 +02:00
}
}
2011-04-07 21:18:24 +02:00
lastfm : : MutableTrack mtrack ( TrackFromSong ( song ) ) ;
mtrack . stamp ( ) ;
2014-01-18 23:13:23 +01:00
already_cached_to_scrobble_ = false ;
2011-04-07 21:18:24 +02:00
last_track_ = mtrack ;
2009-12-29 21:11:03 +01:00
2012-06-28 18:41:51 +02:00
# ifndef HAVE_LIBLASTFM1
// Check immediately if the song is valid
Scrobble : : Invalidity invalidity ;
2014-02-07 16:34:20 +01:00
if ( ! lastfm : : Scrobble ( last_track_ ) . isValid ( & invalidity ) ) {
// for now just notify this, we can also see the cause
2012-06-28 18:41:51 +02:00
emit ScrobbleError ( - 1 ) ;
return ;
}
# else
2015-06-17 14:21:24 +02:00
// TODO(John Maguire): validity was removed from liblastfm1 but might reappear,
// it should have
2014-02-07 16:34:20 +01:00
// no impact as we get a different error when actually trying to scrobble.
2012-06-28 18:41:51 +02:00
# endif
2011-04-07 18:25:52 +02:00
2010-03-21 01:22:15 +01:00
scrobbler_ - > nowPlaying ( mtrack ) ;
2009-12-29 20:22:02 +01:00
}
2014-01-18 23:13:23 +01:00
void LastFMService : : CacheSong ( int scrobble_point ) {
if ( ! InitScrobbler ( ) ) return ;
if ( ! already_cached_to_scrobble_ & & scrobble_point ) {
qLog ( Info ) < < " Caching song to scrobble at " < < scrobble_point ;
scrobbler_ - > cache ( last_track_ ) ;
already_cached_to_scrobble_ = true ;
}
emit CachedToScrobble ( ) ;
}
2009-12-29 21:11:03 +01:00
void LastFMService : : Scrobble ( ) {
2014-02-07 16:34:20 +01:00
if ( ! InitScrobbler ( ) ) return ;
2009-12-29 20:22:02 +01:00
2012-06-28 18:41:51 +02:00
lastfm : : compat : : ScrobbleCache cache ( lastfm : : ws : : Username ) ;
2014-02-07 16:34:20 +01:00
qLog ( Debug ) < < " There are " < < cache . tracks ( ) . count ( )
2014-01-18 23:13:23 +01:00
< < " tracks in the last.fm cache before submit request. " ;
2011-04-28 12:32:56 +02:00
// Let's mark a track as cached, useful when the connection is down
2012-06-25 12:30:53 +02:00
emit ScrobbleError ( 30 ) ;
2014-01-18 23:13:23 +01:00
if ( ! cache . tracks ( ) . isEmpty ( ) ) scrobbler_ - > submit ( ) ;
2009-12-29 20:22:02 +01:00
}
2009-12-29 21:11:03 +01:00
void LastFMService : : Love ( ) {
2014-02-07 16:34:20 +01:00
if ( ! IsAuthenticated ( ) ) ShowConfig ( ) ;
2009-12-29 21:48:50 +01:00
2009-12-29 21:11:03 +01:00
lastfm : : MutableTrack mtrack ( last_track_ ) ;
2009-12-29 20:22:02 +01:00
mtrack . love ( ) ;
2010-03-21 01:22:15 +01:00
last_track_ = mtrack ;
2009-12-29 20:22:02 +01:00
}
2009-12-29 21:11:03 +01:00
void LastFMService : : Ban ( ) {
2015-06-17 14:21:24 +02:00
if ( ! IsAuthenticated ( ) ) ShowConfig ( ) ;
2009-12-29 21:11:03 +01:00
lastfm : : MutableTrack mtrack ( last_track_ ) ;
2009-12-29 20:22:02 +01:00
mtrack . ban ( ) ;
2010-03-21 01:22:15 +01:00
last_track_ = mtrack ;
2009-12-29 21:48:50 +01:00
2014-01-18 23:13:23 +01:00
CacheSong ( 0 ) ;
2009-12-29 21:48:50 +01:00
Scrobble ( ) ;
2012-02-12 14:41:50 +01:00
app_ - > player ( ) - > Next ( ) ;
2009-12-29 20:22:02 +01:00
}
2009-12-30 00:01:07 +01:00
2011-04-07 18:25:52 +02:00
void LastFMService : : ToggleScrobbling ( ) {
2014-02-07 16:34:20 +01:00
// toggle status
2011-04-07 18:25:52 +02:00
scrobbling_enabled_ = ! scrobbling_enabled_ ;
2014-02-07 16:34:20 +01:00
// save to the settings
2011-04-07 18:25:52 +02:00
QSettings s ;
s . beginGroup ( kSettingsGroup ) ;
s . setValue ( " ScrobblingEnabled " , scrobbling_enabled_ ) ;
s . endGroup ( ) ;
emit ScrobblingEnabledChanged ( scrobbling_enabled_ ) ;
}