Contribute: Plugins/ExportPluginsZip
Contents
Export Plugin Tutorial 5: Zip
In this tutorial we'll look at packaging the results of a search into a Zip file. We'll create a directory for each eprint, and a sub-directory for each document belonging to that eprint. We'll also add a metadata file to the Zip.
To prepare for this tutorial you should install the Archive::Any::Create module. The following command as root, or using sudo should work.
cpan Archive::Any::Create
Zip.pm
package EPrints::Plugin::Export::MyPlugins::Zip; @ISA = ("EPrints::Plugin::Export"); use strict; use Archive::Any::Create; sub new { my ($class, %opts) = @_; my $self = $class->SUPER::new(%opts); $self->{name} = "Zip"; $self->{accept} = [ 'list/eprint' ]; $self->{visible} = "all"; $self->{suffix} = ".zip"; $self->{mimetype} = "application/zip"; return $self; } sub output_list { my ($plugin, %opts) = @_; my $archive = ''; open (my $FH, '>', \$archive) or die("Could not create filehandle: $!"); my $zip = Archive::Any::Create->new; my $otherplugin = $plugin->{session}->plugin("Export::MyPlugins::Excel"); my %optscopy = %opts; if (defined $opts{"fh"}) { $optscopy{"fh"} = undef; } my $mdata = $otherplugin->output_list(%optscopy); $zip->add_file("eprints-search/metadata".$otherplugin->{suffix},$mdata); foreach my $dataobj ($opts{"list"}->get_records) { my $dirpath = "eprints-search/".$dataobj->get_id()."/"; my $i = 1; foreach my $doc ($dataobj->get_all_documents) { my $subdirpath = $dirpath."doc$i/"; my %files = $doc->files; foreach my $filename (sort keys %files) { my $filepath = $subdirpath.$filename; my $file = $doc->local_path."/".$filename; if (-d $file) { next; } my $data = ''; open (my $datafh ,'>', \$data); open (INFH, "<$file") or die ("Could not open file $file"); while (<INFH>) { print {$datafh} $_; } close INFH; $zip->add_file($filepath, $data); } $i++; } } if (defined $opts{"fh"}) { $zip->write_filehandle($opts{"fh"},"zip"); return undef; } $zip->write_filehandle($FH,"zip"); return $archive; } 1;
In More Detail
Modules
We need to import a module for creating Zip files.
use Archive::Any::Create;
Constructor
For the sake of simplicity this plugin will only deal with lists of eprints. This avoids some code duplication, and it would be fairly easy to modify the plugin to deal with both individual eprints and lists of eprints sensibly.
$self->{accept} = [ 'list/eprint' ];
The file extension and MIME type are set to values appropriate for Zip files.
$self->{suffix} = ".zip"; $self->{mimetype} = "application/zip";
List Handling
Setting Up
Here we setup an in-memory file for the Zip, and create an Archive object.
my $archive = ''; open (my $FH, '>', \$archive) or die("Could not create filehandle: $!"); my $zip = Archive::Any::Create->new;
Metadata
Here we get another plugin object to create our metadata, in this case we load the Excel plugin we created in the last tutorial.
my $otherplugin = $plugin->{session}->plugin("Export::MyPlugins::Excel");
If we're running the command line export plugin we don't want this other plugin to write to a file handle. Instead, we want to get a string back from this plugin. We create a copy of the %opts hash provided to our plugin and if a file handle has been defined, we set it to be undefined in our copy.
my %optscopy = %opts; if (defined $opts{"fh"}) { $optscopy{"fh"} = undef; }
We use the plugin to create some metadata and then create an appropriately named file in our zip containing that metadata.
my $mdata = $otherplugin->output_list(%optscopy); $zip->add_file("eprints-search/metadata".$otherplugin->{suffix},$mdata);
Handling DataObjs
foreach my $dataobj ($opts{"list"}->get_records) { my $dirpath = "eprints-search/".$dataobj->get_id()."/"; my $i = 1; foreach my $doc ($dataobj->get_all_documents) { my $subdirpath = $dirpath."doc$i/"; my %files = $doc->files; foreach my $filename (sort keys %files) { my $filepath = $subdirpath.$filename; my $file = $doc->local_path."/".$filename; if (-d $file) { next; } my $data = ''; open (my $datafh ,'>', \$data); open (INFH, "<$file") or die ("Could not open file $file"); while (<INFH>) { print {$datafh} $_; } close INFH; $zip->add_file($filepath, $data); } $i++; } } if (defined $opts{"fh"}) { $zip->write_filehandle($opts{"fh"},"zip"); return undef; } $zip->write_filehandle($FH,"zip"); return $archive; } 1;
Testing Your Plugin
Restart your webserver and test the plugin as in the previous tutorial.