常规更新
This commit is contained in:
+2
-2
@@ -38,7 +38,7 @@
|
|||||||
"function_name": "adsb_read"
|
"function_name": "adsb_read"
|
||||||
},
|
},
|
||||||
"web_server": {
|
"web_server": {
|
||||||
"webapp": "D:/ae/proj/projects/ECAP_Server/ver/v1.0.4/wwwroot",
|
"webapp": "@/../third_party/eacp_webapp/wwwroot",
|
||||||
"tiles": "D:/tiles"
|
"tiles": "D:/tiles"
|
||||||
},
|
},
|
||||||
"device": {
|
"device": {
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
"mlat_server": true
|
"mlat_server": true
|
||||||
},
|
},
|
||||||
"external_database": {
|
"external_database": {
|
||||||
"ecap_sqlite_path": "D:/ae/proj/projects/ECAP_Server/sqlite/ecap.sqlite",
|
"ecap_sqlite_path": "@/../data/sqlite/ecap.sqlite",
|
||||||
"list": [
|
"list": [
|
||||||
{
|
{
|
||||||
"name": "tar1090_db_aircraft",
|
"name": "tar1090_db_aircraft",
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
#include "../server/Global.h"
|
#include "../server/Global.h"
|
||||||
#include "../server/Performance_Monitor.h"
|
#include "../server/Performance_Monitor.h"
|
||||||
#include "Core/Base/Coro_Result.h"
|
#include "Core/Base/Coro_Result.h"
|
||||||
#include "Resource_Utils.h"
|
#include "Resource_Utils.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
|
|
||||||
#include <SQLiteCpp/Statement.h>
|
#include <SQLiteCpp/Statement.h>
|
||||||
#include <SQLiteCpp/Transaction.h>
|
#include <SQLiteCpp/Transaction.h>
|
||||||
#include <drogon/MultiPart.h>
|
#include <drogon/MultiPart.h>
|
||||||
#include <trantor/utils/ConcurrentTaskQueue.h>
|
#include <trantor/utils/ConcurrentTaskQueue.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
@@ -18,7 +15,6 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Psc::JSON
|
Psc::JSON
|
||||||
external_resource_status_to_json(const External_Resource_Status& status) {
|
external_resource_status_to_json(const External_Resource_Status& status) {
|
||||||
@@ -30,7 +26,6 @@ namespace {
|
|||||||
{"message", status.message},
|
{"message", status.message},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Psc::JSON external_resource_status_list_to_json(
|
Psc::JSON external_resource_status_list_to_json(
|
||||||
const std::vector<External_Resource_Status>& status_list) {
|
const std::vector<External_Resource_Status>& status_list) {
|
||||||
auto result = Psc::JSON::array();
|
auto result = Psc::JSON::array();
|
||||||
@@ -39,27 +34,24 @@ namespace {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
trantor::ConcurrentTaskQueue& external_database_task_queue() {
|
trantor::ConcurrentTaskQueue& external_database_task_queue() {
|
||||||
static trantor::ConcurrentTaskQueue queue(2, "external_database");
|
static trantor::ConcurrentTaskQueue queue(2, "external_database");
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Work, typename Callback>
|
template <typename T, typename Work, typename Callback>
|
||||||
void run_external_database_async(Work&& work, Callback&& callback) {
|
void run_external_database_async(Work&& work, Callback&& callback) {
|
||||||
auto callback_holder = std::make_shared<std::decay_t<Callback>>(
|
auto callback_holder = std::make_shared<std::decay_t<Callback>>(
|
||||||
std::forward<Callback>(callback));
|
std::forward<Callback>(callback));
|
||||||
|
|
||||||
external_database_task_queue().runTaskInQueue(
|
external_database_task_queue().runTaskInQueue(
|
||||||
[work = std::forward<Work>(work), callback_holder]() mutable {
|
[work = std::forward<Work>(work), callback_holder]() mutable {
|
||||||
try {
|
try {
|
||||||
(*callback_holder)(nullptr, work());
|
(*callback_holder)(nullptr, work());
|
||||||
} catch (...) {
|
}
|
||||||
|
catch (...) {
|
||||||
(*callback_holder)(std::current_exception(), T{});
|
(*callback_holder)(std::current_exception(), T{});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Starter>
|
template <typename T, typename Starter>
|
||||||
asio::awaitable<T> await_external_database_callback(Starter starter) {
|
asio::awaitable<T> await_external_database_callback(Starter starter) {
|
||||||
auto result = co_await Psc::coro::callback_result<T>(
|
auto result = co_await Psc::coro::callback_result<T>(
|
||||||
@@ -76,13 +68,11 @@ namespace {
|
|||||||
co_return std::move(result);
|
co_return std::move(result);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::optional<std::string>
|
std::optional<std::string>
|
||||||
External_Database_Row::get(std::string_view column) const {
|
External_Database_Row::get(std::string_view column) const {
|
||||||
const auto iter = columns.find(std::string(column));
|
const auto iter = columns.find(std::string(column));
|
||||||
return iter == columns.end() ? std::nullopt : iter->second;
|
return iter == columns.end() ? std::nullopt : iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Psc::JSON External_Database_Row::to_json() const {
|
Psc::JSON External_Database_Row::to_json() const {
|
||||||
auto result = Psc::JSON::object();
|
auto result = Psc::JSON::object();
|
||||||
for (const auto& [column, value] : columns) {
|
for (const auto& [column, value] : columns) {
|
||||||
@@ -90,7 +80,6 @@ Psc::JSON External_Database_Row::to_json() const {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resources::External_Resources(
|
External_Resources::External_Resources(
|
||||||
std::string_view name, std::string_view cache_file_name, std::string_view download_url,
|
std::string_view name, std::string_view cache_file_name, std::string_view download_url,
|
||||||
std::string_view description, const std::uint64_t update_interval_seconds) {
|
std::string_view description, const std::uint64_t update_interval_seconds) {
|
||||||
@@ -100,25 +89,22 @@ External_Resources::External_Resources(
|
|||||||
this->description = std::string(description);
|
this->description = std::string(description);
|
||||||
this->update_interval_seconds = update_interval_seconds;
|
this->update_interval_seconds = update_interval_seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources::mark_updated() {
|
void External_Resources::mark_updated() {
|
||||||
last_updated_at = std::time(nullptr);
|
last_updated_at = std::time(nullptr);
|
||||||
}
|
}
|
||||||
|
void External_Resources::clear_last_updated_at() {
|
||||||
void External_Resources::clear_last_updated_at() { last_updated_at = 0; }
|
last_updated_at = 0;
|
||||||
|
}
|
||||||
std::size_t External_Resources::row_count(SQLite::Database& db) const {
|
std::size_t External_Resources::row_count(SQLite::Database& db) const {
|
||||||
return static_cast<std::size_t>(
|
return static_cast<std::size_t>(
|
||||||
db.execAndGet("SELECT COUNT(*) FROM " +
|
db.execAndGet("SELECT COUNT(*) FROM " +
|
||||||
External_Database_Utils::quote_identifier(name))
|
External_Database_Utils::quote_identifier(name))
|
||||||
.getInt64());
|
.getInt64());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path
|
std::filesystem::path
|
||||||
External_Resources::source_file(const std::filesystem::path& cache_pos) const {
|
External_Resources::source_file(const std::filesystem::path& cache_pos) const {
|
||||||
return cache_pos / cache_file_name;
|
return cache_pos / cache_file_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool External_Resources::fetch(const std::filesystem::path& cache_pos,
|
bool External_Resources::fetch(const std::filesystem::path& cache_pos,
|
||||||
const bool force_download) const {
|
const bool force_download) const {
|
||||||
const auto target_file = source_file(cache_pos);
|
const auto target_file = source_file(cache_pos);
|
||||||
@@ -129,7 +115,6 @@ bool External_Resources::fetch(const std::filesystem::path &cache_pos,
|
|||||||
External_Database_Utils::download_to_file(download_url, target_file);
|
External_Database_Utils::download_to_file(download_url, target_file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status External_Resources::update(SQLite::Database& db, const std::filesystem::path& cache_pos,
|
External_Resource_Status External_Resources::update(SQLite::Database& db, const std::filesystem::path& cache_pos,
|
||||||
const bool force_download, const bool only_when_empty) {
|
const bool force_download, const bool only_when_empty) {
|
||||||
create_table(db);
|
create_table(db);
|
||||||
@@ -154,14 +139,12 @@ External_Resource_Status External_Resources::update(SQLite::Database &db, const
|
|||||||
: "cache file unavailable";
|
: "cache file unavailable";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.row_count = import_file(db, local_file);
|
result.row_count = import_file(db, local_file);
|
||||||
result.imported = true;
|
result.imported = true;
|
||||||
result.message = "ok";
|
result.message = "ok";
|
||||||
mark_updated();
|
mark_updated();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status
|
External_Resource_Status
|
||||||
External_Resources::import_offline(SQLite::Database& db,
|
External_Resources::import_offline(SQLite::Database& db,
|
||||||
const std::filesystem::path& source_file) {
|
const std::filesystem::path& source_file) {
|
||||||
@@ -173,7 +156,6 @@ External_Resources::import_offline(SQLite::Database &db,
|
|||||||
mark_updated();
|
mark_updated();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status
|
External_Resource_Status
|
||||||
External_Resources::clear_table(SQLite::Database& db,
|
External_Resources::clear_table(SQLite::Database& db,
|
||||||
const std::filesystem::path& cache_pos) {
|
const std::filesystem::path& cache_pos) {
|
||||||
@@ -182,7 +164,6 @@ External_Resources::clear_table(SQLite::Database &db,
|
|||||||
External_Database_Utils::quote_identifier(name));
|
External_Database_Utils::quote_identifier(name));
|
||||||
create_table(db);
|
create_table(db);
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
if (!cache_file_name.empty()) {
|
if (!cache_file_name.empty()) {
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
std::filesystem::remove(source_file(cache_pos), error);
|
std::filesystem::remove(source_file(cache_pos), error);
|
||||||
@@ -191,11 +172,9 @@ External_Resources::clear_table(SQLite::Database &db,
|
|||||||
": " + error.message());
|
": " + error.message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_last_updated_at();
|
clear_last_updated_at();
|
||||||
return {name, 0, false, false, "table cleared"};
|
return {name, 0, false, false, "table cleared"};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<External_Database_Row> External_Resources::query_one(
|
std::optional<External_Database_Row> External_Resources::query_one(
|
||||||
SQLite::Database& db,
|
SQLite::Database& db,
|
||||||
const std::vector<std::string>& primary_key_values) const {
|
const std::vector<std::string>& primary_key_values) const {
|
||||||
@@ -204,7 +183,6 @@ std::optional<External_Database_Row> External_Resources::query_one(
|
|||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
"primary key value count mismatch for resource: " + name);
|
"primary key value count mismatch for resource: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sql = "SELECT * FROM " +
|
std::string sql = "SELECT * FROM " +
|
||||||
External_Database_Utils::quote_identifier(name) + " WHERE ";
|
External_Database_Utils::quote_identifier(name) + " WHERE ";
|
||||||
for (std::size_t index = 0; index < columns.size(); ++index) {
|
for (std::size_t index = 0; index < columns.size(); ++index) {
|
||||||
@@ -214,7 +192,6 @@ std::optional<External_Database_Row> External_Resources::query_one(
|
|||||||
" = ? COLLATE NOCASE";
|
" = ? COLLATE NOCASE";
|
||||||
}
|
}
|
||||||
sql += " LIMIT 1";
|
sql += " LIMIT 1";
|
||||||
|
|
||||||
SQLite::Statement statement(db, sql);
|
SQLite::Statement statement(db, sql);
|
||||||
for (std::size_t index = 0; index < primary_key_values.size(); ++index) {
|
for (std::size_t index = 0; index < primary_key_values.size(); ++index) {
|
||||||
statement.bind(
|
statement.bind(
|
||||||
@@ -223,19 +200,18 @@ std::optional<External_Database_Row> External_Resources::query_one(
|
|||||||
}
|
}
|
||||||
if (!statement.executeStep())
|
if (!statement.executeStep())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
External_Database_Row row;
|
External_Database_Row row;
|
||||||
for (int index = 0; index < statement.getColumnCount(); ++index) {
|
for (int index = 0; index < statement.getColumnCount(); ++index) {
|
||||||
const auto name = statement.getColumnName(index);
|
const auto name = statement.getColumnName(index);
|
||||||
if (statement.isColumnNull(index)) {
|
if (statement.isColumnNull(index)) {
|
||||||
row.columns.emplace(name, std::nullopt);
|
row.columns.emplace(name, std::nullopt);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
row.columns.emplace(name, statement.getColumn(index).getString());
|
row.columns.emplace(name, statement.getColumn(index).getString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resources_Manager::External_Resources_Manager() {
|
External_Resources_Manager::External_Resources_Manager() {
|
||||||
register_external_resource(make_tar1090_db_aircraft_csv_gz_resource());
|
register_external_resource(make_tar1090_db_aircraft_csv_gz_resource());
|
||||||
register_external_resource(make_wiedehopf_tar1090_db_resource());
|
register_external_resource(make_wiedehopf_tar1090_db_resource());
|
||||||
@@ -249,7 +225,6 @@ External_Resources_Manager::External_Resources_Manager() {
|
|||||||
register_external_resource(make_vradarserver_standing_data_resource());
|
register_external_resource(make_vradarserver_standing_data_resource());
|
||||||
register_external_resource(make_opensky_flightdata_api_resource());
|
register_external_resource(make_opensky_flightdata_api_resource());
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::init(const Psc::JSON* that_json) {
|
void External_Resources_Manager::init(const Psc::JSON* that_json) {
|
||||||
if (!that_json)
|
if (!that_json)
|
||||||
return;
|
return;
|
||||||
@@ -270,7 +245,6 @@ void External_Resources_Manager::init(const Psc::JSON *that_json) {
|
|||||||
}
|
}
|
||||||
Get_J(ecap_sqlite_path)
|
Get_J(ecap_sqlite_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
Psc::JSON External_Resources_Manager::to_base_json() const {
|
Psc::JSON External_Resources_Manager::to_base_json() const {
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
auto ret = Psc::JSON::object();
|
auto ret = Psc::JSON::object();
|
||||||
@@ -282,15 +256,14 @@ Psc::JSON External_Resources_Manager::to_base_json() const {
|
|||||||
ret.children.emplace_back(Psc::JSON{"list", list});
|
ret.children.emplace_back(Psc::JSON{"list", list});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::load_sqlite_db(std::string_view path) {
|
void External_Resources_Manager::load_sqlite_db(std::string_view path) {
|
||||||
try {
|
try {
|
||||||
db_ = std::make_unique<SQLite::Database>(path, SQLite::OPEN_READWRITE |
|
db_ = std::make_unique<SQLite::Database>(path, SQLite::OPEN_READWRITE |
|
||||||
SQLite::OPEN_CREATE);
|
SQLite::OPEN_CREATE);
|
||||||
} catch (SQLite::Exception &error) {
|
}
|
||||||
|
catch (SQLite::Exception& error) {
|
||||||
Psc::fail_fast(std::string("load_sqlite_db error: ") + error.what());
|
Psc::fail_fast(std::string("load_sqlite_db error: ") + error.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
db_->exec("PRAGMA journal_mode=WAL;");
|
db_->exec("PRAGMA journal_mode=WAL;");
|
||||||
db_->exec("PRAGMA synchronous=NORMAL;");
|
db_->exec("PRAGMA synchronous=NORMAL;");
|
||||||
auto pos = std::filesystem::path(path).parent_path();
|
auto pos = std::filesystem::path(path).parent_path();
|
||||||
@@ -298,54 +271,45 @@ void External_Resources_Manager::load_sqlite_db(std::string_view path) {
|
|||||||
initialize(*db_, pos);
|
initialize(*db_, pos);
|
||||||
sync_missing(*db_);
|
sync_missing(*db_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<External_Resource_Status>
|
std::vector<External_Resource_Status>
|
||||||
External_Resources_Manager::refresh_external_databases(
|
External_Resources_Manager::refresh_external_databases(
|
||||||
const bool force_download) {
|
const bool force_download) {
|
||||||
return refresh_all(require_db(), force_download);
|
return refresh_all(require_db(), force_download);
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status External_Resources_Manager::refresh_external_database(
|
External_Resource_Status External_Resources_Manager::refresh_external_database(
|
||||||
std::string_view resource_name, const bool force_download) {
|
std::string_view resource_name, const bool force_download) {
|
||||||
return refresh_one(require_db(), resource_name, force_download);
|
return refresh_one(require_db(), resource_name, force_download);
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status External_Resources_Manager::import_external_database(
|
External_Resource_Status External_Resources_Manager::import_external_database(
|
||||||
std::string_view resource_name,
|
std::string_view resource_name,
|
||||||
const std::filesystem::path& source_file) {
|
const std::filesystem::path& source_file) {
|
||||||
return import_offline(require_db(), resource_name, source_file);
|
return import_offline(require_db(), resource_name, source_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status
|
External_Resource_Status
|
||||||
External_Resources_Manager::clear_external_database_table(
|
External_Resources_Manager::clear_external_database_table(
|
||||||
std::string_view resource_name) {
|
std::string_view resource_name) {
|
||||||
return clear_table(require_db(), resource_name);
|
return clear_table(require_db(), resource_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<External_Database_Row>
|
std::optional<External_Database_Row>
|
||||||
External_Resources_Manager::query_external_database(
|
External_Resources_Manager::query_external_database(
|
||||||
std::string_view resource_name,
|
std::string_view resource_name,
|
||||||
const std::vector<std::string>& primary_key_values) const {
|
const std::vector<std::string>& primary_key_values) const {
|
||||||
return query_one(require_db(), resource_name, primary_key_values);
|
return query_one(require_db(), resource_name, primary_key_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
||||||
External_Resources_Manager::query_aircraft_external_databases(
|
External_Resources_Manager::query_aircraft_external_databases(
|
||||||
std::string_view icao24) const {
|
std::string_view icao24) const {
|
||||||
return query_aircraft(require_db(), icao24);
|
return query_aircraft(require_db(), icao24);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
||||||
External_Resources_Manager::query_callsign_external_databases(
|
External_Resources_Manager::query_callsign_external_databases(
|
||||||
const std::optional<std::string>& callsign) const {
|
const std::optional<std::string>& callsign) const {
|
||||||
return query_callsign(require_db(), callsign);
|
return query_callsign(require_db(), callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<External_Resource_Status>
|
std::vector<External_Resource_Status>
|
||||||
External_Resources_Manager::external_database_status() const {
|
External_Resources_Manager::external_database_status() const {
|
||||||
return status(require_db());
|
return status(require_db());
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_refresh_external_databases(
|
void External_Resources_Manager::async_refresh_external_databases(
|
||||||
const bool force_download, Status_List_Callback callback) {
|
const bool force_download, Status_List_Callback callback) {
|
||||||
run_external_database_async<std::vector<External_Resource_Status>>(
|
run_external_database_async<std::vector<External_Resource_Status>>(
|
||||||
@@ -354,7 +318,6 @@ void External_Resources_Manager::async_refresh_external_databases(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_refresh_external_database(
|
void External_Resources_Manager::async_refresh_external_database(
|
||||||
std::string_view resource_name, const bool force_download,
|
std::string_view resource_name, const bool force_download,
|
||||||
Status_Callback callback) {
|
Status_Callback callback) {
|
||||||
@@ -364,7 +327,6 @@ void External_Resources_Manager::async_refresh_external_database(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_import_external_database(
|
void External_Resources_Manager::async_import_external_database(
|
||||||
std::string_view resource_name, std::filesystem::path source_file,
|
std::string_view resource_name, std::filesystem::path source_file,
|
||||||
Status_Callback callback) {
|
Status_Callback callback) {
|
||||||
@@ -375,7 +337,6 @@ void External_Resources_Manager::async_import_external_database(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_clear_external_database_table(
|
void External_Resources_Manager::async_clear_external_database_table(
|
||||||
std::string_view resource_name, Status_Callback callback) {
|
std::string_view resource_name, Status_Callback callback) {
|
||||||
run_external_database_async<External_Resource_Status>(
|
run_external_database_async<External_Resource_Status>(
|
||||||
@@ -384,7 +345,6 @@ void External_Resources_Manager::async_clear_external_database_table(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_query_external_database(
|
void External_Resources_Manager::async_query_external_database(
|
||||||
std::string_view resource_name, std::vector<std::string> primary_key_values,
|
std::string_view resource_name, std::vector<std::string> primary_key_values,
|
||||||
Row_Callback callback) const {
|
Row_Callback callback) const {
|
||||||
@@ -395,7 +355,6 @@ void External_Resources_Manager::async_query_external_database(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_query_aircraft_external_databases(
|
void External_Resources_Manager::async_query_aircraft_external_databases(
|
||||||
std::string_view icao24, Row_Map_Callback callback) const {
|
std::string_view icao24, Row_Map_Callback callback) const {
|
||||||
run_external_database_async<
|
run_external_database_async<
|
||||||
@@ -405,7 +364,6 @@ void External_Resources_Manager::async_query_aircraft_external_databases(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_query_callsign_external_databases(
|
void External_Resources_Manager::async_query_callsign_external_databases(
|
||||||
std::optional<std::string> callsign, Row_Map_Callback callback) const {
|
std::optional<std::string> callsign, Row_Map_Callback callback) const {
|
||||||
run_external_database_async<
|
run_external_database_async<
|
||||||
@@ -415,13 +373,13 @@ void External_Resources_Manager::async_query_callsign_external_databases(
|
|||||||
},
|
},
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::async_external_database_status(
|
void External_Resources_Manager::async_external_database_status(
|
||||||
Status_List_Callback callback) const {
|
Status_List_Callback callback) const {
|
||||||
run_external_database_async<std::vector<External_Resource_Status>>(
|
run_external_database_async<std::vector<External_Resource_Status>>(
|
||||||
[this]() { return external_database_status(); }, std::move(callback));
|
[this]() {
|
||||||
|
return external_database_status();
|
||||||
|
}, std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<std::vector<External_Resource_Status>>
|
asio::awaitable<std::vector<External_Resource_Status>>
|
||||||
External_Resources_Manager::refresh_external_databases_coro(
|
External_Resources_Manager::refresh_external_databases_coro(
|
||||||
const bool force_download) {
|
const bool force_download) {
|
||||||
@@ -431,7 +389,6 @@ External_Resources_Manager::refresh_external_databases_coro(
|
|||||||
async_refresh_external_databases(force_download, std::move(callback));
|
async_refresh_external_databases(force_download, std::move(callback));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<External_Resource_Status>
|
asio::awaitable<External_Resource_Status>
|
||||||
External_Resources_Manager::refresh_external_database_coro(
|
External_Resources_Manager::refresh_external_database_coro(
|
||||||
std::string_view resource_name, const bool force_download) {
|
std::string_view resource_name, const bool force_download) {
|
||||||
@@ -442,7 +399,6 @@ External_Resources_Manager::refresh_external_database_coro(
|
|||||||
force_download, std::move(callback));
|
force_download, std::move(callback));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<External_Resource_Status>
|
asio::awaitable<External_Resource_Status>
|
||||||
External_Resources_Manager::import_external_database_coro(
|
External_Resources_Manager::import_external_database_coro(
|
||||||
std::string_view resource_name, std::filesystem::path source_file) {
|
std::string_view resource_name, std::filesystem::path source_file) {
|
||||||
@@ -454,7 +410,6 @@ External_Resources_Manager::import_external_database_coro(
|
|||||||
std::move(callback));
|
std::move(callback));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<External_Resource_Status>
|
asio::awaitable<External_Resource_Status>
|
||||||
External_Resources_Manager::clear_external_database_table_coro(
|
External_Resources_Manager::clear_external_database_table_coro(
|
||||||
std::string_view resource_name) {
|
std::string_view resource_name) {
|
||||||
@@ -465,7 +420,6 @@ External_Resources_Manager::clear_external_database_table_coro(
|
|||||||
std::move(callback));
|
std::move(callback));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<std::optional<External_Database_Row>>
|
asio::awaitable<std::optional<External_Database_Row>>
|
||||||
External_Resources_Manager::query_external_database_coro(
|
External_Resources_Manager::query_external_database_coro(
|
||||||
std::string_view resource_name,
|
std::string_view resource_name,
|
||||||
@@ -480,7 +434,6 @@ External_Resources_Manager::query_external_database_coro(
|
|||||||
std::move(callback));
|
std::move(callback));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<std::shared_ptr<External_Database_Row_Map>>
|
asio::awaitable<std::shared_ptr<External_Database_Row_Map>>
|
||||||
External_Resources_Manager::query_aircraft_external_databases_coro(
|
External_Resources_Manager::query_aircraft_external_databases_coro(
|
||||||
std::string_view icao24) const {
|
std::string_view icao24) const {
|
||||||
@@ -501,7 +454,6 @@ External_Resources_Manager::query_aircraft_external_databases_coro(
|
|||||||
});
|
});
|
||||||
co_return result;
|
co_return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<std::shared_ptr<External_Database_Row_Map>>
|
asio::awaitable<std::shared_ptr<External_Database_Row_Map>>
|
||||||
External_Resources_Manager::query_callsign_external_databases_coro(
|
External_Resources_Manager::query_callsign_external_databases_coro(
|
||||||
std::optional<std::string> callsign) const {
|
std::optional<std::string> callsign) const {
|
||||||
@@ -522,7 +474,6 @@ External_Resources_Manager::query_callsign_external_databases_coro(
|
|||||||
});
|
});
|
||||||
co_return result;
|
co_return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
asio::awaitable<std::vector<External_Resource_Status>>
|
asio::awaitable<std::vector<External_Resource_Status>>
|
||||||
External_Resources_Manager::external_database_status_coro() const {
|
External_Resources_Manager::external_database_status_coro() const {
|
||||||
co_return co_await await_external_database_callback<
|
co_return co_await await_external_database_callback<
|
||||||
@@ -531,27 +482,23 @@ External_Resources_Manager::external_database_status_coro() const {
|
|||||||
async_external_database_status(std::move(callback));
|
async_external_database_status(std::move(callback));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::server(Global* g) {
|
void External_Resources_Manager::server(Global* g) {
|
||||||
auto& svr = g->svr;
|
auto& svr = g->svr;
|
||||||
const auto& api = g->api;
|
const auto& api = g->api;
|
||||||
|
|
||||||
svr.Post(api + "get_external_database_config", [this](HTTP_Param) {
|
svr.Post(api + "get_external_database_config", [this](HTTP_Param) {
|
||||||
auto t = warp(to_base_json()).to_json_string();
|
auto t = warp(to_base_json()).to_json_string();
|
||||||
|
|
||||||
res->setBody(t);
|
res->setBody(t);
|
||||||
});
|
});
|
||||||
svr.PostCoro(
|
svr.Post_Coro(
|
||||||
api + "get_external_database_status",
|
api + "get_external_database_status",
|
||||||
[this](HTTP_Param) -> drogon::Task<> {
|
[this](HTTP_Param) -> drogon::Task<> {
|
||||||
auto status_list =
|
auto status_list =
|
||||||
co_await Ecap_Coro::to_drogon(external_database_status_coro());
|
co_await Ecap_Coro::to_drogon(external_database_status_coro());
|
||||||
|
|
||||||
res->setBody(warp(external_resource_status_list_to_json(status_list))
|
res->setBody(warp(external_resource_status_list_to_json(status_list))
|
||||||
.to_json_string());
|
.to_json_string());
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
svr.PostCoro(
|
svr.Post_Coro(
|
||||||
api + "refresh_external_database",
|
api + "refresh_external_database",
|
||||||
[this, g](HTTP_Param) -> drogon::Task<> {
|
[this, g](HTTP_Param) -> drogon::Task<> {
|
||||||
CHECK_JSON_PARAM
|
CHECK_JSON_PARAM
|
||||||
@@ -563,7 +510,7 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
warp(external_resource_status_to_json(result)).to_json_string());
|
warp(external_resource_status_to_json(result)).to_json_string());
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
svr.PostCoro(api + "refresh_external_databases",
|
svr.Post_Coro(api + "refresh_external_databases",
|
||||||
[this, g](HTTP_Param) -> drogon::Task<> {
|
[this, g](HTTP_Param) -> drogon::Task<> {
|
||||||
const auto result = co_await Ecap_Coro::to_drogon(
|
const auto result = co_await Ecap_Coro::to_drogon(
|
||||||
refresh_external_databases_coro(true));
|
refresh_external_databases_coro(true));
|
||||||
@@ -573,7 +520,7 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
.to_json_string());
|
.to_json_string());
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
svr.PostCoro(
|
svr.Post_Coro(
|
||||||
api + "import_external_database",
|
api + "import_external_database",
|
||||||
[this, g](HTTP_Param) -> drogon::Task<> {
|
[this, g](HTTP_Param) -> drogon::Task<> {
|
||||||
CHECK_JSON_PARAM
|
CHECK_JSON_PARAM
|
||||||
@@ -586,7 +533,7 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
warp(external_resource_status_to_json(result)).to_json_string());
|
warp(external_resource_status_to_json(result)).to_json_string());
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
svr.PostCoro(
|
svr.Post_Coro(
|
||||||
api + "upload_external_database",
|
api + "upload_external_database",
|
||||||
[this, g](HTTP_Param) -> drogon::Task<> {
|
[this, g](HTTP_Param) -> drogon::Task<> {
|
||||||
drogon::MultiPartParser parser;
|
drogon::MultiPartParser parser;
|
||||||
@@ -597,7 +544,6 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
if (!name || parser.getFiles().size() != 1) {
|
if (!name || parser.getFiles().size() != 1) {
|
||||||
throw_invalid_http_param("name or file");
|
throw_invalid_http_param("name or file");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& upload = parser.getFiles().front();
|
const auto& upload = parser.getFiles().front();
|
||||||
const auto serial =
|
const auto serial =
|
||||||
std::chrono::steady_clock::now().time_since_epoch().count();
|
std::chrono::steady_clock::now().time_since_epoch().count();
|
||||||
@@ -611,7 +557,6 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Cannot save uploaded external database file");
|
"Cannot save uploaded external database file");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto source_file =
|
const auto source_file =
|
||||||
std::filesystem::path(drogon::app().getUploadPath()) / saved_name;
|
std::filesystem::path(drogon::app().getUploadPath()) / saved_name;
|
||||||
const auto result = co_await Ecap_Coro::to_drogon(
|
const auto result = co_await Ecap_Coro::to_drogon(
|
||||||
@@ -621,7 +566,7 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
warp(external_resource_status_to_json(result)).to_json_string());
|
warp(external_resource_status_to_json(result)).to_json_string());
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
svr.PostCoro(
|
svr.Post_Coro(
|
||||||
api + "clear_external_database_table",
|
api + "clear_external_database_table",
|
||||||
[this, g](HTTP_Param) -> drogon::Task<> {
|
[this, g](HTTP_Param) -> drogon::Task<> {
|
||||||
CHECK_JSON_PARAM
|
CHECK_JSON_PARAM
|
||||||
@@ -633,7 +578,7 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
warp(external_resource_status_to_json(result)).to_json_string());
|
warp(external_resource_status_to_json(result)).to_json_string());
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
svr.PostCoro(
|
svr.Post_Coro(
|
||||||
api + "query_external_database", [this](HTTP_Param) -> drogon::Task<> {
|
api + "query_external_database", [this](HTTP_Param) -> drogon::Task<> {
|
||||||
CHECK_JSON_PARAM
|
CHECK_JSON_PARAM
|
||||||
HTTP_REQUIRE_VALUE(name, params.try_get_string("name"))
|
HTTP_REQUIRE_VALUE(name, params.try_get_string("name"))
|
||||||
@@ -654,14 +599,12 @@ void External_Resources_Manager::server(Global *g) {
|
|||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::register_external_resource(
|
void External_Resources_Manager::register_external_resource(
|
||||||
std::unique_ptr<External_Resources> external_res) {
|
std::unique_ptr<External_Resources> external_res) {
|
||||||
if (!external_res)
|
if (!external_res)
|
||||||
throw std::invalid_argument("external resource is null");
|
throw std::invalid_argument("external resource is null");
|
||||||
resources_.push_back(std::move(external_res));
|
resources_.push_back(std::move(external_res));
|
||||||
}
|
}
|
||||||
|
|
||||||
void External_Resources_Manager::initialize(SQLite::Database& db,
|
void External_Resources_Manager::initialize(SQLite::Database& db,
|
||||||
std::filesystem::path cache_pos) {
|
std::filesystem::path cache_pos) {
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
@@ -669,18 +612,15 @@ void External_Resources_Manager::initialize(SQLite::Database &db,
|
|||||||
for (const auto& resource : resources_)
|
for (const auto& resource : resources_)
|
||||||
resource->create_table(db);
|
resource->create_table(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<External_Resource_Status>
|
std::vector<External_Resource_Status>
|
||||||
External_Resources_Manager::sync_missing(SQLite::Database& db) {
|
External_Resources_Manager::sync_missing(SQLite::Database& db) {
|
||||||
return update_all(db, false, true);
|
return update_all(db, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<External_Resource_Status>
|
std::vector<External_Resource_Status>
|
||||||
External_Resources_Manager::refresh_all(SQLite::Database& db,
|
External_Resources_Manager::refresh_all(SQLite::Database& db,
|
||||||
const bool force_download) {
|
const bool force_download) {
|
||||||
return update_all(db, force_download, false);
|
return update_all(db, force_download, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status
|
External_Resource_Status
|
||||||
External_Resources_Manager::refresh_one(SQLite::Database& db,
|
External_Resources_Manager::refresh_one(SQLite::Database& db,
|
||||||
std::string_view resource_name,
|
std::string_view resource_name,
|
||||||
@@ -689,28 +629,24 @@ External_Resources_Manager::refresh_one(SQLite::Database &db,
|
|||||||
return get_resource(resource_name)
|
return get_resource(resource_name)
|
||||||
.update(db, cache_pos_, force_download, false);
|
.update(db, cache_pos_, force_download, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status External_Resources_Manager::import_offline(
|
External_Resource_Status External_Resources_Manager::import_offline(
|
||||||
SQLite::Database& db, std::string_view resource_name,
|
SQLite::Database& db, std::string_view resource_name,
|
||||||
const std::filesystem::path& source_file) {
|
const std::filesystem::path& source_file) {
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
return get_resource(resource_name).import_offline(db, source_file);
|
return get_resource(resource_name).import_offline(db, source_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resource_Status
|
External_Resource_Status
|
||||||
External_Resources_Manager::clear_table(SQLite::Database& db,
|
External_Resources_Manager::clear_table(SQLite::Database& db,
|
||||||
std::string_view resource_name) {
|
std::string_view resource_name) {
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
return get_resource(resource_name).clear_table(db, cache_pos_);
|
return get_resource(resource_name).clear_table(db, cache_pos_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<External_Database_Row> External_Resources_Manager::query_one(
|
std::optional<External_Database_Row> External_Resources_Manager::query_one(
|
||||||
SQLite::Database& db, std::string_view resource_name,
|
SQLite::Database& db, std::string_view resource_name,
|
||||||
const std::vector<std::string>& primary_key_values) const {
|
const std::vector<std::string>& primary_key_values) const {
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
return get_resource(resource_name).query_one(db, primary_key_values);
|
return get_resource(resource_name).query_one(db, primary_key_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
||||||
External_Resources_Manager::query_aircraft(SQLite::Database& db,
|
External_Resources_Manager::query_aircraft(SQLite::Database& db,
|
||||||
std::string_view icao24) const {
|
std::string_view icao24) const {
|
||||||
@@ -736,7 +672,6 @@ External_Resources_Manager::query_aircraft(SQLite::Database &db,
|
|||||||
shared_row);
|
shared_row);
|
||||||
return shared_row;
|
return shared_row;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<std::string> type_code;
|
std::optional<std::string> type_code;
|
||||||
for (const auto& resource_name : kAircraftResourceKeys) {
|
for (const auto& resource_name : kAircraftResourceKeys) {
|
||||||
const auto row = add_row(resource_name, std::vector<std::string>{std::string(icao24)});
|
const auto row = add_row(resource_name, std::vector<std::string>{std::string(icao24)});
|
||||||
@@ -746,12 +681,10 @@ External_Resources_Manager::query_aircraft(SQLite::Database &db,
|
|||||||
type_code = row->get("typecode");
|
type_code = row->get("typecode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_code)
|
if (type_code)
|
||||||
add_row("icao_doc_8643_aircraft_type_designators", {*type_code});
|
add_row("icao_doc_8643_aircraft_type_designators", {*type_code});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
std::map<std::string, std::shared_ptr<External_Database_Row>>
|
||||||
External_Resources_Manager::query_callsign(
|
External_Resources_Manager::query_callsign(
|
||||||
SQLite::Database& db, const std::optional<std::string>& callsign) const {
|
SQLite::Database& db, const std::optional<std::string>& callsign) const {
|
||||||
@@ -763,7 +696,6 @@ External_Resources_Manager::query_callsign(
|
|||||||
"adsblol_vrs_standing_data_routes",
|
"adsblol_vrs_standing_data_routes",
|
||||||
"vradarserver_standing_data_routes",
|
"vradarserver_standing_data_routes",
|
||||||
};
|
};
|
||||||
|
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
std::map<std::string, std::shared_ptr<External_Database_Row>> result;
|
std::map<std::string, std::shared_ptr<External_Database_Row>> result;
|
||||||
const auto add_row = [&](std::string_view resource_name,
|
const auto add_row = [&](std::string_view resource_name,
|
||||||
@@ -778,7 +710,6 @@ External_Resources_Manager::query_callsign(
|
|||||||
shared_row);
|
shared_row);
|
||||||
return shared_row;
|
return shared_row;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::set<std::string> airport_codes;
|
std::set<std::string> airport_codes;
|
||||||
if (callsign && !callsign->empty()) {
|
if (callsign && !callsign->empty()) {
|
||||||
for (const auto& resource_name : kRouteResourceKeys) {
|
for (const auto& resource_name : kRouteResourceKeys) {
|
||||||
@@ -788,7 +719,6 @@ External_Resources_Manager::query_callsign(
|
|||||||
const auto airports = row->get("AirportCodes");
|
const auto airports = row->get("AirportCodes");
|
||||||
if (!airports)
|
if (!airports)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::size_t start = 0;
|
std::size_t start = 0;
|
||||||
while (start < airports->size()) {
|
while (start < airports->size()) {
|
||||||
const auto end = airports->find('-', start);
|
const auto end = airports->find('-', start);
|
||||||
@@ -799,7 +729,6 @@ External_Resources_Manager::query_callsign(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& airport_code : airport_codes) {
|
for (const auto& airport_code : airport_codes) {
|
||||||
if (airport_code.empty())
|
if (airport_code.empty())
|
||||||
continue;
|
continue;
|
||||||
@@ -807,7 +736,6 @@ External_Resources_Manager::query_callsign(
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<External_Resource_Status>
|
std::vector<External_Resource_Status>
|
||||||
External_Resources_Manager::status(SQLite::Database& db) const {
|
External_Resources_Manager::status(SQLite::Database& db) const {
|
||||||
std::lock_guard lock(mtx_);
|
std::lock_guard lock(mtx_);
|
||||||
@@ -818,14 +746,12 @@ External_Resources_Manager::status(SQLite::Database &db) const {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLite::Database& External_Resources_Manager::require_db() const {
|
SQLite::Database& External_Resources_Manager::require_db() const {
|
||||||
if (!db_) {
|
if (!db_) {
|
||||||
throw std::runtime_error("DB not loaded. Call load_sqlite_db() first.");
|
throw std::runtime_error("DB not loaded. Call load_sqlite_db() first.");
|
||||||
}
|
}
|
||||||
return *db_;
|
return *db_;
|
||||||
}
|
}
|
||||||
|
|
||||||
External_Resources& External_Resources_Manager::get_resource(
|
External_Resources& External_Resources_Manager::get_resource(
|
||||||
std::string_view resource_name) const {
|
std::string_view resource_name) const {
|
||||||
for (const auto& resource : resources_) {
|
for (const auto& resource : resources_) {
|
||||||
@@ -834,7 +760,6 @@ External_Resources &External_Resources_Manager::get_resource(
|
|||||||
}
|
}
|
||||||
throw std::invalid_argument("unknown external resource: " + std::string(resource_name));
|
throw std::invalid_argument("unknown external resource: " + std::string(resource_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<External_Resource_Status>
|
std::vector<External_Resource_Status>
|
||||||
External_Resources_Manager::update_all(SQLite::Database& db,
|
External_Resources_Manager::update_all(SQLite::Database& db,
|
||||||
const bool force_download,
|
const bool force_download,
|
||||||
@@ -849,7 +774,8 @@ External_Resources_Manager::update_all(SQLite::Database &db,
|
|||||||
std::cout << "External database [" << status.name << "] "
|
std::cout << "External database [" << status.name << "] "
|
||||||
<< status.message << ", rows=" << status.row_count << std::endl;
|
<< status.message << ", rows=" << status.row_count << std::endl;
|
||||||
result.push_back(std::move(status));
|
result.push_back(std::move(status));
|
||||||
} catch (const std::exception &error) {
|
}
|
||||||
|
catch (const std::exception& error) {
|
||||||
std::cerr << "External database [" << resource->name
|
std::cerr << "External database [" << resource->name
|
||||||
<< "] update failed: [" << error.what() << "]" << " status.message:" << status.message << std::endl;
|
<< "] update failed: [" << error.what() << "]" << " status.message:" << status.message << std::endl;
|
||||||
result.push_back({
|
result.push_back({
|
||||||
|
|||||||
@@ -5,10 +5,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
BaseLogger* server_logger = nullptr;
|
BaseLogger* server_logger = nullptr;
|
||||||
Debug_Logger_Info_Manager debug_logger_info_manager;
|
Debug_Logger_Info_Manager debug_logger_info_manager;
|
||||||
|
|
||||||
void Global::handle_old_logs() {
|
void Global::handle_old_logs() {
|
||||||
auto mode = log_config.open_mode;
|
auto mode = log_config.open_mode;
|
||||||
std::string dirPath = get_exe_dir() + "/" + "logs";
|
std::string dirPath = get_exe_dir() + "/" + "logs";
|
||||||
@@ -37,7 +35,8 @@ void Global::handle_old_logs() {
|
|||||||
}
|
}
|
||||||
if (fs::create_directories(dirPath)) {
|
if (fs::create_directories(dirPath)) {
|
||||||
std::cout << "Directory created: " << dirPath << std::endl;
|
std::cout << "Directory created: " << dirPath << std::endl;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
std::cout << "创建目录失败: " << dirPath << std::endl;
|
std::cout << "创建目录失败: " << dirPath << std::endl;
|
||||||
Psc::fail_fast();
|
Psc::fail_fast();
|
||||||
}
|
}
|
||||||
@@ -51,13 +50,12 @@ void Global::handle_old_logs() {
|
|||||||
std::cerr << "未知的打开模式!" << std::endl;
|
std::cerr << "未知的打开模式!" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (const std::exception &ex) {
|
}
|
||||||
|
catch (const std::exception& ex) {
|
||||||
std::cerr << "Error: " + Psc::platform_2_utf8(ex.what()) + "\n";
|
std::cerr << "Error: " + Psc::platform_2_utf8(ex.what()) + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Global::Global() {
|
Global::Global() {
|
||||||
|
|
||||||
auto j = load();
|
auto j = load();
|
||||||
log_config.from_base_json(j.get("log"));
|
log_config.from_base_json(j.get("log"));
|
||||||
handle_old_logs();
|
handle_old_logs();
|
||||||
@@ -90,7 +88,6 @@ Global::Global() {
|
|||||||
debug_logger_info_manager.push_info(msg);
|
debug_logger_info_manager.push_info(msg);
|
||||||
});
|
});
|
||||||
fromJson(&j);
|
fromJson(&j);
|
||||||
|
|
||||||
#ifdef Cache_Some_Mode_S
|
#ifdef Cache_Some_Mode_S
|
||||||
auto old_parse_ok_json = SSR::parse_ok_json;
|
auto old_parse_ok_json = SSR::parse_ok_json;
|
||||||
SSR::parse_ok_json = [old_parse_ok_json](Aircraft_Info* aircraft_info,
|
SSR::parse_ok_json = [old_parse_ok_json](Aircraft_Info* aircraft_info,
|
||||||
@@ -101,7 +98,6 @@ Global::Global() {
|
|||||||
f->add_msg_limit(mode_s_msg);
|
f->add_msg_limit(mode_s_msg);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSR::cpr_cb = [](SSR::CPR_Error_Type t, std::string_view log,
|
SSR::cpr_cb = [](SSR::CPR_Error_Type t, std::string_view log,
|
||||||
SSR::P_S msg) {
|
SSR::P_S msg) {
|
||||||
auto src = std::dynamic_pointer_cast<Data_Source>(msg->source);
|
auto src = std::dynamic_pointer_cast<Data_Source>(msg->source);
|
||||||
@@ -127,16 +123,17 @@ Global::Global() {
|
|||||||
if (type == SSR::Parse_Call_Back_Type::Normal_Block) {
|
if (type == SSR::Parse_Call_Back_Type::Normal_Block) {
|
||||||
dfs->add_sub_part(field_name);
|
dfs->add_sub_part(field_name);
|
||||||
info->update(msg);
|
info->update(msg);
|
||||||
} else if (type == SSR::Parse_Call_Back_Type::CRC_Error) {
|
}
|
||||||
|
else if (type == SSR::Parse_Call_Back_Type::CRC_Error) {
|
||||||
dfs->add_crc_error();
|
dfs->add_crc_error();
|
||||||
// std::cout << field_name << " :crc_error msg:" << msg->msg_hex <<
|
// std::cout << field_name << " :crc_error msg:" << msg->msg_hex <<
|
||||||
// " df:" << (int)msg->df << std::endl;
|
// " df:" << (int)msg->df << std::endl;
|
||||||
} else if (type == SSR::Parse_Call_Back_Type::Length_Error) {
|
}
|
||||||
|
else if (type == SSR::Parse_Call_Back_Type::Length_Error) {
|
||||||
ss->add_length_error(field_name);
|
ss->add_length_error(field_name);
|
||||||
// std::cout << field_name << " :length_error msg:" << msg->msg_hex
|
// std::cout << field_name << " :length_error msg:" << msg->msg_hex
|
||||||
// << " df:" << (int)msg->df << std::endl;
|
// << " df:" << (int)msg->df << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// else if (type == Mode_S::Parse_Call_Back_Type::UNKNOWN_ERROR) {} else
|
// else if (type == Mode_S::Parse_Call_Back_Type::UNKNOWN_ERROR) {} else
|
||||||
// {}
|
// {}
|
||||||
};
|
};
|
||||||
@@ -150,8 +147,9 @@ Global::Global() {
|
|||||||
// mode_s_log_info = mode_s_log;
|
// mode_s_log_info = mode_s_log;
|
||||||
init_web_server();
|
init_web_server();
|
||||||
}
|
}
|
||||||
Global::~Global() { std::cout << "Global::~Global()" << std::endl; }
|
Global::~Global() {
|
||||||
|
std::cout << "Global::~Global()" << std::endl;
|
||||||
|
}
|
||||||
void replace(std::string& originalStr, std::string_view findStr,
|
void replace(std::string& originalStr, std::string_view findStr,
|
||||||
std::string_view replaceStr) {
|
std::string_view replaceStr) {
|
||||||
size_t pos = originalStr.find(findStr);
|
size_t pos = originalStr.find(findStr);
|
||||||
@@ -232,7 +230,6 @@ void handle_buffer_head_tail(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_ais_serial_data(std::atomic<bool>& running) {
|
void read_ais_serial_data(std::atomic<bool>& running) {
|
||||||
// static int t = config.ais.read_serial_milliseconds;
|
// static int t = config.ais.read_serial_milliseconds;
|
||||||
// static bool ais_log = config.console_config.ais_serial;
|
// static bool ais_log = config.console_config.ais_serial;
|
||||||
@@ -273,7 +270,6 @@ bool is_10004(SSR::Mode_S_Msg &msg) {
|
|||||||
msg.df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18;
|
msg.df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18;
|
||||||
return DF_11_17_18;
|
return DF_11_17_18;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_file_name(std::string_view str) {
|
std::string to_file_name(std::string_view str) {
|
||||||
auto ret = std::string(str);
|
auto ret = std::string(str);
|
||||||
// 定义允许的合法字符
|
// 定义允许的合法字符
|
||||||
@@ -283,7 +279,9 @@ std::string to_file_name(std::string_view str) {
|
|||||||
};
|
};
|
||||||
// 替换非法字符为下划线 '_'
|
// 替换非法字符为下划线 '_'
|
||||||
std::transform(ret.begin(), ret.end(), ret.begin(),
|
std::transform(ret.begin(), ret.end(), ret.begin(),
|
||||||
[&](char c) { return is_valid_char(c) ? c : '_'; });
|
[&](char c) {
|
||||||
|
return is_valid_char(c) ? c : '_';
|
||||||
|
});
|
||||||
// 检查结果字符串是否全是替换字符,防止生成全是下划线的文件名
|
// 检查结果字符串是否全是替换字符,防止生成全是下划线的文件名
|
||||||
if (ret.find_first_not_of('_') == std::string::npos) {
|
if (ret.find_first_not_of('_') == std::string::npos) {
|
||||||
return "default_file_name"; // 返回一个默认文件名
|
return "default_file_name"; // 返回一个默认文件名
|
||||||
@@ -339,7 +337,94 @@ bool Web_Server::listen(std::string_view host, int port) {
|
|||||||
app->run();
|
app->run();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Web_Server& Web_Server::Post(std::string_view pattern, Handler handler) {
|
||||||
|
drogon::app().registerHandler(
|
||||||
|
std::string(pattern),
|
||||||
|
[handler](const drogon::HttpRequestPtr& request,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
||||||
|
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||||
|
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||||
|
handler(request, resp);
|
||||||
|
callback(resp);
|
||||||
|
},
|
||||||
|
{drogon::Post}
|
||||||
|
);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Web_Server& Web_Server::Post_Coro(std::string_view pattern, CoroHandler handler) {
|
||||||
|
drogon::app().registerHandler(std::string(pattern), [handler = std::move(handler)](
|
||||||
|
const drogon::HttpRequestPtr& request,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
||||||
|
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||||
|
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||||
|
drogon::async_run(
|
||||||
|
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
|
||||||
|
try {
|
||||||
|
co_await handler(request, resp);
|
||||||
|
}
|
||||||
|
catch (const std::exception& error) {
|
||||||
|
resp->setStatusCode(drogon::k500InternalServerError);
|
||||||
|
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
resp->setStatusCode(drogon::k500InternalServerError);
|
||||||
|
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
callback(resp);
|
||||||
|
co_return;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{drogon::Post}
|
||||||
|
);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Web_Server& Web_Server::Get(std::string_view pattern, Handler handler) {
|
||||||
|
drogon::app().registerHandlerViaRegex(
|
||||||
|
std::string(pattern),
|
||||||
|
[handler](const drogon::HttpRequestPtr& request,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
||||||
|
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||||
|
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||||
|
handler(request, resp);
|
||||||
|
callback(resp);
|
||||||
|
},
|
||||||
|
{drogon::Get}
|
||||||
|
);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Web_Server& Web_Server::Get_Coro(std::string_view pattern, CoroHandler handler) {
|
||||||
|
drogon::app().registerHandlerViaRegex(
|
||||||
|
std::string(pattern),
|
||||||
|
[handler = std::move(handler)](
|
||||||
|
const drogon::HttpRequestPtr& request,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
||||||
|
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||||
|
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||||
|
drogon::async_run(
|
||||||
|
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
|
||||||
|
try {
|
||||||
|
co_await handler(request, resp);
|
||||||
|
}
|
||||||
|
catch (const std::exception& error) {
|
||||||
|
resp->setStatusCode(drogon::k500InternalServerError);
|
||||||
|
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
resp->setStatusCode(drogon::k500InternalServerError);
|
||||||
|
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
callback(resp);
|
||||||
|
co_return;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{drogon::Get}
|
||||||
|
);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
std::string
|
std::string
|
||||||
Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) {
|
Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) {
|
||||||
std::lock_guard g(mtx);
|
std::lock_guard g(mtx);
|
||||||
@@ -354,23 +439,23 @@ Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) {
|
|||||||
// << it->sequence << " content.size" << it->content.size() << std::endl;
|
// << it->sequence << " content.size" << it->content.size() << std::endl;
|
||||||
if (it->sequence >= serial_number) {
|
if (it->sequence >= serial_number) {
|
||||||
result = it->content + result; // 叠加 content
|
result = it->content + result; // 叠加 content
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string inet_address_to_string(const trantor::InetAddress& addr) {
|
std::string inet_address_to_string(const trantor::InetAddress& addr) {
|
||||||
char buf[INET6_ADDRSTRLEN] = {0};
|
char buf[INET6_ADDRSTRLEN] = {0};
|
||||||
|
|
||||||
if (!addr.isIpV6()) {
|
if (!addr.isIpV6()) {
|
||||||
// IPv4
|
// IPv4
|
||||||
auto sa = reinterpret_cast<const struct sockaddr_in*>(addr.getSockAddr());
|
auto sa = reinterpret_cast<const struct sockaddr_in*>(addr.getSockAddr());
|
||||||
inet_ntop(AF_INET, &(sa->sin_addr), buf, sizeof(buf));
|
inet_ntop(AF_INET, &(sa->sin_addr), buf, sizeof(buf));
|
||||||
uint16_t port = ntohs(sa->sin_port);
|
uint16_t port = ntohs(sa->sin_port);
|
||||||
return std::string(buf) + ":" + std::to_string(port);
|
return std::string(buf) + ":" + std::to_string(port);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// IPv6
|
// IPv6
|
||||||
auto sa6 =
|
auto sa6 =
|
||||||
reinterpret_cast<const struct sockaddr_in6*>(addr.getSockAddr());
|
reinterpret_cast<const struct sockaddr_in6*>(addr.getSockAddr());
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Core/Base/ThreadManager.h"
|
#include "Core/Base/ThreadManager.h"
|
||||||
#include "../Data_Source/export.h"
|
#include "../Data_Source/export.h"
|
||||||
#include "../State_Report/State_Report.h"
|
#include "../State_Report/State_Report.h"
|
||||||
@@ -10,9 +7,7 @@
|
|||||||
#include "Ucoro_Drogon_Glue.h"
|
#include "Ucoro_Drogon_Glue.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include <drogon/drogon.h>
|
#include <drogon/drogon.h>
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
#include "../../Radarcape_Core/cpp-httplib/httplib.h"
|
#include "../../Radarcape_Core/cpp-httplib/httplib.h"
|
||||||
#include "../Data_Source/export.h"
|
#include "../Data_Source/export.h"
|
||||||
#include "Core/Net_Adapter/Net_Adapter.h"
|
#include "Core/Net_Adapter/Net_Adapter.h"
|
||||||
@@ -20,13 +15,11 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
// 集中 管理日志
|
// 集中 管理日志
|
||||||
using namespace Psc;
|
using namespace Psc;
|
||||||
extern BaseLogger* server_logger;
|
extern BaseLogger* server_logger;
|
||||||
std::string to_file_name(std::string_view str);
|
std::string to_file_name(std::string_view str);
|
||||||
std::string inet_address_to_string(const trantor::InetAddress& addr);
|
std::string inet_address_to_string(const trantor::InetAddress& addr);
|
||||||
|
|
||||||
using Serial_Number_Type = unsigned int;
|
using Serial_Number_Type = unsigned int;
|
||||||
struct Debug_Logger_Info_Manager {
|
struct Debug_Logger_Info_Manager {
|
||||||
void push_info(std::string_view content);
|
void push_info(std::string_view content);
|
||||||
@@ -47,9 +40,6 @@ private:
|
|||||||
std::mutex mtx;
|
std::mutex mtx;
|
||||||
};
|
};
|
||||||
extern Debug_Logger_Info_Manager debug_logger_info_manager;
|
extern Debug_Logger_Info_Manager debug_logger_info_manager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define RET_OK \
|
#define RET_OK \
|
||||||
res.status = StatusCode::OK_200; \
|
res.status = StatusCode::OK_200; \
|
||||||
res.set_content("{\"status\": 200}", "application/json");
|
res.set_content("{\"status\": 200}", "application/json");
|
||||||
@@ -60,11 +50,7 @@ extern Debug_Logger_Info_Manager debug_logger_info_manager;
|
|||||||
// return ret;
|
// return ret;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define HTTP_Param const drogon::HttpRequestPtr& req, const drogon::HttpResponsePtr& res
|
#define HTTP_Param const drogon::HttpRequestPtr& req, const drogon::HttpResponsePtr& res
|
||||||
|
|
||||||
class Web_Server {
|
class Web_Server {
|
||||||
public:
|
public:
|
||||||
std::string update = "update_";
|
std::string update = "update_";
|
||||||
@@ -76,125 +62,22 @@ public:
|
|||||||
using Handler = std::function<void(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
|
using Handler = std::function<void(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
|
||||||
using CoroHandler = std::function<drogon::Task<>(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
|
using CoroHandler = std::function<drogon::Task<>(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
|
||||||
bool listen(std::string_view host, int port);
|
bool listen(std::string_view host, int port);
|
||||||
|
|
||||||
~Web_Server() = default;
|
~Web_Server() = default;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void stop() {
|
static void stop() {
|
||||||
std::cout << "开始停止web服务" << std::endl;
|
std::cout << "开始停止web服务" << std::endl;
|
||||||
drogon::app().quit();
|
drogon::app().quit();
|
||||||
}
|
}
|
||||||
|
Web_Server& Post(std::string_view pattern, Handler handler);
|
||||||
Web_Server& Post(std::string_view pattern, Handler handler) {
|
Web_Server& Post_Coro(std::string_view pattern, CoroHandler handler);
|
||||||
drogon::app().registerHandler(
|
Web_Server& Get(std::string_view pattern, Handler handler);
|
||||||
std::string(pattern),
|
Web_Server& Get_Coro(std::string_view pattern, CoroHandler handler);
|
||||||
[handler](const drogon::HttpRequestPtr& request,
|
|
||||||
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
|
||||||
auto resp = drogon::HttpResponse::newHttpResponse();
|
|
||||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
|
||||||
|
|
||||||
handler(request, resp);
|
|
||||||
|
|
||||||
callback(resp);
|
|
||||||
},
|
|
||||||
{drogon::Post}
|
|
||||||
);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Web_Server& PostCoro(std::string_view pattern, CoroHandler handler) {
|
|
||||||
drogon::app().registerHandler(
|
|
||||||
std::string(pattern),
|
|
||||||
[handler = std::move(handler)](
|
|
||||||
const drogon::HttpRequestPtr& request,
|
|
||||||
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
|
||||||
auto resp = drogon::HttpResponse::newHttpResponse();
|
|
||||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
|
||||||
|
|
||||||
drogon::async_run(
|
|
||||||
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
|
|
||||||
try {
|
|
||||||
co_await handler(request, resp);
|
|
||||||
} catch (const std::exception& error) {
|
|
||||||
resp->setStatusCode(drogon::k500InternalServerError);
|
|
||||||
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
|
|
||||||
} catch (...) {
|
|
||||||
resp->setStatusCode(drogon::k500InternalServerError);
|
|
||||||
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
|
|
||||||
}
|
|
||||||
callback(resp);
|
|
||||||
co_return;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{drogon::Post}
|
|
||||||
);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Web_Server& Get(std::string_view pattern, Handler handler) {
|
|
||||||
drogon::app().registerHandlerViaRegex(
|
|
||||||
std::string(pattern),
|
|
||||||
[handler](const drogon::HttpRequestPtr& request,
|
|
||||||
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
|
||||||
auto resp = drogon::HttpResponse::newHttpResponse();
|
|
||||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
|
||||||
|
|
||||||
handler(request, resp);
|
|
||||||
|
|
||||||
callback(resp);
|
|
||||||
},
|
|
||||||
{drogon::Get}
|
|
||||||
);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Web_Server& GetCoro(std::string_view pattern, CoroHandler handler) {
|
|
||||||
drogon::app().registerHandlerViaRegex(
|
|
||||||
std::string(pattern),
|
|
||||||
[handler = std::move(handler)](
|
|
||||||
const drogon::HttpRequestPtr& request,
|
|
||||||
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
|
|
||||||
auto resp = drogon::HttpResponse::newHttpResponse();
|
|
||||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
|
||||||
|
|
||||||
drogon::async_run(
|
|
||||||
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
|
|
||||||
try {
|
|
||||||
co_await handler(request, resp);
|
|
||||||
} catch (const std::exception& error) {
|
|
||||||
resp->setStatusCode(drogon::k500InternalServerError);
|
|
||||||
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
|
|
||||||
} catch (...) {
|
|
||||||
resp->setStatusCode(drogon::k500InternalServerError);
|
|
||||||
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
|
|
||||||
}
|
|
||||||
callback(resp);
|
|
||||||
co_return;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{drogon::Get}
|
|
||||||
);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 这个对象不释放
|
// 这个对象不释放
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Mlat_MSG {
|
class Mlat_MSG {
|
||||||
public:
|
public:
|
||||||
explicit Mlat_MSG(const std::shared_ptr<SSR::Mode_Msg>& first) { list.push_back(first);}
|
explicit Mlat_MSG(const std::shared_ptr<SSR::Mode_Msg>& first) {
|
||||||
|
list.push_back(first);
|
||||||
|
}
|
||||||
[[nodiscard]] std::optional<std::string> icao() const {
|
[[nodiscard]] std::optional<std::string> icao() const {
|
||||||
auto a = list[0];
|
auto a = list[0];
|
||||||
auto t = a->type;
|
auto t = a->type;
|
||||||
@@ -203,21 +86,26 @@ public:
|
|||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
[[nodiscard]] std::string msg_hex() const { return list[0]->msg_hex;}
|
[[nodiscard]] std::string msg_hex() const {
|
||||||
[[nodiscard]] SSR::Mode_Msg::T type() const { return static_cast<SSR::Mode_Msg::T>(list[0]->type);}
|
return list[0]->msg_hex;
|
||||||
[[nodiscard]] SSR::MLAT_timestamp& timestamp() const { return list[0]->mlat_timestamp;}
|
}
|
||||||
[[nodiscard]] std::shared_ptr<SSR::Data_Source_Interface> data_source() const { return list[0]->source;}
|
[[nodiscard]] SSR::Mode_Msg::T type() const {
|
||||||
|
return static_cast<SSR::Mode_Msg::T>(list[0]->type);
|
||||||
|
}
|
||||||
|
[[nodiscard]] SSR::MLAT_timestamp& timestamp() const {
|
||||||
|
return list[0]->mlat_timestamp;
|
||||||
|
}
|
||||||
|
[[nodiscard]] std::shared_ptr<SSR::Data_Source_Interface> data_source() const {
|
||||||
|
return list[0]->source;
|
||||||
|
}
|
||||||
void add(const std::shared_ptr<SSR::Mode_Msg>& t) {
|
void add(const std::shared_ptr<SSR::Mode_Msg>& t) {
|
||||||
list.push_back(t);
|
list.push_back(t);
|
||||||
}
|
}
|
||||||
[[nodiscard]] size_t size() const { return list.size(); }
|
[[nodiscard]] size_t size() const {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
std::vector<std::shared_ptr<SSR::Mode_Msg>> list;
|
std::vector<std::shared_ptr<SSR::Mode_Msg>> list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Mlat_Handler {
|
class Mlat_Handler {
|
||||||
public:
|
public:
|
||||||
std::list<Mlat_MSG> get_all() {
|
std::list<Mlat_MSG> get_all() {
|
||||||
@@ -227,18 +115,14 @@ public:
|
|||||||
std::swap(ok_list, ret);
|
std::swap(ok_list, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(const std::shared_ptr<SSR::Mode_Msg>& msg) {
|
void push(const std::shared_ptr<SSR::Mode_Msg>& msg) {
|
||||||
std::lock_guard<std::mutex> g(mtx);
|
std::lock_guard<std::mutex> g(mtx);
|
||||||
|
|
||||||
if (list.empty()) {
|
if (list.empty()) {
|
||||||
list.emplace_back(msg);
|
list.emplace_back(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto time = msg->mlat_timestamp;
|
auto time = msg->mlat_timestamp;
|
||||||
auto p = list.rbegin();
|
auto p = list.rbegin();
|
||||||
|
|
||||||
while (p != list.rend()) {
|
while (p != list.rend()) {
|
||||||
auto cur_time = p->timestamp();
|
auto cur_time = p->timestamp();
|
||||||
// 往前最多找3秒
|
// 往前最多找3秒
|
||||||
@@ -261,11 +145,6 @@ protected:
|
|||||||
std::mutex ok_mtx;
|
std::mutex ok_mtx;
|
||||||
std::mutex mtx;
|
std::mutex mtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Global : public Config, public Singleton<Global> {
|
class Global : public Config, public Singleton<Global> {
|
||||||
public:
|
public:
|
||||||
// asio::io_context ctx;
|
// asio::io_context ctx;
|
||||||
@@ -277,8 +156,7 @@ public:
|
|||||||
return mode_acs.data_source_config.map.get(std::string(data_source_key)).value_or(nullptr);
|
return mode_acs.data_source_config.map.get(std::string(data_source_key)).value_or(nullptr);
|
||||||
}
|
}
|
||||||
std::shared_ptr<Data_Source> total_source() {
|
std::shared_ptr<Data_Source> total_source() {
|
||||||
for (auto i : mode_acs.data_source_config.map.list())
|
for (auto i : mode_acs.data_source_config.map.list()) {
|
||||||
{
|
|
||||||
if (i->enable) return i;
|
if (i->enable) return i;
|
||||||
}
|
}
|
||||||
return mode_acs.data_source_config.map.list().at(0);
|
return mode_acs.data_source_config.map.list().at(0);
|
||||||
@@ -291,9 +169,6 @@ public:
|
|||||||
std::time_t start_server_time;
|
std::time_t start_server_time;
|
||||||
DELETE_COPY(Global)
|
DELETE_COPY(Global)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void handle_buffer_muti_start(std::string& buffer, std::string_view data, const std::set<std::string>& prefix_list,
|
void handle_buffer_muti_start(std::string& buffer, std::string_view data, const std::set<std::string>& prefix_list,
|
||||||
const std::function<void(std::string&)>& callback);
|
const std::function<void(std::string&)>& callback);
|
||||||
void handle_buffer_head_tail(std::string& buffer, std::string_view data, std::string_view prefix,
|
void handle_buffer_head_tail(std::string& buffer, std::string_view data, std::string_view prefix,
|
||||||
|
|||||||
Vendored
+1
-5
@@ -10,11 +10,7 @@ fetch_repo() {
|
|||||||
local branch="$2"
|
local branch="$2"
|
||||||
local dir="$3"
|
local dir="$3"
|
||||||
if [ -d "$dir" ]; then
|
if [ -d "$dir" ]; then
|
||||||
git -C "$dir" rev-parse --is-inside-work-tree >/dev/null
|
echo "文件夹【$dir】已存在 跳过初始化 "
|
||||||
git -C "$dir" remote set-url origin "$repo"
|
|
||||||
git -C "$dir" fetch origin "$branch"
|
|
||||||
git -C "$dir" checkout "$branch"
|
|
||||||
git -C "$dir" pull --ff-only origin "$branch"
|
|
||||||
else
|
else
|
||||||
git clone --branch "$branch" --single-branch "$repo" "$dir"
|
git clone --branch "$branch" --single-branch "$repo" "$dir"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Vendored
-44
@@ -1,44 +0,0 @@
|
|||||||
$ErrorActionPreference = "Stop"
|
|
||||||
$scriptDir = $PSScriptRoot
|
|
||||||
if ( [string]::IsNullOrWhiteSpace($scriptDir))
|
|
||||||
{
|
|
||||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
||||||
}
|
|
||||||
$root = (Resolve-Path -LiteralPath (Join-Path $scriptDir "..")).Path
|
|
||||||
Set-Location -LiteralPath $root
|
|
||||||
$origin = git remote get-url origin
|
|
||||||
$origin = $origin.TrimEnd("/")
|
|
||||||
$remoteRoot = $origin -replace "/[^/]+(\.git)?$", ""
|
|
||||||
function Fetch-Repo
|
|
||||||
{
|
|
||||||
param(
|
|
||||||
[string]$Repo,
|
|
||||||
[string]$Branch,
|
|
||||||
[string]$Dir
|
|
||||||
)
|
|
||||||
if (Test-Path -LiteralPath $Dir -PathType Container)
|
|
||||||
{
|
|
||||||
git -C $Dir rev-parse --is-inside-work-tree *> $null
|
|
||||||
git -C $Dir remote set-url origin $Repo
|
|
||||||
git -C $Dir fetch origin $Branch
|
|
||||||
git -C $Dir checkout $Branch
|
|
||||||
git -C $Dir pull --ff-only origin $Branch
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
git clone --branch $Branch --single-branch $Repo $Dir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function Fetch-RepoEx
|
|
||||||
{
|
|
||||||
param(
|
|
||||||
[string]$Name
|
|
||||||
)
|
|
||||||
$repo = "$remoteRoot/$Name"
|
|
||||||
$branch = "master"
|
|
||||||
Fetch-Repo -Repo $repo -Branch $branch -Dir "third_party/$Name"
|
|
||||||
}
|
|
||||||
Fetch-RepoEx "build_infra"
|
|
||||||
Fetch-RepoEx "CPP_Core"
|
|
||||||
Fetch-RepoEx "SSR"
|
|
||||||
Fetch-RepoEx "eacp_webapp"
|
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
node_dir="/c/Users/wyc/AppData/Roaming/JetBrains/WebStorm2026.1/node/versions/24.18.0"
|
||||||
|
export PATH="$node_dir:$PATH"
|
||||||
|
cd "$root/third_party/eacp_webapp"
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
npm run dev -- --host 0.0.0.0
|
||||||
Reference in New Issue
Block a user