ramik_dev/main.cpp
2024-06-15 15:15:13 -04:00

76 lines
2.1 KiB
C++
Executable File

#include <crow_all.h>
#include <filesystem>
#include <string>
#include <array>
#include <memory>
#include <curl/curl.h>
std::string exec(const std::string &cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), static_cast<int>(buffer.size()), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
std::string url_decode(const std::string& encoded) {
int output_length;
const auto decoded_value = curl_easy_unescape(nullptr, encoded.c_str(), static_cast<int>(encoded.length()), &output_length);
std::string result(decoded_value, output_length);
curl_free(decoded_value);
return result;
}
std::string process_file(const std::filesystem::path &path) {
return exec("pandoc --template='templates/post.txt' -t plain '" + path.string() + "'");;
}
namespace route {
std::string root() {
return crow::mustache::load_text("index.html");
}
crow::mustache::rendered_template blog() {
std::string posts = "";
std::filesystem::path postsDir("posts");
std::vector<std::future<std::string>> futures;
for (auto const& entry : std::filesystem::directory_iterator{postsDir}) {
futures.emplace_back(std::async(std::launch::async, process_file, entry.path()));
}
for (auto& future : futures) {
posts += future.get();
}
auto page = crow::mustache::load("posts.html");
crow::mustache::context ctx( {{"posts", posts}} );
return page.render(ctx);
}
std::string post(const std::string &name) {
std::string decoded_name = url_decode(name);
if (std::filesystem::exists("posts/" + decoded_name))
return exec("pandoc --standalone --template templates/template.html './posts/" + decoded_name + "'");
else
return std::string("<h1>Not found</h1>");
}
};
int main() {
crow::SimpleApp app;
CROW_ROUTE(app, "/")(route::root);
CROW_ROUTE(app, "/blog")(route::blog);
CROW_ROUTE(app, "/blog/<string>")(route::post);
app.port(8080).multithreaded().run();
}