165 lines
5.5 KiB
C++
165 lines
5.5 KiB
C++
/**
|
|
This file is a part of rexy's matrix bot
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "raii/rjp_string.hpp"
|
|
#include "raii/curler.hpp"
|
|
#include "raii/string_base.hpp"
|
|
#include "raii/string.hpp"
|
|
#include "raii/curler.hpp"
|
|
|
|
namespace reddit{
|
|
struct auth_data{
|
|
raii::rjp_string bot_name;
|
|
raii::rjp_string bot_pass;
|
|
raii::rjp_string acc_name;
|
|
raii::rjp_string acc_pass;
|
|
|
|
operator bool(void)const{
|
|
return (bot_name && bot_pass && acc_name && acc_pass);
|
|
}
|
|
};
|
|
|
|
|
|
namespace time{
|
|
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{
|
|
image, link, text, video, audio, unrecognized
|
|
};
|
|
|
|
class post
|
|
{
|
|
private:
|
|
enum post_flags{
|
|
POST_FLAGS_NONE = 0,
|
|
POST_FLAGS_CROSSPOSTED = 1
|
|
};
|
|
private:
|
|
raii::string m_post;
|
|
raii::rjp_string m_media_url;
|
|
raii::string m_hosted_video_audio;
|
|
raii::rjp_string m_author;
|
|
raii::rjp_string m_post_hint;
|
|
raii::rjp_string m_title;
|
|
raii::rjp_string m_name;
|
|
raii::rjp_string m_post_url;
|
|
post_type m_type = post_type::unrecognized;
|
|
int m_flags = POST_FLAGS_NONE;
|
|
|
|
public:
|
|
post(void) = default;
|
|
post(const raii::string_base& p);
|
|
post(raii::string_base&& p);
|
|
post(const post& p) = default;
|
|
post(post&& p) = default;
|
|
~post(void) = default;
|
|
|
|
post& operator=(const raii::string_base& p);
|
|
post& operator=(const post& p) = default;
|
|
post& operator=(post&& p) = default;
|
|
|
|
operator bool(void)const;
|
|
|
|
const raii::string& raw(void)const;
|
|
const raii::rjp_string& mediaurl(void)const;
|
|
const raii::string& hosted_video_audio(void)const;
|
|
const raii::rjp_string& posturl(void)const;
|
|
const raii::rjp_string& author(void)const;
|
|
const raii::rjp_string& post_hint(void)const;
|
|
const raii::rjp_string& title(void)const;
|
|
const raii::rjp_string& name(void)const;
|
|
bool is_crosspost(void)const;
|
|
post_type type(void)const;
|
|
private:
|
|
void _parse_post(void);
|
|
static post_type _handle_reddit_hosted_video(RJP_value* data, raii::rjp_string& media_url, raii::string& audio_url);
|
|
};
|
|
|
|
class bot
|
|
{
|
|
private:
|
|
raii::curler m_curl;
|
|
raii::string m_useragent;
|
|
raii::rjp_string m_access_token;
|
|
|
|
public:
|
|
bot(const auth_data& a, const raii::string_base& useragent);
|
|
bot(const auth_data& a, raii::string_base&& useragent);
|
|
bot(const bot& b);
|
|
bot(bot&& b);
|
|
~bot(void) = default;
|
|
|
|
bot& operator=(const bot& b);
|
|
bot& operator=(bot&& b);
|
|
|
|
const raii::rjp_string& access_token(void)const;
|
|
const raii::string& useragent(void)const;
|
|
void set_useragent(const raii::string_base&);
|
|
void set_useragent(raii::string_base&&);
|
|
|
|
void refresh_token(const auth_data& a);
|
|
|
|
post get_new_post(const raii::string_base& subreddit);
|
|
post get_new_post(const raii::string_base& subreddit, const raii::string_base& after);
|
|
post get_hot_post(const raii::string_base& subreddit);
|
|
post get_hot_post(const raii::string_base& subreddit, const raii::string_base& after);
|
|
post get_rising_post(const raii::string_base& subreddit);
|
|
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::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);
|
|
static raii::curl_llist _create_auth_header(const raii::string_base& access_token);
|
|
post _get_post(const raii::string_base& subreddit, const raii::string_base& category, const raii::string_base& extradata);
|
|
void _setup_subreddit_get_curl(const raii::curl_llist& header, const raii::string_base& url, const raii::string_base& reply);
|
|
|
|
static size_t _post_reply_curl_callback(char* ptr, size_t size, size_t nmemb, void* userdata);
|
|
static raii::string _create_request_post_data(const raii::string_base& acc_name, const raii::string_base& acc_pass);
|
|
static raii::string _create_request_userpwd(const raii::string_base& bot_name, const raii::string_base& bot_pass);
|
|
void _setup_token_request_curl(const raii::string_base& userpwd, const raii::string_base& postdata, void* result);
|
|
|
|
raii::string _request_access_token(const auth_data& a);
|
|
raii::rjp_string _acquire_access_token(const auth_data& a);
|
|
};
|
|
|
|
|
|
auth_data parse_auth_data(RJP_value* root);
|
|
|
|
}
|