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

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