Add a GUI to set username/password for last.fm scrobbling in JuK.

FEATURE:
BUG:262194


svn path=/trunk/KDE/kdemultimedia/juk/; revision=1281831
parent 62c3c0ae
......@@ -76,6 +76,7 @@ set(juk_SRCS ${tunepimp_SRCS}
playlistsearch.cpp
playlistsplitter.cpp
scrobbler.cpp
scrobbleconfigdlg.cpp
searchplaylist.cpp
searchwidget.cpp
slideraction.cpp
......
......@@ -49,6 +49,7 @@
#include "keydialog.h"
#include "tagguesserconfigdlg.h"
#include "filerenamerconfigdlg.h"
#include "scrobbleconfigdlg.h"
#include "actioncollection.h"
#include "cache.h"
#include "playlistsplitter.h"
......@@ -312,6 +313,9 @@ void JuK::setupActions()
act = collection->addAction("fileRenamerConfig", this, SLOT(slotConfigureFileRenamer()));
act->setText(i18n("&File Renamer..."));
act = collection->addAction("scrobblerConfig", this, SLOT(slotConfigureScrobbling()));
act->setText(i18n("&Configure scrobbling..."));
//////////////////////////////////////////////////
// just in the toolbar
......@@ -573,6 +577,12 @@ void JuK::slotConfigureFileRenamer()
FileRenamerConfigDlg(this).exec();
}
void JuK::slotConfigureScrobbling()
{
ScrobbleConfigDlg(this).exec();
}
void JuK::slotUndo()
{
TagTransactionManager::instance()->undo();
......
......@@ -73,6 +73,7 @@ private slots:
void slotEditKeys();
void slotConfigureTagGuesser();
void slotConfigureFileRenamer();
void slotConfigureScrobbling();
void slotUndo();
void slotCheckAlbumNextAction(bool albumRandomEnabled);
void slotProcessArgs();
......
......@@ -72,6 +72,7 @@
<!-- <Action name="saveUpcomingTracks" append="show_merge"/> -->
<Action name="tagGuesserConfig" append="save_merge"/>
<Action name="fileRenamerConfig" append="save_merge"/>
<Action name="scrobblerConfig" append="save_merge"/>
<Action name="outputSelect" append="save_merge"/>
</Menu>
</MenuBar>
......
......@@ -74,6 +74,7 @@
<!-- <Action name="saveUpcomingTracks" append="show_merge"/> -->
<Action name="tagGuesserConfig" append="save_merge"/>
<Action name="fileRenamerConfig" append="save_merge"/>
<Action name="scrobblerConfig" append="save_merge"/>
<Action name="outputSelect" append="save_merge"/>
</Menu>
</MenuBar>
......
......@@ -43,6 +43,7 @@ static const char nathan[] = I18N_NOOP("Album cover manager");
static const char pascal[] = I18N_NOOP("Gimper of splash screen");
static const char laurent[] = I18N_NOOP("Porting to KDE 4 when no one else was around");
static const char giorgos[] = I18N_NOOP("Badly-needed tag editor bugfixes.");
static const char sandsmark[] = I18N_NOOP("Last.fm scrobbling support.");
int main(int argc, char *argv[])
{
......@@ -69,6 +70,7 @@ int main(int argc, char *argv[])
aboutData.addCredit(ki18n("Pascal Klein"), ki18n(pascal), "4pascal@tpg.com.au");
aboutData.addCredit(ki18n("Laurent Montel"), ki18n(laurent), "montel@kde.org");
aboutData.addCredit(ki18n("Georg Grabler"), ki18n(georg), "georg@grabler.net");
aboutData.addCredit(ki18n("Martin Sandsmark"), ki18n(sandsmark), "martin.sandsmark@kde.org");
KCmdLineArgs::init(argc, argv, &aboutData);
......
/***************************************************************************
begin : Tue Feb 23 2012
copyright : (C) 2012 by Martin Sandsmark
email : martin.sandsmark@kde.org
***************************************************************************/
/***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "scrobbleconfigdlg.h"
#include "scrobbler.h"
#include <KLineEdit>
#include <KPushButton>
#include <KLocalizedString>
#include <QLayout>
#include <QLabel>
#include <QFormLayout>
ScrobbleConfigDlg::ScrobbleConfigDlg(QWidget* parent, Qt::WindowFlags f)
: KDialog(parent, f)
{
setWindowTitle(i18n("Configure scrobbling..."));
setButtons(Apply | Cancel);
m_passwordEdit = new KLineEdit(this);
m_passwordEdit->setPasswordMode(true);
m_usernameEdit = new KLineEdit(this);
m_testButton = new KPushButton(i18n("Test login..."), this);
m_testFeedbackLabel = new QLabel("");
QWidget *mainWidget = new QWidget();
QFormLayout *layout = new QFormLayout();
mainWidget->setLayout(layout);
QLabel *infoLabel = new QLabel(i18n("Please enter your <a href=\"http://last.fm/\">last.fm</a> login credentials:"));
infoLabel->setOpenExternalLinks(true);
infoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
layout->addRow(infoLabel);
layout->addRow(new QLabel(i18n("Username:")), m_usernameEdit);
layout->addRow(new QLabel(i18n("Password:")), m_passwordEdit);
layout->addRow(m_testButton);
layout->addRow(m_testFeedbackLabel);
connect(m_passwordEdit, SIGNAL(textEdited(QString)), this, SLOT(valuesChanged()));
connect(m_usernameEdit, SIGNAL(textEdited(QString)), this, SLOT(valuesChanged()));
connect(m_testButton, SIGNAL(clicked(bool)), this, SLOT(testLogin()));
connect(this, SIGNAL(applyClicked()), this, SLOT(save()));
setMainWidget(mainWidget);
KConfigGroup config(KGlobal::config(), "Scrobbling");
m_usernameEdit->setText(config.readEntry("Username", ""));//TODO: use kwallet
m_passwordEdit->setText(config.readEntry("Password", ""));//TODO: use kwallet
if (m_passwordEdit->text().isEmpty() || m_usernameEdit->text().isEmpty())
button(Apply)->setEnabled(false);
}
void ScrobbleConfigDlg::valuesChanged()
{
button(Apply)->setEnabled(false);
}
void ScrobbleConfigDlg::save()
{
QDialog::accept();
KConfigGroup config(KGlobal::config(), "Scrobbling");
config.writeEntry("Username", m_usernameEdit->text());
config.writeEntry("Password", m_passwordEdit->text());
}
void ScrobbleConfigDlg::testLogin()
{
m_testFeedbackLabel->setText(i18n("Validating login..."));
Scrobbler *scrobbler = new Scrobbler(this);
connect(scrobbler, SIGNAL(validAuth()), this, SLOT(validLogin()));
connect(scrobbler, SIGNAL(invalidAuth()), this, SLOT(invalidLogin()));
setEnabled(false);
scrobbler->getAuthToken(m_usernameEdit->text(), m_passwordEdit->text());
}
void ScrobbleConfigDlg::invalidLogin()
{
m_testFeedbackLabel->setText(i18n("Login invalid!"));
setEnabled(true);
sender()->deleteLater();
button(Apply)->setEnabled(false);
}
void ScrobbleConfigDlg::validLogin()
{
m_testFeedbackLabel->setText(i18n("Login valid!"));
setEnabled(true);
sender()->deleteLater();
button(Apply)->setEnabled(true);
}
/***************************************************************************
begin : Tue Feb 23 2012
copyright : (C) 2012 by Martin Sandsmark
email : martin.sandsmark@kde.org
***************************************************************************/
/***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef SCROBBLESETTINGS_H
#define SCROBBLESETTINGS_H
#include <KDialog>
class KLineEdit;
class KPushButton;
class QLabel;
class ScrobbleConfigDlg : public KDialog
{
Q_OBJECT
public:
explicit ScrobbleConfigDlg(QWidget* parent = 0, Qt::WindowFlags f = 0);
private slots:
void testLogin();
void validLogin();
void invalidLogin();
void save();
void valuesChanged();
private:
KLineEdit *m_usernameEdit;
KLineEdit *m_passwordEdit;
KPushButton *m_testButton;
QLabel *m_testFeedbackLabel;
};
#endif//SCROBBLESETTINGS_H
\ No newline at end of file
/***************************************************************************
begin : Tue Feb 21 2012
copyright : (C) 2012 by Martin Sandsmark
email : martin.sandsmark@kde.org
***************************************************************************/
/***************************************************************************
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "scrobbler.h"
#include <kglobal.h>
#include <kconfiggroup.h>
......@@ -15,8 +30,8 @@
Scrobbler::Scrobbler(QObject* parent): QObject(parent)
{
KConfigGroup config(KGlobal::config(), "Scrobbling");
m_sessionKey = config.readEntry("SessionKey", "");//TODO: use kwallet
if (m_sessionKey.isEmpty())
QString sessionKey = config.readEntry("SessionKey", "");//TODO: use kwallet
if (sessionKey.isEmpty())
getAuthToken();
}
......@@ -43,17 +58,8 @@ void Scrobbler::sign(QMap< QString, QString >& params)
params["api_sig"] = md5(s.toUtf8());
}
void Scrobbler::getAuthToken()
{
kDebug() << "Getting new auth token...";
KConfigGroup config(KGlobal::config(), "Scrobbling");
QString username = config.readEntry("Username", "");//TODO: use kwallet
QString password = config.readEntry("Password", "");//TODO: use kwallet
if (username.isEmpty() || password.isEmpty())
return;
void Scrobbler::getAuthToken(QString username, QString password)
{
QByteArray authToken = md5((username + md5(password.toUtf8() )).toUtf8());
QMap<QString, QString> params;
......@@ -74,39 +80,57 @@ void Scrobbler::getAuthToken()
connect(reply, SIGNAL(finished()), this, SLOT(handleAuthenticationReply()));
}
void Scrobbler::getAuthToken()
{
kDebug() << "Getting new auth token...";
KConfigGroup config(KGlobal::config(), "Scrobbling");
QString username = config.readEntry("Username", "");//TODO: use kwallet
QString password = config.readEntry("Password", "");//TODO: use kwallet
if (username.isEmpty() || password.isEmpty())
return;
getAuthToken(username, password);
}
void Scrobbler::handleAuthenticationReply()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
qWarning() << "got authentication reply";
kDebug() << "got authentication reply";
if (reply->error() != QNetworkReply::NoError) {
qWarning() << reply->errorString();
emit invalidAuth();
kWarning() << "Error while getting authentication reply" << reply->errorString();
return;
}
QDomDocument doc;
QByteArray data = reply->readAll();
qWarning() << data;
doc.setContent(data);
QDomElement el = doc.documentElement();
m_sessionKey = el.firstChildElement("session").firstChildElement("key").text();
QString sessionKey = el.firstChildElement("session").firstChildElement("key").text();
if (sessionKey.isEmpty()) {
emit invalidAuth();
kWarning() << "Unable to get session key" << data;
return;
}
KConfigGroup config(KGlobal::config(), "Scrobbling");
config.writeEntry("SessionKey", m_sessionKey);
return;
config.writeEntry("SessionKey", sessionKey);
emit validAuth();
}
void Scrobbler::nowPlaying(const FileHandle& file)
{
if (m_sessionKey.isEmpty()) {
KConfigGroup config(KGlobal::config(), "Scrobbling");
QString sessionKey = config.readEntry("SessionKey", "");//TODO: use kwallet
if (sessionKey.isEmpty()) {
getAuthToken();
return;
}
qWarning() << "Now playing" << file.tag()->title();
QMap<QString, QString> params;
params["method"] = "track.updateNowPlaying";
params["sk"] = m_sessionKey;
params["sk"] = sessionKey;
params["track"] = file.tag()->title();
params["artist"] = file.tag()->artist();
......@@ -123,16 +147,18 @@ void Scrobbler::nowPlaying(const FileHandle& file)
void Scrobbler::scrobble()
{
if (m_sessionKey.isEmpty()) {
KConfigGroup config(KGlobal::config(), "Scrobbling");
QString sessionKey = config.readEntry("SessionKey", "");//TODO: use kwallet
if (sessionKey.isEmpty()) {
getAuthToken();
return;
}
qWarning() << "Scrobbling" << m_file.tag()->title();
kDebug() << "Scrobbling" << m_file.tag()->title();
QMap<QString, QString> params;
params["method"] = "track.scrobble";
params["sk"] = m_sessionKey;
params["sk"] = sessionKey;
params["timestamp"] = QString::number(m_startedPlaying);
......@@ -167,7 +193,6 @@ void Scrobbler::handleResults()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
QByteArray data = reply->readAll();
qWarning() << data;
if (data.contains("code=\"9\"")) // We need a new token
getAuthToken();
}
......@@ -35,12 +35,16 @@ public:
public slots:
void nowPlaying(const FileHandle&);
void scrobble();
void getAuthToken(QString username, QString password);
private slots:
void getAuthToken();
void handleAuthenticationReply();
void handleResults();
void getAuthToken();
signals:
void invalidAuth();
void validAuth();
private:
void sign(QMap<QString, QString> &request);
......@@ -49,7 +53,6 @@ private:
FileHandle m_file;
qint64 m_startedPlaying;
QString m_sessionKey;
};
#endif /* SCROBBLER_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment