Rudimentary processing of messages
This commit is contained in:
3
TODO
3
TODO
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
115
src/test.cpp
115
src/test.cpp
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user