Project

General

Profile

« Previous | Next » 

Revision 8814

Only lock the local docid file when creating a new docid, not when inserting, for faster upload times. Remove extra debug messages from testing.

View differences:

src/perl/register-dataset.cgi
1
#!/bin/sh
1
#!/usr/bin/env perl
2
#
3
#  '$RCSfile$'
4
#  Copyright: 2000 Regents of the University of California
5
#
6
#   '$Author$'
7
#     '$Date$'
8
# '$Revision$'
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
#
2 24

  
3
#  test-registry-submission.sh
4
#  
5 25
#
6
#  Created by Lauren Walker on 7/23/14.
26
# This is a CGI application for inserting metadata documents into
27
# the Metacat database.  It utilizes the Metacat.pm module for most work.
28
# In this script, we process the form fields passed in from a POST, insert a
29
# metadata document and an ACL document.
30

  
31
use lib '../WEB-INF/lib';
32
use Metacat;
33
use Config::Properties;
34
use Cwd 'abs_path';
35
use XML::LibXML;
36
use XML::LibXSLT;
37
use Template;
38
use Net::SMTP;
39
use CGI qw/:standard :html3/;
40
use CGI::Session;
41
use Digest::SHA1;
42
use File::stat;
43
use File::Basename;
44
use File::Temp;
45
use File::Copy;
46
use Fcntl qw(:flock);
47
use Data::UUID;
48
use strict;
49

  
50
#debug("running register-dataset.cgi");
51

  
52
# Global configuration paramters
53
my $cgiDir           = $ENV{'SCRIPT_FILENAME'};
54
my $workingDirectory = ".";
55
if ( $cgiDir ne "" ) {
56
	my $workingDirectory = dirname($cgiDir);
57
}
58
my $metacatProps = "${workingDirectory}/../WEB-INF/metacat.properties";
59
my $properties   = new Config::Properties();
60
unless ( open( METACAT_PROPERTIES, $metacatProps ) ) {
61
	print "Content-type: text/html\n\n";
62
	print
63
"Unable to locate Metacat properties. Working directory is set as '$workingDirectory', is this correct?";
64
	exit();
65
}
66

  
67
$properties->load(*METACAT_PROPERTIES);
68

  
69
# local directory configuration
70
my $skinsDir     = "${workingDirectory}/../style/skins";
71
my $templatesDir = abs_path("${workingDirectory}/../style/common/templates");
72
my $tempDir      = $properties->getProperty('application.tempDir');
73
my $dataDir      = $properties->getProperty('application.datafilepath');
74
my $metacatDir   = "/var/metacat";
75

  
76
# url configuration
77
my $server = $properties->splitToTree( qr/\./, 'server' );
78
my $protocol = 'http://';
79
if ( $properties->getProperty('server.httpPort') eq '443' ) {
80
	$protocol = 'https://';
81
}
82
my $contextUrl = $protocol . $properties->getProperty('server.name');
83
if ( $properties->getProperty('server.httpPort') ne '80' ) {
84
	$contextUrl =
85
	  $contextUrl . ':' . $properties->getProperty('server.httpPort');
86
}
87
$contextUrl =
88
  $contextUrl . '/' . $properties->getProperty('application.context');
89

  
90
my $metacatUrl = $contextUrl . "/metacat";
91
my $cgiPrefix =
92
  "/" . $properties->getProperty('application.context') . "/cgi-bin";
93
my $styleSkinsPath  = $contextUrl . "/style/skins";
94
my $styleCommonPath = $contextUrl . "/style/common";
95
my $userManagementUrl = $properties->getProperty('auth.userManagementUrl');
96

  
97
my $now = time;
98

  
99
# Import all of the HTML form fields as variables
100
import_names('FORM');
101

  
102
# Must have a config to use Metacat
103
my $skinName = "";
104
if ( hasContent($FORM::cfg) ) {
105
	$skinName = $FORM::cfg;
106
}
107
elsif ( hasContent( $ARGV[0] ) ) {
108
	$skinName = $ARGV[0];
109
}
110
else {
111
	debug("No configuration set.");
112
	print "Content-type: text/html\n\n";
113
	'Registry Error: The registry requires a skin name to continue.';
114
	exit();
115
}
116

  
117
# Metacat isn't initialized, the registry will fail in strange ways.
118
if ( !hasContent($metacatUrl) ) {
119
	debug("No Metacat.");
120
	print "Content-type: text/html\n\n";
121
	'Registry Error: Metacat is not initialized! Make sure'
122
	  . ' MetacatUrl is set correctly in '
123
	  . $skinName
124
	  . '.properties';
125
	exit();
126
}
127

  
128
# Set up the hash for returning data to the HTML templates
129
my $templateVars = { 'status' => 'success' };
130
my $error = 0;
131
my @errorMessages;
132

  
133
my $skinProperties = new Config::Properties();
134
if ( !hasContent($skinName) ) {
135
	$error = "Application misconfigured.  Please contact the administrator.";
136
	push( @errorMessages, $error );
137
}
138
else {
139
	my $skinProps = "$skinsDir/$skinName/$skinName.properties";
140
	unless ( open( SKIN_PROPERTIES, $skinProps ) ) {
141
		print "Content-type: text/html\n\n";
142
		print "Unable to locate skin properties at $skinProps.  Is this path correct?";
143
		exit();
144
	}
145
	$skinProperties->load(*SKIN_PROPERTIES);
146
}
147

  
148
# replacements for appconfig values using properties
149
my $moderators = $properties->getProperty('auth.moderators');
150
my $config     = $skinProperties->splitToTree( qr/\./, 'registry.config' );
151
my $templates  = $skinProperties->splitToTree( qr/\./, 'registry.templates' );
152
my $modules    = $skinProperties->splitToTree( qr/\./, 'registry.modules' );
153
my $required   = $skinProperties->splitToTree( qr/\./, 'registry.required' );
154
my $spatial    = $skinProperties->splitToTree( qr/\./, 'registry.spatial' );
155
my $show       = $skinProperties->splitToTree( qr/\./, 'registry.show' );
156

  
157
# set stderr printing if configured
158
my $debug_enabled = $config->{'debug'};
159
if ($FORM::debug) {
160
	$debug_enabled = $FORM::debug;
161
}
162

  
163
# skin owner credentials
164
my $adminUsername = $config->{'username'};
165
my $adminPassword = $config->{'password'};
166

  
167
# contains sender, recipient, admin, mailhost
168
my $skinEmail = $skinProperties->splitToTree( qr/\./, 'email' );
169
my $email = $properties->splitToTree( qr/\./, 'email' );
170

  
171
# override email properties with skin-based ones
172
my @emailData = keys(%$email);
173
foreach my $d (@emailData) {
174
	if ( %$skinEmail->{$d} ) {
175
		$email->{$d} = %$skinEmail->{$d};
176
	}
177
}
178

  
179
# convert the lat and lon configs into usable data structures
180
my @sitelist;
181
my %siteLatDMS;
182
my %siteLongDMS;
183

  
184
while ( my ( $key, $value ) = each(%$spatial) ) {
185
	my ( $name, $lon, $lat ) = split( /\|/, $value );
186
	my ( $latd, $latm, $lats, $latdir ) = split( /\|/, $lat );
187
	my ( $lond, $lonm, $lons, $londir ) = split( /\|/, $lon );
188
	push( @sitelist, $name );
189
	$siteLatDMS{$name}  = [ $latd, $latm, $lats, $latdir ];
190
	$siteLongDMS{$name} = [ $lond, $lonm, $lons, $londir ];
191
}
192

  
193
# set some configuration options for the template object
194
my $ttConfig = {
195
	INCLUDE_PATH => $templatesDir,
196
	INTERPOLATE  => 0,
197
	POST_CHOMP   => 1,
198
	DEBUG        => 1,
199
};
200

  
201
# create an instance of the template processor
202
my $template = Template->new($ttConfig) || die $Template::ERROR, "\n";
203

  
204
#print "Content-type: text/html\n\n";
205
#print "Is debug enabled? `$debug_enabled`";
206
#use Data::Dumper;
207
#print Dumper($config);
208
#exit;
209
# Set up the template information that is common to all forms
210

  
211
$$templateVars{'contextUrl'}      = $contextUrl;
212
$$templateVars{'styleSkinsPath'}  = $styleSkinsPath;
213
$$templateVars{'styleCommonPath'} = $styleCommonPath;
214
$$templateVars{'cgiPrefix'}       = $cgiPrefix;
215
$$templateVars{'metacatUrl'}      = $metacatUrl;
216
$$templateVars{'cfg'}             = $skinName;
217
$$templateVars{'email'}           = $email;
218
$$templateVars{'templates'}       = $templates;
219
$$templateVars{'required'}        = $required;
220
$$templateVars{'config'}          = $config;
221
$$templateVars{'userManagementUrl'} = $userManagementUrl;
222

  
223
debug("Initialized -- stage set: $FORM::stage");
224

  
225
# handle pids, set the mapped docid in the FORM params
226
# see: https://projects.ecoinformatics.org/ecoinfo/issues/5932
227
debug("PID: $FORM::pid");
228
if ($FORM::pid ne "" ) {
229
	my $pid = $FORM::pid;
230
	my $metacat = Metacat->new($metacatUrl);
231
	my $docid = $metacat->getDocid($pid);
232
	$FORM::docid = $docid;
233
}
234

  
235
# Process the form based on stage parameter.
236
if ( $FORM::stage =~ "loginform" ) {
237
	print "Content-type: text/html\n\n";
238

  
239
	# Send back the login form.....
240
	my $session = CGI::Session->load() or die CGI::Session->errstr();
241

  
242
	if ( $FORM::submission eq 'true' ) {
243
		$$templateVars{'message'} = 'You must login to view your submissions.';
244
	}
245

  
246
	if ( !$session->is_empty ) {
247

  
248
		# session found ... delete the session....
249
		$session->delete();
250
	}
251

  
252
	$template->process( $templates->{'login'}, $templateVars );
253
	exit();
254
}
255
elsif ( $FORM::stage =~ "logout" ) {
256
	handleLogoutRequest();
257
	exit();
258
}
259
elsif ( $FORM::stage =~ "login" ) {
260
	handleLoginRequest();
261
	exit();
262
}
263
elsif ( $FORM::stage =~ "mod_accept" ) {
264
	handleModAccept();
265
	exit();
266
}
267
elsif ( $FORM::stage =~ "mod_decline" ) {
268
	handleModDecline();
269
	exit();
270
}
271
elsif ( $FORM::stage =~ "mod_revise" ) {
272
	handleModRevise();
273
	exit();
274
}
275
elsif ( $FORM::stage =~ "read" ) {
276
	handleRead();
277
	exit();
278
}
279
elsif ( $FORM::stage =~ "review_frame" ) {
280
	handleReviewFrame();
281
	exit();
282
}
283

  
284
print "Content-type: text/html\n\n";
285

  
286
if ( $FORM::stage =~ "guide" ) {
287

  
288
	# Send back the information on how to fill the form
289
	$$templateVars{'section'} = "Guide on How to Complete Registry Entries";
290
	$template->process( $templates->{'guide'}, $templateVars );
291
	exit();
292

  
293
}
294
elsif ( $FORM::stage =~ "insert" ) {
295

  
296
	# The user has entered the data. Do data validation and send back data
297
	# to confirm the data that has been entered.
298
	toConfirmData();
299
	exit();
300

  
301
}
302
elsif ($FORM::dataWrong =~ "No, go back to editing"
303
	&& $FORM::stage =~ "confirmed" )
304
{
305

  
306
	# The user wants to correct the data that he has entered.
307
	# Hence show the data again in entryData form.
308
	confirmDataToReEntryData();
309
	exit();
310

  
311
}
312
elsif ( $FORM::stage =~ "modify" ) {
313
	#debug("in modify stage");
314
	# Modification of a file has been requested.
315
	# check if the user is logged in...
316
	my $session = CGI::Session->load() or die CGI::Session->errstr();
317
	if ( $session->is_empty ) {
318

  
319
		# no session found ... redirect to login page template
320
		$$templateVars{'message'} = 'You must login to modify your dataset.';
321
		$template->process( $templates->{'login'}, $templateVars );
322
	}
323
	else {
324

  
325
		# Show the form will all the values filled in.
326
		my @sortedSites;
327
		foreach my $site ( sort @sitelist ) {
328
			push( @sortedSites, $site );
329
		}
330
		$$templateVars{'siteList'} = \@sortedSites;
331
		$$templateVars{'section'}  = "Modification Form";
332
		my ( $foundScope, $id, $rev ) = split( /\./, $FORM::docid );
333
		if ( !$rev ) {
334
			my $metacat = Metacat->new($metacatUrl);
335
			my $lastRev = $metacat->getLastRevision($FORM::docid);
336
			$$templateVars{'docid'} = $FORM::docid . "." . $lastRev;
337
		}
338
		else {
339
			$$templateVars{'docid'} = $FORM::docid;
340
		}
341
		modifyData();
342
	}
343
	exit();
344

  
345
}
346
elsif ( $FORM::stage =~ "delete_confirm" ) {
347

  
348
	# Result from deleteData form.
349
	if ( $FORM::deleteData =~ "Delete document" ) {
350

  
351
		# delete Data
352
		deleteData(1);
353
		exit();
354
	}
355
	else {
356
		$$templateVars{'status'}   = "Cancel";
357
		$$templateVars{'function'} = "cancel";
358
		$template->process( $templates->{'response'}, $templateVars );
359
		exit();
360
	}
361

  
362
}
363
elsif ( $FORM::stage =~ "delete" ) {
364

  
365
	# Deletion of a file has been requested.
366
	# Ask for username and password using deleteDataForm
367
	$$templateVars{'docid'} = $FORM::docid;
368
	$template->process( $templates->{'deleteData'}, $templateVars );
369
	exit();
370

  
371
}
372
elsif ( $FORM::stage !~ "confirmed" ) {
373

  
374
	# None of the stages have been reached and data is not being confirmed.
375

  
376
	# check if the user is logged in...
377
	my $session = CGI::Session->load() or die CGI::Session->errstr();
378
	if ( $session->is_empty ) {
379

  
380
		# no session found ... redirect to login page template
381
		$$templateVars{'showInstructions'} = 'true';
382
		$$templateVars{'message'} = 'You must login to register your dataset.';
383
		$template->process( $templates->{'login'}, $templateVars );
384
	}
385
	else {
386

  
387
		# Hence, send back entry form for entry of data.
388
		debug("Sending form");
389
		my @sortedSites;
390
		foreach my $site ( sort @sitelist ) {
391
			push( @sortedSites, $site );
392
		}
393

  
394
		if ( $skinName eq 'nceas' ) {
395
			my $projects = getProjectList($properties);
396
			$$templateVars{'projects'} = $projects;
397
			$$templateVars{'wg'}       = \@FORM::wg;
398
		}
399

  
400
		$$templateVars{'modules'}   = $modules;
401
		$$templateVars{'required'}  = $required;
402
		$$templateVars{'templates'} = $templates;
403
		$$templateVars{'show'}      = $show;
404
		$$templateVars{'site'}      = $config->{'site'};
405

  
406
		$$templateVars{'siteList'} = \@sortedSites;
407
		$$templateVars{'section'}  = "Entry Form";
408
		$$templateVars{'docid'}    = "";
409
		debug("Sending form: ready to process template");
410
		$template->process( $templates->{'entry'}, $templateVars );
411
		debug("Sending form: template processed");
412
	}
413
	exit();
414
}
415

  
416
# Confirm stage has been reached. Enter the data into metacat.
417

  
418
# Initialize some global vars
419
my $latDeg1      = "";
420
my $latMin1      = "";
421
my $latSec1      = "";
422
my $hemisphLat1  = "";
423
my $longDeg1     = "";
424
my $longMin1     = "";
425
my $longSec1     = "";
426
my $hemisphLong1 = "";
427
my $latDeg2      = "";
428
my $latMin2      = "";
429
my $latSec2      = "";
430
my $hemisphLat2  = "";
431
my $longDeg2     = "";
432
my $longMin2     = "";
433
my $longSec2     = "";
434
my $hemisphLong2 = "";
435
my $modUsername  = "";
436
my $modPassword  = "";
437

  
438
# validate the input form parameters
439
my $invalidParams;
440

  
441
if ( !$error ) {
442
	$invalidParams = validateParameters(1);
443
	if ( scalar(@$invalidParams) ) {
444
		$$templateVars{'status'}        = 'failure';
445
		$$templateVars{'invalidParams'} = $invalidParams;
446
		$error                          = 1;
447
	}
448
}
449

  
450
my $docid;
451

  
452
# Create a metacat object
453
my $metacat = Metacat->new($metacatUrl);
454

  
455
if ( !$error ) {
456

  
457
	# Login to metacat
458
	my ( $username, $password ) = getCredentials();
459
	my $response = $metacat->login( $username, $password );
460
	my $errorMessage = "";
461
    
462
	# Parameters have been validated and Create the XML document
463
	my $xmldoc = createXMLDocument();
464
    
465
	my $xmldocWithDocID = $xmldoc;
466
	my $errorMessage    = "";
467

  
468
	if ( !$response ) {
469
		debug("No response from Metacat");
470
		push( @errorMessages, $metacat->getMessage() );
471
		push( @errorMessages, "Failed during login.\n" );
472
		$$templateVars{'status'}        = 'login_failure';
473
		$$templateVars{'errorMessages'} = \@errorMessages;
474
		$$templateVars{'docid'}         = $docid;
475
		$$templateVars{'cfg'}           = $skinName;
476
		$$templateVars{'function'}      = "submitted";
477
		$$templateVars{'section'}       = "Submission Status";
478
		$template->process( $templates->{'response'}, $templateVars );
479
		exit();
480
	}
481
	else {
482

  
483
		if ( $config->{'adminIsDocOwner'} eq 'true' ) {
484
			debug("adminIsDocOwner is set.");
485
			$response = $metacat->login( $adminUsername, $adminPassword );
486
			if ( !$response ) {
487
				push( @errorMessages, $metacat->getMessage() );
488
				push( @errorMessages, "Failed during login for admin.\n" );
489
				$$templateVars{'status'}        = 'login_failure';
490
				$$templateVars{'errorMessages'} = \@errorMessages;
491
				$$templateVars{'docid'}         = $docid;
492
				$$templateVars{'cfg'}           = $skinName;
493
				$$templateVars{'function'}      = "submitted";
494
				$$templateVars{'section'}       = "Submission Status";
495
				$template->process( $templates->{'response'}, $templateVars );
496
				exit();
497
			}
498
		}
499

  
500
		debug("A");
501
		if ( $FORM::docid eq "" ) {
502
			debug("B1");
503

  
504
			# document is being inserted
505
			my $docStatus = "INCOMPLETE";
506
            
507
			while ($docStatus eq "INCOMPLETE") {
508
                                
509
                #Create the docid
510
                $docid = newDocid($config->{'scope'}, $metacat);
511
                                    
512
                $xmldocWithDocID =~ s/docid/$docid/;
513
                debugDoc($xmldocWithDocID);
514
                $docStatus = insertMetadata( $xmldocWithDocID, $docid );
515
                               
516
                debug("B2");
517
                
518
			}
519
                        
520
            debug("B3");
521
            
522
            if ( $docStatus ne "SUCCESS" ) {
523
                debug("NO SUCCESS");
524
                debug("Message is: $docStatus");
525
                
526
                push( @errorMessages, $docStatus );
527
            }
528
            else{
529
                deleteRemovedData();
530
            }
531
            
532
		}
533
		else {
534
			debug("M1");
535

  
536
			# document is being modified
537
			$docid = incrementRevision($FORM::docid);
538

  
539
			$xmldoc =~ s/docid/$docid/;
540
			debugDoc($xmldoc);
541

  
542
			my $response = $metacat->update( $docid, $xmldoc );
543

  
544
			if ( !$response ) {
545
				push( @errorMessages, $metacat->getMessage() );
546
				push( @errorMessages, "Failed while updating.\n" );
547
			}
548

  
549
			debug("M2, $docid");
550
			if ( scalar(@errorMessages) ) {
551
				debug("Errors defined in modify.");
552

  
553
				$$templateVars{'docid'} = $FORM::docid;
554
				copyFormToTemplateVars();
555
				$$templateVars{'status'}        = 'failure';
556
				$$templateVars{'errorMessages'} = \@errorMessages;
557
				$error                          = 1;
558
			}
559
			else {
560
				deleteRemovedData();
561
				$$templateVars{'docid'} = $docid;
562
				$$templateVars{'cfg'}   = $skinName;
563
			}
564

  
565
			# Create our HTML response and send it back
566
			$$templateVars{'function'} = "modified";
567
			$$templateVars{'section'}  = "Modification Status";
568
			$template->process( $templates->{'response'}, $templateVars );
569

  
570
			# send a notification email to the moderator
571
			if ( hasContent($FORM::cfg) && $FORM::cfg eq 'esa' ) {
572
				my $title               = "";
573
				my $contactEmailAddress = "";
574
				my $contactName         = "";
575
				my $parser              = XML::LibXML->new();
576
				my $parsedDoc           = $parser->parse_string($xmldoc);
577
				$FORM::function = 'modified';
578

  
579
				my $findNodes = $parsedDoc->findnodes('//dataset/title');
580
				if ( $findNodes->size() > 0 ) {
581

  
582
					# found title
583
					my $node = '';
584
					foreach $node ( $findNodes->get_nodelist ) {
585
						$title = findValue( $node, '../title' );
586
					}
587
				}
588

  
589
				$findNodes = $parsedDoc->findnodes('//dataset/contact');
590
				if ( $findNodes->size() > 0 ) {
591

  
592
					# found contact email address
593
					my $node = '';
594
					foreach $node ( $findNodes->get_nodelist ) {
595
						my $surName =
596
						  findValue( $node, 'individualName/surName' );
597
						my $givenName =
598
						  findValue( $node, 'individualName/givenName' );
599
						my $organizationName =
600
						  findValue( $node, 'organizationName' );
601

  
602
						if ( $surName ne '' ) {
603
							$contactName = $givenName . ' ' . $surName;
604
						}
605
						else {
606
							$contactName = $organizationName;
607
						}
608
					}
609
				}
610

  
611
				$FORM::docid = $docid;
612

  
613
				modSendNotification( $title, $contactEmailAddress, $contactName,
614
					"Document $docid modification review pending" );
615
			}
616
			exit();
617
		}
618
	}
619

  
620
	if ( hasContent($FORM::cfg) && $FORM::cfg eq 'esa' ) {
621
		my $title               = "";
622
		my $contactEmailAddress = "";
623
		my $contactName         = "";
624
		my $parser              = XML::LibXML->new();
625
		my $parsedDoc           = $parser->parse_string($xmldoc);
626

  
627
		my $findNodes = $parsedDoc->findnodes('//dataset/title');
628
		if ( $findNodes->size() > 0 ) {
629

  
630
			# found title
631
			my $node = '';
632
			foreach $node ( $findNodes->get_nodelist ) {
633
				$title = findValue( $node, '../title' );
634
			}
635
		}
636

  
637
		$findNodes = $parsedDoc->findnodes('//dataset/contact');
638
		if ( $findNodes->size() > 0 ) {
639

  
640
			# found contact email address
641
			my $node = '';
642
			foreach $node ( $findNodes->get_nodelist ) {
643
				$contactEmailAddress = findValue( $node, 'electronicMailAddress' );
644
				my $surName   = findValue( $node, 'individualName/surName' );
645
				my $givenName = findValue( $node, 'individualName/givenName' );
646
				my $organizationName = findValue( $node, 'organizationName' );
647

  
648
				if ( $surName ne '' ) {
649
					$contactName = $givenName . ' ' . $surName;
650
				}
651
				else {
652
					$contactName = $organizationName;
653
				}
654
			}
655
		}
656
		$FORM::docid = $docid;
657

  
658
		modSendNotification( $title, $contactEmailAddress, $contactName,
659
			"Document $docid review pending" );
660
	}
661
    
662
}
663

  
664
debug("C");
665

  
666
if ( scalar(@errorMessages) ) {
667
	debug("ErrorMessages defined.");
668
	$$templateVars{'docid'} = $FORM::docid;
669
	copyFormToTemplateVars();
670
	$$templateVars{'status'}        = 'failure';
671
	$$templateVars{'errorMessages'} = \@errorMessages;
672
	$error                          = 1;
673
}
674
else {
675
	$$templateVars{'docid'} = $docid;
676
	$$templateVars{'cfg'}   = $skinName;
677

  
678
	# delete the remaining file objects from disk
679
	for ( my $fileNum = 0 ; $fileNum <= $FORM::upCount ; $fileNum++ ) {
680
		my $fn = 'uploadname_' . $fileNum;
681
		if ( hasContent( param($fn) ) ) {
682
			deleteFile( param($fn) );
683
		}
684
	}
685

  
686
}
687

  
688
# Create our HTML response and send it back
689
$$templateVars{'function'} = "submitted";
690
$$templateVars{'section'}  = "Submission Status";
691

  
692
$template->process( $templates->{'response'}, $templateVars );
693

  
694
exit();
695

  
696
################################################################################
7 697
#
698
# Subroutine for inserting a document to metacat
699
#
700
################################################################################
701
sub insertMetadata {
702
	my $xmldoc = shift;
703
	my $docid  = shift;
8 704

  
9
> fileDetails.txt
10
> results.html
705
	debug("Trying to insert the following document");
706
	my $docStatus = "SUCCESS";
707
	debug("Starting insert of $docid (D1)");
11 708

  
12
counter="0"
709
	my $response = $metacat->insert( $docid, $xmldoc );
710
	if ( !$response ) {
711
		debug("Response gotten (D2)");
712
		my $errormsg = $metacat->getMessage();
713
		debug( "Error is (D3): " . $errormsg );
714
		if ( $errormsg =~ /is already in use/ ) {
715
			$docStatus = "INCOMPLETE";
716
		}
717
		elsif ( $errormsg =~ /<login>/ ) {
718
			$docStatus = "SUCCESS";
719
		}
720
		else {
721
			$docStatus = $errormsg;
722
		}
723
	}
724
	debug("Ending insert (D4)");
13 725

  
14
while [ $counter -lt 3 ]
15
do
16
    response=$(curl -X POST --cookie "JSESSIONID=81E77F52A2CA1D632B6CF01925D54FE0;SESS6790668dc29fdba8b64e6f4c1193c83d=yRZg3Ap9kK1TJGef_oOsPu4nMUe_SMEB8ICQrpsuOHI;CGISESSID=5c43858469558146ec0439e5b20500fd" --form file_0=@testdata.csv --form cfg=metacatui --form stage=insert --form providerGivenName=Lauren --form providerSurName=Walker --form "title=test with curl $counter" --form site=NCEAS --form origNamefirst0=walker --form origNamelast0=Walker --form abstract=abstract --form beginningYear=2014 --form geogdesc=Cali --form latDeg1=0 --form longDeg1=0 --form dataMedium=digital --form "useConstraints=no restrictions" --form useOrigAddress=on --form fileCount=1 --form justGetUploadDetails=true "https://dev.nceas.ucsb.edu/knb/cgi-bin/register-dataset.cgi")
726
	return $docStatus;
727
}
17 728

  
18
    echo $response >> fileDetails.txt
19
    counter=$[$counter+1]
20
done
729
################################################################################
730
#
731
# Subroutine for generating a new accession number
732
#  Note: this is not threadsafe, assumes only one running process at a time
733
#  Also: need to check metacat for max id # used in this scope already
734
################################################################################
735
sub newAccessionNumber {
736
	my $scope    = shift;
737
	my $metacat  = shift;
738
	my $errormsg = 0;
21 739

  
22
counter="0"
740
	my $docid = $metacat->getLastId($scope);
741
	if ( !$docid ) {
742
		$docid = "$scope.1.1";
743
		debug( "Error in newAccessionNumber: " . $metacat->getMessage() );
744
	}
745
	else {
746
		my ( $foundScope, $id, $rev ) = split( /\./, $docid );
747
		$id++;
748
		$docid = "$scope.$id.1";
749
	}
750
	debug("Metcat handed us a new docid: $docid");
751
	return $docid;
752
}
23 753

  
24
while [ $counter -lt 3 ]
25
do
26
    details=$(tail -n+$counter fileDetails.txt | head -n1)
27 754

  
28
    #Get the variables needed for the confirmation stage
29
    commaLoc=`gexpr index $details ","`
30
    upload=${details:0:commaLoc-1}
755
################################################################################
756
#
757
# Subroutine for generating a new docid
758
# Checks a local file for the max id # in use for this scope. After several tries,
759
# checks metacat using newAccessionNumber
760
################################################################################
761
sub newDocid {
762
    
763
    my $scope   = shift;
764
    my $metacat = shift;
765
    my $getFromMetacat  = shift;
766
    my $scopeFound = 0;
767
    
768
    #Lock a local file while we are creating a new docid
769
    my $lockFilePath = "docids.lock";
770
    open my $lock, '>', $lockFilePath;
771
    flock($lock, LOCK_EX);
772
    
773
    my $lastdocid = newAccessionNumber($scope, $metacat);
774
    #Extract the docid number from the docid
775
    my @line = split(/\./, $lastdocid);
776
    my $num = $line[1];
777
    
778
    my $docidsFilePath    = $tempDir."/docids.txt";
779
    my $docidsFilePathNew = $tempDir."/docids.txt.new";
780
    
781
    #Open/create a local file while we are creating a new docid
782
    open my $docidsFile,  '+<',  $docidsFilePath;
783
    open my $docidsNewFile, '>', $docidsFilePathNew;
784
    
785
    #Read each docid scope,num in the file
786
    while( <$docidsFile> ) {
787
        my @line = split /,/;
788
        my $currentScope = $line[0];
789
        
790
        if($currentScope eq $scope){
791
            
792
            my $docidNum = $line[1] + 1;
793
            
794
            if($num > $docidNum){
795
              $docid = "$scope.$num.1";
796
              print $docidsNewFile "$scope,$num \n";
797
            }
798
            else{
799
              $docid = "$scope.$docidNum.1";
800
              print $docidsNewFile "$scope,$docidNum \n";
801
            }
31 802

  
32
    details=${details:commaLoc}
33
    commaLoc=`gexpr index $details ","`
34
    uploadname=${details:0:commaLoc-1}
803
            $scopeFound = 1;
804
        }
805
        else{
806
            print $docidsNewFile $_;
807
        }
808
    }
809
    
810
    #If this scope is not in the local docid store then add it
811
    if(!$scopeFound){
812
        #Add to the local file
813
        print $docidsNewFile "$scope,$num \n";
814
    }
815
    
816
    #Close the file and replace the old docids file with this new one
817
    close $docidsNewFile;
818
    close $docidsFile;
819
    move($docidsFilePathNew, $docidsFilePath);
820
    close $lock;
821
    
822
    return $docid;
823
}
35 824

  
36
    details=${details:commaLoc}
37
    commaLoc=`gexpr index $details ","`
38
    uploadtype=${details:0:commaLoc-1}
825
sub incrementRevision {
826
	my $initDocid = shift;
827
	my $docid     = '';
828
	if ( !$initDocid ) {
829
		debug("No docid entered.");
830
	}
831
	else {
832
		my ( $scope, $id, $rev ) = split( /\./, $initDocid );
833
		$rev++;
834
		$docid = "$scope.$id.$rev";
835
	}
836
	return $docid;
837
}
39 838

  
40
    curl -X POST --cookie "JSESSIONID=81E77F52A2CA1D632B6CF01925D54FE0;SESS6790668dc29fdba8b64e6f4c1193c83d=yRZg3Ap9kK1TJGef_oOsPu4nMUe_SMEB8ICQrpsuOHI;CGISESSID=5c43858469558146ec0439e5b20500fd" --form file_0=@testdata.csv --form cfg=metacatui --form stage=confirmed --form providerGivenName=Lauren --form providerSurName=Walker --form "title=test with curl $counter" --form site=NCEAS --form origNamefirst0=walker --form origNamelast0=Walker --form abstract=abstract --form beginningYear=2014 --form geogdesc=Cali --form latDeg1=0 --form longDeg1=0 --form dataMedium=digital --form "useConstraints=no restrictions" --form useOrigAddress=on --form fileCount=1 --form upCount=1 --form delCount=1 --form uploadperm_0=public --form upload_0=$upload --form uploadname_0=$uploadname --form uploadtype_0=$uploadtype "https://dev.nceas.ucsb.edu/knb/cgi-bin/register-dataset.cgi" &
839
################################################################################
840
#
841
# Validate the parameters to make sure that required params are provided
842
#
843
################################################################################
844
sub validateParameters {
845
	my $chkUser = shift;
846
	my @invalidParams;
41 847

  
42
    counter=$[$counter+1]
43
done
848
	push( @invalidParams, "Name of the Project is not selected in the form." )
849
	  if ( scalar(@FORM::wg) == 0 && $required->{'wgList'} eq 'true' );
850
	push( @invalidParams, "First name of person entering the form is missing." )
851
	  unless hasContent($FORM::providerGivenName);
852
	push( @invalidParams, "Last name of person entering the form is missing." )
853
	  unless hasContent($FORM::providerSurName);
854
	push( @invalidParams, "Dataset title is missing." )
855
	  unless hasContent($FORM::title);
856
	push( @invalidParams, ucfirst( $config->{'site'} ) . " name is missing." )
857
	  unless ( ( hasContent($FORM::site) && !( $FORM::site =~ /^Select/ ) )
858
		|| $skinName eq "nceas" );
859
	push( @invalidParams, "First name of principal data set owner is missing." )
860
	  unless hasContent($FORM::origNamefirst0);
861
	push( @invalidParams, "Last name of principal data set owner is missing." )
862
	  unless hasContent($FORM::origNamelast0);
863
	push( @invalidParams, "Dataset abstract is missing." )
864
	  unless hasContent($FORM::abstract);
44 865

  
866
	if ( $modules->{'temporal'} eq 'true' ) {
867
		push( @invalidParams, "Year of start date is missing." )
868
		  unless ( hasContent($FORM::beginningYear)
869
			|| $required->{'temporal'} ne 'true' );
870
		push( @invalidParams,
871
"Year of stop date has been specified but year of start date is missing."
872
		  )
873
		  if ( ( !hasContent($FORM::beginningYear) )
874
			&& hasContent($FORM::endingYear) );
875
	}
876
	push( @invalidParams, "Geographic description is missing." )
877
	  unless ( hasContent($FORM::geogdesc)
878
		|| $required->{'spatial'} ne 'true' );
879

  
880
	if ( $FORM::beginningMonth eq "MM" ) {
881
		$FORM::beginningMonth = "";
882
	}
883
	if ( $FORM::beginningDay eq "DD" ) {
884
		$FORM::beginningDay = "";
885
	}
886
	if ( $FORM::endingMonth eq "MM" ) {
887
		$FORM::endingMonth = "";
888
	}
889
	if ( $FORM::endingDay eq "DD" ) {
890
		$FORM::endingDay = "";
891
	}
892

  
893
	if ( hasContent($FORM::beginningYear)
894
		&& !( $FORM::beginningYear =~ /[0-9]{4}/ ) )
895
	{
896
		push( @invalidParams, "Invalid year of start date specified." );
897
	}
898

  
899
	if ( hasContent($FORM::endingYear) && !( $FORM::endingYear =~ /[0-9]{4}/ ) )
900
	{
901
		push( @invalidParams, "Invalid year of stop date specified." );
902
	}
903

  
904
	# If the "use site" coord. box is checked and if the site is in
905
	# the longitude hash ...  && ($siteLatDMS{$FORM::site})
906

  
907
	if ( $modules->{'spatial'} eq 'true' ) {
908
		if ( ($FORM::useSiteCoord) && ( $siteLatDMS{$FORM::site} ) ) {
909
			$latDeg1      = $siteLatDMS{$FORM::site}[0];
910
			$latMin1      = $siteLatDMS{$FORM::site}[1];
911
			$latSec1      = $siteLatDMS{$FORM::site}[2];
912
			$hemisphLat1  = $siteLatDMS{$FORM::site}[3];
913
			$longDeg1     = $siteLongDMS{$FORM::site}[0];
914
			$longMin1     = $siteLongDMS{$FORM::site}[1];
915
			$longSec1     = $siteLongDMS{$FORM::site}[2];
916
			$hemisphLong1 = $siteLongDMS{$FORM::site}[3];
917
		}
918
		else {
919
			$latDeg1      = $FORM::latDeg1;
920
			$latMin1      = $FORM::latMin1;
921
			$latSec1      = $FORM::latSec1;
922
			$hemisphLat1  = $FORM::hemisphLat1;
923
			$longDeg1     = $FORM::longDeg1;
924
			$longMin1     = $FORM::longMin1;
925
			$longSec1     = $FORM::longSec1;
926
			$hemisphLong1 = $FORM::hemisphLong1;
927
		}
928

  
929
		if ( $latDeg1 > 90 || $latDeg1 < 0 ) {
930
			push( @invalidParams, "Invalid first latitude degrees specified." );
931
		}
932
		if ( $latMin1 > 59 || $latMin1 < 0 ) {
933
			push( @invalidParams, "Invalid first latitude minutes specified." );
934
		}
935
		if ( $latSec1 > 59 || $latSec1 < 0 ) {
936
			push( @invalidParams, "Invalid first latitude seconds specified." );
937
		}
938
		if ( $longDeg1 > 180 || $longDeg1 < 0 ) {
939
			push( @invalidParams,
940
				"Invalid first longitude degrees specified." );
941
		}
942
		if ( $longMin1 > 59 || $longMin1 < 0 ) {
943
			push( @invalidParams,
944
				"Invalid first longitude minutes specified." );
945
		}
946
		if ( $longSec1 > 59 || $longSec1 < 0 ) {
947
			push( @invalidParams,
948
				"Invalid first longitude seconds specified." );
949
		}
950

  
951
		if ( hasContent($FORM::latDeg2)
952
			&& ( $FORM::latDeg2 > 90 || $FORM::latDeg2 < 0 ) )
953
		{
954
			push( @invalidParams,
955
				"Invalid second latitude degrees specified." );
956
		}
957
		if ( hasContent($FORM::latMin2)
958
			&& ( $FORM::latMin2 > 59 || $FORM::latMin2 < 0 ) )
959
		{
960
			push( @invalidParams,
961
				"Invalid second latitude minutes specified." );
962
		}
963
		if ( hasContent($FORM::latSec2)
964
			&& ( $FORM::latSec2 > 59 || $FORM::latSec2 < 0 ) )
965
		{
966
			push( @invalidParams,
967
				"Invalid second latitude seconds specified." );
968
		}
969
		if ( hasContent($FORM::latDeg2)
970
			&& ( $FORM::longDeg2 > 180 || $FORM::longDeg2 < 0 ) )
971
		{
972
			push( @invalidParams,
973
				"Invalid second longitude degrees specified." );
974
		}
975
		if ( hasContent($FORM::latMin2)
976
			&& ( $FORM::longMin2 > 59 || $FORM::longMin2 < 0 ) )
977
		{
978
			push( @invalidParams,
979
				"Invalid second longitude minutes specified." );
980
		}
981
		if ( hasContent($FORM::latSec2)
982
			&& ( $FORM::longSec2 > 59 || $FORM::longSec2 < 0 ) )
983
		{
984
			push( @invalidParams,
985
				"Invalid second longitude seconds specified." );
986
		}
987
	}
988

  
989
	# Check if latDeg1 and longDeg1 has values if useSiteCoord is used.
990
	# This check is required because some of the sites dont have lat
991
	# and long mentioned in the config file.
992

  
993
	if ( $modules->{'spatial'} eq 'true' && $required->{'spatial'} eq 'true' ) {
994
		if ($FORM::useSiteCoord) {
995
			push( @invalidParams,
996
"The Data Registry doesn't have latitude and longitude information for the site that you chose. Please go back and enter the spatial information."
997
			) unless ( hasContent($latDeg1) && hasContent($longDeg1) );
998
		}
999
		else {
1000
			push( @invalidParams, "Latitude degrees are missing." )
1001
			  unless ( hasContent($latDeg1)
1002
				|| $required->{'spatial'} ne 'true' );
1003
			push( @invalidParams, "Longitude degrees are missing." )
1004
			  unless ( hasContent($longDeg1)
1005
				|| $required->{'spatial'} ne 'true' );
1006
		}
1007
		push( @invalidParams,
1008
"You must provide a geographic description if you provide latitude and longitude information."
1009
		  )
1010
		  if ( ( hasContent($latDeg1) || ( hasContent($longDeg1) ) )
1011
			&& ( !hasContent($FORM::geogdesc) ) );
1012
	}
1013

  
1014
	if ( $modules->{'method'} eq 'true' ) {
1015
		push( @invalidParams,
1016
"You must provide a method description if you provide a method title."
1017
		  )
1018
		  if (
1019
			hasContent($FORM::methodTitle)
1020
			&& (  !( scalar(@FORM::methodPara) > 0 )
1021
				|| ( !hasContent( $FORM::methodPara[0] ) ) )
1022
		  );
1023
		push( @invalidParams,
1024
"You must provide a method description if you provide an extent of study description."
1025
		  )
1026
		  if (
1027
			hasContent($FORM::studyExtentDescription)
1028
			&& (  !( scalar(@FORM::methodPara) > 0 )
1029
				|| ( !hasContent( $FORM::methodPara[0] ) ) )
1030
		  );
1031
		push( @invalidParams,
1032
"You must provide both an extent of study description and a sampling description, or neither."
1033
		  )
1034
		  if (
1035
			(
1036
				hasContent($FORM::studyExtentDescription)
1037
				&& !hasContent($FORM::samplingDescription)
1038
			)
1039
			|| (  !hasContent($FORM::studyExtentDescription)
1040
				&& hasContent($FORM::samplingDescription) )
1041
		  );
1042
	}
1043

  
1044
	if ( $modules->{'upload'} eq 'true' ) {
1045
		for ( my $upNum = 0 ; $upNum <= $FORM::upCount ; $upNum++ ) {
1046
			my $upn = "upload_$upNum";
1047
			if ( hasContent( param($upn) )
1048
				&& !grep { $_ eq ("uploadname_$upNum") } @FORM::deletefile )
1049
			{
1050
				push( @invalidParams,
1051
					"Must select a permission for file "
1052
					  . param("uploadname_$upNum") )
1053
				  if ( !hasContent( param("uploadperm_$upNum") ) );
1054
			}
1055
		}
1056
	}
1057

  
1058
	push( @invalidParams, "First name of data set contact is missing." )
1059
	  unless ( hasContent($FORM::origNamefirstContact)
1060
		|| $FORM::useOrigAddress );
1061
	push( @invalidParams, "Last name of data set contact is missing." )
1062
	  unless ( hasContent($FORM::origNamelastContact)
1063
		|| $FORM::useOrigAddress );
1064
	if ( $required->{'contactEmailAddress'} eq 'true' ) {
1065
		if ($FORM::useOrigAddress) {
1066
			push( @invalidParams,
1067
"Email address of data set owner is missing. This is required as it will be used as contact email address as specified by you."
1068
			) unless ( hasContent($FORM::origEmail) );
1069
		}
1070
		else {
1071
			push( @invalidParams,
1072
				"Email address of data set contact is missing." )
1073
			  unless ( hasContent($FORM::origEmailContact) );
1074
		}
1075
	}
1076

  
1077
	# check required distribution elements
1078
	push( @invalidParams, "Data medium is required." )
1079
	  unless ( hasContent($FORM::dataMedium) );
1080
	if ( $FORM::dataMedium eq 'other' ) {
1081
		push( @invalidParams,
1082
			"Must enter custom data medium when 'other' is selected." )
1083
		  unless ( hasContent($FORM::dataMediumOther) );
1084
	}
1085
	push( @invalidParams, "Usage rights are required." )
1086
	  unless ( hasContent($FORM::useConstraints) );
1087
	if ( $FORM::useConstraints eq 'other' ) {
1088
		push( @invalidParams,
1089
			"Must enter custom usage rights when 'other' is selected." )
1090
		  unless ( hasContent($FORM::useConstraintsOther) );
1091
	}
1092

  
1093
	return \@invalidParams;
1094
}
1095

  
1096
################################################################################
1097
#
1098
# utility function to determine if a paramter is defined and not an empty string
1099
#
1100
################################################################################
1101
sub hasContent {
1102
	my $param = shift;
1103

  
1104
	my $paramHasContent;
1105
	if ( !defined($param) || $param eq '' ) {
1106
		$paramHasContent = 0;
1107
	}
1108
	else {
1109
		$paramHasContent = 1;
1110
	}
1111
	return $paramHasContent;
1112
}
1113

  
1114
################################################################################
1115
#
1116
# Subroutine for replacing characters not recognizable by XML and otherwise.
1117
#
1118
################################################################################
1119
sub normalize {
1120
	my $val = shift;
1121

  
1122
	$val =~ s/&/&amp;/g;
1123

  
1124
	$val =~ s/</&lt;/g;
1125
	$val =~ s/>/&gt;/g;
1126
	$val =~ s/\"/&quot;/g;
1127
	$val =~ s/%/&#37;/g;
1128

  
1129
	my $returnVal = "";
1130

  
1131
	foreach ( split( //, $val ) ) {
1132
		my $var = unpack "C*", $_;
1133

  
1134
		if ( $var < 128 && $var > 31 ) {
1135
			$returnVal = $returnVal . $_;
1136
		}
1137
		elsif ( $var < 32 ) {
1138
			if ( $var == 10 ) {
1139
				$returnVal = $returnVal . $_;
1140
			}
1141
			if ( $var == 13 ) {
1142
				$returnVal = $returnVal . $_;
1143
			}
1144
			if ( $var == 9 ) {
1145
				$returnVal = $returnVal . $_;
1146
			}
1147
		}
1148
		else {
1149
			$returnVal = $returnVal . $_;
1150
		}
1151
	}
1152

  
1153
	return $returnVal;
1154
}
1155

  
1156
################################################################################
1157
#
1158
# Subroutine for replacing characters not recognizable by XML and otherwise
1159
# except for ", > amd <.
1160
#
1161
################################################################################
1162
sub delNormalize {
1163
	my $val = shift;
1164

  
1165
	$val =~ s/&/&amp;/g;
1166

  
1167
	$val =~ s/%/&#37;/g;
1168

  
1169
	my $returnVal = "";
1170

  
1171
	foreach ( split( //, $val ) ) {
1172
		my $var = unpack "C*", $_;
1173

  
1174
		if ( $var < 128 && $var > 31 ) {
1175
			$returnVal = $returnVal . $_;
1176
		}
1177
		elsif ( $var < 32 ) {
1178
			if ( $var == 10 ) {
1179
				$returnVal = $returnVal . $_;
1180
			}
1181
			if ( $var == 13 ) {
1182
				$returnVal = $returnVal . $_;
1183
			}
1184
			if ( $var == 9 ) {
1185
				$returnVal = $returnVal . $_;
1186
			}
1187
		}
1188
		else {
1189
			$returnVal = $returnVal . "&#" . $var . ";";
1190
		}
1191
	}
1192

  
1193
	$returnVal =~ s/&/%26/g;
1194
	return $returnVal;
1195
}
1196

  
1197
################################################################################
1198
#
1199
# Subroutine for replacing characters that might create problem in HTML.
1200
# Specifically written for " being used in any text field. This creates a
1201
# problem in confirmData template, when you specify input name value pair
1202
# with value having a " in it.
1203
#
1204
################################################################################
1205
sub normalizeCD {
1206
	my $val = shift;
1207

  
1208
	$val =~ s/\"/&quot;/g;
1209

  
1210
	return $val;
1211
}
1212

  
1213
################################################################################
1214
#
1215
# Upload new file objects into Metacat, if they're present and valid.
1216
#
1217
################################################################################
1218
sub allFileData {
1219
	my %uploadedFiles = ();
1220
	my $fileInfo;
1221
	my $docid;
1222

  
1223
	for ( my $fileNum = 0 ; $fileNum <= $FORM::upCount ; $fileNum++ ) {
1224
		my $fn = 'upload_' . $fileNum;
1225
		if ( hasContent( param($fn) ) ) {
1226

  
1227
			# ignore data which is scheduled for deletion
1228
			if ( grep { $_ eq ("uploadname_$fileNum") } @FORM::deletefile ) {
1229
				debug(
1230
"Not generating metadata for file scheduled for deletion: $fn"
1231
				);
1232
			}
1233
			else {
1234
				debug("Retrieving metadata for file: $fn");
1235
				( $docid, $fileInfo ) = fileMetadata($fileNum);
1236
				$uploadedFiles{$docid} = $fileInfo;
1237
			}
1238
		}
1239
	}
1240

  
1241
	return %uploadedFiles;
1242
}
1243

  
1244
sub fileMetadata {
1245
	my $fileNum     = shift;
1246
	my $fileHash    = param("upload_$fileNum");
1247
	my $fileName    = param("uploadname_$fileNum");
1248
	my $contentType = param("uploadtype_$fileNum");
1249
	my $filePerm    = param("uploadperm_$fileNum");
1250
	my $docid;
1251
	my $outFile;
1252
	my $cleanName = $fileName;
1253

  
1254
	# process an _existing_ data file, which is already within Metacat.
1255
	if ( $fileHash =~ /ondisk/ ) {
1256
		( $docid, $fileHash ) = datafileInfo($fileHash);
1257
		$outFile = $dataDir . "/" . $docid;
1258
        
1259
	}
1260
	else {
1261

  
1262
		# normalize input filenames; Windows filenames include full paths
1263
		$cleanName =~ s/.*[\/\\](.*)/$1/;
1264
		$outFile = $tempDir . "/" . $cleanName;        
1265
	}
1266
	debug("Reading file from disk: $outFile");
1267
    
1268
	my $fileSize = stat($outFile)->size;
1269
	if ( $fileSize == 0 ) {
1270
		push( @errorMessages, "file $fileName is zero bytes!" );
1271
		debug("File $fileName is zero bytes!");
1272
	}
1273
    
1274
	# Now the file is on disk, send the object to Metacat
1275
	my $session = CGI::Session->load();
1276
	if ( $session->is_empty ) {
1277
		push( @errorMessages, "Must be logged in to upload files." );
1278
		debug("Not logged in, cannot upload files.");
1279
		return 0;
1280
	}
1281

  
1282
	# remove the uniqueness of the filename
1283
	# 'tempXXXXX'
1284
	$cleanName = substr($cleanName, 9);
1285
    	
1286
	if ( !$docid ) {
1287
                
1288
        my $uploadStatus = shift;
1289
        
1290
        while(!$uploadStatus){
1291
            
1292
            $docid = newDocid($config->{'scope'}, $metacat);
1293
            
1294
            $uploadStatus = uploadData( $outFile, $docid, $cleanName );
1295
                        
1296
            if ( !$uploadStatus ) {
1297
                debug("Uploading the data failed.");
1298
                push( @errorMessages, "Data file $cleanName failed to upload");
1299
            }
1300
        }
1301
	}
1302
	my $entityid  = $fileHash . "001";
1303
	my $distribid = $fileHash . "002";
1304

  
1305
	my $uploadUrl = 'ecogrid://knb/' . $docid;
1306

  
1307
	# TODO:  should match the object promotion path, so that an
1308
	#        Excel upload results in 'dataTable' in this field
1309
	my $entityType = 'Other';
1310
	
1311
	my %dataInfo = (
1312
		'docid'       => $docid,
1313
		'entityid'    => $entityid,
1314
		'distribid'   => $distribid,
1315
		'fileName'    => $cleanName,
1316
		'fileSize'    => $fileSize,
1317
		'fileHash'    => $fileHash,
1318
		'filePerm'    => $filePerm,
1319
		'contentType' => $contentType,
1320
		'url'         => $uploadUrl,
1321
		'entityType'  => $entityType,
1322
	);
1323

  
1324
	return ( $docid, \%dataInfo );
1325
}
1326

  
1327
sub datafileInfo {
1328
	my $finfo = shift;
1329
	$finfo =~ s/ondisk://g;
1330
	return my ( $docid, $fileHash ) = split( ":", $finfo );
1331
}
1332

  
1333
sub processFile {
1334
	my $fileName = shift;
1335

  
1336
	# test that we actually got a file
1337
	if ( !$fileName || cgi_error() ) {
1338
		debug( "Error receiving file " . cgi_error() );
1339
	}
1340

  
1341
	# write file to disk, get SHA1 hash and size
1342
	my ( $outFile, $fileHash ) = writeFile($fileName);
1343
	debug( "processed file to temp directory:  $outFile" );
1344

  
1345
	my $fileSize = stat($outFile)->size;
1346
	if ( $fileSize == 0 ) {
1347
		push( @errorMessages, "file $fileName is zero bytes!" );
1348
		debug("File $fileName is zero bytes!");
1349
	}
1350

  
1351
	# file is in Metacat, generate the pertinent EML elements
1352
	my $contentType = uploadInfo($fileName)->{'Content-Type'};
1353

  
1354
	# occasionally CGI.pm doesn't get the file info.  In this case,
1355
	# use a default MIME type of text/plain.  Seems fixed in the newer CGI.pm:
1356
	# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=313141
1357
	if ( !$contentType ) {
1358
		$contentType = 'text/plain';
1359
	}
1360

  
1361
	my %dataInfo = (
1362
		'fileName'    => $outFile,
1363
		'fileHash'    => $fileHash,
1364
		'contentType' => $contentType,
1365
	);
1366

  
1367
	return \%dataInfo;
1368
}
1369

  
1370
sub writeFile {
1371
	my $fileName = shift;
1372
	my $fileData;
1373
	my $length = 0;
1374
	my $buffer;
1375

  
1376
	my $cleanName = $fileName;
1377

  
1378
	# normalize input filenames; Windows filenames include full paths
1379
	$cleanName =~ s/.*[\/\\](.*)/$1/;
1380

  
1381
	while ( my $bytesRead = read( $fileName, $buffer, 4096 ) ) {
1382
		$fileData .= $buffer;
1383
		$length += $bytesRead;
1384
	}
1385

  
1386
	# create SHA1 sum to store file hash
1387
	my $ctx = Digest::SHA1->new;
1388
	$ctx->add($fileData);
1389
	my $digest = $ctx->hexdigest;
1390
    
1391
	# use tempfile for writing
1392
	my $tmp = File::Temp->new( 
1393
						TEMPLATE => 'tempXXXXX',
1394
                        DIR => $tempDir,
1395
                        SUFFIX => $cleanName, 
1396
                        UNLINK => 0);
1397
	my $outputName = $tmp->filename();
1398
	#open( OUT, ">$outputName" ) or die "Could not open: $!";
1399
	print $tmp $fileData;
1400
	close($tmp);
1401
	debug("Writing output, result is: $outputName");
1402
    
1403
	return ( $outputName, $digest );
1404
}
1405

  
1406
sub deleteRemovedData {
1407

  
1408
# if we have any associated datafiles which are scheduled for deletion, remove them now
1409
	for ( my $delNum = 0 ; $delNum <= $FORM::delCount ; $delNum++ ) {
1410

  
1411
	  # need to look up the actual upload number, which is contained in the name
1412
		my $upNum = param("deletefile_$delNum");
1413
		$upNum =~ s/uploadname_//;
1414
		my $upn = param("upload_$upNum");
1415
		if ( hasContent($upn) ) {
1416
			debug("Deleting upload_$upNum, $upn");
1417
			if ( grep { $_ eq ("uploadname_$upNum") } @FORM::deletefile ) {
1418
				if ( param("upload_$upNum") =~ /ondisk/ ) {
1419
					debug(
1420
						"got a file which is ondisk, proceeding with deletion");
1421
					deleteFileData( param("upload_$upNum") );
1422
				}
1423
				else {
1424
					debug(
1425
"got an old reference, not yet in EML, remove from tempdir"
1426
					);
1427
					deleteFile( param("uploadname_$upNum") );
1428
				}
1429
			}
1430
			else {
1431
				debug("Name didn't match in deletefile list");
1432
			}
1433
		}
1434
	}
1435
}
1436

  
1437
sub deleteFile {
1438
	my $input    = shift;
1439
	#my $fileName = $tempDir . "/" . $input;
1440
	my $fileName = $input;
1441

  
1442
	if ( -e $fileName ) {
1443
		unlink $fileName
1444
		  or debug("Failed to delete file $fileName.");
1445
	}
1446
	else {
1447
		debug("Unable to find file $fileName");
1448
	}
1449
	if ( !-e $fileName ) {
1450
		debug("Successfully deleted $fileName");
1451
	}
1452
}
1453

  
1454
sub deleteFileData {
1455
	my $input = shift;
1456
	my ( $docid, $fileHash ) = datafileInfo($input);
1457
	my $metacat = Metacat->new($metacatUrl);
1458

  
1459
	my ( $username, $password ) = getCredentials();
1460
	my $response = $metacat->login( $username, $password );
1461
	if ( !$response ) {
1462
		my $msg = $metacat->getMessage();
1463
		push( @errorMessages,
1464
			"Failed to login with credentials for `$username`. Error was $msg"
1465
		);
1466
		debug(
1467
"Failed to login with given credentials for username $username, Error is: $msg"
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff