1 /****************************************************************************************
2 * Copyright (c) 2007 Shane King <kde@dontletsstart.com> *
3 * Copyright (c) 2013 Vedant Agarwala <vedant.kota@gmail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify it under *
6 * the terms of the GNU General Public License as published by the Free Software *
7 * Foundation; either version 2 of the License, or (at your option) any later *
8 * version. *
9 * *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
12 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License along with *
15 * this program. If not, see <http://www.gnu.org/licenses/>. *
16 ****************************************************************************************/
17
18 #define DEBUG_PREFIX "LastFmServiceSettings"
19
20 #include "LastFmServiceSettings.h"
21
22 #include "core/collections/QueryMaker.h"
23 #include "core/meta/Meta.h"
24 #include "core/support/Amarok.h"
25 #include "core/support/Debug.h"
26 #include "core-impl/collections/support/CollectionManager.h"
27 #include "network/NetworkAccessManagerProxy.h"
28 #include "ui_LastFmConfigWidget.h"
29
30 #include <KMessageBox>
31 #include <KPluginFactory>
32
33 #include <QCryptographicHash>
34 #include <QRegExpValidator>
35
36 #include <XmlQuery.h>
37
38 K_PLUGIN_FACTORY_WITH_JSON( LastFmServiceSettingsFactory, "amarok_service_lastfm_config.json", registerPlugin<LastFmServiceSettings>(); )
39
LastFmServiceSettings(QWidget * parent,const QVariantList & args)40 LastFmServiceSettings::LastFmServiceSettings( QWidget *parent, const QVariantList &args )
41 : KCModule( parent, args )
42 , m_config( LastFmServiceConfig::instance() )
43 {
44 m_configDialog = new Ui::LastFmConfigWidget;
45 m_configDialog->setupUi( this );
46
47 connect( m_config.data(), &LastFmServiceConfig::updated, this, &LastFmServiceSettings::onConfigUpdated );
48
49 connect( m_configDialog->kcfg_ScrobblerUsername, &QLineEdit::textChanged, this, &LastFmServiceSettings::settingsChanged );
50 connect( m_configDialog->kcfg_ScrobblerPassword, &QLineEdit::textChanged, this, &LastFmServiceSettings::settingsChanged );
51 connect( m_configDialog->kcfg_SubmitPlayedSongs, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
52 connect( m_configDialog->kcfg_RetrieveSimilarArtists, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
53 connect( m_configDialog->kcfg_ScrobbleComposer, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
54 connect( m_configDialog->kcfg_UseFancyRatingTags, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
55 connect( m_configDialog->kcfg_AnnounceCorrections, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
56 connect( m_configDialog->kcfg_FilterByLabel, &QCheckBox::stateChanged, this, &LastFmServiceSettings::settingsChanged );
57 connect( m_configDialog->kcfg_FilteredLabel, QOverload<const QString&>::of( &QComboBox::currentIndexChanged ), this, &LastFmServiceSettings::settingsChanged );
58 connect( m_configDialog->testLogin, &QPushButton::clicked, this, &LastFmServiceSettings::testLogin );
59
60 using namespace Collections;
61
62 QueryMaker *query = CollectionManager::instance()->queryMaker();
63 query->setQueryType( QueryMaker::Label );
64 connect( query, &QueryMaker::newLabelsReady, this, &LastFmServiceSettings::addNewLabels );
65 query->setAutoDelete( true );
66 query->run();
67 }
68
~LastFmServiceSettings()69 LastFmServiceSettings::~LastFmServiceSettings()
70 {
71 delete m_configDialog;
72 }
73
74 void
save()75 LastFmServiceSettings::save()
76 {
77 QString dialogUser = m_configDialog->kcfg_ScrobblerUsername->text();
78 QString dialogPass = m_configDialog->kcfg_ScrobblerPassword->text();
79
80 // clear the session key if credentials changed
81 if( m_config->username() != dialogUser || m_config->password() != dialogPass )
82 m_config->setSessionKey( QString() );
83
84 m_config->setUsername( dialogUser );
85 m_config->setPassword( dialogPass );
86 m_config->setScrobble( m_configDialog->kcfg_SubmitPlayedSongs->isChecked() );
87 m_config->setFetchSimilar( m_configDialog->kcfg_RetrieveSimilarArtists->isChecked() );
88 m_config->setScrobbleComposer( m_configDialog->kcfg_ScrobbleComposer->isChecked() );
89 m_config->setUseFancyRatingTags( m_configDialog->kcfg_UseFancyRatingTags->isChecked() );
90 m_config->setAnnounceCorrections( m_configDialog->kcfg_AnnounceCorrections->isChecked() );
91 m_config->setFilterByLabel( m_configDialog->kcfg_FilterByLabel->isChecked() );
92 m_config->setFilteredLabel( m_configDialog->kcfg_FilteredLabel->currentText() );
93 m_config->save();
94
95 KCModule::save();
96 }
97
98 void
testLogin()99 LastFmServiceSettings::testLogin()
100 {
101 m_configDialog->testLogin->setEnabled( false );
102 m_configDialog->testLogin->setText( i18n( "Testing..." ) );
103 // set the global static Lastfm::Ws stuff
104 lastfm::ws::ApiKey = Amarok::lastfmApiKey();
105 lastfm::ws::SharedSecret = Amarok::lastfmApiSharedSecret();
106 lastfm::ws::setScheme(lastfm::ws::Https);
107 if( lastfm::nam() != The::networkAccessManager() )
108 lastfm::setNetworkAccessManager( The::networkAccessManager() );
109
110 debug() << "username:" << QString( QUrl::toPercentEncoding( m_configDialog->kcfg_ScrobblerUsername->text().toUtf8() ) );
111
112 QMap<QString, QString> query;
113
114 query[ "method" ] = "auth.getMobileSession";
115 query[ "password" ] = m_configDialog->kcfg_ScrobblerPassword->text().toUtf8();
116 query[ "username" ] = m_configDialog->kcfg_ScrobblerUsername->text().toUtf8();
117 m_authQuery = lastfm::ws::post( query );
118
119 connect( m_authQuery, &QNetworkReply::finished, this, &LastFmServiceSettings::onAuthenticated );
120 connect( m_authQuery, QOverload<QNetworkReply::NetworkError>::of( &QNetworkReply::error ),
121 this, &LastFmServiceSettings::onError );
122 }
123
124 void
onAuthenticated()125 LastFmServiceSettings::onAuthenticated()
126 {
127 lastfm::XmlQuery lfm;
128 lfm.parse( m_authQuery->readAll() );
129
130 switch( m_authQuery->error() )
131 {
132 case QNetworkReply::NoError:
133 debug() << "NoError";
134 if( lfm.children( "error" ).size() > 0 )
135 {
136 debug() << "ERROR from last.fm:" << lfm.text();
137 m_configDialog->testLogin->setText( i18nc( "The operation was rejected by the server", "Failed" ) );
138 m_configDialog->testLogin->setEnabled( true );
139
140 } else
141 {
142 m_configDialog->testLogin->setText( i18nc( "The operation completed as expected", "Success" ) );
143 m_configDialog->testLogin->setEnabled( false );
144 m_configDialog->kcfg_SubmitPlayedSongs->setEnabled( true );
145 }
146 break;
147
148 case QNetworkReply::AuthenticationRequiredError:
149 debug() << "AuthenticationFailed";
150 KMessageBox::error( this, i18n( "Either the username or the password is incorrect, please correct and try again" ), i18n( "Failed" ) );
151 m_configDialog->testLogin->setText( i18n( "Test Login" ) );
152 m_configDialog->testLogin->setEnabled( true );
153 break;
154
155 default:
156 debug() << "Unhandled QNetworkReply state, probably not important";
157 }
158 m_authQuery->deleteLater();
159 }
160
161 void
onError(QNetworkReply::NetworkError code)162 LastFmServiceSettings::onError( QNetworkReply::NetworkError code )
163 {
164 if( code == QNetworkReply::NoError )
165 return;
166
167 if( code == QNetworkReply::AuthenticationRequiredError )
168 {
169 onAuthenticated();
170 return;
171 }
172
173 KMessageBox::error( this, i18n( "Unable to connect to Last.fm service." ), i18n( "Failed" ) );
174 m_configDialog->testLogin->setText( i18n( "Test Login" ) );
175 m_configDialog->testLogin->setEnabled( true );
176
177 debug() << "Error occurred during network request: " << m_authQuery->errorString();
178 m_authQuery->deleteLater();
179 }
180
181 void
onConfigUpdated()182 LastFmServiceSettings::onConfigUpdated()
183 {
184 load();
185 }
186
187 void
load()188 LastFmServiceSettings::load()
189 {
190 m_configDialog->kcfg_ScrobblerUsername->setText( m_config->username() );
191 m_configDialog->kcfg_ScrobblerPassword->setText( m_config->password() );
192 m_configDialog->kcfg_SubmitPlayedSongs->setChecked( m_config->scrobble() );
193 m_configDialog->kcfg_RetrieveSimilarArtists->setChecked( m_config->fetchSimilar() );
194 m_configDialog->kcfg_ScrobbleComposer->setChecked( m_config->scrobbleComposer() );
195 m_configDialog->kcfg_UseFancyRatingTags->setChecked( m_config->useFancyRatingTags() );
196 m_configDialog->kcfg_AnnounceCorrections->setChecked( m_config->announceCorrections() );
197 m_configDialog->kcfg_FilterByLabel->setChecked( m_config->filterByLabel() );
198 m_configDialog->kcfg_FilteredLabel->setCurrentIndex( filteredLabelComboIndex( m_config->filteredLabel() ) );
199
200 if( !m_config->username().isEmpty() && !m_config->password().isEmpty() )
201 m_configDialog->kcfg_SubmitPlayedSongs->setEnabled( true );
202
203 KCModule::load();
204 }
205
206 void
defaults()207 LastFmServiceSettings::defaults()
208 {
209 m_configDialog->kcfg_SubmitPlayedSongs->setChecked( m_config->defaultScrobble() );
210 m_configDialog->kcfg_RetrieveSimilarArtists->setChecked( m_config->defaultFetchSimilar() );
211 m_configDialog->kcfg_ScrobbleComposer->setChecked( m_config->defaultScrobbleComposer() );
212 m_configDialog->kcfg_UseFancyRatingTags->setChecked( m_config->defaultUseFancyRatingTags() );
213 m_configDialog->kcfg_AnnounceCorrections->setChecked( m_config->defaultAnnounceCorrections() );
214 m_configDialog->kcfg_FilterByLabel->setChecked( m_config->defaultFilterByLabel() );
215 m_configDialog->kcfg_FilteredLabel->setCurrentIndex( filteredLabelComboIndex( m_config->defaultFilteredLabel() ) );
216 }
217
218 void
settingsChanged()219 LastFmServiceSettings::settingsChanged()
220 {
221 //TODO: Make pretty validation for username and password
222 //with error reporting
223
224 m_configDialog->testLogin->setText( i18n( "&Test Login" ) );
225 m_configDialog->testLogin->setEnabled( true );
226
227 emit changed( true );
228 }
229
230 void
addNewLabels(const Meta::LabelList & labels)231 LastFmServiceSettings::addNewLabels( const Meta::LabelList &labels )
232 {
233 foreach( const Meta::LabelPtr &label , labels )
234 m_configDialog->kcfg_FilteredLabel->addItem( label->name() );
235 }
236
237 int
filteredLabelComboIndex(const QString & label)238 LastFmServiceSettings::filteredLabelComboIndex( const QString &label )
239 {
240 int index = m_configDialog->kcfg_FilteredLabel->findText( label );
241 if( index == -1)
242 {
243 m_configDialog->kcfg_FilteredLabel->addItem( label );
244 return m_configDialog->kcfg_FilteredLabel->findText( label );
245 }
246 else
247 return index;
248 }
249
250 #include "LastFmServiceSettings.moc"
251