diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f5abb9..473cb82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.7) include(GNUInstallDirs) project (mastodon-cpp - VERSION 0.1.1 + VERSION 0.1.2 LANGUAGES CXX ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC") diff --git a/README.md b/README.md index 0a4f487..a4469bb 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,20 @@ Install with `make install`. The HTML reference can be generated with `build_doc.sh`, if doxygen is installed. Or just look in `src/mastodon-cpp.hpp`. There are examples in `src/examples/`. +## Most basic example + + #include + #include + #include + + int main() + { + Mastodon::API masto("social.example.com", "secret_token"); + std::string answer; + masto.get(API::v1::accounts_verify_credentials, answer); + std::cout << answer << '\n'; + } + ## Compiling your project After you did a `make install`, a project consisting of one file can be compiled as follows: diff --git a/src/api_get.cpp b/src/api_get.cpp index bf6615c..66f7e96 100644 --- a/src/api_get.cpp +++ b/src/api_get.cpp @@ -25,12 +25,12 @@ using std::string; using std::cerr; const std::uint16_t API::get(const Mastodon::API::v1 &call, string &answer) { - const std::vector v{}; - return get(call, v, answer); + const parametermap p; + return get(call, p, answer); } const std::uint16_t API::get(const Mastodon::API::v1 &call, - const std::vector ¶meters, string &answer) + const parametermap ¶meters, string &answer) { string strcall = ""; switch (call) @@ -82,15 +82,7 @@ const std::uint16_t API::get(const Mastodon::API::v1 &call, if (parameters.size() > 0) { - char delim = '?'; - for (const string p : parameters) - { - strcall += delim + p; - if (delim == '?') - { - delim = '&'; - } - } + strcall += maptostr(parameters); } return _http.request_sync(http::method::GET, strcall, answer); @@ -99,15 +91,15 @@ const std::uint16_t API::get(const Mastodon::API::v1 &call, const std::uint16_t API::get(const Mastodon::API::v1 &call, const string &argument, string &answer) { - const std::vector v; - return get(call, argument, v, answer); + const parametermap p; + return get(call, argument, p, answer); } const std::uint16_t API::get(const Mastodon::API::v1 &call, const string &argument, - const std::vector ¶meters, string &answer) + const parametermap ¶meters, string &answer) { string strcall = ""; - char delim = '?'; + bool firstparam = true; switch (call) { @@ -125,11 +117,11 @@ const std::uint16_t API::get(const Mastodon::API::v1 &call, break; case v1::accounts_relationships: strcall = "/api/v1/accounts/relationships?id=" + argument; - delim = '&'; + firstparam = false; break; case v1::accounts_search: strcall = "/api/v1/accounts/search?q=" + argument; - delim = '&'; + firstparam = false; break; case v1::accounts_id_lists: strcall = "/api/v1/accounts/" + argument + "/lists"; @@ -145,7 +137,7 @@ const std::uint16_t API::get(const Mastodon::API::v1 &call, break; case v1::search: strcall = "/api/v1/search?q=" + argument; - delim = '&'; + firstparam = false; break; case v1::statuses_id: strcall = "/api/v1/statuses/" + argument; @@ -176,14 +168,7 @@ const std::uint16_t API::get(const Mastodon::API::v1 &call, if (parameters.size() > 0) { - for (const string p : parameters) - { - strcall += delim + p; - if (delim == '?') - { - delim = '&'; - } - } + strcall += maptostr(parameters, firstparam); } return _http.request_sync(http::method::GET, strcall, answer); diff --git a/src/examples/example1_dump_json.cpp b/src/examples/example1_dump_json.cpp index db13ad3..61436dd 100644 --- a/src/examples/example1_dump_json.cpp +++ b/src/examples/example1_dump_json.cpp @@ -29,10 +29,10 @@ int main(int argc, char *argv[]) { std::cout << "Your last toot with media attached:\n"; std::string uid = answer.substr(7, answer.find("\"", 7) - 7); - std::vector parameters = + API::parametermap parameters = { - "limit=1", - "only_media=1" + { "limit", { "1" } }, + { "only_media", { "1" } } }; ret = masto.get(API::v1::accounts_id_statuses, uid,parameters, answer); @@ -49,10 +49,12 @@ int main(int argc, char *argv[]) std::cout << "\nYour last 2 followers:\n"; parameters = { - "limit=2", - "exclude_types[]=favourite", - "exclude_types[]=reblog", - "exclude_types[]=mention" + { + "limit", { "2" } + }, + { + "exclude_types", { "favourite", "reblog", "mention" } + } }; ret = masto.get(API::v1::notifications, parameters, answer); if (ret == 0) diff --git a/src/examples/example3_mastocron.cpp b/src/examples/example3_mastocron.cpp index 882ed6c..6d5c9a7 100644 --- a/src/examples/example3_mastocron.cpp +++ b/src/examples/example3_mastocron.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include "../mastodon-cpp.hpp" #include #include @@ -51,7 +51,11 @@ int main(int argc, char *argv[]) } // Only get toots we haven't seen yet - std::vector params = { "limit=" + limit, "since_id=" + lastid }; + API::parametermap params = + { + { "limit", { limit } }, + { "since_id", { lastid } } + }; ret = masto.get(API::v1::timelines_tag_hashtag, hashtag, params, answer); if (ret == 0) diff --git a/src/mastodon-cpp.cpp b/src/mastodon-cpp.cpp index aa16347..8f518ae 100644 --- a/src/mastodon-cpp.cpp +++ b/src/mastodon-cpp.cpp @@ -15,9 +15,14 @@ */ #include +#include +#include #include "version.hpp" +#include "macros.hpp" #include "mastodon-cpp.hpp" +#include + using namespace Mastodon; using std::string; @@ -35,7 +40,43 @@ const void API::set_useragent(const std::string &useragent) _useragent = useragent; } -const std::string API::get_useragent() const +const string API::get_useragent() const { return _useragent; } + +const string API::maptostr(const parametermap &map, const bool &firstparam) +{ + string result = ""; + char delim = '?'; + if (!firstparam) + { + delim = '&'; + } + + for (const auto &it : map) + { + if (it.second.size() == 1) + { + result += (delim + it.first + "=" + it.second.front()); + if (delim == '?') + { + delim = '&'; + } + } + else + { + for (const string &str : it.second) + { + result += (delim + it.first + "[]=" + str); + if (delim == '?') + { + delim = '&'; + } + } + } + } + + ttdebug << "Constructed parameter string: " << result << '\n'; + return result; +} diff --git a/src/mastodon-cpp.hpp b/src/mastodon-cpp.hpp index 0e5feb7..dc9e93f 100644 --- a/src/mastodon-cpp.hpp +++ b/src/mastodon-cpp.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,19 @@ namespace Mastodon class API { public: + /*! + * @brief Used for passing optional parameters. + * + * Example: + * @code + * parametermap p = + * { + * {"field1", { "value1", "value2" } }, + * {"field2", { "value" } } + * } + * @endcode + */ + typedef std::multimap> parametermap; /*! * @brief A list of all API calls. * @@ -105,7 +119,7 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return Error code. See README.md for details. + * @return @ref error "Error code". */ const std::uint16_t get(const Mastodon::API::v1 &call, std::string &answer); @@ -117,7 +131,7 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return Error code. See README.md for details. + * @return @ref error "Error code". */ const std::uint16_t get(const Mastodon::API::v1 &call, const std::string &argument, @@ -128,15 +142,15 @@ public: * optional parameters. * * @param call A call defined in Mastodon::API::v1 - * @param parameters A std::vector containing optional parameters in the - * form `field=value` + * @param parameters A Mastodon::API::parametermap containing optional + * parameters. * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return Error code. See README.md for details. + * @return @ref error "Error code". */ const std::uint16_t get(const Mastodon::API::v1 &call, - const std::vector ¶meters, + const parametermap ¶meters, std::string &answer); /*! @@ -145,16 +159,16 @@ public: * * @param call A call defined in Mastodon::API::v1 * @param argument The non-optional argument - * @param parameters A std::vector containing optional parameters in the - * form `field=value` + * @param parameters A Mastodon::API::parametermap containing optional + * parameters. * @param answer The answer from the server. Usually JSON. On error * an empty string. * - * @return Error code. See README.md for details. + * @return @ref error "Error code". */ const std::uint16_t get(const Mastodon::API::v1 &call, const std::string &argument, - const std::vector ¶meters, + const parametermap ¶meters, std::string &answer); /*! @@ -164,7 +178,7 @@ public: * @param answer The answer from the server. Usually JSON. On error an * empty string. * - * @return Error code. See README.md for details. + * @return @ref error "Error code". */ const std::uint16_t get(const std::string &call, std::string &answer); @@ -188,6 +202,17 @@ private: const std::string _access_token; std::string _useragent; + /*! + * @brief Converts map of parameters into a string. + * + * @param map Map of parameters + * @param firstparam Contains this map the first parameter? + * + * @return String of parameters + */ + const std::string maptostr(const parametermap &map, + const bool &firstparam = true); + class http { public: