Merge branch 'develop' into main
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
398383143a
|
@ -29,6 +29,11 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
|||
|
||||
include(debug_flags)
|
||||
|
||||
# Disable debug log.
|
||||
if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
|
||||
add_definitions("-DNDEBUG")
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(include)
|
||||
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
#define MASTODONPP_API_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::variant;
|
||||
|
||||
/*!
|
||||
|
@ -76,14 +76,15 @@ public:
|
|||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
explicit API(endpoint_type &endpoint);
|
||||
explicit API(const endpoint_type &endpoint);
|
||||
|
||||
/*!
|
||||
* @brief Convert #endpoint_type to string.
|
||||
* @brief Convert #endpoint_type to `std::string_view`.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
string to_string() const;
|
||||
[[nodiscard]]
|
||||
string_view to_string_view() const;
|
||||
|
||||
private:
|
||||
const endpoint_type _endpoint;
|
||||
|
|
|
@ -14,50 +14,68 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MASTODONPP_REQUEST_HPP
|
||||
#define MASTODONPP_REQUEST_HPP
|
||||
#ifndef MASTODONPP_CONNECTION_HPP
|
||||
#define MASTODONPP_CONNECTION_HPP
|
||||
|
||||
#include "api.hpp"
|
||||
#include "curl_wrapper.hpp"
|
||||
#include "instance.hpp"
|
||||
#include "return_types.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
|
||||
/*!
|
||||
* @brief Used to make a request to the Mastodon API.
|
||||
* @brief Represents a connection to an instance. Used for requests.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @headerfile request.hpp mastodonpp/request.hpp
|
||||
* @headerfile connection.hpp mastodonpp/connection.hpp
|
||||
*/
|
||||
class Request
|
||||
class Connection : public CURLWrapper
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Construct a new Request object.
|
||||
* @brief Construct a new Connection object.
|
||||
*
|
||||
* @param instance An Instance with the access data.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
explicit Request(Instance &instance);
|
||||
explicit Connection(Instance &instance);
|
||||
|
||||
/*!
|
||||
* @brief Make a HTTP GET call.
|
||||
*
|
||||
* @param endpoint Endpoint as API::endpoint_type, for example:
|
||||
* `mastodonpp::API::v1::instance`.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
answer_type get(API::endpoint_type endpoint) const;
|
||||
[[nodiscard]]
|
||||
answer_type get(const API::endpoint_type &endpoint);
|
||||
|
||||
/*!
|
||||
* @brief Make a HTTP GET call.
|
||||
*
|
||||
* @param endpoint Endpoint as string, for example: "/api/v1/instance".
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
answer_type get(const string_view &endpoint);
|
||||
|
||||
private:
|
||||
Instance &_instance;
|
||||
const string_view _baseuri;
|
||||
};
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
||||
#endif // MASTODONPP_REQUEST_HPP
|
||||
#endif // MASTODONPP_CONNECTION_HPP
|
125
include/curl_wrapper.hpp
Normal file
125
include/curl_wrapper.hpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* This file is part of mastodonpp.
|
||||
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MASTODONPP_CURL_WRAPPER_HPP
|
||||
#define MASTODONPP_CURL_WRAPPER_HPP
|
||||
|
||||
#include "return_types.hpp"
|
||||
|
||||
#include "curl/curl.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
|
||||
/*!
|
||||
* @brief The HTTP method.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
enum class http_method
|
||||
{
|
||||
GET,
|
||||
POST
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Handles the details of network connections.
|
||||
*
|
||||
* You don't need to use this.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @headerfile curl_wrapper.hpp mastodonpp/curl_wrapper.hpp
|
||||
*/
|
||||
class CURLWrapper
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Initializes curl and sets up connection.
|
||||
*
|
||||
* Calls `curl_global_init`, which is not thread-safe. For more information
|
||||
* consult [curl_global_init(3)]
|
||||
* (https://curl.haxx.se/libcurl/c/curl_global_init.html).
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
CURLWrapper();
|
||||
|
||||
//! Copy constructor
|
||||
CURLWrapper(const CURLWrapper &other) = default;
|
||||
|
||||
//! Move constructor
|
||||
CURLWrapper(CURLWrapper &&other) noexcept = default;
|
||||
|
||||
/*!
|
||||
* @brief Cleans up curl and connection.
|
||||
*
|
||||
* Calls `curl_global_cleanup`, which is not thread-safe. For more
|
||||
* information consult [curl_global_cleanup(3)]
|
||||
* (https://curl.haxx.se/libcurl/c/curl_global_cleanup.html).
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
virtual ~CURLWrapper() noexcept;
|
||||
|
||||
//! Copy assignment operator
|
||||
CURLWrapper& operator=(const CURLWrapper &other) = default;
|
||||
|
||||
//! Move assignment operator
|
||||
CURLWrapper& operator=(CURLWrapper &&other) noexcept = default;
|
||||
|
||||
/*!
|
||||
* @brief Make a request.
|
||||
*
|
||||
* @param method The HTTP method.
|
||||
* @param uri The full URI.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
answer_type make_request(const http_method &method, const string_view &uri);
|
||||
|
||||
private:
|
||||
CURL *_connection;
|
||||
char _curl_buffer_error[CURL_ERROR_SIZE];
|
||||
string _curl_buffer_headers;
|
||||
string _curl_buffer_body;
|
||||
|
||||
/*!
|
||||
* @brief libcurl write callback function.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
string *writerData);
|
||||
|
||||
/*!
|
||||
* @brief Setup libcurl connection.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void setup_curl();
|
||||
};
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
||||
#endif // MASTODONPP_CURL_WRAPPER_HPP
|
|
@ -58,7 +58,8 @@ public:
|
|||
/*!
|
||||
* @brief The error code returned by libcurl.
|
||||
*
|
||||
* For more information consult libcurl-errors(3).
|
||||
* For more information consult
|
||||
* [libcurl-errors(3)](https://curl.haxx.se/libcurl/c/libcurl-errors.html).
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
|
|
|
@ -17,58 +17,92 @@
|
|||
#ifndef MASTODONPP_INSTANCE_HPP
|
||||
#define MASTODONPP_INSTANCE_HPP
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_wrapper.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::uint64_t;
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
|
||||
/*!
|
||||
* @brief Holds the hostname and access token of an instance.
|
||||
* @brief Holds the access data of an instance.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @headerfile instance.hpp mastodonpp/instance.hpp
|
||||
*/
|
||||
class Instance
|
||||
class Instance : public CURLWrapper
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Construct a new Instance object.
|
||||
*
|
||||
* @param instance The hostname of the instance.
|
||||
* Also queries `/api/v1/instance` for `max_toot_chars'.
|
||||
*
|
||||
* @param hostname The hostname of the instance.
|
||||
* @param access_token Your access token.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
explicit Instance(string instance, string access_token);
|
||||
~Instance();
|
||||
explicit Instance(string hostname, string access_token);
|
||||
|
||||
/*!
|
||||
* @brief Returns the hostname.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
inline string_view get_hostname() const
|
||||
{
|
||||
return _hostname;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Returns the base URI.
|
||||
*
|
||||
* The base URI is “https://” + the hostname.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
inline string_view get_baseuri() const
|
||||
{
|
||||
return _baseuri;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Returns the access token.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
inline string_view get_access_token() const
|
||||
{
|
||||
return _access_token;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Returns the maximum number of characters per post.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
inline uint64_t get_max_chars() const
|
||||
{
|
||||
return _max_chars;
|
||||
}
|
||||
|
||||
private:
|
||||
const string _instance;
|
||||
const string _hostname;
|
||||
const string _baseuri;
|
||||
string _access_token;
|
||||
CURL *_connection;
|
||||
char _curl_buffer_error[CURL_ERROR_SIZE];
|
||||
string _curl_buffer;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief libcurl write callback function.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
string *writerData);
|
||||
|
||||
/*!
|
||||
* @brief Setup libcurl connection.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void setup_curl();
|
||||
uint64_t _max_chars;
|
||||
};
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
#define MASTODONPP_HPP
|
||||
|
||||
#include "api.hpp"
|
||||
#include "connection.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "instance.hpp"
|
||||
#include "request.hpp"
|
||||
#include "return_types.hpp"
|
||||
|
||||
/*!
|
||||
|
@ -68,7 +68,7 @@
|
|||
*/
|
||||
|
||||
/*!
|
||||
* @brief C++ wrapper for the Mastodon API.
|
||||
* @brief C++ wrapper for the Mastodon %API.
|
||||
*
|
||||
* All text input is expected to be UTF-8.
|
||||
*
|
||||
|
|
|
@ -36,31 +36,40 @@ using std::string_view;
|
|||
*
|
||||
* @headerfile return_types.hpp mastodonpp/return_types.hpp
|
||||
*
|
||||
* @section error Error codes
|
||||
* | Code | Explanation |
|
||||
* | --------: |:-------------------------------------------------------------|
|
||||
* | 0 | No error. |
|
||||
*/
|
||||
struct answer_type
|
||||
{
|
||||
/*!
|
||||
* @brief @ref error "Error code".
|
||||
* @brief The error code returned by libcurl.
|
||||
*
|
||||
* For more information consult
|
||||
* [libcurl-errors(3)](https://curl.haxx.se/libcurl/c/libcurl-errors.html).
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
uint8_t error_code;
|
||||
uint8_t curl_error_code{0};
|
||||
|
||||
/*!
|
||||
* @brief The error message.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
string error_message;
|
||||
|
||||
/*!
|
||||
* @brief HTTP status code.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
uint16_t http_status;
|
||||
uint16_t http_status{0};
|
||||
|
||||
/*!
|
||||
* @brief The headers of the response from the server.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
string headers;
|
||||
|
||||
/*!
|
||||
* @brief The response from the server, usually JSON.
|
||||
*
|
||||
|
@ -69,7 +78,8 @@ struct answer_type
|
|||
string body;
|
||||
|
||||
/*!
|
||||
* @brief Returns true if #error_code is 0, false otherwise.
|
||||
* @brief Returns true if #curl_error_code is 0 and #http_status is 200,
|
||||
* false otherwise.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
|
|
|
@ -17,21 +17,18 @@
|
|||
#include "api.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::map;
|
||||
using std::string_view;
|
||||
using std::move;
|
||||
|
||||
API::API(endpoint_type &endpoint)
|
||||
: _endpoint{move(endpoint)}
|
||||
API::API(const endpoint_type &endpoint)
|
||||
: _endpoint{endpoint}
|
||||
{}
|
||||
|
||||
string API::to_string() const
|
||||
string_view API::to_string_view() const
|
||||
{
|
||||
static const map<endpoint_type,string_view> endpoint_map
|
||||
{
|
||||
|
|
|
@ -14,20 +14,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "request.hpp"
|
||||
#include "connection.hpp"
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
Request::Request(Instance &instance)
|
||||
Connection::Connection(Instance &instance)
|
||||
: _instance{instance}
|
||||
, _baseuri{instance.get_baseuri()}
|
||||
{}
|
||||
|
||||
answer_type Request::get(API::endpoint_type endpoint) const
|
||||
answer_type Connection::get(const API::endpoint_type &endpoint)
|
||||
{
|
||||
answer_type answer;
|
||||
answer.body = API{endpoint}.to_string();
|
||||
return answer;
|
||||
return make_request(
|
||||
http_method::GET,
|
||||
string(_baseuri).append(API{endpoint}.to_string_view()));
|
||||
}
|
||||
|
||||
answer_type Connection::get(const string_view &endpoint)
|
||||
{
|
||||
return make_request(http_method::GET, string(_baseuri).append(endpoint));
|
||||
}
|
||||
|
||||
} // namespace mastodonpp
|
153
src/curl_wrapper.cpp
Normal file
153
src/curl_wrapper.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* This file is part of mastodonpp.
|
||||
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "curl_wrapper.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::uint8_t;
|
||||
using std::uint16_t;
|
||||
|
||||
CURLWrapper::CURLWrapper()
|
||||
: _curl_buffer_error{}
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_ALL); // NOLINT(hicpp-signed-bitwise)
|
||||
_connection = curl_easy_init();
|
||||
setup_curl();
|
||||
}
|
||||
CURLWrapper::~CURLWrapper() noexcept
|
||||
{
|
||||
curl_easy_cleanup(_connection);
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
answer_type CURLWrapper::make_request(const http_method &method,
|
||||
const string_view &uri)
|
||||
{
|
||||
debuglog << "Making request to: " << uri << '\n';
|
||||
|
||||
CURLcode code;
|
||||
switch (method)
|
||||
{
|
||||
case http_method::GET:
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_HTTPGET, 1L);
|
||||
break;
|
||||
}
|
||||
case http_method::POST:
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_POST, 1L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set HTTP method",
|
||||
_curl_buffer_error};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_URL, uri.data());
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set URI", _curl_buffer_error};
|
||||
}
|
||||
|
||||
answer_type answer;
|
||||
code = curl_easy_perform(_connection);
|
||||
if (code == CURLE_OK)
|
||||
{
|
||||
long http_status; // NOLINT(google-runtime-int)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
curl_easy_getinfo(_connection, CURLINFO_RESPONSE_CODE, &http_status);
|
||||
answer.http_status = static_cast<uint16_t>(http_status);
|
||||
debuglog << "HTTP status code: " << http_status << '\n';
|
||||
|
||||
answer.headers = _curl_buffer_headers;
|
||||
answer.body = _curl_buffer_body;
|
||||
}
|
||||
else
|
||||
{
|
||||
answer.curl_error_code = static_cast<uint8_t>(code);
|
||||
answer.error_message = _curl_buffer_error;
|
||||
debuglog << "libcurl error: " << code << '\n';
|
||||
debuglog << _curl_buffer_error << '\n';
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
int CURLWrapper::writer(char *data, size_t size, size_t nmemb,
|
||||
string *writerData)
|
||||
{
|
||||
if(writerData == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return static_cast<int>(size * nmemb);
|
||||
}
|
||||
|
||||
void CURLWrapper::setup_curl()
|
||||
{
|
||||
if (_connection == nullptr)
|
||||
{
|
||||
throw CURLException{CURLE_FAILED_INIT, "Failed to initialize curl."};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
CURLcode code{curl_easy_setopt(_connection, CURLOPT_ERRORBUFFER,
|
||||
_curl_buffer_error)};
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set error buffer."};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set writer", _curl_buffer_error};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_HEADERDATA,
|
||||
&_curl_buffer_headers);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set header data",
|
||||
_curl_buffer_error};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEDATA, &_curl_buffer_body);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set write data",
|
||||
_curl_buffer_error};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mastodonpp
|
|
@ -42,7 +42,7 @@ const char *CURLException::what() const noexcept
|
|||
+ " - " + _message};
|
||||
if (!_error_buffer.empty())
|
||||
{
|
||||
error_string.append("[" + _error_buffer + "]");
|
||||
error_string.append(" [" + _error_buffer + "]");
|
||||
}
|
||||
return error_string.c_str();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
*/
|
||||
|
||||
#include "instance.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "log.hpp"
|
||||
#include "return_types.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
@ -24,55 +25,38 @@ namespace mastodonpp
|
|||
|
||||
using std::move;
|
||||
|
||||
Instance::Instance(string instance, string access_token)
|
||||
: _instance{move(instance)}
|
||||
Instance::Instance(string hostname, string access_token)
|
||||
: _hostname{move(hostname)}
|
||||
, _baseuri{"https://" + _hostname}
|
||||
, _access_token{move(access_token)}
|
||||
, _connection{curl_easy_init()}
|
||||
, _max_chars{500}
|
||||
{
|
||||
setup_curl();
|
||||
}
|
||||
Instance::~Instance()
|
||||
{
|
||||
curl_easy_cleanup(_connection);
|
||||
}
|
||||
|
||||
int Instance::writer(char *data, size_t size, size_t nmemb, string *writerData)
|
||||
{
|
||||
if(writerData == nullptr)
|
||||
try
|
||||
{
|
||||
return 0;
|
||||
const auto answer{make_request(http_method::GET,
|
||||
_baseuri + "/api/v1/instance")};
|
||||
if (answer)
|
||||
{
|
||||
debuglog << "Querying instance for max_toot_chars…\n";
|
||||
auto &body{answer.body};
|
||||
size_t pos_start{body.find("max_toot_chars")};
|
||||
if (pos_start == string::npos)
|
||||
{
|
||||
debuglog << "max_toot_chars not found.";
|
||||
return;
|
||||
}
|
||||
pos_start = body.find(':', pos_start) + 1;
|
||||
const size_t pos_end{body.find(',', pos_start)};
|
||||
|
||||
const auto max_toot_chars{body.substr(pos_start,
|
||||
pos_end - pos_start)};
|
||||
_max_chars = std::stoull(max_toot_chars);
|
||||
debuglog << "Set _max_chars to: " << _max_chars << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return static_cast<int>(size * nmemb);
|
||||
}
|
||||
|
||||
void Instance::setup_curl()
|
||||
{
|
||||
if (_connection == nullptr)
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
throw CURLException{CURLE_FAILED_INIT, "Failed to initialize curl."};
|
||||
}
|
||||
|
||||
CURLcode code{curl_easy_setopt(_connection, CURLOPT_ERRORBUFFER,
|
||||
_curl_buffer_error)};
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set error buffer."};
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set writer", _curl_buffer_error};
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEDATA, &_curl_buffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set write data",
|
||||
_curl_buffer_error};
|
||||
debuglog << "Unexpected exception: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,22 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mastodonpp.hpp"
|
||||
#ifndef MASTODONPP_LOG_HPP
|
||||
#define MASTODONPP_LOG_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::cerr;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define debuglog cerr << "[" << __func__ << "():" << __LINE__ << "] DEBUG: "
|
||||
#else
|
||||
#define debuglog false && cerr
|
||||
#endif
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
||||
#endif // MASTODONPP_LOG_HPP
|
|
@ -21,7 +21,7 @@ namespace mastodonpp
|
|||
|
||||
answer_type::operator bool() const
|
||||
{
|
||||
return (error_code == 0);
|
||||
return (curl_error_code == 0 && http_status == 200);
|
||||
}
|
||||
|
||||
answer_type::operator string_view() const
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "instance.hpp"
|
||||
#include "request.hpp"
|
||||
#include "connection.hpp"
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
|
@ -48,12 +48,12 @@ SCENARIO ("Instantiations.")
|
|||
}
|
||||
}
|
||||
|
||||
WHEN ("Request is instantiated.")
|
||||
WHEN ("Connection is instantiated.")
|
||||
{
|
||||
try
|
||||
{
|
||||
Instance instance{"example.com", ""};
|
||||
Request request{instance};
|
||||
Connection connection{instance};
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user