Ahoj, "stream" rikam instanci nejake tridy, ktera zpristupnuje metody read(), write(), readline(), flush() (stejne funkce jako u souboru) a ponekud divokou metodu has_data(timeout), ktera vrati, zda jsou k dispozici nejaka data pro cteni (a volitelne na ne bude cekat nejakou dobu).
Bez problemu mi funguje implementace pro sockety (TCPStream) a na Linuxu i pro procesy (ProcessStream) - poll() na win32 funguje jenom na sockety a ne na pipes. Problem je, ze pro svuj IMAP parser potrebuju funkci starttls(), ktera nejak realizuje SSL/TLS handshake po jiz otevrenem spojeni (tady se muzu omezit jenom na TCP sockety, STARTTLS pres pipe nutne nepotrebuju) a dale jiz data bezi sifrovane. To samotne neni problem, smtplib dela to same, jenomze podle manualu jsem v zadne SSL/TLS knihovne nenasel zadny ekvivalent funkce, ktera by mi rekla, jestli muzu ze siforvaneho streamu cist bez blokovani. select()/poll() na socket, po kterem tecou sifrovana data, nema smysl, protoze ta data mohou byt rezie SSL. Vim, ze Twisted by neco takoveho mel umet, jenomze mi to prijde jako takovy kanon na vrabce. Pletu se? Napada me jedno pomerne hnusne reseni, cist do vlastniho bufferu a operace read(), readline(), write(), flush(), has_data() realizovat nad nim. Takhle to pry ([EMAIL PROTECTED]) resi prave Twisted pro pipes. Koukal jsem i na Polymer (IMAP klient, ktery by neco takoveho mel resit), nicmene ten se one funkci has_data() pomerne zdarile vyhyba. Pripominky jsou vitany, v priloze je relevantni kus meho kodu. -jkt -- cd /local/pub && more beer > /dev/mouth
class PollableStream:
"""Implementation of has_data() call for other streams"""
def has_data(self, timeout=None):
"""Check if we can read from socket without blocking"""
if timeout is None:
timeout = self.timeout
polled = self._r_poll.poll(timeout)
if len(polled):
result = polled[0][1]
if result & select.POLLIN:
if result & select.POLLHUP:
# closed connection, data still available
self.okay = False
return True
elif result & select.POLLHUP:
# connection is closed
time.sleep(timeout/1000.0)
self.okay = False
return False
else:
return False
else:
return False
class ProcessStream(PollableStream):
"""Streamable interface to local process.
Supports read(), readline(), write(), flush(), and has_data() methods. Doesn't
work on Win32 systems due to their lack of poll() functionality on pipes.
"""
def __init__(self, command, timeout=-1):
# disable buffering, otherwise readline() might read more than just
# one line and following poll() would say that there's nothing to read
(self._w, self._r) = os.popen2(command, bufsize=0)
self.read = self._r.read
self.readline = self._r.readline
self.write = self._w.write
self.flush = self._w.flush
self._r_poll = select.poll()
self._r_poll.register(self._r.fileno(), select.POLLIN | select.POLLHUP)
self.timeout = int(timeout)
self.okay = True
class TCPStream(PollableStream):
"""Streamed TCP/IP connection"""
# FIXME: support everything from ProcessStream
def __init__(self, host, port, timeout=-1):
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._sock.connect((host, port))
self._file = self._sock.makefile('rb', bufsize=0)
self._r_poll = select.poll()
self._r_poll.register(self._sock.fileno(), select.POLLIN | select.POLLHUP)
self.read = self._file.read
self.readline = self._file.readline
self.write = self._file.write
self.flush = self._file.flush
self.timeout = int(timeout)
self.okay = True
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Python mailing list [email protected] http://www.py.cz/mailman/listinfo/python
