source: gsdl/trunk/runtime-src/src/recpt/depositoraction.cpp@ 17248

Last change on this file since 17248 was 17248, checked in by kjdon, 16 years ago

Michael has changed import.pl handling of manifest to import files marked with Import not Index, so had to change what we output as a manifest file

  • Property svn:keywords set to Author Date Id Revision
File size: 31.2 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 "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 // 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 repository browser.