Parent Directory
|
Revision Log
Preliminary commit of changes to add Gateway module.
This adds to WeBWorK
- the ability to create versioned, timed problem sets ("gateway tests")
for which all problems are displayed on a single page ("versioned"
means that students can get multiple versions of the problem set),
- the ability to create sets that draw problems from groups of
problems, and
- the ability to create sets that require a proctor login to start
and grade.
Sets can be defined as gateway tests or proctored gateway tests from
the ProblemSetDetail page.
Not quite bug-free yet. Known bugs include handling of problem values
on the Student Progress page (I think this may be a problem with
changing from sql database format where all entries were 'text' to
sql_single in ver 2.1, where they are integer), and a division by zero
error on the grades page (which may be the same problem).
Tests with a number of attempts per version greater than one haven't
been carefully tested, nor has scoring of gateway tests.
1 ################################################################################ 2 # WeBWorK Online Homework Delivery System 3 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ 4 # $CVSHeader$ 5 # 6 # This program is free software; you can redistribute it and/or modify it under 7 # the terms of either: (a) the GNU General Public License as published by the 8 # Free Software Foundation; either version 2, or (at your option) any later 9 # version, or (b) the "Artistic License" which comes with this package. 10 # 11 # This program is distributed in the hope that it will be useful, but WITHOUT 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the 14 # Artistic License for more details. 15 ################################################################################ 16 17 package WeBWorK::ContentGenerator::LoginProctor; 18 use base qw(WeBWorK::ContentGenerator); 19 20 =head1 NAME 21 22 WeBWorK::ContentGenerator::LoginProctor - display a login form for 23 GatewayQuiz proctored tests. 24 25 =cut 26 27 use strict; 28 use warnings; 29 use CGI qw(); 30 use WeBWorK::Utils qw(readFile dequote); 31 use WeBWorK::ContentGenerator::GatewayQuiz qw(can_recordAnswers); 32 33 # This content generator is NOT logged in. 34 # FIXME I'm not sure this is really what we want for the proctor login, 35 # FIXME but I also don't know what this actually does, so I'm ignoring it 36 # FIXME for now. 37 sub if_loggedin { 38 my ($self, $arg) = @_; 39 40 return !$arg; 41 } 42 43 # FIXME This needs to be updated for LoginProctor 44 sub info { 45 my ($self) = @_; 46 my $r = $self->r; 47 my $ce = $r->ce; 48 49 my $login_info = $ce->{courseFiles}->{login_info}; 50 51 if (defined $login_info and $login_info) { 52 my $login_info_path = $ce->{courseDirs}->{templates} . "/$login_info"; 53 54 # deal with previewing a temporary file 55 if (defined $r->param("editMode") and $r->param("editMode") eq "temporaryFile" 56 and defined $r->param("editFileSuffix")) { 57 $login_info_path .= $r->param("editFileSuffix"); 58 } 59 60 if (-f $login_info_path) { 61 my $text = eval { readFile($login_info_path) }; 62 if ($@) { 63 print CGI::div({class=>"ResultsWithError"}, 64 CGI::p("$@"), 65 ); 66 } else { 67 print CGI::p(CGI::b("Login Info")), $text; 68 } 69 } 70 71 return ""; 72 } 73 } 74 75 sub body { 76 my ($self) = @_; 77 my $r = $self->r; 78 my $ce = $r->ce; 79 my $db = $r->db; 80 my $urlpath = $r->urlpath; 81 82 # convenient data variables 83 my $effectiveUser = $r->param("effectiveUser") || ""; 84 my $user = $r->param("user"); 85 my $proctorUser = $r->param("proctor_user") || ""; 86 my $key = $r->param("proctor_key"); 87 my $passwd = $r->param("proctor_passwd") || ""; 88 my $course = $urlpath->arg("courseID"); 89 my $setID = $urlpath->arg("setID"); 90 my $timeNow = time(); 91 92 # data collection 93 my $submitAnswers = $r->param("submitAnswers"); 94 my $EffectiveUser = $db->getUser($effectiveUser); 95 my $User = $db->getUser($user); 96 97 my $effectiveUserFullName = $EffectiveUser->first_name() . " " . 98 $EffectiveUser->last_name(); 99 100 # save the userset for use below 101 my $UserSet; 102 # version_last_attempt_time conditional: if we're submitting the set 103 # for the last time we need to save the submission time. 104 if ( $submitAnswers ) { 105 106 # getMergedVersionedSet returns either the set requested (if the setID 107 # is versioned, "setName,vN") or the latest set (if not). This should 108 # be by default the set we want. 109 $UserSet = $db->getMergedVersionedSet($effectiveUser, $setID); 110 # this should never error out, but we'll check anyway 111 die("Proctor login generated for grade attempt on a nonexistent " . 112 "set?!\n") if ( ! defined($UserSet) ); 113 114 # we need these to get a problem from the set 115 my $setVersionName = ( $setID =~ /,v(\d+)$/ ) ? $setID : 116 $UserSet->set_id(); 117 $setID =~ s/,v\d+$//; 118 119 # we only save the submission time if the attempt will be recorded, 120 # so we have to do some research to determine if that's the case 121 my $PermissionLevel = $db->getPermissionLevel($user); 122 my $Problem = 123 $db->getMergedVersionedProblem($effectiveUser, $setID, 124 $setVersionName, 1); 125 # set last_attempt_time if appropriate 126 if ( WeBWorK::ContentGenerator::GatewayQuiz::can_recordAnswers($self,$User, $PermissionLevel, 127 $EffectiveUser, $UserSet, $Problem) ) { 128 $UserSet->version_last_attempt_time( $timeNow ); 129 $db->putVersionedUserSet( $UserSet ); 130 } 131 } 132 133 134 print CGI::p(CGI::strong("Proctor authorization required."), "\n\n"); 135 # WeBWorK::Authen::verifyProctor will set the note "authen_error" 136 # if invalid authentication is found. If this is done, it's a signal to 137 # us to yell at the user for doing that, since Authen isn't a content- 138 # generating module. 139 if ($r->notes("authen_error")) { 140 print CGI::div({class=>"ResultsWithError"}, 141 CGI::p($r->notes("authen_error")) 142 ); 143 } 144 145 # also print a message about submission times if we're submitting 146 # an answer 147 if ( $submitAnswers ) { 148 my $dueTime = $UserSet->due_date(); 149 my $timeLimit = $UserSet->version_time_limit(); 150 my ($color, $msg) = ("#ddddff", ""); 151 152 if ( $dueTime < $timeNow ) { 153 $color = "#ffffaa"; 154 $msg = CGI::br() . "\nThe time limit on this assignment " . 155 "was exceeded.\nThe assignment may be checked, but " . 156 "the result will not be counted.\n"; 157 } 158 my $style = "background-color: $color; color: black; " . 159 "border: solid black 1px; padding: 2px;"; 160 print CGI::div({-style=>$style}, 161 CGI::strong("Grading assignment: ", CGI::br(), 162 "Submission time: ", 163 scalar(localtime($timeNow)), CGI::br(), 164 "Due: ", 165 scalar(localtime($dueTime)), $msg)); 166 } 167 168 print CGI::div({style=>"background-color:#ddddff;"}, 169 CGI::p("User's uniqname is: ", 170 CGI::strong("$effectiveUser"),"\n", 171 CGI::br(),"User's name is: ", 172 CGI::strong("$effectiveUserFullName"),"\n")),"\n"; 173 174 print CGI::startform({-method=>"POST", -action=>$r->uri}); 175 176 # write out the form data posted to the requested URI 177 # print $self->print_form_data('<input type="hidden" name="','" value="',"\"/>\n",qr/^(user|passwd|key|force_passwd_authen|procter_user|proctor_key|proctor_password)$/); 178 my @fields_to_print = 179 grep { ! /^(user)|(effectiveUser)|(passwd)|(key)|(force_password_authen)|(proctor_user)|(proctor_key)|(proctor_passwd)$/ } $r->param(); 180 181 print $self->hidden_fields(@fields_to_print) if ( @fields_to_print ); 182 print $self->hidden_authen_fields,"\n"; 183 184 print CGI::table({class=>"FormLayout"}, 185 CGI::Tr([ 186 CGI::td([ 187 "Proctor username:", 188 CGI::input({-type=>"text", -name=>"proctor_user", -value=>""}), 189 ]), 190 CGI::td([ 191 "Proctor password:", 192 CGI::input({-type=>"password", -name=>"proctor_passwd", -value=>""}), 193 ]), 194 ]) 195 ); 196 197 print CGI::input({-type=>"submit", -value=>"Continue"}); 198 print CGI::endform(); 199 200 return ""; 201 } 202 203 1;
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |