]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/python/osrf/gateway.py
d9ef123e5474c554d75ff660624da01b0273a9a7
[OpenSRF.git] / src / python / osrf / gateway.py
1 from xml.dom import minidom
2 from xml.sax import handler, make_parser, saxutils
3 from json import *
4 from net_obj import *
5 import urllib, urllib2, sys, re
6
7 #
8
9 defaultHost = None
10 paramRegex = re.compile('\%27')
11
12 class GatewayRequest:
13     def __init__(self, service, method, params=[]):
14         self.service = service
15         self.method = method
16         self.params = params
17
18     def send(self):
19         params = self.buildPOSTParams()
20         request = urllib2.Request(self.buildURL(), data=params)
21         response = None
22         try:
23             response =urllib2.urlopen(request)
24         except urllib2.HTTPError, e:
25             # log this?
26             sys.stderr.write('HTTPError: code=%d : %s' % (e.code, str(e)))
27             raise e
28             
29         return self.handleResponse(response)
30
31     def buildPOSTParams(self):
32
33         params = urllib.urlencode({   
34             'service': self.service,
35             'method': self.method,
36             'format': self.getFormat(),
37             'input_format': self.getInputFormat()
38         })
39
40         for p in self.params:
41             # XXX for some reason, the gateway does not like escaped single-quotes ?
42             param = paramRegex.sub("'", urllib.quote(self.encodeParam(p)))
43             params += '&param=%s' % urllib.quote(self.encodeParam(param))
44
45         return params
46
47     def setDefaultHost(host):
48         global defaultHost
49         defaultHost = host
50     setDefaultHost = staticmethod(setDefaultHost)
51
52     def buildURL(self):
53         return 'http://%s/gateway' % defaultHost
54
55
56 class XMLGatewayRequest(GatewayRequest):
57
58     def __init__(self, service, method, *params):
59         GatewayRequest.__init__(self, service, method, list(params))
60
61     def getFormat(self):
62         return 'xml'
63
64     def getInputFormat(self):
65         return self.getFormat()
66
67     def handleResponse(self, response):
68         handler = XMLGatewayParser()
69         parser = make_parser()
70         parser.setContentHandler(handler)
71         parser.parse(response)
72         return handler.getResult()
73
74     def encodeParam(self, param):
75         return osrfObjectToXML(param);
76
77 class XMLGatewayParser(handler.ContentHandler):
78
79     def __init__(self):
80         self.result = None
81         self.objStack = []
82         self.keyStack = []
83
84     def getResult(self):
85         return self.result
86
87     def __getAttr(self, attrs, name):
88         for (k, v) in attrs.items():
89             if k == name:
90                 return v
91         return None
92
93     def startElement(self, name, attrs):
94
95         # XXX add support for serializable objects!
96
97         if name == 'null':
98             self.appendChild(None)
99             return
100
101         if name == 'element': # this is an object item wrapper
102             self.keyStack.append(self.__getAttr(attrs, 'key'))
103             return
104
105         hint = self.__getAttr(attrs, 'class_hint')
106         if hint:
107             obj = osrfNetworkObject.newFromHint(hint)
108
109         if name == 'array':
110             obj = []
111             self.appendChild(obj)
112             self.objStack.append(obj)
113             return
114
115         if name == 'object':
116             obj = {}
117             self.appendChild(obj)
118             self.objStack.append(obj)
119             return
120
121         if name == 'boolean':
122             self.appendChild((self.__getAttr(attrs, 'value') == 'true'))
123             return
124
125
126     def appendChild(self, child):
127
128         if self.result == None:
129             self.result = child
130
131         if not self.objStack: return;
132
133         parent = self.objStack[len(self.objStack)-1]
134
135         if( isinstance(parent, list) ):
136             parent.append(child)
137         else:
138             parent[self.keyStack.pop()] = child
139
140     def endElement(self, name):
141         if name == 'array' or name == 'object':
142             self.objStack.pop()
143
144     def characters(self, chars):
145         #self.appendChild(''.join(chars[start:leng+start]))
146         self.appendChild(urllib.unquote_plus(chars))
147
148
149
150     
151