Annotation of loncom/homework/lonhomework.pm, revision 1.172

1.63      albertel    1: # The LearningOnline Network with CAPA
1.52      albertel    2: # The LON-CAPA Homework handler
1.63      albertel    3: #
1.172   ! albertel    4: # $Id: lonhomework.pm,v 1.171 2004/03/09 20:37:58 albertel Exp $
1.63      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
1.159     www        27: 
1.1       albertel   28: 
                     29: package Apache::lonhomework;
                     30: use strict;
1.73      albertel   31: use Apache::style();
                     32: use Apache::lonxml();
                     33: use Apache::lonnet();
                     34: use Apache::lonplot();
                     35: use Apache::inputtags();
                     36: use Apache::structuretags();
                     37: use Apache::randomlabel();
                     38: use Apache::response();
                     39: use Apache::hint();
                     40: use Apache::outputtags();
1.83      albertel   41: use Apache::caparesponse();
                     42: use Apache::radiobuttonresponse();
                     43: use Apache::optionresponse();
                     44: use Apache::imageresponse();
                     45: use Apache::essayresponse();
                     46: use Apache::externalresponse();
1.106     albertel   47: use Apache::rankresponse();
1.107     albertel   48: use Apache::matchresponse();
1.137     albertel   49: use Apache::chemresponse();
1.169     albertel   50: use Apache::drawimage();
1.26      www        51: use Apache::Constants qw(:common);
1.73      albertel   52: use HTML::Entities();
1.83      albertel   53: use Apache::loncommon();
1.146     albertel   54: use Apache::lonlocal;
1.47      albertel   55: #use Time::HiRes qw( gettimeofday tv_interval );
1.43      albertel   56: 
1.69      harris41   57: BEGIN {
1.145     albertel   58:     &Apache::lonxml::register_insert();
1.43      albertel   59: }
                     60: 
1.5       albertel   61: sub get_target {
1.145     albertel   62:     if (($ENV{'request.state'} eq "published") ||
                     63: 	($ENV{'request.state'} eq "uploaded")) {
                     64: 	if ( defined($ENV{'form.grade_target'}  ) 
                     65: 	     && ($ENV{'form.grade_target'} eq 'tex')) {
                     66: 	    return ($ENV{'form.grade_target'});
                     67: 	} elsif ( defined($ENV{'form.grade_target'}  ) 
                     68: 		  && ($Apache::lonhomework::viewgrades eq 'F' )) {
                     69: 	    return ($ENV{'form.grade_target'});
                     70: 	}
                     71: 
1.62      albertel   72: 	if ( defined($ENV{'form.submitted'}) &&
1.145     albertel   73: 	     ( !defined($ENV{'form.resetdata'})) &&
                     74: 	     ( !defined($ENV{'form.newrandomization'}))) {
                     75: 	    return ('grade', 'web');
                     76: 	} else {
                     77: 	    return ('web');
                     78: 	}
                     79:     } elsif ($ENV{'request.state'} eq "construct") {
                     80: 	if ( defined($ENV{'form.grade_target'}) ) {
                     81: 	    return ($ENV{'form.grade_target'});
                     82: 	}
                     83: 	if ( defined($ENV{'form.preview'})) {
                     84: 	    if ( defined($ENV{'form.submitted'})) {
                     85: 		return ('grade', 'web');
                     86: 	    } else {
                     87: 		return ('web');
                     88: 	    }
                     89: 	} else {
1.150     albertel   90: 	    if ( $ENV{'form.problemmode'} eq &mt('View') ||
                     91: 		 $ENV{'form.problemmode'} eq &mt('Discard Edits and View')) {
1.145     albertel   92: 		if ( defined($ENV{'form.submitted'}) &&
                     93: 		     (!defined($ENV{'form.resetdata'})) &&
                     94: 		     (!defined($ENV{'form.newrandomization'}))) {
                     95: 		    return ('grade', 'web','answer');
                     96: 		} else {
                     97: 		    return ('web','answer');
                     98: 		}
1.150     albertel   99: 	    } elsif ( $ENV{'form.problemmode'} eq &mt('Edit') ) {
1.145     albertel  100: 		if ( $ENV{'form.submitted'} eq 'edit' ) {
1.150     albertel  101: 		    if ( $ENV{'form.submit'} eq &mt('Submit Changes and View') ) {
1.145     albertel  102: 			return ('modified','web','answer');
                    103: 		    } else {
                    104: 			return ('modified','edit');
                    105: 		    }
                    106: 		} else {
                    107: 		    return ('edit');
                    108: 		}
                    109: 	    } else {
                    110: 		return ('web');
                    111: 	    }
                    112: 	}
1.15      albertel  113:     }
1.145     albertel  114:     return ();
1.5       albertel  115: }
                    116: 
1.3       albertel  117: sub setup_vars {
1.145     albertel  118:     my ($target) = @_;
                    119:     return ';'
1.11      albertel  120: #  return ';$external::target='.$target.';';
1.2       albertel  121: }
                    122: 
                    123: sub send_header {
1.145     albertel  124:     my ($request)= @_;
                    125:     $request->print(&Apache::lontexconvert::header());
1.16      albertel  126: #  $request->print('<form name='.$ENV{'form.request.prefix'}.'lonhomework method="POST" action="'.$request->uri.'">');
1.2       albertel  127: }
                    128: 
1.36      albertel  129: sub createmenu {
1.145     albertel  130:     my ($which,$request)=@_;
                    131:     if ($which eq 'grade') {
                    132: 	$request->print('<script language="JavaScript"> 
1.91      albertel  133:           hwkmenu=window.open("/res/adm/pages/homeworkmenu.html","homeworkremote",
1.52      albertel  134:                  "height=350,width=150,menubar=no");
                    135:           </script>');
1.145     albertel  136:     }
1.36      albertel  137: }
                    138: 
1.2       albertel  139: sub send_footer {
1.145     albertel  140:     my ($request)= @_;
1.16      albertel  141: #  $request->print('</form>');
1.145     albertel  142:     $request->print(&Apache::lontexconvert::footer());
1.2       albertel  143: }
                    144: 
1.52      albertel  145: $Apache::lonxml::browse='';
1.53      www       146: 
1.152     albertel  147: sub check_ip_acc {
                    148:     my ($acc)=@_;
1.154     albertel  149:     if (!defined($acc) || $acc =~ /^\s*$/) { return 1; }
1.152     albertel  150:     my $allowed=0;
                    151:     my $ip=$ENV{'REMOTE_ADDR'};
                    152:     my $name;
                    153:     foreach my $pattern (split(',',$acc)) {
                    154: 	if ($pattern =~ /\*$/) {
                    155: 	    #35.8.*
                    156: 	    $pattern=~s/\*//;
                    157: 	    if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
                    158: 	} elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {    
                    159: 	    #35.8.3.[34-56]
                    160: 	    my $low=$2;
                    161: 	    my $high=$3;
                    162: 	    $pattern=$1;
                    163: 	    if ($ip =~ /^\Q$pattern\E/) { 
                    164: 		my $last=(split(/\./,$ip))[3];
                    165: 		if ($last <=$high && $last >=$low) { $allowed=1; }
                    166: 	    }
                    167: 	} elsif ($pattern =~ /^\*/) {
                    168: 	    #*.msu.edu
                    169: 	    $pattern=~s/\*//;
                    170: 	    if (!defined($name)) {
                    171: 		use Socket;
                    172: 		my $netaddr=inet_aton($ip);
                    173: 		($name)=gethostbyaddr($netaddr,AF_INET);
1.158     albertel  174: 	    }
1.152     albertel  175: 	    if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
                    176: 	} elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
                    177: 	    #127.0.0.1
                    178: 	    if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
                    179: 	} else {
                    180: 	    #some.name.com
                    181: 	    if (!defined($name)) {
                    182: 		use Socket;
                    183: 		my $netaddr=inet_aton($ip);
                    184: 		($name)=gethostbyaddr($netaddr,AF_INET);
                    185: 	    }
                    186: 	    if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
                    187: 	}
                    188: 	if ($allowed) { last; }
                    189:     }
                    190:     return $allowed;
                    191: }
1.92      bowersj2  192: # JB, 9/24/2002: Any changes in this function may require a change
                    193: # in lonnavmaps::resource::getDateStatus.
1.53      www       194: sub check_access {
1.145     albertel  195:     my ($id) = @_;
                    196:     my $date ='';
                    197:     my $status;
                    198:     my $datemsg = '';
                    199:     my $lastdate = '';
                    200:     my $temp;
                    201:     my $type;
                    202:     my $passed;
                    203: 
                    204:     if ($ENV{'request.state'} eq "construct") {
1.167     albertel  205: 	if ($ENV{'form.problemstate'}) {
1.165     albertel  206: 	    if ($ENV{'form.problemstate'} =~ /^CANNOT_ANSWER/) {
1.167     albertel  207: 		if ( ! ($ENV{'form.problemstate'} eq 'CANNOT_ANSWER_correct' &&
                    208: 			lc($Apache::lonhomework::problemstatus) eq 'no')) {
1.168     albertel  209: 		    return ('CANNOT_ANSWER',
                    210: 			    &mt('is in this state by royal decree.'));
1.167     albertel  211: 		}
1.165     albertel  212: 	    } else {
                    213: 		return ($ENV{'form.problemstate'},
1.168     albertel  214: 			&mt('is in this state by royal decree.'));
1.165     albertel  215: 	    }
                    216: 	}
1.145     albertel  217: 	&Apache::lonxml::debug("in construction ignoring dates");
                    218: 	$status='CAN_ANSWER';
1.146     albertel  219: 	$datemsg=&mt('is in under construction');
1.163     albertel  220: #	return ($status,$datemsg);
1.145     albertel  221:     }
                    222: 
                    223:     &Apache::lonxml::debug("checking for part :$id:");
                    224:     &Apache::lonxml::debug("time:".time);
1.152     albertel  225: 
1.163     albertel  226:     if ($ENV{'request.state'} ne "construct") {
                    227: 	my $allowed=&check_ip_acc(&Apache::lonnet::EXT("resource.$id.acc"));
                    228: 	if (!$allowed && ($Apache::lonhomework::browse ne 'F')) {
                    229: 	    $status='INVALID_ACCESS';
                    230: 	    $date=&mt("can not be accessed from your location.");
1.145     albertel  231: 	    return($status,$date);
                    232: 	}
1.163     albertel  233: 	
                    234: 	foreach $temp ("opendate","duedate","answerdate") {
                    235: 	    $lastdate = $date;
                    236: 	    $date = &Apache::lonnet::EXT("resource.$id.$temp");
                    237: 	    my $thistype = &Apache::lonnet::EXT("resource.$id.$temp.type");
                    238: 	    if ($thistype =~ /^(con_lost|no_such_host)/ ||
                    239: 		$date     =~ /^(con_lost|no_such_host)/) {
                    240: 		$status='UNAVAILABLE';
                    241: 		$date=&mt("may open later.");
                    242: 		return($status,$date);
                    243: 	    }
                    244: 	    if ($thistype eq 'date_interval') {
                    245: 		if ($temp eq 'opendate') {
                    246: 		    $date=&Apache::lonnet::EXT("resource.$id.duedate")-$date;
                    247: 		}
                    248: 		if ($temp eq 'answerdate') {
                    249: 		    $date=&Apache::lonnet::EXT("resource.$id.duedate")+$date;
                    250: 		}
1.145     albertel  251: 	    }
1.163     albertel  252: 	    &Apache::lonxml::debug("found :$date: for :$temp:");
                    253: 	    if ($date eq '') {
                    254: 		$date = &mt("an unknown date"); $passed = 0;
                    255: 	    } elsif ($date eq 'con_lost') {
                    256: 		$date = &mt("an indeterminate date"); $passed = 0;
                    257: 	    } else {
                    258: 		if (time < $date) { $passed = 0; } else { $passed = 1; }
                    259: 		$date = localtime $date;
1.145     albertel  260: 	    }
1.163     albertel  261: 	    if (!$passed) { $type=$temp; last; }
1.145     albertel  262: 	}
1.163     albertel  263: 	&Apache::lonxml::debug("have :$type:$passed:");
                    264: 	if ($passed) {
                    265: 	    $status='SHOW_ANSWER';
                    266: 	    $datemsg=$date;
                    267: 	} elsif ($type eq 'opendate') {
                    268: 	    $status='CLOSED';
                    269: 	    $datemsg = &mt("will open on")." $date";
                    270: 	} elsif ($type eq 'duedate') {
                    271: 	    $status='CAN_ANSWER';
                    272: 	    $datemsg = &mt("is due at")." $date";
                    273: 	} elsif ($type eq 'answerdate') {
                    274: 	    $status='CLOSED';
                    275: 	    $datemsg = &mt("was due on")." $lastdate".&mt(", and answers will be available on")." $date";
1.145     albertel  276: 	}
                    277:     }
                    278:     if ($status eq 'CAN_ANSWER') {
                    279: 	#check #tries, and if correct.
                    280: 	my $tries = $Apache::lonhomework::history{"resource.$id.tries"};
                    281: 	my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries");
                    282: 	if ( $tries eq '' ) { $tries = '0'; }
1.164     albertel  283: 	if ( $maxtries eq '' && 
                    284: 	     $ENV{'request.state'} ne 'construct') { $maxtries = '2'; } 
                    285: 	if ($maxtries && $tries >= $maxtries) { $status = 'CANNOT_ANSWER'; }
1.145     albertel  286: 	# if (correct and show prob status) or excused then CANNOT_ANSWER
                    287: 	if(($Apache::lonhomework::history{"resource.$id.solved"}=~/^correct/
                    288: 	    &&
                    289: 	    lc($Apache::lonhomework::problemstatus) ne 'no')
                    290: 	   ||
                    291: 	   $Apache::lonhomework::history{"resource.$id.solved"}=~/^excused/) {
                    292: 	    $status = 'CANNOT_ANSWER';
                    293: 	}
1.121     albertel  294:     }
1.54      www       295: 
1.133     albertel  296:   #if (($status ne 'CLOSED') && ($Apache::lonhomework::type eq 'exam') &&
                    297:   #    (!$Apache::lonhomework::history{"resource.0.outtoken"})) {
                    298:   #    return ('UNCHECKEDOUT','needs to be checked out');
                    299:   #}
1.54      www       300: 
                    301: 
1.145     albertel  302:     &Apache::lonxml::debug("sending back :$status:$datemsg:");
                    303:     if (($Apache::lonhomework::browse eq 'F') && ($status eq 'CLOSED')) {
                    304: 	&Apache::lonxml::debug("should be allowed to browse a resource when closed");
                    305: 	$status='CAN_ANSWER';
1.146     albertel  306: 	$datemsg=&mt('is closed but you are allowed to view it');
1.145     albertel  307:     }
1.106     albertel  308: 
1.145     albertel  309:     return ($status,$datemsg);
1.20      albertel  310: }
                    311: 
1.41      albertel  312: sub showhash {
1.145     albertel  313:     my (%hash) = @_;
                    314:     &showhashsubset(\%hash,'.');
                    315:     return '';
1.79      albertel  316: }
                    317: 
1.106     albertel  318: sub showarray {
                    319:     my ($array)=@_;
                    320:     my $string="(";
                    321:     foreach my $elm (@{ $array }) {
                    322: 	if (ref($elm)) {
                    323: 	    if ($elm =~ /ARRAY/ ) {
                    324: 		$string.=&showarray($elm);
                    325: 	    }
                    326: 	} else {
                    327: 	    $string.="$elm,"
                    328: 	}
                    329:     }
                    330:     chop($string);
                    331:     $string.=")";
                    332:     return $string;
                    333: }
                    334: 
1.79      albertel  335: sub showhashsubset {
1.145     albertel  336:     my ($hash,$keyre) = @_;
                    337:     my $resultkey;
                    338:     foreach $resultkey (sort keys %$hash) {
                    339: 	if ($resultkey =~ /$keyre/) {
                    340: 	    if (ref($$hash{$resultkey})) {
                    341: 		if ($$hash{$resultkey} =~ /ARRAY/ ) {
                    342: 		    &Apache::lonxml::debug("$resultkey ---- ".
                    343: 					   &showarray($$hash{$resultkey}));
                    344: 		} elsif ($$hash{$resultkey} =~ /HASH/ ) {
                    345: 		    &Apache::lonxml::debug("$resultkey ---- $$hash{$resultkey}");
                    346: 		    &showhashsubset($$hash{$resultkey},'.');
                    347: 		} else {
                    348: 		    &Apache::lonxml::debug("$resultkey ---- $$hash{$resultkey}");
                    349: 		}
                    350: 	    } else {
                    351: 		&Apache::lonxml::debug("$resultkey ---- $$hash{$resultkey}");
                    352: 	    }
                    353: 	}
                    354:     }
                    355:     &Apache::lonxml::debug("\n<br />restored values^</br>\n");
                    356:     return '';
1.41      albertel  357: }
                    358: 
                    359: sub setuppermissions {
1.145     albertel  360:     $Apache::lonhomework::browse= &Apache::lonnet::allowed('bre',$ENV{'request.filename'});
                    361:     my $viewgrades = &Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
                    362:     if (! $viewgrades && 
                    363: 	exists($ENV{'request.course.sec'}) && 
                    364: 	$ENV{'request.course.sec'} !~ /^\s*$/) {
                    365: 	$viewgrades = &Apache::lonnet::allowed('vgr',$ENV{'request.course.id'}.
1.127     matthew   366:                                                '/'.$ENV{'request.course.sec'});
1.145     albertel  367:     }
                    368:     $Apache::lonhomework::viewgrades = $viewgrades;
                    369:     return ''
1.41      albertel  370: }
                    371: 
                    372: sub setupheader {
1.120     albertel  373:     my $request=$_[0];
                    374:     if ($ENV{'browser.mathml'}) {
1.151     www       375: 	&Apache::loncommon::content_type($request,'text/xml');
1.120     albertel  376:     } else {
1.151     www       377: 	&Apache::loncommon::content_type($request,'text/html');
1.120     albertel  378:     }
                    379:     if (!$Apache::lonxml::debug && ($ENV{'REQUEST_METHOD'} eq 'GET')) {
                    380: 	&Apache::loncommon::no_cache($request);
                    381:     }
                    382:     $request->send_http_header;
                    383:     return OK if $request->header_only;
                    384:     return ''
1.41      albertel  385: }
1.35      albertel  386: 
1.47      albertel  387: sub handle_save_or_undo {
1.145     albertel  388:     my ($request,$problem,$result) = @_;
                    389:     my $file    = &Apache::lonnet::filelocation("",$request->uri);
                    390:     my $filebak =$file.".bak";
                    391:     my $filetmp =$file.".tmp";
                    392:     my $error=0;
1.156     albertel  393: 
                    394:     &Apache::lonnet::correct_line_ends($result);
1.52      albertel  395: 
1.150     albertel  396:     if ($ENV{'form.Undo'} eq &mt('undo')) {
1.145     albertel  397: 	my $error=0;
                    398: 	if (!copy($file,$filetmp)) { $error=1; }
                    399: 	if ((!$error) && (!copy($filebak,$file))) { $error=1; }
                    400: 	if ((!$error) && (!move($filetmp,$filebak))) { $error=1; }
                    401: 	if (!$error) {
1.171     albertel  402: 	    &Apache::lonxml::info("<p><b>".&mt("Undid changes, Switched")." $filebak ".&mt("and")." $file</b></p>");
1.145     albertel  403: 	} else {
1.171     albertel  404: 	    &Apache::lonxml::info("<p><font color=\"red\" size=\"+1\"><b>".&mt("Unable to undo, unable to switch")." $filebak ".&mt("and")." $file</b></font></p>");
1.145     albertel  405: 	    $error=1;
                    406: 	}
1.52      albertel  407:     } else {
1.145     albertel  408: 	my $fs=Apache::File->new(">$filebak");
                    409: 	if (defined($fs)) {
                    410: 	    print $fs $$problem;
1.171     albertel  411: 	    &Apache::lonxml::info("<b>".&mt("Making Backup to").
                    412: 				  " $filebak</b>");
1.145     albertel  413: 	} else {
1.171     albertel  414: 	    &Apache::lonxml::info("<font color=\"red\" size=\"+1\"><b>".&mt("Unable to make backup")." $filebak</b></font>");
1.145     albertel  415: 	    $error=2;
                    416: 	}
                    417: 	my $fh=Apache::File->new(">$file");
                    418: 	if (defined($fh)) {
                    419: 	    print $fh $$result;
1.171     albertel  420: 	    &Apache::lonxml::info("<b>".&mt("Saving Modifications to").
                    421: 				  " $file</b>");
1.145     albertel  422: 	} else {
1.171     albertel  423: 	    &Apache::lonxml::info("<font color=\"red\" size=\"+1\"><b>".
                    424: 				  &mt("Unable to write to")." $file</b></font>");
1.145     albertel  425: 	    $error|=4;
                    426: 	}
1.52      albertel  427:     }
1.145     albertel  428:     return $error;
1.64      albertel  429: }
                    430: 
1.101     albertel  431: sub analyze_header {
                    432:     my ($request) = @_;
1.109     albertel  433:     my $result.='<html>
1.146     albertel  434:             <head><title>'.&mt("Analyzing a problem").'</title></head>
1.171     albertel  435:             <body bgcolor="#FFFFFF">'.&Apache::lonxml::message_location().'
1.101     albertel  436:             <form name="lonhomework" method="POST" action="'.
1.145     albertel  437: 	    $ENV{'request.uri'}.'">
1.146     albertel  438:             <input type="submit" name="problemmode" value="'.&mt("EditXML").'" />
                    439:             <input type="submit" name="problemmode" value="'.&mt('Edit').'" />
1.101     albertel  440:             <hr />
1.146     albertel  441:             <input type="submit" name="submit" value="'.&mt("View").'" />
1.101     albertel  442:             <hr />
1.146     albertel  443:             '.&mt('List of possible answers').':
1.101     albertel  444:             </form>';
1.171     albertel  445:     &Apache::lonxml::add_messages(\$result);
1.101     albertel  446:     $request->print($result);
                    447:     $request->rflush();
                    448: }
                    449: 
1.109     albertel  450: sub analyze_footer {
                    451:     my ($request) = @_;
                    452:     my $result='</body></html>';
                    453:     $request->print($result);
                    454:     $request->rflush();
                    455: }
                    456: 
1.74      albertel  457: sub analyze {
1.101     albertel  458:     my ($request,$file) = @_;
                    459:     &Apache::lonxml::debug("Analyze");
                    460:     my $result;
                    461:     my %overall;
                    462:     my %allparts;
                    463:     my $rndseed=$ENV{'form.rndseed'};
                    464:     &analyze_header($request);
1.114     albertel  465:     my %prog_state=
1.146     albertel  466: 	&Apache::lonhtmlcommon::Create_PrgWin($request,&mt('Analyze Progress'),
                    467: 					      &mt('Getting Problem Variants'),
1.114     albertel  468: 					      $ENV{'form.numtoanalyze'});
1.102     albertel  469:     for(my $i=1;$i<$ENV{'form.numtoanalyze'}+1;$i++) {
1.114     albertel  470: 	&Apache::lonhtmlcommon::Increment_PrgWin($request,\%prog_state,
1.146     albertel  471: 						 &mt('last problem'));
1.101     albertel  472: 	my $subresult=&Apache::lonnet::ssi($request->uri,
                    473: 					   ('grade_target' => 'analyze'),
1.130     albertel  474: 					   ('rndseed' => $i+$rndseed));
1.101     albertel  475: 	(my $garbage,$subresult)=split(/_HASH_REF__/,$subresult,2);
                    476: 	my %analyze=&Apache::lonnet::str2hash($subresult);
1.114     albertel  477: 	my @parts;
                    478: 	if (defined(@{ $analyze{'parts'} })) {
                    479: 	    @parts=@{ $analyze{'parts'} };
                    480: 	}
1.101     albertel  481: 	foreach my $part (@parts) {
                    482: 	    if (!exists($allparts{$part})) {$allparts{$part}=1;};
1.109     albertel  483: 	    if ($analyze{$part.'.type'} eq 'numericalresponse'	||
                    484: 		$analyze{$part.'.type'} eq 'stringresponse'	||
                    485: 		$analyze{$part.'.type'} eq 'formularesponse'   ) {
1.101     albertel  486: 		push( @{ $overall{$part.'.answer'} },
                    487: 		      [@{ $analyze{$part.'.answer'} }]);
                    488: 	    }
                    489: 	}
                    490:     }
1.114     albertel  491:     &Apache::lonhtmlcommon::Update_PrgWin($request,\%prog_state,
1.146     albertel  492: 					  &mt('Analyzing Results'));
1.134     albertel  493:     foreach my $part (sort(keys(%allparts))) {
1.109     albertel  494: 	if (defined(@{ $overall{$part.'.answer'} })) {
1.132     albertel  495: 	    my $num_cols=scalar(@{ $overall{$part.'.answer'}->[0] });
1.146     albertel  496: 	    $request->print('<table><tr><td colspan="'.($num_cols+1).'">'.&mt('Part').' '.$part.'</td></tr>');
1.130     albertel  497: 	    my %frequency;
1.109     albertel  498: 	    foreach my $answer (sort {$a->[0] <=> $b->[0]} (@{ $overall{$part.'.answer'} })) {
1.132     albertel  499: 		$frequency{join("\0",@{ $answer })}++;
1.130     albertel  500: 	    }
1.146     albertel  501: 	    $request->print('<tr><td colspan="'.($num_cols).'">'.&mt('Answer').'</td><td>'.&mt('Frequency').'</td></tr>');
1.132     albertel  502: 	    foreach my $answer (sort {(split("\0",$a))[0] <=> (split("\0",$b))[0]} (keys(%frequency))) {
                    503: 		$request->print('<tr><td align="right">'.
                    504: 				join('</td><td align="right">',split("\0",$answer)).
1.130     albertel  505: 				'</td><td>('.$frequency{$answer}.
                    506: 				')</td></tr>');
1.109     albertel  507: 	    }
                    508: 	    $request->print('</table>');
                    509: 	} else {
1.162     albertel  510: 	    $request->print('<p>'.&mt('Response').' '.$part.' '.
1.146     albertel  511: 			    &mt('is not analyzable at this time').'</p>');
1.101     albertel  512: 	}
                    513:     }
1.130     albertel  514:     if (scalar(keys(%allparts)) == 0 ) {
1.162     albertel  515: 	$request->print('<p>'.&mt('Found no analyzable respones in this problem, currently only Numerical, Formula and String response styles are supported.').'</p>');
1.130     albertel  516:     }
1.114     albertel  517:     &Apache::lonhtmlcommon::Close_PrgWin($request,\%prog_state);
1.109     albertel  518:     &analyze_footer($request);
1.101     albertel  519:     &Apache::lonhomework::showhash(%overall);
                    520:     return $result;
1.74      albertel  521: }
                    522: 
1.64      albertel  523: sub editxmlmode {
1.145     albertel  524:     my ($request,$file) = @_;
                    525:     my $result;
                    526:     my $problem=&Apache::lonnet::getfile($file);
                    527:     if ($problem eq -1) {
1.146     albertel  528: 	&Apache::lonxml::error("<b> ".&mt('Unable to find').
                    529: 			       " <i>$file</i></b>");
1.145     albertel  530: 	$problem='';
                    531:     }
                    532:     if (defined($ENV{'form.editxmltext'}) || defined($ENV{'form.Undo'})) {
                    533: 	my $error=&handle_save_or_undo($request,\$problem,
                    534: 				       \$ENV{'form.editxmltext'});
                    535: 	if (!$error) { $problem=&Apache::lonnet::getfile($file); }
                    536:     }
1.80      albertel  537:     &Apache::lonhomework::showhashsubset(\%ENV,'^form');
1.150     albertel  538:     if ( $ENV{'form.submit'} eq &mt('Submit Changes and View') ) {
1.145     albertel  539: 	&Apache::lonhomework::showhashsubset(\%ENV,'^form');
                    540: 	$ENV{'form.problemmode'}='View';
                    541: 	&renderpage($request,$file);
                    542:     } else {
                    543: 	my ($rows,$cols) = &Apache::edit::textarea_sizes(\$problem);
1.160     www       544: 	my $xml_help = '<table><tr><td>'.
                    545: 	    &Apache::loncommon::helpLatexCheatsheet("Problem_Editor_XML_Index",
                    546: 						    "Problem Editing Help").
                    547: 						    '</td><td>'.
                    548:        &Apache::loncommon::help_open_faq(5).
                    549:        &Apache::loncommon::help_open_bug('Authoring').'</td></tr></table>';
1.145     albertel  550: 	if ($cols > 80) { $cols = 80; }
                    551: 	if ($cols < 70) { $cols = 70; }
                    552: 	if ($rows < 20) { $rows = 20; }
1.171     albertel  553: 	$result.='<html><body bgcolor="#FFFFFF">'.
                    554: 	    &Apache::lonxml::message_location().'
1.64      albertel  555:             <form name="lonhomework" method="POST" action="'.
1.145     albertel  556: 	    $ENV{'request.uri'}.'">
1.146     albertel  557:             <input type="hidden" name="problemmode" value="'.&mt('EditXML').'" />
1.170     matthew   558:             <input type="submit" name="problemmode" accesskey="d" value="'.&mt('Discard Edits and View').'" />
                    559:             <input type="submit" name="problemmode" accesskey="e" value="'.&mt('Edit').'" />
1.64      albertel  560:             <hr />
1.170     matthew   561:             <input type="submit" name="submit" accesskey="s" value="'.&mt('Submit Changes').'" />
                    562:             <input type="submit" name="submit" accesskey="v" value="'.&mt('Submit Changes and View').'" />
                    563:             <input type="submit" name="Undo" accesskey="u" value="'.&mt('undo').'" />
1.64      albertel  564:             <hr />
1.110     albertel  565:             ' . $xml_help . '
1.64      albertel  566:             <textarea rows="'.$rows.'" cols="'.$cols.'" name="editxmltext">'.
1.172   ! albertel  567: 	    &HTML::Entities::encode($problem,'<>&"').'</textarea>
1.64      albertel  568:             </form></body></html>';
1.171     albertel  569: 	&Apache::lonxml::add_messages(\$result);
1.145     albertel  570: 	$request->print($result);
                    571:     }
                    572:     return '';
1.47      albertel  573: }
                    574: 
1.41      albertel  575: sub renderpage {
1.145     albertel  576:     my ($request,$file) = @_;
1.52      albertel  577: 
1.145     albertel  578:     my (@targets) = &get_target();
1.161     albertel  579:     &Apache::lonhomework::showhashsubset(\%ENV,'form.');
1.145     albertel  580:     &Apache::lonxml::debug("Running targets ".join(':',@targets));
1.171     albertel  581:     my $overall_result;
1.145     albertel  582:     foreach my $target (@targets) {
                    583: 	#my $t0 = [&gettimeofday()];
                    584: 	my $problem=&Apache::lonnet::getfile($file);
                    585: 	if ($problem eq -1) {
1.146     albertel  586: 	    &Apache::lonxml::error("<b> ".&mt('Unable to find')." <i>$file</i></b>");
1.145     albertel  587: 	    $problem='';
                    588: 	}
1.52      albertel  589: 
1.145     albertel  590: 	my %mystyle;
                    591: 	my $result = '';
                    592: 	if ($target eq 'analyze') { %Apache::lonhomework::analyze=(); }
                    593: 	if ($target eq 'answer') { &showhash(%Apache::lonhomework::history); }
                    594: 	if ($target eq 'web') {&Apache::lonhomework::showhashsubset(\%ENV,'^form');}
                    595: 
                    596: 	&Apache::lonxml::debug("Should be parsing now");
                    597: 	$result = &Apache::lonxml::xmlparse($request, $target, $problem,
                    598: 					    &setup_vars($target),%mystyle);
                    599: 	undef($Apache::lonhomework::parsing_a_problem);
                    600: 	#$request->print("Result follows:");
                    601: 	if ($target eq 'modified') {
                    602: 	    &handle_save_or_undo($request,\$problem,\$result);
                    603: 	} else {
                    604: 	    if ($target eq 'analyze') {
                    605: 		$result=&Apache::lonnet::hashref2str(\%Apache::lonhomework::analyze);
                    606: 		undef(%Apache::lonhomework::analyze);
                    607: 	    }
                    608: 	    #my $td=&tv_interval($t0);
                    609: 	    #if ( $Apache::lonxml::debug) {
                    610: 	    #$result =~ s:</body>::;
                    611: 	    #$result.="<br />Spent $td seconds processing target $target\n</body>";
                    612: 	    #}
1.171     albertel  613: #	    $request->print($result);
                    614: 	    $overall_result.=$result;
                    615: #	    $request->rflush();
1.145     albertel  616: 	}
                    617: 	#$request->print(":Result ends");
                    618: 	#my $td=&tv_interval($t0);
1.52      albertel  619:     }
1.171     albertel  620:     &Apache::lonxml::add_messages(\$overall_result);
                    621:     $request->print($overall_result);   
                    622:     $request->rflush();   
1.41      albertel  623: }
                    624: 
1.42      albertel  625: # with no arg it returns a HTML <option> list of the template titles
                    626: # with one arg it returns the filename associated with the arg passed
                    627: sub get_template_list {
1.145     albertel  628:     my ($namewanted,$extension) = @_;
                    629:     my $result;
                    630:     my @allnames;
                    631:     &Apache::lonxml::debug("Looking for :$extension:");
                    632:     foreach my $file (</home/httpd/html/res/adm/includes/templates/*.$extension>) {
                    633: 	my $name=&Apache::lonnet::metadata($file,'title');
                    634: 	if ($namewanted && ($name eq $namewanted)) {
                    635: 	    $result=$file;
                    636: 	    last;
                    637: 	} else {
                    638: 	    if ($name) { push (@allnames, $name); }
                    639: 	}
                    640:     }
                    641:     if (@allnames && !$result) {
1.146     albertel  642: 	$result="<option>".&mt("Select a")." $extension ".&mt('template')."</option>\n<option>".
1.145     albertel  643: 	    join('</option><option>',sort(@allnames)).'</option>';
1.42      albertel  644:     }
1.145     albertel  645:     return $result;
1.42      albertel  646: }
                    647: 
                    648: sub newproblem {
1.65      matthew   649:     my ($request) = @_;
                    650:     my $extension=$request->uri;
                    651:     $extension=~s:^.*\.([\w]+)$:$1:;
                    652:     &Apache::lonxml::debug("Looking for :$extension:");
1.131     albertel  653:     my $templatelist=&get_template_list('',$extension);
1.85      albertel  654:     if ($ENV{'form.template'} &&
1.128     albertel  655: 	$ENV{'form.template'} ne "Select a $extension template") {
1.65      matthew   656: 	use File::Copy;
                    657: 	my $file = &get_template_list($ENV{'form.template'},$extension);
                    658: 	my $dest = &Apache::lonnet::filelocation("",$request->uri);
                    659: 	copy($file,$dest);
                    660: 	&renderpage($request,$dest);
1.131     albertel  661:     } elsif($ENV{'form.newfile'} && !$templatelist) {
                    662: 	# I don't like hard-coded filenames but for now, this will work.
                    663: 	use File::Copy;
                    664: 	my $templatefilename =
                    665: 	    $request->dir_config('lonIncludes').'/templates/blank.problem';
                    666: 	&Apache::lonxml::debug("$templatefilename");
                    667: 	my $dest = &Apache::lonnet::filelocation("",$request->uri);
                    668: 	copy($templatefilename,$dest);
                    669: 	&renderpage($request,$dest);
1.85      albertel  670:     } else {
1.65      matthew   671: 	my $url=$request->uri;
1.157     albertel  672: 	my $shownurl=$url;
                    673: 	$shownurl=~s-^/~-/priv/-;
1.65      matthew   674: 	my $dest = &Apache::lonnet::filelocation("",$request->uri);
1.128     albertel  675: 	my $errormsg;
                    676: 	if ($ENV{'form.newfile'}) {
1.146     albertel  677: 	    $errormsg='<p><font color="red">'.&mt('You did not select a template.').'</font></p>'."\n";
1.128     albertel  678: 	}
1.85      albertel  679: 	my $instructions;
1.159     www       680: 	my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
1.146     albertel  681: 	if ($templatelist) { $instructions=&mt(", select a template from the pull-down menu below.").'<br />'.&mt("Then");}
1.147     albertel  682: 	my %lt=&Apache::lonlocal::texthash( 'create' => 'Creating a new',
1.146     albertel  683: 			  'resource' => 'resource',
                    684: 			  'requested' => 'The requested file',
                    685: 			  'not exist' => 'currently does not exist',
                    686: 			  'createnew' => 'To create a new',
                    687: 			  'click' => 'click on the',
                    688: 			  'Create' => 'Create',
                    689: 			  'button' => 'button');
1.65      matthew   690: 	$request->print(<<ENDNEWPROBLEM);
1.159     www       691: $bodytag
1.148     albertel  692: <h1>$lt{'create'} $extension $lt{'resource'}</h1>
1.128     albertel  693: $errormsg
1.157     albertel  694: $lt{'requested'} <tt>$shownurl</tt> $lt{'not exist'}.
1.105     www       695: <p>
1.146     albertel  696: <b>$lt{'createnew'} $extension$instructions $lt{'click'} "$lt{'Create'} $extension" $lt{'button'}.</b>
1.105     www       697: </p>
                    698: <p><form action="$url" method="POST">
1.42      albertel  699: ENDNEWPROBLEM
1.85      albertel  700: 	if (defined($templatelist)) {
                    701: 	    $request->print("<select name=\"template\">$templatelist</select>");
                    702: 	}
1.146     albertel  703: 	$request->print("<br /><input type=\"submit\" name=\"newfile\" value=\"".&mt('Create')." $extension\" />");
1.105     www       704: 	$request->print("</form></p></body>");
1.65      matthew   705:     }
                    706:     return '';
1.42      albertel  707: }
                    708: 
                    709: sub view_or_edit_menu {
1.145     albertel  710:     my ($request) = @_;
                    711:     my $url=$request->uri;
1.147     albertel  712:     my %lt=&Apache::lonlocal::texthash( 'would' => 'Would you like to',
1.146     albertel  713: 		      'view' => 'View',
                    714: 		      'Edit' => 'edit',
                    715: 		      'or' => 'or',
                    716: 		      'the problem' => 'the problem');
1.145     albertel  717:     $request->print(<<EDITMENU);
1.42      albertel  718: <body bgcolor="#FFFFFF">
                    719: <form action="$url" method="POST">
1.170     matthew   720: $lt{'would'} <input type="submit" name="problemmode" accesskey="v" value="&lt{'view'}">
                    721: &lt{'or'} <input type="submit" name="problemmode" accesskey="e" value="&lt{'Edit'}">
1.146     albertel  722: &lt{'the problem'}.
1.42      albertel  723: </form>
                    724: </body>
                    725: EDITMENU
                    726: }
                    727: 
1.41      albertel  728: sub handler {
1.145     albertel  729:     #my $t0 = [&gettimeofday()];
                    730:     my $request=$_[0];
                    731:     
                    732:     $Apache::lonxml::debug=$ENV{'user.debug'};
                    733:     if (&setupheader($request)) { return OK; }
                    734:     $ENV{'request.uri'}=$request->uri;
1.41      albertel  735: 
1.145     albertel  736:     #setup permissions
                    737:     $Apache::lonhomework::browse= &Apache::lonnet::allowed('bre',$ENV{'request.filename'});
                    738:     $Apache::lonhomework::viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
                    739:     &Apache::lonxml::debug("Permissions:$Apache::lonhomework::browse:$Apache::lonhomework::viewgrades:");
                    740:     # some times multiple problemmodes are submitted, need to select
                    741:     # the last one
                    742:     &Apache::lonxml::debug("Problem Mode ".$ENV{'form.problemmode'});
                    743:     if ( defined($ENV{'form.problemmode'}) &&
                    744: 	 ref($ENV{'form.problemmode'}) ) {
                    745: 	&Apache::lonxml::debug("Problem Mode ".join(",",@$ENV{'form.problemmode'}));
                    746: 	my $mode=$ENV{'form.problemmode'}->[-1];
                    747: 	undef $ENV{'form.problemmode'};
                    748: 	$ENV{'form.problemmode'}=$mode;
                    749:     }
                    750:     &Apache::lonxml::debug("Problem Mode ".$ENV{'form.problemmode'});
                    751:     my $file=&Apache::lonnet::filelocation("",$request->uri);
                    752: 
                    753:     #check if we know where we are
                    754:     if ($ENV{'request.course.fn'} && !&Apache::lonnet::symbread()) { 
                    755: 	# if we are browsing we might not be able to know where we are
                    756: 	if ($Apache::lonhomework::browse ne 'F') {
                    757: 	    #should know where we are, so ask
                    758: 	    if ( &Apache::lonnet::mod_perl_version() == 2 ) {
                    759: 		&Apache::lonnet::cleanenv();
                    760: 	    }
                    761: 	    $request->internal_redirect('/adm/ambiguous'); return;
                    762: 	}
                    763:     }
1.41      albertel  764: 
1.145     albertel  765:     my ($symb) = &Apache::lonxml::whichuser();
                    766:     &Apache::lonxml::debug('symb is '.$symb);
                    767:     if ($ENV{'request.state'} eq "construct" || $symb eq '') {
1.150     albertel  768: 	if ($ENV{'form.resetdata'} eq &mt('Reset Submissions') ||
                    769: 	    $ENV{'form.resetdata'} eq &mt('New Problem Variation') ||
                    770: 	    $ENV{'form.newrandomization'} eq &mt('New Randomization')) {
1.145     albertel  771: 	    my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
                    772: 	    &Apache::lonnet::tmpreset($symb,'',$domain,$name);
                    773: 	    &Apache::lonxml::debug("Attempt reset");
                    774: 	}
                    775:     }
                    776:     if ($ENV{'request.state'} eq "construct") {
                    777: 	if ( -e $file ) {
                    778: 	    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                    779: 						    ['problemmode']);
                    780: 	    if (!(defined $ENV{'form.problemmode'})) {
                    781: 		#first visit to problem in construction space
                    782: 		#&view_or_edit_menu($request);
                    783: 		$ENV{'form.problemmode'}='View';
                    784: 		&renderpage($request,$file);
1.150     albertel  785: 	    } elsif ($ENV{'form.problemmode'} eq &mt('EditXML')) {
1.145     albertel  786: 		&editxmlmode($request,$file);
1.150     albertel  787: 	    } elsif ($ENV{'form.problemmode'} eq &mt('Calculate answers')) {
1.145     albertel  788: 		&analyze($request,$file);
                    789: 	    } else {
                    790: 		&renderpage($request,$file);
                    791: 	    }
                    792: 	} else {
                    793: 	    # requested file doesn't exist in contruction space
                    794: 	    &newproblem($request);
                    795: 	}
                    796:     } else {
                    797: 	# just render the page normally outside of construction space
                    798: 	&Apache::lonxml::debug("not construct");
1.52      albertel  799: 	&renderpage($request,$file);
1.41      albertel  800:     }
1.145     albertel  801:     #my $td=&tv_interval($t0);
                    802:     #&Apache::lonxml::debug("Spent $td seconds processing");
                    803:     # &Apache::lonhomework::send_footer($request);
                    804:     # always turn off debug messages
                    805:     $Apache::lonxml::debug=0;
                    806:     return OK;
1.52      albertel  807: 
1.1       albertel  808: }
                    809: 
                    810: 1;
                    811: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.