Add option to choose between restc-cpp and nap
I don't think this is very clean, but they might fix the bug in restc-cpp that is currently holding this project back, and I might want to go back to it. I might refactor this into a virtual class.
This commit is contained in:
parent
8b09d7da53
commit
80bfbc640a
9 changed files with 182 additions and 42 deletions
|
@ -2,3 +2,4 @@ option('base_url', type: 'string', value: 'https://api.originsro.org')
|
||||||
option('def_sqlite_db_name', type: 'string', value: 'originsro.db3')
|
option('def_sqlite_db_name', type: 'string', value: 'originsro.db3')
|
||||||
option('tests', type: 'feature', value: 'enabled')
|
option('tests', type: 'feature', value: 'enabled')
|
||||||
option('with_sqlite', type: 'feature', value: 'auto')
|
option('with_sqlite', type: 'feature', value: 'auto')
|
||||||
|
option('rest_lib', type: 'combo', choices: ['nap', 'restc-cpp'], value: 'nap')
|
||||||
|
|
|
@ -31,6 +31,9 @@ constexpr const unsigned short int g_version_patch = @PROJECT_VERSION_PATCH@;
|
||||||
|
|
||||||
#mesondefine OROTOOL_WITH_SQLITE
|
#mesondefine OROTOOL_WITH_SQLITE
|
||||||
|
|
||||||
|
#mesondefine OROTOOL_WITH_NAP
|
||||||
|
#mesondefine OROTOOL_WITH_RESTCCPP
|
||||||
|
|
||||||
#if defined(OROTOOL_WITH_SQLITE)
|
#if defined(OROTOOL_WITH_SQLITE)
|
||||||
constexpr const char g_sqlite_backend_name[] = "sqlite";
|
constexpr const char g_sqlite_backend_name[] = "sqlite";
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
#include "duckhandy/int_conv.hpp"
|
#include "duckhandy/int_conv.hpp"
|
||||||
#include "duckhandy/string_bt.hpp"
|
#include "duckhandy/string_bt.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <restc-cpp/error.h>
|
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||||
|
# include <restc-cpp/error.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void print_ping(oro::Api& oro_api) {
|
void print_ping(oro::Api& oro_api) {
|
||||||
|
@ -83,11 +85,13 @@ int main(int argc, char* argv[]) {
|
||||||
app_conf.worker_threads()
|
app_conf.worker_threads()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||||
catch (const restc_cpp::CommunicationException& err) {
|
catch (const restc_cpp::CommunicationException& err) {
|
||||||
std::cerr << "Communication with server \"" << duck::g_base_url <<
|
std::cerr << "Communication with server \"" << duck::g_base_url <<
|
||||||
"\" failed: " << err.what() << '\n';
|
"\" failed: " << err.what() << '\n';
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
catch (const std::exception& err) {
|
catch (const std::exception& err) {
|
||||||
std::cerr << "An error occurred during the program execution: " <<
|
std::cerr << "An error occurred during the program execution: " <<
|
||||||
err.what() << '\n';
|
err.what() << '\n';
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
restc_cpp_dep = dependency('restc-cpp', version: '>=0.1.1',
|
if get_option('rest_lib') == 'restc-cpp'
|
||||||
|
restc_cpp_dep = dependency('restc-cpp', version: '>=0.1.1',
|
||||||
fallback: ['restc-cpp', 'restc_cpp_dep'],
|
fallback: ['restc-cpp', 'restc_cpp_dep'],
|
||||||
default_options: [
|
default_options: [
|
||||||
'restc_cpp_with_unit_tests=false',
|
'restc_cpp_with_unit_tests=false',
|
||||||
'restc_cpp_log_with_boost_log=false',
|
'restc_cpp_log_with_boost_log=false',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
curlcpp_dep = dependency('curlcpp', version: '>=1.4',
|
curlcpp_dep = dependency('curlcpp', version: '>=1.4',
|
||||||
fallback: ['curlcpp', 'curlcpp_dep'],
|
fallback: ['curlcpp', 'curlcpp_dep'],
|
||||||
|
@ -50,6 +52,8 @@ conf.set('PROJECT_VERSION_MAJOR', version_arr[0])
|
||||||
conf.set('PROJECT_VERSION_MINOR', version_arr[1])
|
conf.set('PROJECT_VERSION_MINOR', version_arr[1])
|
||||||
conf.set('PROJECT_VERSION_PATCH', version_arr[2])
|
conf.set('PROJECT_VERSION_PATCH', version_arr[2])
|
||||||
conf.set('OROTOOL_WITH_SQLITE', sqlitecpp_dep.found())
|
conf.set('OROTOOL_WITH_SQLITE', sqlitecpp_dep.found())
|
||||||
|
conf.set('OROTOOL_WITH_NAP', get_option('rest_lib') == 'nap')
|
||||||
|
conf.set('OROTOOL_WITH_RESTCCPP', get_option('rest_lib') == 'restc-cpp')
|
||||||
project_config_file = configure_file(
|
project_config_file = configure_file(
|
||||||
input: 'config.hpp.in',
|
input: 'config.hpp.in',
|
||||||
output: meson.project_name() + '_config.hpp',
|
output: meson.project_name() + '_config.hpp',
|
||||||
|
@ -73,7 +77,6 @@ if not backends_selected
|
||||||
endif
|
endif
|
||||||
|
|
||||||
lib_deps = [
|
lib_deps = [
|
||||||
restc_cpp_dep,
|
|
||||||
ev_dep,
|
ev_dep,
|
||||||
threads_dep,
|
threads_dep,
|
||||||
boost_dep,
|
boost_dep,
|
||||||
|
@ -81,11 +84,22 @@ lib_deps = [
|
||||||
simdjson_dep,
|
simdjson_dep,
|
||||||
] + backend_libs
|
] + backend_libs
|
||||||
|
|
||||||
|
if get_option('rest_lib') == 'nap'
|
||||||
|
oro_rest_sources = [
|
||||||
|
'nap/page_fetch.cpp',
|
||||||
|
'nap/http_header_parse.cpp',
|
||||||
|
'nap/quick_rest.cpp',
|
||||||
|
'oro/api_nap.cpp',
|
||||||
|
]
|
||||||
|
elif get_option('rest_lib') == 'restc-cpp'
|
||||||
|
oro_rest_sources = ['oro/api_restccpp.cpp']
|
||||||
|
lib_deps += [restc_cpp_dep]
|
||||||
|
endif
|
||||||
|
|
||||||
executable(meson.project_name(),
|
executable(meson.project_name(),
|
||||||
'main.cpp',
|
'main.cpp',
|
||||||
'ini_file.cpp',
|
'ini_file.cpp',
|
||||||
'oro/datatypes.cpp',
|
'oro/datatypes.cpp',
|
||||||
'oro/api.cpp',
|
|
||||||
'oro/private/dateconv.cpp',
|
'oro/private/dateconv.cpp',
|
||||||
'oro/items.cpp',
|
'oro/items.cpp',
|
||||||
'oro/shops.cpp',
|
'oro/shops.cpp',
|
||||||
|
@ -103,9 +117,7 @@ executable(meson.project_name(),
|
||||||
'eventia/event.cpp',
|
'eventia/event.cpp',
|
||||||
'timer_oro_api.cpp',
|
'timer_oro_api.cpp',
|
||||||
'oro/originsdb.cpp',
|
'oro/originsdb.cpp',
|
||||||
'nap/page_fetch.cpp',
|
oro_rest_sources,
|
||||||
'nap/http_header_parse.cpp',
|
|
||||||
'nap/quick_rest.cpp',
|
|
||||||
project_config_file,
|
project_config_file,
|
||||||
install: true,
|
install: true,
|
||||||
dependencies: lib_deps,
|
dependencies: lib_deps,
|
||||||
|
|
|
@ -83,12 +83,9 @@ public:
|
||||||
std::pair<Header, Creators> fame_list();
|
std::pair<Header, Creators> fame_list();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_prefix;
|
struct LocalData;
|
||||||
std::string m_api_key;
|
|
||||||
std::string m_client_name;
|
|
||||||
std::string m_client_purpose;
|
|
||||||
|
|
||||||
std::unique_ptr<restc_cpp::RestClient> m_client;
|
std::unique_ptr<LocalData> m_local;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace oro
|
} //namespace oro
|
||||||
|
|
77
src/oro/api_nap.cpp
Normal file
77
src/oro/api_nap.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* Copyright 2020, Michele Santullo
|
||||||
|
* This file is part of orotool.
|
||||||
|
*
|
||||||
|
* Orotool is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Orotool is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "api.hpp"
|
||||||
|
#include "nap/quick_rest.hpp"
|
||||||
|
#include "private/v1_endpoints.hpp"
|
||||||
|
|
||||||
|
namespace oro {
|
||||||
|
|
||||||
|
struct Api::LocalData {
|
||||||
|
LocalData (
|
||||||
|
std::string&& root_address
|
||||||
|
) :
|
||||||
|
prefix(std::move(root_address))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string prefix;
|
||||||
|
nap::QuickRest qrest;
|
||||||
|
};
|
||||||
|
|
||||||
|
Api::Api (
|
||||||
|
std::string&& root_address,
|
||||||
|
std::string&& api_key,
|
||||||
|
std::string&& client_name,
|
||||||
|
std::string&& client_purpose
|
||||||
|
) :
|
||||||
|
m_local(std::make_unique<LocalData>(std::move(root_address)))
|
||||||
|
{
|
||||||
|
if (not m_local->prefix.empty() and m_local->prefix[m_local->prefix.size() - 1] != '/')
|
||||||
|
m_local->prefix.push_back('/');
|
||||||
|
|
||||||
|
m_local->qrest.add_headers({
|
||||||
|
{"X-Client", client_name},
|
||||||
|
{"X-Client-Purpose", client_purpose},
|
||||||
|
{"x-api-key", api_key}
|
||||||
|
});
|
||||||
|
m_local->qrest.set_user_agent(std::move(client_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Api::~Api() noexcept = default;
|
||||||
|
|
||||||
|
std::pair<Header, Ping> Api::ping() {
|
||||||
|
m_local->qrest.fetch(m_local->prefix + g_endpoint_ping);
|
||||||
|
//std::cout << nap::page_fetch(url, client_name).body << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Header, WhoAmI> Api::who_am_i() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Header, Items> Api::items_list() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Header, Icons> Api::items_icons() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Header, Shops> Api::market_list() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Header, Creators> Api::fame_list() {
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace oro
|
|
@ -18,6 +18,7 @@
|
||||||
#include "api.hpp"
|
#include "api.hpp"
|
||||||
#include "datatypes.hpp"
|
#include "datatypes.hpp"
|
||||||
#include "private/dateconv.hpp"
|
#include "private/dateconv.hpp"
|
||||||
|
#include "private/v1_endpoints.hpp"
|
||||||
#include <restc-cpp/restc-cpp.h>
|
#include <restc-cpp/restc-cpp.h>
|
||||||
#include <restc-cpp/RequestBuilder.h>
|
#include <restc-cpp/RequestBuilder.h>
|
||||||
#include <boost/fusion/adapted.hpp>
|
#include <boost/fusion/adapted.hpp>
|
||||||
|
@ -127,12 +128,6 @@ BOOST_FUSION_ADAPT_STRUCT(
|
||||||
namespace oro {
|
namespace oro {
|
||||||
namespace {
|
namespace {
|
||||||
constexpr const std::int64_t g_max_json_mem = 1024 * 1024 * 20;
|
constexpr const std::int64_t g_max_json_mem = 1024 * 1024 * 20;
|
||||||
constexpr const char g_endpoint_ping[] = "api/v1/ping";
|
|
||||||
constexpr const char g_endpoint_whoami[] = "api/v1/whoami";
|
|
||||||
constexpr const char g_endpoint_items_list[] = "api/v1/items/list";
|
|
||||||
constexpr const char g_endpoint_items_icons[] = "api/v1/items/icons";
|
|
||||||
constexpr const char g_endpoint_market_list[] = "api/v1/market/list";
|
|
||||||
constexpr const char g_endpoint_fame_list[] = "api/v1/fame/list";
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::pair<Header, T> call_rest_api (
|
std::pair<Header, T> call_rest_api (
|
||||||
|
@ -183,26 +178,43 @@ namespace {
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
|
struct Api::LocalData {
|
||||||
|
explicit LocalData (
|
||||||
|
std::string&& root_address,
|
||||||
|
std::string&& api_key,
|
||||||
|
std::string&& client_name,
|
||||||
|
std::string&& client_purpose
|
||||||
|
) :
|
||||||
|
prefix(std::move(root_address)),
|
||||||
|
api_key(std::move(api_key)),
|
||||||
|
client_name(std::move(client_name)),
|
||||||
|
client_purpose(std::move(client_purpose)),
|
||||||
|
client(rc::RestClient::Create())
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string prefix;
|
||||||
|
std::string api_key;
|
||||||
|
std::string client_name;
|
||||||
|
std::string client_purpose;
|
||||||
|
std::unique_ptr<restc_cpp::RestClient> client;
|
||||||
|
};
|
||||||
|
|
||||||
Api::Api (
|
Api::Api (
|
||||||
std::string&& root_address,
|
std::string&& root_address,
|
||||||
std::string&& api_key,
|
std::string&& api_key,
|
||||||
std::string&& client_name,
|
std::string&& client_name,
|
||||||
std::string&& client_purpose
|
std::string&& client_purpose
|
||||||
) :
|
) :
|
||||||
m_prefix(std::move(root_address)),
|
m_local(std::make_unique<LocalData>(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)))
|
||||||
m_api_key(std::move(api_key)),
|
|
||||||
m_client_name(std::move(client_name)),
|
|
||||||
m_client_purpose(std::move(client_purpose)),
|
|
||||||
m_client(rc::RestClient::Create())
|
|
||||||
{
|
{
|
||||||
if (not m_prefix.empty() and m_prefix[m_prefix.size() - 1] != '/')
|
if (not m_local->prefix.empty() and m_local->prefix[m_local->prefix.size() - 1] != '/')
|
||||||
m_prefix.push_back('/');
|
m_local->prefix.push_back('/');
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
std::cout << "OriginsRO API settings\n" <<
|
std::cout << "OriginsRO API settings\n" <<
|
||||||
"\troot_address: \"" << m_prefix << "\"\n" <<
|
"\troot_address: \"" << m_local->prefix << "\"\n" <<
|
||||||
"\tapi_key: \"" << m_api_key << "\"\n" <<
|
"\tapi_key: \"" << m_local->api_key << "\"\n" <<
|
||||||
"\tclient_name: \"" << m_client_name << "\"\n" <<
|
"\tclient_name: \"" << m_local->client_name << "\"\n" <<
|
||||||
"\tclient_purpose: \"" << m_client_purpose << "\"\n" <<
|
"\tclient_purpose: \"" << m_local->client_purpose << "\"\n" <<
|
||||||
"";
|
"";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -210,27 +222,27 @@ Api::Api (
|
||||||
Api::~Api() noexcept = default;
|
Api::~Api() noexcept = default;
|
||||||
|
|
||||||
std::pair<Header, Ping> Api::ping() {
|
std::pair<Header, Ping> Api::ping() {
|
||||||
return call_rest_api<oro::Ping>(*m_client, m_prefix + g_endpoint_ping, m_api_key, m_client_name, m_client_purpose);
|
return call_rest_api<oro::Ping>(*m_local->client, m_local->prefix + g_endpoint_ping, m_local->api_key, m_local->client_name, m_local->client_purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Header, WhoAmI> Api::who_am_i() {
|
std::pair<Header, WhoAmI> Api::who_am_i() {
|
||||||
return call_rest_api<oro::WhoAmI>(*m_client, m_prefix + g_endpoint_whoami, m_api_key, m_client_name, m_client_purpose);
|
return call_rest_api<oro::WhoAmI>(*m_local->client, m_local->prefix + g_endpoint_whoami, m_local->api_key, m_local->client_name, m_local->client_purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Header, Items> Api::items_list() {
|
std::pair<Header, Items> Api::items_list() {
|
||||||
return call_rest_api<oro::Items>(*m_client, m_prefix + g_endpoint_items_list, m_api_key, m_client_name, m_client_purpose);
|
return call_rest_api<oro::Items>(*m_local->client, m_local->prefix + g_endpoint_items_list, m_local->api_key, m_local->client_name, m_local->client_purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Header, Icons> Api::items_icons() {
|
std::pair<Header, Icons> Api::items_icons() {
|
||||||
return call_rest_api<oro::Icons>(*m_client, m_prefix + g_endpoint_items_icons, m_api_key, m_client_name, m_client_purpose);
|
return call_rest_api<oro::Icons>(*m_local->client, m_local->prefix + g_endpoint_items_icons, m_local->api_key, m_local->client_name, m_local->client_purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Header, Shops> Api::market_list() {
|
std::pair<Header, Shops> Api::market_list() {
|
||||||
return call_rest_api<oro::Shops>(*m_client, m_prefix + g_endpoint_market_list, m_api_key, m_client_name, m_client_purpose);
|
return call_rest_api<oro::Shops>(*m_local->client, m_local->prefix + g_endpoint_market_list, m_local->api_key, m_local->client_name, m_local->client_purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Header, Creators> Api::fame_list() {
|
std::pair<Header, Creators> Api::fame_list() {
|
||||||
return call_rest_api<oro::Creators>(*m_client, m_prefix + g_endpoint_fame_list, m_api_key, m_client_name, m_client_purpose);
|
return call_rest_api<oro::Creators>(*m_local->client, m_local->prefix + g_endpoint_fame_list, m_local->api_key, m_local->client_name, m_local->client_purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace oro
|
} //namespace oro
|
29
src/oro/private/v1_endpoints.hpp
Normal file
29
src/oro/private/v1_endpoints.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* Copyright 2020, Michele Santullo
|
||||||
|
* This file is part of orotool.
|
||||||
|
*
|
||||||
|
* Orotool is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Orotool is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Orotool. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace oro {
|
||||||
|
namespace {
|
||||||
|
constexpr const char g_endpoint_ping[] = "api/v1/ping";
|
||||||
|
constexpr const char g_endpoint_whoami[] = "api/v1/whoami";
|
||||||
|
constexpr const char g_endpoint_items_list[] = "api/v1/items/list";
|
||||||
|
constexpr const char g_endpoint_items_icons[] = "api/v1/items/icons";
|
||||||
|
constexpr const char g_endpoint_market_list[] = "api/v1/market/list";
|
||||||
|
constexpr const char g_endpoint_fame_list[] = "api/v1/fame/list";
|
||||||
|
} //unnamed namespace
|
||||||
|
} //namespace oro
|
|
@ -16,8 +16,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "timer_oro_api.hpp"
|
#include "timer_oro_api.hpp"
|
||||||
|
#include "orotool_config.hpp"
|
||||||
#include "oro/api.hpp"
|
#include "oro/api.hpp"
|
||||||
#include <restc-cpp/error.h>
|
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||||
|
# include <restc-cpp/error.h>
|
||||||
|
#endif
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
namespace duck {
|
namespace duck {
|
||||||
|
@ -66,6 +69,7 @@ inline void TimerOroApi<Op>::fetch_data() {
|
||||||
set_next_timer(results.first);
|
set_next_timer(results.first);
|
||||||
this->update_db(results.second, results.first);
|
this->update_db(results.second, results.first);
|
||||||
}
|
}
|
||||||
|
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||||
catch (const restc_cpp::RequestFailedWithErrorException& err) {
|
catch (const restc_cpp::RequestFailedWithErrorException& err) {
|
||||||
status_code = err.http_response.status_code;
|
status_code = err.http_response.status_code;
|
||||||
if (429 == err.http_response.status_code) {
|
if (429 == err.http_response.status_code) {
|
||||||
|
@ -75,6 +79,7 @@ inline void TimerOroApi<Op>::fetch_data() {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
catch (...) {
|
catch (...) {
|
||||||
this->set_exception(std::current_exception());
|
this->set_exception(std::current_exception());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue