Bugzilla – Attachment 44355 Details for
Bug 14939
OAI Server classes must be modularized
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14939 Modularize OAI Server existing classes
Bug-14939-Modularize-OAI-Server-existing-classes.patch (text/plain), 27.29 KB, created by
Frédéric Demians
on 2015-11-04 09:43:08 UTC
(
hide
)
Description:
Bug 14939 Modularize OAI Server existing classes
Filename:
MIME Type:
Creator:
Frédéric Demians
Created:
2015-11-04 09:43:08 UTC
Size:
27.29 KB
patch
obsolete
>From c3927248e226a5ef16354ea3a3d56ce21a6c788c Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demians?= <f.demians@tamil.fr> >Date: Fri, 2 Oct 2015 09:18:18 +0200 >Subject: [PATCH] Bug 14939 Modularize OAI Server existing classes > >Koha OAI server has been done in one unique .pl file because there >wasn't any object model or rules in the Koha project when it has been >coded. This patch modularized existing classes, putting each class in a >separate file in Koha::OAI::Server namespace. UT begining. >--- > opac/oai.pl | 745 +------------------------------------------- > t/db_dependent/OAI/Server.t | 96 ++++++ > 2 files changed, 100 insertions(+), 741 deletions(-) > create mode 100644 t/db_dependent/OAI/Server.t > >diff --git a/opac/oai.pl b/opac/oai.pl >index 7eb0f6b..7d3225a 100755 >--- a/opac/oai.pl >+++ b/opac/oai.pl >@@ -1,6 +1,6 @@ > #!/usr/bin/perl > >-# Copyright Biblibre 2008 >+# Copyright Tamil s.a.r.l. 2008-2015 > # > # This file is part of Koha. > # >@@ -18,12 +18,11 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > >-use strict; >-use warnings; >- >+use Modern::Perl; > use CGI qw( :standard -oldstyle_urls -utf8 ); > use vars qw( $GZIP ); > use C4::Context; >+use Koha::OAI::Server::Repository; > > > BEGIN { >@@ -59,741 +58,5 @@ else { > } > > binmode STDOUT, ':encoding(UTF-8)'; >-my $repository = C4::OAI::Repository->new(); >- >- >- >- >-# __END__ Main Prog >- >- >-# >-# Extends HTTP::OAI::ResumptionToken >-# A token is identified by: >-# - metadataPrefix >-# - from >-# - until >-# - offset >-# >-package C4::OAI::ResumptionToken; >- >-use strict; >-use warnings; >-use HTTP::OAI; >- >-use base ("HTTP::OAI::ResumptionToken"); >- >- >-sub new { >- my ($class, %args) = @_; >- >- my $self = $class->SUPER::new(%args); >- >- my ($metadata_prefix, $offset, $from, $until, $set); >- if ( $args{ resumptionToken } ) { >- ($metadata_prefix, $offset, $from, $until, $set) >- = split( '/', $args{resumptionToken} ); >- } >- else { >- $metadata_prefix = $args{ metadataPrefix }; >- $from = $args{ from } || '1970-01-01'; >- $until = $args{ until }; >- unless ( $until) { >- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime( time ); >- $until = sprintf( "%.4d-%.2d-%.2d", $year+1900, $mon+1,$mday ); >- } >- #Add times to the arguments, when necessary, so they correctly match against the DB timestamps >- $from .= 'T00:00:00Z' if length($from) == 10; >- $until .= 'T23:59:59Z' if length($until) == 10; >- $offset = $args{ offset } || 0; >- $set = $args{set} || ''; >- } >- >- $self->{ metadata_prefix } = $metadata_prefix; >- $self->{ offset } = $offset; >- $self->{ from } = $from; >- $self->{ until } = $until; >- $self->{ set } = $set; >- $self->{ from_arg } = _strip_UTC_designators($from); >- $self->{ until_arg } = _strip_UTC_designators($until); >- >- $self->resumptionToken( >- join( '/', $metadata_prefix, $offset, $from, $until, $set ) ); >- $self->cursor( $offset ); >- >- return $self; >-} >- >-sub _strip_UTC_designators { >- my ( $timestamp ) = @_; >- $timestamp =~ s/T/ /g; >- $timestamp =~ s/Z//g; >- return $timestamp; >-} >- >-# __END__ C4::OAI::ResumptionToken >- >- >- >-package C4::OAI::Identify; >- >-use strict; >-use warnings; >-use HTTP::OAI; >-use C4::Context; >- >-use base ("HTTP::OAI::Identify"); >- >-sub new { >- my ($class, $repository) = @_; >- >- my ($baseURL) = $repository->self_url() =~ /(.*)\?.*/; >- my $self = $class->SUPER::new( >- baseURL => $baseURL, >- repositoryName => C4::Context->preference("LibraryName"), >- adminEmail => C4::Context->preference("KohaAdminEmailAddress"), >- MaxCount => C4::Context->preference("OAI-PMH:MaxCount"), >- granularity => 'YYYY-MM-DD', >- earliestDatestamp => '0001-01-01', >- deletedRecord => C4::Context->preference("OAI-PMH:DeletedRecord") || 'no', >- ); >- >- # FIXME - alas, the description element is not so simple; to validate >- # against the OAI-PMH schema, it cannot contain just a string, >- # but one or more elements that validate against another XML schema. >- # For now, simply omitting it. >- # $self->description( "Koha OAI Repository" ); >- >- $self->compression( 'gzip' ); >- >- return $self; >-} >- >-# __END__ C4::OAI::Identify >- >- >- >-package C4::OAI::ListMetadataFormats; >- >-use strict; >-use warnings; >-use HTTP::OAI; >- >-use base ("HTTP::OAI::ListMetadataFormats"); >- >-sub new { >- my ($class, $repository) = @_; >- >- my $self = $class->SUPER::new(); >- >- if ( $repository->{ conf } ) { >- foreach my $name ( @{ $repository->{ koha_metadata_format } } ) { >- my $format = $repository->{ conf }->{ format }->{ $name }; >- $self->metadataFormat( HTTP::OAI::MetadataFormat->new( >- metadataPrefix => $format->{metadataPrefix}, >- schema => $format->{schema}, >- metadataNamespace => $format->{metadataNamespace}, ) ); >- } >- } >- else { >- $self->metadataFormat( HTTP::OAI::MetadataFormat->new( >- metadataPrefix => 'oai_dc', >- schema => 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', >- metadataNamespace => 'http://www.openarchives.org/OAI/2.0/oai_dc/' >- ) ); >- $self->metadataFormat( HTTP::OAI::MetadataFormat->new( >- metadataPrefix => 'marcxml', >- schema => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd', >- metadataNamespace => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim' >- ) ); >- } >- >- return $self; >-} >- >-# __END__ C4::OAI::ListMetadataFormats >- >- >- >-package C4::OAI::Record; >- >-use strict; >-use warnings; >-use HTTP::OAI; >-use HTTP::OAI::Metadata::OAI_DC; >- >-use base ("HTTP::OAI::Record"); >- >-sub new { >- my ($class, $repository, $marcxml, $timestamp, $setSpecs, %args) = @_; >- >- my $self = $class->SUPER::new(%args); >- >- $timestamp =~ s/ /T/, $timestamp .= 'Z'; >- $self->header( new HTTP::OAI::Header( >- identifier => $args{identifier}, >- datestamp => $timestamp, >- ) ); >- >- foreach my $setSpec (@$setSpecs) { >- $self->header->setSpec($setSpec); >- } >- >- my $parser = XML::LibXML->new(); >- my $record_dom = $parser->parse_string( $marcxml ); >- my $format = $args{metadataPrefix}; >- if ( $format ne 'marcxml' ) { >- my %args = ( >- OPACBaseURL => "'" . C4::Context->preference('OPACBaseURL') . "'" >- ); >- $record_dom = $repository->stylesheet($format)->transform($record_dom, %args); >- } >- $self->metadata( HTTP::OAI::Metadata->new( dom => $record_dom ) ); >- >- return $self; >-} >- >-# __END__ C4::OAI::Record >- >-package C4::OAI::DeletedRecord; >- >-use Modern::Perl; >-use HTTP::OAI; >-use HTTP::OAI::Metadata::OAI_DC; >- >-use base ("HTTP::OAI::Record"); >- >-sub new { >- my ($class, $timestamp, $setSpecs, %args) = @_; >- >- my $self = $class->SUPER::new(%args); >- >- $timestamp =~ s/ /T/, $timestamp .= 'Z'; >- $self->header( new HTTP::OAI::Header( >- status => 'deleted', >- identifier => $args{identifier}, >- datestamp => $timestamp, >- ) ); >- >- foreach my $setSpec (@$setSpecs) { >- $self->header->setSpec($setSpec); >- } >- >- return $self; >-} >- >-# __END__ C4::OAI::DeletedRecord >- >- >- >-package C4::OAI::GetRecord; >- >-use strict; >-use warnings; >-use HTTP::OAI; >-use C4::Biblio; >-use C4::OAI::Sets; >-use MARC::File::XML; >- >-use base ("HTTP::OAI::GetRecord"); >- >- >-sub new { >- my ($class, $repository, %args) = @_; >- >- my $self = HTTP::OAI::GetRecord->new(%args); >- >- my $dbh = C4::Context->dbh; >- my $sth = $dbh->prepare(" >- SELECT timestamp >- FROM biblioitems >- WHERE biblionumber=? " ); >- my $prefix = $repository->{koha_identifier} . ':'; >- my ($biblionumber) = $args{identifier} =~ /^$prefix(.*)/; >- $sth->execute( $biblionumber ); >- my ($timestamp, $deleted); >- unless ( ($timestamp) = $sth->fetchrow ) { >- unless ( ($timestamp) = $dbh->selectrow_array(q/ >- SELECT timestamp >- FROM deletedbiblio >- WHERE biblionumber=? /, undef, $biblionumber )) >- { >- return HTTP::OAI::Response->new( >- requestURL => $repository->self_url(), >- errors => [ new HTTP::OAI::Error( >- code => 'idDoesNotExist', >- message => "There is no biblio record with this identifier", >- ) ], >- ); >- } >- else { >- $deleted = 1; >- } >- } >- >- # We fetch it using this method, rather than the database directly, >- # so it'll include the item data >- my $marcxml; >- $marcxml = $repository->get_biblio_marcxml($biblionumber, $args{metadataPrefix}) >- unless $deleted; >- my $oai_sets = GetOAISetsBiblio($biblionumber); >- my @setSpecs; >- foreach (@$oai_sets) { >- push @setSpecs, $_->{spec}; >- } >- >- #$self->header( HTTP::OAI::Header->new( identifier => $args{identifier} ) ); >- $self->record( >- $deleted >- ? C4::OAI::DeletedRecord->new($timestamp, \@setSpecs, %args) >- : C4::OAI::Record->new($repository, $marcxml, $timestamp, \@setSpecs, %args) >- ); >- return $self; >-} >- >-# __END__ C4::OAI::GetRecord >- >- >- >-package C4::OAI::ListIdentifiers; >- >-use strict; >-use warnings; >-use HTTP::OAI; >-use C4::OAI::Sets; >- >-use base ("HTTP::OAI::ListIdentifiers"); >- >- >-sub new { >- my ($class, $repository, %args) = @_; >- >- my $self = HTTP::OAI::ListIdentifiers->new(%args); >- >- my $token = new C4::OAI::ResumptionToken( %args ); >- my $dbh = C4::Context->dbh; >- my $set; >- if(defined $token->{'set'}) { >- $set = GetOAISetBySpec($token->{'set'}); >- } >- my $max = $repository->{koha_max_count}; >- my $sql = " >- (SELECT biblioitems.biblionumber, biblioitems.timestamp >- FROM biblioitems >- "; >- $sql .= " JOIN oai_sets_biblios ON biblioitems.biblionumber = oai_sets_biblios.biblionumber " if defined $set; >- $sql .= " WHERE timestamp >= ? AND timestamp <= ? "; >- $sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; >- $sql .= ") UNION >- (SELECT deletedbiblio.biblionumber, timestamp FROM deletedbiblio"; >- $sql .= " JOIN oai_sets_biblios ON deletedbiblio.biblionumber = oai_sets_biblios.biblionumber " if defined $set; >- $sql .= " WHERE DATE(timestamp) >= ? AND DATE(timestamp) <= ? "; >- $sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; >- >- $sql .= ") ORDER BY biblionumber >- LIMIT " . ($max+1) . " >- OFFSET $token->{offset} >- "; >- my $sth = $dbh->prepare( $sql ); >- my @bind_params = ($token->{'from_arg'}, $token->{'until_arg'}); >- push @bind_params, $set->{'id'} if defined $set; >- push @bind_params, ($token->{'from'}, $token->{'until'}); >- push @bind_params, $set->{'id'} if defined $set; >- $sth->execute( @bind_params ); >- >- my $count = 0; >- while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { >- $count++; >- if ( $count > $max ) { >- $self->resumptionToken( >- new C4::OAI::ResumptionToken( >- metadataPrefix => $token->{metadata_prefix}, >- from => $token->{from}, >- until => $token->{until}, >- offset => $token->{offset} + $max, >- set => $token->{set} >- ) >- ); >- last; >- } >- $timestamp =~ s/ /T/, $timestamp .= 'Z'; >- $self->identifier( new HTTP::OAI::Header( >- identifier => $repository->{ koha_identifier} . ':' . $biblionumber, >- datestamp => $timestamp, >- ) ); >- } >- >- # Return error if no results >- unless ($count) { >- return HTTP::OAI::Response->new( >- requestURL => $repository->self_url(), >- errors => [ new HTTP::OAI::Error( code => 'noRecordsMatch' ) ], >- ); >- } >- >- return $self; >-} >- >-# __END__ C4::OAI::ListIdentifiers >- >-package C4::OAI::Description; >- >-use strict; >-use warnings; >-use HTTP::OAI; >-use HTTP::OAI::SAXHandler qw/ :SAX /; >- >-sub new { >- my ( $class, %args ) = @_; >- >- my $self = {}; >- >- if(my $setDescription = $args{setDescription}) { >- $self->{setDescription} = $setDescription; >- } >- if(my $handler = $args{handler}) { >- $self->{handler} = $handler; >- } >- >- bless $self, $class; >- return $self; >-} >- >-sub set_handler { >- my ( $self, $handler ) = @_; >- >- $self->{handler} = $handler if $handler; >- >- return $self; >-} >- >-sub generate { >- my ( $self ) = @_; >- >- g_data_element($self->{handler}, 'http://www.openarchives.org/OAI/2.0/', 'setDescription', {}, $self->{setDescription}); >- >- return $self; >-} >- >-# __END__ C4::OAI::Description >- >-package C4::OAI::ListSets; >- >-use strict; >-use warnings; >-use HTTP::OAI; >-use C4::OAI::Sets; >- >-use base ("HTTP::OAI::ListSets"); >- >-sub new { >- my ( $class, $repository, %args ) = @_; >- >- my $self = HTTP::OAI::ListSets->new(%args); >- >- my $token = C4::OAI::ResumptionToken->new(%args); >- my $sets = GetOAISets; >- my $pos = 0; >- foreach my $set (@$sets) { >- if ($pos < $token->{offset}) { >- $pos++; >- next; >- } >- my @descriptions; >- foreach my $desc (@{$set->{'descriptions'}}) { >- push @descriptions, C4::OAI::Description->new( >- setDescription => $desc, >- ); >- } >- $self->set( >- HTTP::OAI::Set->new( >- setSpec => $set->{'spec'}, >- setName => $set->{'name'}, >- setDescription => \@descriptions, >- ) >- ); >- $pos++; >- last if ($pos + 1 - $token->{offset}) > $repository->{koha_max_count}; >- } >- >- $self->resumptionToken( >- new C4::OAI::ResumptionToken( >- metadataPrefix => $token->{metadata_prefix}, >- offset => $pos >- ) >- ) if ( $pos > $token->{offset} ); >- >- return $self; >-} >- >-# __END__ C4::OAI::ListSets; >- >-package C4::OAI::ListRecords; >- >-use strict; >-use warnings; >-use C4::Biblio; >-use HTTP::OAI; >-use C4::OAI::Sets; >-use MARC::File::XML; >- >-use base ("HTTP::OAI::ListRecords"); >- >- >-sub new { >- my ($class, $repository, %args) = @_; >- >- my $self = HTTP::OAI::ListRecords->new(%args); >- >- my $token = new C4::OAI::ResumptionToken( %args ); >- my $dbh = C4::Context->dbh; >- my $set; >- if(defined $token->{'set'}) { >- $set = GetOAISetBySpec($token->{'set'}); >- } >- my $max = $repository->{koha_max_count}; >- my $sql = " >- (SELECT biblioitems.biblionumber, biblioitems.timestamp, marcxml >- FROM biblioitems >- "; >- $sql .= " JOIN oai_sets_biblios ON biblioitems.biblionumber = oai_sets_biblios.biblionumber " if defined $set; >- $sql .= " WHERE timestamp >= ? AND timestamp <= ? "; >- $sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; >- $sql .= ") UNION >- (SELECT deletedbiblio.biblionumber, null as marcxml, timestamp FROM deletedbiblio"; >- $sql .= " JOIN oai_sets_biblios ON deletedbiblio.biblionumber = oai_sets_biblios.biblionumber " if defined $set; >- $sql .= " WHERE DATE(timestamp) >= ? AND DATE(timestamp) <= ? "; >- $sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; >- >- $sql .= ") ORDER BY biblionumber >- LIMIT " . ($max + 1) . " >- OFFSET $token->{offset} >- "; >- my $sth = $dbh->prepare( $sql ); >- my @bind_params = ($token->{'from_arg'}, $token->{'until_arg'}); >- push @bind_params, $set->{'id'} if defined $set; >- push @bind_params, ($token->{'from'}, $token->{'until'}); >- push @bind_params, $set->{'id'} if defined $set; >- $sth->execute( @bind_params ); >- >- my $count = 0; >- my $format = $args{metadataPrefix} || $token->{metadata_prefix}; >- while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { >- $count++; >- if ( $count > $max ) { >- $self->resumptionToken( >- new C4::OAI::ResumptionToken( >- metadataPrefix => $token->{metadata_prefix}, >- from => $token->{from}, >- until => $token->{until}, >- offset => $token->{offset} + $max, >- set => $token->{set} >- ) >- ); >- last; >- } >- my $marcxml = $repository->get_biblio_marcxml($biblionumber, $format); >- my $oai_sets = GetOAISetsBiblio($biblionumber); >- my @setSpecs; >- foreach (@$oai_sets) { >- push @setSpecs, $_->{spec}; >- } >- if ($marcxml) { >- $self->record( C4::OAI::Record->new( >- $repository, $marcxml, $timestamp, \@setSpecs, >- identifier => $repository->{ koha_identifier } . ':' . $biblionumber, >- metadataPrefix => $token->{metadata_prefix} >- ) ); >- } else { >- $self->record( C4::OAI::DeletedRecord->new( >- $timestamp, \@setSpecs, identifier => $repository->{ koha_identifier } . ':' . $biblionumber ) ); >- } >- } >- >- # Return error if no results >- unless ($count) { >- return HTTP::OAI::Response->new( >- requestURL => $repository->self_url(), >- errors => [ new HTTP::OAI::Error( code => 'noRecordsMatch' ) ], >- ); >- } >- >- return $self; >-} >- >-# __END__ C4::OAI::ListRecords >- >- >- >-package C4::OAI::Repository; >- >-use base ("HTTP::OAI::Repository"); >- >-use strict; >-use warnings; >- >-use HTTP::OAI; >-use HTTP::OAI::Repository qw/:validate/; >- >-use XML::SAX::Writer; >-use XML::LibXML; >-use XML::LibXSLT; >-use YAML::Syck qw( LoadFile ); >-use CGI qw/:standard -oldstyle_urls/; >- >-use C4::Context; >-use C4::Biblio; >- >- >-sub new { >- my ($class, %args) = @_; >- my $self = $class->SUPER::new(%args); >- >- $self->{ koha_identifier } = C4::Context->preference("OAI-PMH:archiveID"); >- $self->{ koha_max_count } = C4::Context->preference("OAI-PMH:MaxCount"); >- $self->{ koha_metadata_format } = ['oai_dc', 'marcxml']; >- $self->{ koha_stylesheet } = { }; # Build when needed >- >- # Load configuration file if defined in OAI-PMH:ConfFile syspref >- if ( my $file = C4::Context->preference("OAI-PMH:ConfFile") ) { >- $self->{ conf } = LoadFile( $file ); >- my @formats = keys %{ $self->{conf}->{format} }; >- $self->{ koha_metadata_format } = \@formats; >- } >- >- # Check for grammatical errors in the request >- my @errs = validate_request( CGI::Vars() ); >- >- # Is metadataPrefix supported by the respository? >- my $mdp = param('metadataPrefix') || ''; >- if ( $mdp && !grep { $_ eq $mdp } @{$self->{ koha_metadata_format }} ) { >- push @errs, new HTTP::OAI::Error( >- code => 'cannotDisseminateFormat', >- message => "Dissemination as '$mdp' is not supported", >- ); >- } >- >- my $response; >- if ( @errs ) { >- $response = HTTP::OAI::Response->new( >- requestURL => self_url(), >- errors => \@errs, >- ); >- } >- else { >- my %attr = CGI::Vars(); >- my $verb = delete( $attr{verb} ); >- if ( $verb eq 'ListSets' ) { >- $response = C4::OAI::ListSets->new($self, %attr); >- } >- elsif ( $verb eq 'Identify' ) { >- $response = C4::OAI::Identify->new( $self ); >- } >- elsif ( $verb eq 'ListMetadataFormats' ) { >- $response = C4::OAI::ListMetadataFormats->new( $self ); >- } >- elsif ( $verb eq 'GetRecord' ) { >- $response = C4::OAI::GetRecord->new( $self, %attr ); >- } >- elsif ( $verb eq 'ListRecords' ) { >- $response = C4::OAI::ListRecords->new( $self, %attr ); >- } >- elsif ( $verb eq 'ListIdentifiers' ) { >- $response = C4::OAI::ListIdentifiers->new( $self, %attr ); >- } >- } >- >- $response->set_handler( XML::SAX::Writer->new( Output => *STDOUT ) ); >- $response->generate; >- >- bless $self, $class; >- return $self; >-} >- >- >-sub get_biblio_marcxml { >- my ($self, $biblionumber, $format) = @_; >- my $with_items = 0; >- if ( my $conf = $self->{conf} ) { >- $with_items = $conf->{format}->{$format}->{include_items}; >- } >- my $record = GetMarcBiblio($biblionumber, $with_items, 1); >- $record ? $record->as_xml() : undef; >-} >- >- >-sub stylesheet { >- my ( $self, $format ) = @_; >- >- my $stylesheet = $self->{ koha_stylesheet }->{ $format }; >- unless ( $stylesheet ) { >- my $xsl_file = $self->{ conf } >- ? $self->{ conf }->{ format }->{ $format }->{ xsl_file } >- : ( C4::Context->config('intrahtdocs') . >- '/prog/en/xslt/' . >- C4::Context->preference('marcflavour') . >- 'slim2OAIDC.xsl' ); >- my $parser = XML::LibXML->new(); >- my $xslt = XML::LibXSLT->new(); >- my $style_doc = $parser->parse_file( $xsl_file ); >- $stylesheet = $xslt->parse_stylesheet( $style_doc ); >- $self->{ koha_stylesheet }->{ $format } = $stylesheet; >- } >- >- return $stylesheet; >-} >- >- >- >-=head1 NAME >- >-C4::OAI::Repository - Handles OAI-PMH requests for a Koha database. >- >-=head1 SYNOPSIS >- >- use C4::OAI::Repository; >- >- my $repository = C4::OAI::Repository->new(); >- >-=head1 DESCRIPTION >- >-This object extend HTTP::OAI::Repository object. >-It accepts OAI-PMH HTTP requests and returns result. >- >-This OAI-PMH server can operate in a simple mode and extended one. >- >-In simple mode, repository configuration comes entirely from Koha system >-preferences (OAI-PMH:archiveID and OAI-PMH:MaxCount) and the server returns >-records in marcxml or dublin core format. Dublin core records are created from >-koha marcxml records tranformed with XSLT. Used XSL file is located in >-koha-tmpl/intranet-tmpl/prog/en/xslt directory and choosed based on marcflavour, >-respecively MARC21slim2OAIDC.xsl for MARC21 and MARC21slim2OAIDC.xsl for >-UNIMARC. >- >-In extende mode, it's possible to parameter other format than marcxml or Dublin >-Core. A new syspref OAI-PMH:ConfFile specify a YAML configuration file which >-list available metadata formats and XSL file used to create them from marcxml >-records. If this syspref isn't set, Koha OAI server works in simple mode. A >-configuration file koha-oai.conf can look like that: >- >- --- >- format: >- vs: >- metadataPrefix: vs >- metadataNamespace: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs >- schema: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs.xsd >- xsl_file: /usr/local/koha/xslt/vs.xsl >- marcxml: >- metadataPrefix: marxml >- metadataNamespace: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim >- schema: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd >- oai_dc: >- metadataPrefix: oai_dc >- metadataNamespace: http://www.openarchives.org/OAI/2.0/oai_dc/ >- schema: http://www.openarchives.org/OAI/2.0/oai_dc.xsd >- xsl_file: /usr/local/koha/koha-tmpl/intranet-tmpl/xslt/UNIMARCslim2OAIDC.xsl >- >-=cut >- >- > >+my $repository = Koha::OAI::Server::Repository->new(); >diff --git a/t/db_dependent/OAI/Server.t b/t/db_dependent/OAI/Server.t >new file mode 100644 >index 0000000..bc36f6e >--- /dev/null >+++ b/t/db_dependent/OAI/Server.t >@@ -0,0 +1,96 @@ >+#!/usr/bin/perl >+ >+# Copyright Tamil s.a.r.l. 2015 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+ >+use Modern::Perl; >+use C4::Context; >+use C4::Biblio; >+use Test::More tests => 13; >+use Test::MockModule; >+use Test::Warn; >+use DateTime; >+use Capture::Tiny ':all'; >+ >+ >+ >+BEGIN { >+ use_ok('Koha::OAI::Server::DeletedRecord'); >+ use_ok('Koha::OAI::Server::Description'); >+ use_ok('Koha::OAI::Server::GetRecord'); >+ use_ok('Koha::OAI::Server::Identify'); >+ use_ok('Koha::OAI::Server::ListIdentifiers'); >+ use_ok('Koha::OAI::Server::ListMetadataFormats'); >+ use_ok('Koha::OAI::Server::ListRecords'); >+ use_ok('Koha::OAI::Server::ListSets'); >+ use_ok('Koha::OAI::Server::Record'); >+ use_ok('Koha::OAI::Server::Repository'); >+ use_ok('Koha::OAI::Server::ResumptionToken'); >+} >+ >+my $dbh = C4::Context->dbh; >+$dbh->{AutoCommit} = 0; >+$dbh->{RaiseError} = 1; >+$dbh->do('DELETE FROM issues'); >+$dbh->do('DELETE FROM biblio'); >+$dbh->do('DELETE FROM biblioitems'); >+$dbh->do('DELETE FROM items'); >+ >+ >+my %param; >+my $module = Test::MockModule->new('CGI'); >+$module->mock('Vars', sub { %param; }); >+ >+# Add 10 biblio records >+my @bibs = map { >+ my $record = MARC::Record->new(); >+ $record->append_fields( MARC::Field->new('245', '', '', 'a' => "Title $_" ) ); >+ my ($biblionumber) = AddBiblio($record, ''); >+ $biblionumber; >+} (1..10); >+ >+C4::Context->set_preference('OAI::PMH', 1); >+C4::Context->set_preference('OAI-PMH:archiveID', 'TEST'); >+C4::Context->set_preference('OAI-PMH:ConfFile', '' ); >+C4::Context->set_preference('OAI-PMH:MaxCount', 3); >+C4::Context->set_preference('OAI-PMH:DeletedRecord', 'persistent'); >+ >+%param = ( verb => 'ListMetadataFormats' ); >+my ($stdout) = capture { Koha::OAI::Server::Repository->new(); }; >+my $now = DateTime->now . 'Z'; >+my $expected = <<EOS; >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<OAI-PMH xmlns='http://www.openarchives.org/OAI/2.0/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd'><responseDate>$now</responseDate><request>http://localhost</request><ListMetadataFormats><metadataFormat><metadataPrefix>oai_dc</metadataPrefix><schema>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</schema><metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</metadataNamespace></metadataFormat><metadataFormat><metadataPrefix>marcxml</metadataPrefix><schema>http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd</schema><metadataNamespace>http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim</metadataNamespace></metadataFormat></ListMetadataFormats></OAI-PMH> >+EOS >+chop $expected; >+is($stdout, $expected, "ListMetadataFormats"); >+ >+ >+%param = ( verb => 'ListIdentifiers' ); >+($stdout) = capture { Koha::OAI::Server::Repository->new(); }; >+$now = DateTime->now . 'Z'; >+$expected = <<EOS; >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<OAI-PMH xmlns='http://www.openarchives.org/OAI/2.0/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd'><responseDate>$now</responseDate><request>http://localhost</request><error code='badArgument'>Required argument 'metadataPrefix' was undefined</error></OAI-PMH> >+EOS >+chop $expected; >+is($stdout, $expected, "ListIdentifiers without metadaPrefix argument"); >+ >+$dbh->rollback; >-- >2.6.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 14939
:
43045
|
43072
|
44355
|
44371
|
44438
|
44866
|
44875
|
44904
|
44913
|
44914
|
44915
|
45320
|
45386
|
45567
|
45577
|
45602
|
45603