/********************************************************************** * * langaction.cpp -- * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include #include #include #include #include "langaction.h" #include "fileutil.h" #include "gsdltimes.h" #include "gsdltools.h" #include "gsdlunicode.h" #include "langdb.h" #include "receptionist.h" #include "errno.h" #include /*====================* * GLOBAL DEFINITIONS * *====================*/ // text file reading buffer const int LINESIZE = 1024; /*========================* * LOCAL UTILITY ROUTINES * *========================*/ bool text_t_substring (text_t &text, text_t &substr) { int SIZE = substr.size(); if (text.size() >= SIZE) { if (substr <= text) { if (text[0] == substr[0]) { text_t temp = ""; // copy first SIZE elements of 'text' into 'temp' for (int size = 0; size < SIZE; size++) { temp.push_back(text[size]); } if (temp == substr) return true; } } } return false; } /*====================* * CLASS DEFINITIONS * *====================*/ langaction::langaction () { package = ""; cgiarginfo arg_ainfo; arg_ainfo.shortname = "l"; arg_ainfo.longname = "interface language"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "en"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (&cerr, arg_ainfo); arg_ainfo.shortname = "bl"; arg_ainfo.longname = "base language"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "english"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (&cerr, arg_ainfo); arg_ainfo.shortname = "tlng"; arg_ainfo.longname = "translation language"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "french"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (&cerr, arg_ainfo); } langaction::~langaction () { // Nothing to do in destructor } // set_navbarmacros sets _navigationbar_ and _httpbrowseXXX_ macros // reponse contains 1 metadata field (Title) bool langaction::init (ostream & /*logout*/) { // set up GSDLOS, GSDLHOME and PATH environment variables text_t gsdlos, path; unsigned int path_separator = ':'; #if defined (__WIN32__) gsdlos = "windows"; path_separator = ';'; path = filename_cat (gsdlhome, "bin", "windows", "perl", "bin;"); #else struct utsname *buf = new struct utsname(); int i = uname (buf); if (i == -1) gsdlos = "linux"; // uname failed else gsdlos.setcstr (buf->sysname); delete buf; lc (gsdlos); #endif pathc = getenv ("PATH"); path += filename_cat (gsdlhome, "bin", gsdlos); path.push_back (path_separator); path += filename_cat (gsdlhome, "bin", "script"); if (pathc != NULL) { path.push_back (path_separator); path += pathc; } path = "PATH=" + path; gsdlos = "GSDLOS=" + gsdlos; text_t setgsdlhome = "GSDLHOME=" + gsdlhome; // these will be cleaned up in the destructor gsdlosc = gsdlos.getcstr(); gsdlhomec = setgsdlhome.getcstr(); pathc = path.getcstr(); putenv (gsdlosc); putenv (gsdlhomec); putenv (pathc); return true; } bool langaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, recptprotolistclass* /*protos*/, ostream &logout) { // Authenticate the user before allowing modifications args["uan"] = 1; args["ug"] = "langadmin"; return true; } void langaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass* /*protos*/, response_t &response, text_t &response_data, ostream &logout) { response = content; response_data = "text/html"; } void langaction::define_internal_macros (displayclass &disp, cgiargsclass &args, recptprotolistclass *protos, ostream &logout) { text_t text = ""; text_t cmd = ""; text_t dir = filename_cat(gsdlhome, "tmp", "lang"); text_t page = ""; text_t sourcelang = ""; text_t targetlang = ""; // Get the source language from the CGI arguments if (args["bl"] != "") { sourcelang = args["bl"]; } // Get the target language from the CGI arguments if (args["ownchoice"] != "") { targetlang = args["ownchoice"]; } else if (args["language"] != "") { targetlang = args["language"]; } else if (args["tlng"] != "") { targetlang = args["tlng"]; } // Case fold both languages for (int i = 0; i < strlen(sourcelang.getcstr()); i++) { sourcelang[i] = tolower(sourcelang[i]); } for (int i = 0; i < strlen(targetlang.getcstr()); i++) { targetlang[i] = tolower(targetlang[i]); } // overwrite the global content (which should be overwritten by package) // makes it obvious that package macros aren't defined, compared to "oops..." disp.setmacro("content", "Global", "\\_translang:content\\_"); // Make sure the source and target languages are different! if (sourcelang == targetlang) { logout << "Same language!" << endl; args["p"] = "translang"; page = "picklanguage"; define_webpage(disp, sourcelang, targetlang, dir, page, -1, true, logout); return; } // logout << "Source lang: " << sourcelang << " Target lang: " << targetlang << endl; text_t translation = sourcelang + "-" + targetlang; logout << "Translation: " << translation << endl; text_t trans_dir = filename_cat(dir, translation); // argument for page is of the form 'macrofile_pageno' so // we need to split the argument to get the proper page content text_t &arg_p = args["p"]; text_tarray splitarray; splitchar(arg_p.begin(), arg_p.end(), '_', splitarray); arg_p = splitarray[0]; if (splitarray.size() > 1) page = splitarray[splitarray.size()-1]; //if are entering page from macro search if (args["macroname"] != "") { text_t macroname = args["macroname"]; // !! TO DO !! cmd = "perl " + filename_cat(gsdlhome, "bin", "script", "fromsearch.pl") + " " + sourcelang + " " + targetlang + " " + macroname; logout << "COMMAND: " << cmd <> 8; text_t errmsg="

Error

\nrunning translator.pl: "; if (ret==1) errmsg += "GSDLHOME unset"; else if (ret==2) errmsg += "missing arguments"; else if (ret==3) errmsg += "translation not yet initialised"; else if (ret==4) errmsg += "no source macro found"; errmsg+= " (error " + text_t(ret) + ")\n"; disp.setmacro("content", "translang", errmsg); logout << "Process " << cmd << " did not execute.../;-D\n"; return; } const recptconf &rcinfo = recpt->get_configinfo(); // Use sendmail.pl perl script to send email events text_t tmpmailfile = filename_cat (gsdlhome, "tmp", "lang", "email.txt"); char *tmpmailfilec = tmpmailfile.getcstr(); ofstream tmpfile (tmpmailfilec); if (tmpfile) { tmpfile << "[Translator Event]\n" << "Date: " << get_date (true) << "\n" << "Greenstone Username: " << args["un"] << "\n"; tmpfile << "The " << targetlang << " language translation was entered.\n"; tmpfile.close(); text_t sendmail_cmd = "perl -S sendmail.pl"; sendmail_cmd += " -to \"" + rcinfo.maintainer + "\""; sendmail_cmd += " -from \"greenstone@cs.waikato.ac.nz\""; sendmail_cmd += " -smtp \"" + rcinfo.MailServer + "\""; sendmail_cmd += " -subject \"Greenstone Translator Event\""; sendmail_cmd += " -msgfile \"" + tmpmailfile + "\""; // logout << "Sendmail command: " << sendmail_cmd << endl; gsdl_system (sendmail_cmd, true, logout); unlink(tmpmailfilec); } else { logout << "translatoraction:: ERROR: Couldn't open " << "temporary event log file " << tmpmailfile << " for email event.\n"; } delete tmpmailfilec; } //generates the picklanguage page if (page.empty()) { page = "picklanguage"; cmd = "perl " + filename_cat(gsdlhome, "bin", "script", "picklanguage.pl"); logout << cmd << endl; int ret=gsdl_system(cmd,true,logout); if (ret != 0) { // determine error /* // ret=-1 => we couldn't run the script. // ret=1 => GSDLHOME not set. // >=2 implies some file IO error: // ret=2 => can't read etc/main.cfg // ret=3 => "can't create directory $GSDLHOME/tmp/lang/ // ret=4 => can't write $dir/picklanguage.lang **/ // maybe this should be a "real" macro for translation?! text_t errmsg="

Error

\nPermissions problem: picklanguage.pl failed "; ret = ret >> 8; // man perlfunc for the reason for this if (ret==255) errmsg+="running script"; else if (ret==1) errmsg+="GSDLHOME not set"; else if (ret==2) errmsg+="reading etc/main.cfg"; else if (ret==3) errmsg+="creating tmp/lang/"; else if (ret==4) errmsg+="writing picklanguage.lang"; errmsg += " (error="; errmsg += text_t(ret); errmsg += ")"; disp.setmacro("content", "translang", errmsg); return; } define_webpage(disp, sourcelang, targetlang, dir, page, -1, false, logout); return; } // Read the number of translation pages from numpages.log text_t numpagesfilepath = filename_cat(trans_dir, "numpages.log"); ifstream numpagesfile(numpagesfilepath.getcstr(), ios::in); // Check file opened OK if (!numpagesfile) { text_t errmsg="Error: File " + numpagesfilepath + " could not be opened."; logout << errmsg << endl; disp.setmacro("content", "translang", errmsg); return; } // Read the number of pages from the file int numpages; char line[LINESIZE]; if (numpagesfile.getline(line, LINESIZE-1)) { numpages = atoi(line); } numpagesfile.close(); // if (pagenos.empty() && pageno == "") if (numpages == 0) page = "thankyou"; text_t &submitargs = args[page]; text_t submit = "SUBMIT TRANSLATION"; //if the SUBMIT TRANSLATION >> button has been pushed if (text_t_substring(submitargs,submit)) { //creates output stream to argsfile text_t argsfile = filename_cat(trans_dir, "arguments.arg"); logout << "Argsfile: " << argsfile << endl; write_args_file(args, argsfile, logout); //create the command line for submitting the translation cmd = "perl " + filename_cat(gsdlhome, "bin", "script", "submit_translation.pl") + " "; cmd += (sourcelang + " " + targetlang + " " + "arguments.arg"); //give command to system to execute submission of translation if((gsdl_system(cmd, true, logout)) != 0) logout << "Process " << cmd << " did not execute\n"; //increments which page is displayed when translation is submitted int pageno = atoi(page.getcstr()); if (pageno >= numpages) page = "thankyou"; else page = (pageno + 1); } define_webpage(disp, sourcelang, targetlang, trans_dir, page, numpages, false, logout); } void langaction::write_args_file (cgiargsclass &args, text_t argsfile, ostream &logout) { ofstream argsout(argsfile.getcstr(), ios::out); // Informs user and returns if output stream not opened if (!argsout) { logout << "Error: File " << argsfile << " could not be opened." << endl; return; } // Make the file world writable text_t changemode = "chmod a+w " + argsfile; gsdl_system(changemode, false, logout); // Write out the cgiargsclass variable to the argsout file argsout << args; argsout.close(); } void langaction::define_webpage (displayclass &disp, text_t sourcelang, text_t targetlang, text_t dir, text_t page, int numpages, bool error, ostream &logout) { // produces HTML page with the current pages contents // formfile is the file that contains web-form for the // current package whose name is stored in 'package' text_t formfile = filename_cat(dir, page + ".lang"); ifstream readfile(formfile.getcstr(), ios::in); if (!readfile) { logout << "File " << formfile << " could not be found.\n"; return; } /* ============================ START WEB-FORM HTML CODE ============================ */ text_t text = ""; text += "\n"; text += "\n"; text += "\n"; text += "\n"; text += "_texttranshead_"; // If not a special case page display "Page x of y" and Next button if ((page != "thankyou") && (page != "picklanguage") && (page != "fromsearch")) { text += "
"; text += " _textcurrpage_ " + page + " _textof_ " + numpages; text += ""; int pageno = atoi(page.getcstr()); text += " = numpages) text += "thankyou"; else text += (pageno + 1); text += "&baselanguage=" + sourcelang; text += "&language=" + targetlang; text += "\">"; text += "NEXT>>
\n"; } // Read in HTML from file char line[LINESIZE]; while (readfile.getline(line, LINESIZE-1)) { text_t temp = line; text += temp + "\n"; } readfile.close(); if (page == "picklanguage" && error) { text += "
_textchoosedifferent_
"; } // If not a special case page display "Page x of y" and Next button if ((page != "thankyou") && (page != "picklanguage") && (page != "fromsearch")) { text += "
"; text += " _textcurrpage_ " + page + " _textof_ " + numpages; text += ""; int pageno = atoi(page.getcstr()); text += " = numpages) text += "thankyou"; else text += (pageno + 1); text += "&baselanguage=" + sourcelang; text += "&language=" + targetlang; text += "\">"; text += "NEXT>>
\n"; } if (page == "fromsearch") text += "
_textcurrpage_ 1 _textof_ 1
\n"; text += "\n"; /* ============================ END WEB-FORM HTML CODE ============================ */ // THE FOLLOWING MACROS ARE DEFINED IN translang.dm MACRO FILE // set the formcontent as the content of the form-page disp.setmacro("formcontent", "translang", text); // set the action for the form disp.setmacro("formaction", "translang", "_gwcgi_"); text_t navigationbar = "\n"; navigationbar += ""; navigationbar += ""; navigationbar += "
_imagecollection__javalinks_"; // if (page != "picklanguage") { // navigationbar += "_imageserch_"; // } navigationbar += "
\n\n"; navigationbar += "\n"; disp.setmacro ("navigationbar", "translang", navigationbar); } bool langaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, browsermapclass * /*browsers*/, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { text_t &arg_p = args["p"]; // logout << "Arg P: " << arg_p << endl; outconvertclass text2utf8; textout << text2utf8 << disp << ("_" + arg_p + ":header_\n") << ("_" + arg_p + ":content_\n") << ("_" + arg_p + ":footer_\n"); return true; }