repoindex/network/connection.cpp

117 lines
4.0 KiB
C++

#include "connection.h"
#include "alpm/manager.h"
#include "alpm/upgradelookup.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QWebSocket>
using namespace PackageManagement;
namespace Network {
Connection::Connection(const Manager &alpmManager, QWebSocket *socket, QObject *parent) :
QObject(parent),
m_socket(socket),
m_alpmManager(alpmManager),
m_repoInfoUpdatesRequested(false),
m_groupInfoUpdatesRequested(false)
{
socket->setParent(this);
connect(socket, &QWebSocket::textMessageReceived, this, &Connection::processTextMessage);
connect(socket, &QWebSocket::binaryMessageReceived, this, &Connection::processBinaryMessage);
connect(socket, &QWebSocket::disconnected, this, &Connection::socketDisconnected);
}
void Connection::sendJson(const QJsonObject &obj)
{
m_socket->sendTextMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact));
}
void Connection::sendError(const QString &msg)
{
QJsonObject response;
response.insert(QStringLiteral("class"), QStringLiteral("error"));
response.insert(QStringLiteral("msg"), msg);
sendJson(response);
}
void Connection::sendResult(const QJsonValue &what, const QJsonValue &id, const QJsonValue &value)
{
QJsonObject response;
response.insert(QStringLiteral("class"), QStringLiteral("results"));
response.insert(QStringLiteral("what"), what);
response.insert(QStringLiteral("value"), value);
if(!id.isNull()) {
response.insert("id", id);
}
sendJson(response);
}
void Connection::sendResults(const QJsonValue &what, const QJsonValue &id, const QJsonArray &values)
{
QJsonObject response;
response.insert(QStringLiteral("class"), QStringLiteral("results"));
response.insert(QStringLiteral("what"), what);
response.insert(QStringLiteral("values"), values);
if(!id.isNull()) {
response.insert("id", id);
}
sendJson(response);
}
void Connection::handleQuery(const QJsonObject &obj)
{
const auto what = obj.value(QStringLiteral("what")).toString();
const auto id = obj.value(QStringLiteral("id"));
if(what == QLatin1String("basicrepoinfo")) {
m_repoInfoUpdatesRequested = obj.value(QStringLiteral("updates")).toBool(m_repoInfoUpdatesRequested);
sendResults(what, id, m_alpmManager.basicRepoInfo());
} else if(what == QLatin1String("basicpkginfo")) {
sendResults(what, id, m_alpmManager.packageInfo(obj.value("sel").toObject(), false));
} else if(what == QLatin1String("fullpkginfo")) {
sendResults(what, id, m_alpmManager.packageInfo(obj.value("sel").toObject(), true));
} else if(what == QLatin1String("groupinfo")) {
m_groupInfoUpdatesRequested = obj.value(QStringLiteral("updates")).toBool(m_groupInfoUpdatesRequested);
sendResults(what, id, m_alpmManager.groupInfo());
} else if(what == QLatin1String("checkforupdates")) {
connect(new UpgradeLookup(m_alpmManager, obj), &UpgradeLookup::resultsAvailable, this, &Connection::sendResult);
} else if(what == QLatin1String("ping")) {
sendResult(what, id, QStringLiteral("pong"));
} else {
sendResult(what, id, QStringLiteral("unknownquery"));
}
}
void Connection::processTextMessage(const QString &message)
{
QJsonParseError error;
QByteArray jsonData;
jsonData.append(message);
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &error);
if(error.error == QJsonParseError::NoError) {
QString msgClass = doc.object().value(QStringLiteral("class")).toString();
if(msgClass == QLatin1String("query")) {
handleQuery(doc.object());
} else {
sendError(QStringLiteral("no message class specified"));
}
} else {
sendError(QStringLiteral("unable to parse JSON: ") + error.errorString());
}
}
void Connection::processBinaryMessage(const QByteArray &)
{
sendError(QStringLiteral("unable to parse binary messages"));
}
void Connection::socketDisconnected()
{
deleteLater();
}
}