#!/usr/bin/perl -w # Written By Martin Owens, Copyright 2007; GPLv3 use strict; if($ARGV[0] eq '--help') { print "Disc Media File Calculator - This program will calculate how files can best fit onto a CD ROM or other disc media. Uusage: $0 DiscSizeInMB Directories ..."; exit 0; } elsif($ARGV[0] eq '--version') { print "\nDisc Media File Calculator - Version 1.04 (2007-09-12)\n\n"; exit 0; } if(@ARGV > 3 or $ARGV[0] !~ /^\d+$/) { die "Incorrect use: $0 DiscSizeInMB ISO-Location [Directories...] Example: $0 680 /tmp/iso-disc ~/my-files/ ~/my-music/ ~/.* "; } my $disksize = shift(@ARGV) * 1024 * 1024; my $isoroot = shift(@ARGV); my $dirs = @ARGV ? '"'.join('" "', @ARGV).'"' : '.'; open( USE, "du -ab $dirs|" ); #print "Setting it $ARGV[0]\n"; my @discs; my @sizes; my @files; print "\nGenerating list of files..."; while ( ) { if($_ =~ /(\d+)\s+(.+)/) { if(-f $2) { print "."; push @sizes, $1; push @files, $2; } } } close( USE ); print "\nSorting files..."; my @sfiles = @files[ sort { $sizes[$b] <=> $sizes[$a] } 0 .. $#sizes ]; my @ssizes = sort { $b <=> $a } @sizes; FILE: for(my $i=0;$i<=$#sfiles;$i++) { my $file = $sfiles[$i]; my $size = $ssizes[$i]; foreach my $disk (@discs) { if($disk->{'space'} > $size) { push @{$disk->{'files'}}, $file; $disk->{'space'} -= $size; $disk->{'count'}++; next FILE } } # We need a new disk if($disksize > $size) { push @discs, { space => $disksize - $size, count => 1, files => [ $file ] }; } else { warn "Error unable to fit $file onto any Disc, discs are too small.\n"; } } print "\nCreating iso disc images...\n"; my $index = 0; foreach my $disc (@discs) { $index++; my $isofile = "$isoroot-$index.iso"; print "Creating ISO file '$isofile'\n"; open(ISOFILE, "|mkisofs -J -input-charset iso8859-1 -graft-points -quiet -o $isofile -A BACKUP -path-list -"); foreach my $file (@{$disc->{'files'}}) { $file =~ /^(.*?)[^\/]+$/; my $dir = $1; $dir =~ s/^\.?\///; #print " - $dir=$file\n"; if($dir) { print ISOFILE "$dir=$file\n"; } else { print ISOFILE "$file\n"; } } print "Writing ISO file to disk\n"; close(ISOFILE); print "\n"; } exit 0;