#!/usr/pkg/bin/perl
# ====================================================================
# ingest
#
# Copyright (c) 2000 David Burren.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# 3. The end-user documentation included with the redistribution,
#    if any, must include the following acknowledgment:
#       "This product includes software developed by David Burren."
#    Alternately, this acknowledgment may appear in the software itself,
#    if and wherever such third-party acknowledgments normally appear.
#
# 4. The name "David Burren" must not be used to endorse or promote
#    products derived from this software without prior written
#    permission. For written permission, please contact david@burren.cx.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL DAVID BURREN BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ====================================================================
# $Id: ingest,v 1.12 2000/09/05 23:49:11 davidb Exp $
#
# ingest CF
#

use Getopt::Std;

getopts('c:dpv', \%opts);

if (defined ($drive = $opts{"c"})) {
	$drive =~ s/:.*//;
} else {
	$drive = "f";
}
$delete_after_copy = $opts{"d"};
$prune_empty_dirs = $opts{"p"};
$verbose = $opts{"v"};

if (!defined ($dest_dir = shift)) {
	usage();
	exit 1;
}
if (! -d $dest_dir."/.") {
	print STDERR "$dest_dir not a directory\n";
	exit 1;
}
if (!defined ($home = $ENV{"HOME"})) {
	print STDERR "HOME not defined\n";
	exit 1;
}
$ingestid = "";
if (open(INGESTID, "<$home/.ingest_id")) {
	while (<INGESTID>) {
		s/\s+$//;
		s/#.*$//;
		if (($ingestid = $_) ne "") {
			last;
		}
	}
	close(INGESTID);
}
if ($ingestid eq "") {
	$ingestid = $ENV{"USER"}."+0";
} else {
	if ($ingestid =~ /^([^\+]*)\+(\d+)$/) {
		$ingestid = $1."+".($2+1);
	} else {
		$ingestid = $ingestid."+0";
	}
}
if (open(INGESTID, ">$home/.ingest_id")) {
	print INGESTID $ingestid, "\n";
	close(INGESTID);
}

if (open(DIR, "mdir -a -/ -X $drive:|")) {
	while (<DIR>) {
		s/\s+$//;
		if (/^[^:]+:\/(.+)$/) {
			$path = $1;
			if ($path =~ /^(.+)\/([^\/]+)$/) {
				($dir, $file) = ($1, $2);
				($ext = $file) =~ s/^.+\.//;
				$ext =~ tr/A-Z/a-z/;
				# Make as if to copy THM files (DCF thumbnails)
				# but they will be discarded later.
				if ($ext ne "jpg" &&
					$ext ne "crw" &&
					$ext ne "thm" &&
					$ext ne "tif") {
					print "Ignoring $path\n" if ($verbose);
					next;
				}
				$dest = longname($dir, $file);
				$copy_from{$path} = $dest;
			}
		}
	}
	close(DIR);
} else {
	die "mdir ".$drive.": failed: $!";
}
while (($file, $dest) = each %copy_from) {
	$dest = $dest_dir."/".$dest;
	($ext = $file) =~ s/^.+\.//;
	if ($ext ne "thm") {
		print $file, " => ", $dest, "\n" if ($verbose);
		system("mcopy", 
				$drive.":/".$file,
				$dest) == 0
			or
			print STDERR "Unable to copy $file\n";
		$new_size = -s $dest;
		$old_size = dossize($drive, $file);
	} else {
		# If we're deleting, delete the THM files but don't
		# try to copy them.
		$new_size = $old_size = 0;
	}
	if ($delete_after_copy && $new_size == $old_size) {
		print "Removing $drive:/$file\n" if ($verbose);
		system("mdel", $drive.":/".$file) == 0
			or
			print STDERR "Failed to delete ", $drive, ":/", $file, "\n";
	}
}
if ($prune_empty_dirs) {
	my $pruned = 1;
	while ($pruned) {
		%dir = ();
		if (open(DIR, "mdir -a -/ -X $drive:|")) {
			while (<DIR>) {
				chomp;
				(my $check = $_) =~ s/\s+$//;
				@components = split(/\//, $check);
				for ($i = 0; $i + 1 < scalar @components; $i++) {
					my $sdir = join("/", @components[0..$i]);
					if (! $dir{$sdir}) {
						$dir{$sdir} = 1;
					} else {
						$dir{$sdir}++;
					}
				}
				(my $dir = $check) =~ s/\/[^\/]*$//;
				if ($check =~ /\/$/) {
					if (! $dir{$dir}) {
						$dir{$dir} = 0;
					}
				}
			}
			close(DIR);
		} else {
			die "mdir ".$drive.": failed: $!";
		}
		$pruned = 0;
		while (($dir, $count) = each %dir) {
			next if ($count);
			print "Removing empty dir: $dir\n" if ($verbose);
			if (system("mrd", $dir) == 0) {
				$pruned++;
			} else {
				print STDERR "Failed to delete $dir\n";
			}
		}
	}
}

sub longname {
	local($dir, $file) = @_;
	my $mdir = $dir."/".$file;;

	$mdir =~ tr/A-Z /a-z_/;

	my $longname;
	if ($mdir =~ /^(.*)dcim\/(\d{3})(\w{5})\/(\w{4})(\d{4})\.(.{3})$/) {
		# DCF format
		($prefix, $folder, $folderfree, $objfree, $obj, $ext) =
			($1, $2, $3, $4, $5, $6);

		my @longname = ($ingestid);
		if ($prefix =~ /^dw0+([1-9]\d*)$/) {
			# Digital Wallet "download" folder
			$prefix = "dw".$1;
		}
		if ($prefix ne "") {
			push(@longname, $prefix);
		}
		push(@longname, $folder, $obj);
		$longname = join("-", @longname).".".$ext;
	} else {
		$longname = join("-", $ingestid, split(/\//, $mdir));
	}
	$longname;
}

sub usage {
	print STDERR "Usage: ingest [-c drive] [-v] [-d] [-p] dest_dir\n";
}


sub dossize {
	local($drive, $file) = @_;
	my $size = undef;

	if (open(DIR, "mdir ".$drive.":/".$file."|")) {
		while (<DIR>) {
			if (/^\s+1 file\s+(\d[0123456789 ]+)bytes/) {
				$size = $1;
				$size =~ s/ //g;
			}
		}
		close(DIR);
	}
	$size;
}
