annotate server/r_impl.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
rev   line source
ferencd@0 1 #include "r_impl.h"
ferencd@0 2 #include "templater.h"
ferencd@0 3 #include "url_breaker.h"
ferencd@0 4 #include "logger.h"
ferencd@0 5 #include "json.h"
ferencd@0 6 #include <dictionary.h>
ferencd@0 7 #include "maddy/parser.h"
ferencd@0 8
ferencd@0 9 #include <boost/algorithm/string.hpp>
ferencd@0 10 #include <tntdb.h>
ferencd@0 11
ferencd@0 12 std::string r_impl::getMd(const std::string& key, const std::string &f, const std::string& cCurrentPath)
ferencd@0 13 {
ferencd@0 14 std::string filenameDesc(cCurrentPath);
ferencd@0 15 filenameDesc += RECIPES_ROOT + key + "/" + m_lang + "/" + f;
ferencd@0 16
ferencd@0 17 std::ifstream finIntro(filenameDesc.c_str(), std::ios::in | std::ios::binary);
ferencd@0 18 if(finIntro)
ferencd@0 19 {
ferencd@0 20 std::ostringstream ossIntro;
ferencd@0 21 ossIntro << finIntro.rdbuf();
ferencd@0 22 std::string intro(ossIntro.str());
ferencd@0 23 std::stringstream markdownInput(intro);
ferencd@0 24
ferencd@0 25 // config is optional
ferencd@0 26 std::shared_ptr<maddy::ParserConfig> config = std::make_shared<maddy::ParserConfig>();
ferencd@0 27 config->isEmphasizedParserEnabled = true; // default
ferencd@0 28 config->isHTMLWrappedInParagraph = true; // default
ferencd@0 29
ferencd@0 30 std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>(config);
ferencd@0 31 return parser->Parse(markdownInput);
ferencd@0 32 }
ferencd@0 33
ferencd@0 34 return "";
ferencd@0 35 }
ferencd@0 36
ferencd@0 37 r_impl::r_impl(tnt::HttpRequest &request, tnt::HttpReply &reply, const std::string &what) : web_component(request, reply, "")
ferencd@0 38 {
ferencd@0 39 url_breaker r("r/key", boost::to_lower_copy(what));
ferencd@0 40 m_key = r["key"];
ferencd@0 41
ferencd@0 42 // identify the language
ferencd@0 43 auto pars = request.getQueryParams();
ferencd@0 44 m_lang = pars.arg<std::string>("l");
ferencd@0 45
ferencd@0 46 char cCurrentPath[FILENAME_MAX] = {0};
ferencd@0 47
ferencd@0 48 if (!getcwd(cCurrentPath, sizeof(cCurrentPath)))
ferencd@0 49 {
ferencd@0 50 log_err() << "Cannot get current path";
ferencd@0 51 return;
ferencd@0 52 }
ferencd@0 53
ferencd@0 54 std::string filename(cCurrentPath);
ferencd@0 55 filename += RECIPES_ROOT + "/" + m_key + "/descriptor.json";
ferencd@0 56 bool found_lang = false;
ferencd@0 57
ferencd@0 58 {
ferencd@0 59 std::ifstream fin(filename.c_str(), std::ios::in | std::ios::binary);
ferencd@0 60 if(fin)
ferencd@0 61 {
ferencd@0 62 std::ostringstream oss;
ferencd@0 63 oss << fin.rdbuf();
ferencd@0 64 std::string fileData(oss.str());
ferencd@0 65 auto j = nlohmann::json::parse(fileData);
ferencd@0 66 auto langs = j["lang"];
ferencd@0 67 for(const auto& l : langs)
ferencd@0 68 {
ferencd@0 69 std::string cpp_string;
ferencd@0 70 l.get_to(cpp_string);
ferencd@0 71 if(cpp_string == m_lang)
ferencd@0 72 {
ferencd@0 73 found_lang = true;
ferencd@0 74 break;
ferencd@0 75 }
ferencd@0 76 }
ferencd@0 77 }
ferencd@0 78 }
ferencd@0 79 if(!found_lang)
ferencd@0 80 {
ferencd@0 81 log_err() << "Cannot find the language " << m_lang << " for " << m_key;
ferencd@0 82 return;
ferencd@0 83 }
ferencd@0 84
ferencd@0 85 m_intro = getMd(m_key, "intro.md", cCurrentPath);
ferencd@0 86 m_body = getMd(m_key, "recipe.md", cCurrentPath);
ferencd@0 87
ferencd@0 88 // fix the image, if it contains {#rroot}
ferencd@0 89 stringholder sh(m_body);
ferencd@0 90 sh.replace_all("{#rroot}", RECIPES_ROOT + m_key + SLASH);
ferencd@0 91 sh.replace_all("//", "/");
ferencd@0 92 m_body = sh.get();
ferencd@0 93
ferencd@0 94 m_body = "<img src='" + RECIPES_ROOT + m_key + SLASH + "img/main.jpg'>" + m_body;
ferencd@0 95
ferencd@0 96 }
ferencd@0 97
ferencd@0 98 unsigned r_impl::send()
ferencd@0 99 {
ferencd@0 100 std::string stype = "";
ferencd@0 101 try {
ferencd@0 102
ferencd@0 103 tntdb::Connection conn = tntdb::connect("sqlite:lang.db");
ferencd@0 104
ferencd@0 105 std::string v = std::string("select type from food where food_key='") + m_key + "'";
ferencd@0 106 tntdb::Result result = conn.select(v);
ferencd@0 107 for (tntdb::Result::const_iterator it = result.begin(); it != result.end(); ++it)
ferencd@0 108 {
ferencd@0 109 std::string type;
ferencd@0 110 std::string key;
ferencd@0 111 tntdb::Row row = *it;
ferencd@0 112
ferencd@0 113 row[0].get(type);
ferencd@0 114
ferencd@0 115 if(ctg_to_name.count(type))
ferencd@0 116 {
ferencd@0 117 stype = ctg_to_name[type];
ferencd@0 118 }
ferencd@0 119 else
ferencd@0 120 {
ferencd@0 121 return HTTP_NOT_FOUND;
ferencd@0 122 }
ferencd@0 123 }
ferencd@0 124 }
ferencd@0 125 catch (std::exception& ex)
ferencd@0 126 {
ferencd@0 127 log_critical() << ex.what();
ferencd@0 128 return HTTP_NOT_FOUND;
ferencd@0 129 }
ferencd@0 130
ferencd@0 131 prepareLanguages();
ferencd@0 132 template_vector_par tvp_languages("languages", m_languageStructs);
ferencd@0 133
ferencd@0 134 std::string title = dictionary::translate(m_key + "_name", m_lang);
ferencd@0 135 std::string rply = templater<recipe>().templatize("intro" <is> m_intro,
ferencd@0 136 "body" <is> m_body,
ferencd@0 137 "title" <is> title,
ferencd@0 138 "key" <is> m_key,
ferencd@0 139 "lng" <is> m_lang,
ferencd@0 140 "category" <is> stype).templatize(tvp_languages).get();
ferencd@0 141
ferencd@0 142 std::map<std::string, std::map<std::string, std::string> > translations;
ferencd@0 143 mreply.out() << translator<void>::translate(rply, m_lang, translations);
ferencd@0 144
ferencd@0 145
ferencd@0 146 return HTTP_OK;
ferencd@0 147 }