mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 11:55:35 +08:00
refs #610, VATSIM status file
* automatically load status file * keep VATSIM data file locations * use METAR/datafile locations from bootstrap or VATSIM status file
This commit is contained in:
committed by
Mathew Sutcliffe
parent
06bcbe2a2f
commit
1eb65a873c
@@ -5,6 +5,17 @@
|
||||
"url": "https://vatsim-germany.org:50443/mapping/public"
|
||||
},
|
||||
"development": false,
|
||||
"fsdTestServers": {
|
||||
"containerbase": [
|
||||
]
|
||||
},
|
||||
"newsUrls": {
|
||||
"containerbase": [
|
||||
{
|
||||
"url": "http://swift-project.org/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sharedUrls": {
|
||||
"containerbase": [
|
||||
{
|
||||
@@ -15,7 +26,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"timestampMSecsSinceEpoch": 0,
|
||||
"timestampMSecsSinceEpoch": 1457055734000,
|
||||
"vatsimBookingsUrl": {
|
||||
"url": "http://vatbook.euroutepro.com/xml2.php"
|
||||
},
|
||||
@@ -26,14 +37,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"vatsimMetarsUrl": {
|
||||
"url": "http://metar.vatsim.net/metar.php"
|
||||
},
|
||||
"newsUrls": {
|
||||
"vatsimMetarsUrls": {
|
||||
"containerbase": [
|
||||
{
|
||||
"url": "http://swift-project.org/"
|
||||
"url": "http://metar.vatsim.net/metar.php"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vatsimStatusFileUrls": {
|
||||
"containerbase": [
|
||||
{
|
||||
"url": "https://status.vatsim.net"
|
||||
}
|
||||
]
|
||||
},
|
||||
"wasLoaded": true
|
||||
}
|
||||
@@ -471,7 +471,7 @@ namespace BlackCore
|
||||
this->addParserOption(this->m_cmdDevelopment);
|
||||
|
||||
this->m_cmdSharedDir = QCommandLineOption({ "shared", "shareddir" },
|
||||
QCoreApplication::translate("application", "Local shred directory."),
|
||||
QCoreApplication::translate("application", "Local shared directory."),
|
||||
"shared");
|
||||
this->addParserOption(this->m_cmdSharedDir);
|
||||
}
|
||||
@@ -769,4 +769,37 @@ namespace BlackCore
|
||||
if (!supportsContexts()) { return nullptr; }
|
||||
return this->m_coreFacade->getIContextSimulator();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// Setup
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
CUrlList CApplication::getVatsimMetarUrls() const
|
||||
{
|
||||
if (this->m_webDataServices)
|
||||
{
|
||||
const CUrlList urls(this->m_webDataServices->getVatsimMetarUrls());
|
||||
if (!urls.empty()) { return urls; }
|
||||
}
|
||||
if (this->m_setupReader)
|
||||
{
|
||||
return this->m_setupReader->getSetup().vatsimMetarsUrls();
|
||||
}
|
||||
return CUrlList();
|
||||
}
|
||||
|
||||
CUrlList CApplication::getVatsimDataFileUrls() const
|
||||
{
|
||||
if (this->m_webDataServices)
|
||||
{
|
||||
const CUrlList urls(this->m_webDataServices->getVatsimDataFileUrls());
|
||||
if (!urls.empty()) { return urls; }
|
||||
}
|
||||
if (this->m_setupReader)
|
||||
{
|
||||
return this->m_setupReader->getSetup().vatsimDataFileUrls();
|
||||
}
|
||||
return CUrlList();
|
||||
}
|
||||
|
||||
} // ns
|
||||
|
||||
@@ -49,6 +49,8 @@ namespace BlackCore
|
||||
* - The core facade (aka core runtime) is now part of the application. It can be started via cmd line arguments.
|
||||
* - Settings are loaded
|
||||
* - Setup is loaded (load the so called bootsrap file) to find servers and other resources
|
||||
* - Update information (new swift versions etc.) are loaded
|
||||
* - If applicable VATSIM status data (where are the VATSIM files?) are loaded
|
||||
* - An end of lifetime can be specified, aka time bombing
|
||||
*
|
||||
* \sa BlackGui::CGuiApplication for the GUI version of application
|
||||
@@ -213,6 +215,16 @@ namespace BlackCore
|
||||
IContextSimulator *getIContextSimulator();
|
||||
//! @}
|
||||
|
||||
// ----------------------- direct access to some setup data ---------------------------------
|
||||
|
||||
//! Consolidated version of METAR URLs, either from CGlobalSetup or CVatsimSetup
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrlList getVatsimMetarUrls() const;
|
||||
|
||||
//! Consolidated version of data file URLs, either from CGlobalSetup or CVatsimSetup
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrlList getVatsimDataFileUrls() const;
|
||||
|
||||
public slots:
|
||||
//! Graceful shutdown
|
||||
virtual void gracefulShutdown();
|
||||
|
||||
@@ -25,8 +25,9 @@ namespace BlackCore
|
||||
ITimestampBased(0),
|
||||
m_dbRootDirectoryUrl("http://ubuntu12/swiftdatastore/public"),
|
||||
m_vatsimBookingsUrl("http://vatbook.euroutepro.com/xml2.php"),
|
||||
m_vatsimMetarsUrl("http://metar.vatsim.net/metar.php"),
|
||||
m_vatsimDataFileUrls(QStringList( { "http://info.vroute.net/vatsim-data.txt" })),
|
||||
m_vatsimMetarsUrls( {"http://metar.vatsim.net/metar.php"}),
|
||||
m_vatsimStatusFileUrls({ "https://status.vatsim.net" }),
|
||||
m_vatsimDataFileUrls({ "http://info.vroute.net/vatsim-data.txt" }),
|
||||
m_sharedUrls(CProject::swiftTeamDefaultServers()),
|
||||
m_newsUrls(QStringList({ "http://swift-project.org/" }))
|
||||
{ }
|
||||
@@ -72,11 +73,6 @@ namespace BlackCore
|
||||
return this->isDevelopment() == otherSetup.isDevelopment();
|
||||
}
|
||||
|
||||
CUrl CGlobalSetup::vatsimMetarsUrl() const
|
||||
{
|
||||
return this->m_vatsimMetarsUrl.withAppendedQuery("id=all");
|
||||
}
|
||||
|
||||
CUrlList CGlobalSetup::bootstrapFileUrls() const
|
||||
{
|
||||
CUrlList urls(m_sharedUrls);
|
||||
@@ -179,7 +175,7 @@ namespace BlackCore
|
||||
s.append(vatsimBookingsUrl().toQString(i18n));
|
||||
s.append(separator);
|
||||
s.append("VATSIM METARs: ");
|
||||
s.append(vatsimMetarsUrl().toQString(i18n));
|
||||
s.append(vatsimMetarsUrls().toQString(i18n));
|
||||
s.append(separator);
|
||||
s.append("VATSIM data file: ");
|
||||
s.append(vatsimDataFileUrls().toQString(i18n));
|
||||
@@ -206,12 +202,14 @@ namespace BlackCore
|
||||
return CVariant::fromValue(this->m_dbHttpsPort);
|
||||
case IndexDbLoginService:
|
||||
return CVariant::fromValue(this->dbLoginServiceUrl());
|
||||
case IndexVatsimStatus:
|
||||
return CVariant::fromValue(this->m_vatsimStatusFileUrls);
|
||||
case IndexVatsimData:
|
||||
return CVariant::fromValue(this->m_vatsimDataFileUrls);
|
||||
case IndexVatsimBookings:
|
||||
return CVariant::fromValue(this->m_vatsimDataFileUrls);
|
||||
case IndexVatsimMetars:
|
||||
return CVariant::fromValue(this->m_vatsimMetarsUrl);
|
||||
return CVariant::fromValue(this->m_vatsimMetarsUrls);
|
||||
case IndexUpdateInfo:
|
||||
return CVariant::fromValue(this->updateInfoFileUrls());
|
||||
case IndexBootstrap:
|
||||
@@ -257,7 +255,7 @@ namespace BlackCore
|
||||
this->m_vatsimBookingsUrl.setPropertyByIndex(variant, index.copyFrontRemoved());
|
||||
break;
|
||||
case IndexVatsimMetars:
|
||||
this->m_vatsimMetarsUrl.setPropertyByIndex(variant, index.copyFrontRemoved());
|
||||
this->m_vatsimMetarsUrls = variant.value<CUrlList>();
|
||||
break;
|
||||
case IndexShared:
|
||||
this->m_sharedUrls = variant.value<CUrlList>();
|
||||
@@ -273,7 +271,7 @@ namespace BlackCore
|
||||
|
||||
const QString &CGlobalSetup::versionString()
|
||||
{
|
||||
static const QString v("0.6.1");
|
||||
static const QString v("0.7.0");
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace BlackCore
|
||||
IndexDbHttpPort,
|
||||
IndexDbHttpsPort,
|
||||
IndexDbLoginService,
|
||||
IndexVatsimStatus,
|
||||
IndexVatsimBookings,
|
||||
IndexVatsimMetars,
|
||||
IndexVatsimData,
|
||||
@@ -93,7 +94,10 @@ namespace BlackCore
|
||||
const BlackMisc::Network::CUrl &vatsimBookingsUrl() const { return m_vatsimBookingsUrl; }
|
||||
|
||||
//! VATSIM METAR URL
|
||||
BlackMisc::Network::CUrl vatsimMetarsUrl() const;
|
||||
const BlackMisc::Network::CUrlList &vatsimMetarsUrls() const { return this->m_vatsimMetarsUrls; }
|
||||
|
||||
//! VATSIM status file URLs
|
||||
const BlackMisc::Network::CUrlList &vatsimStatusFileUrls() const { return m_vatsimStatusFileUrls; }
|
||||
|
||||
//! VATSIM data file URLs
|
||||
const BlackMisc::Network::CUrlList &vatsimDataFileUrls() const { return m_vatsimDataFileUrls; }
|
||||
@@ -149,7 +153,8 @@ namespace BlackCore
|
||||
bool m_development = false; //!< dev. version?
|
||||
BlackMisc::Network::CUrl m_dbRootDirectoryUrl; //!< Root directory of DB
|
||||
BlackMisc::Network::CUrl m_vatsimBookingsUrl; //!< ATC bookings
|
||||
BlackMisc::Network::CUrl m_vatsimMetarsUrl; //!< METAR data
|
||||
BlackMisc::Network::CUrlList m_vatsimMetarsUrls; //!< METAR data
|
||||
BlackMisc::Network::CUrlList m_vatsimStatusFileUrls; //!< Status file, where to find the VATSIM files (METAR, data, ATIS, other status files)
|
||||
BlackMisc::Network::CUrlList m_vatsimDataFileUrls; //!< Overall VATSIM data file / merely for bootstrapping the first time
|
||||
BlackMisc::Network::CUrlList m_sharedUrls; //!< where we can obtain shared info files such as bootstrap, ..
|
||||
BlackMisc::Network::CUrlList m_newsUrls; //!< where we can obtain latest news
|
||||
@@ -183,9 +188,10 @@ BLACK_DECLARE_TUPLE_CONVERSION(BlackCore::Data::CGlobalSetup, (
|
||||
attr(o.m_dbRootDirectoryUrl),
|
||||
attr(o.m_dbHttpPort),
|
||||
attr(o.m_dbHttpsPort),
|
||||
attr(o.m_vatsimBookingsUrl),
|
||||
attr(o.m_vatsimMetarsUrl),
|
||||
attr(o.m_vatsimStatusFileUrls),
|
||||
attr(o.m_vatsimDataFileUrls),
|
||||
attr(o.m_vatsimBookingsUrl),
|
||||
attr(o.m_vatsimMetarsUrls),
|
||||
attr(o.m_sharedUrls),
|
||||
attr(o.m_newsUrls),
|
||||
attr(o.m_fsdTestServers),
|
||||
|
||||
@@ -33,8 +33,12 @@ namespace BlackCore
|
||||
//! Properties by index
|
||||
enum ColumnIndex
|
||||
{
|
||||
IndexFsdServers = BlackMisc::CPropertyIndex::GlobalIndexCGlobalSetup + 50,
|
||||
IndexDataFiles
|
||||
IndexServerFiles = BlackMisc::CPropertyIndex::GlobalIndexCVatsimSetup,
|
||||
IndexDataFiles,
|
||||
IndexMetarFiles,
|
||||
IndexFsdServers,
|
||||
IndexCVoiceServers,
|
||||
IndexLastLoginUser
|
||||
};
|
||||
|
||||
//! Default constructor
|
||||
@@ -49,6 +53,18 @@ namespace BlackCore
|
||||
//! Set VATSIM data file URLs
|
||||
void setDataFileUrls(const BlackMisc::Network::CUrlList &urls) { m_dataFileUrls = urls; }
|
||||
|
||||
//! Server file URLs (like data file, only servers)
|
||||
const BlackMisc::Network::CUrlList &getServerFileUrls() const { return m_serverFileUrls; }
|
||||
|
||||
//! Set server file URLs (like data file, only servers)
|
||||
void setServerFileUrls(const BlackMisc::Network::CUrlList &urls) { m_serverFileUrls = urls; }
|
||||
|
||||
//! METAR file URLs
|
||||
const BlackMisc::Network::CUrlList &getMetarFileUrls() const { return m_metarFileUrls; }
|
||||
|
||||
//! METAR file URLs
|
||||
void setMetarFileUrls(const BlackMisc::Network::CUrlList &urls) { m_metarFileUrls = urls; }
|
||||
|
||||
//! FSD test servers
|
||||
const BlackMisc::Network::CServerList &getFsdServers() const { return m_fsdServers; }
|
||||
|
||||
@@ -82,7 +98,9 @@ namespace BlackCore
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(BlackCore::Data::CVatsimSetup)
|
||||
|
||||
BlackMisc::Network::CUrlList m_dataFileUrls; //!< Overall VATSIM data file / merely for bootstrapping the first time
|
||||
BlackMisc::Network::CUrlList m_serverFileUrls; //!< only the FSD servers
|
||||
BlackMisc::Network::CUrlList m_dataFileUrls; //!< Full VATSIM files
|
||||
BlackMisc::Network::CUrlList m_metarFileUrls; //!< METAR files
|
||||
BlackMisc::Network::CServerList m_fsdServers; //!< FSD test servers
|
||||
BlackMisc::Network::CServerList m_voiceServers; //!< voice servers
|
||||
BlackMisc::Network::CUser m_lastLoginUser; //!< last login user
|
||||
@@ -107,9 +125,12 @@ namespace BlackCore
|
||||
|
||||
Q_DECLARE_METATYPE(BlackCore::Data::CVatsimSetup)
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackCore::Data::CVatsimSetup, (
|
||||
attr(o.m_serverFileUrls),
|
||||
attr(o.m_dataFileUrls),
|
||||
attr(o.m_metarFileUrls),
|
||||
attr(o.m_fsdServers),
|
||||
attr(o.m_voiceServers),
|
||||
attr(o.m_lastLoginUser),
|
||||
attr(o.m_timestampMSecsSinceEpoch)
|
||||
))
|
||||
#endif // guard
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "blackmisc/lockfree.h"
|
||||
#include "blackcore/data/globalsetup.h"
|
||||
#include "blackcore/data/updateinfo.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QNetworkReply>
|
||||
@@ -27,9 +26,13 @@
|
||||
namespace BlackCore
|
||||
{
|
||||
//! Read the central URLs / locations of our data / setup.
|
||||
//! This should be only used in BlackCore::CApplication
|
||||
//!
|
||||
//! \details This class should be only used in BlackCore::CApplication. It will also trigger reading
|
||||
//! update information.
|
||||
//!
|
||||
//! \note This class is no(!) BlackCore::CThreadedReader as it will be loaded once during startup
|
||||
//! and is usually fast.
|
||||
//! and reading setup data is fast.
|
||||
//!
|
||||
//! \sa BlackCore::Data::GlobalSetup
|
||||
//! \sa BlackCore::Data::UpdateInfo
|
||||
class BLACKCORE_EXPORT CSetupReader : public QObject
|
||||
|
||||
@@ -158,7 +158,8 @@ namespace BlackCore
|
||||
// remark: Don't use QThread to run network operations in the background
|
||||
// see http://qt-project.org/doc/qt-4.7/qnetworkaccessmanager.html
|
||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing application");
|
||||
const QUrl url(sApp->getGlobalSetup().vatsimDataFileUrls().getRandomUrl());
|
||||
CFailoverUrlList urls(sApp->getVatsimDataFileUrls());
|
||||
const QUrl url(urls.obtainNextWorkingUrl(true));
|
||||
if (url.isEmpty()) { return; }
|
||||
sApp->getFromNetwork(url, { this, &CVatsimDataFileReader::ps_parseVatsimFile});
|
||||
|
||||
@@ -239,7 +240,7 @@ namespace BlackCore
|
||||
if (callsign.isEmpty()) { break; }
|
||||
const BlackMisc::Network::CUser user(clientPartsMap["cid"], clientPartsMap["realname"], callsign);
|
||||
const QString clientType = clientPartsMap["clienttype"].toLower();
|
||||
if (clientType.isEmpty()) break; // sometimes type is empty
|
||||
if (clientType.isEmpty()) { break; } // sometimes type is empty
|
||||
const double lat = clientPartsMap["latitude"].toDouble();
|
||||
const double lng = clientPartsMap["longitude"].toDouble();
|
||||
const double alt = clientPartsMap["altitude"].toDouble();
|
||||
@@ -384,8 +385,8 @@ namespace BlackCore
|
||||
QMap<QString, QString> parts;
|
||||
for (int i = 0; i < clientSectionAttributes.size(); i++)
|
||||
{
|
||||
Q_ASSERT(i < clientSectionAttributes.size());
|
||||
Q_ASSERT(i < clientParts.size());
|
||||
BLACK_VERIFY_X(i < clientSectionAttributes.size(), Q_FUNC_INFO, "Wrong section attribute size");
|
||||
BLACK_VERIFY_X(i < clientParts.size(), Q_FUNC_INFO, "Wrong parts size");
|
||||
parts.insert(clientSectionAttributes.at(i).toLower(), clientParts.at(i));
|
||||
}
|
||||
return parts;
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
//! Read bookings from VATSIM
|
||||
//! Read vatsim data file
|
||||
//! \sa http://info.vroute.net/vatsim-data.txt
|
||||
class BLACKCORE_EXPORT CVatsimDataFileReader : public BlackMisc::CThreadedReader
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -57,7 +58,7 @@ namespace BlackCore
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CServerList getVoiceServers() const;
|
||||
|
||||
//! Get all FSD servers
|
||||
//! Get all VATSIM FSD servers
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CServerList getFsdServers() const;
|
||||
|
||||
|
||||
@@ -63,10 +63,11 @@ namespace BlackCore
|
||||
void CVatsimMetarReader::ps_readMetars()
|
||||
{
|
||||
this->threadAssertCheck();
|
||||
const CUrl url(sApp->getGlobalSetup().vatsimMetarsUrl());
|
||||
CFailoverUrlList urls(sApp->getVatsimMetarUrls());
|
||||
const CUrl url(urls.obtainNextWorkingUrl(true));
|
||||
if (url.isEmpty()) { return; }
|
||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "No Application");
|
||||
sApp->getFromNetwork(url, { this, &CVatsimMetarReader::ps_decodeMetars});
|
||||
sApp->getFromNetwork(url.withAppendedQuery("id=all"), { this, &CVatsimMetarReader::ps_decodeMetars});
|
||||
}
|
||||
|
||||
void CVatsimMetarReader::ps_decodeMetars(QNetworkReply *nwReplyPtr)
|
||||
|
||||
162
src/blackcore/vatsimstatusfilereader.cpp
Normal file
162
src/blackcore/vatsimstatusfilereader.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "blackcore/vatsimstatusfilereader.h"
|
||||
#include "blackcore/application.h"
|
||||
#include "blackmisc/network/urllist.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::Network;
|
||||
using namespace BlackMisc::Geo;
|
||||
using namespace BlackMisc::Simulation;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackCore::Data;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
CVatsimStatusFileReader::CVatsimStatusFileReader(QObject *owner) :
|
||||
CThreadedReader(owner, "CVatsimStatusFileReader")
|
||||
{
|
||||
this->connect(this->m_updateTimer, &QTimer::timeout, this, &CVatsimStatusFileReader::ps_read);
|
||||
}
|
||||
|
||||
void CVatsimStatusFileReader::readInBackgroundThread()
|
||||
{
|
||||
bool s = QMetaObject::invokeMethod(this, "ps_read");
|
||||
Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed");
|
||||
Q_UNUSED(s);
|
||||
}
|
||||
|
||||
CUrlList CVatsimStatusFileReader::getMetarFileUrls() const
|
||||
{
|
||||
return this->m_lastGoodSetup.getCopy().getMetarFileUrls();
|
||||
}
|
||||
|
||||
CUrlList CVatsimStatusFileReader::getDataFileUrls() const
|
||||
{
|
||||
return this->m_lastGoodSetup.getCopy().getDataFileUrls();
|
||||
}
|
||||
|
||||
void CVatsimStatusFileReader::cleanup()
|
||||
{
|
||||
// void
|
||||
}
|
||||
|
||||
void CVatsimStatusFileReader::ps_read()
|
||||
{
|
||||
this->threadAssertCheck();
|
||||
|
||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing application");
|
||||
CFailoverUrlList urls(sApp->getGlobalSetup().vatsimStatusFileUrls());
|
||||
const CUrl url(urls.obtainNextWorkingUrl(true)); // random working URL
|
||||
if (url.isEmpty()) { return; }
|
||||
sApp->getFromNetwork(url, { this, &CVatsimStatusFileReader::ps_parseVatsimFile});
|
||||
}
|
||||
|
||||
void CVatsimStatusFileReader::ps_parseVatsimFile(QNetworkReply *nwReplyPtr)
|
||||
{
|
||||
// wrap pointer, make sure any exit cleans up reply
|
||||
// required to use delete later as object is created in a different thread
|
||||
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
|
||||
|
||||
this->threadAssertCheck();
|
||||
|
||||
// Worker thread, make sure to write only synced here!
|
||||
if (this->isAbandoned())
|
||||
{
|
||||
CLogMessage(this).debug() << Q_FUNC_INFO;
|
||||
CLogMessage(this).info("Terminated VATSIM status file parsing process"); // for users
|
||||
return; // stop, terminate straight away, ending thread
|
||||
}
|
||||
|
||||
QStringList illegalIcaoCodes;
|
||||
if (nwReply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
const QString dataFileData = nwReply->readAll();
|
||||
nwReply->close(); // close asap
|
||||
|
||||
if (dataFileData.isEmpty()) return;
|
||||
const QStringList lines = dataFileData.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
|
||||
if (lines.isEmpty()) { return; }
|
||||
|
||||
CUrlList dataFiles;
|
||||
CUrlList serverFiles;
|
||||
CUrlList metarFiles;
|
||||
|
||||
for (const QString &cl : lines)
|
||||
{
|
||||
if (this->isAbandoned())
|
||||
{
|
||||
CLogMessage(this).debug() << Q_FUNC_INFO;
|
||||
CLogMessage(this).info("Terminated status parsing process"); // for users
|
||||
return; // stop, terminate straight away, ending thread
|
||||
}
|
||||
|
||||
// parse lines
|
||||
const QString currentLine(cl.trimmed());
|
||||
if (currentLine.isEmpty()) { continue; }
|
||||
if (currentLine.startsWith(";")) { continue; }
|
||||
if (!currentLine.contains("=")) { continue; }
|
||||
|
||||
const QStringList parts(currentLine.split('='));
|
||||
if (parts.length() != 2) { continue; }
|
||||
const QString key(parts[0].trimmed().toLower());
|
||||
const QString value(parts[1].trimmed());
|
||||
const CUrl url(value);
|
||||
if (key.startsWith("url0"))
|
||||
{
|
||||
dataFiles.push_back(url);
|
||||
}
|
||||
else if (key.startsWith("url1"))
|
||||
{
|
||||
serverFiles.push_back(url);
|
||||
}
|
||||
else if (key.startsWith("metar"))
|
||||
{
|
||||
metarFiles.push_back(url);
|
||||
}
|
||||
else if (key.startsWith("atis"))
|
||||
{
|
||||
// not yet used
|
||||
}
|
||||
} // for each line
|
||||
|
||||
// this part needs to be synchronized
|
||||
{
|
||||
// cache itself is thread safe
|
||||
CVatsimSetup vs(this->m_lastGoodSetup.getCopy());
|
||||
vs.setDataFileUrls(dataFiles);
|
||||
vs.setMetarFileUrls(metarFiles);
|
||||
vs.setServerFileUrls(serverFiles);
|
||||
vs.setUtcTimestamp(QDateTime::currentDateTime());
|
||||
this->m_lastGoodSetup.set(vs);
|
||||
}
|
||||
|
||||
// warnings, if required
|
||||
if (!illegalIcaoCodes.isEmpty())
|
||||
{
|
||||
CLogMessage(this).info("Illegal / ignored ICAO code(s) in VATSIM data file: %1") << illegalIcaoCodes.join(", ");
|
||||
}
|
||||
|
||||
// data read finished
|
||||
emit this->dataFileRead(lines.count());
|
||||
emit this->dataRead(CEntityFlags::VatsimStatusFile, CEntityFlags::ReadFinished, lines.count());
|
||||
}
|
||||
else
|
||||
{
|
||||
// network error
|
||||
CLogMessage(this).warning("Reading VATSIM status file failed %1 %2") << nwReply->errorString() << nwReply->url().toString();
|
||||
nwReply->abort();
|
||||
emit this->dataRead(CEntityFlags::VatsimStatusFile, CEntityFlags::ReadFailed, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
71
src/blackcore/vatsimstatusfilereader.h
Normal file
71
src/blackcore/vatsimstatusfilereader.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* Copyright (C) 2013
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKCORE_VATSIMSTATUSFILEREADER_H
|
||||
#define BLACKCORE_VATSIMSTATUSFILEREADER_H
|
||||
|
||||
#include "blackcoreexport.h"
|
||||
#include "blackcore/data/vatsimsetup.h"
|
||||
#include "blackmisc/threadedreader.h"
|
||||
#include "blackmisc/network/urllist.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
//! Sole purpose is to read the URLs where VATSIM data can be downloaded
|
||||
//! \sa https://status.vatsim.net/
|
||||
class BLACKCORE_EXPORT CVatsimStatusFileReader : public BlackMisc::CThreadedReader
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
explicit CVatsimStatusFileReader(QObject *owner);
|
||||
|
||||
//! METAR URLs
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrlList getMetarFileUrls() const;
|
||||
|
||||
//! Data file URLs
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrlList getDataFileUrls() const;
|
||||
|
||||
public slots:
|
||||
//! Start reading in own thread
|
||||
void readInBackgroundThread();
|
||||
|
||||
signals:
|
||||
//! Data have been read
|
||||
void dataFileRead(int lines);
|
||||
|
||||
//! Data have been read
|
||||
void dataRead(BlackMisc::Network::CEntityFlags::Entity entity, BlackMisc::Network::CEntityFlags::ReadState state, int number);
|
||||
|
||||
protected:
|
||||
//! \copydoc BlackMisc::CThreadedReader::cleanup
|
||||
virtual void cleanup() override;
|
||||
|
||||
private slots:
|
||||
//! Data have been read, parse VATSIM file
|
||||
void ps_parseVatsimFile(QNetworkReply *nwReply);
|
||||
|
||||
//! Read / re-read data file
|
||||
void ps_read();
|
||||
|
||||
private:
|
||||
BlackMisc::CData<BlackCore::Data::VatsimSetup> m_lastGoodSetup { this };
|
||||
};
|
||||
} // ns
|
||||
|
||||
#endif // guard
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "blackcore/modeldatareader.h"
|
||||
#include "blackcore/icaodatareader.h"
|
||||
#include "blackcore/databasewriter.h"
|
||||
#include "blackcore/vatsimstatusfilereader.h"
|
||||
#include "blackcore/vatsimbookingreader.h"
|
||||
#include "blackcore/vatsimdatafilereader.h"
|
||||
#include "blackcore/vatsimmetarreader.h"
|
||||
@@ -99,6 +100,18 @@ namespace BlackCore
|
||||
return CServerList();
|
||||
}
|
||||
|
||||
CUrlList CWebDataServices::getVatsimMetarUrls() const
|
||||
{
|
||||
if (m_vatsimStatusReader) { return m_vatsimStatusReader->getMetarFileUrls(); }
|
||||
return CUrlList();
|
||||
}
|
||||
|
||||
CUrlList CWebDataServices::getVatsimDataFileUrls() const
|
||||
{
|
||||
if (m_vatsimStatusReader) { return m_vatsimStatusReader->getDataFileUrls(); }
|
||||
return CUrlList();
|
||||
}
|
||||
|
||||
CUserList CWebDataServices::getUsersForCallsign(const CCallsign &callsign) const
|
||||
{
|
||||
if (m_vatsimDataFileReader) { return m_vatsimDataFileReader->getUsersForCallsign(callsign); }
|
||||
@@ -392,6 +405,7 @@ namespace BlackCore
|
||||
void CWebDataServices::gracefulShutdown()
|
||||
{
|
||||
this->disconnect(); // all signals
|
||||
if (this->m_vatsimStatusReader) { this->m_vatsimStatusReader->gracefulShutdown(); }
|
||||
if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->gracefulShutdown(); }
|
||||
if (this->m_vatsimDataFileReader) { this->m_vatsimDataFileReader->gracefulShutdown(); }
|
||||
if (this->m_vatsimMetarReader) { this->m_vatsimMetarReader->gracefulShutdown(); }
|
||||
@@ -408,7 +422,16 @@ namespace BlackCore
|
||||
|
||||
void CWebDataServices::initReaders(CWebReaderFlags::WebReader flags)
|
||||
{
|
||||
// 1. VATSIM bookings
|
||||
// 1. Status file, updating the cache
|
||||
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimDataReader) || flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimMetarReader))
|
||||
{
|
||||
this->m_vatsimStatusReader = new CVatsimStatusFileReader(this);
|
||||
this->m_vatsimStatusReader->start(QThread::LowPriority);
|
||||
this->m_vatsimStatusReader->setInterval(60 * 60 * 1000); // very slow updates required only
|
||||
QTimer::singleShot(100, this->m_vatsimStatusReader, &CVatsimStatusFileReader::readInBackgroundThread);
|
||||
}
|
||||
|
||||
// 2. VATSIM bookings
|
||||
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimBookingReader))
|
||||
{
|
||||
this->m_vatsimBookingReader = new CVatsimBookingReader(this);
|
||||
@@ -419,7 +442,7 @@ namespace BlackCore
|
||||
this->m_vatsimBookingReader->setInterval(3 * 60 * 1000);
|
||||
}
|
||||
|
||||
// 2. VATSIM data file
|
||||
// 3. VATSIM data file
|
||||
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimDataReader))
|
||||
{
|
||||
this->m_vatsimDataFileReader = new CVatsimDataFileReader(this);
|
||||
@@ -430,7 +453,7 @@ namespace BlackCore
|
||||
this->m_vatsimDataFileReader->setInterval(90 * 1000);
|
||||
}
|
||||
|
||||
// 3. VATSIM metar data
|
||||
// 4. VATSIM metar data
|
||||
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::VatsimMetarReader))
|
||||
{
|
||||
this->m_vatsimMetarReader = new CVatsimMetarReader(this);
|
||||
@@ -441,7 +464,7 @@ namespace BlackCore
|
||||
this->m_vatsimMetarReader->setInterval(90 * 1000);
|
||||
}
|
||||
|
||||
// 4. ICAO data reader
|
||||
// 5. ICAO data reader
|
||||
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::IcaoDataReader))
|
||||
{
|
||||
bool c;
|
||||
@@ -452,7 +475,7 @@ namespace BlackCore
|
||||
this->m_icaoDataReader->start(QThread::LowPriority);
|
||||
}
|
||||
|
||||
// 5. Model reader
|
||||
// 6. Model reader
|
||||
if (flags.testFlag(CWebReaderFlags::WebReaderFlag::ModelReader))
|
||||
{
|
||||
this->m_modelDataReader = new CModelDataReader(this);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "blackmisc/aviation/airlineicaocodelist.h"
|
||||
#include "blackmisc/aviation/aircrafticaocodelist.h"
|
||||
#include "blackmisc/network/serverlist.h"
|
||||
#include "blackmisc/network/urllist.h"
|
||||
#include "blackmisc/network/voicecapabilities.h"
|
||||
#include "blackmisc/network/entityflags.h"
|
||||
#include "blackmisc/simulation/distributorlist.h"
|
||||
@@ -31,6 +32,7 @@
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
class CVatsimStatusFileReader;
|
||||
class CVatsimBookingReader;
|
||||
class CVatsimDataFileReader;
|
||||
class CVatsimMetarReader;
|
||||
@@ -84,6 +86,14 @@ namespace BlackCore
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CServerList getVatsimVoiceServers() const;
|
||||
|
||||
//! METAR URLs (from status file)
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrlList getVatsimMetarUrls() const;
|
||||
|
||||
//! Data file locations (from status file)
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrlList getVatsimDataFileUrls() const;
|
||||
|
||||
//! Users by callsign
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUserList getUsersForCallsign(const BlackMisc::Aviation::CCallsign &callsign) const;
|
||||
@@ -283,6 +293,7 @@ namespace BlackCore
|
||||
bool m_initialRead = false; //!< Initial read conducted
|
||||
|
||||
// for reading XML and VATSIM data files
|
||||
CVatsimStatusFileReader *m_vatsimStatusReader = nullptr;
|
||||
CVatsimBookingReader *m_vatsimBookingReader = nullptr;
|
||||
CVatsimDataFileReader *m_vatsimDataFileReader = nullptr;
|
||||
CVatsimMetarReader *m_vatsimMetarReader = nullptr;
|
||||
|
||||
@@ -29,31 +29,32 @@ namespace BlackMisc
|
||||
//! Which data to read, requires corresponding readers
|
||||
enum EntityFlag
|
||||
{
|
||||
NoEntity = 0, ///< no data at all
|
||||
VatsimDataFile = 1 << 0, ///< the VATSIM data file (multiple data entities)
|
||||
BookingEntity = 1 << 1, ///< bookings
|
||||
MetarEntity = 1 << 2,
|
||||
AircraftIcaoEntity = 1 << 3, ///< ICAO codes for aircraft
|
||||
AirlineIcaoEntity = 1 << 4, ///< ICAO codes for airlines
|
||||
CountryEntity = 1 << 5, ///< country codes
|
||||
DistributorEntity = 1 << 6, ///< distributors
|
||||
LiveryEntity = 1 << 7, ///< liveries
|
||||
ModelEntity = 1 << 8, ///< models
|
||||
AllIcaoEntities = AircraftIcaoEntity | AirlineIcaoEntity, ///< all ICAO codes
|
||||
AllIcaoAndCountries = AircraftIcaoEntity | AirlineIcaoEntity | CountryEntity, ///< all ICAO codes and countries
|
||||
DistributorLiveryModel = DistributorEntity | LiveryEntity | ModelEntity, ///< Combinded
|
||||
AllDbEntities = AllIcaoEntities | DistributorLiveryModel, ///< All DB stuff
|
||||
AllEntities = 0xFFFF ///< everything
|
||||
NoEntity = 0, //!< no data at all
|
||||
BookingEntity = 1 << 0, //!< bookings
|
||||
MetarEntity = 1 << 1, //!< METAR
|
||||
AircraftIcaoEntity = 1 << 2, //!< ICAO codes for aircraft
|
||||
AirlineIcaoEntity = 1 << 3, //!< ICAO codes for airlines
|
||||
CountryEntity = 1 << 4, //!< country codes
|
||||
DistributorEntity = 1 << 5, //!< distributors
|
||||
LiveryEntity = 1 << 6, //!< liveries
|
||||
ModelEntity = 1 << 7, //!< models
|
||||
VatsimDataFile = 1 << 8, //!< the VATSIM data file (multiple data entities)
|
||||
VatsimStatusFile = 1 << 9, //!< the VATSIM status file (URLs for data files etc.)
|
||||
AllEntities = ((1<<10)-1), //!< everything
|
||||
AllIcaoEntities = AircraftIcaoEntity | AirlineIcaoEntity, //!< all ICAO codes
|
||||
AllIcaoAndCountries = AircraftIcaoEntity | AirlineIcaoEntity | CountryEntity, //!< all ICAO codes and countries
|
||||
DistributorLiveryModel = DistributorEntity | LiveryEntity | ModelEntity, //!< Combinded
|
||||
AllDbEntities = AllIcaoEntities | DistributorLiveryModel, //!< All DB stuff
|
||||
};
|
||||
Q_DECLARE_FLAGS(Entity, EntityFlag)
|
||||
|
||||
//! State of operation
|
||||
enum ReadState
|
||||
{
|
||||
StartRead, ///< reading has been started
|
||||
ReadFinished, ///< reading done
|
||||
ReadFinishedRestricted, ///< finished a timestamp restricted read
|
||||
ReadFailed ///< reading failed
|
||||
StartRead, //!< reading has been started
|
||||
ReadFinished, //!< reading done
|
||||
ReadFinishedRestricted, //!< finished a timestamp restricted read
|
||||
ReadFailed //!< reading failed
|
||||
};
|
||||
|
||||
//! Convert to string
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace BlackMisc
|
||||
GlobalIndexIDatastoreString = 11100,
|
||||
GlobalIndexCGlobalSetup = 12000,
|
||||
GlobalIndexCUpdateInfo = 12100,
|
||||
GlobalIndexCVatsimSetup = 12200,
|
||||
GlobalIndexAbuseMode = 20000 // property index abused as map key or otherwise, to be removed if no longer needed
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user