]> git.evergreen-ils.org Git - working/random.git/blob - contrib/evergreen/eg_utils.py
added configurable dictionary file option, fixed comment typo
[working/random.git] / contrib / evergreen / eg_utils.py
1 from constrictor.properties import Properties
2 from constrictor.log import *
3 from osrf.net_obj import NetworkObject
4 import osrf.json
5 from osrf.gateway import GatewayRequest, XMLGatewayRequest, JSONGatewayRequest
6 from oils.utils.idl import IDLParser
7 from oils.utils.utils import md5sum
8 from oils.event import Event
9 from oils.const import *
10 import os, errno, random
11
12 props = Properties.getProperties()
13 words = []
14 default_dictionary = '/usr/share/dict/words'
15
16 def init():
17     global words
18
19     loadIDL()
20     initOsrf()
21
22     if props.getProperty('evergreen.autologin') == 'true':
23         login(
24             props.getProperty('evergreen.username'),
25             props.getProperty('evergreen.password'),
26             props.getProperty('evergreen.workstation'))
27
28         user = None
29         if not props.getProperty('evergreen.patronIDs'):
30             # if there are not configured patron IDs, go ahead 
31             # and use the ID of the logged in user
32             user = fetchSessionUser()
33             logInfo("Setting evergreen.patronIDs to logged in user %s" % str(user.id()))
34             props.setProperty('evergreen.patronIDs', str(user.id()))
35
36         if not props.getProperty('evergreen.orgIDs'):
37             # simlilarly, if no org is provided, use the home org of the logged in user
38             if not user:
39                 user = fetchSessionUser()
40             logInfo("Setting evergreen.orgIDs to logged in user's home_ou %s" % str(user.home_ou()))
41             props.setProperty('evergreen.orgIDs', str(user.home_ou()))
42
43
44     dict_file = props.getProperty('evergreen.dictionary') or default_dictionary
45     try:
46         words_file = open(dict_file)
47     except Exception:
48         logError("Unable to open dictionary file '%s'" % dict_file)
49         return
50         
51     words = words_file.readlines()
52     words_file.close()
53
54
55 def initOsrf():
56     # if necessary, create a connection to the opensrf network for this thread
57     if str(props.getProperty('evergreen.netProtocol')).lower() == 'jabber':
58         if props.getProperty('evergreen.osrfConfig'):
59             logInfo("Connecting to the opensrf network")
60             from osrf.system import osrfConnect
61             osrfConnect(
62                 props.getProperty('evergreen.osrfConfig'),
63                 props.getProperty('evergreen.osrfConfigContext'))
64
65
66 def initThread():
67     ''' Performs thread-specific initialization '''
68     initOsrf()
69
70 def fetchSessionUser():
71     user = request('open-ils.auth', 'open-ils.auth.session.retrieve', authtoken()).send()
72     if Event.parse_event(user):
73         raise ILSEventException(osrf.json.to_json(user))
74     logInfo("fetched user %s" % user.usrname())
75     return user
76
77 def loadIDL():
78     
79     # XX add logic to allow IDL fetching via jabber
80
81     server = props.getProperty('evergreen.server')
82     cacheDir = props.getProperty('constrictor.cacheDir')
83     GatewayRequest.setDefaultHost(server)
84
85     import urllib2
86     parser = IDLParser()
87     file = None
88     filePath = '%s/evergreen/fm_IDL.xml' % cacheDir
89
90     try:
91         # see if we have a local copy of the IDL already in the cache
92         file = open(filePath, 'r')
93
94     except IOError:
95         logInfo('fetching: http://%s/%s' % (server, props.getProperty('evergreen.IDLPath')))
96         f = urllib2.urlopen('http://%s/%s' % (server, props.getProperty('evergreen.IDLPath')))
97
98         if not os.path.exists('%s/evergreen' % cacheDir):
99             os.mkdir('%s/evergreen' % cacheDir)
100
101         file = open(filePath, 'w')
102         file.write(f.read())
103         file.close()
104
105     logInfo("parsing Evergreen IDL file...")
106     parser.set_IDL(filePath)
107     parser.parse_IDL()
108
109
110 class AtomicReqWrapper(object):
111     ''' This wraps the built-in osrfAtomicRequest in a 
112         gateway request-style class interface '''
113
114     def __init__(self, service, method, *args):
115         self.service = service
116         self.method = method
117         self.args = list(args)
118
119     def send(self):
120         from osrf.ses import osrfAtomicRequest
121         return osrfAtomicRequest(self.service, self.method, *(self.args))
122
123
124
125 def request(service, method, *args):
126     global props
127     proto = props.getProperty('evergreen.netProtocol')
128     if str(proto).lower() == 'jabber':
129         req = AtomicReqWrapper(service, method, *args)
130     else:
131         if str(proto).lower() == 'json':
132             req = JSONGatewayRequest(service, method, *args)
133         else:
134             req = XMLGatewayRequest(service, method, *args)
135         req.setPath(props.getProperty('evergreen.gatewayPath'))
136     return req
137
138
139 __authtoken = None
140 def authtoken():
141     if not __authtoken:
142         raise AuthException()
143     return __authtoken
144
145 def login(username, password, workstation=None):
146     ''' Login to the server and get back an authtoken'''
147     global __authtoken 
148
149     logInfo("attempting login with user " + username)
150
151     seed = request(
152         'open-ils.auth', 
153         'open-ils.auth.authenticate.init', username).send()
154
155     # generate the hashed password
156     password = md5sum(seed + md5sum(password))
157
158     result = request(
159         'open-ils.auth',
160         'open-ils.auth.authenticate.complete',
161         {   'workstation' : workstation,
162             'username' : username,
163             'password' : password,
164             'type' : 'staff' 
165         }).send()
166
167     evt = Event.parse_event(result)
168     if evt and not evt.success:
169        raise AuthException(evt.text_code)
170
171     __authtoken = result['payload']['authtoken']
172     return __authtoken
173
174      
175 class AuthException(Exception):
176     def __init__(self, msg=''):
177         self.msg = msg
178     def __str__(self):
179         return 'AuthException: %s' % self.msg
180
181 class ILSEventException(Exception):
182     pass
183
184
185 def random_phrase(num_words, max_num_words=3):
186
187     if num_words is None:
188         num_words = int( (random.random() * max_num_words) % max_num_words) + 1
189
190     phrase = ''
191
192     for i in range(0, num_words):
193         try:
194             word = words[ int(random.random() * len(words)) ]
195         except IndexError:
196             continue
197         phrase += '%s ' % word[0:len(word)-1]
198
199     return phrase
200