root/gsdl/trunk/src/recpt/depositoraction.cpp @ 16310

Revision 16310, 28.2 KB (checked in by davidb, 12 years ago)

Introduction of 'collecthome' which parallels 'gsdlhome' to allow the toplevel collect folder to be outside of the gsdlhome area

  • 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.db 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  return true;
366
367
368
369void depositoraction::define_internal_macros (displayclass &disp, cgiargsclass &args,
370                          recptprotolistclass *protos, ostream &logout) {
371
372  // define_internal_macros sets some/all of the following macros (depending
373  // on cgiargs):
374  //
375  // _pagescriptextra_
376  // _header_
377  // _depositorbar_
378  // _textfailmsg_
379  // _di1userfile_
380  // _di1userfilesize_
381
382  text_t &depositor_page = args["p"];
383 
384  // set _pagescriptextra_ macro to _cpagescriptextra_
385  disp.setmacro ("pagescriptextra", "depositor", "_" + depositor_page + "scriptextra_");
386
387  if (depositor_page == "bildstatus" || depositor_page == "bilddone" ||
388      depositor_page == "bildfail" || depositor_page == "bildframe1" ||
389      depositor_page == "select") {
390    disp.setmacro ("header", "depositor", "_" + depositor_page + "header_");
391  }
392
393  if (depositor_page == "bildstatus") {
394    set_statusline (disp, args, logout);
395  }
396
397  if (depositor_page == "select") {
398    set_fullnamemenu (disp, args, protos, logout);
399  }
400
401  //how many pages in collection?
402  //we need a _depositorbar_ for each
403
404  text_t numsteps_str;
405  disp.expandstring("depositor", "_numsteps_", numsteps_str);
406  int numsteps = numsteps_str.getint();
407   
408  //is the page a step page?
409
410  text_t::const_iterator here = depositor_page.begin();
411  text_t::const_iterator end = depositor_page.end();
412  text_t stepstring = substr(here,here+4);
413
414  if((stepstring) == "step" || (depositor_page == "depositonly") ) {
415    disp.setmacro("di1userfile","depositor",args["di1userfile"]);
416    disp.setmacro("di1userfilesize","depositor",args["di1userfilesize"]);
417  }
418
419  //set up the depositor bar
420  text_t depositorbar = "<table class=wizardbar border=0 cellspacing=4 cellpadding=0><tr>\n";
421
422  if(stepstring == "step") {
423
424    here = depositor_page.begin();
425    text_t stepnums = substr(here+4,here+5);
426    int stepnum = stepnums.getint();
427
428    text_t lastpage_textt = args["di1lastpage"];
429    int lastpage = lastpage_textt.getint();
430   
431    // again, begin with the select bar...
432    //the first button - selecting a collection
433    for(int i = 1; i <= numsteps; i++) {
434      text_t numstr(i);
435      if(i <= lastpage && i == stepnum) {
436    depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, false);
437      } else if (i <= lastpage) {
438    depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, true);
439      } else if((i == lastpage+1)){
440    depositorbar += get_button (args,depositor_page, "green", "step"+numstr, true);       
441      } else {
442    depositorbar += get_button (args,depositor_page, "grey", "step"+numstr, false);       
443      }
444      depositorbar += "<td>_icongreyarrow_</td>\n";
445
446    }
447
448    //the build and preview pages are always last
449    if(lastpage == numsteps) {
450      depositorbar += get_button (args,depositor_page, "green", "laststep", true);
451    } else {
452      depositorbar += get_button (args,depositor_page, "grey", "laststep", false);
453    }
454
455    text_t laststep_textt;
456    disp.expandstring("depositor", "_laststep_", laststep_textt);
457    if(laststep_textt == "bild") {
458      depositorbar += "<td>_icongreyarrow_</td>\n";
459      depositorbar += get_button (args,depositor_page, "grey", "view", false);
460    }
461    depositorbar += "</tr><tr>";
462
463    for(int j = 1; j <= 2*(stepnum-1); j++) {
464      depositorbar += "<td></td>";
465    }
466    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";   
467
468    depositorbar += "</tr></table>\n";
469   
470  }
471 
472  if ((depositor_page == "bildcancel") || (depositor_page == "bildfail")) {
473 
474    for(int i = 1; i <= numsteps; i++) {
475
476      text_t numstr(i);
477      depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, true);       
478      depositorbar += "<td>_icongreyarrow_</td>\n";
479
480    }
481
482    //the build and preview pages are always last
483    depositorbar += get_button (args,depositor_page, "green", "laststep", true);
484    depositorbar += "<td>_icongreyarrow_</td>\n";
485    depositorbar += get_button (args,depositor_page, "grey", "view", false);
486
487    depositorbar += "</tr><tr>";
488
489    for(int j = 1; j <= 2*numsteps; j++) {
490      depositorbar += "<td></td>";
491    }
492    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";   
493
494    depositorbar += "</tr></table>\n";
495
496  }
497
498  if(depositor_page == "bilddone"){
499   
500    for(int i = 1; i <= numsteps; i++) {
501
502      text_t numstr(i);
503      depositorbar += get_button (args, depositor_page, "grey", "step"+numstr, false);       
504      depositorbar += "<td>_icongreyarrow_</td>\n";
505
506    }
507
508    //the build and preview pages are always last
509    depositorbar += get_button (args,depositor_page, "yellow", "laststep", false);
510    depositorbar += "<td>_icongreyarrow_</td>\n";
511    depositorbar += get_button (args,depositor_page, "green", "view", true);
512
513    depositorbar += "</tr><tr>";
514
515    for(int j = 1; j <= 2*numsteps; j++) {
516      depositorbar += "<td></td>";
517    }
518    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";   
519
520    depositorbar += "</tr></table>\n";
521  }
522  disp.setmacro ("depositorbar", "depositor", depositorbar);
523
524  if (depositor_page == "bildfail") {
525 
526    text_t textfailmsg = "_textfailmsg";
527    textfailmsg.push_back(failcode);
528    textfailmsg.push_back('_');
529    disp.setmacro("textfailmsg", "depositor", textfailmsg);
530
531    text_t bldlog = filename_cat(gsdlhome, "tmp", args["di1tmp"], args["di1dirname"] + ".bld");
532    text_t rawlog = file_tail (bldlog, 6, 0);
533    // we'll shove in some <br> tags where \n's occur
534    text_t faillog;
535    text_t::const_iterator here = rawlog.begin();
536    text_t::const_iterator end = rawlog.end();
537    while (here != end) {
538      if (*here == '\n') faillog += "<br>";
539      faillog.push_back (*here);
540      ++here;
541    }
542    disp.setmacro ("faillog", "depositor", dm_safe(faillog));
543  }
544}
545
546
547//basic framework
548bool depositoraction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/,
549                 browsermapclass * /*browsers*/, displayclass &disp,
550                 outconvertclass &outconvert, ostream &textout,
551                 ostream &logout) {
552  // make sure the depositor is enabled
553  if (disabled) {
554    textout << outconvert
555        << "<html>\n"
556        << "<head>\n"
557        << "<title>Depositor disabled</title>\n"
558        << "</head>\n"
559        << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
560        << "alink=\"#cc9900\" vlink=\"#666633\">\n"
561        << "<h2>Facility disabled</h2>\n"
562        << "Sorry, the Depositor end-user collecation update facility is currently disabled\n"
563        << "\n</body>\n"
564        << "</html>\n";
565    return true;
566  }
567
568  text_t &depositor_page = args["p"];
569  text_t &collection = args["di1dirname"];
570
571  // make sure we have perl (we won't bother with this check for the
572  // building status pages to avoid slowing things down unneccessarily)
573  if (depositor_page != "bildstatus" && depositor_page != "bildframe1" && !perl_ok(logout)) {
574    textout << outconvert
575        << "<html>\n"
576        << "<head>\n"
577        << "<title>Perl not found</title>\n"
578        << "</head>\n"
579        << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
580        << "alink=\"#cc9900\" vlink=\"#666633\">\n"
581        << "<h2>Perl not found</h2>\n"
582        << "Greenstone could not detect perl on this system. It is therefore not\n"
583        << "possible to build a Greenstone collection, either from the Collector or the \n"
584        << "command-line tools, or to use the Collector for any other task.\n"
585        << "<p>Please refer to the Greenstone Installer's Guide for details on\n"
586        << "installing perl on your system.\n"
587        << "\n</body>\n"
588        << "</html>\n";
589    return true;
590
591  }
592
593  text_t::const_iterator here = depositor_page.begin();
594  text_t::const_iterator end = depositor_page.end();
595  text_t stepstring = substr(here,here+4);
596
597  if ((depositor_page == "select") || (stepstring == "step")) {
598          textout << outconvert << disp << ("_depositor:header_\n")
599          << ("_depositor:" + depositor_page + "content_\n")
600          << ("_depositor:footer_\n");
601     
602  }
603
604  if ((depositor_page == "bild") || (depositor_page == "depositoronly")) {
605
606    text_t filename_textt = args["di1userfile"];
607    text_t timestamp_str = args["di1timestamp"];
608    //check to make sure a file was uploaded
609    //if more than one upload occurred, the last one is taken
610    if(filename_textt == "") {
611      textout << outconvert << disp << "<p> no file available</p>\n";
612    } else {
613   
614      text_t col_dirname = filename_cat(collecthome,args[macro_prefix+"dirname"]);
615      text_t import_dirname = filename_cat(col_dirname,"import");
616      if(!directory_exists(import_dirname)) {
617    bool flag = mk_dir(import_dirname);
618    if(!flag) {
619      cerr << "Error: unable to make directory " << import_dirname << endl;
620      return true;
621    }
622      }
623
624      text_t dirname = filename_cat(import_dirname,timestamp_str);
625      bool flag = mk_dir(dirname);
626      if(!flag) {
627    cerr << "Error: unable to make timestamp directory " << dirname << endl;
628    return true;
629      }
630
631      text_t filename_textt = args["di1userfile"];
632      text_t tmpdir = filename_cat(gsdlhome,"tmp",args["di1tmp"],timestamp_str);
633      text_t tmpfile = filename_cat(tmpdir,filename_textt);
634      text_t filename = filename_cat(dirname, filename_textt); 
635      if(!file_copy(tmpfile, filename)) {
636    cerr << "Unable to copy " << tmpfile << " to " << filename << endl;
637      }
638     
639      //write the metadata file
640      write_metadata_file(args, filename_textt, timestamp_str);
641
642      if(depositor_page == "bild"){
643
644    //create a manifest file
645    write_manifest_file(args, filename_textt, timestamp_str);
646   
647    // do the work (download, import, build)
648    gsdl_build (args, logout);
649
650    if (message.empty()) {
651      // bild page is a frameset so we don't want headers and stuff
652      textout << outconvert << disp << ("_depositor:bildcontent_\n");
653    }
654      }
655    }
656  }
657
658  if (message.empty()) {
659
660    if (depositor_page != "bild" && stepstring != "step" && depositor_page != "select") {
661      // output page ("bild" page was already output above)
662      textout << outconvert << disp << ("_depositor:header_\n")
663          << ("_depositor:" + depositor_page + "content_\n")
664          << ("_depositor:footer_\n");
665    }
666  } else {
667    // message was set somewhere (probably an error), output message page
668    textout << outconvert << disp << ("_depositor:header_\n")
669        << ("_depositor:" + message + "content_\n")
670        << ("_depositor:footer_\n");
671    message.clear();
672  }
673 
674  return true;
675
676}
677
678
679//This function creates a metadata.xml file
680void depositoraction::write_metadata_file(cgiargsclass &args, text_t filename_str, text_t& timestamp_str)
681{
682
683    //build metadata file
684    //the front
685    text_t metadata_file = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
686    metadata_file += "<!DOCTYPE DirectoryMetadata SYSTEM \"http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\">\n";
687    metadata_file += "<DirectoryMetadata>\n";
688    metadata_file += "    <FileSet>\n";
689    metadata_file += "        <FileName>";
690
691    // Generate 'regular expression' save version of filename
692    // for now that means escaping any '.' characters
693    // consider generalising as function in gsdltools.h/cpp?
694
695    text_t filename_re;
696    text_t::const_iterator here = filename_str.begin();
697    text_t::const_iterator end = filename_str.end();
698    while (here != end) {
699      if (*here == '.') {
700    filename_re.push_back('\\');
701      }
702
703      filename_re.push_back(*here);
704      ++here;
705    }
706
707    metadata_file += filename_re;
708
709    metadata_file += "</FileName>\n";
710    metadata_file += "        <Description>\n";
711
712
713    cgiargsclass::const_iterator args_here = args.begin();
714    cgiargsclass::const_iterator args_end = args.end();
715
716    while (args_here != args_end) {
717      text_t args_name = (*args_here).first;
718
719      int prefix_len = macro_prefix.size();
720     
721      text_t args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len+3);
722     
723      if (args_prefix == (macro_prefix+"md.")) {     
724        text_t args_val = args[args_name];
725
726    text_t args_suffix = substr(args_name.begin()+prefix_len+3,args_name.end());
727
728    text_tarray mdvalues;
729    splitchar (args_val.begin(), args_val.end(), ',', mdvalues);
730    int numvalues = mdvalues.size();
731
732    for (int i = 0; i < numvalues; ++i) {
733      if (!mdvalues[i].empty()) {
734
735        decode_cgi_arg(mdvalues[i]);
736
737        metadata_file += "            <Metadata mode=\"accumulate\" name=\"";
738        metadata_file += args_suffix;
739        metadata_file += "\">";
740        metadata_file += mdvalues[i];
741        metadata_file += "</Metadata>\n";
742
743      }
744    }
745
746      }
747
748
749      ++args_here;
750    }
751   
752    //the end of the file
753    metadata_file += "        </Description>\n";
754    metadata_file += "    </FileSet>\n";
755    metadata_file += "</DirectoryMetadata>\n";
756
757    //create metadata.xml file
758    text_t metadata_path = filename_cat(collecthome, args[macro_prefix+"dirname"], "import", timestamp_str, "metadata.xml");
759    text_t my_path = filename_cat(gsdlhome,"tmp", "metadata.xml");
760
761    ofstream metadata(metadata_path.getcstr());
762    ofstream my_tmp(my_path.getcstr());
763
764    if(!metadata.is_open()) {
765      cerr << "Cannot open metadata.xml!" << endl;
766    } else {
767
768      //write metadata.xml
769      metadata.write(metadata_file.getcstr(), metadata_file.size());
770      my_tmp.write(metadata_file.getcstr(), metadata_file.size());
771    }
772}
773
774//This function creates a manifest.xml file
775void depositoraction::write_manifest_file(cgiargsclass &args, text_t filename,
776                      text_t& timestamp_str)
777{
778
779    //build manifest file
780
781    //the front
782    text_t manifest_file = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
783    manifest_file += "<Manifest>\n";
784    manifest_file += "    <Index>\n";
785    manifest_file += "        <Filename>\n";
786    manifest_file += "          " + timestamp_str + "\n";
787    manifest_file += "        </Filename>\n";
788   
789    //the end of the file
790    manifest_file += "    </Index>\n";
791    manifest_file += "</Manifest>\n";
792
793    //create manifest.xml file
794    text_t manifest_path = filename_cat(collecthome, args[macro_prefix+"dirname"], "manifest.xml");
795
796    char* manifest_cstr = manifest_path.getcstr();
797
798    ofstream manifest(manifest_cstr);
799
800    if(!manifest.is_open()) {
801      cerr << "Cannot open" << manifest_cstr << endl;
802    } else {
803
804      //write manifest.xml
805      char *manifest_file_cstr = manifest_file.getcstr();
806      manifest.write(manifest_file_cstr, manifest_file.size());
807      delete [] manifest_file_cstr;
808    }
809
810    delete [] manifest_cstr;
811}
812
813
814
815text_t depositoraction::get_button(cgiargsclass &args, const text_t &thispage,
816                   const text_t &color,
817                   const text_t &type, bool enabled)
818{
819
820  text_t::const_iterator here = type.begin();
821  text_t::const_iterator end = type.end();
822  text_t stepstring = substr(here,here+4);
823  if ((color != "green" && color != "grey" && color != "yellow") ||
824      (type != "select" && type != "laststep" && stepstring != "step" && type != "view"))
825    return g_EmptyText;
826
827  text_t href = "_http"+type+"_";
828  text_t target = "";
829
830  here = thispage.begin();
831  stepstring = substr(here,here+4); 
832  if (thispage == "bildcancel" || thispage == "bildfail" || thispage == "select"|| stepstring == "step") {
833    // call the check submit macro instead of linking directly to the page
834
835    if(type == "laststep") {
836      href="\"javascript:check_submit('_"+type+"_');\"";
837    } else {
838      href="\"javascript:check_submit('"+type+"');\"";
839    }
840
841  } else if (type == "view") {
842   //target = " target=_top";
843    target = " target=_blank";
844  }
845
846  text_t tdclass = "wizardbar"+color;
847  if (enabled) {
848    // link to the appropriate page
849    return "<td class="+tdclass+"><a href="+href+target+">_text"+type+"_</a></td>";
850  }
851  else {
852    // just display the text
853    return "<td class="+tdclass+">_text"+type+"_</td>";
854  }
855}
856
857
858#endif //GSDL_USE_DEPOSITOR_ACTION
Note: See TracBrowser for help on using the browser.