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

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

Stopped running to_utf8 on the submitted strings, as this is causing the submitted values to be UTF-8 encoded twice -- buggering things up. Hopefully this doesn't mess up other languages though?

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