Annotation of loncom/homework/lonhomework.pm, revision 1.51
1.51 ! harris41 1: # The LON-CAPA homework handler
! 2: #
! 3: # Handles homework.
! 4: #
! 5: # YEAR=2000
! 6: # 7/25,8/2,8/7,8/8,8/11,9/14,9/19,10/2,10/5,10/11,11/7,11/21 Guy Albertelli
1.17 www 7: # 11/30 Gerd Kortemeyer
1.51 ! harris41 8: # 12/4,12/8,12/12,12/15,12/19,12/21 Guy Albertelli
! 9: # YEAR=2001
! 10: # 1/6,1/8,1/9,1/10,1/11,1/12,1/15,1/25,2/7,2/13,2/19,4/16,4/26 Guy Albertelli
! 11: # 5/4,5/13,5/21 Guy Albertelli
1.25 www 12: # 6/1 Gerd Kortemeyer
1.51 ! harris41 13: # 6/5,6/12,6/26,7/2,7/18 Guy Albertelli
! 14: # 8/6 Scott Harrison
1.1 albertel 15:
16: package Apache::lonhomework;
17: use strict;
18: use Apache::style;
19: use Apache::lonxml;
1.2 albertel 20: use Apache::lonnet;
21: use Apache::inputtags;
22: use Apache::structuretags;
1.9 albertel 23: use Apache::response;
1.22 albertel 24: use Apache::hint;
1.31 albertel 25: use Apache::outputtags;
1.26 www 26: use Apache::Constants qw(:common);
1.47 albertel 27: #use Time::HiRes qw( gettimeofday tv_interval );
1.43 albertel 28:
1.51 ! harris41 29: # ======================================================================= BEGIN
1.43 albertel 30: sub BEGIN {
31: &Apache::lonxml::register_insert();
32: }
33:
1.51 ! harris41 34: # =============================================== Get target (returns an array)
1.5 albertel 35: sub get_target {
1.51 ! harris41 36: if ( $ENV{'request.state'} eq "published") {
1.42 albertel 37: if ( defined $ENV{'form.submitted'}) {
1.51 ! harris41 38: return ('grade','web');
1.42 albertel 39: } else {
1.51 ! harris41 40: return ('web');
1.42 albertel 41: }
1.51 ! harris41 42: } elsif ($ENV{'request.state'} eq "construct") {
! 43: if ( defined $ENV{'form.preview'}) {
! 44: if ( defined $ENV{'form.submitted'}) {
! 45: return ('grade','web');
! 46: } else {
! 47: return ('web');
! 48: }
1.42 albertel 49: } else {
1.51 ! harris41 50: if ( $ENV{'form.problemmode'} eq 'View' ) {
! 51: if ( defined $ENV{'form.submitted'}) {
! 52: return ('grade','web');
! 53: } else {
! 54: return ('web');
! 55: }
! 56: } elsif ( $ENV{'form.problemmode'} eq 'Edit' ) {
! 57: if ( $ENV{'form.submitted'} eq 'edit' ) {
! 58: return ('modified','edit');
! 59: } else {
! 60: return ('edit');
! 61: }
! 62: } else {
! 63: return ('web');
! 64: }
1.42 albertel 65: }
1.15 albertel 66: }
1.51 ! harris41 67: return ();
1.5 albertel 68: }
69:
1.51 ! harris41 70: # ===================================== Set up variables (return scalar string)
1.3 albertel 71: sub setup_vars {
1.51 ! harris41 72: my ($target) = @_;
! 73: return ';'
1.11 albertel 74: # return ';$external::target='.$target.';';
1.2 albertel 75: }
76:
1.51 ! harris41 77: # ================================================================= Send header
1.2 albertel 78: sub send_header {
1.51 ! harris41 79: my ($request) = @_;
! 80: $request->print(&Apache::lontexconvert::header());
1.16 albertel 81: # $request->print('<form name='.$ENV{'form.request.prefix'}.'lonhomework method="POST" action="'.$request->uri.'">');
1.2 albertel 82: }
83:
1.51 ! harris41 84: # ================================================================= Create menu
1.36 albertel 85: sub createmenu {
1.51 ! harris41 86: my ($which,$request) = @_;
! 87: if ($which eq 'grade') {
! 88: $request->print('<script language="JavaScript">'."\n".
! 89: 'hwkmenu=window.open("/res/adm/pages/homeworkmenu.html'.
! 90: '","homeworkremote","height=350,width=150,menubar=no");'.
! 91: '</script>');
! 92: }
1.36 albertel 93: }
94:
1.51 ! harris41 95: # ================================================================= Send footer
1.2 albertel 96: sub send_footer {
1.51 ! harris41 97: my ($request) = @_;
1.16 albertel 98: # $request->print('</form>');
1.51 ! harris41 99: $request->print(&Apache::lontexconvert::footer());
1.2 albertel 100: }
101:
1.51 ! harris41 102: $Apache::lonxml::browse = '';
! 103:
! 104: # =============================================== Check date (returns an array)
1.20 albertel 105: sub check_date {
1.51 ! harris41 106: my ($id) = @_;
! 107: my $date ='';
! 108: my $status = '';
! 109: my $datemsg = '';
! 110: my $lastdate = '';
! 111: my $temp;
! 112: my $type;
! 113: my $passed;
! 114: &Apache::lonxml::debug("checking for part :$id:");
! 115: foreach $temp ("opendate","duedate","answerdate") {
! 116: $lastdate = $date;
! 117: $date = &Apache::lonnet::EXT("resource.$id.$temp");
! 118: &Apache::lonxml::debug("found :$date: for :$temp:");
! 119: if ($date eq '') {
! 120: $date = "an unknown date"; $passed = 0;
! 121: } elsif ($date eq 'con_lost') {
! 122: $date = "an indeterminate date"; $passed = 0;
! 123: } else {
! 124: if (time < $date) { $passed = 0; } else { $passed = 1; }
! 125: $date = localtime $date;
! 126: }
! 127: if (!$passed) { $type = $temp; last; }
! 128: }
! 129: &Apache::lonxml::debug("have :$type:$passed:");
! 130: if ($passed) {
! 131: $status = 'SHOW_ANSWER';
! 132: $datemsg = $date;
! 133: } elsif ($type eq 'opendate') {
! 134: $status = 'CLOSED';
! 135: $datemsg = "will open on $date";
! 136: } elsif ($type eq 'duedate') {
! 137: $status = 'CAN_ANSWER';
! 138: $datemsg = "is due at $date";
! 139: } elsif ($type eq 'answerdate') {
! 140: $status = 'CLOSED';
! 141: $datemsg = "was due on $lastdate, and answers will be available on ".
! 142: "$date";
! 143: }
! 144: if ($status eq 'CAN_ANSWER') {
! 145: #check #tries
! 146: my $tries = $Apache::lonhomework::history{"resource.$id.tries"};
! 147: my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries");
! 148: if ( $tries eq '' ) { $tries = '0'; }
! 149: if ( $maxtries eq '' ) { $maxtries = '2'; }
! 150: if ($tries >= $maxtries) { $status = 'CANNOT_ANSWER'; }
! 151: }
! 152: &Apache::lonxml::debug("sending back :$status:$datemsg:");
! 153: if (($Apache::lonhomework::browse eq 'F') && ($status eq 'CLOSED')) {
! 154: &Apache::lonxml::debug("should be allowed to browse a resource when ".
! 155: "closed");
! 156: $status = 'CAN_ANSWER';
! 157: $datemsg = 'is closed but you are allowed to view it';
! 158: }
! 159: if ($ENV{'request.state'} eq "construct") {
! 160: &Apache::lonxml::debug("in construction ignoring dates");
! 161: $status = 'CAN_ANSWER';
! 162: $datemsg = 'is in under construction';
1.21 albertel 163: }
1.51 ! harris41 164: return ($status,$datemsg);
1.20 albertel 165: }
166:
1.51 ! harris41 167: # ================================================================== Shows hash
1.41 albertel 168: sub showhash {
1.51 ! harris41 169: my (%hash) = @_;
! 170: my $resultkey;
! 171: foreach $resultkey (sort keys %hash) {
! 172: &Apache::lonxml::debug("$resultkey ---- $hash{$resultkey}");
! 173: }
! 174: &Apache::lonxml::debug("\n<br />restored values^</br>\n");
! 175: return '';
1.41 albertel 176: }
177:
1.51 ! harris41 178: # =========================================================== Setup permissions
1.41 albertel 179: sub setuppermissions {
1.51 ! harris41 180: $Apache::lonhomework::browse = &Apache::lonnet::allowed('bre',
! 181: $ENV{'request.filename'});
! 182: $Apache::lonhomework::viewgrades = &Apache::lonnet::allowed('vgr',
! 183: $ENV{'request.course.id'});
! 184: return '';
1.41 albertel 185: }
186:
1.51 ! harris41 187: # ================================================================ Setup header
1.41 albertel 188: sub setupheader {
1.51 ! harris41 189: my $request = $_[0];
! 190: if ($ENV{'browser.mathml'}) {
! 191: $request->content_type('text/xml');
! 192: } else {
! 193: $request->content_type('text/html');
! 194: }
! 195: $request->send_http_header;
! 196: return OK if $request->header_only;
! 197: return '';
1.41 albertel 198: }
1.35 albertel 199:
1.51 ! harris41 200: # ========================================================= Handle save or undo
1.47 albertel 201: sub handle_save_or_undo {
1.51 ! harris41 202: my ($request,$problem,$result) = @_;
! 203: my $fileout = &Apache::lonnet::filelocation("",$request->uri);
! 204: my $filesave = $fileout.".bak";
! 205: if ($ENV{'form.Undo'} eq 'undo') {
! 206: if (copy($filesave,$fileout)) {
! 207: $request->print("<b>Undid changes, Copied $filesave to $fileout".
! 208: "<br /></b>");
! 209: } else {
! 210: $request->print("<font color=\"red\" size=\"+1\"><b>Unable to ".
! 211: "undo, unable to copy $filesave to $fileout<br ".
! 212: "/></b></font>");
! 213: }
1.47 albertel 214: } else {
1.51 ! harris41 215: my $fs=Apache::File->new(">$filesave");
! 216: if (defined($fs)) {
! 217: print $fs $$problem;
! 218: $request->print("<b>Making Backup to $filesave</b><br />");
! 219: } else {
! 220: $request->print("<font color=\"red\" size=\"+1\"><b>Unable to ".
! 221: "make backup $filesave</b></font>");
! 222: }
! 223: my $fh=Apache::File->new(">$fileout");
! 224: if (defined($fh)) {
! 225: print $fh $$result;
! 226: $request->print("<b>Saving Modifications to $fileout</b><br />");
! 227: } else {
! 228: $request->print("<font color=\"red\" size=\"+1\"><b>Unable to ".
! 229: "write to $fileout</b></font>");
! 230: }
1.47 albertel 231: }
232: }
233:
1.51 ! harris41 234: # ================================================================= Render page
1.41 albertel 235: sub renderpage {
1.51 ! harris41 236: my ($request,$file) = @_;
! 237:
! 238: my (@targets) = &get_target();
! 239: foreach my $target (@targets) {
! 240: #my $t0 = [&gettimeofday()];
! 241: my $problem=&Apache::lonnet::getfile($file);
! 242: if ($problem == -1) {
! 243: &Apache::lonxml::error("<b> Unable to find <i>$file</i></b>");
! 244: $problem='';
! 245: }
! 246:
! 247: my %mystyle;
! 248: my $result = '';
! 249: &Apache::inputtags::initialize_inputtags;
! 250: &Apache::edit::initialize_edit;
! 251: %Apache::lonhomework::results=();
! 252: %Apache::lonhomework::history=&Apache::lonnet::restore();
! 253: #ignore error conditions
! 254: my ($temp)=keys %Apache::lonhomework::history ;
! 255: if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); }
! 256: if ($target eq 'web') {
! 257: if (&Apache::lonnet::symbread() eq '') {
! 258: if ($ENV{'request.state'} eq "construct") {
! 259: $request->print("In construction space, submissions ".
! 260: "ignored<br />");
! 261: } else {
! 262: $request->print("Browsing or <a href=\"/adm/ambiguous\">".
! 263: "ambiguous</a> reference, submissions ".
! 264: "ignored<br />");
! 265: }
! 266: }
! 267: #if ($Apache::lonhomework::viewgrades eq 'F') {&createmenu('grade',$request); }
! 268: }
! 269: if ($target eq 'grade') { &showhash(%Apache::lonhomework::history); }
! 270:
! 271: my $default=&Apache::lonnet::getfile('/home/httpd/html/res/adm/'.
! 272: 'includes/default_homework.lcpm');
! 273: if ($default == -1) {
! 274: &Apache::lonxml::error("<b>Unable to find <i>default_homework.".
! 275: "lcpm</i></b>");
! 276: $default='';
! 277: }
! 278: $result = &Apache::lonxml::xmlparse($target, $problem,
! 279: $default.&setup_vars($target),
! 280: %mystyle);
! 281: #$request->print("Result follows:");
! 282: if ($target eq 'modified') {
! 283: &handle_save_or_undo($request,\$problem,\$result);
1.36 albertel 284: } else {
1.51 ! harris41 285: #my $td=&tv_interval($t0);
! 286: #if ( $Apache::lonxml::debug) {
! 287: #$result =~ s:</body>::;
! 288: #$result.="<br />Spent $td seconds processing target $target\n</body>";
! 289: #}
! 290: $request->print($result);
! 291: }
! 292: #$request->print(":Result ends");
! 293: if ($target eq 'grade') { &showhash(%Apache::lonhomework::results); }
! 294:
! 295: #store new values
! 296: my ($temp) = keys %Apache::lonhomework::results;
! 297: if ( $temp ne '' ) {
! 298: &Apache::lonxml::debug("Store return message:".
! 299: &Apache::lonnet::cstore(\%Apache::lonhomework::results));
1.36 albertel 300: }
1.51 ! harris41 301: #my $td=&tv_interval($t0);
1.20 albertel 302: }
1.41 albertel 303: }
304:
1.51 ! harris41 305: # =========================================================== Get template list
1.42 albertel 306: # with no arg it returns a HTML <option> list of the template titles
307: # with one arg it returns the filename associated with the arg passed
308: sub get_template_list {
1.51 ! harris41 309: my ($namewanted,$extension) = @_;
! 310: my $result;
! 311: &Apache::lonxml::debug("Looking for :$extension:");
! 312: foreach my $file
! 313: (</home/httpd/html/res/adm/includes/templates/*.$extension>) {
! 314: my $name=&Apache::lonnet::metadata($file,'title');
! 315: if ($namewanted && ($name eq $namewanted)) {
! 316: $result=$file;
! 317: last;
! 318: } else {
! 319: $result.="<option>$name</option>";
! 320: }
1.42 albertel 321: }
1.51 ! harris41 322: return $result;
1.42 albertel 323: }
324:
1.51 ! harris41 325: # ================================================================= New problem
1.42 albertel 326: sub newproblem {
1.51 ! harris41 327: my ($request) = @_;
! 328: my $extension = $request->uri;
! 329: $extension =~ s:^.*\.([\w]+)$:$1:;
! 330: &Apache::lonxml::debug("Looking for :$extension:");
! 331: if ($ENV{'form.template'}) {
! 332: use File::Copy;
! 333: my $file = &get_template_list($ENV{'form.template'},$extension);
! 334: my $dest = &Apache::lonnet::filelocation("",$request->uri);
! 335: copy($file,$dest);
! 336: &renderpage($request,$file);
! 337: } else {
! 338: my $templatelist = &get_template_list('',$extension);
! 339: my $url = $request->uri;
! 340: my $dest = &Apache::lonnet::filelocation("",$request->uri);
! 341: $request->print(<<ENDNEWPROBLEM);
1.42 albertel 342: <body bgcolor="#FFFFFF">
1.50 albertel 343: The request file $url doesn\'t exist. You can create a new $extension <br />
1.42 albertel 344: <form action="$url" method="POST">
1.50 albertel 345: <input type="submit" value="New $extension"><br />
1.42 albertel 346: <select name="template">
347: $templatelist
348: </select>
349: </form>
350: </body>
351: ENDNEWPROBLEM
352: }
353:
354: return '';
355: }
356:
357: sub view_or_edit_menu {
1.51 ! harris41 358: my ($request) = @_;
! 359: my $url = $request->uri;
! 360: $request->print(<<EDITMENU);
1.42 albertel 361: <body bgcolor="#FFFFFF">
362: <form action="$url" method="POST">
363: Would you like to <input type="submit" name="problemmode" value="View"> or
364: <input type="submit" name="problemmode" value="Edit"> the problem.
365: </form>
366: </body>
367: EDITMENU
368: }
369:
1.51 ! harris41 370: # ===================================================================== Handler
1.41 albertel 371: sub handler {
1.51 ! harris41 372: #my $t0 = [&gettimeofday()];
! 373: my $request = $_[0];
1.41 albertel 374:
1.51 ! harris41 375: if ( $ENV{'user.name'} eq 'albertel' ) {$Apache::lonxml::debug = 1;}
1.41 albertel 376:
377: if (&setupheader($request)) { return OK; }
1.51 ! harris41 378: $ENV{'request.uri'} = $request->uri;
1.41 albertel 379:
380: #setup permissions
1.51 ! harris41 381: $Apache::lonhomework::browse = &Apache::lonnet::allowed('bre',
! 382: $ENV{'request.filename'});
! 383: $Apache::lonhomework::viewgrades = &Apache::lonnet::allowed('vgr',
! 384: $ENV{'request.course.id'});
! 385: &Apache::lonxml::debug("Permissions:".
! 386: $Apache::lonhomework::browse.":".
! 387: $Apache::lonhomework::viewgrades.":");
! 388:
! 389: my $file = &Apache::lonnet::filelocation("",$request->uri);
! 390:
! 391: #check if we know where we are
! 392: if ($ENV{'request.course.fn'} && !&Apache::lonnet::symbread()) {
! 393: # if we are browsing we might not be able to know where we are
! 394: if ($Apache::lonhomework::browse ne 'F') {
! 395: #should know where we are, so ask
! 396: $request->internal_redirect('/adm/ambiguous'); return;
! 397: }
1.41 albertel 398: }
399:
1.51 ! harris41 400: if ($ENV{'request.state'} eq "construct") {
! 401: if ( -e $file ) {
! 402: if (!(defined $ENV{'form.problemmode'})) {
! 403: #first visit to problem in construction space
! 404: &view_or_edit_menu($request);
! 405: #&renderpage($request,$file);
! 406: } else {
! 407: &renderpage($request,$file);
1.41 albertel 408: }
1.51 ! harris41 409: } else {
! 410: # requested file doesn't exist in contruction space
! 411: &newproblem($request);
! 412: }
1.41 albertel 413: } else {
1.51 ! harris41 414: # just render the page normally outside of construction space
! 415: &renderpage($request,$file);
1.41 albertel 416: }
1.51 ! harris41 417: #my $td=&tv_interval($t0);
! 418: #&Apache::lonxml::debug("Spent $td seconds processing");
! 419: # &Apache::lonhomework::send_footer($request);
! 420: # always turn off debug messages
! 421: $Apache::lonxml::debug=0;
! 422: return OK;
1.1 albertel 423: }
424:
425: 1;
1.51 ! harris41 426:
1.1 albertel 427: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>