Compare commits
	
		
			9 Melakukan
		
	
	
		
			172129179e
			...
			feature/ma
		
	
	| Penulis | SHA1 | Tanggal | |
|---|---|---|---|
| ebd4adf22f | |||
| 3745a778e5 | |||
| cec56d5a73 | |||
| 534d9f74e7 | |||
| 5f674cfe6f | |||
| ea7476a882 | |||
| ab9e5fb0bd | |||
| 7ca04fbf45 | |||
| 8b44dd4e94 | 
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -7,3 +7,6 @@ | ||||
| [submodule "submodules/qssb.h"] | ||||
| 	path = submodules/qssb.h | ||||
| 	url = https://gitea.quitesimple.org/crtxcr/qssb.h.git | ||||
| [submodule "submodules/qsmaddy"] | ||||
| 	path = submodules/qsmaddy | ||||
| 	url = https://gitea.quitesimple.org/crtxcr/qsmaddy | ||||
|   | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| CXXFLAGS=-std=c++17 -O0 -g -no-pie -pipe -MMD -Wall -Wextra | ||||
| RELEASE_CXXFLAGS=-std=c++17 -O3 -pipe -MMD -Wall -Wextra | ||||
| LDFLAGS=-lsqlite3 -lpthread -lcrypto -lstdc++fs -lseccomp | ||||
| INCLUDEFLAGS=-I submodules/sqlitemoderncpp/hdr -I submodules/cpp-httplib -I submodules/qssb.h | ||||
| INCLUDEFLAGS=-I submodules/sqlitemoderncpp/hdr -I submodules/cpp-httplib -I submodules/qssb.h -I submodules/qsmaddy/include/ | ||||
|  | ||||
| CXX=g++ | ||||
|  | ||||
|   | ||||
| @@ -71,6 +71,7 @@ Config::Config(const std::map<std::string, std::string> &map) | ||||
|  | ||||
| 	this->configmap = map; | ||||
| 	this->wikipath = optional("wikipath", "/"); | ||||
| 	this->parser = optional("parser", "markdown"); | ||||
| 	this->handlersConfig.anon_username = optional("anon_username", "anonymouse"); | ||||
| 	this->handlersConfig.wikiname = required("wikiname"); | ||||
| 	this->logfile = required("logfile"); | ||||
|   | ||||
							
								
								
									
										1
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								config.h
									
									
									
									
									
								
							| @@ -86,6 +86,7 @@ class Config | ||||
| 	std::string templateprefix; | ||||
| 	std::string logfile; | ||||
| 	std::string connectionstring; | ||||
| 	std::string parser; | ||||
| 	int session_max_lifetime; | ||||
| 	int threadscount; | ||||
|  | ||||
|   | ||||
| @@ -9,10 +9,13 @@ | ||||
| #include "../database/queryoption.h" | ||||
| #include "../logger.h" | ||||
| #include "../cache/icache.h" | ||||
| #include "../iparser.h" | ||||
|  | ||||
| class Handler | ||||
| { | ||||
|   protected: | ||||
| 	ICache *cache; | ||||
| 	IParser *parser; | ||||
| 	Template *templ; | ||||
| 	Database *database; | ||||
| 	Session *userSession; | ||||
| @@ -25,7 +28,7 @@ class Handler | ||||
|  | ||||
|   public: | ||||
| 	Handler(HandlerConfig &handlersConfig, Template &templ, Database &db, Session &userSession, UrlProvider &provider, | ||||
| 			ICache &cache) | ||||
| 			ICache &cache, IParser &parser) | ||||
| 	{ | ||||
| 		this->handlersConfig = &handlersConfig; | ||||
| 		this->templ = &templ; | ||||
| @@ -33,6 +36,7 @@ class Handler | ||||
| 		this->userSession = &userSession; | ||||
| 		this->urlProvider = &provider; | ||||
| 		this->cache = &cache; | ||||
| 		this->parser = &parser; | ||||
| 	} | ||||
|  | ||||
| 	virtual Response handle(const Request &r); | ||||
|   | ||||
| @@ -10,15 +10,16 @@ class HandlerFactory | ||||
| 	Database &db; | ||||
| 	UrlProvider &urlProvider; | ||||
| 	ICache &cache; | ||||
| 	IParser &parser; | ||||
|  | ||||
| 	template <class T> inline std::unique_ptr<T> produce(Session &userSession) | ||||
| 	{ | ||||
| 		return std::make_unique<T>(handlerConfig, templ, db, userSession, urlProvider, cache); | ||||
| 		return std::make_unique<T>(handlerConfig, templ, db, userSession, urlProvider, cache, parser); | ||||
| 	} | ||||
|  | ||||
|   public: | ||||
| 	HandlerFactory(HandlerConfig &handlerConfig, Template &templ, Database &db, UrlProvider &urlprovider, ICache &cache) | ||||
| 		: handlerConfig(handlerConfig), templ(templ), db(db), urlProvider(urlprovider), cache(cache) | ||||
| 	HandlerFactory(HandlerConfig &handlerConfig, Template &templ, Database &db, UrlProvider &urlprovider, ICache &cache, IParser &parser) | ||||
| 		: handlerConfig(handlerConfig), templ(templ), db(db), urlProvider(urlprovider), cache(cache), parser(parser) | ||||
| 	{ | ||||
| 	} | ||||
| 	std::unique_ptr<Handler> createHandler(const std::string &action, Session &userSession); | ||||
|   | ||||
| @@ -21,8 +21,8 @@ SOFTWARE. | ||||
| #include "handlerpageedit.h" | ||||
| #include "../database/exceptions.h" | ||||
| #include "../request.h" | ||||
| #include "../parserlegacy.h" | ||||
|  | ||||
| #include "../parser.h" | ||||
| bool HandlerPageEdit::canAccess(std::string page) | ||||
| { | ||||
| 	return this->userSession->user.permissions.canEdit(); | ||||
| @@ -59,7 +59,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename, | ||||
|  | ||||
| 			// TODO: must check, whether categories differ, and perhaps don't allow every user | ||||
| 			// to set categories | ||||
| 			Parser parser; | ||||
| 			ParserLegacy parser; | ||||
| 			std::vector<std::string> cats = parser.extractCategories(newContent); | ||||
| 			try | ||||
| 			{ | ||||
| @@ -107,7 +107,7 @@ Response HandlerPageEdit::handleRequest(PageDao &pageDao, std::string pagename, | ||||
| 		if(r.post("do") == "preview") | ||||
| 		{ | ||||
| 			std::string newContent = r.post("content"); | ||||
| 			Parser parser; | ||||
| 			ParserLegacy parser; | ||||
| 			TemplatePage templatePage = this->templ->getPage("page_creation_preview"); | ||||
| 			templatePage.setVar("actionurl", urlProvider->editPage(pagename)); | ||||
| 			templatePage.setVar("preview_content", parser.parse(pageDao, *this->urlProvider, newContent)); | ||||
|   | ||||
| @@ -21,7 +21,7 @@ SOFTWARE. | ||||
| #include "handlerpageview.h" | ||||
| #include "../database/exceptions.h" | ||||
| #include "../logger.h" | ||||
| #include "../parser.h" | ||||
| #include "../parserlegacy.h" | ||||
| #include "../htmllink.h" | ||||
|  | ||||
| bool HandlerPageView::canAccess(std::string page) | ||||
| @@ -130,7 +130,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename, | ||||
|  | ||||
| 	TemplatePage &page = this->templ->getPage(templatepartname); | ||||
|  | ||||
| 	Parser parser; | ||||
|  | ||||
| 	Response result; | ||||
| 	result.setStatus(200); | ||||
| 	std::string indexcontent; | ||||
| @@ -138,8 +138,8 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename, | ||||
|  | ||||
| 	if(revisionid > 0) | ||||
| 	{ | ||||
| 		indexcontent = createIndexContent(parser, revision->content); | ||||
| 		parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content); | ||||
| 		indexcontent = createIndexContent(*parser, revision->content); | ||||
| 		parsedcontent = parser->parse(pageDao, *this->urlProvider, revision->content); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| @@ -153,7 +153,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename, | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			indexcontent = createIndexContent(parser, revision->content); | ||||
| 			indexcontent = createIndexContent(*parser, revision->content); | ||||
| 			this->cache->put(cachekeyindexcontent, indexcontent); | ||||
| 		} | ||||
| 		if(cachedparsedcontent) | ||||
| @@ -162,7 +162,7 @@ Response HandlerPageView::handleRequest(PageDao &pageDao, std::string pagename, | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			parsedcontent = parser.parse(pageDao, *this->urlProvider, revision->content); | ||||
| 			parsedcontent = parser->parse(pageDao, *this->urlProvider, revision->content); | ||||
| 			this->cache->put(cachekeyparsedcontent, parsedcontent); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -5,6 +5,8 @@ | ||||
| #include "headline.h" | ||||
| #include "database/pagedao.h" | ||||
| #include "urlprovider.h" | ||||
|  | ||||
|  | ||||
| class IParser | ||||
| { | ||||
|   public: | ||||
| @@ -16,4 +18,6 @@ class IParser | ||||
| 	virtual ~IParser(){}; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif // PARSER_H | ||||
|   | ||||
| @@ -24,29 +24,22 @@ SOFTWARE. | ||||
| #include <vector> | ||||
| #include <algorithm> | ||||
| #include <iterator> | ||||
| #include "parser.h" | ||||
| #include "parserlegacy.h" | ||||
| #include "utils.h" | ||||
| #include "htmllink.h" | ||||
| std::vector<Headline> Parser::extractHeadlines(std::string content) const | ||||
| std::vector<Headline> ParserLegacy::extractHeadlines(std::string content) const | ||||
| { | ||||
| 	std::vector<Headline> result; | ||||
| 	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(); | ||||
| 
 | ||||
| 	for(auto it = begin; it != end; it++) | ||||
| 	{ | ||||
| 		auto smatch = *it; | ||||
| 	utils::regex_callback_extractor(std::regex(R"(\[h(1|2|3)\](.*?)\[/h\1\])"), content, [&](std::smatch &smatch) { | ||||
| 		Headline h; | ||||
| 		h.level = utils::toUInt(smatch.str(1)); | ||||
| 		h.title = smatch.str(2); | ||||
| 		result.push_back(h); | ||||
| 	} | ||||
| 	}); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| std::vector<std::string> Parser::extractCategories(std::string content) const | ||||
| std::vector<std::string> ParserLegacy::extractCategories(std::string content) const | ||||
| { | ||||
| 	std::vector<std::string> result; | ||||
| 	std::string reg = R"(\[category\](.*?)\[/category\])"; | ||||
| @@ -62,7 +55,7 @@ std::vector<std::string> Parser::extractCategories(std::string content) const | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| std::string Parser::extractCommand(std::string cmdname, std::string content) const | ||||
| std::string ParserLegacy::extractCommand(std::string cmdname, std::string content) const | ||||
| { | ||||
| 	std::string cmd = "[cmd:" + cmdname + "]"; | ||||
| 	std::string cmdend = "[/cmd:" + cmdname + "]"; | ||||
| @@ -81,7 +74,7 @@ std::string Parser::extractCommand(std::string cmdname, std::string content) con | ||||
| 	} | ||||
| 	return ""; | ||||
| } | ||||
| std::string Parser::processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const | ||||
| std::string ParserLegacy::processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const | ||||
| { | ||||
| 	std::string linktag = match.str(1); | ||||
| 	std::string inside = match.str(2); | ||||
| @@ -116,7 +109,7 @@ std::string Parser::processLink(const PageDao &pageDao, UrlProvider &urlProvider | ||||
| 	return htmllink.render(); | ||||
| } | ||||
| 
 | ||||
| std::string Parser::parse(const PageDao &pagedao, UrlProvider &provider, std::string content) const | ||||
| std::string ParserLegacy::parse(const PageDao &pagedao, UrlProvider &provider, std::string content) const | ||||
| { | ||||
| 	std::string result; | ||||
| 	// we don't care about commands, but we nevertheless replace them with empty strings
 | ||||
| @@ -2,7 +2,7 @@ | ||||
| #define PARSER_H | ||||
| #include "iparser.h" | ||||
| 
 | ||||
| class Parser : public IParser | ||||
| class ParserLegacy : public IParser | ||||
| { | ||||
|   private: | ||||
| 	std::string processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const; | ||||
| @@ -13,7 +13,7 @@ class Parser : public IParser | ||||
| 	std::vector<std::string> extractCategories(std::string content) const override; | ||||
| 	std::string parse(const PageDao &pagedao, UrlProvider &provider, std::string content) const override; | ||||
| 	using IParser::IParser; | ||||
| 	~Parser(){}; | ||||
| 	~ParserLegacy(){}; | ||||
| }; | ||||
| 
 | ||||
| #endif // PARSER_H
 | ||||
							
								
								
									
										71
									
								
								parsermarkdown.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								parsermarkdown.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| #include "parsermarkdown.h" | ||||
| #include "logger.h" | ||||
| #include "htmllink.h" | ||||
|  | ||||
| std::string ParserMarkdown::processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const | ||||
| { | ||||
| 	std::string inner = match.str(1); | ||||
| 	std::string link = match.str(2); | ||||
| 	HtmlLink htmllink; | ||||
| 	htmllink.href = link; | ||||
| 	htmllink.innervalue = inner; | ||||
|  | ||||
| 	if(link.find("http://") == 0 || link.find("https://") == 0) | ||||
| 	{ | ||||
| 		return htmllink.render(); | ||||
| 	} | ||||
|  | ||||
| 	if(pageDao.exists(link)) | ||||
| 	{ | ||||
| 		htmllink.cssclass = "exists"; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		htmllink.cssclass = "notexists"; | ||||
| 	} | ||||
|  | ||||
| 	htmllink.href = urlProvider.page(htmllink.href); | ||||
|  | ||||
| 	return htmllink.render(); | ||||
| } | ||||
|  | ||||
| ParserMarkdown::ParserMarkdown() | ||||
| { | ||||
| } | ||||
|  | ||||
| std::vector<Headline> ParserMarkdown::extractHeadlines(std::string content) const | ||||
| { | ||||
| 	std::vector<Headline> result; | ||||
| 	utils::regex_callback_extractor(std::regex(R"((#{1,6}) (.*))"), content, [&](std::smatch &smatch) { | ||||
| 		Headline h; | ||||
| 		h.level = smatch.str(1).length(); | ||||
| 		h.title = smatch.str(2); | ||||
| 		result.push_back(h); | ||||
| 	}); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::string ParserMarkdown::parse(const PageDao &pagedao, UrlProvider &provider, std::string content) const | ||||
| { | ||||
| 	std::shared_ptr<maddy::ParserConfig> config = std::make_shared<maddy::ParserConfig>(); | ||||
| 	auto maddy = std::make_shared<maddy::Parser>(config); | ||||
|  | ||||
| 	auto linkParser = std::make_shared<maddy::LinkParser>(); | ||||
| 	linkParser->setCallback([&](std::smatch &match) { return processLink(pagedao, provider, match); }); | ||||
| 	maddy->setLinkParser(linkParser); | ||||
| 	// TODO: hack because the parser breaks if there is an \r | ||||
| 	content = utils::strreplace(content, "\r", ""); | ||||
| 	std::stringstream s{content}; | ||||
| 	std::string result = maddy->Parse(s); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::string ParserMarkdown::extractCommand(std::string cmdname, std::string content) const | ||||
| { | ||||
| 	return ""; | ||||
| } | ||||
|  | ||||
| std::vector<std::string> ParserMarkdown::extractCategories(std::string content) const | ||||
| { | ||||
| 	return { }; | ||||
| } | ||||
							
								
								
									
										21
									
								
								parsermarkdown.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								parsermarkdown.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| #ifndef PARSER_MARKDOWN_H | ||||
| #define PARSER_MARKDOWN_H | ||||
|  | ||||
| #include "iparser.h" | ||||
| #include "maddy/parser.h" | ||||
|  | ||||
| class ParserMarkdown : public IParser | ||||
| { | ||||
| private: | ||||
| 	std::string processLink(const PageDao &pageDao, UrlProvider &urlProvider, std::smatch &match) const; | ||||
|  | ||||
| public: | ||||
| 	ParserMarkdown(); | ||||
| 	std::vector<Headline> extractHeadlines(std::string content) const; | ||||
| 	std::string parse(const PageDao &pagedao, UrlProvider &provider, std::string content) const; | ||||
|  | ||||
| 	std::string extractCommand(std::string cmdname, std::string content) const; | ||||
| 	std::vector<std::string> extractCategories(std::string content) const; | ||||
| }; | ||||
|  | ||||
| #endif // PARSER_MARKDOWN_H | ||||
							
								
								
									
										20
									
								
								qswiki.cpp
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								qswiki.cpp
									
									
									
									
									
								
							| @@ -37,6 +37,10 @@ SOFTWARE. | ||||
| #include "requestworker.h" | ||||
| #include "cache/fscache.h" | ||||
| #include "sandbox/sandboxfactory.h" | ||||
| #include "iparser.h" | ||||
| #include "parserlegacy.h" | ||||
| #include "parsermarkdown.h" | ||||
|  | ||||
| void sigterm_handler(int arg) | ||||
| { | ||||
| 	// TODO: proper shutdown. | ||||
| @@ -63,6 +67,17 @@ std::unique_ptr<ICache> createCache(const ConfigVariableResolver &resolver) | ||||
|  | ||||
| 	return std::make_unique<FsCache>(path); | ||||
| } | ||||
|  | ||||
| std::unique_ptr<IParser> createParser(const ConfigVariableResolver &resolver) | ||||
| { | ||||
| 	std::string parser = resolver.getConfig("parser"); | ||||
| 	if(parser == "legacy") | ||||
| 	{ | ||||
| 		return std::make_unique<ParserLegacy>(); | ||||
| 	} | ||||
| 	return std::make_unique<ParserMarkdown>(); | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	if(geteuid() == 0) | ||||
| @@ -135,7 +150,10 @@ int main(int argc, char **argv) | ||||
| 		auto cache = createCache(config.configVarResolver); | ||||
| 		cache->clear(); | ||||
|  | ||||
| 		HandlerFactory handlerFactory{config.handlersConfig, siteTemplate, *database.get(), urlProvider, *cache.get()}; | ||||
| 		auto parser = createParser(config.configVarResolver); | ||||
|  | ||||
|  | ||||
| 		HandlerFactory handlerFactory{config.handlersConfig, siteTemplate, *database.get(), urlProvider, *cache.get(), *parser.get()}; | ||||
| 		RequestWorker requestWorker{handlerFactory, database->createSessionDao(), siteTemplate}; | ||||
|  | ||||
| 		auto interface = createGateway(config); | ||||
|   | ||||
							
								
								
									
										1
									
								
								submodules/qsmaddy
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								submodules/qsmaddy
									
									
									
									
									
										Submodule
									
								
							 Submodule submodules/qsmaddy added at 167ce3943d
									
								
							
							
								
								
									
										11
									
								
								utils.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								utils.cpp
									
									
									
									
									
								
							| @@ -175,3 +175,14 @@ std::string utils::toISODate(time_t t) | ||||
| 	} | ||||
| 	return std::string{result}; | ||||
| } | ||||
|  | ||||
| void utils::regex_callback_extractor(std::regex regex, const std::string &input, std::function<void (std::smatch &)> callback) | ||||
| { | ||||
| 	auto begin = std::sregex_iterator(input.begin(), input.end(), regex); | ||||
| 	auto end = std::sregex_iterator(); | ||||
| 	for(auto it = begin; it != end; it++) | ||||
| 	{ | ||||
| 		std::smatch smatch = *it; | ||||
| 		callback(smatch); | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								utils.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								utils.h
									
									
									
									
									
								
							| @@ -60,6 +60,7 @@ template <class T, class U> std::vector<U> getAll(std::multimap<T, U> map, T key | ||||
| std::string regex_callback_replacer(std::regex regex, const std::string &input, | ||||
| 									std::function<std::string(std::smatch &)> callback); | ||||
|  | ||||
| void regex_callback_extractor(std::regex regex, const std::string &input, std::function<void(std::smatch &)> callback); | ||||
| std::string readCompleteFile(std::string_view filepath); | ||||
|  | ||||
| inline std::string nz(const char *s) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user