Changeset 402
- Timestamp:
- 01/14/03 23:08:02 (6 years ago)
- Files:
-
- trunk/RBTelepathy/RBTelepathy/Packet/Elements.py (modified) (1 diff)
- trunk/RBTelepathy/RBTelepathy/Packet/StreamElements.py (modified) (1 diff)
- trunk/RBTelepathy/RBTelepathy/Packet/__init__.py (modified) (5 diffs)
- trunk/RBTelepathy/RBTelepathy/Stream/Protocol.py (modified) (4 diffs)
- trunk/RBTelepathy/test/test_streamProtocol.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/RBTelepathy/RBTelepathy/Packet/Elements.py
r398 r402 77 77 return ''.join(results) 78 78 79 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80 81 class Error(PacketElementBase): 82 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83 #~ OnStreamData adaptor 84 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 85 86 def OnStreamData(self, data, OnPacketComplete=None): 87 if OnPacketComplete is not None: 88 OnPacketComplete(self) 89 return data 90 91 def GetStreamHeader(self): 92 return self._toXML() 93 94 def GetStreamData(self): 95 return '' 96 trunk/RBTelepathy/RBTelepathy/Packet/StreamElements.py
r391 r402 53 53 _default_attributes = { 54 54 'format':'length', 55 'size':'0',55 #'size': None, 56 56 } 57 57 trunk/RBTelepathy/RBTelepathy/Packet/__init__.py
r398 r402 25 25 26 26 from RBFoundation.XMLClassBuilder import ElementFactory as EF 27 from RBFoundation import XMLClassBuilder 27 28 from RBFoundation.XMLObjectify import BaseObjectifiedXML, ObjectifiedXML 28 29 import Builder … … 32 33 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 34 #~ Constants / Variables / Etc. 35 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 36 37 StandardNamespaceSynonyms = { 38 'RBMessaging': 'http://namespaces.runeblade.com/RBMessaging', 39 None: 'http://namespaces.runeblade.com/RBMessaging', 40 } 41 42 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 #~ Definitions 34 44 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 35 45 … … 46 56 'terminator': StreamElements.TerminatedStream, 47 57 'term': StreamElements.TerminatedStream, 58 59 None: StreamElements.LengthStream, 48 60 } 49 61 … … 53 65 54 66 def __call__(self, owner, parent, node, attributes, namespacemap): 55 format = attributes ['format']67 format = attributes.get('format') 56 68 return self.StreamFormatTable[format] 57 69 58 70 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 59 71 60 StandardElementFactories = { 61 ## Long names 62 ('http://namespaces.runeblade.com/RBMessaging', 'message'): EF.Static(MessageElements.Message), 63 ('http://namespaces.runeblade.com/RBMessaging', 'stream'): StreamFormatFactory(), 64 ('http://namespaces.runeblade.com/RBMessaging', 'error'): EF.Static(ObjectifiedXML), 65 66 ('http://namespaces.runeblade.com/RBMessaging', ): EF.Static(ObjectifiedXML), 67 None: EF.Static(ObjectifiedXML), 68 } 72 class MessageErrorFactory(object): 73 def __call__(self, owner, parent, node, attributes, namespacemap): 74 raise KeyError, '"%s" is not a valid subchild of "%s"' % (node[1], parent.__node__) 69 75 70 76 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 71 77 72 StandardNamespaceSynonyms = { 73 'RBMessaging': 'http://namespaces.runeblade.com/RBMessaging', 74 None: 'http://namespaces.runeblade.com/RBMessaging', 75 } 78 class StandardMessage(MessageElements.Message, XMLClassBuilder.XMLClassBuilderBaseMixin): 79 ElementFactories = XMLClassBuilder.ElementFactorySet({ 80 ('http://namespaces.runeblade.com/RBMessaging', 'stream'): StreamFormatFactory(), 81 ('http://namespaces.runeblade.com/RBMessaging', 'to'): EF.Static(ObjectifiedXML), 82 ('http://namespaces.runeblade.com/RBMessaging', ): MessageErrorFactory(), 83 None: EF.Static(ObjectifiedXML), 84 }) 85 86 NamespaceSynonyms = StandardNamespaceSynonyms 87 DefaultNamespace = NamespaceSynonyms[None] 88 89 def _xmlChildFactory(self, owner, parent, node, attributes, namespacemap): 90 return self.ElementFactorySet._GetElementFactory(owner, parent, node, attributes, namespacemap) 76 91 77 92 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 80 95 81 96 class StandardStreamPacketBuilder(Builder.StreamPacketBuilder): 82 ElementFactories = Builder.StreamPacketBuilder.ElementFactories.copy() 83 ElementFactories.update(StandardElementFactories) 97 ElementFactories = XMLClassBuilder.ElementFactorySet({ 98 ('http://namespaces.runeblade.com/RBMessaging', 'message'): EF.Static(StandardMessage), 99 ('http://namespaces.runeblade.com/RBMessaging', 'error'): EF.Static(MessageElements.Error), 100 }) 84 101 85 NamespaceSynonyms = Builder.StreamPacketBuilder.NamespaceSynonyms.copy() 86 NamespaceSynonyms.update(StandardNamespaceSynonyms) 87 102 NamespaceSynonyms = StandardNamespaceSynonyms 88 103 DefaultNamespace = NamespaceSynonyms[None] 89 104 90 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~91 #~ Testing92 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~93 94 if __name__=='__main__':95 print "Testing..."96 pb = StandardStreamPacketBuilder()97 info = '''<?xml version='1.0'?>98 <msg>99 <to>account@network/resource?type=mobile</to>100 <stream format='term'/>101 <stream format='len' size='10'/>102 </msg>'''103 104 def printit(packet):105 print106 print packet.GetStreamInfo()107 print repr(packet.GetStreamData())108 print109 print 'Stream Content:'110 for each in packet.datastreams:111 print ' ', repr(each.StreamContent)112 print113 114 packet = pb.BuildPacket(info)115 116 data = '''Some real text\x04ThereAre10@Trash@'''117 packet.OnStreamData(data)118 119 printit(packet)120 121 newdata = ['New terminated data', 'New length-based data']122 for stream, nd in zip(packet.datastreams, newdata):123 stream.StreamContent = nd124 125 printit(packet)126 127 print "Test complete."trunk/RBTelepathy/RBTelepathy/Stream/Protocol.py
r401 r402 26 26 from RBMessaging.Packet import StandardStreamPacketBuilder 27 27 from xml.sax.saxutils import escape as xmlescape 28 from xml.sax.saxutils import quoteattr as xmlquoteattr 29 import logging 28 30 29 31 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 39 41 data = None 40 42 currentpacket = None 43 packetbuilder = None 44 stream = None 45 log = logging.getLogger('.'.join((__name__, 'StreamProtocol'))) 41 46 42 47 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 44 49 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 45 50 51 def __init__(self, PacketBuilderClass=StandardStreamPacketBuilder): 52 self.packetbuilder = PacketBuilderClass() 53 self.log.debug('StreamProtocol created') 54 55 def __del__(self): 56 self.log.debug('StreamProtocol destroyed') 57 46 58 def SendPacket(self, packet): 47 data = ''.join((packet.GetStreamHeader(), self.delimiter, packet.GetStreamData())) 48 self.stream.write(data) 59 if isinstance(packet, (str, unicode)): 60 streamdata = packet + self.delimiter 61 else: 62 streamdata = ''.join((packet.GetStreamHeader(), self.delimiter, packet.GetStreamData())) 63 self.log.debug('Sent %d bytes', len(streamdata)) 64 self.stream.write(streamdata) 49 65 50 66 def OnRecvStreamData(self, streamdata): 51 if self.data: self.data += streamdata 52 else: self.data = streamdata 67 self.log.debug('Received %d bytes', len(streamdata)) 68 if self.data: 69 self.data += streamdata 70 else: 71 self.data = streamdata 53 72 54 if self.currentpacket is None: 55 try: 56 # Try to seperate the information packet from the data packet 57 info, self.data = self.data.split(self.delimiter, 1) 58 except ValueError: 59 pass # We don't have a complete info packet yet... 73 while self.data: 74 # While there is still data to be processed 75 if self.currentpacket is None: 76 try: 77 # Try to seperate the information packet from the data packet 78 info, self.data = self.data.split(self.delimiter, 1) 79 except ValueError: 80 # We don't have a complete info packet yet. 81 # Break out of the while self.data loop 82 break 83 else: 84 # We now have our information packet in string form 85 try: 86 # Build the packet from the string 87 self.currentpacket = self.packetbuilder.BuildPacket(info) 88 if self.currentpacket is None: 89 # We expected a packet, so not getting one is an error 90 self.StreamError('Incomplete XML header') 91 else: 92 # Good... send the rest of the data as potential stream data 93 self.data = self.currentpacket.OnStreamData(self.data, self._OnPacketComplete) 94 except Exception, e: 95 # Something happened, report to the client 96 self.StreamError('%s: %s' % (e.__class__.__name__, str(e))) 97 self.log.error(e) 60 98 else: 61 # We now have our information packet... we can figure out what we 62 # are supposed to do with the content stream now 63 try: 64 self.currentpacket = self._BuildPacket(info) 65 if self.currentpacket is None: 66 self.OnStreamError('Incomplete XML Header:\n' + info) 67 else: 68 self.data = self.currentpacket.OnStreamData(self.data, self._OnPacketComplete) 69 except Exception, e: 70 self.OnStreamError(e) 71 else: 72 self.data = self.currentpacket.OnStreamData(self.data, self._OnPacketComplete) 99 self.data = self.currentpacket.OnStreamData(self.data, self._OnPacketComplete) 100 101 102 def StreamError(self, error='Unknown Error', errortype='stream', namespace=None): 103 if namespace is None: 104 try: 105 namespace = self.packetbuilder.DefaultNamespace 106 except AttributeError: 107 namespace = StandardStreamPacketBuilder.DefaultNamespace 108 namespace = 'xmlns=%s' % (xmlquoteattr(namespace),) 109 110 if errortype is not None: 111 errortype = 'type=%s' % (xmlquoteattr(errortype),) 112 else: errortype = '' 113 114 error = xmlescape(error) 115 116 self.log.info('Stream error from client connection. Shutting down.') 117 self.stream.write('''<error %s %s>%s</error>%s''' % (namespace, errortype, error, self.delimiter)) 118 self.stream.shutdown() 119 120 def OnPacketComplete(self, packet): 121 pass 122 123 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 124 #~ Protected Methods 125 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 73 126 74 127 def _OnPacketComplete(self, packet): … … 76 129 self.OnPacketComplete(packet) 77 130 78 def OnPacketComplete(self, packet):79 pass80 81 def OnStreamError(self, error=None):82 self.stream.write('''<error xmlns='%s'>%s</error>%s''' % (StandardStreamPacketBuilder.DefaultNamespace, xmlescape(str(error or 'Unknown')), self.delimiter))83 self.stream.shutdown()84 85 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~86 #~ Protected Methods87 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~88 89 def _BuildPacket(self, info):90 try:91 packetbuilder = self.packetbuilder92 except AttributeError:93 packetbuilder = self.packetbuilder = StandardStreamPacketBuilder()94 return self.packetbuilder.BuildPacket(info)95
