author | Mikael Berthe <mikael@lilotux.net> |
Sat, 25 Aug 2007 15:46:55 +0200 | |
changeset 42 | cb52cef33d61 |
parent 0 | 93b25987d3e5 |
permissions | -rw-r--r-- |
0
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
1 |
## transports.py |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
2 |
## |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
3 |
## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
4 |
## |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
5 |
## This program is free software; you can redistribute it and/or modify |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
6 |
## it under the terms of the GNU General Public License as published by |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
7 |
## the Free Software Foundation; either version 2, or (at your option) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
8 |
## any later version. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
9 |
## |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
10 |
## This program is distributed in the hope that it will be useful, |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
11 |
## but WITHOUT ANY WARRANTY; without even the implied warranty of |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
12 |
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
13 |
## GNU General Public License for more details. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
14 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
15 |
# $Id: dispatcher.py,v 1.41 2006/06/03 13:53:27 normanr Exp $ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
16 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
17 |
""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
18 |
Main xmpppy mechanism. Provides library with methods to assign different handlers |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
19 |
to different XMPP stanzas. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
20 |
Contains one tunable attribute: DefaultTimeout (25 seconds by default). It defines time that |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
21 |
Dispatcher.SendAndWaitForResponce method will wait for reply stanza before giving up. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
22 |
""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
23 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
24 |
import simplexml,time,sys |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
25 |
from protocol import * |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
26 |
from client import PlugIn |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
27 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
28 |
DefaultTimeout=25 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
29 |
ID=0 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
30 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
31 |
class Dispatcher(PlugIn): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
32 |
""" Ancestor of PlugIn class. Handles XMPP stream, i.e. aware of stream headers. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
33 |
Can be plugged out/in to restart these headers (used for SASL f.e.). """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
34 |
def __init__(self): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
35 |
PlugIn.__init__(self) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
36 |
DBG_LINE='dispatcher' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
37 |
self.handlers={} |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
38 |
self._expected={} |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
39 |
self._defaultHandler=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
40 |
self._pendingExceptions=[] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
41 |
self._eventHandler=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
42 |
self._cycleHandlers=[] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
43 |
self._exported_methods=[self.Process,self.RegisterHandler,self.RegisterDefaultHandler,\ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
44 |
self.RegisterEventHandler,self.UnregisterCycleHandler,self.RegisterCycleHandler,\ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
45 |
self.RegisterHandlerOnce,self.UnregisterHandler,self.RegisterProtocol,\ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
46 |
self.WaitForResponse,self.SendAndWaitForResponse,self.send,self.disconnect,\ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
47 |
self.SendAndCallForResponse, ] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
48 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
49 |
def dumpHandlers(self): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
50 |
""" Return set of user-registered callbacks in it's internal format. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
51 |
Used within the library to carry user handlers set over Dispatcher replugins. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
52 |
return self.handlers |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
53 |
def restoreHandlers(self,handlers): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
54 |
""" Restores user-registered callbacks structure from dump previously obtained via dumpHandlers. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
55 |
Used within the library to carry user handlers set over Dispatcher replugins. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
56 |
self.handlers=handlers |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
57 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
58 |
def _init(self): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
59 |
""" Registers default namespaces/protocols/handlers. Used internally. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
60 |
self.RegisterNamespace('unknown') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
61 |
self.RegisterNamespace(NS_STREAMS) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
62 |
self.RegisterNamespace(self._owner.defaultNamespace) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
63 |
self.RegisterProtocol('iq',Iq) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
64 |
self.RegisterProtocol('presence',Presence) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
65 |
self.RegisterProtocol('message',Message) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
66 |
self.RegisterDefaultHandler(self.returnStanzaHandler) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
67 |
self.RegisterHandler('error',self.streamErrorHandler,xmlns=NS_STREAMS) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
68 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
69 |
def plugin(self, owner): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
70 |
""" Plug the Dispatcher instance into Client class instance and send initial stream header. Used internally.""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
71 |
self._init() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
72 |
for method in self._old_owners_methods: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
73 |
if method.__name__=='send': self._owner_send=method; break |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
74 |
self._owner.lastErrNode=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
75 |
self._owner.lastErr=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
76 |
self._owner.lastErrCode=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
77 |
self.StreamInit() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
78 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
79 |
def plugout(self): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
80 |
""" Prepares instance to be destructed. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
81 |
self.Stream.dispatch=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
82 |
self.Stream.DEBUG=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
83 |
self.Stream.features=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
84 |
self.Stream.destroy() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
85 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
86 |
def StreamInit(self): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
87 |
""" Send an initial stream header. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
88 |
self.Stream=simplexml.NodeBuilder() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
89 |
self.Stream._dispatch_depth=2 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
90 |
self.Stream.dispatch=self.dispatch |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
91 |
self.Stream.stream_header_received=self._check_stream_start |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
92 |
self._owner.debug_flags.append(simplexml.DBG_NODEBUILDER) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
93 |
self.Stream.DEBUG=self._owner.DEBUG |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
94 |
self.Stream.features=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
95 |
self._metastream=Node('stream:stream') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
96 |
self._metastream.setNamespace(self._owner.Namespace) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
97 |
self._metastream.setAttr('version','1.0') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
98 |
self._metastream.setAttr('xmlns:stream',NS_STREAMS) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
99 |
self._metastream.setAttr('to',self._owner.Server) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
100 |
self._owner.send("<?xml version='1.0'?>%s>"%str(self._metastream)[:-2]) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
101 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
102 |
def _check_stream_start(self,ns,tag,attrs): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
103 |
if ns<>NS_STREAMS or tag<>'stream': |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
104 |
raise ValueError('Incorrect stream start: (%s,%s). Terminating.'%(tag,ns)) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
105 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
106 |
def Process(self, timeout=0): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
107 |
""" Check incoming stream for data waiting. If "timeout" is positive - block for as max. this time. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
108 |
Returns: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
109 |
1) length of processed data if some data were processed; |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
110 |
2) '0' string if no data were processed but link is alive; |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
111 |
3) 0 (zero) if underlying connection is closed. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
112 |
Take note that in case of disconnection detect during Process() call |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
113 |
disconnect handlers are called automatically. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
114 |
""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
115 |
for handler in self._cycleHandlers: handler(self) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
116 |
if len(self._pendingExceptions) > 0: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
117 |
_pendingException = self._pendingExceptions.pop() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
118 |
raise _pendingException[0], _pendingException[1], _pendingException[2] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
119 |
if self._owner.Connection.pending_data(timeout): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
120 |
try: data=self._owner.Connection.receive() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
121 |
except IOError: return |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
122 |
self.Stream.Parse(data) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
123 |
if len(self._pendingExceptions) > 0: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
124 |
_pendingException = self._pendingExceptions.pop() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
125 |
raise _pendingException[0], _pendingException[1], _pendingException[2] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
126 |
if data: return len(data) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
127 |
return '0' # It means that nothing is received but link is alive. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
128 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
129 |
def RegisterNamespace(self,xmlns,order='info'): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
130 |
""" Creates internal structures for newly registered namespace. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
131 |
You can register handlers for this namespace afterwards. By default one namespace |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
132 |
already registered (jabber:client or jabber:component:accept depending on context. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
133 |
self.DEBUG('Registering namespace "%s"'%xmlns,order) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
134 |
self.handlers[xmlns]={} |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
135 |
self.RegisterProtocol('unknown',Protocol,xmlns=xmlns) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
136 |
self.RegisterProtocol('default',Protocol,xmlns=xmlns) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
137 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
138 |
def RegisterProtocol(self,tag_name,Proto,xmlns=None,order='info'): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
139 |
""" Used to declare some top-level stanza name to dispatcher. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
140 |
Needed to start registering handlers for such stanzas. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
141 |
Iq, message and presence protocols are registered by default. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
142 |
if not xmlns: xmlns=self._owner.defaultNamespace |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
143 |
self.DEBUG('Registering protocol "%s" as %s(%s)'%(tag_name,Proto,xmlns), order) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
144 |
self.handlers[xmlns][tag_name]={type:Proto, 'default':[]} |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
145 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
146 |
def RegisterNamespaceHandler(self,xmlns,handler,typ='',ns='', makefirst=0, system=0): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
147 |
""" Register handler for processing all stanzas for specified namespace. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
148 |
self.RegisterHandler('default', handler, typ, ns, xmlns, makefirst, system) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
149 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
150 |
def RegisterHandler(self,name,handler,typ='',ns='',xmlns=None, makefirst=0, system=0): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
151 |
"""Register user callback as stanzas handler of declared type. Callback must take |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
152 |
(if chained, see later) arguments: dispatcher instance (for replying), incomed |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
153 |
return of previous handlers. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
154 |
The callback must raise xmpp.NodeProcessed just before return if it want preven |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
155 |
callbacks to be called with the same stanza as argument _and_, more importantly |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
156 |
library from returning stanza to sender with error set (to be enabled in 0.2 ve |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
157 |
Arguments: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
158 |
"name" - name of stanza. F.e. "iq". |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
159 |
"handler" - user callback. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
160 |
"typ" - value of stanza's "type" attribute. If not specified any value match |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
161 |
"ns" - namespace of child that stanza must contain. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
162 |
"chained" - chain together output of several handlers. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
163 |
"makefirst" - insert handler in the beginning of handlers list instead of |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
164 |
adding it to the end. Note that more common handlers (i.e. w/o "typ" and " |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
165 |
will be called first nevertheless. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
166 |
"system" - call handler even if NodeProcessed Exception were raised already. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
167 |
""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
168 |
if not xmlns: xmlns=self._owner.defaultNamespace |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
169 |
self.DEBUG('Registering handler %s for "%s" type->%s ns->%s(%s)'%(handler,name,typ,ns,xmlns), 'info') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
170 |
if not typ and not ns: typ='default' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
171 |
if not self.handlers.has_key(xmlns): self.RegisterNamespace(xmlns,'warn') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
172 |
if not self.handlers[xmlns].has_key(name): self.RegisterProtocol(name,Protocol,xmlns,'warn') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
173 |
if not self.handlers[xmlns][name].has_key(typ+ns): self.handlers[xmlns][name][typ+ns]=[] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
174 |
if makefirst: self.handlers[xmlns][name][typ+ns].insert(0,{'func':handler,'system':system}) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
175 |
else: self.handlers[xmlns][name][typ+ns].append({'func':handler,'system':system}) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
176 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
177 |
def RegisterHandlerOnce(self,name,handler,typ='',ns='',xmlns=None,makefirst=0, system=0): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
178 |
""" Unregister handler after first call (not implemented yet). """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
179 |
if not xmlns: xmlns=self._owner.defaultNamespace |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
180 |
self.RegisterHandler(name, handler, typ, ns, xmlns, makefirst, system) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
181 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
182 |
def UnregisterHandler(self,name,handler,typ='',ns='',xmlns=None): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
183 |
""" Unregister handler. "typ" and "ns" must be specified exactly the same as with registering.""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
184 |
if not xmlns: xmlns=self._owner.defaultNamespace |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
185 |
if not typ and not ns: typ='default' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
186 |
for pack in self.handlers[xmlns][name][typ+ns]: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
187 |
if handler==pack['func']: break |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
188 |
else: pack=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
189 |
try: self.handlers[xmlns][name][typ+ns].remove(pack) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
190 |
except ValueError: pass |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
191 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
192 |
def RegisterDefaultHandler(self,handler): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
193 |
""" Specify the handler that will be used if no NodeProcessed exception were raised. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
194 |
This is returnStanzaHandler by default. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
195 |
self._defaultHandler=handler |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
196 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
197 |
def RegisterEventHandler(self,handler): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
198 |
""" Register handler that will process events. F.e. "FILERECEIVED" event. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
199 |
self._eventHandler=handler |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
200 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
201 |
def returnStanzaHandler(self,conn,stanza): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
202 |
""" Return stanza back to the sender with <feature-not-implemennted/> error set. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
203 |
if stanza.getType() in ['get','set']: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
204 |
conn.send(Error(stanza,ERR_FEATURE_NOT_IMPLEMENTED)) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
205 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
206 |
def streamErrorHandler(self,conn,error): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
207 |
name,text='error',error.getData() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
208 |
for tag in error.getChildren(): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
209 |
if tag.getNamespace()==NS_XMPP_STREAMS: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
210 |
if tag.getName()=='text': text=tag.getData() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
211 |
else: name=tag.getName() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
212 |
if name in stream_exceptions.keys(): exc=stream_exceptions[name] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
213 |
else: exc=StreamError |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
214 |
raise exc((name,text)) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
215 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
216 |
def RegisterCycleHandler(self,handler): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
217 |
""" Register handler that will be called on every Dispatcher.Process() call. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
218 |
if handler not in self._cycleHandlers: self._cycleHandlers.append(handler) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
219 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
220 |
def UnregisterCycleHandler(self,handler): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
221 |
""" Unregister handler that will is called on every Dispatcher.Process() call.""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
222 |
if handler in self._cycleHandlers: self._cycleHandlers.remove(handler) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
223 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
224 |
def Event(self,realm,event,data): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
225 |
""" Raise some event. Takes three arguments: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
226 |
1) "realm" - scope of event. Usually a namespace. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
227 |
2) "event" - the event itself. F.e. "SUCESSFULL SEND". |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
228 |
3) data that comes along with event. Depends on event.""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
229 |
if self._eventHandler: self._eventHandler(realm,event,data) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
230 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
231 |
def dispatch(self,stanza,session=None,direct=0): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
232 |
""" Main procedure that performs XMPP stanza recognition and calling apppropriate handlers for it. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
233 |
Called internally. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
234 |
if not session: session=self |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
235 |
session.Stream._mini_dom=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
236 |
name=stanza.getName() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
237 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
238 |
if not direct and self._owner._route: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
239 |
if name == 'route': |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
240 |
if stanza.getAttr('error') == None: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
241 |
if len(stanza.getChildren()) == 1: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
242 |
stanza = stanza.getChildren()[0] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
243 |
name=stanza.getName() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
244 |
else: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
245 |
for each in stanza.getChildren(): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
246 |
self.dispatch(each,session,direct=1) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
247 |
return |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
248 |
elif name == 'presence': |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
249 |
return |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
250 |
elif name in ('features','bind'): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
251 |
pass |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
252 |
else: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
253 |
raise UnsupportedStanzaType(name) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
254 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
255 |
if name=='features': session.Stream.features=stanza |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
256 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
257 |
xmlns=stanza.getNamespace() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
258 |
if not self.handlers.has_key(xmlns): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
259 |
self.DEBUG("Unknown namespace: " + xmlns,'warn') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
260 |
xmlns='unknown' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
261 |
if not self.handlers[xmlns].has_key(name): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
262 |
self.DEBUG("Unknown stanza: " + name,'warn') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
263 |
name='unknown' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
264 |
else: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
265 |
self.DEBUG("Got %s/%s stanza"%(xmlns,name), 'ok') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
266 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
267 |
if stanza.__class__.__name__=='Node': stanza=self.handlers[xmlns][name][type](node=stanza) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
268 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
269 |
typ=stanza.getType() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
270 |
if not typ: typ='' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
271 |
stanza.props=stanza.getProperties() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
272 |
ID=stanza.getID() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
273 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
274 |
session.DEBUG("Dispatching %s stanza with type->%s props->%s id->%s"%(name,typ,stanza.props,ID),'ok') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
275 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
276 |
list=['default'] # we will use all handlers: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
277 |
if self.handlers[xmlns][name].has_key(typ): list.append(typ) # from very common... |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
278 |
for prop in stanza.props: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
279 |
if self.handlers[xmlns][name].has_key(prop): list.append(prop) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
280 |
if typ and self.handlers[xmlns][name].has_key(typ+prop): list.append(typ+prop) # ...to very particular |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
281 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
282 |
chain=self.handlers[xmlns]['default']['default'] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
283 |
for key in list: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
284 |
if key: chain = chain + self.handlers[xmlns][name][key] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
285 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
286 |
output='' |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
287 |
if session._expected.has_key(ID): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
288 |
user=0 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
289 |
if type(session._expected[ID])==type(()): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
290 |
cb,args=session._expected[ID] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
291 |
session.DEBUG("Expected stanza arrived. Callback %s(%s) found!"%(cb,args),'ok') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
292 |
try: cb(session,stanza,**args) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
293 |
except Exception, typ: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
294 |
if typ.__class__.__name__<>'NodeProcessed': raise |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
295 |
else: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
296 |
session.DEBUG("Expected stanza arrived!",'ok') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
297 |
session._expected[ID]=stanza |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
298 |
else: user=1 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
299 |
for handler in chain: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
300 |
if user or handler['system']: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
301 |
try: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
302 |
handler['func'](session,stanza) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
303 |
except Exception, typ: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
304 |
if typ.__class__.__name__<>'NodeProcessed': |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
305 |
self._pendingExceptions.insert(0, sys.exc_info()) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
306 |
return |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
307 |
user=0 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
308 |
if user and self._defaultHandler: self._defaultHandler(session,stanza) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
309 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
310 |
def WaitForResponse(self, ID, timeout=DefaultTimeout): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
311 |
""" Block and wait until stanza with specific "id" attribute will come. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
312 |
If no such stanza is arrived within timeout, return None. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
313 |
If operation failed for some reason then owner's attributes |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
314 |
lastErrNode, lastErr and lastErrCode are set accordingly. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
315 |
self._expected[ID]=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
316 |
has_timed_out=0 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
317 |
abort_time=time.time() + timeout |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
318 |
self.DEBUG("Waiting for ID:%s with timeout %s..." % (ID,timeout),'wait') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
319 |
while not self._expected[ID]: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
320 |
if not self.Process(0.04): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
321 |
self._owner.lastErr="Disconnect" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
322 |
return None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
323 |
if time.time() > abort_time: |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
324 |
self._owner.lastErr="Timeout" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
325 |
return None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
326 |
response=self._expected[ID] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
327 |
del self._expected[ID] |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
328 |
if response.getErrorCode(): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
329 |
self._owner.lastErrNode=response |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
330 |
self._owner.lastErr=response.getError() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
331 |
self._owner.lastErrCode=response.getErrorCode() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
332 |
return response |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
333 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
334 |
def SendAndWaitForResponse(self, stanza, timeout=DefaultTimeout): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
335 |
""" Put stanza on the wire and wait for recipient's response to it. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
336 |
return self.WaitForResponse(self.send(stanza),timeout) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
337 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
338 |
def SendAndCallForResponse(self, stanza, func, args={}): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
339 |
""" Put stanza on the wire and call back when recipient replies. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
340 |
Additional callback arguments can be specified in args. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
341 |
self._expected[self.send(stanza)]=(func,args) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
342 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
343 |
def send(self,stanza): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
344 |
""" Serialise stanza and put it on the wire. Assign an unique ID to it before send. |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
345 |
Returns assigned ID.""" |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
346 |
if type(stanza) in [type(''), type(u'')]: return self._owner_send(stanza) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
347 |
if not isinstance(stanza,Protocol): _ID=None |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
348 |
elif not stanza.getID(): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
349 |
global ID |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
350 |
ID+=1 |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
351 |
_ID=`ID` |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
352 |
stanza.setID(_ID) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
353 |
else: _ID=stanza.getID() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
354 |
if self._owner._registered_name and not stanza.getAttr('from'): stanza.setAttr('from',self._owner._registered_name) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
355 |
if self._owner._route and stanza.getName()!='bind': |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
356 |
to=self._owner.Server |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
357 |
if stanza.getTo() and stanza.getTo().getDomain(): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
358 |
to=stanza.getTo().getDomain() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
359 |
frm=stanza.getFrom() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
360 |
if frm.getDomain(): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
361 |
frm=frm.getDomain() |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
362 |
route=Protocol('route',to=to,frm=frm,payload=[stanza]) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
363 |
stanza=route |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
364 |
stanza.setNamespace(self._owner.Namespace) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
365 |
stanza.setParent(self._metastream) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
366 |
self._owner_send(stanza) |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
367 |
return _ID |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
368 |
|
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
369 |
def disconnect(self): |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
370 |
""" Send a stream terminator and and handle all incoming stanzas before stream closure. """ |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
371 |
self._owner_send('</stream:stream>') |
93b25987d3e5
Initial Mercurial repository
Mikael Berthe <mikael@lilotux.net>
parents:
diff
changeset
|
372 |
while self.Process(1): pass |