Diff for /loncom/homework/lonhomework.pm between versions 1.358 and 1.367

version 1.358, 2015/10/05 02:35:40 version 1.367, 2017/01/05 19:39:31
Line 210  sub proctor_checked_in { Line 210  sub proctor_checked_in {
 }  }
   
 sub check_slot_access {  sub check_slot_access {
     my ($id,$type,$symb)=@_;      my ($id,$type,$symb,$partlist)=@_;
   
     # does it pass normal muster      # does it pass normal muster
     my ($status,$datemsg)=&check_access($id,$symb);      my ($status,$datemsg)=&check_access($id,$symb);
Line 228  sub check_slot_access { Line 228  sub check_slot_access {
         $checkin = "resource.$version.0.checkedin";          $checkin = "resource.$version.0.checkedin";
     }      }
     my $checkedin = $Apache::lonhomework::history{$checkin};      my $checkedin = $Apache::lonhomework::history{$checkin};
     my ($returned_slot,$slot_name,$checkinslot,$ipused,$blockip,$now,$ip);      my ($returned_slot,$slot_name,$checkinslot,$ipused,$blockip,$now,$ip,
           $consumed_uniq);
     $now = time;      $now = time;
     $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};      $ip=$ENV{'REMOTE_ADDR'} || $env{'request.host'};
   
     if ($checkedin) {      if ($checkedin) {
         $checkinslot = $Apache::lonhomework::history{"$checkin.slot"};          $checkinslot = $Apache::lonhomework::history{"$checkin.slot"};
         my %slot=&Apache::lonnet::get_slot($checkinslot);          my %slot=&Apache::lonnet::get_slot($checkinslot);
           $consumed_uniq = $slot{'uniqueperiod'};
         if ($slot{'iptied'}) {          if ($slot{'iptied'}) {
             $ipused = $Apache::lonhomework::history{"$checkin.ip"};              $ipused = $Apache::lonhomework::history{"$checkin.ip"};
             unless (($ip ne '') && ($ipused eq $ip)) {              unless (($ip ne '') && ($ipused eq $ip)) {
Line 349  sub check_slot_access { Line 351  sub check_slot_access {
     ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass'      ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass'
      || $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ );       || $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ );
     } elsif ($type eq 'problem') {      } elsif ($type eq 'problem') {
  $got_grade  = 1;          if ((ref($partlist) eq 'ARRAY') && (@{$partlist} > 0)) {
  $is_correct =              my ($numcorrect,$numgraded) = (0,0);
     ($Apache::lonhomework::history{"resource.0.solved"} =~/^correct_/);              foreach my $part (@{$partlist}) {
                   my $currtries = $Apache::lonhomework::history{"resource.$part.tries"};
                   my $maxtries = &Apache::lonnet::EXT("resource.$part.maxtries",$symb);
                   my $probstatus = &Apache::structuretags::get_problem_status($part);
                   my $earlyout;
                   unless (($probstatus eq 'no') ||
                           ($probstatus eq 'no_feedback_ever')) { 
                       if ($Apache::lonhomework::history{"resource.$part.solved"} =~/^correct_/) {
                           $numcorrect ++;
                       } else {
                           $earlyout = 1;
                       }
                   }
                   if (($currtries == $maxtries) || ($is_correct)) {
                       $earlyout = 1;
                   } else { 
                       $numgraded ++;
                   }
                   last if ($earlyout);
               }
               my $numparts = scalar(@{$partlist});
               if ($numparts == $numcorrect) {
                   $is_correct = 1;
               }
               if ($numparts == $numgraded) {
                   $got_grade = 1;
               }
           } else {
               my $currtries = $Apache::lonhomework::history{"resource.0.tries"};
               my $maxtries = &Apache::lonnet::EXT("resource.0.maxtries",$symb);
               my $probstatus = &Apache::structuretags::get_problem_status('0');
               unless (($probstatus eq 'no') ||
                       ($probstatus eq 'no_feedback_ever')) {
                   $is_correct =
                       ($Apache::lonhomework::history{"resource.0.solved"} =~/^correct_/);
               }
               unless (($currtries == $maxtries) || ($is_correct)) {
                   $got_grade = 1;
               }
           }
     }      }
           
     &Apache::lonxml::debug(" slot is $slotstatus checkedin ($checkedin) got_grade ($got_grade) is_correct ($is_correct)");      &Apache::lonxml::debug(" slot is $slotstatus checkedin ($checkedin) got_grade ($got_grade) is_correct ($is_correct)");
Line 384  sub check_slot_access { Line 425  sub check_slot_access {
                         &Apache::loncommon::get_future_slots($cnum,$cdom,$now,$symb);                          &Apache::loncommon::get_future_slots($cnum,$cdom,$now,$symb);
                     if ((ref($reservable_now_order) eq 'ARRAY') && (ref($reservable_now) eq 'HASH')) {                      if ((ref($reservable_now_order) eq 'ARRAY') && (ref($reservable_now) eq 'HASH')) {
                         if (@{$reservable_now_order} > 0) {                          if (@{$reservable_now_order} > 0) {
                             $slotstatus = 'RESERVABLE';                              if ((!$checkedin) || (ref($consumed_uniq) ne 'ARRAY')) {
                             $datemsg = $reservable_now->{$reservable_now_order->[-1]}{'endreserve'};                                  $slotstatus = 'RESERVABLE';
                                   $datemsg = $reservable_now->{$reservable_now_order->[-1]}{'endreserve'};
                               } else {
                                   my ($uniqstart,$uniqend,$useslot);
                                   if (ref($consumed_uniq) eq 'ARRAY') {
                                       ($uniqstart,$uniqend)=@{$consumed_uniq};
                                   }
                                   foreach my $slot (reverse(@{$reservable_now_order})) {
                                       if ($reservable_now->{$slot}{'uniqueperiod'} =~ /^(\d+)\,(\d+)$/) {
                                           my ($new_uniq_start,$new_uniq_end) = ($1,$2);
                                           next if (!
                                               ($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) ||
                                               ($uniqstart > $new_uniq_end   &&  $uniqend > $new_uniq_end  ));
                                       }
                                       $useslot = $slot;
                                       last;
                                   }
                                   if ($useslot) {
                                       $slotstatus = 'RESERVABLE';
                                       $datemsg = $reservable_now->{$useslot}{'endreserve'};
                                   }
                               }
                         }                          }
                     }                      }
                     unless ($slotstatus eq 'RESERVABLE') {                      unless ($slotstatus eq 'RESERVABLE') {
                         if ((ref($reservable_future_order) eq 'ARRAY') && (ref($reservable_future) eq 'HASH')) {                          if ((ref($reservable_future_order) eq 'ARRAY') && (ref($reservable_future) eq 'HASH')) {
                             if (@{$reservable_future_order} > 0) {                              if (@{$reservable_future_order} > 0) {
                                 $slotstatus = 'RESERVABLE_LATER';                                  if ((!$checkedin) || (ref($consumed_uniq) ne 'ARRAY')) {
                                 $datemsg = $reservable_future->{$reservable_future_order->[0]}{'startreserve'};                                      $slotstatus = 'RESERVABLE_LATER';
                                       $datemsg = $reservable_future->{$reservable_future_order->[0]}{'startreserve'};
                                   } else {
                                       my ($uniqstart,$uniqend,$useslot);
                                       if (ref($consumed_uniq) eq 'ARRAY') {
                                           ($uniqstart,$uniqend)=@{$consumed_uniq};
                                       }
                                       foreach my $slot (@{$reservable_future_order}) {
                                           if ($reservable_future->{$slot}{'uniqueperiod'} =~ /^(\d+),(\d+)$/) {
                                               my ($new_uniq_start,$new_uniq_end) = ($1,$2);
                                               next if (!
                                                  ($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) ||
                                                  ($uniqstart > $new_uniq_end   &&  $uniqend > $new_uniq_end  ));
                                           }
                                           $useslot = $slot;
                                           last;
                                       }
                                       if ($useslot) {
                                           $slotstatus = 'RESERVABLE_LATER';
                                           $datemsg = $reservable_future->{$useslot}{'startreserve'};
                                       }
                                   }
                             }                              }
                         }                          }
                     }                      }
Line 561  sub check_access { Line 644  sub check_access {
     if ($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER') {      if ($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER') {
  my @interval=&Apache::lonnet::EXT("resource.$id.interval",$symb);   my @interval=&Apache::lonnet::EXT("resource.$id.interval",$symb);
  &Apache::lonxml::debug("looking for interval @interval");   &Apache::lonxml::debug("looking for interval @interval");
  if ($interval[0]) {   if ($interval[0]=~ /^\d+/) {
     my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);      my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
     &Apache::lonxml::debug("looking for accesstime $first_access");      &Apache::lonxml::debug("looking for accesstime $first_access");
     if (!$first_access) {      if (!$first_access) {
  $status='NOT_YET_VIEWED';   $status='NOT_YET_VIEWED';
  my $due_date = &due_date($id,$symb);   my $due_date = &due_date($id,$symb);
  my $seconds_left = $due_date - time;   my $seconds_left = $due_date - time;
  if ($seconds_left > $interval[0] || $due_date eq '') {   my ($timelimit) = ($interval[0] =~ /^(\d+)/);
     $seconds_left = $interval[0];   if ($seconds_left > $timelimit || $due_date eq '') {
       $seconds_left = $timelimit;
  }   }
  $datemsg=&seconds_to_human_length($seconds_left);   $datemsg=&seconds_to_human_length($seconds_left);
     }      }
Line 604  sub due_date { Line 688  sub due_date {
  my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);   my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
  &Apache::lonxml::debug("looking for first_access $first_access ($interval[1])");   &Apache::lonxml::debug("looking for first_access $first_access ($interval[1])");
  if (defined($first_access)) {   if (defined($first_access)) {
     my $interval = $first_access+$interval[0];      my ($timelimit) = ($interval[0] =~ /^(\d+)/);
       my $interval = $first_access+$timelimit;
     $date = (!$due_date || $interval < $due_date) ? $interval      $date = (!$due_date || $interval < $due_date) ? $interval
                                                           : $due_date;                                                            : $due_date;
  } else {   } else {
Line 1172  sub editxmlmode { Line 1257  sub editxmlmode {
 #    Render the page in whatever target desired.  #    Render the page in whatever target desired.
 #  #
 sub renderpage {  sub renderpage {
     my ($request,$file,$targets,$return_string) = @_;      my ($request,$file,$targets,$return_string,$donebuttonmsg) = @_;
   
     my @targets = @{$targets || [&get_target()]};      my @targets = @{$targets || [&get_target()]};
     &Apache::lonhomework::showhashsubset(\%env,'form.');      &Apache::lonhomework::showhashsubset(\%env,'form.');
Line 1225  sub renderpage { Line 1310  sub renderpage {
     if ($target eq 'analyze') {      if ($target eq 'analyze') {
  $result=&Apache::lonnet::hashref2str(\%Apache::lonhomework::analyze);   $result=&Apache::lonnet::hashref2str(\%Apache::lonhomework::analyze);
  undef(%Apache::lonhomework::analyze);   undef(%Apache::lonhomework::analyze);
     }      } elsif ($target eq 'web') {
                   if ($donebuttonmsg) {
                       $result =~ s{</body>}{};
                       $result.= &Apache::loncommon::confirmwrapper(&Apache::lonhtmlcommon::confirm_success($donebuttonmsg,1))."\n</body>";
                   }
               }
     #my $td=&tv_interval($t0);      #my $td=&tv_interval($t0);
     #if ( $Apache::lonxml::debug) {      #if ( $Apache::lonxml::debug) {
     #$result =~ s:</body>::;      #$result =~ s:</body>::;
Line 1341  sub get_template_html { Line 1431  sub get_template_html {
 sub newproblem {  sub newproblem {
     my ($request) = @_;      my ($request) = @_;
   
  if ($env{'form.mode'} eq 'blank'){      if ($env{'form.mode'} eq 'blank'){
         my $dest = &Apache::lonnet::filelocation("",$request->uri);          my $dest = &Apache::lonnet::filelocation("",$request->uri);
         &File::Copy::copy('/home/httpd/html/res/adm/includes/templates/blank.problem',$dest);          my $templatefilename =
               $request->dir_config('lonIncludes').'/templates/blank.problem';
           &File::Copy::copy($templatefilename,$dest);
         &renderpage($request,$dest);          &renderpage($request,$dest);
         return;          return;
     }      }
       my $errormsg;
     if ($env{'form.template'}) {      if ($env{'form.template'}) {
  my $file = $env{'form.template'};          my $file;
  my $dest = &Apache::lonnet::filelocation("",$request->uri);          my ($extension) = ($env{'form.template'} =~ /\.(\w+)$/);
  &File::Copy::copy($file,$dest);          if ($extension) {
  &renderpage($request,$dest);              my @files = &get_template_list($extension);
  return;              foreach my $poss (@files) {
                   if (ref($poss) eq 'ARRAY') {
                       if ($env{'form.template'} eq $poss->[0]) {
                           $file = $env{'form.template'};
                           last;
                       }
                   }
               }
               if ($file) {
           my $dest = &Apache::lonnet::filelocation("",$request->uri);
           &File::Copy::copy($file,$dest);
           &renderpage($request,$dest);
           return;
               } else {
                   $errormsg = '<p class="LC_error">'.&mt('Invalid template file.').'</p>';
               }
           } else {
               $errormsg = '<p class="LC_error">'.&mt('Invalid template file; template needs to be a .problem, .library, or .task file.').'</p>';
           }
     }      }
   
     my ($extension) = ($request->uri =~ m/\.(\w+)$/);      my ($extension) = ($request->uri =~ m/\.(\w+)$/);
Line 1369  sub newproblem { Line 1480  sub newproblem {
     } else {      } else {
  my $url=&HTML::Entities::encode($request->uri,'<>&"');   my $url=&HTML::Entities::encode($request->uri,'<>&"');
  my $dest = &Apache::lonnet::filelocation("",$request->uri);   my $dest = &Apache::lonnet::filelocation("",$request->uri);
  my $errormsg;  
  my $instructions;   my $instructions;
         my $brcrum = [{'href' => &Apache::loncommon::authorspace($request->uri),          my $brcrum = [{'href' => &Apache::loncommon::authorspace($request->uri),
                        'text' => 'Authoring Space'},                         'text' => 'Authoring Space'},
Line 1430  sub zero_timer { Line 1540  sub zero_timer {
     my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb);      my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb);
     if (@interval > 1) {      if (@interval > 1) {
         if ($interval[1] eq 'course') {          if ($interval[1] eq 'course') {
             return;              return ('fail',&mt('Ending of timed events not supported for intervals set course-wide'));
         } else {          } else {
             my $now = time;              my $now = time;
             my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);              my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
             if ($first_access > 0) {              if ($first_access > 0) {
                 my ($timelimit) = split(/_/,$interval[0]);                  my ($timelimit,$donesuffix) = split(/_/,$interval[0],2);
                 if ($first_access+$timelimit > $now) {                  if ($donesuffix =~ /^done(?:|\:[^\:]+\:)(.*)$/) {
                     my $done_time = $now - $first_access;                      my ($dummy,$proctor,$secret) = split(/_/,$1);
                     my $snum = 1;                      if (($proctor) && ($secret ne '')) {
                     if ($interval[1] eq 'map') {                          my $key = $env{'form.LC_interval_done_proctorpass'};
                         $snum = 2;                          $key =~ s/^\s+//;
                           $key =~ s/\s+$//;
                           if ($env{'form.LC_interval_done_proctorpass'} ne $secret) {
                               return ('fail',
                                      &mt('Incorrect key entered by proctor')); 
                           }
                     }                      }
                     my $result =                       if ($first_access+$timelimit > $now) {
                         &Apache::lonparmset::storeparm_by_symb_inner($symb,'0_interval',                          my $done_time = $now - $first_access;
                                                                      $snum,$done_time,                          my $snum = 1;
                                                                      'date_interval',                          if ($interval[1] eq 'map') {
                                                                      $env{'user.name'},                              $snum = 2;
                                                                      $env{'user.domain'});                          }
                     return $result;                          my $result =
                               &Apache::lonparmset::storeparm_by_symb_inner($symb,'0_interval',
                                                                            $snum,$done_time,
                                                                            'date_interval',
                                                                            $env{'user.name'},
                                                                            $env{'user.domain'});
                           if ($result eq '') {
                               # Record action in "User Notes"
                               &Apache::lonmsg::store_instructor_comment(
                                   'Pressed Done button for symb:<br />'.$symb,
                                   $env{'user.name'}, $env{'user.domain'});
                               return ('ok');
                           } else {
                               return ('fail',&mt('Error ending timed event: [_1]',$result));
                           } 
                       } else {
                           return ('fail',&mt('Timed event already ended'));
                       }
                   } else {
                       return ('fail',&mt('Timed event can not be ended before the time limit'));
                 }                  }
               } else {
                   return ('fail',&mt('Timer not yet started for this timed event'));
             }              }
         }          }
       } else {
           return ('fail',&mt('No timer in use'));
     }      }
     return;      return();
 }  }
   
 sub handler {  sub handler {
Line 1515  sub handler { Line 1653  sub handler {
     } else {      } else {
         # Set the event timer to zero if the "done button" was clicked.  The button is          # Set the event timer to zero if the "done button" was clicked.  The button is
         # part of the doneButton form created in lonmenu.pm          # part of the doneButton form created in lonmenu.pm
           my ($donebuttonresult,$donemsg);
         if ($symb && $env{'form.LC_interval_done'} eq 'true') {            if ($symb && $env{'form.LC_interval_done'} eq 'true') {  
             &zero_timer($symb);              ($donebuttonresult,$donemsg) = &zero_timer($symb);
             undef($env{'form.LC_interval_done'});              undef($env{'form.LC_interval_done'});
               undef($env{'form.LC_interval_done_proctorpass'});
         }          }
  # just render the page normally outside of construction space   # just render the page normally outside of construction space
  &Apache::lonxml::debug("not construct");   &Apache::lonxml::debug("not construct");
  &renderpage($request,$file);   &renderpage($request,$file,undef,undef,$donemsg);
     }      }
     #my $td=&tv_interval($t0);      #my $td=&tv_interval($t0);
     #&Apache::lonxml::debug("Spent $td seconds processing");      #&Apache::lonxml::debug("Spent $td seconds processing");
Line 1667  sub default_xml_tag { Line 1807  sub default_xml_tag {
   
 sub helpmenu_datastructure {  sub helpmenu_datastructure {
   
  my $width = 500;   # filename, title, width, height
  my $height = 600;  
   
  my $helpers = [   my $helpers = [
  ['Problem_LON-CAPA_Functions', &mt('Script Functions')],   ['Problem_LON-CAPA_Functions.hlp', &mt('Script Functions'), 800, 600],
  ['Greek_Symbols', &mt('Greek Symbols')],   ['Greek_Symbols.hlp', &mt('Greek Symbols'), 500, 600],
   ['Other_Symbols', &mt('Other Symbols')],    ['Other_Symbols.hlp', &mt('Other Symbols'), 500, 600],
  ['Authoring_Output_Tags', &mt('Output Tags')],   ['Authoring_Output_Tags.hlp', &mt('Output Tags'), 800, 600],
  ['Authoring_Multilingual_Problems',    ['Authoring_Multilingual_Problems.hlp', 
  &mt('How to create problems in different languages')]   &mt('How to create problems in different languages'), 800, 600],
    ['loncapa.html', &mt('Language reference'), 800, 600],
  ];   ];
   
  my $help_structure = [];   my $help_structure = [];
Line 1684  sub helpmenu_datastructure { Line 1823  sub helpmenu_datastructure {
  foreach my $count (0..(scalar(@{$helpers})-1)) {   foreach my $count (0..(scalar(@{$helpers})-1)) {
  my $filename = $helpers->[$count]->[0];   my $filename = $helpers->[$count]->[0];
  my $title = $helpers->[$count]->[1];   my $title = $helpers->[$count]->[1];
  my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');");   my $width = $helpers->[$count]->[2];
                   my $height = $helpers->[$count]->[3];
    my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename',$width,$height,'yes');");
  push @{$help_structure}, [$href, $title, undef];   push @{$help_structure}, [$href, $title, undef];
  }   }
   

Removed from v.1.358  
changed lines
  Added in v.1.367


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