root/trunk/RBJabber/sandbox/ether/jabberRPC.py

Revision 759, 5.0 kB (checked in by sholloway, 4 years ago)

--

Line 
1 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ Copyright (C) 2002-2004  TechGame Networks, LLC.
4 ##~
5 ##~ This library is free software; you can redistribute it and/or
6 ##~ modify it under the terms of the BSD style License as found in the
7 ##~ LICENSE file included with this distribution.
8 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9
10 #~ Imports
11 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12
13 import sys
14 import xmlrpclib
15 from RBJabber import Client
16 from RBFoundation.SmartSelect import SmartSelectList
17
18 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 #~ Constants / Variables / Etc.
20 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 nsXMLRPC = 'RBJabber.xmlrpc'
23
24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 #~ Definitions
26 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27
28 class JabberXMLRPCServerProxy(object):
29     """Derived from xmlrpclib.ServerProxy"""
30
31     def __init__(self, jcHost, serverJID, encoding=None, verbose=False, allow_none=False):
32         self.jcHost = jcHost
33         self.serverJID = serverJID
34         self.messageBody = 'XMLRPC over jabber'
35
36         self._allow_none = allow_none
37
38     def _request(self, methodname, params):
39         request = xmlrpclib.dumps(params, methodname, allow_none=self._allow_none)
40         # trim off the <?xml version=''?> because we are encapsulated
41         request = request.split('\n', 1)[1]
42         request = '<xmlrpc xmlns="%s">\n%s\n</xmlrpc>'%(nsXMLRPC, request)
43
44         self.jcHost.Message(self.serverJID, self.messageBody, xml=request)
45
46     def __getattr__(self, name):
47         return xmlrpclib._Method(self._request, name)
48
49 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50
51 class JabberXMLRPC(Client.Client):
52     remoteObject = None
53
54     def hookMessages(self):
55         self.stream.AddObserver('message', self.onMessage)
56
57     def onMessage(self, subject, message):
58         for each in message._iterElements(nsXMLRPC, 'xmlrpc'):
59             self.onXMLRPCMessage(each)
60
61     def onXMLRPCMessage(self, elem):
62         results = []
63         for xmlrpcElem in elem._iterAllElements():
64             results.append(self._marshaled_dispatch(xmlrpcElem._toXML()))
65         return results
66
67     def getJID(self):
68         return self.information.jid
69     jid = property(getJID)
70
71     def getRemoteObject(self):
72         return self.remoteObject
73     def setRemoteObject(self, value):
74         self.remoteObject = value
75
76     def _dispatch(self, method, params):
77         return getattr(self.getRemoteObject(), method)(*params)
78
79     def _marshaled_dispatch(self, data, dispatch_method = None):
80         """from python2.3's SimpleXMLPRCServer"""
81         data = '\n'+data
82         params, method = xmlrpclib.loads(data)
83
84         # generate response
85         try:
86             response = self._dispatch(method, params)
87             response = xmlrpclib.dumps((response,), methodresponse=1)
88         except xmlrpclib.Fault, fault:
89             response = xmlrpclib.dumps(fault)
90         except:
91             # report exception back to server
92             response = xmlrpclib.dumps(
93                 xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
94                 )
95
96         return response
97
98 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 #~ Testing
100 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101
102 class TestEventObject(object):
103     rpcOther = None
104     def __init__(self, name):
105         self.name = name
106
107     def __repr__(self):
108         return "%s<%s>" % (self.__class__.__name__, self.name)
109
110     def onEvent(self, msg):
111         print "%r.onEvent(%r)" % (self, msg)
112         self.rpcOther.onEventReply(msg, "I got it!")
113
114     def onEventReply(self, msg, reply):
115         print "%r.onEventReply(%r, %r)" % (self, msg, reply)
116
117 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
119 def test(loginInfos=[
120             ('swh.test.1', 'ok2jab4test', 'xmlrpc'),
121             ('swh.test.2', 'ok2jab4test', 'xmlrpc'),
122             ],
123         server='techgame.net',
124         ):
125
126     jcs = SmartSelectList([JabberXMLRPC(server) for each in loginInfos])
127     for jc, info in zip(jcs, loginInfos):
128         #jc._SetDebug(sys.stdout, sys.stdout)
129         jc.hookMessages()
130         jc.Authenticate(*info)
131         jc.setRemoteObject(TestEventObject(info[0]))
132
133     rpcs = []
134     for i, jc in enumerate(jcs):
135         jid = jcs[(i+1)%len(jcs)].getJID()
136         rpc = JabberXMLRPCServerProxy(jc, jid)
137         jc.getRemoteObject().rpcOther = rpc
138         rpcs.append(rpc)
139
140     jcs.ProcessPending(0.1)
141     return jcs, rpcs
142
143 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144 #~ Main
145 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146
147 if __name__=='__main__':
148     jcs, rpcs = test()
149     try:
150         rpcs[0].onEvent('From client 0')
151         jcs.ProcessPending(0.5)
152         rpcs[1].onEvent('From client 1')
153         jcs.ProcessPending(0.5)
154
155     finally:
156         for each in jcs:
157             each.Shutdown()
158         jcs.ProcessPending(0.5)
159
Note: See TracBrowser for help on using the browser.