matrix_thing/include/reddit.hpp
2019-03-05 19:16:29 -08:00

156 lines
5.2 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{
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;
}
enum class post_type{
image, link, text, video, unrecognized
};
class post
{
private:
raii::string m_post;
raii::rjp_string m_media_url;
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;
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::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;
post_type type(void)const;
private:
void _parse_post(void);
};
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&&);
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::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);
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);
}