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