Compare commits
8 Commits
ba06d04a08
...
9b35e43161
Author | SHA1 | Date | |
---|---|---|---|
9b35e43161 | |||
73a4e4c10f | |||
1e224fdac6 | |||
fbca85e5ed | |||
15e4f081cc | |||
e876b15c5d | |||
3e736db0ef | |||
03c5646858 |
@ -85,6 +85,7 @@ Config::Config(const std::map<std::string, std::string> &map)
|
||||
this->urls.linkindex = required("linkindex");
|
||||
this->urls.linklogout = required("linklogout");
|
||||
this->urls.linkpage = required("linkpage");
|
||||
this->urls.linkpagebytitle = required("linkpagebytitle");
|
||||
this->urls.linkrecent = required("linkrecent");
|
||||
this->urls.linkrevision = required("linkrevision");
|
||||
this->urls.linksettings = required("linksettings");
|
||||
|
1
config.h
1
config.h
@ -26,6 +26,7 @@ struct ConfigUrls
|
||||
std::string linkallcats;
|
||||
std::string linkshere;
|
||||
std::string linkpage;
|
||||
std::string linkpagebytitle;
|
||||
std::string linkrevision;
|
||||
std::string linkhistory;
|
||||
std::string linkedit;
|
||||
|
@ -13,6 +13,7 @@ class PageDao
|
||||
virtual bool exists(std::string page) const = 0;
|
||||
virtual bool exists(unsigned int id) const = 0;
|
||||
virtual std::optional<Page> find(std::string name) = 0;
|
||||
virtual std::optional<Page> findByTitle(std::string title) = 0;
|
||||
virtual std::optional<Page> find(unsigned int id) = 0;
|
||||
virtual std::vector<std::string> getPageList(QueryOption option) = 0;
|
||||
virtual std::vector<std::string> fetchCategories(std::string pagename, QueryOption option) = 0;
|
||||
|
@ -52,6 +52,26 @@ std::optional<Page> PageDaoSqlite::find(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Page> PageDaoSqlite::findByTitle(std::string title)
|
||||
{
|
||||
Page result;
|
||||
try
|
||||
{
|
||||
auto ps = *db << "SELECT id, name, title, lastrevision, visible FROM page WHERE title = ?";
|
||||
ps << title >> std::tie(result.pageid, result.name, result.title, result.current_revision, result.listed);
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<Page> PageDaoSqlite::find(unsigned int id)
|
||||
{
|
||||
Page result;
|
||||
|
@ -20,6 +20,7 @@ class PageDaoSqlite : public PageDao, protected SqliteDao
|
||||
bool exists(std::string name) const override;
|
||||
void save(const Page &page) override;
|
||||
std::optional<Page> find(std::string name) override;
|
||||
std::optional<Page> findByTitle(std::string title) override;
|
||||
std::optional<Page> find(unsigned int id) override;
|
||||
std::vector<std::string> getPageList(QueryOption option) override;
|
||||
std::vector<std::string> fetchCategories(std::string pagename, QueryOption option) override;
|
||||
|
11
dynamic/dynamiccontentgetvar.cpp
Normal file
11
dynamic/dynamiccontentgetvar.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "dynamiccontentgetvar.h"
|
||||
|
||||
std::string DynamicContentGetVar::render()
|
||||
{
|
||||
return (*this->map)[this->argument];
|
||||
}
|
||||
|
||||
void DynamicContentGetVar::setMap(std::map<std::string, std::string> &map)
|
||||
{
|
||||
this->map = ↦
|
||||
}
|
19
dynamic/dynamiccontentgetvar.h
Normal file
19
dynamic/dynamiccontentgetvar.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef DYNAMICCONTENTGETVAR_H
|
||||
#define DYNAMICCONTENTGETVAR_H
|
||||
|
||||
#include "dynamiccontent.h"
|
||||
class DynamicContentGetVar : public DynamicContent
|
||||
{
|
||||
private:
|
||||
std::map<std::string, std::string> *map;
|
||||
|
||||
public:
|
||||
using DynamicContent::DynamicContent;
|
||||
|
||||
// DynamicContent interface
|
||||
public:
|
||||
std::string render();
|
||||
void setMap(std::map<std::string, std::string> &map);
|
||||
};
|
||||
|
||||
#endif // DYNAMICCONTENTGETVAR_H
|
@ -6,9 +6,7 @@ std::string DynamicContentIncludePage::render()
|
||||
auto rev = revisionDao->getCurrentForPage(this->argument);
|
||||
if(rev)
|
||||
{
|
||||
Parser parser;
|
||||
auto result = parser.parse(*this->database->createPageDao(), *this->urlProvider, rev->content);
|
||||
return result;
|
||||
return rev->content;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -25,12 +25,13 @@ std::string DynamicContentPostList::render()
|
||||
stream << postListBegin;
|
||||
for(auto &pair : pageList)
|
||||
{
|
||||
std::string link = this->urlProvider->page(pair.first);
|
||||
std::string title = pageDao->find(pair.first)->title;
|
||||
std::string link = this->urlProvider->pageByTitle(title);
|
||||
std::string date = utils::toISODate(pair.second);
|
||||
Varreplacer replacer{"{"};
|
||||
replacer.addKeyValue("url", link);
|
||||
replacer.addKeyValue("date", date);
|
||||
replacer.addKeyValue("title", pageDao->find(pair.first)->title);
|
||||
replacer.addKeyValue("title", title);
|
||||
|
||||
stream << replacer.parse(postLink);
|
||||
}
|
||||
|
21
dynamic/dynamiccontentsetvar.cpp
Normal file
21
dynamic/dynamiccontentsetvar.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "dynamiccontentsetvar.h"
|
||||
|
||||
std::string DynamicContentSetVar::render()
|
||||
{
|
||||
auto result = utils::split(this->argument, '=');
|
||||
if(result.size() == 2)
|
||||
{
|
||||
this->map->emplace(std::make_pair(result[0], result[1]));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void DynamicContentSetVar::setArgument(std::string argument)
|
||||
{
|
||||
this->argument = argument;
|
||||
}
|
||||
|
||||
void DynamicContentSetVar::setMap(std::map<std::string, std::string> &map)
|
||||
{
|
||||
this->map = ↦
|
||||
}
|
17
dynamic/dynamiccontentsetvar.h
Normal file
17
dynamic/dynamiccontentsetvar.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef DYNAMCCONTENTPUSHVAR_H
|
||||
#define DYNAMCCONTENTPUSHVAR_H
|
||||
#include "dynamiccontent.h"
|
||||
class DynamicContentSetVar : public DynamicContent
|
||||
{
|
||||
private:
|
||||
std::map<std::string, std::string> *map;
|
||||
|
||||
public:
|
||||
using DynamicContent::DynamicContent;
|
||||
|
||||
std::string render();
|
||||
void setArgument(std::string argument);
|
||||
void setMap(std::map<std::string, std::string> &map);
|
||||
};
|
||||
|
||||
#endif // DYNAMCCONTENTPUSHVAR_H
|
@ -27,7 +27,18 @@ Response HandlerPage::handle(const Request &r)
|
||||
auto pageDao = this->database->createPageDao();
|
||||
if(pagename.empty())
|
||||
{
|
||||
return errorResponse("No page given", "No page given to request");
|
||||
std::string title = r.get("title");
|
||||
if(title.empty())
|
||||
{
|
||||
return errorResponse("No page given", "No page given to request");
|
||||
}
|
||||
title = utils::strreplace(title, "-", " ");
|
||||
auto page = pageDao->findByTitle(title);
|
||||
if(!page)
|
||||
{
|
||||
return errorResponse("No page by such title", "No page with such title exists");
|
||||
}
|
||||
pagename = page->name;
|
||||
}
|
||||
|
||||
if(pageMustExist() && !pageDao->exists(pagename))
|
||||
|
@ -25,6 +25,9 @@ SOFTWARE.
|
||||
#include "../htmllink.h"
|
||||
#include "../dynamic/dynamiccontentpostlist.h"
|
||||
#include "../dynamic/dynamiccontentincludepage.h"
|
||||
#include "../dynamic/dynamiccontentsetvar.h"
|
||||
#include "../dynamic/dynamiccontentgetvar.h"
|
||||
|
||||
bool HandlerPageView::canAccess(std::string page)
|
||||
{
|
||||
return effectivePermissions(page).canRead();
|
||||
@ -137,6 +140,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
std::string indexcontent;
|
||||
std::string parsedcontent;
|
||||
|
||||
std::map<std::string, std::string> dynamicVarsMap;
|
||||
std::function<std::string(std::string_view, std::string_view)> dynamicParseCallback =
|
||||
[&](std::string_view key, std::string_view value) -> std::string
|
||||
{
|
||||
@ -148,16 +152,34 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
}
|
||||
if(key == "dynamic:includepage")
|
||||
{
|
||||
std::shared_ptr<DynamicContentIncludePage> includePage = createDynamic<DynamicContentIncludePage>();
|
||||
includePage->setArgument(std::string(value));
|
||||
return includePage->render();
|
||||
if((effectivePermissions(std::string(value)).canRead()))
|
||||
{
|
||||
std::shared_ptr<DynamicContentIncludePage> includePage = createDynamic<DynamicContentIncludePage>();
|
||||
includePage->setArgument(std::string(value));
|
||||
return parser.parseDynamics(includePage->render(), dynamicParseCallback);
|
||||
}
|
||||
}
|
||||
if(key == "dynamic:setvar")
|
||||
{
|
||||
std::shared_ptr<DynamicContentSetVar> setVar = createDynamic<DynamicContentSetVar>();
|
||||
setVar->setMap(dynamicVarsMap);
|
||||
setVar->setArgument(std::string(value));
|
||||
return setVar->render();
|
||||
}
|
||||
if(key == "dynamic:getvar")
|
||||
{
|
||||
std::shared_ptr<DynamicContentGetVar> getVar = createDynamic<DynamicContentGetVar>();
|
||||
getVar->setMap(dynamicVarsMap);
|
||||
getVar->setArgument(std::string(value));
|
||||
return getVar->render();
|
||||
}
|
||||
return std::string{};
|
||||
};
|
||||
std::string resolvedContent = parser.parseDynamics(revision->content, dynamicParseCallback);
|
||||
if(revisionid > 0)
|
||||
{
|
||||
indexcontent = createIndexContent(parser, revision->content);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content, dynamicParseCallback);
|
||||
indexcontent = createIndexContent(parser, resolvedContent);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, resolvedContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -171,7 +193,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
}
|
||||
else
|
||||
{
|
||||
indexcontent = createIndexContent(parser, revision->content);
|
||||
indexcontent = createIndexContent(parser, resolvedContent);
|
||||
this->cache->put(cachekeyindexcontent, indexcontent);
|
||||
}
|
||||
if(cachedparsedcontent)
|
||||
@ -180,7 +202,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename,
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content, dynamicParseCallback);
|
||||
parsedcontent = parser.parse(pageDao, *this->urlProvider, resolvedContent);
|
||||
this->cache->put(cachekeyparsedcontent, parsedcontent);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ class IParser
|
||||
}
|
||||
virtual std::string parse(const PageDao &pagedao, UrlProvider &provider, const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const = 0;
|
||||
|
||||
virtual std::string parseDynamics(
|
||||
const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const = 0;
|
||||
virtual std::vector<std::string> extractCategories(const std::string &content) const = 0;
|
||||
|
||||
virtual ~IParser(){};
|
||||
|
15
parser.cpp
15
parser.cpp
@ -30,7 +30,8 @@ SOFTWARE.
|
||||
std::vector<Headline> Parser::extractHeadlines(const std::string &content) const
|
||||
{
|
||||
std::vector<Headline> result;
|
||||
std::string reg = R"(\[h(1|2|3)\](.*?)\[/h\1\])";
|
||||
|
||||
std::string reg = R"(\[h(1|2|3)\](\[.*?\])*(.*?)\[.*?\]*\[\/h\1\])";
|
||||
std::regex headerfinder(reg);
|
||||
auto begin = std::sregex_iterator(content.begin(), content.end(), headerfinder);
|
||||
auto end = std::sregex_iterator();
|
||||
@ -40,7 +41,7 @@ std::vector<Headline> Parser::extractHeadlines(const std::string &content) const
|
||||
auto smatch = *it;
|
||||
Headline h;
|
||||
h.level = utils::toUInt(smatch.str(1));
|
||||
h.title = smatch.str(2);
|
||||
h.title = smatch.str(3);
|
||||
result.push_back(h);
|
||||
}
|
||||
return result;
|
||||
@ -122,7 +123,7 @@ std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const s
|
||||
std::string result;
|
||||
// we don't care about commands, but we nevertheless replace them with empty strings
|
||||
std::regex tagfinder(
|
||||
R"(\[(b|i|u|li||ul|ol|link|wikilink|h\d|cmd:rename|cmd:redirect|cmd:pagetitle|category|dynamic:postlist|dynamic:includepage)*?\]((\s|\S)*?)\[/\1])");
|
||||
R"(\[(b|i|u|li||ul|ol|link|wikilink|h\d|cmd:rename|cmd:redirect|cmd:pagetitle|category|dynamic:postlist|dynamic:includepage|dynamic:getvar|dynamic:setvar)*?\]((\s|\S)*?)\[/\1])");
|
||||
result = utils::regex_callback_replacer(
|
||||
tagfinder, content,
|
||||
[&](std::smatch &match)
|
||||
@ -150,3 +151,11 @@ std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, const s
|
||||
result = utils::strreplace(result, "\r\n", "<br>");
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Parser::parseDynamics(const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const
|
||||
{
|
||||
std::regex tagfinder(R"(\[(dynamic:\w+)*?\]((\s|\S)*?)\[/\1])");
|
||||
return utils::regex_callback_replacer(tagfinder, content,
|
||||
[&](std::smatch &match) { return callback(match.str(1), match.str(2)); });
|
||||
}
|
||||
|
3
parser.h
3
parser.h
@ -15,6 +15,9 @@ class Parser : public IParser
|
||||
virtual std::string parse(
|
||||
const PageDao &pagedao, UrlProvider &provider, const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const override;
|
||||
std::string parseDynamics(
|
||||
const std::string &content,
|
||||
const std::function<std::string(std::string_view, std::string_view)> &callback) const override;
|
||||
|
||||
using IParser::IParser;
|
||||
};
|
||||
|
@ -63,6 +63,11 @@ std::string UrlProvider::page(std::string pagename)
|
||||
return replaceOnlyPage(config->linkpage, pagename);
|
||||
}
|
||||
|
||||
std::string UrlProvider::pageByTitle(std::string title)
|
||||
{
|
||||
return replaceSingleVar(config->linkpagebytitle, "title", utils::strreplace(title, " ", "-"));
|
||||
}
|
||||
|
||||
std::string UrlProvider::linksHere(std::string pagename)
|
||||
{
|
||||
return replaceOnlyPage(config->linkshere, pagename);
|
||||
|
@ -27,6 +27,8 @@ class UrlProvider
|
||||
|
||||
std::string page(std::string pagename);
|
||||
|
||||
std::string pageByTitle(std::string title);
|
||||
|
||||
std::string linksHere(std::string pagename);
|
||||
|
||||
std::string pageHistory(std::string pagename);
|
||||
|
Loading…
Reference in New Issue
Block a user