From 76dcd56da5fab0198106a28581b259ca14ff9111 Mon Sep 17 00:00:00 2001 From: gfawcett Date: Fri, 3 Apr 2009 01:31:41 +0000 Subject: [PATCH] first actual SIP integration Doing patron and item-info lookups through SIP. checkout is next. woohoo! git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@250 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- conifer/custom/lib_integration.py | 27 ++++++++++++++++++ conifer/libsystems/sip/sipclient.py | 52 +++++++++++++++++++++++++++++++++-- conifer/static/main.css | 2 +- conifer/syrup/models.py | 16 +++++++++++ conifer/syrup/views.py | 22 +++++++++++---- conifer/templates/phys/checkout.xhtml | 13 +++++---- 6 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 conifer/custom/lib_integration.py diff --git a/conifer/custom/lib_integration.py b/conifer/custom/lib_integration.py new file mode 100644 index 0000000..9dbce90 --- /dev/null +++ b/conifer/custom/lib_integration.py @@ -0,0 +1,27 @@ +# Our integration-point with back-end library systems. + +# TODO: write some documentation about the lib_integration interface. + +# Our example configuration: +# Z39.50 for catalogue search, +# SIP for patron and item_info, and for item checkout and checkin, +# OpenSRF for extended item info. + +from conifer.libsystems.sip import sipclient + + +def patron_info(barcode): + conn = sipclient.sip_connection() + resp = sipclient.sip_connection().patron_info(barcode) + conn.close() + return resp + +def item_info(barcode): + conn = sipclient.sip_connection() + resp = conn.item_info(barcode) + conn.close() + return resp + + + + diff --git a/conifer/libsystems/sip/sipclient.py b/conifer/libsystems/sip/sipclient.py index b7ceaab..5a84383 100644 --- a/conifer/libsystems/sip/sipclient.py +++ b/conifer/libsystems/sip/sipclient.py @@ -374,6 +374,10 @@ class SipClient(object): self.socket = so self.seqno = self.error_detect and 1 or 0 + def close(self): + # fixme, do SIP close first. + self.socket.close() + def send(self, outmsg, inmsg, args=None): msg_template = MESSAGES[outmsg] resp_template = MESSAGES[inmsg] @@ -395,12 +399,56 @@ class SipClient(object): # Common protocol methods def login(self, uid, pwd, locn): - return self.send(LOGIN, LOGIN_RESP, - dict(uid=uid, pwd=pwd, locn=locn)) + msg = self.send(LOGIN, LOGIN_RESP, + dict(uid=uid, pwd=pwd, locn=locn)) + return msg.get('okay') == '1' def status(self): return self.send(SC_STATUS, ACS_STATUS) + def patron_info(self, barcode): + msg = self.send(PATRON_INFO,PATRON_INFO_RESP, + {'patron':barcode, + 'startitem':1, 'enditem':2}) + return msg + + def item_info(self, barcode): + msg = self.send(ITEM_INFORMATION, ITEM_INFO_RESP, + {'item':barcode}) + decode_status = { + '01': 'Other', + '02': 'On order', + '03': 'Available', + '04': 'Charged', + '05': 'Charged; not to be recalled until', + '06': 'In process', + '07': 'Recalled', + '08': 'Waiting on hold shelf', + '09': 'Waiting to be re-shelved', + '10': 'In transit between library locations', + '11': 'Claimed returned', + '12': 'Lost', + '13': 'Missing ', + } + msg['available'] = msg['circstat'] == '03' + msg['status'] = decode_status[msg['circstat']] + return msg + + +# ------------------------------------------------------------ +# Django stuff. Optional. + +try: + from django.conf import settings + def sip_connection(): + sip = SipClient(*settings.SIP_HOST) + if not sip.login(*settings.SIP_CREDENTIALS): + raise 'SipLoginError' + return sip + +except ImportError: + pass + # ------------------------------------------------------------ # Test code. diff --git a/conifer/static/main.css b/conifer/static/main.css index 513f84d..4582472 100644 --- a/conifer/static/main.css +++ b/conifer/static/main.css @@ -30,7 +30,7 @@ min-height: 300; position: relative; top: -5px; float: right; - margin:0.2em 0 1em; + margin: 0.2em 0 0 0; padding:0 0.2em 0 0.5em; color: #ccc; } diff --git a/conifer/syrup/models.py b/conifer/syrup/models.py index f6e53d6..df32f8e 100644 --- a/conifer/syrup/models.py +++ b/conifer/syrup/models.py @@ -527,3 +527,19 @@ class Target(m.Model): def __unicode__(self): return self.name + +#---------------------------------------------------------------------- +# SIP checkout + +class Checkout(m.Model): + """A log of checkout events.""" + + patron = m.CharField(max_length=100) + patron_descrip = m.CharField(max_length=512) + item = m.CharField(max_length=100, null=True) + item_descrip = m.CharField(max_length=512, null=True) + staff = m.ForeignKey(User) + initiated = m.DateTimeField(auto_now_add=True) + completed = m.DateTimeField(default=None, null=True) + outcome = m.CharField(max_length=100, null=True) + diff --git a/conifer/syrup/views.py b/conifer/syrup/views.py index f2c46ae..e47e1f9 100644 --- a/conifer/syrup/views.py +++ b/conifer/syrup/views.py @@ -34,6 +34,7 @@ import django.forms import re import sys from django.forms.models import modelformset_factory +from conifer.custom import lib_integration #----------------------------------------------------------------------------- # Z39.50 Support @@ -1226,23 +1227,32 @@ def phys_checkout(request): patron, item = post('patron'), post('item') if post('step') == '1': # patron entered, need item - patron_descrip = 'Fred Example, Jr.' # fixme, lookup + # first get patron data. + msg = lib_integration.patron_info(patron) + patron_descrip = '%s (%s) — %s' % ( + msg['personal'], msg['home_library'], + msg['screenmsg']) return g.render('phys/checkout.xhtml', step=2, patron=patron, patron_descrip=patron_descrip) elif post('step') == '2': # patron + item. do SIP calls. # log the checkout in a local table. - patron_descrip = 'Fred Example, Jr.' # fixme, lookup - item_descrip = 'War and Peace (Reader\'s Digest edition)' + # also, make sure the barcode actually matches with a + # known barcode in Syrup. We only checkout what we know + # about. + msg = lib_integration.item_info(item) + item_descrip = '%s — %s' % ( + msg['title'], msg['status']) + + # do the checkout return g.render('phys/checkout.xhtml', step=3, patron=patron, item=item, - patron_descrip=patron_descrip, + patron_descrip=post('patron_descrip'), item_descrip=item_descrip) elif post('step') == '3': # continue after checkout. Go to 'checkout another item'. - patron_descrip = 'Fred Example, Jr.' # fixme, lookup return g.render('phys/checkout.xhtml', step=2, patron=patron, - patron_descrip=patron_descrip) + patron_descrip=post('patron_descrip')) diff --git a/conifer/templates/phys/checkout.xhtml b/conifer/templates/phys/checkout.xhtml index 38078cd..737102b 100644 --- a/conifer/templates/phys/checkout.xhtml +++ b/conifer/templates/phys/checkout.xhtml @@ -1,4 +1,6 @@ Patron Barcode - + - ${patron}: ${patron_descrip} + ${patron}: ${Markup(patron_descrip)} + Item Barcode - + - ${item}: ${item_descrip} + ${item}: ${Markup(item_descrip)} - Success: Item Checked Out. + Success: Item Checked Out (FOR PRETEND! Not doing checkout yet). -- 2.11.0