improve build system

This commit is contained in:
Jay Robson 2024-05-08 12:24:04 +10:00
parent 36fe41f0da
commit a127a48715
19 changed files with 180 additions and 93 deletions

3
.clangd Normal file
View File

@ -0,0 +1,3 @@
CompileFlags:
Add: -std=c++20

View File

@ -1,3 +1,5 @@
file(GLOB SOURCES src/*.cpp)
include(src/page/CMakeLists.txt)
file(GLOB SOURCES ${SOURCES} src/*.cpp)

View File

@ -3,12 +3,12 @@
#include <format>
#include <unistd.h>
bool Contact::init()
bool Contact::Init()
{
return true;
}
bool Contact::send(const std::string &name, const std::string &email, const std::string &message)
bool Contact::Send(const std::string &name, const std::string &email, const std::string &message)
{
int id = fork();

View File

@ -6,8 +6,8 @@
namespace Contact
{
bool init();
bool send(const std::string& name, const std::string& email, const std::string& message);
bool Init();
bool Send(const std::string& name, const std::string& email, const std::string& message);
};

View File

@ -3,7 +3,7 @@
#include <fstream>
#include <sstream>
std::string Files::load(const std::string& path)
std::string Files::Load(const std::string& path)
{
std::ifstream file(path);
std::stringstream ss;

View File

@ -5,6 +5,6 @@
namespace Files
{
std::string load(const std::string& path);
std::string Load(const std::string& path);
}

View File

@ -1,100 +1,21 @@
#include "cpp-httplib/httplib.h"
#include "page/contact.hpp"
#include "page/error_handler.hpp"
#include "page/nav_targets.hpp"
#include "files.hpp"
#include "contact.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <format>
#include <regex>
const std::string DATA_INDEX = Files::load("../static/index.html");
const std::string DATA_ERROR = Files::load("../static/error.html");
const std::string PATH_LIGHT = "/static/css/light.css";
const std::string PATH_DARK = "/static/css/dark.css";
httplib::Server svr;
std::string get_theme(const httplib::Request& req)
{
std::string cookies = req.get_header_value("Cookie");
return regex_search(cookies, std::regex("(^|;) *theme=light")) ? PATH_LIGHT : PATH_DARK;
}
struct page_handler
{
std::string path;
page_handler(std::string path) : path(path) {}
void operator()(const httplib::Request& req, httplib::Response& res)
{
std::string data_content = Files::load(path);
std::string theme = get_theme(req);
std::string page = std::vformat(DATA_INDEX, std::make_format_args(theme, data_content));
res.set_content(page, "text/html");
}
};
struct theme_handler
{
std::string theme;
std::string content;
theme_handler(std::string theme, std::string content) : theme(theme), content(content) {}
void operator()(const httplib::Request& req, httplib::Response& res)
{
res.set_header("Set-Cookie", std::format("theme={}; Path=/; SameSite=Strict; HttpOnly; Max-Age=31536000", theme));
res.set_content(content, "text/html");
}
};
void put_contact(const httplib::Request& req, httplib::Response& res)
{
if(!req.has_param("name") || !req.has_param("email") || !req.has_param("message"))
{
res.status = 400;
res.set_content("<p>Bad request</p>", "text/html");
return;
}
if(!Contact::send(req.get_param_value("name"), req.get_param_value("email"), req.get_param_value("message")))
{
res.status = 500;
res.set_content("<p>Internal server error</p>", "text/html");
return;
}
res.set_content("<p>Message sent. Thanks!</p>", "text/html");
}
void error_handler(const httplib::Request& req, httplib::Response& res)
{
std::string theme = get_theme(req);
std::string page = std::vformat(DATA_INDEX, std::make_format_args(theme, DATA_ERROR));
res.set_content(page, "text/html");
}
int main()
{
if(!Contact::init())
{
return 1;
}
svr.set_mount_point("/static", "../static/public/");
svr.Get("/", page_handler("../static/public/html/projects.html"));
svr.Get("/projects", page_handler("../static/public/html/projects.html"));
svr.Get("/contact", page_handler("../static/public/html/contact.html"));
svr.Get("/about", page_handler("../static/public/html/about.html"));
svr.Put("/contact", put_contact);
svr.set_error_handler(error_handler);
Page::NavTargets::Init(svr);
Page::Contact::Init(svr);
Page::ErrorHandler::Init(svr);
std::cout << "Listening on port 8080\n";
svr.listen("0.0.0.0", 8080);

3
src/page/CMakeLists.txt Normal file
View File

@ -0,0 +1,3 @@
file(GLOB SOURCES ${SOURCES} src/page/*.cpp)

30
src/page/contact.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "contact.hpp"
#include "../contact.hpp"
void put_contact(const httplib::Request& req, httplib::Response& res)
{
if(!req.has_param("name") || !req.has_param("email") || !req.has_param("message"))
{
res.status = 400;
res.set_content("<p>Bad request</p>", "text/html");
return;
}
if(!::Contact::Send(req.get_param_value("name"), req.get_param_value("email"), req.get_param_value("message")))
{
res.status = 500;
res.set_content("<p>Internal server error</p>", "text/html");
return;
}
res.set_content("<p>Message sent. Thanks!</p>", "text/html");
}
void Page::Contact::Init(httplib::Server &svr)
{
::Contact::Init();
svr.Put("/contact", put_contact);
}

10
src/page/contact.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include "../cpp-httplib/httplib.h"
namespace Page::Contact
{
void Init(httplib::Server& svr);
};

View File

@ -0,0 +1,24 @@
#include "../files.hpp"
#include "error_handler.hpp"
#include "root.hpp"
#include "theme.hpp"
#include <format>
using namespace Page;
static const std::string DATA_ERROR = Files::Load("../static/error.html");
void error_handler(const httplib::Request& req, httplib::Response& res)
{
std::string theme = Theme::Get(req);
std::string page = std::vformat(Root::DATA_INDEX, std::make_format_args(theme, DATA_ERROR));
res.set_content(page, "text/html");
}
void Page::ErrorHandler::Init(httplib::Server &svr)
{
svr.set_error_handler(error_handler);
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "../cpp-httplib/httplib.h"
namespace Page::ErrorHandler
{
void Init(httplib::Server& svr);
};

32
src/page/nav_targets.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "nav_targets.hpp"
#include "root.hpp"
#include "theme.hpp"
#include "../files.hpp"
#include <format>
using namespace Page;
struct page_handler
{
std::string path;
page_handler(std::string path) : path(path) {}
void operator()(const httplib::Request& req, httplib::Response& res)
{
std::string data_content = Files::Load(path);
std::string theme = Theme::Get(req);
std::string page = std::vformat(Root::DATA_INDEX, std::make_format_args(theme, data_content));
res.set_content(page, "text/html");
}
};
void NavTargets::Init(httplib::Server &svr)
{
svr.Get("/", page_handler("../static/public/html/projects.html"));
svr.Get("/projects", page_handler("../static/public/html/projects.html"));
svr.Get("/contact", page_handler("../static/public/html/contact.html"));
svr.Get("/about", page_handler("../static/public/html/about.html"));
}

10
src/page/nav_targets.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include "../cpp-httplib/httplib.h"
namespace Page::NavTargets
{
void Init(httplib::Server& svr);
};

8
src/page/root.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "root.hpp"
#include "../files.hpp"
using namespace Page;
const std::string Root::DATA_INDEX = Files::Load("../static/index.html");

10
src/page/root.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <string>
namespace Page::Root
{
const extern std::string DATA_INDEX;
};

14
src/page/theme.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "theme.hpp"
static const std::string PATH_LIGHT = "/static/css/light.css";
static const std::string PATH_DARK = "/static/css/dark.css";
using namespace Page;
std::string Theme::Get(const httplib::Request& req)
{
std::string cookies = req.get_header_value("Cookie");
return regex_search(cookies, std::regex("(^|;) *theme=light")) ? PATH_LIGHT : PATH_DARK;
}

10
src/page/theme.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include "../cpp-httplib/httplib.h"
namespace Page::Theme
{
std::string Get(const httplib::Request& req);
};

View File

@ -1,7 +1,7 @@
<title>Jays Portfolio - About</title>
<h2>About Me</h2>
<h1>About Me</h1>
<div class="about-me">
<div>
<p>