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('tests', type: 'feature', value: 'enabled')
|
||||
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_NAP
|
||||
#mesondefine OROTOOL_WITH_RESTCCPP
|
||||
|
||||
#if defined(OROTOOL_WITH_SQLITE)
|
||||
constexpr const char g_sqlite_backend_name[] = "sqlite";
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
#include "duckhandy/int_conv.hpp"
|
||||
#include "duckhandy/string_bt.hpp"
|
||||
#include <iostream>
|
||||
#include <restc-cpp/error.h>
|
||||
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||
# include <restc-cpp/error.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
void print_ping(oro::Api& oro_api) {
|
||||
|
@ -83,11 +85,13 @@ int main(int argc, char* argv[]) {
|
|||
app_conf.worker_threads()
|
||||
);
|
||||
}
|
||||
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||
catch (const restc_cpp::CommunicationException& err) {
|
||||
std::cerr << "Communication with server \"" << duck::g_base_url <<
|
||||
"\" failed: " << err.what() << '\n';
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "An error occurred during the program execution: " <<
|
||||
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'],
|
||||
default_options: [
|
||||
'restc_cpp_with_unit_tests=false',
|
||||
'restc_cpp_log_with_boost_log=false',
|
||||
],
|
||||
)
|
||||
)
|
||||
endif
|
||||
|
||||
curlcpp_dep = dependency('curlcpp', version: '>=1.4',
|
||||
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_PATCH', version_arr[2])
|
||||
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(
|
||||
input: 'config.hpp.in',
|
||||
output: meson.project_name() + '_config.hpp',
|
||||
|
@ -73,7 +77,6 @@ if not backends_selected
|
|||
endif
|
||||
|
||||
lib_deps = [
|
||||
restc_cpp_dep,
|
||||
ev_dep,
|
||||
threads_dep,
|
||||
boost_dep,
|
||||
|
@ -81,11 +84,22 @@ lib_deps = [
|
|||
simdjson_dep,
|
||||
] + 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(),
|
||||
'main.cpp',
|
||||
'ini_file.cpp',
|
||||
'oro/datatypes.cpp',
|
||||
'oro/api.cpp',
|
||||
'oro/private/dateconv.cpp',
|
||||
'oro/items.cpp',
|
||||
'oro/shops.cpp',
|
||||
|
@ -103,9 +117,7 @@ executable(meson.project_name(),
|
|||
'eventia/event.cpp',
|
||||
'timer_oro_api.cpp',
|
||||
'oro/originsdb.cpp',
|
||||
'nap/page_fetch.cpp',
|
||||
'nap/http_header_parse.cpp',
|
||||
'nap/quick_rest.cpp',
|
||||
oro_rest_sources,
|
||||
project_config_file,
|
||||
install: true,
|
||||
dependencies: lib_deps,
|
||||
|
|
|
@ -83,12 +83,9 @@ public:
|
|||
std::pair<Header, Creators> fame_list();
|
||||
|
||||
private:
|
||||
std::string m_prefix;
|
||||
std::string m_api_key;
|
||||
std::string m_client_name;
|
||||
std::string m_client_purpose;
|
||||
struct LocalData;
|
||||
|
||||
std::unique_ptr<restc_cpp::RestClient> m_client;
|
||||
std::unique_ptr<LocalData> m_local;
|
||||
};
|
||||
|
||||
} //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 "datatypes.hpp"
|
||||
#include "private/dateconv.hpp"
|
||||
#include "private/v1_endpoints.hpp"
|
||||
#include <restc-cpp/restc-cpp.h>
|
||||
#include <restc-cpp/RequestBuilder.h>
|
||||
#include <boost/fusion/adapted.hpp>
|
||||
|
@ -127,12 +128,6 @@ BOOST_FUSION_ADAPT_STRUCT(
|
|||
namespace oro {
|
||||
namespace {
|
||||
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>
|
||||
std::pair<Header, T> call_rest_api (
|
||||
|
@ -183,26 +178,43 @@ 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 (
|
||||
std::string&& root_address,
|
||||
std::string&& api_key,
|
||||
std::string&& client_name,
|
||||
std::string&& client_purpose
|
||||
) :
|
||||
m_prefix(std::move(root_address)),
|
||||
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())
|
||||
m_local(std::make_unique<LocalData>(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)))
|
||||
{
|
||||
if (not m_prefix.empty() and m_prefix[m_prefix.size() - 1] != '/')
|
||||
m_prefix.push_back('/');
|
||||
if (not m_local->prefix.empty() and m_local->prefix[m_local->prefix.size() - 1] != '/')
|
||||
m_local->prefix.push_back('/');
|
||||
#if !defined(NDEBUG)
|
||||
std::cout << "OriginsRO API settings\n" <<
|
||||
"\troot_address: \"" << m_prefix << "\"\n" <<
|
||||
"\tapi_key: \"" << m_api_key << "\"\n" <<
|
||||
"\tclient_name: \"" << m_client_name << "\"\n" <<
|
||||
"\tclient_purpose: \"" << m_client_purpose << "\"\n" <<
|
||||
"\troot_address: \"" << m_local->prefix << "\"\n" <<
|
||||
"\tapi_key: \"" << m_local->api_key << "\"\n" <<
|
||||
"\tclient_name: \"" << m_local->client_name << "\"\n" <<
|
||||
"\tclient_purpose: \"" << m_local->client_purpose << "\"\n" <<
|
||||
"";
|
||||
#endif
|
||||
}
|
||||
|
@ -210,27 +222,27 @@ Api::Api (
|
|||
Api::~Api() noexcept = default;
|
||||
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
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
|
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 "orotool_config.hpp"
|
||||
#include "oro/api.hpp"
|
||||
#include <restc-cpp/error.h>
|
||||
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||
# include <restc-cpp/error.h>
|
||||
#endif
|
||||
#include <exception>
|
||||
|
||||
namespace duck {
|
||||
|
@ -66,6 +69,7 @@ inline void TimerOroApi<Op>::fetch_data() {
|
|||
set_next_timer(results.first);
|
||||
this->update_db(results.second, results.first);
|
||||
}
|
||||
#if defined(OROTOOL_WITH_RESTCCPP)
|
||||
catch (const restc_cpp::RequestFailedWithErrorException& err) {
|
||||
status_code = err.http_response.status_code;
|
||||
if (429 == err.http_response.status_code) {
|
||||
|
@ -75,6 +79,7 @@ inline void TimerOroApi<Op>::fetch_data() {
|
|||
throw err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
catch (...) {
|
||||
this->set_exception(std::current_exception());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue