Rudimentary processing of messages

This commit is contained in:
rexy712
2019-03-21 15:38:42 -07:00
parent 02c02115c2
commit c083e74ecb
6 changed files with 215 additions and 56 deletions

3
TODO
View File

@@ -5,3 +5,6 @@ youtube video download
raii swscontext
thorough error checking
register libav in the libav namespace somewhere
handle user admin levels
ignore own messages
handle events other than user messages

View File

@@ -25,6 +25,7 @@
#include "raii/filerd.hpp"
#include <vector>
#include <functional>
#define HAS_FREEIMAGE
#define HAS_FFMPEG
@@ -59,6 +60,52 @@ namespace matrix{
struct video_info : public image_info{};
struct audio_info : public file_info{};
class msgtype{
private:
const char* m_str;
const int m_num;
public:
msgtype(const char* s, int n):
m_str(s), m_num(n){}
msgtype(const msgtype&) = default;
~msgtype(void) = default;
msgtype& operator=(const msgtype&) = default;
bool operator==(const msgtype& m){
return m_num == m.m_num;
}
bool operator!=(const msgtype& m){
return m_num != m.m_num;
}
const char* str(void)const{
return m_str;
}
};
struct msg{
inline static msgtype text = msgtype("text", 0);
inline static msgtype audio = msgtype("audio", 1);
inline static msgtype video = msgtype("video", 2);
inline static msgtype file = msgtype("file", 3);
inline static msgtype image = msgtype("image", 4);
inline static msgtype other = msgtype("other", 100);
static msgtype& from_str(const char* str){
if(!strcmp(str, "m.text")){
return text;
}else if(!strcmp(str, "m.audio")){
return audio;
}else if(!strcmp(str, "m.video")){
return video;
}else if(!strcmp(str, "m.file")){
return file;
}else if(!strcmp(str, "m.image")){
return image;
}else{
return other;
}
}
};
class bot
{
private:
@@ -94,6 +141,10 @@ namespace matrix{
raii::rjp_string m_next_batch; //string which tracks where we are in the server history
std::function<void(const raii::string_base&,const raii::string_base&,msgtype,
const raii::string_base&,const raii::string_base&)>
m_message_callback;
public:
bot(const auth_data& a, const raii::string_base& useragent);
bot(const auth_data& a, raii::string&& useragent);
@@ -142,10 +193,15 @@ namespace matrix{
raii::rjp_string send_audio(const raii::string_base& room, const audio_info& audio);
raii::rjp_string send_file(const raii::string_base& room, const file_info& file);
template<class Func>
void set_sync_callback(Func&& f){
m_message_callback = std::forward<Func>(f);
}
raii::string sync(size_t timeout);
void logout(void);
protected:
void _send_read_receipt(const raii::string_base& roomid, const raii::string_base& eventid);
raii::rjp_string _upload_file(raii::filerd& fp, const raii::curl_llist& header);
raii::rjp_string _send_message(const raii::string_base& room, const raii::string_base& msg);
static size_t _post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata);

View File

@@ -36,24 +36,22 @@ namespace reddit{
namespace time{
namespace detail{
class time_period{
protected:
const char* data;
public:
constexpr time_period(const char* d):
data(d){}
constexpr const char* get(void)const{
return data;
}
};
}
extern detail::time_period hour;
extern detail::time_period day;
extern detail::time_period week;
extern detail::time_period month;
extern detail::time_period year;
extern detail::time_period all;
class period{
protected:
const char* data;
public:
constexpr period(const char* d):
data(d){}
constexpr const char* get(void)const{
return data;
}
};
extern period hour;
extern period day;
extern period week;
extern period month;
extern period year;
extern period all;
}
enum class post_type{
@@ -139,10 +137,10 @@ namespace reddit{
post get_rising_post(const raii::string_base& subreddit, const raii::string_base& after);
post get_best_post(const raii::string_base& subreddit);
post get_best_post(const raii::string_base& subreddit, const raii::string_base& after);
post get_top_post(const raii::string_base& subreddit, time::detail::time_period period = time::day);
post get_top_post(const raii::string_base& subreddit, const raii::string_base& after, time::detail::time_period period = time::day);
post get_controversial_post(const raii::string_base& subreddit, time::detail::time_period period = time::day);
post get_controversial_post(const raii::string_base& subreddit, const raii::string_base& after, time::detail::time_period period = time::day);
post get_top_post(const raii::string_base& subreddit, time::period period = time::day);
post get_top_post(const raii::string_base& subreddit, const raii::string_base& after, time::period period = time::day);
post get_controversial_post(const raii::string_base& subreddit, time::period period = time::day);
post get_controversial_post(const raii::string_base& subreddit, const raii::string_base& after, time::period period = time::day);
protected:
static size_t _get_response_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata);

View File

@@ -433,6 +433,37 @@ namespace matrix{
if(!res.value)
return reply;
m_next_batch = res.value;
if(m_message_callback == nullptr){
return reply;
}
res = rjp_search_member(root.get(), "rooms", 0);
if(!res.value) return reply;
res = rjp_search_member(res.value, "join", 0);
if(!res.value) return reply;
for(RJP_value* roomid = rjp_get_member(res.value);roomid;roomid = rjp_next_member(roomid)){
res = rjp_search_member(roomid, "timeline", 0);
if(!res.value) continue;
res = rjp_search_member(res.value, "events", 0);
if(!res.value) continue;
for(RJP_value* event = rjp_get_element(res.value);event;event = rjp_next_element(event)){
res = rjp_search_member(event, "content", 0);
if(!res.value) continue;
RJP_search_res msg = rjp_search_member(res.value, "msgtype", 0);
if(!msg.value) continue;
RJP_search_res body = rjp_search_member(res.value, "body", 0);
if(!body.value) continue;
RJP_search_res sender = rjp_search_member(event, "sender", 0);
if(!sender.value) continue;
res = rjp_search_member(event, "event_id", 0);
if(!res.value) continue;
raii::rjp_string room_str = rjp_member_name(roomid);
raii::rjp_string eventid_str = res.value;
m_message_callback(room_str, raii::rjp_string(sender.value), msg::from_str(rjp_value_string(msg.value)), raii::rjp_string(body.value), eventid_str);
_send_read_receipt(room_str, eventid_str);
}
}
return reply;
}
@@ -442,6 +473,10 @@ namespace matrix{
Internal functions
********************************/
void bot::_send_read_receipt(const raii::string_base& roomid, const raii::string_base& eventid){
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());
}
raii::rjp_string bot::_upload_file(raii::filerd& fp, const raii::curl_llist& header){
raii::string fileurl;
m_curl.postreq();

View File

@@ -35,12 +35,12 @@
namespace reddit{
namespace time{
detail::time_period hour = "hour";
detail::time_period day = "day";
detail::time_period week = "week";
detail::time_period month = "month";
detail::time_period year = "year";
detail::time_period all = "all";
period hour = "hour";
period day = "day";
period week = "week";
period month = "month";
period year = "year";
period all = "all";
}
auth_data parse_auth_data(RJP_value* root){
@@ -404,19 +404,19 @@ namespace reddit{
post bot::get_best_post(const raii::string_base& subreddit, const raii::string_base& after){
return _get_post(subreddit, "best"_ss, raii::string("limit=1&after=" + after));
}
post bot::get_top_post(const raii::string_base& subreddit, time::detail::time_period period){
post bot::get_top_post(const raii::string_base& subreddit, time::period period){
raii::static_string pstr = period.get();
return _get_post(subreddit, "top"_ss, raii::string("limit=1&t=" + pstr));
}
post bot::get_top_post(const raii::string_base& subreddit, const raii::string_base& after, time::detail::time_period period){
post bot::get_top_post(const raii::string_base& subreddit, const raii::string_base& after, time::period period){
raii::static_string pstr = period.get();
return _get_post(subreddit, "top"_ss, raii::string("limit=1&t=" + pstr + "&after=" + after));
}
post bot::get_controversial_post(const raii::string_base& subreddit, time::detail::time_period period){
post bot::get_controversial_post(const raii::string_base& subreddit, time::period period){
raii::static_string pstr = period.get();
return _get_post(subreddit, "controversial"_ss, raii::string("limit=1&t=" + pstr));
}
post bot::get_controversial_post(const raii::string_base& subreddit, const raii::string_base& after, time::detail::time_period period){
post bot::get_controversial_post(const raii::string_base& subreddit, const raii::string_base& after, time::period period){
raii::static_string pstr = period.get();
return _get_post(subreddit, "controversial"_ss, raii::string("limit=1&t=" + pstr + "&after=" + after));
}

File diff suppressed because one or more lines are too long