The first GET requests are working.
This commit is contained in:
parent
cd9b3f28d5
commit
be6fca69fe
@ -1,9 +1,9 @@
|
||||
cmake_minimum_required (VERSION 3.7)
|
||||
project (mastodon-cpp
|
||||
VERSION 0.0.0
|
||||
VERSION 0.0.1
|
||||
LANGUAGES CXX
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -rdynamic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
|
||||
|
||||
# Write SHA1 hash and date of current git commit to a header file. Also version.
|
||||
@ -38,7 +38,7 @@ set_target_properties(mastodon-cpp PROPERTIES
|
||||
SOVERSION ${mastodon-cpp_VERSION_MAJOR}
|
||||
)
|
||||
install(TARGETS mastodon-cpp DESTINATION lib)
|
||||
#target_link_libraries(mastodon-cpp pthread boost_system boost_filesystem dl)
|
||||
target_link_libraries(mastodon-cpp pthread boost_system ssl crypto)
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/src/lib/mastodon-cpp.hpp DESTINATION include)
|
||||
|
||||
# Example client
|
||||
@ -59,19 +59,3 @@ if(NOT NOTESTS)
|
||||
add_test(${bin} ${bin})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
# Binary and source packages
|
||||
# Some variables are not respected, it seems
|
||||
# include(InstallRequiredSystemLibraries)
|
||||
# set(CPACK_GENERATOR "TGZ")
|
||||
# set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
# set(CPACK_PACKAGE_VERSION_MAJOR "${cdcl_VERSION_MAJOR}")
|
||||
# set(CPACK_PACKAGE_VERSION_MINOR "${cdcl_VERSION_MINOR}")
|
||||
# set(CPACK_PACKAGE_VERSION_PATCH "${cdcl_VERSION_PATCH}")
|
||||
# set(CPACK_PACKAGE_DESCRIPTION_SUMMARY, "Edit checklists on CalDAV servers.")
|
||||
# set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
||||
# set(CPACK_PACKAGE_CHECKSUM, "SHA256")
|
||||
# set(CPACK_SOURCE_PACKAGE_FILE_NAME, "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
# set(CPACK_SOURCE_IGNORE_FILES, "/\\\\.git/;/build/;.\\\\.sublime-")
|
||||
# include (CPack)
|
||||
|
47
README.md
47
README.md
@ -1,4 +1,6 @@
|
||||
**mastodon-cpp** is an interface for the Mastodon API.
|
||||
**mastodon-cpp** is a CPP wrapper for the Mastodon API. The aim is to be as simple as possible.
|
||||
The library takes care of the network stuff. You submit a query and get the raw JSON.
|
||||
All versions below 1.0.0 (SOVERSION 0) are considered insecure, unstable and can change drastically any time.
|
||||
|
||||
# Install
|
||||
## Dependencies
|
||||
@ -18,24 +20,39 @@
|
||||
make
|
||||
|
||||
# Usage
|
||||
…
|
||||
Mastodon::API masto("social.example.com", "access token");
|
||||
std::cout << masto.get(Mastodon::API::v1::accounts_id, "12345") << '\n';
|
||||
|
||||
# Status of implementation
|
||||
There is an example in `src/example`.
|
||||
|
||||
* [ ] GET /api/v1/accounts/:id
|
||||
* [ ] GET /api/v1/accounts/verify_credentials
|
||||
# TODO
|
||||
* Version 0.1.0
|
||||
* [ ] Implement all GET methods
|
||||
* [ ] Proper error handling
|
||||
* [x] Network stuff
|
||||
* Version 0.2.0
|
||||
* [ ] Implement all PATCH methods
|
||||
* [ ] Implement all POST methods
|
||||
* [ ] Implement all DELETE methods
|
||||
* Later
|
||||
[ ] Escape user input
|
||||
[ ] Asynchronous I/O
|
||||
|
||||
## Status of implementation
|
||||
* [x] GET /api/v1/accounts/:id
|
||||
* [x] GET /api/v1/accounts/verify_credentials
|
||||
* [ ] PATCH /api/v1/accounts/update_credentials
|
||||
* [ ] GET /api/v1/accounts/:id/followers
|
||||
* [ ] GET /api/v1/accounts/:id/following
|
||||
* [ ] GET /api/v1/accounts/:id/statuses
|
||||
* [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
|
||||
* [ ] GET /api/v1/accounts/:id/block
|
||||
* [ ] GET /api/v1/accounts/:id/unblock
|
||||
* [ ] GET /api/v1/accounts/:id/mute
|
||||
* [ ] GET /api/v1/accounts/:id/unmute
|
||||
* [ ] GET /api/v1/accounts/relationships
|
||||
* [ ] GET /api/v1/accounts/search
|
||||
* [ ] 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] GET /api/v1/accounts/relationships
|
||||
* [x] GET /api/v1/accounts/search
|
||||
* [ ] POST /api/v1/apps
|
||||
* [ ] GET /api/v1/blocks
|
||||
* [ ] GET /api/v1/favourites
|
||||
@ -69,7 +86,7 @@
|
||||
* [ ] GET /api/v1/timelines/list/:list_id
|
||||
|
||||
# Copyright
|
||||
Copyright © 2017 tastytea <tastytea@tastytea.de>.
|
||||
Copyright © 2018 tastytea <tastytea@tastytea.de>.
|
||||
License GPLv3: GNU GPL version 3 <https://www.gnu.org/licenses/gpl-3.0.html>.
|
||||
This program comes with ABSOLUTELY NO WARRANTY. This is free software,
|
||||
and you are welcome to redistribute it under certain conditions.
|
||||
|
95
src/api_get.cpp
Normal file
95
src/api_get.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/* 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 "mastodon-cpp.hpp"
|
||||
|
||||
using namespace Mastodon;
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
const string API::get(const Mastodon::API::v1 &method)
|
||||
{
|
||||
const std::vector<string> v{};
|
||||
return get(method, v);
|
||||
}
|
||||
|
||||
const string API::get(const Mastodon::API::v1 &method,
|
||||
const std::vector<string> ¶meters)
|
||||
{
|
||||
string strmethod = "";
|
||||
switch (method)
|
||||
{
|
||||
case v1::accounts_verify_credentials:
|
||||
strmethod = "/api/v1/accounts/verify_credentials";
|
||||
break;
|
||||
default:
|
||||
cerr << "ERROR: Invalid method.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
string answer;
|
||||
_http.request_sync(http::method::GET, strmethod, answer);
|
||||
return answer;
|
||||
}
|
||||
|
||||
const string API::get(const Mastodon::API::v1 &method,
|
||||
const string &argument)
|
||||
{
|
||||
const std::vector<string> v;
|
||||
return get(method, argument, v);
|
||||
}
|
||||
const string API::get(const Mastodon::API::v1 &method,
|
||||
const string &argument,
|
||||
const std::vector<string> ¶meters)
|
||||
{
|
||||
string strmethod = "";
|
||||
switch (method)
|
||||
{
|
||||
case v1::accounts_id:
|
||||
strmethod = "/api/v1/accounts/" + argument;
|
||||
break;
|
||||
case v1::accounts_id_followers:
|
||||
strmethod = "/api/v1/accounts/" + argument + "/followers";
|
||||
break;
|
||||
case v1::accounts_id_following:
|
||||
strmethod = "/api/v1/accounts/" + argument + "/following";
|
||||
break;
|
||||
case v1::accounts_id_statuses:
|
||||
strmethod = "/api/v1/accounts/" + argument + "/statuses";
|
||||
break;
|
||||
case v1::accounts_relationships:
|
||||
strmethod = "/api/v1/accounts/relationships?id=" + argument;
|
||||
break;
|
||||
case v1::accounts_search:
|
||||
strmethod = "/api/v1/accounts/search?q=" + argument;
|
||||
break;
|
||||
default:
|
||||
cerr << "ERROR: Invalid method.\n";
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
|
||||
string answer;
|
||||
_http.request_sync(http::method::GET, strmethod, answer);
|
||||
return answer;
|
||||
}
|
||||
|
||||
const string API::get(const std::string &method)
|
||||
{
|
||||
return method;
|
||||
}
|
@ -1,22 +1,19 @@
|
||||
/* 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 "../mastodon-cpp.hpp"
|
||||
|
||||
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]);
|
||||
|
||||
std::cout << masto.get(Mastodon::API::v1::accounts_id,
|
||||
"44897") << '\n';
|
||||
}
|
||||
|
157
src/http.cpp
Normal file
157
src/http.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/* 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 <string>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include "mastodon-cpp.hpp"
|
||||
|
||||
using namespace Mastodon;
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
namespace ssl = boost::asio::ssl;
|
||||
typedef ssl::stream<tcp::socket> ssl_socket;
|
||||
|
||||
API::http::http(const string &instance, const string &access_token,
|
||||
const string &useragent)
|
||||
: _instance(instance)
|
||||
, _access_token(access_token)
|
||||
, _useragent(useragent)
|
||||
, _ctx(ssl::context::tlsv12)
|
||||
, _resolver(_io_service)
|
||||
, _socket(_io_service, _ctx)
|
||||
{
|
||||
_ctx.set_options(ssl::context::tlsv12 | ssl::context::tlsv11 |
|
||||
ssl::context::no_sslv3 | ssl::context::no_sslv2 |
|
||||
ssl::context::no_tlsv1);
|
||||
_ctx.set_default_verify_paths();
|
||||
}
|
||||
|
||||
const std::uint16_t API::http::request_sync(const method &meth,
|
||||
const string &path,
|
||||
string &answer)
|
||||
{
|
||||
return request_sync(meth, path, "", answer);
|
||||
}
|
||||
|
||||
const std::uint16_t API::http::request_sync(const method &meth,
|
||||
const string &path,
|
||||
const string &data,
|
||||
string &answer)
|
||||
{
|
||||
try
|
||||
{
|
||||
tcp::resolver::query query(_instance, "https");
|
||||
tcp::resolver::iterator endpoint_iterator = _resolver.resolve(query);
|
||||
boost::asio::connect(_socket.lowest_layer(), endpoint_iterator);
|
||||
_socket.lowest_layer().set_option(tcp::no_delay(true));
|
||||
// Server Name Indication (SNI)
|
||||
SSL_set_tlsext_host_name(_socket.native_handle(), _instance.c_str());
|
||||
|
||||
_socket.set_verify_mode(ssl::verify_peer);
|
||||
_socket.set_verify_callback(ssl::rfc2818_verification(_instance));
|
||||
|
||||
_socket.handshake(ssl_socket::client);
|
||||
|
||||
boost::asio::streambuf request;
|
||||
std::ostream request_stream(&request);
|
||||
switch (meth)
|
||||
{
|
||||
case http::method::GET:
|
||||
request_stream << "GET";
|
||||
request_stream << " " << path;
|
||||
break;
|
||||
// case http::method::PATCH:
|
||||
// request_stream << "PATCH";
|
||||
// break;
|
||||
// case http::method::POST:
|
||||
// request_stream << "POST";
|
||||
// break;
|
||||
// case http::method::DELETE:
|
||||
// request_stream << "DELETE";
|
||||
// break;
|
||||
default:
|
||||
cerr << "NOT IMPLEMENTED\n";
|
||||
return 0xffff;
|
||||
}
|
||||
request_stream << " HTTP/1.0\r\n";
|
||||
request_stream << "Host: " << _instance << "\r\n";
|
||||
request_stream << "Accept: */*\r\n";
|
||||
request_stream << "Connection: close\r\n";
|
||||
request_stream << "User-Agent: " << _useragent << "\r\n";
|
||||
request_stream << "Authorization: Bearer "
|
||||
<< _access_token << "\r\n\r\n";
|
||||
boost::asio::write(_socket, request);
|
||||
|
||||
boost::asio::streambuf response;
|
||||
boost::asio::read_until(_socket, response, "\r\n");
|
||||
|
||||
// Check that response is OK.
|
||||
std::istream response_stream(&response);
|
||||
std::string http_version;
|
||||
std::uint16_t status_code;
|
||||
std::string status_message;
|
||||
response_stream >> http_version;
|
||||
response_stream >> status_code;
|
||||
std::getline(response_stream, status_message);
|
||||
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
|
||||
{
|
||||
cerr << "Invalid response\n";
|
||||
return 0xffff;
|
||||
}
|
||||
if (status_code != 200)
|
||||
{
|
||||
cerr << "Response returned with status code " << status_code
|
||||
<< ": " << status_message << "\n";
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
// Read headers
|
||||
boost::asio::read_until(_socket, response, "\r\n\r\n");
|
||||
std::string header;
|
||||
while (std::getline(response_stream, header) && header != "\r")
|
||||
{}
|
||||
//response.consume(response.size());
|
||||
|
||||
// Read body
|
||||
boost::system::error_code error;
|
||||
answer = "";
|
||||
std::ostringstream ss;
|
||||
while (boost::asio::read(_socket, response,
|
||||
boost::asio::transfer_at_least(1), error))
|
||||
{
|
||||
ss << &response;
|
||||
}
|
||||
if (error != boost::asio::error::eof)
|
||||
{
|
||||
throw boost::system::system_error(error);
|
||||
}
|
||||
answer = ss.str();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cerr << "Exception: " << e.what() << "\n";
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -14,12 +14,23 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "version.hpp"
|
||||
#include "mastodon-cpp.hpp"
|
||||
|
||||
using std::cout;
|
||||
using namespace Mastodon;
|
||||
using std::string;
|
||||
|
||||
Mastodon::Mastodon()
|
||||
API::API(const string &instance, const string &access_token)
|
||||
: _instance(instance)
|
||||
, _access_token(access_token)
|
||||
, _useragent(string("mastodon-cpp/") + global::version)
|
||||
, _http(instance, access_token, _useragent)
|
||||
{
|
||||
cout << "Test.\n";
|
||||
//
|
||||
}
|
||||
|
||||
const void API::set_useragent(const std::string &useragent)
|
||||
{
|
||||
_useragent = useragent;
|
||||
}
|
||||
|
@ -17,10 +17,81 @@
|
||||
#ifndef MASTODON_CPP_HPP
|
||||
#define MASTODON_CPP_HPP
|
||||
|
||||
class Mastodon
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
||||
namespace Mastodon
|
||||
{
|
||||
public:
|
||||
Mastodon();
|
||||
};
|
||||
class API
|
||||
{
|
||||
public:
|
||||
enum class v1
|
||||
{
|
||||
accounts_id,
|
||||
accounts_verify_credentials,
|
||||
accounts_id_followers,
|
||||
accounts_id_following,
|
||||
accounts_id_statuses,
|
||||
accounts_relationships,
|
||||
accounts_search
|
||||
};
|
||||
|
||||
explicit API(const std::string &instance,
|
||||
const std::string &access_token);
|
||||
// Select one of the predefined methods.
|
||||
const std::string get(const Mastodon::API::v1 &method);
|
||||
const std::string get(const Mastodon::API::v1 &method,
|
||||
const std::vector<std::string> ¶meters);
|
||||
const std::string get(const Mastodon::API::v1 &method,
|
||||
const std::string &argument,
|
||||
const std::vector<std::string> ¶meters);
|
||||
const std::string get(const Mastodon::API::v1 &method,
|
||||
const std::string &argument);
|
||||
// Supply a custom method as string.
|
||||
const std::string get(const std::string &method);
|
||||
|
||||
const void set_useragent(const std::string &useragent);
|
||||
|
||||
private:
|
||||
const std::string _instance;
|
||||
const std::string _access_token;
|
||||
std::string _useragent;
|
||||
|
||||
class http
|
||||
{
|
||||
public:
|
||||
enum class method
|
||||
{
|
||||
GET,
|
||||
PATCH,
|
||||
POST,
|
||||
DELETE
|
||||
};
|
||||
|
||||
explicit http(const std::string &instance,
|
||||
const std::string &access_token,
|
||||
const std::string &useragent);
|
||||
const std::uint16_t request_sync(const method &meth,
|
||||
const std::string &path,
|
||||
std::string &answer);
|
||||
const std::uint16_t request_sync(const method &meth,
|
||||
const std::string &path,
|
||||
const std::string &data,
|
||||
std::string &answer);
|
||||
|
||||
private:
|
||||
const std::string _instance;
|
||||
const std::string _access_token;
|
||||
const std::string _useragent;
|
||||
boost::asio::ssl::context _ctx;
|
||||
boost::asio::io_service _io_service;
|
||||
boost::asio::ip::tcp::resolver _resolver;
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> _socket;
|
||||
} _http;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,22 +1,9 @@
|
||||
/* 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 "../mastodon-cpp.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Mastodon test;
|
||||
Mastodon::API test("", "");
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
#ifndef VERSION_HPP
|
||||
#define VERSION_HPP
|
||||
|
||||
namespace global {
|
||||
static constexpr char version[] = "@PROJECT_VERSION@";
|
||||
static constexpr char git_sha1[] ="@GIT_SHA1@";
|
||||
static constexpr char git_date[] ="@GIT_DATE@";
|
||||
namespace Mastodon
|
||||
{
|
||||
namespace global
|
||||
{
|
||||
static constexpr char version[] = "@PROJECT_VERSION@";
|
||||
static constexpr char git_sha1[] ="@GIT_SHA1@";
|
||||
static constexpr char git_date[] ="@GIT_DATE@";
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VERSION_HPP
|
||||
|
Reference in New Issue
Block a user