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

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Python mailing list
[email protected]
http://www.py.cz/mailman/listinfo/python

Odpovedet emailem