#!/usr/bin/perl use warnings; use strict; use File::Find::Wanted; use File::Basename; use File::Spec; use File::Spec::Functions; use Image::Size; use Data::Dumper::Simple; use Math::Round; my $conf = { src_dir => "./slike", dst_dir => "./linki", debug => 0, }; sub msg { my $text = shift; print $text; } sub msg_error { my $text = shift; print STDERR "ERROR: $text"; } sub msg_warn { my $text = shift; print STDERR "warning: $text"; } sub msg_debug { my $text = shift; print "$text" if $conf->{debug}; } # verify the source dir if (! -d $conf->{src_dir}) { msg_error "Source directory '$conf->{src_dir}' does not exist. Aborting.\n" ; exit 1; } # verify the destination dir if (! -d $conf->{dst_dir}) { msg_error "Destination directory '$conf->{dst_dir}' does not exist. Aborting.\n"; exit 1; } # gather the list of files my @list = find_wanted( sub { -f && ( /\.jpg$/i || /\.jpeg$/i ) }, $conf->{src_dir} ); if (! @list) { msg "No files found.\n"; exit 0 } # Go through all the image files and build the hash that holds all the # information about them. my $count = 0; # how many files? my $errors = 0; # how many errors? my $ars = {}; # a hashref that holds all the encountered aspect rations and their number of occurence my $files = {}; # a hashref that holds all the files, their exif data, and their calculcated aspect ratio foreach my $f (@list) { $count++; msg "Gathering sizes for image in file: '$f'\n"; (my $x, my $y) = imgsize($f); # calculate aspect ratio my $ar; if ($x and $y) { $ar = nearest(0.1, ($x > $y) ? $x / $y : $y / $x); $ars->{$ar}++; } else { $errors++; } # append the stuff to hash $files->{$f}->{x} = $x; $files->{$f}->{y} = $y; $files->{$f}->{ar} = $ar; } # Dump the hash data if we are in debug mode. if ($conf->{debug}) { msg_debug "All images and their data:\n"; print Dumper $files; msg_debug "\n"; } # Dump some statistics. msg "Number of images found: $count. Number of images with errors: $errors.\n"; msg "Aspect ratio information for all images (aspect ratio => number of occurences):\n"; print Dumper $ars; # Create destination directories. TODO: use something smarter than just string # concatenation. msg_debug "Creating destination directories: "; foreach my $d (keys %$ars) { my $dirname = $conf->{dst_dir} . "/" . $d; msg_debug "'$dirname' "; mkdir $dirname; } msg_debug "\n"; # Symlink msg "Symlinking source files into destination directories.\n"; foreach my $f (keys %$files) { next unless exists $files->{$f}->{ar}; # Construct the path of the symlink. This is quite tricky to get right. # TODO: use something smarter than just string concatenation. msg_debug "\$f='$f' "; my $ar = $files->{$f}->{ar}; msg_debug "\$ar='$ar' "; my $symlink_dir = $conf->{dst_dir} . "/" . $ar; msg_debug "\$symlink_dir='$symlink_dir' "; my $symlink = $symlink_dir . "/" . basename($f); msg_debug "\$symlink='$symlink' "; my $symlink_dst = File::Spec->abs2rel( File::Spec->rel2abs($f), File::Spec->rel2abs($symlink_dir) ); msg_debug "\$symlink_dst='$symlink_dst' "; msg_debug "\n"; # Create the symlink. msg_debug "symlink($symlink_dst, $symlink);\n"; symlink($symlink_dst, $symlink); } # vim: set ts=4 sw=4 et cc=80: