2011-12-06 00:10:25 +01:00
|
|
|
#include "subsonicservice.h"
|
|
|
|
#include "internetmodel.h"
|
2011-12-07 19:06:11 +01:00
|
|
|
#include "core/logging.h"
|
|
|
|
|
|
|
|
#include <QNetworkAccessManager>
|
|
|
|
#include <QNetworkReply>
|
|
|
|
#include <QNetworkCookieJar>
|
|
|
|
#include <QXmlStreamReader>
|
2011-12-06 00:10:25 +01:00
|
|
|
|
|
|
|
const char* SubsonicService::kServiceName = "Subsonic";
|
|
|
|
const char* SubsonicService::kSettingsGroup = "Subsonic";
|
|
|
|
const char* SubsonicService::kApiVersion = "1.6.0";
|
|
|
|
const char* SubsonicService::kApiClientName = "Clementine";
|
|
|
|
|
|
|
|
SubsonicService::SubsonicService(InternetModel *parent)
|
2011-12-07 19:06:11 +01:00
|
|
|
: InternetService(kServiceName, parent, parent),
|
|
|
|
network_(new QNetworkAccessManager(this)),
|
|
|
|
login_state_(LoginState_OtherError)
|
2011-12-06 00:10:25 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SubsonicService::~SubsonicService()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QStandardItem* SubsonicService::CreateRootItem()
|
|
|
|
{
|
|
|
|
root_ = new QStandardItem(QIcon(":providers/subsonic.png"), kServiceName);
|
|
|
|
root_->setData(true, InternetModel::Role_CanLazyLoad);
|
|
|
|
return root_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsonicService::LazyPopulate(QStandardItem *item)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-12-07 19:06:11 +01:00
|
|
|
void SubsonicService::ReloadSettings()
|
|
|
|
{
|
|
|
|
QSettings s;
|
|
|
|
s.beginGroup(kSettingsGroup);
|
|
|
|
|
|
|
|
server_ = s.value("server").toString();
|
|
|
|
username_ = s.value("username").toString();
|
|
|
|
password_ = s.value("password").toString();
|
|
|
|
|
|
|
|
// TODO: Move this?
|
|
|
|
Login();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsonicService::Login()
|
|
|
|
{
|
|
|
|
// Forget session ID
|
|
|
|
network_->setCookieJar(new QNetworkCookieJar(network_));
|
|
|
|
// Ping is enough to authenticate
|
|
|
|
Ping();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsonicService::Login(const QString &server, const QString &username, const QString &password)
|
|
|
|
{
|
|
|
|
server_ = QString(server);
|
|
|
|
username_ = QString(username);
|
|
|
|
password_ = QString(password);
|
|
|
|
Login();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SubsonicService::Ping()
|
|
|
|
{
|
|
|
|
QUrl request_url = BuildRequestUrl("ping");
|
|
|
|
QNetworkReply *reply = network_->get(QNetworkRequest(request_url));
|
|
|
|
reply->ignoreSslErrors();
|
|
|
|
connect(reply, SIGNAL(finished()), this, SLOT(onPingFinished()));
|
|
|
|
}
|
|
|
|
|
2011-12-06 00:10:25 +01:00
|
|
|
QModelIndex SubsonicService::GetCurrentIndex()
|
|
|
|
{
|
|
|
|
return context_item_;
|
|
|
|
}
|
|
|
|
|
2011-12-07 19:06:11 +01:00
|
|
|
QUrl SubsonicService::BuildRequestUrl(const QString &view, const RequestOptions *options)
|
2011-12-06 00:10:25 +01:00
|
|
|
{
|
2011-12-07 19:06:11 +01:00
|
|
|
QUrl url(server_ + "rest/" + view + ".view");
|
2011-12-06 00:10:25 +01:00
|
|
|
url.addQueryItem("v", kApiVersion);
|
|
|
|
url.addQueryItem("c", kApiClientName);
|
2011-12-07 19:06:11 +01:00
|
|
|
// TODO: only send username/password for login
|
2011-12-06 00:10:25 +01:00
|
|
|
url.addQueryItem("u", username_);
|
|
|
|
url.addQueryItem("p", password_);
|
2011-12-07 19:06:11 +01:00
|
|
|
if (options)
|
2011-12-06 00:10:25 +01:00
|
|
|
{
|
2011-12-07 19:06:11 +01:00
|
|
|
for (RequestOptions::const_iterator i = options->begin(); i != options->end(); ++i)
|
|
|
|
{
|
|
|
|
url.addQueryItem(i.key(), i.value());
|
|
|
|
}
|
2011-12-06 00:10:25 +01:00
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
2011-12-07 19:06:11 +01:00
|
|
|
|
|
|
|
void SubsonicService::onPingFinished()
|
|
|
|
{
|
|
|
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
|
|
|
reply->deleteLater();
|
|
|
|
|
|
|
|
if (reply->error() != QNetworkReply::NoError)
|
|
|
|
{
|
|
|
|
login_state_ = LoginState_BadServer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QXmlStreamReader reader(reply);
|
|
|
|
reader.readNextStartElement();
|
|
|
|
QStringRef status = reader.attributes().value("status");
|
|
|
|
if (status == "ok")
|
|
|
|
{
|
|
|
|
login_state_ = LoginState_Loggedin;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reader.readNextStartElement();
|
|
|
|
int error = reader.attributes().value("code").toString().toInt();
|
|
|
|
switch (error)
|
|
|
|
{
|
|
|
|
case ApiError_BadCredentials:
|
|
|
|
login_state_ = LoginState_BadCredentials;
|
|
|
|
break;
|
|
|
|
case ApiError_Unlicensed:
|
|
|
|
login_state_ = LoginState_Unlicensed;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
login_state_ = LoginState_OtherError;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qLog(Debug) << "Login state changed: " << login_state_;
|
|
|
|
emit LoginStateChanged();
|
|
|
|
}
|