source: main/trunk/greenstone2/runtime-src/src/recpt/depositoraction.cpp@ 30328

Last change on this file since 30328 was 30328, checked in by kjdon, 8 years ago

testing commit

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