root/main/trunk/greenstone2/runtime-src/src/recpt/depositoraction.cpp @ 31687

Revision 31687, 32.1 KB (checked in by kjdon, 3 years ago)

this wasn't looking lang args to the depositormetadata cfg line, and was therefore setting depositormetaata to [l=en]. Made it use lang params

  • Property svn:keywords set to Author Date Id Revision
Line 
1/**********************************************************************
2 *
3 * depositoraction.cpp --
4 * Copyright (C) 2000  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#include "gsdl_modules_cfg.h"
27#ifdef GSDL_USE_DEPOSITOR_ACTION
28
29// note that the collectoraction relies on having direct access to a
30// collections configuration file. this breaks the separation between
31// receptionist and collection server and so is not suitable (at least
32// in its current form) for use when collection servers are separate
33// from the receptionist (e.g. when using the CORBA protocol).
34
35// following line required to get fstream.filedesc() on darwin (Mac OS X)
36#define _STREAM_COMPAT  1
37// required for utsname on solaris???
38#ifndef _XOPEN_SOURCE
39#define _XOPEN_SOURCE 1
40#endif
41// This was added for Solaris, but it makes things worse on Solaris for me...
42// #define _XOPEN_SOURCE_EXTENDED 1
43
44#include "depositoraction.h"
45#include "OIDtools.h"
46#include "fileutil.h"
47#include "cfgread.h"
48#include "gsdltools.h"
49#include "gsdlunicode.h"
50#include "gsdltimes.h"
51#include "argdb.h"
52#include "cgiutils.h"
53
54#include <stdio.h>
55//#include <strings.h> // seems to be needed for gcc 2.95, but not particularly happy it
56#include <fcntl.h>
57#include <time.h>
58
59#if !defined (__WIN32__)
60#include <sys/utsname.h>
61#include <unistd.h>
62#endif
63
64#include <new>
65//#include <string>
66#include <vector>
67#include <stdexcept>
68#include <iostream>
69//#include <cstdlib>
70
71depositoraction::depositoraction ()
72  : wizardaction()
73{
74  macro_prefix = "di1";  //deposit item
75  lastpage = 0;
76
77  cgiarginfo arg_ainfo;
78  arg_ainfo.shortname = "a";
79  arg_ainfo.longname = "action";
80  arg_ainfo.multiplechar = true;
81  arg_ainfo.multiplevalue = false;
82  arg_ainfo.defaultstatus = cgiarginfo::weak;
83  arg_ainfo.argdefault = "depositor";
84  arg_ainfo.savedarginfo = cgiarginfo::must;
85  argsinfo.addarginfo (NULL, arg_ainfo);
86
87  arg_ainfo.shortname = "p";
88  arg_ainfo.longname = "page";
89  arg_ainfo.multiplechar = true;
90  arg_ainfo.multiplevalue = false;
91  arg_ainfo.defaultstatus = cgiarginfo::weak;
92  arg_ainfo.argdefault = "select";   
93  arg_ainfo.savedarginfo = cgiarginfo::must;
94  argsinfo.addarginfo (NULL, arg_ainfo);
95
96  //furthest page that has been visited
97  arg_ainfo.shortname = "di1lastpage";
98  arg_ainfo.longname = "depositor specific";
99  arg_ainfo.multiplechar = true;
100  arg_ainfo.multiplevalue = false;
101  arg_ainfo.defaultstatus = cgiarginfo::weak;
102  arg_ainfo.argdefault = "0";   
103  arg_ainfo.savedarginfo = cgiarginfo::must;
104  argsinfo.addarginfo (NULL, arg_ainfo);
105 
106  // the fileupload info that cgiwrapper produces - we parse the fileupload_t
107  // and set di1userfile, di1userfilesize
108  arg_ainfo.shortname = "di1userfileinfo";
109  arg_ainfo.longname = "depositor specific";
110  arg_ainfo.fileupload = true;
111  arg_ainfo.multiplevalue = false;
112  arg_ainfo.savedarginfo = cgiarginfo::mustnot; 
113  argsinfo.addarginfo (NULL, arg_ainfo);
114
115  // essential: reset fileupload to default as we are not setting
116  // it for each arg
117  arg_ainfo.fileupload = false;
118
119  //the name of the file to be added
120  arg_ainfo.shortname = "di1userfile";
121  arg_ainfo.longname = "depositor specific";
122  arg_ainfo.multiplechar = true;
123  arg_ainfo.multiplevalue = false;
124  arg_ainfo.defaultstatus = cgiarginfo::weak;
125  arg_ainfo.argdefault = g_EmptyText;   
126  arg_ainfo.savedarginfo = cgiarginfo::must;
127  argsinfo.addarginfo (NULL, arg_ainfo);
128
129  //the file size
130  arg_ainfo.shortname = "di1userfilesize";
131  arg_ainfo.longname = "depositor specific";
132  arg_ainfo.multiplechar = true;
133  arg_ainfo.multiplevalue = false;
134  arg_ainfo.defaultstatus = cgiarginfo::weak;
135  arg_ainfo.argdefault = "0";   
136  arg_ainfo.savedarginfo = cgiarginfo::must;
137  argsinfo.addarginfo (NULL, arg_ainfo);
138
139 //the file timestamp
140  arg_ainfo.shortname = "di1timestamp";
141  arg_ainfo.longname = "depositor specific";
142  arg_ainfo.multiplechar = true;
143  arg_ainfo.multiplevalue = false;
144  arg_ainfo.defaultstatus = cgiarginfo::weak;
145  arg_ainfo.argdefault = "0";   
146  arg_ainfo.savedarginfo = cgiarginfo::must;
147  argsinfo.addarginfo (NULL, arg_ainfo);
148
149  // temporary directory name for this collector
150  // session
151  arg_ainfo.shortname = "di1tmp";
152  arg_ainfo.longname = "depositor specific";
153  arg_ainfo.multiplechar = true;
154  arg_ainfo.multiplevalue = false;
155  arg_ainfo.defaultstatus = cgiarginfo::weak;
156  arg_ainfo.argdefault = g_EmptyText;
157  arg_ainfo.savedarginfo = cgiarginfo::must;
158  argsinfo.addarginfo (NULL, arg_ainfo);
159
160  arg_ainfo.shortname = "di1dirname";
161  arg_ainfo.longname = "depositor specific";
162  arg_ainfo.multiplechar = true;
163  arg_ainfo.multiplevalue = false;
164  arg_ainfo.defaultstatus = cgiarginfo::weak;
165  arg_ainfo.argdefault = g_EmptyText;
166  arg_ainfo.savedarginfo = cgiarginfo::must;
167  argsinfo.addarginfo (NULL, arg_ainfo);
168
169  arg_ainfo.shortname = "di1contactemail";
170  arg_ainfo.longname = "depositor specific";
171  arg_ainfo.multiplechar = true;
172  arg_ainfo.multiplevalue = false;
173  arg_ainfo.defaultstatus = cgiarginfo::weak;
174  arg_ainfo.argdefault = g_EmptyText;
175  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
176  argsinfo.addarginfo (NULL, arg_ainfo);
177
178
179  // wizard uses this to see if we are working with an existing collection:
180  // set the default to 1
181  arg_ainfo.shortname = "di1esrce";
182  arg_ainfo.longname = "depositor specific";
183  arg_ainfo.multiplechar = false;
184  arg_ainfo.multiplevalue = false;
185  arg_ainfo.defaultstatus = cgiarginfo::weak;
186  arg_ainfo.argdefault = "1";
187  arg_ainfo.savedarginfo = cgiarginfo::must;
188  argsinfo.addarginfo (NULL, arg_ainfo);
189
190  // collection specific depositing. We are bypassing the select page. Need to do the clearing that happens at select. And depositor link at top right should be back to local deposit
191  arg_ainfo.shortname = "di1local";
192  arg_ainfo.longname = "depositor specific";
193  arg_ainfo.multiplechar = false;
194  arg_ainfo.multiplevalue = false;
195  arg_ainfo.defaultstatus = cgiarginfo::weak;
196  arg_ainfo.argdefault = "0";
197  arg_ainfo.savedarginfo = cgiarginfo::must;
198  argsinfo.addarginfo (NULL, arg_ainfo);
199 
200  // shall we cache the metadata values? Made this an arg so we can turn it off if wanted
201  arg_ainfo.shortname = "di1cache";
202  arg_ainfo.longname = "depositor specific";
203  arg_ainfo.multiplechar = false;
204  arg_ainfo.multiplevalue = false;
205  arg_ainfo.defaultstatus = cgiarginfo::weak;
206  arg_ainfo.argdefault = "1";
207  arg_ainfo.savedarginfo = cgiarginfo::must;
208  argsinfo.addarginfo (NULL, arg_ainfo);
209
210}
211
212depositoraction::~depositoraction () {
213}
214
215
216bool depositoraction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, recptprotolistclass * protos, ostream &logout) {
217
218  wizardaction::check_cgiargs(argsinfo,args,protos,logout);
219
220  text_t &current_page = args["p"];
221
222  // note that the "bildstatus" and "bildframe1" pages don't actually do anything
223  // functional so we don't need to worry about authenticating them (it's the
224  // underlying "bild" page that does the building (and creates the frameset))
225  // This helps us overcome a bit of a problem we have with multiple pages trying
226  // to read from the key.gdb database at the same time.
227
228  //right now, anyone can do anything until it's time to build
229
230  // Used to check current page was "select", now changed to "step1".
231  // (i.e. one page later).  This is needed so users that belong to
232  // specific collection-edit groups (e.g. demo-collection-editor) are able
233  // to log in successfully.
234  //   
235
236  if (current_page == "step1") {
237    //authenticate the user if authentication is available
238    args["uan"] = 1;
239    args["ug"] = "all-collections-editor," + args["c"] + "-collection-editor";
240  }
241
242
243  //Check to see if a file was specified
244  //if so, upload it and set the di1userfile, di1userfilesize, and
245  //di1timestamp args.
246  //every time a new file is specified, a new timestamped folder is
247  //created. 
248
249  // This doesn't create a problem but is inefficient (wasted space)
250  // Consider recoding at some point in the future.
251
252  fileupload_t *fileupload = args.getargfile("di1userfileinfo");
253
254  if (fileupload != NULL) {
255
256    if (!(*fileupload).tmp_name.empty() && file_exists((*fileupload).tmp_name)) {
257      // create the timestamp
258      time_t timestamp = time(NULL);
259      text_t timestamp_str(timestamp);
260
261      args["di1timestamp"] = timestamp_str;
262
263      // set filename and size from the fileupload struct
264      args["di1userfilesize"] = (*fileupload).size;
265      args["di1userfile"] = (*fileupload).name;
266      // copy the file into its temporary location
267      text_t tmpdir = filename_cat(gsdlhome,"tmp",args["di1tmp"],timestamp_str);
268      bool tflag = mk_dir(tmpdir);
269      text_t tmpfile = filename_cat(tmpdir,(*fileupload).name);
270      if (!file_copy((*fileupload).tmp_name, tmpfile)) {
271    cerr << "Depositor error: cannot save uploaded fileto  "<<tmpfile<<endl;
272      } else {
273    cerr << "Depositor: saved uploaded file to "<<tmpfile<<endl;
274      }
275    }
276  }
277 
278  if (current_page == "select" || (current_page == "step1" && args["di1local"] == "1")) { 
279 
280    //make sure the last page arg is re-set to zero
281    //since a new collection is being chosen
282    args["di1lastpage"] = "0";
283
284    // assign (and create) a temporary directory This will create a new
285    // tbuild directory every time the user goes back to select a new
286    // collection.  It causes no problems except wasted space.  Should be
287    // addressed in the future
288    if (assign_tmpname (args, logout)==false) {
289      // there was an error creating the tmp dir
290      message="tmpfail";
291      return true; // true because we could still parse the arguments
292    }
293
294    // clean up any old builds left laying about in the tmp directory
295    // (note that it's possible this could take some time if there's a huge
296    // partially built collecton laying about so we'll make it an asynchronous
297    // system call)
298    gsdl_system ("perl -S cleantmp.pl", false, logout);
299
300  }
301
302  if (current_page == "bildstatus" || current_page == "bildcancel") {
303    // if .final file exists then build has finished
304    text_t fbld = filename_cat (gsdlhome, "tmp", args[macro_prefix + "tmp"], args[macro_prefix + "dirname"] + ".bld.final");
305    if (file_exists (fbld)) {
306      char *fbldc = fbld.getcstr();
307      ifstream fbld_in (fbldc);
308      if (fbld_in) {
309    failcode = fbld_in.get();
310    fbld_in.close();
311    if (failcode == '0') {
312      // success - we need to create and configure a collection server for the
313      // newly built collection (for fastcgi and local library where
314      // initialization isn't going to be redone when the user clicks the
315      // "view your new collection" button
316      create_colserver (args[macro_prefix + "dirname"], logout);
317      current_page = "bilddone";
318    }
319    else current_page = "bildfail";
320      } else {
321    // assume build failed (we shouldn't get here though ... right?)
322    current_page = "bildfail";
323      }
324      delete []fbldc;
325    }
326  }
327
328  //is it a step page?
329  text_t::const_iterator here = current_page.begin();
330  text_t::const_iterator end = current_page.end();
331  text_t stepstring = substr(here,here+4);
332
333  //if so, increment the step count
334  //this should not be going up more than one at a time.
335  if(stepstring == "step") {
336    text_t currpage_textt = substr(here+4,here+5);
337    int currpage = currpage_textt.getint();
338
339    text_t lastpage_textt = args["di1lastpage"];
340    int lastpage = lastpage_textt.getint();
341    if (currpage > lastpage) {
342      lastpage++;
343      text_t lastpage_textt(lastpage);
344      args["di1lastpage"] = lastpage_textt;     
345    }
346
347    // create cached metadata values
348    if (args["di1cache"] == "1") {
349    text_t cached_metadata_values = "";
350    cgiargsclass::const_iterator args_here = args.begin();
351    cgiargsclass::const_iterator args_end = args.end();
352    while (args_here != args_end) {
353      text_t args_name = (*args_here).first;
354      int prefix_len = macro_prefix.size();
355      int args_name_len = args_name.size();
356
357      if(args_name_len >= prefix_len+3) { // Only now can we substring args_name by prefix_len+3
358          text_t args_prefix;
359          if(args_name_len == prefix_len+3) {
360              args_prefix = args_name;
361          } else { // >, so substring
362              args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len+3);
363          }
364
365          if (args_prefix == (macro_prefix+"md.")) {     
366            text_t args_val = args[args_name];
367            cerr << "caching md arg "<<args_val<<endl;
368            decode_cgi_arg(args_val);
369            text_t args_suffix = substr(args_name.begin()+prefix_len+3,args_name.end());
370
371            text_tarray mdvalues;
372            splitchar (args_val.begin(), args_val.end(), ',', mdvalues);
373            int numvalues = mdvalues.size();
374
375            for (int i = 0; i < numvalues; ++i) {
376              if (!mdvalues[i].empty()) {
377               
378                //decode_cgi_arg(mdvalues[i]);
379               
380                if (cached_metadata_values == "") {
381                  cached_metadata_values = "var CachedMDValues = new Array(\\{";
382                } else {
383                  cached_metadata_values += ",";
384                }
385
386                cached_metadata_values += "\"" + args_name + "\":\"" + encodeForJavascript(args_val) + "\"";
387              }
388            }   
389          }
390      }
391      ++args_here;
392    }
393
394    if (cached_metadata_values != "") {
395      cached_metadata_values += "\\});";
396      args["cachedMDValues"] = cached_metadata_values;
397    }
398    }
399  }
400  return true;
401
402
403
404void depositoraction::define_internal_macros (displayclass &disp, cgiargsclass &args,
405                          recptprotolistclass *protos, ostream &logout) {
406
407  // define_internal_macros sets some/all of the following macros (depending
408  // on cgiargs):
409  //
410  // _pagescriptextra_
411  // _header_
412  // _depositorbar_
413  // _textfailmsg_
414  // _di1userfile_
415  // _di1userfilesize_
416
417  text_t &depositor_page = args["p"];
418 
419  // set _pagescriptextra_ macro to _cpagescriptextra_
420  disp.setmacro ("pagescriptextra", "depositor", "_" + depositor_page + "scriptextra_");
421
422  if (depositor_page == "bildstatus" || depositor_page == "bilddone" ||
423      depositor_page == "bildfail" || depositor_page == "bildframe1" ||
424      depositor_page == "select") {
425    disp.setmacro ("header", "depositor", "_" + depositor_page + "header_");
426  }
427
428  if (depositor_page == "bildstatus") {
429    set_statusline (disp, args, logout);
430  }
431
432  if (depositor_page == "select") {
433    set_fullnamemenu (disp, args, protos, logout);
434  }
435
436  //how many pages in collection?
437  //we need a _depositorbar_ for each
438
439  text_t numsteps_str;
440  disp.expandstring("depositor", "_numsteps_", numsteps_str);
441  int numsteps = numsteps_str.getint();
442   
443  //is the page a step page?
444
445  text_t::const_iterator here = depositor_page.begin();
446  text_t::const_iterator end = depositor_page.end();
447  text_t stepstring = substr(here,here+4);
448
449  if((stepstring) == "step" || (depositor_page == "depositonly") ) {
450    disp.setmacro("di1userfile","depositor",args["di1userfile"]);
451    disp.setmacro("di1userfilesize","depositor",args["di1userfilesize"]);
452  }
453
454  //set up the depositor bar
455  text_t depositorbar = "<table class=wizardbar border=0 cellspacing=4 cellpadding=0><tr>\n";
456
457  if(stepstring == "step") {   
458    // check configured metadata elements
459    if (args["metadataconf"] == "var DepositorMDFields = new Array();" || args["metadataconf"] == "") {
460
461      text_t cfgfile_name = filename_cat (collecthome, args[macro_prefix + "dirname"], "etc", "collect.cfg");
462      text_t key;
463      text_t params;
464      text_tarray cfgline;
465      char *cstr = cfgfile_name.getcstr();
466      ifstream confin (cstr);
467      delete []cstr;
468
469      text_t metadata_str;
470      text_t default_metadata_str;
471      if (confin) {
472    while (read_cfg_line(confin, cfgline) >= 0) {
473      if (cfgline.size () >= 3) {
474        key = cfgline[0];
475        if (key == "collectionmeta") {
476          if (cfgline[1] == "depositormetadata") {
477        if (cfgline.size() == 3) {
478          // no lang arg
479          default_metadata_str = cfgline[2];
480        } else {
481          params = cfgline[2];
482          text_t::const_iterator first=params.begin()+1;
483          text_t::const_iterator last=params.end()-1;
484          params=substr(first, last);
485          // get the lang out of params
486          paramhashtype params_hash;
487          splitparams(params, params_hash);
488     
489          text_t lang = params_hash["l"];
490          if (lang == args["l"]) {
491            metadata_str = cfgline[3];
492            break;
493          }
494          if (default_metadata_str.empty()) {
495            default_metadata_str = cfgline[3];
496          }
497        }
498          }
499        }
500      }
501    }
502      }
503      confin.close ();
504      // use default value if there was one
505     if (metadata_str.empty()) {
506    metadata_str = default_metadata_str;
507      }
508     // if there still isn't one set, use this default setting
509      if (metadata_str == "") {
510    metadata_str = "{\"name\":\"dc.Title\",\"label\":\"Title\",\"tooltip\":\"dc.Title: A name given to the resource.\",\"type\":\"text\"}, {\"name\":\"dc.Creator\",\"label\":\"Creator\",\"tooltip\":\"dc.Creator: An entity primarily responsible for making the content of the resource.\",\"type\":\"text\"}, {\"name\":\"dc.Description\",\"label\":\"Description\",\"tooltip\":\"dc.Description: An account of the content of the resource.\",\"type\":\"textarea\"}";
511      }
512      args["metadataconf"] = "var DepositorMDFields = new Array("+metadata_str+");";
513 
514    }
515
516    here = depositor_page.begin();
517    text_t stepnums = substr(here+4,here+5);
518    int stepnum = stepnums.getint();
519
520    text_t lastpage_textt = args["di1lastpage"];
521    int lastpage = lastpage_textt.getint();
522   
523    // again, begin with the select bar...
524    //the first button - selecting a collection
525    for(int i = 1; i <= numsteps; i++) {
526      text_t numstr(i);
527      if(i <= lastpage && i == stepnum) {
528    depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, false);
529      } else if (i <= lastpage) {
530    depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, true);
531      } else if((i == lastpage+1)){
532    depositorbar += get_button (args,depositor_page, "green", "step"+numstr, true);       
533      } else {
534    depositorbar += get_button (args,depositor_page, "grey", "step"+numstr, false);       
535      }
536      depositorbar += "<td>_icongreyarrow_</td>\n";
537
538    }   
539
540    //the build and preview pages are always last
541    if(lastpage == numsteps) {
542      depositorbar += get_button (args,depositor_page, "green", "laststep", true);
543    } else {
544      depositorbar += get_button (args,depositor_page, "grey", "laststep", false);
545    }
546
547    text_t laststep_textt;
548    disp.expandstring("depositor", "_laststep_", laststep_textt);
549    if(laststep_textt == "bild") {
550      depositorbar += "<td>_icongreyarrow_</td>\n";
551      depositorbar += get_button (args,depositor_page, "grey", "view", false);
552    }
553    depositorbar += "</tr><tr>";
554
555    for(int j = 1; j <= 2*(stepnum-1); j++) {
556      depositorbar += "<td></td>";
557    }
558    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";   
559
560    depositorbar += "</tr></table>\n";
561
562    // set the javascript so that the metadata form can read the existing values
563    if (args["cachedMDValues"] != "") {
564      disp.setmacro("cachedmetadatavalues", "depositor", args["cachedMDValues"]);
565    }
566    if (args["metadataconf"] != "") {
567      disp.setmacro("metadataconf", "depositor", args["metadataconf"]);
568    }   
569  }
570 
571  if ((depositor_page == "bildcancel") || (depositor_page == "bildfail")) {
572 
573    for(int i = 1; i <= numsteps; i++) {
574
575      text_t numstr(i);
576      depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, true);       
577      depositorbar += "<td>_icongreyarrow_</td>\n";
578
579    }
580
581    //the build and preview pages are always last
582    depositorbar += get_button (args,depositor_page, "green", "laststep", true);
583    depositorbar += "<td>_icongreyarrow_</td>\n";
584    depositorbar += get_button (args,depositor_page, "grey", "view", false);
585
586    depositorbar += "</tr><tr>";
587
588    for(int j = 1; j <= 2*numsteps; j++) {
589      depositorbar += "<td></td>";
590    }
591    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";   
592
593    depositorbar += "</tr></table>\n";
594
595  }
596
597  if(depositor_page == "bilddone"){
598   
599    for(int i = 1; i <= numsteps; i++) {
600
601      text_t numstr(i);
602      depositorbar += get_button (args, depositor_page, "grey", "step"+numstr, false);       
603      depositorbar += "<td>_icongreyarrow_</td>\n";
604
605    }
606
607    //the build and preview pages are always last
608    depositorbar += get_button (args,depositor_page, "yellow", "laststep", false);
609    depositorbar += "<td>_icongreyarrow_</td>\n";
610    depositorbar += get_button (args,depositor_page, "green", "view", true);
611
612    depositorbar += "</tr><tr>";
613
614    for(int j = 1; j <= 2*numsteps; j++) {
615      depositorbar += "<td></td>";
616    }
617    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";   
618
619    depositorbar += "</tr></table>\n";
620  }
621  disp.setmacro ("depositorbar", "depositor", depositorbar);
622
623  if (depositor_page == "bildfail") {
624 
625    text_t textfailmsg = "_textfailmsg";
626    textfailmsg.push_back(failcode);
627    textfailmsg.push_back('_');
628    disp.setmacro("textfailmsg", "depositor", textfailmsg);
629
630    text_t bldlog = filename_cat(gsdlhome, "tmp", args["di1tmp"], args["di1dirname"] + ".bld");
631    //text_t rawlog = file_tail (bldlog, 6, 0);
632    text_t rawlog;
633    read_file(bldlog, rawlog);
634    // we'll shove in some <br> tags where \n's occur
635    text_t faillog;
636    text_t::const_iterator here = rawlog.begin();
637    text_t::const_iterator end = rawlog.end();
638    while (here != end) {
639      if (*here == '\n') faillog += "<br>";
640      faillog.push_back (*here);
641      ++here;
642    }
643    disp.setmacro ("faillog", "depositor", dm_safe(faillog));
644  }
645}
646
647
648//basic framework
649bool depositoraction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/,
650                 browsermapclass * /*browsers*/, displayclass &disp,
651                 outconvertclass &outconvert, ostream &textout,
652                 ostream &logout) {
653  // make sure the depositor is enabled
654  if (disabled) {
655    textout << outconvert
656        << "<html>\n"
657        << "<head>\n"
658        << "<title>Depositor disabled</title>\n"
659        << "</head>\n"
660        << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
661        << "alink=\"#cc9900\" vlink=\"#666633\">\n"
662        << "<h2>Facility disabled</h2>\n"
663        << "Sorry, the Depositor end-user collecation update facility is currently disabled\n"
664        << "\n</body>\n"
665        << "</html>\n";
666    return true;
667  }
668
669  text_t &depositor_page = args["p"];
670  text_t &collection = args["di1dirname"];
671
672  // make sure we have perl (we won't bother with this check for the
673  // building status pages to avoid slowing things down unneccessarily)
674  if (depositor_page != "bildstatus" && depositor_page != "bildframe1" && !perl_ok(logout)) {
675    textout << outconvert
676        << "<html>\n"
677        << "<head>\n"
678        << "<title>Perl not found</title>\n"
679        << "</head>\n"
680        << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
681        << "alink=\"#cc9900\" vlink=\"#666633\">\n"
682        << "<h2>Perl not found</h2>\n"
683        << "Greenstone could not detect perl on this system. It is therefore not\n"
684        << "possible to build a Greenstone collection, either from the Collector or the \n"
685        << "command-line tools, or to use the Collector for any other task.\n"
686        << "<p>Please refer to the Greenstone Installer's Guide for details on\n"
687        << "installing perl on your system.\n"
688        << "\n</body>\n"
689        << "</html>\n";
690    return true;
691
692  }
693
694  text_t::const_iterator here = depositor_page.begin();
695  text_t::const_iterator end = depositor_page.end();
696  text_t stepstring = substr(here,here+4);
697
698  if ((depositor_page == "select") || (stepstring == "step")) {
699          textout << outconvert << disp << ("_depositor:header_\n")
700          << ("_depositor:" + encodeForHTML(depositor_page) + "content_\n")
701          << ("_depositor:footer_\n");
702     
703  }
704
705  if ((depositor_page == "bild") || (depositor_page == "depositonly")) {
706
707    text_t filename_textt = args["di1userfile"];
708    text_t timestamp_str = args["di1timestamp"];
709    //check to make sure a file was uploaded
710    //if more than one upload occurred, the last one is taken
711    if(filename_textt == "") {
712      textout << outconvert << disp << "<p> no file available</p>\n";
713    } else {
714   
715      text_t col_dirname = filename_cat(collecthome,args[macro_prefix+"dirname"]);
716      text_t import_dirname = filename_cat(col_dirname,"import");
717      if(!directory_exists(import_dirname)) {
718    bool flag = mk_dir(import_dirname);
719    if(!flag) {
720      cerr << "Error: unable to make directory " << import_dirname << endl;
721      return true;
722    }
723      }
724
725      text_t dirname = filename_cat(import_dirname,timestamp_str);
726      bool flag = mk_dir(dirname);
727      if(!flag) {
728    cerr << "Error: unable to make timestamp directory " << dirname << endl;
729    return true;
730      }
731
732      text_t filename_textt = args["di1userfile"];
733      text_t tmpdir = filename_cat(gsdlhome,"tmp",args["di1tmp"],timestamp_str);
734      text_t tmpfile = filename_cat(tmpdir,filename_textt);
735      text_t filename = filename_cat(dirname, filename_textt); 
736      if(!file_copy(tmpfile, filename)) {
737    cerr << "Unable to copy " << tmpfile << " to " << filename << endl;
738      }
739     
740      //write the metadata file
741      write_metadata_file(args, filename_textt, timestamp_str);
742
743      if(depositor_page == "bild"){
744
745    //create a manifest file
746    write_manifest_file(args, filename_textt, timestamp_str);
747   
748    // do the work (download, import, build)
749    gsdl_build (args, logout);
750
751    if (message.empty()) {
752      // bild page is a frameset so we don't want headers and stuff
753      textout << outconvert << disp << ("_depositor:bildcontent_\n");
754    }
755      }
756    }
757  }
758
759  if (message.empty()) {
760
761    if (depositor_page != "bild" && stepstring != "step" && depositor_page != "select") {
762      // output page ("bild" page was already output above)
763      textout << outconvert << disp << ("_depositor:header_\n")
764          << ("_depositor:" + encodeForHTML(depositor_page) + "content_\n")
765          << ("_depositor:footer_\n");
766    }
767  } else {
768    // message was set somewhere (probably an error), output message page
769    textout << outconvert << disp << ("_depositor:header_\n")
770        << ("_depositor:" + message + "content_\n")
771        << ("_depositor:footer_\n");
772    message.clear();
773  }
774 
775  return true;
776
777}
778
779
780//This function creates a metadata.xml file
781void depositoraction::write_metadata_file(cgiargsclass &args, text_t filename_str, text_t& timestamp_str)
782{
783
784    //build metadata file
785    //the front
786    text_t metadata_file = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
787    metadata_file += "<!DOCTYPE DirectoryMetadata SYSTEM \"http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\">\n";
788    metadata_file += "<DirectoryMetadata>\n";
789    metadata_file += "    <FileSet>\n";
790    metadata_file += "        <FileName>";
791
792    // Generate 'regular expression' save version of filename
793    // for now that means escaping any '.' characters
794    // consider generalising as function in gsdltools.h/cpp?
795
796    text_t filename_re;
797    text_t::const_iterator here = filename_str.begin();
798    text_t::const_iterator end = filename_str.end();
799    while (here != end) {
800      if (*here == '.') {
801    filename_re.push_back('\\');
802      }
803
804      filename_re.push_back(*here);
805      ++here;
806    }
807
808    metadata_file += filename_re;
809
810    metadata_file += "</FileName>\n";
811    metadata_file += "        <Description>\n";
812
813   
814    cgiargsclass::const_iterator args_here = args.begin();
815    cgiargsclass::const_iterator args_end = args.end();
816
817    while (args_here != args_end) {
818      text_t args_name = (*args_here).first;
819
820      int prefix_len = macro_prefix.size();
821      int args_name_len = args_name.size();
822
823      if(args_name_len >= prefix_len+3) { // Only now can we substring args_name by prefix_len+3
824          text_t args_prefix;
825          if(args_name_len == prefix_len+3) {
826              args_prefix = args_name;
827          } else { // >, so substring
828              args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len+3);
829          }
830
831          if (args_prefix == (macro_prefix+"md.")) {     
832            text_t args_val = args[args_name];
833            cerr << "args val = "<<args_val<<endl;
834            decode_cgi_arg(args_val);
835            cerr << "decoded" << args_val<<endl;
836            text_t args_suffix = substr(args_name.begin()+prefix_len+3,args_name.end());
837
838            text_tarray mdvalues;
839            splitchar (args_val.begin(), args_val.end(), ',', mdvalues);
840            int numvalues = mdvalues.size();
841            cerr << "numvals = "<<numvalues<<endl;
842            for (int i = 0; i < numvalues; ++i) {
843              if (!mdvalues[i].empty()) {
844                //decode_cgi_arg(mdvalues[i]);
845                metadata_file += "            <Metadata mode=\"accumulate\" name=\"";       
846                metadata_file += args_suffix;
847                metadata_file += "\">";
848                metadata_file += xml_safe(mdvalues[i]);
849                metadata_file += "</Metadata>\n";
850
851              }
852            }
853          }
854      }
855      ++args_here;
856    }
857   
858    //the end of the file
859    metadata_file += "        </Description>\n";
860    metadata_file += "    </FileSet>\n";
861    metadata_file += "</DirectoryMetadata>\n";
862
863    //create metadata.xml file
864    text_t metadata_path = filename_cat(collecthome, args[macro_prefix+"dirname"], "import", timestamp_str, "metadata.xml");
865    text_t my_path = filename_cat(gsdlhome,"tmp", "metadata.xml");
866
867    ofstream metadata(metadata_path.getcstr());
868    ofstream my_tmp(my_path.getcstr());
869
870    if(!metadata.is_open()) {
871      cerr << "Cannot open metadata.xml!" << endl;
872    } else {
873     
874      //write metadata.xml
875      // need to convert to utf8 before writing it out.
876      text_t utf8_meta = to_utf8(metadata_file);
877      metadata.write(utf8_meta.getcstr(), utf8_meta.size());
878      my_tmp.write(utf8_meta.getcstr(), utf8_meta.size());
879    }
880}
881
882//This function creates a manifest.xml file
883void depositoraction::write_manifest_file(cgiargsclass &args, text_t filename,
884                      text_t& timestamp_str)
885{
886
887    //build manifest file
888
889    //the front
890    text_t manifest_file = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
891    manifest_file += "<Manifest>\n";
892    manifest_file += "    <Index>\n";
893    manifest_file += "        <Filename>\n";
894    manifest_file += "          " + timestamp_str + "\n";
895    manifest_file += "        </Filename>\n";
896   
897    //the end of the file
898    manifest_file += "    </Index>\n";
899    manifest_file += "</Manifest>\n";
900
901    //create manifest.xml file
902    text_t manifest_path = filename_cat(collecthome, args[macro_prefix+"dirname"], "manifest.xml");
903
904    char* manifest_cstr = manifest_path.getcstr();
905
906    ofstream manifest(manifest_cstr);
907
908    if(!manifest.is_open()) {
909      cerr << "Cannot open" << manifest_cstr << endl;
910    } else {
911
912      //write manifest.xml
913      char *manifest_file_cstr = manifest_file.getcstr();
914      manifest.write(manifest_file_cstr, manifest_file.size());
915      delete [] manifest_file_cstr;
916    }
917
918    delete [] manifest_cstr;
919}
920
921
922
923text_t depositoraction::get_button(cgiargsclass &args, const text_t &thispage,
924                   const text_t &color,
925                   const text_t &type, bool enabled)
926{
927
928  text_t::const_iterator here = type.begin();
929  text_t::const_iterator end = type.end();
930  text_t stepstring = substr(here,here+4);
931  if ((color != "green" && color != "grey" && color != "yellow") ||
932      (type != "select" && type != "laststep" && stepstring != "step" && type != "view"))
933    return g_EmptyText;
934
935  text_t href = "_http"+type+"_";
936  text_t target = "";
937
938  here = thispage.begin();
939  stepstring = substr(here,here+4); 
940  if (thispage == "bildcancel" || thispage == "bildfail" || thispage == "select"|| stepstring == "step") {
941    // call the check submit macro instead of linking directly to the page
942
943    if(type == "laststep") {
944      href="\"javascript:check_submit('_"+type+"_');\"";
945    } else {
946      href="\"javascript:check_submit('"+type+"');\"";
947    }
948
949  } else if (type == "view") {
950   //target = " target=_top";
951    target = " target=_blank";
952  }
953
954  text_t tdclass = "wizardbar"+color;
955  if (enabled) {
956    // link to the appropriate page
957    return "<td class="+tdclass+"><a href="+href+target+">_text"+type+"_</a></td>";
958  }
959  else {
960    // just display the text
961    return "<td class="+tdclass+">_text"+type+"_</td>";
962  }
963}
964
965
966#endif //GSDL_USE_DEPOSITOR_ACTION
Note: See TracBrowser for help on using the browser.