Parent Directory
|
Revision Log
modified use lib lines in cgi-scripts, scripts, courseScripts removed Global.pm updating and use lib line code from system_webwork_setup modified Global.pm to use webworkConfig (which is not in the repository!)
1 #!/usr/local/bin/webwork-perl 2 3 ## $Id$ 4 5 #################################################################### 6 # Copyright @ 1995-1998 University of Rochester 7 # All Rights Reserved 8 #################################################################### 9 10 11 ############################################################################### 12 ############ PRELIMINARY SETUP ####################### 13 ############################################################################### 14 15 use lib '.'; use webworkInit; # WeBWorKInitLine 16 17 use Global; 18 use CGI qw(:standard); 19 use Auth; 20 use TimeLocal; # the module Time::Local.pm has a bug which interacts 21 # with DProf. (They call a subroutine assuming @_ doesn't change. 22 23 use strict; 24 25 # begin Timing code 26 use Benchmark; 27 my $beginTime = new Benchmark; 28 # end Timing code 29 30 31 &CGI::ReadParse(*main::inputs); 32 my %inputs=%main::inputs; 33 34 # get primary data from CGI form 35 my $User = $inputs{'user'}; 36 my $Course = $inputs{'course'}; 37 my $Key = $inputs{'key'}; 38 my $psvn = $inputs{'probSetKey'}; 39 40 # set course environment 41 &Global::getCourseEnvironment($Course); 42 43 my $scriptDirectory = getWebworkScriptDirectory($Course); 44 my $databaseDirectory = getCourseDatabaseDirectory($Course); 45 my $cgiURL = getWebworkCgiURL($Course); 46 my $htmlURL = getCourseHtmlURL($Course); 47 my $logsDirectory = getCourseLogsDirectory($Course); 48 49 require "${scriptDirectory}$Global::DBglue_pl"; 50 require "${scriptDirectory}$Global::classlist_DBglue_pl"; 51 require "${scriptDirectory}$Global::FILE_pl"; 52 require "${scriptDirectory}HTMLglue.pl"; 53 54 my $keyFile = getCourseKeyFile($Course); 55 &verify_key($inputs{'user'}, $inputs{'key'}, "$keyFile", $inputs{'course'}); 56 57 my $permissionsFile = &Global::getCoursePermissionsFile($inputs{'course'}); 58 my $permissions = &get_permissions($inputs{'user'}, $permissionsFile); 59 60 if ($permissions != $Global::instructor_permissions ) { 61 print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n"; 62 print &html_NO_PERMISSION; 63 exit(0); 64 } 65 66 # get additional data from calling CGI form 67 my ( $Mode, $studentLogin, $setNumber); 68 69 $Mode = "HTML"; #default viewing mode 70 $Mode = $inputs{'Mode'} if defined($inputs{'Mode'}); 71 $studentLogin = $inputs{'studentLogin'}; 72 $setNumber = $inputs{'setNo'}; 73 74 # if the psvn is not given we need to derive it from the set number and 75 # the student login ID 76 if (!defined($psvn) ) { 77 unless ( defined($studentLogin) && defined($setNumber) ) { 78 Global::error("DataMunger: Need psvn, or studentLogin and setNumber"); 79 } 80 my %loginList = &getAllSetNumbersForStudentLoginHash($studentLogin); 81 $psvn =$loginList{$setNumber}; 82 } 83 84 85 # define data to be displayed in the form 86 # the data for this will be loaded by the subroutine load 87 # my (@row1, @row2, @row3, @row4); 88 # my ($StudentLastName, $StudentFirstName, $StudentID); 89 # @row1 = qw(StudentLastName StudentFirstName StudentID); 90 # 91 # my ($StudentStatus, $StudentGrade, $SetNumber); 92 # @row2 = qw(StudentStatus StudentGrade SetNumber); 93 # 94 # my ($OpenDate, $DueDate, $AnswerDate ); 95 # @row3 = qw(OpenDate DueDate AnswerDate ); 96 # 97 # my ($StudentLogin, $ClassSection ); 98 # @row4 = qw(StudentLogin ClassSection ); 99 # my ($SetHeaderFileName, $ProbHeaderFileName ); 100 # @row5 = qw(SetHeaderFileName, ProbHeaderFileName ); 101 102 103 ############################################################################### 104 ############ MODIFY SET DATA IN THE DATABASE ####################### 105 ############################################################################### 106 107 108 # First make sure that the psvn is properly defined 109 # then save the information from the CGI form to the database 110 # Whether or not information is saved, at the end of this block 111 # the most current information has been placed in %probSetRecord 112 # using &fetchProbSetRecord. 113 if (not &fetchProbSetRecord($psvn)) { 114 Global::error("in dataMunger.pl:","Can't find record with psvn = $psvn 115 in the database"); 116 } 117 $studentLogin = getStudentLogin($psvn); 118 attachCLRecord($studentLogin); 119 120 if (defined( $inputs{'save'} ) && $inputs{'save'} eq "ON" ) { 121 # in this case we obtain the data from the CGI from and store it in the database 122 123 # update the database from the CGI script: 124 &updateDatabase($psvn); 125 # loads the information into %probSetRecord, 126 # modifies the data and saves it back to the database 127 # This effectively executes fetchProbSetRecord 128 # so that the contents of %probSetRecord is now current 129 130 #log the changes: -- the format for loggin the changes needs improvement 131 &logChanges( &getProbSetRecord() ); 132 &print_modification_form; 133 134 } elsif (defined($inputs{'save'}) && $inputs{'save'} eq "OFF" ){ 135 # No new information in the calling CGI form 136 # and the information has already been loaded into %probSetRecord using &fetchProbSetRecord($psvn); 137 # Nothing needs to be done in this case except print the form 138 &print_modification_form; 139 } elsif ( defined($inputs{'deleteMode'}) && $inputs{'deleteMode'} eq 'delete') { 140 # In this case the problem is deleted 141 my $psvnSetNumber = getSetNumber($psvn); 142 &deleteProbSetRecord($psvn); 143 # remove .sco file if it exists 144 system ("rm ${databaseDirectory}S${psvnSetNumber}-${psvn}.sco") if (-e "${databaseDirectory}S${psvnSetNumber}-${psvn}.sco"); 145 # remove any l2h files 146 my $l2hDir = getCoursel2hDirectory(); 147 my $tempDir = convertPath("${l2hDir}set${psvnSetNumber}/*-$psvn"); 148 system ("rm -rf $tempDir"); 149 &record_successfully_deleted_message; #reload empty record 150 } else { 151 152 # The calling CGI script must define the 'save' variable or the 'deleteMode' variable 153 Global::error( "<P><B>in dataMunger.pl:<BR>", "No value for 'save' mode in the calling CGI form.</B><P>"); 154 } 155 156 # begin Timing code 157 my $endTime = new Benchmark; 158 &Global::logTimingInfo($beginTime,$endTime,"dataMunger.pl",$Course,$User); 159 # end Timing code 160 exit; 161 162 #### END of main program 163 164 ############################################################################### 165 ############################ SUBROUTINES ############################ 166 ############################################################################### 167 168 169 ############################################################################### 170 ########################## PRINT FORM ############################## 171 ############################################################################### 172 sub print_modification_form { 173 print &htmlTOP("data for the problem set version number $psvn"); 174 print <<END_OF_HTML; 175 176 <A HREF="${cgiURL}profLogin.pl?user=$inputs{'user'}&key=$inputs{'key'}&course=$inputs{'course'}"> 177 <IMG SRC="${Global::upImgUrl}" align="right" BORDER=1 ALT="[Up]"></A><p> 178 <H3 ALIGN ="CENTER">Class Identification: $inputs{'course'}</H3> 179 <H3 ALIGN ="CENTER">Data for problem set version number: <FONT COLOR="#AA4400">$psvn</FONT></H3> 180 <HR SIZE =2> 181 <FORM ACTION="${cgiURL}dataMunger.pl" METHOD=POST> 182 183 Changes can be saved only if the Read/Write Mode button is selected: <BR> 184 185 <INPUT TYPE="radio" CHECKED NAME="save" VALUE="OFF" > Read Only Mode <BR> 186 <INPUT TYPE="radio" NAME="save" VALUE="ON"> Read/Write Mode <B>Make a backup copy of your database first.</B><BR> 187 <INPUT TYPE="hidden" NAME="firsttime" VALUE=0> 188 END_OF_HTML 189 190 191 ###################################################### 192 # return messages 193 #print message about saving to the database and current mode of CGI form 194 if (defined( $inputs{'firsttime'} ) && $inputs{'firsttime'} == 0 ) { 195 if (defined( $inputs{'save'} ) && $inputs{'save'} eq "ON" ) { 196 print "<P><FONT COLOR='#ff00aa'><B>DATABASE MODIFIED</B></font> <P>"; 197 } elsif (defined($inputs{'save'}) && $inputs{'save'} eq "OFF" ){ 198 199 print "<P><FONT COLOR='#ff00aa'><B>READ ONLY MODE: DATABASE UNCHANGED</B></font> <P>"; 200 201 } else { 202 # When initially entering this CGI the 'save' mode is undefined. 203 wwerror( $0, "No value for 'save' mode.</B><P>"); 204 } 205 } 206 # submit button 207 208 print qq!<INPUT TYPE="SUBMIT" VALUE="SAVE CHANGES"><INPUT TYPE = "RESET" VALUE= "RESET FORM"> <BR>!; 209 210 211 # Get set data 212 my $StudentLastName = CL_getStudentLastName($studentLogin); 213 my $StudentFirstName = CL_getStudentFirstName($studentLogin); 214 my $StudentID = CL_getStudentID($studentLogin); 215 my $StudentStatus = CL_getStudentStatus($studentLogin); 216 my $SetNumber = &getSetNumber($psvn); 217 my $OpenDate = &getOpenDate($psvn); 218 my $DueDate = &getDueDate($psvn); 219 my $AnswerDate = &getAnswerDate($psvn); 220 my $ClassSection = CL_getClassSection($psvn); 221 my $ClassRecitation = CL_getClassRecitation($psvn); 222 my $SetHeaderFileName = &getSetHeaderFileName($psvn); 223 my $ProbHeaderFileName = &getProbHeaderFileName($psvn); 224 my $StudentLogin = $studentLogin; 225 226 # replace empty strings by a non breaking space 227 $ClassSection = ' ' unless ($ClassSection =~ /\S/); 228 $ClassRecitation = ' ' unless ($ClassRecitation =~ /\S/); 229 $SetHeaderFileName = ' ' unless ($SetHeaderFileName =~ /\S/); 230 $ProbHeaderFileName = ' ' unless ($ProbHeaderFileName =~ /\S/); 231 232 233 # format the dates properly 234 235 $OpenDate = &formatDateAndTime($OpenDate); 236 $DueDate = &formatDateAndTime($DueDate); 237 $AnswerDate = &formatDateAndTime($AnswerDate); 238 239 # continue printing form ###################################################### 240 print &sessionKeyInputs(\%inputs); 241 print qq!<INPUT TYPE="HIDDEN" NAME="probSetKey" VALUE="$psvn">!; 242 print qq! <TABLE BORDER="1" CELLPADDING="1" CELLSPACING="2" > <FONT SIZE=-2>!; 243 244 print "<TR>\n"; 245 print &formatHeaderCell("Last Name"); 246 print &formatHeaderCell("First Name"); 247 print &formatHeaderCell("Student ID" ); 248 print "</TR>\n"; 249 print "<TR>\n"; 250 print &formatFixedDataCell("StudentLastName",$StudentLastName, "20"); 251 print &formatFixedDataCell("StudentFirstName", $StudentFirstName, "20"); 252 print &formatFixedDataCell("StudentID", $StudentID, "20"); 253 print "</TR>\n"; 254 255 print "<TR>\n"; 256 print &formatHeaderCell("Student login name"); 257 print &formatHeaderCell("Enrollment Status"); 258 print &formatHeaderCell("Set Number" ); 259 print "</TR>\n"; 260 print "<TR>\n"; 261 print &formatFixedDataCell("StudentLogin",$StudentLogin, "20"); 262 print &formatFixedDataCell("StudentStatus",$StudentStatus, "20"); 263 print &formatFixedDataCell("SetNumber", $SetNumber, "20"); 264 print "</TR>\n"; 265 266 print "<TR>\n"; 267 print &formatHeaderCell("Class Section"); 268 print &formatHeaderCell("Class Recitation"); 269 print "</TR>\n"; 270 271 print "<TR>\n"; 272 print &formatFixedDataCell("ClassSection", $ClassSection, "20"); 273 print &formatFixedDataCell("ClassRecitation", $ClassRecitation, "20"); 274 print "</TR>\n"; 275 276 print "<TR>\n"; 277 print &formatHeaderCell("Open Date"); 278 print &formatHeaderCell("Due Date"); 279 print &formatHeaderCell("Answer Date" ); 280 print "</TR>\n"; 281 282 print "<TR>\n"; 283 print &formatDataCell("OpenDate",$OpenDate, "20"); 284 print &formatDataCell("DueDate", $DueDate, "20"); 285 print &formatDataCell("AnswerDate", $AnswerDate, "20"); 286 print "</TR>\n"; 287 288 289 290 print "<TR>\n"; 291 print &formatHeaderCell("Paper Header File Name" ); 292 print &formatHeaderCell("Screen Header File Name" ); 293 print "</TR>\n"; 294 295 print "<TR>\n"; 296 print &formatFixedDataCell("SetHeaderFileName", $SetHeaderFileName, "20"); 297 print &formatFixedDataCell("ProbHeaderFileName", $ProbHeaderFileName, "20"); 298 print "</TR>\n"; 299 300 print "</TR>\n"; 301 print " </FONT></TABLE>"; 302 303 print qq! <TABLE BORDER="1" CELLPADDING="1" CELLSPACING="2" >!; 304 my $i; 305 my @row5; 306 my @problems = sort {$a <=> $b} &getAllProblemsForProbSetRecord($psvn); 307 foreach $i (@problems) { 308 @row5 = ("ProblemFileName$i", "ProblemStatus$i","ProblemSeed$i", "ProblemValue$i", "ProblemMaxNumOfIncorrectAttemps$i"); 309 print "<TR>"; 310 print &formatHeaderCell( qq! 311 <A HREF="${Global::processProblem_CGI}?probSetKey=$psvn&probNum=$i&Mode=$Mode&course=$Course&user=$User&key=$Key" TARGET="ViewProblem"> 312 Problem $i</A>!); 313 314 print &formatHeaderCell( "Attempted"); 315 print &formatHeaderCell( "Status"); 316 print &formatHeaderCell( "Correct"); 317 print &formatHeaderCell( "Wrong"); 318 print &formatHeaderCell( "Seed"); 319 print &formatHeaderCell( "Value"); 320 print &formatHeaderCell( "MaxAttmp"); 321 print "</TR>"; 322 323 print "<TR>"; 324 325 print &formatFixedDataCell( "ProblemFileName$i" , &getProblemFileName($i,$psvn) ,"30" ); 326 print &formatDataCell( "ProblemAttempted$i" , &getProblemAttempted($i,$psvn) ,"1"); 327 print &formatDataCell( "ProblemStatus$i" , &getProblemStatus($i,$psvn) ,"5"); 328 my $correctAns = &getProblemNumOfCorrectAns($i,$psvn); 329 my $incorrectAns = &getProblemNumOfIncorrectAns($i,$psvn); 330 $correctAns = "0" unless $correctAns; # Force 0 to print instead of a space 331 $incorrectAns = "0" unless $incorrectAns; # ditto 332 print &formatDataCell( "ProblemNumOfCorrectAns$i" , $correctAns ,"2"); 333 print &formatDataCell( "ProblemNumOfIncorrectAns$i" , $incorrectAns ,"2"); 334 print &formatDataCell( "ProblemSeed$i" , &getProblemSeed($i,$psvn) ,"7"); 335 print &formatFixedDataCell( "ProblemValue$i" , &getProblemValue($i,$psvn) ,"4"); 336 print &formatDataCell( "ProblemMaxNumOfIncorrectAttemps$i" , &getProblemMaxNumOfIncorrectAttemps($i,$psvn) ,"4"); 337 print "</TR>"; 338 339 } 340 341 342 print <<END_HTML; 343 </TABLE > 344 345 </FORM> 346 END_HTML 347 348 349 # FORM for downloading postscript versions 350 print qq! 351 <FORM action="${Global::cgiWebworkURL}welcomeAction.pl"> 352 <HR NOSHADE><H4>Download the postscript version of this problem set:</H4>\n 353 Problem Set Number $SetNumber -- psvn: $psvn -- for $StudentLastName, $StudentFirstName<BR> 354 <INPUT TYPE='HIDDEN' NAME='local_psvns' VALUE="$psvn"> 355 <INPUT TYPE='HIDDEN' NAME='action' VALUE='Get_hard_copy'> 356 <B>Download Type:</B> <INPUT TYPE=RADIO NAME=\"downloadType\" VALUE=\"ps\" CHECKED><B>postscript</B> format 357 <INPUT TYPE=RADIO NAME=\"downloadType\" VALUE=\"pdf\"><B>pdf</B> format 358 <INPUT TYPE=RADIO NAME=\"downloadType\" VALUE=\"TeX\"><B>TeX</B> format 359 <INPUT TYPE=RADIO NAME=\"downloadType\" VALUE=\"dvi\"><B>DVI</B> format<BR> 360 <INPUT TYPE=CHECKBOX NAME=\"ShowAns\" VALUE=\"1\"> Show answers in hard copy.<BR> 361 362 !; 363 364 print &sessionKeyInputs(\%inputs); 365 366 print qq! 367 <br><input type="submit" value="Download File"> 368 </FORM> 369 !; 370 371 # form for viewing student summary 372 print qq! 373 <FORM ACTION="studentSummary.pl" METHOD=POST>\n 374 <HR NOSHADE><H4>Form for viewing student summary of homework</H4>\n 375 <INPUT TYPE="HIDDEN" NAME="studentLogin" VALUE = "$StudentLogin"> 376 !; 377 378 print &sessionKeyInputs(\%inputs); 379 380 print qq! 381 <input type="submit" value="Get homework summary">\n 382 </FORM> 383 !; 384 385 # form for deleting problem set 386 print qq! 387 <HR NOSHADE><H3>Delete this problem set:</H3>\n 388 Problem Set Number $SetNumber -- psvn: $psvn -- for $StudentLastName, $StudentFirstName<BR> 389 <B>This action cannot be undone\!</B> 390 <FORM ACTION="${cgiURL}dataMunger.pl" METHOD=POST>\n 391 <INPUT TYPE="HIDDEN" NAME="probSetKey" VALUE="$psvn">\n 392 <INPUT TYPE="RADIO" NAME="deleteMode" VALUE="save" CHECKED> Off<BR>\n 393 <INPUT TYPE="RADIO" NAME="deleteMode" VALUE="delete"> Delete this record 394 !; 395 396 print &sessionKeyInputs(\%inputs); 397 398 print qq! 399 <br><input type="submit" value="Delete this person's problem set">\n 400 </FORM> 401 !; 402 403 404 print &htmlBOTTOM("dataMunger.pl", \%inputs); 405 406 } # end of print_modification_form 407 408 409 sub updateDatabase { 410 my $psvn = shift @_; 411 &fetchProbSetRecord($psvn); 412 413 my $time1 = &unformatDateAndTime($inputs{'OpenDate'}); 414 my $time2 = &unformatDateAndTime($inputs{'DueDate'}); 415 my $time3 = &unformatDateAndTime($inputs{'AnswerDate'}); 416 if ($time2 < $time1 or $time3 < $time2) { 417 &Global::error('Dates not in chronological order', "The open date: $inputs{'OpenDate'}, 418 due date: $inputs{'DueDate'}, and answer date: $inputs{'AnswerDate'} must be in chronologicasl order."); 419 } 420 &putOpenDate ($time1,$psvn); 421 &putDueDate ($time2,$psvn); 422 &putAnswerDate ($time3,$psvn); 423 424 425 # now update the problem information 426 # @problems was defined "globally" within this file 427 my @problems = sort {$a <=> $b} &getAllProblemsForProbSetRecord($psvn); 428 my ($i,$old_seed, $new_seed); 429 my $l2hDir = getCoursel2hDirectory(); 430 foreach $i (@problems) { 431 $old_seed = getProblemSeed($i,$psvn); 432 $new_seed = stripWhiteSpace($inputs{"ProblemSeed$i"}); 433 # &putProblemFileName( stripWhiteSpace($inputs{"ProblemFileName$i"}), $i,$psvn); 434 &putProblemAttempted( stripWhiteSpace($inputs{"ProblemAttempted$i"}), $i,$psvn); 435 &putProblemStatus( stripWhiteSpace($inputs{"ProblemStatus$i"}), $i,$psvn); 436 &putProblemNumOfCorrectAns( stripWhiteSpace($inputs{"ProblemNumOfCorrectAns$i"}), $i,$psvn); 437 &putProblemNumOfIncorrectAns( stripWhiteSpace($inputs{"ProblemNumOfIncorrectAns$i"}), $i,$psvn); 438 # &putProblemValue( stripWhiteSpace($inputs{"ProblemValue$i"}), $i,$psvn); 439 &putProblemMaxNumOfIncorrectAttemps( stripWhiteSpace($inputs{"ProblemMaxNumOfIncorrectAttemps$i"}), $i,$psvn); 440 &putProblemSeed( $new_seed,$i,$psvn); 441 442 if ($old_seed != $new_seed) { ## remove latex2html cached images 443 my $psvnSetNumber = getSetNumber($psvn); 444 my $tempDir = convertPath("${l2hDir}set${psvnSetNumber}/${i}-$psvn"); 445 system ("rm -rf $tempDir"); 446 } 447 } 448 # save the updated information to the database 449 &saveProbSetRecord($psvn); 450 } 451 # logs the incremental changes made by dataMunger to a log file 452 sub logChanges { 453 my @dataArray = @_; 454 my $fullLogFileName ="${logsDirectory}dataMunger.log"; 455 open(LOGFILE,">>$fullLogFileName") || &Global::error( "Can't open $fullLogFileName"); 456 457 my $timeNow = formatDateAndTime(time); 458 print LOGFILE "\n$Course, psvn is $psvn, user is $User, time is $timeNow, data is: "; 459 my $dataString = join( ' ',@dataArray); 460 print LOGFILE "@dataArray\n" ; 461 close(LOGFILE); 462 } 463 464 sub formatDataCell { 465 my ($name,$value,$size) = @_; 466 # if the data hasn't been entered it appears as a blank: 467 $value = '' unless defined($value); 468 469 my $out = qq! 470 <TD ALIGN=CENTER VALIGN=MIDDLE > 471 <INPUT TYPE="TEXT" NAME="$name" VALUE="$value", SIZE="$size"> 472 </TD> 473 !; 474 $out; 475 } 476 sub formatFixedDataCell { 477 my ($name,$value,$size) = @_; 478 # if the data hasn't been entered it appears as a blank: 479 $value = '' unless defined($value); 480 481 my $out = qq! 482 <TD ALIGN=CENTER VALIGN=MIDDLE > 483 <INPUT TYPE="HIDDEN" NAME="$name" VALUE="$value"> 484 $value 485 </TD> 486 !; 487 $out; 488 } 489 sub formatHeaderCell { 490 my ($item,$options) = @_; 491 $options = '' unless defined($options); 492 my $out = qq! 493 <TH ALIGN=CENTER VALIGN=MIDDLE $options> 494 $item 495 </TH> 496 !; 497 $out; 498 } 499 500 501 502 sub record_successfully_deleted_message{ 503 504 print &htmlTOP("data for the problem set version number $psvn"); 505 print <<END_OF_HTML; 506 <A HREF="${cgiURL}profLogin.pl?user=$inputs{'user'}&key=$inputs{'key'}&course=$inputs{'course'}"> 507 <IMG SRC="${Global::upImgUrl}" align="right" BORDER=1 ALT="[Up]"></A> 508 END_OF_HTML 509 510 my $setNumber = getSetNumber($psvn); 511 my $studentName = CL_getStudentName($studentLogin); 512 print qq!<P><B> Problem set version $psvn for set number !, 513 $setNumber, " for ", 514 $studentName, 515 " deleted.</B><P>"; 516 print &htmlBOTTOM("dataMunger.pl", \%inputs); 517 518 }
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |