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 }