File indexing completed on 2024-05-19 04:50:16

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Shane King <kde@dontletsstart.com>                                *
0003  * Copyright (c) 2013 Vedant Agarwala <vedant.kota@gmail.com>                           *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #define DEBUG_PREFIX "LastFmServiceSettings"
0019 
0020 #include "LastFmServiceSettings.h"
0021 
0022 #include "core/collections/QueryMaker.h"
0023 #include "core/meta/Meta.h"
0024 #include "core/support/Amarok.h"
0025 #include "core/support/Debug.h"
0026 #include "core-impl/collections/support/CollectionManager.h"
0027 #include "network/NetworkAccessManagerProxy.h"
0028 #include "ui_LastFmConfigWidget.h"
0029 
0030 #include <KMessageBox>
0031 #include <KPluginFactory>
0032 
0033 #include <QCryptographicHash>
0034 #include <QRegExpValidator>
0035 
0036 #include <XmlQuery.h>
0037 
0038 K_PLUGIN_FACTORY_WITH_JSON( LastFmServiceSettingsFactory, "amarok_service_lastfm_config.json", registerPlugin<LastFmServiceSettings>(); )
0039 
0040 LastFmServiceSettings::LastFmServiceSettings( QWidget *parent, const QVariantList &args )
0041     : KCModule( parent, args )
0042     , m_config( LastFmServiceConfig::instance() )
0043 {
0044     m_configDialog = new Ui::LastFmConfigWidget;
0045     m_configDialog->setupUi( this );
0046 
0047     connect( m_config.data(), &LastFmServiceConfig::updated, this, &LastFmServiceSettings::onConfigUpdated );
0048 
0049     connect( m_configDialog->kcfg_ScrobblerUsername, &QLineEdit::textChanged, this, &LastFmServiceSettings::settingsChanged );
0050     connect( m_configDialog->kcfg_ScrobblerPassword, &QLineEdit::textChanged, this, &LastFmServiceSettings::settingsChanged );
0051     connect( m_configDialog->kcfg_SubmitPlayedSongs, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
0052     connect( m_configDialog->kcfg_RetrieveSimilarArtists, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
0053     connect( m_configDialog->kcfg_ScrobbleComposer, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
0054     connect( m_configDialog->kcfg_UseFancyRatingTags, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
0055     connect( m_configDialog->kcfg_AnnounceCorrections, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
0056     connect( m_configDialog->kcfg_FilterByLabel, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
0057     connect( m_configDialog->kcfg_FilteredLabel, QOverload<int>::of( &QComboBox::currentIndexChanged ), this, &LastFmServiceSettings::settingsChanged );
0058     connect( m_configDialog->testLogin, &QPushButton::clicked, this, &LastFmServiceSettings::testLogin );
0059 
0060     using namespace Collections;
0061 
0062     QueryMaker *query = CollectionManager::instance()->queryMaker();
0063     query->setQueryType( QueryMaker::Label );
0064     connect( query, &QueryMaker::newLabelsReady, this, &LastFmServiceSettings::addNewLabels );
0065     query->setAutoDelete( true );
0066     query->run();
0067 }
0068 
0069 LastFmServiceSettings::~LastFmServiceSettings()
0070 {
0071     delete m_configDialog;
0072 }
0073 
0074 void
0075 LastFmServiceSettings::save()
0076 {
0077     QString dialogUser = m_configDialog->kcfg_ScrobblerUsername->text();
0078     QString dialogPass = m_configDialog->kcfg_ScrobblerPassword->text();
0079 
0080     // clear the session key if credentials changed
0081     if( m_config->username() != dialogUser || m_config->password() != dialogPass )
0082         m_config->setSessionKey( QString() );
0083 
0084     m_config->setUsername( dialogUser );
0085     m_config->setPassword( dialogPass );
0086     m_config->setScrobble( m_configDialog->kcfg_SubmitPlayedSongs->isChecked() );
0087     m_config->setFetchSimilar( m_configDialog->kcfg_RetrieveSimilarArtists->isChecked() );
0088     m_config->setScrobbleComposer( m_configDialog->kcfg_ScrobbleComposer->isChecked() );
0089     m_config->setUseFancyRatingTags( m_configDialog->kcfg_UseFancyRatingTags->isChecked() );
0090     m_config->setAnnounceCorrections( m_configDialog->kcfg_AnnounceCorrections->isChecked() );
0091     m_config->setFilterByLabel( m_configDialog->kcfg_FilterByLabel->isChecked() );
0092     m_config->setFilteredLabel( m_configDialog->kcfg_FilteredLabel->currentText() );
0093     m_config->save();
0094 
0095     KCModule::save();
0096 }
0097 
0098 void
0099 LastFmServiceSettings::testLogin()
0100 {
0101     m_configDialog->testLogin->setEnabled( false );
0102     m_configDialog->testLogin->setText( i18n( "Testing..." ) );
0103     // set the global static Lastfm::Ws stuff
0104     lastfm::ws::ApiKey = Amarok::lastfmApiKey();
0105     lastfm::ws::SharedSecret = Amarok::lastfmApiSharedSecret();
0106     lastfm::ws::setScheme(lastfm::ws::Https);
0107     if( lastfm::nam() != The::networkAccessManager() )
0108         lastfm::setNetworkAccessManager( The::networkAccessManager() );
0109 
0110     debug() << "username:" << QString( QUrl::toPercentEncoding( m_configDialog->kcfg_ScrobblerUsername->text().toUtf8() ) );
0111 
0112     QMap<QString, QString> query;
0113 
0114     query[ "method" ] = "auth.getMobileSession";
0115     query[ "password" ] = m_configDialog->kcfg_ScrobblerPassword->text().toUtf8();
0116     query[ "username" ] = m_configDialog->kcfg_ScrobblerUsername->text().toUtf8();
0117     m_authQuery = lastfm::ws::post( query );
0118 
0119     connect( m_authQuery, &QNetworkReply::finished, this, &LastFmServiceSettings::onAuthenticated );
0120     connect( m_authQuery, QOverload<QNetworkReply::NetworkError>::of( &QNetworkReply::errorOccurred ),
0121              this, &LastFmServiceSettings::onError );
0122 }
0123 
0124 void
0125 LastFmServiceSettings::onAuthenticated()
0126 {
0127     lastfm::XmlQuery lfm;
0128     lfm.parse( m_authQuery->readAll() );
0129 
0130     switch( m_authQuery->error() )
0131     {
0132         case QNetworkReply::NoError:
0133              debug() << "NoError";
0134              if( lfm.children( "error" ).size() > 0 )
0135              {
0136                  debug() << "ERROR from last.fm:" << lfm.text();
0137                  m_configDialog->testLogin->setText( i18nc( "The operation was rejected by the server", "Failed" ) );
0138                  m_configDialog->testLogin->setEnabled( true );
0139 
0140              } else
0141              {
0142                  m_configDialog->testLogin->setText( i18nc( "The operation completed as expected", "Success" ) );
0143                  m_configDialog->testLogin->setEnabled( false );
0144                  m_configDialog->kcfg_SubmitPlayedSongs->setEnabled( true );
0145              }
0146              break;
0147 
0148         case QNetworkReply::AuthenticationRequiredError:
0149             debug() << "AuthenticationFailed";
0150             KMessageBox::error( this, i18n( "Either the username or the password is incorrect, please correct and try again" ), i18n( "Failed" ) );
0151             m_configDialog->testLogin->setText( i18n( "Test Login" ) );
0152             m_configDialog->testLogin->setEnabled( true );
0153             break;
0154 
0155         default:
0156             debug() << "Unhandled QNetworkReply state, probably not important";
0157     }
0158     m_authQuery->deleteLater();
0159 }
0160 
0161 void
0162 LastFmServiceSettings::onError( QNetworkReply::NetworkError code )
0163 {
0164     if( code == QNetworkReply::NoError )
0165         return;
0166 
0167     if( code == QNetworkReply::AuthenticationRequiredError )
0168     {
0169         onAuthenticated();
0170         return;
0171     }
0172 
0173     KMessageBox::error( this, i18n( "Unable to connect to Last.fm service." ), i18n( "Failed" ) );
0174     m_configDialog->testLogin->setText( i18n( "Test Login" ) );
0175     m_configDialog->testLogin->setEnabled( true );
0176 
0177     debug() << "Error occurred during network request: " << m_authQuery->errorString();
0178     m_authQuery->deleteLater();
0179 }
0180 
0181 void
0182 LastFmServiceSettings::onConfigUpdated()
0183 {
0184     load();
0185 }
0186 
0187 void
0188 LastFmServiceSettings::load()
0189 {
0190     m_configDialog->kcfg_ScrobblerUsername->setText( m_config->username() );
0191     m_configDialog->kcfg_ScrobblerPassword->setText( m_config->password() );
0192     m_configDialog->kcfg_SubmitPlayedSongs->setChecked( m_config->scrobble() );
0193     m_configDialog->kcfg_RetrieveSimilarArtists->setChecked( m_config->fetchSimilar() );
0194     m_configDialog->kcfg_ScrobbleComposer->setChecked( m_config->scrobbleComposer() );
0195     m_configDialog->kcfg_UseFancyRatingTags->setChecked( m_config->useFancyRatingTags() );
0196     m_configDialog->kcfg_AnnounceCorrections->setChecked( m_config->announceCorrections() );
0197     m_configDialog->kcfg_FilterByLabel->setChecked( m_config->filterByLabel() );
0198     m_configDialog->kcfg_FilteredLabel->setCurrentIndex( filteredLabelComboIndex( m_config->filteredLabel() ) );
0199 
0200     if( !m_config->username().isEmpty() && !m_config->password().isEmpty() )
0201         m_configDialog->kcfg_SubmitPlayedSongs->setEnabled( true );
0202 
0203     KCModule::load();
0204 }
0205 
0206 void
0207 LastFmServiceSettings::defaults()
0208 {
0209     m_configDialog->kcfg_SubmitPlayedSongs->setChecked( m_config->defaultScrobble() );
0210     m_configDialog->kcfg_RetrieveSimilarArtists->setChecked( m_config->defaultFetchSimilar() );
0211     m_configDialog->kcfg_ScrobbleComposer->setChecked( m_config->defaultScrobbleComposer() );
0212     m_configDialog->kcfg_UseFancyRatingTags->setChecked( m_config->defaultUseFancyRatingTags() );
0213     m_configDialog->kcfg_AnnounceCorrections->setChecked( m_config->defaultAnnounceCorrections() );
0214     m_configDialog->kcfg_FilterByLabel->setChecked( m_config->defaultFilterByLabel() );
0215     m_configDialog->kcfg_FilteredLabel->setCurrentIndex( filteredLabelComboIndex( m_config->defaultFilteredLabel() ) );
0216 }
0217 
0218 void
0219 LastFmServiceSettings::settingsChanged()
0220 {
0221     //TODO: Make pretty validation for username and password
0222     //with error reporting
0223 
0224     m_configDialog->testLogin->setText( i18n( "&Test Login" ) );
0225     m_configDialog->testLogin->setEnabled( true );
0226 
0227     emit changed( true );
0228 }
0229 
0230 void
0231 LastFmServiceSettings::addNewLabels( const Meta::LabelList &labels )
0232 {
0233     foreach( const Meta::LabelPtr &label , labels )
0234         m_configDialog->kcfg_FilteredLabel->addItem( label->name() );
0235 }
0236 
0237 int
0238 LastFmServiceSettings::filteredLabelComboIndex( const QString &label )
0239 {
0240     int index = m_configDialog->kcfg_FilteredLabel->findText( label );
0241     if( index == -1)
0242     {
0243         m_configDialog->kcfg_FilteredLabel->addItem( label );
0244         return m_configDialog->kcfg_FilteredLabel->findText( label );
0245     }
0246     else
0247         return index;
0248 }
0249 
0250 #include "LastFmServiceSettings.moc"