Merge branch 'develop' into main
This commit is contained in:
commit
23eb3ff43e
@ -53,12 +53,12 @@ Have a look at the link:{uri-reference}[reference].
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
mastodonpp::Instance instance{"example.com", {}};
|
mastodonpp::Instance instance{"example.com", "123AccessToken123"};
|
||||||
mastodonpp::Connection connection{instance};
|
mastodonpp::Connection connection{instance};
|
||||||
|
|
||||||
const mastodonpp::parametermap parameters
|
const mastodonpp::parametermap parameters
|
||||||
{
|
{
|
||||||
{"status", "How is the wheather?"},
|
{"status", "How is the weather?"},
|
||||||
{"poll[options]", vector<string_view>{"Nice", "not nice"}},
|
{"poll[options]", vector<string_view>{"Nice", "not nice"}},
|
||||||
{"poll[expires_in]", "86400"}
|
{"poll[expires_in]", "86400"}
|
||||||
};
|
};
|
||||||
@ -88,7 +88,7 @@ emerge -a dev-cpp/mastodonpp
|
|||||||
=== Debian and Ubuntu
|
=== Debian and Ubuntu
|
||||||
|
|
||||||
We automatically generate packages for Debian buster (10) and Ubuntu bionic
|
We automatically generate packages for Debian buster (10) and Ubuntu bionic
|
||||||
(18.04), but only for x86_64 (amd64). Download the them at
|
(18.04), but only for x86_64 (amd64). Download them at
|
||||||
link:{uri-base}/releases[schlomp.space].
|
link:{uri-base}/releases[schlomp.space].
|
||||||
|
|
||||||
[source,shell]
|
[source,shell]
|
||||||
@ -99,7 +99,7 @@ apt install ./libmastodonpp*.deb
|
|||||||
=== CentOS
|
=== CentOS
|
||||||
|
|
||||||
We automatically generate packages for CentOS 8, but only for x86_64
|
We automatically generate packages for CentOS 8, but only for x86_64
|
||||||
(amd64). Download the them at link:{uri-base}/releases[schlomp.space].
|
(amd64). Download them at link:{uri-base}/releases[schlomp.space].
|
||||||
|
|
||||||
[source,shell]
|
[source,shell]
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -33,7 +33,7 @@ using std::vector;
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const vector<string_view> args(argv, argv + argc);
|
const vector<string_view> args(argv, argv + argc);
|
||||||
if (args.size() <= 1)
|
if (args.size() <= 2)
|
||||||
{
|
{
|
||||||
cerr << "Usage: " << args[0] << " <instance hostname> <access token>\n";
|
cerr << "Usage: " << args[0] << " <instance hostname> <access token>\n";
|
||||||
return 1;
|
return 1;
|
||||||
@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
|||||||
constexpr auto poll_seconds{60 * 60 * 24 * 2}; // 2 days.
|
constexpr auto poll_seconds{60 * 60 * 24 * 2}; // 2 days.
|
||||||
const masto::parametermap parameters
|
const masto::parametermap parameters
|
||||||
{
|
{
|
||||||
{"status", "How is the wheather?"},
|
{"status", "How is the weather?"},
|
||||||
{"poll[options]", vector<string_view>{"Nice", "not nice"}},
|
{"poll[options]", vector<string_view>{"Nice", "not nice"}},
|
||||||
{"poll[expires_in]", to_string(poll_seconds)}
|
{"poll[expires_in]", to_string(poll_seconds)}
|
||||||
};
|
};
|
||||||
|
100
examples/example04_post_with_attachment.cpp
Normal file
100
examples/example04_post_with_attachment.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* This file is part of mastodonpp.
|
||||||
|
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Post a status (/api/v1/status) with an attachment (/api/v1/media).
|
||||||
|
|
||||||
|
#include "mastodonpp.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace masto = mastodonpp;
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::string;
|
||||||
|
using std::to_string;
|
||||||
|
using std::string_view;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const vector<string_view> args(argv, argv + argc);
|
||||||
|
if (args.size() <= 3)
|
||||||
|
{
|
||||||
|
cerr << "Usage: " << args[0]
|
||||||
|
<< " <instance hostname> <access token> <file>\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Initialize an Instance and a Connection.
|
||||||
|
masto::Instance instance{args[1], args[2]};
|
||||||
|
masto::Connection connection{instance};
|
||||||
|
const string_view filename{args[3]};
|
||||||
|
|
||||||
|
// Create attachment.
|
||||||
|
auto answer{connection.post(masto::API::v1::media,
|
||||||
|
{
|
||||||
|
{"file", string("@file:") += filename},
|
||||||
|
{"description", "Test."}
|
||||||
|
})};
|
||||||
|
|
||||||
|
// Get the ID of the attachment.
|
||||||
|
// You normally would use a JSON parser, of course. I don't use one
|
||||||
|
// because I don't want to add a dependency just for an example.
|
||||||
|
const auto pos{answer.body.find(R"("id":")") + 6};
|
||||||
|
const auto endpos{answer.body.find(R"(",)", pos)};
|
||||||
|
const auto media_id{answer.body.substr(pos, endpos - pos)};
|
||||||
|
cout << "Attachment has ID: " << media_id << endl;
|
||||||
|
|
||||||
|
// Post the status. Note that “media_ids” always has to be a vector.
|
||||||
|
answer = connection.post(masto::API::v1::statuses,
|
||||||
|
{
|
||||||
|
{"status", "Attachment test."},
|
||||||
|
{"media_ids",
|
||||||
|
vector<string_view>{media_id}}
|
||||||
|
});
|
||||||
|
if (answer)
|
||||||
|
{
|
||||||
|
cout << "Successfully posted " << filename << ".\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (answer.curl_error_code == 0)
|
||||||
|
{
|
||||||
|
// If it is no libcurl error, it must be an HTTP error.
|
||||||
|
cerr << "HTTP status: " << answer.http_status << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Network errors like “Couldn't resolve host.”.
|
||||||
|
cerr << "libcurl error " << to_string(answer.curl_error_code)
|
||||||
|
<< ": " << answer.error_message << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const masto::CURLException &e)
|
||||||
|
{
|
||||||
|
// Only libcurl errors that are not network errors will be thrown.
|
||||||
|
// There went probably something wrong with the initialization.
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
84
examples/example05_update_notification_settings.cpp
Normal file
84
examples/example05_update_notification_settings.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* This file is part of mastodonpp.
|
||||||
|
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Update notification settings (/api/pleroma/notification_settings).
|
||||||
|
|
||||||
|
#include "mastodonpp.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace masto = mastodonpp;
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::to_string;
|
||||||
|
using std::string_view;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const vector<string_view> args(argv, argv + argc);
|
||||||
|
if (args.size() <= 2)
|
||||||
|
{
|
||||||
|
cerr << "Usage: " << args[0] << " <instance hostname> <access token>\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Initialize an Instance and a Connection.
|
||||||
|
masto::Instance instance{args[1], args[2]};
|
||||||
|
masto::Connection connection{instance};
|
||||||
|
|
||||||
|
// Update the settings.
|
||||||
|
const auto answer{connection.put(
|
||||||
|
masto::API::pleroma::notification_settings,
|
||||||
|
{
|
||||||
|
{"followers", "true"},
|
||||||
|
{"follows", "true"},
|
||||||
|
{"remote", "true"},
|
||||||
|
{"local", "true"},
|
||||||
|
})};
|
||||||
|
if (answer)
|
||||||
|
{
|
||||||
|
cout << answer << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (answer.curl_error_code == 0)
|
||||||
|
{
|
||||||
|
// If it is no libcurl error, it must be an HTTP error.
|
||||||
|
cerr << "HTTP status: " << answer.http_status << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Network errors like “Couldn't resolve host.”.
|
||||||
|
cerr << "libcurl error " << to_string(answer.curl_error_code)
|
||||||
|
<< ": " << answer.error_message << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const masto::CURLException &e)
|
||||||
|
{
|
||||||
|
// Only libcurl errors that are not network errors will be thrown.
|
||||||
|
// There went probably something wrong with the initialization.
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
83
examples/example06_update_name.cpp
Normal file
83
examples/example06_update_name.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* This file is part of mastodonpp.
|
||||||
|
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Update account display name settings (/api/v1/accounts/update_credentials).
|
||||||
|
|
||||||
|
#include "mastodonpp.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace masto = mastodonpp;
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::to_string;
|
||||||
|
using std::string_view;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const vector<string_view> args(argv, argv + argc);
|
||||||
|
if (args.size() <= 3)
|
||||||
|
{
|
||||||
|
cerr << "Usage: " << args[0]
|
||||||
|
<< " <instance hostname> <access token> <name>\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const auto name{args[3]};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Initialize an Instance and a Connection.
|
||||||
|
masto::Instance instance{args[1], args[2]};
|
||||||
|
masto::Connection connection{instance};
|
||||||
|
|
||||||
|
// Update the settings.
|
||||||
|
const auto answer{connection.patch(
|
||||||
|
masto::API::v1::accounts_update_credentials,
|
||||||
|
{
|
||||||
|
{"display_name", name},
|
||||||
|
})};
|
||||||
|
if (answer)
|
||||||
|
{
|
||||||
|
cout << "Successfully changed display name.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (answer.curl_error_code == 0)
|
||||||
|
{
|
||||||
|
// If it is no libcurl error, it must be an HTTP error.
|
||||||
|
cerr << "HTTP status: " << answer.http_status << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Network errors like “Couldn't resolve host.”.
|
||||||
|
cerr << "libcurl error " << to_string(answer.curl_error_code)
|
||||||
|
<< ": " << answer.error_message << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const masto::CURLException &e)
|
||||||
|
{
|
||||||
|
// Only libcurl errors that are not network errors will be thrown.
|
||||||
|
// There went probably something wrong with the initialization.
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
98
examples/example07_delete_status.cpp
Normal file
98
examples/example07_delete_status.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* This file is part of mastodonpp.
|
||||||
|
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Post a status (/api/v1/status), then delete it (/api/v1/statuses/:id).
|
||||||
|
|
||||||
|
#include "mastodonpp.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace masto = mastodonpp;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::to_string;
|
||||||
|
using std::string_view;
|
||||||
|
using std::this_thread::sleep_for;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const vector<string_view> args(argv, argv + argc);
|
||||||
|
if (args.size() <= 2)
|
||||||
|
{
|
||||||
|
cerr << "Usage: " << args[0] << " <instance hostname> <access token>\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Initialize an Instance and a Connection.
|
||||||
|
masto::Instance instance{args[1], args[2]};
|
||||||
|
masto::Connection connection{instance};
|
||||||
|
|
||||||
|
// Post a status.
|
||||||
|
auto answer{connection.post(masto::API::v1::statuses,
|
||||||
|
{{"status", "Delete me."}})};
|
||||||
|
if (answer)
|
||||||
|
{
|
||||||
|
cout << "Successfully posted a status.\n";
|
||||||
|
|
||||||
|
// Get the ID of the post.
|
||||||
|
// You normally would use a JSON parser, of course. I don't use one
|
||||||
|
// because I don't want to add a dependency just for an example.
|
||||||
|
const auto pos{answer.body.rfind(R"("id":")") + 6};
|
||||||
|
const auto endpos{answer.body.find(R"(",)", pos)};
|
||||||
|
const auto id{answer.body.substr(pos, endpos - pos)};
|
||||||
|
cout << "Post has ID: " << id << endl;
|
||||||
|
cout << "Waiting 10 seconds…\n";
|
||||||
|
sleep_for(10s);
|
||||||
|
|
||||||
|
answer = connection.del(masto::API::v1::statuses_id, {{"id", id}});
|
||||||
|
if (answer)
|
||||||
|
{
|
||||||
|
cout << "Successfully deleted the status.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (answer.curl_error_code == 0)
|
||||||
|
{
|
||||||
|
// If it is no libcurl error, it must be an HTTP error.
|
||||||
|
cerr << "HTTP status: " << answer.http_status << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Network errors like “Couldn't resolve host.”.
|
||||||
|
cerr << "libcurl error " << to_string(answer.curl_error_code)
|
||||||
|
<< ": " << answer.error_message << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const masto::CURLException &e)
|
||||||
|
{
|
||||||
|
// Only libcurl errors that are not network errors will be thrown.
|
||||||
|
// There went probably something wrong with the initialization.
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -281,9 +281,9 @@ public:
|
|||||||
disable_account,
|
disable_account,
|
||||||
account_register,
|
account_register,
|
||||||
|
|
||||||
pleroma_notification_settings,
|
notification_settings,
|
||||||
pleroma_healthcheck,
|
healthcheck,
|
||||||
pleroma_change_email
|
change_email
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -161,6 +161,84 @@ public:
|
|||||||
return post(endpoint, {});
|
return post(endpoint, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Make a HTTP PATCH call with parameters.
|
||||||
|
*
|
||||||
|
* @param endpoint Endpoint as API::endpoint_type or `std::string_view`.
|
||||||
|
* @param parameters A map of parameters.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
answer_type patch(const endpoint_variant &endpoint,
|
||||||
|
const parametermap ¶meters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Make a HTTP PATCH call.
|
||||||
|
*
|
||||||
|
* @param endpoint Endpoint as API::endpoint_type or `std::string_view`.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
inline answer_type patch(const endpoint_variant &endpoint)
|
||||||
|
{
|
||||||
|
return patch(endpoint, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Make a HTTP PUT call with parameters.
|
||||||
|
*
|
||||||
|
* @param endpoint Endpoint as API::endpoint_type or `std::string_view`.
|
||||||
|
* @param parameters A map of parameters.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
answer_type put(const endpoint_variant &endpoint,
|
||||||
|
const parametermap ¶meters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Make a HTTP PUT call.
|
||||||
|
*
|
||||||
|
* @param endpoint Endpoint as API::endpoint_type or `std::string_view`.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
inline answer_type put(const endpoint_variant &endpoint)
|
||||||
|
{
|
||||||
|
return put(endpoint, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Make a HTTP DELETE call with parameters.
|
||||||
|
*
|
||||||
|
* @param endpoint Endpoint as API::endpoint_type or `std::string_view`.
|
||||||
|
* @param parameters A map of parameters.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
answer_type del(const endpoint_variant &endpoint,
|
||||||
|
const parametermap ¶meters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Make a HTTP DELETE call.
|
||||||
|
*
|
||||||
|
* @param endpoint Endpoint as API::endpoint_type or `std::string_view`.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
inline answer_type del(const endpoint_variant &endpoint)
|
||||||
|
{
|
||||||
|
return del(endpoint, {});
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Copy new stream contents and delete the “original”.
|
* @brief Copy new stream contents and delete the “original”.
|
||||||
*
|
*
|
||||||
|
@ -57,12 +57,17 @@ enum class http_method
|
|||||||
/*!
|
/*!
|
||||||
* @brief `std::map` of parameters for %API calls.
|
* @brief `std::map` of parameters for %API calls.
|
||||||
*
|
*
|
||||||
|
* Note that arrays always have to be specified as vectors, even if they have
|
||||||
|
* only 1 element. To send a file, use “<tt>\@file:</tt>” followed by the file
|
||||||
|
* name as value.
|
||||||
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* @code
|
* @code
|
||||||
* parametermap parameters
|
* parametermap parameters
|
||||||
* {
|
* {
|
||||||
* {"id", "12"},
|
* {"poll[expires_in]", "86400"},
|
||||||
* {"poll[options]", vector<string_view>{"Yes", "No", "Maybe"}}
|
* {"poll[options]", vector<string_view>{"Yes", "No", "Maybe"}},
|
||||||
|
* {"status", "How is the weather?"}
|
||||||
* };
|
* };
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
@ -294,6 +299,18 @@ private:
|
|||||||
*/
|
*/
|
||||||
void add_parameters_to_uri(string &uri, const parametermap ¶meters);
|
void add_parameters_to_uri(string &uri, const parametermap ¶meters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Add `*curl_mimepart` to `*curl_mime`.
|
||||||
|
*
|
||||||
|
* @param mime Initialized `*curl_mime`. @param name Name of the field.
|
||||||
|
* @param data Data of the field. If it begins with <tt>`\@file:<tt>, the
|
||||||
|
* rest of the ergument is treated as a filename.
|
||||||
|
*
|
||||||
|
* @since 0.1.1
|
||||||
|
*/
|
||||||
|
void add_mime_part(curl_mime *mime,
|
||||||
|
string_view name, string_view data) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Convert parametermap to `*curl_mime`.
|
* @brief Convert parametermap to `*curl_mime`.
|
||||||
*
|
*
|
||||||
|
@ -69,7 +69,9 @@
|
|||||||
*
|
*
|
||||||
* @subsection input Input
|
* @subsection input Input
|
||||||
*
|
*
|
||||||
* All text input is expected to be UTF-8.
|
* * All text input is expected to be UTF-8.
|
||||||
|
* * To send a file, use “<tt>\@file:</tt>” followed by the file name as value
|
||||||
|
* in the @link mastodonpp::parametermap parametermap@endlink.
|
||||||
*
|
*
|
||||||
* @section exceptions Exceptions
|
* @section exceptions Exceptions
|
||||||
*
|
*
|
||||||
@ -99,6 +101,10 @@
|
|||||||
* @example example01_instance_info.cpp
|
* @example example01_instance_info.cpp
|
||||||
* @example example02_streaming.cpp
|
* @example example02_streaming.cpp
|
||||||
* @example example03_post_status.cpp
|
* @example example03_post_status.cpp
|
||||||
|
* @example example04_post_with_attachment.cpp
|
||||||
|
* @example example05_update_notification_settings.cpp
|
||||||
|
* @example example06_update_name.cpp
|
||||||
|
* @example example07_delete_status.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
39
src/api.cpp
39
src/api.cpp
@ -31,8 +31,8 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::apps_verify_credentials, "/api/v1/apps/verify/credentials"},
|
{v1::apps_verify_credentials, "/api/v1/apps/verify/credentials"},
|
||||||
|
|
||||||
{v1::accounts, "/api/v1/accounts"},
|
{v1::accounts, "/api/v1/accounts"},
|
||||||
{v1::accounts_verify_credentials, "/api/v1/accounts/verify/credentials"},
|
{v1::accounts_verify_credentials, "/api/v1/accounts/verify_credentials"},
|
||||||
{v1::accounts_update_credentials, "/api/v1/accounts/update/credentials"},
|
{v1::accounts_update_credentials, "/api/v1/accounts/update_credentials"},
|
||||||
{v1::accounts_id, "/api/v1/accounts/<ID>"},
|
{v1::accounts_id, "/api/v1/accounts/<ID>"},
|
||||||
{v1::accounts_id_statuses, "/api/v1/accounts/<ID>/statuses"},
|
{v1::accounts_id_statuses, "/api/v1/accounts/<ID>/statuses"},
|
||||||
{v1::accounts_id_followers, "/api/v1/accounts/<ID>/followers"},
|
{v1::accounts_id_followers, "/api/v1/accounts/<ID>/followers"},
|
||||||
@ -61,7 +61,7 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::domain_blocks, "/api/v1/domain/blocks"},
|
{v1::domain_blocks, "/api/v1/domain/blocks"},
|
||||||
|
|
||||||
{v1::filters, "/api/v1/filters"},
|
{v1::filters, "/api/v1/filters"},
|
||||||
{v1::filters_id, "/api/v1/filters/id"},
|
{v1::filters_id, "/api/v1/filters/<ID>"},
|
||||||
|
|
||||||
{v1::reports, "/api/v1/reports"},
|
{v1::reports, "/api/v1/reports"},
|
||||||
|
|
||||||
@ -73,16 +73,16 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::endorsements, "/api/v1/endorsements"},
|
{v1::endorsements, "/api/v1/endorsements"},
|
||||||
|
|
||||||
{v1::featured_tags, "/api/v1/featured/tags"},
|
{v1::featured_tags, "/api/v1/featured/tags"},
|
||||||
{v1::featured_tags_id, "/api/v1/featured/tags/id"},
|
{v1::featured_tags_id, "/api/v1/featured/tags/<ID>"},
|
||||||
{v1::featured_tags_suggestions, "/api/v1/featured/tags/suggestions"},
|
{v1::featured_tags_suggestions, "/api/v1/featured/tags/suggestions"},
|
||||||
|
|
||||||
{v1::preferences, "/api/v1/preferences"},
|
{v1::preferences, "/api/v1/preferences"},
|
||||||
|
|
||||||
{v1::suggestions, "/api/v1/suggestions"},
|
{v1::suggestions, "/api/v1/suggestions"},
|
||||||
{v1::suggestions_account_id, "/api/v1/suggestions/account/id"},
|
{v1::suggestions_account_id, "/api/v1/suggestions/account/<ID>"},
|
||||||
|
|
||||||
{v1::statuses, "/api/v1/statuses"},
|
{v1::statuses, "/api/v1/statuses"},
|
||||||
{v1::statuses_id, "/api/v1/statuses/id"},
|
{v1::statuses_id, "/api/v1/statuses/<ID>"},
|
||||||
{v1::statuses_id_context, "/api/v1/statuses/<ID>/context"},
|
{v1::statuses_id_context, "/api/v1/statuses/<ID>/context"},
|
||||||
{v1::statuses_id_reblogged_by, "/api/v1/statuses/<ID>/reblogged/by"},
|
{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_favourited_by, "/api/v1/statuses/<ID>/favourited/by"},
|
||||||
@ -98,21 +98,21 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::statuses_id_unpin, "/api/v1/statuses/<ID>/unpin"},
|
{v1::statuses_id_unpin, "/api/v1/statuses/<ID>/unpin"},
|
||||||
|
|
||||||
{v1::media, "/api/v1/media"},
|
{v1::media, "/api/v1/media"},
|
||||||
{v1::media_id, "/api/v1/media/id"},
|
{v1::media_id, "/api/v1/media/<ID>"},
|
||||||
|
|
||||||
{v1::polls_id, "/api/v1/polls/id"},
|
{v1::polls_id, "/api/v1/polls/<ID>"},
|
||||||
{v1::polls_id_votes, "/api/v1/polls/<ID>/votes"},
|
{v1::polls_id_votes, "/api/v1/polls/<ID>/votes"},
|
||||||
|
|
||||||
{v1::scheduled_statuses, "/api/v1/scheduled/statuses"},
|
{v1::scheduled_statuses, "/api/v1/scheduled/statuses"},
|
||||||
{v1::scheduled_statuses_id, "/api/v1/scheduled/statuses/id"},
|
{v1::scheduled_statuses_id, "/api/v1/scheduled/statuses/<ID>"},
|
||||||
|
|
||||||
{v1::timelines_public, "/api/v1/timelines/public"},
|
{v1::timelines_public, "/api/v1/timelines/public"},
|
||||||
{v1::timelines_tag_hashtag, "/api/v1/timelines/tag/<HASHTAG>"},
|
{v1::timelines_tag_hashtag, "/api/v1/timelines/tag/<HASHTAG>"},
|
||||||
{v1::timelines_home, "/api/v1/timelines/home"},
|
{v1::timelines_home, "/api/v1/timelines/home"},
|
||||||
{v1::timelines_list_list_id, "/api/v1/timelines/list/list/id"},
|
{v1::timelines_list_list_id, "/api/v1/timelines/list/list/<ID>"},
|
||||||
|
|
||||||
{v1::conversations, "/api/v1/conversations"},
|
{v1::conversations, "/api/v1/conversations"},
|
||||||
{v1::conversations_id, "/api/v1/conversations/id"},
|
{v1::conversations_id, "/api/v1/conversations/<ID>"},
|
||||||
{v1::conversations_id_read, "/api/v1/conversations/<ID>/read"},
|
{v1::conversations_id_read, "/api/v1/conversations/<ID>/read"},
|
||||||
|
|
||||||
{v1::lists, "/api/v1/lists"},
|
{v1::lists, "/api/v1/lists"},
|
||||||
@ -131,7 +131,7 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::streaming_direct, "/api/v1/streaming/direct"},
|
{v1::streaming_direct, "/api/v1/streaming/direct"},
|
||||||
|
|
||||||
{v1::notifications, "/api/v1/notifications"},
|
{v1::notifications, "/api/v1/notifications"},
|
||||||
{v1::notifications_id, "/api/v1/notifications/id"},
|
{v1::notifications_id, "/api/v1/notifications/<ID>"},
|
||||||
{v1::notifications_clear, "/api/v1/notifications/clear"},
|
{v1::notifications_clear, "/api/v1/notifications/clear"},
|
||||||
{v1::notifications_id_dismiss, "/api/v1/notifications/<ID>/dismiss"},
|
{v1::notifications_id_dismiss, "/api/v1/notifications/<ID>/dismiss"},
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::custom_emojis, "/api/v1/custom/emojis"},
|
{v1::custom_emojis, "/api/v1/custom/emojis"},
|
||||||
|
|
||||||
{v1::admin_accounts, "/api/v1/admin/accounts"},
|
{v1::admin_accounts, "/api/v1/admin/accounts"},
|
||||||
{v1::admin_accounts_id, "/api/v1/admin/accounts/id"},
|
{v1::admin_accounts_id, "/api/v1/admin/accounts/<ID>"},
|
||||||
{v1::admin_accounts_account_id_action,
|
{v1::admin_accounts_account_id_action,
|
||||||
"/api/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_approve, "/api/v1/admin/accounts/<ID>/approve"},
|
||||||
@ -157,11 +157,11 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::admin_accounts_id_unsilence, "/api/v1/admin/accounts/<ID>/unsilence"},
|
{v1::admin_accounts_id_unsilence, "/api/v1/admin/accounts/<ID>/unsilence"},
|
||||||
{v1::admin_accounts_id_unsuspend, "/api/v1/admin/accounts/<ID>/unsuspend"},
|
{v1::admin_accounts_id_unsuspend, "/api/v1/admin/accounts/<ID>/unsuspend"},
|
||||||
{v1::admin_reports, "/api/v1/admin/reports"},
|
{v1::admin_reports, "/api/v1/admin/reports"},
|
||||||
{v1::admin_reports_id, "/api/v1/admin/reports/id"},
|
{v1::admin_reports_id, "/api/v1/admin/reports/<ID>"},
|
||||||
{v1::admin_reports_id_assign_to_self,
|
{v1::admin_reports_id_assign_to_self,
|
||||||
"/api/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_unassign, "/api/v1/admin/reports/<ID>/unassign"},
|
||||||
{v1::admin_reports_id_resolve, "/api/v1/admin/reports/resolve"},
|
{v1::admin_reports_id_resolve, "/api/v1/admin/reports/<ID>/resolve"},
|
||||||
{v1::admin_reports_id_reopen, "/api/v1/admin/reports/<ID>/reopen"},
|
{v1::admin_reports_id_reopen, "/api/v1/admin/reports/<ID>/reopen"},
|
||||||
|
|
||||||
{v1::pleroma_notifications_read, " /api/v1/pleroma/notifications/read"},
|
{v1::pleroma_notifications_read, " /api/v1/pleroma/notifications/read"},
|
||||||
@ -171,7 +171,7 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{v1::pleroma_accounts_id_unsubscribe,
|
{v1::pleroma_accounts_id_unsubscribe,
|
||||||
"/api/v1/pleroma/accounts/<ID>/unsubscribe"},
|
"/api/v1/pleroma/accounts/<ID>/unsubscribe"},
|
||||||
{v1::pleroma_accounts_id_favourites,
|
{v1::pleroma_accounts_id_favourites,
|
||||||
"/api/v1/pleroma/accounts/:id/favourites"},
|
"/api/v1/pleroma/accounts/<ID>/favourites"},
|
||||||
{v1::pleroma_accounts_update_avatar,
|
{v1::pleroma_accounts_update_avatar,
|
||||||
"/api/v1/pleroma/accounts/update_avatar"},
|
"/api/v1/pleroma/accounts/update_avatar"},
|
||||||
{v1::pleroma_accounts_update_banner,
|
{v1::pleroma_accounts_update_banner,
|
||||||
@ -239,10 +239,9 @@ const map<API::endpoint_type,string_view> API::_endpoint_map
|
|||||||
{pleroma::disable_account, "/api/pleroma/disable_account"},
|
{pleroma::disable_account, "/api/pleroma/disable_account"},
|
||||||
{pleroma::account_register, "/api/pleroma/account/register"},
|
{pleroma::account_register, "/api/pleroma/account/register"},
|
||||||
|
|
||||||
{pleroma::pleroma_notification_settings,
|
{pleroma::notification_settings, "/api/pleroma/notification_settings"},
|
||||||
"/api/pleroma/pleroma/notification_settings"},
|
{pleroma::healthcheck, "/api/pleroma/healthcheck"},
|
||||||
{pleroma::pleroma_healthcheck, "/api/pleroma/pleroma/healthcheck"},
|
{pleroma::change_email, "/api/pleroma/change_email"},
|
||||||
{pleroma::pleroma_change_email, "/api/pleroma/pleroma/change_email"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mastodonpp
|
} // namespace mastodonpp
|
||||||
|
@ -61,6 +61,27 @@ answer_type Connection::post(const endpoint_variant &endpoint,
|
|||||||
endpoint_to_uri(endpoint), parameters);
|
endpoint_to_uri(endpoint), parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
answer_type Connection::patch(const endpoint_variant &endpoint,
|
||||||
|
const parametermap ¶meters)
|
||||||
|
{
|
||||||
|
return make_request(http_method::PATCH,
|
||||||
|
endpoint_to_uri(endpoint), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
answer_type Connection::put(const endpoint_variant &endpoint,
|
||||||
|
const parametermap ¶meters)
|
||||||
|
{
|
||||||
|
return make_request(http_method::PUT,
|
||||||
|
endpoint_to_uri(endpoint), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
answer_type Connection::del(const endpoint_variant &endpoint,
|
||||||
|
const parametermap ¶meters)
|
||||||
|
{
|
||||||
|
return make_request(http_method::DELETE,
|
||||||
|
endpoint_to_uri(endpoint), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
string Connection::get_new_stream_contents()
|
string Connection::get_new_stream_contents()
|
||||||
{
|
{
|
||||||
buffer_mutex.lock();
|
buffer_mutex.lock();
|
||||||
|
@ -111,20 +111,44 @@ answer_type CURLWrapper::make_request(const http_method &method, string uri,
|
|||||||
}
|
}
|
||||||
case http_method::PATCH:
|
case http_method::PATCH:
|
||||||
{
|
{
|
||||||
|
if (!parameters.empty())
|
||||||
|
{
|
||||||
|
curl_mime *mime{parameters_to_curl_mime(uri, parameters)};
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
code = curl_easy_setopt(_connection, CURLOPT_MIMEPOST, mime);
|
||||||
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "PATCH");
|
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case http_method::PUT:
|
case http_method::PUT:
|
||||||
{
|
{
|
||||||
|
if (!parameters.empty())
|
||||||
|
{
|
||||||
|
curl_mime *mime{parameters_to_curl_mime(uri, parameters)};
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
code = curl_easy_setopt(_connection, CURLOPT_MIMEPOST, mime);
|
||||||
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
code = curl_easy_setopt(_connection, CURLOPT_UPLOAD, 1L);
|
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case http_method::DELETE:
|
case http_method::DELETE:
|
||||||
{
|
{
|
||||||
|
if (!parameters.empty())
|
||||||
|
{
|
||||||
|
curl_mime *mime{parameters_to_curl_mime(uri, parameters)};
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
|
code = curl_easy_setopt(_connection, CURLOPT_MIMEPOST, mime);
|
||||||
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "DELETE");
|
code = curl_easy_setopt(_connection, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,6 +317,8 @@ bool CURLWrapper::replace_parameter_in_uri(string &uri,
|
|||||||
{
|
{
|
||||||
uri.replace(pos, parameter.first.size() + 2,
|
uri.replace(pos, parameter.first.size() + 2,
|
||||||
get<string_view>(parameter.second));
|
get<string_view>(parameter.second));
|
||||||
|
debuglog << "Replaced :" << parameter.first << " in URI with "
|
||||||
|
<< get<string_view>(parameter.second) << '\n';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,12 +365,45 @@ void CURLWrapper::add_parameters_to_uri(string &uri,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CURLWrapper::add_mime_part(curl_mime *mime,
|
||||||
|
string_view name, string_view data) const
|
||||||
|
{
|
||||||
|
curl_mimepart *part{curl_mime_addpart(mime)};
|
||||||
|
if (part == nullptr)
|
||||||
|
{
|
||||||
|
throw CURLException{"Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode code{curl_mime_name(part, name.data())};
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw CURLException{code, "Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.substr(0, 6) == "@file:")
|
||||||
|
{
|
||||||
|
const string_view filename{data.substr(6)};
|
||||||
|
code = curl_mime_filedata(part, filename.data());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code = curl_mime_data(part, data.data(), CURL_ZERO_TERMINATED);
|
||||||
|
}
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw CURLException{code, "Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
|
||||||
|
debuglog << "Set form part: " << name << " = " << data << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
curl_mime *CURLWrapper::parameters_to_curl_mime(string &uri,
|
curl_mime *CURLWrapper::parameters_to_curl_mime(string &uri,
|
||||||
const parametermap ¶meters)
|
const parametermap ¶meters)
|
||||||
{
|
{
|
||||||
debuglog << "Building HTTP form.\n";
|
debuglog << "Building HTTP form.\n";
|
||||||
|
|
||||||
curl_mime *mime{curl_mime_init(_connection)};
|
curl_mime *mime{curl_mime_init(_connection)};
|
||||||
|
|
||||||
for (const auto ¶m : parameters)
|
for (const auto ¶m : parameters)
|
||||||
{
|
{
|
||||||
if (replace_parameter_in_uri(uri, param))
|
if (replace_parameter_in_uri(uri, param))
|
||||||
@ -352,52 +411,16 @@ curl_mime *CURLWrapper::parameters_to_curl_mime(string &uri,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode code;
|
|
||||||
if (holds_alternative<string_view>(param.second))
|
if (holds_alternative<string_view>(param.second))
|
||||||
{
|
{
|
||||||
curl_mimepart *part{curl_mime_addpart(mime)};
|
add_mime_part(mime, param.first, get<string_view>(param.second));
|
||||||
if (part == nullptr)
|
|
||||||
{
|
|
||||||
throw CURLException{"Could not build HTTP form."};
|
|
||||||
}
|
|
||||||
|
|
||||||
code = curl_mime_name(part, param.first.data());
|
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
|
||||||
throw CURLException{code, "Could not build HTTP form."};
|
|
||||||
}
|
|
||||||
|
|
||||||
code = curl_mime_data(part, get<string_view>(param.second).data(),
|
|
||||||
CURL_ZERO_TERMINATED);
|
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
|
||||||
throw CURLException{code, "Could not build HTTP form."};
|
|
||||||
}
|
|
||||||
debuglog << "Set form part: " << param.first << " = "
|
|
||||||
<< get<string_view>(param.second) << '\n';
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const auto &arg : get<vector<string_view>>(param.second))
|
for (const auto &arg : get<vector<string_view>>(param.second))
|
||||||
{
|
{
|
||||||
curl_mimepart *part{curl_mime_addpart(mime)};
|
const string_view name{string(param.first) += "[]"};
|
||||||
if (part == nullptr)
|
add_mime_part(mime, name, arg);
|
||||||
{
|
|
||||||
throw CURLException{"Could not build HTTP form."};
|
|
||||||
}
|
|
||||||
|
|
||||||
const string name{string(param.first) += "[]"};
|
|
||||||
code = curl_mime_name(part, name.c_str());
|
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
|
||||||
throw CURLException{code, "Could not build HTTP form."};
|
|
||||||
}
|
|
||||||
code = curl_mime_data(part, arg.data(), CURL_ZERO_TERMINATED);
|
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
|
||||||
throw CURLException{code, "Could not build HTTP form."};
|
|
||||||
}
|
|
||||||
debuglog << "Set form part: " << name << " = " << arg << '\n';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user