Fixed PATCH, implemented all POST requests
This commit is contained in:
parent
ac680f1ef5
commit
83efdf7ce0
|
@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.7)
|
|||
include(GNUInstallDirs)
|
||||
|
||||
project (mastodon-cpp
|
||||
VERSION 0.1.3
|
||||
VERSION 0.1.4
|
||||
LANGUAGES CXX
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC")
|
||||
|
|
59
README.md
59
README.md
|
@ -87,8 +87,8 @@ If you use a debug build, you get more verbose error messages.
|
|||
* [x] Comprehensive example
|
||||
* Version 0.2.0
|
||||
* [x] Escape user input
|
||||
* [ ] Implement all PATCH calls
|
||||
* [ ] Implement all POST calls
|
||||
* [x] Implement all PATCH calls
|
||||
* [x] Implement all POST calls
|
||||
* [ ] Implement all DELETE calls
|
||||
* Version 0.3.0
|
||||
* [ ] Handle HTTP statuses 301 & 302
|
||||
|
@ -96,68 +96,69 @@ If you use a debug build, you get more verbose error messages.
|
|||
* Later
|
||||
* [ ] Asynchronous I/O
|
||||
* [ ] Handle X-RateLimit header
|
||||
* [ ] Find out why the "short read" error occurs with PATCH and POST
|
||||
|
||||
## Status of implementation
|
||||
|
||||
* [x] GET /api/v1/accounts/:id
|
||||
* [x] GET /api/v1/accounts/verify_credentials
|
||||
* [ ] PATCH /api/v1/accounts/update_credentials
|
||||
* [x] PATCH /api/v1/accounts/update_credentials
|
||||
* [x] GET /api/v1/accounts/:id/followers
|
||||
* [x] GET /api/v1/accounts/:id/following
|
||||
* [x] GET /api/v1/accounts/:id/statuses
|
||||
* [ ] POST /api/v1/accounts/:id/follow
|
||||
* [ ] POST /api/v1/accounts/:id/unfollow
|
||||
* [ ] POST /api/v1/accounts/:id/block
|
||||
* [ ] POST /api/v1/accounts/:id/unblock
|
||||
* [ ] POST /api/v1/accounts/:id/mute
|
||||
* [ ] POST /api/v1/accounts/:id/unmute
|
||||
* [x] POST /api/v1/accounts/:id/follow
|
||||
* [x] POST /api/v1/accounts/:id/unfollow
|
||||
* [x] POST /api/v1/accounts/:id/block
|
||||
* [x] POST /api/v1/accounts/:id/unblock
|
||||
* [x] POST /api/v1/accounts/:id/mute
|
||||
* [x] POST /api/v1/accounts/:id/unmute
|
||||
* [x] GET /api/v1/accounts/relationships
|
||||
* [x] GET /api/v1/accounts/search
|
||||
* [ ] POST /api/v1/apps
|
||||
* [x] POST /api/v1/apps
|
||||
* [x] GET /api/v1/blocks
|
||||
* [x] GET /api/v1/domain_blocks
|
||||
* [ ] POST /api/v1/domain_blocks
|
||||
* [x] POST /api/v1/domain_blocks
|
||||
* [ ] DELETE /api/v1/domain_blocks
|
||||
* [x] GET /api/v1/favourites
|
||||
* [x] GET /api/v1/follow_requests
|
||||
* [ ] POST /api/v1/follow_requests/:id/authorize
|
||||
* [ ] POST /api/v1/follow_requests/:id/reject
|
||||
* [ ] POST /api/v1/follows
|
||||
* [x] POST /api/v1/follow_requests/:id/authorize
|
||||
* [x] POST /api/v1/follow_requests/:id/reject
|
||||
* [x] POST /api/v1/follows
|
||||
* [x] GET /api/v1/instance
|
||||
* [x] GET /api/v1/custom_emojis
|
||||
* [x] GET /api/v1/lists
|
||||
* [x] GET /api/v1/accounts/:id/lists
|
||||
* [x] GET /api/v1/lists/:id/accounts
|
||||
* [x] GET /api/v1/lists/:id
|
||||
* [ ] POST /api/v1/lists
|
||||
* [x] POST /api/v1/lists
|
||||
* [ ] PUT /api/v1/lists/:id
|
||||
* [ ] DELETE /api/v1/lists/:id
|
||||
* [ ] POST /api/v1/lists/:id/accounts
|
||||
* [x] POST /api/v1/lists/:id/accounts
|
||||
* [ ] DELETE /api/v1/lists/:id/accounts
|
||||
* [ ] POST /api/v1/media
|
||||
* [x] POST /api/v1/media
|
||||
* [x] GET /api/v1/mutes
|
||||
* [x] GET /api/v1/notifications
|
||||
* [x] GET /api/v1/notifications/:id
|
||||
* [ ] POST /api/v1/notifications/clear
|
||||
* [ ] POST /api/v1/notifications/dismiss
|
||||
* [x] POST /api/v1/notifications/clear
|
||||
* [x] POST /api/v1/notifications/dismiss
|
||||
* [x] GET /api/v1/reports
|
||||
* [ ] POST /api/v1/reports
|
||||
* [x] POST /api/v1/reports
|
||||
* [x] GET /api/v1/search
|
||||
* [x] GET /api/v1/statuses/:id
|
||||
* [x] GET /api/v1/statuses/:id/context
|
||||
* [x] GET /api/v1/statuses/:id/card
|
||||
* [x] GET /api/v1/statuses/:id/reblogged_by
|
||||
* [x] GET /api/v1/statuses/:id/favourited_by
|
||||
* [ ] POST /api/v1/statuses
|
||||
* [x] POST /api/v1/statuses
|
||||
* [ ] DELETE /api/v1/statuses/:id
|
||||
* [ ] POST /api/v1/statuses/:id/reblog
|
||||
* [ ] POST /api/v1/statuses/:id/unreblog
|
||||
* [ ] POST /api/v1/statuses/:id/favourite
|
||||
* [ ] POST /api/v1/statuses/:id/unfavourite
|
||||
* [ ] POST /api/v1/statuses/:id/pin
|
||||
* [ ] POST /api/v1/statuses/:id/unpin
|
||||
* [ ] POST /api/v1/statuses/:id/mute
|
||||
* [ ] POST /api/v1/statuses/:id/unmute
|
||||
* [x] POST /api/v1/statuses/:id/reblog
|
||||
* [x] POST /api/v1/statuses/:id/unreblog
|
||||
* [x] POST /api/v1/statuses/:id/favourite
|
||||
* [x] POST /api/v1/statuses/:id/unfavourite
|
||||
* [x] POST /api/v1/statuses/:id/pin
|
||||
* [x] POST /api/v1/statuses/:id/unpin
|
||||
* [x] POST /api/v1/statuses/:id/mute
|
||||
* [x] POST /api/v1/statuses/:id/unmute
|
||||
* [x] GET /api/v1/timelines/home
|
||||
* [x] GET /api/v1/timelines/public
|
||||
* [x] GET /api/v1/timelines/tag/:hashtag
|
||||
|
|
|
@ -27,8 +27,6 @@ const std::uint16_t API::patch(const Mastodon::API::v1 &call,
|
|||
const parametermap ¶meters,
|
||||
string &answer)
|
||||
{
|
||||
std::cerr << "NOT IMPLEMENTED\n";
|
||||
return 2;
|
||||
string strcall = "";
|
||||
switch (call)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/* This file is part of mastodon-cpp.
|
||||
* Copyright © 2018 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program 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, 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "macros.hpp"
|
||||
#include "mastodon-cpp.hpp"
|
||||
|
||||
using namespace Mastodon;
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
const std::uint16_t API::post(const Mastodon::API::v1 &call, string &answer)
|
||||
{
|
||||
const parametermap p;
|
||||
return post(call, p, answer);
|
||||
}
|
||||
|
||||
const std::uint16_t API::post(const Mastodon::API::v1 &call,
|
||||
const parametermap ¶meters, string &answer)
|
||||
{
|
||||
string strcall = "";
|
||||
|
||||
switch (call)
|
||||
{
|
||||
case v1::accounts_id_follow:
|
||||
strcall = "/api/v1/apps";
|
||||
break;
|
||||
case v1::domain_blocks:
|
||||
strcall = "/api/v1/domain_blocks";
|
||||
break;
|
||||
case v1::follows:
|
||||
strcall = "/api/v1/follows";
|
||||
break;
|
||||
case v1::lists:
|
||||
strcall = "/api/v1/lists";
|
||||
break;
|
||||
case v1::media:
|
||||
strcall = "/api/v1/media";
|
||||
break;
|
||||
case v1::notifications_clear:
|
||||
strcall = "/api/v1/notifications/clear";
|
||||
break;
|
||||
case v1::notifications_dismiss:
|
||||
strcall = "/api/v1/notifications/dismiss";
|
||||
break;
|
||||
case v1::reports:
|
||||
strcall = "/api/v1/reports";
|
||||
break;
|
||||
default:
|
||||
ttdebug << "ERROR: Invalid call.\n";
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return _http.request_sync(http::method::POST, strcall,
|
||||
maptoformdata(parameters), answer);
|
||||
}
|
||||
|
||||
const std::uint16_t API::post(const Mastodon::API::v1 &call,
|
||||
const string &argument, string &answer)
|
||||
{
|
||||
const parametermap p;
|
||||
return post(call, argument, p, answer);
|
||||
}
|
||||
const std::uint16_t API::post(const Mastodon::API::v1 &call,
|
||||
const string &argument,
|
||||
const parametermap ¶meters, string &answer)
|
||||
{
|
||||
string strcall = "";
|
||||
const string argument_encoded = urlencode(argument);
|
||||
|
||||
switch (call)
|
||||
{
|
||||
case v1::accounts_id_follow:
|
||||
strcall = "/api/v1/accounts/" + argument + "/follow";
|
||||
break;
|
||||
case v1::accounts_id_unfollow:
|
||||
strcall = "/api/v1/accounts/" + argument + "/unfollow";
|
||||
break;
|
||||
case v1::accounts_id_block:
|
||||
strcall = "/api/v1/accounts/" + argument + "/block";
|
||||
break;
|
||||
case v1::accounts_id_unblock:
|
||||
strcall = "/api/v1/accounts/" + argument + "/unblock";
|
||||
break;
|
||||
case v1::accounts_id_mute:
|
||||
strcall = "/api/v1/accounts/" + argument + "/mute";
|
||||
break;
|
||||
case v1::accounts_id_unmute:
|
||||
strcall = "/api/v1/accounts/" + argument + "/unmute";
|
||||
break;
|
||||
case v1::follow_requests_id_authorize:
|
||||
strcall = "/api/v1/folow_requests/" + argument + "/authorize";
|
||||
break;
|
||||
case v1::follow_requests_id_reject:
|
||||
strcall = "/api/v1/folow_requests/" + argument + "/reject";
|
||||
break;
|
||||
case v1::lists_id_accounts:
|
||||
strcall = "/api/v1/lists/" + argument + "/accounts";
|
||||
break;
|
||||
case v1::statuses_id:
|
||||
strcall = "/api/v1/statuses/" + argument;
|
||||
break;
|
||||
case v1::statuses_id_reblog:
|
||||
strcall = "/api/v1/statuses/" + argument + "/reblog";
|
||||
break;
|
||||
case v1::statuses_id_unreblog:
|
||||
strcall = "/api/v1/statuses/" + argument + "/unreblog";
|
||||
break;
|
||||
case v1::statuses_id_favourite:
|
||||
strcall = "/api/v1/statuses/" + argument + "/favourite";
|
||||
break;
|
||||
case v1::statuses_id_unfavourite:
|
||||
strcall = "/api/v1/statuses/" + argument + "/unfavourite";
|
||||
break;
|
||||
case v1::statuses_id_pin:
|
||||
strcall = "/api/v1/statuses/" + argument + "/pin";
|
||||
break;
|
||||
case v1::statuses_id_unpin:
|
||||
strcall = "/api/v1/statuses/" + argument + "/unpin";
|
||||
break;
|
||||
case v1::statuses_id_mute:
|
||||
strcall = "/api/v1/statuses/" + argument + "/mute";
|
||||
break;
|
||||
case v1::statuses_id_unmute:
|
||||
strcall = "/api/v1/statuses/" + argument + "/unmute";
|
||||
break;
|
||||
default:
|
||||
ttdebug << "ERROR: Invalid call.\n";
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return _http.request_sync(http::method::POST, strcall,
|
||||
maptoformdata(parameters), answer);
|
||||
}
|
||||
|
||||
const std::uint16_t API::post(const std::string &call,
|
||||
const parametermap ¶meters, string &answer)
|
||||
{
|
||||
|
||||
return _http.request_sync(http::method::POST, call,
|
||||
maptoformdata(parameters), answer);
|
||||
}
|
|
@ -11,9 +11,6 @@ using Mastodon::API;
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::cerr << "Doesn't work yet. :-(\n";
|
||||
return 2;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " <instance> <access token>\n";
|
||||
|
@ -24,11 +21,40 @@ int main(int argc, char *argv[])
|
|||
masto.set_useragent("mastodon-cpp-example/1.3.3.7");
|
||||
std::string answer;
|
||||
std::uint16_t ret;
|
||||
// This is the Gimp icon, 24x24px, GPL-3
|
||||
const std::string avatar =
|
||||
"data:image/png;base64,"
|
||||
"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz"
|
||||
"AAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAMdEVY"
|
||||
"dFRpdGxlAEZvbGRlcuNZL58AAAAUdEVYdEF1dGhvcgBKYWt1YiBTdGVpbmVy5vv3LwAAACF0RVh0"
|
||||
"U291cmNlAGh0dHA6Ly9qaW1tYWMubXVzaWNoYWxsLmN6aWbjXgAAAFJ0RVh0Q29weXJpZ2h0AEND"
|
||||
"IEF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5z"
|
||||
"ZXMvYnktc2EvMy4wL16DWrwAAARFSURBVEiJtZXNbxtFGMafGe+ud9eO7bXbNBsSNx9GSaW2aQgK"
|
||||
"UDiQUmQJiQsHJETFhVNBKuLAhQviT0Aq6g0heqjUS4UQqhYJhCrxoUZKQakIJTFuTGzXjmN7d+31"
|
||||
"endnhwNNiEIKRWpeaTSjmdHzm/cZzbwkn8/jIIMeqDoA4VGIVCqVZ0DxUuAFn2Wz2dXda/tmUC6X"
|
||||
"z21sbGQfRrxarb4Mig8BvEkpHdy7vi+AUvokpfSNUqmk/8fJXyeEvD8xNvpcTFUzlNLI3j37W0Rx"
|
||||
"WKDC/OnTT72gaRoAIJ4YuJ3OaLpl2ZptWtRnjOsjQ1m3a49kUgmp1TJ5FyAPBwCk+bmZ6ZHRUWly"
|
||||
"YjISi8WkWv3erOd78tkzL0paSiPVaoX//NMiGvUaOrZJ/qG8F2AYBs3n8yEApBKpiBKLq6dmTglj"
|
||||
"Y+OQJJEoSjSZyRzG1NQxqKoKXdeJqkRx8+Z36PU6D7Rx5w6i0ehkvdH4qLRR/mpk9LFnj5+YEaem"
|
||||
"j/Hx8Qly7drnxHF6GDoyBMYYlpaWcPHix2i1TRD85QslhP9rBkktee6t8+df5cDg2todDA8PE0VW"
|
||||
"cOnSJVy5cgXvXHgbAOA4Dq5evYobN24gNzkBgIA80KBdAOazCcZYYkjX6fXrX3JVpFAVOTI39wRU"
|
||||
"VUIyNYDVtV+RSKaxcGYBs7OzqNc2sFEqwrYsBCFzGWHhAwEAbl++fHkhlTmk3C3+TkK3jaDfhqYl"
|
||||
"Ydk9tBoVCIIAKSpDllWwkGHxx+9BwdFxfe55QYsxFhqGIQAIt+9zB0AixFwv3Q3anS7cfh89x0Fz"
|
||||
"8x563SZ6bgh1IA3f9yH1qoj5W2i4IhyzBzWlo+/58INADdxgAEAMQN8wDD+fz7MdAGf8iyAIT7S3"
|
||||
"Gq9FBKoFYQjXC8A40Gya8Co1MMZAmYsMNbFwpIn+oQgKbhc9VyYkCFYty4oDyAAwAXQNwwgjuVwO"
|
||||
"ALC8vNyhsnwnoShxRVGyw/qgeiiTJqIoggAIfB+EAJwIECQZHQ/QxD5mkm2kFBHlXkxumu6iZdtV"
|
||||
"AP79FuwACoUC6TtOJx6PFwWBmv2ADRNCU4TSiBAREFNVpFIaUuk0lHgagXIEdTtEyQz5b20Z82df"
|
||||
"ERgRp5LJ5POapvXDMCw6jtPdAeRyORQKBViW1REEsciBdcZ4xbS6TttywqbVxWbTJvWtNq1utru1"
|
||||
"hrleavSKf1j4utzsf2K7XG+1WpOU0izn/HFZlr/Z3Nys7P0qQgBurVYrO45z3XXcHyRJ0kRRHGCM"
|
||||
"xQMeKAAID7jnc26HnucxxqxOp7Nle7/cSiQGLoii9HQYhkc9zxsEECH7VTTDMHYe6P2eAJABSAA4"
|
||||
"gOC+x9uvlwPg09PTR2VZfo9zftyyrA+KxeK3+wL2C8MwKP7+Wvguceyaw8mTJ8cIIe96nvfpysrK"
|
||||
"rYcG/J+oVqvjAOq6rncfScncG7quF7fHB170DxzwJ8uH9gSkOVdYAAAAAElFTkSuQmCC";
|
||||
|
||||
API::parametermap params =
|
||||
{
|
||||
{ "display_name", { "Botty McBotface" } },
|
||||
// { "note", { "Beep Bop." } }
|
||||
{ "note", { "Beep Bop." } },
|
||||
{ "avatar", { avatar } }
|
||||
};
|
||||
|
||||
ret = masto.patch(API::v1::accounts_update_credentials, params, answer);
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/* This file is part of mastodon-cpp.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "../mastodon-cpp.hpp"
|
||||
|
||||
using Mastodon::API;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " <instance> <access token>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Mastodon::API masto(argv[1], argv[2]);
|
||||
masto.set_useragent("mastodon-cpp-example/1.3.3.7");
|
||||
std::string answer;
|
||||
std::uint16_t ret;
|
||||
std::string id;
|
||||
|
||||
std::cout << "Follow [ID or username@domain]: ";
|
||||
std::cin >> id;
|
||||
|
||||
// If no @ is found, it is presumably an ID
|
||||
if (id.find('@') == std::string::npos)
|
||||
{
|
||||
ret = masto.post(API::v1::accounts_id_follow, id, answer);
|
||||
if (ret == 0)
|
||||
{
|
||||
// std::cout << answer << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error code: " << ret << '\n';
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::cout << "Unfollowing in 30 seconds...\n";
|
||||
std::this_thread::sleep_for(std::chrono::seconds(30));
|
||||
ret = masto.post(API::v1::accounts_id_unfollow, id, answer);
|
||||
if (ret == 0)
|
||||
{
|
||||
// std::cout << answer << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error code: " << ret << '\n';
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
API::parametermap params =
|
||||
{
|
||||
{ "uri", { id } }
|
||||
};
|
||||
ret = masto.post(API::v1::follows, params, answer);
|
||||
if (ret == 0)
|
||||
{
|
||||
// std::cout << answer << '\n';
|
||||
id = answer.substr(7, answer.find("\"", 7) - 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error code: " << ret << '\n';
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::cout << "Unfollowing " << id << " in 30 seconds...\n";
|
||||
std::this_thread::sleep_for(std::chrono::seconds(30));
|
||||
ret = masto.post(API::v1::accounts_id_unfollow, id, answer);
|
||||
if (ret == 0)
|
||||
{
|
||||
// std::cout << answer << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error code: " << ret << '\n';
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -187,7 +187,11 @@ const std::uint16_t API::http::request_sync(const method &meth,
|
|||
}
|
||||
if (error != boost::asio::error::eof)
|
||||
{
|
||||
throw boost::system::system_error(error);
|
||||
// TODO: Find out why the "short read" error occurs
|
||||
// with PATCH and POST
|
||||
//throw boost::system::system_error(error);
|
||||
ttdebug << "ERROR: " << error.message() << '\n';
|
||||
ttdebug << "The preceding error is ignored.\n";
|
||||
}
|
||||
answer = oss.str();
|
||||
ttdebug << "Answer from server: " << oss.str() << '\n';
|
||||
|
|
|
@ -117,19 +117,42 @@ const string API::maptoformdata(const parametermap &map)
|
|||
|
||||
header = "Content-type: multipart/form-data, boundary=" + boundary + "\r\n";
|
||||
header += "Content-Length: ";
|
||||
body = "--" + boundary + "\r\n";
|
||||
body = "--" + boundary;
|
||||
|
||||
for (const auto &it : map)
|
||||
{
|
||||
// This is directly after the last boundary
|
||||
body += "\r\n";
|
||||
if (it.second.size() == 1)
|
||||
{
|
||||
body += ("content-disposition: form-data; name=\"" +
|
||||
it.first + "\"\r\n\r\n");
|
||||
body += (it.second.front() + "\r\n--" + boundary + "\r\n");
|
||||
if (it.first == "avatar" ||
|
||||
it.first == "header" ||
|
||||
it.first == "file")
|
||||
{
|
||||
body += "Content-Transfer-Encoding: base64\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "Content-Transfer-Encoding: 8bit\r\n";
|
||||
}
|
||||
body += ("Content-Disposition: form-data; name=\"" +
|
||||
it.first + "\"\r\n\r\n");
|
||||
body += (it.second.front() + "\r\n--" + boundary);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const string &str : it.second)
|
||||
{
|
||||
body += ("Content-Disposition: form-data; name=\"" +
|
||||
it.first + "[]\"\r\n\r\n");
|
||||
body += (str + "\r\n--" + boundary);
|
||||
}
|
||||
}
|
||||
}
|
||||
// The last segment has to have "--" after the boundary
|
||||
body += "--\r\n";
|
||||
|
||||
header += (std::to_string(body.length() - 2) + "\r\n\r\n");
|
||||
header += (std::to_string(body.length()) + "\r\n\r\n");
|
||||
|
||||
ttdebug << "Form data: \n" << header << body;
|
||||
return header + body;
|
||||
|
|
|
@ -28,11 +28,14 @@
|
|||
* @example example1_dump_json.cpp
|
||||
* @example example2_parse_account.cpp
|
||||
* @example example3_mastocron.cpp
|
||||
* @example example4_update_credentials.cpp
|
||||
* @example example5_follow_unfollow.cpp
|
||||
*/
|
||||
namespace Mastodon
|
||||
{
|
||||
/*!
|
||||
* @brief Class for the Mastodon API. All input is expected to be UTF-8.
|
||||
* Binary data must be base64-encoded.
|
||||
* @section error Error codes
|
||||
* | Code | Explanation |
|
||||
* | --------: |:------------------------------|
|
||||
|
@ -197,7 +200,7 @@ public:
|
|||
*
|
||||
* @param call A call defined in Mastodon::API::v1
|
||||
* @param parameters A Mastodon::API::parametermap containing optional
|
||||
* parameters.
|
||||
* parameters
|
||||
* @param answer The answer from the server. Usually JSON. On error
|
||||
* an empty string.
|
||||
*
|
||||
|
@ -214,7 +217,7 @@ public:
|
|||
* @param call A call defined in Mastodon::API::v1
|
||||
* @param argument The non-optional argument
|
||||
* @param parameters A Mastodon::API::parametermap containing optional
|
||||
* parameters.
|
||||
* parameters
|
||||
* @param answer The answer from the server. Usually JSON. On error
|
||||
* an empty string.
|
||||
*
|
||||
|
@ -240,11 +243,11 @@ public:
|
|||
/*!
|
||||
* @brief Make a PATCH request.
|
||||
*
|
||||
* Couldn't make it work yet.
|
||||
* Binary data must be base64-encoded.
|
||||
*
|
||||
* @param call A call defined in Mastodon::API::v1
|
||||
* @param parameters A Mastodon::API::parametermap containing optional
|
||||
* parameters.
|
||||
* parameters
|
||||
* @param answer The answer from the server. Usually JSON. On error
|
||||
* an empty string.
|
||||
*
|
||||
|
@ -283,9 +286,11 @@ public:
|
|||
* @brief Make a POST request which doesn't require an argument, pass
|
||||
* optional parameters.
|
||||
*
|
||||
* Binary data must be base64-encoded.
|
||||
*
|
||||
* @param call A call defined in Mastodon::API::v1
|
||||
* @param parameters A Mastodon::API::parametermap containing optional
|
||||
* parameters.
|
||||
* parameters
|
||||
* @param answer The answer from the server. Usually JSON. On error
|
||||
* an empty string.
|
||||
*
|
||||
|
@ -299,10 +304,12 @@ public:
|
|||
* @brief Make a POST request which requires an argument, pass optional
|
||||
* parameters.
|
||||
*
|
||||
* Binary data must be base64-encoded.
|
||||
*
|
||||
* @param call A call defined in Mastodon::API::v1
|
||||
* @param argument The non-optional argument
|
||||
* @param parameters A Mastodon::API::parametermap containing optional
|
||||
* parameters.
|
||||
* parameters
|
||||
* @param answer The answer from the server. Usually JSON. On error
|
||||
* an empty string.
|
||||
*
|
||||
|
@ -316,14 +323,19 @@ public:
|
|||
/*!
|
||||
* @brief Make a custom POST request.
|
||||
*
|
||||
* @param call String in the form `/api/v1/example`
|
||||
* @param answer The answer from the server. Usually JSON. On error an
|
||||
* empty string.
|
||||
* Binary data must be base64-encoded.
|
||||
*
|
||||
* @param call String in the form `/api/v1/example`
|
||||
* @param parameters A Mastodon::API::parametermap containing optional
|
||||
* parameters
|
||||
* @param answer The answer from the server. Usually JSON. On error
|
||||
* an empty string.
|
||||
*
|
||||
* @return @ref error "Error code".
|
||||
*/
|
||||
const std::uint16_t post(const std::string &call,
|
||||
std::string &answer);
|
||||
const parametermap ¶meters,
|
||||
std::string &answer);
|
||||
|
||||
private:
|
||||
const std::string _instance;
|
||||
|
|
Reference in New Issue