source: trunk/gsdl/src/recpt/gtiaction.cpp@ 12485

Last change on this file since 12485 was 12485, checked in by mdewsnip, 18 years ago

The username of the person submitting translations is now passed to gti.pl so it can be recorded.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 27.0 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 "fileutil.h"
36#include "gsdlunicode.h"
37
38
39
40gtiaction::gtiaction()
41{
42 cgiarginfo arg_ainfo;
43
44 arg_ainfo.shortname = "tlc";
45 arg_ainfo.longname = "translation target language code";
46 arg_ainfo.multiplechar = true;
47 arg_ainfo.defaultstatus = cgiarginfo::weak;
48 arg_ainfo.savedarginfo = cgiarginfo::must;
49 argsinfo.addarginfo (&cerr, arg_ainfo);
50
51 arg_ainfo.shortname = "tfk";
52 arg_ainfo.longname = "translation file key";
53 arg_ainfo.multiplechar = true;
54 arg_ainfo.defaultstatus = cgiarginfo::weak;
55 arg_ainfo.savedarginfo = cgiarginfo::must;
56 argsinfo.addarginfo (&cerr, arg_ainfo);
57
58 arg_ainfo.shortname = "ncpp";
59 arg_ainfo.longname = "number of chunks per page";
60 arg_ainfo.multiplechar = true;
61 arg_ainfo.defaultstatus = cgiarginfo::weak;
62 arg_ainfo.argdefault = "1";
63 arg_ainfo.savedarginfo = cgiarginfo::must;
64 argsinfo.addarginfo (&cerr, arg_ainfo);
65}
66
67
68
69gtiaction::~gtiaction()
70{
71 delete[] set_gsdlhome_cstr;
72 delete[] set_gsdlos_cstr;
73}
74
75
76
77bool gtiaction::init (ostream& /*logout*/)
78{
79 // Set GSDLHOME and GSDLOS environment variables
80 text_t set_gsdlhome = "GSDLHOME=" + gsdlhome;
81 text_t set_gsdlos = "GSDLOS=";
82
83#if defined (__WIN32__)
84 set_gsdlos += "windows";
85#else
86 struct utsname *buf = new struct utsname();
87 if (uname(buf) == -1) {
88 // uname failed, so this must be linux
89 set_gsdlos += "linux";
90 }
91 else {
92 text_t gsdlos = buf->sysname;
93 lc(gsdlos);
94 set_gsdlos += gsdlos;
95 }
96 delete buf;
97#endif
98
99 // These will be cleaned up in the destructor
100 set_gsdlhome_cstr = set_gsdlhome.getcstr();
101 set_gsdlos_cstr = set_gsdlos.getcstr();
102 putenv(set_gsdlhome_cstr);
103 putenv(set_gsdlos_cstr);
104
105 return true;
106}
107
108
109
110bool gtiaction::check_cgiargs(cgiargsinfoclass& /*argsinfo*/, cgiargsclass& args,
111 recptprotolistclass* /*protos*/, ostream& logout)
112{
113 // Authenticate the user, except for the "home" and "lang" pages
114 if (args["p"] != "home" && args["p"] != "lang") {
115 args["uan"] = 1;
116 args["ug"] = "langadmin_" + args["tlc"];
117 }
118
119 return true;
120}
121
122
123
124bool gtiaction::do_action(cgiargsclass& args, recptprotolistclass* /*protos*/,
125 browsermapclass* /*browsers*/, displayclass& disp,
126 outconvertclass& outconvert, ostream& textout,
127 ostream& logout)
128{
129 textout << outconvert << disp << ("_gti:header_\n") << ("_gti:content_\n") << ("_gti:footer_\n");
130 return true;
131}
132
133
134
135void gtiaction::get_cgihead_info(cgiargsclass& /*args*/, recptprotolistclass* /*protos*/,
136 response_t& response, text_t& response_data,
137 ostream& logout)
138{
139 response = content;
140 response_data = "text/html";
141}
142
143
144
145void gtiaction::define_internal_macros(displayclass& disp, cgiargsclass& args,
146 recptprotolistclass* protos, ostream& logout)
147{
148 // logout << endl << "Arguments: " << args << endl;
149 logout << endl << "CGI arg p: " << args["p"] << endl;
150
151 // For some reason this must be done as well as setting the macro in gti.dm
152 // is that still true??
153 disp.setmacro("preflink", displayclass::defaultpackage, "_gti:preflink_");
154
155 // Define the page content for the GTI home page
156 if (args["p"] == "home") {
157 define_gti_home_page(disp, args, logout);
158 return;
159 }
160
161 // Define the page content for the GTI language page
162 if (args["p"] == "lang") {
163 define_gti_lang_page(disp, args, logout);
164 return;
165 }
166
167 // Define the page content for the GTI search page
168 if (args["p"] == "find") {
169 define_gti_find_page(disp, args, logout);
170 return;
171 }
172
173 // Define the page content for the GTI excel page
174 if (args["p"] == "excel") {
175 define_gti_excel_page(disp, args, logout);
176 return;
177 }
178
179 // Process user translations
180 if (args["p"] == "submit") {
181 process_gti_submissions(disp, args, logout, true);
182 }
183
184 // Define the page content for the GTI core pages (containing the translation input forms)
185 define_gti_core_page(disp, args, logout);
186}
187
188
189
190void gtiaction::define_gti_home_page(displayclass& disp, cgiargsclass& args, ostream& logout)
191{
192 disp.setmacro("gtiformcontent", "gti", "_gti:gtihome_");
193
194 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
195
196 // Get the languages specified in the main.cfg file, and put them into a map to sort by name
197 text_tmap gti_languages_name_code_mapping;
198 languageinfo_tmap::const_iterator loaded_language = loaded_languages.begin();
199 while (loaded_language != loaded_languages.end()) {
200 // English is not a valid GTI target language, since it is the source language
201 if (loaded_language->first != "en") {
202 gti_languages_name_code_mapping[loaded_language->second.longname] = loaded_language->first;
203 }
204 ++loaded_language;
205 }
206
207 // Set the gtitlcselection macro
208 text_t gti_tlc_selection = "<select name=\"tlc\">\n";
209 text_tmap::iterator gti_language = gti_languages_name_code_mapping.begin();
210 while (gti_language != gti_languages_name_code_mapping.end()) {
211 gti_tlc_selection += "<option value=\"" + gti_language->second + "\">" + gti_language->first + "</option>\n";
212 ++gti_language;
213 }
214 gti_tlc_selection += "</select>";
215 disp.setmacro("gtitlcselection", "gti", gti_tlc_selection);
216}
217
218
219
220void gtiaction::define_gti_lang_page(displayclass& disp, cgiargsclass& args, ostream& logout)
221{
222 // Get the target language code from the CGI arguments
223 text_t target_language_code = args["tlc"];
224
225 disp.setmacro("gtiformcontent", "gti", "_gti:gtilang_");
226
227 // Send a request to gti.pl to get the valid translation files
228 text_t gti_arguments = "get-language-status " + target_language_code;
229 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
230 if (gti_response.error_message != "") {
231 // An error has occurred
232 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
233 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
234 return;
235 }
236
237 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
238 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
239
240 // Set the gtitfkselection macro
241 text_t gti_tfk_selection = "<table>";
242 text_tmap::iterator translation_file = gti_response.translation_files_index_to_key_mapping.begin();
243 while (translation_file != gti_response.translation_files_index_to_key_mapping.end()) {
244 text_t translation_file_key = translation_file->second;
245
246 gti_tfk_selection += "<tr><td>";
247 gti_tfk_selection += "<input type=\"radio\" name=\"tfk\" value=\"" + translation_file_key + "\"></td>\n";
248 gti_tfk_selection += "<td>_textgti" + translation_file_key + "_</td></tr>\n";
249
250 text_t num_chunks_translated = gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key];
251 text_t num_chunks_requiring_translation = gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key];
252 text_t num_chunks_requiring_updating = gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key];
253 gti_tfk_selection += "<tr><td></td><td>_gtitranslationfilestatus_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td></tr>\n";
254 ++translation_file;
255 }
256 gti_tfk_selection += "</table>";
257 disp.setmacro("gtitfkselection", "gti", gti_tfk_selection);
258}
259
260
261
262void gtiaction::define_gti_find_page(displayclass& disp, cgiargsclass& args, ostream& logout)
263{
264 // Get the target language code and file to translate from the CGI arguments
265 text_t target_language_code = args["tlc"];
266 text_t translation_file_key = args["tfk"];
267 text_t query_string = to_utf8(args["q"]);
268
269 // Process user corrections
270 if (args["sp"] != "") {
271 process_gti_submissions(disp, args, logout, false);
272 }
273
274 disp.setmacro("gtiformcontent", "gti", "_gti:gtifind_");
275
276 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
277 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
278 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
279
280 if (query_string == "") {
281 // No query, so no search results
282 disp.setmacro("gtifindformcontent", "gti", "");
283 return;
284 }
285
286 // Display text right to left if target language is Arabic or Farsi or Urdu
287 if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") {
288 disp.setmacro("gtitextdirection", "gti", "rtl");
289 }
290 else {
291 disp.setmacro("gtitextdirection", "gti", "ltr");
292 }
293
294 // Send a request to gti.pl to get the valid translation files
295 logout << "Query argument: " << query_string << endl;
296 text_t gti_arguments = "search-chunks " + target_language_code + " " + translation_file_key + " " + query_string;
297 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
298 if (gti_response.error_message != "") {
299 // An error has occurred
300 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
301 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
302 return;
303 }
304
305 disp.setmacro("gtinumchunksmatchingquery", "gti", gti_response.num_chunks_matching_query);
306
307 // Loop through the chunks returned, displaying them on the page
308 text_t gti_find_form_content = "_gtifindformheader_\n";
309 text_tmap::iterator chunk_key_iterator = gti_response.target_file_chunks_key_to_text_mapping.begin();
310 while (chunk_key_iterator != gti_response.target_file_chunks_key_to_text_mapping.end()) {
311 text_t chunk_key = chunk_key_iterator->first;
312
313 // Need to escape any underscores in the chunk key to show it correctly on the page
314 text_t chunk_key_escaped = escape_all(chunk_key, '_');
315
316 // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
317 text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
318 text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
319 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
320 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ',');
321 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '(');
322 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')');
323 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '"');
324 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\'');
325
326 // This chunk matches the query
327 gti_find_form_content += "_gtichunkmatchingquery_(" + chunk_key_escaped + "," + target_file_chunk_text_escaped + ")\n";
328
329 chunk_key_iterator++;
330 }
331 gti_find_form_content += "_gtifindformfooter_\n";
332
333 disp.setmacro("gtifindformcontent", "gti", gti_find_form_content);
334}
335
336
337
338void gtiaction::define_gti_excel_page(displayclass& disp, cgiargsclass& args, ostream& logout)
339{
340 // Get the target language code and file to translate from the CGI arguments
341 text_t target_language_code = args["tlc"];
342 text_t translation_file_key = args["tfk"];
343
344 disp.setmacro("gtiformcontent", "gti", "_gti:gtiexcel_");
345
346 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
347 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
348 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
349
350 // Send a request to gti.pl to get the valid translation files
351 text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + "10000" + " | java -classpath $GSDLHOME/bin/java ApplyXSLT $GSDLHOME/etc/gti-generate-excel-xml.xsl -";
352 text_t gti_response_xml_text = do_gti_request(gti_arguments, logout);
353
354 // !! UNFINISHED !!
355}
356
357
358
359void gtiaction::define_gti_core_page(displayclass& disp, cgiargsclass& args, ostream& logout)
360{
361 // Get the target language code and file to translate from the CGI arguments
362 text_t target_language_code = args["tlc"];
363 text_t translation_file_key = args["tfk"];
364 text_t num_chunks_per_page = args["ncpp"];
365 logout << "Num chunks per page: " << num_chunks_per_page << endl;
366
367 disp.setmacro("gtiformcontent", "gti", "_gti:gticore_");
368
369 // Display text right to left if target language is Arabic or Farsi or Urdu
370 if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") {
371 disp.setmacro("gtitextdirection", "gti", "rtl");
372 }
373 else {
374 disp.setmacro("gtitextdirection", "gti", "ltr");
375 }
376
377 // Send a request to gti.pl to get the first string to translate
378 text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + num_chunks_per_page;
379 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
380 if (gti_response.error_message != "") {
381 // An error has occurred
382 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
383 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
384 return;
385 }
386
387 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
388 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
389 disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]);
390 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
391 disp.setmacro("gtiviewtranslationfileinaction", "gti", "_gti:gtiview" + translation_file_key + "inaction_");
392
393 disp.setmacro("gtinumchunkstranslated", "gti", gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key]);
394 disp.setmacro("gtinumchunksrequiringtranslation", "gti", gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key]);
395 disp.setmacro("gtinumchunksrequiringupdating", "gti", gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key]);
396
397 // Check if the translation file is finished
398 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") {
399 disp.setmacro("gtiformcontent", "gti", "_gti:gtidone_");
400 return;
401 }
402
403 // Loop through the chunks returned, displaying them on the page
404 text_t gti_core_form_content = "";
405 text_tmap::iterator chunk_key_iterator = gti_response.source_file_chunks_key_to_text_mapping.begin();
406 while (chunk_key_iterator != gti_response.source_file_chunks_key_to_text_mapping.end()) {
407 text_t chunk_key = chunk_key_iterator->first;
408
409 // Need to escape any underscores in the chunk key to show it correctly on the page
410 text_t chunk_key_escaped = escape_all(chunk_key, '_');
411
412 // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
413 text_t source_file_chunk_text = gti_response.source_file_chunks_key_to_text_mapping[chunk_key];
414 text_t source_file_chunk_text_escaped = escape_all(source_file_chunk_text, '\\');
415 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '_');
416 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ',');
417 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '(');
418 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ')');
419 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '\'');
420 text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
421 text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
422 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
423 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ',');
424 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '(');
425 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')');
426 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\'');
427
428 text_t source_file_chunk_date = gti_response.source_file_chunks_key_to_date_mapping[chunk_key];
429 text_t target_file_chunk_date = gti_response.target_file_chunks_key_to_date_mapping[chunk_key];
430
431 // This chunk requires translation
432 if (target_file_chunk_text == "") {
433 gti_core_form_content += "_gtichunkrequiringtranslation_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + ")\n";
434 }
435 // This chunk requires updating
436 else {
437 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";
438 }
439
440 chunk_key_iterator++;
441 }
442
443 disp.setmacro("gticoreformcontent", "gti", gti_core_form_content);
444}
445
446
447
448void gtiaction::process_gti_submissions(displayclass& disp, cgiargsclass& args, ostream& logout, bool force_submission)
449{
450 // Get the target language code and file to translate from the CGI arguments
451 text_t target_language_code = args["tlc"];
452 text_t translation_file_key = args["tfk"];
453 text_t submitter_username = args["un"];
454
455 // Submitted chunk arguments contain the language code followed by "::"
456 char* source_chunk_key_start_cstr = ((text_t) "en" + "%3A%3A").getcstr();
457 char* target_chunk_key_start_cstr = (target_language_code + "%3A%3A").getcstr();
458
459 // Find the cgi arguments with submitted chunk information
460 text_t submission_text;
461 cgiargsclass::const_iterator cgi_argument = args.begin();
462 while (cgi_argument != args.end()) {
463 char* cgi_argument_name_cstr = cgi_argument->first.getcstr();
464
465 // Source file text
466 if (strncmp(cgi_argument_name_cstr, source_chunk_key_start_cstr, strlen(source_chunk_key_start_cstr)) == 0) {
467 submission_text += "<SourceFileText key=\"";
468 submission_text += &cgi_argument_name_cstr[strlen(source_chunk_key_start_cstr)];
469 submission_text += "\">\n";
470 submission_text += to_utf8(xml_safe(args[cgi_argument->first])) + "\n";
471 submission_text += "</SourceFileText>\n";
472 }
473 // Target file text
474 if (strncmp(cgi_argument_name_cstr, target_chunk_key_start_cstr, strlen(target_chunk_key_start_cstr)) == 0) {
475 submission_text += "<TargetFileText key=\"";
476 submission_text += &cgi_argument_name_cstr[strlen(target_chunk_key_start_cstr)];
477 submission_text += "\">\n";
478 submission_text += to_utf8(xml_safe(args[cgi_argument->first])) + "\n";
479 submission_text += "</TargetFileText>\n";
480 }
481
482 delete[] cgi_argument_name_cstr;
483 ++cgi_argument;
484 }
485
486 logout << "Submission text: " << submission_text << endl;
487
488 // Send the submission to gti.pl
489 text_t gti_arguments = "submit-translations " + target_language_code + " " + translation_file_key + " " + submitter_username;
490 if (force_submission) {
491 gti_arguments += " -force_submission";
492 }
493 do_gti_submission(gti_arguments, submission_text, logout);
494 logout << "Done." << endl;
495
496 delete[] source_chunk_key_start_cstr;
497 delete[] target_chunk_key_start_cstr;
498}
499
500
501
502text_t gtiaction::escape_all(text_t text_string, char character_to_escape)
503{
504 text_t text_string_escaped = "";
505
506 text_t::iterator text_string_character = text_string.begin();
507 while (text_string_character != text_string.end()) {
508 if (*text_string_character == character_to_escape) {
509 text_string_escaped += "\\";
510 }
511 text_string_escaped.push_back(*text_string_character);
512 text_string_character++;
513 }
514
515 return text_string_escaped;
516}
517
518
519
520text_t gtiaction::xml_safe(const text_t &text_string)
521{
522 text_t text_string_safe;
523 text_t::const_iterator here = text_string.begin();
524 text_t::const_iterator end = text_string.end();
525 while (here != end) {
526 if (*here == '&') text_string_safe += "&amp;";
527 else if (*here == '<') text_string_safe += "&lt;";
528 else if (*here == '>') text_string_safe += "&gt;";
529 else text_string_safe.push_back(*here);
530 ++here;
531 }
532
533 return text_string_safe;
534}
535
536
537
538char* xml_get_attribute(const char** attributes, char* attribute_name)
539{
540 for (int i = 0; (attributes[i] != NULL); i += 2) {
541 if (strcmp(attribute_name, attributes[i]) == 0) {
542 return strdup(attributes[i+1]);
543 }
544 }
545
546 return NULL;
547}
548
549
550static void XMLCALL gti_response_xml_start_element(void* user_data, const char* element_name_cstr, const char** attributes)
551{
552 GTI_Response* gti_response = (GTI_Response*) user_data;
553 text_t element_name = element_name_cstr;
554 cerr << "In startElement() for " << element_name << endl;
555
556 if (element_name == "GTIError") {
557 gti_response->recorded_text = "";
558 gti_response->is_recording_text = true;
559 }
560
561 if (element_name == "TranslationFile") {
562 int translation_file_index = gti_response->translation_files_index_to_key_mapping.size();
563 gti_response->translation_file_key = xml_get_attribute(attributes, "key");
564 gti_response->translation_files_index_to_key_mapping[translation_file_index] = gti_response->translation_file_key;
565 gti_response->translation_files_key_to_target_file_path_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "target_file_path");
566 gti_response->translation_files_key_to_num_chunks_translated_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_translated");
567 gti_response->translation_files_key_to_num_chunks_requiring_translation_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_translation");
568 gti_response->translation_files_key_to_num_chunks_requiring_updating_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_updating");
569 }
570
571 if (element_name == "ChunksMatchingQuery") {
572 gti_response->num_chunks_matching_query = xml_get_attribute(attributes, "size");
573 }
574
575 if (element_name == "Chunk") {
576 gti_response->chunk_key = xml_get_attribute(attributes, "key");
577 }
578
579 if (element_name == "SourceFileText") {
580 gti_response->source_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
581 gti_response->recorded_text = "";
582 gti_response->is_recording_text = true;
583 }
584
585 if (element_name == "TargetFileText") {
586 if (xml_get_attribute(attributes, "date") != NULL) {
587 gti_response->target_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
588 }
589 gti_response->recorded_text = "";
590 gti_response->is_recording_text = true;
591 }
592}
593
594
595static void XMLCALL gti_response_xml_end_element(void* user_data, const char* element_name_cstr)
596{
597 GTI_Response* gti_response = (GTI_Response*) user_data;
598 text_t element_name = element_name_cstr;
599
600 if (element_name == "GTIError") {
601 gti_response->error_message = to_uni(gti_response->recorded_text);
602 gti_response->is_recording_text = false;
603 }
604
605 if (element_name == "SourceFileText") {
606 gti_response->source_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
607 gti_response->is_recording_text = false;
608 }
609
610 if (element_name == "TargetFileText") {
611 gti_response->target_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
612 gti_response->is_recording_text = false;
613 }
614}
615
616
617static void XMLCALL gti_response_xml_character_data(void *user_data, const char* text_cstr, int text_length)
618{
619 GTI_Response* gti_response = (GTI_Response*) user_data;
620 if (gti_response->is_recording_text) {
621 gti_response->recorded_text.appendcarr(text_cstr, text_length);
622 }
623}
624
625
626
627text_t gtiaction::do_gti_request(text_t gti_arguments, ostream& logout)
628{
629 // Send the request to gti.pl and read the XML output
630 text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
631 char* gti_command_cstr = gti_command.getcstr();
632 FILE *gti_pipe = popen(gti_command_cstr, "r");
633 delete[] gti_command_cstr;
634 if (gti_pipe == NULL) {
635 logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
636 return "";
637 }
638
639 // Read the gti.pl response
640 text_t gti_response_xml_text;
641 while (!feof(gti_pipe)) {
642 char buffer[1024];
643 gti_response_xml_text.appendcarr(buffer, fread(buffer, 1, 1024, gti_pipe));
644 }
645 pclose(gti_pipe);
646
647 return gti_response_xml_text;
648}
649
650
651
652GTI_Response gtiaction::parse_gti_response(text_t gti_response_xml_text, ostream& logout)
653{
654 GTI_Response gti_response;
655 gti_response.is_recording_text = false;
656
657 // Parse the gti.pl response (XML)
658 logout << "Parsing GTI command response: " << gti_response_xml_text << endl;
659 XML_Parser xml_parser = XML_ParserCreate(NULL);
660 XML_SetUserData(xml_parser, &gti_response);
661 XML_SetElementHandler(xml_parser, gti_response_xml_start_element, gti_response_xml_end_element);
662 XML_SetCharacterDataHandler(xml_parser, gti_response_xml_character_data);
663
664 char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr();
665 int parse_status = XML_Parse(xml_parser, gti_response_xml_text_cstr, strlen(gti_response_xml_text_cstr), XML_TRUE);
666 delete[] gti_response_xml_text_cstr;
667 if (parse_status == XML_STATUS_ERROR) {
668 logout << "Parse error " << XML_ErrorString(XML_GetErrorCode(xml_parser)) << " at line " << XML_GetCurrentLineNumber(xml_parser) << endl;
669 return gti_response;
670 }
671
672 XML_ParserFree(xml_parser);
673
674 logout << "Finished parse." << endl;
675 return gti_response;
676}
677
678
679
680void gtiaction::do_gti_submission(text_t gti_arguments, text_t gti_submission, ostream& logout)
681{
682 // Send the submission to gti.pl
683 text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
684 char* gti_command_cstr = gti_command.getcstr();
685 FILE *gti_pipe = popen(gti_command_cstr, "w");
686 delete[] gti_command_cstr;
687 if (gti_pipe == NULL) {
688 logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
689 return;
690 }
691
692 // Write the gti.pl submission
693 char* gti_submission_cstr = gti_submission.getcstr();
694 fwrite(gti_submission_cstr, 1, strlen(gti_submission_cstr), gti_pipe);
695 delete[] gti_submission_cstr;
696
697 pclose(gti_pipe);
698}
699
700
701
702#endif // GSDL_USE_GTI_ACTION
Note: See TracBrowser for help on using the repository browser.