--- loncom/homework/bridgetask.pm	2010/09/27 20:59:41	1.254
+++ loncom/homework/bridgetask.pm	2023/01/23 20:31:13	1.273
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: bridgetask.pm,v 1.254 2010/09/27 20:59:41 raeburn Exp $
+# $Id: bridgetask.pm,v 1.273 2023/01/23 20:31:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -37,6 +37,7 @@ use Apache::lonmenu;
 use Apache::lonlocal;
 use Apache::lonxml;
 use Apache::slotrequest();
+use Apache::structuretags();
 use Time::HiRes qw( gettimeofday tv_interval );
 use LONCAPA;
  
@@ -64,6 +65,7 @@ sub initialize_bridgetask {
 sub proctor_check_auth {
     my ($slot_name,$slot,$type)=@_;
     my $user=$env{'form.proctorname'};
+    $user =~ s/^\s+|\s+$//g;
     my $domain=$env{'form.proctordomain'};
     
     my @allowed=split(",",$slot->{'proctor'});
@@ -82,7 +84,7 @@ sub proctor_check_auth {
 		}
 	    }
 	    if ($authenticated) {
-		my $check = &check_in($type,$user,$domain,$slot_name);
+		my $check = &check_in($type,$user,$domain,$slot_name,$slot->{'iptied'});
                 if ($check =~ /^error:/) {
                     return 0;
                 }
@@ -94,47 +96,82 @@ sub proctor_check_auth {
 }
 
 sub check_in {
-    my ($type,$user,$domain,$slot_name) = @_;
+    my ($type,$user,$domain,$slot_name,$needsiptied) = @_;
     my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
+    my $ip=$ENV{'REMOTE_ADDR'} || $env{'request.host'};
     if ( $useslots eq 'map_map') {
-	my $result = &check_in_sequence($user,$domain,$slot_name);
+	my $result = &check_in_sequence($user,$domain,$slot_name,$ip,$needsiptied);
         if ($result =~ /^error: /) {
             return $result;
         }
     } else {
-	&create_new_version($type,$user,$domain,$slot_name);
-	&Apache::structuretags::finalize_storage();
+        my ($symb) = &Apache::lonnet::whichuser();
+	my $result = &create_new_version($type,$user,$domain,$slot_name,$symb,$ip,$needsiptied);
+        if ($result eq 'ok') {
+	    &Apache::structuretags::finalize_storage();
+        }
+        return $result; 
     }
     return 1;
 }
 
 sub check_in_sequence {
-    my ($user,$domain,$slot_name) = @_;
+    my ($user,$domain,$slot_name,$ip,$needsiptied) = @_;
     my $navmap = Apache::lonnavmaps::navmap->new();
     if (!defined($navmap)) {
-        return 'error: ';
+        return 'error: No navmap';
     }
     my ($symb) = &Apache::lonnet::whichuser();
     my ($map)  = &Apache::lonnet::decode_symb($symb);
     my @resources = 
-	$navmap->retrieveResources($map, sub { $_[0]->is_problem() },0,0);
+	$navmap->retrieveResources($map, sub { $_[0]->is_problem() || $_[0]->is_tool() },0,0);
     my %old_history = %Apache::lonhomework::history;
     my %old_results = %Apache::lonhomework::results;
 
+    my $errorcount;
     foreach my $res (@resources) {
 	&Apache::lonxml::debug("doing ".$res->src);
 	&Apache::structuretags::initialize_storage($res->symb);
-	my $type = ($res->is_task()) ? 'Task' : 'problem';
-	&create_new_version($type,$user,$domain,$slot_name);
-	&Apache::structuretags::finalize_storage($res->symb);
+	my $type;
+        if ($res->is_task()) {
+            $type = 'Task';
+        } elsif ($res->is_tool) {
+            $type = 'tool';
+        } else {
+            $type = 'problem';
+        }
+	my $result = &create_new_version($type,$user,$domain,$slot_name,$res->symb,$ip,$needsiptied);
+        if ($result eq 'ok') {
+	    &Apache::structuretags::finalize_storage($res->symb);
+        } else {
+            $errorcount ++;
+        }
     }
     
     %Apache::lonhomework::history = %old_history;
     %Apache::lonhomework::results = %old_results;
+    if ($errorcount) {
+        return 'error: IP taken';
+    }
 }
 
 sub create_new_version {
-    my ($type,$user,$domain,$slot_name) = @_;
+    my ($type,$user,$domain,$slot_name,$symb,$ip,$needsiptied) = @_;
+
+    if ($needsiptied) {
+        my $uniqkey = "$slot_name\0$symb\0$ip";
+        my ($cdom,$cnum);
+        if ($env{'request.course.id'}) {
+            my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+            my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+            my %hash = (
+                          "$slot_name\0$symb\0$ip" => $env{'user.name'}.':'.$env{'user.domain'}, 
+                       );
+            unless (&Apache::lonnet::newput('slot_uniqueips',\%hash,$cdom,$cnum) eq 'ok') {
+                return 'error: IP taken';
+            }
+        }
+    }
     
     my $id = '0';
     if ($type eq 'Task') {
@@ -158,7 +195,7 @@ sub create_new_version {
 	    $domain = $env{'user.domain'};
 	}
 	
-    } elsif ($type eq 'problem') {
+    } elsif (($type eq 'problem') || ($type eq 'tool')) {
 	&Apache::lonxml::debug("authed $slot_name");
     }
     if (!defined($user) || !defined($domain)) {
@@ -168,11 +205,13 @@ sub create_new_version {
 
     $Apache::lonhomework::results{"resource.$id.checkedin"}=
 	$user.':'.$domain;
+    $Apache::lonhomework::results{"resource.$id.checkedin.ip"}=$ip;
 
     if (defined($slot_name)) {
 	$Apache::lonhomework::results{"resource.$id.checkedin.slot"}=
 	    $slot_name;
     }
+    return 'ok'; 
 }
 
 sub get_version {
@@ -198,6 +237,10 @@ sub get_version {
 
 sub add_previous_version_button {
     my ($status)=@_;
+    my (undef,undef,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
     my $result;
     if ($Apache::lonhomework::history{'resource.0.version'} eq '') {
 	return '';
@@ -234,7 +277,10 @@ sub add_previous_version_button {
 }
 
 sub add_grading_button {
-    my (undef,$cid)=&Apache::lonnet::whichuser();
+    my (undef,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
     my $cnum=$env{'course.'.$cid.'.num'};
     my $cdom=$env{'course.'.$cid.'.domain'};
     my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
@@ -244,15 +290,19 @@ sub add_grading_button {
 	$size=scalar(keys(%sections))+2;
     }
     my $sec_select = "\n".'<select multiple="multiple" name="chosensections" size="'.$size.'">'."\n";
-    $sec_select .= "\t<option value='all' selected='selected'>all</option>\n";
+    $sec_select .= "\t".'<option value="all" selected="selected">'.&mt('all')."</option>\n";
     foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
 	$sec_select .= "\t<option value=\"$sec\">$sec</option>\n";
     }
-    $sec_select .= "\t<option value='none'>none</option>\n</select>\n";
-    
-    my $result="\n\t".'<input type="submit" name="gradeasubmission" value="'.
-	&mt("Get a submission to grade").'" />';
-    $result.="\n\t".'<input type="hidden" name="grade_target" value="webgrade" />';
+    $sec_select .= "\t".'<option value="none">'.&mt('none')."</option>\n</select>\n";
+
+    my $uri=$env{'request.uri'};
+    if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
+    my $result = 
+        '<form name="gradesubmission" method="post" action="'.$uri.'">'.
+        "\n\t".'<input type="submit" name="gradeasubmission" value="'.
+	&mt("Get a submission to grade").'" />'.
+        "\n\t".'<input type="hidden" name="grade_target" value="webgrade" />';
     my $see_all = &Apache::lonnet::allowed('mgq',$env{'request.course.id'});
     my $see_sec = &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.
 					   '/'.$env{'request.course.sec'});
@@ -298,11 +348,46 @@ sub add_grading_button {
 	$result.=&Apache::loncommon::studentbrowser_javascript();
 	$result.= '</p>'."\n";
     }
+    $result .= '</form>'."\n";
+    return $result;
+}
+
+sub add_slotlist_button {
+    my (undef,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
+    my $symb=&Apache::lonnet::symbread();
+    my $result;
+    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'}) ||
+        &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
+        $result = '<form method="post" name="slotrequest" action="/adm/slotrequest">'.
+                  '<input type="hidden" name="symb" value="'.$symb.'" />'.
+                  '<input type="hidden" name="command" value="showslots" />'.
+                  '<input type="submit" name="requestattempt" value="'.
+                  &mt('Show Slot list').'" />'.
+                  '</form>';
+        my $target_id =
+               &Apache::lonstathelpers::make_target_id({symb => $symb,
+                                                             part => '0'});
+        if (!&section_restricted()) {
+            $result.='<form method="post" name="gradingstatus" action="/adm/statistics">'.
+                     '<input type="hidden" name="problemchoice" value="'.$target_id.'" />'.
+                     '<input type="hidden" name="reportSelected" value="grading_analysis" />'.
+                     '<input type="submit" name="grading" value="'.
+                     &mt('Show Grading Status').'" />'.
+                     '</form>';
+        }
+    }
     return $result;
 }
 
 sub add_request_another_attempt_button {
     my ($text)=@_;
+    my (undef,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
+    if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
+        return;
+    }
     if (!$text) { $text=&mt('Request another attempt'); }
     my $result;
     my $symb=&Apache::lonnet::symbread();
@@ -380,6 +465,7 @@ sub show_task {
 		       ( $status eq 'BANNED') ||
 		       ( $status eq 'UNAVAILABLE') ||
 		       ( $status eq 'NOT_IN_A_SLOT') ||
+                       ( $status eq 'NOT_YET_VIEWED') ||
 		       ( $status eq 'NEEDS_CHECKIN') ||
 		       ( $status eq 'WAITING_FOR_GRADE') ||
 		       ( $status eq 'INVALID_ACCESS') ||
@@ -545,23 +631,35 @@ sub done_screen {
     my $title=&Apache::lonnet::gettitle($env{'request.uri'});
     my @files=split(',',$Apache::lonhomework::history{'resource.'.$version.'.0.bridgetask.portfiles'});
     my (undef,undef,$domain,$user)= &Apache::lonnet::whichuser();
-    my $files = '<ul>';
-    my $msg;
-    foreach my $file (@files) {
-	my $url="/uploaded/$domain/$user/portfolio$file";
-	if (! &Apache::lonnet::stat_file($url)) {
-	    $file = '<span class="LC_error">'
-                   .&mt('[_1]Nonexistent file:[_2]'
-                       ,'<span class="LC_error"> '
-                       ,'</span> <span class="LC_filename">'.$file.'</span>');
-	    $msg .= "<p>".&mt('Submitted non-existent file [_1]',$file)."</p>\n";
-	} else {
-	    $file = '<span class="LC_filename">'.$file.'</span>';
-	    $msg .= "<p>".&mt('Submitted file [_1]',$file)."</p>\n";
-	}
-	$files .= '<li>'.$file.'</li>';
+    my ($msg,$files,$shown);
+    if (@files > 0) {
+        $files = '<ul>';
+        foreach my $file (@files) {
+	    my $url="/uploaded/$domain/$user/portfolio$file";
+	    if (! &Apache::lonnet::stat_file($url)) {
+	        $file = '<span class="LC_error">'
+                       .&mt('[_1]Nonexistent file:[_2]'
+                           ,'<span class="LC_error"> '
+                           ,'</span> <span class="LC_filename">'.$file.'</span>');
+	        $msg .= "<p>".&mt('Submitted non-existent file [_1]',$file)."</p>\n";
+	    } else {
+	        $file = '<span class="LC_filename">'.$file.'</span>';
+	        $msg .= "<p>".&mt('Submitted file [_1]',$file)."</p>\n";
+	    }
+	    $files .= '<li>'.$file.'</li>';
+        }
+        $files.='</ul>';
+        $shown = '<p>'.&mt('Files submitted: [_1]',$files).'</p>'
+                .'<p>'.&mt('You are now done with this Bridge Task').'</p>'
+                .'<hr />'
+                .'<p><a href="/adm/logout">'.&mt('Logout').'</a></p>'
+                .'<p><a href="/adm/roles">'.&mt('Change to a different course').'</a></p>';
+    } else {
+        $msg = &mt("Submission status: no files currently submitted, when 'Done' was indicated.");
+        $shown = '<p class="LC_error">'.
+                 &mt('You did not submit any files.  Please try again.').'</span>'.
+                 '</p><p><a href="javascript:history.go(-1);">'.&mt('Back to Bridge Task').'</a></p><hr />';
     }
-    $files.='</ul>';
     my $subject = &mt('Submission message for [_1]',$title);
     my ($message_status,$comment_status);
     my $setting = $env{'course.'.$env{'request.course.id'}.'.task_messages'};
@@ -581,15 +679,11 @@ sub done_screen {
 	$comment_status = '<p>'.&mt('Message sent to instructor: [_1]',
 				    $comment_status).' </p>';
     }
+ 
     return "<h2>$title</h2>"
-          .'<p>'.&mt('Files submitted: [_1]',$files).'</p>'
-          .'<p>'.&mt('You are now done with this Bridge Task').'</p>'
-          .'<hr />'
-          .'<p><a href="/adm/logout">'.&mt('Logout').'</a></p>'
-.'<p><a href="/adm/roles">'.&mt('Change to a different course').'</a></p>'
-.$message_status
-.$comment_status;
-
+          .$shown
+          .$message_status
+          .$comment_status;
 }
 
 sub start_Task {
@@ -619,35 +713,25 @@ sub start_Task {
 	    &Apache::structuretags::page_start($target,$token,$tagstack,
 					       $parstack,$parser,$safeeval,
 					       $name,&style($target));
+
+    }
+    if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
+        $target eq 'tex') {
+        if ($env{'form.markaccess'}) {
+            my @interval=&Apache::lonnet::EXT("resource.0.interval");
+            my ($timelimit) = ($interval[0] =~ /^(\d+)/);
+            &Apache::lonnet::set_first_access($interval[1],$timelimit);
+        }
     }
 
     if ($target eq 'web' && $env{'request.state'} ne 'construct') {
 	if ($Apache::lonhomework::queuegrade
 	    || $Apache::lonhomework::modifygrades) {
-	    $result.='<form name="gradesubmission" method="post" action="';
-	    my $uri=$env{'request.uri'};
-	    if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
-	    $result.=$uri.'">'.&add_grading_button()."</form>\n";
+	    $result .= &add_grading_button();
 	    my $symb=&Apache::lonnet::symbread();
 	    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})
 		|| &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
-		$result.='<form method="post" name="slotrequest" action="/adm/slotrequest">'.
-		    '<input type="hidden" name="symb" value="'.$symb.'" />'.
-		    '<input type="hidden" name="command" value="showslots" />'.
-		    '<input type="submit" name="requestattempt" value="'.
-		    &mt('Show Slot list').'" />'.
-		    '</form>';
-		my $target_id = 
-		    &Apache::lonstathelpers::make_target_id({symb => $symb,
-							     part => '0'});
-		if (!&section_restricted()) {
-		    $result.='<form method="post" name="gradingstatus" action="/adm/statistics">'.
-			'<input type="hidden" name="problemchoice" value="'.$target_id.'" />'.
-			'<input type="hidden" name="reportSelected" value="grading_analysis" />'.
-			'<input type="submit" name="grading" value="'.
-			&mt('Show Grading Status').'" />'.
-			'</form>';
-		}
+                $result .= &add_slotlist_button(); 
 	    }
 	}
     }
@@ -661,23 +745,38 @@ sub start_Task {
 	my ($version,$previous)=&get_version();
 	($status,$accessmsg,my $slot_name,$slot) = 
 	    &Apache::lonhomework::check_slot_access('0','Task');
-	if ($status eq 'CAN_ANSWER' && $version eq '') {
-	    # CAN_ANSWER mode, and no current version, unproctored access
+	if ((($status eq 'CAN_ANSWER') || ($status eq 'NOT_YET_VIEWED')) && ($version eq '')) {
+	    # CAN_ANSWER or NOT_YET_VIEWED mode, and no current version, unproctored access
 	    # thus self-checkedin
-	    my $check = &check_in('Task',undef,undef,$slot_name);
-            if ($check =~ /^error: /) {
+            my $needsiptied;
+            if (ref($slot)) {
+                $needsiptied = $slot->{'iptied'};
+            }
+	    my $check = &check_in('Task',undef,undef,$slot_name,$needsiptied);
+            if ($check =~ /^error:\s+(.*)$/) {
                 my $symb=&Apache::lonnet::symbread();
-                &Apache::lonnet::logthis("Error during self-checkin of version $version of Task (symb: $symb) using slot: $slot_name");   
+                &Apache::lonnet::logthis("Error: $1 during self-checkin of version $version of Task (symb: $symb) using slot: $slot_name");   
             }
 	    &add_to_queue('gradingqueue',{'type' => 'Task',
 					  'time' => time,
 					  'slot' => $slot_name});
 	    ($version,$previous)=&get_version();
 	}
-	
-	my $status_id = 
-	    ($previous || $status eq 'SHOW_ANSWER') ? 'LC_task_feedback'
-	                                            : 'LC_task_take';
+        if (($target eq 'web') && ($version ne '') && ($slot_name ne '')) {
+            if (ref($slot) eq 'HASH') {
+                if ($slot->{'endtime'} > time()) {
+                    $result .=
+                        &Apache::lonhtmlcommon::set_due_date($slot->{'endtime'});
+                }
+            }
+	}
+
+	my $status_id = 'LC_task_take';
+        if ($previous && $target eq 'answer') {
+            $status_id = 'LC_task_answer';
+        } elsif ($previous || $status eq 'SHOW_ANSWER') {
+	    $status_id = 'LC_task_feedback';
+        }
 	$result .= '<div class="LC_task" id="'.$status_id.'">'."\n";
 
 	push(@Apache::inputtags::status,$status);
@@ -695,19 +794,24 @@ sub start_Task {
 		}
 		my $msg;
 		if ($status eq 'UNAVAILABLE') {
-		    $msg.='<h1>'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</h1>';
+		    $msg.='<p class="LC_error">'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</p>';
 		} elsif ($status eq 'NOT_IN_A_SLOT') {
-		    $msg.='<h1>'.&mt('You are not currently signed up to work at this time and/or place.').'</h1>';
+		    $msg.='<p class="LC_warning">'.&mt('You are not currently signed up to work at this time and/or place.').'</p>';
 		    $msg.=&add_request_another_attempt_button("Sign up for time to work");
 		} elsif ($status eq 'NEEDS_CHECKIN') {
-		    $msg.='<h1>'.&mt('You need the Proctor to validate you.').
-			'</h1>'.&proctor_validation_screen($slot);
+		    $msg.='<p class="LC_warning">'.&mt('You need the Proctor to validate you.').
+			'</p>'.&proctor_validation_screen($slot);
 		} elsif ($status eq 'WAITING_FOR_GRADE') {
-		    $msg.='<h1>'.&mt('Your submission is in the grading queue.').'</h1>';
+		    $msg.='<p class="LC_info">'.&mt('Your submission is in the grading queue.').'</p>';
 		} elsif ($env{'form.donescreen'}) {
 		    $result .= &done_screen($version);
-		} elsif ($status ne 'NOT_YET_VIEWED') {
-		    $msg.='<h1>'.&mt('Not open to be viewed').'</h1>';
+		} elsif ($status eq 'NOT_YET_VIEWED') {
+                    my $symb=&Apache::lonnet::symbread();
+                    $msg.=&Apache::structuretags::firstaccess_msg($accessmsg,$symb);
+                } elsif ($status eq 'NEED_DIFFERENT_IP') {
+#FIXME
+		} else {
+		    $msg.='<p class="LC_warning">'.&mt('Not open to be viewed').'</p>';
 		}
 		if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') {
 		    $msg.='The problem '.$accessmsg;
@@ -937,7 +1041,7 @@ sub get_key_todo {
 	    my $classlist=&get_limited_classlist();
 	    if (!&allow_grade_user($classlist->{$uname.':'.$udom})) {
 		return (undef,'not_allowed',
-			&mt('Requested student ([_1]) is in a section you aren\'t allowed to grade.',$uname.':'.$udom));
+			&mt("Requested student ([_1]) is in a section you aren't allowed to grade.",$uname.':'.$udom));
 	    }
 	}
 	my $gradingkey=&encode_queue_key($symb,$udom,$uname);
@@ -1104,13 +1208,13 @@ sub end_Task {
                         $portheader = &mt('Submit Portfolio Files for Grading');
                         $porttext = &mt('Indicate the files from your portfolio to be evaluated in grading this task.');
                     }
-		    $result.="\n".'<p>'.&Apache::lonhtmlcommon::start_pick_box().
+		    $result.="\n".'<div>'.&Apache::lonhtmlcommon::start_pick_box().
 			&Apache::inputtags::file_selector("$version.0",
 							  "bridgetask","*",
 							  'portfolioonly',
                                                           '<h3>'.$portheader.'</h3><br />'.
                                                           $porttext.'<br />').
-			&Apache::lonhtmlcommon::end_pick_box().'</p>';
+			&Apache::lonhtmlcommon::end_pick_box().'</div>';
 		}
 		if (!$previous && $status ne 'SHOW_ANSWER' &&
 		    &show_task($status,$previous)) {
@@ -1193,7 +1297,9 @@ DONEBUTTON
 		}
 		$result.="\n</div>\n".
 		    &Apache::loncommon::end_page({'discussion' => 1});
-	    }
+	    } elsif ($target eq 'answer') {
+                $result.="\n</div>\n";
+            }
 	}
 
 	my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
@@ -1204,7 +1310,7 @@ DONEBUTTON
 	} elsif (defined($Apache::lonhomework::history{"resource.$version.0.checkedin.slot"})) {
 	    $queue_data{'slot'} = $Apache::lonhomework::history{"resource.$version.0.checkedin.slot"};
 	}
-	
+
 
 	if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous
 	    && $status eq 'CAN_ANSWER') {
@@ -1331,10 +1437,10 @@ DONEBUTTON
 		    $Apache::lonhomework::results{"resource.$version.0.solved"};
 	    }
 	    &minimize_storage();
-            my ($canstore,$domain,$name);
+            my ($canstore,$domain,$name,$symb,$courseid);
+            ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();
+
             if ($env{'form.gradingkey'}) {
-                (my $symb,my $courseid,$domain,$name) =
-                    &Apache::lonnet::whichuser();
                 my $todo=&unescape($env{'form.gradingkey'});
                 my ($keysymb,$uname,$udom)=&decode_queue_key($todo);
                 if ($symb eq $keysymb) {
@@ -1345,6 +1451,16 @@ DONEBUTTON
             }
             if ($canstore) {
 	        &Apache::structuretags::finalize_storage();
+                my @interval = &Apache::lonnet::EXT("resource.0.interval");
+                if ($interval[0] =~ /^\d+/ && $interval[1] eq 'resource') {
+                    my $key=$courseid."\0".$symb;
+                    my %times=&Apache::lonnet::get('firstaccesstimes',
+                                                   [$key],$domain,$name);
+                    if ($times{$key}) {
+                        my $delresult.=&Apache::lonnet::del('firstaccesstimes',
+                                                            [$key],$domain,$name);
+                    }
+                }
 	        # data stored, now handle queue
 	        if ($review) {
 		    if ($env{'form.queue'} eq 'reviewqueue') {
@@ -1725,7 +1841,7 @@ sub show_queue {
 		    $result.=(<<FORM);
 <td>$status</td>
 <td>
-<form style="display: inline" method="post">
+<form style="display: inline" method="post" action="">
  <input type="hidden" name="gradingkey" value="$ekey" />
  <input type="hidden" name="queue" value="$queue" />
  <input type="hidden" name="gradingaction" value="$action" />
@@ -2144,7 +2260,7 @@ sub select_user {
 	    $result.=&Apache::loncommon::start_data_table_row();
 	    $result.=<<RESULT;
   <td>
-    <form style="display: inline" method="post">
+    <form style="display: inline" method="post" action="">
       <input type="hidden" name="gradingkey" value="$todo" />
       <input type="hidden" name="queue" value="$queue" />
       <input type="hidden" name="webgrade" value="no" />
@@ -3214,9 +3330,9 @@ sub proctor_validation_screen {
 <input type="hidden" name="validate" value="yes" />
 <input type="hidden" name="submitted" value="yes" />
 <table>
-  <tr><td>$lt{'prus'}</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
-  <tr><td>$lt{'pasw'}</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
-  <tr><td>$lt{'prdo'}</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
+  <tr><td>$lt{'prus'}</td><td><input type="text" name="proctorname" value="$env{'form.proctorname'}" autocomplete="new-password" /></td></tr>
+  <tr><td>$lt{'pasw'}</td><td><input type="password" name="proctorpassword" value="" autocomplete="new-password" /></td></tr>
+  <tr><td>$lt{'prdo'}</td><td><input type="text" name="proctordomain" value="$env{'form.proctordomain'}" autocomplete="off" /></td></tr>
 </table>
 <input type="submit" name="checkoutbutton" value="$lt{'vali'}"  /><br />
 <table border="1">