155 lines
4.2 KiB
C++
155 lines
4.2 KiB
C++
#include "beerservice.h"
|
|
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonArray>
|
|
#include <QStandardPaths>
|
|
#include <QFile>
|
|
#include <QDebug>
|
|
|
|
#include "settingsservice.h"
|
|
|
|
BeerService::BeerService()
|
|
: QObject{nullptr}
|
|
{
|
|
m_actions = {
|
|
{ ActionGet, "get" },
|
|
{ ActionAdd, "add" },
|
|
{ ActionDelete, "del" },
|
|
{ ActionModify, "mod" }
|
|
};
|
|
|
|
restoreStash();
|
|
|
|
connect(&m_socket, &QWebSocket::textMessageReceived, this, [this](QString message) {
|
|
QJsonParseError err;
|
|
QJsonDocument doc = QJsonDocument::fromJson(message.toLocal8Bit(), &err);
|
|
if (err.error != QJsonParseError::NoError) {
|
|
qWarning() << "Json parse error:" << err.errorString() << message;
|
|
return;
|
|
}
|
|
|
|
QString entity = doc.object().value("entity").toString();
|
|
const QList<QObject *> listeners = m_listeners.values(entity);
|
|
for (QObject *listener : listeners) {
|
|
QString event = doc.object().value("event").toString();
|
|
QVariant data = doc.object().value("data").toVariant();
|
|
QMetaObject::invokeMethod(listener, event.toLatin1(), Qt::QueuedConnection, Q_ARG(QVariant, data));
|
|
}
|
|
});
|
|
|
|
connect(&m_socket, &QWebSocket::errorOccurred, this, [this](QAbstractSocket::SocketError error) {
|
|
qInfo() << error << m_socket.errorString();
|
|
});
|
|
|
|
connect(&m_socket, &QWebSocket::connected, this, [this]() {
|
|
while (!m_commandStash.isEmpty()) {
|
|
sendCommand(m_commandStash.takeFirst().toMap());
|
|
}
|
|
});
|
|
|
|
connect(&m_socket, &QWebSocket::stateChanged, this, &BeerService::connectedChanged);
|
|
|
|
connect(settings(), &SettingsService::serverAddressChanged, this, &BeerService::reconnect);
|
|
connect(settings(), &SettingsService::selectedUserIdChanged, this, &BeerService::reconnect);
|
|
|
|
reconnect();
|
|
}
|
|
|
|
BeerService::~BeerService()
|
|
{
|
|
saveStash();
|
|
m_socket.close();
|
|
}
|
|
|
|
SettingsService *BeerService::settings() const
|
|
{
|
|
return SettingsService::instance();
|
|
}
|
|
|
|
void BeerService::sendCommand(const QString &entity, Action action, const QVariantMap &data)
|
|
{
|
|
Q_ASSERT(action != ActionUndefined);
|
|
|
|
sendCommand(QVariantMap {
|
|
{ "entity", entity },
|
|
{ "action", m_actions[action] },
|
|
{ "data", data }
|
|
});
|
|
}
|
|
|
|
void BeerService::connectListener(QObject *listener)
|
|
{
|
|
QString entity = listener->property("entity").toString();
|
|
m_listeners.insert(entity, listener);
|
|
}
|
|
|
|
void BeerService::removeListener(QObject *listener)
|
|
{
|
|
QString entity = listener->property("entity").toString();
|
|
m_listeners.remove(entity, listener);
|
|
}
|
|
|
|
QString BeerService::stashFileName() const
|
|
{
|
|
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/command.stash";
|
|
}
|
|
|
|
void BeerService::saveStash() const
|
|
{
|
|
if (m_commandStash.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
QFile stash(stashFileName());
|
|
if (stash.open(QIODevice::WriteOnly)) {
|
|
stash.write(QJsonDocument::fromVariant(m_commandStash).toJson(QJsonDocument::Compact));
|
|
stash.close();
|
|
} else {
|
|
qWarning() << stash.errorString();
|
|
}
|
|
}
|
|
|
|
void BeerService::restoreStash()
|
|
{
|
|
QFile stash(stashFileName());
|
|
if (stash.open(QIODevice::ReadOnly)) {
|
|
QJsonDocument doc = QJsonDocument::fromJson(stash.readAll());
|
|
m_commandStash = doc.array().toVariantList();
|
|
stash.close();
|
|
stash.remove();
|
|
} else {
|
|
qWarning() << stash.errorString();
|
|
}
|
|
}
|
|
|
|
void BeerService::reconnect()
|
|
{
|
|
if (connected()) {
|
|
m_socket.close();
|
|
}
|
|
|
|
QString userId = settings()->selectedUserId();
|
|
QUrl serverUrl(QString("ws://%1").arg(settings()->serverAddress()));
|
|
|
|
QNetworkRequest request(serverUrl);
|
|
request.setRawHeader("Authorization", "Basic " + QString("%1:pass").arg(userId).toLatin1().toBase64());
|
|
m_socket.open(request);
|
|
|
|
}
|
|
|
|
void BeerService::sendCommand(const QVariantMap &command)
|
|
{
|
|
if (connected()) {
|
|
QJsonDocument doc = QJsonDocument::fromVariant(command);
|
|
m_socket.sendTextMessage(doc.toJson(QJsonDocument::Compact));
|
|
} else {
|
|
m_commandStash << command;
|
|
}
|
|
}
|
|
|
|
bool BeerService::connected() const
|
|
{
|
|
return QAbstractSocket::ConnectedState == m_socket.state();
|
|
}
|