#!/home/wziemer/ww/perl/bin/perl # # W.K. Ziemer 2002 for webwork 1.7, wziemer@csulb.edu # extract answers from the access log. # # these lines should be all one needs to modify for other systems. # use lib "/var/www/webwork/system/lib"; use Global; require "${Global::scriptDirectory}$Global::DBglue_pl"; $webwork_system_path = "/var/www/webwork/system"; $tmpDir = "/var/www/webwork/courses"; # #input desired information # assembling a system fgrep call to the access log # if(@ARGV == 0){ print "Course ID? "; chomp( $courseID = ); $logfile = "$webwork_system_path/logs/access_log"; print "Student's user name: "; chomp($user = ); $shellstr = "fgrep $user $logfile | fgrep course=$courseID"; print "Problem number: "; chomp( $prob = ); if($prob){ $shellstr = $shellstr."|fgrep Num=$prob " }; print "Set name (e.g. setWeek1 is Week1): "; chomp( $set = ); if($set){ $psvn = getPsvnFromDB($courseID, $user, $set); exit(1) unless($psvn); # trap error from subroutine $shellstr = $shellstr."|fgrep probSetKey=$psvn " }else{ $psvn = '' }; $shellstr = $shellstr.">${tmpDir}/tmpfile"; }elsif(@ARGV==2){ $logfile = "$webwork_system_path/logs/access_log"; $courseID = $ARGV[0]; $user = $ARGV[1]; $psvn = ''; $shellstr = "fgrep $courseID $logfile | fgrep $user > ${tmpDir}/tmpfile"; }elsif(@ARGV==4){ $courseID = $ARGV[0]; $logfile = "$webwork_system_path/logs/access_log"; $user = $ARGV[1]; $prob = $ARGV[2]; $set = $ARGV[3]; $psvn = getPsvnFromDB($courseID, $user, $set); exit(1) unless($psvn); # make sure $psvn exists $shellstr = "fgrep $courseID $logfile | fgrep $user |fgrep Num=$prob | fgrep $psvn > ${tmpDir}/tmpfile"; }else{ print "syntax: getAnswersFromLog.pl courseID user problem set"; print "example: getAnswersFromLog.pl demoCourse jdoe 6 Week1"; }; print "performing the command\n${shellstr}\n ... this may take a minute.\n\n"; system "$shellstr"; open(IN,"${tmpDir}/tmpfile")||die "can't open tmpfile: $!"; print "-------------------------------------------------------------\n"; print "The answers of $user in $courseID:\n\n"; # Typical entry is of the form #INFO () Thu Oct 4 20:43:57 2001: AnSwEr1=4;doNotRecordAns=0;ShowAns=0;ShowSol=0;probNum=1;probSetKey=35268;answer_form_submitted=1;course=ma112_Simpson;user=jennychahal;key=DZUI5FINKXWHMK7g6hSABpjIcpZ0D9ktDsHm6YDU;action=Submit%20Answer;Mode=Latex2HTML at /var/www/webwork/system/cgi/cgi-scripts/processProblem8.pl line 153 # while(){ chomp; next unless /answer_form_submitted=1/i; @ans = (); foreach $logitem ( split /;/ ){ if( $logitem =~ /(.*?:[0-9]{2}:[0-9]{2}.*?):/i ){ $date = $1; $date =~ s/INFO.*?\)//; }; if( $logitem =~ /Num=(.*)/ ){ $prob2 = $1; }; if( $logitem =~ /answer(.*?)=(.*)/i ){ $ans[$1] = $2; # translate URI-escaped strings into ascii $ans[$1] =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; }; if( $logitem =~ /SetKey=(.*)/ ){ $psvn2 = $1; if($psvn ne $psvn2){ $set = getSetFromPsvn($courseID,$psvn2); print "Problem Set $set:\n"; }else{ $psvn = $psvn2; } }; # print "$logitem\n"; }; for($i=1;$i<@ans;$i++){ print " Problem $prob2 \t Answer$i = $ans[$i]\t on $date\n"; }; }; close(IN)||die "close tmpfile failed: $!"; unlink "${tmpDir}/tmpfile"; print " Done.\n"; ################# subroutines #################### sub getSetFromPsvn { use lib "$webwork_system_path/lib"; use Global; require "${Global::scriptDirectory}$Global::DBglue_pl"; my ($courseID, $psvn) =@_ ; my $flag = 'R'; my %PROBSET; my @probSetRecord; my %probSetRecord; &Global::getCourseEnvironment($courseID); #get the database into %PROBSET &read_psvn_record(\$wwDbOj, \%PROBSET, "${Global::databaseDirectory}$Global::database", $flag, $Global::standard_tie_permission); unless(defined($PROBSET{$psvn})){ print "Error, the psvn $psvn is not in the database\n"; exit(1); } @probSetRecord = split(/[\&=]/, $PROBSET{$psvn}); # Hack: append a blank entry if odd number of elements. push(@probSetRecord, " ") unless @probSetRecord % 2 == 0; %probSetRecord = @probSetRecord; my $setNum = $probSetRecord{'stnm'}; # print "$setNum is the set\n"; return $setNum; } sub getPsvnFromDB { use lib "$webwork_system_path/lib"; use Global; require "${Global::scriptDirectory}$Global::DBglue_pl"; my ($courseID, $user, $set) = @_; my $psvn; my $flag = 'R'; my %PROBSET; my @probSetRecord; my %probSetRecord; &Global::getCourseEnvironment($courseID); #get the database into %PROBSET &read_psvn_record(\$wwDbOj, \%PROBSET, "${Global::databaseDirectory}$Global::database", $flag, $Global::standard_tie_permission); if(defined($PROBSET{"set<>$set"})){ @probSetRecord = split(/[\&=]/, $PROBSET{"set<>$set"}); # Hack: append a blank entry if odd number of elements. push(@probSetRecord, " ") unless @probSetRecord % 2 == 0; %probSetRecord = @probSetRecord; #print "$probSetRecord{$user}\n"; $psvn = $probSetRecord{$user}; }else{ print "No problem set of name set$set\n"; $psvn = 0; }; return $psvn; }