Document-Manager

 view release on metacpan or  search on metacpan

lib/Document/Manager.pm  view on Meta::CPAN


=head2 checkout()

Checks out a copy of the document specified by $doc_id, placing
a copy into the directory specified by $dir.  By default it will
return the most recent revision, but a specific revision can be
retrieved by specifying $revision.

Returns the filename(s) copied into $dir on success.  If there is an
error, it returns undef.  The error message can be retrieved via
get_error().

=cut

sub checkout {
    my $self = shift;
    my $dir = shift;
    my $doc_id = shift;
    my $revision = shift;
    $self->_set_error('');

    if (! $doc_id || $doc_id !~ /^\d+/) {
	$self->_set_error("Invalid doc_id specified to checkout()");
	return undef;
    }

    if (! $dir || ! -d $dir) {
	$self->_set_error("Invalid dir specified to checkout()");
	return undef;
    }

    return $self->_repo()->get($doc_id, $revision, $dir);
}

=head2 add()

Takes a hash of filenames => content pairs, and inserts each into the
dms as a separate document.  The documents are scanned for valid RDF
metadata which, if present, will be made available for use in the
system.  [Note that for metadata, currently only SVG documents are
supported.]

Returns the new ID number of the document added, or undef if failed.

=cut

sub add {
    my $self = shift;

    my (%files) = (@_);
    my @doc_ids;
    my $doc_id;
    my ($sec, $min, $hr, $day, $month, $year) = (gmtime)[0..5];
    my $now = sprintf("%04s-%02s-%02s %02s:%02s:%02s",
		      $year+1900, $month+1, $day, $hr, $min, $sec);
    foreach my $filename (keys %files) {
	my $content = $files{$filename};
	next unless $content;
	($filename) = (File::Spec->splitpath($filename))[2];
	my $local_filename = catfile('/tmp', $filename);
	my $decoded = decode_base64($content);
	if (! open(FILE, ">$local_filename") ) {
	    warn "Error:  Could not open file '$local_filename' for writing: $!\n";
	    next;
	}
	binmode(FILE);
	print FILE $decoded;
	if (! close(FILE) ) {
	    warn "Error:  Could not close file '$local_filename':  $!\n";
	}

	$doc_id = $self->_repo()->add($local_filename);
	if ($doc_id) {
	    push @doc_ids, $doc_id;
	} else {
	    $self->_set_error($self->_repo()->get_error());
	}

	# Generate metadata
	my %properties;
	# TODO:  Determine file type.  For now assume SVG
	my $format = 'svg';

	# Based on file type, extract metadata
	if ($format eq 'svg') {
	    my $svgmeta = new SVG::Metadata;
	    if (! $svgmeta->parse($local_filename) ) {
		$self->_set_error($svgmeta->errormsg());
		warn $svgmeta->errormsg()."\n";
	    }
	    $properties{title}         = $svgmeta->title();
	    $properties{author}        = $svgmeta->author();
	    $properties{creator}       = $svgmeta->creator();
	    $properties{creator_url}   = $svgmeta->creator_url();
	    $properties{owner}         = $svgmeta->owner();
	    $properties{owner_url}     = $svgmeta->owner_url();
	    $properties{publisher}     = $svgmeta->publisher();
	    $properties{publisher_url} = $svgmeta->publisher_url();
	    $properties{license}       = $svgmeta->license();
	    $properties{license_date}  = $svgmeta->license_date();
	    $properties{description}   = $svgmeta->description();
	    $properties{language}      = $svgmeta->language();
	    $properties{keywords}      = join('; ', $svgmeta->keywords());
	}

	$properties{title} ||= $filename;

	my $inode = stat($local_filename);

	$properties{state} = 'new';
	$properties{size}  = $inode->size;
	$properties{date}  = $now;
	$properties{mimetype} = `file -bi $local_filename`;  # TODO:  PApp::MimeType?
	chomp $properties{mimetype};

	if (! $self->properties($doc_id, %properties) ) {
	    warn "Error:  ".$self->get_error()."\n";
	}

	# Remove the temporary file
	unlink($local_filename);
    }

    return $doc_id;
}

=head2 checkin()



( run in 0.517 second using v1.01-cache-2.11-cpan-2398b32b56e )