/Vector/File.pm
package Vector::File;
use CGI::Fast qw/:cgi/;
use Digest::SHA;
use Vector::Config qw/$datadir $thumbdir $max_upload_size/;
use strict;

sub store {
	my $buf;

	my $fh = upload('file');
	return unless defined $fh;

	die "File too large\n" if -s $fh > $max_upload_size;

	my $filename = param('file');
	$filename =~ s'^.*[/\\:]'';		# trim path bits

	my $tmpdir = "upload.$$";
	mkdir "$datadir/$tmpdir";

	my $hash = new Digest::SHA('sha256');
	open FILE, '>', "$datadir/$tmpdir/$filename";
	while (read($fh, $buf, 16384)) {
		print FILE $buf;
		$hash->add($buf);
	}
	close FILE;

	my $file_id = $hash->hexdigest;

	if (-d "$datadir/$file_id") {
		unlink "$datadir/$tmpdir/$filename";
		rmdir "$datadir/$tmpdir";

		unless (-e "$datadir/$file_id/$filename") {
			my ($oldfilename) = <$datadir/$file_id/*>;
			link $oldfilename, "$datadir/$file_id/$filename";
		}
	} else {
		rename "$datadir/$tmpdir", "$datadir/$file_id";

		thumb($file_id, $filename);
	}
	return "$file_id/$filename";
}

sub thumb {
	my ($file_id, $filename) = @_;

	mkdir "$thumbdir/$file_id" unless -d "$thumbdir/$file_id";

	my $r = system '/usr/bin/convert', "$datadir/$file_id/$filename", '-thumbnail', '200x200', "$thumbdir/$file_id/thumbnail.jpg";
	if ($r >> 8) {
		rmdir "$thumbdir/$file_id";
	}
}

1;