root/trunk/RBTelepathy/RBTelepathy/Connection.py

Revision 463, 5.5 kB (checked in by sholloway, 6 years ago)

*** empty log message ***

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 """
23 A Connection is the intermediatary between packet handlers and the
24 protocol.  OnStreamPacket distributes inbound packets based on packet type
25 and namespace to the registered packet handler.  Packet handlers
26 registrations are managed with the LoadHandler and UnloadHandler methods.
27 In this way, new features and functionality can be added within the
28 framework by simply extending the packet handler table.
29
30 The Connection is also the central repository for sharing state information
31 between packet handlers.  So, common information like login id can be found
32 here, or a few steps from here.
33
34 Related Packages:
35     Packet
36     Stream
37 """
38
39 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40 #~ Imports
41 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
43 from __future__ import generators
44 import logging
45 import weakref
46
47 import ErrorTypes
48
49 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 #~ Definitions
51 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52
53 class Connection(object):
54     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55     #~ Constants / Variables / Etc.
56     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57
58     log = logging.getLogger('Connection')
59     StreamPacketHandlers = {}
60     RoutedPacketHandlers = {}
61
62     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63     #~ Public Methods
64     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65
66     def __init__(self):
67         self.StreamPacketHandlers = self.StreamPacketHandlers.copy()
68         self.RoutedPacketHandlers = self.RoutedPacketHandlers.copy()
69
70     #~ Connection Operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71
72     def LoadDefaultHandlers(self):
73         pass
74
75     def Shutdown(self, *args, **kw):
76         raise NotImplementedError
77
78     def SendPacket(self, *args, **kw):
79         raise NotImplementedError
80
81     #~ Handler Management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82    
83     def LoadHandler(self, HandlerFactory, *args, **kw):
84         try:
85             connection = weakref.proxy(self)
86             handler = HandlerFactory(connection, *args, **kw)
87             self.protocol.packetbuilder.AddElementFactories(handler.ElementFactories)
88             for key in handler.StreamPacketHandlers:
89                 self.StreamPacketHandlers[key] = handler
90             for key in handler.RoutedPacketHandlers:
91                 self.RoutedPacketHandlers[key] = handler
92             return handler
93         except ErrorTypes.RBTelepathyError, e:
94             raise
95         except:
96             self.log.critical('Unexpected error loading handler %r', HandlerFactory, exc_info=1)
97             raise
98
99     def UnloadHandler(self, handler):
100         try:
101             self.protocol.packetbuilder.RemoveElementFactories(handler.ElementFactories)
102             for key in handler.StreamPacketHandlers:
103                 try: del self.StreamPacketHandlers[key]
104                 except KeyError: pass
105             for key in handler.RoutedPacketHandlers:
106                 try: del self.RoutedPacketHandlers[key]
107                 except KeyError: pass
108         except ErrorTypes.RBTelepathyError, e:
109             raise
110         except:
111             self.log.critical('Unexpected error unloading handler %r', handler, exc_info=1)
112             raise
113
114     #~ Event Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115
116     def OnRoutedPacket(self, packet, *args, **kw):
117         self.log.debug('Received Routed packet (%s, %s)', packet.namespace, packet.node)
118
119         # Lookup our packet handler
120         for nodeidx in self._GetPacketHandlerIndices((packet.namespace, packet.node)):
121             packethandler = self.RoutedPacketHandlers.get(nodeidx, None)
122             if packethandler is not None: break
123         else:
124             raise ErrorTypes.RoutedHandlerError("No RoutedPacketHandler for (%s, %s)" % (packet.namespace, packet.node))
125
126         return packethandler.OnRoutedPacket(packet, *args, **kw)
127
128     def OnStreamPacket(self, packet, *args, **kw):
129         self.log.debug('Received Stream packet (%s, %s)', packet.namespace, packet.node)
130
131         # Lookup our packet handler
132         for nodeidx in self._GetPacketHandlerIndices((packet.namespace, packet.node)):
133             packethandler = self.StreamPacketHandlers.get(nodeidx, None)
134             if packethandler is not None: break
135         else:
136             raise ErrorTypes.PacketHandlerError("No StreamPacketHandler for (%s, %s)" % (packet.namespace, packet.node))
137
138         return packethandler.OnStreamPacket(packet, *args, **kw)
139
140     def OnShutdown(self, how):
141         self.log.debug('Stream shutdown by "%s"', how)
142
143     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144     #~ Protected Methods
145     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146
147     def _GetPacketHandlerIndices(self, (namespace, node)):
148         yield (namespace, node)
149         yield (namespace, )
150         yield node
151         yield None
152
Note: See TracBrowser for help on using the browser.