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

Last change on this file since 10739 was 10148, checked in by mdewsnip, 19 years ago

Split up doing a GTI request into doing the request, and parsing the XML output. This is necessary for the Excel stuff (soon).

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 25.1 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
318 // This chunk matches the query
319 gti_find_form_content += "_gtichunkmatchingquery_(" + chunk_key_escaped + "," + target_file_chunk_text_escaped + ")\n";
320
321 chunk_key_iterator++;
322 }
323 gti_find_form_content += "_gtifindformfooter_\n";
324
325 disp.setmacro("gtifindformcontent", "gti", gti_find_form_content);
326}
327
328
329
330void gtiaction::define_gti_core_page(displayclass& disp, cgiargsclass& args, ostream& logout)
331{
332 // Get the target language code and file to translate from the CGI arguments
333 text_t target_language_code = args["tlc"];
334 text_t translation_file_key = args["tfk"];
335 text_t num_chunks_per_page = args["ncpp"];
336 logout << "Num chunks per page: " << num_chunks_per_page << endl;
337
338 disp.setmacro("gtiformcontent", "gti", "_gti:gticore_");
339
340 // Display text right to left if target language is Arabic or Farsi
341 if (target_language_code == "ar" || target_language_code == "fa") {
342 disp.setmacro("gtitextdirection", "gti", "rtl");
343 }
344 else {
345 disp.setmacro("gtitextdirection", "gti", "ltr");
346 }
347
348 // Send a request to gti.pl to get the first string to translate
349 text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + num_chunks_per_page;
350 GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
351 if (gti_response.error_message != "") {
352 // An error has occurred
353 disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
354 disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
355 return;
356 }
357
358 languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
359 disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
360 disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]);
361 disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
362 disp.setmacro("gtiviewtranslationfileinaction", "gti", "_gti:gtiview" + translation_file_key + "inaction_");
363
364 disp.setmacro("gtinumchunkstranslated", "gti", gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key]);
365 disp.setmacro("gtinumchunksrequiringtranslation", "gti", gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key]);
366 disp.setmacro("gtinumchunksrequiringupdating", "gti", gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key]);
367
368 // Check if the translation file is finished
369 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") {
370 disp.setmacro("gtiformcontent", "gti", "_gti:gtidone_");
371 return;
372 }
373
374 // Loop through the chunks returned, displaying them on the page
375 text_t gti_core_form_content = "";
376 text_tmap::iterator chunk_key_iterator = gti_response.source_file_chunks_key_to_text_mapping.begin();
377 while (chunk_key_iterator != gti_response.source_file_chunks_key_to_text_mapping.end()) {
378 text_t chunk_key = chunk_key_iterator->first;
379
380 // Need to escape any underscores in the chunk key to show it correctly on the page
381 text_t chunk_key_escaped = escape_all(chunk_key, '_');
382
383 // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
384 text_t source_file_chunk_text = gti_response.source_file_chunks_key_to_text_mapping[chunk_key];
385 text_t source_file_chunk_text_escaped = escape_all(source_file_chunk_text, '\\');
386 source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '_');
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 text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
392 text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
393 target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
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
399 text_t source_file_chunk_date = gti_response.source_file_chunks_key_to_date_mapping[chunk_key];
400 text_t target_file_chunk_date = gti_response.target_file_chunks_key_to_date_mapping[chunk_key];
401
402 // This chunk requires translation
403 if (target_file_chunk_text == "") {
404 gti_core_form_content += "_gtichunkrequiringtranslation_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + ")\n";
405 }
406 // This chunk requires updating
407 else {
408 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";
409 }
410
411 chunk_key_iterator++;
412 }
413
414 disp.setmacro("gticoreformcontent", "gti", gti_core_form_content);
415}
416
417
418
419void gtiaction::process_gti_submissions(displayclass& disp, cgiargsclass& args, ostream& logout, bool force_submission)
420{
421 // Get the target language code and file to translate from the CGI arguments
422 text_t target_language_code = args["tlc"];
423 text_t translation_file_key = args["tfk"];
424
425 // Submitted chunk arguments contain the language code followed by "::"
426 char* source_chunk_key_start_cstr = ((text_t) "en" + "%3A%3A").getcstr();
427 char* target_chunk_key_start_cstr = (target_language_code + "%3A%3A").getcstr();
428
429 // Find the cgi arguments with submitted chunk information
430 text_t submission_text;
431 cgiargsclass::const_iterator cgi_argument = args.begin();
432 while (cgi_argument != args.end()) {
433 char* cgi_argument_name_cstr = cgi_argument->first.getcstr();
434
435 // Source file text
436 if (strncmp(cgi_argument_name_cstr, source_chunk_key_start_cstr, strlen(source_chunk_key_start_cstr)) == 0) {
437 submission_text += "<SourceFileText key=\"";
438 submission_text += &cgi_argument_name_cstr[strlen(source_chunk_key_start_cstr)];
439 submission_text += "\">\n";
440 submission_text += to_utf8(args[cgi_argument->first]) + "\n";
441 submission_text += "</SourceFileText>\n";
442 }
443 // Target file text
444 if (strncmp(cgi_argument_name_cstr, target_chunk_key_start_cstr, strlen(target_chunk_key_start_cstr)) == 0) {
445 submission_text += "<TargetFileText key=\"";
446 submission_text += &cgi_argument_name_cstr[strlen(target_chunk_key_start_cstr)];
447 submission_text += "\">\n";
448 submission_text += to_utf8(args[cgi_argument->first]) + "\n";
449 submission_text += "</TargetFileText>\n";
450 }
451
452 delete[] cgi_argument_name_cstr;
453 ++cgi_argument;
454 }
455
456 logout << "Submission text: " << submission_text << endl;
457
458 // Send the submission to gti.pl
459 text_t gti_arguments = "submit-translations " + target_language_code + " " + translation_file_key;
460 if (force_submission) {
461 gti_arguments += " -force_submission";
462 }
463 do_gti_submission(gti_arguments, submission_text, logout);
464 logout << "Done." << endl;
465
466 delete[] source_chunk_key_start_cstr;
467 delete[] target_chunk_key_start_cstr;
468}
469
470
471
472text_t gtiaction::escape_all(text_t text_string, char character_to_escape)
473{
474 text_t text_string_escaped = "";
475
476 text_t::iterator text_string_character = text_string.begin();
477 while (text_string_character != text_string.end()) {
478 if (*text_string_character == character_to_escape) {
479 text_string_escaped += "\\";
480 }
481 text_string_escaped.push_back(*text_string_character);
482 text_string_character++;
483 }
484
485 return text_string_escaped;
486}
487
488
489
490char* xml_get_attribute(const char** attributes, char* attribute_name)
491{
492 for (int i = 0; (attributes[i] != NULL); i += 2) {
493 if (strcmp(attribute_name, attributes[i]) == 0) {
494 return strdup(attributes[i+1]);
495 }
496 }
497
498 return NULL;
499}
500
501
502static void XMLCALL gti_response_xml_start_element(void* user_data, const char* element_name_cstr, const char** attributes)
503{
504 GTI_Response* gti_response = (GTI_Response*) user_data;
505 text_t element_name = element_name_cstr;
506 cerr << "In startElement() for " << element_name << endl;
507
508 if (element_name == "GTIError") {
509 gti_response->recorded_text = "";
510 gti_response->is_recording_text = true;
511 }
512
513 if (element_name == "TranslationFile") {
514 int translation_file_index = gti_response->translation_files_index_to_key_mapping.size();
515 gti_response->translation_file_key = xml_get_attribute(attributes, "key");
516 gti_response->translation_files_index_to_key_mapping[translation_file_index] = gti_response->translation_file_key;
517 gti_response->translation_files_key_to_target_file_path_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "target_file_path");
518 gti_response->translation_files_key_to_num_chunks_translated_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_translated");
519 gti_response->translation_files_key_to_num_chunks_requiring_translation_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_translation");
520 gti_response->translation_files_key_to_num_chunks_requiring_updating_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_updating");
521 }
522
523 if (element_name == "ChunksMatchingQuery") {
524 gti_response->num_chunks_matching_query = xml_get_attribute(attributes, "size");
525 }
526
527 if (element_name == "Chunk") {
528 gti_response->chunk_key = xml_get_attribute(attributes, "key");
529 }
530
531 if (element_name == "SourceFileText") {
532 gti_response->source_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
533 gti_response->recorded_text = "";
534 gti_response->is_recording_text = true;
535 }
536
537 if (element_name == "TargetFileText") {
538 if (xml_get_attribute(attributes, "date") != NULL) {
539 gti_response->target_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
540 }
541 gti_response->recorded_text = "";
542 gti_response->is_recording_text = true;
543 }
544}
545
546
547static void XMLCALL gti_response_xml_end_element(void* user_data, const char* element_name_cstr)
548{
549 GTI_Response* gti_response = (GTI_Response*) user_data;
550 text_t element_name = element_name_cstr;
551
552 if (element_name == "GTIError") {
553 gti_response->error_message = to_uni(gti_response->recorded_text);
554 gti_response->is_recording_text = false;
555 }
556
557 if (element_name == "SourceFileText") {
558 gti_response->source_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
559 gti_response->is_recording_text = false;
560 }
561
562 if (element_name == "TargetFileText") {
563 gti_response->target_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
564 gti_response->is_recording_text = false;
565 }
566}
567
568
569static void XMLCALL gti_response_xml_character_data(void *user_data, const char* text_cstr, int text_length)
570{
571 GTI_Response* gti_response = (GTI_Response*) user_data;
572 if (gti_response->is_recording_text) {
573 gti_response->recorded_text.appendcarr(text_cstr, text_length);
574 }
575}
576
577
578
579text_t gtiaction::do_gti_request(text_t gti_arguments, ostream& logout)
580{
581 // Send the request to gti.pl and read the XML output
582 text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
583 char* gti_command_cstr = gti_command.getcstr();
584 FILE *gti_pipe = popen(gti_command_cstr, "r");
585 delete[] gti_command_cstr;
586 if (gti_pipe == NULL) {
587 logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
588 return "";
589 }
590
591 // Read the gti.pl response
592 text_t gti_response_xml_text;
593 while (!feof(gti_pipe)) {
594 char buffer[1024];
595 gti_response_xml_text.appendcarr(buffer, fread(buffer, 1, 1024, gti_pipe));
596 }
597 pclose(gti_pipe);
598
599 return gti_response_xml_text;
600}
601
602
603
604GTI_Response gtiaction::parse_gti_response(text_t gti_response_xml_text, ostream& logout)
605{
606 GTI_Response gti_response;
607 gti_response.is_recording_text = false;
608
609 // Parse the gti.pl response (XML)
610 logout << "Parsing GTI command response: " << gti_response_xml_text << endl;
611 XML_Parser xml_parser = XML_ParserCreate(NULL);
612 XML_SetUserData(xml_parser, &gti_response);
613 XML_SetElementHandler(xml_parser, gti_response_xml_start_element, gti_response_xml_end_element);
614 XML_SetCharacterDataHandler(xml_parser, gti_response_xml_character_data);
615
616 char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr();
617 int parse_status = XML_Parse(xml_parser, gti_response_xml_text_cstr, strlen(gti_response_xml_text_cstr), XML_TRUE);
618 delete[] gti_response_xml_text_cstr;
619 if (parse_status == XML_STATUS_ERROR) {
620 logout << "Parse error " << XML_ErrorString(XML_GetErrorCode(xml_parser)) << " at line " << XML_GetCurrentLineNumber(xml_parser) << endl;
621 return gti_response;
622 }
623
624 XML_ParserFree(xml_parser);
625
626 logout << "Finished parse." << endl;
627 return gti_response;
628}
629
630
631
632void gtiaction::do_gti_submission(text_t gti_arguments, text_t gti_submission, ostream& logout)
633{
634 // Send the submission to gti.pl
635 text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
636 char* gti_command_cstr = gti_command.getcstr();
637 FILE *gti_pipe = popen(gti_command_cstr, "w");
638 delete[] gti_command_cstr;
639 if (gti_pipe == NULL) {
640 logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
641 return;
642 }
643
644 // Write the gti.pl submission
645 char* gti_submission_cstr = gti_submission.getcstr();
646 fwrite(gti_submission_cstr, 1, strlen(gti_submission_cstr), gti_pipe);
647 delete[] gti_submission_cstr;
648
649 pclose(gti_pipe);
650}
651
652
653
654#endif // GSDL_USE_GTI_ACTION
Note: See TracBrowser for help on using the repository browser.