source: trunk/gsdl/src/recpt/depositoraction.cpp@ 12576

Last change on this file since 12576 was 12576, checked in by kjdon, 18 years ago

we now use a specialised header on the select page too. Wizardaction sets up fullnamemenu to have selected the previous collection. Since we have no button on the select page, just going forward based on the menu changing, this means that we can't select the same collection very easily. So now the header macro calls initialize on page load, and this sets the menu back to no collection selected

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