Suite de notre série de billets sur Blacklight, commencée par une présentation générale.
La question qui nous intéresse désormais est de savoir comment connecter Blacklight à un SIGB. À priori, les nouvelles sont peu réjouissantes car Blacklight ne connait ni le z3950, ni OAI-PMH, ni aucun autre protocole pour interroger directement un catalogue. On peut l’alimenter d’une seule manière par défaut : en lisant des données au format Marc en XML ou ISO2709. Cependant, on peut le faire communiquer avec un catalogue, via z3950 notamment, sans devoir reprogrammer entièrement un client dédié. Si z3950 ne peut pas servir a récupérer un catalogue entier il peut être utile en revanche pour récupérer des informations en direct, comme les données d’exemplaires.
Nous allons utiliser ruby-zoom, une bibliothèque écrite en ruby et interrogeant ZOOM, une API disponible pour développer des services autour de z3950 (ce composant existe aussi pour PHP et C).
Pour l’installer sur un serveur Debian disposant d’un environnement Ruby, cette commande suffit :
[sourcecode language=”bash” gutter=”false”]$ apt-get install yaz libyaz4-dev[/sourcecode]
Ensuite, dans le fichier Gemfile de BL, ajoutons la ligne :
[sourcecode language=”ruby” gutter=”false”]gem ‘zoom’, :git => ‘https://github.com/bricestacey/ruby-zoom.git'[/sourcecode]
puis, dans le répertoire de BL, exécutons la commande suivante pour terminer l’installation de ruby-zoom (il sera compilé puis installé dans ruby on rails) :
[sourcecode language=”ruby” gutter=”false”]$ bundle install[/sourcecode]
Quelques lignes de code pour finir
À cette étape, il faut mettre la main à la pâte et programmer en Ruby. Le plus simple est de créer un nouveau modèle dans le framework Ruby on rails de BL dédié à la connexion z3950. Voici un exemple utilisant les fonctionnalités de ZOOM.
[sourcecode language=”ruby”]
class Z3950
attr_reader :ip, :base, :port, :url
attr_accessor :keyword
def initialize(ip, base, port)
@ip = ip
@base = base
@port = port
@url = @ip + ‘:’ + @port + ‘/’ + @base
end
def search
resultats = ”
begin
ZOOM::Connection.open(url) do |conn|
rset = conn.search(@keyword)
rset.each_record do |record|
resultats += record.xml
end
end
resultats.force_encoding(“ISO-8859-1”).encode(“UTF-8″)
rescue
nil
end
end
def get_localisations(resultats=”)
doc = REXML::Document.new(resultats)
resultats = []
root = doc.root
if root.respond_to?(‘elements’)
#parcours des champs 998
root.elements.each(“datafield[@tag=’998′]”) do |element|
resultab = {}
#pour chaque element fils on récupère les informations d’exemplaire (localisation, salle, cote, empruntable ou non)
element.each do |field|
if field.respond_to?(‘elements’)
resultab[:localisation] = field.elements[“[@code=’b’]”].text if !field.elements[“[@code=’b’]”].nil?
resultab[:salle] = field.elements[“[@code=’c’]”].text if !field.elements[“[@code=’c’]”].nil?
resultab[:cote] = field.elements[“[@code=’e’]”].text if !field.elements[“[@code=’e’]”].nil?
if !field.elements[“[@code=’h’]”].nil?
if field.elements[“[@code=’h’]”].text == ‘ ‘
resultab[:empruntable] = nil
else
resultab[:empruntable] = field.elements[“[@code=’h’]”].text
end
end
end
end
resultats << resultab
end
end
resultats
end
end
[/sourcecode]
La méthode search définie ici s’occupe de la connexion au serveur z3950 et la méthode get_localisations récupère et traite la réponse XML du serveur pour obtenir les données d’exemplaire.
Il reste à ajouter quelques lignes de code dans le fichier catalog_controller.rb ou l’on utilise les deux méthodes précédemment créées, puis dans le fichier show.html.erb pour afficher les résultats obtenus. Voici le résultat sur notre serveur de test, suivi des quelques lignes de code adéquates dans la vue et le contrôleur.
Le code à ajouter dans le fichier catalog_controller.rb :
[sourcecode language=”ruby”]
# surcharge de la méthode show du module catalog de blacklight
def show
@response, @document = get_solr_response_for_doc_id
connexion_z3950 = Z3950.new(‘X.X.X.X’, ‘base’, ‘port’)
connexion_z3950.keyword = @document.id
resultats = connexion_z3950.search
@localisations = connexion_z3950.get_localisations(resultats)
respond_to do |format|
format.html {setup_next_and_previous_documents}
# Add all dynamically added (such as by document extensions)
# export formats.
@document.export_formats.each_key do | format_name |
# It’s important that the argument to send be a symbol;
# if it’s a string, it makes Rails unhappy for unclear reasons.
format.send(format_name.to_sym) { render :text => @document.export_as(format_name), :layout => false }
end
end
end
[/sourcecode]
Et dans la vue (le fichier show.html.erb)
[sourcecode language=”html”]<p>
<table>
<tr>
<td>Disponibilité</td>
<td>Localisation</td>
<td>Salle</td>
<td>Cote</td>
</tr>
<% @localisations.each do |loc| %>
<tr>
<td><%= render_bouton_empruntable loc[:empruntable] %></td>
<td><%= loc[:localisation]%></td>
<td><%= loc[:salle]%></td>
<td><%= loc[:cote]%></td>
</tr>
<% end %>
</table>
</p>
[/sourcecode]