#!/usr/bin/perl
#
# Create a separate tree of symlinks in $outdir which reflects iPhoto's internal
# album structure as found in $albumfile.
# 
# Use this for whatever you like, for me it makes mythgallery (mythtv) able to display
# my iPhoto libraries, which are rsynced from my Mac.
#
# 	Tim Gould <iphoto2d@reverb.com.au>
#
# 	1.0	5/7/2008	First working Version
#
#
# Known Issues
# - Mac::iPhoto's parsing is amazingly slow, ie. ~30mins for me
# - hard-coded paths
# - ampersands (&) in album names break things
# - empty albums should be not put into output
# - sorting could be much improved
# - would be nice to understand Events too, hmmm...
#

use Mac::iPhoto;	# Publicly available one is broken, I fixed it
use File::Basename;

#$ENV{PLIST_DEBUG} = 10;

#my $albumfile = '/pictures/Test/AlbumData.xml.tmp';
my $albumfile = '/pictures/Current/AlbumData.xml';
my $tmpfile = "/tmp/printalbum.$$";
my $outdir = '/pictures/01_Current';


# iPhoto 7.1.3's header line does not get detected as valid by PropertyList.pm 1.31
# So, need to strip the lines manually
open( ALBUMFILE, "<$albumfile" ) or die "Couldn't open $albumfile for reading";
open( TMPFILE, ">$tmpfile" ) or die "Couldn't open $tmpfile for writing";
foreach $line ( <ALBUMFILE> ){
	next if $line =~ /^<\?xml.*?>\s*/;
	next if $line =~ /^<plist.*?>\s*/;
	print TMPFILE $line;
}
close ALBUMFILE;
close TMPFILE;


if( ! -d $outdir ){
	`mkdir -p $outdir`;
}

my $a = new Mac::iPhoto( "$tmpfile" );

print "Parsing $albumfile, this will take a LOOONG time.\n"; 
$a->parse;

printf "Album path: %s\n", $a->{Properties}->{'Archive Path'};

for my $album (@{$a->{Data}->{Albums}}) {
	my $album_name = $album->{'AlbumName'};
	print "\n** Creating $outdir/$album_name\n";
	if( -d "$outdir/$album_name" ){
		`rm -rf "$outdir/$album_name/"`;
	}
	`mkdir -p "$outdir/$album_name"`;

	my $seq_num = 0;
	for my $key ( @{$album->{'KeyList'}}) {
		my $image_path = $a->{Data}->{Images}->[$key]->{'ImagePath'};
		#$image_path =~ s/:/ï ¢/g;	# Weird Samba stuff, didn't work anyway
		#$image_path =~ s/:/\\:/g;	# Not necessary
		$image_path =~ s/\&amp;/\&/g;
		#my $image_name = basename($image_path);

		# For my purposes I don't want videos included
		next if $image_path =~ /mp4$/;
		next if $image_path =~ /mov$/;

		my $image_name = sprintf( '%08s.jpg', $seq_num++ );

		`ln -s "$image_path" "$outdir/$album_name/$image_name"`;
	}
}

`rm $tmpfile`;
