From 4e63e1b24675df7ce8601b6cd417f94fe988d65d Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 29 Aug 2020 17:10:41 +0100 Subject: [PATCH] Make Api virtual. I think this is a bit better than what I had before. Still a mess, but that's conditional compilation for you. --- src/main.cpp | 6 +-- src/meson.build | 1 + src/oro/api.cpp | 80 ++++++++++++++++++++++++++++++++ src/oro/api.hpp | 34 ++++++++------ src/oro/api_nap.cpp | 49 +++++++------------ src/oro/api_restccpp.cpp | 64 +++++++------------------ src/oro/private/api_nap.hpp | 47 +++++++++++++++++++ src/oro/private/api_restccpp.hpp | 49 +++++++++++++++++++ 8 files changed, 233 insertions(+), 97 deletions(-) create mode 100644 src/oro/api.cpp create mode 100644 src/oro/private/api_nap.hpp create mode 100644 src/oro/private/api_restccpp.hpp diff --git a/src/main.cpp b/src/main.cpp index 45bce47..3b2d8ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,19 +67,19 @@ int main(int argc, char* argv[]) { try { duck::AppConfig app_conf; std::string_view api_key = (2 == argc ? std::string_view(argv[1]) : app_conf.api_key()); - oro::Api oro_api( + auto oro_api = oro::make_api( duck::g_base_url, std::string(api_key), app_api_name().data(), duck::g_build_purpose ); - print_ping(oro_api); + print_ping(*oro_api); std::unique_ptr db(oro::OriginsDB::make(app_conf.backend(), app_conf.db_path())); duck::test( - &oro_api, + oro_api.get(), db.get(), app_conf.fetch_extra_delay(), app_conf.worker_threads() diff --git a/src/meson.build b/src/meson.build index 21e0914..a5c1bfe 100644 --- a/src/meson.build +++ b/src/meson.build @@ -117,6 +117,7 @@ executable(meson.project_name(), 'eventia/event.cpp', 'timer_oro_api.cpp', 'oro/originsdb.cpp', + 'oro/api.cpp', oro_rest_sources, project_config_file, install: true, diff --git a/src/oro/api.cpp b/src/oro/api.cpp new file mode 100644 index 0000000..5cbdd9d --- /dev/null +++ b/src/oro/api.cpp @@ -0,0 +1,80 @@ +/* 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 . + */ + +#include "api.hpp" +#include "orotool_config.hpp" +#if defined(OROTOOL_WITH_RESTCCPP) +# include "private/api_restccpp.hpp" +#elif defined(OROTOOL_WITH_NAP) +# include "private/api_nap.hpp" +#else +# error "No REST backend library specified" +#endif +#if !defined(NDEBUG) +# include +#endif + +namespace oro { + +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)) +{ + if (not m_prefix.empty() and m_prefix[m_prefix.size() - 1] != '/') + m_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" << + ""; +#endif +} + +Api::~Api() noexcept = default; + +std::unique_ptr make_api ( + std::string&& root_address, + std::string&& api_key, + std::string&& client_name, + std::string&& client_purpose +) { +#if defined(OROTOOL_WITH_RESTCCPP) + typedef ApiRestcCpp RetType; +#elif defined(OROTOOL_WITH_NAP) + typedef ApiNap RetType; +#else +# error "No REST backend library specified" +#endif + + return std::make_unique( + std::move(root_address), + std::move(api_key), + std::move(client_name), + std::move(client_purpose) + ); +} + +} //namespace oro diff --git a/src/oro/api.hpp b/src/oro/api.hpp index 8ebd436..77c1009 100644 --- a/src/oro/api.hpp +++ b/src/oro/api.hpp @@ -27,10 +27,6 @@ #include #include -namespace restc_cpp { -class RestClient; -} //namespace restc_cpp - namespace oro { struct Header { @@ -73,19 +69,27 @@ public: std::string&& client_name, std::string&& client_purpose ); - ~Api() noexcept; + virtual ~Api() noexcept; - std::pair ping(); - std::pair who_am_i(); - std::pair items_list(); - std::pair items_icons(); - std::pair market_list(); - std::pair fame_list(); + virtual std::pair ping() = 0; + virtual std::pair who_am_i() = 0; + virtual std::pair items_list() = 0; + virtual std::pair items_icons() = 0; + virtual std::pair market_list() = 0; + virtual std::pair fame_list() = 0; -private: - struct LocalData; - - std::unique_ptr m_local; +protected: + std::string m_prefix; + std::string m_api_key; + std::string m_client_name; + std::string m_client_purpose; }; +std::unique_ptr make_api ( + std::string&& root_address, + std::string&& api_key, + std::string&& client_name, + std::string&& client_purpose +); + } //namespace oro diff --git a/src/oro/api_nap.cpp b/src/oro/api_nap.cpp index 39acc55..83a1cf2 100644 --- a/src/oro/api_nap.cpp +++ b/src/oro/api_nap.cpp @@ -15,63 +15,48 @@ * along with Orotool. If not, see . */ -#include "api.hpp" -#include "nap/quick_rest.hpp" +#include "private/api_nap.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 ( +ApiNap::ApiNap ( std::string&& root_address, std::string&& api_key, std::string&& client_name, std::string&& client_purpose ) : - m_local(std::make_unique(std::move(root_address))) + Api(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)), + m_qrest() { - 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_qrest.add_headers({ + {"X-Client", m_client_name}, + {"X-Client-Purpose", m_client_purpose}, + {"x-api-key", m_api_key} }); - m_local->qrest.set_user_agent(std::move(client_name)); + m_qrest.set_user_agent(std::string(m_client_name)); } -Api::~Api() noexcept = default; +ApiNap::~ApiNap() noexcept = default; -std::pair Api::ping() { - m_local->qrest.fetch(m_local->prefix + g_endpoint_ping); +std::pair ApiNap::ping() { + m_qrest.fetch(m_prefix + g_endpoint_ping); //std::cout << nap::page_fetch(url, client_name).body << '\n'; } -std::pair Api::who_am_i() { +std::pair ApiNap::who_am_i() { } -std::pair Api::items_list() { +std::pair ApiNap::items_list() { } -std::pair Api::items_icons() { +std::pair ApiNap::items_icons() { } -std::pair Api::market_list() { +std::pair ApiNap::market_list() { } -std::pair Api::fame_list() { +std::pair ApiNap::fame_list() { } } //namespace oro diff --git a/src/oro/api_restccpp.cpp b/src/oro/api_restccpp.cpp index cd28505..3d77977 100644 --- a/src/oro/api_restccpp.cpp +++ b/src/oro/api_restccpp.cpp @@ -15,7 +15,7 @@ * along with Orotool. If not, see . */ -#include "api.hpp" +#include "private/api_restccpp.hpp" #include "datatypes.hpp" #include "private/dateconv.hpp" #include "private/v1_endpoints.hpp" @@ -178,71 +178,41 @@ 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 client; -}; - -Api::Api ( +ApiRestcCpp::ApiRestcCpp ( std::string&& root_address, std::string&& api_key, std::string&& client_name, std::string&& client_purpose ) : - m_local(std::make_unique(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose))) + Api(std::move(root_address), std::move(api_key), std::move(client_name), std::move(client_purpose)), + m_client(rc::RestClient::Create()) { - 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_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 } -Api::~Api() noexcept = default; +ApiRestcCpp::~ApiRestcCpp() noexcept = default; -std::pair Api::ping() { - return call_rest_api(*m_local->client, m_local->prefix + g_endpoint_ping, m_local->api_key, m_local->client_name, m_local->client_purpose); +std::pair ApiRestcCpp::ping() { + return call_rest_api(*m_client, m_prefix + g_endpoint_ping, m_api_key, m_client_name, m_client_purpose); } -std::pair Api::who_am_i() { - return call_rest_api(*m_local->client, m_local->prefix + g_endpoint_whoami, m_local->api_key, m_local->client_name, m_local->client_purpose); +std::pair ApiRestcCpp::who_am_i() { + return call_rest_api(*m_client, m_prefix + g_endpoint_whoami, m_api_key, m_client_name, m_client_purpose); } -std::pair Api::items_list() { - return call_rest_api(*m_local->client, m_local->prefix + g_endpoint_items_list, m_local->api_key, m_local->client_name, m_local->client_purpose); +std::pair ApiRestcCpp::items_list() { + return call_rest_api(*m_client, m_prefix + g_endpoint_items_list, m_api_key, m_client_name, m_client_purpose); } -std::pair Api::items_icons() { - return call_rest_api(*m_local->client, m_local->prefix + g_endpoint_items_icons, m_local->api_key, m_local->client_name, m_local->client_purpose); +std::pair ApiRestcCpp::items_icons() { + return call_rest_api(*m_client, m_prefix + g_endpoint_items_icons, m_api_key, m_client_name, m_client_purpose); } -std::pair Api::market_list() { - return call_rest_api(*m_local->client, m_local->prefix + g_endpoint_market_list, m_local->api_key, m_local->client_name, m_local->client_purpose); +std::pair ApiRestcCpp::market_list() { + return call_rest_api(*m_client, m_prefix + g_endpoint_market_list, m_api_key, m_client_name, m_client_purpose); } -std::pair Api::fame_list() { - return call_rest_api(*m_local->client, m_local->prefix + g_endpoint_fame_list, m_local->api_key, m_local->client_name, m_local->client_purpose); +std::pair ApiRestcCpp::fame_list() { + return call_rest_api(*m_client, m_prefix + g_endpoint_fame_list, m_api_key, m_client_name, m_client_purpose); } } //namespace oro diff --git a/src/oro/private/api_nap.hpp b/src/oro/private/api_nap.hpp new file mode 100644 index 0000000..d8bbb52 --- /dev/null +++ b/src/oro/private/api_nap.hpp @@ -0,0 +1,47 @@ +/* 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 . + */ + +#pragma once + +#include "oro/api.hpp" +#include "nap/quick_rest.hpp" + +namespace oro { + +class ApiNap : public Api { +public: + ApiNap ( + std::string&& root_address, + std::string&& api_key, + std::string&& client_name, + std::string&& client_purpose + ); + + virtual ~ApiNap() noexcept; + + virtual std::pair ping() override; + virtual std::pair who_am_i() override; + virtual std::pair items_list() override; + virtual std::pair items_icons() override; + virtual std::pair market_list() override; + virtual std::pair fame_list() override; + +private: + nap::QuickRest m_qrest; +}; + +} //namespace oro diff --git a/src/oro/private/api_restccpp.hpp b/src/oro/private/api_restccpp.hpp new file mode 100644 index 0000000..8a85976 --- /dev/null +++ b/src/oro/private/api_restccpp.hpp @@ -0,0 +1,49 @@ +/* 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 . + */ + +#pragma once + +#include "oro/api.hpp" + +namespace restc_cpp { +class RestClient; +} //namespace restc_cpp + +namespace oro { + +class ApiRestcCpp : public Api { +public: + ApiRestcCpp ( + std::string&& root_address, + std::string&& api_key, + std::string&& client_name, + std::string&& client_purpose + ); + ~ApiRestcCpp() noexcept; + + virtual std::pair ping() override; + virtual std::pair who_am_i() override; + virtual std::pair items_list() override; + virtual std::pair items_icons() override; + virtual std::pair market_list() override; + virtual std::pair fame_list() override; + +private: + std::unique_ptr m_client; +}; + +} //namespace oro