[system] / branches / rel-2-1-patches / webwork2 / bin / ww_db_v2_to_v3 Repository:
ViewVC logotype

Annotation of /branches/rel-2-1-patches/webwork2/bin/ww_db_v2_to_v3

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3141 - (view) (download)

1 : sh002i 3012 #!/usr/bin/env perl
2 :     ################################################################################
3 :     # WeBWorK Online Homework Delivery System
4 :     # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
5 : sh002i 3075 # $CVSHeader: webwork2/bin/ww_db_v2_to_v3,v 1.4 2004/12/09 16:30:12 sh002i Exp $
6 : sh002i 3012 #
7 :     # This program is free software; you can redistribute it and/or modify it under
8 :     # the terms of either: (a) the GNU General Public License as published by the
9 :     # Free Software Foundation; either version 2, or (at your option) any later
10 :     # version, or (b) the "Artistic License" which comes with this package.
11 :     #
12 :     # This program is distributed in the hope that it will be useful, but WITHOUT
13 :     # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 :     # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the
15 :     # Artistic License for more details.
16 :     ################################################################################
17 :    
18 :     =head1 NAME
19 :    
20 :     ww_db_v2_to_v3 - convert a WWDBv2 database to a WWDBv3 database.
21 :    
22 :     =head1 SYNOPSIS
23 :    
24 : sh002i 3021 ww_db_v2_to_v3 -crsuv course ...
25 : sh002i 3012
26 :     =head1 DESCRIPTION
27 :    
28 :     Copies course data from legacy WWDBv2 database(s) to a WWDBv3 database. This may
29 :     take a long time.
30 :    
31 :     You must disallow login to the WeBWorK system while the transfer is taking
32 :     place. To disable logins for all courses, set the permission level necessary for
33 :     C<login> to $nobody in F<global.conf>. (It is usually set to $student.)
34 :    
35 :     =head1 OPTIONS
36 :    
37 :     =over
38 :    
39 :     =item -c
40 :    
41 :     If an error occurs while copying a course's data, continue copying with the next
42 :     course.
43 :    
44 :     =item -r
45 :    
46 :     Update role table in WWDBv3 database from permission level information in
47 :     F<global.conf>.
48 :    
49 :     =item -s
50 :    
51 :     Update status table in WWDBv3 database from the status information in
52 :     F<global.conf>.
53 :    
54 :     =item -u
55 :    
56 :     When importing a user that already exists in the WWDBv3 database, replace the
57 :     existing information (including the password) with the information in the user
58 :     record being imported.
59 :    
60 :     If this option is not specified, existing users are not updated.
61 :    
62 :     =item -v
63 :    
64 :     Verbose operation.
65 :    
66 :     =item course ...
67 :    
68 :     Data from these courses will be copied.
69 :    
70 :     =back
71 :    
72 :     =head1 BEHAVIOR
73 :    
74 :     =head2 ROLES
75 :    
76 :     =over
77 :    
78 :     =item *
79 :    
80 : sh002i 3015 Roles created with the -r switch are created as system-wide roles.
81 :    
82 :     =item *
83 :    
84 : sh002i 3012 Roles are created by observing the %permissionLevels hash in F<global.conf>, and
85 :     collecting the privileges granted at each permission level into sets. Each set
86 :     of privileges becomes a WWDBv3 role record.
87 :    
88 :     =item *
89 :    
90 :     When a role with the same set of permissions already exists in the WWDBv3
91 :     database, a new one is not created.
92 :    
93 :     =back
94 :    
95 : sh002i 3015 =head2 STATUSES
96 :    
97 :     =over
98 :    
99 :     =item *
100 :    
101 :     Statuses created with the -s switch are created as system-wide statuses.
102 :    
103 :     =item *
104 :    
105 :     Statuses are created by observing the %{$siteDefaults{status}} hash in
106 :     F<global.conf>, and
107 :    
108 :     =item *
109 :    
110 :     A status named "Enrolled" is imported into the database with the
111 :     C<allow_course_access>, C<include_in_assignment>, C<include_in_stats>, and
112 :     C<include_in_scoring> flags set.
113 :    
114 :     =item *
115 :    
116 :     A status named "Audit" is imported into the database with the
117 :     C<allow_course_access>, C<include_in_assignment>, and C<include_in_stats>, flags
118 :     set, and the C<include_in_scoring> flag unset.
119 :    
120 :     =item *
121 :    
122 :     A status named "Drop" is imported into the database with the
123 :     C<allow_course_access>, C<include_in_assignment>, C<include_in_stats>, and
124 :     C<include_in_scoring> flags unset.
125 :    
126 :     =item *
127 :    
128 :     Statuses with other names are imported into the database with the same flags set
129 :     as the "Enrolled" flag.
130 :    
131 :     =back
132 :    
133 : sh002i 3012 =head2 USERS
134 :    
135 :     =over
136 :    
137 :     =item *
138 :    
139 : sh002i 3021 WWDBv2 user IDs are converted to login IDs.
140 : sh002i 3012
141 :     =item *
142 :    
143 : sh002i 3021 Users with the same v2 user ID in different courses are assumed to be the same
144 : sh002i 3012 user.
145 :    
146 : sh002i 3021 =item *
147 :    
148 :     A user's permission level is used to determine the role to assign to their v3
149 :     participant record. (See L<ROLES>.) If the user has an empty permission level,
150 :     they are assigned the role associated with permission level "0".
151 :    
152 :     =item *
153 :    
154 :     A user's status abbreviation is used to determine the status to assign to their
155 :     v3 participant record. (See L<STATUSES>.) If the user has an empty status, they
156 :     are assigned the status "Enrolled".
157 :    
158 :     =item *
159 :    
160 :     If a user has a non-empty section or recitation, their v3 participant record
161 :     will be assigned to the section or recitation with a matching name.
162 :    
163 : sh002i 3012 =back
164 :    
165 :     =cut
166 :    
167 :     use strict;
168 :     use warnings;
169 :     use Data::Dumper;
170 : sh002i 3021 use DateTime;
171 : sh002i 3012 use Getopt::Std;
172 :    
173 :     BEGIN {
174 :     die "WEBWORK_ROOT not found in environment.\n"
175 :     unless exists $ENV{WEBWORK_ROOT};
176 :     }
177 :    
178 :     use lib "$ENV{WEBWORK_ROOT}/lib";
179 :     use WeBWorK::CourseEnvironment;
180 :     use WeBWorK::DB;
181 :     use WeBWorK::DBv3;
182 :    
183 : sh002i 3015 # map statuses from course environment to sets of status privileges
184 :     use constant STATUS_MAP => {
185 :     Enrolled => { allow_course_access => 1, include_in_assignment => 1, include_in_stats => 1, include_in_scoring => 1 },
186 :     Audit => { allow_course_access => 1, include_in_assignment => 1, include_in_stats => 1, include_in_scoring => 0 },
187 :     Drop => { allow_course_access => 0, include_in_assignment => 0, include_in_stats => 0, include_in_scoring => 0 },
188 :     };
189 :    
190 : sh002i 3021 use constant DEFAULT_STATUS => "C";
191 : sh002i 3016 use constant DEFAULT_PERMISSION_LEVEL => "0";
192 :    
193 : sh002i 3012 our ($opt_c, $opt_r, $opt_s, $opt_u, $opt_v);
194 :     getopts("crsuv");
195 :    
196 :     sub debug { print STDERR @_ if $opt_v }
197 : sh002i 3015 sub usage { print STDERR "usage: $0 [-crsuv] course ...\n"; exit 1 }
198 : sh002i 3012
199 :     main(@ARGV);
200 :    
201 :     sub main {
202 :     my (@courseIDs) = @_;
203 :    
204 :     usage() unless @courseIDs;
205 :    
206 :     my $ce = WeBWorK::CourseEnvironment->new({webwork_dir => $ENV{WEBWORK_ROOT}});
207 :    
208 :     WeBWorK::DBv3::init($ce->{wwdbv3_settings});
209 :    
210 : sh002i 3016 my %abbrev_to_status_id = set_up_statuses($ce->{siteDefaults}{status});
211 :     warn "abbrev_to_status_id: ", Dumper(\%abbrev_to_status_id);
212 :    
213 : sh002i 3012 my %level_to_role_id = set_up_roles($ce->{permissionLevels});
214 : sh002i 3016 warn "level_to_role_id: ", Dumper(\%level_to_role_id);
215 : sh002i 3012
216 :     foreach my $courseID (@courseIDs) {
217 : sh002i 3016 eval { copy_course_data($courseID, \%abbrev_to_status_id, \%level_to_role_id) };
218 : sh002i 3012 if ($@) {
219 :     warn "An error occured while copying data from course '$courseID':\n\n$@\n\n";
220 :     if ($opt_c) {
221 :     warn "Continuing with the next course...\n";
222 :     } else {
223 :     warn "Exiting.\n";
224 :     exit 2;
225 :     }
226 :     }
227 :     }
228 :     }
229 :    
230 :     ################################################################################
231 :    
232 : sh002i 3021 sub reverse_hash {
233 :     my (%hash) = @_;
234 :    
235 :     my %reverse_hash;
236 :     foreach my $key (keys %hash) {
237 :     my $value = $hash{$key};
238 :     if (defined $value and not ref $value) {
239 :     push @{ $reverse_hash{$value} }, $key;
240 :     #} else {
241 :     # my $val_string = defined $value ? $value : "UNDEF";
242 :     # warn "pair ( $key => $val_string ) skipped.\n";
243 :     }
244 :     }
245 :    
246 :     return %reverse_hash;
247 :     }
248 :    
249 :     sub listeq {
250 :     my ($a, $b) = @_;
251 :     return "" unless @$a == @$b;
252 :     for (my $i = 0; $i < @$a; $i++) {
253 :     return "" unless $a->[$i] eq $b->[$i];
254 :     }
255 :     return 1;
256 :     }
257 :    
258 :     sub is_empty {
259 :     my ($val) = @_;
260 :     return (not defined $val or $val eq "");
261 :     }
262 :    
263 :     ################################################################################
264 :    
265 : sh002i 3012 sub set_up_roles {
266 :     my ($permissionLevels) = @_;
267 :     my %permissionLevels = %$permissionLevels;
268 :    
269 :     my %level_to_role_id;
270 :    
271 : sh002i 3015 # reverse the permission levels hash, resulting in a hash mapping
272 :     # permissions levels to arrayrefs containing privileges
273 :     my %levels = reverse_hash(%permissionLevels);
274 : sh002i 3012
275 :     # copy up the privileges at each level to the next-higher level
276 :     # also sort each level
277 : sh002i 3015 my @level_names = sort { $a <=> $b } keys %levels;
278 : sh002i 3012 foreach my $i (0 .. $#level_names-1) {
279 :     my $this_level = $level_names[$i];
280 :     my $next_level = $level_names[$i+1];
281 :     push @{ $levels{$next_level} }, @{ $levels{$this_level} };
282 :     }
283 :    
284 :     # sort the privileges in each level
285 :     debug("I found the following permission levels:\n");
286 :     foreach my $level (keys %levels) {
287 :     my @sorted = sort @{ $levels{$level} };
288 :     $levels{$level} = [ @sorted ];
289 :     debug("\t$level => @sorted\n");
290 :     }
291 :    
292 :     # keep track of role names so we know if we need to rename any of our new ones
293 :     my %role_names;
294 :    
295 :     # look at existing roles to see if we can avoid adding some new ones
296 :     my $i = retrieve_all WeBWorK::DBv3::Role;
297 :     while (my $Role = $i->next) {
298 :     $role_names{$Role->name} = 1;
299 : sh002i 3075 my @role_privs = sort $Role->privs_list;
300 : sh002i 3012
301 :     foreach my $level (keys %levels) {
302 :     if (listeq($levels{$level}, \@role_privs)) {
303 :     debug("Permission level '$level' is already represented as role '",
304 : sh002i 3015 $Role->name, "' (ID $Role) -- skipping.\n");
305 : sh002i 3012 delete $levels{$level};
306 :     $level_to_role_id{$level} = $Role->id;
307 :     }
308 :     }
309 :     }
310 :    
311 :     if ($opt_r) {
312 :     debug("Updating role table (as per -r switch).\n");
313 :     foreach my $level (keys %levels) {
314 :     my $name = "Legacy permission level $level";
315 :     if (exists $role_names{$name}) {
316 :     my $i = 2;
317 :     while (1) {
318 :     my $try_name = "$name (#$i)";
319 :     if (not exists $role_names{$try_name}) {
320 :     $name = $try_name;
321 :     last;
322 :     }
323 :     }
324 :     }
325 :    
326 :     my @privs = @{ $levels{$level} };
327 :    
328 : sh002i 3075 my $Role = create WeBWorK::DBv3::Role({name => $name});
329 :     $Role->privs_list(@privs);
330 : sh002i 3012 $Role->update;
331 : sh002i 3015 debug("Added role '", $Role->name, "' (ID $Role) with privileges '@privs'.\n");
332 : sh002i 3012 $level_to_role_id{$level} = $Role->id;
333 :     }
334 :     } else {
335 :     debug("Not updating role table (as per lack of -r switch).\n");
336 :     debug("I might run into users with permission levels that don't map to roles later.\n");
337 :     }
338 :    
339 :     return %level_to_role_id;
340 :     }
341 :    
342 :     sub set_up_statuses {
343 : sh002i 3015 my ($abbrevs) = @_;
344 :     my %abbrevs = %$abbrevs;
345 :    
346 :     my %abbrev_to_status_id;
347 :    
348 :     # reverse the statuses hash, resulting in a hash mapping statuses to
349 :     # arrayrefs containing abbreviations
350 :     my %statuses = reverse_hash(%abbrevs);
351 :    
352 :     # look at existing statuses to see if we can avoid adding some new ones
353 :     my $i = retrieve_all WeBWorK::DBv3::Status;
354 :     while (my $Status = $i->next) {
355 :     if (exists $statuses{$Status->name}) {
356 :     debug("Status '", $Status->name, "' (ID $Status) already exists in the database -- skipping.\n");
357 :     # add entries mapping abbreviations to the ID of this status
358 :     foreach my $abbrev (@{$statuses{$Status->name}}) {
359 :     $abbrev_to_status_id{$abbrev} = $Status->id;
360 :     }
361 :    
362 :     delete $statuses{$Status->name};
363 :     }
364 :     }
365 :    
366 :     if ($opt_s) {
367 :     debug("Updating status table (as per -s switch).\n");
368 :     foreach my $status (keys %statuses) {
369 :     my %flags;
370 :     %flags = %{ STATUS_MAP->{$status} } if exists STATUS_MAP->{$status};
371 :     my $Status = create WeBWorK::DBv3::Status({name => $status, %flags});
372 :    
373 :     my @flags = grep { $flags{$_} } keys %flags;
374 :     debug("Added status '", $Status->name, "' (ID $Status) with flags '@flags'.\n");
375 :    
376 :     # add entries mapping abbreviations to the ID of this status
377 :     foreach my $abbrev (@{$statuses{$status}}) {
378 :     $abbrev_to_status_id{$abbrev} = $Status->id;
379 :     }
380 :     }
381 :     } else {
382 :     debug("Not updating status table (as per lack of -s switch).\n");
383 :     debug("I might run into users with status abbreviations that don't map to statuses later.\n");
384 :     }
385 :    
386 :     return %abbrev_to_status_id;
387 : sh002i 3012 }
388 :    
389 :     ################################################################################
390 :    
391 :     sub copy_course_data {
392 : sh002i 3016 my ($courseID, $abbrev_to_status_id, $level_to_role_id) = @_;
393 : sh002i 3012
394 :     debug("Processing course '$courseID'...\n");
395 :    
396 :     my $course_ce = WeBWorK::CourseEnvironment->new({
397 :     webwork_dir => $ENV{WEBWORK_ROOT},
398 :     courseName => $courseID,
399 :     });
400 :    
401 :     my $course_db = WeBWorK::DB->new($course_ce->{dbLayout});
402 :    
403 : sh002i 3075 debug("Adding course '$courseID' to v3 DB.\n");
404 :     my $v3Course = eval { create WeBWorK::DBv3::Course({name => $courseID}) };
405 :     $@ =~ /Duplicate entry/ and die "Course '$courseID' exists in v3 DB.\n";
406 :     $@ and die $@;
407 : sh002i 3012
408 : sh002i 3016 copy_users($course_db, $v3Course, $abbrev_to_status_id, $level_to_role_id);
409 :    
410 : sh002i 3075 # { $globalSetID => [ $v3AbsSet->id, { $globalProblemID => $vAbsProb->id, ... }, ... }
411 :     my %global_set_id_to_abstract_set_data = copy_abstract_data($course_db, $v3Course);
412 : sh002i 3016 }
413 :    
414 : sh002i 3021 ################################################################################
415 :    
416 : sh002i 3016 sub copy_users {
417 :     my ($course_db, $v3Course, $abbrev_to_status_id, $level_to_role_id) = @_;
418 :    
419 : sh002i 3021 my $DefaultStatus = find_status(DEFAULT_STATUS, $abbrev_to_status_id);
420 :     die "Default status '", DEFAULT_STATUS, "' does not correspond to any v3 status.\n"
421 :     unless $DefaultStatus;
422 :    
423 :     my $DefaultRole = find_role(DEFAULT_PERMISSION_LEVEL, $level_to_role_id);
424 :     die "Default permission level '", DEFAULT_PERMISSION_LEVEL, "' does not correspond to any v3 role.\n"
425 :     unless $DefaultRole;
426 :    
427 : sh002i 3012 my @userIDs = $course_db->listUsers;
428 :     my %Users; @Users{@userIDs} = $course_db->getUsers(@userIDs);
429 : sh002i 3016 my %Passwords; @Passwords{@userIDs} = $course_db->getPasswords(@userIDs);
430 :     my %PermissionLevels; @PermissionLevels{@userIDs} = $course_db->getPermissionLevels(@userIDs);
431 : sh002i 3012
432 :     foreach my $userID (keys %Users) {
433 :     my $User = $Users{$userID};
434 : sh002i 3016 my $Password = $Passwords{$userID};
435 :     my $PermissionLevel = $PermissionLevels{$userID};
436 :    
437 : sh002i 3012 unless (defined $User) {
438 :     debug("User record for user ID '$userID' not found -- skipping.\n");
439 :     next;
440 :     }
441 :    
442 : sh002i 3016 debug("Processing user '$userID'...\n");
443 :    
444 :     # create/update user record
445 : sh002i 3021 my ($v3User) = search WeBWorK::DBv3::User(login_id => $userID);
446 : sh002i 3012 if ($v3User) {
447 : sh002i 3016 debug("A user with login_id '$userID' exists in v3 database -- ");
448 : sh002i 3012 if ($opt_u) {
449 : sh002i 3021 # password record might not exist (annoying...)
450 :     my $password = defined $Password ? $Password->password : "";
451 :    
452 : sh002i 3016 debug("updating (as per -u switch).\n");
453 : sh002i 3021 $v3User->first_name($User->first_name) unless is_empty($User->first_name);
454 :     $v3User->last_name($User->first_name) unless is_empty($User->last_name);
455 :     $v3User->email_address($User->email_address) unless is_empty($User->email_address);
456 :     $v3User->student_id($User->student_id) unless is_empty($User->student_id);
457 :     $v3User->password($password) unless is_empty($password);
458 : sh002i 3012 $v3User->update;
459 :     } else {
460 : sh002i 3016 debug("not updating (as per lack of -u switch).\n");
461 : sh002i 3012 }
462 :     } else {
463 : sh002i 3021 # password record might not exist (annoying...)
464 :     my $password = defined $Password ? $Password->password : "";
465 :    
466 : sh002i 3016 debug("No user with login_id '$userID' exists in v3 database -- adding.\n");
467 : sh002i 3021 $v3User = create WeBWorK::DBv3::User({
468 : sh002i 3016 first_name => $User->first_name,
469 :     last_name => $User->last_name,
470 :     email_address => $User->email_address,
471 :     student_id => $User->student_id,
472 :     login_id => $User->user_id,
473 : sh002i 3021 password => $password,
474 : sh002i 3012 });
475 :     }
476 : sh002i 3016
477 :     # get status
478 : sh002i 3021 my $v3Status = find_status($User->status, $abbrev_to_status_id);
479 :     unless ($v3Status) {
480 :     debug("Using default status '", $DefaultStatus->name, "'.\n");
481 :     $v3Status = $DefaultStatus;
482 : sh002i 3016 }
483 :    
484 :     # get role
485 : sh002i 3021 my $level = defined $PermissionLevel ? $PermissionLevel->permission : "";
486 :     my $v3Role = find_role($level, $level_to_role_id);
487 :     unless ($v3Role) {
488 :     debug("Using default role '", $DefaultRole->name, "'.\n");
489 :     $v3Role = $DefaultRole;
490 : sh002i 3016 }
491 :    
492 :     # find/create section record
493 :     my $section = $User->section;
494 :     my $v3Section;
495 : sh002i 3021 if (is_empty($section)) {
496 : sh002i 3016 debug("This user has section '$section'.\n");
497 : sh002i 3021 ($v3Section) = search WeBWorK::DBv3::Section(course => $v3Course, name => $section);
498 : sh002i 3016 if ($v3Section) {
499 :     debug("This corresponds to existing section ID $v3Section in v3 database.\n");
500 :     } else {
501 :     debug("No corresponding section exists in v3 DB -- adding.\n");
502 : sh002i 3021 $v3Section = create WeBWorK::DBv3::Section({
503 :     course => $v3Course,
504 : sh002i 3016 name => $section,
505 :     });
506 :     debug("Added section '", $v3Section->name, "' (ID $v3Section).\n");
507 :     }
508 :     } else {
509 :     debug("This user has no section.\n");
510 :     }
511 :    
512 :     # find/create recitation record
513 :     my $recitation = $User->recitation;
514 :     my $v3Recitation;
515 : sh002i 3021 if (is_empty($recitation)) {
516 : sh002i 3016 debug("This user has recitation '$recitation'.\n");
517 : sh002i 3021 ($v3Recitation) = search WeBWorK::DBv3::Recitation(course => $v3Course, name => $User->recitation);
518 : sh002i 3016 if ($v3Recitation) {
519 :     debug("This correponds to existing recitation ID $v3Recitation in v3 database.\n");
520 :     } else {
521 :     debug("No corresponding recitation exists in v3 DB -- adding.\n");
522 : sh002i 3021 $v3Recitation = create WeBWorK::DBv3::Recitation({
523 :     course => $v3Course,
524 : sh002i 3016 name => $User->recitation,
525 :     });
526 :     debug("Added recitation '", $v3Recitation->name, "' (ID $v3Recitation).\n");
527 :     }
528 :     } else {
529 :     debug("This user has no recitation.\n");
530 :     }
531 :    
532 :     # create participant record
533 : sh002i 3021 debug("Adding participant record for user '$userID'...");
534 :     #my $sectionID = $v3Section->id if defined $v3Section;
535 :     #my $recitationID = $v3Recitation->id if defined $v3Recitation;
536 :     my $v3Participant = create WeBWorK::DBv3::Participant({
537 :     course => $v3Course,
538 :     user => $v3User,
539 :     status => $v3Status,
540 :     role => $v3Role,
541 :     section => $v3Section,
542 :     recitation => $v3Recitation,
543 : sh002i 3016 comment => $User->comment,
544 :     });
545 : sh002i 3021 debug(" added participant ID $v3Participant.\n");
546 : sh002i 3012 }
547 :     }
548 :    
549 : sh002i 3021 sub find_status {
550 :     my ($status, $abbrev_to_status_id) = @_;
551 : sh002i 3016
552 : sh002i 3021 return if is_empty($status);
553 : sh002i 3016
554 : sh002i 3021 my $v3Status_id = $abbrev_to_status_id->{$status};
555 :     my $v3Status;
556 :     if (defined $v3Status_id) {
557 :     #debug("Status '$status' maps to v3 status ID '$v3Status_id'.\n");
558 :     $v3Status = retrieve WeBWorK::DBv3::Status($v3Status_id);
559 :     } else {
560 :     #debug("Status '$status' doesn't map to any v3 status.\n");
561 :     }
562 :    
563 :     return $v3Status;
564 : sh002i 3016 }
565 :    
566 : sh002i 3021 sub find_role {
567 :     my ($level, $level_to_role_id) = @_;
568 :    
569 :     return if is_empty($level);
570 :    
571 :     my $v3Role_id = $level_to_role_id->{$level};
572 :     my $v3Role;
573 :     if (defined $v3Role_id) {
574 :     #debug("Permission level '$level' maps to v3 role ID '$v3Role_id'.\n");
575 :     $v3Role = retrieve WeBWorK::DBv3::Role($v3Role_id);
576 :     } else {
577 :     #debug("Permission level '$level' doesn't map to any v3 role.\n");
578 :     }
579 :    
580 :     return $v3Role;
581 :     }
582 :    
583 : sh002i 3012 ################################################################################
584 :    
585 : sh002i 3021 sub copy_abstract_data {
586 :     my ($course_db, $v3Course) = @_;
587 :    
588 : sh002i 3075 my %global_set_id_to_abstract_set_data;
589 :    
590 : sh002i 3021 my @globalSetIDs = $course_db->listGlobalSets;
591 :     my %GlobalSets; @GlobalSets{@globalSetIDs} = $course_db->getGlobalSets(@globalSetIDs);
592 :    
593 :     foreach my $globalSetID (keys %GlobalSets) {
594 :     my $GlobalSet = $GlobalSets{$globalSetID};
595 :    
596 :     unless (defined $GlobalSet) {
597 :     debug("Global set record for global set ID '$globalSetID' not found -- skipping.\n");
598 :     next;
599 :     }
600 :    
601 :     debug("Processing global set '$globalSetID'...\n");
602 :    
603 :     # set up some fields that need setting up
604 :     # (if the conditional is false, the variable is left undefined)
605 :    
606 :     # convert empty strings to undefined values
607 :     my $set_header = $GlobalSet->set_header unless is_empty($GlobalSet->set_header);
608 :     my $hardcopy_header = $GlobalSet->hardcopy_header unless is_empty($GlobalSet->hardcopy_header);
609 :    
610 :     # convert
611 :     my $open_date = DateTime->from_epoch(epoch => $GlobalSet->open_date);
612 :     my $due_date = DateTime->from_epoch(epoch => $GlobalSet->due_date);
613 :     my $answer_date = DateTime->from_epoch(epoch => $GlobalSet->answer_date);
614 :    
615 :     # create abstract_set record
616 :     debug("Adding abstract_set record for global set '$globalSetID'...");
617 :     my $v3AbsSet = create WeBWorK::DBv3::AbstractSet({
618 :     course => $v3Course,
619 :     name => $GlobalSet->set_id,
620 :     set_header => $set_header,
621 :     hardcopy_header => $hardcopy_header,
622 :     open_date => $open_date,
623 :     due_date => $due_date,
624 :     answer_date => $answer_date,
625 :     published => $GlobalSet->published,
626 :     });
627 :     debug(" added abstract_set ID '$v3AbsSet'.\n");
628 :    
629 : sh002i 3075
630 :     my %problem_mapping;
631 :    
632 : sh002i 3021 my @globalProblemIDs = sort { $a <=> $b } $course_db->listGlobalProblems($globalSetID);
633 :     warn "globalProblemIDs=@globalProblemIDs\n";
634 :     my %GlobalProblems; @GlobalProblems{@globalProblemIDs}
635 :     = $course_db->getGlobalProblems(map { [ $globalSetID, $_ ] } @globalProblemIDs);
636 :    
637 :     my @problem_order;
638 :    
639 :     foreach my $globalProblemID (@globalProblemIDs) {
640 :     my $GlobalProblem = $GlobalProblems{$globalProblemID};
641 :    
642 :     unless (defined $GlobalProblem) {
643 :     warn "Global problem record for global problem ID '$globalProblemID' in set ID '$globalSetID' not found -- skipping.\n";
644 :     next;
645 :     }
646 :    
647 :     debug("Processing global problem '$globalProblemID'...\n");
648 :    
649 :     # convert max_attempts of -1 to undef
650 :     my $max_attempts_per_version = $GlobalProblem->max_attempts
651 :     if $GlobalProblem->max_attempts >= 0;
652 :    
653 :     # create abstract_problem record
654 :     debug("Adding abstract_set record for global problem '$globalProblemID'...");
655 :     my $v3AbsProb = create WeBWorK::DBv3::AbstractProblem({
656 :     abstract_set => $v3AbsSet,
657 :     name => "Legacy problem $globalProblemID",
658 :     source_type => "file",
659 :     source_file => $GlobalProblem->source_file,
660 :     weight => $GlobalProblem->value,
661 :     max_attempts_per_version => $max_attempts_per_version,
662 :     version_creation_interval => undef,
663 :     versions_per_interval => 1,
664 :     version_due_date_offset => undef,
665 :     version_answer_date_offset => undef,
666 :     });
667 :     debug(" added abstract_problem ID '$v3AbsProb'.\n");
668 :    
669 :     push @problem_order, $v3AbsProb->id;
670 : sh002i 3075
671 :     $problem_mapping{$globalProblemID} = $v3AbsProb->id;
672 : sh002i 3021 }
673 :    
674 :     # update problem order
675 :     debug("Setting problem order to: '@problem_order'...");
676 :     $v3AbsSet->problem_order_list(@problem_order);
677 :     $v3AbsSet->update;
678 :     debug(" done.\n");
679 : sh002i 3075
680 :     $global_set_id_to_abstract_set_data{$globalSetID} = [ $v3AbsSet->id, \%problem_mapping ];
681 : sh002i 3012 }
682 : sh002i 3075
683 :     return %global_set_id_to_abstract_set_data;
684 : sh002i 3012 }
685 : sh002i 3021
686 : sh002i 3075 ################################################################################
687 : sh002i 3021
688 : sh002i 3075 sub copy_assignment_data {
689 :     my ($course_db, $v3Course, $global_set_id_to_abstract_set_data) = @_;
690 :    
691 :     my $participant_iter = WeBWorK::DBv3::Participant->search(course => $v3Course);
692 :    
693 :     while (my $Participant = $participant_iter->next) {
694 :     my @userSetIDs = $course_db->listUserSets($Participant->user->login_id);
695 :     $v3AbsSet->
696 :     }
697 :     }
698 : sh002i 3021
699 : sh002i 3075 sub copy_single_assignment {
700 :     my ($course_db, $v3Course, $v3Participant, $v3AbsSet, $global_set_id_to_abstract_set_data) = @_;
701 :    
702 :    
703 :     }

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9