[system] / trunk / webwork2 / lib / WeBWorK / ContentGenerator / CourseAdmin.pm Repository:
ViewVC logotype

Diff of /trunk/webwork2/lib/WeBWorK/ContentGenerator/CourseAdmin.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 7139 Revision 7140
38 listArchivedCourses unarchiveCourse initNonNativeTables); 38 listArchivedCourses unarchiveCourse initNonNativeTables);
39use WeBWorK::Utils::CourseIntegrityCheck; 39use WeBWorK::Utils::CourseIntegrityCheck;
40#use WeBWorK::Utils::DBImportExport qw(dbExport dbImport); 40#use WeBWorK::Utils::DBImportExport qw(dbExport dbImport);
41# needed for location management 41# needed for location management
42use Net::IP; 42use Net::IP;
43use File::Path 'remove_tree';
43use File::Path; 44use File::stat;
45use Time::localtime;
44 46
45use constant IMPORT_EXPORT_WARNING => "The ability to import and export 47use constant IMPORT_EXPORT_WARNING => "The ability to import and export
46databases is still under development. It seems to work but it is <b>VERY</b> 48databases is still under development. It seems to work but it is <b>VERY</b>
47slow on large courses. You may prefer to use webwork2/bin/wwdb or the mysql 49slow on large courses. You may prefer to use webwork2/bin/wwdb or the mysql
48dump facility for archiving large courses. Please send bug reports if you find 50dump facility for archiving large courses. Please send bug reports if you find
158 if (@errors) { 160 if (@errors) {
159 $method_to_call = "delete_course_form"; 161 $method_to_call = "delete_course_form";
160 } else { 162 } else {
161 $method_to_call = "do_delete_course"; 163 $method_to_call = "do_delete_course";
162 } 164 }
165 }
166 elsif (defined ($r->param("delete_course_refresh"))) {
167 $method_to_call = "delete_course_form";
163 } else { 168 } else {
164 # form only 169 # form only
165 $method_to_call = "delete_course_form"; 170 $method_to_call = "delete_course_form";
166 } 171 }
167 } 172 }
229 if (@errors) { 234 if (@errors) {
230 $method_to_call = "archive_course_form"; 235 $method_to_call = "archive_course_form";
231 } else { 236 } else {
232 $method_to_call = "archive_course_confirm"; # upgrade and recheck tables & directories. 237 $method_to_call = "archive_course_confirm"; # upgrade and recheck tables & directories.
233 } 238 }
239 }
240 elsif (defined ($r->param("archive_course_refresh"))) {
241 $method_to_call = "archive_course_form";
234 } else { 242 } else {
235 # form only 243 # form only
236 $method_to_call = "archive_course_form"; 244 $method_to_call = "archive_course_form";
237 } 245 }
238 } 246 }
291 } 299 }
292 else{ 300 else{
293 $method_to_call = "manage_location_form"; 301 $method_to_call = "manage_location_form";
294 } 302 }
295 } 303 }
304 elsif ($subDisplay eq "hide_inactive_course") {
305# warn "subDisplay is $subDisplay";
306 if (defined ($r->param("hide_course"))) {
307 @errors = $self->hide_course_validate;
308 if (@errors) {
309 $method_to_call = "hide_inactive_course_form";
310 } else {
311 $method_to_call = "do_hide_inactive_course";
312 }
313 }
314 elsif (defined ($r->param("unhide_course"))) {
315 @errors = $self->unhide_course_validate;
316 if (@errors) {
317 $method_to_call = "hide_inactive_course_form";
318 } else {
319 $method_to_call = "do_unhide_inactive_course";
320 }
321 }
322 elsif (defined ($r->param("hide_course_refresh"))) {
323 $method_to_call = "hide_inactive_course_form";
324 }
325 else{
326 $method_to_call = "hide_inactive_course_form";
327 }
328 }
296 elsif ($subDisplay eq "registration") { 329 elsif ($subDisplay eq "registration") {
297 if (defined ($r->param("register_site"))) { 330 if (defined ($r->param("register_site"))) {
298 $method_to_call = "do_registration"; 331 $method_to_call = "do_registration";
299 } 332 }
300 else{ 333 else{
393 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"unarchive_course"})}, "Unarchive Course"), 426 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"unarchive_course"})}, "Unarchive Course"),
394 "|", 427 "|",
395 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"upgrade_course"})}, "Upgrade courses"), 428 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"upgrade_course"})}, "Upgrade courses"),
396 "|", 429 "|",
397 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"manage_locations"})}, "Manage Locations"), 430 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"manage_locations"})}, "Manage Locations"),
431 "|",
432 CGI::a({href=>$self->systemLink($urlpath, params=>{subDisplay=>"hide_inactive_course"})}, "Hide Inactive courses"),
398 CGI::hr(), 433 CGI::hr(),
399 $methodMessage, 434 $methodMessage,
400 435
401 ); 436 );
402 437
889 my @courseIDs = listCourses($ce); 924 my @courseIDs = listCourses($ce);
890 @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs; 925 @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs;
891 926
892 my %courseLabels; # records... heh. 927 my %courseLabels; # records... heh.
893 foreach my $courseID (@courseIDs) { 928 foreach my $courseID (@courseIDs) {
894 my $tempCE = new WeBWorK::CourseEnvironment({ 929# my $tempCE = new WeBWorK::CourseEnvironment({
895 %WeBWorK::SeedCE, 930# %WeBWorK::SeedCE,
896 courseName => $courseID, 931# courseName => $courseID,
897 }); 932# });
898 $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")"; 933# $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")";
934 $courseLabels{$courseID} = "$courseID";
899 } 935 }
900 936
901 print CGI::h2("Rename Course"); 937 print CGI::h2("Rename Course");
902 938
903 print CGI::start_form(-method=>"POST", -action=>$r->uri); 939 print CGI::start_form(-method=>"POST", -action=>$r->uri);
1166 ); 1202 );
1167 } else { 1203 } else {
1168 print CGI::div({class=>"ResultsWithoutError"}, 1204 print CGI::div({class=>"ResultsWithoutError"},
1169 CGI::p("Successfully renamed the course $rename_oldCourseID to $rename_newCourseID"), 1205 CGI::p("Successfully renamed the course $rename_oldCourseID to $rename_newCourseID"),
1170 ); 1206 );
1207 writeLog($ce, "hosted_courses", join("\t",
1208 "\tRenamed",
1209 "",
1210 "",
1211 "$rename_oldCourseID to $rename_newCourseID",
1212 ));
1171 my $newCoursePath = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets", $r, 1213 my $newCoursePath = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets", $r,
1172 courseID => $rename_newCourseID); 1214 courseID => $rename_newCourseID);
1173 my $newCourseURL = $self->systemLink($newCoursePath, authen => 0); 1215 my $newCourseURL = $self->systemLink($newCoursePath, authen => 0);
1174 print CGI::div({style=>"text-align: center"}, 1216 print CGI::div({style=>"text-align: center"},
1175 CGI::a({href=>$newCourseURL}, "Log into $rename_newCourseID"), 1217 CGI::a({href=>$newCourseURL}, "Log into $rename_newCourseID"),
1177 } 1219 }
1178} 1220}
1179 1221
1180################################################################################ 1222################################################################################
1181 1223
1224my %coursesData;
1225sub byLoginActivity {$coursesData{$a}{'epoch_modify_time'} <=> $coursesData{$b}{'epoch_modify_time'}}
1226
1182sub delete_course_form { 1227sub delete_course_form {
1183 my ($self) = @_; 1228 my ($self) = @_;
1184 my $r = $self->r; 1229 my $r = $self->r;
1185 my $ce = $r->ce; 1230 my $ce = $r->ce;
1186 #my $db = $r->db; 1231 #my $db = $r->db;
1187 #my $authz = $r->authz; 1232 #my $authz = $r->authz;
1188 #my $urlpath = $r->urlpath; 1233 #my $urlpath = $r->urlpath;
1189 1234
1190 my $delete_courseID = $r->param("delete_courseID") || ""; 1235 my $delete_courseID = $r->param("delete_courseID") || "";
1191 1236
1237 my $coursesDir = $ce->{webworkDirs}->{courses};
1192 my @courseIDs = listCourses($ce); 1238 my @courseIDs = listCourses($ce);
1193 @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs; #make sort case insensitive 1239# @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs; #make sort case insensitive
1240 my $delete_listing_format = $r->param("delete_listing_format");
1241 unless (defined $delete_listing_format) {$delete_listing_format = 'alphabetically';} #use the default
1194 1242
1195 my %courseLabels; # records... heh. 1243# my %courseLabels; # records... heh.
1244# foreach my $courseID (@courseIDs) {
1245# my $tempCE = new WeBWorK::CourseEnvironment({
1246# %WeBWorK::SeedCE,
1247# courseName => $courseID,
1248# });
1249# $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")";
1250# }
1251 # Get and store last modify time for login.log for all courses. Also get visibility status.
1252 my %courseLabels;
1253 my @noLoginLogIDs = ();
1254 my @loginLogIDs = ();
1255
1256 my ($loginLogFile, $epoch_modify_time, $courseDir);
1196 foreach my $courseID (@courseIDs) { 1257 foreach my $courseID (@courseIDs) {
1197 my $tempCE = new WeBWorK::CourseEnvironment({ 1258 $loginLogFile = "$coursesDir/$courseID/logs/login.log";
1198 %WeBWorK::SeedCE, 1259 if (-e $loginLogFile) { #this should always exist except for the model course
1199 courseName => $courseID, 1260 $epoch_modify_time = stat($loginLogFile)->mtime;
1200 }); 1261 $coursesData{$courseID}{'epoch_modify_time'} = $epoch_modify_time;
1201 $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")"; 1262 $coursesData{$courseID}{'local_modify_time'} = ctime($epoch_modify_time);
1263 push(@loginLogIDs,$courseID);
1264 } else {
1265 $coursesData{$courseID}{'local_modify_time'} = 'no login.log'; #this should never be the case except for the model course
1266 push(@noLoginLogIDs,$courseID);
1202 } 1267 }
1203 1268 if (-f "$coursesDir/$courseID/hide_directory") {
1269 $coursesData{$courseID}{'status'} = 'hidden';
1270 } else {
1271 $coursesData{$courseID}{'status'} = 'visible';
1272 }
1273 $courseLabels{$courseID} = "$courseID ($coursesData{$courseID}{'status'} :: $coursesData{$courseID}{'local_modify_time'}) ";
1274 }
1275 if ($delete_listing_format eq 'last_login') {
1276 @noLoginLogIDs = sort {lc($a) cmp lc ($b) } @noLoginLogIDs; #this should be an empty arrey except for the model course
1277 @loginLogIDs = sort byLoginActivity @loginLogIDs; # oldest first
1278 @courseIDs = (@noLoginLogIDs,@loginLogIDs);
1279 } else { # in this case we sort alphabetically
1280 @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs;
1281 }
1282
1204 print CGI::h2("Delete Course"); 1283 print CGI::h2("Delete Course");
1205 1284
1206 print CGI::start_form(-method=>"POST", -action=>$r->uri); 1285 print CGI::start_form(-method=>"POST", -action=>$r->uri);
1286 my %list_labels = (
1287 alphabetically => 'alphabetically',
1288 last_login => 'by last login date',
1289 );
1290 print CGI::p(
1291 'Courses are listed either alphabetically or in order by the time of most recent login activity, oldest first.
1292 To change the listing order check the mode you want and click "Refresh Listing". The listing format is: Course_Name
1293 (status :: date/time of most recent login) where status is "hidden" or "visible".');
1294
1295 print CGI::table(
1296 CGI::Tr({},
1297 CGI::p("Select a listing format:"),
1298 CGI::radio_group(-name=>'delete_listing_format',
1299 -values=>['alphabetically', 'last_login'],
1300 -default=>'alphabetically',
1301 -labels=>\%list_labels,
1302 ),
1303 ),
1304 );
1305 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"delete_course_refresh", -value=>"Refresh Listing"),
1306 CGI::submit(-name=>"delete_course", -value=>"Delete Course"));
1207 print $self->hidden_authen_fields; 1307 print $self->hidden_authen_fields;
1208 print $self->hidden_fields("subDisplay"); 1308 print $self->hidden_fields("subDisplay");
1209 1309
1310
1210 print CGI::p("Select a course to delete."); 1311 print CGI::p("Select a course to delete.");
1211
1212 print CGI::table({class=>"FormLayout"}, 1312 print CGI::table({class=>"FormLayout"},
1213 CGI::Tr({}, 1313 CGI::Tr({},
1214 CGI::th({class=>"LeftHeader"}, "Course Name:"), 1314 CGI::th({class=>"LeftHeader"}, "Course Name:"),
1215 CGI::td( 1315 CGI::td(
1216 CGI::scrolling_list( 1316 CGI::scrolling_list(
1217 -name => "delete_courseID", 1317 -name => "delete_courseID",
1218 -values => \@courseIDs, 1318 -values => \@courseIDs,
1219 -default => $delete_courseID, 1319 -default => $delete_courseID,
1220 -size => 10, 1320 -size => 15,
1221 -multiple => 0, 1321 -multiple => 0,
1222 -labels => \%courseLabels, 1322 -labels => \%courseLabels,
1223 ), 1323 ),
1224 ), 1324 ),
1225 ), 1325 ),
1226 ); 1326 );
1227 1327
1228 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"delete_course", -value=>"Delete Course")); 1328 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"delete_course_refresh", -value=>"Refresh Listing"),
1329 CGI::submit(-name=>"delete_course", -value=>"Delete Course"));
1229 1330
1230 print CGI::end_form(); 1331 print CGI::end_form();
1231} 1332}
1232 1333
1233sub delete_course_validate { 1334sub delete_course_validate {
1369 #my $authz = $r->authz; 1470 #my $authz = $r->authz;
1370 #my $urlpath = $r->urlpath; 1471 #my $urlpath = $r->urlpath;
1371 1472
1372 my $archive_courseID = $r->param("archive_courseID") || ""; 1473 my $archive_courseID = $r->param("archive_courseID") || "";
1373 1474
1475 my $coursesDir = $ce->{webworkDirs}->{courses};
1374 my @courseIDs = listCourses($ce); 1476 my @courseIDs = listCourses($ce);
1375 @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs; #make sort case insensitive 1477# @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs; #make sort case insensitive
1478 my $archive_listing_format = $r->param("archive_listing_format");
1479 unless (defined $archive_listing_format) {$archive_listing_format = 'alphabetically';} #use the default
1376 1480
1377 my %courseLabels; # records... heh. 1481# my %courseLabels; # records... heh.
1482# foreach my $courseID (@courseIDs) {
1483# my $tempCE = new WeBWorK::CourseEnvironment({
1484# %WeBWorK::SeedCE,
1485# courseName => $courseID,
1486# });
1487# $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")";
1488# }
1489 # Get and store last modify time for login.log for all courses. Also get visibility status.
1490 my %courseLabels;
1491 my @noLoginLogIDs = ();
1492 my @loginLogIDs = ();
1493
1494 my ($loginLogFile, $epoch_modify_time, $courseDir);
1378 foreach my $courseID (@courseIDs) { 1495 foreach my $courseID (@courseIDs) {
1379 my $tempCE = new WeBWorK::CourseEnvironment({ 1496 $loginLogFile = "$coursesDir/$courseID/logs/login.log";
1380 %WeBWorK::SeedCE, 1497 if (-e $loginLogFile) { #this should always exist except for the model course
1381 courseName => $courseID, 1498 $epoch_modify_time = stat($loginLogFile)->mtime;
1499 $coursesData{$courseID}{'epoch_modify_time'} = $epoch_modify_time;
1500 $coursesData{$courseID}{'local_modify_time'} = ctime($epoch_modify_time);
1501 push(@loginLogIDs,$courseID);
1502 } else {
1503 $coursesData{$courseID}{'local_modify_time'} = 'no login.log'; #this should never be the case except for the model course
1504 push(@noLoginLogIDs,$courseID);
1382 }); 1505 }
1383 $courseLabels{$courseID} = "$courseID (" . $tempCE->{dbLayoutName} . ")"; 1506 if (-f "$coursesDir/$courseID/hide_directory") {
1507 $coursesData{$courseID}{'status'} = 'hidden';
1508 } else {
1509 $coursesData{$courseID}{'status'} = 'visible';
1510 }
1511 $courseLabels{$courseID} = "$courseID ($coursesData{$courseID}{'status'} :: $coursesData{$courseID}{'local_modify_time'}) ";
1512 }
1513 if ($archive_listing_format eq 'last_login') {
1514 @noLoginLogIDs = sort {lc($a) cmp lc ($b) } @noLoginLogIDs; #this should be an empty arrey except for the model course
1515 @loginLogIDs = sort byLoginActivity @loginLogIDs; # oldest first
1516 @courseIDs = (@noLoginLogIDs,@loginLogIDs);
1517 } else { # in this case we sort alphabetically
1518 @courseIDs = sort {lc($a) cmp lc ($b) } @courseIDs;
1384 } 1519 }
1385 1520
1386 print CGI::h2("archive Course"); 1521 print CGI::h2("archive Course");
1387 1522
1388 print CGI::p( 1523 print CGI::p(
1389 "Creates a gzipped tar archive (.tar.gz) of a course in the WeBWorK 1524 'Creates a gzipped tar archive (.tar.gz) of a course in the WeBWorK
1390 courses directory. Before archiving, the course database is dumped into 1525 courses directory. Before archiving, the course database is dumped into
1391 a subdirectory of the course's DATA directory. Currently the archive 1526 a subdirectory of the course\'s DATA directory. Currently the archive
1392 facility is only available for mysql databases. It depends on the 1527 facility is only available for mysql databases. It depends on the
1393 mysqldump application." 1528 mysqldump application.'
1394 ); 1529 );
1395 1530 print CGI::p(
1531 'Courses are listed either alphabetically or in order by the time of most recent login activity, oldest first.
1532 To change the listing order check the mode you want and click "Refresh Listing". The listing format is: Course_Name
1533 (status :: date/time of most recent login) where status is "hidden" or "visible".');
1534
1396 print CGI::start_form(-method=>"POST", -action=>$r->uri); 1535 print CGI::start_form(-method=>"POST", -action=>$r->uri);
1536 my %list_labels = (
1537 alphabetically => 'alphabetically',
1538 last_login => 'by last login date',
1539 );
1540
1541 print CGI::table(
1542 CGI::Tr({},
1543 CGI::p("Select a listing format:"),
1544 CGI::radio_group(-name=>'archive_listing_format',
1545 -values=>['alphabetically', 'last_login'],
1546 -default=>'alphabetically',
1547 -labels=>\%list_labels,
1548 ),
1549 ),
1550 );
1551 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"archive_course_refresh", -value=>"Refresh Listing"),
1552 CGI::submit(-name=>"archive_course", -value=>"Archive Courses"));
1397 print $self->hidden_authen_fields; 1553 print $self->hidden_authen_fields;
1398 print $self->hidden_fields("subDisplay"); 1554 print $self->hidden_fields("subDisplay");
1399 1555
1400 print CGI::p("Select a course to archive."); 1556 print CGI::p("Select course(s) to archive.");
1401 1557
1402 print CGI::table({class=>"FormLayout"}, 1558 print CGI::table({class=>"FormLayout"},
1403 CGI::Tr({}, 1559 CGI::Tr({},
1404 CGI::th({class=>"LeftHeader"}, "Course Name:"), 1560 CGI::th({class=>"LeftHeader"}, "Course Name:"),
1405 CGI::td( 1561 CGI::td(
1406 CGI::scrolling_list( 1562 CGI::scrolling_list(
1407 -name => "archive_courseIDs", 1563 -name => "archive_courseIDs",
1408 -values => \@courseIDs, 1564 -values => \@courseIDs,
1409 -default => $archive_courseID, 1565 -default => $archive_courseID,
1410 -size => 10, 1566 -size => 15,
1411 -multiple => 1, 1567 -multiple => 1,
1412 -labels => \%courseLabels, 1568 -labels => \%courseLabels,
1413 ), 1569 ),
1414 ), 1570 ),
1415 1571
1425 ), 1581 ),
1426 ), 1582 ),
1427 ) 1583 )
1428 ); 1584 );
1429 1585
1430 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"archive_course", -value=>"archive Course")); 1586 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"archive_course_refresh", -value=>"Refresh Listing"),
1587 CGI::submit(-name=>"archive_course", -value=>"Archive Courses"));
1431 1588
1432 print CGI::end_form(); 1589 print CGI::end_form();
1433} 1590}
1434 1591
1435sub archive_course_validate { 1592sub archive_course_validate {
1674 courseName => $archive_courseID, 1831 courseName => $archive_courseID,
1675 }); 1832 });
1676 1833
1677 # Remove course specific temp files before archiving 1834 # Remove course specific temp files before archiving
1678 my $courseTempDir = $ce2->{courseDirs}{html_temp}; 1835 my $courseTempDir = $ce2->{courseDirs}{html_temp};
1679 rmtree("$courseTempDir"); 1836 remove_tree("$courseTempDir");
1680 # Remove the original default tmp directory if it exists 1837 # Remove the original default tmp directory if it exists
1681 my $orgDefaultCourseTempDir = "$ce2->{courseDirs}{html}/tmp"; 1838 my $orgDefaultCourseTempDir = "$ce2->{courseDirs}{html}/tmp";
1682 if (-d "$orgDefaultCourseTempDir") { 1839 if (-d "$orgDefaultCourseTempDir") {
1683 rmtree("$orgDefaultCourseTempDir"); 1840 remove_tree("$orgDefaultCourseTempDir");
1684 } 1841 }
1685 1842
1686 # this is kinda left over from when we had 'gdbm' and 'sql' database layouts 1843 # this is kinda left over from when we had 'gdbm' and 'sql' database layouts
1687 # below this line, we would grab values from getopt and put them in this hash 1844 # below this line, we would grab values from getopt and put them in this hash
1688 # but for now the hash can remain empty 1845 # but for now the hash can remain empty
1689 my %dbOptions; 1846 my %dbOptions;
1690 1847
2749 2906
2750 $self->edit_location_form; 2907 $self->edit_location_form;
2751 } 2908 }
2752} 2909}
2753 2910
2911sub hide_inactive_course_form {
2912 my ($self) = @_;
2913 my $r = $self->r;
2914 my $ce = $r->ce;
2915
2916 my $coursesDir = $ce->{webworkDirs}->{courses};
2917 my @courseIDs = listCourses($ce);
2918 my $hide_listing_format = $r->param("hide_listing_format");
2919 unless (defined $hide_listing_format) {$hide_listing_format = 'last_login';} #use the default
2920# warn "hide_listing_format is $hide_listing_format";
2921
2922 # Get and store last modify time for login.log for all courses. Also get visibility status.
2923 my %courseLabels;
2924 my @noLoginLogIDs = ();
2925 my @loginLogIDs = ();
2926 my @hideCourseIDs = ();
2927 my ($loginLogFile, $epoch_modify_time, $courseDir);
2928 foreach my $courseID (@courseIDs) {
2929 $loginLogFile = "$coursesDir/$courseID/logs/login.log";
2930 if (-e $loginLogFile) { #this should always exist except for the model course
2931 $epoch_modify_time = stat($loginLogFile)->mtime;
2932 $coursesData{$courseID}{'epoch_modify_time'} = $epoch_modify_time;
2933 $coursesData{$courseID}{'local_modify_time'} = ctime($epoch_modify_time);
2934 push(@loginLogIDs,$courseID);
2935 } else {
2936 $coursesData{$courseID}{'local_modify_time'} = 'no login.log'; #this should never be the case except for the model course
2937 push(@noLoginLogIDs,$courseID);
2938 }
2939 if (-f "$coursesDir/$courseID/hide_directory") {
2940 $coursesData{$courseID}{'status'} = 'hidden';
2941 } else {
2942 $coursesData{$courseID}{'status'} = 'visible';
2943 }
2944 $courseLabels{$courseID} = "$courseID ($coursesData{$courseID}{'status'} :: $coursesData{$courseID}{'local_modify_time'}) ";
2945 }
2946 if ($hide_listing_format eq 'last_login') {
2947 @noLoginLogIDs = sort {lc($a) cmp lc ($b) } @noLoginLogIDs; #this should be an empty arrey except for the model course
2948 @loginLogIDs = sort byLoginActivity @loginLogIDs; # oldest first
2949 @hideCourseIDs = (@noLoginLogIDs,@loginLogIDs);
2950 } else { # in this case we sort alphabetically
2951 @hideCourseIDs = sort {lc($a) cmp lc ($b) } @courseIDs;
2952 }
2953
2954 print CGI::h2("Hide Inactive courses");
2955
2956 print CGI::p(
2957 'Select the course(s) you want to hide (or unhide) and then click "Hide Courses" (or "Unhide Courses"). Hiding
2958 a course that is already hidden does no harm (the action is skipped). Likewise unhiding a course that is
2959 already visible does no harm (the action is skipped). Hidden courses are still active but are not listed in
2960 the list of WeBWorK courses on the opening page. To access the course, an instructor or student must know the
2961 full URL address for the course.'
2962 );
2963
2964 print CGI::p(
2965 'Courses are listed either alphabetically or in order by the time of most recent login activity, oldest first.
2966 To change the listing order check the mode you want and click "Refresh Listing". The listing format is:
2967 Course_Name (status :: date/time of most recent login) where status is "hidden" or "visible".');
2968
2969
2970 print CGI::start_form(-method=>"POST", -action=>$r->uri);
2971
2972 my %list_labels = (
2973 alphabetically => 'alphabetically',
2974 last_login => 'by last login date',
2975 );
2976
2977 print CGI::table(
2978 CGI::Tr({},
2979 CGI::p("Select a listing format:"),
2980 CGI::radio_group(-name=>'hide_listing_format',
2981 -values=>['alphabetically', 'last_login'],
2982 -default=>'last_login',
2983 -labels=>\%list_labels,
2984 ),
2985 ),
2986 );
2987 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"hide_course_refresh", -value=>"Refresh Listing"), CGI::submit(-name=>"hide_course", -value=>"Hide Courses"),
2988 CGI::submit(-name=>"unhide_course", -value=>"Unhide Courses"));
2989 print $self->hidden_authen_fields;
2990 print $self->hidden_fields("subDisplay");
2991
2992 print CGI::p("Select course(s) to hide or unhide.");
2993
2994 print CGI::table({class=>"FormLayout"},
2995 CGI::Tr({},
2996 CGI::td(
2997 CGI::scrolling_list(
2998 -name => "hide_courseIDs",
2999 -values => \@hideCourseIDs,
3000 -size => 15,
3001 -multiple => 1,
3002 -labels => \%courseLabels,
3003 ),
3004 ),
3005
3006 ),
3007 );
3008
3009 print CGI::p({style=>"text-align: center"}, CGI::submit(-name=>"hide_course_refresh", -value=>"Refresh Listing"), CGI::submit(-name=>"hide_course", -value=>"Hide Courses"),
3010 CGI::submit(-name=>"unhide_course", -value=>"Unhide Courses"));
3011
3012 print CGI::end_form();
3013}
3014
3015sub hide_course_validate {
3016 my ($self) = @_;
3017 my $r = $self->r;
3018 my $ce = $r->ce;
3019 #my $db = $r->db;
3020 #my $authz = $r->authz;
3021 my $urlpath = $r->urlpath;
3022
3023 my @hide_courseIDs = $r->param("hide_courseIDs");
3024 @hide_courseIDs = () unless @hide_courseIDs;
3025
3026 my @errors;
3027
3028 unless (@hide_courseIDs) {
3029 push @errors, "You must specify a course name.";
3030 }
3031 return @errors;
3032}
3033
3034
3035sub do_hide_inactive_course {
3036 my ($self) = @_;
3037 my $r = $self->r;
3038 my $ce = $r->ce;
3039
3040 my $coursesDir = $ce->{webworkDirs}->{courses};
3041
3042 my $hide_courseID;
3043 my @hide_courseIDs = $r->param("hide_courseIDs");
3044 @hide_courseIDs = () unless @hide_courseIDs;
3045
3046 my $hideDirFileContent = 'Place a file named "hide_directory" in a course or other directory
3047and it will not show up in the courses list on the WeBWorK home page.
3048It will still appear in the Course Administration listing.';
3049 my @succeeded_courses = ();
3050 my $succeeded_count = 0;
3051 my @failed_courses = ();
3052 my $already_hidden_count = 0;
3053
3054 foreach $hide_courseID (@hide_courseIDs) {
3055 my $hideDirFile = "$coursesDir/$hide_courseID/hide_directory";
3056 if (-f $hideDirFile) {
3057 $already_hidden_count++;
3058 next;
3059 } else {
3060 local *HIDEFILE;
3061 if (open (HIDEFILE, ">", $hideDirFile)) {
3062 print HIDEFILE "$hideDirFileContent";
3063 close HIDEFILE;
3064 push @succeeded_courses,$hide_courseID;
3065 $succeeded_count++;
3066 } else {
3067 push @failed_courses,$hide_courseID;
3068 }
3069 }
3070 }
3071
3072 if (@failed_courses) {
3073 print CGI::div({class=>"ResultsWithError"},
3074 CGI::p("Errors occured while hiding the courses listed below when attempting to create the file hide_directory in the course's directory.
3075Check the ownership and permissions of the course's directory, e.g $coursesDir/$failed_courses[0]/"),
3076 CGI::p("@failed_courses"),
3077 );
3078 }
3079 my $succeeded_message = '';
3080
3081 if ($succeeded_count < 1 and $already_hidden_count > 0) {
3082 $succeeded_message = "Except for possible errors listed above, all selected courses are already hidden.";
3083 }
3084
3085 if ($succeeded_count) {
3086 if ($succeeded_count < 6) {
3087 $succeeded_message = "The following courses were successfully hidden: @succeeded_courses";
3088 } else {
3089 $succeeded_message = "$succeeded_count courses were successfully hidden.";
3090 }
3091 }
3092 if ($succeeded_count or $already_hidden_count) {
3093 print CGI::div({class=>"ResultsWithoutError"},
3094 CGI::p("$succeeded_message"),
3095 );
3096 }
3097}
3098
3099sub unhide_course_validate {
3100 my ($self) = @_;
3101 my $r = $self->r;
3102 my $ce = $r->ce;
3103 #my $db = $r->db;
3104 #my $authz = $r->authz;
3105 my $urlpath = $r->urlpath;
3106
3107 my @unhide_courseIDs = $r->param("hide_courseIDs");
3108 @unhide_courseIDs = () unless @unhide_courseIDs;
3109
3110 my @errors;
3111
3112 unless (@unhide_courseIDs) {
3113 push @errors, "You must specify a course name.";
3114 }
3115 return @errors;
3116}
3117
3118
3119sub do_unhide_inactive_course {
3120 my ($self) = @_;
3121 my $r = $self->r;
3122 my $ce = $r->ce;
3123
3124 my $coursesDir = $ce->{webworkDirs}->{courses};
3125
3126 my $unhide_courseID;
3127 my @unhide_courseIDs = $r->param("hide_courseIDs");
3128 @unhide_courseIDs = () unless @unhide_courseIDs;
3129
3130 my @succeeded_courses = ();
3131 my $succeeded_count = 0;
3132 my @failed_courses = ();
3133 my $already_visible_count = 0;
3134
3135 foreach $unhide_courseID (@unhide_courseIDs) {
3136 my $hideDirFile = "$coursesDir/$unhide_courseID/hide_directory";
3137 unless (-f $hideDirFile) {
3138 $already_visible_count++;
3139 next;
3140 }
3141 remove_tree("$hideDirFile", {error => \my $err});
3142 if (@$err) {
3143 push @failed_courses,$unhide_courseID;
3144 } else {
3145 push @succeeded_courses,$unhide_courseID;
3146 $succeeded_count++;
3147 }
3148 }
3149 my $succeeded_message = '';
3150
3151 if ($succeeded_count < 1 and $already_visible_count > 0) {
3152 $succeeded_message = "Except for possible errors listed above, all selected courses are already unhidden.";
3153 }
3154
3155 if ($succeeded_count) {
3156 if ($succeeded_count < 6) {
3157 $succeeded_message = "The following courses were successfully unhidden: @succeeded_courses";
3158 } else {
3159 $succeeded_message = "$succeeded_count courses were successfully unhidden.";
3160 }
3161 }
3162 if ($succeeded_count or $already_visible_count) {
3163 print CGI::div({class=>"ResultsWithoutError"},
3164 CGI::p("$succeeded_message"),
3165 );
3166 }
3167 if (@failed_courses) {
3168 print CGI::div({class=>"ResultsWithError"},
3169 CGI::p("Errors occured while unhiding the courses listed below when attempting delete the file hide_directory in the course's directory.
3170Check the ownership and permissions of the course's directory, e.g $coursesDir/$failed_courses[0]/"),
3171 CGI::p("@failed_courses"),
3172 );
3173 }
3174}
3175
3176
3177
2754################################################################################ 3178################################################################################
2755# registration forms added by Mike Gage 5-5-2008 3179# registration forms added by Mike Gage 5-5-2008
2756################################################################################ 3180################################################################################
2757 3181
2758our $registered_file_name = "registered_$main::VERSION"; 3182our $registered_file_name = "registered_$main::VERSION";
2785 q! 3209 q!
2786 </td></tr> 3210 </td></tr>
2787 </table> 3211 </table>
2788 </center> 3212 </center>
2789 !; 3213 !;
2790
2791
2792
2793} 3214}
2794 3215
2795sub registration_form { 3216sub registration_form {
2796 my $self = shift; 3217 my $self = shift;
2797 my $ce = $self->r->ce; 3218 my $ce = $self->r->ce;

Legend:
Removed from v.7139  
changed lines
  Added in v.7140

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9