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