#!/usr/bin/perl -w
#
# edit-images: browse a set of image thumbnails and perform operations on
# their source images (delete, resize, rotate)
#
# Gerald Oskoboiny, 9 May 2002
#
# $Id: edit-images,v 1.10 2006/09/24 10:22:18 gerald Exp $
#
# usage: http://your-server.example.org/edit-images?path=foo/2002/05/09
#
# bugs:
# - security holes: lets people browse a filesystem, isn't careful about input
# - doesn't actually change anything, just outputs commands to do stuff
# - assumes a certain filenaming scheme (thumbs named foo-sq.jpg)
# - assumes thumbnails etc are already generated
# - only handles one dir at a time
# - usage is not intuitive
#
# source: http://impressive.net/software/photo/source/edit-images
#
# see also:
# http://impressive.net/software/photo/
# http://impressive.net/archives/fogo/20020510011350.GA744@impressive.net
#
# changelog:
#
# $Log: edit-images,v $
# Revision 1.10 2006/09/24 10:22:18 gerald
# made output more compact
#
# Revision 1.9 2005/12/15 03:33:49 gerald
# made it use foo-tn.jpg if foo-sq.jpg does not exist
#
# Revision 1.8 2005/12/12 00:17:56 gerald
# use square -sq.jpg variants instead of -tn.jpg
#
# Revision 1.7 2005/02/10 06:23:54 gerald
# eliminated an error from error log (still a few more left)
#
# Revision 1.6 2004/08/20 07:41:22 gerald
# output a list of months if no path specified
#
# Revision 1.5 2004/08/20 00:39:26 gerald
# committing changes dated Aug 14 12:36 ET (done in radium):
# added month at a glance (random image on each day of a calendar)
#
# Revision 1.4 2004/06/28 19:26:44 gerald
# removed some uninteresting info from output of 'identify'
#
# Revision 1.3 2002/05/21 22:23:46 gerald
# added a pointer to writeup on fogo
#
# Revision 1.2 2002/05/12 01:16:21 gerald
# 4 images per row instead of 3
#
# Revision 1.1 2002/05/09 21:19:54 gerald
# CGI script to browse a set of image thumbnails and perform operations on
# their source images (delete, resize, rotate)
#
# this rev is a quick hack that just outputs unix commands that can be used
# to perform the operations intended.
#
#
use strict;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
# if ( $ENV{REMOTE_ADDR} ne "127.0.0.1" ) {
# print "Content-Type: text/plain\n\n";
# print "may be unsafe to use this except on localhost; exiting.\n";
# exit;
# }
my $path = $ENV{QUERY_STRING};
$path =~ s/^path=//;
my $docroot = $ENV{DOCUMENT_ROOT};
my $dir = $docroot . "/" . $path;
chdir( $dir ) or die "couldn't chdir to $dir: $!";
if ( "\L$ENV{REQUEST_METHOD}" eq "post" ) {
&handle_posted_form;
exit;
}
if ( $path =~ m,[0-9]{4}/[0-9]{2}/$, ) {
&output_month_at_a_glance( $path );
}
if ( $path !~ m,[0-9]{4}/[0-9]{2}/[0-9]{2}/$, ) {
&output_list_of_months( $ENV{DOCUMENT_ROOT} . "/" . $path );
}
$path =~ s,/$,,;
print qq{Content-Type: text/html\n\n};
print qq{
edit-images: $path\n\n};
print qq{edit images in $path
\n\n};
print qq{\n};
exit;
sub handle_posted_form {
print "Content-Type: text/plain\n\n";
print "# cut and paste this, sucka!\n\n";
print "cd $dir\n";
print "mkdir .trash\n";
foreach my $pair (split(/[&;,]/, join('',))) {
my ($image, $action) = split(/=/, $pair);
$action =~ tr/+/ /;
$action =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
if ( $action eq "ok" ) {
next; # leave this image as is
}
elsif ( $action eq "delete" ) {
(my $imagestar = $image) =~ s/\.jpg$/*.jpg/; # want foo*.jpg
print "mv $imagestar .trash\n";
}
elsif ( $action =~ /^rx/ ) {
(my $size = $action) =~ s/^r//;
print "resize-images $size $image\n";
}
else {
print "# unknown name/value pair submitted: [$image] = [$action]\n";
}
}
exit;
}
sub output_month_at_a_glance {
my $path = shift;
my %ymd;
my ($year,$month) = ($path =~ m,([0-9]{4})/([0-9]{2})/,);
my $mso = &day_of_week($year,$month,1); # "mso" == "month starts on"
my $verbose_mmyy = `date '+%B %Y' --date '$year-$month-01'`;
print qq{Content-Type: text/html\n\n};
print qq{edit-images: $verbose_mmyy\n\n};
print qq{$verbose_mmyy
\n\n};
print qq{\n};
print qq{| | } x $mso;
open( FIND,
"find $docroot/$path -type f -name '*tn.jpg' -print | sort -n |" )
or die "unable to find: $!";
while () {
chomp;
my ($yyyy,$mm,$dd,$file) =
(m,([0-9]{4})/([0-9]{2})/([0-9]{2})/([^/]+),);
$ymd{"$yyyy$mm$dd"} .= " " . $file;
}
foreach my $day (1..31) {
my $day0 = sprintf("%02d",$day);
if ( ! defined $ymd{"$year$month$day0"} ) {
print qq{$day
| \n};
}
else {
my @files = split(" ",$ymd{"$year$month$day0"});
print qq{$day};
print qq{ (} . ($#files + 1) . qq{ pic};
print "s" unless $#files == 0;
print qq{)
![]() | \n};
}
print "
\n\n" if &day_of_week($year,$month,$day) == 6;
}
close( FIND ) or warn "error closing pipe to find: $!";
print "
\n";
exit;
}
#
# day_of_week($year, $month, $date)
#
# provided by Tkil, http://slinky.scrye.com/~tkil/
# on #perl, Dec 13, 1998 -- gerald
#
# Return the day of the week (0 == Sunday ... 6 == Saturday) for the
# given date. $year should have four digits; $month and $date
# both start at 1, not zero.
#
# Algorithm is from the CRC Handbook of Mathematics, 30th Ed, page 738.
#
# see also: appendix B of RFC 3339, http://www.ietf.org/rfc/rfc3339.txt
#
sub day_of_week {
my ($year, $month, $date) = @_;
$month -= 2;
if ($month <= 0) {
-- $year;
$month += 12;
}
my $cent = int($year/100);
$year %= 100;
# print STDERR "year=$year, cent=$cent, date=$date, month=$month\n";
my $dow = ($date
+ int(2.6*$month - 0.2)
- 2*$cent
+ $year
+ int($year/4)
+ int($cent/4));
$dow += 7 while $dow < 0;
$dow %= 7;
return $dow;
}
sub output_list_of_months {
my $path = shift;
print "Content-Type: text/html\n\n";
print qq{edit-images: list of months\n\n};
print qq{list of months
\n\n};
print "\n";
open( FIND,
"find $path -name '[0-9][0-9]' -print | egrep '/[0-9][0-9][0-9][0-9]/[0-9][0-9]\$' | sort -rn |" )
or die "unable to find: $!";
while () {
chomp;
s,$docroot/,,;
print qq{ - $_
\n};
}
close( FIND ) or warn "error closing pipe to find: $!";
print "
\n";
exit;
}