2
# Makes a zip file of the most recent files in a specified directory.
3
# By Rudi Farkas, rudif@bluemail.ch, 9 December 2000
5
# ziprecent <dir> -d <ageDays> [-e <ext> ...]> [-h] [-msvc] [-q] [<zippath>]
6
# Zips files in source directory and its subdirectories
7
# whose file extension is in specified extensions (default: any extension).
8
# -d <days> max age (days) for files to be zipped (default: 1 day)
9
# <dir> source directory
10
# -e <ext> one or more space-separated extensions
11
# -h print help text and exit
12
# -msvc may be given instead of -e and will zip all msvc source files
13
# -q query only (list files but don't zip)
14
# <zippath>.zip path to zipfile to be created (or updated if it exists)
20
use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
27
# argument and variable defaults
29
my $maxFileAgeDays = 1;
30
my $defaultzipdir = 'h:/zip/_homework';
31
my ($sourcedir, $zipdir, $zippath, @extensions, $query);
36
my $scriptname = basename $0;
37
my $usage = <<ENDUSAGE;
38
$scriptname <dir> -d <ageDays> [-e <ext> ...]> [-h] [-msvc] [-q] [<zippath>]
39
Zips files in source directory and its subdirectories
40
whose file extension is in specified extensions (default: any extension).
41
-d <days> max age (days) for files to be zipped (default: 1 day)
42
<dir> source directory
43
-e <ext> one or more space-separated extensions
44
-h print help text and exit
45
-msvc may be given instead of -e and will zip all msvc source files
46
-q query only (list files but don't zip)
47
<zippath>.zip path to zipfile to be created (or updated if it exists)
57
$maxFileAgeDays = shift;
58
$maxFileAgeDays = 0.0 if $maxFileAgeDays < 0.0;
60
elsif ($arg eq '-e') {
61
while ($ARGV[0] && $ARGV[0] !~ /^-/) {
62
push @extensions, shift;
65
elsif ($arg eq '-msvc') {
66
push @extensions, qw / bmp c cpp def dlg dsp dsw h ico idl mak odl rc rc2 rgs /;
68
elsif ($arg eq '-q') {
71
elsif ($arg eq '-h') {
78
elsif ($arg eq '-z') {
83
elsif ($arg =~ /\.zip$/) {
87
errorExit("Unknown option or argument: $arg");
93
errorExit("Please specify an existing source directory") unless defined($sourcedir) && -d $sourcedir;
97
$extensions = join "|", @extensions;
103
# change '\' to '/' (avoids trouble in substitution on Win2k)
105
$sourcedir =~ s|\\|/|g;
106
$zippath =~ s|\\|/|g if defined($zippath);
113
find(\&listFiles, $sourcedir);
114
printf STDERR "Found %d file(s)\n", scalar @files;
123
# prepare zip directory
125
if (defined($zippath)) {
126
# deduce directory from zip path
127
$zipdir = dirname($zippath);
128
$zipdir = '.' unless length $zipdir;
131
$zipdir= $defaultzipdir;
134
# make sure that zip directory exists
136
mkpath $zipdir unless -d $zipdir;
137
-d $zipdir or die "Can't find/make directory $zipdir\n";
141
# create the zip object
143
my $zip = Archive::Zip->new();
146
# read-in the existing zip file if any
148
if (defined $zippath && -f $zippath) {
149
my $status = $zip->read($zippath);
150
warn "Read $zippath failed\n" if $status != AZ_OK;
155
foreach my $memberName (@files)
159
warn "Can't add tree $memberName\n"
160
if $zip->addTree( $memberName, $memberName ) != AZ_OK;
164
$zip->addFile( $memberName )
165
or warn "Can't add file $memberName\n";
170
# prepare the new zip path
172
my $newzipfile = genfilename();
173
my $newzippath = "$zipdir/$newzipfile";
176
# write the new zip file
178
my $status = $zip->writeToFileNamed($newzippath);
179
if ($status == AZ_OK) {
180
# rename (and overwrite the old zip file if any)?
182
if (defined $zippath) {
183
my $res = rename $newzippath, $zippath;
185
print STDERR "Updated file $zippath\n";
188
print STDERR "Created file $newzippath, failed to rename to $zippath\n";
192
print STDERR "Created file $newzippath\n";
196
print STDERR "Failed to create file $newzippath\n";
205
if (/\.($extensions)$/) {
206
cwd $File::Find::dir;
207
return if -d $File::Find::name; # skip directories
208
my $fileagedays = fileAgeDays($_);
209
if ($fileagedays < $maxFileAgeDays) {
210
printf STDERR "$File::Find::name (%.3g)\n", $fileagedays;
211
(my $filename = $File::Find::name) =~ s/^[a-zA-Z]://; # remove the leading drive letter:
212
push @files, $filename;
218
printf STDERR "*** %s ***\n$usage\n", shift;
227
(time() - mtime(shift)) / 86400;
231
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
232
sprintf "%04d%02d%02d-%02d%02d%02d.zip", $year+1900, $mon+1, $mday, $hour, $min, $sec;
245
ziprecent h:/myperl -e pl pm -d 365
247
ziprecent h:/myperl -q
249
ziprecent h:/myperl h:/temp/zip/file1.zip
256
This script helps to collect recently modified files in a source directory
257
into a zip file (new or existing).
259
It uses Archive::Zip.
261
=item C< ziprecent h:/myperl >
263
Lists and zips all files more recent than 1 day (24 hours)
264
in directory h:/myperl and it's subdirectories,
265
and places the zip file into default zip directory.
266
The generated zip file name is based on local time (e.g. 20001208-231237.zip).
269
=item C< ziprecent h:/myperl -e pl pm -d 365 >
271
Zips only .pl and .pm files more recent than one year.
274
=item C< ziprecent h:/myperl -msvc >
276
Zips source files found in a typical MSVC project.
279
=item C< ziprecent h:/myperl -q >
281
Lists files that should be zipped.
284
=item C< ziprecent h:/myperl h:/temp/zip/file1.zip >
286
Updates file named h:/temp/zip/file1.zip
287
(overwrites an existing file if writable).
290
=item C< ziprecent -h >
292
Prints the help text and exits.
294
ziprecent.pl <dir> -d <days> [-e <ext> ...]> [-h] [-msvc] [-q] [<zippath>]
295
Zips files in source directory and its subdirectories
296
whose file extension is in specified extensions (default: any extension).
297
-d <days> max age (days) for files to be zipped (default: 1 day)
298
<dir> source directory
299
-e <ext> one or more space-separated extensions
300
-h print help text and exit
301
-msvc may be given instead of -e and will zip all msvc source files
302
-q query only (list files but don't zip)
303
<zippath>.zip path to zipfile to be created (or updated if it exists)
310
Tested only on Win2k.
312
Does not handle filenames without extension.
314
Does not accept more than one source directory (workaround: invoke separately
315
for each directory, specifying the same zip file).
320
Rudi Farkas rudif@lecroy.com rudif@bluemail.ch