#!/usr/local/bin/perl ## $Id$ #################################################################### # Copyright @ 1995-1998 University of Rochester # All Rights Reserved #################################################################### ############################################################################### ############ PRELIMINARY SETUP ####################### ############################################################################### use lib '/ww/webwork/gage_system/webwork/system/lib/'; # mainWeBWorKDirectory use Global; use CGI qw(:standard); use Auth; use TimeLocal; # the module Time::Local.pm has a bug which interacts # with DProf. (They call a subroutine assuming @_ doesn't change. use strict; # begin Timing code use Benchmark; my $beginTime = new Benchmark; # end Timing code &CGI::ReadParse(*main::inputs); my %inputs=%main::inputs; # get primary data from CGI form my $User = $inputs{'user'}; my $Course = $inputs{'course'}; my $Key = $inputs{'key'}; my $psvn = $inputs{'probSetKey'}; # set course environment &Global::getCourseEnvironment($Course); my $scriptDirectory = getWebworkScriptDirectory($Course); my $databaseDirectory = getCourseDatabaseDirectory($Course); my $cgiURL = getWebworkCgiURL($Course); my $htmlURL = getCourseHtmlURL($Course); my $logsDirectory = getCourseLogsDirectory($Course); require "${scriptDirectory}$Global::DBglue_pl"; require "${scriptDirectory}$Global::classlist_DBglue_pl"; require "${scriptDirectory}$Global::FILE_pl"; require "${scriptDirectory}HTMLglue.pl"; my $keyFile = getCourseKeyFile($Course); &verify_key($inputs{'user'}, $inputs{'key'}, "$keyFile", $inputs{'course'}); my $permissionsFile = &Global::getCoursePermissionsFile($inputs{'course'}); my $permissions = &get_permissions($inputs{'user'}, $permissionsFile); if ($permissions != $Global::instructor_permissions ) { print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n"; print &html_NO_PERMISSION; exit(0); } # get additional data from calling CGI form my ( $Mode, $studentLogin, $setNumber); $Mode = "HTML"; #default viewing mode $Mode = $inputs{'Mode'} if defined($inputs{'Mode'}); $studentLogin = $inputs{'studentLogin'}; $setNumber = $inputs{'setNo'}; # if the psvn is not given we need to derive it from the set number and # the student login ID if (!defined($psvn) ) { unless ( defined($studentLogin) && defined($setNumber) ) { Global::error("DataMunger: Need psvn, or studentLogin and setNumber"); } my %loginList = &getAllSetNumbersForStudentLoginHash($studentLogin); $psvn =$loginList{$setNumber}; } # define data to be displayed in the form # the data for this will be loaded by the subroutine load # my (@row1, @row2, @row3, @row4); # my ($StudentLastName, $StudentFirstName, $StudentID); # @row1 = qw(StudentLastName StudentFirstName StudentID); # # my ($StudentStatus, $StudentGrade, $SetNumber); # @row2 = qw(StudentStatus StudentGrade SetNumber); # # my ($OpenDate, $DueDate, $AnswerDate ); # @row3 = qw(OpenDate DueDate AnswerDate ); # # my ($StudentLogin, $ClassSection ); # @row4 = qw(StudentLogin ClassSection ); # my ($SetHeaderFileName, $ProbHeaderFileName ); # @row5 = qw(SetHeaderFileName, ProbHeaderFileName ); ############################################################################### ############ MODIFY SET DATA IN THE DATABASE ####################### ############################################################################### # First make sure that the psvn is properly defined # then save the information from the CGI form to the database # Whether or not information is saved, at the end of this block # the most current information has been placed in %probSetRecord # using &fetchProbSetRecord. if (not &fetchProbSetRecord($psvn)) { Global::error("in dataMunger.pl:","Can't find record with psvn = $psvn in the database"); } $studentLogin = getStudentLogin($psvn); attachCLRecord($studentLogin); if (defined( $inputs{'save'} ) && $inputs{'save'} eq "ON" ) { # in this case we obtain the data from the CGI from and store it in the database # update the database from the CGI script: &updateDatabase($psvn); # loads the information into %probSetRecord, # modifies the data and saves it back to the database # This effectively executes fetchProbSetRecord # so that the contents of %probSetRecord is now current #log the changes: -- the format for loggin the changes needs improvement &logChanges( &getProbSetRecord() ); &print_modification_form; } elsif (defined($inputs{'save'}) && $inputs{'save'} eq "OFF" ){ # No new information in the calling CGI form # and the information has already been loaded into %probSetRecord using &fetchProbSetRecord($psvn); # Nothing needs to be done in this case except print the form &print_modification_form; } elsif ( defined($inputs{'deleteMode'}) && $inputs{'deleteMode'} eq 'delete') { # In this case the problem is deleted my $psvnSetNumber = getSetNumber($psvn); &deleteProbSetRecord($psvn); # remove .sco file if it exists system ("rm ${databaseDirectory}S${psvnSetNumber}-${psvn}.sco") if (-e "${databaseDirectory}S${psvnSetNumber}-${psvn}.sco"); # remove any l2h files my $l2hDir = getCoursel2hDirectory(); my $tempDir = convertPath("${l2hDir}set${psvnSetNumber}/*-$psvn"); system ("rm -rf $tempDir"); &record_successfully_deleted_message; #reload empty record } else { # The calling CGI script must define the 'save' variable or the 'deleteMode' variable Global::error( "

in dataMunger.pl:
", "No value for 'save' mode in the calling CGI form.

"); } # begin Timing code my $endTime = new Benchmark; &Global::logTimingInfo($beginTime,$endTime,"dataMunger.pl",$Course,$User); # end Timing code exit; #### END of main program ############################################################################### ############################ SUBROUTINES ############################ ############################################################################### ############################################################################### ########################## PRINT FORM ############################## ############################################################################### sub print_modification_form { print &htmlTOP("data for the problem set version number $psvn"); print < [Up]

Class Identification: $inputs{'course'}

Data for problem set version number: $psvn


Changes can be saved only if the Read/Write Mode button is selected:
Read Only Mode
Read/Write Mode Make a backup copy of your database first.
END_OF_HTML ###################################################### # return messages #print message about saving to the database and current mode of CGI form if (defined( $inputs{'firsttime'} ) && $inputs{'firsttime'} == 0 ) { if (defined( $inputs{'save'} ) && $inputs{'save'} eq "ON" ) { print "

DATABASE MODIFIED

"; } elsif (defined($inputs{'save'}) && $inputs{'save'} eq "OFF" ){ print "

READ ONLY MODE: DATABASE UNCHANGED

"; } else { # When initially entering this CGI the 'save' mode is undefined. wwerror( $0, "No value for 'save' mode.

"); } } # submit button print qq!
!; # Get set data my $StudentLastName = CL_getStudentLastName($studentLogin); my $StudentFirstName = CL_getStudentFirstName($studentLogin); my $StudentID = CL_getStudentID($studentLogin); my $StudentStatus = CL_getStudentStatus($studentLogin); my $SetNumber = &getSetNumber($psvn); my $OpenDate = &getOpenDate($psvn); my $DueDate = &getDueDate($psvn); my $AnswerDate = &getAnswerDate($psvn); my $ClassSection = CL_getClassSection($psvn); my $ClassRecitation = CL_getClassRecitation($psvn); my $SetHeaderFileName = &getSetHeaderFileName($psvn); my $ProbHeaderFileName = &getProbHeaderFileName($psvn); my $StudentLogin = $studentLogin; # replace empty strings by a non breaking space $ClassSection = ' ' unless ($ClassSection =~ /\S/); $ClassRecitation = ' ' unless ($ClassRecitation =~ /\S/); $SetHeaderFileName = ' ' unless ($SetHeaderFileName =~ /\S/); $ProbHeaderFileName = ' ' unless ($ProbHeaderFileName =~ /\S/); # format the dates properly $OpenDate = &formatDateAndTime($OpenDate); $DueDate = &formatDateAndTime($DueDate); $AnswerDate = &formatDateAndTime($AnswerDate); # continue printing form ###################################################### print &sessionKeyInputs(\%inputs); print qq!!; print qq! !; print "\n"; print &formatHeaderCell("Last Name"); print &formatHeaderCell("First Name"); print &formatHeaderCell("Student ID" ); print "\n"; print "\n"; print &formatFixedDataCell("StudentLastName",$StudentLastName, "20"); print &formatFixedDataCell("StudentFirstName", $StudentFirstName, "20"); print &formatFixedDataCell("StudentID", $StudentID, "20"); print "\n"; print "\n"; print &formatHeaderCell("Student login name"); print &formatHeaderCell("Enrollment Status"); print &formatHeaderCell("Set Number" ); print "\n"; print "\n"; print &formatFixedDataCell("StudentLogin",$StudentLogin, "20"); print &formatFixedDataCell("StudentStatus",$StudentStatus, "20"); print &formatFixedDataCell("SetNumber", $SetNumber, "20"); print "\n"; print "\n"; print &formatHeaderCell("Class Section"); print &formatHeaderCell("Class Recitation"); print "\n"; print "\n"; print &formatFixedDataCell("ClassSection", $ClassSection, "20"); print &formatFixedDataCell("ClassRecitation", $ClassRecitation, "20"); print "\n"; print "\n"; print &formatHeaderCell("Open Date"); print &formatHeaderCell("Due Date"); print &formatHeaderCell("Answer Date" ); print "\n"; print "\n"; print &formatDataCell("OpenDate",$OpenDate, "20"); print &formatDataCell("DueDate", $DueDate, "20"); print &formatDataCell("AnswerDate", $AnswerDate, "20"); print "\n"; print "\n"; print &formatHeaderCell("Paper Header File Name" ); print &formatHeaderCell("Screen Header File Name" ); print "\n"; print "\n"; print &formatFixedDataCell("SetHeaderFileName", $SetHeaderFileName, "20"); print &formatFixedDataCell("ProbHeaderFileName", $ProbHeaderFileName, "20"); print "\n"; print "\n"; print "
"; print qq! !; my $i; my @row5; my @problems = sort {$a <=> $b} &getAllProblemsForProbSetRecord($psvn); foreach $i (@problems) { @row5 = ("ProblemFileName$i", "ProblemStatus$i","ProblemSeed$i", "ProblemValue$i", "ProblemMaxNumOfIncorrectAttemps$i"); print ""; print &formatHeaderCell( qq! Problem $i!); print &formatHeaderCell( "Attempted"); print &formatHeaderCell( "Status"); print &formatHeaderCell( "Correct"); print &formatHeaderCell( "Wrong"); print &formatHeaderCell( "Seed"); print &formatHeaderCell( "Value"); print &formatHeaderCell( "MaxAttmp"); print ""; print ""; print &formatFixedDataCell( "ProblemFileName$i" , &getProblemFileName($i,$psvn) ,"30" ); print &formatDataCell( "ProblemAttempted$i" , &getProblemAttempted($i,$psvn) ,"1"); print &formatDataCell( "ProblemStatus$i" , &getProblemStatus($i,$psvn) ,"5"); my $correctAns = &getProblemNumOfCorrectAns($i,$psvn); my $incorrectAns = &getProblemNumOfIncorrectAns($i,$psvn); $correctAns = "0" unless $correctAns; # Force 0 to print instead of a space $incorrectAns = "0" unless $incorrectAns; # ditto print &formatDataCell( "ProblemNumOfCorrectAns$i" , $correctAns ,"2"); print &formatDataCell( "ProblemNumOfIncorrectAns$i" , $incorrectAns ,"2"); print &formatDataCell( "ProblemSeed$i" , &getProblemSeed($i,$psvn) ,"7"); print &formatFixedDataCell( "ProblemValue$i" , &getProblemValue($i,$psvn) ,"4"); print &formatDataCell( "ProblemMaxNumOfIncorrectAttemps$i" , &getProblemMaxNumOfIncorrectAttemps($i,$psvn) ,"4"); print ""; } print < END_HTML # FORM for downloading postscript versions print qq!

Download the postscript version of this problem set:

\n Problem Set Number $SetNumber -- psvn: $psvn -- for $StudentLastName, $StudentFirstName
Download Type: postscript format pdf format TeX format DVI format
Show answers in hard copy.
!; print &sessionKeyInputs(\%inputs); print qq!
!; # form for viewing student summary print qq!
\n

Form for viewing student summary of homework

\n !; print &sessionKeyInputs(\%inputs); print qq! \n !; # form for deleting problem set print qq!

Delete this problem set:

\n Problem Set Number $SetNumber -- psvn: $psvn -- for $StudentLastName, $StudentFirstName
This action cannot be undone\!
\n \n Off
\n Delete this record !; print &sessionKeyInputs(\%inputs); print qq!
\n !; print &htmlBOTTOM("dataMunger.pl", \%inputs); } # end of print_modification_form sub updateDatabase { my $psvn = shift @_; &fetchProbSetRecord($psvn); my $time1 = &unformatDateAndTime($inputs{'OpenDate'}); my $time2 = &unformatDateAndTime($inputs{'DueDate'}); my $time3 = &unformatDateAndTime($inputs{'AnswerDate'}); if ($time2 < $time1 or $time3 < $time2) { &Global::error('Dates not in chronological order', "The open date: $inputs{'OpenDate'}, due date: $inputs{'DueDate'}, and answer date: $inputs{'AnswerDate'} must be in chronologicasl order."); } &putOpenDate ($time1,$psvn); &putDueDate ($time2,$psvn); &putAnswerDate ($time3,$psvn); # now update the problem information # @problems was defined "globally" within this file my @problems = sort {$a <=> $b} &getAllProblemsForProbSetRecord($psvn); my ($i,$old_seed, $new_seed); my $l2hDir = getCoursel2hDirectory(); foreach $i (@problems) { $old_seed = getProblemSeed($i,$psvn); $new_seed = stripWhiteSpace($inputs{"ProblemSeed$i"}); # &putProblemFileName( stripWhiteSpace($inputs{"ProblemFileName$i"}), $i,$psvn); &putProblemAttempted( stripWhiteSpace($inputs{"ProblemAttempted$i"}), $i,$psvn); &putProblemStatus( stripWhiteSpace($inputs{"ProblemStatus$i"}), $i,$psvn); &putProblemNumOfCorrectAns( stripWhiteSpace($inputs{"ProblemNumOfCorrectAns$i"}), $i,$psvn); &putProblemNumOfIncorrectAns( stripWhiteSpace($inputs{"ProblemNumOfIncorrectAns$i"}), $i,$psvn); # &putProblemValue( stripWhiteSpace($inputs{"ProblemValue$i"}), $i,$psvn); &putProblemMaxNumOfIncorrectAttemps( stripWhiteSpace($inputs{"ProblemMaxNumOfIncorrectAttemps$i"}), $i,$psvn); &putProblemSeed( $new_seed,$i,$psvn); if ($old_seed != $new_seed) { ## remove latex2html cached images my $psvnSetNumber = getSetNumber($psvn); my $tempDir = convertPath("${l2hDir}set${psvnSetNumber}/${i}-$psvn"); system ("rm -rf $tempDir"); } } # save the updated information to the database &saveProbSetRecord($psvn); } # logs the incremental changes made by dataMunger to a log file sub logChanges { my @dataArray = @_; my $fullLogFileName ="${logsDirectory}dataMunger.log"; open(LOGFILE,">>$fullLogFileName") || &Global::error( "Can't open $fullLogFileName"); my $timeNow = formatDateAndTime(time); print LOGFILE "\n$Course, psvn is $psvn, user is $User, time is $timeNow, data is: "; my $dataString = join( ' ',@dataArray); print LOGFILE "@dataArray\n" ; close(LOGFILE); } sub formatDataCell { my ($name,$value,$size) = @_; # if the data hasn't been entered it appears as a blank: $value = '' unless defined($value); my $out = qq!
!; $out; } sub formatFixedDataCell { my ($name,$value,$size) = @_; # if the data hasn't been entered it appears as a blank: $value = '' unless defined($value); my $out = qq! !; $out; } sub formatHeaderCell { my ($item,$options) = @_; $options = '' unless defined($options); my $out = qq! !; $out; } sub record_successfully_deleted_message{ print &htmlTOP("data for the problem set version number $psvn"); print < [Up] END_OF_HTML my $setNumber = getSetNumber($psvn); my $studentName = CL_getStudentName($studentLogin); print qq!

Problem set version $psvn for set number !, $setNumber, " for ", $studentName, " deleted.

"; print &htmlBOTTOM("dataMunger.pl", \%inputs); }

$value $item