Mercurial > thymian
comparison server/category_sender.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 "category_sender.h" | |
| 2 #include "templater.h" | |
| 3 #include "url_breaker.h" | |
| 4 #include "logger.h" | |
| 5 #include "json.h" | |
| 6 #include <dictionary.h> | |
| 7 | |
| 8 #include <boost/algorithm/string.hpp> | |
| 9 #include <tntdb.h> | |
| 10 | |
| 11 category_sender::category_sender(tnt::HttpRequest &request, tnt::HttpReply &reply, const std::string &what) : web_component(request, reply, "") | |
| 12 { | |
| 13 | |
| 14 // identify the category | |
| 15 static std::map<std::string, std::string> name_to_dbtype = { {"soups", "0"}, {"sides", "2"}, {"mains", "3"}, {"sweets", "4"}, {"starters", "1"} }; | |
| 16 | |
| 17 url_breaker r("l/category", boost::to_lower_copy(what)); | |
| 18 std::string food_type = r["category"]; | |
| 19 // identify the language | |
| 20 auto pars = request.getQueryParams(); | |
| 21 m_lang = pars.arg<std::string>("l"); | |
| 22 | |
| 23 if(food_type == "about") | |
| 24 { | |
| 25 char cCurrentPath[FILENAME_MAX] = {0}; | |
| 26 | |
| 27 if (!getcwd(cCurrentPath, sizeof(cCurrentPath))) | |
| 28 { | |
| 29 log_err() << "Cannot get working path"; | |
| 30 m_translated = "Internal server error"; | |
| 31 return; | |
| 32 } | |
| 33 | |
| 34 std::string filename(cCurrentPath); | |
| 35 | |
| 36 std::ifstream fin(filename + "/theme/current/About.html", std::ios::in | std::ios::binary); | |
| 37 if(fin) | |
| 38 { | |
| 39 std::ostringstream oss; | |
| 40 oss << fin.rdbuf(); | |
| 41 m_translated = oss.str(); | |
| 42 } | |
| 43 | |
| 44 } | |
| 45 | |
| 46 if(name_to_dbtype.find(food_type) == name_to_dbtype.end()) | |
| 47 { | |
| 48 log_critical() << "Not found:" << what; | |
| 49 m_status = HTTP_NOT_FOUND; | |
| 50 return; | |
| 51 } | |
| 52 m_category = food_type; m_category[0] = std::toupper(m_category[0]); | |
| 53 food_type = name_to_dbtype[food_type]; | |
| 54 | |
| 55 | |
| 56 | |
| 57 // generate the page elements as translateable | |
| 58 try { | |
| 59 tntdb::Connection conn = tntdb::connect("sqlite:lang.db"); | |
| 60 | |
| 61 std::string v = std::string("select * from food where type='") + food_type + "'"; | |
| 62 tntdb::Result result = conn.select(v); | |
| 63 std::vector<std::string> keys; | |
| 64 for (tntdb::Result::const_iterator it = result.begin(); it != result.end(); ++it) | |
| 65 { | |
| 66 std::string name_src = ""; | |
| 67 std::string img = ""; | |
| 68 int food_idx = -1; | |
| 69 std::string type; | |
| 70 std::string key; | |
| 71 | |
| 72 tntdb::Row row = *it; | |
| 73 | |
| 74 row[0].get(food_idx); | |
| 75 row[1].get(name_src); | |
| 76 row[2].get(type); | |
| 77 row[3].get(img); | |
| 78 row[4].get(key); | |
| 79 | |
| 80 template_struct food("foods", "fooditem"); | |
| 81 | |
| 82 food["name"] = "<!--#translate " + name_src + "#-->"; | |
| 83 | |
| 84 // fix the image, if it contains {#rroot} | |
| 85 stringholder sh(img); | |
| 86 sh.replace_all("{#rroot}", RECIPES_ROOT + key + SLASH); | |
| 87 sh.replace_all("//", "/"); | |
| 88 | |
| 89 food["img"] = sh.get(); | |
| 90 food["desc"] = "<!--#translate " + key + "_desc#-->"; | |
| 91 food["key"] = key; | |
| 92 | |
| 93 keys.push_back(key); | |
| 94 | |
| 95 populate_short_description(key); | |
| 96 | |
| 97 m_foodStructs.push_back(food); | |
| 98 } | |
| 99 | |
| 100 prepareLanguages(); | |
| 101 | |
| 102 template_vector_par tvp_foods("foods", m_foodStructs); | |
| 103 template_vector_par tvp_languages("languages", m_languageStructs); | |
| 104 | |
| 105 std::string page = templater<category_list>().templatize("category" <is> ctg_to_name[food_type], "lang" <is> m_lang).templatize(tvp_languages).templatize(tvp_foods).get(); | |
| 106 | |
| 107 std::map<std::string, std::map<std::string, std::string> > translations; | |
| 108 m_translated = translator<void>::translate(page, m_lang, translations); | |
| 109 | |
| 110 stringholder sh(m_translated); | |
| 111 sh.replace_all("{#jsfun}", prepareLangJs(translations)); | |
| 112 sh.replace_all("{#trjsfun}", prepareLangTrs(keys)); | |
| 113 sh.replace_all("{#divChanger}", "changeDivs('" + m_lang + "');"); | |
| 114 m_translated = sh.get(); | |
| 115 | |
| 116 | |
| 117 } | |
| 118 catch (std::exception& ex) | |
| 119 { | |
| 120 log_critical() << ex.what(); | |
| 121 m_status = HTTP_NOT_FOUND; | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 unsigned category_sender::send() | |
| 126 { | |
| 127 mreply.out() << m_translated; | |
| 128 return HTTP_OK; | |
| 129 } | |
| 130 | |
| 131 bool category_sender::populate_short_description(const std::string &key) const | |
| 132 { | |
| 133 char cCurrentPath[FILENAME_MAX] = {0}; | |
| 134 | |
| 135 if (!getcwd(cCurrentPath, sizeof(cCurrentPath))) | |
| 136 { | |
| 137 log_err() << "Cannot get current path"; | |
| 138 return false; | |
| 139 } | |
| 140 | |
| 141 std::string filename(cCurrentPath); | |
| 142 filename += RECIPES_ROOT + "/" + key + "/descriptor.json"; | |
| 143 std::ifstream fin(filename.c_str(), std::ios::in | std::ios::binary); | |
| 144 | |
| 145 if(fin) | |
| 146 { | |
| 147 std::ostringstream oss; | |
| 148 oss << fin.rdbuf(); | |
| 149 std::string fileData(oss.str()); | |
| 150 auto j = nlohmann::json::parse(fileData); | |
| 151 auto langs = j["lang"]; | |
| 152 for(const auto& l : langs) | |
| 153 { | |
| 154 std::string filenameDesc(cCurrentPath); | |
| 155 std::string cpp_string; | |
| 156 l.get_to(cpp_string); | |
| 157 | |
| 158 filenameDesc += RECIPES_ROOT + key + "/" + cpp_string+ "/descr.md"; | |
| 159 std::ifstream finDesc(filenameDesc.c_str(), std::ios::in | std::ios::binary); | |
| 160 if(finDesc) | |
| 161 { | |
| 162 std::ostringstream ossDesc; | |
| 163 ossDesc << finDesc.rdbuf(); | |
| 164 std::string fileDataDesc(ossDesc.str()); | |
| 165 | |
| 166 dictionary::add_translation(key + "_desc", cpp_string, fileDataDesc); | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 else | |
| 171 { | |
| 172 log_err() << "Cannot get descriptor file:" << filename; | |
| 173 return false; | |
| 174 } | |
| 175 | |
| 176 return true; | |
| 177 } | |
| 178 | |
| 179 std::string category_sender::prepareLangTrs(const std::vector<std::string>& keys) | |
| 180 { | |
| 181 std::string javascript = "function changeTrs(l) {"; | |
| 182 for(const auto &k : keys) | |
| 183 { | |
| 184 javascript += "$('#tr_" + k + "').data('href', '/r/" + k + "?l=' + l);\n"; | |
| 185 } | |
| 186 | |
| 187 javascript += "}\n"; | |
| 188 return javascript; | |
| 189 } |
