Package pyfics :: Module protocols
[hide private]

Source Code for Module pyfics.protocols

 1  #!/usr/bin/env python 
 2  # -*- coding: utf-8 -*- 
 3  # vim: set sw=4 ts=4 sts=4 et tw=79 : 
 4  # Copyright 2006-2007 Ali Polatel <polatel@gmail.com> 
 5  # Distributed under the terms of the GNU General Public License v3 
 6   
 7  """Ics related protocols""" 
 8   
 9  from twisted.protocols.basic import LineOnlyReceiver 
10  from twisted.conch.telnet import TelnetProtocol 
11   
12 -class SmartLineReceiver(LineOnlyReceiver):
13 """A protocol that received only lines. Predefined prompts are considered 14 as lines. 15 16 @cvar delimiter: The line-ending delimiter to use. 17 Default is '\\r\\n'. 18 @type delimiter: C{string} 19 @cvar MAX_LENGTH: The maximum length of a line to allow (If a 20 sent line is longer than this, the connection is dropped). 21 Default is 16384. 22 @type MAX_LENGTH: C{int} 23 @cvar linealike: When L{SmartLineReceiver} receives data ending with one the 24 strings in this list, it'll add a delimiter at the end. 25 @type linealike: C{list} of C{string} 26 @cvar rmlinealike: When set to True, used strings from C{prompt} are removed. 27 @type rmlinealike: C{bool} 28 """ 29 linealike = [] 30 rmlinealike = True 31
32 - def dataReceived(self, data):
33 """Translates bytes into lines, and calls lineReceived. If data ends 34 with any string in C{prompt} add C{delimiter} at the end. If 35 C{promptremove} is True, remove the used string from C{prompt}.""" 36 for line in self.linealike: 37 if data.endswith(line): 38 data += self.delimiter 39 if self.rmlinealike: 40 self.linealike.remove(line) 41 break 42 return LineOnlyReceiver.dataReceived(self, data)
43
44 -class ChangingLineReceiver(SmartLineReceiver):
45 """A protocol that can receive only lines. It can handle data with 46 changing line delimiters. 47 48 @cvar delimiters: A list of delimiters. 49 @type delimiters: C{list} 50 """ 51 delimiters = [] 52
53 - def dataReceived(self, data):
54 for delim in self.delimiters: 55 if delim in data: 56 tail, delim, head = data.rpartition(delim) 57 SmartLineReceiver.dataReceived(self, head) 58 self.delimiter = delim 59 self.delimiters.remove(delim) 60 data = tail 61 return SmartLineReceiver.dataReceived(self, data)
62
63 -class IcsProtocol(ChangingLineReceiver, TelnetProtocol):
64 """Ics protocol implementation.""" 65 linealike = [ 'login: ', 'password: ' ]
66
67 -class IcsParsingProtocol(IcsProtocol):
68 """Ics protocol with parsing capabilities. This protocol can parse received 69 data with a specified parser. 70 71 @cvar parser: An object with a parse callable. When a line is 72 received, this objects parse callable is called with line as an 73 argument and the return value is sent to datagramReceived. 74 @type parser: C{object}""" 75 parser = None 76
77 - def lineReceived(self, line):
78 """Parse line and send to datagramReceived.""" 79 datagram = self.parser.parse(line) 80 self.datagramReceived(datagram)
81
82 - def datagramReceived(self, datagram):
83 """Override this to do anything useful with datagrams.""" 84 raise NotImplementedError
85
86 -class InteractiveIcsParsingProtocol(IcsParsingProtocol):
87 """Ics protocol with interactive parsing capabilities. This protocol can 88 parse received data with a specified parser and provides socket interaction 89 for the parser. 90 91 @cvar server: This object can be used to provide useful information to the 92 parser for interaction like login and password etc. 93 @type server: anything""" 94 server = None 95
96 - def __init__(self):
97 self.parser.protocol = self
98