matrix_thing/src/matrix/roomcxn.cpp
2019-09-18 18:10:27 -07:00

145 lines
5.9 KiB
C++

/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix/roomcxn.hpp"
#include "raii/static_string.hpp"
#include "matrix/fat_strings.hpp"
#include "raii/util.hpp"
#include "raii/rjp_ptr.hpp"
#include <utility> //move
#include <map>
namespace matrix{
roomcxn::roomcxn(const std::shared_ptr<internal::session_info>& ses, const raii::string_base& roomid):
roomcxn(ses, raii::string(roomid)){}
roomcxn::roomcxn(const std::shared_ptr<internal::session_info>& ses, raii::string&& roomid):
connection(ses),
m_roomid(std::move(roomid)),
m_urls(ses->homeserver, ses->access_token, m_curl.encode(m_roomid), ses->userid){}
bool roomcxn::join_room(void)const{
return _post_curl(raii::string(), m_urls.join_room(), raii::curl_llist());
}
bool roomcxn::leave_room(void)const{
return _post_curl(raii::string(), m_urls.leave_room(), raii::curl_llist());
}
bool roomcxn::accept_invite(void)const{
return join_room();
}
bool roomcxn::reject_invite(void)const{
return leave_room();
}
std::vector<raii::rjp_string> roomcxn::members(void)const{
std::vector<raii::rjp_string> retval;
raii::string resp = _get_curl(m_urls.room_members());
if(!resp) return {};
raii::rjp_ptr root(rjp_parse(resp.get()));
if(!root) return {};
RJP_search_res res = rjp_search_member(root.get(), "joined", 0);
if(!res.value) return{};
for(RJP_value* mem = rjp_get_member(res.value);mem;mem = rjp_next_member(mem)){
raii::rjp_string tmp = raii::rjp_string_from_key(mem);
retval.emplace_back(std::move(tmp));
}
return retval;
}
raii::rjp_string roomcxn::send_custom_event(const raii::string_base& event, const raii::string_base& eventtype)const{
return _post_and_find(
event,
m_urls.send(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), eventtype),
raii::curl_llist(),
"event_id"_ss);
}
raii::rjp_string roomcxn::send_message(const raii::string_base& text)const{
return _send_message(detail::_message_body(text));
}
raii::rjp_string roomcxn::send_file(const uploaded_file& file)const{
return _send_message(detail::_file_body(file));
}
raii::rjp_string roomcxn::send_image(const uploaded_image& image)const{
return _send_message(detail::_image_body(image));
}
raii::rjp_string roomcxn::send_video(const uploaded_video& video)const{
return _send_message(detail::_video_body(video));
}
raii::rjp_string roomcxn::send_audio(const uploaded_audio& audio)const{
return _send_message(detail::_audio_body(audio));
}
bool roomcxn::send_typing(bool active, int timeout)const{
if(active)
return _put_curl(raii::string("{\"timeout\":" + raii::itostr(timeout) + ",\"typing\":true}"), m_urls.typing(), raii::curl_llist());
else
return _put_curl("{\"typing\":false}"_ss, m_urls.typing(), raii::curl_llist());
}
bool roomcxn::send_read_receipt(const raii::string_base& eventid)const{
return _post_curl(""_ss, m_urls.read_receipt(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), m_curl.encode(eventid)), raii::curl_llist());
}
raii::rjp_string roomcxn::redact_event(const raii::string_base& eventid, const raii::string_base& reason)const{
auto 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 {};
raii::rjp_ptr root(rjp_parse(ret.get()));
if(!root) return {};
RJP_search_res res = rjp_search_member(root.get(), "event_id", 0);
if(!res.value) return {};
return raii::rjp_string(res.value);
}
raii::rjp_string roomcxn::redact_event(const raii::string_base& eventid)const{
return redact_event(eventid, "No reason given"_ss);
}
sync::roomcxn_message_event_list roomcxn::_get_events(int amount, raii::static_string direction, const raii::string_base& from, const raii::string_base& to){
raii::string reply = _get_curl(m_urls.messages(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), from, to, direction, amount));
if(!reply) return {};
raii::rjp_ptr root(rjp_parse(reply.get()));
if(!root.get()) return {};
RJP_value* chunk = rjp_search_member(root.get(), "chunk", 0).value;
if(!chunk) return {};
return sync::roomcxn_message_event_list(root, rjp_get_element(chunk), m_roomid);
}
sync::roomcxn_message_event_list roomcxn::get_events_forward(int amount){
return _get_events(amount, "f"_ss, ""_ss, ""_ss);
}
sync::roomcxn_message_event_list roomcxn::get_events_backward(int amount){
return _get_events(amount, "b"_ss, ""_ss, ""_ss);
}
sync::roomcxn_message_event_list roomcxn::get_events_forward(int amount, const raii::string_base& from, const raii::string_base& to){
return _get_events(amount, "f"_ss, from, to);
}
sync::roomcxn_message_event_list roomcxn::get_events_backward(int amount, const raii::string_base& from, const raii::string_base& to){
return _get_events(amount, "b"_ss, from, to);
}
void roomcxn::regenerate_urls(void){
m_urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid, m_roomid);
}
raii::rjp_string roomcxn::upgrade(int version)const{
return _post_and_find(raii::string("{\"new_version\":\""_ss + raii::itostr(version) + "\"}"_ss), m_urls.upgrade(), raii::curl_llist(), "replacement_room"_ss);
}
raii::rjp_string roomcxn::_send_message(const raii::string_base& msg)const{
return send_custom_event(msg, "m.room.message"_ss);
}
}