#include "../http.hh"
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <functional>
using json = nlohmann::json;
GMainLoop *loop;
std::string roomid;
void handleMessages(std::shared_ptr<Error::Error> error,
const std::string &start,
const std::string &end,
const std::vector<json> &events,
Operator::Client::HTTPClientAPI *pClient, std::vector<std::string> *pMessages, std::vector<std::string>::iterator *pMsg_it) {
if (error)
{
std::cerr << "Error backfilling: " << error->to_string() << std::endl;
client.
logout([](std::shared_ptr<Error::Error> error) {
g_main_loop_quit(loop);
});
}
else
{
std::vector<std::string> &messages = *pMessages;
std::vector<std::string>::iterator &msg_it = *pMsg_it;
for (auto it = events.begin(); msg_it != messages.begin() && it != events.end(); ++it)
{
if ((*it)["type"].get<std::string>() == "m.room.message")
{
--msg_it;
const json &content = (*it)["content"];
if ((*it)["content"]["msgtype"].get<std::string>() == "m.emote")
{
*msg_it = "* " + (*it)["sender"].get<std::string>() + content["body"].get<std::string>();
}
else
{
*msg_it = (*it)["sender"].get<std::string>() + ": " + content["body"].get<std::string>();
}
}
}
if (msg_it != messages.begin() && !events.empty())
{
pClient->
roomMessages(roomid, end,
"",
"b", 0, std::bind(handleMessages, _1, _2, _3, _4, pClient, pMessages, pMsg_it));
}
else
{
for (; msg_it != messages.end(); ++msg_it)
{
std::cout << (*msg_it) << std::endl;
}
pClient->
logout([](std::shared_ptr<Error::Error> error) {
if (error)
{
std::cerr << "Error in logout: " << error->to_string() << std::endl;
}
g_main_loop_quit(loop);
});
}
}
}
int main(int argc, char**argv)
{
if (argc != 6 || !strcmp(argv[1], "--help"))
{
std::cout << "Usage:\n";
std::cout << " " << argv[0] << " <homeserver> <username> <password> <roomid> <limit>\n";
exit(0);
}
roomid = argv[4];
SoupSession *session = soup_session_new();
loop = g_main_loop_new(nullptr, FALSE);
std::vector<std::string> messages(atoi(argv[5]));
auto msg_it = messages.end();
client.
login(argv[2], argv[3], [&client, &messages, &msg_it](std::shared_ptr<Error::Error> error,
const std::string &username,
const std::string &homeserver) {
if (error)
{
std::cerr << "Error in login: " << error->to_string() << std::endl;
g_main_loop_quit(loop);
}
else
{
client.
sync(
"",
"",
false,
"offline", 0, [&client, &messages, &msg_it](std::shared_ptr<Error::Error> error,
const std::string &next, json rooms, json presence) {
if (error)
{
std::cerr << "Error in sync: " << error->to_string() << std::endl;
client.
logout([](std::shared_ptr<Error::Error> error) {
g_main_loop_quit(loop);
});
}
else
{
json &timeline = rooms["join"][roomid]["timeline"];
json &events = timeline["events"];
for (auto it = events.end(); msg_it != messages.begin() && it != events.begin(); --it)
{
json::iterator prev = it; --prev;
if ((*prev)["type"].get<std::string>() == "m.room.message")
{
--msg_it;
json &content = (*prev)["content"];
if ((*prev)["content"]["msgtype"].get<std::string>() == "m.emote")
{
*msg_it = "* " + (*prev)["sender"].get<std::string>() + content["body"].get<std::string>();
}
else
{
*msg_it = (*prev)["sender"].get<std::string>() + ": " + content["body"].get<std::string>();
}
}
}
std::cerr << "[done copying]\n";
if (msg_it != messages.begin() && timeline["limited"].get<bool>())
{
std::cerr << "[Backfilling]\n";
client.
roomMessages(roomid, timeline[
"prev_batch"],
"",
"b", 0, std::bind(handleMessages, _1, _2, _3, _4, &client, &messages, &msg_it));
}
else
{
for (; msg_it != messages.end(); ++msg_it)
{
std::cout << (*msg_it) << std::endl;
}
client.
logout([](std::shared_ptr<Error::Error> error) {
if (error)
{
std::cerr << "Error in logout: " << error->to_string() << std::endl;
}
g_main_loop_quit(loop);
});
}
}
});
}
});
g_main_loop_run(loop);
}