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.
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.
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 ;
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 ;
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) ;
}
=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
@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;
$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}) {
$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++;
}
}
}
=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<marc_breeding> table of the Koha database.
+array of references-to-hash; the keys are the items from the C<marc_breeding> 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;
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;
&getz3950servers
&z3950servername
&addz3950queue
+ &checkz3950searchdone
);
#------------------------------------------------
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
} # 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__
#--------------------------------------
# $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.
=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
=cut
sub find_value {
- my ($tagfield,$insubfield,$record) = @_;
+ my ($tagfield,$insubfield,$record,$encoding) = @_;
+ warn "FIND_VALUE : $encoding /";
my @result;
my $indicator;
if ($tagfield <10) {
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);
}
}
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;
-multiple => 0 );
}
-sub build_tabs ($$$) {
- my($template, $record, $dbh) = @_;
+sub build_tabs ($$$$) {
+ my($template, $record, $dbh,$encoding) = @_;
# fill arrays
my @loop_data =();
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;
# 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;
}
}
-
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;
$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);
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;
#------------------------------------------------------------------------------------------------------------------------------
} else {
#------------------------------------------------------------------------------------------------------------------------------
- build_tabs ($template, $record, $dbh);
+ build_tabs ($template, $record, $dbh,$encoding);
build_hidden_data;
$template->param(
oldbiblionumber => $oldbiblionumber,
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,
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,
#---------------
# 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
$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;
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";
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;
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'),
$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'),
$input->param('searchfield'),
$input->param('checked'),
$input->param('rank'),
+ $input->param('syntax'),
);
}
$sth->finish;
password => ($results->[$i]{'password'}) ? ('#######') : (' '),
checked => $results->[$i]{'checked'},
rank => $results->[$i]{'rank'},
+ syntax => $results->[$i]{'syntax'},
toggle => $toggle);
push @loop, \%row;
<td width=10% align="center"><input type="hidden" name="op" value="addbiblio">
<input type="hidden" name="oldbiblionumber" value="<TMPL_VAR name="oldbiblionumber">">
<input type="button" value="Add biblio" onClick='Check(this.form)' accesskey="w">
+ <a href="javascript:PopupZ3950()">z3950 search</a>
</td>
</tr>
</table>
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=<TMPL_VAR name="bibid">","z3950 search",'width=500,height=400,toolbar=false,scrollbars=yes');
+}
+
</script>
</body>
</html>
</td>
</tr>
<tr valign="top">
+ <td>Character encoding (USMARC or UNIMARC)</td>
+ <td>
+ <select name="syntax"/><option value="USMARC">USMARC</option><option value="UNIMARC">UNIMARC</option></select><br/>
+ </td>
+ </tr>
+ <tr valign="top">
<td>If ISBN already in breeding farm: </td>
<td><input type="radio" name="overwrite_biblio" value="0" checked>Ignore this one, keep the existing one<br/>
<input type="radio" name="overwrite_biblio" value="1">Overwrite the existing one with this</td>
</td>
</tr>
<tr>
+ <td>Syntax (z3950 can send records in various format. Choose one)</td>
+ <td>
+ <select name="syntax">
+ <option value="USMARC">USMARC</option>
+ <option value="UNIMARC">UNIMARC</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
<td> </td>
<td>
<INPUT type=button value='OK' onClick='Check(this.form)'>
<td background='<TMPL_VAR name="themelang">/images/background-mem.gif'><b>Userid</b></td>
<td background='<TMPL_VAR name="themelang">/images/background-mem.gif'><b>Password</b></td>
<td background='<TMPL_VAR name="themelang">/images/background-mem.gif'><b>Checked</b></td>
- <td background='<TMPL_VAR name="themelang">/images/background-mem.gif'><b>Rank</b></td>
+ <td background='<TMPL_VAR name="themelang">/images/background-mem.gif'><b>Rank</b></td>
+ <td background='<TMPL_VAR name="themelang">/images/background-mem.gif'><b>Syntax</b></td>
<td background='<TMPL_VAR name="themelang">/images/background-mem.gif'> </td>
<td background='<TMPL_VAR name="themelang">/images/background-mem.gif'> </td>
</tr>
<td><TMPL_VAR NAME=password></td>
<td><TMPL_VAR NAME=checked></td>
<td><TMPL_VAR NAME=rank></td>
+ <td><TMPL_VAR NAME=syntax></td>
<td><a href="<TMPL_VAR NAME=script_name>?op=add_form&searchfield=<TMPL_VAR NAME=name>"><img src="<TMPL_VAR name="interface">/<TMPL_VAR name="theme">/images/fileopen.png" ALT="Edit" title="edit" BORDER=0 ></a></td>
- <td><a href="<TMPL_VAR NAME=script_name>?op=delete_confirm&searchfield=<TMPL_VAR NAME=name>"><img src="<TMPL_VAR name="interface">/<TMPL_VAR name="theme">/images/edittrash.png" ALT="Delete" title="delete" BORDER=0 ></a></td>
+ <td><a href="<TMPL_VAR NAME=script_name>?op=delete_confirm&searchfield=<TMPL_VAR NAME=name>"><img src="<TMPL_VAR name="interface">/<TMPL_VAR name="theme">/images/edittrash.png" ALT="Delete" title="delete" BORDER=0 ></a></td>
</tr>
</TMPL_LOOP>
</table>
</TMPL_IF>
-
+
<TMPL_IF NAME=ltcount>
<a href="<TMPL_VAR NAME=script_name>?offset=<TMPL_VAR NAME=nextpage>">Next >></a>
</TMPL_iF>
--- /dev/null
+<HTML>
+<TMPL_IF name="refresh">
+ <meta http-equiv="refresh" content="2; url=<TMPL_VAR name="refresh">">
+</TMPL_IF>
+<font size="6"><em>Z3950 Search Results</em></font><br />
+
+<table width="80%" cellpadding="3">
+ <tr valign="center">
+ <td><font size="4">Biblios found</font></td>
+ </tr>
+</table>
+<table border="0" cellspacing="0" cellpadding="5" width="80%">
+ <tr valign=top bgcolor=#ffcc00>
+ <td><b>Title</b></td>
+ <td><b>Author</b></td>
+ <td><b>ISBN</b></td>
+ <td><b>coming from</b></td>
+ <td><b> </b></td>
+ <td> </td>
+ </tr>
+ <TMPL_IF name="breeding_loop">
+ <TMPL_LOOP name="breeding_loop">
+ <tr valign="top" bgcolor="<TMPL_VAR name="toggle">">
+ <td><TMPL_VAR name="title"></a>
+ <td><TMPL_VAR name="author"></td>
+ <td><TMPL_VAR name="isbn"></td>
+ <td><TMPL_VAR name="file"></td>
+ <td><a href="javascript:Import(<TMPL_VAR name="id">)">Import this biblio</a></td>
+ </tr>
+ </TMPL_LOOP>
+ <TMPL_ELSE>
+ <tr><td colspan=6>Nothing found</td></tr>
+ </TMPL_IF>
+</table>
+<TMPL_IF name="numberpending"><H1><center>Still <TMPL_VAR name="numberpending"> requests to go</center></H1></TMPL_IF>
+<br />
+<script>
+ function Import(GetThisOne) {
+ opener.document.location= "../acqui.simple/addbiblio.pl?z3950=1&oldbiblionumber=<TMPL_VAR name="oldbiblionumber">&breedingid="+GetThisOne;
+ self.close();
+ return false;
+ }
+</script>
+<TMPL_INCLUDE NAME="acquisitions-bottom.inc">
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)
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.
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");
my $serverinfo;
my $stillprocessing=0;
my $globalname;
+ my $globalsyntax;
+ my $globalencoding;
foreach $serverinfo (split(/\s+/, $servers)) {
(next) if ($serverdone{$serverinfo} == 1);
my $stillprocessing=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;
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);
print " $server done.\n";
exit;
sub pe {
-# return 0;
+ return 0;
my $code=$conn->errcode();
my $msg=$conn->errmsg();
my $ai=$conn->addinfo();
--- /dev/null
+#!/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;
# 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
#----------------------------
#--------------
# $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
#
#----------------------------
-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
#-------------------
# $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
#