Parent Directory
|
Revision Log
Revision 5319 - (view) (download)
| 1 : | jj | 2408 | #!/usr/bin/env perl |
| 2 : | ################################################################################ | ||
| 3 : | # WeBWorK Online Homework Delivery System | ||
| 4 : | sh002i | 5319 | # Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ |
| 5 : | # $CVSHeader: webwork2/bin/remove_stale_images,v 1.4 2006/01/25 23:13:45 sh002i Exp $ | ||
| 6 : | jj | 2408 | # |
| 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 : | remove_stale_images - remove old dvipng images | ||
| 21 : | |||
| 22 : | =head1 SYNOPSIS | ||
| 23 : | |||
| 24 : | remove_stale_images ARGUMENTS | ||
| 25 : | |||
| 26 : | =head1 DESCRIPTION | ||
| 27 : | |||
| 28 : | Remove old dvipng images. | ||
| 29 : | |||
| 30 : | =head1 ARGUMENTS | ||
| 31 : | |||
| 32 : | =over | ||
| 33 : | |||
| 34 : | Arguments are optional. | ||
| 35 : | |||
| 36 : | --help prints the usage message | ||
| 37 : | --delete delete selected images | ||
| 38 : | --remove same as --delete | ||
| 39 : | --report just report information about image dates | ||
| 40 : | |||
| 41 : | --days=E final date for images considered is E days ago | ||
| 42 : | E can be a decimal. E defaults to 7 days ago | ||
| 43 : | for deleting, and now for reporting | ||
| 44 : | --access-dates use last-accessed date, the default | ||
| 45 : | --modify-dates use last-modified date (probably the creation date) | ||
| 46 : | |||
| 47 : | --from=D start deleting D days ago; D can be a decimal | ||
| 48 : | defaulting at the beginning of time | ||
| 49 : | |||
| 50 : | |||
| 51 : | You can also just specify E at the end of the command line. | ||
| 52 : | |||
| 53 : | To get a status report on all of your images, use | ||
| 54 : | |||
| 55 : | remove_stale_images | ||
| 56 : | |||
| 57 : | To remove all which have not been accessed in the past 10 days, use | ||
| 58 : | |||
| 59 : | remove_stale_images --delete --days=10 | ||
| 60 : | |||
| 61 : | =cut | ||
| 62 : | |||
| 63 : | use strict; | ||
| 64 : | use warnings; | ||
| 65 : | use Getopt::Long; | ||
| 66 : | use Pod::Usage; | ||
| 67 : | use File::Find; | ||
| 68 : | |||
| 69 : | BEGIN { | ||
| 70 : | die "WEBWORK_ROOT not found in environment.\n" | ||
| 71 : | unless exists $ENV{WEBWORK_ROOT}; | ||
| 72 : | } | ||
| 73 : | |||
| 74 : | use lib "$ENV{WEBWORK_ROOT}/lib"; | ||
| 75 : | use WeBWorK::CourseEnvironment; | ||
| 76 : | use WeBWorK::Utils qw(runtime_use readFile); | ||
| 77 : | |||
| 78 : | use constant ACCESSED => 8; | ||
| 79 : | use constant MODIFIED => 9; | ||
| 80 : | |||
| 81 : | my $now = time(); | ||
| 82 : | my $which = ACCESSED; | ||
| 83 : | |||
| 84 : | ##### global variables to hold information from the find | ||
| 85 : | |||
| 86 : | my $num_removed = 0; | ||
| 87 : | my %kept = (); | ||
| 88 : | my %days=(); | ||
| 89 : | my %week=(); | ||
| 90 : | my $grandtotal=0; | ||
| 91 : | |||
| 92 : | ##### get command-line options ##### | ||
| 93 : | |||
| 94 : | my $start = $now; # way too big, but definitely before the beginning of the epoch | ||
| 95 : | my $end = -1; | ||
| 96 : | my $help = 0; | ||
| 97 : | my $deloption = 0; | ||
| 98 : | my $reportoption = 0; | ||
| 99 : | my $modifydate = 0; | ||
| 100 : | my $accessdate = 0; | ||
| 101 : | |||
| 102 : | GetOptions('from=s' => \$start, | ||
| 103 : | 'days=s' => \$end, | ||
| 104 : | 'delete|remove' => \$deloption, | ||
| 105 : | 'report' => \$reportoption, | ||
| 106 : | 'modify-dates' => \$modifydate, | ||
| 107 : | 'access-dates' => \$accessdate, | ||
| 108 : | 'help' => \$help) or pod2usage(1); | ||
| 109 : | |||
| 110 : | pod2usage(1) if $help; | ||
| 111 : | |||
| 112 : | $reportoption = 1 if(not $deloption); | ||
| 113 : | |||
| 114 : | if($modifydate and $accessdate) { | ||
| 115 : | print "You cannot specify using both access dates and modify dates\n"; | ||
| 116 : | pod2usage(1); | ||
| 117 : | } | ||
| 118 : | |||
| 119 : | ## now fix up type | ||
| 120 : | my $type = $accessdate ? ACCESSED : MODIFIED; | ||
| 121 : | |||
| 122 : | if(scalar(@ARGV)>0) { | ||
| 123 : | if(scalar(@ARGV)>1) { | ||
| 124 : | print "Too many arguments given\n"; | ||
| 125 : | pod2usage(1); | ||
| 126 : | } | ||
| 127 : | $end = $ARGV[0]; | ||
| 128 : | } | ||
| 129 : | |||
| 130 : | $end = 7 if($end == -1 and $deloption); | ||
| 131 : | |||
| 132 : | if($start<= $end) { | ||
| 133 : | print "The start time must be greater than the end length\n"; | ||
| 134 : | exit(); | ||
| 135 : | } | ||
| 136 : | ## Fix up the start and end times | ||
| 137 : | |||
| 138 : | $start = $now - 24*60*60*$start; | ||
| 139 : | $end = $now - 24*60*60*$end; | ||
| 140 : | |||
| 141 : | ##### "wanted" function for find ##### | ||
| 142 : | |||
| 143 : | sub wanted { | ||
| 144 : | if(-f $File::Find::name and $File::Find::name =~ /\.png$/) { | ||
| 145 : | my @stat = stat(_); | ||
| 146 : | |||
| 147 : | jj | 2411 | if($deloption) { |
| 148 : | jj | 2408 | my $fullmd5 = $File::Find::name; |
| 149 : | if(length($_) > (4+32)) { # this is an old style path | ||
| 150 : | $fullmd5 = $_; | ||
| 151 : | $fullmd5 =~ s/\.png$//; | ||
| 152 : | } else { | ||
| 153 : | $fullmd5 =~ s|.*/([^/]+)/([^/]+)$|$1$2|; | ||
| 154 : | $fullmd5 =~ s/\.png$//; | ||
| 155 : | } | ||
| 156 : | if($stat[$type]<$start or $stat[$type]>$end) { | ||
| 157 : | $kept{$fullmd5} = ''; | ||
| 158 : | } else { | ||
| 159 : | jj | 2411 | my $result = unlink($File::Find::name); |
| 160 : | if($result) { | ||
| 161 : | $num_removed++; | ||
| 162 : | return(); | ||
| 163 : | } else { | ||
| 164 : | # If you don't have permissions to delete a file, you will probably | ||
| 165 : | # mess up the permissions on the equation cache | ||
| 166 : | die "Tried, but could not remove $File::Find::name\n"; | ||
| 167 : | } | ||
| 168 : | jj | 2408 | } |
| 169 : | } | ||
| 170 : | jj | 2411 | |
| 171 : | if($reportoption) { | ||
| 172 : | return() if(not $deloption and ($stat[$type]<$start or $stat[$type]>$end)); | ||
| 173 : | my $lapse = $now - $stat[$type]; | ||
| 174 : | my $val = int(($lapse)/(60*60*24)); | ||
| 175 : | $val = " ".$val if($val<10); | ||
| 176 : | $val = " ".$val if($val<100); | ||
| 177 : | if(defined($days{$val})) {$days{$val} += 1;} else {$days{$val} = 1;} | ||
| 178 : | $val = int($val/7); | ||
| 179 : | if(defined($week{$val})) {$week{$val} += 1;} else {$week{$val} = 1;} | ||
| 180 : | $grandtotal++; | ||
| 181 : | } | ||
| 182 : | |||
| 183 : | jj | 2408 | } |
| 184 : | } | ||
| 185 : | |||
| 186 : | ##### reporting function ##### | ||
| 187 : | |||
| 188 : | sub count_report { | ||
| 189 : | my $j; | ||
| 190 : | print "Days\n"; | ||
| 191 : | for $j (sort keys(%days)) { | ||
| 192 : | print "$j $days{$j}\n"; | ||
| 193 : | } | ||
| 194 : | |||
| 195 : | print "\nWeeks\n"; | ||
| 196 : | for $j (sort keys(%week)) { | ||
| 197 : | print " $j $week{$j}\n"; | ||
| 198 : | } | ||
| 199 : | |||
| 200 : | print "\nTotal: $grandtotal\n"; | ||
| 201 : | } | ||
| 202 : | |||
| 203 : | ##### main function ##### | ||
| 204 : | |||
| 205 : | |||
| 206 : | # bring up a minimal course environment | ||
| 207 : | sh002i | 2819 | my $ce = WeBWorK::CourseEnvironment->new({ webwork_dir => $ENV{WEBWORK_ROOT} }); |
| 208 : | |||
| 209 : | jj | 2408 | my $dirHead = $ce->{webworkDirs}->{equationCache}; |
| 210 : | my $cachePath = $ce->{webworkFiles}->{equationCacheDB}; | ||
| 211 : | my $tmpdir = $ce->{webworkDirs}->{tmp}; | ||
| 212 : | my $tmpfile = "$tmpdir/equationcache.tmp"; | ||
| 213 : | |||
| 214 : | find({wanted => \&wanted, follow_fast => 1}, $dirHead); | ||
| 215 : | |||
| 216 : | jj | 2411 | print "Removed $num_removed images.\n\n" if($deloption); |
| 217 : | jj | 2408 | count_report() if($reportoption); |
| 218 : | jj | 2411 | |
| 219 : | ## The rest is updating the equation cache if we deleted images and there is a cache | ||
| 220 : | exit() unless($deloption and $num_removed); | ||
| 221 : | exit() unless ($cachePath); | ||
| 222 : | print "Updating the equation cache\n"; | ||
| 223 : | jj | 2408 | my ($perms, $uid, $groupID) = (stat $cachePath)[2,4,5]; #Get values from current cache file |
| 224 : | my $cachevalues = readFile($cachePath); | ||
| 225 : | my @cachelines = split "\n", $cachevalues; | ||
| 226 : | my $ent; | ||
| 227 : | for $ent (@cachelines) { | ||
| 228 : | chomp($ent); | ||
| 229 : | my $entmd5 = $ent; | ||
| 230 : | $entmd5 =~ s/^(\S+)\s+(\S+)\s+.*$/$1$2/; | ||
| 231 : | if(defined($kept{$entmd5})) { | ||
| 232 : | $kept{$entmd5} = $ent; | ||
| 233 : | } | ||
| 234 : | } | ||
| 235 : | |||
| 236 : | jj | 2411 | #print "Temp file $tmpfile\n"; |
| 237 : | #print "Cache file had group $groupID and perms $perms\n"; | ||
| 238 : | jj | 2408 | open(OUTF, ">$tmpfile") or die "Could not write to temp file $tmpfile"; |
| 239 : | for $ent (keys %kept) { | ||
| 240 : | if($kept{$ent}) { | ||
| 241 : | print OUTF $kept{$ent}."\n"; | ||
| 242 : | } else {print "could not find $ent\n";} | ||
| 243 : | } | ||
| 244 : | close(OUTF); | ||
| 245 : | rename($tmpfile, $cachePath); | ||
| 246 : | # hopefully, either we are superuser and this works, or we are | ||
| 247 : | # the web server in which case it wasn't needed | ||
| 248 : | chmod $perms, $cachePath; | ||
| 249 : | chown $uid, $groupID, $cachePath; | ||
| 250 : | |||
| 251 : | |||
| 252 : | |||
| 253 : | |||
| 254 : |
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |