[system] / branches / rel-2-1-a1 / webwork-modperl / lib / WeBWorK / ContentGenerator / Instructor.pm Repository:
ViewVC logotype

Annotation of /branches/rel-2-1-a1/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2289 - (view) (download) (as text)
Original Path: trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor.pm

1 : sh002i 1661 ################################################################################
2 : sh002i 1663 # WeBWorK Online Homework Delivery System
3 :     # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4 : toenail 2289 # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor.pm,v 1.40 2004/06/09 02:51:30 jj Exp $
5 : sh002i 1663 #
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 : sh002i 1661
17 : malsyned 805 package WeBWorK::ContentGenerator::Instructor;
18 : sh002i 818 use base qw(WeBWorK::ContentGenerator);
19 : malsyned 805
20 :     =head1 NAME
21 :    
22 : sh002i 1734 WeBWorK::ContentGenerator::Instructor - Abstract superclass for the Instructor
23 :     tools, providing useful utility functions.
24 : malsyned 805
25 :     =cut
26 :    
27 :     use strict;
28 :     use warnings;
29 :     use CGI qw();
30 : sh002i 1913 use WeBWorK::DB::Utils qw(initializeUserProblem);
31 : malsyned 805
32 : sh002i 1734 =head1 METHODS
33 : malsyned 1005
34 : sh002i 1734 =cut
35 :    
36 :     ################################################################################
37 :     # Primary assignment methods
38 :     ################################################################################
39 :    
40 :     =head2 Primary assignment methods
41 :    
42 :     =over
43 :    
44 :     =item assignSetToUser($userID, $GlobalSet)
45 :    
46 : sh002i 1839 Assigns the given set and all problems contained therein to the given user. If
47 :     the set (or any problems in the set) are already assigned to the user, a list of
48 :     failure messages is returned.
49 : sh002i 1734
50 :     =cut
51 :    
52 :     sub assignSetToUser {
53 :     my ($self, $userID, $GlobalSet) = @_;
54 :     my $setID = $GlobalSet->set_id;
55 :     my $db = $self->{db};
56 : malsyned 1005
57 : sh002i 1734 my $UserSet = $db->newUserSet;
58 :     $UserSet->user_id($userID);
59 :     $UserSet->set_id($setID);
60 :    
61 : sh002i 1839 my @results;
62 :     my $set_assigned = 0;
63 :    
64 : sh002i 1734 eval { $db->addUserSet($UserSet) };
65 :     if ($@) {
66 : sh002i 1839 if ($@ =~ m/user set exists/) {
67 :     push @results, "set $setID is already assigned to user $userID.";
68 :     $set_assigned = 1;
69 :     } else {
70 :     die $@;
71 :     }
72 : malsyned 1005 }
73 :    
74 : sh002i 1734 my @GlobalProblems = grep { defined $_ } $db->getAllGlobalProblems($setID);
75 :     foreach my $GlobalProblem (@GlobalProblems) {
76 : sh002i 1839 my @result = $self->assignProblemToUser($userID, $GlobalProblem);
77 :     push @results, @result if @result and not $set_assigned;
78 : sh002i 1734 }
79 : sh002i 1839
80 :     return @results;
81 : malsyned 1005 }
82 :    
83 : sh002i 1734 =item unassignSetFromUser($userID, $setID, $problemID)
84 : malsyned 1015
85 : sh002i 1734 Unassigns the given set and all problems therein from the given user.
86 :    
87 :     =cut
88 :    
89 :     sub unassignSetFromUser {
90 :     my ($self, $userID, $setID) = @_;
91 : malsyned 1013 my $db = $self->{db};
92 :    
93 : sh002i 1734 $db->deleteUserSet($userID, $setID);
94 : malsyned 1013 }
95 : malsyned 1005
96 : sh002i 1734 =item assignProblemToUser($userID, $GlobalProblem)
97 :    
98 : sh002i 1839 Assigns the given problem to the given user. If the problem is already assigned
99 :     to the user, an error string is returned.
100 : sh002i 1734
101 :     =cut
102 :    
103 :     sub assignProblemToUser {
104 :     my ($self, $userID, $GlobalProblem) = @_;
105 : malsyned 1013 my $db = $self->{db};
106 :    
107 : sh002i 1734 my $UserProblem = $db->newUserProblem;
108 :     $UserProblem->user_id($userID);
109 :     $UserProblem->set_id($GlobalProblem->set_id);
110 :     $UserProblem->problem_id($GlobalProblem->problem_id);
111 :     initializeUserProblem($UserProblem);
112 :    
113 :     eval { $db->addUserProblem($UserProblem) };
114 :     if ($@) {
115 : sh002i 1839 if ($@ =~ m/user problem exists/) {
116 :     return "problem " . $GlobalProblem->problem_id
117 :     . " in set " . $GlobalProblem->set_id
118 :     . " is already assigned to user $userID.";
119 :     } else {
120 :     die $@;
121 :     }
122 : malsyned 1013 }
123 : sh002i 1839
124 :     return ();
125 : malsyned 1013 }
126 :    
127 : sh002i 1734 =item unassignProblemFromUser($userID, $setID, $problemID)
128 :    
129 :     Unassigns the given problem from the given user.
130 :    
131 :     =cut
132 :    
133 :     sub unassignProblemFromUser {
134 :     my ($self, $userID, $setID, $problemID) = @_;
135 : malsyned 1013 my $db = $self->{db};
136 :    
137 : sh002i 1734 $db->deleteUserProblem($userID, $setID, $problemID);
138 : malsyned 1013 }
139 :    
140 : sh002i 1734 =back
141 :    
142 :     =cut
143 :    
144 :     ################################################################################
145 :     # Secondary set assignment methods
146 :     ################################################################################
147 :    
148 :     =head2 Secondary assignment methods
149 :    
150 :     =over
151 :    
152 :     =item assignSetToAllUsers($setID)
153 :    
154 :     Assigns the set specified and all problems contained therein to all users in
155 :     the course. This is more efficient than repeatedly calling assignSetToUser().
156 : sh002i 1839 If any assignments fail, a list of failure messages is returned.
157 : sh002i 1734
158 :     =cut
159 :    
160 : malsyned 1015 sub assignSetToAllUsers {
161 :     my ($self, $setID) = @_;
162 :     my $db = $self->{db};
163 : toenail 2108 my @userIDs = $db->listUsers;
164 :    
165 :     $WeBWorK::timer->continue("$setID: getting user list") if defined $WeBWorK::timer;
166 :     my @userRecords = $db->getUsers(@userIDs);
167 :     $WeBWorK::timer->continue("$setID: (done with that)") if defined $WeBWorK::timer;
168 : malsyned 1015
169 : sh002i 1790 $WeBWorK::timer->continue("$setID: getting problem list") if defined $WeBWorK::timer;
170 : sh002i 1734 my @GlobalProblems = grep { defined $_ } $db->getAllGlobalProblems($setID);
171 : sh002i 1790 $WeBWorK::timer->continue("$setID: (done with that)") if defined $WeBWorK::timer;
172 : sh002i 1734
173 : sh002i 1839 my @results;
174 :    
175 : toenail 2108 foreach my $User (@userRecords) {
176 :     next if grep /$User->{status}/, @{$self->{r}->{ce}->{siteDefaults}->{statusDrop}};
177 : sh002i 1734 my $UserSet = $db->newUserSet;
178 : toenail 2108 my $userID = $User->user_id;
179 : sh002i 1734 $UserSet->user_id($userID);
180 :     $UserSet->set_id($setID);
181 : sh002i 1790 $WeBWorK::timer->continue("$setID: adding UserSet for $userID") if defined $WeBWorK::timer;
182 : sh002i 1734 eval { $db->addUserSet($UserSet) };
183 :     if ($@) {
184 :     next if $@ =~ m/user set exists/;
185 :     die $@;
186 : malsyned 1015 }
187 : sh002i 1790 $WeBWorK::timer->continue("$setID: (done with that)") if defined $WeBWorK::timer;
188 :    
189 :     $WeBWorK::timer->continue("$setID: adding UserProblems for $userID") if defined $WeBWorK::timer;
190 : sh002i 1734 foreach my $GlobalProblem (@GlobalProblems) {
191 : sh002i 1839 my @result = $self->assignProblemToUser($userID, $GlobalProblem);
192 :     push @results, @result if @result;
193 : sh002i 1734 }
194 : sh002i 1790 $WeBWorK::timer->continue("$setID: (done with that)") if defined $WeBWorK::timer;
195 : malsyned 1015 }
196 : sh002i 1839
197 :     return @results;
198 : malsyned 1015 }
199 :    
200 : sh002i 1734 =item unassignSetFromAllUsers($setID)
201 :    
202 :     Unassigns the specified sets and all problems contained therein from all users.
203 :    
204 :     =cut
205 :    
206 :     sub unassignSetFromAllUsers {
207 :     my ($self, $setID) = @_;
208 :     my $db = $self->{db};
209 :    
210 :     my @userIDs = $db->listSetUsers($setID);
211 :    
212 :     foreach my $userID (@userIDs) {
213 :     $self->unassignSetFromUser($userID, $setID);
214 :     }
215 :     }
216 :    
217 :     =item assignAllSetsToUser($userID)
218 :    
219 :     Assigns all sets in the course and all problems contained therein to the
220 :     specified user. This is more efficient than repeatedly calling
221 : sh002i 1839 assignSetToUser(). If any assignments fail, a list of failure messages is
222 :     returned.
223 : sh002i 1734
224 :     =cut
225 :    
226 : sh002i 1642 sub assignAllSetsToUser {
227 :     my ($self, $userID) = @_;
228 :     my $db = $self->{db};
229 :    
230 :     # assign only sets that are not already assigned
231 : sh002i 1734 #my %userSetIDs = map { $_ => 1 } $db->listUserSets($userID);
232 :     #my @globalSetIDs = grep { not exists $userSetIDs{$_} } $db->listGlobalSets;
233 :     #my @GlobalSets = $db->getGlobalSets(@globalSetIDs);
234 :     # FIXME: i don't think we need to do the above, since asignSetToUser fails
235 :     # silently if a UserSet already exists. instead we do this:
236 :     my @globalSetIDs = $db->listGlobalSets;
237 : sh002i 1642 my @GlobalSets = $db->getGlobalSets(@globalSetIDs);
238 :    
239 : sh002i 1839 my @results;
240 :    
241 : sh002i 1642 my $i = 0;
242 :     foreach my $GlobalSet (@GlobalSets) {
243 :     if (not defined $GlobalSet) {
244 :     warn "record not found for global set $globalSetIDs[$i]";
245 :     } else {
246 : sh002i 1839 my @result = $self->assignSetToUser($userID, $GlobalSet);
247 :     push @results, @result if @result;
248 : sh002i 1642 }
249 :     $i++;
250 :     }
251 : sh002i 1839
252 :     return @results;
253 : sh002i 1642 }
254 :    
255 : sh002i 1734 =item unassignAllSetsFromUser($userID)
256 :    
257 :     Unassigns all sets and all problems contained therein from the specified user.
258 :    
259 :     =cut
260 :    
261 : sh002i 1642 sub unassignAllSetsFromUser {
262 :     my ($self, $userID) = @_;
263 :     my $db = $self->{db};
264 :    
265 : sh002i 1734 my @setIDs = $db->listUserSets($userID);
266 : sh002i 1642
267 : sh002i 1734 foreach my $setID (@setIDs) {
268 :     $self->unassignSetFromUser($userID, $setID);
269 : sh002i 1642 }
270 :     }
271 :    
272 : sh002i 1734 =back
273 :    
274 :     =cut
275 :    
276 :     ################################################################################
277 :     # Utility assignment methods
278 :     ################################################################################
279 :    
280 :     =head2 Utility assignment methods
281 :    
282 :     =over
283 :    
284 :     =item assignSetsToUsers($setIDsRef, $userIDsRef)
285 :    
286 : sh002i 1839 Assign each of the given sets to each of the given users. If any assignments
287 :     fail, a list of failure messages is returned.
288 : sh002i 1734
289 :     =cut
290 :    
291 :     sub assignSetsToUsers {
292 :     my ($self, $setIDsRef, $userIDsRef) = @_;
293 :     my $db = $self->{db};
294 :    
295 : sh002i 1742 my @setIDs = @$setIDsRef;
296 :     my @userIDs = @$userIDsRef;
297 : sh002i 1734 my @GlobalSets = $db->getGlobalSets(@setIDs);
298 :    
299 : sh002i 1839 my @results;
300 :    
301 : sh002i 1734 foreach my $GlobalSet (@GlobalSets) {
302 :     foreach my $userID (@userIDs) {
303 : sh002i 1839 my @result = $self->assignSetToUser($userID, $GlobalSet);
304 :     push @results, @result if @result;
305 : sh002i 1734 }
306 :     }
307 : sh002i 1839
308 :     return @results;
309 : sh002i 1734 }
310 :    
311 :     =item unassignSetsFromUsers($setIDsRef, $userIDsRef)
312 :    
313 :     Unassign each of the given sets from each of the given users.
314 :    
315 :     =cut
316 :    
317 :     sub unassignSetsFromUsers {
318 :     my ($self, $setIDsRef, $userIDsRef) = @_;
319 :     my @setIDs = $setIDsRef;
320 :     my @userIDs = $userIDsRef;
321 :    
322 :     foreach my $setID (@setIDs) {
323 :     foreach my $userID (@userIDs) {
324 :     $self->unassignSetFromUser($userID, $setID);
325 :     }
326 :     }
327 :     }
328 :    
329 :     =item assignProblemToAllSetUsers($GlobalProblem)
330 :    
331 :     Assigns the problem specified to all users to whom the problem's set is
332 : sh002i 1839 assigned. If any assignments fail, a list of failure messages is returned.
333 : sh002i 1734
334 :     =cut
335 :    
336 :     sub assignProblemToAllSetUsers {
337 :     my ($self, $GlobalProblem) = @_;
338 :     my $db = $self->{db};
339 :     my $setID = $GlobalProblem->set_id;
340 :     my @userIDs = $db->listSetUsers($setID);
341 :    
342 : sh002i 1839 my @results;
343 :    
344 : sh002i 1734 foreach my $userID (@userIDs) {
345 : sh002i 1839 my @result = $self->assignProblemToUser($userID, $GlobalProblem);
346 :     push @results, @result if @result;
347 : sh002i 1734 }
348 : sh002i 1839
349 :     return @results;
350 : sh002i 1734 }
351 :    
352 :     =back
353 :    
354 :     =cut
355 :    
356 :     ################################################################################
357 : jj 2282 # Utility method for adding problems to a set
358 :     ################################################################################
359 :    
360 :     =head2 Utility method for adding problems to a set
361 :    
362 :     =over
363 :    
364 :     =cut
365 :    
366 :     sub addProblemToSet {
367 : toenail 2289 my ($self, %args) = @_;
368 :     my $db = $self->r->db;
369 :    
370 :     die "addProblemToSet called without specifying the set name." if $args{setName} eq "";
371 :     my $setName = $args{setName};
372 :    
373 :     my $sourceFile = $args{sourceFile} or
374 :     die "addProblemToSet called without specifying the sourceFile.";
375 :    
376 :     # The rest of the arguments are optional
377 :     my $value = $args{value} || 1;
378 :     my $maxAttempts = $args{maxAttempts} || -1;
379 :     my $problemID = $args{problemID};
380 :    
381 :     unless ($problemID) {
382 :     $problemID = WeBWorK::Utils::max($db->listGlobalProblems($setName)) + 1;
383 :     }
384 :    
385 :     my $problemRecord = $db->newGlobalProblem;
386 :     $problemRecord->problem_id($problemID);
387 :     $problemRecord->set_id($setName);
388 :     $problemRecord->source_file($sourceFile);
389 :     $problemRecord->value($value);
390 :     $problemRecord->max_attempts($maxAttempts);
391 :     $db->addGlobalProblem($problemRecord);
392 :    
393 :     return $problemRecord;
394 : jj 2282 }
395 :    
396 :     ################################################################################
397 : sh002i 1734 # Utility methods
398 :     ################################################################################
399 :    
400 :     =head2 Utility methods
401 :    
402 :     =over
403 :    
404 :     =cut
405 :    
406 :     sub hiddenEditForUserFields {
407 :     my ($self, @editForUser) = @_;
408 :     my $return = "";
409 :     foreach my $editUser (@editForUser) {
410 :     $return .= CGI::input({type=>"hidden", name=>"editForUser", value=>$editUser});
411 :     }
412 :    
413 :     return $return;
414 :     }
415 :    
416 :     sub userCountMessage {
417 :     my ($self, $count, $numUsers) = @_;
418 :    
419 :     my $message;
420 :     if ($count == 0) {
421 :     $message = CGI::em("no users");
422 :     } elsif ($count == $numUsers) {
423 :     $message = "all users";
424 :     } elsif ($count == 1) {
425 :     $message = "1 user";
426 :     } elsif ($count > $numUsers || $count < 0) {
427 :     $message = CGI::em("an impossible number of users: $count out of $numUsers");
428 :     } else {
429 :     $message = "$count users";
430 :     }
431 :    
432 :     return $message;
433 :     }
434 :    
435 : gage 1397 sub read_dir { # read a directory
436 :     my $self = shift;
437 :     my $directory = shift;
438 :     my $pattern = shift;
439 :     my @files = grep /$pattern/, WeBWorK::Utils::readDirectory($directory);
440 :     return sort @files;
441 :     }
442 :    
443 :     sub read_scoring_file { # used in SendMail and ....?
444 :     my $self = shift;
445 :     my $fileName = shift;
446 :     my $delimiter = shift;
447 :     $delimiter = ',' unless defined($delimiter);
448 :     my $scoringDirectory= $self->{ce}->{courseDirs}->{scoring};
449 :     my $filePath = "$scoringDirectory/$fileName";
450 :     # Takes a delimited file as a parameter and returns an
451 :     # associative array with the first field as the key.
452 :     # Blank lines are skipped. White space is removed
453 :     my(@dbArray,$key,$dbString);
454 :     my %assocArray = ();
455 :     local(*FILE);
456 :     if ($fileName eq 'None') {
457 :     # do nothing
458 :     } elsif ( open(FILE, "$filePath") ) {
459 :     my $index=0;
460 :     while (<FILE>){
461 :     unless ($_ =~ /\S/) {next;} ## skip blank lines
462 :     chomp;
463 :     @{$dbArray[$index]} =$self->getRecord($_,$delimiter);
464 :     $key =$dbArray[$index][0];
465 :     $assocArray{$key}=$dbArray[$index];
466 :     $index++;
467 :     }
468 :     close(FILE);
469 :     } else {
470 :     warn "Couldn't read file $filePath";
471 :     }
472 :     return \%assocArray;
473 :     }
474 : sh002i 1614
475 : sh002i 1734 =back
476 :    
477 :     =cut
478 :    
479 : sh002i 1614 ################################################################################
480 : sh002i 1734 # Methods for listing various types of files
481 : sh002i 1614 ################################################################################
482 :    
483 : sh002i 1734 =head2 Methods for listing various types of files
484 :    
485 :     =over
486 :    
487 :     =cut
488 :    
489 : sh002i 1614 # list classlist files
490 :     sub getCSVList {
491 :     my ($self) = @_;
492 :     my $ce = $self->{ce};
493 :     my $dir = $ce->{courseDirs}->{templates};
494 :     return grep { not m/^\./ and m/\.lst$/ and -f "$dir/$_" } WeBWorK::Utils::readDirectory($dir);
495 :     }
496 :    
497 :     sub getDefList {
498 :     my ($self) = @_;
499 :     my $ce = $self->{ce};
500 :     my $dir = $ce->{courseDirs}->{templates};
501 :     return $self->read_dir($dir, qr/.*\.def/);
502 :     }
503 :    
504 : sh002i 2000 sub getScoringFileList {
505 :     my ($self) = @_;
506 :     my $ce = $self->{ce};
507 :     my $dir = $ce->{courseDirs}->{scoring};
508 :     return $self->read_dir($dir, qr/.*\.csv/);
509 :     }
510 :    
511 : sh002i 1734 =back
512 : malsyned 1005
513 : sh002i 1734 =cut
514 : malsyned 829
515 :     1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9