source: main/trunk/greenstone2/runtime-src/src/recpt/gtiaction.cpp@ 21752

Last change on this file since 21752 was 18460, checked in by anna, 15 years ago

Added several functions in GTI.\n 1. Create spreadsheet for all the strings in current module (gtiaction.cpp, english2.dm).\n 2. Create operational files for GLI Help (HTML files etc) as requested, zip them and provide for download (gtiaction.h|cpp, gti.dm, gti.pl).\n 3. Functions for processing GS3 interfaces (gti.pl).

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 33.4 KB
Line 
1/**********************************************************************
2 *
3 * gtiaction.cpp --
4 * Copyright (C) 2005 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26
27#include "gsdl_modules_cfg.h"
28#ifdef GSDL_USE_GTI_ACTION
29
30
31#include <expat.h>
32#include <stdio.h>
33#include <sys/utsname.h>
34#include "gtiaction.h"
35#include "cgiutils.h"
36#include "fileutil.h"
37#include "gsdlunicode.h"
38
39
40
41gtiaction::gtiaction()
42{
43 cgiarginfo arg_ainfo;
44
45 arg_ainfo.shortname = "tlc";
46 arg_ainfo.longname = "translation target language code";
47 arg_ainfo.multiplechar = true;
48 arg_ainfo.defaultstatus = cgiarginfo::weak;
49 arg_ainfo.savedarginfo = cgiarginfo::must;
50 argsinfo.addarginfo (&cerr, arg_ainfo);
51
52 arg_ainfo.shortname = "tfk";
53 arg_ainfo.longname = "translation file key";
54 arg_ainfo.multiplechar = true;
55 arg_ainfo.defaultstatus = cgiarginfo::weak;
56 arg_ainfo.savedarginfo = cgiarginfo::must;
57 argsinfo.addarginfo (&cerr, arg_ainfo);
58
59 arg_ainfo.shortname = "ncpp";
60 arg_ainfo.longname = "number of chunks per page";
61 arg_ainfo.multiplechar = true;
62 arg_ainfo.defaultstatus = cgiarginfo::weak;
63 arg_ainfo.argdefault = "1";
64 arg_ainfo.savedarginfo = cgiarginfo::must;
65 argsinfo.addarginfo (&cerr, arg_ainfo);
66}
67
68
69
70gtiaction::~gtiaction()
71{
72 delete[] set_gsdlhome_cstr;
73 delete[] set_gsdlos_cstr;
74}
75
76
77
78bool gtiaction::init (ostream& /*logout*/)
79{
80 // Set GSDLHOME and GSDLOS environment variables
81 text_t set_gsdlhome = "GSDLHOME=" + gsdlhome;
82 text_t set_gsdlos = "GSDLOS=";
83
84#if defined (__WIN32__)
85 set_gsdlos += "windows";
86#else
87 struct utsname *buf = new struct utsname();
88 if (uname(buf) == -1) {
89 // uname failed, so this must be linux
90 set_gsdlos += "linux";
91 }
92 else {
93 text_t gsdlos = buf->sysname;
94 lc(gsdlos);
95 set_gsdlos += gsdlos;
96 }
97 delete buf;
98#endif
99
100 // These will be cleaned up in the destructor
101 set_gsdlhome_cstr = set_gsdlhome.getcstr();
102 set_gsdlos_cstr = set_gsdlos.getcstr();
103 putenv(set_gsdlhome_cstr);
104 putenv(set_gsdlos_cstr);
105
106 return true;
107}
108
109
110
111bool gtiaction::check_cgiargs(cgiargsinfoclass& /*argsinfo*/, cgiargsclass& args,
112 recptprotolistclass* /*protos*/, ostream& logout)
113{
114 // Authenticate the user, except for the "home" and "lang" pages
115 if (args["p"] != "home" && args["p"] != "lang" && args["p"] != "status") {
116 args["uan"] = 1;
117 args["ug"] = "langadmin_" + args["tlc"];
118 }
119
120 return true;
121}
122
123
124
125bool gtiaction::do_action(cgiargsclass& args, recptprotolistclass* /*protos*/,
126 browsermapclass* /*browsers*/, displayclass& disp,
127 outconvertclass& outconvert, ostream& textout,
128 ostream& logout)
129{
130 // Special case for producing Excel spreadsheets, as these are downloaded
131 if (args["p"] == "excel") {
132 return produce_excel_spreadsheet(args, logout);
133 }
134
135 textout << outconvert << disp << ("_gti:header_\n") << ("_gti:content_\n") << ("_gti:footer_\n");
136 return true;
137}
138
139
140
141void gtiaction::get_cgihead_info(cgiargsclass& args, recptprotolistclass* /*protos*/,
142 response_t& response, text_t& response_data,
143 ostream& logout)
144{
145 // Special case for producing Excel spreadsheets, as these are downloaded
146 if (args["p"] == "excel") {
147 printf("Content-Disposition: attachment; filename=\"Greenstone-%s-%s.xml\"\n", args["tlc"].getcstr(), args["tfk"].getcstr());
148 response = content;
149 response_data = "text/xml";
150 return;
151 }
152
153 response = content;
154 response_data = "text/html";
155}
156
157
158
159void gtiaction::define_internal_macros(displayclass& disp, cgiargsclass& args,
160 recptprotolistclass* protos, ostream& logout)
161{
162 // logout << endl << "Arguments: " << args << endl;
163 logout << endl << "CGI arg p: " << args["p"] << endl;
164
165 // For some reason this must be done as well as setting the macro in gti.dm
166 // is that still true??
167 disp.setmacro("preflink", displayclass::defaultpackage, "_gti:preflink_");
168
169 // Define the page content for the GTI home page
170 if (args["p"] == "home") {
171 define_gti_home_page(disp, args, logout);
172 return;
173 }
174
175 // Define the page content for the GTI language page
176 if (args["p"] == "lang") {
177 define_gti_lang_page(disp, args, logout);
178 return;
179 }
180
181 // Define the page content for the GTI search page
182 if (args["p"] == "find") {
183 define_gti_find_page(disp, args, logout);
184 return;
185 }
186
187 // Define the page content for the GTI offline page
188 if (args["p"] == "offline") {
189 define_gti_offline_page(disp, args, logout);
190 return;
191 }
192
193 // Define the page content for the GTI view status page
194 if (args["p"] == "status") {
195 define_gti_status_page(disp, args, logout);
196 return;
197 }
198
199 // Process user translations
200 if (args["p"] == "submit") {
201 process_gti_submissions(disp, args, logout, true);
202 }
203
204 if (args["p"] == "glihelp") {
205 produce_glihelp_zipfile(disp, args, logout);
206 }
207
208 // Define the page content for the GTI core pages (containing the translation input forms)
209 define_gti_core_page(disp, args, logout);
210}
211
212
213
214void gtiaction::define_gti_home_page(displayclass& disp, cgiargsclass& args, ostream& logout)
215{
216 disp.setmacro("gtiformcontent", "gti", "_gti:gtihome_");
217
218 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
219
220 // Get the languages specified in the main.cfg file, and put them into a map to sort by name
221 text_tmap gti_languages_name_code_mapping;
222 languageinfo_tmap::const_iterator loaded_language = loaded_languages.begin();
223 while (loaded_language != loaded_languages.end()) {
224 // English is not a valid GTI target language, since it is the source language
225 if (loaded_language->first != "en") {
226 gti_languages_name_code_mapping[loaded_language->second.longname] = loaded_language->first;
227 }
228 ++loaded_language;
229 }
230
231 // Set the gtitlcselection macro
232 text_t gti_tlc_selection = "<select name=\"tlc\">\n";
233 text_tmap::iterator gti_language = gti_languages_name_code_mapping.begin();
234 while (gti_language != gti_languages_name_code_mapping.end()) {
235 gti_tlc_selection += "<option value=\"" + gti_language->second + "\">" + gti_language->first + "</option>\n";
236 ++gti_language;
237 }
238 gti_tlc_selection += "</select>";
239 disp.setmacro("gtitlcselection", "gti", gti_tlc_selection);
240}
241
242
243
244void gtiaction::define_gti_lang_page(displayclass& disp, cgiargsclass& args, ostream& logout)
245{
246 // Get the target language code from the CGI arguments
247 text_t target_language_code = args["tlc"];
248
249 disp.setmacro("gtiformcontent", "gti", "_gti:gtilang_");
250
251 // Send a request to gti.pl to get the valid translation files
252 text_t gti_arguments = "get-language-status " + target_language_code;
253 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
254 if (gti_response.error_message != "") {
255 // An error has occurred
256 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
257 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
258 return;
259 }
260
261 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
262 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
263
264 // Set the gtitfkselection macro
265 text_t gti_tfk_selection = "<table>";
266 text_tmap::iterator translation_file = gti_response.translation_files_index_to_key_mapping.begin();
267 while (translation_file != gti_response.translation_files_index_to_key_mapping.end()) {
268 text_t translation_file_key = translation_file->second;
269
270 gti_tfk_selection += "<tr><td>";
271 gti_tfk_selection += "<input type=\"radio\" name=\"tfk\" value=\"" + translation_file_key + "\"></td>\n";
272 gti_tfk_selection += "<td>_textgti" + translation_file_key + "_</td></tr>\n";
273
274 text_t num_chunks_translated = gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key];
275 text_t num_chunks_requiring_translation = gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key];
276 text_t num_chunks_requiring_updating = gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key];
277 gti_tfk_selection += "<tr><td></td><td>_gtitranslationfilestatus_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td></tr>\n";
278 ++translation_file;
279 }
280 gti_tfk_selection += "</table>";
281 disp.setmacro("gtitfkselection", "gti", gti_tfk_selection);
282}
283
284
285
286void gtiaction::define_gti_status_page(displayclass& disp, cgiargsclass& args, ostream& logout)
287{
288 disp.setmacro("gtiformcontent", "gti", "_gti:gtistatus_");
289
290 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
291
292 // Get the languages specified in the main.cfg file, and put them into a map to sort by name
293 text_tmap gti_languages_name_code_mapping;
294 languageinfo_tmap::const_iterator loaded_language = loaded_languages.begin();
295 while (loaded_language != loaded_languages.end()) {
296 // English is not a valid GTI target language, since it is the source language
297 if (loaded_language->first != "en") {
298 gti_languages_name_code_mapping[loaded_language->second.longname] = loaded_language->first;
299 }
300 ++loaded_language;
301 }
302
303 // Get the languages, for each language, send a request to gti.pl to get the valid translation files and the current status for each file
304 text_t gti_status_table = "<table class=\"status\">\n";
305 text_tmap::iterator gti_language = gti_languages_name_code_mapping.begin();
306 bool first_lang = true;
307 while (gti_language != gti_languages_name_code_mapping.end()) {
308 // Send a request to gti.pl to get the valid translation files
309 text_t gti_arguments = "get-language-status " + gti_language->second;
310 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
311 if (gti_response.error_message != "") {
312 // An error has occurred
313 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
314 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
315 return;
316 }
317
318 text_tmap::iterator translation_file = gti_response.translation_files_index_to_key_mapping.begin();
319
320 text_t lang_status_temp = "<tr><td class=\"first\">" + gti_language->first + "</td>\n";
321 text_t files_temp = "<tr><th class=\"status\">_textgtilanguage_</th>\n";
322 text_t number_of_strings_temp = "<tr><td class=\"first\"><b>_textgtitotalnumberoftranslations_</b></td>\n";
323
324 while (translation_file != gti_response.translation_files_index_to_key_mapping.end()) {
325 text_t translation_file_key = translation_file->second;
326
327 text_t num_chunks_translated = gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key];
328 text_t num_chunks_requiring_translation = gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key];
329 text_t num_chunks_requiring_updating = gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key];
330
331 lang_status_temp += "<td class=\"status\">";
332 if(num_chunks_translated.getint() > 0){
333 lang_status_temp += "<div class=\"nowrap\"><div class=\"done\">";
334 lang_status_temp += num_chunks_translated+"</div><div class=\"plus\">+</div><div class=\"update\">";
335 lang_status_temp += num_chunks_requiring_updating+"</div><div class=\"plus\">+</div><div class=\"todo\">";
336 lang_status_temp += num_chunks_requiring_translation+"</div></div>";
337 }
338 lang_status_temp += "</td>\n";
339
340
341 //lang_status_temp += "<td valign=\"top\" nowrap>_gtitranslationfilestatus2_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td>";
342
343 // List the file names as the first row of the status table
344 // Add up number of strings need to be translate in each file, as the second line of the status table
345 if (first_lang) {
346 files_temp += "<th class=\"status\">_textgti" + translation_file_key + "_</th>\n";
347 int int_number_of_strings = num_chunks_translated.getint() + num_chunks_requiring_translation.getint();
348 number_of_strings_temp += "<td class=\"status\"><b>";
349 number_of_strings_temp.appendint(int_number_of_strings);
350 number_of_strings_temp += "</b></td>\n";
351 }
352 ++translation_file;
353 }
354
355 if(first_lang) {
356 gti_status_table += files_temp + "</tr>" + number_of_strings_temp + "</tr>";
357 first_lang = false;
358 }
359
360 gti_status_table += lang_status_temp + "</tr>";
361 ++gti_language;
362 }
363 gti_status_table += "\n</table>";
364 disp.setmacro("gtistatustable", "gti", gti_status_table);
365}
366
367
368
369void gtiaction::define_gti_find_page(displayclass& disp, cgiargsclass& args, ostream& logout)
370{
371 // Get the target language code and file to translate from the CGI arguments
372 text_t target_language_code = args["tlc"];
373 text_t translation_file_key = args["tfk"];
374 text_t query_string = to_utf8(args["q"]);
375
376 // Process user corrections
377 if (args["sp"] != "") {
378 process_gti_submissions(disp, args, logout, false);
379 }
380
381 disp.setmacro("gtiformcontent", "gti", "_gti:gtifind_");
382
383 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
384 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
385 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
386
387 if (query_string == "") {
388 // No query, so no search results
389 disp.setmacro("gtifindformcontent", "gti", "");
390 return;
391 }
392
393 // Display text right to left if target language is Arabic or Farsi or Urdu
394 if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") {
395 disp.setmacro("gtitextdirection", "gti", "rtl");
396 }
397 else {
398 disp.setmacro("gtitextdirection", "gti", "ltr");
399 }
400
401 // Send a request to gti.pl to get the valid translation files
402 logout << "Query argument: " << query_string << endl;
403 text_t gti_arguments = "search-chunks " + target_language_code + " " + translation_file_key + " " + query_string;
404 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
405 if (gti_response.error_message != "") {
406 // An error has occurred
407 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
408 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
409 return;
410 }
411
412 disp.setmacro("gtinumchunksmatchingquery", "gti", gti_response.num_chunks_matching_query);
413
414 // Loop through the chunks returned, displaying them on the page
415 text_t gti_find_form_content = "_gtifindformheader_\n";
416 text_tmap::iterator chunk_key_iterator = gti_response.target_file_chunks_key_to_text_mapping.begin();
417 while (chunk_key_iterator != gti_response.target_file_chunks_key_to_text_mapping.end()) {
418 text_t chunk_key = chunk_key_iterator->first;
419
420 // Need to escape any underscores in the chunk key to show it correctly on the page
421 text_t chunk_key_escaped = escape_all(chunk_key, '_');
422
423 // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
424 text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
425 text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
426 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
427 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ',');
428 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '(');
429 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')');
430 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '"');
431 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\'');
432
433 // This chunk matches the query
434 gti_find_form_content += "_gtichunkmatchingquery_(" + chunk_key_escaped + "," + target_file_chunk_text_escaped + ")\n";
435
436 chunk_key_iterator++;
437 }
438 gti_find_form_content += "_gtifindformfooter_\n";
439
440 disp.setmacro("gtifindformcontent", "gti", gti_find_form_content);
441}
442
443
444
445void gtiaction::define_gti_offline_page(displayclass& disp, cgiargsclass& args, ostream& logout)
446{
447 // Get the target language code and file to translate from the CGI arguments
448 text_t target_language_code = args["tlc"];
449 text_t translation_file_key = args["tfk"];
450
451 disp.setmacro("gtiformcontent", "gti", "_gti:gtioffline_");
452
453 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
454 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
455 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
456}
457
458
459
460void gtiaction::define_gti_core_page(displayclass& disp, cgiargsclass& args, ostream& logout)
461{
462 // Get the target language code and file to translate from the CGI arguments
463 text_t target_language_code = args["tlc"];
464 text_t translation_file_key = args["tfk"];
465 text_t num_chunks_per_page = args["ncpp"];
466 logout << "Num chunks per page: " << num_chunks_per_page << endl;
467
468 disp.setmacro("gtiformcontent", "gti", "_gti:gticore_");
469
470 // Display text right to left if target language is Arabic or Farsi or Urdu
471 if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") {
472 disp.setmacro("gtitextdirection", "gti", "rtl");
473 }
474 else {
475 disp.setmacro("gtitextdirection", "gti", "ltr");
476 }
477
478 // Send a request to gti.pl to get the first string to translate
479 text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + num_chunks_per_page;
480 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
481 if (gti_response.error_message != "") {
482 // An error has occurred
483 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
484 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
485 return;
486 }
487
488 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
489 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
490 if (translation_file_key == "glihelp") {
491 disp.setmacro("gtitargetfilepath", "gti", "_gtidownloadglihelp_");
492 } else {
493 disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]);
494 }
495 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
496 disp.setmacro("gtiviewtranslationfileinaction", "gti", "_gti:gtiview" + translation_file_key + "inaction_");
497
498 disp.setmacro("gtinumchunkstranslated", "gti", gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key]);
499 disp.setmacro("gtinumchunksrequiringtranslation", "gti", gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key]);
500 disp.setmacro("gtinumchunksrequiringupdating", "gti", gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key]);
501
502 // Check if the translation file is finished
503 if (gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key] == "0" && gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key] == "0") {
504 disp.setmacro("gtiformcontent", "gti", "_gti:gtidone_");
505 return;
506 }
507
508 // Loop through the chunks returned, displaying them on the page
509 text_t gti_core_form_content = "";
510 text_tmap::iterator chunk_key_iterator = gti_response.source_file_chunks_key_to_text_mapping.begin();
511 while (chunk_key_iterator != gti_response.source_file_chunks_key_to_text_mapping.end()) {
512 text_t chunk_key = chunk_key_iterator->first;
513
514 // Need to escape any underscores in the chunk key to show it correctly on the page
515 text_t chunk_key_escaped = escape_all(chunk_key, '_');
516
517 // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
518 text_t source_file_chunk_text = gti_response.source_file_chunks_key_to_text_mapping[chunk_key];
519 text_t source_file_chunk_text_escaped = escape_all(source_file_chunk_text, '\\');
520 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '_');
521 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ',');
522 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '(');
523 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ')');
524 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '\'');
525 text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
526 text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
527 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
528 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ',');
529 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '(');
530 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')');
531 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\'');
532
533 text_t source_file_chunk_date = gti_response.source_file_chunks_key_to_date_mapping[chunk_key];
534 text_t target_file_chunk_date = gti_response.target_file_chunks_key_to_date_mapping[chunk_key];
535
536 // This chunk requires translation
537 if (target_file_chunk_text == "") {
538 gti_core_form_content += "_gtichunkrequiringtranslation_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + ")\n";
539 }
540 // This chunk requires updating
541 else {
542 gti_core_form_content += "_gtichunkrequiringupdating_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + "," + target_file_chunk_text_escaped + "," + target_file_chunk_date + ")\n";
543 }
544
545 chunk_key_iterator++;
546 }
547
548 disp.setmacro("gticoreformcontent", "gti", gti_core_form_content);
549}
550
551
552
553void gtiaction::process_gti_submissions(displayclass& disp, cgiargsclass& args, ostream& logout, bool force_submission)
554{
555 // Get the target language code and file to translate from the CGI arguments
556 text_t target_language_code = args["tlc"];
557 text_t translation_file_key = args["tfk"];
558 text_t submitter_username = args["un"];
559
560 // Submitted chunk arguments contain the language code followed by "::"
561 char* source_chunk_key_start_cstr = ((text_t) "en" + "%3A%3A").getcstr();
562 char* target_chunk_key_start_cstr = (target_language_code + "%3A%3A").getcstr();
563
564 // Find the cgi arguments with submitted chunk information
565 text_t submission_text;
566 cgiargsclass::const_iterator cgi_argument = args.begin();
567 while (cgi_argument != args.end()) {
568 char* cgi_argument_name_cstr = cgi_argument->first.getcstr();
569
570 // Source file text
571 if (strncmp(cgi_argument_name_cstr, source_chunk_key_start_cstr, strlen(source_chunk_key_start_cstr)) == 0) {
572 submission_text += "<SourceFileText key=\"";
573 text_t source_key = &cgi_argument_name_cstr[strlen(source_chunk_key_start_cstr)];
574 decode_cgi_arg(source_key);
575 submission_text += source_key;
576 //submission_text += &cgi_argument_name_cstr[strlen(source_chunk_key_start_cstr)];
577 submission_text += "\">\n";
578
579 text_t source_value = xml_safe(decode_commas(args[cgi_argument->first]));
580 // if (args["w"] != "utf-8") {
581 // source_value = to_utf8(source_value);
582 // }
583 submission_text += source_value + "\n";
584 submission_text += "</SourceFileText>\n";
585 }
586 // Target file text
587 if (strncmp(cgi_argument_name_cstr, target_chunk_key_start_cstr, strlen(target_chunk_key_start_cstr)) == 0) {
588 submission_text += "<TargetFileText key=\"";
589 text_t target_key = &cgi_argument_name_cstr[strlen(target_chunk_key_start_cstr)];
590 decode_cgi_arg(target_key);
591 submission_text += target_key;
592 //submission_text += &cgi_argument_name_cstr[strlen(target_chunk_key_start_cstr)];
593 submission_text += "\">\n";
594
595 text_t target_value = xml_safe(decode_commas(args[cgi_argument->first]));
596 // if (args["w"] != "utf-8") {
597 // target_value = to_utf8(target_value);
598 // }
599 submission_text += target_value + "\n";
600 submission_text += "</TargetFileText>\n";
601 }
602
603 delete[] cgi_argument_name_cstr;
604 ++cgi_argument;
605 }
606
607 logout << "Submission text: " << submission_text << endl;
608
609 // Send the submission to gti.pl
610 text_t gti_arguments = "submit-translations " + target_language_code + " " + translation_file_key + " " + submitter_username;
611 if (force_submission) {
612 gti_arguments += " -force_submission";
613 }
614 do_gti_submission(gti_arguments, submission_text, logout);
615 logout << "Done." << endl;
616
617 delete[] source_chunk_key_start_cstr;
618 delete[] target_chunk_key_start_cstr;
619}
620
621
622
623bool gtiaction::produce_excel_spreadsheet(cgiargsclass& args, ostream& logout)
624{
625 // Get the target language code and file to translate from the CGI arguments
626 text_t target_language_code = args["tlc"];
627 text_t translation_file_key = args["tfk"];
628 text_t target_chunk_type = args["tct"];
629
630 // Send a request to gti.pl to get the Excel spreadsheet data
631 text_t gti_arguments = "";
632 if (target_chunk_type == "work") {
633 gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + "10000" + " | /opt/jdk1.6.0/bin/java -cp /home/nzdl/gti:/home/nzdl/gti/xalan.jar ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
634 } else {
635 gti_arguments = "get-all-chunks " + target_language_code + " " + translation_file_key + " | /opt/jdk1.6.0/bin/java -cp /home/nzdl/gti:/home/nzdl/gti/xalan.jar ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
636 }
637
638 text_t gti_response_xml_text = do_gti_request(gti_arguments, logout);
639 if (gti_response_xml_text == "") {
640 // An error has occurred
641 return false;
642 }
643
644 // Write the Excel spreadsheet data to the browser
645 char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr();
646 printf(gti_response_xml_text_cstr);
647 delete[] gti_response_xml_text_cstr;
648
649 return true;
650}
651
652bool gtiaction::produce_glihelp_zipfile(displayclass& disp, cgiargsclass& args, ostream& logout)
653{
654 text_t target_language_code = args["tlc"];
655 text_t gti_arguments = "create-glihelp-zip-file " + target_language_code;
656
657 do_gti_request(gti_arguments, logout);
658
659 disp.setmacro("gtiglihelpzipfilepath", "gti", target_language_code + "_GLIHelp.zip");
660
661 return true;
662}
663
664
665text_t gtiaction::escape_all(text_t text_string, char character_to_escape)
666{
667 text_t text_string_escaped = "";
668
669 text_t::iterator text_string_character = text_string.begin();
670 while (text_string_character != text_string.end()) {
671 if (*text_string_character == character_to_escape) {
672 text_string_escaped += "\\";
673 }
674 text_string_escaped.push_back(*text_string_character);
675 text_string_character++;
676 }
677
678 return text_string_escaped;
679}
680
681
682
683char* xml_get_attribute(const char** attributes, char* attribute_name)
684{
685 for (int i = 0; (attributes[i] != NULL); i += 2) {
686 if (strcmp(attribute_name, attributes[i]) == 0) {
687 return strdup(attributes[i+1]);
688 }
689 }
690
691 return NULL;
692}
693
694
695static void XMLCALL gti_response_xml_start_element(void* user_data, const char* element_name_cstr, const char** attributes)
696{
697 GTI_Response* gti_response = (GTI_Response*) user_data;
698 text_t element_name = element_name_cstr;
699 cerr << "In startElement() for " << element_name << endl;
700
701 if (element_name == "GTIError") {
702 gti_response->recorded_text = "";
703 gti_response->is_recording_text = true;
704 }
705
706 if (element_name == "TranslationFile") {
707 int translation_file_index = gti_response->translation_files_index_to_key_mapping.size();
708 gti_response->translation_file_key = xml_get_attribute(attributes, "key");
709 gti_response->translation_files_index_to_key_mapping[translation_file_index] = gti_response->translation_file_key;
710 gti_response->translation_files_key_to_target_file_path_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "target_file_path");
711 gti_response->translation_files_key_to_num_chunks_translated_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_translated");
712 gti_response->translation_files_key_to_num_chunks_requiring_translation_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_translation");
713 gti_response->translation_files_key_to_num_chunks_requiring_updating_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_updating");
714 }
715
716 if (element_name == "ChunksMatchingQuery") {
717 gti_response->num_chunks_matching_query = xml_get_attribute(attributes, "size");
718 }
719
720 if (element_name == "Chunk") {
721 gti_response->chunk_key = xml_get_attribute(attributes, "key");
722 }
723
724 if (element_name == "SourceFileText") {
725 gti_response->source_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
726 gti_response->recorded_text = "";
727 gti_response->is_recording_text = true;
728 }
729
730 if (element_name == "TargetFileText") {
731 if (xml_get_attribute(attributes, "date") != NULL) {
732 gti_response->target_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
733 }
734 gti_response->recorded_text = "";
735 gti_response->is_recording_text = true;
736 }
737}
738
739
740static void XMLCALL gti_response_xml_end_element(void* user_data, const char* element_name_cstr)
741{
742 GTI_Response* gti_response = (GTI_Response*) user_data;
743 text_t element_name = element_name_cstr;
744
745 if (element_name == "GTIError") {
746 gti_response->error_message = to_uni(gti_response->recorded_text);
747 gti_response->is_recording_text = false;
748 }
749
750 if (element_name == "SourceFileText") {
751 gti_response->source_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
752 gti_response->is_recording_text = false;
753 }
754
755 if (element_name == "TargetFileText") {
756 gti_response->target_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
757 gti_response->is_recording_text = false;
758 }
759}
760
761
762static void XMLCALL gti_response_xml_character_data(void *user_data, const char* text_cstr, int text_length)
763{
764 GTI_Response* gti_response = (GTI_Response*) user_data;
765 if (gti_response->is_recording_text) {
766 gti_response->recorded_text.appendcarr(text_cstr, text_length);
767 }
768}
769
770
771
772text_t gtiaction::do_gti_request(text_t gti_arguments, ostream& logout)
773{
774 // Send the request to gti.pl and read the XML output
775 text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
776 char* gti_command_cstr = gti_command.getcstr();
777 FILE *gti_pipe = popen(gti_command_cstr, "r");
778 delete[] gti_command_cstr;
779 if (gti_pipe == NULL) {
780 logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
781 return "";
782 }
783
784 // Read the gti.pl response
785 text_t gti_response_xml_text;
786 while (!feof(gti_pipe)) {
787 char buffer[1024];
788 gti_response_xml_text.appendcarr(buffer, fread(buffer, 1, 1024, gti_pipe));
789 }
790 pclose(gti_pipe);
791
792 return gti_response_xml_text;
793}
794
795
796
797GTI_Response gtiaction::parse_gti_response(text_t gti_response_xml_text, ostream& logout)
798{
799 GTI_Response gti_response;
800 gti_response.is_recording_text = false;
801
802 // Parse the gti.pl response (XML)
803 logout << "Parsing GTI command response: " << gti_response_xml_text << endl;
804 XML_Parser xml_parser = XML_ParserCreate(NULL);
805 XML_SetUserData(xml_parser, &gti_response);
806 XML_SetElementHandler(xml_parser, gti_response_xml_start_element, gti_response_xml_end_element);
807 XML_SetCharacterDataHandler(xml_parser, gti_response_xml_character_data);
808
809 char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr();
810 int parse_status = XML_Parse(xml_parser, gti_response_xml_text_cstr, strlen(gti_response_xml_text_cstr), XML_TRUE);
811 delete[] gti_response_xml_text_cstr;
812 if (parse_status == XML_STATUS_ERROR) {
813 logout << "Parse error " << XML_ErrorString(XML_GetErrorCode(xml_parser)) << " at line " << XML_GetCurrentLineNumber(xml_parser) << endl;
814 return gti_response;
815 }
816
817 XML_ParserFree(xml_parser);
818
819 logout << "Finished parse." << endl;
820 return gti_response;
821}
822
823
824
825void gtiaction::do_gti_submission(text_t gti_arguments, text_t gti_submission, ostream& logout)
826{
827 // Send the submission to gti.pl
828 text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
829 char* gti_command_cstr = gti_command.getcstr();
830 FILE *gti_pipe = popen(gti_command_cstr, "w");
831 delete[] gti_command_cstr;
832 if (gti_pipe == NULL) {
833 logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
834 return;
835 }
836
837 // Write the gti.pl submission
838 char* gti_submission_cstr = gti_submission.getcstr();
839 fwrite(gti_submission_cstr, 1, strlen(gti_submission_cstr), gti_pipe);
840 delete[] gti_submission_cstr;
841
842 pclose(gti_pipe);
843}
844
845
846
847#endif // GSDL_USE_GTI_ACTION
Note: See TracBrowser for help on using the repository browser.