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

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

Also need to escape double quotes?

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