Changed matrix::client, matrix::session, and matrix::syncer member functions to return netreturn values

This commit is contained in:
rexy712 2019-10-21 16:31:02 -07:00
parent a5ece2e08a
commit e7c1dd010d
14 changed files with 194 additions and 171 deletions

View File

@ -26,6 +26,7 @@
#include "matrix/upload_info.hpp"
#include "matrix/connection.hpp"
#include "matrix/roomcxn.hpp"
#include "matrix/netreturn.hpp"
#include <vector> //vector
#include <memory> //shared_ptr
#include <cstdlib> //size_t
@ -53,43 +54,43 @@ namespace matrix{
* Note name must be safe to be placed in a json string.
* Returns: true if the operation was successful.
*/
bool set_display_name(const raii::string_base&);
netreturn<void> set_display_name(const raii::string_base&);
/*
* Sets the url of the user's profile picture on the homeserver.
* Note url must be safe to be placed in a json string.
* Returns: true if the operation was successful.
*/
bool set_profile_picture(const raii::string_base&);
netreturn<void> set_profile_picture(const raii::string_base&);
bool set_presence(const raii::string_base& status);
raii::rjp_string get_presence(const raii::string_base& userid);
netreturn<void> set_presence(const raii::string_base& status);
netreturn<raii::rjp_string> get_presence(const raii::string_base& userid);
/*
* Gets the display name of the logged in user from the homeserver.
* Returns: the display name on success, an empty string on failure.
*/
raii::rjp_string get_display_name(void)const;
netreturn<raii::rjp_string> get_display_name(void)const;
/*
* Gets the profile picture url of the logged in user from the homeserver.
* Returns: the profile picture url on success, an empty string on failure.
*/
raii::rjp_string get_profile_picture(void)const;
netreturn<raii::rjp_string> get_profile_picture(void)const;
/*
* Lookup a room id given a room alias.
* Returns: the room id of the associated room on success, empty string on failure.
*/
raii::rjp_string room_alias_to_id(const raii::string_base& alias)const;
netreturn<raii::rjp_string> room_alias_to_id(const raii::string_base& alias)const;
/*
* Get a list of rooms the logged in user is a member of.
* Returns: a vector of room id strings.
*/
std::vector<raii::rjp_string> list_rooms(void)const;
netreturn<std::vector<raii::rjp_string>> list_rooms(void)const;
/*
* Create a new room on the logged in user's homeserver. Assign an alias to the room.
* Returns: the room id of the newly created room on success, an empty string on failure.
*/
raii::rjp_string create_room(const raii::string_base& name, const raii::string_base& alias)const;
netreturn<raii::rjp_string> create_room(const raii::string_base& name, const raii::string_base& alias)const;
/*
* Create a new matrix::roomcxn object for the given roomid.
@ -108,30 +109,30 @@ namespace matrix{
* Returns: file_info struct containing the url of the file on the homeserver.
* Note check the file_info::fileurl field to check if the upload succeeded.
*/
uploaded_file upload_file(const file_details& file)const;
netreturn<uploaded_file> upload_file(const file_details& file)const;
/*
* Upload a file as an image.
* Returns: image_info struct containing the url of the image on the homeserver.
* Note check the image_info::fileurl field to check if the upload succeeded.
*/
uploaded_image upload_image(const image_details& file)const;
netreturn<uploaded_image> upload_image(const image_details& file)const;
/*
* Upload data as a video.
* Returns: video_info struct containing the url of the image on the homeserver.
* Note check the video_info::fileurl field to check if the upload succeeded.
*/
uploaded_video upload_video(const video_details& file)const;
netreturn<uploaded_video> upload_video(const video_details& file)const;
/*
* Upload a file as an audio file.
* Returns: audio_info struct containing the url of the image on the homeserver.
* Note check the audio_info::fileurl field to check if the upload succeeded.
*/
uploaded_audio upload_audio(const audio_details& file)const;
netreturn<uploaded_audio> upload_audio(const audio_details& file)const;
bool create_thumbnail(uploaded_image& info)const;
bool create_thumbnail(uploaded_video& video)const;
netreturn<void> create_thumbnail(uploaded_image& info)const;
netreturn<void> create_thumbnail(uploaded_video& video)const;
raii::binary download_file(const raii::string_base& url);
template<class DLHandler>
@ -153,7 +154,7 @@ namespace matrix{
static size_t _download_dispatch(char* ptr, size_t size, size_t nmemb, void* userdata){
return reinterpret_cast<DLHandler*>(userdata)(ptr, size, nmemb, nullptr);
}
uploaded_file _upload_file(const file_details& file, const raii::curl_llist& header)const;
netreturn<uploaded_file> _upload_file(const file_details& file, const raii::curl_llist& header)const;
};
}

View File

@ -91,8 +91,9 @@ namespace matrix{
raii::binary _post_curl_binary(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header, binary_callback_fun = _binary_reply_curl_callback)const;
raii::string _put_curl(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header, reply_callback_fun = _reply_curl_callback)const;
raii::binary _put_curl_binary(const raii::string_base& postdata, const raii::string_base& url, const raii::curl_llist& header, binary_callback_fun = _binary_reply_curl_callback)const;
raii::rjp_string _post_and_find(const raii::string_base& data, const raii::string_base& url, const raii::curl_llist& header, const raii::string_base& target)const;
raii::rjp_string _get_and_find(const raii::string_base& url, const raii::string_base& search)const;
netreturn<raii::rjp_string> _post_and_find(const raii::string_base& data, const raii::string_base& url, const raii::curl_llist& header, const raii::string_base& target)const;
netreturn<raii::rjp_string> _put_and_find(const raii::string_base& data, const raii::string_base& url, const raii::curl_llist& header, const raii::string_base& target)const;
netreturn<raii::rjp_string> _get_and_find(const raii::string_base& url, const raii::string_base& search)const;
raii::rjp_string _curl_reply_search(const raii::string_base& reply, const raii::string_base& search)const;
raii::rjp_string _curl_reply_search(const raii::rjp_ptr& root, const raii::string_base& search)const;
void _set_curl_defaults(const raii::string_base& useragent)const;

View File

@ -37,10 +37,13 @@ namespace matrix{
netreturn_base(const raii::rjp_string& error, raii::rjp_string&& errorcode, int httpstatus);
netreturn_base(raii::rjp_string&& error, const raii::rjp_string& errorcode, int httpstatus);
netreturn_base(raii::rjp_string&& error, raii::rjp_string&& errorcode, int httpstatus);
operator bool(void)const;
const raii::rjp_string mxerror(void)const;
const raii::rjp_string mxerrorcode(void)const;
bool ok(void)const;
const raii::rjp_string& mxerror(void)const;
const raii::rjp_string& mxerrorcode(void)const;
raii::rjp_string& mxerror(void);
raii::rjp_string& mxerrorcode(void);
int httpstatus(void)const;
bool has_httperror(void)const;
};
template<class Retval>
class netreturn : public netreturn_base
@ -51,7 +54,7 @@ namespace matrix{
Retval m_ret = {};
public:
constexpr netreturn(void) = default;
template<class Str1, class Str2, class Val>
template<class Str1, class Str2, class Val = Retval>
netreturn(Str1&& error, Str2&& errorcode, int httpcode, Val&& val = Val()):
netreturn_base(std::forward<Str1>(error), std::forward<Str2>(errorcode), httpcode),
m_ret(std::forward<Val>(val)){}

View File

@ -89,7 +89,7 @@ namespace matrix{
* This will regenerate the urls and ensure access token and homeserver are valid.
* Returns: true if success, false otherwise.
*/
bool login(void);
netreturn<void> login(void);
/*
* NOT thread safe.
* Manually log in to a homeserver first using the current access token, then trying the
@ -97,13 +97,13 @@ namespace matrix{
* homeserver are valid.
* Returns: true if success, false otherwise.
*/
bool login(const raii::string_base& username, const raii::string_base& pass);
netreturn<void> login(const raii::string_base& username, const raii::string_base& pass);
/*
* Logout of the current connection to the homeserver. Will invalidate the access token on the server side.
* Returns: true if the logout was successful, false otherwise.
*/
bool logout(void);
netreturn<void> logout(void);
/*
* Returns: true if the session is successfully connected to the homeserver.
*/
@ -132,11 +132,11 @@ namespace matrix{
*/
void invalidate(void);
private:
bool _do_login(const raii::string_base& username, const raii::string_base& pass);
netreturn<void> _do_login(const raii::string_base& username, const raii::string_base& pass);
void _populate_session_info(const auth_data& a);
raii::rjp_string _get_userid(void);
netreturn<raii::rjp_string> _get_userid(void);
raii::string _request_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl)const;
std::pair<raii::rjp_string,raii::rjp_string> _get_new_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl);
netreturn<std::pair<raii::rjp_string,raii::rjp_string>> _get_new_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl);
};
}

View File

@ -120,8 +120,9 @@ namespace matrix::sync{
class response
{
private:
raii::rjp_ptr m_root;
raii::rjp_ptr m_root = nullptr;
public:
constexpr response(void) = default;
response(const raii::string_base& src);
response(RJP_value* root);

View File

@ -25,6 +25,7 @@
#include "matrix/session_info.hpp"
#include "matrix/connection.hpp"
#include "matrix/sync_response.hpp"
#include "matrix/netreturn.hpp"
#include <cstdlib> //size_t
#include <memory> //shared_ptr
@ -55,7 +56,7 @@ namespace matrix{
* Sync state with the homeserver. Will wait for up to timeout ms.
* Returns: the raw json response from the homeserver.
*/
sync::response sync(size_t timeout);
netreturn<sync::response> sync(size_t timeout);
};
}

View File

@ -105,29 +105,32 @@ namespace raii{
string_intermediary(char* data, size_t len):
string_base(data, len){}
string_intermediary(const char* data, size_t len):
string_base(reinterpret_cast<char*>(Allocator::copy(data, len+1)), len){}
string_base(reinterpret_cast<char*>(len ? Allocator::copy(data, len+1) : nullptr), len){}
string_intermediary(const char* data):
string_base(strlen(data))
string_base(data ? strlen(data) : 0)
{
if(m_length)
m_data = reinterpret_cast<char*>(Allocator::copy(data, m_length+1));
}
string_intermediary(size_t len):
string_base(reinterpret_cast<char*>(Allocator::allocate(len+1)), len){}
string_base(reinterpret_cast<char*>(len ? Allocator::allocate(len+1) : nullptr), len){}
//normal copy and move ctors
string_intermediary(const string_intermediary& b):
string_base(reinterpret_cast<char*>(Allocator::copy(b.m_data, b.m_length+1)), b.m_length){}
string_base(reinterpret_cast<char*>(b.m_length ? Allocator::copy(b.m_data, b.m_length+1) : nullptr), b.m_length){}
string_intermediary(string_intermediary&& s):
string_base(std::exchange(s.m_data, nullptr), s.m_length){}
string_intermediary(const string_base& b):
string_base(reinterpret_cast<char*>(Allocator::copy(b.get(), b.length()+1)), b.length()){}
string_base(reinterpret_cast<char*>(b.length() ? Allocator::copy(b.get(), b.length()+1) : nullptr), b.length()){}
//copy from string expression
template<class T, typename std::enable_if<detail::is_string<T>::value && !detail::is_concrete_string<T>::value,void>::type* = nullptr>
string_intermediary(T&& t){
size_t len = t.length();
if(!len){
return;
}
char* tmp = reinterpret_cast<char*>(Allocator::allocate(len+1));
_assign(tmp, t.get(), 0);
m_data = tmp;

View File

@ -30,55 +30,55 @@ namespace matrix{
connection(ses){}
//networked setter
bool client::set_display_name(const raii::string_base& newname){
netreturn<void> client::set_display_name(const raii::string_base& newname){
_put_curl(raii::string("{\"displayname\":\"" + newname + "\"}"), m_ses->urls.displayname(), raii::curl_llist());
return http_status() == 200;
return netreturn<void>(raii::string(), raii::string(), http_status());
}
bool client::set_profile_picture(const raii::string_base& media_url){
netreturn<void> client::set_profile_picture(const raii::string_base& media_url){
_put_curl(raii::string("{\"avatar_url\":\"" + media_url + "\"}"), m_ses->urls.profile_picture(), raii::curl_llist());
return http_status() == 200;
return netreturn<void>(raii::string(), raii::string(), http_status());
}
bool client::set_presence(const raii::string_base& status){
netreturn<void> client::set_presence(const raii::string_base& status){
_put_curl(raii::string("{\"presence\":\""_ss + status + "\"}"), m_ses->urls.presence(m_ses->homeserver, m_ses->access_token, m_ses->userid), raii::curl_llist());
return http_status() == 200;
return netreturn<void>(raii::string(), raii::string(), http_status());
}
raii::rjp_string client::get_presence(const raii::string_base& userid){
netreturn<raii::rjp_string> client::get_presence(const raii::string_base& userid){
return _get_and_find(m_ses->urls.presence(m_ses->homeserver, m_ses->access_token, userid), "presence"_ss);
}
//networked getter
raii::rjp_string client::get_display_name(void)const{
netreturn<raii::rjp_string> client::get_display_name(void)const{
return _get_and_find(m_ses->urls.displayname(), "displayname"_ss);
}
raii::rjp_string client::get_profile_picture(void)const{
netreturn<raii::rjp_string> client::get_profile_picture(void)const{
return _get_and_find(m_ses->urls.profile_picture(), "avatar_url"_ss);
}
raii::rjp_string client::room_alias_to_id(const raii::string_base& alias)const{
netreturn<raii::rjp_string> client::room_alias_to_id(const raii::string_base& alias)const{
auto tmp = m_curl.encode(alias, alias.length());
return _get_and_find(raii::string(m_ses->urls.alias_lookup() + tmp), "room_id"_ss);
}
std::vector<raii::rjp_string> client::list_rooms(void)const{
std::vector<raii::rjp_string> ret;
netreturn<std::vector<raii::rjp_string>> client::list_rooms(void)const{
raii::string reply = _get_curl(m_ses->urls.room_list());
if(!reply)
return ret;
return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply));
netreturn<std::vector<raii::rjp_string>> retval = _create_netreturn(root, http_status());
if(!root)
return ret;
return retval;
RJP_search_res res = rjp_search_member(root.get(), "joined_rooms", 0);
if(!res.value)
return ret;
return retval;
for(RJP_value* v = rjp_get_element(res.value);v;v = rjp_next_element(v)){
ret.emplace_back(v);
retval.value().emplace_back(v);
}
return ret;
return retval;
}
//room membership
raii::rjp_string client::create_room(const raii::string_base& name, const raii::string_base& alias)const{
netreturn<raii::rjp_string> client::create_room(const raii::string_base& name, const raii::string_base& alias)const{
raii::string postdata;
if(alias)
postdata = "{\"name\": \"" + raii::json_escape(name) + "\",\"room_alias_name\": \"" + raii::json_escape(alias) + "\"}";
@ -95,33 +95,33 @@ namespace matrix{
}
//upload media
uploaded_file client::upload_file(const file_details& file)const{
netreturn<uploaded_file> client::upload_file(const file_details& file)const{
return _upload_file(file, raii::curl_llist{});
}
uploaded_image client::upload_image(const image_details& file)const{
uploaded_image ret = {};
netreturn<uploaded_image> client::upload_image(const image_details& file)const{
raii::curl_llist headers(raii::string("Content-Type: "_ss + file.mimetype));
ret = _upload_file(file, headers);
ret.m_width = file.width;
ret.m_height = file.height;
ret.m_mimetype = file.mimetype;
return ret;
netreturn<uploaded_file> upfile = _upload_file(file, headers);
netreturn<uploaded_image> retval(std::move(upfile.mxerror()), std::move(upfile.mxerrorcode()), upfile.httpstatus());
retval.value().m_width = file.width;
retval.value().m_height = file.height;
retval.value().m_mimetype = file.mimetype;
return retval;
}
uploaded_audio client::upload_audio(const audio_details& file)const{
uploaded_audio ret = {};
netreturn<uploaded_audio> client::upload_audio(const audio_details& file)const{
raii::curl_llist headers(raii::string("Content-Type: "_ss + file.mimetype));
ret = _upload_file(file, headers);
ret.m_mimetype = file.mimetype;
return ret;
netreturn<uploaded_file> upfile = _upload_file(file, headers);
netreturn<uploaded_audio> retval(std::move(upfile.mxerror()), std::move(upfile.mxerrorcode()), upfile.httpstatus());
retval.value().m_mimetype = file.mimetype;
return retval;
}
uploaded_video client::upload_video(const video_details& file)const{
uploaded_video ret = {};
netreturn<uploaded_video> client::upload_video(const video_details& file)const{
raii::curl_llist headers(raii::string("Content-Type: "_ss + file.mimetype));
ret = _upload_file(file, headers);
ret.m_width = file.width;
ret.m_height = file.height;
ret.m_mimetype = file.mimetype;
return ret;
netreturn<uploaded_file> upfile = _upload_file(file, headers);
netreturn<uploaded_video> retval(std::move(upfile.mxerror()), std::move(upfile.mxerrorcode()), upfile.httpstatus());
retval.value().m_width = file.width;
retval.value().m_height = file.height;
retval.value().m_mimetype = file.mimetype;
return retval;
}
static size_t _thumbnail_header_callback(char* ptr, size_t size, size_t nmemb, void* userdata){
@ -133,7 +133,7 @@ namespace matrix{
return size*nmemb;
}
bool client::create_thumbnail(uploaded_image& info)const{
netreturn<void> client::create_thumbnail(uploaded_image& info)const{
image_details i;
raii::string reply_header;
if(info.thumb_width() > info.width() || info.thumb_height() > info.height()){
@ -146,21 +146,21 @@ namespace matrix{
i.data = _get_curl_binary(m_ses->urls.file_thumbnail(m_ses->homeserver, info.m_fileurl, info.m_thumb.m_width, info.m_thumb.m_height, "crop"_ss));
m_curl.setopt(CURLOPT_HEADERFUNCTION, NULL);
m_curl.setopt(CURLOPT_HEADERDATA, NULL);
if(!i.data){
return false;
}
if(!i.data)
return netreturn<void>(raii::string(), raii::string(), http_status());
i.width = info.thumb_width();
i.height = info.thumb_height();
i.mimetype = std::move(reply_header);
uploaded_image thumb_data = upload_image(i);
if(!thumb_data.m_fileurl)
return false;
info.m_thumb.m_url = std::move(thumb_data.m_fileurl);
info.m_thumb.m_size = thumb_data.m_filesize;
info.m_thumb.m_mimetype = std::move(thumb_data.m_mimetype);
return true;
netreturn<uploaded_image> thumb_data = upload_image(i);
netreturn<void> retval(std::move(thumb_data.mxerror()), std::move(thumb_data.mxerrorcode()), thumb_data.httpstatus());
if(!thumb_data.ok() || !thumb_data.value().m_fileurl)
return retval;
info.m_thumb.m_url = std::move(thumb_data.value().m_fileurl);
info.m_thumb.m_size = thumb_data.value().m_filesize;
info.m_thumb.m_mimetype = std::move(thumb_data.value().m_mimetype);
return retval;
}
bool client::create_thumbnail(uploaded_video& info)const{
netreturn<void> client::create_thumbnail(uploaded_video& info)const{
return create_thumbnail(static_cast<uploaded_image&>(info));
}
raii::binary client::download_file(const raii::string_base& url){
@ -185,9 +185,8 @@ namespace matrix{
return to_copy;
}
uploaded_file client::_upload_file(const file_details& file, const raii::curl_llist& header)const{
netreturn<uploaded_file> client::_upload_file(const file_details& file, const raii::curl_llist& header)const{
raii::string fileurl;
uploaded_file retval = {};
internal_upload_data upload_data = {file.data.get(), file.data.size()};
m_curl.postreq();
m_curl.setopt(CURLOPT_POSTFIELDS, NULL);
@ -201,21 +200,19 @@ namespace matrix{
m_curl.setwritedata(&fileurl);
bool succ = _perform_curl();
m_curl.setreaddata(NULL);
if(!succ)
return {};
if(!fileurl)
return {};
if(!succ || !fileurl)
return _create_netreturn(fileurl, http_status());
raii::rjp_ptr root(rjp_parse(fileurl));
netreturn<uploaded_file> retval = _create_netreturn(root, http_status());
if(!root)
return {};
return retval;
RJP_search_res res = rjp_search_member(root.get(), "content_uri", 0);
if(!res.value)
return {};
retval.m_fileurl = res.value;
retval.m_filename = file.name;
retval.m_filesize = file.data.size();
return retval;
retval.value().m_fileurl = res.value;
retval.value().m_filename = file.name;
retval.value().m_filesize = file.data.size();
return retval;
}
}

View File

@ -155,19 +155,36 @@ namespace matrix{
return {};
return reply;
}
raii::rjp_string connection::_post_and_find(const raii::string_base& data, const raii::string_base& url,
netreturn<raii::rjp_string> connection::_post_and_find(const raii::string_base& data, const raii::string_base& url,
const raii::curl_llist& header, const raii::string_base& target)const
{
raii::string reply = _post_curl(data, url, header);
if(!reply)
return {};
return _curl_reply_search(reply, target);
return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply));
netreturn<raii::rjp_string> retval = _create_netreturn(root, http_status());
retval.value() = _curl_reply_search(reply, target);
return retval;
}
raii::rjp_string connection::_get_and_find(const raii::string_base& url, const raii::string_base& target)const{
netreturn<raii::rjp_string> connection::_put_and_find(const raii::string_base& data, const raii::string_base& url,
const raii::curl_llist& header, const raii::string_base& target)const
{
raii::string reply = _put_curl(data, url, header);
if(!reply)
return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply));
netreturn<raii::rjp_string> retval = _create_netreturn(root, http_status());
retval.value() = _curl_reply_search(reply, target);
return retval;
}
netreturn<raii::rjp_string> connection::_get_and_find(const raii::string_base& url, const raii::string_base& target)const{
raii::string reply = _get_curl(url);
if(!reply)
return {};
return _curl_reply_search(reply, target);
return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply));
netreturn<raii::rjp_string> retval = _create_netreturn(root, http_status());
retval.value() = _curl_reply_search(reply, target);
return retval;
}
raii::rjp_string connection::_curl_reply_search(const raii::string_base& reply, const raii::string_base& target)const{
raii::rjp_ptr root(rjp_parse(reply));
@ -194,7 +211,7 @@ namespace matrix{
m_curl.setopt(CURLOPT_FOLLOWLOCATION, 1L);
m_curl.forcessl(CURL_SSLVERSION_TLSv1_2);
m_curl.setopt(CURLOPT_TCP_KEEPALIVE, 1L);
m_curl.setopt(CURLOPT_FAILONERROR, 1L);
//m_curl.setopt(CURLOPT_FAILONERROR, 0L);
}
netreturn_base connection::_create_netreturn(const raii::string_base& mxjson, int httpstatus){
if(!mxjson)
@ -205,9 +222,7 @@ namespace matrix{
netreturn_base connection::_create_netreturn(const raii::rjp_ptr& root, int httpstatus){
if(!root)
return netreturn_base("Invalid JSON"_ss, "Invalid JSON"_ss, -1);
raii::rjp_string error = rjp_search_member(root.get(), "error", 0).value;
raii::rjp_string errorcode = rjp_search_member(root.get(), "errorcode", 0).value;
return netreturn_base(std::move(error), std::move(errorcode), httpstatus);
return netreturn_base(rjp_search_member(root.get(), "error", 0).value, rjp_search_member(root.get(), "errorcode", 0).value, httpstatus);
}
}

View File

@ -27,16 +27,25 @@ namespace matrix{
m_error(std::move(error)), m_errorcode(errorcode), m_http_error(httpstatus){}
netreturn_base::netreturn_base(raii::rjp_string&& error, raii::rjp_string&& errorcode, int httpstatus):
m_error(std::move(error)), m_errorcode(std::move(errorcode)), m_http_error(httpstatus){}
netreturn_base::operator bool(void)const{
return m_http_error > 299;
bool netreturn_base::ok(void)const{
return (!has_httperror() && !m_error);
}
const raii::rjp_string netreturn_base::mxerror(void)const{
const raii::rjp_string& netreturn_base::mxerror(void)const{
return m_error;
}
const raii::rjp_string netreturn_base::mxerrorcode(void)const{
const raii::rjp_string& netreturn_base::mxerrorcode(void)const{
return m_errorcode;
}
raii::rjp_string& netreturn_base::mxerror(void){
return m_error;
}
raii::rjp_string& netreturn_base::mxerrorcode(void){
return m_errorcode;
}
int netreturn_base::httpstatus(void)const{
return m_http_error;
}
bool netreturn_base::has_httperror(void)const{
return (m_http_error > 299 || m_http_error < 200);
}
}

View File

@ -134,12 +134,7 @@ namespace matrix{
}
netreturn<raii::rjp_string> roomcxn::redact_event(const raii::string_base& eventid, const raii::string_base& reason)const{
raii::string ret = _put_curl(raii::string("{\"reason\":\"" + reason + "\"}"), m_urls.redact(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), m_curl.encode(eventid)), raii::curl_llist());
if(!ret) return _create_netreturn(ret, http_status());
raii::rjp_ptr root(rjp_parse(ret.get()));
netreturn<raii::rjp_string> retval = _create_netreturn(root, http_status());
retval.value() = _curl_reply_search(root, "event_id"_ss);
return retval;
return _put_and_find(raii::string("{\"reason\":\"" + reason + "\"}"), m_urls.redact(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), m_curl.encode(eventid)), raii::curl_llist(), "event_id"_ss);
}
netreturn<raii::rjp_string> roomcxn::redact_event(const raii::string_base& eventid)const{
return redact_event(eventid, "No reason given"_ss);
@ -173,13 +168,7 @@ namespace matrix{
m_urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid, m_roomid);
}
netreturn<raii::rjp_string> roomcxn::upgrade(int version)const{
raii::string reply = _post_curl(raii::string("{\"new_version\":\""_ss + raii::itostr(version) + "\"}"_ss), m_urls.upgrade(), raii::curl_llist());
if(!reply) return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply));
netreturn<raii::rjp_string> retval = _create_netreturn(root, http_status());
if(!root) return retval;
retval.value() = _curl_reply_search(root, "event_id"_ss);
return retval;
return _post_and_find(raii::string("{\"new_version\":\""_ss + raii::itostr(version) + "\"}"_ss), m_urls.upgrade(), raii::curl_llist(), "event_id"_ss);
}
netreturn<raii::rjp_string> roomcxn::_send_message(const raii::string_base& msg)const{

View File

@ -55,15 +55,15 @@ namespace matrix{
m_ses->access_token = std::move(tok);
}
bool session::login(void){
netreturn<void> session::login(void){
return _do_login(raii::string(), raii::string());
}
bool session::login(const raii::string_base& username, const raii::string_base& pass){
netreturn<void> session::login(const raii::string_base& username, const raii::string_base& pass){
return _do_login(username, pass);
}
bool session::logout(void){
_post_curl(""_ss, m_ses->urls.logout(m_ses->homeserver, m_ses->access_token), raii::curl_llist());
return http_status() == 200;
netreturn<void> session::logout(void){
raii::string reply = _post_curl(""_ss, m_ses->urls.logout(m_ses->homeserver, m_ses->access_token), raii::curl_llist());
return _create_netreturn(reply, http_status());
}
bool session::valid(void)const{
@ -84,26 +84,37 @@ namespace matrix{
m_ses->urls.invalidate_accesstoken();
}
bool session::_do_login(const raii::string_base& username, const raii::string_base& pass){
netreturn<void> session::_do_login(const raii::string_base& username, const raii::string_base& pass){
auto reply = _get_curl(client_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token));
if(!reply){
netreturn<void> retval = _create_netreturn(reply, http_status());
if(!retval.ok()){
if(!username || !pass){
return (m_valid = false);
m_valid = false;
return retval;
}
auto [token, id] = _get_new_access_token(username, pass, client_url_list::login(m_ses->homeserver));
auto newtoken = _get_new_access_token(username, pass, client_url_list::login(m_ses->homeserver));
auto& token = newtoken.value().first;
auto& id = newtoken.value().second;
if(token && id){
m_ses->access_token = std::move(token);
m_ses->userid = std::move(id);
m_ses->urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid);
return (m_valid = true);
m_valid = true;
}else{
return (m_valid = false);
m_valid = false;
}
return netreturn<void>(std::move(newtoken.mxerror()), std::move(newtoken.mxerrorcode()), newtoken.httpstatus());
}else{
m_ses->urls.repopulate_accesstoken(m_ses->homeserver, m_ses->access_token);
m_ses->userid = _get_userid();
netreturn<raii::rjp_string> uid = _get_userid();
if(!uid.ok()){
invalidate();
return netreturn<void>(std::move(uid.mxerror()), std::move(uid.mxerrorcode()), uid.httpstatus());
}
m_ses->userid = std::move(uid.value());
m_ses->urls.repopulate_userid(m_ses->homeserver, m_ses->access_token, m_ses->userid);
return (m_valid = true);
m_valid = true;
return retval;
}
}
void session::_populate_session_info(const auth_data& a){
@ -117,28 +128,21 @@ namespace matrix{
raii::string reply = _post_curl(postdata, loginurl, raii::curl_llist{});
return reply;
}
raii::rjp_string session::_get_userid(void){
auto reply = _get_curl(client_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token));
if(!reply)
return {};
raii::rjp_ptr root(rjp_parse(reply));
if(!root)
return {};
RJP_search_res id = rjp_search_member(root.get(), "user_id", 0);
return raii::rjp_string{id.value};
netreturn<raii::rjp_string> session::_get_userid(void){
return _get_and_find(client_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token), "user_id"_ss);
}
std::pair<raii::rjp_string,raii::rjp_string> session::_get_new_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl){
netreturn<std::pair<raii::rjp_string,raii::rjp_string>> session::_get_new_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl){
raii::string reply = _request_access_token(name, pass, loginurl);
if(!reply)
return {};
return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply));
netreturn<std::pair<raii::rjp_string,raii::rjp_string>> retval = _create_netreturn(root, http_status());
if(!root)
return {};
std::pair<raii::rjp_string,raii::rjp_string> retval;
return retval;
RJP_search_res token = rjp_search_member(root.get(), "access_token", 0);
retval.first = raii::rjp_string{token.value};
retval.value().first = raii::rjp_string{token.value};
token = rjp_search_member(root.get(), "user_id", 0);
retval.second = raii::rjp_string{token.value};
retval.value().second = raii::rjp_string{token.value};
return retval;
}
}

View File

@ -25,19 +25,21 @@ namespace matrix{
syncer::syncer(const std::shared_ptr<internal::session_info>& ses):
connection(ses){}
sync::response syncer::sync(size_t timeout){
netreturn<sync::response> syncer::sync(size_t timeout){
raii::string reply = _get_curl(m_ses->urls.sync(m_ses->homeserver, m_ses->access_token, m_next_batch, raii::itostr(timeout)));
if(!reply)
return {nullptr};
return netreturn<sync::response>(raii::string(), raii::string(), http_status(), {nullptr});
raii::rjp_ptr root(rjp_parse(reply));
netreturn<sync::response> retval = _create_netreturn(root, http_status());
if(!root)
return reply;
return retval;
RJP_search_res res = rjp_search_member(root.get(), "next_batch", 0);
if(!res.value)
return reply;
return retval;
m_next_batch = res.value;
return sync::response(root.release());
retval.value() = sync::response(root.release());
return retval;
}
}

View File

@ -35,7 +35,7 @@ void sync_fn(matrix::syncer syn, std::atomic_bool& should_quit){
printf("continuing\n");
while(!should_quit){
auto sync_reply = syn.sync(30000);
for(auto room : sync_reply.room_join_events()){
for(auto room : sync_reply.value().room_join_events()){
for(auto event : room.timeline_events()){
printf("%s\n", event.sender().get());
}
@ -74,21 +74,18 @@ int main(){
auto syn = ses.spawn_syncer();
auto client = ses.spawn_client();
auto room = client.spawn_room("!IaZlRZWhZiNMMsiZRl:rexy712.chickenkiller.com"_ss);
auto reply = std::move(room.get_events_backward(5).value());
printf("%s\n", reply.start_token().get());
printf("%s\n", reply.end_token().get());
for(auto event : reply){
printf("%s\n", event.eventid().get());
}
syn.sync(0);
auto status = room.send_message("gay"_ss);
if(!status.ok())
fprintf(stderr, "http error: %d\n", status.httpstatus());
if(status.mxerror())
fprintf(stderr, "matrix error: %s\n", status.mxerror().get());
//auto room = ses.spawn_client().spawn_room("!OwuhlJnHlsmyPwiLIH:rexy712.chickenkiller.com"_ss);
//printf("%s\n", room.get_events_backward(1).get());
std::thread sync_thread(sync_fn, ses.spawn_syncer(), std::ref(should_quit));
//std::thread sync_thread(sync_fn, ses.spawn_syncer(), std::ref(should_quit));
//std::thread key_thread(keyboard_fn, ses.spawn_client().spawn_room("!cEIFONpAlHTbGBUFAE:rexy712.chickenkiller.com"_ss), std::ref(should_quit));
//one of these threads will always hang until another input is recieved
sync_thread.join();
//sync_thread.join();
//key_thread.join();
}