| … | |
… | |
| 15 | ################################################################################ |
15 | ################################################################################ |
| 16 | |
16 | |
| 17 | package WeBWorK::ContentGenerator::Instructor::FileManager; |
17 | package WeBWorK::ContentGenerator::Instructor::FileManager; |
| 18 | use base qw(WeBWorK::ContentGenerator::Instructor); |
18 | use base qw(WeBWorK::ContentGenerator::Instructor); |
| 19 | |
19 | |
| 20 | use WeBWorK::Utils qw(readDirectory readFile sortByName); |
20 | use WeBWorK::Utils qw(readDirectory readFile sortByName listFilesRecursive); |
| 21 | use WeBWorK::Upload; |
21 | use WeBWorK::Upload; |
| 22 | use File::Path; |
22 | use File::Path; |
| 23 | use File::Copy; |
23 | use File::Copy; |
| 24 | use File::Spec; |
24 | use File::Spec; |
| 25 | use String::ShellQuote; |
25 | use String::ShellQuote; |
| … | |
… | |
| 600 | # |
600 | # |
| 601 | # If confirmed, go ahead and delete the files |
601 | # If confirmed, go ahead and delete the files |
| 602 | # |
602 | # |
| 603 | foreach my $file (@files) { |
603 | foreach my $file (@files) { |
| 604 | if (defined $self->checkPWD("$pwd/$file",1)) { |
604 | if (defined $self->checkPWD("$pwd/$file",1)) { |
| 605 | if (-d "$dir/$file") { |
605 | if (-d "$dir/$file" && !-l "$dir/$file") { |
| 606 | my $removed = eval {rmtree("$dir/$file",0,1)}; |
606 | my $removed = eval {rmtree("$dir/$file",0,1)}; |
| 607 | if ($removed) {$self->addgoodmessage("Directory '$file' removed (items deleted: $removed)")} |
607 | if ($removed) {$self->addgoodmessage("Directory '$file' removed (items deleted: $removed)")} |
| 608 | else {$self->addbadmessage("Directory '$file' not removed: $!")} |
608 | else {$self->addbadmessage("Directory '$file' not removed: $!")} |
| 609 | } else { |
609 | } else { |
| 610 | if (unlink("$dir/$file")) {$self->addgoodmessage("File '$file' successfully removed")} |
610 | if (unlink("$dir/$file")) {$self->addgoodmessage("File '$file' successfully removed")} |
| … | |
… | |
| 615 | $self->Refresh; |
615 | $self->Refresh; |
| 616 | |
616 | |
| 617 | } else { |
617 | } else { |
| 618 | |
618 | |
| 619 | # |
619 | # |
|
|
620 | # Look up the files to be deleted, and for directories, add / and the contents of the directory |
|
|
621 | # |
|
|
622 | my @filelist = (); |
|
|
623 | foreach my $file (@files) { |
|
|
624 | if (defined $self->checkPWD("$pwd/$file",1)) { |
|
|
625 | if (-l "$dir/$file") { |
|
|
626 | push(@filelist,"$file@"); |
|
|
627 | } elsif (-d "$dir/$file") { |
|
|
628 | my @contents = (); my $dcount = 0; |
|
|
629 | foreach my $item (readDirectory("$dir/$file")) { |
|
|
630 | next if $item eq "." || $item eq ".."; |
|
|
631 | if (-l "$dir/$file/$item") { |
|
|
632 | push(@contents, "$item@"); |
|
|
633 | } elsif (-d "$dir/$file/$item") { |
|
|
634 | my $count = scalar(listFilesRecursive("$dir/$file/$item",".*")); |
|
|
635 | my $s = ($count == 1 ? "" : "s"); $dcount += $count; |
|
|
636 | push (@contents, "$item/".CGI::small({style=>"float:right;margin-right:3em"},CGI::i("($count item$s)"))); |
|
|
637 | } else { |
|
|
638 | push(@contents, $item); |
|
|
639 | } |
|
|
640 | $dcount += 1; |
|
|
641 | } |
|
|
642 | my $s = ($dcount == 1 ? "": "s"); |
|
|
643 | @contents = (@contents[0..10]," ."," ."," .") if scalar(@contents) > 15; |
|
|
644 | push (@filelist,$file."/". |
|
|
645 | CGI::small({style=>"float:right;margin-right:4em"},CGI::i("($dcount item$s total)")). |
|
|
646 | CGI::div({style=>"margin-left:1ex"},join(CGI::br(),@contents))); |
|
|
647 | } else { |
|
|
648 | push(@filelist,$file); |
|
|
649 | } |
|
|
650 | } |
|
|
651 | } |
|
|
652 | |
|
|
653 | # |
| 620 | # Put up the confirmation dialog box |
654 | # Put up the confirmation dialog box |
| 621 | # |
655 | # |
| 622 | print CGI::start_table({border=>1,cellspacing=>2,cellpadding=>20, style=>"margin: 1em 0 0 5em"}); |
656 | print CGI::start_table({border=>1,cellspacing=>2,cellpadding=>20, style=>"margin: 1em 0 0 5em"}); |
| 623 | print CGI::Tr( |
657 | print CGI::Tr( |
| 624 | CGI::td( |
658 | CGI::td( |
| 625 | CGI::b("Warning:")," You have requested that the following items be deleted\n", |
659 | CGI::b("Warning:")," You have requested that the following items be deleted\n", |
| 626 | CGI::ul(CGI::li(\@files)), |
660 | CGI::ul(CGI::li(\@filelist)), |
| 627 | ((grep { -d "$dir/$_" } @files)? |
661 | ((grep { -d "$dir/$_" } @files)? |
| 628 | CGI::p({style=>"width:500"},"Some of these files are directories. ", |
662 | CGI::p({style=>"width:500"},"Some of these files are directories. ", |
| 629 | "Only delete directories if you really know what you are doing. ", |
663 | "Only delete directories if you really know what you are doing. ", |
| 630 | "You can seriously damage your course if you delete the wrong thing."): ""), |
664 | "You can seriously damage your course if you delete the wrong thing."): ""), |
| 631 | CGI::p({style=>"color:red"},"There is no undo for deleting files or directories!"), |
665 | CGI::p({style=>"color:red"},"There is no undo for deleting files or directories!"), |
| 632 | CGI::p("Really delete the items listed above?"), |
666 | CGI::p("Really delete the items listed above?"), |
| 633 | CGI::div({style=>"float:left; padding-left:3ex"}, |
667 | CGI::div({style=>"float:left; padding-left:3ex"}, |
| 634 | CGI::input({type=>"submit",name=>"action",value=>"Cancel"})), |
668 | CGI::input({type=>"submit",name=>"action",value=>"Cancel"})), |
| 635 | CGI::div({style=>"float:right; padding-right:3ex"}, |
669 | CGI::div({style=>"float:right; padding-right:3ex"}, |