/** 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 . */ #include "matrix/fat_strings.hpp" #include "matrix/upload_info.hpp" #include "raii/string_base.hpp" #include "matrix/json_targets.hpp" #include "raii/util.hpp" namespace matrix::json{ static constexpr auto quote(const raii::string_base& str){ return "\"" + str + "\""; } static constexpr auto key(const raii::string_base& str){ return "\"" + str + "\":"; } static constexpr raii::static_string open_brace(void){ return "{"_ss; } static constexpr raii::static_string close_brace(void){ return "}"_ss; } static constexpr raii::static_string comma(void){ return ","_ss; } template static constexpr auto object_impl(Arg&& arg, Args&&... args){ if constexpr(sizeof...(args) > 0){ return arg + comma() + object_impl(std::forward(args)...); }else{ return std::forward(arg); } } template static constexpr auto object(Args&&... args){ return open_brace() + object_impl(std::forward(args)...) + close_brace(); } template static constexpr auto member(Str1&& k, Str2&& value){ return key(k) + value; } raii::static_string _empty(void){ return "{}"_ss; } raii::string _image_body(const uploaded_image& image){ raii::string url = raii::json_escape(image.url()); const raii::string_base* thumburl; if(image.thumb_url()) thumburl = &image.thumb_url(); else thumburl = &url; return raii::string( object( member(json::keys::message::body(), quote(raii::json_escape(image.name()))), member(json::keys::message::info(), object( member(json::keys::message::infobody::height(), raii::itostr(image.height())), member(json::keys::message::infobody::mimetype(), quote(image.mimetype())), member(json::keys::message::infobody::size(), raii::itostr(image.size())), member(json::keys::message::infobody::thumbinfo(), object( member(json::keys::message::infobody::thumbnail::height(), raii::itostr(image.thumb_height())), member(json::keys::message::infobody::thumbnail::mimetype(), quote(image.thumb_mimetype())), member(json::keys::message::infobody::thumbnail::size(), raii::itostr(image.thumb_size())), member(json::keys::message::infobody::thumbnail::width(), raii::itostr(image.thumb_width())) )), member(json::keys::message::infobody::thumburl(), quote(raii::json_escape(*thumburl))), member(json::keys::message::infobody::width(), raii::itostr(image.width())) )), member(json::keys::message::msgtype(), quote("m.image"_ss)), member(json::keys::message::url(), quote(raii::json_escape(url))) )); } raii::string _video_body(const uploaded_video& video){ return raii::string( object( member(json::keys::message::body(), quote(raii::json_escape(video.name()))), member(json::keys::message::info(), object( member(json::keys::message::infobody::height(), raii::itostr(video.height())), member(json::keys::message::infobody::mimetype(), quote(video.mimetype())), member(json::keys::message::infobody::size(), raii::itostr(video.size())), member(json::keys::message::infobody::thumbinfo(), object( member(json::keys::message::infobody::thumbnail::height(), raii::itostr(video.thumb_height())), member(json::keys::message::infobody::thumbnail::mimetype(), quote(video.thumb_mimetype())), member(json::keys::message::infobody::thumbnail::size(), raii::itostr(video.thumb_size())), member(json::keys::message::infobody::thumbnail::width(), raii::itostr(video.thumb_width())) )), member(json::keys::message::infobody::thumburl(), quote(raii::json_escape(video.thumb_url()))), member(json::keys::message::infobody::width(), raii::itostr(video.width())) )), member(json::keys::message::msgtype(), quote("m.video"_ss)), member(json::keys::message::url(), quote(raii::json_escape(video.url()))) )); } raii::string _file_body(const uploaded_file& file){ return raii::string( object( member(json::keys::message::body(), quote(raii::json_escape(file.name()))), member(json::keys::message::info(), object( member(json::keys::message::infobody::size(), raii::itostr(file.size())) )), member(json::keys::message::msgtype(), quote("m.file"_ss)), member(json::keys::message::url(), quote(raii::json_escape(file.url()))) )); } raii::string _audio_body(const uploaded_audio& audio){ return raii::string( object( member(json::keys::message::body(), quote(raii::json_escape(audio.name()))), member(json::keys::message::info(), object( member(json::keys::message::infobody::mimetype(), quote(audio.mimetype())), member(json::keys::message::infobody::size(), raii::itostr(audio.size())) )), member(json::keys::message::msgtype(), quote("m.audio"_ss)), member(json::keys::message::url(), quote(raii::json_escape(audio.url()))) )); } raii::string _message_body(const raii::string_base& msg){ return raii::string( object( member(json::keys::message::body(), quote(raii::json_escape(msg))), member(json::keys::message::msgtype(), quote("m.text"_ss)) )); } raii::string _login_password(const raii::string_base& username, const raii::string_base& password){ return raii::string( object( member(json::keys::auth::type(), quote("m.login.password"_ss)), member(json::keys::auth::identifier(), object( member(json::keys::auth::identifierbody::type(), quote("m.id.user"_ss)), member(json::keys::auth::identifierbody::user(), quote(raii::json_escape(username))) )), member(json::keys::auth::password(), quote(raii::json_escape(password))) )); } raii::string _change_psk_password(const raii::string_base& userid, const raii::string_base& newpass, const raii::string_base& oldpass, const raii::string_base& session){ return raii::string( object( member(json::keys::auth::newpassword(), quote(raii::json_escape(newpass))), member(json::keys::auth::auth(), object( member(json::keys::auth::authbody::type(), quote("m.login.password"_ss)), member(json::keys::auth::authbody::session(), quote(session)), member(json::keys::auth::authbody::user(), quote(raii::json_escape(userid))), member(json::keys::auth::authbody::password(), quote(raii::json_escape(oldpass))) )) )); } raii::string _displayname_set(const raii::string_base& newname){ return raii::string( object( member(json::keys::client::displayname(), quote(raii::json_escape(newname))) )); } raii::string _avatar_set(const raii::string_base& mediaurl){ return raii::string( object( member(json::keys::client::avatarurl(), quote(raii::json_escape(mediaurl))) )); } raii::string _presence_set(const raii::string_base& status){ return raii::string( object( member(json::keys::client::presence(), quote(status)) )); } raii::string _create_room(const raii::string_base& name, const raii::string_base& alias){ if(alias){ return raii::string( object( member(json::keys::client::name(), quote(raii::json_escape(name))), member(json::keys::client::roomaliasname(), quote(raii::json_escape(alias))) )); }else{ return raii::string( object( member(json::keys::client::name(), quote(raii::json_escape(name))) )); } } raii::string _userid(const raii::string_base& id){ return raii::string( object( member(json::keys::auth::userid(), quote(raii::json_escape(id))) )); } raii::string _userid_reason(const raii::string_base& id, const raii::string_base& reason){ return raii::string( object( member(json::keys::auth::userid(), quote(raii::json_escape(id))), member(json::reason(), quote(raii::json_escape(reason))) )); } raii::string _typing(bool active, int timeout){ return raii::string( object( member(json::keys::client::typing(), active ? json::True() : json::False()), member(json::keys::client::timeout(), raii::itostr(timeout)) )); } raii::string _redact(const raii::string_base& reason){ return raii::string( object( member(json::reason(), quote(raii::json_escape(reason))) )); } raii::string _room_upgrade(int version){ return raii::string( object( member(json::keys::rooms::newversion(), raii::itostr(version)) )); } }