Diff for /loncom/interface/lonquickgrades.pm between versions 1.49.6.8 and 1.50

version 1.49.6.8, 2021/12/14 02:44:05 version 1.50, 2010/11/27 20:51:26
Line 29 Line 29
 package Apache::lonquickgrades;  package Apache::lonquickgrades;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http REDIRECT);  use Apache::Constants qw(:common :http);
 use POSIX;  use POSIX;
 use Apache::loncommon;  use Apache::loncommon;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::grades;  use Apache::grades;
 use Apache::lonuserstate;  
   
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
Line 58  sub real_handler { Line 57  sub real_handler {
         return OK;          return OK;
     }      }
   
     my $cangrade=&Apache::lonnet::allowed('mgr');      # Send header, don't cache this page
     my $showPoints =      &Apache::loncommon::no_cache($r);
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'standard';      $r->send_http_header;
   
     my $reinitresult;  
   
     if ($env{'request.course.id'}) {  
         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
         my $clientip = &Apache::lonnet::get_requestor_ip($r);  
         my ($blocked,$blocktext) =  
             &Apache::loncommon::blocking_status('grades',$clientip,$cnum,$cdom);  
         if ($blocked) {  
             my $checkrole = "cm./$cdom/$cnum";  
             if ($env{'request.course.sec'} ne '') {  
                 $checkrole .= "/$env{'request.course.sec'}";  
             }  
             unless ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) &&  
                     ($env{'request.role'} !~ m{^st\./$cdom/$cnum})) {  
                 &grades_blocked($r,$blocktext,$showPoints);  
                 return OK;  
             }  
         }  
     }  
   
     unless ($cangrade) {  
         # Check for critical messages and redirect if present.  
         my ($redirect,$url) = &Apache::loncommon::critical_redirect(300);  
         if ($redirect) {  
             &Apache::loncommon::content_type($r,'text/html');  
             $r->header_out(Location => $url);  
             return REDIRECT;  
         }  
   
         # Check if course needs to be re-initialized  
         my $loncaparev = $r->dir_config('lonVersion');  
         ($reinitresult,my @reinit) = &Apache::loncommon::needs_coursereinit($loncaparev);  
   
         if ($reinitresult eq 'switch') {  
             &Apache::loncommon::content_type($r,'text/html');  
             $r->send_http_header;  
             $r->print(&Apache::loncommon::check_release_result(@reinit));  
             return OK;  
         } elsif ($reinitresult eq 'update') {  
             my $cid = $env{'request.course.id'};  
             my $cnum = $env{'course.'.$cid.'.num'};  
             my $cdom = $env{'course.'.$cid.'.domain'};  
             &Apache::loncommon::content_type($r,'text/html');  
             $r->send_http_header;  
             &startpage($r,$showPoints);  
             my $preamble = '<div id="LC_update_'.$cid.'" class="LC_info">'.  
                            '<br />'.  
                            &mt('Your course session is being updated because of recent changes by course personnel.').  
                            ' '.&mt('Please be patient').'.<br /></div>'.  
                            '<div style="padding:0;clear:both;margin:0;border:0"></div>';  
             my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,undef,$preamble);  
             &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Updating course'));  
             $r->rflush();  
             my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");  
             &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Finished!'));  
             &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);  
             my $closure = <<ENDCLOSE;  
 <script type="text/javascript">  
 // <![CDATA[  
 \$("#LC_update_$cid").hide('slow');  
 // ]]>  
 </script>  
 ENDCLOSE  
             if ($ferr) {  
                 $r->print($closure.&Apache::loncommon::end_page());  
                 my $requrl = $r->uri;  
                 $env{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";  
                 $env{'user.reinit'} = 1;  
                 return HTTP_NOT_ACCEPTABLE;  
             } else {  
                $r->print($closure);  
             }  
         }  
     }  
   
     unless ($reinitresult eq 'update') {  
         # Send header, don't cache this page  
         &Apache::loncommon::no_cache($r);  
         $r->send_http_header;  
         &startpage($r,$showPoints);  
     }  
     $r->rflush();  
   
     &startGradeScreen($r);  
   
 #  
 # Pick student  
 #  
     my $uname;  
     my $udom;  
     my $stdid;  
     if ($cangrade) {  
         if ($env{'form.uname'}) { $uname=$env{'form.uname'}; }  
         if ($env{'form.udom'}) { $udom=$env{'form.udom'}; }  
         if ($env{'form.id'}) { $stdid=$env{'form.id'}; }  
         if (($stdid) && ($udom)) {  
             $uname=(&Apache::lonnet::idget($udom,[$stdid],'ids'))[1];  
         }  
         if (($stdid) && (!$uname)) {  
             $r->print('<p><span class="LC_warning">'.&mt("Unknown Student/Employee ID: [_1]",$stdid).'</span></p>');  
             $stdid='';  
         }  
         if (($uname eq '') && ($udom eq '')) {  
             $uname = $env{'user.name'};  
             $udom = $env{'user.domain'};  
         }  
         $r->print('<form method="post" name="quickform" action="/adm/quickgrades">');  
         my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.  
            &Apache::loncommon::selectstudent_link('quickform','uname','udom');  
         $r->print("<p>\n".&Apache::loncommon::studentbrowser_javascript()."\n");  
         $r->print(&mt('For User [_1] or Student/Employee ID [_2] at Domain [_3]'  
                  ,'<input type="text" value="'.$uname.'" size="12" name="uname" />'  
                  ,'<input type="text" value="'.$stdid.'" size="12" name="id" /> '  
                  ,$chooseopt).  
                  '&nbsp;&nbsp;<input type="submit" name="display" value="'.&mt('Display Individual Student').'" /></p>');  
         if (($uname) && ($udom)) {  
             $r->print('<p>'.&mt('Full Name: [_1]',&Apache::loncommon::plainname($uname,$udom)).'</p>');  
         }  
     } else {  
         $r->print('<p class="LC_info">'.&mt('This may take a few moments to display.').'</p>');  
     }  
     $r->rflush();  
   
       my $showPoints = 
           $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'standard';
       my $notshowSPRSlink = 
           (($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'external')
         || ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals'));
     my $notshowTotals=      my $notshowTotals=
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals';          $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals';
       my $showCategories=
           $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'categories';
   
     my ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,  
         $topLevelRight,$topLevelAttempted) = &getData($showPoints,$uname,$udom);  
   
     if (ref($navmap)) {      # Create the nav map
         &outputTable($r,$showPoints,$notshowTotals,$navmap,$totalParts,$totalPossible,      my $navmap = Apache::lonnavmaps::navmap->new();
                      $totalRight,$totalAttempted,$topLevelParts,$topLevelRight,  
                      $topLevelAttempted);      if (!defined($navmap)) {
     } else {  
         if ($cangrade) { $r->print("\n</form>\n"); }  
         my $requrl = $r->uri;          my $requrl = $r->uri;
         $env{'user.error.msg'} = "$requrl:bre:0:0:Navmap initialization failed.";          $env{'user.error.msg'} = "$requrl:bre:0:0:Navamp initialization failed.";
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
     if ($cangrade) { $r->print("\n</form>\n"); }  
     &endGradeScreen($r);  
     return OK;  
 }  
   
 sub grades_blocked {      # Keep this hash in sync with %statusIconMap in lonnavmaps; they
     my ($r,$blocktext,$caller) = @_;      # should match color/icon
     my $title = 'Points Display';      my $res = $navmap->firstResource(); # temp resource to access constants
     if ($caller eq 'spreadsheet') {   
         $title = 'Spreadsheet';      # Header
     } elsif ($env{'course.'.$env{'request.course.id'}.'.grading'} ne 'standard') {      my $title = "Grading and Statistics";#$showPoints ? "Points Display" : "Completed Problems Display";
         $title = 'Completed Problems Display';      my $brcrum = [{href=>"/adm/quickgrades",text => "Points Display"}];
     }      $r->print(&Apache::loncommon::start_page($title,undef,
     my $brcrum = [{href=>"/adm/quickgrades",text => $title}];                                              {'bread_crumbs' => $brcrum})
     &Apache::lonhtmlcommon::clear_breadcrumbs();               );
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/quickgrades',  
                                             text=> $title});  
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs($title);  
     &Apache::loncommon::content_type($r,'text/html');  
     &Apache::loncommon::no_cache($r);  
     $r->send_http_header;  
     $r->print(&Apache::loncommon::start_page($title).  
               $breadcrumbs.  
               $blocktext.  
               &Apache::loncommon::end_page());  
     return;  
 }  
   
 #  
 # Go through the complete course and collect data  
 #  
   
 sub getData {  
   
     my ($showPoints,$uname,$udom)=@_;      if (!$showPoints && !$notshowSPRSlink ) {
           $r->print('<p>'
                    .&mt('This screen shows how many problems (or problem parts) you have completed'
                        .', and how many you have not yet done.'
                        .' You can also look at [_1]a detailed score sheet[_2].'
                        ,'<a href="/adm/studentcalc">','</a>')
                    .'</p>');
       }
   
     # Create the nav map      $r->print('<p class="LC_info">'.&mt('This may take a few moments to display.').'</p>');
     my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);  
   
     if (!defined($navmap)) {      $r->rflush();
         return ();  
     }  
   
     my $res = $navmap->firstResource(); # temp resource to access constants      # End navmap using boilerplate
   
     my $iterator = $navmap->getIterator(undef, undef, undef, 1);      my $iterator = $navmap->getIterator(undef, undef, undef, 1);
     my $depth = 1;      my $depth = 1;
     $iterator->next(); # ignore first BEGIN_MAP      $iterator->next(); # ignore first BEGIN_MAP
     my $curRes = $iterator->next();      my $curRes = $iterator->next();
       
     # General overview of the following: Walk along the course resources.      # General overview of the following: Walk along the course resources.
     # For every problem in the resource, tell its parent maps how many      # For every problem in the resource, tell its parent maps how many
     # parts and how many parts correct it has. After that, each map will      # parts and how many parts correct it has. After that, each map will
Line 284  sub getData { Line 144  sub getData {
             my $stack = $iterator->getStack();              my $stack = $iterator->getStack();
                           
             for my $part (@{$parts}) {              for my $part (@{$parts}) {
    my $completionStatus = $curRes->getCompletionStatus($part);
  my $dateStatus = $curRes->getDateStatus($part);   my $dateStatus = $curRes->getDateStatus($part);
                 my $weight = $curRes->weight($part);  
                 my $problemstatus = $curRes->problemstatus($part);                  if ($completionStatus == $curRes->EXCUSED()) {
   
                 if ($curRes->solved($part) eq 'excused') {  
                     next;                      next;
                 }                  }
  if ($showPoints) {   if ($showPoints) {
     my $score = 0;      my $score = 0;
     # If we're not telling status and the answer date isn't passed yet,       # If we're not telling status and the answer date isn't passed yet, 
     # it's an "attempted" point      # it's an "attempted" point
     if ((($problemstatus eq 'no') ||      if ((($curRes->problemstatus($part) eq 'no') ||
                          ($problemstatus eq 'no_feedback_ever')) &&                          ($curRes->problemstatus($part) eq 'no_feedback_ever')) &&
  ($dateStatus != $curRes->ANSWER_OPEN)) {   ($dateStatus != $curRes->ANSWER_OPEN)) {
  my $status = $curRes->simpleStatus($part);   my $status = $curRes->simpleStatus($part);
  if ($status == $curRes->ATTEMPTED) {   if ($status == $curRes->ATTEMPTED) {
     $partsAttempted += $weight;      $partsAttempted += $curRes->weight($part);
     $totalAttempted += $partsAttempted;      $totalAttempted += $partsAttempted;
  }   }
     } else {      } else {
  $score = &Apache::grades::compute_points($weight, $curRes->awarded($part));   $score = &Apache::grades::compute_points($curRes->weight($part), $curRes->awarded($part));
     }      }
     $partsRight += $score;      $partsRight += $score;
     $totalRight += $score;      $totalRight += $score;
     $partsCount += $weight;      $partsCount += $curRes->weight($part);
   
     if ($curRes->opendate($part) < $now) {      if ($curRes->opendate($part) < $now) {
  $totalPossible += $weight;   $totalPossible += $curRes->weight($part);
     }      }
     $totalParts += $weight;      $totalParts += $curRes->weight($part);
  } else {   } else {
     my $status = $curRes->simpleStatus($part);      my $status = $curRes->simpleStatus($part);
     my $thisright = 0;      my $thisright = 0;
Line 330  sub getData { Line 189  sub getData {
  $totalAttempted++;   $totalAttempted++;
     }      }
           
       my $dateStatus = $curRes->getDateStatus($part);
     $totalParts++;      $totalParts++;
     if ($curRes->opendate($part) < $now) {      if ($curRes->opendate($part) < $now) {
  $totalPossible++;   $totalPossible++;
Line 360  sub getData { Line 220  sub getData {
         }          }
         $curRes = $iterator->next();          $curRes = $iterator->next();
     }      }
     return ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,  
             $topLevelParts,$topLevelRight,$topLevelAttempted);  
 }  
   
 #      $iterator = $navmap->getIterator(undef, undef, undef, 1);
 # Outputting everything.      $depth = 1;
 #      $iterator->next(); # ignore first BEGIN_MAP
       $curRes = $iterator->next();
 sub outputTable {  
   
     my ($r,$showPoints,$notshowTotals,$navmap,$totalParts,$totalPossible,$totalRight,  
         $totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=@_;  
   
     my @start = (255, 255, 192);      my @start = (255, 255, 192);
     my @end   = (0, 192, 0);      my @end   = (0, 192, 0);
Line 382  sub outputTable { Line 235  sub outputTable {
     $r->print(&Apache::loncommon::start_data_table()      $r->print(&Apache::loncommon::start_data_table()
              .&Apache::loncommon::start_data_table_header_row()               .&Apache::loncommon::start_data_table_header_row()
              .'<th>'.&mt('Folder').'</th>');               .'<th>'.&mt('Folder').'</th>');
     my $title = &mt($showPoints ? "Points Scored" : "Done");      $title = &mt($showPoints ? "Points Scored" : "Done");
     if ($totalAttempted) {      if ($totalAttempted) {
         $title .= " / " . &mt("Attempted");   $title .= " / " . &mt("Attempted");
     }      }
     $r->print("<th>$title".($notshowTotals?'':" / ".&mt('Total')).'</th>'      $r->print("<th>$title".($notshowTotals?'':" / ".&mt('Total')).'</th>'
              .&Apache::loncommon::end_data_table_header_row());               .&Apache::loncommon::end_data_table_header_row());
 #  
 # Output of folder scores  
 #  
   
     my $iterator = $navmap->getIterator(undef, undef, undef, 1);  
     my $depth = 1;  
     $iterator->next(); # ignore first BEGIN_MAP  
     my $curRes = $iterator->next();  
   
     while ($depth > 0) {      while ($depth > 0) {
         if ($curRes == $iterator->BEGIN_MAP()) {$depth++;}          if ($curRes == $iterator->BEGIN_MAP()) {$depth++;}
         if ($curRes == $iterator->END_MAP()) { $depth--; }          if ($curRes == $iterator->END_MAP()) { $depth--; }
Line 411  sub outputTable { Line 255  sub outputTable {
             if ($total > 0) {              if ($total > 0) {
                 my $ratio;                  my $ratio;
                 $ratio = $correct / $total;                  $ratio = $correct / $total;
                 my $color = &mixColors(\@start, \@end, $ratio);                  my $color = mixColors(\@start, \@end, $ratio);
                 $r->print(&Apache::loncommon::start_data_table_row()                  $r->print(&Apache::loncommon::start_data_table_row()
                          .'<td style="background-color:'.$color.';">');                           .'<td style="background-color:'.$color.';">');
                                   
Line 444  sub outputTable { Line 288  sub outputTable {
     # If there were any problems at the top level, print an extra "catchall"      # If there were any problems at the top level, print an extra "catchall"
     if ($topLevelParts > 0) {      if ($topLevelParts > 0) {
         my $ratio = $topLevelRight / $topLevelParts;          my $ratio = $topLevelRight / $topLevelParts;
         my $color = &mixColors(\@start, \@end, $ratio);          my $color = mixColors(\@start, \@end, $ratio);
         $r->print(&Apache::loncommon::start_data_table_row()          $r->print(&Apache::loncommon::start_data_table_row()
                  .'<td style="background-color:'.$color.';">');                   .'<td style="background-color:'.$color.';">');
         $r->print(&mt("Problems Not Contained In A Folder")."</td><td>");          $r->print(&mt("Problems Not Contained In A Folder")."</td><td>");
Line 452  sub outputTable { Line 296  sub outputTable {
                  .&Apache::loncommon::end_data_table_row());                   .&Apache::loncommon::end_data_table_row());
     }      }
   
 #  
 # show totals (if applicable), close table  
 #  
     if ($showPoints) {      if ($showPoints) {
  my $maxHelpLink = &Apache::loncommon::help_open_topic("Quick_Grades_Possibly_Correct");   my $maxHelpLink = Apache::loncommon::help_open_topic("Quick_Grades_Possibly_Correct");
   
  $title = $showPoints ? "Points" : "Parts Done";   $title = $showPoints ? "Points" : "Parts Done";
  my $totaltitle = $showPoints ? &mt("Awarded Total Points") : &mt("Total Parts Done");   my $totaltitle = $showPoints ? &mt("Awarded Total Points") : &mt("Total Parts Done");
Line 468  sub outputTable { Line 309  sub outputTable {
                  .&Apache::loncommon::end_data_table_row());                   .&Apache::loncommon::end_data_table_row());
     }      }
   
     $r->print(&Apache::loncommon::end_data_table());      $r->print(&Apache::loncommon::end_data_table()
     return;               .&Apache::loncommon::end_page());
 }  
   
 sub startpage {  
     my ($r,$showPoints) = @_;  
     my $title = "Grading and Statistics";#$showPoints ? "Points Display" : "Completed Problems Display";  
     my $brcrum = [{href=>"/adm/quickgrades",text => "Points Display"}];  
     $r->print(&Apache::loncommon::start_page($title,undef,  
                                             {'bread_crumbs' => $brcrum})  
              );  
 }  
   
 sub startGradeScreen {  
     my ($r)=@_;  
   
     my $showPoints =  
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'standard';  
     my $notshowSPRSlink =  
         (($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'external')  
       || ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals'));  
     my $notshowTotals =  
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'externalnototals';  
     my $showSPRSlink =  
         $env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet';  
   
     my $allowed_to_view = &Apache::lonnet::allowed('vgr',$env{'request.course.id'});  
     if ((!$allowed_to_view) && ($env{'request.course.sec'} ne '')) {  
         $allowed_to_view = &Apache::lonnet::allowed('vgr',  
                                "$env{'request.course.id'}/$env{'request.course.sec'}");  
     }  
   
     my $allowed_to_edit = &Apache::lonnet::allowed('mgr',$env{'request.course.id'});  
     if ((!$allowed_to_edit) && ($env{'request.course.sec'} ne '')) {  
         $allowed_to_edit = &Apache::lonnet::allowed('mgr',  
                                "$env{'request.course.id'}/$env{'request.course.sec'}");  
     }  
   
     if ($allowed_to_view) {      return OK;
         my @notes;  
         push(@notes,&mt('Students do not see total points.')) if ($notshowTotals);  
         push(@notes,&mt('Students do not see link to spreadsheet.')) if ($notshowSPRSlink);  
         push(@notes,&mt('Students will see points based on problem weights.')) if ($showPoints);  
         push(@notes,&mt('Students will see link to spreadsheet.')) if ($showSPRSlink);  
         push(@notes,&Apache::lonhtmlcommon::coursepreflink(&mt('Grade display settings'),'grading'));  
         $r->print(&Apache::loncommon::head_subbox(join('&nbsp;&nbsp;',@notes)));  
     } elsif (!$allowed_to_edit) {  
         if (!$showPoints && !$notshowSPRSlink ) {  
             $r->print(&Apache::loncommon::head_subbox(  
                       &mt('This screen shows how many problems (or problem parts) you have completed'  
                      .', and how many you have not yet done.'  
                      .' You can also look at [_1]a detailed score sheet[_2].'  
                      ,'<a href="/adm/studentcalc">','</a>')));  
         }  
     }  
     return;  
 }  
   
 sub endGradeScreen {  
     my ($r)=@_;  
     $r->print(&Apache::loncommon::end_page());  
     return;  
 }  }
   
 # Pass this two refs to arrays for the start and end color, and a number  # Pass this two refs to arrays for the start and end color, and a number

Removed from v.1.49.6.8  
changed lines
  Added in v.1.50


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>