[open-ils-commits] r1278 - in servres/trunk/conifer: libsystems/evergreen syrup/views (artunit)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Mar 22 23:21:00 EDT 2011
Author: artunit
Date: 2011-03-22 23:20:57 -0400 (Tue, 22 Mar 2011)
New Revision: 1278
Modified:
servres/trunk/conifer/libsystems/evergreen/opensrf.py
servres/trunk/conifer/syrup/views/items.py
Log:
thanks to dbs, much better opensrf interaction for update
Modified: servres/trunk/conifer/libsystems/evergreen/opensrf.py
===================================================================
--- servres/trunk/conifer/libsystems/evergreen/opensrf.py 2011-03-23 02:26:20 UTC (rev 1277)
+++ servres/trunk/conifer/libsystems/evergreen/opensrf.py 2011-03-23 03:20:57 UTC (rev 1278)
@@ -1,39 +1,70 @@
# session-based opensrf calls go here
+# thanks to dan scott for sorting out the python integration
-from conifer.libsystems import marcxml as M
-from conifer.libsystems.evergreen import item_status as I
-from conifer.libsystems.evergreen.support import initialize, E1
from datetime import date
from django.conf import settings
-import hashlib
import os
import re
import traceback
-def auth_token(username, password, org, workstation):
- try:
- authtoken = None
- payload = E1(settings.OPENSRF_AUTHENTICATE_INIT, username)
- pw = hashlib.md5(password).hexdigest()
- pw = hashlib.md5(payload + pw).hexdigest()
- authinfo = E1(settings.OPENSRF_AUTHENTICATE,{"password":pw, "type":"staff",
- "org": org, "username":username,
- "workstation":workstation})
- if authinfo:
- payload = authinfo.get("payload")
- authtoken = payload.get("authtoken")
- except:
- print "authentication problem: ", username
- print "*** print_exc:"
- traceback.print_exc()
- pass # fail silently in production
- return None
+import oils.event
+import oils.utils.idl
+import oils.utils.utils
+import osrf.gateway
+import osrf.json
+import sys
+import tempfile
+import urllib2
+class AuthException(Exception):
+ """
+ Exceptions for authentication events
+ """
+
+ def __init__(self, msg=''):
+ """
+ Initialize the authentication exception
+ """
+ Exception.__init__(self)
+ self.msg = msg
+
+ def __str__(self):
+ """
+ Stringify the authentication exception
+ """
+ return 'AuthException: %s' % self.msg
+
+def auth_token(username, password, workstation):
+ authtoken = None
+ seed = request(
+ 'open-ils.auth',
+ 'open-ils.auth.authenticate.init', username).send()
+
+ # generate the hashed password
+ password = oils.utils.utils.md5sum(seed + oils.utils.utils.md5sum(password))
+
+ result = request(
+ 'open-ils.auth',
+ 'open-ils.auth.authenticate.complete', {
+ 'workstation' : workstation,
+ 'username' : username,
+ 'password' : password,
+ 'type' : 'staff'
+ }).send()
+
+ evt = oils.event.Event.parse_event(result)
+ if evt and not evt.success:
+ print "authentication problem: ", AuthException(evt.text_code)
+ return None
+
+ authtoken = result['payload']['authtoken']
return authtoken
def session_cleanup(authtoken):
try:
- payload = E1(settings.OPENSRF_CLEANUP, authtoken)
+ result = request(
+ 'open-ils.auth',
+ 'open-ils.auth.session.delete', authtoken).send()
except:
print "session problem: ", authtoken
print "*** print_exc:"
@@ -43,55 +74,121 @@
return True
-def evergreen_item_update(barcode, callno, modifier, desk):
+def load_idl():
+ """
+ Loads the fieldmapper IDL, registering class hints for the defined objects
+
+ We use a temporary file to store the IDL each time load_idl()
+ is invoked to ensure that the IDL is in sync with the target
+ server. One could a HEAD request to do some smarter caching,
+ perhaps.
+ """
+
+ parser = oils.utils.idl.IDLParser()
+ idlfile = tempfile.TemporaryFile()
+
+ # Get the fm_IDL.xml file from the server
try:
- token = auth_token(settings.OPENSRF_STAFF_USERID, settings.OPENSRF_STAFF_PW,
- settings.OPENSRF_STAFF_ORG, settings.OPENSRF_STAFF_WORKSTATION)
+ idl = urllib2.urlopen('%s://%s/%s' %
+ (settings.OSRF_HTTP, settings.EVERGREEN_GATEWAY_SERVER, settings.IDL_URL)
+ )
+ idlfile.write(idl.read())
+ # rewind to the beginning of the file
+ idlfile.seek(0)
- null = None
- true = True
- false = False
- barcode_copy = E1(settings.OPENSRF_CN_BARCODE, token, barcode);
+ #no pass on these, updates are too critical to ever be out of sync
+ except urllib2.URLError, exc:
+ print("Could not open URL to read IDL: %s", exc.code)
- copy = None
- volumeinfo = None
+ except IOError, exc:
+ print("Could not write IDL to file: %s", exc.code)
- if barcode_copy:
- volumeinfo = barcode_copy.get("volume")
- if volumeinfo:
- volume = volumeinfo['__p']
- if volume and volume[7] != callno:
- volume[0] = []
- volume[7] = str(callno)
- vol_len = len(volume) - 1
- volume[vol_len] = str(volume[vol_len])
- # ok, this is bad, need to find what these values are
- for i in range(0, 4):
- volume.append(None)
- volume.append('1')
- # print "volume", volume
- updaterec = E1(settings.OPENSRF_VOLUME_UPDATE,
- token, [{"__c":"acn","__p":volume}], false,
- {"auto_merge_vols":false})
- # print "update", updaterec
- copy = barcode_copy.get("copy")
- if copy:
- # print "copy", copy
- detailid = copy['__p'][21]
- details = E1(settings.OPENSRF_FLESHEDCOPY_CALL, [detailid])
- if details and (details[0]['__p'][7] != modifier or details[0]['__p'][23] != desk):
- details[0]['__p'][7] = str(modifier)
- details[0]['__p'][23] = str(desk)
- # ditto here too, need to find what these values are
- for i in range(0, 6):
- details[0]['__p'].append(None)
- details[0]['__p'].append('1')
+ # parse the IDL
+ parser.set_IDL(idlfile)
+ parser.parse_IDL()
- print "details", details
- updaterec = E1(settings.OPENSRF_BATCH_UPDATE, token, details,true)
- # print "updaterec", updaterec
+def request(service, method, *args):
+ """
+ Make a JSON request to the OpenSRF gateway
- session_cleanup(token)
+ This is as simple as it gets. Atomic requests will require a bit
+ more effort.
+ """
+
+ req = osrf.gateway.JSONGatewayRequest(service, method, *args)
+
+ # The gateway URL ensures we're using JSON v1, not v0
+ req.setPath(settings.GATEWAY_URL)
+ return req
+
+def ils_item_update(barcode, callno, modifier, location):
+ try:
+ item_changed = False
+ callno_changed = False
+
+ # Set the host for our requests
+ osrf.gateway.GatewayRequest.setDefaultHost(settings.EVERGREEN_GATEWAY_SERVER)
+
+ # Pull all of our object definitions together
+ load_idl()
+
+ # We get our copy object
+ req = request('open-ils.search',
+ 'open-ils.search.asset.copy.fleshed2.find_by_barcode',
+ barcode)
+ barcode_copy = req.send()
+
+ # are there changes?
+ if barcode_copy.location().id != location or barcode_copy.circ_modifier != modifier:
+ item_changed = True
+
+ # And our call number object
+ req = request('open-ils.search',
+ 'open-ils.search.asset.call_number.retrieve',
+ barcode_copy.call_number())
+ call_num = req.send()
+
+ # are there changes?
+ if call_num.label() != callno:
+ callno_changed = True
+
+ # there might be nothing to do
+ if not item_changed and not callno_changed:
+ return True
+
+ # ok, we are going to update, first we authenticate
+ authtoken = auth_token(settings.OPENSRF_STAFF_USERID,
+ settings.OPENSRF_STAFF_PW,
+ settings.OPENSRF_STAFF_WORKSTATION)
+
+ # item changes first, location and circ modifier
+ if authtoken and item_changed:
+ barcode_copy.location().id(location);
+ barcode_copy.circ_modifier(modifier);
+ barcode_copy.ischanged(True)
+
+ acp = [barcode_copy]
+ req = request('open-ils.cat',
+ 'open-ils.cat.asset.copy.fleshed.batch.update',
+ authtoken, acp, False, None)
+ result = req.send()
+ # print "item result", result
+
+ # on to call number
+ if authtoken and callno_changed:
+ call_num.label(callno)
+ call_num.ischanged(True)
+
+ # volume.fleshed.batch.update expects an array of call number objects
+ acn = [call_num]
+ req = request('open-ils.cat',
+ 'open-ils.cat.asset.volume.fleshed.batch.update',
+ authtoken, acn, False, None)
+ result = req.send()
+ # print "callno result", result
+
+ #clean up session
+ session_cleanup(authtoken)
except:
print "item update problem"
print "*** print_exc:"
Modified: servres/trunk/conifer/syrup/views/items.py
===================================================================
--- servres/trunk/conifer/syrup/views/items.py 2011-03-23 02:26:20 UTC (rev 1277)
+++ servres/trunk/conifer/syrup/views/items.py 2011-03-23 03:20:57 UTC (rev 1278)
@@ -361,6 +361,7 @@
eg_modifier = None
eg_desk = None
+ #TODO: use python bindings for these interactions
bar_num=request.POST.get('bc')
if bar_num and settings.OPENSRF_STAFF_USERID:
bc = bar_num
@@ -456,7 +457,7 @@
update_status = True
if update_option == 'Cat':
- update_status = evergreen_item_update(item.barcode, item.orig_callno,
+ update_status = ils_item_update(item.barcode, item.orig_callno,
modifier_option, location_option)
#leave values alone if update failed
More information about the open-ils-commits
mailing list