You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(53) |
Feb
(56) |
Mar
|
Apr
|
May
(30) |
Jun
(78) |
Jul
(121) |
Aug
(155) |
Sep
(77) |
Oct
(61) |
Nov
(45) |
Dec
(94) |
2006 |
Jan
(116) |
Feb
(33) |
Mar
(11) |
Apr
(23) |
May
(60) |
Jun
(89) |
Jul
(130) |
Aug
(109) |
Sep
(124) |
Oct
(63) |
Nov
(82) |
Dec
(45) |
2007 |
Jan
(31) |
Feb
(35) |
Mar
(123) |
Apr
(36) |
May
(18) |
Jun
(134) |
Jul
(133) |
Aug
(241) |
Sep
(126) |
Oct
(31) |
Nov
(15) |
Dec
(5) |
2008 |
Jan
(11) |
Feb
(6) |
Mar
(16) |
Apr
(29) |
May
(43) |
Jun
(149) |
Jul
(27) |
Aug
(29) |
Sep
(37) |
Oct
(20) |
Nov
(4) |
Dec
(6) |
2009 |
Jan
(34) |
Feb
(30) |
Mar
(16) |
Apr
(6) |
May
(1) |
Jun
(32) |
Jul
(22) |
Aug
(7) |
Sep
(18) |
Oct
(50) |
Nov
(22) |
Dec
(8) |
2010 |
Jan
(17) |
Feb
(15) |
Mar
(10) |
Apr
(9) |
May
(67) |
Jun
(30) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
|
From: Mike G. v. a. <we...@ma...> - 2005-12-14 00:19:47
|
Log Message: ----------- Removed a link for creating a blank problem that is not yet fully supported. Commented out cheerful green goodmessages announcing which subroutine handler of the PGProblemEditor was being executed. They seem to have fulfilled their role and are no longer needed. :-) -- Mike Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: PGProblemEditor.pm ProblemSetDetail.pm Revision Data ------------- Index: PGProblemEditor.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v retrieving revision 1.64 retrieving revision 1.65 diff -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -u -r1.64 -r1.65 --- lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm +++ lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm @@ -914,7 +914,7 @@ sub fresh_edit_handler { my ($self, $genericParams, $actionParams, $tableParams) = @_; - $self->addgoodmessage("fresh_edit_handler called"); + #$self->addgoodmessage("fresh_edit_handler called"); } sub view_form { my ($self, $onChange, %actionParams) = @_; @@ -1059,7 +1059,7 @@ sub add_problem_handler { my ($self, $genericParams, $actionParams, $tableParams) = @_; -# $self->addgoodmessage("add_problem_handler called"); + #$self->addgoodmessage("add_problem_handler called"); my $courseName = $self->{courseID}; my $setName = $self->{setID}; my $problemNumber = $self->{problemID}; @@ -1159,7 +1159,7 @@ sub save_handler { my ($self, $genericParams, $actionParams, $tableParams) = @_; - $self->addgoodmessage("save_handler called"); + #$self->addgoodmessage("save_handler called"); my $courseName = $self->{courseID}; my $setName = $self->{setID}; my $problemNumber = $self->{problemID}; @@ -1271,7 +1271,7 @@ sub save_as_handler { my ($self, $genericParams, $actionParams, $tableParams) = @_; - $self->addgoodmessage("save_as_handler called"); + #$self->addgoodmessage("save_as_handler called"); my $courseName = $self->{courseID}; my $setName = $self->{setID}; my $problemNumber = $self->{problemID}; @@ -1384,7 +1384,7 @@ } sub revert_handler { my ($self, $genericParams, $actionParams, $tableParams) = @_; - $self->addgoodmessage("revert_handler called"); + #$self->addgoodmessage("revert_handler called"); my $courseName = $self->{courseID}; my $setName = $self->{setID}; @@ -1423,7 +1423,7 @@ sub make_local_copy_handler { my ($self, $genericParams, $actionParams, $tableParams) = @_; - $self->addgoodmessage("make_local_copy_handler called"); + #$self->addgoodmessage("make_local_copy_handler called"); my $courseName = $self->{courseID}; my $setName = $self->{setID}; Index: ProblemSetDetail.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm,v retrieving revision 1.28 retrieving revision 1.29 diff -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -u -r1.28 -r1.29 --- lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -1416,7 +1416,8 @@ my $editNewProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID =>'new_problem' }); my $editNewProblemLink = $self->systemLink($editNewProblemPage, params => { make_local_copy => 1, file_type => 'blank_problem' }); - print CGI::p( CGI::a({href=>$editNewProblemLink},'Edit'). ' a new blank problem'); + # This next feature isn't fully supported and is causing problems. Remove for now. #FIXME + #print CGI::p( CGI::a({href=>$editNewProblemLink},'Edit'). ' a new blank problem'); print CGI::end_form(); |
From: Sam H. v. a. <we...@ma...> - 2005-12-13 19:36:33
|
Log Message: ----------- remove dummy checkboxes for the time being, sort of closing bug #805. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: Scoring.pm Revision Data ------------- Index: Scoring.pm =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instr= uctor/Scoring.pm,v retrieving revision 1.52 retrieving revision 1.53 diff -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -Llib/WeBWorK/C= ontentGenerator/Instructor/Scoring.pm -u -r1.52 -r1.53 --- lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm @@ -165,20 +165,21 @@ }, ), CGI::br(), - CGI::checkbox({ -name=3D>'includeTotals', - -value=3D>1, - -label=3D>'Include Total score column', - -checked=3D>1, - }, - ), - CGI::br(), - CGI::checkbox({ -name=3D>'includePercent', - -value=3D>1, - -label=3D>'Include Percent correct column', - -checked=3D>1, - }, - ), - CGI::br(), + # These are not yet implemented + #CGI::checkbox({ -name=3D>'includeTotals', + # -value=3D>1, + # -label=3D>'Include Total score column', + # -checked=3D>1, + # }, + #), + #CGI::br(), + #CGI::checkbox({ -name=3D>'includePercent', + # -value=3D>1, + # -label=3D>'Include Percent correct column', + # -checked=3D>1, + # }, + #), + #CGI::br(), CGI::checkbox({ -name=3D>'recordSingleSetScores', -value=3D>1, -label=3D>'Record Scores for Single Sets', @@ -833,5 +834,5 @@ average number of incorrect attempts index =3D ( total_status / total_value )**2 / average_number_of_attem= pts =20 -"value" is the weight of the problem, in the range [0,=83), usually 1. +"value" is the weight of the problem, in the range [0,inf), usually 1. "status" is the correctness of a problem, in the range [0,1]. |
From: Sam H. v. a. <we...@ma...> - 2005-12-13 18:31:47
|
Log Message: ----------- use Parser-based num_cmp and fun_cmp by default. Modified Files: -------------- webwork2/conf: global.conf.dist Revision Data ------------- Index: global.conf.dist =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/global.conf.dist,v retrieving revision 1.154 retrieving revision 1.155 diff -Lconf/global.conf.dist -Lconf/global.conf.dist -u -r1.154 -r1.155 --- conf/global.conf.dist +++ conf/global.conf.dist @@ -745,9 +745,9 @@ # Size in pixels of dynamically-generated images, i.e. graphs. $pg{specialPGEnvironmentVars}{onTheFlyImageSize} = 400, -# To activate Parser-based versions of num_cmp and fun_cmp, change this -# value to 0. -$pg{specialPGEnvironmentVars}{useOldAnswerMacros} = 1; +# To disable the Parser-based versions of num_cmp and fun_cmp, and use the +# original versions instead, set this value to 1. +$pg{specialPGEnvironmentVars}{useOldAnswerMacros} = 0; # Strings to insert at the start and end of the body of a problem # (at beginproblem() and ENDDOCUMENT) in various modes. More display modes |
From: Sam H. v. a. <we...@ma...> - 2005-12-13 18:26:41
|
Log Message: ----------- give answer is equivalent message regardless of correctness. fixes bug #752. Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.49 retrieving revision 1.50 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.49 -r1.50 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -2030,15 +2030,13 @@ ); # - # Produce a message if the previous answer equals this one - # (and is not correct, and is not specified the same way) + # Produce a message if the previous answer equals this one and is not specified the same way # $cmp->install_post_filter( sub { my $rh_ans = shift; $rh_ans->{_filter_name} = "produce_equivalence_message"; - return $rh_ans unless $rh_ans->{prev_equals_current} && - ($rh_ans->{score} != 1 || $rh_ans->{isPreview}); + return $rh_ans unless $rh_ans->{prev_equals_current}; # # If the match is exact don't give an error since there may be multiple # entry blanks and the student is trying to get one of the other ones @@ -2335,7 +2333,7 @@ $answer_evaluator->install_post_filter( sub { my $rh_ans = shift; - if ( defined($rh_ans->{'ans_equals_prev_ans'}) and $rh_ans->{'ans_equals_prev_ans'} and $rh_ans->{score}==0) { + if ( defined($rh_ans->{'ans_equals_prev_ans'}) and $rh_ans->{'ans_equals_prev_ans'}) { ## $rh_ans->{ans_message} = "This answer is the same as the one you just submitted or previewed."; $rh_ans->{ans_message} = "This answer is equivalent to the one you just submitted or previewed."; ## DPVC } |
From: Sam H. v. a. <we...@ma...> - 2005-12-13 18:21:34
|
Log Message: ----------- push loginstatus over to the right Modified Files: -------------- webwork2/conf/templates: ur.template Revision Data ------------- Index: ur.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/ur.template,v retrieving revision 1.44 retrieving revision 1.45 diff -Lconf/templates/ur.template -Lconf/templates/ur.template -u -r1.44 -r1.45 --- conf/templates/ur.template +++ conf/templates/ur.template @@ -70,7 +70,7 @@ <!--#else--> <td class="TopPanel" > <!--#endif--> - <table cellpadding="0" cellspacing="0" border="0"> + <table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr valign="top"> <td class="TopPanel"> <!--#if can="path"--> @@ -78,7 +78,7 @@ <!--#endif--> </td> <td> </td> - <td class="TopPanel" nowrap> + <td class="TopPanel" align="right" nowrap> <!--#if can="loginstatus"--> <span class="LoginStatus"><!--#loginstatus--></span> <!--#endif--> |
From: Sam H. v. a. <we...@ma...> - 2005-12-12 22:27:46
|
Log Message: ----------- added some notes at the bottom. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: Scoring.pm Revision Data ------------- Index: Scoring.pm =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instr= uctor/Scoring.pm,v retrieving revision 1.51 retrieving revision 1.52 diff -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -Llib/WeBWorK/C= ontentGenerator/Instructor/Scoring.pm -u -r1.51 -r1.52 --- lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm @@ -797,3 +797,41 @@ =20 } 1; + +__END__ + +Here's pretty much everything I can think of that we can get out of the = database +or calculate: + +for each set, we have a few rows of non-user-specific data above the stu= dent rows +(we could just have additional columns for these values, but they'd have= the same value in every row) + set_id + optional other set data (dates, etc) + per-problem data (usually not shown, but available if needed) + problem_id + problem value + for all problems in the set + total value +for each student (one row) we need columns for: + user_id and/or student_id + optional other user data (first_name/last_name, section, recitation, et= c) + per-set data + per-problem data (usually not shown, but available if needed) + status + score =3D value*status + number of attempts + number of correct attempts + number of incorrect attempts + for all problems in the set + total status + total score + total number of attempts + average number of attempts + total number of correct attempts + average number of correct attempts + total number of incorrect attempts + average number of incorrect attempts + index =3D ( total_status / total_value )**2 / average_number_of_attem= pts + +"value" is the weight of the problem, in the range [0,=83), usually 1. +"status" is the correctness of a problem, in the range [0,1]. |
From: Sam H. v. a. <we...@ma...> - 2005-12-12 21:33:42
|
Log Message: ----------- fixed divide-by-zero error when calculating index. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: Scoring.pm Revision Data ------------- Index: Scoring.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm,v retrieving revision 1.50 retrieving revision 1.51 diff -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -Llib/WeBWorK/ContentGenerator/Instructor/Scoring.pm -u -r1.50 -r1.51 --- lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm +++ lib/WeBWorK/ContentGenerator/Instructor/Scoring.pm @@ -484,7 +484,7 @@ if ($scoringItems->{successIndex}) { for (my $user = 0; $user < @sortedUserIDs; $user++) { my $avg_num_attempts = ($num_of_problems) ? $numberOfAttempts{$user}/$num_of_problems : 0; - $userSuccessIndex{$user} = ($avg_num_attempts) ? ($userStatusTotals{$user}/$valueTotal)**2/$avg_num_attempts : 0; + $userSuccessIndex{$user} = ($avg_num_attempts && $valueTotal) ? ($userStatusTotals{$user}/$valueTotal)**2/$avg_num_attempts : 0; } } # write the status totals |
From: Mike G. v. a. <we...@ma...> - 2005-12-11 01:36:21
|
Log Message: ----------- Put a little space between the bread crumb path and the login status information. Modified Files: -------------- webwork-modperl/conf/templates: ur.template Revision Data ------------- Index: ur.template =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/conf/templates/ur.template,v retrieving revision 1.43 retrieving revision 1.44 diff -Lconf/templates/ur.template -Lconf/templates/ur.template -u -r1.43 -r1.44 --- conf/templates/ur.template +++ conf/templates/ur.template @@ -77,6 +77,7 @@ <span class="Path"><!--#path style="text" image="/webwork2_files/images/right_arrow.png" text=" > "--></span> <!--#endif--> </td> + <td> </td> <td class="TopPanel" nowrap> <!--#if can="loginstatus"--> <span class="LoginStatus"><!--#loginstatus--></span> |
From: Sam H. v. a. <we...@ma...> - 2005-12-09 15:54:23
|
Log Message: ----------- note the "force renumber" is always enabled when problems are being reordered. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: ProblemSetDetail.pm Revision Data ------------- Index: ProblemSetDetail.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm,v retrieving revision 1.27 retrieving revision 1.28 diff -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -u -r1.27 -r1.28 --- lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -1390,7 +1390,7 @@ # print final lines print CGI::end_table(); print CGI::checkbox({ - label=> "Force problems to be numbered consecutively from one", + label=> "Force problems to be numbered consecutively from one (always done when reordering problems)", name=>"force_renumber", value=>"1"}), CGI::br(), CGI::checkbox({ |
From: Sam H. v. a. <we...@ma...> - 2005-12-08 19:18:57
|
Log Message: ----------- Allow reordering to succeed even if some UserProblems are missing. Addresses bug #878. By the way, I found the reordering code really hard to read, so I added a lot of comments and replaced multidimensional array accesses with a shorter form. ($sortme[$j][0] rather than $sortme[$j]->[0].) I'd like to maybe rewrite this code sometime to eliminate some indirection and make things clearer. There are two substantive changes: (1) When a UserProblem has to get reordered, we only reorder it if a UserProblem record actually exists. If it doesn't exist, we figure out where it would have moved to, and delete that problem instead. (2) When moving a UserProblem, the target location either contains or doesn't contain a record. Previously, the code checked whether a GlobalProblem existed in this location, assuming that if a global problem existed the corresponding UserProblem would as well. Now, it checks whether a UserProblem exists, which allows for missing UserProblem records. Lingering questions: (1) When multiple problems are assigned the same number, this results in the last one ending up first in the new ordering. I think it would be more natural for the first one to end up first. This would be an easy fix. (2) $force always gets set if reordering needs to be done, so we aren't able to delete a problem, reorder some other problems, and end up with a hole where where the deleted problem was. We can either fix this by mentioning this next to the force checkbox, or change it so that particular holes (i.e. those left by deleted problems) are allowed when reordering. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: ProblemSetDetail.pm Revision Data ------------- Index: ProblemSetDetail.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm,v retrieving revision 1.26 retrieving revision 1.27 diff -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -u -r1.26 -r1.27 --- lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -416,22 +416,31 @@ my @sortme=(); my ($j, $val); + # keys are current problem numbers, values are target problem numbers foreach $j (keys %newProblemNumbers) { - # what happens our first time on this page + # we don't want to act unless all problems have been assigned a new problem number, so if any have not, return return "" if (not defined $newProblemNumbers{"$j"}); + # if the problem has been given a new number, we reduce the "score" of the problem by the original number of the problem + # when multiple problems are assigned the same number, this results in the last one ending up first -- FIXME? if ($newProblemNumbers{"$j"} != $j) { + # force always gets set if reordering is done, so don't expect to be able to delete a problem, + # reorder some other problems, and end up with a hole -- FIXME $force = 1; $val = 1000 * $newProblemNumbers{$j} - $j; } else { $val = 1000 * $newProblemNumbers{$j}; } + # store a mapping between current problem number and score (based on currnet and new problem number) push @sortme, [$j, $val]; + # replace new problem numbers in hash with the (global) problems themselves $newProblemNumbers{$j} = $db->getGlobalProblem($setID, $j); die "global $j for set $setID not found." unless $newProblemNumbers{$j}; } + # we don't have to do anything if we're not getting rid of holes return "" unless $force; + # sort the curr. prob. num./score pairs by score @sortme = sort {$a->[1] <=> $b->[1]} @sortme; # now, for global and each user with this set, loop through problem list # get all of the problem records @@ -443,14 +452,17 @@ # Now, three stages. First global values for ($j = 0; $j < scalar @sortme; $j++) { - if($sortme[$j]->[0] == $j + 1) { + if($sortme[$j][0] == $j + 1) { + # if the jth problem (according to the new ordering) is in the right place (problem IDs are numbered from 1, hence $j+1) # do nothing } elsif (not defined $newProblemNumbers{$j + 1}) { - $newProblemNumbers{$sortme[$j]->[0]}->problem_id($j + 1); - $db->addGlobalProblem($newProblemNumbers{$sortme[$j]->[0]}); + # otherwise, if there's a hole for it, add it there + $newProblemNumbers{$sortme[$j][0]}->problem_id($j + 1); + $db->addGlobalProblem($newProblemNumbers{$sortme[$j][0]}); } else { - $newProblemNumbers{$sortme[$j]->[0]}->problem_id($j + 1); - $db->putGlobalProblem($newProblemNumbers{$sortme[$j]->[0]}); + # otherwise, overwrite the data for the problem that's already there with the jth problem's data (with a changed problemID) + $newProblemNumbers{$sortme[$j][0]}->problem_id($j + 1); + $db->putGlobalProblem($newProblemNumbers{$sortme[$j][0]}); } } @@ -463,32 +475,57 @@ # we can't do it again. This relies on the global user not having # a blank name. next if $globalUserID eq $user; + # grab a copy of each UserProblem for this user. @problist can be sparse (if problems were deleted) for $j (keys %newProblemNumbers) { $problist[$j] = $db->getUserProblem($user, $setID, $j); - die " problem $j for set $setID and effective user $user not found" - unless $problist[$j]; } - # ok, now we have all problem data for $user + use Data::Dumper; for($j = 0; $j < scalar @sortme; $j++) { - if ($sortme[$j]->[0] == $j + 1) { + if ($sortme[$j][0] == $j + 1) { + # same as above -- the jth problem is in the right place, so don't worry about it # do nothing - } elsif (not defined $newProblemNumbers{$j + 1}) { - $problist[$sortme[$j]->[0]]->problem_id($j + 1); - $db->addUserProblem($problist[$sortme[$j]->[0]]); - } else { - $problist[$sortme[$j]->[0]]->problem_id($j + 1); - $db->putUserProblem($problist[$sortme[$j]->[0]]); - } + } elsif ($problist[$sortme[$j][0]]) { + # we've made sure the user's problem actually exists HERE, since we want to be able to fail gracefullly if it doesn't + # the problem with the original conditional below is that %newProblemNumbers maps oldids => global problem record + # we need to check if the target USER PROBLEM exists, which is what @problist knows + #if (not defined $newProblemNumbers{$j + 1}) { + if (not defined $problist[$j+1]) { + # same as above -- there's a hole for that problem to go into, so add it in its new place + $problist[$sortme[$j][0]]->problem_id($j + 1); + $db->addUserProblem($problist[$sortme[$j][0]]); + } else { + # same as above -- there's a problem already there, so overwrite its data with the data from the jth problem + $problist[$sortme[$j][0]]->problem_id($j + 1); + $db->putUserProblem($problist[$sortme[$j][0]]); + } + } else { + warn "UserProblem missing for user=$user set=$setID problem=$sortme[$j][0]. This may indicate database corruption.\n"; + # when a problem doesn't exist in the target slot, a new problem gets added there, but the original problem + # never gets overwritten (because there wan't a problem it would have to get exchanged with) + # i think this can get pretty complex. consider 1=>2, 2=>3, 3=>4, 4=>1 where problem 1 doesn't exist for some user: + # @sortme[$j][0] will contain: 4, 1, 2, 3 + # - problem 1 will get **added** with the data from problem 4 (because problem 1 doesn't exist for this user) + # - problem 2 will get overwritten with the data from problem 1 + # - problem 3 will get overwritten with the data from problem 2 + # - nothing will happend to problem 4, since problem 1 doesn't exit + # so the solution is to delete problem 4 altogether! + # here's the fix: + + # the data from problem $j+1 was/will be moved to another problem slot, + # but there's no problem $sortme[$j][0] to replace it. thus, we delete it now. + $db->deleteUserProblem($user, $setID, $j+1); + } } } - + # any problems with IDs above $maxNum get deleted -- presumably their data has been copied into problems with lower IDs foreach ($j = scalar @sortme; $j < $maxNum; $j++) { if (defined $newProblemNumbers{$j + 1}) { $db->deleteGlobalProblem($setID, $j+1); } } + # return a string form of the old problem IDs in the new order (not used by caller, incidentally) return join(', ', map {$_->[0]} @sortme); } |
From: Sam H. v. a. <we...@ma...> - 2005-12-08 18:13:18
|
Log Message: ----------- quick hack to prevent path text and loginstatus text from overlapping. Modified Files: -------------- webwork2/conf/templates: ur.template webwork2/htdocs/css: ur.css Revision Data ------------- Index: ur.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/ur.template,v retrieving revision 1.42 retrieving revision 1.43 diff -Lconf/templates/ur.template -Lconf/templates/ur.template -u -r1.42 -r1.43 --- conf/templates/ur.template +++ conf/templates/ur.template @@ -70,18 +70,20 @@ <!--#else--> <td class="TopPanel" > <!--#endif--> - <div style="position:relative; width:100%;"> - <!--#if can="path"--> - <span class="Path"> - <!--#path style="text" image="/webwork2_files/images/right_arrow.png" text=" > "--> - </span> - <!--#endif--> - <!--#if can="loginstatus"--> - <span class="LoginStatus"> - <!--#loginstatus--> - </span> - <!--#endif--> - </div> + <table cellpadding="0" cellspacing="0" border="0"> + <tr valign="top"> + <td class="TopPanel"> + <!--#if can="path"--> + <span class="Path"><!--#path style="text" image="/webwork2_files/images/right_arrow.png" text=" > "--></span> + <!--#endif--> + </td> + <td class="TopPanel" nowrap> + <!--#if can="loginstatus"--> + <span class="LoginStatus"><!--#loginstatus--></span> + <!--#endif--> + </td> + </tr> + </table> </td> </tr> <tr valign="top"> Index: ur.css =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/css/ur.css,v retrieving revision 1.14 retrieving revision 1.15 diff -Lhtdocs/css/ur.css -Lhtdocs/css/ur.css -u -r1.14 -r1.15 --- htdocs/css/ur.css +++ htdocs/css/ur.css @@ -29,7 +29,8 @@ .Path { } -.LoginStatus { text-align: right; font-size: small; position:absolute; top: 0; right: 0; } +/*.LoginStatus { text-align: right; font-size: small; position:absolute; top: 0; right: 0; }*/ +.LoginStatus { text-align: right; font-size: small; } td.Timestamp { text-align: left; font-size: small; font-style: italic; } /* (should have ContentPanelError here) */ |
From: dpvc v. a. <we...@ma...> - 2005-12-07 16:16:40
|
Log Message: ----------- Prevent error message when num_cmp specifies the same string more than once (e.g., upper and lower case versions of the same thing). Modified Files: -------------- pg/macros: PGanswermacros.pl Revision Data ------------- Index: PGanswermacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PGanswermacros.pl,v retrieving revision 1.48 retrieving revision 1.49 diff -Lmacros/PGanswermacros.pl -Lmacros/PGanswermacros.pl -u -r1.48 -r1.49 --- macros/PGanswermacros.pl +++ macros/PGanswermacros.pl @@ -1080,7 +1080,8 @@ foreach my $string (@{$num_params{strings}}) { my %tex = ($string =~ m/^(-?)inf(inity)?$/i)? (TeX => "$1\\infty"): (); %tex = (TeX => "-\\infty") if uc($string) eq "MINF"; - $context->strings->add(uc($string) => {%tex}); + $context->strings->add(uc($string) => {%tex}) + unless $context->strings->get(uc($string)); } } |
From: Sam H. v. a. <we...@ma...> - 2005-12-06 21:13:48
|
Log Message: ----------- remove specific login error mesasges -- log to login.log instead. some messages leaked information. (i.e. "user not found" versus "incorrect password".) Modified Files: -------------- webwork2/lib/WeBWorK: Authen.pm Revision Data ------------- Index: Authen.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/Authen.pm,v retrieving revision 1.47 retrieving revision 1.48 diff -Llib/WeBWorK/Authen.pm -Llib/WeBWorK/Authen.pm -u -r1.47 -r1.48 --- lib/WeBWorK/Authen.pm +++ lib/WeBWorK/Authen.pm @@ -26,9 +26,11 @@ use warnings; use Apache::Cookie; use Date::Format; -use WeBWorK::Utils qw(writeCourseLog); +use Socket qw/unpack_sockaddr_in inet_ntoa/; +use WeBWorK::Utils qw/writeCourseLog/; use constant COOKIE_LIFESPAN => 60*60*24*30; # 30 days +use constant GENERIC_ERROR_MESSAGE => "Invalid user ID or password."; ################################################################################ # Public API @@ -125,11 +127,13 @@ $r->param("user", $userID); $r->param("key", $Key->key); $found = 1; - $self->record_login($userID); + $credentialSource = "guest"; + $self->write_log_entry("GUEST LOGIN OK $userID"); last; } } unless ($found) { + $self->write_log_entry("GUEST LOGIN FAILED - no logins availabe"); $error = "No practice users are available. Please try again in a few minutes."; } last VERIFY; @@ -147,6 +151,7 @@ #$r->args->{user} = $user; $r->param("key", $key); $credentialSource = "cookie"; + $self->write_log_entry("COOKIE LOGIN OK $user"); } else { $failWithoutError = 1; last VERIFY; @@ -167,8 +172,8 @@ # Make sure user is in the database my $User = $db->getUser($user); # checked unless (defined $User) { - # FIXME too much information! - $error = "There is no account for $user in this course."; + $self->write_log_entry("LOGIN FAILED $user - user unknown"); + $error = GENERIC_ERROR_MESSAGE; last VERIFY; } @@ -185,15 +190,15 @@ # make sure users with this user's status are allowed to access the course (jeez...) unless ($ce->status_abbrev_has_behavior($User->status, "allow_course_access")) { - # FIXME too much information! - $error = "The user $user has been dropped from this course."; + $self->write_log_entry("LOGIN FAILED $user - course access denied"); + $error = GENERIC_ERROR_MESSAGE; last VERIFY; } # make sure the user is allowed to login unless ($authz->hasPermissions($user, "login")) { - # FIXME too much information? - $error = "The user $user is not allowed to log in."; + $self->write_log_entry("LOGIN FAILED $user - no permission to login"); + $error = GENERIC_ERROR_MESSAGE; last VERIFY; } @@ -207,9 +212,11 @@ if ($key) { if ($self->checkKey($user, $key)) { # they key was valid. + #$self->write_log_entry("KEY LOGIN OK $user"); last VERIFY; } else { # the key was invalid. + #$self->write_log_entry("KEY LOGIN FAILED $user - invalid key"); $error = "Your session has timed out due to inactivity. You must login again."; last VERIFY; } @@ -228,7 +235,9 @@ } # an unexpired key exists -- the account is in use. + # FIXME improve the error message here if ($self->unexpiredKeyExists($user)) { + $self->write_log_entry("GUEST LOGIN FAILED $user - in use"); $error = "That practice account is in use."; last VERIFY; } @@ -277,11 +286,12 @@ $r->param("key", $Key->key()); # also delete the password $r->param("passwd", ""); - $self->record_login($user); + $self->write_log_entry("LOGIN OK $user - valid password"); last VERIFY; } else { # incorrect password. fail. - $error = "Incorrect username or password."; + $self->write_log_entry("LOGIN FAILED $user - invalid password"); + $error = "Invalid user ID or password."; last VERIFY; } } @@ -438,21 +448,21 @@ my $Proctor = $db->getUser($proctorUser); unless(defined $Proctor) { - # FIXME too much information - $error = "There is no proctor account for $proctorUser in this course"; + $self->write_log_entry("PROCTOR LOGIN FAILED $proctorUser - user unknown"); + $error = "Invalid user ID or password"; last VERIFY; } - unless( !defined($Proctor->status) or $Proctor->status() eq 'C' ) { - # FIXME too much information - $error = "Proctor user $proctorUser does not have a valid status in this course."; - last VERIFY; - } + #unless( !defined($Proctor->status) or $Proctor->status() eq 'C' ) { + # $self->write_log_entry("PROCTOR LOGIN FAILED $proctorUser - invalid status"); + # $error = GENERIC_ERROR_MESSAGE; + # last VERIFY; + #} # make sure proctor has valid status unless($ce->status_abbrev_has_behavior($Proctor->status, "allow_course_access")) { - # FIXME too much information - $error = "Proctor user $proctorUser does not have a valid status in this course."; + $self->write_log_entry("PROCTOR LOGIN FAILED $proctorUser - course access denied"); + $error = GENERIC_ERROR_MESSAGE; last VERIFY; } @@ -713,15 +723,18 @@ # Utilities ################################################################################ -sub record_login($$) { - my ($self, $userID) = @_; +sub write_log_entry { + my ($self, $message) = @_; + my $r = $self->{r}; my $ce = $r->ce; - my $timestamp = localtime; - ($timestamp) = $timestamp =~ /^\w+\s(.*)\s/; - my $remote_host = $r->get_remote_host || "(cannot get host)"; + + my ($remote_port, $remote_host) = unpack_sockaddr_in($r->connection->remote_addr); + $remote_host = defined $remote_host ? inet_ntoa($remote_host) : "UNKNOWN"; + $remote_port = "UNKNOWN" unless defined $remote_port; my $user_agent = $r->header_in("User-Agent"); - writeCourseLog($ce, "login_log", "$userID on $remote_host ($user_agent)"); + + writeCourseLog($ce, "login_log", "$message (host=$remote_host port=$remote_port UA=$user_agent"); } 1; |
From: Sam H. v. a. <we...@ma...> - 2005-12-06 19:59:09
|
Log Message: ----------- fixed warnings in &nav and &options when set is not asssigned. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Problem.pm Revision Data ------------- Index: Problem.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm,v retrieving revision 1.188 retrieving revision 1.189 diff -Llib/WeBWorK/ContentGenerator/Problem.pm -Llib/WeBWorK/ContentGenerator/Problem.pm -u -r1.188 -r1.189 --- lib/WeBWorK/ContentGenerator/Problem.pm +++ lib/WeBWorK/ContentGenerator/Problem.pm @@ -666,8 +666,8 @@ #warn "doing options in Problem"; # don't show options if we don't have anything to show - return if $self->{invalidSet} or $self->{invalidProblem}; - return unless $self->{isOpen}; + return "" if $self->{invalidSet} or $self->{invalidProblem}; + return "" unless $self->{isOpen}; my $displayMode = $self->{displayMode}; my %can = %{ $self->{can} }; @@ -762,7 +762,11 @@ push @links, "Next Problem", "", "navNext"; } - my $tail = "&displayMode=".$self->{displayMode}."&showOldAnswers=".$self->{will}->{showOldAnswers}; + my $tail = ""; + + $tail .= "&displayMode=".$self->{displayMode} if defined $self->{displayMode}; + $tail .= "&showOldAnswers=".$self->{will}->{showOldAnswers} + if defined $self->{will}->{showOldAnswers}; return $self->navMacro($args, $tail, @links); } |
From: Sam H. v. a. <we...@ma...> - 2005-12-06 19:58:30
|
Log Message: ----------- removed useless debugging statement Modified Files: -------------- webwork2/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.156 retrieving revision 1.157 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.156 -r1.157 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -1361,7 +1361,7 @@ sub optionsMacro { my ($self, %options) = @_; - debug("HELLO WORLD!"); + my @options_to_show = @{$options{options_to_show}} if exists $options{options_to_show}; @options_to_show = "displayMode" unless @options_to_show; my %options_to_show; @options_to_show{@options_to_show} = (); # make hash for easy lookups |
From: Arnie P. v. a. <we...@ma...> - 2005-12-06 02:34:23
|
Log Message: ----------- Allow the admin course to be hidden by the hide_directort technique Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator: Home.pm Revision Data ------------- Index: Home.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Home.pm,v retrieving revision 1.11 retrieving revision 1.12 diff -Llib/WeBWorK/ContentGenerator/Home.pm -Llib/WeBWorK/ContentGenerator/Home.pm -u -r1.11 -r1.12 --- lib/WeBWorK/ContentGenerator/Home.pm +++ lib/WeBWorK/ContentGenerator/Home.pm @@ -83,7 +83,7 @@ print CGI::p("Welcome to WeBWorK!"); - if ($haveAdminCourse) { + if ($haveAdminCourse and !(-f "$coursesDir/admin/hide_directory")) { my $urlpath = $r->urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets", courseID => "admin"); print CGI::p(CGI::a({href=>$self->systemLink($urlpath, authen => 0)}, "Course Administration")); } |
From: Sam H. v. a. <we...@ma...> - 2005-12-05 19:46:43
|
Log Message: ----------- add permission for viewing problem debugging info. Modified Files: -------------- webwork2/conf: global.conf.dist webwork2/lib/WeBWorK/ContentGenerator: Problem.pm Revision Data ------------- Index: global.conf.dist =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/global.conf.dist,v retrieving revision 1.153 retrieving revision 1.154 diff -Lconf/global.conf.dist -Lconf/global.conf.dist -u -r1.153 -r1.154 --- conf/global.conf.dist +++ conf/global.conf.dist @@ -549,6 +549,8 @@ record_answers_after_due_date => undef, record_answers_after_answer_date => undef, dont_log_past_answers => "professor", + # does the user get to see a dump of the problem? + view_problem_debugging_info => "ta", ##### Behavior of the Hardcopy Processor ##### Index: Problem.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm,v retrieving revision 1.187 retrieving revision 1.188 diff -Llib/WeBWorK/ContentGenerator/Problem.pm -Llib/WeBWorK/ContentGenerator/Problem.pm -u -r1.187 -r1.188 --- lib/WeBWorK/ContentGenerator/Problem.pm +++ lib/WeBWorK/ContentGenerator/Problem.pm @@ -833,7 +833,11 @@ ##### translation errors? ##### if ($pg->{flags}->{error_flag}) { - print $self->errorOutput($pg->{errors}, $pg->{body_text}); + if ($authz->hasPermissions($user, "view_problem_debugging_info")) { + print $self->errorOutput($pg->{errors}, $pg->{body_text}); + } else { + print $self->errorOutput($pg->{errors}, "You do not have permission to view the details of this error."); + } print $editorLink; return ""; } |
From: Sam H. v. a. <we...@ma...> - 2005-12-05 18:00:43
|
Log Message: ----------- comment cleanup -- ignore Modified Files: -------------- webwork2/lib/WeBWorK/DB/Record: User.pm Revision Data ------------- Index: User.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/DB/Record/User.pm,v retrieving revision 1.8 retrieving revision 1.9 diff -Llib/WeBWorK/DB/Record/User.pm -Llib/WeBWorK/DB/Record/User.pm -u -r1.8 -r1.9 --- lib/WeBWorK/DB/Record/User.pm +++ lib/WeBWorK/DB/Record/User.pm @@ -82,29 +82,21 @@ } } -# mailbox = addr-spec ; simple address -# / phrase route-addr ; name & addr-spec -# route-addr = "<" [route] addr-spec ">" -# addr-spec = local-part "@" domain ; global address # phrase = 1*word ; Sequence of words # word = atom / quoted-string # atom = 1*<any CHAR except specials, SPACE and CTLs> # specials = "(" / ")" / "<" / ">" / "@" ; Must be in quoted- # / "," / ";" / ":" / "\" / <"> ; string, to use # / "." / "[" / "]" ; within a word. -# CR = <ASCII CR, carriage return> ; ( 15, 13.) +# SPACE = <ASCII SP, space> ; ( 40, 32.) # CTL = <any ASCII control ; ( 0- 37, 0.- 31.) # character and DEL> ; ( 177, 127.) -# SPACE = <ASCII SP, space> ; ( 40, 32.) -# HTAB = <ASCII HT, horizontal-tab> ; ( 11, 9.) # quoted-string = <"> *(qtext/quoted-pair) <">; Regular qtext or # ; quoted chars. # qtext = <any CHAR excepting <">, ; => may be folded # "\" & CR, and including # linear-white-space> -# linear-white-space = 1*([CRLF] LWSP-char) ; semantics = SPACE -# ; CRLF => folding -# LWSP-char = SPACE / HTAB ; semantics = SPACE +# CR = <ASCII CR, carriage return> ; ( 15, 13.) # quoted-pair = "\" CHAR ; may quote any char sub rfc822_mailbox { |
From: Sam H. v. a. <we...@ma...> - 2005-12-05 17:52:38
|
Log Message: ----------- added proper phrase quoting to rfc822_mailbox -- fixes bug #875. Modified Files: -------------- webwork2/lib/WeBWorK/DB/Record: User.pm Revision Data ------------- Index: User.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/DB/Record/User.pm,v retrieving revision 1.7 retrieving revision 1.8 diff -Llib/WeBWorK/DB/Record/User.pm -Llib/WeBWorK/DB/Record/User.pm -u -r1.7 -r1.8 --- lib/WeBWorK/DB/Record/User.pm +++ lib/WeBWorK/DB/Record/User.pm @@ -82,6 +82,31 @@ } } +# mailbox = addr-spec ; simple address +# / phrase route-addr ; name & addr-spec +# route-addr = "<" [route] addr-spec ">" +# addr-spec = local-part "@" domain ; global address +# phrase = 1*word ; Sequence of words +# word = atom / quoted-string +# atom = 1*<any CHAR except specials, SPACE and CTLs> +# specials = "(" / ")" / "<" / ">" / "@" ; Must be in quoted- +# / "," / ";" / ":" / "\" / <"> ; string, to use +# / "." / "[" / "]" ; within a word. +# CR = <ASCII CR, carriage return> ; ( 15, 13.) +# CTL = <any ASCII control ; ( 0- 37, 0.- 31.) +# character and DEL> ; ( 177, 127.) +# SPACE = <ASCII SP, space> ; ( 40, 32.) +# HTAB = <ASCII HT, horizontal-tab> ; ( 11, 9.) +# quoted-string = <"> *(qtext/quoted-pair) <">; Regular qtext or +# ; quoted chars. +# qtext = <any CHAR excepting <">, ; => may be folded +# "\" & CR, and including +# linear-white-space> +# linear-white-space = 1*([CRLF] LWSP-char) ; semantics = SPACE +# ; CRLF => folding +# LWSP-char = SPACE / HTAB ; semantics = SPACE +# quoted-pair = "\" CHAR ; may quote any char + sub rfc822_mailbox { my ($self) = @_; @@ -90,6 +115,12 @@ if (defined $address and $address ne "") { if (defined $full_name and $full_name ne "") { + # see if we need to quote the phrase + # (this regex matches CTL, SPACE, and specials) + if ($full_name =~ /[\0-\037\177 ()<>@,;:\\".\[\]]/) { + $full_name =~ s/(["\\\r])/\\$1/g; # escape <">, "\", or CR + $full_name = "\"$full_name\""; + } return "$full_name <$address>"; } else { return $address; |
From: Sam H. v. a. <we...@ma...> - 2005-12-05 16:12:43
|
Log Message: ----------- Corrected error message when mailing to an address is not allowed. This used to refer to the courseWeBWorK.ph file, which is WW1-specific. It now mentions global.conf and course.conf. Modified Files: -------------- pg/macros: IO.pl Revision Data ------------- Index: IO.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/IO.pl,v retrieving revision 1.2 retrieving revision 1.3 diff -Lmacros/IO.pl -Lmacros/IO.pl -u -r1.2 -r1.3 --- macros/IO.pl +++ macros/IO.pl @@ -72,7 +72,7 @@ die "There has been an error in creating this problem.\n" . "Please notify your instructor.\n\n" . "Mail is not permitted to address $user_address.\n" - . "Permitted addresses are specified in the courseWeBWorK.ph file."; + . "Permitted addresses are specified in global.conf or course.conf."; $out = 0; } |
From: Mike G. v. a. <we...@ma...> - 2005-12-03 21:27:29
|
Log Message: ----------- Fixed typo in instructor links for problem. Modified Files: -------------- webwork-modperl/lib/WeBWorK: ContentGenerator.pm Revision Data ------------- Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.155 retrieving revision 1.156 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.155 -r1.156 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -652,7 +652,7 @@ if (defined $problemID) { print CGI::start_ul(); - print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$setID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args)); + print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args)); print CGI::end_ul(); } |
From: Mike G. v. a. <we...@ma...> - 2005-12-03 21:21:17
|
Log Message: ----------- Modifying messages given when editing set detail. Also changed the way blank problems are handled in editor. You can save as or save a copy as Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator: Instructor.pm webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: PGProblemEditor.pm ProblemSetDetail.pm Revision Data ------------- Index: Instructor.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor.pm,v retrieving revision 1.51 retrieving revision 1.52 diff -Llib/WeBWorK/ContentGenerator/Instructor.pm -Llib/WeBWorK/ContentGenerator/Instructor.pm -u -r1.51 -r1.52 --- lib/WeBWorK/ContentGenerator/Instructor.pm +++ lib/WeBWorK/ContentGenerator/Instructor.pm @@ -547,15 +547,15 @@ my $message; if ($count == 0) { - $message = CGI::em("no users"); + $message = CGI::em("no students"); } elsif ($count == $numUsers) { - $message = "all users"; + $message = "all students"; } elsif ($count == 1) { - $message = "1 user"; + $message = "1 student"; } elsif ($count > $numUsers || $count < 0) { $message = CGI::em("an impossible number of users: $count out of $numUsers"); } else { - $message = "$count users"; + $message = "$count students out of $numUsers"; } return $message; Index: PGProblemEditor.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v retrieving revision 1.63 retrieving revision 1.64 diff -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -Llib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm -u -r1.63 -r1.64 --- lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm +++ lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm @@ -113,7 +113,7 @@ # save_to_new_file # -use constant ACTION_FORMS => [qw(view add_problem make_local_copy save save_as revert)]; #[qw(view save save_as revert add_problem add_header make_local_copy)]; +use constant ACTION_FORMS => [qw(view add_problem make_local_copy save save_as revert)]; #[qw(view save save_as revert add_problem add_header make_local_copy)]; # permissions needed to perform a given action use constant FORM_PERMS => { @@ -122,10 +122,12 @@ make_local_copy => "modify_student_data", save => "modify_student_data", save_as => "modify_student_data", +# rename => "modify_student_data", revert => "modify_student_data", }; - +our $BLANKPROBLEM = 'blankProblem.pg'; +# use constant BLANKPROBLEM => 'blankProblem.pg'; # doesn't work because this constant needs to be used inside a match. sub pre_header_initialize { my ($self) = @_; my $r = $self->r; @@ -351,7 +353,10 @@ $self->addbadmessage("This file '$inputFilePath' is protected! ".CGI::br()."To edit this text you must either 'Make a local copy' of this problem, or use 'Save As' to save it to another file."); } - + if ($inputFilePath =~/$BLANKPROBLEM$/) { + $self->addbadmessage("This file '$inputFilePath' is a blank problem! ".CGI::br()."To edit this text you must + use 'Save As' to save it to another file."); + } } @@ -1142,8 +1147,10 @@ sub save_form { my ($self, $onChange, %actionParams) = @_; my $r => $self->r; - if (-w $self->{editFilePath}) { - return "Save"; + if ($self->{editFilePath} =~ /$BLANKPROBLEM$/ ) { + return ""; #Can't save blank problems without changing names + } elsif (-w $self->{editFilePath}) { + return "Save"; } else { return ""; #"Can't save -- No write permission"; } @@ -1251,7 +1258,14 @@ sub save_as_form { my ($self, $onChange, %actionParams) = @_; - return "Save as [TMPL]/".CGI::textfield(-name=>'action.save_as.target_file', -size=>40, -value=>""),; + my $sourceFilePath = $self->{editFilePath}; + my $templatesPath = $self->r->ce->{courseDirs}->{templates}; + $sourceFilePath =~ s|^$templatesPath/||; # make sure path relative to templates directory + + return "Save ". + CGI::popup_menu(-name=>'action.save_as.saveMode', -values=>['rename','save_a_copy'], + -default=>'rename',-labels=>{rename=>' as ',save_a_copy=>'a copy to'} + ). ": [TMPL]/".CGI::textfield(-name=>'action.save_as.target_file', -size=>40, -value=>$sourceFilePath),; } @@ -1265,13 +1279,13 @@ my $problemSeed = $self->{problemSeed}; my $do_not_save = 0; + my $saveMode = $actionParams->{'action.save_as.saveMode'}->[0] || ''; my $new_file_name = $actionParams->{'action.save_as.target_file'}->[0] || ''; $new_file_name =~ s/^\s*//; #remove initial and final white space $new_file_name =~ s/\s*$//; if ( $new_file_name !~ /\S/) { # need a non-blank file name # setting $self->{failure} stops saving and any redirects $do_not_save = 1; - warn "new file name is $new_file_name"; $self->addbadmessage(CGI::p("Please specify a file to save to.")); last ACTION_CASES; #stop processing } @@ -1309,10 +1323,26 @@ $self->{inputFilePath} = ''; } - unless ($do_not_save ) { - $self->new_saveFileChanges($outputFilePath, \$problemContents); + $self->new_saveFileChanges($outputFilePath, \$problemContents); + my $sourceFilePath = $outputFilePath; + my $templatesPath = $self->r->ce->{courseDirs}->{templates}; + $sourceFilePath =~ s|^$templatesPath/||; # make sure path relative to templates directory + + if ($saveMode eq 'rename') { #save to new file + my $problemRecord = $self->r->db->getGlobalProblem($setName,$problemNumber); + $problemRecord->source_file($new_file_name); + if ( $self->r->db->putGlobalProblem($problemRecord) ) { + $self->addgoodmessage("The current source file for problem $problemNumber has been renamed to [TMPL]/$sourceFilePath.") ; + } else { + $self->addbadmessage("Unable to change the source file path for set $setName, problem $problemNumber. Unknown error."); + } + } elsif ($saveMode eq 'save_a_copy') { + $self->addgoodmessage("A new local, editable, copy of this problem has been created at [TMPL]/$sourceFilePath.") ; + } else { + $self->addbadmessage("Don't recognize saveMode: |$saveMode|. Unknown error."); + } } my $edit_level = $self->r->param("edit_level") || 0; $edit_level++; @@ -1321,9 +1351,19 @@ # Set up redirect # The redirect gives the server time to detect that the new file exists. ################################################# - my $problemPage = $self->r->urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", - courseID => $courseName, setID => 'Undefined_Set', problemID => 'Undefined_Set' - ); + my $problemPage; + if ($saveMode eq 'save_a_copy' ) { + $problemPage = $self->r->urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", + courseID => $courseName, setID => 'Undefined_Set', problemID => 'Undefined_Set' + ); + } elsif ($saveMode eq 'rename') { + $problemPage = $self->r->urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", + courseID => $courseName, setID => $setName, problemID => $problemNumber + ); + + } else { + $self->addbadmessage("Don't recognize saveMode: |$saveMode|. Unknown error."); + } my $viewURL = $self->systemLink($problemPage, params=>{ sourceFilePath => $outputFilePath, #The path relative to the templates directory is required. @@ -1465,7 +1505,25 @@ $self->reply_with_redirect($viewURL); } +sub rename_form { + my ($self, $onChange, %actionParams) = @_; + my $problemPath = $self->{editFilePath}; + my $templatesDir = $self->r->ce->{courseDirs}->{templates}; + #warn "problemPath $problemPath $templatesDir"; + $problemPath =~ s|^$templatesDir/||; + return join("", + "Rename problem file to : [TMPL]/".CGI::textfield(-name=>'action.rename.target_file', -size=>40, -value=>$problemPath), + CGI::hidden(-name=>'action.make_local_copy.source_file', -value=>$self->{editFilePath} ), + ); + +} + +sub rename_handler { + my ($self, $genericParams, $actionParams, $tableParams) = @_; + $actionParams->{'action.make_local_copy.target_file'}->[0] = $actionParams->{'action.rename.target_file'}->[0]; + make_local_copy_handler($self, $genericParams, $actionParams, $tableParams); +} 1; Index: ProblemSetDetail.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm,v retrieving revision 1.25 retrieving revision 1.26 diff -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -u -r1.25 -r1.26 --- lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -67,6 +67,9 @@ # 1 => "Yes", # 0 => "No", # }, + +use constant BLANKPROBLEM => 'blankProblem.pg'; + use constant FIELD_PROPERTIES => { # Set information set_header => { @@ -807,18 +810,28 @@ ##################################################################### if (defined($r->param("add_blank_problem") ) and $r->param("add_blank_problem") == 1) { my $targetProblemNumber = 1+ WeBWorK::Utils::max( $self->r->db->listGlobalProblems($setID)); + ################################################## + # make local copy of the blankProblem + ################################################## my $blank_file_path = $ce->{webworkFiles}->{screenSnippets}->{blankProblem}; - my $new_file_path = $ce->{courseDirs}->{templates}."/set$setID/blank.pg"; + my $problemContents = WeBWorK::Utils::readFile($blank_file_path); + my $new_file_path = "set$setID/".BLANKPROBLEM(); + my $fullPath = WeBWorK::Utils::surePathToFile($ce->{courseDirs}->{templates},'/'.$new_file_path); + local(*TEMPFILE); + open(TEMPFILE, ">$fullPath") or warn "Can't write to file $fullPath"; + print TEMPFILE $problemContents; + close(TEMPFILE); + ################################################# # Update problem record ################################################# my $problemRecord = $self->addProblemToSet( setName => $setID, - sourceFile => $blank_file_path, + sourceFile => $new_file_path, problemID => $targetProblemNumber, #added to end of set ); $self->assignProblemToAllSetUsers($problemRecord); - $self->addgoodmessage("Added $blank_file_path to ". $setID. " as problem $targetProblemNumber") ; + $self->addgoodmessage("Added $new_file_path to ". $setID. " as problem $targetProblemNumber") ; } # Sets the specified header to "" so that the default file will get used. @@ -966,7 +979,7 @@ unshift @unassignedUsers, $ID; } } - @editForUser = @assignedUsers; + @editForUser = sort @assignedUsers; $r->param("editForUser", \@editForUser); if (scalar @editForUser && scalar @unassignedUsers) { @@ -987,7 +1000,7 @@ my $userToShow = $forUsers ? $editForUser[0] : $userID; my $userCount = $db->listUsers(); - my $setCount = $db->listGlobalSets() if $forOneUser; + my $setCount = $db->listGlobalSets(); # if $forOneUser; my $setUserCount = $db->countSetUsers($setID); my $userSetCount = $db->countUserSets($editForUser[0]) if $forOneUser; @@ -1013,12 +1026,43 @@ $setCountMessage = "The user $editForUser[0] has been assigned " . $setCountMessage . "." if $forOneUser; if ($forUsers) { - print CGI::p("$userCountMessage Editing user-specific overrides for ". CGI::b(join ", ", @editForUser)); - if ($forOneUser) { - print CGI::p($setCountMessage); - } + ############################################## + # calculate links for the users being edited: + ############################################## + my @userLinks = (); + foreach my $userID (@editForUser) { + my $u = $db->getUser($userID); + my $line = $u->last_name.", ".$u->first_name." ".$u->user_id." "; + my $editSetsAssignedToUserURL = $self->systemLink( + $urlpath->newFromModule( + "WeBWorK::ContentGenerator::Instructor::SetsAssignedToUser", + courseID => $courseID, userID => $u->user_id)); + $line .= CGI::a({href=>$editSetsAssignedToUserURL}, + $self->setCountMessage($db->countUserSets($u->user_id), $setCount)); + unshift @userLinks,$line; + } + @userLinks = sort @userLinks; + + print CGI::table({border=>2,cellpadding=>10}, + CGI::Tr( + CGI::td([ + "Editing problem set ".CGI::strong($setID)." data for these individual students:".CGI::br(). + CGI::strong(join CGI::br(), @userLinks), + CGI::a({href=>$setDetailURL },"Edit set ".CGI::strong($setID)." data for ALL students assigned to this set."), + + ]) + ) + ); } else { - print CGI::p($userCountMessage); + print CGI::table({border=>2,cellpadding=>10}, + CGI::Tr( + CGI::td([ + "This set ".CGI::strong($setID)." is assigned to ".$self->userCountMessage($setUserCount, $userCount).'.' , + 'Edit '.CGI::a({href=>$editUsersAssignedToSetURL},'individual versions '). "of set $setID.", + + ]) + ) + ); } # handle renumbering of problems if necessary @@ -1319,15 +1363,14 @@ CGI::br(); print CGI::input({type=>"submit", name=>"submit_changes", value=>"Save Changes"}); print CGI::input({type=>"submit", name=>"handle_numbers", value=>"Reorder problems only"}) . "(Any unsaved changes will be lost.)"; - print CGI::p(<<HERE); + print CGI::p(<<EOF); Any time problem numbers are intentionally changed, the problems will always be renumbered consecutively, starting from one. When deleting problems, gaps will be left in the numbering unless the box above is checked. -HERE - print CGI::p("It is before the open date. You probably want to renumber the problems if you are deleting some from the middle.") if ($setRecord->open_date>time()); - print CGI::p("When changing problem numbers, we will move - the problem to be ", CGI::em("before"), " the chosen number."); +EOF + print CGI::p("It is before the open date. You probably want to renumber the problems if you are deleting some from the middle.") if ($setRecord->open_date>time()); + print CGI::p("When changing problem numbers, we will move the problem to be ", CGI::em("before"), " the chosen number."); } else { print CGI::p(CGI::b("This set doesn't contain any problems yet.")); @@ -1336,7 +1379,7 @@ my $editNewProblemPage = $urlpath->new(type => 'instructor_problem_editor_withset_withproblem', args => { courseID => $courseID, setID => $setID, problemID =>'new_problem' }); my $editNewProblemLink = $self->systemLink($editNewProblemPage, params => { make_local_copy => 1, file_type => 'blank_problem' }); - print CGI::p( CGI::a({href=>$editNewProblemLink},'Edit'). 'a new blank problem'); + print CGI::p( CGI::a({href=>$editNewProblemLink},'Edit'). ' a new blank problem'); print CGI::end_form(); |
From: Sam H. v. a. <we...@ma...> - 2005-12-02 23:37:46
|
Log Message: ----------- 1-liner adding course hiding support. place a file named "hidden_directory" in a course directory and it will not show up in the courses list on the WeBWorK home page. it will still appear in the CourseAdmin module. The file can be added/removed via UNIX access or by using the FileManager module. Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator: Home.pm Revision Data ------------- Index: Home.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Home.pm,v retrieving revision 1.10 retrieving revision 1.11 diff -Llib/WeBWorK/ContentGenerator/Home.pm -Llib/WeBWorK/ContentGenerator/Home.pm -u -r1.10 -r1.11 --- lib/WeBWorK/ContentGenerator/Home.pm +++ lib/WeBWorK/ContentGenerator/Home.pm @@ -94,6 +94,7 @@ foreach my $courseID (sort {lc($a) cmp lc($b) } @courseIDs) { next if $courseID eq "admin"; # done already above + next if -f "$coursesDir/$courseID/hide_directory"; my $urlpath = $r->urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets", courseID => $courseID); print CGI::li(CGI::a({href=>$self->systemLink($urlpath, authen => 0)}, $courseID)); } |
From: Mike G. v. a. <we...@ma...> - 2005-12-02 18:40:21
|
Log Message: ----------- This fixes bug #919 -- the "update user-sets" line remained commented out. I'm amazed this bug lasted as long as it did before it caused trouble. -- Mike Modified Files: -------------- webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor: ProblemSetDetail.pm Revision Data ------------- Index: ProblemSetDetail.pm =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm,v retrieving revision 1.24 retrieving revision 1.25 diff -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -Llib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm -u -r1.24 -r1.25 --- lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -817,12 +817,8 @@ sourceFile => $blank_file_path, problemID => $targetProblemNumber, #added to end of set ); - #$self->assignProblemToAllSetUsers($problemRecord); + $self->assignProblemToAllSetUsers($problemRecord); $self->addgoodmessage("Added $blank_file_path to ". $setID. " as problem $targetProblemNumber") ; - #warn "A new blank problem has been added at number $targetProblemNumber with source $blank_file_path and record is $problemRecord" ; - #FIXME -- for reasons I don't understand the sourceFile reference is not accepted. - # furthermore, while the new problem appears in the listing for problem set details, it doesn't appear in the "hmwk set editor" (ProblemSetEditor.pm) - # this snippet was copied from PGProblemSetEditor.pm line 1038 where it appears to work. What's up?? } # Sets the specified header to "" so that the default file will get used. |
From: Sam H. v. a. <we...@ma...> - 2005-12-01 20:38:18
|
Log Message: ----------- Modified Files: -------------- CVSROOT: config Revision Data ------------- Index: config =================================================================== RCS file: /webwork/cvs/system/CVSROOT/config,v retrieving revision 1.5 retrieving revision 1.6 diff -Lconfig -Lconfig -u -r1.5 -r1.6 --- config +++ config @@ -2,7 +2,7 @@ #SystemAuth=no # Put CVS lock files in this directory rather than directly in the repository. -LockDir=/var/lock/cvs/system +LockDir=/var/lock/cvs # Set `TopLevelAdmin' to `yes' to create a CVS directory at the top # level of the new working directory when using the `cvs checkout' |