implemented PUT and DELETE, fixed argument encoding in POST

This commit is contained in:
tastytea 2018-01-24 18:52:24 +01:00
parent 764a739a13
commit 13a5e23a8b
Signed by: tastytea
GPG Key ID: 59346E0EA35C67E5
8 changed files with 344 additions and 50 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.7)
include(GNUInstallDirs) include(GNUInstallDirs)
project (mastodon-cpp project (mastodon-cpp
VERSION 0.1.5 VERSION 0.1.6
LANGUAGES CXX LANGUAGES CXX
) )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC")

View File

@ -89,8 +89,8 @@ If you use a debug build, you get more verbose error messages.
* [x] Escape user input * [x] Escape user input
* [x] Implement all PATCH calls * [x] Implement all PATCH calls
* [x] Implement all POST calls * [x] Implement all POST calls
* [ ] Implement all PUT calls * [x] Implement all PUT calls
* [ ] Implement all DELETE calls * [x] Implement all DELETE calls
* Version 0.3.0 * Version 0.3.0
* [ ] Handle HTTP statuses 301 & 302 * [ ] Handle HTTP statuses 301 & 302
* [ ] Support registering as an application * [ ] Support registering as an application
@ -119,7 +119,7 @@ If you use a debug build, you get more verbose error messages.
* [x] GET /api/v1/blocks * [x] GET /api/v1/blocks
* [x] GET /api/v1/domain_blocks * [x] GET /api/v1/domain_blocks
* [x] POST /api/v1/domain_blocks * [x] POST /api/v1/domain_blocks
* [ ] DELETE /api/v1/domain_blocks * [x] DELETE /api/v1/domain_blocks
* [x] GET /api/v1/favourites * [x] GET /api/v1/favourites
* [x] GET /api/v1/follow_requests * [x] GET /api/v1/follow_requests
* [x] POST /api/v1/follow_requests/:id/authorize * [x] POST /api/v1/follow_requests/:id/authorize
@ -132,10 +132,10 @@ If you use a debug build, you get more verbose error messages.
* [x] GET /api/v1/lists/:id/accounts * [x] GET /api/v1/lists/:id/accounts
* [x] GET /api/v1/lists/:id * [x] GET /api/v1/lists/:id
* [x] POST /api/v1/lists * [x] POST /api/v1/lists
* [ ] PUT /api/v1/lists/:id * [x] PUT /api/v1/lists/:id
* [ ] DELETE /api/v1/lists/:id * [x] DELETE /api/v1/lists/:id
* [x] POST /api/v1/lists/:id/accounts * [x] POST /api/v1/lists/:id/accounts
* [ ] DELETE /api/v1/lists/:id/accounts * [x] DELETE /api/v1/lists/:id/accounts
* [x] POST /api/v1/media * [x] POST /api/v1/media
* [x] GET /api/v1/mutes * [x] GET /api/v1/mutes
* [x] GET /api/v1/notifications * [x] GET /api/v1/notifications
@ -151,7 +151,7 @@ If you use a debug build, you get more verbose error messages.
* [x] GET /api/v1/statuses/:id/reblogged_by * [x] GET /api/v1/statuses/:id/reblogged_by
* [x] GET /api/v1/statuses/:id/favourited_by * [x] GET /api/v1/statuses/:id/favourited_by
* [x] POST /api/v1/statuses * [x] POST /api/v1/statuses
* [ ] DELETE /api/v1/statuses/:id * [x] DELETE /api/v1/statuses/:id
* [x] POST /api/v1/statuses/:id/reblog * [x] POST /api/v1/statuses/:id/reblog
* [x] POST /api/v1/statuses/:id/unreblog * [x] POST /api/v1/statuses/:id/unreblog
* [x] POST /api/v1/statuses/:id/favourite * [x] POST /api/v1/statuses/:id/favourite

88
src/api_delete.cpp Normal file
View File

@ -0,0 +1,88 @@
/* 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;
const std::uint16_t API::del(const Mastodon::API::v1 &call,
const parametermap &parameters)
{
string strcall = "";
switch (call)
{
case v1::domain_blocks:
strcall = "/api/v1/domain_blocks";
break;
default:
ttdebug << "ERROR: Invalid call.\n";
return 1;
break;
}
string answer;
return _http.request_sync(http::method::DELETE, strcall,
maptoformdata(parameters), answer);
}
const std::uint16_t API::del(const Mastodon::API::v1 &call,
const string &argument)
{
const parametermap p = {};
return del(call, argument, p);
}
const std::uint16_t API::del(const Mastodon::API::v1 &call,
const string &argument,
const parametermap &parameters)
{
string strcall = "";
const string argument_encoded = urlencode(argument);
switch (call)
{
case v1::lists_id:
strcall = "/api/v1/lists/" + argument_encoded;
break;
case v1::lists_id_accounts:
strcall = "/api/v1/lists/" + argument_encoded + "/accounts";
break;
case v1::statuses_id:
strcall = "/api/v1/statuses/" + argument_encoded;
break;
default:
ttdebug << "ERROR: Invalid call.\n";
return 1;
break;
}
string answer;
return _http.request_sync(http::method::DELETE, strcall,
maptoformdata(parameters), answer);
}
const std::uint16_t API::del(const std::string &call,
const parametermap &parameters, string &answer)
{
return _http.request_sync(http::method::DELETE, call,
maptoformdata(parameters), answer);
}

View File

@ -22,7 +22,7 @@
using namespace Mastodon; using namespace Mastodon;
using std::string; using std::string;
using std::cerr;
const std::uint16_t API::post(const Mastodon::API::v1 &call, string &answer) const std::uint16_t API::post(const Mastodon::API::v1 &call, string &answer)
{ {
const parametermap p; const parametermap p;
@ -89,55 +89,55 @@ const std::uint16_t API::post(const Mastodon::API::v1 &call,
switch (call) switch (call)
{ {
case v1::accounts_id_follow: case v1::accounts_id_follow:
strcall = "/api/v1/accounts/" + argument + "/follow"; strcall = "/api/v1/accounts/" + argument_encoded + "/follow";
break; break;
case v1::accounts_id_unfollow: case v1::accounts_id_unfollow:
strcall = "/api/v1/accounts/" + argument + "/unfollow"; strcall = "/api/v1/accounts/" + argument_encoded + "/unfollow";
break; break;
case v1::accounts_id_block: case v1::accounts_id_block:
strcall = "/api/v1/accounts/" + argument + "/block"; strcall = "/api/v1/accounts/" + argument_encoded + "/block";
break; break;
case v1::accounts_id_unblock: case v1::accounts_id_unblock:
strcall = "/api/v1/accounts/" + argument + "/unblock"; strcall = "/api/v1/accounts/" + argument_encoded + "/unblock";
break; break;
case v1::accounts_id_mute: case v1::accounts_id_mute:
strcall = "/api/v1/accounts/" + argument + "/mute"; strcall = "/api/v1/accounts/" + argument_encoded + "/mute";
break; break;
case v1::accounts_id_unmute: case v1::accounts_id_unmute:
strcall = "/api/v1/accounts/" + argument + "/unmute"; strcall = "/api/v1/accounts/" + argument_encoded + "/unmute";
break; break;
case v1::follow_requests_id_authorize: case v1::follow_requests_id_authorize:
strcall = "/api/v1/folow_requests/" + argument + "/authorize"; strcall = "/api/v1/folow_requests/" + argument_encoded + "/authorize";
break; break;
case v1::follow_requests_id_reject: case v1::follow_requests_id_reject:
strcall = "/api/v1/folow_requests/" + argument + "/reject"; strcall = "/api/v1/folow_requests/" + argument_encoded + "/reject";
break; break;
case v1::lists_id_accounts: case v1::lists_id_accounts:
strcall = "/api/v1/lists/" + argument + "/accounts"; strcall = "/api/v1/lists/" + argument_encoded + "/accounts";
break; break;
case v1::statuses_id_reblog: case v1::statuses_id_reblog:
strcall = "/api/v1/statuses/" + argument + "/reblog"; strcall = "/api/v1/statuses/" + argument_encoded + "/reblog";
break; break;
case v1::statuses_id_unreblog: case v1::statuses_id_unreblog:
strcall = "/api/v1/statuses/" + argument + "/unreblog"; strcall = "/api/v1/statuses/" + argument_encoded + "/unreblog";
break; break;
case v1::statuses_id_favourite: case v1::statuses_id_favourite:
strcall = "/api/v1/statuses/" + argument + "/favourite"; strcall = "/api/v1/statuses/" + argument_encoded + "/favourite";
break; break;
case v1::statuses_id_unfavourite: case v1::statuses_id_unfavourite:
strcall = "/api/v1/statuses/" + argument + "/unfavourite"; strcall = "/api/v1/statuses/" + argument_encoded + "/unfavourite";
break; break;
case v1::statuses_id_pin: case v1::statuses_id_pin:
strcall = "/api/v1/statuses/" + argument + "/pin"; strcall = "/api/v1/statuses/" + argument_encoded + "/pin";
break; break;
case v1::statuses_id_unpin: case v1::statuses_id_unpin:
strcall = "/api/v1/statuses/" + argument + "/unpin"; strcall = "/api/v1/statuses/" + argument_encoded + "/unpin";
break; break;
case v1::statuses_id_mute: case v1::statuses_id_mute:
strcall = "/api/v1/statuses/" + argument + "/mute"; strcall = "/api/v1/statuses/" + argument_encoded + "/mute";
break; break;
case v1::statuses_id_unmute: case v1::statuses_id_unmute:
strcall = "/api/v1/statuses/" + argument + "/unmute"; strcall = "/api/v1/statuses/" + argument_encoded + "/unmute";
break; break;
default: default:
ttdebug << "ERROR: Invalid call.\n"; ttdebug << "ERROR: Invalid call.\n";

54
src/api_put.cpp Normal file
View File

@ -0,0 +1,54 @@
/* 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;
const std::uint16_t API::put(const Mastodon::API::v1 &call,
const string &argument,
const parametermap &parameters, string &answer)
{
string strcall = "";
const string argument_encoded = urlencode(argument);
switch (call)
{
case v1::lists_id:
strcall = "/api/v1/lists/" + argument_encoded;
break;
default:
ttdebug << "ERROR: Invalid call.\n";
return 1;
break;
}
return _http.request_sync(http::method::PUT, strcall,
maptoformdata(parameters), answer);
}
const std::uint16_t API::put(const std::string &call,
const parametermap &parameters, string &answer)
{
return _http.request_sync(http::method::PUT, call,
maptoformdata(parameters), answer);
}

View File

@ -0,0 +1,63 @@
/* 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 toot;
std::string id;
std::cout << "Toot: ";
std::cin >> toot;
API::parametermap parameters =
{
{ "status", { toot } },
{ "visibility", { "unlisted" } },
{ "spoiler_text", { "test" } }
};
ret = masto.post(API::v1::statuses, parameters, answer);
if (ret == 0)
{
id = answer.substr(7, answer.find("\"", 7) - 7);
std::cout << "Deleting in 30 seconds...\n";
std::this_thread::sleep_for(std::chrono::seconds(30));
ret = masto.del(API::v1::statuses_id, id);
if (ret == 0)
{
std::cout << "Status " << id << " deleted.\n";
}
else
{
std::cerr << "Error code: " << ret << '\n';
return ret;
}
}
else
{
std::cerr << "Error code: " << ret << '\n';
return ret;
}
return 0;
}

View File

@ -98,15 +98,23 @@ const std::uint16_t API::http::request_sync(const method &meth,
{ {
case http::method::GET: case http::method::GET:
request_stream << "GET"; request_stream << "GET";
ttdebug << "Method is GET\n";
break; break;
case http::method::PATCH: case http::method::PATCH:
request_stream << "PATCH"; request_stream << "PATCH";
ttdebug << "Method is PATCH\n";
break; break;
case http::method::POST: case http::method::POST:
request_stream << "POST"; request_stream << "POST";
ttdebug << "Method is POST\n";
break;
case http::method::PUT:
request_stream << "PUT";
ttdebug << "Method is PUT\n";
break; break;
case http::method::DELETE: case http::method::DELETE:
request_stream << "DELETE"; request_stream << "DELETE";
ttdebug << "Method is DELETE\n";
break; break;
default: default:
ttdebug << "ERROR: Not implemented\n"; ttdebug << "ERROR: Not implemented\n";
@ -129,6 +137,8 @@ const std::uint16_t API::http::request_sync(const method &meth,
request_stream << formdata; request_stream << formdata;
break; break;
case http::method::POST: case http::method::POST:
case http::method::PUT:
case http::method::DELETE:
if (formdata.empty()) if (formdata.empty())
{ {
request_stream << "\r\n"; request_stream << "\r\n";

View File

@ -52,7 +52,7 @@ class API
{ {
public: public:
/*! /*!
* @brief Used for passing optional parameters. * @brief Used for passing (most of the time) optional parameters.
* *
* Example: * Example:
* @code * @code
@ -196,11 +196,10 @@ public:
/*! /*!
* @brief Make a GET request which doesn't require an argument, pass * @brief Make a GET request which doesn't require an argument, pass
* optional parameters. * parameters.
* *
* @param call A call defined in Mastodon::API::v1 * @param call A call defined in Mastodon::API::v1
* @param parameters A Mastodon::API::parametermap containing optional * @param parameters A Mastodon::API::parametermap containing parameters
* parameters
* @param answer The answer from the server. Usually JSON. On error * @param answer The answer from the server. Usually JSON. On error
* an empty string. * an empty string.
* *
@ -211,13 +210,11 @@ public:
std::string &answer); std::string &answer);
/*! /*!
* @brief Make a GET request which requires an argument, pass optional * @brief Make a GET request which requires an argument, pass parameters.
* parameters.
* *
* @param call A call defined in Mastodon::API::v1 * @param call A call defined in Mastodon::API::v1
* @param argument The non-optional argument * @param argument The non-optional argument
* @param parameters A Mastodon::API::parametermap containing optional * @param parameters A Mastodon::API::parametermap containing parameters
* parameters
* @param answer The answer from the server. Usually JSON. On error * @param answer The answer from the server. Usually JSON. On error
* an empty string. * an empty string.
* *
@ -246,8 +243,7 @@ public:
* Binary data must be base64-encoded. * Binary data must be base64-encoded.
* *
* @param call A call defined in Mastodon::API::v1 * @param call A call defined in Mastodon::API::v1
* @param parameters A Mastodon::API::parametermap containing optional * @param parameters A Mastodon::API::parametermap containing parameters
* parameters
* @param answer The answer from the server. Usually JSON. On error * @param answer The answer from the server. Usually JSON. On error
* an empty string. * an empty string.
* *
@ -255,7 +251,7 @@ public:
*/ */
const std::uint16_t patch(const Mastodon::API::v1 &call, const std::uint16_t patch(const Mastodon::API::v1 &call,
const parametermap &parameters, const parametermap &parameters,
std::string &answer); std::string &answer);
/*! /*!
* @brief Make a POST request which doesn't require an argument. * @brief Make a POST request which doesn't require an argument.
@ -266,7 +262,8 @@ public:
* *
* @return @ref error "Error code". * @return @ref error "Error code".
*/ */
const std::uint16_t post(const Mastodon::API::v1 &call, std::string &answer); const std::uint16_t post(const Mastodon::API::v1 &call,
std::string &answer);
/*! /*!
* @brief Make a POST request which requires an argument * @brief Make a POST request which requires an argument
@ -284,13 +281,12 @@ public:
/*! /*!
* @brief Make a POST request which doesn't require an argument, pass * @brief Make a POST request which doesn't require an argument, pass
* optional parameters. * parameters.
* *
* Binary data must be base64-encoded. * Binary data must be base64-encoded.
* *
* @param call A call defined in Mastodon::API::v1 * @param call A call defined in Mastodon::API::v1
* @param parameters A Mastodon::API::parametermap containing optional * @param parameters A Mastodon::API::parametermap containing parameters
* parameters
* @param answer The answer from the server. Usually JSON. On error * @param answer The answer from the server. Usually JSON. On error
* an empty string. * an empty string.
* *
@ -301,24 +297,22 @@ public:
std::string &answer); std::string &answer);
/*! /*!
* @brief Make a POST request which requires an argument, pass optional * @brief Make a POST request which requires an argument, pass parameters.
* parameters.
* *
* Binary data must be base64-encoded. * Binary data must be base64-encoded.
* *
* @param call A call defined in Mastodon::API::v1 * @param call A call defined in Mastodon::API::v1
* @param argument The non-optional argument * @param argument The non-optional argument
* @param parameters A Mastodon::API::parametermap containing optional * @param parameters A Mastodon::API::parametermap containing parameters
* parameters
* @param answer The answer from the server. Usually JSON. On error * @param answer The answer from the server. Usually JSON. On error
* an empty string. * an empty string.
* *
* @return @ref error "Error code". * @return @ref error "Error code".
*/ */
const std::uint16_t post(const Mastodon::API::v1 &call, const std::uint16_t post(const Mastodon::API::v1 &call,
const std::string &argument, const std::string &argument,
const parametermap &parameters, const parametermap &parameters,
std::string &answer); std::string &answer);
/*! /*!
* @brief Make a custom POST request. * @brief Make a custom POST request.
@ -326,8 +320,7 @@ public:
* Binary data must be base64-encoded. * Binary data must be base64-encoded.
* *
* @param call String in the form `/api/v1/example` * @param call String in the form `/api/v1/example`
* @param parameters A Mastodon::API::parametermap containing optional * @param parameters A Mastodon::API::parametermap containing parameters
* parameters
* @param answer The answer from the server. Usually JSON. On error * @param answer The answer from the server. Usually JSON. On error
* an empty string. * an empty string.
* *
@ -337,6 +330,91 @@ public:
const parametermap &parameters, const parametermap &parameters,
std::string &answer); std::string &answer);
/*!
* @brief Make a PUT request which requires an argument, pass parameters.
*
* @param call A call defined in Mastodon::API::v1
* @param argument The non-optional argument
* @param parameters A Mastodon::API::parametermap containing
* parameters
* @param answer The answer from the server. Usually JSON. On error
* an empty string.
*
* @return @ref error "Error code".
*/
const std::uint16_t put(const Mastodon::API::v1 &call,
const std::string &argument,
const parametermap &parameters,
std::string &answer);
/*!
* @brief Make a custom PUT request.
*
* @param call String in the form `/api/v1/example`
* @param parameters A Mastodon::API::parametermap containing
* parameters
* @param answer The answer from the server. Usually JSON. On error
* an empty string.
*
* @return @ref error "Error code".
*/
const std::uint16_t put(const std::string &call,
const parametermap &parameters,
std::string &answer);
/*!
* @brief Make a DELETE request which requires an argument
*
* @param call A call defined in Mastodon::API::v1
* @param argument The non-optional argument
* @param answer The answer from the server. Usually JSON. On error an
* empty string.
*
* @return @ref error "Error code".
*/
const std::uint16_t del(const Mastodon::API::v1 &call,
const std::string &argument);
/*!
* @brief Make a DELETE request which doesn't require an argument, pass
* parameters.
*
* @param call A call defined in Mastodon::API::v1
* @param parameters A Mastodon::API::parametermap containing parameters
*
* @return @ref error "Error code".
*/
const std::uint16_t del(const Mastodon::API::v1 &call,
const parametermap &parameters);
/*!
* @brief Make a DELETE request which requires an argument, pass
* parameters.
*
* @param call A call defined in Mastodon::API::v1
* @param argument The non-optional argument
* @param parameters A Mastodon::API::parametermap containing parameters
*
* @return @ref error "Error code".
*/
const std::uint16_t del(const Mastodon::API::v1 &call,
const std::string &argument,
const parametermap &parameters);
/*!
* @brief Make a custom DELETE request.
*
* @param call String in the form `/api/v1/example`
* @param parameters A Mastodon::API::parametermap containing parameters
* @param answer The answer from the server. Usually JSON. On error
* an empty string.
*
* @return @ref error "Error code".
*/
const std::uint16_t del(const std::string &call,
const parametermap &parameters,
std::string &answer);
private: private:
const std::string _instance; const std::string _instance;
const std::string _access_token; const std::string _access_token;
@ -362,6 +440,7 @@ private:
GET, GET,
PATCH, PATCH,
POST, POST,
PUT,
DELETE DELETE
}; };