mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-03 07:35:48 +08:00
refs #526, network
* signal when data have been published * parsing of publishing JSON object * utility functions
This commit is contained in:
@@ -109,6 +109,17 @@ namespace BlackCore
|
||||
return cl;
|
||||
}
|
||||
|
||||
QList<QMetaObject::Connection> CWebDataServices::connectDataPublishSignal(QObject *receiver, std::function<void (const CAircraftModelList &, const CAircraftModelList &, const CStatusMessageList &)> dataPublished)
|
||||
{
|
||||
Q_ASSERT_X(receiver, Q_FUNC_INFO, "Missing receiver");
|
||||
QList<QMetaObject::Connection> cl;
|
||||
if (!m_databaseWriter) { return cl; }
|
||||
QMetaObject::Connection con = connect(this->m_databaseWriter, &CDatabaseWriter::published, receiver, dataPublished);
|
||||
Q_ASSERT_X(con, Q_FUNC_INFO, "connect failed publishing signal");
|
||||
cl.push_back(con);
|
||||
return cl;
|
||||
}
|
||||
|
||||
CServerList CWebDataServices::getVatsimFsdServers() const
|
||||
{
|
||||
if (m_vatsimDataFileReader) { return m_vatsimDataFileReader->getFsdServers(); }
|
||||
@@ -144,9 +155,9 @@ namespace BlackCore
|
||||
if (m_vatsimDataFileReader) { m_vatsimDataFileReader->updateWithVatsimDataFileData(aircraftToBeUdpated); }
|
||||
}
|
||||
|
||||
CStatusMessageList CWebDataServices::asyncWriteModel(const CAircraftModel &model) const
|
||||
CStatusMessageList CWebDataServices::asyncPublishModels(const CAircraftModelList &models) const
|
||||
{
|
||||
if (m_databaseWriter) { return m_databaseWriter->asyncWriteModel(model);}
|
||||
if (m_databaseWriter) { return m_databaseWriter->asyncPublishModels(models);}
|
||||
return CStatusMessageList();
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,12 @@ namespace BlackCore
|
||||
QObject *receiver,
|
||||
std::function<void (BlackMisc::Network::CEntityFlags::Entity, BlackMisc::Network::CEntityFlags::ReadState, int)> dataRead) override;
|
||||
|
||||
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::connectDataPublishSignal
|
||||
//! \ingroup webdatareaderprovider
|
||||
virtual QList<QMetaObject::Connection> connectDataPublishSignal(
|
||||
QObject *receiver,
|
||||
std::function<void (const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished) override;
|
||||
|
||||
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::triggerRead
|
||||
//! \ingroup webdatareaderprovider
|
||||
virtual BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead) override;
|
||||
@@ -227,15 +233,15 @@ namespace BlackCore
|
||||
//! \ingroup webdatareaderprovider
|
||||
virtual void updateWithVatsimDataFileData(BlackMisc::Simulation::CSimulatedAircraft &aircraftToBeUdpated) const override;
|
||||
|
||||
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::asyncWriteModel
|
||||
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::asyncPublishModels
|
||||
//! \ingroup webdatareaderprovider
|
||||
virtual BlackMisc::CStatusMessageList asyncWriteModel(const BlackMisc::Simulation::CAircraftModel &model) const override;
|
||||
virtual BlackMisc::CStatusMessageList asyncPublishModels(const BlackMisc::Simulation::CAircraftModelList &models) const override;
|
||||
|
||||
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::canConnectSwiftDb
|
||||
//! \ingroup webdatareaderprovider
|
||||
virtual bool canConnectSwiftDb() const override;
|
||||
|
||||
//! Save all DB data to JSON files
|
||||
//! Save all DB data to a JSON files
|
||||
//! \ingroup webdatareaderprovider
|
||||
virtual bool writeDbDataToDisk(const QString &dir) const override;
|
||||
|
||||
|
||||
@@ -35,6 +35,14 @@ namespace BlackMisc
|
||||
this->m_dbKey = k;
|
||||
}
|
||||
|
||||
int IDatastoreObjectWithIntegerKey::stringToDbKey(const QString &candidate)
|
||||
{
|
||||
if (candidate.isEmpty()) { return invalidDbKey(); }
|
||||
bool ok;
|
||||
int k = candidate.toInt(&ok);
|
||||
return ok ? k : invalidDbKey();
|
||||
}
|
||||
|
||||
QJsonValue IDatastoreObjectWithIntegerKey::getDbKeyAsJsonValue() const
|
||||
{
|
||||
if (this->hasValidDbKey()) { return QJsonValue(this->m_dbKey); }
|
||||
|
||||
@@ -55,6 +55,9 @@ namespace BlackMisc
|
||||
//! Invalid key
|
||||
static int invalidDbKey() { return -1; }
|
||||
|
||||
//! Convert string to DB key
|
||||
static int stringToDbKey(const QString &candidate);
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
IDatastoreObjectWithIntegerKey() {}
|
||||
|
||||
@@ -7,12 +7,16 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "blackmisc/simulation/aircraftmodellist.h"
|
||||
#include "blackmisc/datastoreutility.h"
|
||||
#include "blackmisc/blackmiscfreefunctions.h"
|
||||
#include "blackmisc/stringutils.h"
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Simulation;
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
bool CDatastoreUtility::dbBoolStringToBool(const QString &dbBool)
|
||||
@@ -48,7 +52,6 @@ namespace BlackMisc
|
||||
|
||||
QDateTime CDatastoreUtility::parseTimestamp(const QString ×tamp)
|
||||
{
|
||||
Q_ASSERT_X(!timestamp.isEmpty(), Q_FUNC_INFO, "Missing timestamp");
|
||||
if (!timestamp.isEmpty())
|
||||
{
|
||||
QString ts(timestamp.trimmed().remove(' ').remove('-').remove(':')); // normalize
|
||||
@@ -61,33 +64,76 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
bool CDatastoreUtility::parseSwiftWriteResponse(const QString &jsonResponse, CStatusMessageList &messages, CVariant &key)
|
||||
bool CDatastoreUtility::parseSwiftPublishResponse(const QString &jsonResponse, CAircraftModelList &publishedModels, CAircraftModelList &skippedModels, CStatusMessageList &messages)
|
||||
{
|
||||
if (jsonResponse.isEmpty()) { return ""; }
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(jsonResponse.toUtf8()));
|
||||
if (!jsonDoc.isObject()) { return ""; }
|
||||
QJsonObject json(jsonDoc.object());
|
||||
Q_ASSERT_X(!json.value("id").isNull(), Q_FUNC_INFO, "malformed response");
|
||||
if (json.value("id").isNull()) { return false; }
|
||||
QString id(json.value("id").toString().trimmed());
|
||||
QJsonArray msgObject(json.value("messages").toArray());
|
||||
messages.push_back(CStatusMessageList::fromDatabaseJson(msgObject));
|
||||
bool success = false;
|
||||
static const CLogCategoryList cats({ CLogCategory::swiftDbWebservice()});
|
||||
if (jsonResponse.isEmpty())
|
||||
{
|
||||
messages.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Empty JSON data"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int intKey;
|
||||
bool isInt;
|
||||
intKey = id.toInt(&isInt);
|
||||
if (isInt)
|
||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(jsonResponse.toUtf8()));
|
||||
|
||||
// array of messages
|
||||
if (jsonDoc.isArray())
|
||||
{
|
||||
key.setValue(intKey);
|
||||
success = (intKey >= 0);
|
||||
CStatusMessageList msgs(CStatusMessageList::fromDatabaseJson(jsonDoc.array()));
|
||||
messages.push_back(msgs);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
// no object -> most likely some fucked up HTML string with the PHP error
|
||||
if (!jsonDoc.isObject())
|
||||
{
|
||||
key.setValue(id);
|
||||
success = !id.isEmpty();
|
||||
QString phpError(jsonResponse);
|
||||
phpError.remove(QRegExp("<[^>]*>"));
|
||||
messages.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, phpError));
|
||||
return false;
|
||||
}
|
||||
return success;
|
||||
|
||||
// fully blown object
|
||||
QJsonObject json(jsonDoc.object());
|
||||
bool data = false;
|
||||
if (json.contains("msgs"))
|
||||
{
|
||||
QJsonValue msgJson(json.take("msgs"));
|
||||
CStatusMessageList msgs(CStatusMessageList::fromDatabaseJson(msgJson.toArray()));
|
||||
if (!msgs.isEmpty())
|
||||
{
|
||||
messages.push_back(msgs);
|
||||
data = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (json.contains("publishedModels"))
|
||||
{
|
||||
QJsonValue publishedJson(json.take("publishedModels"));
|
||||
CAircraftModelList published = CAircraftModelList::fromDatabaseJson(publishedJson.toArray());
|
||||
if (!published.isEmpty())
|
||||
{
|
||||
publishedModels.push_back(published);
|
||||
data = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (json.contains("skippedModels"))
|
||||
{
|
||||
QJsonValue skippedJson(json.take("skippedModels"));
|
||||
CAircraftModelList skipped = CAircraftModelList::fromDatabaseJson(skippedJson.toArray());
|
||||
if (!skipped.isEmpty())
|
||||
{
|
||||
skippedModels.push_back(skipped);
|
||||
data = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data)
|
||||
{
|
||||
messages.push_back(CStatusMessage(cats, CStatusMessage::SeverityError, "Received response, but no JSON data"));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace BlackMisc
|
||||
//! Parse a timestamp object
|
||||
static QDateTime parseTimestamp(const QString ×tamp);
|
||||
|
||||
//! Get id from a DB response
|
||||
static bool parseSwiftWriteResponse(const QString &jsonResponse, BlackMisc::CStatusMessageList &messages, BlackMisc::CVariant &key);
|
||||
//! Get data from a DB response
|
||||
static bool parseSwiftPublishResponse(const QString &jsonResponse, BlackMisc::Simulation::CAircraftModelList &publishedModels, BlackMisc::Simulation::CAircraftModelList &skippedModels, BlackMisc::CStatusMessageList &messages);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace BlackMisc
|
||||
{
|
||||
QStringList ips;
|
||||
if (!CNetworkUtils::hasConnectedInterface(false)) return ips;
|
||||
foreach(const QHostAddress & address, QNetworkInterface::allAddresses())
|
||||
foreach (const QHostAddress &address, QNetworkInterface::allAddresses())
|
||||
{
|
||||
if (address.isLoopback() || address.isNull()) continue;
|
||||
if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress(QHostAddress::LocalHost))
|
||||
@@ -207,13 +207,24 @@ namespace BlackMisc
|
||||
qurl.addQueryItem("XDEBUG_SESSION_START", "ECLIPSE_DBGP");
|
||||
}
|
||||
|
||||
QHttpPart CNetworkUtils::getJsonTextMutlipart(const QJsonObject &json)
|
||||
QHttpPart CNetworkUtils::getJsonTextMultipart(const QJsonObject &json)
|
||||
{
|
||||
const QByteArray bytes(QJsonDocument(json).toJson(QJsonDocument::Compact));
|
||||
return getJsonTextMultipart(bytes);
|
||||
}
|
||||
|
||||
QHttpPart CNetworkUtils::getJsonTextMultipart(const QJsonArray &json)
|
||||
{
|
||||
const QByteArray bytes(QJsonDocument(json).toJson(QJsonDocument::Compact));
|
||||
return getJsonTextMultipart(bytes);
|
||||
}
|
||||
|
||||
QHttpPart CNetworkUtils::getJsonTextMultipart(const QByteArray &bytes)
|
||||
{
|
||||
const QByteArray jsonData(QJsonDocument(json).toJson(QJsonDocument::Compact));
|
||||
QHttpPart textPart;
|
||||
QString name("form-data; name=\"swiftjson\"");
|
||||
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(name));
|
||||
textPart.setBody(jsonData);
|
||||
textPart.setBody(bytes);
|
||||
return textPart;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,13 @@ namespace BlackMisc
|
||||
static void addDebugFlag(QUrlQuery &qurl);
|
||||
|
||||
//! Multipart for JSON
|
||||
static QHttpPart getJsonTextMutlipart(const QJsonObject &json);
|
||||
static QHttpPart getJsonTextMultipart(const QJsonObject &json);
|
||||
|
||||
//! Multipart for JSON
|
||||
static QHttpPart getJsonTextMultipart(const QJsonArray &json);
|
||||
|
||||
//! Multipart for JSON
|
||||
static QHttpPart getJsonTextMultipart(const QByteArray &bytes);
|
||||
|
||||
//! Our tweakes network request
|
||||
static QNetworkRequest getNetworkRequest(const CUrl &url, RequestType type = Get);
|
||||
|
||||
@@ -261,11 +261,11 @@ namespace BlackMisc
|
||||
return this->m_webDataReaderProvider->updateWithVatsimDataFileData(aircraftToBeUdpated);
|
||||
}
|
||||
|
||||
CStatusMessageList CWebDataServicesAware::asyncWriteModel(const CAircraftModel &model) const
|
||||
CStatusMessageList CWebDataServicesAware::asyncPublishModels(const CAircraftModelList &models) const
|
||||
{
|
||||
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
|
||||
if (!hasProvider()) { return CStatusMessageList(); }
|
||||
return this->m_webDataReaderProvider->asyncWriteModel(model);
|
||||
return this->m_webDataReaderProvider->asyncPublishModels(models);
|
||||
}
|
||||
|
||||
void CWebDataServicesAware::setProvider(IWebDataServicesProvider *webDataReaderProvider)
|
||||
@@ -296,6 +296,16 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
void CWebDataServicesAware::connectDataPublishSignal(QObject *receiver, std::function<void (const CAircraftModelList &, const CAircraftModelList &, const CStatusMessageList &)> dataPublished)
|
||||
{
|
||||
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
|
||||
if (!hasProvider()) { return; }
|
||||
if (receiver)
|
||||
{
|
||||
this->m_swiftConnections.append(this->m_webDataReaderProvider->connectDataPublishSignal(receiver, dataPublished));
|
||||
}
|
||||
}
|
||||
|
||||
CEntityFlags::Entity CWebDataServicesAware::triggerRead(CEntityFlags::Entity whatToRead)
|
||||
{
|
||||
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
|
||||
|
||||
@@ -184,10 +184,10 @@ namespace BlackMisc
|
||||
//! \threadsafe
|
||||
virtual int getMetarsCount() const = 0;
|
||||
|
||||
//! Write directly to database
|
||||
virtual BlackMisc::CStatusMessageList asyncWriteModel(const BlackMisc::Simulation::CAircraftModel &model) const = 0;
|
||||
//! Publish models to database
|
||||
virtual BlackMisc::CStatusMessageList asyncPublishModels(const BlackMisc::Simulation::CAircraftModelList &models) const = 0;
|
||||
|
||||
//! Relay signals for swift data
|
||||
//! Relay signals for read swift data
|
||||
//! Connect signals to slot receiver. As the interface is no QObject, slots can not be connected directly.
|
||||
//! In order to disconnect a list of connections is provided, which have to be disconnected manually.
|
||||
//! \note receiver is required for connection type
|
||||
@@ -195,16 +195,24 @@ namespace BlackMisc
|
||||
QObject *receiver,
|
||||
std::function<void(BlackMisc::Network::CEntityFlags::Entity, BlackMisc::Network::CEntityFlags::ReadState, int)> dataRead) = 0;
|
||||
|
||||
//! Relay signals for published swift data
|
||||
//! Connect signals to slot receiver. As the interface is no QObject, slots can not be connected directly.
|
||||
//! In order to disconnect a list of connections is provided, which have to be disconnected manually.
|
||||
//! \note receiver is required for connection type
|
||||
virtual QList<QMetaObject::Connection> connectDataPublishSignal(
|
||||
QObject *receiver,
|
||||
std::function<void(const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished) = 0;
|
||||
|
||||
//! Trigger read of new data
|
||||
virtual BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead) = 0;
|
||||
|
||||
//! Can connect to swift DB?
|
||||
virtual bool canConnectSwiftDb() const = 0;
|
||||
|
||||
//! Write data to disk
|
||||
//! Write data to disk (mainly for testing scenarios)
|
||||
virtual bool writeDbDataToDisk(const QString &dir) const = 0;
|
||||
|
||||
//! Load DB data from disk
|
||||
//! Load DB data from disk (mainly for testing scenarios)
|
||||
virtual bool readDbDataFromDisk(const QString &dir, bool inBackground) = 0;
|
||||
};
|
||||
|
||||
@@ -322,8 +330,8 @@ namespace BlackMisc
|
||||
//! \copydoc IWebDataServicesProvider::updateWithVatsimDataFileData
|
||||
void updateWithVatsimDataFileData(BlackMisc::Simulation::CSimulatedAircraft &aircraftToBeUdpated) const;
|
||||
|
||||
//! \copydoc IWebDataServicesProvider::asyncWriteModel
|
||||
BlackMisc::CStatusMessageList asyncWriteModel(const BlackMisc::Simulation::CAircraftModel &model) const;
|
||||
//! \copydoc IWebDataServicesProvider::asyncPublishModels
|
||||
BlackMisc::CStatusMessageList asyncPublishModels(const BlackMisc::Simulation::CAircraftModelList &models) const;
|
||||
|
||||
//! Set the provider
|
||||
virtual void setProvider(IWebDataServicesProvider *webDataReaderProvider);
|
||||
@@ -339,6 +347,11 @@ namespace BlackMisc
|
||||
QObject *receiver,
|
||||
std::function<void(BlackMisc::Network::CEntityFlags::Entity, BlackMisc::Network::CEntityFlags::ReadState, int)> dataRead);
|
||||
|
||||
//! \copydoc IWebDataServicesProvider::connectDataPublishSignal
|
||||
virtual void connectDataPublishSignal(
|
||||
QObject *receiver,
|
||||
std::function<void(const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished);
|
||||
|
||||
//! \copydoc IWebDataServicesProvider::triggerRead
|
||||
BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user