EPrints Technical Mailing List Archive
See the EPrints wiki for instructions on how to join this mailing list and related information.
Message: #01318
< Previous (by date) | Next (by date) > | < Previous (in thread) | Next (in thread) > | Messages - Most Recent First | Threads - Most Recent First
[EP-tech] Exporting a .zip file
- To: eprints <eprints-tech@ecs.soton.ac.uk>
- Subject: [EP-tech] Exporting a .zip file
- From: Ian Stuart <Ian.Stuart@ed.ac.uk>
- Date: Tue, 20 Nov 2012 09:49:28 +0000
EPrints 3.2.2 on SolarisI'm writing an exporter to download the item as a .zip file (as in, a file that can be used in a SWORD deposit.)
I can create the .zip file; I can send something called foo.zip back to the user.... but the thing I get back is not readable as a .zip file!
Here is the code (with most of the integrity-checking & sanity-checking taken out)
---------------- code -----------------
package EPrints::Plugin::Export::SWORD_Deposit_File;
use strict;
use warnings;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS);
use EPrints::Plugin::Export::METS_Broker;
our @ISA = qw( EPrints::Plugin::Export::METS_Broker );
our $PREFIX = '';
sub new
{
my ($class, %opts) = @_;
my $self = $class->SUPER::new(%opts);
$self->{name} = "foo";
$self->{accept} = ['dataobj/eprint', 'list/eprint'];
$self->{visible} = "all";
$self->{xmlns} = "foo";
$self->{schemaLocation} = "foo2";
$self->{suffix} = ".zip";
$self->{mimetype} = 'application/zip';
return $self;
} ## end sub new
sub output_dataobj
{
my ($plugin, $dataobj) = @_;
my $text;
$text = <<EOX;
<?xml version="1.0" encoding="utf-8" ?>
EOX
my $xml = $plugin->xml_dataobj($dataobj);
$text .= EPrints::XML::to_string($xml);
# Use Archive::Zip to create the zip file
my $archive = Archive::Zip->new();
# Add the manifest as mets.xml
# for some reason, I can't get Archive::Zip to add a file with
# unicode characters, so this is a nasty hack, sorry
my $tmpdir = EPrints::TempDir->new(UNLINK => 0);
my $tmpfile = "${tmpdir}/mets.xml";
warn "tempfile: $tmpfile\n";
# write out the xml file
my $FH;
open($FH, ">:utf8", "$tmpfile");
print $FH $text;
close($FH);
$archive->addFile($tmpfile, "mets.xml");
# end of fudge
# Each 'Document' is represented by a directory
# Each 'Document' many have a number of files
foreach my $doc ($dataobj->get_all_documents)
{
# In the zip file, we use file paths rather than URLs, however
# this routine is very similar to the methodology in
# EPrints::Plugin::Export::METS_Broker::_make_fileSec
# the docpath is the path to the document on the disk,
# formatted:
# /<EprintsRoot>/archive/<archiveID>/documents/<somepath>/<doc_id>
my $docroot = $doc->local_path;
$docroot =~ /\/(\d+)$/;
my $doc_id = $doc->get_id;
$archive->addTree($docroot, $doc_id);
} ## end foreach my $doc ($dataobj->get_all_documents...)
my @M = $archive->memberNames();
warn "Archive: @M\n";
# as of Perl 5.8.0, we can open a filehandle to variables
my $buffer = "";
open(my $fh, ">:bytes", \$buffer) || warn "Can't open a buffer in
memory\n";
unless ($archive->writeToFileHandle($fh) == AZ_OK)
{
warn "failed to write archive into scalar\n";
}
close $fh;
warn "Written archive into scalar\n";
warn "size:". length($buffer)."\n";
$archive->writeToFileNamed("${tmpdir}/deposit.zip");
return $buffer;
} ## end sub output_dataobj
1;
---------------- code -----------------
As you can see, I've got some debugging going on
tempfile: /var/tmp/n2grhkaewB/mets.xml
Archive: mets.xml 474/ 474/2012-09-06767_121010093659.zip
Written archive into scalar
size:2638
and looking at the .zip file:
[broker@devel:Export]: unzip -l /var/tmp/n2grhkaewB/deposit.zip
Archive: /var/tmp/n2grhkaewB/deposit.zip
Length Date Time Name
-------- ---- ---- ----
4206 11-20-12 09:29 mets.xml
0 10-10-12 14:37 474/
1178 10-10-12 14:37 474/2012-09-06767_121010093659.zip
-------- -------
5384 3 files
So.... I can obviously MAKE the file.... I just can't send it back to
the user sensibly.
Anyone done this? If not - anyone any suggestions as to why it's not working?Oh - and a SWORD transfer exporter is fine: it's essentially this code, but then uses LWP::UserAgent to do a post:
my $ua = LWP::UserAgent->new();
my $rxml = $plugin->{session}->xml;
my $returns = $rxml->create_element("returns");
my $req = HTTP::Request->new(POST => $target->{uri});
# Tell SWORD to process the contents of the zip file as my format
$req->header(
'X-Packaging' => 'http://opendepot.org/broker/1.0',
'X-No-Op' => 'false',
'X-Verbose' => 'false',
'Content-Disposition' => 'filename=sword_deposit.zip',
'filename' => 'sword_deposit.zip',
);
$req->content_type('application/zip');
$req->content($buffer);
my $res = $ua->request($req);
if ($res->is_success)
{
my $content_dom = $rxml->parse_string($res->content);
my $fragment = $content_dom->getElementsByTagName('entry')->item(0);
$return->appendChild($fragment);
} ## end if ($res->is_success)
--
Ian Stuart.
Developer: ORI, RJ-Broker, and OpenDepot.org
Bibliographics and Multimedia Service Delivery team,
EDINA,
The University of Edinburgh.
http://edina.ac.uk/
This email was sent via the University of Edinburgh.
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
- Prev by Date: [EP-tech] EPrints in GitHUB
- Next by Date: [EP-tech] NET::SMTP needs Hello in EPrints 3.3.10
- Previous by thread: [EP-tech] Public saved searches are not public!
- Next by thread: [EP-tech] Re: Exporting a .zip file
- Index(es):
