--- loncom/homework/grades.pm 2003/03/28 20:49:55 1.80 +++ loncom/homework/grades.pm 2003/04/11 17:57:37 1.84 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.80 2003/03/28 20:49:55 ng Exp $ +# $Id: grades.pm,v 1.84 2003/04/11 17:57:37 ng Exp $ # # Copyright Michigan State University Board of Trustees # @@ -717,7 +717,7 @@ sub sub_page_kw_js { height = 600; scrollbar = "yes"; } -// if (window.pWin) window.pWin.close(); +// if (window.pWin) {window.pWin.close(); window.pWin=null} pWin = window.open('', 'MessageCenter', 'toolbar=no,location=no,scrollbars='+scrollbar+',screenx=70,screeny=75,width=600,height='+height); pWin.focus(); pDoc = pWin.document; @@ -752,11 +752,7 @@ sub sub_page_kw_js { pDoc.write(" includemsg = 1;"); pDoc.write(" }"); pDoc.write(" imgformname = eval(\\"opener.document.SCORE.mailicon\\"+usrctr);"); - pDoc.write(" if (includemsg) {"); - pDoc.write(" imgformname.src = \\"$iconpath/mailto.gif\\";"); - pDoc.write(" } else {"); - pDoc.write(" imgformname.src = \\"$iconpath/mailbkgrd.gif\\";"); - pDoc.write(" }"); + pDoc.write(" imgformname.src = \\"$iconpath/\\"+((includemsg) ? \\"mailto.gif\\" : \\"mailbkgrd.gif\\");"); pDoc.write(" var includemsg = eval(\\"opener.document.SCORE.includemsg\\"+usrctr);"); pDoc.write(" includemsg.value = msgchk;"); @@ -1250,6 +1246,7 @@ KEYWORDS my $lastone = pop @col_fullnames; $msgfor .= ', '.(join ', ',@col_fullnames).' and '.$lastone.'.'; } + $msgfor =~ s/\'/\\'/g; $result.=''."\n". ' '. @@ -2779,6 +2776,15 @@ sub updateGradeByPage { # #------ start of section for handling grading by page/sequence --------- +sub defaultFormData { + my ($symb,$url)=@_; + return ' + '."\n". + ''."\n". + ''."\n". + ''."\n"; +} + sub getSequenceDropDown { my ($request,$symb)=@_; my $result=''; + opendir(DIR,$Apache::lonnet::perlvar{'lonScansDir'}); + my @files=sort(readdir(DIR)); + foreach my $filename (@files) { + if ($filename eq '.' or $filename eq '..') { next; } + $result.="\n"; + } + closedir(DIR); + $result.=""; + return $result; +} + +sub scantron_scantab { + my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab'); + my $result=''."\n"; + + return $result; +} + sub scantron_selectphase { my ($r) = @_; my ($symb,$url)=&get_symb_and_url($r); if (!$symb) {return '';} my $sequence_selector=&getSequenceDropDown($r,$symb); + my $default_form_data=&defaultFormData($symb,$url); + my $grading_menu_button=&show_grading_menu_form($symb,$url); + my $file_selector=&scantron_uploads(); + my $format_selector=&scantron_scantab(); my $result; $result.= < - - - +
+ + $default_form_data + + +
@@ -2823,12 +2859,12 @@ sub scantron_selectphase {
- - Filename of scoring office file: - + Filename of scoring office file: $file_selector +
+ Format of data file: $format_selector
@@ -2837,39 +2873,179 @@ sub scantron_selectphase {
+$grading_menu_button SCANTRONFORM return $result; } -sub scantron_configphase { +sub get_scantron_config { + my ($which) = @_; + my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab'); + my %config; + foreach my $line (<$fh>) { + my ($name,$descrip)=split(/:/,$line); + if ($name ne $which ) { next; } + chomp($line); + my @config=split(/:/,$line); + $config{'name'}=$config[0]; + $config{'description'}=$config[1]; + $config{'CODElocation'}=$config[2]; + $config{'CODEstart'}=$config[3]; + $config{'CODElength'}=$config[4]; + $config{'IDstart'}=$config[5]; + $config{'IDlength'}=$config[6]; + $config{'Qstart'}=$config[7]; + $config{'Qlength'}=$config[8]; + $config{'Qoff'}=$config[9]; + $config{'Qon'}=$config[10]; + last; + } + return %config; +} + +sub username_to_idmap { + my ($classlist)= @_; + my %idmap; + foreach my $student (keys(%$classlist)) { + $idmap{$classlist->{$student}->[&Apache::loncoursedata::CL_ID]}= + $student; + } + return %idmap; +} + +sub scantron_parse_scanline { + my ($line,$scantron_config)=@_; + my %record; + my $questions=substr($line,$$scantron_config{'Qstart'}-1); + my $data=substr($line,0,$$scantron_config{'Qstart'}-1); + if ($$scantron_config{'CODElocation'} ne 0) { + if ($$scantron_config{'CODElocation'} < 0) { + $record{'scantron.CODE'}=substr($data,$$scantron_config{'CODEstart'}-1, + $$scantron_config{'CODElength'}); + } else { + #FIXME interpret first N questions + } + } + $record{'scantron.ID'}=substr($data,$$scantron_config{'IDstart'}-1, + $$scantron_config{'IDlength'}); + my @alphabet=('A'..'Z'); + my $questnum=0; + while ($questions) { + $questnum++; + my $currentquest=substr($questions,0,$$scantron_config{'Qlength'}); + substr($questions,0,$$scantron_config{'Qlength'})=''; + if (length($currentquest) < $$scantron_config{'Qlength'}) { next; } + my (@array)=split(/$$scantron_config{'Qon'}/,$currentquest); + if (scalar(@array) gt 2) { + #FIXME do something intelligent with double bubbles + Apache->request->print("
Wha!!!
".scalar(@array).
+				   '-'.$currentquest.'-'.$questnum.'

'); + } + if (length($array[0]) eq $$scantron_config{'Qlength'}) { + $record{"scantron.$questnum.answer"}=''; + } else { + $record{"scantron.$questnum.answer"}=$alphabet[length($array[0])]; + } + } + $record{'scantron.maxquest'}=$questnum; + return \%record; +} + +sub scantron_add_delay { +} + +sub scantron_find_student { + my ($scantron_record,$idmap)=@_; + my $scanID=$$scantron_record{'scantron.ID'}; + foreach my $id (keys(%$idmap)) { + Apache->request->print('
checking studnet -'.$id.'- againt -'.$scanID.'- 
'); + if (lc($id) eq lc($scanID)) { Apache->request->print('success');return $$idmap{$id}; } + } + return undef; +} + +sub scantron_filter { + my ($curres)=@_; + if (ref($curres) && $curres->is_problem() && !$curres->randomout) { + return 1; + } + return 0; +} + +sub scantron_process_students { my ($r) = @_; - my $sequence=$ENV{'form.selectpage'}; - my $result; - $result.="got page $sequence"; + my (undef,undef,$sequence)=split(/___/,$ENV{'form.selectpage'}); + my ($symb,$url)=&get_symb_and_url($r); + if (!$symb) {return '';} + my $default_form_data=&defaultFormData($symb,$url); + + my %scantron_config=&get_scantron_config($ENV{'form.scantron_format'}); + my $scanlines=Apache::File->new($Apache::lonnet::perlvar{'lonScansDir'}."/$ENV{'form.scantron_selectfile'}"); + my $classlist=&Apache::loncoursedata::get_classlist(); + my %idmap=&username_to_idmap($classlist); + my $navmap=Apache::lonnavmaps::navmap->new($ENV{'request.course.fn'}.'.db',$ENV{'request.course.fn'}.'_parms.db',1, 1); + my $map=$navmap->getResourceByUrl($sequence); + my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); + $r->print("geto ".scalar(@resources)."
"); + my $result= < + + $default_form_data +SCANTRONFORM + $r->print($result); + + my @delayqueue; + + foreach my $line (<$scanlines>) { + chomp($line); + my $scan_record=&scantron_parse_scanline($line,\%scantron_config); + my ($uname,$udom); + if ($uname=&scantron_find_student($scan_record,\%idmap)) { + &scantron_add_delay(\@delayqueue,$line, + 'Unable to find a student that matches'); + } + $r->print('
doing studnet'.$uname.'
'); + ($uname,$udom)=split(/:/,$uname); + &Apache::lonnet::delenv('form\.counter$'); #') stupid emacs + &Apache::lonnet::appenv(%$scan_record); $Apache::lonxml::debug=1; &Apache::lonhomework::showhash(%ENV); $Apache::lonxml::debug=0; - #FIXME Needs to present some lines from the file and allow the instructor to specify which columns represent what data, possibly have some nice defaults setup, probably should do a pass through all problems for a student to get an idea of how many questions there are, and homw many lines we'll have, - return $result; -} - -sub scantron_process_students { + + foreach my $resource (@resources) { + my $result=&Apache::lonnet::ssi($resource->src(), + ('submitted' =>'scantron', + 'grade_target' =>'grade', + 'grade_username'=>$uname, + 'grade_domain' =>$udom, + 'grade_courseid'=>$ENV{'request.course.id'}, + 'grade_symb' =>$resource->symb())); + $r->print('
'.
+		      $resource->symb().'-'.
+		      $resource->src().'-'.'
result is'.$result); + last; + } + &Apache::lonnet::delenv('form\.counter$'); #') stupid emacs + &Apache::lonnet::delenv('scantron\.'); + last; + #FIXME + #get iterator for $sequence + #foreach question 'submit' the students answer to the server + # through grade target { + # generate data to pass back that includes grade recevied + #} + } + foreach my $delay (@delayqueue) { + #FIXME + #print out each delayed student with interface to select how + # to repair student provided info + #Expected errors include + # 1 bad/no stuid/username + # 2 invalid bubblings + + } #FIXME - # loop through students, { - # Check if studnet info valid, if not add line to delay queue - # foreach question 'submit' the students answer to the server - # through grade target { - # generate data to pass back that includes grade recevied - # } - # } - # loop through delay queue { - # print out each delayed student with interface to select how - # to repair student provided info - # Expected errors include - # 1 bad/no stuid/username - # 2 invalid bubblings - # } # if delay queue exists 2 submits one to process delayed students one # to ignore delayed students, possibly saving the delay queue for later @@ -3088,7 +3264,8 @@ GRADINGMENUJS 'Upload scores from file'."\n"; $result.=''. - ' '. + ' '. 'Grade scantron forms'."\n"; if ((&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'})) && ($symb)) { @@ -3221,8 +3398,8 @@ sub handler { } } elsif ($command eq 'scantron_selectphase') { $request->print(&scantron_selectphase($request)); - } elsif ($command eq 'scantron_configphase') { - $request->print(&scantron_configphase($request)); + } elsif ($command eq 'scantron_process') { + $request->print(&scantron_process_students($request)); } else { $request->print("Unknown action: $command:"); }