aboutsummaryrefslogtreecommitdiffstats
path: root/src/SimpleHandlers.cpp
blob: d9c6448344bf6f669270d136d1ba638178f0f030 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "SimpleHandlers.hpp"

#include "Response.hpp"

#include <array>
#include <cctype>
#include <memory>
#include <string>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <stdexcept>

using namespace Response;

Handler::json Handler::klingerHandler(std::string const &arguments, std::string const &session, void *payload) {
    (void) payload;
    return simple_response("Bonjour!");
}

Handler::json Handler::wikiHandler(std::string const &arguments, std::string const &session, void *payload) {
    (void) payload;

    std::vector<json> linkAnnotations;
    linkAnnotations.emplace_back(create_annotation(Reply::AnnotationType::link, "Wikipedia"));
    linkAnnotations.emplace_back(create_annotation(Reply::AnnotationType::underline));

    std::vector<json> reply_vec;
    reply_vec.emplace_back(create_text("Visit "));
    reply_vec.emplace_back(create_text("https://eo.wikipedia.org/", std::move(linkAnnotations)));
    reply_vec.emplace_back(create_text(" today!"));

    return create_response(std::move(reply_vec), session, true);
}

Handler::json Handler::helpHandler(std::string const &arguments, std::string const &session, void *payload) {
    auto commands = (std::vector<CommandHandler> *) payload;

    std::vector<json> reply_vec;
    reply_vec.emplace_back(create_text(
            "Reading from the gospel according to saint N,\n"
            "And you shall feast upon the fruits and vegetables as I do in the offering for they will make you strong.\n"
            "\n"
            "Dear my fellow users, these are my official commands, which are offered to my believers.\n"
            "\n"));

    for (auto const &itor : *commands) {
        std::vector<json> commandAnnotations;

        commandAnnotations.emplace_back(
                create_annotation(Reply::AnnotationType::command, std::move(itor.get_description())));

        reply_vec.emplace_back(create_text("- "));
        reply_vec.emplace_back(create_text(itor.command, std::move(commandAnnotations)));
    }

    reply_vec.emplace_back(create_text(
            "\n"
            "Thanks for using me. Takk skal du ha.\n"
            "Bussy\n"
            "N"));

    return create_response(std::move(reply_vec), session, true);
}

Handler::json Handler::stopHandler(std::string const &arguments, std::string const &session, void *payload) {
    auto app = (crow::SimpleApp *) payload;

    auto args = tokenizeArguments(arguments);

    if (args.empty()) {
        return simple_response("Needs PIN!", session, true);
    }

    int admin_pin;
    std::ifstream infile("/root/.n_admin_pin");

    if (!(infile >> admin_pin) || admin_pin != std::stoi(args.at(0))) {
        return simple_response("No PIN registered on server, admin commands unavailable", session, true);
    }

    app->stop();

    std::vector<json> annotations;
    annotations.emplace_back(create_annotation(Reply::AnnotationType::bold));

    std::vector<json> reply_vec;
    reply_vec.emplace_back(create_text("stopped", std::move(annotations)));

    return create_response(std::move(reply_vec), session, true);
}

json Handler::sayHandler(const std::string &arguments, const std::string &session, void *payload) {
    (void) payload;
    return simple_response(arguments, session, true);
}

std::string url_encode(std::string const &value) {
    std::ostringstream escaped;
    escaped.fill('0');
    escaped << std::hex;

    for (char c : value) {
        // Keep alphanumeric and other accepted characters intact
        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
            escaped << c;
            continue;
        }

        // Any other characters are percent-encoded
        escaped << std::uppercase;
        escaped << '%' << std::setw(2) << int((unsigned char) c);
        escaped << std::nouppercase;
    }

    return escaped.str();
}


std::string exec(const char* cmd) {
    std::array<char, 128> buffer{};
    std::string result;
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
    if (!pipe) {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
        result += buffer.data();
    }
    return result;
}

json Handler::latexRenderHandler(std::string const &arguments, std::string const &session, void *payload) {
    (void) payload;

    std::string file = exec("mktemp");

    std::string result = exec(("curl -s 'https://latex.codecogs.com/png.latex?" + url_encode(arguments) + "' "
            "-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' "
            "-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' "
            "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' "
            "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str());

    return simple_response(result, session, true);
}