#!/usr/bin/perl -w # Copyright © 2002-2012 Jamie Zawinski # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation. No representations are made about the suitability of this # software for any purpose. It is provided "as is" without express or # implied warranty. # # Created: 18-Apr-2002. # # Script for automating the conversion of outside promoters' jpegs. # Creates the right file names, front and back images, and thumbnails, # all with a 40% gray 1 pixel border. require 5; use diagnostics; use strict; my $progname = $0; $progname =~ s@.*/@@g; my $version = q{ $Revision: 1.121 $ }; $version =~ s/^[^0-9]+([0-9.]+).*$/$1/; my $verbose = 0; my $debug_p = 0; my $bdcolor = "#666666"; my $flyer_dir = "flyers"; my $names_file = "calendar/names.txt"; my %event_names; # maps dates to pretty event names my @months = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); my %monthvals = ( 'jan' => 1, 'january' => 1, 'february' => 2, 'feb' => 2, 'march' => 3, 'mar' => 3, 'april' => 4, 'apr' => 4, 'may' => 5, 'jun' => 6, 'june' => 6, 'jul' => 7, 'july' => 7, 'august' => 8, 'aug' => 8, 'sep' => 9, 'sept' => 9, 'september' => 9, 'oct' => 10, 'october' => 10, 'nov' => 11, 'november' => 11, 'dec' => 12, 'december' => 12 ); sub safe_system(@) { my @cmd = @_; system (@cmd); my $exit_value = $? >> 8; my $signal_num = $? & 127; my $dumped_core = $? & 128; error ("$cmd[0]: core dumped!") if ($dumped_core); error ("$cmd[0]: signal $signal_num!") if ($signal_num); error ("$cmd[0]: exited with $exit_value!") if ($exit_value); } sub image_size($) { my ($file) = @_; error ("$file does not exist") unless ($debug_p || -f $file); return (0, 0) unless -f $file; # my $cmd = ("convert -density 300x300 '$file' " . ## ($file =~ m/\.(ps|eps|epsf|pdf|psd)$/i ? "-trim " : "") . # "info:"); $file =~ s/([\\"!])/\\$1/g; my $cmd = ("identify -format \"%wx%h \" \"$file\""); print STDERR "$progname: executing: $cmd\n" if ($verbose > 2); my $result = `$cmd`; print STDERR "$progname: ==> $result\n" if ($verbose > 2); my ($w, $h) = ($result =~ m/^(\d+)x(\d+)(\s|$)/); error ("no size: $file") unless ($w && $h); if ($file =~ m@\.pdf$@si) { # "identify -size" on PDF is nonsense. $w *= 10; # scale it up to something sensible. $h *= 10; } return ($w, $h); } # Populate the %event_names table. # sub load_event_names() { my $count = 0; print STDERR "$progname: reading $names_file\n" if ($verbose > 1); open (my $in, '<', $names_file) || error ("$names_file: $!"); my $body = ''; while (<$in>) { my ($date, $pres, $name) = m/^(\d{4}-\d\d-\d\d[ab]?)\t([^\t]*)\t\*?([^\t]+)/s; error ("unparsable: $_") unless ($name); $event_names{$date} = $name; $count++; } close $in; error ("no event names?") unless $count; print STDERR "$progname: $count names\n" if ($verbose > 1); } sub date_to_dir($) { my ($date) = @_; my ($dotm, $month, $year, $ord); if ($date =~ m!^(\d\d\d\d)[-/ ](\d\d)[-/ ](\d\d?)([ab]?)$!s) { ($dotm, $month, $year, $ord) = ($3, $2, $1, $4); } elsif ($date =~ m!^(\d\d?)([ab]?)[-/ ]([a-z]+)[-/ ](\d\d\d\d)([ab]?)$!s) { my $ord2; ($dotm, $ord, $month, $year, $ord2) = ($1, $2, $3, $4, $5); $ord = $ord || $ord2; $month =~ s/^(...).*$/$1/; $month =~ tr/A-Z/a-z/; $month = $monthvals{$month}; error ("unparsable date: $date") unless defined ($month); } else { error ("unparsable date: $date"); } error ("unparsable date: $date") if ($dotm == 0 || $dotm > 31 || $month == 0 || $month > 12 || $year < 1970); { my @now = localtime(); my $d1 = $year * 12 + $month; my $d2 = ($now[5]+1900) * 12 + ($now[4]+1); my $n = $d2 - $d1; # error ("$date was $n months ago, dumbass.") # if ($n >= 2); } error ("$flyer_dir: no such directory") unless (-d $flyer_dir); my $year_dir = sprintf ("%s/%04d", $flyer_dir, $year); mkdir ($year_dir) unless -d $year_dir; error ("$year_dir: no such directory") unless (-d $year_dir); my $month_dir = sprintf ("%s/%02d", $year_dir, $month); mkdir ($month_dir) unless -d $month_dir; error ("$month_dir: no such directory") unless (-d $month_dir); my $name = $event_names{sprintf("%04d-%02d-%02d$ord", $year, $month, $dotm)}; error ("no event on $date") unless $name; $dotm = sprintf("%02d%s", $dotm, $ord); return ($month_dir, $dotm, $name); } # Returns the highest numbered existing flyer file (0 if none.) # Also returns the file name. # sub existing_number($$) { my ($dir, $dotm) = @_; my $last_n = 0; my $last_f = undef; for (my $n = 0; $n < 9; $n++) { my $file = sprintf ("%s/%s-%s.jpg", $dir, $dotm, $n); if (-f $file) { $last_n = $n; $last_f = $file; } } return ($last_n, $last_f); } # Given the size of an image, pick the size to which we should scale it. # This is used for converting "raw" images to "full sized" images; and # for converting "full sized" images to thumbnails. # sub pick_image_size($$$) { my ($ow, $oh, $thumb_p) = @_; my $square_p = (int (($ow / 10) + 0.5) == # within 10% of square int (($oh / 10) + 0.5)); my $tall_p = ($oh > $ow); # portrait = 1, landscape = 0 my $square_size; # size of square images my $max_size; # max size of largest dimension of a rectangular image my $min_size; # min size of smallest dimension of a rectangular image if (!$thumb_p) { $square_size = 1024; # was 600 $max_size = 1280; # was 800 $min_size = 512; # was 360 } else { $square_size = 120; $max_size = ($tall_p ? 300 : 220); # very tall is ok, very wide is not. $min_size = 120; # If it's approximately 1x2 (or 2x1) then reduce min size. my $r = $oh ? (int($ow/5) / int($oh/5)) : 1; if ($r == 0.5 || $r == 2.0) { $min_size = 100; } # For the "dual" flyers, we always want them to be 250 wide. if ($thumb_p == 2) { $tall_p = 1; $square_p = 0; $min_size = 250 - 2; $max_size = 900; # For the "medium" flyers, we want them to be around 480 wide or tall. } elsif ($thumb_p == 3) { $square_size = 360; $max_size = 480; $min_size = 480; } } my ($nw, $nh); if ($square_p) { # square is the same for both. $nw = $square_size; $nh = $square_size; } elsif ($thumb_p) { # with thumbs, aim for min size. $nw = ($tall_p || !$oh ? $min_size : int ($min_size * ($ow / $oh))); $nh = ($tall_p && $ow ? int ($min_size * ($oh / $ow)) : $min_size); } else { # with non-thumbs, aim for max size. $nw = ($tall_p ? int ($max_size * ($ow / $oh)) : $max_size); $nh = ($tall_p ? $max_size : int ($max_size * ($oh / $ow))); } # Enforce max size for both. # if ($nw > $max_size) { $nw = $max_size; $nh = int ($max_size * ($oh / $ow)); } elsif ($nh > $max_size) { $nw = int ($max_size * ($ow / $oh)); $nh = $max_size; } # Enforce min size (only for non-thumbs). # if ($thumb_p) { } elsif ($nw < $min_size) { $nw = $min_size; $nh = int ($min_size * ($oh / $ow)); } elsif ($nh < $min_size) { $nw = int ($min_size * ($ow / $oh)); $nh = $min_size; } return ($nw, $nh); } # Converts the raw source images, to the "full sized" images. # Returns a list of the image files written. # sub make_images($$$$$$$$$$) { my ($dir, $dotm, $n, $thumb_p, $border_p, $crop, $stretch_p, $qual, $front, $back) = @_; my ($fw, $fh) = image_size ($front); my ($bw, $bh) = image_size ($back) if ($back); my ($ofw, $ofh) = ($fw, $fh); my ($obw, $obh) = ($bw, $bh); $crop = 0 if $thumb_p; if ($crop) { $fw -= $crop*2; $fh -= $crop*2; $bw -= $crop*2; $bh -= $crop*2; } my $dual_p = ($thumb_p == 2); my $med_p = ($thumb_p == 3); my ($fw2, $fh2) = pick_image_size ($fw, $fh, $thumb_p); my ($bw2, $bh2) = pick_image_size ($bw, $bh, $thumb_p) if ($back); # If the source images are not exactly the same shape, but are *very close*, # then just pretend the back image was the size of the front image, and # deform it to fit. # my $force_scale = 0; if ($back && !($fw2 == $bw2 && $fh2 == $bh2) && !($fw2 == $bh2 && $fh2 == $bw2)) { my $rotated_p = ($fh != 0 && $bh != 0 && (($fw/$fh < 1) != # rotate if aspect ratios differ ($bw/$bh < 1))); print STDERR "$progname: images are rotated: ${fw}x$fh vs ${bw}x$bh\n" if ($verbose > 1 && $rotated_p); if ($rotated_p && $thumb_p) { # When rotating a back flyer, make it the same size as the front. # Needed for 2009/01/16-hubbahubba.html. $bw2 = $fh2; $bh2 = $fw2; } my $fudge = 5; my $o1 = "${fw2}x$fh2 (${fw}x$fh)"; my $o2 = "${bw2}x$bh2 (${bw}x$bh)"; my $ok = (!$rotated_p ? ((abs ($fw2 - $bw2) < $fudge) && (abs ($fh2 - $bh2) < $fudge)) : ((abs ($fw2 - $bh2) < $fudge) && (abs ($fh2 - $bw2) < $fudge))); if ($ok || $stretch_p) { print STDERR "$progname: fudging" . ($ok ? " close-enough" : "") . " image sizes:\n" . "$progname: $front is $o1;\n" . "$progname: $back was $o2.\n" unless ($fw2 == $bh2 && $fh2 == $bw2); if (!$rotated_p) { ($bw2, $bh2) = ($fw2, $fh2); } else { ($bw2, $bh2) = ($fh2, $fw2); } $force_scale = 1; } } # If the source images are small, then don't scale them. # if (!$force_scale && ($fw < $fw2 || $fh < $fh2)) { print STDERR "$progname: $front: not scaling small flyer ($fw x $fh)\n"; $fw2 = $fw; $fh2 = $fh; $bw2 = $bw; $bh2 = $bh; } # The resultant images should be the exact same dimensions, modulo rotation. # if ($back && !($fw2 == $bw2 && $fh2 == $bh2) && !($fw2 == $bh2 && $fh2 == $bw2)) { my $e = ( "$front is ${fw}x$fh (${fw2}x$fh2);\n" . "$progname: $back is ${bw}x$bh (${bw2}x$bh2)"); if ($debug_p) { print STDERR "$progname: $e\n"; } else { error ($e); } } # When making thumbnails: # If the back image seems to be rotated 90 degrees from the front image, # (and is not square) then rotate it so that they are the same. # For non-thumbnails, leave it as-is. # my $rotate_back_p = ($back && $thumb_p && ($fw2 == $bh2 && $fh2 == $bw2 && $fw2 != $fh2)); my @files = (); my ($n1, $n2); if (! $med_p) { $n1 = $n . ($thumb_p ? "-thumb" : ""); $n2 = ($n+1) . ($thumb_p ? "-thumb" : ""); } if ($dual_p) { push @files, scale_dual_image ($front, $back, $dir, $dotm, $n1, $border_p, $crop, $qual, $rotate_back_p, $ofw, $ofh, $fw2, $fh2, $obw, $obh, $bw2, $bh2); } elsif ($med_p) { push @files, scale_image ($front, undef, $dir, $dotm, $n, $border_p, $crop, $qual, 0, $ofw, $ofh, $fw2, $fh2); } else { push @files, scale_image ($front, undef, $dir, $dotm, $n1, $border_p, $crop, $qual, 0, $ofw, $ofh, $fw2, $fh2); push @files, scale_image ($back, undef, $dir, $dotm, $n2, $border_p, $crop, $qual, $rotate_back_p, $obw, $obh, $bw2, $bh2) if ($back); } return @files; } sub flyerize($$$$$$$$$) { my ($date, $border_p, $crop, $stretch_p, $qual, $add_p, $second_p, $front, $back) = @_; my @files = (); my ($dir, $dotm, $event_name) = date_to_dir ($date); my ($last_n, $last_file) = existing_number ($dir, $dotm); my $n = ($add_p ? (($last_n + 1) | 1) : $second_p ? 3 : 1); error ("-2 was specified, but no flyers exist already") if ($add_p && $n == 1); error ("bogus crop: $crop") if (defined($crop) && "$crop" !~ m/^\d+$/); my $tqual = 95; # thumbs are always high quality (they're small regardless.) my (@main) = make_images($dir, $dotm, $n, 0, $border_p, $crop, $stretch_p, $qual, $front, $back); my (@thumb) = make_images($dir, $dotm, $n, 1, $border_p, $crop, 0, $tqual, $main[0], $main[1]); my (@dual) = make_images($dir, $dotm, $n, 2, $border_p, $crop, 0, $qual, $main[0], $main[1]) unless ($add_p || $second_p); my (@med) = make_images($dir, $dotm, 'm', 3, $border_p, $crop, 0, $qual, $main[0], $main[1]) unless ($add_p || $second_p); return (@main, @thumb, @dual, @med); } sub scale_image($$$$$$$$$$$$$) { my ($file, $outfile, $dir, $dotm, $n, $border_p, $crop, $qual, $rotate_p, $ow, $oh, $w2, $h2) = @_; error ("$dir: no such directory") unless (-d $dir); $outfile = sprintf ("%s/%s-%s.jpg", $dir, $dotm, $n) unless $outfile; # error ("$outfile already exists") if (-f $outfile); print STDERR "$progname: WARNING: $outfile exists, replacing...\n" if (-f $outfile); if ($rotate_p) { ($w2, $h2) = ($h2, $w2); } my ($w2i, $h2i) = ($w2, $h2); # internal size (not counting border) if ($border_p) { $w2i -= 2; $h2i -= 2; } $qual = int($qual); error ("bogus quality: $qual") if ($qual <= 50 || $qual > 100); $file .= '[0]' if ($file =~ m/\.psd$/i); # WTF? my @cmd = ("convert", "-density", "300x300", $file ); # push @cmd, "-trim" if ($file =~ m/\.(ps|eps|epsf|pdf)$/i); if ($crop) { push @cmd, ("-crop", sprintf ("%dx%d+%d+%d", $ow-$crop*2, $oh-$crop*2, $crop, $crop), "+repage"); } elsif (defined($crop) && $crop == 0) { # "-crop", "-crop 0" means auto. push @cmd, ("-fuzz", "1%", "-trim", "+repage"); } push @cmd, ("-rotate", "-90") if ($rotate_p); if ($ow != $w2i || $oh != $h2i) { push @cmd, ("-resize", "${w2i}x${h2i}!"); print STDERR "$progname: $file: scaling" . ($rotate_p ? "/rotating" : "") . " ${ow}x${oh}" . ($crop ? sprintf(" -> %dx%d+%d+%d", $ow-$crop*2, $oh-$crop*2, $crop, $crop) : "") . " -> ${w2}x${h2}\n" if ($verbose > 1); } push @cmd, ("-bordercolor", $bdcolor, "-border", "1") if ($border_p); push @cmd, ("-colorspace", "RGB", "-quality", $qual, "-strip", $outfile); if ($debug_p) { print STDERR "$progname: not running: " . join(' ', @cmd) . "\n" if ($verbose > 2); print STDERR "$progname: not writing $outfile (${w2} x $h2)\n" if ($verbose); if (-f $outfile) { my ($oow, $ooh) = image_size ($outfile); # if ($border_p) { $oow -= 2; $ooh -= 2; } $oow = $w2 if ($oow == $w2+1 || $oow == $w2-1); # ignore off-by-1 $ooh = $h2 if ($ooh == $h2+1 || $ooh == $h2-1); if ($w2 != $oow || $h2 != $ooh) { print STDERR "$progname: WARNING: would have changed $outfile\n" . "$progname: WARNING: from $oow x $ooh to $w2 x $h2\n"; } } return $outfile; } print STDERR "$progname: executing: " . join(' ', @cmd) . "\n" if ($verbose > 2); safe_system (@cmd); error ("$cmd[0] failed: $outfile does not exist") unless (-f $outfile); my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($outfile); my $k = int (($size + 1023) / 1024); ($w2, $h2) = image_size ($outfile); # be truthful, ok? print STDERR "$progname: wrote $outfile (${k}K, ${w2} x $h2)\n" if ($verbose && $outfile !~ m@^/tmp/@s); return $outfile; } sub scale_dual_image($$$$$$$$$$$$$) { my ($front, $back, $dir, $dotm, $n, $border_p, $crop, $qual, $rotate_back_p, $ofw, $ofh, $fw2, $fh2, $obw, $obh, $bw2, $bh2) = @_; my $outfile = sprintf ("%s/%s-0.jpg", $dir, $dotm); my $n1 = 0; # error ("$outfile already exists") if (-f $outfile); $qual = 89; if (! $back) { # If there is only one image, and it is very wide, rotate it, # and scale it up. my $aspect = $fw2 / $fh2; my $rotate_p = $aspect >= 2.5; if ($rotate_p) { $fw2 = int($fw2 * $aspect); $fh2 = int($fh2 * $aspect); } $fw2 += 2; # wtf? $fh2 += 2; # error ("$outfile is not 250 wide: $fw2 x $fh2") # if (($rotate_p ? $fh2 : $fw2) != 250); return scale_image ($front, $outfile, $dir, $dotm, $n1, $border_p, $crop, $qual, $rotate_p, $ofw, $ofh, $fw2, $fh2); } else { my $tmp1 = "/tmp/flyerize-01.jpg"; my $tmp2 = "/tmp/flyerize-02.jpg"; unlink $tmp1; unlink $tmp2; my $faspect = $fh2 ? $fw2 / $fh2 : 1; my $baspect = $bh2 ? $bw2 / $bh2 : 1; # If both images are really tall, put them side by side. # my $horiz_p = 0; if ($faspect <= 0.4 && $baspect <= 0.4) { $fw2 = int($fw2 / 2); $fh2 = int($fh2 / 2); $bw2 = int($bw2 / 2); $bh2 = int($bh2 / 2); $horiz_p = 1; } if ($fw2 != $bw2) { # If the back flyer is not the same width as the front flyer, # scale it to be the same width. The two sides won't be the # same size, but since we're stacking them, that doesn't matter. $bh2 = int ($bh2 * $fw2 / $bw2); $bw2 = $fw2; } # my $targ = ($horiz_p ? 124 : 250); # error("$outfile is not $targ wide: $fw2 x $fh2") if ($fw2 != $targ); # error("$outfile is not $targ wide: $bw2 x $bh2") if ($bw2 != $targ); scale_image ($front, $tmp1, $dir, $dotm, $n1, $border_p, $crop, $qual, 0, $ofw, $ofh, $fw2, $fh2); scale_image ($back, $tmp2, $dir, $dotm, $n1, $border_p, $crop, $qual, 0, $obw, $obh, $bw2, $bh2); my @cmd = ("convert", "-density", "300x300"); push @cmd, $tmp1; push @cmd, $tmp2; push @cmd, ($horiz_p ? "+append" : "-append"); push @cmd, ("-bordercolor", $bdcolor, "-border", "1") if ($border_p); push @cmd, ("-colorspace", "RGB", "-quality", $qual, "-strip", $outfile); my $w2 = $fh2; my $h2 = $fh2 + $bh2 + ($border_p ? 2 : 0); error ("widths don't match: $fw2 / $bw2 on $front / $back") if ($bw2 != 0 && $bw2 != $fw2); if ($debug_p) { print STDERR "$progname: not running: " . join(' ', @cmd) . "\n" if ($verbose > 2); print STDERR "$progname: not writing $outfile (${fw2} x $h2)\n" if ($verbose); if (-f $outfile) { my ($oow, $ooh) = image_size ($outfile); # if ($border_p) { $oow -= 2; $ooh -= 2; } $oow = $w2 if ($oow == $w2+1 || $oow == $w2-1); # ignore off-by-1 $ooh = $h2 if ($ooh == $h2+1 || $ooh == $h2-1); if ($w2 != $oow || $h2 != $ooh) { print STDERR "$progname: WARNING: would have changed $outfile\n" . "$progname: WARNING: from $oow x $ooh to $w2 x $h2\n"; } } return $outfile; } print STDERR "$progname: executing: " . join(' ', @cmd) . "\n" if ($verbose > 2); safe_system (@cmd); error ("$cmd[0] failed: $outfile does not exist") unless (-f $outfile); my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($outfile); my $k = int (($size + 1023) / 1024); ($w2, $h2) = image_size ($outfile); # be truthful, ok? print STDERR "$progname: wrote $outfile (${k}K, ${w2} x $h2)\n" if ($verbose); unlink $tmp1; unlink $tmp2; return $outfile; } } # Regenerate all thumbnails of the given event. # sub rethumb($$$$) { my ($dir, $dotm, $border_p, $dual_only_p) = @_; my $tqual = 90; # thumbs are always 90% (they're small regardless.) my @files; foreach my $file (glob("$dir/$dotm-*")) { if ($file =~ m@/\d\d[ab]?-(\d+)\.[^-./]+$@) { my $n = $1; $files[$n] = $file; } } if (! $dual_only_p) { for (my $n = 1; $n <= $#files; $n += 2) { my $front = $files[$n]; my $back = $files[$n+1]; make_images ($dir, $dotm, $n, 1, $border_p, 0, 0, $tqual, $front, $back); } } # And also generate the "dual" thumb #0, and the "m" medium thumb for cal. # make_images ($dir, $dotm, 0, 2, $border_p, 0, 0, $tqual, $files[1], $files[2]); make_images ($dir, $dotm, 'm', 3, $border_p, 0, 0, $tqual, $files[1], $files[2]); } # Regenerate all thumbnails of the given date. # sub rethumb_date($$$) { my ($date, $border_p, $dual_only_p) = @_; my ($dir, $dotm) = date_to_dir ($date); $dotm = sprintf("%02d", $dotm); my $glob = "$dir/$dotm-*"; print STDERR "$progname: rethumbing: $glob\n" if ($verbose > 2); error("#### fix me"); rethumb ($dir, $dotm, $border_p, $dual_only_p); } # Regenerate all thumbnails under flyers/. # sub rethumb_all($$) { my ($border_p, $dual_only_p) = @_; foreach my $dir (sort { $b cmp $a } glob "flyers/*/*") { # next if ($dir =~ m@/200[2-9]|/201./@s); my %dotms; foreach (glob ("$dir/*")) { $dotms{$1} = 1 if (m@/(\d\d[ab]?)-[^/]*$@i); } foreach my $dotm (sort keys (%dotms)) { next if ("$dir/$dotm" eq "flyers/2001/07/14"); # die-cut redsquare next if ("$dir/$dotm" eq "flyers/2001/08/18"); # die-cut redsquare next if ("$dir/$dotm" eq "flyers/2001/09/15"); # die-cut redsquare next if ("$dir/$dotm" eq "flyers/2002/07/20"); # die-cut qool next if ("$dir/$dotm" eq "flyers/2002/08/10"); # die-cut thump next if ("$dir/$dotm" eq "flyers/2002/08/23"); # die-cut atomic next if ("$dir/$dotm" eq "flyers/2003/09/13"); # die-cut thump rethumb ($dir, $dotm, $border_p, $dual_only_p); } } } sub flyerize_1($$$$$$$$$$) { my ($date, $border_p, $crop, $stretch_p, $split_p, $qual, $add_p, $front, $back, $second_p) = @_; my $front_tmp = $front; my $back_tmp = $back; if ($split_p) { error ("can't split two images!") if $back; $front_tmp = "/tmp/flyerize-01.jpg"; $back_tmp = "/tmp/flyerize-02.jpg"; my ($w, $h) = image_size($front); my $horiz_p = ($split_p > 1); # horizontal cut or vertical cut my $w2 = ($horiz_p ? $w : int($w/2)); my $h2 = ($horiz_p ? int($h/2) : $h); print STDERR "$progname: splitting ${w}x${h} image into " . "two ${w2}x${h2} images.\n"; my @cmd = ("convert", "-density", "300x300", "-crop", "${w2}x${h2}+0+0", "-strip", $front, $front_tmp); print STDERR "$progname: executing: " . join(' ', @cmd) . "\n" if ($verbose > 2); safe_system (@cmd); @cmd = ("convert", "-density", "300x300", "-crop", "${w2}x${h2}+" . ($horiz_p ? "0+${h2}" : "${w2}+0"), "-strip", $front, $back_tmp); print STDERR "$progname: executing: " . join(' ', @cmd) . "\n" if ($verbose > 2); safe_system (@cmd); } my @files = flyerize ($date, $border_p, $crop, $stretch_p, $qual, $add_p, $second_p, $front_tmp, $back_tmp); unlink $front_tmp if ($front_tmp && $front_tmp ne ($front || '')); unlink $back_tmp if ($back_tmp && $back_tmp ne ($back || '')); my ($dir, $dotm) = date_to_dir ($date); $back = '' unless $back; $front =~ s/([\\"!])/\\$1/g; $back =~ s/([\\"!])/\\$1/g; $front = "\"$front\"" if ($front =~ m/[\s\\()\[\]]/); $back = "\"$back\"" if ($back =~ m/[\s\\()\[\]]/); my $dir2 = $dir; $dir2 =~ s@/[^/]+$@@s; my $cmd = ("rm $front $back\n" . (! -d "$dir2/CVS" ? "cvs add $dir2\n" : "") . (! -d "$dir2/CVS" ? "cvs add $dir2/index.html\n" : "") . (! -d "$dir/CVS" ? "cvs add $dir\n" : "") . (! -d "$dir/CVS" ? "cvs add $dir/index.html\n" : "") . "cvs add " . ($second_p ? "" : "$dir/$dotm.html ") . join(" ", @files) . "\n"); return $cmd; } sub error($) { my ($err) = @_; print STDERR "$progname: $err\n"; exit 1; } sub usage() { print STDERR "usage: $progname [--verbose] [--no-border] " . "[--quality NN] [--crop [N]]\n" . "\t\t [--rethumb] [--rethumb0] [--debug]\n" . "\t\t [--split-vert] [--split-horiz] [--stretch]\n" . "\t\t [--auto]\n" . "\t\t dd-mmm-yyy front.jpg [back.jpg] [front2.jpg] [back2.jpg]\n"; exit 1; } sub main() { my ($date, $front, $back, $front2, $back2, $border_p, $qual); $qual = 90; $verbose = 1; $border_p = 1; my $add_p = 0; my $rethumb_p = 0; my $rethumb0_p = 0; my $split_p = 0; my $stretch_p = 0; my $auto_p = 0; my $crop = undef; while (defined($_ = $ARGV[0])) { shift @ARGV; if (m/^--?verbose$/) { $verbose++; } elsif (m/^--?debug$/) { $debug_p++; } elsif (m/^--?rethumb$/) { $rethumb_p++; } elsif (m/^--?rethumb0$/) { $rethumb0_p++; } elsif (m/^-v+$/) { $verbose += length($_)-1; } elsif (m/^--?no-border$/) { $border_p = 0; } elsif (m/^--?crop$/) { $crop = ((defined($ARGV[1]) && $ARGV[1] =~ m/^-?\d+$/s) ? shift(@ARGV) : 0); } elsif (m/^--?split(|v|-vert(ical)?)$/) { $split_p = 1; } elsif (m/^--?split(h|-horiz(ontal)?)?$/) { $split_p = 2; } elsif (m/^--?stretch$/) { $stretch_p++; } elsif (m/^--?auto$/) { $auto_p++; } elsif (m/^--?q(ual(ity)?)?$/) { $qual = shift(@ARGV); } elsif (m/^--?2$/) { $add_p++; } elsif (m/^-./) { usage; } elsif (!defined($date)) { $date = $_; } elsif (!defined($front)) { $front = $_; } elsif (!defined($back)) { $back = $_; } elsif (!defined($front2)) { $front2 = $_; } elsif (!defined($back2)) { $back2 = $_; } else { usage; } } error ("you're in the wrong directory: no $flyer_dir/ subdir") unless -d $flyer_dir; # When writing files, make permissions match the parent directory # by computing a umask from the directory's permissions. # umask (~((stat($flyer_dir))[2] & 0666) & 0666); load_event_names(); if ($rethumb_p || $rethumb0_p) { usage unless ($date); if ($date eq 'all') { return rethumb_all ($border_p, $rethumb0_p); } else { return rethumb_date ($date, $border_p, $rethumb0_p); } } usage unless ($date && $front); usage if ($front =~ m/^\d+$/s); $back = undef if ($back && $back eq '-'); my ($dir, $dotm, $event_name) = date_to_dir ($date); print STDERR "$progname: flyerizing \"$event_name\"\n"; my $cmd = ''; $cmd = "make fastup flyers _pull_tickets _pull_ids cal\n"; $cmd .= flyerize_1 ($date, $border_p, $crop, $stretch_p, $split_p, $qual, $add_p, $front, $back, 0); $cmd .= flyerize_1 ($date, $border_p, $crop, $stretch_p, $split_p, $qual, $add_p, $front2, $back2, 1) if $front2; $cmd .= "utils/cvs.sh -q commit -m '' flyers calendar\n"; if ($auto_p) { foreach my $c (split (m/\n/, $cmd)) { $c =~ s/^\s+|\s+$//gs; if ($debug_p) { print STDERR "$progname: not executing: $c\n"; } else { print STDERR "$progname: exec: $c\n"; safe_system ($c); } } } else { $cmd =~ s/^/ /gm; print STDOUT "\nMight I recommend:\n\n$cmd\n" unless ($debug_p); } } main(); exit 0;