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

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

commented out strings.h include as complains on windows, and doesn't seem to be needed for linux, changed i to j on some for loops otherwise windows complains about reinitialization

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