#!/usr/bin/perl ########################################### # Mike Schilli, 2003 (m@perlmeister.com) ########################################### use warnings; use strict; my $IMG_FILE_DIR = "/ms2/PHOTOS"; use CameraStore; use Log::Log4perl qw(:easy); use Image::Info qw(image_info); use File::Path; use File::Copy; use Getopt::Long; use Pod::Usage; my $ID_REGEX = qr#^(\d{4})-(\d\d)-(\d\d) _(\d\d):(\d\d):(\d\d)$#x; my $TS_REGEX = qr#^(\d{4}):(\d\d):(\d\d)\s (\d\d):(\d\d):(\d\d)$#x; my $PIC_REGEX = qr#(\.jpg)$#i; Log::Log4perl->easy_init( { file => 'stderr', level => $WARN, layout => "%p %m%n"}); GetOptions( "import" => \my $import, "tag=s" => \my $tag, "untag=s" => \my $untag, "filter" => \my $filter, "list" => \my $list, "grep=s" => \my $grep, "search=s" => \my $search, "paths" => \my $paths) or pod2usage(); my $db = CameraStore->new(); if($search) { for($db->search_tag($search, $paths)) { print "$_\n"; } exit 0; } my $in = get_input_sub(); while($_ = $in->()) { if($import) { add_file($db, $_, $tag); next; } my($id) = (-f) ? file_info($_) : $_; unless(defined $id and $id =~ /$ID_REGEX/) { ERROR "Image $_ not in DB"; next; } if($tag) { $db->add_tag($tag, $id); } elsif($untag) { $db->delete_tag($untag, $id); } elsif($grep) { print "$_\n" for $db->search_tag($grep, $paths, $id); } elsif($list) { print "$_: ", join(', ', $db->list_tags($id)), "\n"; } else { pod2usage("Options error"); } } ########################################### sub add_file { ########################################### my($db, $ofile, $tag) = @_; my($stamp, $dir, $file) = file_info($ofile); return undef unless defined $file; if(!-d $dir) { mkpath($dir) or LOGDIE "Cannot mkpath $dir"; } copy($ofile, "$dir/$file") or LOGDIE "$ofile > $dir/$file failed"; $db->add_image($stamp, "$dir/$file", $tag); print "$stamp\n"; } ########################################### sub file_info { ########################################### my($ofile) = @_; my ($suffix) = ($ofile =~ $PIC_REGEX); unless($suffix) { ERROR "Unknown image type: $ofile"; return undef; } my($y, $m, $d, $h, $mi, $s) = image_date($ofile); return undef unless defined $s; my $stamp = "$y-$m-${d}_$h:$mi:$s"; my $dir = "$IMG_FILE_DIR/$y/$m/$d"; my $file = "$h:$mi:$s$suffix"; return($stamp, $dir, $file); } ########################################### sub image_date { ########################################### my($file) = @_; my $info = image_info($file); if ($info->{error} or ! exists $info->{DateTime} or $info->{DateTime} !~ $TS_REGEX) { WARN "No timestamp from $file"; return undef; } return($1, $2, $3, $4, $5, $6); } ########################################### sub get_input_sub { ########################################### my @items = (); if(@ARGV) { push @items, @ARGV; } else { while() { chomp; push @items, $_; } } return sub { if(@items and -d $items[0]) { my $dir = shift @items; unshift @items, grep /$PIC_REGEX/, <$dir/*>; } return shift @items; }; } __END__ =head1 NAME idb - Image database client =head1 SYNOPSIS # Import and tag idb -i -t tag [file|dir] ... # Filter files and tag ls *.jpg | idb -t tag # DB search for tags, print paths idb -s search_pattern -p # Grep for tags in files idb -g search_pattern [file|dir] ... # List files/tags idb -l [file|dir] ...