Initial support from premium digitally imported streams.
NOTE: This has *not* been tested - as I have no account!!!
This commit is contained in:
committed by
craig.p.drummond
parent
dffe99f038
commit
811c64d507
@@ -92,12 +92,12 @@ set(CANTATA_SRCS gui/application.cpp gui/main.cpp gui/initialsettingswizard.cpp
|
||||
gui/settings.cpp gui/covers.cpp gui/filesettings.cpp gui/interfacesettings.cpp gui/playbacksettings.cpp
|
||||
gui/serversettings.cpp gui/librarypage.cpp gui/albumspage.cpp gui/folderpage.cpp gui/playlistspage.cpp gui/trayitem.cpp
|
||||
gui/cachesettings.cpp gui/coverdialog.cpp gui/stdactions.cpp
|
||||
streams/streamspage.cpp streams/streamdialog.cpp streams/streamfetcher.cpp
|
||||
streams/streamspage.cpp streams/streamdialog.cpp streams/streamfetcher.cpp streams/digitallyimportedsettings.cpp
|
||||
models/musiclibraryitemroot.cpp models/musiclibraryitemartist.cpp models/musiclibraryitemalbum.cpp models/musiclibrarymodel.cpp
|
||||
models/musiclibraryproxymodel.cpp models/playlistsmodel.cpp models/playlistsproxymodel.cpp models/playqueuemodel.cpp
|
||||
models/playqueueproxymodel.cpp models/dirviewmodel.cpp models/dirviewproxymodel.cpp models/dirviewitem.cpp models/dirviewitemdir.cpp
|
||||
models/streamsmodel.cpp models/streamsproxymodel.cpp models/albumsmodel.cpp models/albumsproxymodel.cpp models/proxymodel.cpp
|
||||
models/actionmodel.cpp
|
||||
models/actionmodel.cpp models/digitallyimported.cpp
|
||||
mpd/mpdconnection.cpp mpd/mpdparseutils.cpp mpd/mpdstats.cpp mpd/mpdstatus.cpp mpd/song.cpp mpd/mpduser.cpp
|
||||
dynamic/dynamic.cpp dynamic/dynamicpage.cpp dynamic/dynamicproxymodel.cpp dynamic/dynamicruledialog.cpp dynamic/dynamicrulesdialog.cpp
|
||||
widgets/treeview.cpp widgets/listview.cpp widgets/itemview.cpp widgets/autohidingsplitter.cpp widgets/timeslider.cpp
|
||||
@@ -114,10 +114,10 @@ set(CANTATA_MOC_HDRS
|
||||
gui/initialsettingswizard.h gui/mainwindow.h gui/settings.h gui/covers.h gui/folderpage.h gui/librarypage.h gui/albumspage.h
|
||||
gui/playlistspage.h gui/playbacksettings.h gui/serversettings.h gui/preferencesdialog.h gui/filesettings.h
|
||||
gui/interfacesettings.h gui/cachesettings.h gui/trayitem.h gui/coverdialog.h
|
||||
streams/streamspage.h streams/streamdialog.h streams/streamfetcher.h
|
||||
streams/streamspage.h streams/streamdialog.h streams/streamfetcher.h streams/digitallyimportedsettings.h
|
||||
models/musiclibrarymodel.h models/musiclibraryproxymodel.h models/playlistsmodel.h models/playlistsproxymodel.h models/playqueuemodel.h
|
||||
models/playqueueproxymodel.h models/dirviewmodel.h models/dirviewproxymodel.h models/albumsmodel.h models/streamsmodel.h
|
||||
models/actionmodel.h
|
||||
models/actionmodel.h models/digitallyimported.h
|
||||
mpd/mpdconnection.h mpd/mpdstats.h mpd/mpdstatus.h
|
||||
dynamic/dynamic.h dynamic/dynamicpage.h dynamic/dynamicruledialog.h dynamic/dynamicrulesdialog.h
|
||||
widgets/treeview.h widgets/listview.h widgets/itemview.h widgets/autohidingsplitter.h widgets/timeslider.h widgets/actionlabel.h
|
||||
@@ -131,7 +131,7 @@ set(CANTATA_MOC_HDRS
|
||||
set(CANTATA_UIS
|
||||
gui/initialsettingswizard.ui gui/mainwindow.ui gui/folderpage.ui gui/librarypage.ui gui/albumspage.ui gui/playlistspage.ui
|
||||
gui/filesettings.ui gui/interfacesettings.ui gui/playbacksettings.ui gui/serversettings.ui gui/coverdialog.ui
|
||||
streams/streamspage.ui
|
||||
streams/streamspage.ui streams/digitallyimportedsettings.ui
|
||||
dynamic/dynamicpage.ui dynamic/dynamicrule.ui dynamic/dynamicrules.ui
|
||||
context/togglelist.ui context/othersettings.ui
|
||||
widgets/itemview.ui)
|
||||
|
||||
207
models/digitallyimported.cpp
Normal file
207
models/digitallyimported.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Cantata
|
||||
*
|
||||
* Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com>
|
||||
*
|
||||
* ----
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "digitallyimported.h"
|
||||
#include "settings.h"
|
||||
#include "networkaccessmanager.h"
|
||||
#include "qjson/parser.h"
|
||||
#include "localize.h"
|
||||
#include <QNetworkRequest>
|
||||
#include <QTime>
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
#include <KDE/KGlobal>
|
||||
K_GLOBAL_STATIC(DigitallyImported, instance)
|
||||
#endif
|
||||
|
||||
static const char * constDiGroup="DigitallyImported";
|
||||
static const QStringList constPremiumValues=QStringList() << QLatin1String("premium_high") << QLatin1String("premium_medium") << QLatin1String("premium");
|
||||
static const QUrl constAuthUrl(QLatin1String("http://api.audioaddict.com/v1/di/members/authenticate"));
|
||||
const QString DigitallyImported::constApiUserName=QLatin1String("ephemeron");
|
||||
const QString DigitallyImported::constApiPassword=QLatin1String("dayeiph0ne@pp");
|
||||
const QString DigitallyImported::constPublicValue=QLatin1String("public3");
|
||||
|
||||
DigitallyImported * DigitallyImported::self()
|
||||
{
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
return instance;
|
||||
#else
|
||||
static DigitallyImported *instance=0;
|
||||
if(!instance) {
|
||||
instance=new DigitallyImported;
|
||||
}
|
||||
return instance;
|
||||
#endif
|
||||
}
|
||||
|
||||
DigitallyImported::DigitallyImported()
|
||||
: job(0)
|
||||
, streamType(0)
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
DigitallyImported::~DigitallyImported()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
void DigitallyImported::login()
|
||||
{
|
||||
if (job) {
|
||||
job->deleteLater();
|
||||
job=0;
|
||||
}
|
||||
QNetworkRequest req(constAuthUrl);
|
||||
addAuthHeader(req);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
job=NetworkAccessManager::self()->post(req, "username="+QUrl::toPercentEncoding(userName)+"&password="+QUrl::toPercentEncoding(password));
|
||||
connect(job, SIGNAL(finished()), SLOT(loginResponse()));
|
||||
}
|
||||
|
||||
void DigitallyImported::addAuthHeader(QNetworkRequest &req) const
|
||||
{
|
||||
#if QT_VERSION < 0x050000
|
||||
req.setRawHeader("Authorization", "Basic "+QString("%1:%2").arg(constApiUserName, constApiPassword).toAscii().toBase64());
|
||||
#else
|
||||
req.setRawHeader("Authorization", "Basic "+QString("%1:%2").arg(constApiUserName, constApiPassword).toLatin1().toBase64());
|
||||
#endif
|
||||
}
|
||||
|
||||
void DigitallyImported::load()
|
||||
{
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
KConfigGroup cfg(KGlobal::config(), constDiGroup);
|
||||
#else
|
||||
QSettings cfg;
|
||||
cfg.beginGroup(constDiGroup);
|
||||
#endif
|
||||
userName=GET_STRING("userName", userName);
|
||||
password=GET_STRING("password", password);
|
||||
listenHash=GET_STRING("listenHash", listenHash);
|
||||
streamType=GET_INT("streamType", streamType);
|
||||
QString ex=GET_STRING("expires", QString());
|
||||
|
||||
status=i18n("Not logged in");
|
||||
if (ex.isEmpty()) {
|
||||
listenHash=QString();
|
||||
} else {
|
||||
expires=QDateTime::fromString(ex, Qt::ISODate);
|
||||
// If we have expired, or are about to expire in 5 minutes, then clear the hash...
|
||||
if (QDateTime::currentDateTime().secsTo(expires)<(5*60)) {
|
||||
listenHash=QString();
|
||||
} else if (!listenHash.isEmpty()) {
|
||||
status=i18n("Logged in");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DigitallyImported::save()
|
||||
{
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
KConfigGroup cfg(KGlobal::config(), constDiGroup);
|
||||
#else
|
||||
QSettings cfg;
|
||||
cfg.beginGroup(constDiGroup);
|
||||
#endif
|
||||
|
||||
SET_VALUE("userName", userName);
|
||||
SET_VALUE("password", password);
|
||||
SET_VALUE("listenHash", listenHash);
|
||||
SET_VALUE("streamType", streamType);
|
||||
SET_VALUE("expires", expires.toString(Qt::ISODate));
|
||||
|
||||
#ifndef ENABLE_KDE_SUPPORT
|
||||
cfg.endGroup();
|
||||
#endif
|
||||
CFG_SYNC;
|
||||
}
|
||||
|
||||
QString DigitallyImported::modifyUrl(const QString &u) const
|
||||
{
|
||||
if (listenHash.isEmpty()) {
|
||||
return u;
|
||||
}
|
||||
QString premValue=constPremiumValues.at(streamType>0 && streamType<constPremiumValues.count() ? streamType : 0);
|
||||
QString url=u;
|
||||
return url.replace(constPublicValue, premValue)+QLatin1String("?hash=")+listenHash;
|
||||
}
|
||||
|
||||
void DigitallyImported::loginResponse()
|
||||
{
|
||||
QNetworkReply *reply=dynamic_cast<QNetworkReply *>(sender());
|
||||
|
||||
if (!reply) {
|
||||
return;
|
||||
}
|
||||
reply->deleteLater();
|
||||
|
||||
if (reply!=job) {
|
||||
return;
|
||||
}
|
||||
job=0;
|
||||
|
||||
status=listenHash=QString();
|
||||
const int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
if (403==httpStatus) {
|
||||
status=reply->readAll();
|
||||
emit loginStatus(false, status);
|
||||
return;
|
||||
} else if (200!=httpStatus) {
|
||||
status=i18n("Unknown error");
|
||||
emit loginStatus(false, status);
|
||||
return;
|
||||
}
|
||||
|
||||
QJson::Parser parser;
|
||||
QVariantMap data = parser.parse(reply).toMap();
|
||||
|
||||
if (!data.contains("subscriptions")) {
|
||||
status=i18n("No subscriptions");
|
||||
emit loginStatus(false, status);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantList subscriptions = data.value("subscriptions", QVariantList()).toList();
|
||||
if (subscriptions.isEmpty() || QLatin1String("active")!=subscriptions[0].toMap().value("status").toString()) {
|
||||
status=i18n("You do not have an active subscription");
|
||||
emit loginStatus(false, status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!subscriptions[0].toMap().contains("expires_on") || !data.contains("listen_key")) {
|
||||
status=i18n("Unknown error");
|
||||
emit loginStatus(false, status);
|
||||
return;
|
||||
}
|
||||
|
||||
QDateTime ex = QDateTime::fromString(subscriptions[0].toMap()["expires_on"].toString(), Qt::ISODate);
|
||||
QString lh = data["listen_key"].toString();
|
||||
|
||||
if (ex!=expires || lh!=listenHash) {
|
||||
expires=ex;
|
||||
listenHash=lh;
|
||||
save();
|
||||
}
|
||||
status=i18n("Logged in (expiry:%1)").arg(expires.toString(Qt::ISODate));
|
||||
emit loginStatus(true, status);
|
||||
}
|
||||
83
models/digitallyimported.h
Normal file
83
models/digitallyimported.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Cantata
|
||||
*
|
||||
* Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com>
|
||||
*
|
||||
* ----
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef DIGITALLYIMPORTED_H
|
||||
#define DIGITALLYIMPORTED_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
|
||||
class QNetworkRequest;
|
||||
class QNetworkReply;
|
||||
|
||||
class DigitallyImported : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static const QString constApiUserName;
|
||||
static const QString constApiPassword;
|
||||
static const QString constPublicValue;
|
||||
static DigitallyImported * self();
|
||||
|
||||
DigitallyImported();
|
||||
~DigitallyImported();
|
||||
|
||||
void addAuthHeader(QNetworkRequest &req) const;
|
||||
void load();
|
||||
void save();
|
||||
bool haveAccount() const { return !userName.isEmpty() && !password.isEmpty(); }
|
||||
bool loggedIn() const { return !listenHash.isEmpty(); }
|
||||
|
||||
const QString & user() const { return userName; }
|
||||
const QString & pass() const { return password; }
|
||||
int audioType() const { return streamType; }
|
||||
const QDateTime & sessionExpiry() const { return expires; }
|
||||
void setUser(const QString &u) { userName=u; }
|
||||
void setPass(const QString &p) { password=p; }
|
||||
void setAudioType(int a) { streamType=a; }
|
||||
|
||||
const QString & statusString() const { return status; }
|
||||
|
||||
QString modifyUrl(const QString &u) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void login();
|
||||
|
||||
Q_SIGNALS:
|
||||
void loginStatus(bool ok, const QString &msg);
|
||||
|
||||
private Q_SLOTS:
|
||||
void loginResponse();
|
||||
|
||||
private:
|
||||
QNetworkReply *job;
|
||||
QString status;
|
||||
QString userName;
|
||||
QString password;
|
||||
QString listenHash;
|
||||
QDateTime expires;
|
||||
int streamType;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "itemview.h"
|
||||
#include "action.h"
|
||||
#include "stdactions.h"
|
||||
#include "digitallyimported.h"
|
||||
#include "qjson/parser.h"
|
||||
#include "qtiocompressor/qtiocompressor.h"
|
||||
#include <QModelIndex>
|
||||
@@ -44,13 +45,14 @@
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QTimer>
|
||||
#if QT_VERSION >= 0x050000
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QUrlQuery>
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QDesktopServices>
|
||||
#endif
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
#include <KDE/KGlobal>
|
||||
K_GLOBAL_STATIC(StreamsModel, instance)
|
||||
#endif
|
||||
|
||||
@@ -82,9 +84,7 @@ static QString constJazzRadioUrl=QLatin1String("http://www.jazzradio.com");
|
||||
static QString constRockRadioUrl=QLatin1String("http://www.rockradio.com");
|
||||
static QString constSkyFmUrl=QLatin1String("http://www.sky.fm");
|
||||
static QStringList constDiUrls=QStringList() << constDigitiallyImportedUrl << constJazzRadioUrl << constSkyFmUrl << constRockRadioUrl;
|
||||
static const char * constDiApiUsername="ephemeron";
|
||||
static const char * constDiApiPassword="dayeiph0ne@pp";
|
||||
//static const QString constDiAuthUrl=QLatin1String("http://api.audioaddict.com/v1/%1/members/authenticate");
|
||||
|
||||
static const QString constDiChannelListHost=QLatin1String("api.v2.audioaddict.com");
|
||||
static const QString constDiChannelListUrl=QLatin1String("http://")+constDiChannelListHost+("/v1/%1/mobile/batch_update?asset_group_key=mobile_icons&stream_set_key=");
|
||||
static const QString constDiStdUrl=QLatin1String("http://%1/public3/%2.pls");
|
||||
@@ -283,11 +283,7 @@ void StreamsModel::fetchMore(const QModelIndex &index)
|
||||
QNetworkRequest req;
|
||||
if (constDiUrls.contains(cat->url)) {
|
||||
req=QNetworkRequest(constDiChannelListUrl.arg(cat->url.split(".").at(1)));
|
||||
#if QT_VERSION < 0x050000
|
||||
req.setRawHeader("Authorization", "Basic "+QString("%1:%2").arg(constDiApiUsername, constDiApiPassword).toAscii().toBase64());
|
||||
#else
|
||||
req.setRawHeader("Authorization", "Basic "+QString("%1:%2").arg(constDiApiUsername, constDiApiPassword).toLatin1().toBase64());
|
||||
#endif
|
||||
DigitallyImported::self()->addAuthHeader(req);
|
||||
} else if (QUrl(item->url).host()==constShoutCastHost) {
|
||||
req=QNetworkRequest(cat->url);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
@@ -459,13 +455,19 @@ QString StreamsModel::modifyUrl(const QString &u, bool addPrefix, const QString
|
||||
return MPDParseUtils::addStreamName(!addPrefix || !u.startsWith("http:") ? u : (constPrefix+u), name);
|
||||
}
|
||||
|
||||
static QString addDiHash(const StreamsModel::Item *item)
|
||||
{
|
||||
return item->parent && constDiUrls.contains(item->parent->url)
|
||||
? DigitallyImported::self()->modifyUrl(item->url) : item->url;
|
||||
}
|
||||
|
||||
static void filenames(QStringList &fn, bool addPrefix, const StreamsModel::CategoryItem *cat)
|
||||
{
|
||||
foreach (const StreamsModel::Item *i, cat->children) {
|
||||
if (i->isCategory()) {
|
||||
filenames(fn, addPrefix, static_cast<const StreamsModel::CategoryItem *>(i));
|
||||
::filenames(fn, addPrefix, static_cast<const StreamsModel::CategoryItem *>(i));
|
||||
} else if (!fn.contains(i->url) && StreamsModel::validProtocol(i->url)) {
|
||||
fn << StreamsModel::modifyUrl(i->url, addPrefix, i->name);
|
||||
fn << StreamsModel::modifyUrl(addDiHash(i), addPrefix, i->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,7 +481,7 @@ QStringList StreamsModel::filenames(const QModelIndexList &indexes, bool addPref
|
||||
if (item->isCategory()) {
|
||||
::filenames(fnames, addPrefix, static_cast<const StreamsModel::CategoryItem *>(item));
|
||||
} else if (!fnames.contains(item->url) && validProtocol(item->url)) {
|
||||
fnames << modifyUrl(item->url, addPrefix, item->name);
|
||||
fnames << modifyUrl(addDiHash(item), addPrefix, item->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QIcon>
|
||||
#include <QDateTime>
|
||||
|
||||
class QNetworkReply;
|
||||
class QXmlStreamReader;
|
||||
|
||||
126
streams/digitallyimportedsettings.cpp
Normal file
126
streams/digitallyimportedsettings.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Cantata
|
||||
*
|
||||
* Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com>
|
||||
*
|
||||
* ----
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "digitallyimportedsettings.h"
|
||||
#include "digitallyimported.h"
|
||||
#include "localize.h"
|
||||
#include "buddylabel.h"
|
||||
#include "lineedit.h"
|
||||
#include <QPushButton>
|
||||
#include <QComboBox>
|
||||
|
||||
DigitallyImportedSettings::DigitallyImportedSettings(QWidget *parent)
|
||||
: Dialog(parent)
|
||||
{
|
||||
setButtons(Ok|Cancel);
|
||||
setCaption(i18n("Digitally Imported Settings"));
|
||||
QWidget *mainWidet = new QWidget(this);
|
||||
setupUi(mainWidet);
|
||||
setMainWidget(mainWidet);
|
||||
|
||||
audio->addItem(i18n("MP3 256k"), 0);
|
||||
audio->addItem(i18n("AAC 64k"), 1);
|
||||
audio->addItem(i18n("AAC 128k"), 2);
|
||||
|
||||
connect(loginButton, SIGNAL(clicked()), this, SLOT(login()));
|
||||
connect(DigitallyImported::self(), SIGNAL(loginStatus(bool,QString)), SLOT(loginStatus(bool,QString)));
|
||||
|
||||
adjustSize();
|
||||
int h=fontMetrics().height();
|
||||
resize(h*30, height());
|
||||
}
|
||||
|
||||
void DigitallyImportedSettings::show()
|
||||
{
|
||||
prevUser=DigitallyImported::self()->user();
|
||||
prevPass=DigitallyImported::self()->pass();
|
||||
wasLoggedIn=DigitallyImported::self()->loggedIn();
|
||||
prevAudioType=DigitallyImported::self()->audioType();
|
||||
|
||||
if (DigitallyImported::self()->sessionExpiry().isValid()) {
|
||||
expiryLabel->setText(DigitallyImported::self()->sessionExpiry().toString(Qt::ISODate));
|
||||
} else {
|
||||
expiryLabel->setText(QString());
|
||||
}
|
||||
user->setText(prevUser);
|
||||
pass->setText(prevPass);
|
||||
|
||||
for (int i=0; i<audio->count(); ++i) {
|
||||
if (audio->itemData(i).toInt()==DigitallyImported::self()->audioType()) {
|
||||
audio->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
loginStatusLabel->setText(DigitallyImported::self()->statusString());
|
||||
if (QDialog::Accepted==Dialog::exec()) {
|
||||
QString u=user->text().trimmed();
|
||||
QString p=pass->text().trimmed();
|
||||
int at=audio->itemData(audio->currentIndex()).toInt();
|
||||
bool changed=false;
|
||||
bool needToLogin=false;
|
||||
if (u!=DigitallyImported::self()->user()) {
|
||||
DigitallyImported::self()->setUser(u);
|
||||
needToLogin=changed=true;
|
||||
}
|
||||
if (p!=DigitallyImported::self()->pass()) {
|
||||
DigitallyImported::self()->setPass(p);
|
||||
needToLogin=changed=true;
|
||||
}
|
||||
if (DigitallyImported::self()->audioType()!=at) {
|
||||
DigitallyImported::self()->setAudioType(at);
|
||||
changed=true;
|
||||
}
|
||||
if (needToLogin) {
|
||||
DigitallyImported::self()->login();
|
||||
}
|
||||
if (changed) {
|
||||
DigitallyImported::self()->save();
|
||||
}
|
||||
} else {
|
||||
DigitallyImported::self()->setUser(prevUser);
|
||||
DigitallyImported::self()->setPass(prevPass);
|
||||
DigitallyImported::self()->setAudioType(prevAudioType);
|
||||
if (wasLoggedIn) {
|
||||
DigitallyImported::self()->login();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DigitallyImportedSettings::login()
|
||||
{
|
||||
loginStatusLabel->setText(i18n("Logging in..."));
|
||||
DigitallyImported::self()->setUser(user->text().trimmed());
|
||||
DigitallyImported::self()->setPass(pass->text().trimmed());
|
||||
DigitallyImported::self()->login();
|
||||
}
|
||||
|
||||
void DigitallyImportedSettings::loginStatus(bool, const QString &msg)
|
||||
{
|
||||
loginStatusLabel->setText(msg);
|
||||
if (DigitallyImported::self()->sessionExpiry().isValid()) {
|
||||
expiryLabel->setText(DigitallyImported::self()->sessionExpiry().toString(Qt::ISODate));
|
||||
} else {
|
||||
expiryLabel->setText(QString());
|
||||
}
|
||||
}
|
||||
54
streams/digitallyimportedsettings.h
Normal file
54
streams/digitallyimportedsettings.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Cantata
|
||||
*
|
||||
* Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com>
|
||||
*
|
||||
* ----
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef DIGITALLYIMPORTED_SETTINGS_H
|
||||
#define DIGITALLYIMPORTED_SETTINGS_H
|
||||
|
||||
#include "dialog.h"
|
||||
#include "ui_digitallyimportedsettings.h"
|
||||
class LineEdit;
|
||||
class QComboBox;
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
|
||||
class DigitallyImportedSettings : public Dialog, public Ui::DigitallyImportedSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DigitallyImportedSettings(QWidget *parent);
|
||||
|
||||
void show();
|
||||
|
||||
private Q_SLOTS:
|
||||
void login();
|
||||
void loginStatus(bool, const QString &msg);
|
||||
|
||||
private:
|
||||
bool wasLoggedIn;
|
||||
QString prevUser;
|
||||
QString prevPass;
|
||||
int prevAudioType;
|
||||
};
|
||||
|
||||
#endif
|
||||
171
streams/digitallyimportedsettings.ui
Normal file
171
streams/digitallyimportedsettings.ui
Normal file
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DigitallyImportedSettings</class>
|
||||
<widget class="QWidget" name="DigitallyImportedSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>518</width>
|
||||
<height>252</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>To listen to higher quality streams, without advertisments, a premium account is required.<br><a href=\"http://www.di.fm/premium/\">Upgrade to Premium</a></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Premium Account</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="BuddyLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Username:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>user</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LineEdit" name="user"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="BuddyLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Password:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>pass</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LineEdit" name="pass">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="BuddyLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Stream type:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>audio</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="audio"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="BuddyLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Status:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>loginButton</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="loginButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Login</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="loginStatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Session expiry:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="expiryLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>6</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>lineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BuddyLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>buddylabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "settings.h"
|
||||
#include "streamsmodel.h"
|
||||
#include "statuslabel.h"
|
||||
#include "digitallyimported.h"
|
||||
#include "digitallyimportedsettings.h"
|
||||
#include <QToolButton>
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
#include <KDE/KFileDialog>
|
||||
@@ -55,7 +57,7 @@ StreamsPage::StreamsPage(QWidget *p)
|
||||
addAction = ActionCollection::get()->createAction("addstream", i18n("Add New Stream To Favourites"), Icons::self()->addRadioStreamIcon);
|
||||
addToFavouritesAction = ActionCollection::get()->createAction("addtofavourites", i18n("Add Stream To Favourites"), Icons::self()->addRadioStreamIcon);
|
||||
editAction = ActionCollection::get()->createAction("editstream", i18n("Edit"), Icons::self()->editIcon);
|
||||
|
||||
Action *settingsAct = new Action(i18n("Digitally Imported Settings"), this);
|
||||
replacePlayQueue->setDefaultAction(StdActions::self()->replacePlayQueueAction);
|
||||
// connect(view, SIGNAL(itemsSelected(bool)), addToPlaylist, SLOT(setEnabled(bool)));
|
||||
connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(itemDoubleClicked(const QModelIndex &)));
|
||||
@@ -66,16 +68,21 @@ StreamsPage::StreamsPage(QWidget *p)
|
||||
connect(editAction, SIGNAL(triggered(bool)), this, SLOT(edit()));
|
||||
connect(importAction, SIGNAL(triggered(bool)), this, SLOT(importXml()));
|
||||
connect(exportAction, SIGNAL(triggered(bool)), this, SLOT(exportXml()));
|
||||
connect(settingsAct, SIGNAL(triggered(bool)), this, SLOT(diSettings()));
|
||||
connect(StreamsModel::self(), SIGNAL(error(const QString &)), this, SIGNAL(error(const QString &)));
|
||||
connect(StreamsModel::self(), SIGNAL(loading()), view, SLOT(showSpinner()));
|
||||
connect(StreamsModel::self(), SIGNAL(loaded()), view, SLOT(hideSpinner()));
|
||||
connect(MPDConnection::self(), SIGNAL(dirChanged()), SLOT(mpdDirChanged()));
|
||||
connect(DigitallyImported::self(), SIGNAL(loginStatus(bool,QString)), SLOT(updateDiStatus()));
|
||||
QMenu *menu=new QMenu(this);
|
||||
menu->addAction(addAction);
|
||||
menu->addAction(StdActions::self()->removeAction);
|
||||
menu->addAction(editAction);
|
||||
menu->addSeparator();
|
||||
menu->addAction(importAction);
|
||||
menu->addAction(exportAction);
|
||||
menu->addSeparator();
|
||||
menu->addAction(settingsAct);
|
||||
menuButton->setMenu(menu);
|
||||
Icon::init(replacePlayQueue);
|
||||
|
||||
@@ -94,6 +101,7 @@ StreamsPage::StreamsPage(QWidget *p)
|
||||
|
||||
infoLabel->hide();
|
||||
infoLabel->setType(StatusLabel::Locked);
|
||||
updateDiStatus();
|
||||
}
|
||||
|
||||
StreamsPage::~StreamsPage()
|
||||
@@ -182,6 +190,12 @@ void StreamsPage::itemDoubleClicked(const QModelIndex &index)
|
||||
}
|
||||
}
|
||||
|
||||
void StreamsPage::diSettings()
|
||||
{
|
||||
DigitallyImportedSettings(this).show();
|
||||
updateDiStatus();
|
||||
}
|
||||
|
||||
void StreamsPage::importXml()
|
||||
{
|
||||
if (!StreamsModel::self()->isFavoritesWritable()) {
|
||||
@@ -397,3 +411,13 @@ void StreamsPage::controlActions()
|
||||
StdActions::self()->addWithPriorityAction->setEnabled(selected.count());
|
||||
menuButton->controlState();
|
||||
}
|
||||
|
||||
void StreamsPage::updateDiStatus()
|
||||
{
|
||||
if (DigitallyImported::self()->user().isEmpty() || DigitallyImported::self()->pass().isEmpty()) {
|
||||
diStatusLabel->setVisible(false);
|
||||
} else {
|
||||
diStatusLabel->setVisible(true);
|
||||
diStatusLabel->setText(DigitallyImported::self()->loggedIn() ? i18n("DI: Logged In") : i18n("DI: Not Logged In"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public Q_SLOTS:
|
||||
void controlActions();
|
||||
|
||||
private Q_SLOTS:
|
||||
void diSettings();
|
||||
void importXml();
|
||||
void exportXml();
|
||||
void add();
|
||||
@@ -67,6 +68,7 @@ private Q_SLOTS:
|
||||
void edit();
|
||||
void searchItems();
|
||||
void itemDoubleClicked(const QModelIndex &index);
|
||||
void updateDiStatus();
|
||||
|
||||
private:
|
||||
void addItemsToPlayQueue(const QModelIndexList &indexes, bool replace, quint8 priorty=0);
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>310</width>
|
||||
<height>387</height>
|
||||
<width>277</width>
|
||||
<height>259</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="vlayout">
|
||||
@@ -29,25 +29,28 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="hlayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<widget class="SqueezedTextLabel" name="diStatusLabel"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="MenuButton" name="menuButton"/>
|
||||
</item>
|
||||
@@ -59,6 +62,11 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SqueezedTextLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>squeezedtextlabel.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ItemView</class>
|
||||
<extends>QTreeView</extends>
|
||||
|
||||
Reference in New Issue
Block a user