| 1 | ################################################################################ |
1 | ################################################################################ |
| 2 | # WeBWorK Online Homework Delivery System |
2 | # WeBWorK Online Homework Delivery System |
| 3 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
3 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 | # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.19 2004/06/07 02:50:52 jj Exp $ |
4 | # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.20 2004/06/09 02:51:57 jj Exp $ |
| 5 | # |
5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify it under |
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 |
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 |
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. |
9 | # version, or (b) the "Artistic License" which comes with this package. |
| … | |
… | |
| 35 | require WeBWorK::Utils::ListingDB; |
35 | require WeBWorK::Utils::ListingDB; |
| 36 | |
36 | |
| 37 | use constant MAX_SHOW_DEFAULT => 20; |
37 | use constant MAX_SHOW_DEFAULT => 20; |
| 38 | use constant NO_LOCAL_SET_STRING => 'There are no local sets yet'; |
38 | use constant NO_LOCAL_SET_STRING => 'There are no local sets yet'; |
| 39 | use constant SELECT_SET_STRING => 'Select a Set for This Course'; |
39 | use constant SELECT_SET_STRING => 'Select a Set for This Course'; |
| 40 | use constant SELECT_LOCAL_STRING => 'Select a Local Problem Collection'; |
40 | use constant SELECT_LOCAL_STRING => 'Select a Problem Collection'; |
|
|
41 | use constant MY_PROBLEMS => ' My Problems '; |
|
|
42 | use constant MAIN_PROBLEMS => ' Main Problems '; |
| 41 | |
43 | |
| 42 | ## Flags for operations on files |
44 | ## Flags for operations on files |
| 43 | |
45 | |
| 44 | use constant ADDED => 1; |
46 | use constant ADDED => 1; |
| 45 | use constant HIDDEN => (1 << 1); |
47 | use constant HIDDEN => (1 << 1); |
| 46 | use constant SUCCESS => (1 << 2); |
48 | use constant SUCCESS => (1 << 2); |
|
|
49 | |
|
|
50 | ## for additional problib buttons |
|
|
51 | my %problib; ## filled in in global.conf |
|
|
52 | my %ignoredir = ('.' => 1, '..' => 1, 'Library' => 1); |
| 47 | |
53 | |
| 48 | ## This is for searching the disk for directories containing pg files. |
54 | ## This is for searching the disk for directories containing pg files. |
| 49 | ## to make the recursion work, this returns an array where the first |
55 | ## to make the recursion work, this returns an array where the first |
| 50 | ## item is 1 or 0 depending on whether or not the current |
56 | ## item is 1 or 0 depending on whether or not the current |
| 51 | ## directory has any pg files. The second is a list of directories |
57 | ## directory has any pg files. The second is a list of directories |
| 52 | ## which contain pg files. |
58 | ## which contain pg files. |
| 53 | sub get_library_sets { |
59 | sub get_library_sets { |
| 54 | my $amtop = shift; |
60 | my $amtop = shift; |
| 55 | my $topdir = shift; |
61 | my $topdir = shift; |
| 56 | my @lis = readDirectory($topdir); |
62 | my @lis = readDirectory($topdir); |
| 57 | my @pgs = grep { m/\.pg$/ and (not m/Header\.pg/) and -f "$topdir/$_"} @lis; |
63 | my @pgs = grep { m/\.pg$/ and (not m/(Header|-text)\.pg/) and -f "$topdir/$_"} @lis; |
| 58 | my $havepg = scalar(@pgs)>0 ? 1 : 0; |
64 | my $havepg = scalar(@pgs)>0 ? 1 : 0; |
| 59 | my @mdirs = grep {$_ ne "." and $_ ne ".." and $_ ne "Library" |
65 | my @mdirs = grep {!defined($ignoredir{$_}) and -d "$topdir/$_"} @lis; |
| 60 | and -d "$topdir/$_"} @lis; |
66 | if ($amtop) {@mdirs = grep {!defined($problib{$_})} @mdirs} |
| 61 | if($amtop) { # we don't want the library |
|
|
| 62 | @mdirs = grep {$_ ne "Library"} @mdirs; |
|
|
| 63 | } |
|
|
| 64 | my ($adir, @results, @thisresult); |
67 | my ($adir, @results, @thisresult); |
| 65 | for $adir (@mdirs) { |
68 | for $adir (@mdirs) { |
| 66 | @results = get_library_sets(0, "$topdir/$adir"); |
69 | @results = get_library_sets(0, "$topdir/$adir"); |
| 67 | my $isadirok = shift @results; |
70 | my $isadirok = shift @results; |
| 68 | @thisresult = (@thisresult, @results); |
71 | @thisresult = (@thisresult, @results); |
| … | |
… | |
| 77 | sub list_pg_files { |
80 | sub list_pg_files { |
| 78 | my $templatedir = shift; |
81 | my $templatedir = shift; |
| 79 | my $topdir = shift; |
82 | my $topdir = shift; |
| 80 | |
83 | |
| 81 | my @lis = readDirectory("$templatedir/$topdir"); |
84 | my @lis = readDirectory("$templatedir/$topdir"); |
| 82 | my @pgs = grep { m/\.pg$/ and (not m/Header\.pg/) and -f "$templatedir/$topdir/$_"} @lis; |
85 | my @pgs = grep { m/\.pg$/ and (not m/(Header|-text)\.pg/) and -f "$templatedir/$topdir/$_"} @lis; |
| 83 | @pgs = map { "$topdir/$_" } @pgs; |
86 | @pgs = map { "$topdir/$_" } @pgs; |
| 84 | return(@pgs); |
87 | return(@pgs); |
| 85 | } |
88 | } |
| 86 | |
89 | |
| 87 | ## go through past page getting a list of identifiers for the problems |
90 | ## go through past page getting a list of identifiers for the problems |
| … | |
… | |
| 131 | |
134 | |
| 132 | ############# List of sets of problems in templates directory |
135 | ############# List of sets of problems in templates directory |
| 133 | |
136 | |
| 134 | sub get_problem_directories { |
137 | sub get_problem_directories { |
| 135 | my $ce = shift; |
138 | my $ce = shift; |
|
|
139 | my $lib = shift; |
|
|
140 | my $source = $ce->{courseDirs}{templates}; |
|
|
141 | my $main = MY_PROBLEMS; my $isTop = 1; |
|
|
142 | if ($lib) {$source .= "/$lib"; $main = MAIN_PROBLEMS; $isTop = 0} |
| 136 | my @all_problem_directories = get_library_sets(1, $ce->{courseDirs}->{templates}); |
143 | my @all_problem_directories = get_library_sets($isTop, $source); |
| 137 | my $includetop = shift @all_problem_directories; |
144 | my $includetop = shift @all_problem_directories; |
| 138 | my $j; |
145 | my $j; |
| 139 | for ($j=0; $j<scalar(@all_problem_directories); $j++) { |
146 | for ($j=0; $j<scalar(@all_problem_directories); $j++) { |
| 140 | $all_problem_directories[$j] =~ s|^$ce->{courseDirs}->{templates}/?||; |
147 | $all_problem_directories[$j] =~ s|^$ce->{courseDirs}->{templates}/?||; |
| 141 | } |
148 | } |
| 142 | @all_problem_directories = sort @all_problem_directories; |
149 | @all_problem_directories = sort @all_problem_directories; |
| 143 | unshift @all_problem_directories, ' My Problems ' if($includetop); |
150 | unshift @all_problem_directories, $main if($includetop); |
| 144 | return (\@all_problem_directories); |
151 | return (\@all_problem_directories); |
| 145 | } |
152 | } |
| 146 | |
153 | |
| 147 | ############# Everyone has a view problems line. Abstract it |
154 | ############# Everyone has a view problems line. Abstract it |
| 148 | sub view_problems_line { |
155 | sub view_problems_line { |
| … | |
… | |
| 175 | ### The browsing panel has three versions |
182 | ### The browsing panel has three versions |
| 176 | ##### Version 1 is local problems |
183 | ##### Version 1 is local problems |
| 177 | sub browse_local_panel { |
184 | sub browse_local_panel { |
| 178 | my $self = shift; |
185 | my $self = shift; |
| 179 | my $library_selected = shift; |
186 | my $library_selected = shift; |
|
|
187 | my $lib = shift || ''; $lib =~ s/^browse_//; |
|
|
188 | my $name = ($lib eq '')? 'Local' : $problib{$lib}; |
| 180 | |
189 | |
| 181 | my $list_of_prob_dirs= get_problem_directories($self->r->ce); |
190 | my $list_of_prob_dirs= get_problem_directories($self->r->ce,$lib); |
| 182 | if(scalar(@$list_of_prob_dirs) == 0) { |
191 | if(scalar(@$list_of_prob_dirs) == 0) { |
| 183 | $library_selected = "Found no directories containing problems"; |
192 | $library_selected = "Found no directories containing problems"; |
| 184 | unshift @{$list_of_prob_dirs}, $library_selected; |
193 | unshift @{$list_of_prob_dirs}, $library_selected; |
| 185 | } else { |
194 | } else { |
| 186 | my $default_value = SELECT_LOCAL_STRING; |
195 | my $default_value = SELECT_LOCAL_STRING; |
| … | |
… | |
| 188 | unshift @{$list_of_prob_dirs}, $default_value; |
197 | unshift @{$list_of_prob_dirs}, $default_value; |
| 189 | $library_selected = $default_value; |
198 | $library_selected = $default_value; |
| 190 | } |
199 | } |
| 191 | } |
200 | } |
| 192 | my $view_problem_line = view_problems_line('view_local_set', 'View Problems', $self->r); |
201 | my $view_problem_line = view_problems_line('view_local_set', 'View Problems', $self->r); |
| 193 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Local Problems: ", |
202 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "$name Problems: ", |
| 194 | CGI::popup_menu(-name=> 'library_sets', |
203 | CGI::popup_menu(-name=> 'library_sets', |
| 195 | -values=>$list_of_prob_dirs, |
204 | -values=>$list_of_prob_dirs, |
| 196 | -default=> $library_selected), |
205 | -default=> $library_selected), |
| 197 | CGI::br(), |
206 | CGI::br(), |
| 198 | $view_problem_line, |
207 | $view_problem_line, |
| … | |
… | |
| 312 | } |
321 | } |
| 313 | |
322 | |
| 314 | sub make_top_row { |
323 | sub make_top_row { |
| 315 | my $self = shift; |
324 | my $self = shift; |
| 316 | my $r = $self->r; |
325 | my $r = $self->r; |
|
|
326 | my $ce = $r->ce; |
| 317 | my %data = @_; |
327 | my %data = @_; |
| 318 | |
328 | |
| 319 | my $list_of_local_sets = $data{all_set_defs}; |
329 | my $list_of_local_sets = $data{all_set_defs}; |
| 320 | my $have_local_sets = scalar(@$list_of_local_sets); |
330 | my $have_local_sets = scalar(@$list_of_local_sets); |
| 321 | my $browse_which = $data{browse_which}; |
331 | my $browse_which = $data{browse_which}; |
| … | |
… | |
| 325 | my ($dis1, $dis2, $dis3) = ("","",""); |
335 | my ($dis1, $dis2, $dis3) = ("","",""); |
| 326 | $dis1 = '-disabled' if($browse_which eq 'browse_library'); |
336 | $dis1 = '-disabled' if($browse_which eq 'browse_library'); |
| 327 | $dis2 = '-disabled' if($browse_which eq 'browse_local'); |
337 | $dis2 = '-disabled' if($browse_which eq 'browse_local'); |
| 328 | $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); |
338 | $dis3 = '-disabled' if($browse_which eq 'browse_mysets'); |
| 329 | |
339 | |
|
|
340 | ## Make buttons for additional problem libraries |
|
|
341 | my $libs = ''; |
|
|
342 | foreach my $lib (sort(keys(%problib))) { |
|
|
343 | $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib}, |
|
|
344 | ($browse_which eq "browse_$lib")? '-disabled': '') |
|
|
345 | if (-d "$ce->{courseDirs}{templates}/$lib"); |
|
|
346 | } |
|
|
347 | $libs = CGI::br()."or Problems from".$libs if $libs ne ''; |
|
|
348 | |
| 330 | my $these_widths = "width: 27ex"; |
349 | my $these_widths = "width: 20ex"; |
| 331 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
350 | print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, |
|
|
351 | "Browse ", |
| 332 | CGI::submit(-name=>"browse_library", -value=>"Browse Problem Library", -style=>$these_widths, $dis1), |
352 | CGI::submit(-name=>"browse_library", -value=>"Problem Library", -style=>$these_widths, $dis1), |
| 333 | CGI::submit(-name=>"browse_local", -value=>"Browse Local Problems", -style=>$these_widths, $dis2), |
353 | CGI::submit(-name=>"browse_local", -value=>"Local Problems", -style=>$these_widths, $dis2), |
| 334 | CGI::submit(-name=>"browse_mysets", -value=>"Browse From This Course", -style=>$these_widths, $dis3), |
354 | CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, $dis3), |
|
|
355 | $libs, |
| 335 | )); |
356 | )); |
| 336 | |
357 | |
| 337 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
358 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
| 338 | |
359 | |
| 339 | if ($browse_which eq 'browse_local') { |
360 | if ($browse_which eq 'browse_local') { |
| 340 | $self->browse_local_panel($library_selected); |
361 | $self->browse_local_panel($library_selected); |
| 341 | } elsif ($browse_which eq 'browse_mysets') { |
362 | } elsif ($browse_which eq 'browse_mysets') { |
| 342 | $self->browse_mysets_panel($library_selected, $list_of_local_sets); |
363 | $self->browse_mysets_panel($library_selected, $list_of_local_sets); |
| 343 | } else { |
364 | } elsif ($browse_which eq 'browse_library') { |
| 344 | $self->browse_library_panel(); |
365 | $self->browse_library_panel(); |
|
|
366 | } else { ## handle other problem libraries |
|
|
367 | $self->browse_local_panel($library_selected,$browse_which); |
| 345 | } |
368 | } |
| 346 | |
369 | |
| 347 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
370 | print CGI::Tr(CGI::td({-bgcolor=>"black"})); |
| 348 | |
371 | |
| 349 | if($have_local_sets ==0) { |
372 | if($have_local_sets ==0) { |
| … | |
… | |
| 468 | my $ce = $r->ce; |
491 | my $ce = $r->ce; |
| 469 | my $db = $r->db; |
492 | my $db = $r->db; |
| 470 | my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
493 | my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; |
| 471 | $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more |
494 | $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more |
| 472 | |
495 | |
|
|
496 | ## These directories will have individual buttons |
|
|
497 | %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs}; |
| 473 | |
498 | |
| 474 | my $userName = $r->param('user'); |
499 | my $userName = $r->param('user'); |
| 475 | my $user = $db->getUser($userName); # checked |
500 | my $user = $db->getUser($userName); # checked |
| 476 | die "record for user $userName (real user) does not exist." |
501 | die "record for user $userName (real user) does not exist." |
| 477 | unless defined $user; |
502 | unless defined $user; |
| … | |
… | |
| 523 | my $browse_which = $r->param('browse_which') || 'browse_local'; |
548 | my $browse_which = $r->param('browse_which') || 'browse_local'; |
| 524 | |
549 | |
| 525 | my $problem_seed = $r->param('problem_seed') || 0; |
550 | my $problem_seed = $r->param('problem_seed') || 0; |
| 526 | $r->param('problem_seed', $problem_seed); # if it wasn't defined before |
551 | $r->param('problem_seed', $problem_seed); # if it wasn't defined before |
| 527 | |
552 | |
|
|
553 | ## check for problem lib buttons |
|
|
554 | my $browse_lib = ''; |
|
|
555 | foreach my $lib (keys %problib) { |
|
|
556 | if ($r->param("browse_$lib")) { |
|
|
557 | $browse_lib = "browse_$lib"; |
|
|
558 | last; |
|
|
559 | } |
|
|
560 | } |
|
|
561 | |
| 528 | ########### Start the logic through if elsif elsif ... |
562 | ########### Start the logic through if elsif elsif ... |
| 529 | |
563 | |
| 530 | ##### Asked to browse certain problems |
564 | ##### Asked to browse certain problems |
|
|
565 | if ($browse_lib ne '') { |
|
|
566 | $browse_which = $browse_lib; |
|
|
567 | $r->param('library_sets', ""); |
|
|
568 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 531 | if ($r->param('browse_library')) { |
569 | } elsif ($r->param('browse_library')) { |
| 532 | $browse_which = 'browse_library'; |
570 | $browse_which = 'browse_library'; |
| 533 | $r->param('library_sets', ""); |
571 | $r->param('library_sets', ""); |
|
|
572 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 534 | } elsif ($r->param('browse_local')) { |
573 | } elsif ($r->param('browse_local')) { |
| 535 | $browse_which = 'browse_local'; |
574 | $browse_which = 'browse_local'; |
| 536 | $r->param('library_sets', ""); |
575 | $r->param('library_sets', ""); |
|
|
576 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 537 | } elsif ($r->param('browse_mysets')) { |
577 | } elsif ($r->param('browse_mysets')) { |
| 538 | $browse_which = 'browse_mysets'; |
578 | $browse_which = 'browse_mysets'; |
| 539 | $r->param('library_sets', ""); |
579 | $r->param('library_sets', ""); |
|
|
580 | $use_previous_problems = 0; @pg_files = (); ## clear old problems |
| 540 | |
581 | |
| 541 | ##### Change the seed value |
582 | ##### Change the seed value |
| 542 | |
583 | |
| 543 | } elsif ($r->param('rerandomize')) { |
584 | } elsif ($r->param('rerandomize')) { |
| 544 | $problem_seed++; |
585 | $problem_seed++; |
| … | |
… | |
| 558 | |
599 | |
| 559 | my $set_to_display = $r->param('library_sets'); |
600 | my $set_to_display = $r->param('library_sets'); |
| 560 | if (not defined($set_to_display) or $set_to_display eq SELECT_LOCAL_STRING or $set_to_display eq "Found no directories containing problems") { |
601 | if (not defined($set_to_display) or $set_to_display eq SELECT_LOCAL_STRING or $set_to_display eq "Found no directories containing problems") { |
| 561 | $self->addbadmessage('You need to select a set to view.'); |
602 | $self->addbadmessage('You need to select a set to view.'); |
| 562 | } else { |
603 | } else { |
| 563 | $set_to_display = '.' if $set_to_display eq ' My Problems '; |
604 | $set_to_display = '.' if $set_to_display eq MY_PROBLEMS; |
|
|
605 | $set_to_display = substr($browse_which,7) if $set_to_display eq MAIN_PROBLEMS; |
| 564 | @pg_files = list_pg_files($ce->{courseDirs}->{templates}, |
606 | @pg_files = list_pg_files($ce->{courseDirs}->{templates}, |
| 565 | "$set_to_display"); |
607 | "$set_to_display"); |
| 566 | $use_previous_problems=0; |
608 | $use_previous_problems=0; |
| 567 | } |
609 | } |
| 568 | |
610 | |