Compare commits
3 Commits
b59e81a41d
...
828d827c3d
Author | SHA1 | Date | |
---|---|---|---|
828d827c3d | |||
8ffa64beea | |||
e970ba1682 |
1
cache/mapcache.cpp
vendored
Normal file
1
cache/mapcache.cpp
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "mapcache.h"
|
37
cache/mapcache.h
vendored
Normal file
37
cache/mapcache.h
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef MAPCACHE_H
|
||||||
|
#define MAPCACHE_H
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <shared_mutex>
|
||||||
|
|
||||||
|
/* Thread-Safe Key-Value store */
|
||||||
|
template <class T> class MapCache
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<std::string, T> cache;
|
||||||
|
mutable std::shared_mutex sharedMutex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::optional<T> find(const std::string &key) const
|
||||||
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> lock(this->sharedMutex);
|
||||||
|
auto it = this->cache.find(key);
|
||||||
|
if(it != this->cache.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
void set(const std::string &key, const T &val)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::shared_mutex> lock{sharedMutex};
|
||||||
|
this->cache[key] = val;
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::shared_mutex> lock{sharedMutex};
|
||||||
|
this->cache.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAPCACHE_H
|
@ -34,7 +34,7 @@ void Handler::setGeneralVars(TemplatePage &page)
|
|||||||
}
|
}
|
||||||
Response Handler::errorResponse(std::string errortitle, std::string errormessage, int status)
|
Response Handler::errorResponse(std::string errortitle, std::string errormessage, int status)
|
||||||
{
|
{
|
||||||
TemplatePage &error = this->templ->getPage("error");
|
TemplatePage error = this->templ->getPage("error");
|
||||||
error.setVar("title", createPageTitle(errortitle));
|
error.setVar("title", createPageTitle(errortitle));
|
||||||
error.setVar("errortitle", errortitle);
|
error.setVar("errortitle", errortitle);
|
||||||
error.setVar("errormessage", errormessage);
|
error.setVar("errormessage", errormessage);
|
||||||
|
@ -32,7 +32,7 @@ Response HandlerAllCategories::handleRequest(const Request &r)
|
|||||||
"No categories",
|
"No categories",
|
||||||
"This wiki does not have any categories defined yet or your query options did not yield any results");
|
"This wiki does not have any categories defined yet or your query options did not yield any results");
|
||||||
}
|
}
|
||||||
TemplatePage &searchPage = this->templ->getPage("allcategories");
|
TemplatePage searchPage = this->templ->getPage("allcategories");
|
||||||
std::string body =
|
std::string body =
|
||||||
this->templ->renderSearch(resultList, [&](std::string str) { return this->urlProvider->category(str); });
|
this->templ->renderSearch(resultList, [&](std::string str) { return this->urlProvider->category(str); });
|
||||||
searchPage.setVar("categorylist", body);
|
searchPage.setVar("categorylist", body);
|
||||||
|
@ -32,7 +32,7 @@ Response HandlerAllPages::handleRequest(const Request &r)
|
|||||||
{
|
{
|
||||||
return errorResponse("No pages", "This wiki does not have any pages yet");
|
return errorResponse("No pages", "This wiki does not have any pages yet");
|
||||||
}
|
}
|
||||||
TemplatePage &searchPage = this->templ->getPage("allpages");
|
TemplatePage searchPage = this->templ->getPage("allpages");
|
||||||
std::string body = this->templ->renderSearch(resultList);
|
std::string body = this->templ->renderSearch(resultList);
|
||||||
searchPage.setVar("pagelist", body);
|
searchPage.setVar("pagelist", body);
|
||||||
searchPage.setVar("title", createPageTitle("All pages"));
|
searchPage.setVar("title", createPageTitle("All pages"));
|
||||||
|
@ -33,7 +33,7 @@ Response HandlerCategory::handleRequest(const Request &r)
|
|||||||
}
|
}
|
||||||
QueryOption qo = queryOption(r);
|
QueryOption qo = queryOption(r);
|
||||||
auto resultList = categoryDao->fetchMembers(categoryname, qo);
|
auto resultList = categoryDao->fetchMembers(categoryname, qo);
|
||||||
TemplatePage &searchPage = this->templ->getPage("show_category");
|
TemplatePage searchPage = this->templ->getPage("show_category");
|
||||||
std::string body = this->templ->renderSearch(resultList);
|
std::string body = this->templ->renderSearch(resultList);
|
||||||
searchPage.setVar("pagelist", body);
|
searchPage.setVar("pagelist", body);
|
||||||
searchPage.setVar("categoryname", categoryname);
|
searchPage.setVar("categoryname", categoryname);
|
||||||
|
@ -55,7 +55,7 @@ Response HandlerLogin::handleRequest(const Request &r)
|
|||||||
{
|
{
|
||||||
page = "index";
|
page = "index";
|
||||||
}
|
}
|
||||||
TemplatePage &loginTemplatePage = this->templ->getPage("login");
|
TemplatePage loginTemplatePage = this->templ->getPage("login");
|
||||||
setGeneralVars(loginTemplatePage);
|
setGeneralVars(loginTemplatePage);
|
||||||
loginTemplatePage.setVar("loginurl", urlProvider->login(page));
|
loginTemplatePage.setVar("loginurl", urlProvider->login(page));
|
||||||
loginTemplatePage.setVar("title", createPageTitle("Login"));
|
loginTemplatePage.setVar("title", createPageTitle("Login"));
|
||||||
|
@ -63,8 +63,9 @@ void HandlerPage::setPageVars(TemplatePage &page, std::string pagename)
|
|||||||
if(!pagename.empty())
|
if(!pagename.empty())
|
||||||
{
|
{
|
||||||
std::string headerlinks;
|
std::string headerlinks;
|
||||||
TemplatePage &headerlink = this->templ->getPage("_headerlink");
|
TemplatePage headerlink = this->templ->getPage("_headerlink");
|
||||||
auto addHeaderLink = [&headerlinks, &headerlink](std::string href, std::string value) {
|
auto addHeaderLink = [&headerlinks, &headerlink](std::string href, std::string value)
|
||||||
|
{
|
||||||
headerlink.setVar("href", href);
|
headerlink.setVar("href", href);
|
||||||
headerlink.setVar("value", value);
|
headerlink.setVar("value", value);
|
||||||
headerlinks += headerlink.render();
|
headerlinks += headerlink.render();
|
||||||
|
@ -121,7 +121,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplatePage &templatePage = this->templ->getPage("page_creation");
|
TemplatePage templatePage = this->templ->getPage("page_creation");
|
||||||
templatePage.setVar("actionurl", urlProvider->editPage(pagename));
|
templatePage.setVar("actionurl", urlProvider->editPage(pagename));
|
||||||
templatePage.setVar("content", body);
|
templatePage.setVar("content", body);
|
||||||
setPageVars(templatePage, pagename);
|
setPageVars(templatePage, pagename);
|
||||||
|
@ -128,7 +128,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
|||||||
return errorResponse("Database error", "While trying to fetch revision, a database error occured");
|
return errorResponse("Database error", "While trying to fetch revision, a database error occured");
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplatePage &page = this->templ->getPage(templatepartname);
|
TemplatePage page = this->templ->getPage(templatepartname);
|
||||||
|
|
||||||
Parser parser;
|
Parser parser;
|
||||||
Response result;
|
Response result;
|
||||||
|
@ -37,7 +37,7 @@ Response HandlerSearch::handleRequest(const Request &r)
|
|||||||
{
|
{
|
||||||
return errorResponse("No results", "Your search for " + q + " did not yield any results.");
|
return errorResponse("No results", "Your search for " + q + " did not yield any results.");
|
||||||
}
|
}
|
||||||
TemplatePage &searchPage = this->templ->getPage("search");
|
TemplatePage searchPage = this->templ->getPage("search");
|
||||||
std::string body = this->templ->renderSearch(resultList);
|
std::string body = this->templ->renderSearch(resultList);
|
||||||
searchPage.setVar("pagelist", body);
|
searchPage.setVar("pagelist", body);
|
||||||
searchPage.setVar("searchterm", q);
|
searchPage.setVar("searchterm", q);
|
||||||
|
@ -51,7 +51,7 @@ Response HandlerUserSettings::handleRequest(const Request &r)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplatePage &userSettingsPage = this->templ->getPage("usersettings");
|
TemplatePage userSettingsPage = this->templ->getPage("usersettings");
|
||||||
setGeneralVars(userSettingsPage);
|
setGeneralVars(userSettingsPage);
|
||||||
userSettingsPage.setVar("usersettingsurl", urlProvider->userSettings());
|
userSettingsPage.setVar("usersettingsurl", urlProvider->userSettings());
|
||||||
userSettingsPage.setVar("title", createPageTitle("User settings - " + this->userSession->user.login));
|
userSettingsPage.setVar("title", createPageTitle("User settings - " + this->userSession->user.login));
|
||||||
|
@ -180,7 +180,9 @@ int main(int argc, char **argv)
|
|||||||
userdao->save(anon.value());
|
userdao->save(anon.value());
|
||||||
User::setAnon(anon.value());
|
User::setAnon(anon.value());
|
||||||
|
|
||||||
Template siteTemplate{config.templateprefix, config.templatepath, config.urls, config.configVarResolver};
|
MapCache<TemplatePage> mapCache;
|
||||||
|
Template siteTemplate{config.templateprefix, config.templatepath, config.urls, config.configVarResolver,
|
||||||
|
mapCache};
|
||||||
UrlProvider urlProvider{config.urls};
|
UrlProvider urlProvider{config.urls};
|
||||||
|
|
||||||
auto cache = createCache(config.configVarResolver);
|
auto cache = createCache(config.configVarResolver);
|
||||||
|
@ -59,7 +59,7 @@ Response RequestWorker::processRequest(const Request &r)
|
|||||||
if(session.loggedIn && session.csrf_token != r.post("csrf_token"))
|
if(session.loggedIn && session.csrf_token != r.post("csrf_token"))
|
||||||
{
|
{
|
||||||
// TODO: this is code duplication
|
// TODO: this is code duplication
|
||||||
TemplatePage &error = this->templ->getPage("error");
|
TemplatePage error = this->templ->getPage("error");
|
||||||
error.setVar("errortitle", "Invalid csrf token");
|
error.setVar("errortitle", "Invalid csrf token");
|
||||||
error.setVar("errormessage", "Invalid csrf token");
|
error.setVar("errormessage", "Invalid csrf token");
|
||||||
return {403, error.render()};
|
return {403, error.render()};
|
||||||
|
25
template.cpp
25
template.cpp
@ -24,12 +24,25 @@ SOFTWARE.
|
|||||||
#include "htmllink.h"
|
#include "htmllink.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
Template::Template(std::string templateprefix, std::string templatepath, ConfigUrls &configUrls,
|
Template::Template(std::string templateprefix, std::string templatepath, ConfigUrls &configUrls,
|
||||||
ConfigVariableResolver &configVarsResolver)
|
ConfigVariableResolver &configVarsResolver, MapCache<TemplatePage> &pageCache)
|
||||||
{
|
{
|
||||||
this->templateprefix = templateprefix;
|
this->templateprefix = templateprefix;
|
||||||
this->templatepath = templatepath;
|
this->templatepath = templatepath;
|
||||||
this->configUrls = &configUrls;
|
this->configUrls = &configUrls;
|
||||||
this->configVarResolver = &configVarsResolver;
|
this->configVarResolver = &configVarsResolver;
|
||||||
|
this->pageCache = &pageCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
TemplatePage Template::getPage(const std::string &pagename)
|
||||||
|
{
|
||||||
|
auto result = this->pageCache->find(pagename);
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
auto page = createPage(pagename);
|
||||||
|
this->pageCache->set(pagename, page);
|
||||||
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Template::getPartPath(std::string_view partname)
|
std::string Template::getPartPath(std::string_view partname)
|
||||||
@ -65,16 +78,6 @@ TemplatePage Template::createPage(std::string name)
|
|||||||
return TemplatePage(replacer.parse(content));
|
return TemplatePage(replacer.parse(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplatePage &Template::getPage(const std::string &pagename)
|
|
||||||
{
|
|
||||||
if(utils::hasKey(pagesMap, pagename))
|
|
||||||
{
|
|
||||||
return pagesMap[pagename];
|
|
||||||
}
|
|
||||||
pagesMap.insert(std::make_pair(pagename, createPage(pagename)));
|
|
||||||
return pagesMap[pagename];
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this restricts template a bit
|
// TODO: this restricts template a bit
|
||||||
std::string Template::renderSearch(const std::vector<std::string> &results,
|
std::string Template::renderSearch(const std::vector<std::string> &results,
|
||||||
std::function<std::string(std::string)> callback) const
|
std::function<std::string(std::string)> callback) const
|
||||||
|
12
template.h
12
template.h
@ -8,16 +8,17 @@
|
|||||||
#include "response.h"
|
#include "response.h"
|
||||||
#include "searchresult.h"
|
#include "searchresult.h"
|
||||||
#include "revision.h"
|
#include "revision.h"
|
||||||
|
#include "cache/mapcache.h"
|
||||||
class Template
|
class Template
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ConfigVariableResolver *configVarResolver;
|
ConfigVariableResolver *configVarResolver;
|
||||||
ConfigUrls *configUrls;
|
ConfigUrls *configUrls;
|
||||||
|
MapCache<TemplatePage> *pageCache;
|
||||||
|
|
||||||
std::string templateprefix;
|
std::string templateprefix;
|
||||||
std::string templatepath;
|
std::string templatepath;
|
||||||
|
|
||||||
std::map<std::string, TemplatePage> pagesMap;
|
|
||||||
std::string resolveIncludes(std::string_view content);
|
std::string resolveIncludes(std::string_view content);
|
||||||
|
|
||||||
std::string getPartPath(std::string_view partname);
|
std::string getPartPath(std::string_view partname);
|
||||||
@ -27,12 +28,9 @@ class Template
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Template(std::string templateprefix, std::string templatepath, ConfigUrls &configUrls,
|
Template(std::string templateprefix, std::string templatepath, ConfigUrls &configUrls,
|
||||||
ConfigVariableResolver &configVarsResolver);
|
ConfigVariableResolver &configVarsResolver, MapCache<TemplatePage> &pageCache);
|
||||||
/* TODO: returning this as a reference is by no means a risk free business,
|
|
||||||
because between requests, different vars can be set conditionally,
|
TemplatePage getPage(const std::string &pagename);
|
||||||
thus creating a mess
|
|
||||||
*/
|
|
||||||
TemplatePage &getPage(const std::string &pagename);
|
|
||||||
|
|
||||||
std::string renderSearch(const std::vector<std::string> &results,
|
std::string renderSearch(const std::vector<std::string> &results,
|
||||||
std::function<std::string(std::string)> callback) const;
|
std::function<std::string(std::string)> callback) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user