--- loncom/homework/lonhomework.pm 2007/11/13 23:26:08 1.284
+++ loncom/homework/lonhomework.pm 2009/06/30 10:18:47 1.313
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Homework handler
#
-# $Id: lonhomework.pm,v 1.284 2007/11/13 23:26:08 albertel Exp $
+# $Id: lonhomework.pm,v 1.313 2009/06/30 10:18:47 bisitz Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -137,8 +137,8 @@ sub get_target {
if ($env{'form.problemstate'} eq 'WEB_GRADE') {
#$env{'form.webgrade'} = 'yes';
return ('grade','webgrade','answer');
- } elsif ( $env{'form.problemmode'} eq &mt('View') ||
- $env{'form.problemmode'} eq &mt('Discard Edits and View')) {
+ } elsif (($env{'form.problemmode'} eq 'view') ||
+ ($env{'form.problemmode'} eq 'discard')) {
if ( defined($env{'form.submitted'}) &&
(!defined($env{'form.resetdata'})) &&
(!defined($env{'form.newrandomization'}))) {
@@ -146,10 +146,9 @@ sub get_target {
} else {
return ('web','answer');
}
- } elsif ( $env{'form.problemmode'} eq &mt('Edit') ||
- $env{'form.problemmode'} eq 'Edit') {
+ } elsif ($env{'form.problemmode'} eq 'edit') {
if ( $env{'form.submitted'} eq 'edit' ) {
- if ( $env{'form.submit'} eq &mt('Save and View') ) {
+ if ( $env{'form.submitbutton'} eq &mt('Save and View') ) {
return ('modified','web','answer');
} else {
return ('modified','no_output_web','edit');
@@ -174,7 +173,7 @@ sub setup_vars {
sub createmenu {
my ($which,$request)=@_;
if ($which eq 'grade') {
- $request->print('');
@@ -210,58 +209,6 @@ sub proctor_checked_in {
return 0;
}
-sub check_ip_acc {
- my ($acc)=@_;
- &Apache::lonxml::debug("acc is $acc");
- if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
- return 1;
- }
- my $allowed=0;
- my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
-
- my $name;
- foreach my $pattern (split(',',$acc)) {
- $pattern =~ s/^\s*//;
- $pattern =~ s/\s*$//;
- if ($pattern =~ /\*$/) {
- #35.8.*
- $pattern=~s/\*//;
- if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
- } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {
- #35.8.3.[34-56]
- my $low=$2;
- my $high=$3;
- $pattern=$1;
- if ($ip =~ /^\Q$pattern\E/) {
- my $last=(split(/\./,$ip))[3];
- if ($last <=$high && $last >=$low) { $allowed=1; }
- }
- } elsif ($pattern =~ /^\*/) {
- #*.msu.edu
- $pattern=~s/\*//;
- if (!defined($name)) {
- use Socket;
- my $netaddr=inet_aton($ip);
- ($name)=gethostbyaddr($netaddr,AF_INET);
- }
- if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
- } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
- #127.0.0.1
- if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
- } else {
- #some.name.com
- if (!defined($name)) {
- use Socket;
- my $netaddr=inet_aton($ip);
- ($name)=gethostbyaddr($netaddr,AF_INET);
- }
- if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
- }
- if ($allowed) { last; }
- }
- return $allowed;
-}
-
sub check_slot_access {
my ($id,$type)=@_;
@@ -292,9 +239,9 @@ sub check_slot_access {
}
}
- my @slots=
- (split(':',&Apache::lonnet::EXT("resource.0.availablestudent")),
- split(':',&Apache::lonnet::EXT("resource.0.available")));
+ my $availablestudent = &Apache::lonnet::EXT("resource.0.availablestudent");
+ my $available = &Apache::lonnet::EXT("resource.0.available");
+ my @slots= (split(':',$availablestudent),split(':',$available));
# if (!@slots) {
# return ($status,$datemsg);
@@ -308,7 +255,7 @@ sub check_slot_access {
&Apache::lonhomework::showhash(%slot);
if ($slot{'starttime'} < time &&
$slot{'endtime'} > time &&
- &check_ip_acc($slot{'ip'})) {
+ &Apache::loncommon::check_ip_acc($slot{'ip'})) {
&Apache::lonxml::debug("$slot is good");
$slotstatus='NEEDS_CHECKIN';
$returned_slot=\%slot;
@@ -350,12 +297,15 @@ sub check_slot_access {
return ('WAITING_FOR_GRADE');
}
- # no slot is currently open, and has been checked in for this version
- # previous slot is therefore CLOSED, so therefore the problem is
+ # Previously used slot is no longer open, and has been checked in for this version.
+ # However, the problem is not closed, and potentially, another slot might be
+ # used to gain access to it to work on it, until the due date is reached, and the
+ # problem then becomes CLOSED. Therefore return the slotstatus -
+ # (which will be NOT_IN_SLOT).
if (!defined($slot_name)
&& $checkedin
&& $type eq 'problem') {
- return ('CLOSED',$datemsg);
+ return ($slotstatus);
}
if ($slotstatus eq 'NOT_IN_A_SLOT'
@@ -421,7 +371,8 @@ sub check_access {
&Apache::lonxml::debug("symb:".$symb);
#if ($env{'request.state'} ne "construct" && $symb ne '') {
if ($env{'request.state'} ne "construct") {
- my $allowed=&check_ip_acc(&Apache::lonnet::EXT("resource.$id.acc"));
+ my $idacc = &Apache::lonnet::EXT("resource.$id.acc");
+ my $allowed=&Apache::loncommon::check_ip_acc($idacc);
if (!$allowed && ($Apache::lonhomework::browse ne 'F')) {
$status='INVALID_ACCESS';
$date=&mt("can not be accessed from your location.");
@@ -494,19 +445,23 @@ sub check_access {
$Apache::lonhomework::history{"resource.$id.solved"}=~/^excused/) {
$status = 'CANNOT_ANSWER';
}
+ if ($status eq 'CANNOT_ANSWER'
+ && &show_answer_problem_status()) {
+ $status = 'SHOW_ANSWER';
+ }
}
if ($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER') {
- my $interval=&Apache::lonnet::EXT("resource.$id.interval");
- &Apache::lonxml::debug("looking for interval $interval");
- if ($interval) {
- my $first_access=&Apache::lonnet::get_first_access('map');
+ my @interval=&Apache::lonnet::EXT("resource.$id.interval");
+ &Apache::lonxml::debug("looking for interval @interval");
+ if ($interval[0]) {
+ my $first_access=&Apache::lonnet::get_first_access($interval[1]);
&Apache::lonxml::debug("looking for accesstime $first_access");
if (!$first_access) {
$status='NOT_YET_VIEWED';
my $due_date = &due_date($id);
my $seconds_left = $due_date - time;
- if ($seconds_left > $interval || $due_date eq '') {
- $seconds_left = $interval;
+ if ($seconds_left > $interval[0] || $due_date eq '') {
+ $seconds_left = $interval[0];
}
$datemsg=&seconds_to_human_length($seconds_left);
}
@@ -532,17 +487,17 @@ sub check_access {
sub due_date {
my ($part_id,$symb,$udom,$uname)=@_;
my $date;
- my $interval= &Apache::lonnet::EXT("resource.$part_id.interval",$symb,
+ my @interval= &Apache::lonnet::EXT("resource.$part_id.interval",$symb,
$udom,$uname);
- &Apache::lonxml::debug("looking for interval $part_id $symb $interval");
+ &Apache::lonxml::debug("looking for interval $part_id $symb @interval");
my $due_date= &Apache::lonnet::EXT("resource.$part_id.duedate",$symb,
$udom,$uname);
&Apache::lonxml::debug("looking for due_date $part_id $symb $due_date");
- if ($interval =~ /\d+/) {
- my $first_access=&Apache::lonnet::get_first_access('map',$symb);
- &Apache::lonxml::debug("looking for first_access $first_access");
+ if ($interval[0] =~ /\d+/) {
+ my $first_access=&Apache::lonnet::get_first_access($interval[1],$symb);
+ &Apache::lonxml::debug("looking for first_access $first_access ($interval[1])");
if (defined($first_access)) {
- $interval = $first_access+$interval;
+ my $interval = $first_access+$interval[0];
$date = (!$due_date || $interval < $due_date) ? $interval
: $due_date;
} else {
@@ -708,10 +663,6 @@ sub handle_save_or_undo {
my $fs=Apache::File->new(">$filebak");
if (defined($fs)) {
print $fs $$problem;
- &Apache::lonxml::info("".&mt("Making Backup to [_1]",
- ''.
- $filebak.'').
- "");
} else {
&Apache::lonxml::info("".
&mt("Unable to make backup [_1]",
@@ -722,9 +673,6 @@ sub handle_save_or_undo {
my $fh=Apache::File->new(">$file");
if (defined($fh)) {
print $fh $$result;
- &Apache::lonxml::info("".&mt("Saving Modifications to [_1]",
- ''.
- $file.'' )."");
} else {
&Apache::lonxml::info(''.
&mt("Unable to write to [_1]",
@@ -739,21 +687,38 @@ sub handle_save_or_undo {
sub analyze_header {
my ($request) = @_;
- my $result =
- &Apache::loncommon::start_page('Analyzing a problem',undef);
+ my $js = &Apache::structuretags::setmode_javascript();
+
+ # Breadcrumbs
+ my $brcrum = [{'href' => &Apache::loncommon::authorspace(),
+ 'text' => 'Construction Space'},
+ {'href' => '',
+ 'text' => 'Problem Testing'},
+ {'href' => '',
+ 'text' => 'Analyzing a problem'}];
+ my $result =
+ &Apache::loncommon::start_page('Analyzing a problem',
+ $js,
+ {'bread_crumbs' => $brcrum,})
+ .&Apache::loncommon::head_subbox(
+ &Apache::loncommon::CSTR_pageheader());
$result .=
&Apache::lonxml::message_location().'
- ';
&Apache::lonxml::add_messages(\$result);
@@ -827,37 +792,62 @@ sub analyze {
}
&Apache::lonhtmlcommon::Update_PrgWin($request,\%prog_state,
&mt('Analyzing Results'));
- $request->print('
'.&mt('List of possible answers').': ');
+ $request->print('
'
+ .''
+ .&mt('List of possible answers')
+ .'
'
+ );
foreach my $part (sort(keys(%allparts))) {
if (defined(@{ $overall{$part.'.answer'} })) {
for (my $i=0;$iprint(''.&mt('Part').' '.$part);
+ $request->print(&Apache::loncommon::start_data_table()
+ .&Apache::loncommon::start_data_table_header_row()
+ .' | '
+ .&mt('Part').' '.$part
+ );
if (scalar(@{ $overall{$part.'.answer'} }) > 1) {
- $request->print(&mt(' Answer [_1]',$i+1));
+ $request->print(' '.&mt('Answer [_1]',$i+1));
}
- $request->print(' |
');
+ $request->print(''
+ .&Apache::loncommon::end_data_table_header_row()
+ );
my %frequency;
foreach my $answer (sort {$a->[0] <=> $b->[0]} (@{ $overall{$part.'.answer'}[$i] })) {
$frequency{join("\0",@{ $answer })}++;
}
- $request->print(''.&mt('Answer').' | '.&mt('Frequency').' ('
- .&mt('click for example').') |
');
+ $request->print(&Apache::loncommon::start_data_table_header_row()
+ .''.&mt('Answer').' | '
+ .''.&mt('Frequency').' '
+ .'('.&mt('click for example').') | '
+ .&Apache::loncommon::end_data_table_header_row()
+ );
foreach my $answer (sort {(split("\0",$a))[0] <=> (split("\0",$b))[0]} (keys(%frequency))) {
- $request->print(''.
- join(' | ',split("\0",$answer)).
- ' | '.$frequency{$answer}.
- ' |
');
+ $request->print(&Apache::loncommon::start_data_table_row()
+ .''
+ .join(' | ',split("\0",$answer))
+ .' | '
+ .''
+ .''.$frequency{$answer}.''
+ .' | '
+ .&Apache::loncommon::end_data_table_row()
+ );
}
- $request->print('
');
+ $request->print(&Apache::loncommon::end_data_table());
}
} else {
- $request->print(''.&mt('Response').' '.$part.' '.
- &mt('is not analyzable at this time').'
');
+ $request->print(''
+ .&mt('Response [_1] is not analyzable at this time.',$part)
+ .'
'
+ );
}
}
if (scalar(keys(%allparts)) == 0 ) {
- $request->print(''.&mt('Found no analyzable responses in this problem, currently only Numerical, Formula and String response styles are supported.').'
');
+ $request->print(''
+ .&mt('Found no analyzable responses in this problem.'
+ .' Currently only Numerical, Formula and String response styles are supported.')
+ .'
'
+ );
}
&Apache::lonhtmlcommon::Close_PrgWin($request,\%prog_state);
&analyze_footer($request);
@@ -883,6 +873,7 @@ sub analyze {
sub show_problem_status {
return ($show_problem_status eq 'yes'
+ || $show_problem_status eq 'answer'
|| $show_problem_status eq '');
}
@@ -893,6 +884,10 @@ sub analyze {
sub show_no_problem_status {
return ($show_problem_status eq 'no_feedback_ever');
}
+
+ sub show_answer_problem_status {
+ return ($show_problem_status eq 'answer');
+ }
}
sub editxmlmode {
@@ -900,8 +895,12 @@ sub editxmlmode {
my $result;
my $problem=&Apache::lonnet::getfile($file);
if ($problem eq -1) {
- &Apache::lonxml::error(" ".&mt('Unable to find').
- " $file");
+ &Apache::lonxml::error(
+ ' '
+ .&mt('Unable to find [_1]',
+ ''.$file.'')
+ .'');
+
$problem='';
}
if (defined($env{'form.editxmltext'}) || defined($env{'form.Undo'})) {
@@ -910,25 +909,30 @@ sub editxmlmode {
if (!$error) { $problem=&Apache::lonnet::getfile($file); }
}
&Apache::lonhomework::showhashsubset(\%env,'^form');
- if ( $env{'form.submit'} eq &mt('Save and View') ) {
+ if ( $env{'form.submitbutton'} eq &mt('Save and View') ) {
&Apache::lonhomework::showhashsubset(\%env,'^form');
- $env{'form.problemmode'}='View';
+ $env{'form.problemmode'}='view';
&renderpage($request,$file);
} else {
my ($rows,$cols) = &Apache::edit::textarea_sizes(\$problem);
- my $xml_help = ''.
- &Apache::loncommon::helpLatexCheatsheet("Problem_Editor_XML_Index",
- "Problem Editing Help").
- ' | '.
- &Apache::loncommon::help_open_menu(undef,undef,5,'Authoring').
- ' |
';
if ($cols > 80) { $cols = 80; }
if ($cols < 70) { $cols = 70; }
if ($rows < 20) { $rows = 20; }
my $js =
&Apache::edit::js_change_detection().
- &Apache::loncommon::resize_textarea_js();
+ &Apache::loncommon::resize_textarea_js().
+ &Apache::structuretags::setmode_javascript().
+ &Apache::lonhtmlcommon::dragmath_js("EditMathPopup");
my $only_body = ($env{'environment.remote'} eq 'off')? 0 : 1;
+ my $dragmath_button =
+ &Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1);
+
+ # Breadcrumbs
+ my $brcrum = [{'href' => &Apache::loncommon::authorspace(),
+ 'text' => 'Construction Space'},
+ {'href' => '',
+ 'text' => 'Problem Editing'}];
+
my $start_page =
&Apache::loncommon::start_page(&mt("EditXML [_1]",$file),$js,
{'no_auto_mt_title' => 1,
@@ -936,31 +940,38 @@ sub editxmlmode {
'add_entries' => {
'onresize' => q[resize_textarea('LC_editxmltext','LC_aftertextarea')],
'onload' => q[resize_textarea('LC_editxmltext','LC_aftertextarea')],
- }});
-
- $result.=$start_page.
- &renderpage($request,$file,['no_output_web'],1).
- '