Diff for /loncom/homework/grades.pm between versions 1.798 and 1.806

version 1.798, 2024/12/09 02:46:01 version 1.806, 2024/12/14 17:47:39
Line 1263  sub do_passback { Line 1263  sub do_passback {
     my $cdom = $env{"course.$env{'request.course.id'}.domain"};      my $cdom = $env{"course.$env{'request.course.id'}.domain"};
     my $cnum = $env{"course.$env{'request.course.id'}.num"};      my $cnum = $env{"course.$env{'request.course.id'}.num"};
     my $crstype = &Apache::loncommon::course_type();      my $crstype = &Apache::loncommon::course_type();
     my ($launcher,$appname,$setter,$linkuri,$linkprotector,$scope,$chosen);      my ($launchsymb,$appname,$setter,$linkuri,$linkprotector,$scope,$chosen);
     if ($env{'form.passback'} ne '') {      if ($env{'form.passback'} ne '') {
         $chosen = &unescape($env{'form.passback'});          $chosen = &unescape($env{'form.passback'});
         ($linkuri,$linkprotector,$scope) = split("\0",$chosen);          ($linkuri,$linkprotector,$scope) = split("\0",$chosen);
         ($launcher,$appname,$setter) = &get_passback_launcher($cdom,$cnum,$chosen);          ($launchsymb,$appname,$setter) = &get_passback_launcher($cdom,$cnum,$chosen);
     }      }
     if ($launcher ne '') {      if ($launchsymb ne '') {
         $request->print(&launcher_info_box($launcher,$appname,$setter,$linkuri,$scope));          $request->print(&launcher_info_box($launchsymb,$appname,$setter,$linkuri,$scope));
     }      }
     my $error;      my $error;
     if ($perm{'mgr'}) {      if ($perm{'mgr'}) {
         if ($launcher ne '') {          if ($launchsymb ne '') {
             my @poss_students = &Apache::loncommon::get_env_multiple('form.stuinfo');              my @poss_students = &Apache::loncommon::get_env_multiple('form.stuinfo');
             if (@poss_students) {              if (@poss_students) {
                 my %possibles;                  my %possibles;
Line 1312  sub do_passback { Line 1312  sub do_passback {
                             if ($lti_in_use->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {                              if ($lti_in_use->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
                                 $scoretype = $1;                                  $scoretype = $1;
                             }                              }
                             my $pbsymb = &Apache::loncommon::symb_from_tinyurl($linkuri,$cnum,$cdom);  
                             my $pbmap;                              my $pbmap;
                             if ($pbsymb =~ /\.(page|sequence)$/) {                              if ($launchsymb =~ /\.(page|sequence)$/) {
                                 $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pbsymb))[2]);                                  $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($launchsymb))[2]);
                             } else {                              } else {
                                 $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pbsymb))[0]);                                  $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($launchsymb))[0]);
                             }                              }
                             $pbmap = &Apache::lonnet::clutter($pbmap);                              $pbmap = &Apache::lonnet::clutter($pbmap);
                             my $pbscope;                              my $pbscope;
Line 1332  sub do_passback { Line 1331  sub do_passback {
                             my $numstudents = scalar(keys(%tosend));                              my $numstudents = scalar(keys(%tosend));
                             my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($request,$numstudents);                              my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($request,$numstudents);
                             my $outcome = &Apache::loncommon::start_data_table().                              my $outcome = &Apache::loncommon::start_data_table().
                                          &Apache::loncommon::start_data_table_header_row();                                            &Apache::loncommon::start_data_table_header_row();
                             my $loop = 0;                              my $loop = 0;
                             while ($loop < 2) {                              while ($loop < 2) {
                                 $outcome .= '<th>'.&mt('No.').'</th>'.                                  $outcome .= '<th>'.&mt('No.').'</th>'.
                                            '<th>'.&nameUserString('header').'&nbsp;'.&mt('Section/Group').'</th>'.                                              '<th>'.&nameUserString('header').'&nbsp;'.&mt('Section/Group').'</th>'.
                                            '<th>'.&mt('Score').'</th>';                                              '<th>'.&mt('Score').'</th>';
                                  $loop++;                                  $loop++;
                             }                              }
                             $outcome .= &Apache::loncommon::end_data_table_header_row()."\n";                              $outcome .= &Apache::loncommon::end_data_table_header_row()."\n";
                             my $ctr=0;                              my $ctr=0;
Line 1365  sub do_passback { Line 1364  sub do_passback {
                                     $possible = 0;                                      $possible = 0;
                                     my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);                                      my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);
                                     if (ref($navmap)) {                                      if (ref($navmap)) {
                                         my $res = $navmap->getBySymb($pbsymb);                                          my $res = $navmap->getBySymb($launchsymb);
                                         if (ref($res)) {                                          if (ref($res)) {
                                             my $partlist = $res->parts();                                              my $partlist = $res->parts();
                                             if (ref($partlist) eq 'ARRAY') {                                              if (ref($partlist) eq 'ARRAY') {
                                                 my %record = &Apache::lonnet::restore($pbsymb,$env{'request.course.id'},$udom,$uname);                                                  my %record = &Apache::lonnet::restore($launchsymb,$env{'request.course.id'},$udom,$uname);
                                                 foreach my $part (@{$partlist}) {                                                  foreach my $part (@{$partlist}) {
                                                     next if ($record{"resource.$part.solved"} =~/^excused/);                                                      next if ($record{"resource.$part.solved"} =~/^excused/);
                                                     my $weight = &Apache::lonnet::EXT("resource.$part.weight",$pbsymb,$udom,$uname,$usec);                                                      my $weight = &Apache::lonnet::EXT("resource.$part.weight",$launchsymb,$udom,$uname,$usec);
                                                     $possible += $weight;                                                      $possible += $weight;
                                                     if (($record{'version'}) && (exists($record{"resource.$part.awarded"}))) {                                                      if (($record{'version'}) && (exists($record{"resource.$part.awarded"}))) {
                                                         my $awarded = $record{"resource.$part.awarded"};                                                          my $awarded = $record{"resource.$part.awarded"};
Line 1386  sub do_passback { Line 1385  sub do_passback {
                                     }                                      }
                                 } elsif (($pbscope eq 'map') || ($pbscope eq 'nonrec')) {                                  } elsif (($pbscope eq 'map') || ($pbscope eq 'nonrec')) {
                                     ($total,$possible) =                                      ($total,$possible) =
                                         &Apache::lonhomework::get_lti_score($uname,$udom,$pbmap,$pbscope);                                          &Apache::lonhomework::get_lti_score($uname,$udom,$usec,$pbmap,$pbscope);
                                 }                                  }
                                 if (($id ne '') && ($url ne '') && ($possible)) {                                  if (($id ne '') && ($url ne '') && ($possible)) {
                                     my ($sent,$score,$code,$result) =                                      my ($sent,$score,$code,$result) =
Line 1408  sub do_passback { Line 1407  sub do_passback {
                                                  'id' => $id,                                                   'id' => $id,
                                                  'clientip' => $pb{'clientip'},                                                   'clientip' => $pb{'clientip'},
                                                  'whodoneit' => $env{'user.name'}.':'.$env{'user.domain'},                                                   'whodoneit' => $env{'user.name'}.':'.$env{'user.domain'},
                                                 };                                              };
                                             my $value='';                                              my $value='';
                                             foreach my $key (keys(%{$store})) {                                              foreach my $key (keys(%{$store})) {
                                                 $value.=&escape($key).'='.&Apache::lonnet::freeze_escape($store->{$key}).'&';                                                  $value.=&escape($key).'='.&Apache::lonnet::freeze_escape($store->{$key}).'&';
Line 1420  sub do_passback { Line 1419  sub do_passback {
                                             if ($ctr%2 ==1) {                                              if ($ctr%2 ==1) {
                                                 $outcome .= &Apache::loncommon::start_data_table_row();                                                  $outcome .= &Apache::loncommon::start_data_table_row();
                                             }                                              }
                                             my $section = $classlist->{$student}->[&Apache::loncoursedata::CL_SECTION()];  
                                             my $group = $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];                                              my $group = $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];
                                             $outcome .= '<td align="right">'.$ctr.'&nbsp;</td>'.                                              $outcome .= '<td align="right">'.$ctr.'&nbsp;</td>'.
                                                        '<td>'.&nameUserString(undef,$$fullname{$student},$uname,$udom).                                                          '<td>'.&nameUserString(undef,$$fullname{$student},$uname,$udom).
                                                        '&nbsp;'.$section.($group ne '' ?'/'.$group:'').'</td>'.                                                          '&nbsp;'.$usec.($group ne '' ?'/'.$group:'').'</td>'.
                                                        '<td>'.$score.'</td>'."\n";                                                          '<td>'.$score.'</td>'."\n";
                                             if ($ctr%2 ==0) {                                              if ($ctr%2 ==0) {
                                                 $outcome .= &Apache::loncommon::end_data_table_row()."\n";                                                  $outcome .= &Apache::loncommon::end_data_table_row()."\n";
                                             }                                              }
Line 1441  sub do_passback { Line 1439  sub do_passback {
                                     }                                      }
                                     if ($no_passback) {                                      if ($no_passback) {
                                         &Apache::lonnet::log($udom,$uname,$uhome,$no_passback." score: $score; total: $total; possible: $possible");                                          &Apache::lonnet::log($udom,$uname,$uhome,$no_passback." score: $score; total: $total; possible: $possible");
                                           my $key = &Time::HiRes::time().':'.$uname.':'.$udom.':'.
                                                     "$linkuri\0$linkprotector\0$scope"; 
                                         my $ltigrade = {                                          my $ltigrade = {
                                             'ltinum'   => $ltinum,                                                           $key => {
                                             'lti'      => $lti_in_use,                                                                     'ltinum'   => $ltinum,
                                             'crsdef'   => $crsdef,                                                                     'lti'      => $lti_in_use,
                                             'cid'      => $cdom.'_'.$cnum,                                                                     'crsdef'   => $crsdef,
                                             'uname'    => $uname,                                                                     'cid'      => $cdom.'_'.$cnum,
                                             'udom'     => $udom,                                                                     'uname'    => $uname,
                                             'uhome'    => $uhome,                                                                     'udom'     => $udom,
                                             'pbid'     => $id,                                                                     'uhome'    => $uhome,
                                             'pburl'    => $url,                                                                     'pbid'     => $id,
                                             'pbtype'   => $pb{'type'},                                                                     'pburl'    => $url,
                                             'pbscope'  => $pbscope,                                                                     'pbtype'   => $pb{'type'},
                                             'pbmap'    => $pbmap,                                                                     'pbscope'  => $pbscope,
                                             'pbsymb'   => $pbsymb,                                                                     'pbmap'    => $pbmap,
                                             'format'   => $scoretype,                                                                     'pbsymb'   => $launchsymb,
                                             'scope'    => $scope,                                                                     'format'   => $scoretype,
                                             'clientip' => $pb{'clientip'},                                                                     'scope'    => $scope,
                                             'linkprot' => $linkprotector,                                                                     'clientip' => $pb{'clientip'},
                                             'total'    => $total,                                                                     'linkprot' => $linkprotector.':'.$linkuri,
                                             'possible' => $possible,                                                                     'total'    => $total,
                                             'score'    => $score,                                                                     'possible' => $possible,
                                                                      'score'    => $score,
                                                                    },
                                         };                                          };
                                         &Apache::lonnet::put('linkprot_passback_pending',$ltigrade,$cdom,$cnum);                                          &Apache::lonnet::put('linkprot_passback_pending',$ltigrade,$cdom,$cnum);
                                     }                                      }
Line 1575  sub get_passback_launcher { Line 1577  sub get_passback_launcher {
             }              }
         }          }
     }      }
     if ($linkuri =~ m{^\Q/tiny/$cdom/\E(\w+)$}) {      my $launchsymb = &Apache::loncommon::symb_from_tinyurl($linkuri,$cnum,$cdom);
         my $key = $1;      if ($launchsymb eq '') {
         my $tinyurl;          my %passback = &Apache::lonnet::dump('nohist_linkprot_passback',$cdom,$cnum);
         my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key);          foreach my $poss_symb (keys(%passback)) {
         if (defined($cached)) {              if (ref($passback{$poss_symb}) eq 'HASH') {
             $tinyurl = $result;                  if (exists($passback{$poss_symb}{$chosen})) {
         } else {                      $launchsymb = $poss_symb;
             my $configuname = &Apache::lonnet::get_domainconfiguser($cdom);                      last;
             my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname);  
             if ($currtiny{$key} ne '') {  
                 $tinyurl = $currtiny{$key};  
                 &Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600);  
             }  
         }  
         if ($tinyurl) {  
             my ($crsnum,$launchsymb) = split(/\&/,$tinyurl);  
             if ($crsnum eq $cnum) {  
                 my %passback = &Apache::lonnet::get('nohist_linkprot_passback',[$launchsymb],$cdom,$cnum);  
                 if (ref($passback{$launchsymb}) eq 'HASH') {  
                     if (exists($passback{$launchsymb}{$chosen})) {  
                         return ($launchsymb,$appname,$setter);  
                     }  
                 }                  }
             }              }
         }          }
           if ($launchsymb ne '') {
               return ($launchsymb,$appname,$setter);
           }
       } else {
           my %passback = &Apache::lonnet::get('nohist_linkprot_passback',[$launchsymb],$cdom,$cnum);
           if (ref($passback{$launchsymb}) eq 'HASH') {
               if (exists($passback{$launchsymb}{$chosen})) {
                   return ($launchsymb,$appname,$setter);
               }
           }
     }      }
     return ();      return ();
 }  }
Line 1679  sub passbacks_for_symb { Line 1677  sub passbacks_for_symb {
             }              }
             if (ref($passback{$symb}) eq 'HASH') {              if (ref($passback{$symb}) eq 'HASH') {
                 foreach my $launcher (keys(%{$passback{$symb}})) {                  foreach my $launcher (keys(%{$passback{$symb}})) {
                     $needpb{$launcher} = 1;                      $needpb{$launcher} = $symb;
                 }                  }
             }              }
         }          }
Line 1696  sub passbacks_for_symb { Line 1694  sub passbacks_for_symb {
                         }                          }
                         if (ref($passback{$mapsymb}) eq 'HASH') {                          if (ref($passback{$mapsymb}) eq 'HASH') {
                             foreach my $launcher (keys(%{$passback{$mapsymb}})) {                              foreach my $launcher (keys(%{$passback{$mapsymb}})) {
                                 $needpb{$launcher} = 1;                                  $needpb{$launcher} = $mapsymb;
                             }                              }
                         }                          }
                     }                      }
Line 1713  sub passbacks_for_symb { Line 1711  sub passbacks_for_symb {
                                 foreach my $launcher (keys(%{$passback{$key}})) {                                  foreach my $launcher (keys(%{$passback{$key}})) {
                                     my ($linkuri,$linkprotector,$scope) = split("\0",$launcher);                                      my ($linkuri,$linkprotector,$scope) = split("\0",$launcher);
                                     next unless ($scope eq 'rec');                                      next unless ($scope eq 'rec');
                                     $needpb{$launcher} = 1;                                      $needpb{$launcher} = $key;
                                 }                                  }
                             }                              }
                         }                          }
Line 1726  sub passbacks_for_symb { Line 1724  sub passbacks_for_symb {
 }  }
   
 sub process_passbacks {  sub process_passbacks {
     my ($context,$symbs,$cdom,$cnum,$udom,$uname,$weights,$awardeds,$excuseds,$needpb,      my ($context,$symbs,$cdom,$cnum,$udom,$uname,$usec,$weights,$awardeds,$excuseds,$needpb,
         $skip_passback,$pbsave,$pbids) = @_;          $skip_passback,$pbsave,$pbids) = @_;
     if ((ref($needpb) eq 'HASH') && (ref($skip_passback) eq 'HASH') && (ref($pbsave) eq 'HASH')) {      if ((ref($needpb) eq 'HASH') && (ref($skip_passback) eq 'HASH') && (ref($pbsave) eq 'HASH')) {
         my (%weight,%awarded,%excused);          my (%weight,%awarded,%excused);
Line 1778  sub process_passbacks { Line 1776  sub process_passbacks {
                             if ($pb{'lti_in_use'}->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {                              if ($pb{'lti_in_use'}->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
                                 $pb{'scoretype'} = $1;                                  $pb{'scoretype'} = $1;
                             }                              }
                             $pb{'symb'} = &Apache::loncommon::symb_from_tinyurl($pb{'linkuri'},$cnum,$cdom);                              $pb{'symb'} = $needpb->{$launcher};
                             if ($pb{'symb'} =~ /\.(page|sequence)$/) {                              if ($pb{'symb'} =~ /\.(page|sequence)$/) {
                                 $pb{'map'} = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pb{'symb'}))[2]);                                  $pb{'map'} = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pb{'symb'}))[2]);
                             } else {                              } else {
Line 1827  sub process_passbacks { Line 1825  sub process_passbacks {
                                         'uname'      => $uname,                                          'uname'      => $uname,
                                         'udom'       => $udom,                                          'udom'       => $udom,
                                         'uhome'      => $uhome,                                          'uhome'      => $uhome,
                                           'usec'       => $usec,
                                         'pbid'       => $pbid,                                          'pbid'       => $pbid,
                                         'pburl'      => $pburl,                                          'pburl'      => $pburl,
                                         'pbtype'     => $pb{'type'},                                          'pbtype'     => $pb{'type'},
Line 1836  sub process_passbacks { Line 1835  sub process_passbacks {
                                         'format'     => $pb{'scoretype'},                                          'format'     => $pb{'scoretype'},
                                         'scope'      => $pb{'scope'},                                          'scope'      => $pb{'scope'},
                                         'clientip'   => $pb{'clientip'},                                          'clientip'   => $pb{'clientip'},
                                         'linkprot'   => $pb{'linkprotector'},                                          'linkprot'   => $pb{'linkprotector'}.':'.$pb{'linkuri'},
                                         'total_s'    => \%total_by_symb,                                          'total_s'    => \%total_by_symb,
                                         'possible_s' => \%possible_by_symb,                                          'possible_s' => \%possible_by_symb,
                         };                          };
                         push(@Apache::lonhomework::ltipassback,$ltigrade);                          push(@Apache::grades::ltipassback,$ltigrade);
                         next;                          next;
                     }                      }
                     my ($total,$possible);                      my ($total,$possible);
Line 1849  sub process_passbacks { Line 1848  sub process_passbacks {
                         $possible = $possible_by_symb{$pb{'symb'}};                          $possible = $possible_by_symb{$pb{'symb'}};
                     } elsif (($pb{'pbscope'} eq 'map') || ($pb{'pbscope'} eq 'nonrec')) {                      } elsif (($pb{'pbscope'} eq 'map') || ($pb{'pbscope'} eq 'nonrec')) {
                         ($total,$possible) =                          ($total,$possible) =
                             &Apache::lonhomework::get_lti_score($uname,$udom,$pb{'map'},$pb{'pbscope'},                              &Apache::lonhomework::get_lti_score($uname,$udom,$usec,$pb{'map'},$pb{'pbscope'},
                                                                 \%total_by_symb,\%possible_by_symb);                                                                  \%total_by_symb,\%possible_by_symb);
                     }                      }
                     if (!$possible) {                      if (!$possible) {
Line 1908  sub process_passbacks { Line 1907  sub process_passbacks {
                            'format'   => $pb{'scoretype'},                             'format'   => $pb{'scoretype'},
                            'scope'    => $pb{'scope'},                             'scope'    => $pb{'scope'},
                            'clientip' => $pb{'clientip'},                             'clientip' => $pb{'clientip'},
                            'linkprot' => $pb{'linkprotector'},                             'linkprot' => $pb{'linkprotector'}.':'.$pb{'linkuri'},
                            'total'    => $total,                             'total'    => $total,
                            'possible' => $possible,                             'possible' => $possible,
                            'score'    => $score,                             'score'    => $score,
Line 4240  sub processHandGrade { Line 4239  sub processHandGrade {
  foreach my $collabstr (@collabstrs) {   foreach my $collabstr (@collabstrs) {
     my ($part,@collaborators) = split(/:/,$collabstr);      my ($part,@collaborators) = split(/:/,$collabstr);
     foreach my $collaborator (@collaborators) {      foreach my $collaborator (@collaborators) {
  my ($errorflag,$pts,$wgt) =    my ($errorflag,$pts,$wgt,$numchg,$numupdate) = 
     &saveHandGrade($request,$symb,$collaborator,$udom,$ctr,      &saveHandGrade($request,$symb,$collaborator,$udom,$ctr,
    $env{'form.unamedom'.$ctr},$part,\%queueable,\%needpb,\%skip_passback,%pbsave);     $env{'form.unamedom'.$ctr},$part,\%queueable);
  if ($errorflag eq 'not_allowed') {   if ($errorflag eq 'not_allowed') {
     $request->print("<span class=\"LC_error\">".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."</span>");      $request->print("<span class=\"LC_error\">".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."</span>");
     next;      next;
  } else {   } else {
                             $pbcollab{$collaborator}{$part} = [$pts,$wgt];                              if ($numchg || $numupdate) { 
                                   $pbcollab{$collaborator}{$part} = [$pts,$wgt];
                               }
                             if ($message ne '') {                              if ($message ne '') {
     my ($baseurl,$showsymb) =           my ($baseurl,$showsymb) = 
  &get_feedurl_and_symb($symb,$collaborator,      &get_feedurl_and_symb($symb,$collaborator,
       $udom);            $udom);
     if ($env{'form.withgrades'.$ctr}) {          if ($env{'form.withgrades'.$ctr}) {
  $messagetail = " for <a href=\"".      $messagetail = " for <a href=\"".
                                     $baseurl."?symb=$showsymb\">$restitle</a>";                                          $baseurl."?symb=$showsymb\">$restitle</a>";
           }
           $msgstatus =
       &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);
     }      }
     $msgstatus =           }
  &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);  
  }  
     }      }
  }   }
     }      }
     $ctr++;      $ctr++;
  }   }
         if ((keys(%pbcollab)) && (keys(%needpb))) {          if ((keys(%pbcollab)) && (keys(%needpb))) {
             # FIXME passback scores for collaborators              foreach my $user (keys(%pbcollab)) {
                   my ($clbuname,$clbudom) = split(/:/,$user);
                   my $clbusec = &Apache::lonnet::getsection($clbudom,$clbuname,$cdom.'_'.$cnum); 
                   if (ref($pbcollab{$user}) eq 'HASH') {
                       my @clparts = keys(%{$pbcollab{$user}});
                       if (@clparts) {
                           my $navmap = Apache::lonnavmaps::navmap->new($clbuname,$clbudom,$clbusec);
                           if (ref($navmap)) {
                               my $res = $navmap->getBySymb($symb);
                               if (ref($res)) {
                                   my $partlist = $res->parts();
                                   if (ref($partlist) eq 'ARRAY') {
                                       my (%weights,%awardeds,%excuseds);
                                       foreach my $part (@{$partlist}) {
                                           if ($res->status($part) eq $res->EXCUSED) {
                                               $excuseds{$symb}{$part} = 1;
                                           } else { 
                                               $excuseds{$symb}{$part} = '';
                                           }
                                           if ((exists($pbcollab{$user}{$part})) && (ref($pbcollab{$user}{$part}) eq 'ARRAY')) {
                                               my $pts = $pbcollab{$user}{$part}[0];
                                               my $wt = $pbcollab{$user}{$part}[1];
                                               if ($wt) {
                                                   $awardeds{$symb}{$part} = $pts/$wt;
                                                   $weights{$symb}{$part} = $wt;
                                               } else {
                                                   $awardeds{$symb}{$part} = 0;
                                                   $weights{$symb}{$part} = 0;
                                               }
                                           } else {
                                               $awardeds{$symb}{$part} = $res->awarded($part);
                                               $weights{$symb}{$part} = $res->weight($part);
                                           }
                                       }
                                       &process_passbacks('handgrade',[$symb],$cdom,$cnum,$clbudom,$clbuname,$clbusec,\%weights,
                                                          \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
                                   }
                               }
                           }
                       }
                   }
               }
         }          }
     }      }
   
Line 4428  sub saveHandGrade { Line 4471  sub saveHandGrade {
     my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname);      my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname);
     my @parts_graded;      my @parts_graded;
     my %newrecord  = ();      my %newrecord  = ();
     my ($pts,$wgt,$totchg) = ('','',0);      my ($pts,$wgt,$totchg,$sendupdate) = ('','',0,0);
     my %aggregate = ();      my %aggregate = ();
     my $aggregateflag = 0;      my $aggregateflag = 0;
     my $sendupdate;  
     if ($env{'form.HIDE'.$newflg}) {      if ($env{'form.HIDE'.$newflg}) {
         my ($version,$parts) = split(/:/,$env{'form.HIDE'.$newflg},2);          my ($version,$parts) = split(/:/,$env{'form.HIDE'.$newflg},2);
         my $numchgs = &makehidden($version,$parts,\%record,$symb,$domain,$stuname,1);          my $numchgs = &makehidden($version,$parts,\%record,$symb,$domain,$stuname,1);
         $totchg += $numchgs;          $totchg += $numchgs;
         if ($numchgs) {  
             $sendupdate = 1;  
         }  
     }      }
     my (%weights,%awardeds,%excuseds);      my (%weights,%awardeds,%excuseds);
     my @parts = split(/:/,$env{'form.partlist'.$newflg});      my @parts = split(/:/,$env{'form.partlist'.$newflg});
     foreach my $new_part (@parts) {      foreach my $new_part (@parts) {
  #collaborator ($submi may vary for different parts   #collaborator ($submitter may vary for different parts)
  if ($submitter && $new_part ne $part) { next; }   if ($submitter && $new_part ne $part) { next; }
  my $dropMenu = $env{'form.GD_SEL'.$newflg.'_'.$new_part};   my $dropMenu = $env{'form.GD_SEL'.$newflg.'_'.$new_part};
         if ($env{'form.WGT'.$newflg.'_'.$new_part} eq '') {          if ($env{'form.WGT'.$newflg.'_'.$new_part} eq '') {
Line 4460  sub saveHandGrade { Line 4499  sub saveHandGrade {
     $newrecord{'resource.'.$new_part.'.awarded'} = '';      $newrecord{'resource.'.$new_part.'.awarded'} = '';
  }   }
         $newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";          $newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
                 $sendupdate = 1;                  $sendupdate ++;
     }      }
  } elsif ($dropMenu eq 'reset status'   } elsif ($dropMenu eq 'reset status'
  && exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts   && exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts
Line 4484  sub saveHandGrade { Line 4523  sub saveHandGrade {
                 &decrement_aggs($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus);                  &decrement_aggs($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus);
                 $aggregateflag = 1;                  $aggregateflag = 1;
             }              }
             $sendupdate = 1;              $sendupdate ++;
             $excuseds{$symb}{$new_part} = '';              $excuseds{$symb}{$new_part} = '';
             $awardeds{$symb}{$new_part} = '';              $awardeds{$symb}{$new_part} = '';
  } elsif ($dropMenu eq '') {   } elsif ($dropMenu eq '') {
Line 4505  sub saveHandGrade { Line 4544  sub saveHandGrade {
  next;   next;
     } else {      } else {
         push(@parts_graded,$new_part);          push(@parts_graded,$new_part);
                 $sendupdate = 1;                  $sendupdate ++;
     }      }
     if ($record{'resource.'.$new_part.'.awarded'} ne $partial) {      if ($record{'resource.'.$new_part.'.awarded'} ne $partial) {
  $newrecord{'resource.'.$new_part.'.awarded'}  = $partial;   $newrecord{'resource.'.$new_part.'.awarded'}  = $partial;
Line 4557  sub saveHandGrade { Line 4596  sub saveHandGrade {
         &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,          &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
       $cdom,$cnum);        $cdom,$cnum);
     }      }
     if (($sendupdate) && (!$submitter)) {      if (($sendupdate || $totchg) && (!$submitter)) {
         if ((ref($needpb) eq 'HASH') &&          if ((ref($needpb) eq 'HASH') &&
             (keys(%{$needpb}))) {              (keys(%{$needpb}))) {
             &process_passbacks('handgrade',[$symb],$cdom,$cnum,$domain,$stuname,\%weights,              &process_passbacks('handgrade',[$symb],$cdom,$cnum,$domain,$stuname,$usec,\%weights,
                                \%awardeds,\%excuseds,$needpb,$skip_passback,$pbsave);                                 \%awardeds,\%excuseds,$needpb,$skip_passback,$pbsave);
         }          }
     }      }
     return ('',$pts,$wgt,$totchg);      return ('',$pts,$wgt,$totchg,$sendupdate);
 }  }
   
 sub makehidden {  sub makehidden {
Line 5649  sub editgrades { Line 5688  sub editgrades {
     $updateCtr++;      $updateCtr++;
             if (keys(%needpb)) {              if (keys(%needpb)) {
                 $weights{$symb} = \%weight;                  $weights{$symb} = \%weight;
                 &process_passbacks('editgrades',[$symb],$cdom,$cnum,$udom,$uname,\%weights,                  &process_passbacks('editgrades',[$symb],$cdom,$cnum,$udom,$uname,$usec,\%weights,
                                    \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);                                     \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
             }              }
  } else {   } else {
Line 6178  sub csvuploadassign { Line 6217  sub csvuploadassign {
       $request->print('.');        $request->print('.');
 # Remove from grading queue  # Remove from grading queue
               &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,$cnum,                &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,$cnum,
                                              $domain,$username);       $domain,$username);
               $countdone++;                $countdone++;
               if ($passback) {                if ($passback) {
                   my @parts_in_upload;                    my @parts_in_upload;
Line 6200  sub csvuploadassign { Line 6239  sub csvuploadassign {
                           $awardeds{$symb}{$part} = $record{"resource.$part.awarded"};                            $awardeds{$symb}{$part} = $record{"resource.$part.awarded"};
                       }                        }
                   }                    }
                   &process_passbacks('csvupload',[$symb],$cdom,$cnum,$domain,$username,\%weights,                    &process_passbacks('csvupload',[$symb],$cdom,$cnum,$domain,$username,$usec,\%weights,
                                      \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);                                       \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
               }                }
            } else {             } else {
Line 6951  sub updateGradeByPage { Line 6990  sub updateGradeByPage {
     $request->print($hidemsg.$grademsg.$studentTable);      $request->print($hidemsg.$grademsg.$studentTable);
   
     if (@updates) {      if (@updates) {
         undef(@Apache::lonhomework::ltipassback);  
         my (@allsymbs,$mapsymb,@recurseup,%parentmapsymbs,%possmappb,%possrespb);          my (@allsymbs,$mapsymb,@recurseup,%parentmapsymbs,%possmappb,%possrespb);
         @allsymbs = @updates;          @allsymbs = @updates;
         if (ref($map)) {          if (ref($map)) {
Line 6964  sub updateGradeByPage { Line 7002  sub updateGradeByPage {
             map { $parentmapsymbs{$_} = 1; } @recurseup;              map { $parentmapsymbs{$_} = 1; } @recurseup;
         }          }
         my %passback = &Apache::lonnet::get('nohist_linkprot_passback',\@allsymbs,$cdom,$cnum);          my %passback = &Apache::lonnet::get('nohist_linkprot_passback',\@allsymbs,$cdom,$cnum);
         my (%uniqsymbs,$use_symbs_in_map);          my (%uniqsymbs,$use_symbs_in_map,%launch_to_symb);
         if (keys(%passback)) {          if (keys(%passback)) {
             foreach my $possible (keys(%passback)) {              foreach my $possible (keys(%passback)) {
                 if (ref($passback{$possible}) eq 'HASH') {                  if (ref($passback{$possible}) eq 'HASH') {
                     if ($possible eq $mapsymb) {                      if ($possible eq $mapsymb) {
                         foreach my $launcher (keys(%{$passback{$possible}})) {                          foreach my $launcher (keys(%{$passback{$possible}})) {
                             $possmappb{$launcher} = 1;                              $possmappb{$launcher} = 1;
                               $launch_to_symb{$launcher} = $possible;
                         }                          }
                         $use_symbs_in_map = 1;                          $use_symbs_in_map = 1;
                     } elsif (exists($parentmapsymbs{$possible})) {                      } elsif (exists($parentmapsymbs{$possible})) {
Line 6979  sub updateGradeByPage { Line 7018  sub updateGradeByPage {
                             if ($scope eq 'rec') {                              if ($scope eq 'rec') {
                                 $possmappb{$launcher} = 1;                                  $possmappb{$launcher} = 1;
                                 $use_symbs_in_map = 1;                                  $use_symbs_in_map = 1;
                                   $launch_to_symb{$launcher} = $possible;
                             }                              }
                         }                          }
                     } elsif (grep(/^\Q$possible$\E$/,@updates)) {                      } elsif (grep(/^\Q$possible$\E$/,@updates)) {
                         foreach my $launcher (keys(%{$passback{$possible}})) {                          foreach my $launcher (keys(%{$passback{$possible}})) {
                             $possrespb{$launcher} = 1;                              $possrespb{$launcher} = 1;
                               $launch_to_symb{$launcher} = $possible;
                         }                          }
                         $uniqsymbs{$possible} = 1;                          $uniqsymbs{$possible} = 1;
                     }                      }
Line 7005  sub updateGradeByPage { Line 7046  sub updateGradeByPage {
             my %pbids = &Apache::lonnet::get('nohist_'.$cdom.'_'.$cnum.'_linkprot_pb',\@posslaunchers,$udom,$uname);              my %pbids = &Apache::lonnet::get('nohist_'.$cdom.'_'.$cnum.'_linkprot_pb',\@posslaunchers,$udom,$uname);
             foreach my $key (keys(%pbids)) {              foreach my $key (keys(%pbids)) {
                 if (ref($pbids{$key}) eq 'ARRAY') {                  if (ref($pbids{$key}) eq 'ARRAY') {
                     $needpb{$key} = 1;                      if ($launch_to_symb{$key}) {
                           $needpb{$key} = $launch_to_symb{$key};
                       }
                 }                  }
             }              }
             my @symbs = keys(%uniqsymbs);              my @symbs = keys(%uniqsymbs);
             &process_passbacks('updatebypage',\@symbs,$cdom,$cnum,$udom,$uname,\%weights,              &process_passbacks('updatebypage',\@symbs,$cdom,$cnum,$udom,$uname,$usec,\%weights,
                                \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave,\%pbids);                                 \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave,\%pbids);
             if (@Apache::lonhomework::ltipassback) {              if (@Apache::grades::ltipassback) {
                 unless ($registered_cleanup) {                  unless ($registered_cleanup) {
                     my $handlers = $request->get_handlers('PerlCleanupHandler');                      my $handlers = $request->get_handlers('PerlCleanupHandler');
                     $request->set_handlers('PerlCleanupHandler' =>                      $request->set_handlers('PerlCleanupHandler' =>
                                            [\&Apache::lonhomework::do_ltipassback,@{$handlers}]);                                             [\&Apache::grades::make_passback,@{$handlers}]);
                       $registered_cleanup=1;
                 }                  }
             }              }
         }          }
Line 7023  sub updateGradeByPage { Line 7067  sub updateGradeByPage {
     return '';      return '';
 }  }
   
   sub make_passback {
       if (@Apache::grades::ltipassback) {
           my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
           my $ip = &Apache::lonnet::get_host_ip($lonhost);
           foreach my $item (@Apache::grades::ltipassback) {
               &Apache::lonhomework::run_passback($item,$lonhost,$ip);
           }
           undef(@Apache::grades::ltipassback);
       }
   }
   
 #-------- end of section for handling grading by page/sequence ---------  #-------- end of section for handling grading by page/sequence ---------
 #  #
 #-------------------------------------------------------------------  #-------------------------------------------------------------------
Line 12539  sub assign_clicker_grades { Line 12594  sub assign_clicker_grades {
     if ($res_error) {      if ($res_error) {
         return &navmap_errormsg();          return &navmap_errormsg();
     }      }
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my %needpb = &passbacks_for_symb($cdom,$cnum,$symb);
       my (%skip_passback,%pbsave); 
 # FIXME: This should probably look for the first handgradeable part  # FIXME: This should probably look for the first handgradeable part
     my $part=$$partlist[0];      my $part=$$partlist[0];
 # Start screen output  # Start screen output
Line 12648  sub assign_clicker_grades { Line 12707  sub assign_clicker_grades {
              $result.="<br /><span class=\"LC_error\">Failed to save student $username:$domain. Message when trying to save was ($returncode)</span>";               $result.="<br /><span class=\"LC_error\">Failed to save student $username:$domain. Message when trying to save was ($returncode)</span>";
           } else {            } else {
              $storecount++;               $storecount++;
              #FIXME Do passback for $user if required               if (keys(%needpb)) {
                    my (%weights,%awardeds,%excuseds);
                    my $usec = &Apache::lonnet::getsection($domain,$username,$env{'request.course.id'});
                    $weights{$symb}{$part} = &Apache::lonnet::EXT("resource.$part.weight",$symb,$domain,$username,$usec);
                    $awardeds{$symb}{$part} = $ave;
                    $excuseds{$symb}{$part} = '';
                    &process_passbacks('clickergrade',[$symb],$cdom,$cnum,$domain,$username,$usec,\%weights,
                                       \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
                }
           }            }
        }         }
     }      }
Line 12807  sub handler { Line 12874  sub handler {
  &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));   &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));
     }      }
   
   # -------------------------------------- Flag and buffer for registered cleanup
       $registered_cleanup=0;
       undef(@Apache::grades::ltipassback);
   
 # see what the symb is  # see what the symb is
   
     my $symb=$env{'form.symb'};      my $symb=$env{'form.symb'};

Removed from v.1.798  
changed lines
  Added in v.1.806


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