From 577af3c0400b5442a436878e5363ffe23be934c7 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sun, 1 Sep 2019 18:47:45 -0700 Subject: [PATCH] Changed syncing to return a sync::response object to make for easier parsing with a to-be-standard api --- .gitignore | 2 + doc/TODO | 4 + include/matrix/events.hpp | 113 +++++++++++++++++++++ include/matrix/iterable.hpp | 166 +++++++++++++++++++++++++++++++ include/matrix/room_url_list.hpp | 3 + include/matrix/roomcxn.hpp | 3 + include/matrix/sync_response.hpp | 156 +++++++++++++++++++++++++++++ include/matrix/syncer.hpp | 3 +- include/raii/rjp_iterator.hpp | 85 ++++++++++++++++ include/raii/string_base.hpp | 6 +- src/matrix/events.cpp | 109 ++++++++++++++++++++ src/matrix/room_url_list.cpp | 10 ++ src/matrix/roomcxn.cpp | 6 ++ src/matrix/sync_response.cpp | 108 ++++++++++++++++++++ src/matrix/syncer.cpp | 7 +- src/raii/string_base.cpp | 9 -- src/test.cpp | 23 ++++- 17 files changed, 791 insertions(+), 22 deletions(-) create mode 100644 include/matrix/events.hpp create mode 100644 include/matrix/iterable.hpp create mode 100644 include/matrix/sync_response.hpp create mode 100644 include/raii/rjp_iterator.hpp create mode 100644 src/matrix/events.cpp create mode 100644 src/matrix/sync_response.cpp diff --git a/.gitignore b/.gitignore index eb03c8b..a8dbf81 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ data testout audio video +result*.json +dissection_result*.txt diff --git a/doc/TODO b/doc/TODO index 1ffd3fe..435cad6 100644 --- a/doc/TODO +++ b/doc/TODO @@ -22,7 +22,11 @@ matrix: 1:query/addto public room directory 1:deactivate account 1:user search + sync: + 3:filters room: + 10:query previous messages + 3:message query filters 2:kick users 2:ban/unban users 2:forget room diff --git a/include/matrix/events.hpp b/include/matrix/events.hpp new file mode 100644 index 0000000..8d518f9 --- /dev/null +++ b/include/matrix/events.hpp @@ -0,0 +1,113 @@ +/** + This file is a part of r0nk, atlas_moon, and 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 . +*/ + +#ifndef MATRIX_EVENT_HPP +#define MATRIX_EVENT_HPP + +#include "raii/rjp_ptr.hpp" +#include "raii/static_string.hpp" +#include "raii/rjp_string.hpp" + +namespace matrix::sync{ + + /* + Base class for events returned by a sync + */ + class event + { + protected: + RJP_value* m_event; + public: + constexpr explicit event(RJP_value* ev): + m_event(ev){} + constexpr event(const event&) = default; + ~event(void) = default; + constexpr event& operator=(const event&) = default; + + raii::static_string type(void)const&; + raii::rjp_string type(void)&&; + const RJP_value* content(void)const; + RJP_value* content(void); + + }; + + /* + Base class for events associated with a room returned by a sync + */ + class room_event_base + { + protected: + const raii::static_string m_roomid; + public: + constexpr room_event_base(const raii::string_base& roomid): + m_roomid(roomid.get(), roomid.length()){} + constexpr const raii::static_string& roomid(void)const{ + return m_roomid; + } + }; + + /* + Class to represent a single event associated with a specific room. + */ + class room_event : public room_event_base, public event + { + public: + constexpr room_event(RJP_value* ev, const raii::string_base& roomid): + room_event_base(roomid), event(ev){} + + raii::static_string eventid(void)const&; + raii::rjp_string eventid(void)&&; + raii::static_string sender(void)const&; + raii::rjp_string sender(void)&&; + int origin_server_ts(void)const; + const RJP_value* extra(void)const; + RJP_value* extra(void); + + //only for m.room.redacts events + raii::static_string redacts(void)const&; + raii::rjp_string redacts(void)&&; + }; + + /* + Class to represent a single state event associated with a specific room + */ + class room_state_event : public room_event + { + public: + constexpr room_state_event(RJP_value* ev, const raii::string_base& roomid): + room_event(ev, roomid){} + + raii::static_string state_key(void)const&; + raii::rjp_string state_key(void)&&; + raii::static_string prev_content(void)const&; + raii::rjp_string prev_content(void)&&; + }; + + /* + Class to represent a single ephemeral event associated with a specific room + */ + class room_ephemeral_event : public room_event_base, public event + { + public: + constexpr room_ephemeral_event(RJP_value* ev, const raii::string_base& roomid): + room_event_base(roomid),event(ev){} + }; + +} + +#endif diff --git a/include/matrix/iterable.hpp b/include/matrix/iterable.hpp new file mode 100644 index 0000000..dce05b7 --- /dev/null +++ b/include/matrix/iterable.hpp @@ -0,0 +1,166 @@ +/** + This file is a part of r0nk, atlas_moon, and 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 . +*/ + +#ifndef MATRIX_ITERABLE_HPP +#define MATRIX_ITERABLE_HPP + +#include "matrix/events.hpp" +#include "raii/rjp_string.hpp" +#include "raii/static_string.hpp" +#include "raii/rjp_iterator.hpp" + +namespace matrix::sync{ + + namespace detail{ + /* + Class for iterating over an event array returned by a sync + */ + template + class event_iterator + { + protected: + raii::rjp_array_iterator m_event; + public: + constexpr event_iterator(RJP_value* v): + m_event(v){} + constexpr event_iterator(const event_iterator& i): + m_event(i.m_event){} + constexpr bool operator==(const event_iterator& e){ + return m_event == e.m_event; + } + constexpr bool operator!=(const event_iterator& e){ + return m_event != e.m_event; + } + event_iterator& operator++(void){ + ++m_event; + return *this; + } + constexpr T operator*(void){ + return T(*m_event); + } + }; + /* + Class for iterating over an event array associated with a room returned by a sync + */ + template + class room_event_iterator + { + private: + raii::rjp_array_iterator m_event; + raii::static_string m_roomid; + public: + constexpr room_event_iterator(RJP_value* v, const raii::string_base& roomid): + m_event(v), m_roomid(roomid){} + constexpr room_event_iterator(const room_event_iterator& i): + m_event(i.m_event), m_roomid(i.m_roomid){} + constexpr bool operator==(const room_event_iterator& e){ + return m_event == e.m_event; + } + constexpr bool operator!=(const room_event_iterator& e){ + return m_event != e.m_event; + } + room_event_iterator& operator++(void){ + ++m_event; + return *this; + } + constexpr T operator*(void){ + return T(*m_event, m_roomid); + } + constexpr const raii::static_string& roomid(void)const{ + return m_roomid; + } + }; + } + /////////////////////////////////////////////////////////////////////////////////////////////////// + /* + Base class shared by all room lists + */ + template + class iterable_event_base + { + public: + using iterator = T; + using const_iterator = const T; + protected: + iterator m_event; + public: + constexpr iterable_event_base(RJP_value* ev): + m_event(ev){} + constexpr iterable_event_base(const iterable_event_base& i): + m_event(i.m_event){} + constexpr const_iterator& begin(void)const{ + return m_event; + } + constexpr iterator& begin(void){ + return m_event; + } + constexpr const_iterator end(void)const{ + return const_iterator(nullptr); + } + }; + template + class iterable_room_event_base + { + public: + using iterator = T; + using const_iterator = const T; + protected: + iterator m_event; + public: + constexpr iterable_room_event_base(RJP_value* ev, const raii::string_base& roomid): + m_event(ev, roomid){} + constexpr iterable_room_event_base(const iterable_room_event_base& i): + m_event(i.m_event){} + constexpr const_iterator& begin(void)const{ + return m_event; + } + constexpr iterator& begin(void){ + return m_event; + } + constexpr const_iterator end(void)const{ + return const_iterator(nullptr, m_event.roomid()); + } + }; + class event_list : public iterable_event_base> + { + public: + using iterable_event_base>::iterable_event_base; + }; + //Class representing a list of room state events + class room_state_event_list : public iterable_room_event_base> + { + public: + using iterable_room_event_base>::iterable_room_event_base; + }; + //Class representing a list of room events + class room_event_list : public iterable_room_event_base> + { + public: + using iterable_room_event_base>::iterable_room_event_base; + }; + //Class representing a list of room ephemeral events + class room_ephem_event_list : public iterable_room_event_base> + { + public: + using iterable_room_event_base>::iterable_room_event_base; + }; + + +} + +#endif diff --git a/include/matrix/room_url_list.hpp b/include/matrix/room_url_list.hpp index 3b7875d..3c41812 100644 --- a/include/matrix/room_url_list.hpp +++ b/include/matrix/room_url_list.hpp @@ -49,6 +49,9 @@ namespace matrix{ const raii::string& invite(void)const; const raii::string& room_members(void)const; const raii::string& upgrade(void)const; + raii::string messages(const raii::string_base& homeserver, const raii::string_base& access_token, + const raii::string_base& roomid, const raii::string_base& from, const raii::string_base& to, + const raii::string_base& dir, int limit)const; void repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid, const raii::string_base& roomid); void invalidate_accesstoken(void); diff --git a/include/matrix/roomcxn.hpp b/include/matrix/roomcxn.hpp index 33f9557..06f210c 100644 --- a/include/matrix/roomcxn.hpp +++ b/include/matrix/roomcxn.hpp @@ -68,6 +68,9 @@ namespace matrix{ raii::rjp_string redact_event(const raii::string_base& eventid, const raii::string_base& reason)const; raii::rjp_string redact_event(const raii::string_base& eventid)const; + //recieve events + raii::string get_events_forward(int amount); + raii::string get_events_backward(int amount); //meta stuff void regenerate_urls(void); diff --git a/include/matrix/sync_response.hpp b/include/matrix/sync_response.hpp new file mode 100644 index 0000000..e4292cd --- /dev/null +++ b/include/matrix/sync_response.hpp @@ -0,0 +1,156 @@ +/** + This file is a part of r0nk, atlas_moon, and 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 . +*/ + +#ifndef SYNC_RESPONSE_HPP +#define SYNC_RESPONSE_HPP + +#include "raii/rjp_string.hpp" +#include "raii/static_string.hpp" +#include "raii/rjp_iterator.hpp" +#include "raii/rjp_ptr.hpp" +#include "matrix/events.hpp" +#include "matrix/iterable.hpp" + +namespace matrix::sync{ + + /////////////////////////////////////////////////////////////////////////////////////////////////// + /* + Class representing the "rooms" section of a sync response + */ + class room_event_response + { + private: + RJP_value* m_room; + public: + constexpr room_event_response(RJP_value* room):m_room(room){} + raii::static_string roomid(void)const; + room_event_list account_events(void); + room_ephem_event_list ephemeral_events(void); + room_state_event_list state_events(void); + room_state_event_list timeline_events(void); + RJP_value* notifications(void); + RJP_value* summary(void); + private: + RJP_value* _find_event_list(const char* mname)const; + }; + + /* + Class used to iterate over an array of rooms returned by a sync + */ + class room_iterator + { + private: + raii::rjp_object_iterator m_room; + public: + constexpr room_iterator(RJP_value* r):m_room(r){} + constexpr bool operator==(const room_iterator& r){ + return r.m_room == m_room; + } + constexpr bool operator!=(const room_iterator& r){ + return r.m_room != m_room; + } + room_iterator& operator++(void){ + ++m_room; + return *this; + } + constexpr room_event_response operator*(void){ + return room_event_response(*m_room); + } + }; + + /* + Class representing a list of rooms + */ + class room_list + { + public: + using iterator = room_iterator; + using const_iterator = const iterator; + private: + iterator m_room; + public: + constexpr room_list(RJP_value* room):m_room(room){} + constexpr room_list(const room_list& r):m_room(r.m_room){} + + constexpr iterator& begin(void){ + return m_room; + } + constexpr const_iterator& begin(void)const{ + return m_room; + } + constexpr const_iterator end(void)const{ + return const_iterator(nullptr); + } + }; + + class device_list + { + private: + RJP_value* m_root; + public: + device_list(RJP_value* root): + m_root(root){} + event_list left(void)const{ + return rjp_get_element(rjp_search_member(m_root, "left", 0).value); + } + event_list changed(void)const{ + return rjp_get_element(rjp_search_member(m_root, "changed", 0).value); + } + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////// + /* + Class returned by a sync. Makes for theoretically easier processing than a pure raw response + */ + class response + { + private: + raii::rjp_ptr m_root; + public: + response(const raii::string_base& src); + response(RJP_value* root); + + room_list room_join_events(void)const; + room_list room_invite_events(void)const; + room_list room_leave_events(void)const; + + device_list device_lists(void)const; + raii::static_string next_batch(void)const&; + raii::rjp_string next_batch(void)&&; + + event_list to_device_events(void)const; + event_list presence_events(void)const; + event_list account_data_events(void)const; + + //TODO + room_list groups_join_events(void)const; + room_list groups_leave_events(void)const; + room_list group_invite_events(void)const; + RJP_value* device_one_time_keys_count(void)const; + + RJP_value* raw_handle(void); + const RJP_value* raw_handle(void)const; + raii::rjp_string raw_str(void)const; + private: + RJP_value* _find_room_list(const char* segment)const; + }; + +} + +#endif + diff --git a/include/matrix/syncer.hpp b/include/matrix/syncer.hpp index f21eddb..e7ba6e5 100644 --- a/include/matrix/syncer.hpp +++ b/include/matrix/syncer.hpp @@ -24,6 +24,7 @@ #include "raii/string.hpp" #include "matrix/session_info.hpp" #include "matrix/connection.hpp" +#include "matrix/sync_response.hpp" #include //size_t #include //shared_ptr @@ -54,7 +55,7 @@ namespace matrix{ * Sync state with the homeserver. Will wait for up to timeout ms. * Returns: the raw json response from the homeserver. */ - raii::string sync(size_t timeout); + sync::response sync(size_t timeout); }; } diff --git a/include/raii/rjp_iterator.hpp b/include/raii/rjp_iterator.hpp new file mode 100644 index 0000000..152fde5 --- /dev/null +++ b/include/raii/rjp_iterator.hpp @@ -0,0 +1,85 @@ +#ifndef RJP_ITERATOR_HPP +#define RJP_ITERATOR_HPP + +#include + +namespace raii{ + + class rjp_object_iterator + { + public: + using iterator = RJP_value*; + using const_iterator = const iterator; + private: + RJP_value* m_value; + public: + constexpr rjp_object_iterator(RJP_value* v):m_value(v){} + constexpr rjp_object_iterator(const rjp_object_iterator& e):m_value(e.m_value){} + constexpr rjp_object_iterator& operator=(const rjp_object_iterator& e){ + m_value = e.m_value; + return *this; + } + constexpr bool operator==(const rjp_object_iterator& e)const{ + return m_value == e.m_value; + } + constexpr bool operator!=(const rjp_object_iterator& e)const{ + return m_value != e.m_value; + } + rjp_object_iterator& operator++(void){ + m_value = rjp_next_member(m_value); + return *this; + } + constexpr RJP_value* operator*(void){ + return m_value; + } + constexpr const RJP_value* operator*(void)const{ + return m_value; + } + constexpr RJP_value& operator->(void){ + return *m_value; + } + constexpr const RJP_value& operator->(void)const{ + return *m_value; + } + }; + class rjp_array_iterator + { + public: + using iterator = RJP_value*; + using const_iterator = const iterator; + private: + RJP_value* m_value; + public: + constexpr rjp_array_iterator(RJP_value* v):m_value(v){} + constexpr rjp_array_iterator(const rjp_array_iterator& e):m_value(e.m_value){} + constexpr rjp_array_iterator& operator=(const rjp_array_iterator& e){ + m_value = e.m_value; + return *this; + } + constexpr bool operator==(const rjp_array_iterator& e)const{ + return m_value == e.m_value; + } + constexpr bool operator!=(const rjp_array_iterator& e)const{ + return m_value != e.m_value; + } + rjp_array_iterator& operator++(void){ + m_value = rjp_next_element(m_value); + return *this; + } + constexpr RJP_value* operator*(void){ + return m_value; + } + constexpr const RJP_value* operator*(void)const{ + return m_value; + } + constexpr RJP_value& operator->(void){ + return *m_value; + } + constexpr const RJP_value& operator->(void)const{ + return *m_value; + } + }; + +} + +#endif diff --git a/include/raii/string_base.hpp b/include/raii/string_base.hpp index 23909ad..1dc56a5 100644 --- a/include/raii/string_base.hpp +++ b/include/raii/string_base.hpp @@ -104,10 +104,10 @@ namespace raii{ char* release(void); //Length of string not including null terminator - size_t length(void)const; + constexpr size_t length(void)const{return m_length;} //direct access to managed pointer - char* get(void); - const char* get(void)const; + constexpr char* get(void){return m_data;} + constexpr const char* get(void)const{return m_data;} operator char*(void); operator const char*(void)const; //true if m_data is not null diff --git a/src/matrix/events.cpp b/src/matrix/events.cpp new file mode 100644 index 0000000..505aa41 --- /dev/null +++ b/src/matrix/events.cpp @@ -0,0 +1,109 @@ +/** + This file is a part of r0nk, atlas_moon, and 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/events.hpp" + +namespace matrix::sync{ + + //Event base + raii::static_string event::type(void)const&{ + RJP_search_res res = rjp_search_member(m_event, "type", 0); + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + } + raii::rjp_string event::type(void)&&{ + RJP_search_res res = rjp_search_member(m_event, "type", 0); + return raii::rjp_string(res.value); + } + const RJP_value* event::content(void)const{ + RJP_search_res res = rjp_search_member(m_event, "content", 0); + return res.value; + } + RJP_value* event::content(void){ + RJP_search_res res = rjp_search_member(m_event, "content", 0); + return res.value; + } + + //Room event + raii::static_string room_event::eventid(void)const&{ + RJP_search_res res = rjp_search_member(m_event, "event_id", 0); + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + } + raii::rjp_string room_event::eventid(void)&&{ + RJP_search_res res = rjp_search_member(m_event, "event_id", 0); + return raii::rjp_string(res.value); + } + raii::static_string room_event::sender(void)const&{ + RJP_search_res res = rjp_search_member(m_event, "sender", 0); + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + } + raii::rjp_string room_event::sender(void)&&{ + RJP_search_res res = rjp_search_member(m_event, "sender", 0); + return raii::rjp_string(res.value); + } + int room_event::origin_server_ts(void)const{ + RJP_search_res res = rjp_search_member(m_event, "origin_server_ts", 0); + return rjp_value_integer(res.value); + } + const RJP_value* room_event::extra(void)const{ + RJP_search_res res = rjp_search_member(m_event, "unsigned", 0); + return res.value; + } + RJP_value* room_event::extra(void){ + RJP_search_res res = rjp_search_member(m_event, "unsigned", 0); + return res.value; + } + raii::static_string room_event::redacts(void)const&{ + RJP_search_res res = rjp_search_member(m_event, "redacts", 0); + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + } + raii::rjp_string room_event::redacts(void)&&{ + RJP_search_res res = rjp_search_member(m_event, "redacts", 0); + return raii::rjp_string(res.value); + } + + //Room state event + raii::static_string room_state_event::state_key(void)const&{ + RJP_search_res res = rjp_search_member(m_event, "state_key", 0); + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + } + raii::rjp_string room_state_event::state_key(void)&&{ + RJP_search_res res = rjp_search_member(m_event, "state_key", 0); + return raii::rjp_string(res.value); + } + raii::static_string room_state_event::prev_content(void)const&{ + RJP_search_res res = rjp_search_member(m_event, "prev_content", 0); + if(res.value) + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + res = rjp_search_member(m_event, "unsigned", 0); + if(!res.value) + return raii::static_string{}; + res = rjp_search_member(res.value, "prev_content", 0); + return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value)); + } + raii::rjp_string room_state_event::prev_content(void)&&{ + RJP_search_res res = rjp_search_member(m_event, "prev_content", 0); + if(res.value) + return raii::rjp_string(res.value); + res = rjp_search_member(m_event, "unsigned", 0); + if(!res.value) + return raii::static_string{}; + res = rjp_search_member(res.value, "prev_content", 0); + return raii::rjp_string(res.value); + } + +} diff --git a/src/matrix/room_url_list.cpp b/src/matrix/room_url_list.cpp index 455552b..06a688d 100644 --- a/src/matrix/room_url_list.cpp +++ b/src/matrix/room_url_list.cpp @@ -17,6 +17,7 @@ */ #include "matrix/room_url_list.hpp" +#include "raii/util.hpp" namespace matrix{ @@ -69,6 +70,15 @@ namespace matrix{ const raii::string& room_url_list::upgrade(void)const{ return m_upgrade; } + raii::string room_url_list::messages(const raii::string_base& homeserver, const raii::string_base& access_token, + const raii::string_base& roomid, const raii::string_base& from, const raii::string_base& to, + const raii::string_base& dir, int limit)const + { + if(to) + return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/messages?from=" + from + "&to=" + to + "&limit=" + raii::itostr(limit) + "&dir=" + dir + "&access_token=" + access_token); + else + return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/messages?from=" + from + "&limit=" + raii::itostr(limit) + "&dir=" + dir + "&access_token=" + access_token); + } void room_url_list::repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid, const raii::string_base& roomid){ m_join = s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/join?access_token=" + access_token; m_leave = s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/leave?access_token=" + access_token; diff --git a/src/matrix/roomcxn.cpp b/src/matrix/roomcxn.cpp index 3d8e6b0..b4d9a15 100644 --- a/src/matrix/roomcxn.cpp +++ b/src/matrix/roomcxn.cpp @@ -109,6 +109,12 @@ namespace matrix{ raii::rjp_string roomcxn::redact_event(const raii::string_base& eventid)const{ return redact_event(eventid, "No reason given"_ss); } + raii::string roomcxn::get_events_forward(int amount){ + return _get_curl(m_urls.messages(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), ""_ss, raii::static_string(), "f"_ss, amount)); + } + raii::string roomcxn::get_events_backward(int amount){ + return _get_curl(m_urls.messages(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), ""_ss, raii::static_string(), "b"_ss, amount)); + } void roomcxn::regenerate_urls(void){ m_urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid, m_roomid); diff --git a/src/matrix/sync_response.cpp b/src/matrix/sync_response.cpp new file mode 100644 index 0000000..a53b342 --- /dev/null +++ b/src/matrix/sync_response.cpp @@ -0,0 +1,108 @@ +/** + This file is a part of r0nk, atlas_moon, and 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/sync_response.hpp" + +namespace matrix::sync{ + + //Room event response + raii::static_string room_event_response::roomid(void)const{ + return raii::static_string(rjp_member_name(m_room), rjp_member_name_length(m_room)); + } + RJP_value* room_event_response::_find_event_list(const char* mname)const{ + RJP_search_res res = rjp_search_member(m_room, mname, 0); + if(!res.value) + return nullptr; + res = rjp_search_member(res.value, "events", 0); + if(!res.value) + return nullptr; + return rjp_get_element(res.value); + } + room_event_list room_event_response::account_events(void){ + return room_event_list(_find_event_list("account_data"), roomid()); + } + room_ephem_event_list room_event_response::ephemeral_events(void){ + return room_ephem_event_list(_find_event_list("ephemeral"), roomid()); + } + room_state_event_list room_event_response::state_events(void){ + return room_state_event_list(_find_event_list("state"), roomid()); + } + room_state_event_list room_event_response::timeline_events(void){ + return room_state_event_list(_find_event_list("timeline"), roomid()); + } + RJP_value* room_event_response::notifications(void){ + return rjp_search_member(m_room, "unread_notifications", 0).value; + } + RJP_value* room_event_response::summary(void){ + return rjp_search_member(m_room, "summary", 0).value; + } + + //Sync response + response::response(const raii::string_base& s): + m_root(rjp_parse(s)){} + response::response(RJP_value* root): + m_root(root){} + room_list response::room_join_events(void)const{ + return _find_room_list("join"); + } + room_list response::room_invite_events(void)const{ + return _find_room_list("invite"); + } + room_list response::room_leave_events(void)const{ + return _find_room_list("leave"); + } + device_list response::device_lists(void)const{ + return rjp_search_member(m_root.get(), "device_lists", 0).value; + } + raii::static_string response::next_batch(void)const&{ + RJP_value* nb = rjp_search_member(m_root.get(), "next_batch", 0).value; + if(!nb) return {}; + return raii::static_string(rjp_value_string(nb), rjp_value_string_length(nb)); + } + raii::rjp_string response::next_batch(void)&&{ + return raii::rjp_string(rjp_search_member(m_root.get(), "next_batch", 0).value); + } + event_list response::to_device_events(void)const{ + return rjp_search_member(rjp_search_member(m_root.get(), "to_device", 0).value, "events", 0).value; + } + event_list response::presence_events(void)const{ + return rjp_search_member(rjp_search_member(m_root.get(), "presence", 0).value, "events", 0).value; + } + RJP_value* response::device_one_time_keys_count(void)const{ + return rjp_search_member(m_root.get(), "device_one_time_keys_count", 0).value; + } + + RJP_value* response::raw_handle(void){ + return m_root.get(); + } + const RJP_value* response::raw_handle(void)const{ + return m_root.get(); + } + raii::rjp_string response::raw_str(void)const{ + return raii::rjp_string(rjp_to_json(m_root.get())); + } + RJP_value* response::_find_room_list(const char* segment)const{ + RJP_search_res res = rjp_search_member(m_root.get(), "rooms", 0); + if(!res.value) + return {nullptr}; + res = rjp_search_member(res.value, segment, 0); + if(!res.value) + return {nullptr}; + return {rjp_get_member(res.value)}; + } +} diff --git a/src/matrix/syncer.cpp b/src/matrix/syncer.cpp index f0e3d39..4690c81 100644 --- a/src/matrix/syncer.cpp +++ b/src/matrix/syncer.cpp @@ -25,11 +25,11 @@ namespace matrix{ syncer::syncer(const std::shared_ptr& ses): connection(ses){} - raii::string syncer::sync(size_t timeout){ + 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 {}; + return {nullptr}; raii::rjp_ptr root(rjp_parse(reply)); if(!root) return reply; @@ -38,7 +38,6 @@ namespace matrix{ if(!res.value) return reply; m_next_batch = res.value; - - return reply; + return sync::response(root.release()); } } diff --git a/src/raii/string_base.cpp b/src/raii/string_base.cpp index c9e86f2..2bd5a07 100644 --- a/src/raii/string_base.cpp +++ b/src/raii/string_base.cpp @@ -39,15 +39,6 @@ namespace raii{ m_length = val ? strlen(val) : 0; } - size_t string_base::length(void)const{ - return m_length; - } - char* string_base::get(void){ - return m_data; - } - const char* string_base::get(void)const{ - return m_data; - } string_base::operator bool(void)const{ return m_data; } diff --git a/src/test.cpp b/src/test.cpp index 3771913..9f6b4a5 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -20,6 +20,7 @@ #include "matrix/matrix.hpp" #include "raii/static_string.hpp" +#include "matrix/sync_response.hpp" #include #include @@ -27,11 +28,18 @@ #include void sync_fn(matrix::syncer syn, std::atomic_bool& should_quit){ - auto sync_reply = syn.sync(0); + syn.sync(0); + printf("paused\n"); + getchar(); + printf("continuing\n"); while(!should_quit){ - sync_reply = syn.sync(30000); - printf("%s\n", sync_reply.get()); + auto sync_reply = syn.sync(30000); + for(auto room : sync_reply.room_join_events()){ + for(auto event : room.timeline_events()){ + printf("%s\n", event.sender().get()); + } + } } } @@ -63,10 +71,15 @@ int main(){ std::atomic_bool should_quit = false; + auto syn = ses.spawn_syncer(); + syn.sync(0); + + //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 key_thread(keyboard_fn, ses.spawn_client().spawn_room("!cEIFONpAlHTbGBUFAE:rexy712.chickenkiller.com"_ss), 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(); - key_thread.join(); + //key_thread.join(); }