From ed2af27652110cd6037d9baab1f79cf0b88d162d Mon Sep 17 00:00:00 2001 From: rexy712 Date: Fri, 29 Mar 2019 17:23:29 -0700 Subject: [PATCH] Better organized matrix urls --- doc/TODO | 4 -- include/matrix.hpp | 44 +++++++++---- src/matrix.cpp | 151 +++++++++++++++++++++++++++++---------------- 3 files changed, 131 insertions(+), 68 deletions(-) diff --git a/doc/TODO b/doc/TODO index c745dc3..55998f4 100644 --- a/doc/TODO +++ b/doc/TODO @@ -6,12 +6,8 @@ general/other: register libav in the libav namespace somewhere matrix: - thread pool for workers. rehurn std::promise? handle user admin levels - ignore own messages/invites handle events other than user messages - organize matrix urls. Prevent reallocation of reusable urls. - generate nonreusable urls for matrix in an organized manner. ignore old messages based on value of 'age' parameter? reddit: diff --git a/include/matrix.hpp b/include/matrix.hpp index 740ebae..6eb0f8e 100644 --- a/include/matrix.hpp +++ b/include/matrix.hpp @@ -134,30 +134,52 @@ namespace matrix{ class bot { private: - struct mat_url_list{ + class mat_url_list + { + private: + raii::string m_create_room; + raii::string m_file_upload; + raii::string m_room_list; + raii::string m_login; + raii::string m_alias_lookup; + raii::string m_whoami; + raii::string m_displayname; + raii::string m_profile_picture; + + public: mat_url_list(void) = default; mat_url_list(const raii::string_base& homeserver); - mat_url_list(const raii::string_base& homeserver, const raii::string_base& access_token); + mat_url_list(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid); mat_url_list(const mat_url_list&) = default; mat_url_list(mat_url_list&&) = default; mat_url_list& operator=(const mat_url_list&) = default; mat_url_list& operator=(mat_url_list&&) = default; - void repopulate_accesstoken(const raii::string_base& homeserver, const raii::string_base& access_token); - void repopulate(const raii::string_base& homeserver, const raii::string_base& access_token); - void invalidate_accesstoken(void); + const raii::string& create_room(void)const; + const raii::string& file_upload(void)const; + const raii::string& room_list(void)const; + const raii::string& login(void)const; + const raii::string& alias_lookup(void)const; + const raii::string& whoami(void)const; + const raii::string& displayname(void)const; + const raii::string& profile_picture(void)const; + raii::string logout(const raii::string_base& homeserver, const raii::string_base& access_token)const; + raii::string join_room(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const; + raii::string sync(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& next_batch, const raii::string_base& timeout)const; + raii::string read_receipt(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid, const raii::string_base& eventid)const; + raii::string send(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const; - raii::string create_room; - raii::string file_upload; - raii::string room_list; - raii::string login; - raii::string alias_lookup; - raii::string whoami; + void repopulate_accesstoken(const raii::string_base& homeserver, const raii::string_base& access_token); + void repopulate_userid(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid); + void repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid); + void invalidate_accesstoken(void); private: void _initial_populate(const raii::string_base& homeserver); static constexpr const char* s_proto = "https://"; + static constexpr const char* s_revision = "r0"; }; + private: mutable raii::curler m_curl; //https access raii::string m_useragent; //useragent to identify our application diff --git a/src/matrix.cpp b/src/matrix.cpp index 9f68ebc..2bff23a 100644 --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -52,35 +52,6 @@ namespace matrix{ details[3].value}; } - bot::mat_url_list::mat_url_list(const raii::string_base& homeserver){ - _initial_populate(homeserver); - } - bot::mat_url_list::mat_url_list(const raii::string_base& homeserver, const raii::string_base& access_token){ - repopulate(homeserver, access_token); - } - void bot::mat_url_list::repopulate_accesstoken(const raii::string_base& homeserver, const raii::string_base& access_token){ - create_room = s_proto + homeserver + "/_matrix/client/r0/createRoom?access_token=" + access_token; - file_upload = s_proto + homeserver + "/_matrix/media/r0/upload?access_token=" + access_token; - room_list = s_proto + homeserver + "/_matrix/client/r0/joined_rooms?access_token=" + access_token; - whoami = s_proto + homeserver + "/_matrix/client/r0/account/whoami?access_token=" + access_token; - } - void bot::mat_url_list::repopulate(const raii::string_base& homeserver, const raii::string_base& access_token){ - repopulate_accesstoken(homeserver, access_token); - _initial_populate(homeserver); - } - void bot::mat_url_list::invalidate_accesstoken(void){ - create_room.reset(); - file_upload.reset(); - room_list.reset(); - whoami.reset(); - } - void bot::mat_url_list::_initial_populate(const raii::string_base& homeserver){ - alias_lookup = s_proto + homeserver + "/_matrix/client/r0/directory/room/"; - login = s_proto + homeserver + "/_matrix/client/r0/login"; - } - - - bot::bot(const auth_data& a, const raii::string_base& useragent): m_curl(), m_useragent(useragent), @@ -113,19 +84,19 @@ namespace matrix{ } void bot::set_display_name(const raii::string_base& newname){ - raii::string reply = _put_curl(raii::string("{\"displayname\":\"" + newname + "\"}"), raii::string("https://" + m_homeserver + "/_matrix/client/r0/profile/" + m_userid + "/displayname?access_token=" + m_access_token), raii::curl_llist()); + raii::string reply = _put_curl(raii::string("{\"displayname\":\"" + newname + "\"}"), m_urls.displayname(), raii::curl_llist()); } void bot::set_profile_picture(const raii::string_base& media_url){ - raii::string reply = _put_curl(raii::string("{\"avatar_url\":\"" + media_url + "\"}"), raii::string("https://" + m_homeserver + "/_matrix/client/r0/profile/" + m_curl.encode(m_userid) + "/avatar_url?access_token=" + m_access_token), raii::curl_llist()); + raii::string reply = _put_curl(raii::string("{\"avatar_url\":\"" + media_url + "\"}"), m_urls.profile_picture(), raii::curl_llist()); } raii::rjp_string bot::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_urls.alias_lookup + tmp), "room_id"_ss); + return _get_and_find(raii::string(m_urls.alias_lookup() + tmp), "room_id"_ss); } std::vector bot::list_rooms(void)const{ std::vector ret; - raii::string reply = _get_curl(m_urls.room_list); + raii::string reply = _get_curl(m_urls.room_list()); if(!reply) return ret; @@ -150,11 +121,10 @@ namespace matrix{ else postdata = "{\"name\": \"" + raii::json_escape(name) + "\"}"; - return _post_curl(postdata, m_urls.create_room, raii::curl_llist()); + return _post_curl(postdata, m_urls.create_room(), raii::curl_llist()); } bool bot::join_room(const raii::string_base& roomid)const{ - raii::string url = "https://" + m_homeserver + "/_matrix/client/r0/rooms/" + m_curl.encode(roomid) + "/join?access_token=" + m_access_token; - return _post_curl(raii::string(), url, raii::curl_llist()); + return _post_curl(raii::string(), m_urls.join_room(m_homeserver, m_access_token, m_curl.encode(roomid)), raii::curl_llist()); } file_info bot::upload_file(const raii::string_base& filename)const{ return upload_file(filename, raii::static_string()); @@ -232,7 +202,7 @@ namespace matrix{ std::vector thumb_data = _load_image_thumbnail_info(image, ret, type); if(thumb_data.size()) - ret.thumburl = _post_and_find(raii::static_string(thumb_data.data(), thumb_data.size()), m_urls.file_upload, header, "content_uri"_ss); + ret.thumburl = _post_and_find(raii::static_string(thumb_data.data(), thumb_data.size()), m_urls.file_upload(), header, "content_uri"_ss); return ret; } @@ -364,7 +334,7 @@ namespace matrix{ ret.thumb_width = thumbw; ret.thumb_height = thumbh; ret.thumbsize = packet->size; - ret.thumburl = _post_and_find(raii::static_string((char*)packet->data, packet->size), m_urls.file_upload, header, "content_uri"_ss); + ret.thumburl = _post_and_find(raii::static_string((char*)packet->data, packet->size), m_urls.file_upload(), header, "content_uri"_ss); packet.reset(); } @@ -427,16 +397,11 @@ namespace matrix{ return _send_message(room, detail::_message_body(text)); } void bot::logout(void){ - _get_curl(raii::string("https://" + m_homeserver + "/_matrix/client/r0/logout?access_token=" + m_access_token)); + _get_curl(m_urls.logout(m_homeserver, m_access_token)); m_urls.invalidate_accesstoken(); } raii::string bot::sync(size_t timeout){ - raii::string url; - if(m_next_batch) - url = "https://" + m_homeserver + "/_matrix/client/r0/sync?access_token=" + m_access_token + "&timeout=" + raii::itostr(timeout) + "&since=" + m_next_batch; - else - url = "https://" + m_homeserver + "/_matrix/client/r0/sync?access_token=" + m_access_token + "&timeout=" + raii::itostr(timeout); - raii::string reply = _get_curl(url); + raii::string reply = _get_curl(m_urls.sync(m_homeserver, m_access_token, m_next_batch, raii::itostr(timeout))); raii::rjp_ptr root(rjp_parse(reply)); if(!root) @@ -512,8 +477,7 @@ namespace matrix{ } void bot::_send_read_receipt(const raii::string_base& roomid, const raii::string_base& eventid)const{ - raii::string url = "https://" + m_homeserver + "/_matrix/client/r0/rooms/" + m_curl.encode(roomid) + "/receipt/m.read/" + m_curl.encode(eventid) + "?access_token=" + m_access_token; - _post_curl(""_ss, url, raii::curl_llist()); + _post_curl(""_ss, m_urls.read_receipt(m_homeserver, m_access_token, m_curl.encode(roomid), m_curl.encode(eventid)), raii::curl_llist()); } raii::rjp_string bot::_upload_file(raii::filerd& fp, const raii::curl_llist& header)const{ raii::string fileurl; @@ -522,7 +486,7 @@ namespace matrix{ m_curl.setopt(CURLOPT_READDATA, (void*)fp.get()); m_curl.setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)fp.length()); m_curl.setopt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)fp.length()); - m_curl.seturl(m_urls.file_upload); + m_curl.seturl(m_urls.file_upload()); m_curl.setheader(header); m_curl.setopt(CURLOPT_WRITEFUNCTION, _post_reply_curl_callback); m_curl.setopt(CURLOPT_WRITEDATA, &fileurl); @@ -544,7 +508,7 @@ namespace matrix{ raii::rjp_string bot::_send_message(const raii::string_base& room, const raii::string_base& msg)const{ raii::rjp_string reply = _post_and_find( msg, - raii::string("https://" + m_homeserver + "/_matrix/client/r0/rooms/" + m_curl.encode(room) + "/send/m.room.message?access_token=" + m_access_token), + m_urls.send(m_homeserver, m_access_token, m_curl.encode(room)), raii::curl_llist(), "event_id"_ss); return reply; @@ -652,7 +616,7 @@ namespace matrix{ raii::string postdata("{\"type\":\"m.login.password\", \"user\":\"" + raii::json_escape(a.bot_name) + "\", \"password\":\"" + raii::json_escape(a.bot_pass) + "\"}"); raii::string reply; - m_curl.seturl(m_urls.login); + m_curl.seturl(m_urls.login()); m_curl.setpostdata(postdata); m_curl.postreq(); m_curl.setopt(CURLOPT_WRITEFUNCTION, _post_reply_curl_callback); @@ -669,8 +633,8 @@ namespace matrix{ _set_curl_defaults(); if(a.access_token){ m_access_token = a.access_token; - m_urls = mat_url_list(m_homeserver, m_access_token); - raii::string reply = _get_curl(m_urls.whoami); + m_urls.repopulate_accesstoken(m_homeserver, m_access_token); + raii::string reply = _get_curl(m_urls.whoami()); if(!reply) return; raii::rjp_ptr root(rjp_parse(reply)); @@ -678,6 +642,7 @@ namespace matrix{ return; RJP_search_res id = rjp_search_member(root.get(), "user_id", 0); m_userid = raii::rjp_string(id.value); + m_urls.repopulate_userid(m_homeserver, m_access_token, m_curl.encode(m_userid)); }else{ m_urls = mat_url_list(m_homeserver); raii::string reply = _request_access_token(a); @@ -688,11 +653,91 @@ namespace matrix{ return; RJP_search_res token = rjp_search_member(root.get(), "access_token", 0); m_access_token = raii::rjp_string{token.value}; - m_urls = mat_url_list(m_homeserver, m_access_token); token = rjp_search_member(root.get(), "user_id", 0); m_userid = raii::rjp_string{token.value}; + m_urls.repopulate_accesstoken(m_homeserver, m_access_token); + m_urls.repopulate_userid(m_homeserver, m_access_token, m_curl.encode(m_userid)); } } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + bot::mat_url_list::mat_url_list(const raii::string_base& homeserver){ + _initial_populate(homeserver); + } + bot::mat_url_list::mat_url_list(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid){ + repopulate(homeserver, access_token, userid); + } + void bot::mat_url_list::repopulate_accesstoken(const raii::string_base& homeserver, const raii::string_base& access_token){ + m_create_room = s_proto + homeserver + "/_matrix/client/r0/createRoom?access_token=" + access_token; + m_file_upload = s_proto + homeserver + "/_matrix/media/r0/upload?access_token=" + access_token; + m_room_list = s_proto + homeserver + "/_matrix/client/r0/joined_rooms?access_token=" + access_token; + m_whoami = s_proto + homeserver + "/_matrix/client/r0/account/whoami?access_token=" + access_token; + } + void bot::mat_url_list::repopulate_userid(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid){ + m_displayname = s_proto + homeserver + "/_matrix/client/r0/profile/" + userid + "/displayname?access_token=" + access_token; + m_profile_picture = s_proto + homeserver + "/_matrix/client/r0/profile/" + userid + "/avatar_url?access_token=" + access_token; + } + void bot::mat_url_list::repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid){ + _initial_populate(homeserver); + repopulate_accesstoken(homeserver, access_token); + repopulate_userid(homeserver, access_token, userid); + } + void bot::mat_url_list::invalidate_accesstoken(void){ + m_create_room.reset(); + m_file_upload.reset(); + m_room_list.reset(); + m_whoami.reset(); + m_displayname.reset(); + m_profile_picture.reset(); + } + const raii::string& bot::mat_url_list::create_room(void)const{ + return m_create_room; + } + const raii::string& bot::mat_url_list::file_upload(void)const{ + return m_file_upload; + } + const raii::string& bot::mat_url_list::room_list(void)const{ + return m_room_list; + } + const raii::string& bot::mat_url_list::login(void)const{ + return m_login; + } + const raii::string& bot::mat_url_list::alias_lookup(void)const{ + return m_alias_lookup; + } + const raii::string& bot::mat_url_list::whoami(void)const{ + return m_whoami; + } + const raii::string& bot::mat_url_list::displayname(void)const{ + return m_displayname; + } + const raii::string& bot::mat_url_list::profile_picture(void)const{ + return m_profile_picture; + } + raii::string bot::mat_url_list::logout(const raii::string_base& homeserver, const raii::string_base& access_token)const{ + return raii::string(s_proto + homeserver + "/_matrix/client/r0/logout?access_token=" + access_token); + } + raii::string bot::mat_url_list::join_room(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const{ + return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/join?access_token=" + access_token); + } + raii::string bot::mat_url_list::sync(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& next_batch, const raii::string_base& timeout)const{ + if(!next_batch) + return raii::string(s_proto + homeserver + "/_matrix/client/r0/sync?access_token=" + access_token + "&timeout=" + timeout); + return raii::string(s_proto + homeserver + "/_matrix/client/r0/sync?access_token=" + access_token + "&timeout=" + timeout + "&since=" + next_batch); + } + raii::string bot::mat_url_list::read_receipt(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid, const raii::string_base& eventid)const{ + return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/receipt/m.read/" + eventid + "?access_token=" + access_token); + } + raii::string bot::mat_url_list::send(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const{ + return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/send/m.room.message?access_token=" + access_token); + + } + void bot::mat_url_list::_initial_populate(const raii::string_base& homeserver){ + m_alias_lookup = s_proto + homeserver + "/_matrix/client/r0/directory/room/"; + m_login = s_proto + homeserver + "/_matrix/client/r0/login"; + } + }