matrix_thing/src/matrix/roomcxn.cpp

197 lines
8.9 KiB
C++

/**
This file is a part of rexy's matrix client
Copyright (C) 2019-2020 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 <rexy/string_base.hpp>
#include "matrix/fat_strings.hpp"
#include "matrix/json_targets.hpp"
#include "raii/util.hpp"
#include "raii/rjp_ptr.hpp"
#include <utility> //move
namespace matrix{
roomcxn::roomcxn(const std::shared_ptr<session_info>& ses, const rexy::string_base& roomid):
roomcxn(ses, rexy::string(roomid)){}
roomcxn::roomcxn(const std::shared_ptr<session_info>& ses, rexy::string&& roomid):
connection(ses),
m_roomid(std::move(roomid)),
m_urls(*ses, m_curl.encode(m_roomid)){}
netreturn<void> roomcxn::join(void)const{
rexy::string response = _post_curl(rexy::string(), m_urls.join(*m_ses, m_roomid), raii::curl_llist());
return _create_netreturn(response, http_status());
}
netreturn<void> roomcxn::leave(void)const{
rexy::string response = _post_curl(rexy::string(), m_urls.leave(*m_ses, m_roomid), raii::curl_llist());
return _create_netreturn(response, http_status());
}
netreturn<void> roomcxn::forget(void)const{
rexy::string response = _post_curl(rexy::string(), m_urls.forget(*m_ses, m_roomid), raii::curl_llist());
return _create_netreturn(response, http_status());
}
netreturn<void> roomcxn::accept_invite(void)const{
return join();
}
netreturn<void> roomcxn::reject_invite(void)const{
return leave();
}
netreturn<std::vector<raii::rjp_string>> roomcxn::members(void)const{
netreturn<std::vector<raii::rjp_string>> retval;
rexy::string resp = _get_curl(m_urls.room_members());
if(!resp) return _create_netreturn(resp, http_status());
raii::rjp_ptr root(rjp_parse(resp.get()));
if(!root) return _create_netreturn(root, http_status());
RJP_value* res = rjp_search_member(root.get(), json::keys::joined());
if(!res) return _create_netreturn(root, http_status());
raii::rjp_object_iterator it(res);
for(raii::rjp_object_iterator it = res;*it;++it){
raii::rjp_string tmp(rjp_member_key(*it)->value, rjp_member_key(*it)->length);
retval.value().emplace_back(std::move(tmp));
}
return retval;
}
netreturn<void> roomcxn::invite(const rexy::string_base& userid){
rexy::string json(json::_userid(userid));
printf("%s\n", json.get());
rexy::string response = _post_curl(json, m_urls.invite(), raii::curl_llist());
return _create_netreturn(response, http_status());
}
netreturn<void> roomcxn::uninvite(const rexy::string_base& userid, const rexy::string_base& reason){
return kick(userid, reason);
}
netreturn<void> roomcxn::kick(const rexy::string_base& userid, const rexy::string_base& reason){
rexy::string response;
if(reason){
response = _post_curl(json::_userid_reason(userid, reason), m_urls.kick(), raii::curl_llist());
}else{
response = _post_curl(json::_userid(userid), m_urls.kick(), raii::curl_llist());
}
return _create_netreturn(response, http_status());
}
netreturn<void> roomcxn::ban(const rexy::string_base& userid, const rexy::string_base& reason){
rexy::string response;
if(reason){
response = _post_curl(json::_userid_reason(userid, reason), m_urls.ban(), raii::curl_llist());
}else{
response = _post_curl(json::_userid(userid), m_urls.ban(), raii::curl_llist());
}
return _create_netreturn(response, http_status());
}
netreturn<void> roomcxn::unban(const rexy::string_base& userid){
rexy::string response = _post_curl(json::_userid(userid), m_urls.unban(), raii::curl_llist());
return _create_netreturn(response, http_status());
}
netreturn<raii::rjp_string> roomcxn::send_custom_event(const rexy::string_base& event, const rexy::string_base& eventtype)const{
rexy::string reply = _post_curl(event, m_urls.send(*m_ses, m_curl.encode(m_roomid), eventtype), 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());
retval.value() = _curl_reply_search(root, json::keys::event::eventid());
return retval;
}
netreturn<raii::rjp_string> roomcxn::send_message(const rexy::string_base& text)const{
return _send_message(json::_message_body(text));
}
netreturn<raii::rjp_string> roomcxn::send_notice(const rexy::string_base& text)const{
return _send_message(json::_notice_body(text));
}
netreturn<raii::rjp_string> roomcxn::send_file(const uploaded_file& file)const{
return _send_message(json::_file_body(file));
}
netreturn<raii::rjp_string> roomcxn::send_image(const uploaded_image& image)const{
return _send_message(json::_image_body(image));
}
netreturn<raii::rjp_string> roomcxn::send_video(const uploaded_video& video)const{
return _send_message(json::_video_body(video));
}
netreturn<raii::rjp_string> roomcxn::send_audio(const uploaded_audio& audio)const{
return _send_message(json::_audio_body(audio));
}
netreturn<raii::rjp_string> roomcxn::forward_event(const sync::room_event& event)const{
raii::rjp_string content = rjp_to_json(event.content(), RJP_FORMAT_NONE);
return send_custom_event(content, event.type());
}
netreturn<void> roomcxn::send_typing(bool active, int timeout)const{
return _create_netreturn(_put_curl(json::_typing(active, timeout), m_urls.typing(), raii::curl_llist()), http_status());
}
netreturn<void> roomcxn::send_read_receipt(const rexy::string_base& eventid)const{
return _create_netreturn(_post_curl(rexy::string(), m_urls.read_receipt(*m_ses, m_curl.encode(m_roomid), m_curl.encode(eventid)), raii::curl_llist()), http_status());
}
netreturn<sync::roomcxn_message_event_list> roomcxn::get_event(const rexy::string_base& eventid)const{
rexy::string reply = _get_curl(m_urls.event(*m_ses, m_curl.encode(m_roomid), eventid));
if(!reply) return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply.get()));
if(!root.get()) _create_netreturn(root, http_status());
netreturn<sync::roomcxn_message_event_list> retval = _create_netreturn(root, http_status());
retval.value() = sync::roomcxn_message_event_list(root, root.get(), m_roomid);
return retval;
}
netreturn<raii::rjp_string> roomcxn::redact_event(const rexy::string_base& eventid, const rexy::string_base& reason)const{
return _put_and_find(json::_redact(reason), m_urls.redact(*m_ses, m_curl.encode(m_roomid), m_curl.encode(eventid)), raii::curl_llist(), json::keys::event::eventid());
}
netreturn<raii::rjp_string> roomcxn::redact_event(const rexy::string_base& eventid)const{
return redact_event(eventid, "No reason given"_ss);
}
netreturn<sync::roomcxn_message_event_list> roomcxn::_get_events(int amount, rexy::static_string direction, const rexy::string_base& from, const rexy::string_base& to){
rexy::string reply = _get_curl(m_urls.messages(*m_ses, m_curl.encode(m_roomid), from, to, direction, amount));
if(!reply) return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply.get()));
if(!root.get()) _create_netreturn(root, http_status());
netreturn<sync::roomcxn_message_event_list> retval = _create_netreturn(root, http_status());
RJP_value* chunk = rjp_search_member(root.get(), json::keys::chunk());
if(!chunk) return retval;
raii::rjp_array_iterator it(chunk);
retval.value() = sync::roomcxn_message_event_list(root, *it, m_roomid);
return retval;
}
netreturn<sync::roomcxn_message_event_list> roomcxn::get_events_forward(int amount){
return _get_events(amount, "f"_ss, rexy::string(), rexy::string());
}
netreturn<sync::roomcxn_message_event_list> roomcxn::get_events_backward(int amount){
return _get_events(amount, "b"_ss, rexy::string(), rexy::string());
}
netreturn<sync::roomcxn_message_event_list> roomcxn::get_events_forward(int amount, const rexy::string_base& from, const rexy::string_base& to){
return _get_events(amount, "f"_ss, from, to);
}
netreturn<sync::roomcxn_message_event_list> roomcxn::get_events_backward(int amount, const rexy::string_base& from, const rexy::string_base& to){
return _get_events(amount, "b"_ss, from, to);
}
void roomcxn::regenerate_urls(void){
m_urls.repopulate(*m_ses, m_roomid);
}
netreturn<raii::rjp_string> roomcxn::upgrade(int version)const{
return _post_and_find(json::_room_upgrade(version), m_urls.upgrade(*m_ses, m_roomid), raii::curl_llist(), json::keys::event::eventid());
}
netreturn<raii::rjp_string> roomcxn::_send_message(const rexy::string_base& msg)const{
return send_custom_event(msg, "m.room.message"_ss);
}
}