From 26543b430e1df3866f50e79fbfb724ec69a26791 Mon Sep 17 00:00:00 2001 From: tipaul Date: Tue, 29 Apr 2003 16:48:25 +0000 Subject: [PATCH] really proud of this commit :-) z3950 search and import seems to works fine. Let me explain how : * a "search z3950" button is added in the addbiblio template. * when clicked, a popup appears and z3950/search.pl is called * z3950/search.pl calls addz3950search in the DB * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled Note : * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. --- C4/Biblio.pm | 28 ++++- C4/Breeding.pm | 43 ++++--- C4/Search.pm | 30 +++-- C4/Z3950.pm | 56 ++++++++-- acqui.simple/addbiblio.pl | 35 +++--- acqui.simple/marcimport.pl | 18 ++- admin/z3950servers.pl | 15 ++- .../default/en/acqui.simple/addbiblio.tmpl | 5 + .../default/en/acqui.simple/marcimport.tmpl | 6 + .../default/en/parameters/z3950servers.tmpl | 17 ++- .../default/en/z3950/searchresult.tmpl | 44 ++++++++ updater/updatedatabase | 16 +++ z3950/processz3950queue | 45 ++++++-- z3950/search.pl | 105 ++++++++++++++++++ z3950/z3950-daemon-launch.sh | 17 ++- z3950/z3950-daemon-shell.sh | 21 +++- 16 files changed, 420 insertions(+), 81 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/default/en/z3950/searchresult.tmpl create mode 100755 z3950/search.pl diff --git a/C4/Biblio.pm b/C4/Biblio.pm index d14fcc4adb..d1add18a8f 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -1,6 +1,21 @@ package C4::Biblio; # $Id$ # $Log$ +# Revision 1.45 2003/04/29 16:50:49 tipaul +# really proud of this commit :-) +# z3950 search and import seems to works fine. +# Let me explain how : +# * a "search z3950" button is added in the addbiblio template. +# * when clicked, a popup appears and z3950/search.pl is called +# * z3950/search.pl calls addz3950search in the DB +# * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. +# * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. +# * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled +# +# Note : +# * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. +# * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. +# # Revision 1.44 2003/04/28 13:07:14 tipaul # Those fixes solves the "internal server error" with MARC::Record 1.12. # It was due to an illegal contruction in Koha : we tried to retrive subfields from <10 tags. @@ -2137,9 +2152,10 @@ sub getoraddbiblio { sub char_decode { # converts ISO 5426 coded string to ISO 8859-1 # sloppy code : should be improved in next issue - my ($string) = @_ ; + my ($string,$encoding) = @_ ; $_ = $string ; - if (C4::Context->preference("marcflavour") eq "UNIMARC") { +# $encoding = C4::Context->preference("marcflavour") unless $encoding; + if ($encoding eq "UNIMARC") { s/\xe1/Æ/gm ; s/\xe2/Ð/gm ; s/\xe9/Ø/gm ; @@ -2201,7 +2217,9 @@ sub char_decode { s/\xca\x61/å/gm ; s/\xd0\x43/Ç/gm ; s/\xd0\x63/ç/gm ; - } else { + # this handles non-sorting blocks (if implementation requires this) + $string = nsb_clean($_) ; + } elsif ($encoding eq "USMARC") { if(/[\xc1-\xff]/) { s/\xe1\x61/à/gm ; s/\xe1\x65/è/gm ; @@ -2254,10 +2272,10 @@ sub char_decode { s/\xe9\x75/ü/gm ; s/\xea\x41/Å/gm ; s/\xea\x61/å/gm ; + # this handles non-sorting blocks (if implementation requires this) + $string = nsb_clean($_) ; } } - # this handles non-sorting blocks (if implementation requires this) - $string = nsb_clean($_) ; return($string) ; } diff --git a/C4/Breeding.pm b/C4/Breeding.pm index 40048f70c5..7fb2dc475d 100644 --- a/C4/Breeding.pm +++ b/C4/Breeding.pm @@ -33,8 +33,17 @@ C4::Breeding : script to add a biblio in marc_breeding table. =head1 SYNOPSIS - use C4::Scan; - &ImportBreeding($marcrecords,$); + use C4::Scan; + &ImportBreeding($marcrecords,$overwrite_biblio,$filename,$z3950random); + + C<$marcrecord> => the MARC::Record + C<$overwrite_biblio> => if set to 1 a biblio with the same ISBN will be overwritted. + if set to 0 a biblio with the same isbn will be ignored (the previous will be kept) + if set to -1 the biblio will be added anyway (more than 1 biblio with the same ISBN possible in the breeding + C<$encoding> => USMARC + or UNIMARC. used for char_decoding. + If not present, the parameter marcflavour is used instead + C<$z3950random> => the random value created during a z3950 search result. =head1 DESCRIPTION @@ -46,14 +55,15 @@ This module doesn't do anything. @EXPORT = qw(&ImportBreeding); sub ImportBreeding { - my ($marcrecords,$overwrite_biblio,$filename) = @_; + my ($marcrecords,$overwrite_biblio,$filename,$encoding,$z3950random) = @_; my @marcarray = split /\x1D/, $marcrecords; my $dbh = C4::Context->dbh; my $searchisbn = $dbh->prepare("select biblioitemnumber from biblioitems where isbn=?"); my $searchissn = $dbh->prepare("select biblioitemnumber from biblioitems where issn=?"); my $searchbreeding = $dbh->prepare("select id from marc_breeding where isbn=?"); - my $insertsql = $dbh->prepare("insert into marc_breeding (file,isbn,title,author,marc) values(?,?,?,?,?)"); - my $replacesql = $dbh->prepare("update marc_breeding set file=?,isbn=?,title=?,author=?,marc=? where id=?"); + my $insertsql = $dbh->prepare("insert into marc_breeding (file,isbn,title,author,marc,encoding,z3950random) values(?,?,?,?,?,?,?)"); + my $replacesql = $dbh->prepare("update marc_breeding set file=?,isbn=?,title=?,author=?,marc=?,encoding=?,z3950random=? where id=?"); + $encoding = C4::Context->preference("marcflavour") unless $encoding; # fields used for import results my $imported=0; my $alreadyindb = 0; @@ -65,11 +75,14 @@ sub ImportBreeding { $notmarcrecord++; } else { my $oldbiblio = MARCmarc2koha($dbh,$marcrecord); - $oldbiblio->{title} = char_decode($oldbiblio->{title}); - $oldbiblio->{author} = char_decode($oldbiblio->{author}); + $oldbiblio->{title} = char_decode($oldbiblio->{title},$encoding); + $oldbiblio->{author} = char_decode($oldbiblio->{author},$encoding); # if isbn found and biblio does not exist, add it. If isbn found and biblio exists, overwrite or ignore depending on user choice # drop every "special" char : spaces, - ... $oldbiblio->{isbn} =~ s/ |-|\.//g, + $oldbiblio->{isbn} = substr($oldbiblio->{isbn},0,10); + $oldbiblio->{issn} =~ s/ |-|\.//g, + $oldbiblio->{issn} = substr($oldbiblio->{issn},0,10); # search if biblio exists my $biblioitemnumber; if ($oldbiblio->{isbn}) { @@ -91,17 +104,17 @@ sub ImportBreeding { $searchbreeding->execute($oldbiblio->{issn}); ($breedingid) = $searchbreeding->fetchrow; } - if (!$breedingid || $overwrite_biblio) { + if ($breedingid && $overwrite_biblio eq 0) { + $alreadyinfarm++; + } else { my $recoded; $recoded = $marcrecord->as_usmarc(); - if ($breedingid) { - $replacesql ->execute($filename,substr($oldbiblio->{isbn}.$oldbiblio->{issn},0,10),$oldbiblio->{title},$oldbiblio->{author},$recoded,$breedingid); - } else { - $insertsql ->execute($filename,substr($oldbiblio->{isbn}.$oldbiblio->{issn},0,10),$oldbiblio->{title},$oldbiblio->{author},$recoded); - } + if ($breedingid && $overwrite_biblio eq 1) { + $replacesql ->execute($filename,substr($oldbiblio->{isbn}.$oldbiblio->{issn},0,10),$oldbiblio->{title},$oldbiblio->{author},$recoded,$encoding,$z3950random,$breedingid); + } else { + $insertsql ->execute($filename,substr($oldbiblio->{isbn}.$oldbiblio->{issn},0,10),$oldbiblio->{title},$oldbiblio->{author},$recoded,$encoding,$z3950random); + } $imported++; - } else { - $alreadyinfarm++; } } } diff --git a/C4/Search.pm b/C4/Search.pm index 2a0f825c70..cbc091cb09 100755 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -2380,16 +2380,18 @@ and itemtype = 'WEB'"; =item breedingsearch - ($count, @results) = &breedingsearch($title); + ($count, @results) = &breedingsearch($title,$isbn,$random); +C<$title> contains the title, +C<$isbn> contains isbn or issn, +C<$random> contains the random seed from a z3950 search. C<$count> is the number of items in C<@results>. C<@results> is an -array of references-to-hash; the keys are the items from the -C table of the Koha database. +array of references-to-hash; the keys are the items from the C table of the Koha database. =cut sub breedingsearch { - my ($title,$isbn) = @_; + my ($title,$isbn,$z3950random) = @_; my $dbh = C4::Context->dbh; my $count = 0; my $query; @@ -2397,14 +2399,18 @@ sub breedingsearch { my @results; $query = "Select id,file,isbn,title,author from marc_breeding where "; - if ($title) { - $query .= "title like \"$title%\""; - } - if ($title && $isbn) { - $query .= " and "; - } - if ($isbn) { - $query .= "isbn like \"$isbn%\""; + if ($z3950random) { + $query .= "z3950random = \"$z3950random\""; + } else { + if ($title) { + $query .= "title like \"$title%\""; + } + if ($title && $isbn) { + $query .= " and "; + } + if ($isbn) { + $query .= "isbn like \"$isbn%\""; + } } $sth = $dbh->prepare($query); $sth->execute; diff --git a/C4/Z3950.pm b/C4/Z3950.pm index a6d2586691..83c4fd3e85 100755 --- a/C4/Z3950.pm +++ b/C4/Z3950.pm @@ -69,6 +69,7 @@ entering Z39.50 lookup requests. &getz3950servers &z3950servername &addz3950queue + &checkz3950searchdone ); #------------------------------------------------ @@ -198,23 +199,23 @@ sub addz3950queue { if ($server =~ /:/ ) { push @serverlist, $server; } elsif ($server eq 'DEFAULT' || $server eq 'CHECKED' ) { - $sth=$dbh->prepare("select host,port,db,userid,password ,name from z3950servers where checked <> 0 "); + $sth=$dbh->prepare("select host,port,db,userid,password ,name,syntax from z3950servers where checked <> 0 "); $sth->execute; - while ( my ($host, $port, $db, $userid, $password,$servername) = $sth->fetchrow ) { - push @serverlist, "$servername/$host\:$port/$db/$userid/$password"; + while ( my ($host, $port, $db, $userid, $password,$servername,$syntax) = $sth->fetchrow ) { + push @serverlist, "$servername/$host\:$port/$db/$userid/$password/$syntax"; } # while } else { - $sth=$dbh->prepare("select host,port,db,userid,password from z3950servers where id=? "); + $sth=$dbh->prepare("select host,port,db,userid,password,syntax from z3950servers where id=? "); $sth->execute($server); - my ($host, $port, $db, $userid, $password) = $sth->fetchrow; - push @serverlist, "$server/$host\:$port/$db/$userid/$password"; + my ($host, $port, $db, $userid, $password,$syntax) = $sth->fetchrow; + push @serverlist, "$server/$host\:$port/$db/$userid/$password/$syntax"; } } my $serverlist=''; $serverlist = join(" ", @serverlist); - chop $serverlist; +# chop $serverlist; # FIXME - Is this test supposed to test whether @serverlist is # empty? If so, then a) there are better ways to do that in @@ -266,6 +267,32 @@ sub addz3950queue { } # sub addz3950queue +=item &checkz3950searchdone + + $numberpending= & &checkz3950searchdone($random); + +Returns the number of pending z3950 requests + +C<$random> is the random z3950 query number. + +=cut +sub checkz3950searchdone { + my ($z3950random) = @_; + my $dbh = C4::Context->dbh; + # first, check that the deamon already created the requests... + my $sth = $dbh->prepare("select count(*) from z3950queue,z3950results where z3950queue.id = z3950results.queryid and z3950queue.identifier=?"); + $sth->execute($z3950random); + my ($result) = $sth->fetchrow; + if ($result eq 0) { # search not yet begun => should be searches to do ! + return "??"; + } + # second, count pending requests + $sth = $dbh->prepare("select count(*) from z3950queue,z3950results where z3950queue.id = z3950results.queryid and z3950results.enddate is null and z3950queue.identifier=?"); + $sth->execute($z3950random); + ($result) = $sth->fetchrow; + return $result; +} + 1; __END__ @@ -279,6 +306,21 @@ Koha Developement team #-------------------------------------- # $Log$ +# Revision 1.9 2003/04/29 16:50:51 tipaul +# really proud of this commit :-) +# z3950 search and import seems to works fine. +# Let me explain how : +# * a "search z3950" button is added in the addbiblio template. +# * when clicked, a popup appears and z3950/search.pl is called +# * z3950/search.pl calls addz3950search in the DB +# * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. +# * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. +# * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled +# +# Note : +# * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. +# * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. +# # Revision 1.8 2003/04/29 08:09:45 tipaul # z3950 support is coming... # * adding a syntax column in z3950 table = this column will say wether the z3950 must be called with PerferedRecordsyntax => USMARC or PerferedRecordsyntax => UNIMARC. I tried some french UNIMARC z3950 servers, and some only send USMARC, some only UNIMARC, some can answer with both. diff --git a/acqui.simple/addbiblio.pl b/acqui.simple/addbiblio.pl index 51adbf6bde..98d2f7db3a 100755 --- a/acqui.simple/addbiblio.pl +++ b/acqui.simple/addbiblio.pl @@ -36,7 +36,7 @@ use vars qw( $is_a_modif ); =item find_value - ($indicators, $value) = find_value($tag, $subfield, $record); + ($indicators, $value) = find_value($tag, $subfield, $record,$encoding); Find the given $subfield in the given $tag in the given MARC::Record $record. If the subfield is found, returns @@ -46,7 +46,8 @@ returned. =cut sub find_value { - my ($tagfield,$insubfield,$record) = @_; + my ($tagfield,$insubfield,$record,$encoding) = @_; + warn "FIND_VALUE : $encoding /"; my @result; my $indicator; if ($tagfield <10) { @@ -60,7 +61,8 @@ sub find_value { my @subfields = $field->subfields(); foreach my $subfield (@subfields) { if (@$subfield[0] eq $insubfield) { - push @result,@$subfield[1]; + warn "@$subfield[1]==> ".char_decode(@$subfield[1],$encoding); + push @result,char_decode(@$subfield[1],$encoding); $indicator = $field->indicator(1).$field->indicator(2); } } @@ -77,20 +79,21 @@ sub find_value { Look up the breeding farm with database handle $dbh, for the record with id $breedingid. If found, returns the decoded MARC::Record; otherwise, -1 is returned (FIXME). +Returns as second parameter the character encoding. =cut sub MARCfindbreeding { my ($dbh,$id) = @_; - my $sth = $dbh->prepare("select file,marc from marc_breeding where id=?"); + my $sth = $dbh->prepare("select file,marc,encoding from marc_breeding where id=?"); $sth->execute($id); - my ($file,$marc) = $sth->fetchrow; + my ($file,$marc,$encoding) = $sth->fetchrow; if ($marc) { my $record = MARC::File::USMARC::decode($marc); if (ref($record) eq undef) { return -1; } else { - return $record; + return $record,$encoding; } } return -1; @@ -154,8 +157,8 @@ sub build_authorized_values_list ($$$$$) { -multiple => 0 ); } -sub build_tabs ($$$) { - my($template, $record, $dbh) = @_; +sub build_tabs ($$$$) { + my($template, $record, $dbh,$encoding) = @_; # fill arrays my @loop_data =(); @@ -180,7 +183,7 @@ sub build_tabs ($$$) { next if ($tagslib->{$tag}->{$subfield}->{tab} ne $tabloop); # if breeding is not empty if ($record ne -1) { - my ($x,@value) = find_value($tag,$subfield,$record); + my ($x,@value) = find_value($tag,$subfield,$record,$encoding); push (@value,"") if ($#value eq -1); foreach my $value (@value) { my %subfield_data; @@ -211,8 +214,8 @@ sub build_tabs ($$$) { # if breeding is empty } else { my ($x,$value); - ($x,$value) = find_value($tag,$subfield,$record) if ($record ne -1); - $value=char_decode($value) unless ($is_a_modif); + ($x,$value) = find_value($tag,$subfield,$record,$encoding) if ($record ne -1); +# $value=char_decode($value) unless ($is_a_modif); my %subfield_data; $subfield_data{tag}=$tag; $subfield_data{subfield}=$subfield; @@ -277,11 +280,11 @@ sub build_hidden_data () { } } - my $input = new CGI; my $error = $input->param('error'); my $oldbiblionumber=$input->param('oldbiblionumber'); # if bib exists, it's a modif, not a new biblio. my $breedingid = $input->param('breedingid'); +my $z3950 = $input->param('z3950'); my $op = $input->param('op'); my $dbh = C4::Context->dbh; my $bibid; @@ -301,8 +304,10 @@ my ($template, $loggedinuser, $cookie) $tagslib = &MARCgettagslib($dbh,1); my $record=-1; +my $encoding=""; $record = MARCgetbiblio($dbh,$bibid) if ($bibid); -$record = MARCfindbreeding($dbh,$breedingid) if ($breedingid); +($record,$encoding) = MARCfindbreeding($dbh,$breedingid) if ($breedingid); + $is_a_modif=0; my ($oldbiblionumtagfield,$oldbiblionumtagsubfield); my ($oldbiblioitemnumtagfield,$oldbiblioitemnumtagsubfield,$bibitem,$oldbiblioitemnumber); @@ -330,9 +335,7 @@ if ($op eq "addbiblio") { for (my $i=0;$i<=$#ind_tag;$i++) { $indicators{$ind_tag[$i]} = $indicator[$i]; } - warn "MARChtml"; my $record = MARChtml2marc($dbh,\@tags,\@subfields,\@values,%indicators); - warn "MARChtml2"; # MARC::Record built => now, record in DB my $oldbibnum; my $oldbibitemnum; @@ -347,7 +350,7 @@ if ($op eq "addbiblio") { #------------------------------------------------------------------------------------------------------------------------------ } else { #------------------------------------------------------------------------------------------------------------------------------ - build_tabs ($template, $record, $dbh); + build_tabs ($template, $record, $dbh,$encoding); build_hidden_data; $template->param( oldbiblionumber => $oldbiblionumber, diff --git a/acqui.simple/marcimport.pl b/acqui.simple/marcimport.pl index cb605ff43d..cf9f505680 100755 --- a/acqui.simple/marcimport.pl +++ b/acqui.simple/marcimport.pl @@ -67,6 +67,7 @@ my $dbh = C4::Context->dbh; my $uploadmarc=$input->param('uploadmarc'); my $overwrite_biblio = $input->param('overwrite_biblio'); my $filename = $input->param('filename'); +my $syntax = $input->param('syntax'); my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "acqui.simple/marcimport.tmpl", query => $input, @@ -83,7 +84,7 @@ if ($uploadmarc && length($uploadmarc)>0) { while (<$uploadmarc>) { $marcrecord.=$_; } - my ($notmarcrecord,$alreadyindb,$alreadyinfarm,$imported) = ImportBreeding($marcrecord,$overwrite_biblio,$filename); + my ($notmarcrecord,$alreadyindb,$alreadyinfarm,$imported) = ImportBreeding($marcrecord,$overwrite_biblio,$filename,$syntax); $template->param(imported => $imported, alreadyindb => $alreadyindb, @@ -102,6 +103,21 @@ my $file; #--------------- # log cleared, as marcimport is (almost) rewritten from scratch. # $Log$ +# Revision 1.33 2003/04/29 16:48:36 tipaul +# really proud of this commit :-) +# z3950 search and import seems to works fine. +# Let me explain how : +# * a "search z3950" button is added in the addbiblio template. +# * when clicked, a popup appears and z3950/search.pl is called +# * z3950/search.pl calls addz3950search in the DB +# * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. +# * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. +# * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled +# +# Note : +# * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. +# * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. +# # Revision 1.32 2003/04/22 12:22:54 tipaul # 1st draft for z3950 client import. # moving Breeding farm script to a perl package C4/Breeding.pm diff --git a/admin/z3950servers.pl b/admin/z3950servers.pl index d61cf86365..f694243aff 100755 --- a/admin/z3950servers.pl +++ b/admin/z3950servers.pl @@ -35,7 +35,7 @@ sub StringSearch { $searchstring=~ s/\'/\\\'/g; my @data=split(' ',$searchstring); my $count=@data; - my $query="Select host,port,db,userid,password,name,id,checked,rank from z3950servers where (name like \"$data[0]\%\") order by rank,name"; + my $query="Select host,port,db,userid,password,name,id,checked,rank,syntax from z3950servers where (name like \"$data[0]\%\") order by rank,name"; my $sth=$dbh->prepare($query); $sth->execute; my @results; @@ -52,7 +52,7 @@ sub StringSearch { my $input = new CGI; my $searchfield=$input->param('searchfield'); -my $reqsel="select host,port,db,userid,password,name,id,checked,rank from z3950servers where (name = '$searchfield') order by rank,name"; +my $reqsel="select host,port,db,userid,password,name,id,checked,rank,syntax from z3950servers where (name = '$searchfield') order by rank,name"; my $reqdel="delete from z3950servers where name='$searchfield'"; my $offset=$input->param('offset'); my $script_name="/cgi-bin/koha/admin/z3950servers.pl"; @@ -82,7 +82,7 @@ if ($op eq 'add_form') { my $data; if ($searchfield) { my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank from z3950servers where (name = '$searchfield') order by rank,name"); + my $sth=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax from z3950servers where (name = '$searchfield') order by rank,name"); $sth->execute; $data=$sth->fetchrow_hashref; $sth->finish; @@ -104,7 +104,7 @@ if ($op eq 'add_form') { my $sth=$dbh->prepare("select * from z3950servers where name=?"); $sth->execute($input->param('searchfield')); if ($sth->rows) { - $sth=$dbh->prepare("update z3950servers set host=?, port=?, db=?, userid=?, password=?, name=?, checked=?, rank=? where name=?"); + $sth=$dbh->prepare("update z3950servers set host=?, port=?, db=?, userid=?, password=?, name=?, checked=?, rank=?,syntax=? where name=?"); $sth->execute($input->param('host'), $input->param('port'), $input->param('db'), @@ -113,10 +113,11 @@ if ($op eq 'add_form') { $input->param('searchfield'), $input->param('checked'), $input->param('rank'), - $input->param('searchfield') + $input->param('syntax'), + $input->param('searchfield'), ); } else { - $sth=$dbh->prepare("insert into z3950servers (host,port,db,userid,password,name,checked,rank) values (?, ?, ?, ?, ?, ?, ?, ?)"); + $sth=$dbh->prepare("insert into z3950servers (host,port,db,userid,password,name,checked,rank,syntax) values (?, ?, ?, ?, ?, ?, ?, ?,?)"); $sth->execute($input->param('host'), $input->param('port'), $input->param('db'), @@ -125,6 +126,7 @@ if ($op eq 'add_form') { $input->param('searchfield'), $input->param('checked'), $input->param('rank'), + $input->param('syntax'), ); } $sth->finish; @@ -178,6 +180,7 @@ if ($op eq 'add_form') { password => ($results->[$i]{'password'}) ? ('#######') : (' '), checked => $results->[$i]{'checked'}, rank => $results->[$i]{'rank'}, + syntax => $results->[$i]{'syntax'}, toggle => $toggle); push @loop, \%row; diff --git a/koha-tmpl/intranet-tmpl/default/en/acqui.simple/addbiblio.tmpl b/koha-tmpl/intranet-tmpl/default/en/acqui.simple/addbiblio.tmpl index b16a7914b0..e84262ddc8 100644 --- a/koha-tmpl/intranet-tmpl/default/en/acqui.simple/addbiblio.tmpl +++ b/koha-tmpl/intranet-tmpl/default/en/acqui.simple/addbiblio.tmpl @@ -29,6 +29,7 @@ "> + z3950 search @@ -363,6 +364,10 @@ function Dopop(link,i) { newin=window.open(link+"&result="+defaultvalue,"value builder",'width=500,height=400,toolbar=false,scrollbars=yes'); } +function PopupZ3950(link,i) { + newin=window.open("../z3950/search.pl?bibid=","z3950 search",'width=500,height=400,toolbar=false,scrollbars=yes'); +} + diff --git a/koha-tmpl/intranet-tmpl/default/en/acqui.simple/marcimport.tmpl b/koha-tmpl/intranet-tmpl/default/en/acqui.simple/marcimport.tmpl index b4a1d56a3c..930b39a40d 100644 --- a/koha-tmpl/intranet-tmpl/default/en/acqui.simple/marcimport.tmpl +++ b/koha-tmpl/intranet-tmpl/default/en/acqui.simple/marcimport.tmpl @@ -38,6 +38,12 @@
+ + Character encoding (USMARC or UNIMARC) + +
+ + If ISBN already in breeding farm: Ignore this one, keep the existing one
diff --git a/koha-tmpl/intranet-tmpl/default/en/parameters/z3950servers.tmpl b/koha-tmpl/intranet-tmpl/default/en/parameters/z3950servers.tmpl index 1a16649064..b588f431e9 100644 --- a/koha-tmpl/intranet-tmpl/default/en/parameters/z3950servers.tmpl +++ b/koha-tmpl/intranet-tmpl/default/en/parameters/z3950servers.tmpl @@ -136,6 +136,15 @@ + + Syntax (z3950 can send records in various format. Choose one) + + + + @@ -234,7 +243,8 @@ Userid Password Checked - Rank + Rank + Syntax @@ -248,8 +258,9 @@ + //images/fileopen.png" ALT="Edit" title="edit" BORDER=0 > - //images/edittrash.png" ALT="Delete" title="delete" BORDER=0 > + //images/edittrash.png" ALT="Delete" title="delete" BORDER=0 > @@ -262,7 +273,7 @@        - + Next >> diff --git a/koha-tmpl/intranet-tmpl/default/en/z3950/searchresult.tmpl b/koha-tmpl/intranet-tmpl/default/en/z3950/searchresult.tmpl new file mode 100644 index 0000000000..e0cab21642 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/default/en/z3950/searchresult.tmpl @@ -0,0 +1,44 @@ + + + "> + +Z3950 Search Results
+ + + + + +
Biblios found
+ + + + + + + + + + + + "> + + + + + + + + + +
TitleAuthorISBNcoming from  
+ )">Import this biblio
Nothing found
+

Still requests to go

+
+ + diff --git a/updater/updatedatabase b/updater/updatedatabase index 94acf17081..d32b52f940 100755 --- a/updater/updatedatabase +++ b/updater/updatedatabase @@ -193,6 +193,7 @@ my %requiretables=( title varchar(128) default NULL, author varchar(80) default NULL, marc text NOT NULL, + encoding varchar(40) default NULL, PRIMARY KEY (id), KEY title (title), KEY isbn (isbn) @@ -548,6 +549,21 @@ $sth->finish; exit; # $Log$ +# Revision 1.42 2003/04/29 16:53:25 tipaul +# really proud of this commit :-) +# z3950 search and import seems to works fine. +# Let me explain how : +# * a "search z3950" button is added in the addbiblio template. +# * when clicked, a popup appears and z3950/search.pl is called +# * z3950/search.pl calls addz3950search in the DB +# * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. +# * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. +# * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled +# +# Note : +# * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. +# * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. +# # Revision 1.41 2003/04/29 08:09:44 tipaul # z3950 support is coming... # * adding a syntax column in z3950 table = this column will say wether the z3950 must be called with PerferedRecordsyntax => USMARC or PerferedRecordsyntax => UNIMARC. I tried some french UNIMARC z3950 servers, and some only send USMARC, some only UNIMARC, some can answer with both. diff --git a/z3950/processz3950queue b/z3950/processz3950queue index e0953e1e18..f753469cf3 100755 --- a/z3950/processz3950queue +++ b/z3950/processz3950queue @@ -50,11 +50,12 @@ my $lastrun=0; while (1) { if ((time-$lastrun)>5) { print "starting loop\n"; + $checkqueue = 1; # FIXME during testing, this line forces the loop. REMOVE it to use SIG{HUP} when "daemonized" ! if ($checkqueue) { # everytime a SIG{HUP} is recieved $checkqueue=0; - my $sth=$dbh->prepare("select id,term,type,servers from z3950queue order by id"); + my $sth=$dbh->prepare("select id,term,type,servers,identifier from z3950queue order by id"); $sth->execute; - while (my ($id, $term, $type, $servers) = $sth->fetchrow) { + while (my ($id, $term, $type, $servers,$random) = $sth->fetchrow) { if ($forkcounter<12) { my $now=time(); my $stk=$dbh->prepare("select id,server,startdate,enddate,numrecords,active from z3950results where queryid=$id"); @@ -93,6 +94,8 @@ while (1) { my $serverinfo; my $stillprocessing=0; my $globalname; + my $globalsyntax; + my $globalencoding; foreach $serverinfo (split(/\s+/, $servers)) { (next) if ($serverdone{$serverinfo} == 1); my $stillprocessing=1; @@ -100,12 +103,13 @@ while (1) { $forkcounter++; } else { my $dbi = C4::Context->dbh; - my ($name, $server, $database, $user, $password) = split(/\//, $serverinfo, 5); + my ($name, $server, $database, $user, $password,$syntax) = split(/\//, $serverinfo, 6); $globalname=$name; + $globalsyntax = $syntax; $server=~/(.*)\:(\d+)/; my $servername=$1; my $port=$2; - print "Processing $type=$term at $name $server $database (".($forkcounter+1)." forks)\n"; + print "Processing $type=$term at $name $server $database $syntax (".($forkcounter+1)." forks)\n"; $now=time(); my $q_serverinfo=$dbi->quote($serverinfo); my $resultsid; @@ -149,26 +153,43 @@ while (1) { if ($noconnection || $error) { warn "no connection at $globalname "; } else { - eval { $conn->option(preferredRecordSyntax => Net::Z3950::RecordSyntax::USMARC);}; + warn "$globalname ==> $globalsyntax"; + eval { $conn->option(preferredRecordSyntax => Net::Z3950::RecordSyntax::USMARC);} if ($globalsyntax eq "USMARC"); + eval { $conn->option(preferredRecordSyntax => Net::Z3950::RecordSyntax::UNIMARC);} if ($globalsyntax eq "UNIMARC"); if ($@) { print "$globalname ERROR: $@\n"; } else { - print "Q: $query\n"; +# print "Q: $query\n"; my $rs=$conn->search($query); pe(); my $numresults=$rs->size(); + if ($numresults eq 0) { + warn "$globalname ==> answered : no records found"; + } else { + warn "$globalname ==> answered : $numresults found"; + } pe(); my $i; my $result=''; my $scantimerstart=time(); for ($i=1; $i<=(($numresults<80) ? ($numresults) : (80)); $i++) { my $rec=$rs->record($i); - my $marcdata=$rec->render(); - my $marcrecord = MARC::File::USMARC::decode($rec->render()); - warn "$globalname ==> ".$marcrecord->as_formatted(); - $result.=$marcdata; - my ($notmarcrecord,$alreadyindb,$alreadyinfarm,$imported) = ImportBreeding($marcdata,1,"Z3950-$globalname"); + my $marcdata; + # use render() or rawdata() depending on the type of the returned record + my $marcrecord; + if (ref($rec) eq "Net::Z3950::Record::USMARC") { + $marcdata = $rec->rawdata(); + $marcrecord = MARC::File::USMARC::decode($rec->rawdata()) + } + if (ref($rec) eq "Net::Z3950::Record::UNIMARC") { + $marcdata = $rec->render(); + $marcrecord = MARC::File::USMARC::decode($rec->render()) + } + $globalencoding = ref($rec); + $result.=$marcdata; } + my @x=split /::/,$globalencoding; + my ($notmarcrecord,$alreadyindb,$alreadyinfarm,$imported) = ImportBreeding($result,-1,"Z3950-$globalname",$x[3],$random); my $scantimerend=time(); my $numrecords; ($numresults<80) ? ($numrecords=$numresults) : ($numrecords=80); @@ -230,7 +251,7 @@ while (1) { print " $server done.\n"; exit; sub pe { -# return 0; + return 0; my $code=$conn->errcode(); my $msg=$conn->errmsg(); my $ai=$conn->addinfo(); diff --git a/z3950/search.pl b/z3950/search.pl new file mode 100755 index 0000000000..1c74fd8289 --- /dev/null +++ b/z3950/search.pl @@ -0,0 +1,105 @@ +#!/usr/bin/perl + +# Copyright 2000-2002 Katipo Communications +# +# 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use strict; +use CGI; +use C4::Auth; +use C4::Output; +use C4::Interface::CGI::Output; +use C4::Biblio; +use C4::Context; +use C4::Koha; # XXX subfield_is_koha_internal_p +use C4::Z3950; +use C4::Search; +use HTML::Template; +use MARC::File::USMARC; + +use vars qw( $tagslib ); +use vars qw( $is_a_modif ); + + +my $input = new CGI; +my $dbh = C4::Context->dbh; +my $error = $input->param('error'); +my $bibid=$input->param('bibid'); +my $title = $input->param('title'); +my $isbn = $input->param('isbn'); +my $issn = $input->param('issn'); +my $random = $input->param('random'); +my @results; +my $count; +my $toggle; + +my $record; +my $oldbiblio; +if ($bibid) { + $record = MARCgetbiblio($dbh,$bibid); + $oldbiblio = MARCmarc2koha($dbh,$record); +} +$isbn = $oldbiblio->{'isbn'}; +$issn = $oldbiblio->{'issn'}; +$title = $oldbiblio->{'title'}; +my $errmsg; +unless ($random) { # if random is a parameter => we're just waiting for the search to end, it's a refresh. + if ($isbn) { + $random =rand(1000000000); + $errmsg = addz3950queue($isbn, "isbn", $random, 'CHECKED'); + } +} +my ($template, $loggedinuser, $cookie) += get_template_and_user({template_name => "z3950/searchresult.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {catalogue => 1}, + debug => 1, + }); + +# fill with books in breeding farm +($count, @results) = breedingsearch($title,$isbn,$random); +my $numberpending= &checkz3950searchdone($random); +my @breeding_loop = (); +for (my $i=0; $i <= $#results; $i++) { + my %row_data; + if ($i % 2) { + $toggle="#ffffcc"; + } else { + $toggle="white"; + } + $row_data{toggle} = $toggle; + $row_data{id} = $results[$i]->{'id'}; + $row_data{isbn} = $results[$i]->{'isbn'}; + $row_data{file} = $results[$i]->{'file'}; + $row_data{title} = $results[$i]->{'title'}; + $row_data{author} = $results[$i]->{'author'}; + push (@breeding_loop, \%row_data); +} + +$template->param(isbn => $isbn, + title => $title, + breeding_loop => \@breeding_loop, + refresh => ($numberpending eq 0 ? 0 : "search.pl?bibid=$bibid&random=$random"), + numberpending => $numberpending, + oldbiblionumber => $oldbiblio->{'biblionumber'}, + ); + +print $input->header( +-type => guesstype($template->output), +-cookie => $cookie +),$template->output; diff --git a/z3950/z3950-daemon-launch.sh b/z3950/z3950-daemon-launch.sh index 1f1b0e9e8c..5123ed49c2 100755 --- a/z3950/z3950-daemon-launch.sh +++ b/z3950/z3950-daemon-launch.sh @@ -17,7 +17,7 @@ # User ID to run the daemon as. Don't use "root" RunAsUser=apache -KohaZ3950Dir=/usr/local/www/koha/htdocs/cgi-bin/koha/acqui.simple +KohaZ3950Dir=/home/paul/koha.dev/koha/z3950 export KohaZ3950Dir #---------------------------- @@ -41,6 +41,21 @@ exit #-------------- # $Log$ +# Revision 1.2 2003/04/29 16:48:25 tipaul +# really proud of this commit :-) +# z3950 search and import seems to works fine. +# Let me explain how : +# * a "search z3950" button is added in the addbiblio template. +# * when clicked, a popup appears and z3950/search.pl is called +# * z3950/search.pl calls addz3950search in the DB +# * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. +# * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. +# * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled +# +# Note : +# * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. +# * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. +# # Revision 1.1 2002/11/22 10:15:22 tipaul # moving z3950 related scripts to specific dir # diff --git a/z3950/z3950-daemon-shell.sh b/z3950/z3950-daemon-shell.sh index b115596a98..764b1e85d9 100755 --- a/z3950/z3950-daemon-shell.sh +++ b/z3950/z3950-daemon-shell.sh @@ -13,9 +13,9 @@ #---------------------------- -KohaZ3950Dir=/usr/local/www/koha/htdocs/cgi-bin/koha/acqui.simple -KohaModuleDir=/usr/local/koha/modules -LogDir=/var/log/koha +KohaZ3950Dir=/home/paul/koha.dev/koha/z3950 +KohaModuleDir=/home/paul/koha.dev/koha +LogDir=/tmp #---------------------------- LOGFILE=$LogDir/z3950-daemon-`date +%Y%m%d-%H%M`.log @@ -41,6 +41,21 @@ exec $KohaZ3950Script $LogDir >>$LOGFILE 2>&1 #------------------- # $Log$ +# Revision 1.2 2003/04/29 16:48:25 tipaul +# really proud of this commit :-) +# z3950 search and import seems to works fine. +# Let me explain how : +# * a "search z3950" button is added in the addbiblio template. +# * when clicked, a popup appears and z3950/search.pl is called +# * z3950/search.pl calls addz3950search in the DB +# * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table. +# * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending. +# * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled +# +# Note : +# * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support. +# * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup. +# # Revision 1.1 2002/11/22 10:15:22 tipaul # moving z3950 related scripts to specific dir # -- 2.20.1