[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