8#include "MantidJson/Json.h"
12#include <Poco/Net/HTTPClientSession.h>
13#include <Poco/Net/HTTPRequest.h>
14#include <Poco/Net/HTTPResponse.h>
15#include <Poco/StreamCopier.h>
18#include <boost/algorithm/string/predicate.hpp>
19#include <boost/lexical_cast.hpp>
26using namespace Types::Core;
38Logger
g_log(
"GitHubApiHelper");
40const std::string RATE_LIMIT_URL(
"https://api.github.com/rate_limit");
43const std::string CONFIG_KEY_GITHUB_TOKEN(
"network.github.api_token");
45std::string formatRateLimit(
const int rateLimit,
const int remaining,
const int expires) {
46 DateAndTime expiresDateAndTime;
47 expiresDateAndTime.set_from_time_t(expires);
49 std::stringstream msg;
50 msg <<
"GitHub API limited to " << remaining <<
" of " << rateLimit <<
" calls left. Resets at "
51 << expiresDateAndTime.toISO8601String() <<
"Z";
58std::string getApiToken() {
60 std::string token(DEFAULT_GITHUB_TOKEN);
67 if (token.empty() || boost::istarts_with(token,
"unset")) {
72 if (token.size() != 40) {
73 g_log.
notice() <<
"GitHub API token is not 40 characters (found " << token.size() <<
") with token =\"" << token
74 <<
"\" using unauthenticated connection\n";
88 std::stringstream token_header;
89 token_header <<
"token " << token;
90 return token_header.str();
125 int rateLimitRemaining = 0;
129 rateLimitLimit = boost::lexical_cast<int>(res.get(
"X-RateLimit-Limit",
"-1"));
130 rateLimitRemaining = boost::lexical_cast<int>(res.get(
"X-RateLimit-Remaining",
"-1"));
131 rateLimitReset = boost::lexical_cast<int>(res.get(
"X-RateLimit-Reset",
"0"));
132 }
catch (boost::bad_lexical_cast
const &) {
135 if (rateLimitLimit > -1) {
136 g_log.
debug(formatRateLimit(rateLimitLimit, rateLimitRemaining, rateLimitReset));
141 std::stringstream responseStream;
143 auto responseString = responseStream.str();
146 if (!Mantid::JsonHelpers::parse(responseString, &root, NULL)) {
147 return "Failed to parse json document from \"" + RATE_LIMIT_URL +
"\"";
150 const auto &rateInfo = root.get(
"rate",
"");
151 if (rateInfo.empty())
152 return std::string();
154 const int limit = rateInfo.get(
"limit", -1).asInt();
155 const int remaining = rateInfo.get(
"remaining", -1).asInt();
156 const int expires = rateInfo.get(
"reset", 0).asInt();
158 return formatRateLimit(limit, remaining, expires);
162 std::ostream &responseStream) {
163 g_log.
debug(
"Repeating API call anonymously\n");
166 return this->
sendRequest(uri.toString(), responseStream);
170 std::ostream &responseStream) {
175 std::istream &rs = session.receiveResponse(*
m_response);
177 g_log.
debug() <<
"Answer from web: " <<
static_cast<int>(retStatus) <<
" " <<
m_response->getReason() <<
"\n";
180 Poco::StreamCopier::copyStream(rs, responseStream);
194 Poco::StreamCopier::copyStream(rs, responseStream);
virtual InternetHelper::HTTPStatus sendRequestAndProcess(Poco::Net::HTTPClientSession &session, Poco::URI &uri, std::ostream &responseStream) override
std::string getRateLimitDescription()
String describing the rate limit status.
void reset() override
Resets properties to defaults (except the proxy)
void addAuthenticationToken()
InternetHelper::HTTPStatus processAnonymousRequest(Poco::URI &uri, std::ostream &responseStream)
GitHubApiHelper()
Constructor.
virtual void processResponseHeaders(const Poco::Net::HTTPResponse &res) override
Process any headers from the response stream Basic implementation does nothing.
std::string m_api_token
API token for github access.
InternetHelper : A helper class for supporting access to resources through HTTP and HTTPS.
void createRequest(Poco::URI &uri)
InternetHelper::HTTPStatus processRelocation(const Poco::Net::HTTPResponse &response, std::ostream &responseStream)
bool isRelocated(const HTTPStatus &response)
Checks the HTTP status to decide if this is a relocation.
std::unique_ptr< Poco::Net::HTTPRequest > m_request
void addHeader(const std::string &key, const std::string &value)
Adds a header.
StringToStringMap m_headers
virtual HTTPStatus processErrorStates(const Poco::Net::HTTPResponse &res, std::istream &rs, const std::string &url)
Process any HTTP errors states.
virtual HTTPStatus sendRequest(const std::string &url, std::ostream &responseStream)
Performs a request using http or https depending on the url.
void removeHeader(const std::string &key)
Removes a header.
virtual void reset()
Resets properties to defaults (except the proxy)
std::unique_ptr< Poco::Net::HTTPResponse > m_response
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
ProxyInfo : Container for carrying around network proxy information.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Logger g_log("DateAndTime")
Helper class which provides the Collimation Length for SANS instruments.