root/gsdl/trunk/runtime-src/src/recpt/depositoraction.cpp @ 19062

Revision 19062, 31.2 KB (checked in by kjdon, 10 years ago)

all gdbm files (key, users, history, argdb) now use gdb extension instead of db

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