|
Lines 2-8
Link Here
|
| 2 |
|
2 |
|
| 3 |
use strict; |
3 |
use strict; |
| 4 |
use warnings; |
4 |
use warnings; |
| 5 |
use diagnostics; |
|
|
| 6 |
|
5 |
|
| 7 |
use CGI qw/:standard -oldstyle_urls/; |
6 |
use CGI qw/:standard -oldstyle_urls/; |
| 8 |
use vars qw( $GZIP ); |
7 |
use vars qw( $GZIP ); |
|
Lines 59-65
package C4::OAI::ResumptionToken;
Link Here
|
| 59 |
|
58 |
|
| 60 |
use strict; |
59 |
use strict; |
| 61 |
use warnings; |
60 |
use warnings; |
| 62 |
use diagnostics; |
|
|
| 63 |
use HTTP::OAI; |
61 |
use HTTP::OAI; |
| 64 |
|
62 |
|
| 65 |
use base ("HTTP::OAI::ResumptionToken"); |
63 |
use base ("HTTP::OAI::ResumptionToken"); |
|
Lines 70-78
sub new {
Link Here
|
| 70 |
|
68 |
|
| 71 |
my $self = $class->SUPER::new(%args); |
69 |
my $self = $class->SUPER::new(%args); |
| 72 |
|
70 |
|
| 73 |
my ($metadata_prefix, $offset, $from, $until); |
71 |
my ($metadata_prefix, $offset, $from, $until, $set); |
| 74 |
if ( $args{ resumptionToken } ) { |
72 |
if ( $args{ resumptionToken } ) { |
| 75 |
($metadata_prefix, $offset, $from, $until) |
73 |
($metadata_prefix, $offset, $from, $until, $set) |
| 76 |
= split( ':', $args{resumptionToken} ); |
74 |
= split( ':', $args{resumptionToken} ); |
| 77 |
} |
75 |
} |
| 78 |
else { |
76 |
else { |
|
Lines 84-98
sub new {
Link Here
|
| 84 |
$until = sprintf( "%.4d-%.2d-%.2d", $year+1900, $mon+1,$mday ); |
82 |
$until = sprintf( "%.4d-%.2d-%.2d", $year+1900, $mon+1,$mday ); |
| 85 |
} |
83 |
} |
| 86 |
$offset = $args{ offset } || 0; |
84 |
$offset = $args{ offset } || 0; |
|
|
85 |
$set = $args{set}; |
| 87 |
} |
86 |
} |
| 88 |
|
87 |
|
| 89 |
$self->{ metadata_prefix } = $metadata_prefix; |
88 |
$self->{ metadata_prefix } = $metadata_prefix; |
| 90 |
$self->{ offset } = $offset; |
89 |
$self->{ offset } = $offset; |
| 91 |
$self->{ from } = $from; |
90 |
$self->{ from } = $from; |
| 92 |
$self->{ until } = $until; |
91 |
$self->{ until } = $until; |
|
|
92 |
$self->{ set } = $set; |
| 93 |
|
93 |
|
| 94 |
$self->resumptionToken( |
94 |
$self->resumptionToken( |
| 95 |
join( ':', $metadata_prefix, $offset, $from, $until ) ); |
95 |
join( ':', $metadata_prefix, $offset, $from, $until, $set ) ); |
| 96 |
$self->cursor( $offset ); |
96 |
$self->cursor( $offset ); |
| 97 |
|
97 |
|
| 98 |
return $self; |
98 |
return $self; |
|
Lines 106-112
package C4::OAI::Identify;
Link Here
|
| 106 |
|
106 |
|
| 107 |
use strict; |
107 |
use strict; |
| 108 |
use warnings; |
108 |
use warnings; |
| 109 |
use diagnostics; |
|
|
| 110 |
use HTTP::OAI; |
109 |
use HTTP::OAI; |
| 111 |
use C4::Context; |
110 |
use C4::Context; |
| 112 |
|
111 |
|
|
Lines 145-151
package C4::OAI::ListMetadataFormats;
Link Here
|
| 145 |
|
144 |
|
| 146 |
use strict; |
145 |
use strict; |
| 147 |
use warnings; |
146 |
use warnings; |
| 148 |
use diagnostics; |
|
|
| 149 |
use HTTP::OAI; |
147 |
use HTTP::OAI; |
| 150 |
|
148 |
|
| 151 |
use base ("HTTP::OAI::ListMetadataFormats"); |
149 |
use base ("HTTP::OAI::ListMetadataFormats"); |
|
Lines 188-201
package C4::OAI::Record;
Link Here
|
| 188 |
|
186 |
|
| 189 |
use strict; |
187 |
use strict; |
| 190 |
use warnings; |
188 |
use warnings; |
| 191 |
use diagnostics; |
|
|
| 192 |
use HTTP::OAI; |
189 |
use HTTP::OAI; |
| 193 |
use HTTP::OAI::Metadata::OAI_DC; |
190 |
use HTTP::OAI::Metadata::OAI_DC; |
| 194 |
|
191 |
|
| 195 |
use base ("HTTP::OAI::Record"); |
192 |
use base ("HTTP::OAI::Record"); |
| 196 |
|
193 |
|
| 197 |
sub new { |
194 |
sub new { |
| 198 |
my ($class, $repository, $marcxml, $timestamp, %args) = @_; |
195 |
my ($class, $repository, $marcxml, $timestamp, $setSpecs, %args) = @_; |
| 199 |
|
196 |
|
| 200 |
my $self = $class->SUPER::new(%args); |
197 |
my $self = $class->SUPER::new(%args); |
| 201 |
|
198 |
|
|
Lines 205-215
sub new {
Link Here
|
| 205 |
datestamp => $timestamp, |
202 |
datestamp => $timestamp, |
| 206 |
) ); |
203 |
) ); |
| 207 |
|
204 |
|
|
|
205 |
foreach my $setSpec (@$setSpecs) { |
| 206 |
$self->header->setSpec($setSpec); |
| 207 |
} |
| 208 |
|
| 208 |
my $parser = XML::LibXML->new(); |
209 |
my $parser = XML::LibXML->new(); |
| 209 |
my $record_dom = $parser->parse_string( $marcxml ); |
210 |
my $record_dom = $parser->parse_string( $marcxml ); |
| 210 |
my $format = $args{metadataPrefix}; |
211 |
my $format = $args{metadataPrefix}; |
| 211 |
if ( $format ne 'marcxml' ) { |
212 |
if ( $format ne 'marcxml' ) { |
| 212 |
$record_dom = $repository->stylesheet($format)->transform( $record_dom ); |
213 |
my %args = ( |
|
|
214 |
OPACBaseURL => "'" . C4::Context->preference('OPACBaseURL') . "'" |
| 215 |
); |
| 216 |
$record_dom = $repository->stylesheet($format)->transform($record_dom, %args); |
| 213 |
} |
217 |
} |
| 214 |
$self->metadata( HTTP::OAI::Metadata->new( dom => $record_dom ) ); |
218 |
$self->metadata( HTTP::OAI::Metadata->new( dom => $record_dom ) ); |
| 215 |
|
219 |
|
|
Lines 224-231
package C4::OAI::GetRecord;
Link Here
|
| 224 |
|
228 |
|
| 225 |
use strict; |
229 |
use strict; |
| 226 |
use warnings; |
230 |
use warnings; |
| 227 |
use diagnostics; |
|
|
| 228 |
use HTTP::OAI; |
231 |
use HTTP::OAI; |
|
|
232 |
use C4::OAI::Sets; |
| 229 |
|
233 |
|
| 230 |
use base ("HTTP::OAI::GetRecord"); |
234 |
use base ("HTTP::OAI::GetRecord"); |
| 231 |
|
235 |
|
|
Lines 254-262
sub new {
Link Here
|
| 254 |
); |
258 |
); |
| 255 |
} |
259 |
} |
| 256 |
|
260 |
|
|
|
261 |
my $oai_sets = GetOAISetsBiblio($biblionumber); |
| 262 |
my @setSpecs; |
| 263 |
foreach (@$oai_sets) { |
| 264 |
push @setSpecs, $_->{spec}; |
| 265 |
} |
| 266 |
|
| 257 |
#$self->header( HTTP::OAI::Header->new( identifier => $args{identifier} ) ); |
267 |
#$self->header( HTTP::OAI::Header->new( identifier => $args{identifier} ) ); |
| 258 |
$self->record( C4::OAI::Record->new( |
268 |
$self->record( C4::OAI::Record->new( |
| 259 |
$repository, $marcxml, $timestamp, %args ) ); |
269 |
$repository, $marcxml, $timestamp, \@setSpecs, %args ) ); |
| 260 |
|
270 |
|
| 261 |
return $self; |
271 |
return $self; |
| 262 |
} |
272 |
} |
|
Lines 269-276
package C4::OAI::ListIdentifiers;
Link Here
|
| 269 |
|
279 |
|
| 270 |
use strict; |
280 |
use strict; |
| 271 |
use warnings; |
281 |
use warnings; |
| 272 |
use diagnostics; |
|
|
| 273 |
use HTTP::OAI; |
282 |
use HTTP::OAI; |
|
|
283 |
use C4::OAI::Sets; |
| 274 |
|
284 |
|
| 275 |
use base ("HTTP::OAI::ListIdentifiers"); |
285 |
use base ("HTTP::OAI::ListIdentifiers"); |
| 276 |
|
286 |
|
|
Lines 282-323
sub new {
Link Here
|
| 282 |
|
292 |
|
| 283 |
my $token = new C4::OAI::ResumptionToken( %args ); |
293 |
my $token = new C4::OAI::ResumptionToken( %args ); |
| 284 |
my $dbh = C4::Context->dbh; |
294 |
my $dbh = C4::Context->dbh; |
| 285 |
my $sql = "SELECT biblionumber, timestamp |
295 |
my $set; |
| 286 |
FROM biblioitems |
296 |
if(defined $token->{'set'}) { |
| 287 |
WHERE timestamp >= ? AND timestamp <= ? |
297 |
$set = GetOAISetBySpec($token->{'set'}); |
| 288 |
LIMIT " . $repository->{koha_max_count} . " |
298 |
} |
| 289 |
OFFSET " . $token->{offset}; |
299 |
my $sql = " |
|
|
300 |
SELECT biblioitems.biblionumber, biblioitems.timestamp |
| 301 |
FROM biblioitems |
| 302 |
"; |
| 303 |
$sql .= " JOIN oai_sets_biblios ON biblioitems.biblionumber = oai_sets_biblios.biblionumber " if defined $set; |
| 304 |
$sql .= " WHERE DATE(timestamp) >= ? AND DATE(timestamp) <= ? "; |
| 305 |
$sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; |
| 306 |
$sql .= " |
| 307 |
LIMIT $repository->{'koha_max_count'} |
| 308 |
OFFSET $token->{'offset'} |
| 309 |
"; |
| 290 |
my $sth = $dbh->prepare( $sql ); |
310 |
my $sth = $dbh->prepare( $sql ); |
| 291 |
$sth->execute( $token->{from}, $token->{until} ); |
311 |
my @bind_params = ($token->{'from'}, $token->{'until'}); |
|
|
312 |
push @bind_params, $set->{'id'} if defined $set; |
| 313 |
$sth->execute( @bind_params ); |
| 292 |
|
314 |
|
| 293 |
my $pos = $token->{offset}; |
315 |
my $pos = $token->{offset}; |
| 294 |
while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { |
316 |
while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { |
| 295 |
$timestamp =~ s/ /T/, $timestamp .= 'Z'; |
317 |
$timestamp =~ s/ /T/, $timestamp .= 'Z'; |
| 296 |
$self->identifier( new HTTP::OAI::Header( |
318 |
$self->identifier( new HTTP::OAI::Header( |
| 297 |
identifier => $repository->{ koha_identifier} . ':' . $biblionumber, |
319 |
identifier => $repository->{ koha_identifier} . ':' . $biblionumber, |
| 298 |
datestamp => $timestamp, |
320 |
datestamp => $timestamp, |
| 299 |
) ); |
321 |
) ); |
| 300 |
$pos++; |
322 |
$pos++; |
| 301 |
} |
323 |
} |
| 302 |
$self->resumptionToken( new C4::OAI::ResumptionToken( |
324 |
$self->resumptionToken( |
| 303 |
metadataPrefix => $token->{metadata_prefix}, |
325 |
new C4::OAI::ResumptionToken( |
| 304 |
from => $token->{from}, |
326 |
metadataPrefix => $token->{metadata_prefix}, |
| 305 |
until => $token->{until}, |
327 |
from => $token->{from}, |
| 306 |
offset => $pos ) ) if ($pos > $token->{offset}); |
328 |
until => $token->{until}, |
|
|
329 |
offset => $pos, |
| 330 |
set => $token->{set} |
| 331 |
) |
| 332 |
) if ($pos > $token->{offset}); |
| 307 |
|
333 |
|
| 308 |
return $self; |
334 |
return $self; |
| 309 |
} |
335 |
} |
| 310 |
|
336 |
|
| 311 |
# __END__ C4::OAI::ListIdentifiers |
337 |
# __END__ C4::OAI::ListIdentifiers |
| 312 |
|
338 |
|
|
|
339 |
package C4::OAI::Description; |
| 340 |
|
| 341 |
use strict; |
| 342 |
use warnings; |
| 343 |
use HTTP::OAI; |
| 344 |
use HTTP::OAI::SAXHandler qw/ :SAX /; |
| 345 |
|
| 346 |
sub new { |
| 347 |
my ( $class, %args ) = @_; |
| 348 |
|
| 349 |
my $self = {}; |
| 350 |
|
| 351 |
if(my $setDescription = $args{setDescription}) { |
| 352 |
$self->{setDescription} = $setDescription; |
| 353 |
} |
| 354 |
if(my $handler = $args{handler}) { |
| 355 |
$self->{handler} = $handler; |
| 356 |
} |
| 357 |
|
| 358 |
bless $self, $class; |
| 359 |
return $self; |
| 360 |
} |
| 361 |
|
| 362 |
sub set_handler { |
| 363 |
my ( $self, $handler ) = @_; |
| 364 |
|
| 365 |
$self->{handler} = $handler if $handler; |
| 366 |
|
| 367 |
return $self; |
| 368 |
} |
| 369 |
|
| 370 |
sub generate { |
| 371 |
my ( $self ) = @_; |
| 372 |
|
| 373 |
g_data_element($self->{handler}, 'http://www.openarchives.org/OAI/2.0/', 'setDescription', {}, $self->{setDescription}); |
| 374 |
|
| 375 |
return $self; |
| 376 |
} |
| 377 |
|
| 378 |
# __END__ C4::OAI::Description |
| 379 |
|
| 380 |
package C4::OAI::ListSets; |
| 381 |
|
| 382 |
use strict; |
| 383 |
use warnings; |
| 384 |
use HTTP::OAI; |
| 385 |
use C4::OAI::Sets; |
| 386 |
|
| 387 |
use base ("HTTP::OAI::ListSets"); |
| 388 |
|
| 389 |
sub new { |
| 390 |
my ( $class, $repository, %args ) = @_; |
| 391 |
|
| 392 |
my $self = HTTP::OAI::ListSets->new(%args); |
| 393 |
|
| 394 |
my $token = C4::OAI::ResumptionToken->new(%args); |
| 395 |
my $sets = GetOAISets; |
| 396 |
my $pos = 0; |
| 397 |
foreach my $set (@$sets) { |
| 398 |
if ($pos < $token->{offset}) { |
| 399 |
$pos++; |
| 400 |
next; |
| 401 |
} |
| 402 |
my @descriptions; |
| 403 |
foreach my $desc (@{$set->{'descriptions'}}) { |
| 404 |
push @descriptions, C4::OAI::Description->new( |
| 405 |
setDescription => $desc, |
| 406 |
); |
| 407 |
} |
| 408 |
$self->set( |
| 409 |
HTTP::OAI::Set->new( |
| 410 |
setSpec => $set->{'spec'}, |
| 411 |
setName => $set->{'name'}, |
| 412 |
setDescription => \@descriptions, |
| 413 |
) |
| 414 |
); |
| 415 |
$pos++; |
| 416 |
last if ($pos + 1 - $token->{offset}) > $repository->{koha_max_count}; |
| 417 |
} |
| 313 |
|
418 |
|
|
|
419 |
$self->resumptionToken( |
| 420 |
new C4::OAI::ResumptionToken( |
| 421 |
metadataPrefix => $token->{metadata_prefix}, |
| 422 |
offset => $pos |
| 423 |
) |
| 424 |
) if ( $pos > $token->{offset} ); |
| 425 |
|
| 426 |
return $self; |
| 427 |
} |
| 428 |
|
| 429 |
# __END__ C4::OAI::ListSets; |
| 314 |
|
430 |
|
| 315 |
package C4::OAI::ListRecords; |
431 |
package C4::OAI::ListRecords; |
| 316 |
|
432 |
|
| 317 |
use strict; |
433 |
use strict; |
| 318 |
use warnings; |
434 |
use warnings; |
| 319 |
use diagnostics; |
|
|
| 320 |
use HTTP::OAI; |
435 |
use HTTP::OAI; |
|
|
436 |
use C4::OAI::Sets; |
| 321 |
|
437 |
|
| 322 |
use base ("HTTP::OAI::ListRecords"); |
438 |
use base ("HTTP::OAI::ListRecords"); |
| 323 |
|
439 |
|
|
Lines 329-356
sub new {
Link Here
|
| 329 |
|
445 |
|
| 330 |
my $token = new C4::OAI::ResumptionToken( %args ); |
446 |
my $token = new C4::OAI::ResumptionToken( %args ); |
| 331 |
my $dbh = C4::Context->dbh; |
447 |
my $dbh = C4::Context->dbh; |
| 332 |
my $sql = "SELECT biblionumber, marcxml, timestamp |
448 |
my $set; |
| 333 |
FROM biblioitems |
449 |
if(defined $token->{'set'}) { |
| 334 |
WHERE timestamp >= ? AND timestamp <= ? |
450 |
$set = GetOAISetBySpec($token->{'set'}); |
| 335 |
LIMIT " . $repository->{koha_max_count} . " |
451 |
} |
| 336 |
OFFSET " . $token->{offset}; |
452 |
my $sql = " |
|
|
453 |
SELECT biblioitems.biblionumber, biblioitems.marcxml, biblioitems.timestamp |
| 454 |
FROM biblioitems |
| 455 |
"; |
| 456 |
$sql .= " JOIN oai_sets_biblios ON biblioitems.biblionumber = oai_sets_biblios.biblionumber " if defined $set; |
| 457 |
$sql .= " WHERE DATE(timestamp) >= ? AND DATE(timestamp) <= ? "; |
| 458 |
$sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; |
| 459 |
$sql .= " |
| 460 |
LIMIT $repository->{'koha_max_count'} |
| 461 |
OFFSET $token->{'offset'} |
| 462 |
"; |
| 463 |
|
| 337 |
my $sth = $dbh->prepare( $sql ); |
464 |
my $sth = $dbh->prepare( $sql ); |
| 338 |
$sth->execute( $token->{from}, $token->{until} ); |
465 |
my @bind_params = ($token->{'from'}, $token->{'until'}); |
|
|
466 |
push @bind_params, $set->{'id'} if defined $set; |
| 467 |
$sth->execute( @bind_params ); |
| 339 |
|
468 |
|
| 340 |
my $pos = $token->{offset}; |
469 |
my $pos = $token->{offset}; |
| 341 |
while ( my ($biblionumber, $marcxml, $timestamp) = $sth->fetchrow ) { |
470 |
while ( my ($biblionumber, $marcxml, $timestamp) = $sth->fetchrow ) { |
|
|
471 |
my $oai_sets = GetOAISetsBiblio($biblionumber); |
| 472 |
my @setSpecs; |
| 473 |
foreach (@$oai_sets) { |
| 474 |
push @setSpecs, $_->{spec}; |
| 475 |
} |
| 342 |
$self->record( C4::OAI::Record->new( |
476 |
$self->record( C4::OAI::Record->new( |
| 343 |
$repository, $marcxml, $timestamp, |
477 |
$repository, $marcxml, $timestamp, \@setSpecs, |
| 344 |
identifier => $repository->{ koha_identifier } . ':' . $biblionumber, |
478 |
identifier => $repository->{ koha_identifier } . ':' . $biblionumber, |
| 345 |
metadataPrefix => $token->{metadata_prefix} |
479 |
metadataPrefix => $token->{metadata_prefix} |
| 346 |
) ); |
480 |
) ); |
| 347 |
$pos++; |
481 |
$pos++; |
| 348 |
} |
482 |
} |
| 349 |
$self->resumptionToken( new C4::OAI::ResumptionToken( |
483 |
$self->resumptionToken( |
| 350 |
metadataPrefix => $token->{metadata_prefix}, |
484 |
new C4::OAI::ResumptionToken( |
| 351 |
from => $token->{from}, |
485 |
metadataPrefix => $token->{metadata_prefix}, |
| 352 |
until => $token->{until}, |
486 |
from => $token->{from}, |
| 353 |
offset => $pos ) ) if ($pos > $token->{offset}); |
487 |
until => $token->{until}, |
|
|
488 |
offset => $pos, |
| 489 |
set => $token->{set} |
| 490 |
) |
| 491 |
) if ($pos > $token->{offset}); |
| 354 |
|
492 |
|
| 355 |
return $self; |
493 |
return $self; |
| 356 |
} |
494 |
} |
|
Lines 365-371
use base ("HTTP::OAI::Repository");
Link Here
|
| 365 |
|
503 |
|
| 366 |
use strict; |
504 |
use strict; |
| 367 |
use warnings; |
505 |
use warnings; |
| 368 |
use diagnostics; |
|
|
| 369 |
|
506 |
|
| 370 |
use HTTP::OAI; |
507 |
use HTTP::OAI; |
| 371 |
use HTTP::OAI::Repository qw/:validate/; |
508 |
use HTTP::OAI::Repository qw/:validate/; |
|
Lines 418-431
sub new {
Link Here
|
| 418 |
else { |
555 |
else { |
| 419 |
my %attr = CGI::Vars(); |
556 |
my %attr = CGI::Vars(); |
| 420 |
my $verb = delete( $attr{verb} ); |
557 |
my $verb = delete( $attr{verb} ); |
| 421 |
if ( grep { $_ eq $verb } qw( ListSets ) ) { |
558 |
if ( $verb eq 'ListSets' ) { |
| 422 |
$response = HTTP::OAI::Response->new( |
559 |
$response = C4::OAI::ListSets->new($self, %attr); |
| 423 |
requestURL => $self->self_url(), |
|
|
| 424 |
errors => [ new HTTP::OAI::Error( |
| 425 |
code => 'noSetHierarchy', |
| 426 |
message => "Koha repository doesn't have sets", |
| 427 |
) ] , |
| 428 |
); |
| 429 |
} |
560 |
} |
| 430 |
elsif ( $verb eq 'Identify' ) { |
561 |
elsif ( $verb eq 'Identify' ) { |
| 431 |
$response = C4::OAI::Identify->new( $self ); |
562 |
$response = C4::OAI::Identify->new( $self ); |
| 432 |
- |
|
|