--- loncom/homework/bridgetask.pm 2010/08/23 03:24:01 1.252 +++ loncom/homework/bridgetask.pm 2022/10/18 23:28:01 1.272 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # definition of tags that give a structure to a document # -# $Id: bridgetask.pm,v 1.252 2010/08/23 03:24:01 raeburn Exp $ +# $Id: bridgetask.pm,v 1.272 2022/10/18 23:28:01 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".'\n"; - - my $result="\n\t".''; - $result.="\n\t".''; + $sec_select .= "\t".'\n\n"; + + my $uri=$env{'request.uri'}; + if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); } + my $result = + '
'."\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 = ''; + my $target_id = + &Apache::lonstathelpers::make_target_id({symb => $symb, + part => '0'}); + if (!§ion_restricted()) { + $result.=''; + } + } 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 = '".&mt('Submitted non-existent file [_1]',$file)."
\n"; - } else { - $file = ''.$file.''; - $msg .= "".&mt('Submitted file [_1]',$file)."
\n"; - } - $files .= '".&mt('Submitted non-existent file [_1]',$file)."
\n"; + } else { + $file = ''.$file.''; + $msg .= "".&mt('Submitted file [_1]',$file)."
\n"; + } + $files .= ''.&mt('Files submitted: [_1]',$files).'
' + .''.&mt('You are now done with this Bridge Task').'
' + .''.&mt('Change to a different course').'
'; + } else { + $msg = &mt("Submission status: no files currently submitted, when 'Done' was indicated."); + $shown = ''. + &mt('You did not submit any files. Please try again.').'
'. + ''.&mt('Back to Bridge Task').'
'.&mt('Message sent to instructor: [_1]', $comment_status).'
'; } + return "'.&mt('Files submitted: [_1]',$files).'
' - .''.&mt('You are now done with this Bridge Task').'
' - .''.&mt('Change to a different course').'
' -.$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.='\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.=''; - my $target_id = - &Apache::lonstathelpers::make_target_id({symb => $symb, - part => '0'}); - if (!§ion_restricted()) { - $result.=''; - } + $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 .= ''.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'
'; } elsif ($status eq 'NOT_IN_A_SLOT') { - $msg.=''.&mt('You are not currently signed up to work at this time and/or place.').'
'; $msg.=&add_request_another_attempt_button("Sign up for time to work"); } elsif ($status eq 'NEEDS_CHECKIN') { - $msg.=''.&mt('You need the Proctor to validate you.'). + '
'.&proctor_validation_screen($slot); } elsif ($status eq 'WAITING_FOR_GRADE') { - $msg.=''.&mt('Your submission is in the grading queue.').'
'; } elsif ($env{'form.donescreen'}) { $result .= &done_screen($version); - } elsif ($status ne 'NOT_YET_VIEWED') { - $msg.=''.&mt('Not open to be viewed').'
'; } if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') { $msg.='The problem '.$accessmsg; @@ -784,6 +888,11 @@ sub start_Task { $result.=''.&mt("Stopped grading.").''.$back; } elsif ($status_code eq 'cancel') { $result.=''.&mt("Cancelled grading.").''.$back; + } elsif ($status_code eq 'terminated') { + $result.= ''.&mt('Terminated grading').''.&Apache::lonhtmlcommon::start_pick_box(). + $result.="\n".'