Merge branch 'develop' into main
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
tastytea 2020-01-05 16:18:16 +01:00
commit ab5c4ee290
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
7 changed files with 483 additions and 24 deletions

View File

@ -11,6 +11,7 @@
:uri-catch: https://github.com/catchorg/Catch2 :uri-catch: https://github.com/catchorg/Catch2
:uri-dpkg: https://packages.qa.debian.org/dpkg :uri-dpkg: https://packages.qa.debian.org/dpkg
:uri-rpm-build: http://www.rpm.org :uri-rpm-build: http://www.rpm.org
:uri-curl: https://curl.haxx.se/
*{project}* is a C++ wrapper for the Mastodon API. It replaces *{project}* is a C++ wrapper for the Mastodon API. It replaces
link:{uri-mastodon-cpp}[mastodon-cpp]. link:{uri-mastodon-cpp}[mastodon-cpp].
@ -40,6 +41,7 @@ Have a look at the link:{uri-reference}[reference].
* Tested OS: Linux * Tested OS: Linux
* C++ compiler (tested: link:{uri-gcc}[GCC] 7/8/9) * C++ compiler (tested: link:{uri-gcc}[GCC] 7/8/9)
* link:{uri-cmake}[CMake] (at least: 3.9) * link:{uri-cmake}[CMake] (at least: 3.9)
* link:{uri-curl}[curl] (tested: 7.66 / 7.58)
* Optional * Optional
** Documentation: link:{uri-doxygen}[Doxygen] (tested: 1.8) ** Documentation: link:{uri-doxygen}[Doxygen] (tested: 1.8)
** Tests: link:{uri-catch}[Catch] (tested: 2.5 / 1.2) ** Tests: link:{uri-catch}[Catch] (tested: 2.5 / 1.2)

View File

@ -24,11 +24,14 @@
namespace mastodonpp namespace mastodonpp
{ {
using std::map;
using std::string_view; using std::string_view;
using std::variant; using std::variant;
/*! /*!
* @brief Holds API endpoints. * @brief Holds %API endpoints.
*
* Supported %API endpoints: Mastodon 3.0.1, Pleroma 1.1.7.
* *
* @since 0.1.0 * @since 0.1.0
* *
@ -46,7 +49,154 @@ public:
*/ */
enum class v1 enum class v1
{ {
instance apps,
apps_verify_credentials,
accounts,
accounts_verify_credentials,
accounts_update_credentials,
accounts_id,
accounts_id_statuses,
accounts_id_followers,
accounts_id_following,
accounts_id_lists,
accounts_id_identity_proofs,
accounts_id_follow,
accounts_id_unfollow,
accounts_id_block,
accounts_id_unblock,
accounts_id_mute,
accounts_id_unmute,
accounts_id_pin,
accounts_id_unpin,
accounts_relationships,
accounts_search,
bookmarks,
favourites,
mutes,
blocks,
domain_blocks,
filters,
filters_id,
reports,
follow_requests,
follow_requests_id_authorize,
follow_requests_id_reject,
endorsements,
featured_tags,
featured_tags_id,
featured_tags_suggestions,
preferences,
suggestions,
suggestions_account_id,
statuses,
statuses_id,
statuses_id_context,
statuses_id_reblogged_by,
statuses_id_favourited_by,
statuses_id_favourite,
statuses_id_unfavourite,
statuses_id_reblog,
statuses_id_unreblog,
statuses_id_bookmark,
statuses_id_unbookmark,
statuses_id_mute,
statuses_id_unmute,
statuses_id_pin,
statuses_id_unpin,
media,
media_id,
polls_id,
polls_id_votes,
scheduled_statuses,
scheduled_statuses_id,
timelines_public,
timelines_tag_hashtag,
timelines_home,
timelines_list_list_id,
conversations,
conversations_id,
conversations_id_read,
lists,
lists_id,
lists_id_accounts,
markers,
streaming_health,
streaming_user,
streaming_public,
streaming_public_local,
streaming_hashtag,
streaming_hashtag_local,
streaming_list,
streaming_direct,
notifications,
notifications_id,
notifications_clear,
notifications_id_dismiss,
push_subscription,
instance,
instance_peers,
instance_activity,
trends,
directory,
custom_emojis,
admin_accounts,
admin_accounts_id,
admin_accounts_account_id_action,
admin_accounts_id_approve,
admin_accounts_id_reject,
admin_accounts_id_enable,
admin_accounts_id_unsilence,
admin_accounts_id_unsuspend,
admin_reports,
admin_reports_id,
admin_reports_id_assign_to_self,
admin_reports_id_unassign,
admin_reports_id_resolve,
admin_reports_id_reopen,
pleroma_notifications_read,
pleroma_accounts_id_subscribe,
pleroma_accounts_id_unsubscribe,
pleroma_accounts_id_favourites,
pleroma_accounts_update_avatar,
pleroma_accounts_update_banner,
pleroma_accounts_update_background,
pleroma_accounts_confirmation_resend,
pleroma_mascot,
pleroma_conversations_id_statuses,
pleroma_conversations_id,
}; };
/*! /*!
@ -62,11 +212,87 @@ public:
}; };
/*! /*!
* @brief Type for endpoints. Either API::v1 or API::v2. * @brief An enumeration of all oauth %API endpoints.
*
* The original `/` are substituted with `_`.
* *
* @since 0.1.0 * @since 0.1.0
*/ */
using endpoint_type = variant<v1,v2>; enum class oauth
{
authorize,
token,
revoke
};
/*!
* @brief An enumeration of all other %API endpoints.
*
* These endpoints are directly under `/api/`.
*
* The original `/` are substituted with `_`.
*
* @since 0.1.0
*/
enum class other
{
proofs,
oembed
};
/*!
* @brief An enumeration of all pleroma %API endpoints.
*
* The original `/` are substituted with `_`.
*
* @since 0.1.0
*/
enum class pleroma
{
admin_users,
admin_users_follow,
admin_users_unfollow,
admin_users_nickname,
admin_users_tag,
admin_users_nickname_permission_group,
admin_users_nickname_permission_group_permission_group,
admin_users_nickname_activation_status,
admin_users_nickname_or_id,
admin_users_nickname_or_id_statuses,
admin_relay,
admin_users_invite_token,
admin_users_invites,
admin_users_revoke_invite,
admin_users_email_invite,
admin_users_nickname_password_reset,
admin_reports,
admin_reports_id,
admin_reports_id_respond,
admin_statuses_id,
admin_config_migrate_to_db,
admin_config_migrate_from_db,
admin_config,
emoji,
follow_import,
captcha,
delete_account,
disable_account,
account_register,
pleroma_notification_settings,
pleroma_healthcheck,
pleroma_change_email
};
/*!
* @brief Type for endpoints. Can be API::v1, API::v2, API::oauth,
* API::other or API::pleroma.
*
* @since 0.1.0
*/
using endpoint_type = variant<v1,v2,oauth,other,pleroma>;
/*! /*!
* @brief Constructs an API object. You should never need this. * @brief Constructs an API object. You should never need this.
@ -76,7 +302,7 @@ public:
* *
* @since 0.1.0 * @since 0.1.0
*/ */
explicit API(const endpoint_type &endpoint); explicit API();
/*! /*!
* @brief Convert #endpoint_type to `std::string_view`. * @brief Convert #endpoint_type to `std::string_view`.
@ -84,10 +310,14 @@ public:
* @since 0.1.0 * @since 0.1.0
*/ */
[[nodiscard]] [[nodiscard]]
string_view to_string_view() const; inline string_view endpoint_to_string_view(const endpoint_type &endpoint)
const
{
return _endpoint_map.at(endpoint).data();
}
private: private:
const endpoint_type _endpoint; const map<endpoint_type,string_view> _endpoint_map;
}; };
} // namespace mastodonpp } // namespace mastodonpp

View File

@ -74,6 +74,7 @@ public:
private: private:
Instance &_instance; Instance &_instance;
const string_view _baseuri; const string_view _baseuri;
const API _api;
}; };
} // namespace mastodonpp } // namespace mastodonpp

View File

@ -38,7 +38,10 @@ using std::string_view;
enum class http_method enum class http_method
{ {
GET, GET,
POST POST,
PATCH,
PUT,
DELETE
}; };
/*! /*!

View File

@ -16,25 +16,229 @@
#include "api.hpp" #include "api.hpp"
#include <map>
namespace mastodonpp namespace mastodonpp
{ {
using std::map; API::API()
using std::string_view; : _endpoint_map
{
{v1::apps, "/api/v1/apps"},
{v1::apps_verify_credentials, "/api/v1/apps/verify/credentials"},
API::API(const endpoint_type &endpoint) {v1::accounts, "/api/v1/accounts"},
: _endpoint{endpoint} {v1::accounts_verify_credentials, "/api/v1/accounts/verify/credentials"},
{v1::accounts_update_credentials, "/api/v1/accounts/update/credentials"},
{v1::accounts_id, "/api/v1/accounts/id"},
{v1::accounts_id_statuses, "/api/v1/accounts/<ID>/statuses"},
{v1::accounts_id_followers, "/api/v1/accounts/<ID>/followers"},
{v1::accounts_id_following, "/api/v1/accounts/<ID>/following"},
{v1::accounts_id_lists, "/api/v1/accounts/<ID>/lists"},
{v1::accounts_id_identity_proofs, "/api/v1/accounts/<ID>/identity/proofs"},
{v1::accounts_id_follow, "/api/v1/accounts/<ID>/follow"},
{v1::accounts_id_unfollow, "/api/v1/accounts/<ID>/unfollow"},
{v1::accounts_id_block, "/api/v1/accounts/<ID>/block"},
{v1::accounts_id_unblock, "/api/v1/accounts/<ID>/unblock"},
{v1::accounts_id_mute, "/api/v1/accounts/<ID>/mute"},
{v1::accounts_id_unmute, "/api/v1/accounts/<ID>/unmute"},
{v1::accounts_id_pin, "/api/v1/accounts/<ID>/pin"},
{v1::accounts_id_unpin, "/api/v1/accounts/<ID>/unpin"},
{v1::accounts_relationships, "/api/v1/accounts/relationships"},
{v1::accounts_search, "/api/v1/accounts/search"},
{v1::bookmarks, "/api/v1/bookmarks"},
{v1::favourites, "/api/v1/favourites"},
{v1::mutes, "/api/v1/mutes"},
{v1::blocks, "/api/v1/blocks"},
{v1::domain_blocks, "/api/v1/domain/blocks"},
{v1::filters, "/api/v1/filters"},
{v1::filters_id, "/api/v1/filters/id"},
{v1::reports, "/api/v1/reports"},
{v1::follow_requests, "/api/v1/follow/requests"},
{v1::follow_requests_id_authorize,
"/api/v1/follow/requests/<ID>/authorize"},
{v1::follow_requests_id_reject, "/api/v1/follow/requests/<ID>/reject"},
{v1::endorsements, "/api/v1/endorsements"},
{v1::featured_tags, "/api/v1/featured/tags"},
{v1::featured_tags_id, "/api/v1/featured/tags/id"},
{v1::featured_tags_suggestions, "/api/v1/featured/tags/suggestions"},
{v1::preferences, "/api/v1/preferences"},
{v1::suggestions, "/api/v1/suggestions"},
{v1::suggestions_account_id, "/api/v1/suggestions/account/id"},
{v1::statuses, "/api/v1/statuses"},
{v1::statuses_id, "/api/v1/statuses/id"},
{v1::statuses_id_context, "/api/v1/statuses/<ID>/context"},
{v1::statuses_id_reblogged_by, "/api/v1/statuses/<ID>/reblogged/by"},
{v1::statuses_id_favourited_by, "/api/v1/statuses/<ID>/favourited/by"},
{v1::statuses_id_favourite, "/api/v1/statuses/<ID>/favourite"},
{v1::statuses_id_unfavourite, "/api/v1/statuses/<ID>/unfavourite"},
{v1::statuses_id_reblog, "/api/v1/statuses/<ID>/reblog"},
{v1::statuses_id_unreblog, "/api/v1/statuses/<ID>/unreblog"},
{v1::statuses_id_bookmark, "/api/v1/statuses/<ID>/bookmark"},
{v1::statuses_id_unbookmark, "/api/v1/statuses/<ID>/unbookmark"},
{v1::statuses_id_mute, "/api/v1/statuses/<ID>/mute"},
{v1::statuses_id_unmute, "/api/v1/statuses/<ID>/unmute"},
{v1::statuses_id_pin, "/api/v1/statuses/<ID>/pin"},
{v1::statuses_id_unpin, "/api/v1/statuses/<ID>/unpin"},
{v1::media, "/api/v1/media"},
{v1::media_id, "/api/v1/media/id"},
{v1::polls_id, "/api/v1/polls/id"},
{v1::polls_id_votes, "/api/v1/polls/<ID>/votes"},
{v1::scheduled_statuses, "/api/v1/scheduled/statuses"},
{v1::scheduled_statuses_id, "/api/v1/scheduled/statuses/id"},
{v1::timelines_public, "/api/v1/timelines/public"},
{v1::timelines_tag_hashtag, "/api/v1/timelines/tag/<HASHTAG>"},
{v1::timelines_home, "/api/v1/timelines/home"},
{v1::timelines_list_list_id, "/api/v1/timelines/list/list/id"},
{v1::conversations, "/api/v1/conversations"},
{v1::conversations_id, "/api/v1/conversations/id"},
{v1::conversations_id_read, "/api/v1/conversations/<ID>/read"},
{v1::lists, "/api/v1/lists"},
{v1::lists_id, "/api/v1/lists/id"},
{v1::lists_id_accounts, "/api/v1/lists/<ID>/accounts"},
{v1::markers, "/api/v1/markers"},
{v1::streaming_health, "/api/v1/streaming/health"},
{v1::streaming_user, "/api/v1/streaming/user"},
{v1::streaming_public, "/api/v1/streaming/public"},
{v1::streaming_public_local, "/api/v1/streaming/public/local"},
{v1::streaming_hashtag, "/api/v1/streaming/hashtag"},
{v1::streaming_hashtag_local, "/api/v1/streaming/hashtag/local"},
{v1::streaming_list, "/api/v1/streaming/list"},
{v1::streaming_direct, "/api/v1/streaming/direct"},
{v1::notifications, "/api/v1/notifications"},
{v1::notifications_id, "/api/v1/notifications/id"},
{v1::notifications_clear, "/api/v1/notifications/clear"},
{v1::notifications_id_dismiss, "/api/v1/notifications/<ID>/dismiss"},
{v1::push_subscription, "/api/v1/push/subscription"},
{v1::instance, "/api/v1/instance"},
{v1::instance_peers, "/api/v1/instance/peers"},
{v1::instance_activity, "/api/v1/instance/activity"},
{v1::trends, "/api/v1/trends"},
{v1::directory, "/api/v1/directory"},
{v1::custom_emojis, "/api/v1/custom/emojis"},
{v1::admin_accounts, "/api/v1/admin/accounts"},
{v1::admin_accounts_id, "/api/v1/admin/accounts/id"},
{v1::admin_accounts_account_id_action,
"/api/v1/admin/accounts/account/<ID>/action"},
{v1::admin_accounts_id_approve, "/api/v1/admin/accounts/<ID>/approve"},
{v1::admin_accounts_id_reject, "/api/v1/admin/accounts/<ID>/reject"},
{v1::admin_accounts_id_enable, "/api/v1/admin/accounts/<ID>/enable"},
{v1::admin_accounts_id_unsilence, "/api/v1/admin/accounts/<ID>/unsilence"},
{v1::admin_accounts_id_unsuspend, "/api/v1/admin/accounts/<ID>/unsuspend"},
{v1::admin_reports, "/api/v1/admin/reports"},
{v1::admin_reports_id, "/api/v1/admin/reports/id"},
{v1::admin_reports_id_assign_to_self,
"/api/v1/admin/reports/<ID>/assign/to/self"},
{v1::admin_reports_id_unassign, "/api/v1/admin/reports/<ID>/unassign"},
{v1::admin_reports_id_resolve, "/api/v1/admin/reports/resolve"},
{v1::admin_reports_id_reopen, "/api/v1/admin/reports/<ID>/reopen"},
{v1::pleroma_notifications_read, " /api/v1/pleroma/notifications/read"},
{v1::pleroma_accounts_id_subscribe,
"/api/v1/pleroma/accounts/<ID>/subscribe"},
{v1::pleroma_accounts_id_unsubscribe,
"/api/v1/pleroma/accounts/<ID>/unsubscribe"},
{v1::pleroma_accounts_id_favourites,
"/api/v1/pleroma/accounts/:id/favourites"},
{v1::pleroma_accounts_update_avatar,
"/api/v1/pleroma/accounts/update_avatar"},
{v1::pleroma_accounts_update_banner,
"/api/v1/pleroma/accounts/update_banner"},
{v1::pleroma_accounts_update_background,
"/api/v1/pleroma/accounts/update_background"},
{v1::pleroma_accounts_confirmation_resend,
"/api/v1/pleroma/accounts/confirmation_resend"},
{v1::pleroma_mascot, "/api/v1/pleroma/mascot"},
{v1::pleroma_conversations_id_statuses,
"/api/v1/pleroma/conversations/<ID>/statuses"},
{v1::pleroma_conversations_id, "/api/v1/pleroma/conversations/<ID>"},
{v2::search, "/api/v2/search"},
{oauth::authorize, "/oauth/authorize"},
{oauth::token, "/oauth/token"},
{oauth::revoke, "/oauth/revoke"},
{other::proofs, "/api/proofs"},
{other::oembed, "/api/oembed"},
{pleroma::admin_users, "/api/pleroma/admin/users"},
{pleroma::admin_users_follow, "/api/pleroma/admin/users/follow"},
{pleroma::admin_users_unfollow, "/api/pleroma/admin/users/unfollow"},
{pleroma::admin_users_nickname, "/api/pleroma/admin/users/<NICKNAME>"},
{pleroma::admin_users_tag, "/api/pleroma/admin/users/tag"},
{pleroma::admin_users_nickname_permission_group,
"/api/pleroma/admin/users/<NICKNAME>/permission_group"},
{pleroma::admin_users_nickname_permission_group_permission_group,
"/api/pleroma/admin/users/<NICKNAME>/permission_group/<PERMISSION_GROUP>"},
{pleroma::admin_users_nickname_activation_status,
"/api/pleroma/admin/users/<NICKNAME>/activation_status"},
{pleroma::admin_users_nickname_or_id,
"/api/pleroma/admin/users/<NICKNAME_OR_ID>"},
{pleroma::admin_users_nickname_or_id_statuses,
"/api/pleroma/admin/users/<NICKNAME_OR_ID>/statuses"},
{pleroma::admin_relay, "/api/pleroma/admin/relay"},
{pleroma::admin_users_invite_token,
"/api/pleroma/admin/users/invite_token"},
{pleroma::admin_users_invites, "/api/pleroma/admin/users/invites"},
{pleroma::admin_users_revoke_invite,
"/api/pleroma/admin/users/revoke_invite"},
{pleroma::admin_users_email_invite,
"/api/pleroma/admin/users/email_invite"},
{pleroma::admin_users_nickname_password_reset,
"/api/pleroma/admin/users/<NICKNAME>/password_reset"},
{pleroma::admin_reports, "/api/pleroma/admin/reports"},
{pleroma::admin_reports_id, "/api/pleroma/admin/reports/<ID>"},
{pleroma::admin_reports_id_respond,
"/api/pleroma/admin/reports/<ID>/respond"},
{pleroma::admin_statuses_id, "/api/pleroma/admin/statuses/<ID>"},
{pleroma::admin_config_migrate_to_db,
"/api/pleroma/admin/config/migrate_to_db"},
{pleroma::admin_config_migrate_from_db,
"/api/pleroma/admin/config/migrate_from_db"},
{pleroma::admin_config, "/api/pleroma/admin/config"},
{pleroma::emoji, "/api/pleroma/emoji"},
{pleroma::follow_import, "/api/pleroma/follow_import"},
{pleroma::captcha, "/api/pleroma/captcha,"},
{pleroma::delete_account, "/api/pleroma/delete_account"},
{pleroma::disable_account, "/api/pleroma/disable_account"},
{pleroma::account_register, "/api/pleroma/account/register"},
{pleroma::pleroma_notification_settings,
"/api/pleroma/pleroma/notification_settings"},
{pleroma::pleroma_healthcheck, "/api/pleroma/pleroma/healthcheck"},
{pleroma::pleroma_change_email, "/api/pleroma/pleroma/change_email"},
}
{} {}
string_view API::to_string_view() const
{
static const map<endpoint_type,string_view> endpoint_map
{
{v1::instance, "/api/v1/instance"},
{v2::search, "/api/v2/search"}
};
return endpoint_map.at(_endpoint).data();
}
} // namespace mastodonpp } // namespace mastodonpp

View File

@ -22,13 +22,14 @@ namespace mastodonpp
Connection::Connection(Instance &instance) Connection::Connection(Instance &instance)
: _instance{instance} : _instance{instance}
, _baseuri{instance.get_baseuri()} , _baseuri{instance.get_baseuri()}
, _api{}
{} {}
answer_type Connection::get(const API::endpoint_type &endpoint) answer_type Connection::get(const API::endpoint_type &endpoint)
{ {
return make_request( return make_request(
http_method::GET, http_method::GET,
string(_baseuri).append(API{endpoint}.to_string_view())); string(_baseuri).append(_api.endpoint_to_string_view(endpoint)));
} }
answer_type Connection::get(const string_view &endpoint) answer_type Connection::get(const string_view &endpoint)

View File

@ -59,6 +59,24 @@ answer_type CURLWrapper::make_request(const http_method &method,
code = curl_easy_setopt(_connection, CURLOPT_POST, 1L); code = curl_easy_setopt(_connection, CURLOPT_POST, 1L);
break; break;
} }
case http_method::PATCH:
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "PATCH");
break;
}
case http_method::PUT:
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
code = curl_easy_setopt(_connection, CURLOPT_UPLOAD, 1L);
break;
}
case http_method::DELETE:
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "DELETE");
break;
}
} }
if (code != CURLE_OK) if (code != CURLE_OK)
{ {