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.
105 lines
2.8 KiB
C++
105 lines
2.8 KiB
C++
/* 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 "timer_oro_api.hpp"
|
|
#include "orotool_config.hpp"
|
|
#include "oro/api.hpp"
|
|
#if defined(OROTOOL_WITH_RESTCCPP)
|
|
# include <restc-cpp/error.h>
|
|
#endif
|
|
#include <exception>
|
|
|
|
namespace duck {
|
|
|
|
namespace {
|
|
template <oro::DBOperation Op> auto invoke_api_func (oro::Api& api);
|
|
|
|
template <>
|
|
inline auto invoke_api_func<oro::DBOperation::Icons> (oro::Api& api) {
|
|
return api.items_icons();
|
|
}
|
|
|
|
template <>
|
|
inline auto invoke_api_func<oro::DBOperation::Items> (oro::Api& api) {
|
|
return api.items_list();
|
|
}
|
|
|
|
template <>
|
|
inline auto invoke_api_func<oro::DBOperation::Creators> (oro::Api& api) {
|
|
return api.fame_list();
|
|
}
|
|
|
|
template <>
|
|
inline auto invoke_api_func<oro::DBOperation::Shops> (oro::Api& api) {
|
|
return api.market_list();
|
|
}
|
|
} //unnamed namespace
|
|
|
|
template<oro::DBOperation Op>
|
|
inline TimerOroApi<Op>::TimerOroApi (
|
|
const eve::Context& ctx,
|
|
const TimerSettings& settings,
|
|
roar11::ThreadPool* pool,
|
|
oro::Api* oro_api,
|
|
oro::OriginsDB* db
|
|
) :
|
|
TimerBase(ctx, Op, settings, pool, oro_api, db)
|
|
{
|
|
}
|
|
|
|
template<oro::DBOperation Op>
|
|
inline void TimerOroApi<Op>::fetch_data() {
|
|
int status_code = 200;
|
|
try {
|
|
auto results = invoke_api_func<Op>(oro_api());
|
|
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) {
|
|
//server received too many requests, give up for now
|
|
}
|
|
else {
|
|
throw err;
|
|
}
|
|
}
|
|
#endif
|
|
catch (...) {
|
|
this->set_exception(std::current_exception());
|
|
}
|
|
|
|
|
|
if (429 == status_code) {
|
|
oro::Header head;
|
|
head.date.ts = std::chrono::time_point_cast<oro::timestamp_t::duration>(std::chrono::system_clock::now());
|
|
head.rate_limit = 1;
|
|
head.rate_limit_remaining = 0;
|
|
head.rate_limit_reset = 600;
|
|
head.retry_after = 600;
|
|
std::string server = "forged_header";
|
|
set_next_timer(head);
|
|
}
|
|
}
|
|
|
|
template class TimerOroApi<oro::DBOperation::Shops>;
|
|
template class TimerOroApi<oro::DBOperation::Icons>;
|
|
template class TimerOroApi<oro::DBOperation::Items>;
|
|
template class TimerOroApi<oro::DBOperation::Creators>;
|
|
|
|
} //namespace duck
|