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