def callback(_): ctx.transport.write(str(command('QUIT'))) expect = range(200, 300) def callback(recv): try: replyLine = rfc5321.replyLine.match(recv, '( replyCode, textstring )') except ValueError: asdf.callback.insert(0, callback) return ctx.transport.protocol.dataReceived.shift().then(recv.__add__) ctx.recv = recv[len(replyLine):] result = reply(int(replyLine.replyCode), *map(str, replyLine.textstring)) if int(result) not in expect: raise result return result asdf = promise.promise().then(callback) return asdf(ctx.recv)
def callback(clone): def callback(recv): try: replyLine = rfc5321.replyLine.match(recv, '( replyCode, textstring )') except ValueError: asdf.callback.insert(0, callback) return ctx.transport.protocol.dataReceived.shift().then(recv.__add__) ctx.recv = recv[len(replyLine):] @clone.then def _(_): result = reply(int(replyLine.replyCode), *map(str, replyLine.textstring)) if int(result) not in expect: raise result return result return clone asdf = promise.promise().then(callback) return asdf(ctx.recv)
def __call__(ctx): transport = promise.promise() # Extend protocol.ClientFactory for .startedConnecting() @untwisted.call class factory(protocol.ClientFactory): class protocol: def __init__(ctx): ctx.connectionLost = promise.promise() ctx.dataReceived = promise.sequence() # .dataReceived() must return falsy: SelectReactor._doReadOrWrite() __call__ = ctx.dataReceived.__call__ @untwisted.partial(setattr, ctx.dataReceived, '__call__') def _(*args, **kwds): __call__(*args, **kwds) makeConnection = transport type.__call__(ctx, host, port, factory, timeout, bindAddress, reactor).connect() return transport
def sdfg(callback): log.startLogging(sys.stdout) # Test complete whether success or exception callback().then(promise.promise()).then(lambda _: reactor.stop()) reactor.callLater(3, reactor.stop) reactor.run() reactor.__init__()
def cascade(ctx, asdf): parent = ctx.head ctx.head = result = promise.promise() parent.then(result.then(promise.promise())) @result.then def _(clone): try: parent.traceback = clone.traceback except AttributeError: pass parent.args = clone.args parent.kwds = clone.kwds return asdf(clone) return result
def __init__(ctx): ctx.connectionLost = promise.promise() ctx.dataReceived = promise.sequence() # .dataReceived() must return falsy: SelectReactor._doReadOrWrite() __call__ = ctx.dataReceived.__call__ @untwisted.partial(setattr, ctx.dataReceived, '__call__') def _(*args, **kwds): __call__(*args, **kwds)
def sdfg(cbl): log.startLogging(sys.stdout) for cursor in conn: cursor.execute('DELETE FROM address').execute('DELETE FROM message_id') # Test complete whether success or exception cbl().then(promise.promise()).then(lambda _: reactor.stop()) @untwisted.call @promise.resume def _(): while True: ok(False, (yield listen())) reactor.callLater(2, reactor.stop) reactor.run()
def command(ctx): def callback(recv): try: result, ctx.recv = recv.split('\r\n', 1) except ValueError: asdf.callback.insert(0, callback) return ctx.transport.protocol.dataReceived.shift().then(recv.__add__) result = command(result) return result asdf = promise.promise().then(callback) return asdf(ctx.recv)
def callback(recv): try: replyLine = rfc5321.replyLine.match(recv, '( replyCode, textstring )') except ValueError: asdf.callback.insert(0, callback) return ctx.ctx.transport.protocol.dataReceived.shift().then(recv.__add__) ctx.ctx.recv = recv[len(replyLine):] result = reply(int(replyLine.replyCode), *map(str, replyLine.textstring)) if int(result) not in expect: raise result ctx.ctx.transport.write(content) return promise.promise()(ctx.ctx.reply())
def __call__(ctx): transport = promise.promise() @untwisted.call class protocol: datagramReceived = promise.sequence() # Avoid AttributeError: protocol instance has no attribute 'doStop' def doStop(ctx): pass @transport.then @promise.resume def makeConnection(transport): nstHost = host try: try: transport.connect(host, port) except ValueError: # Avoid ImportError: cannot import name dns from untwisted import dns nstHost = (yield dns.lookup(host)).answer[0].address transport.connect(nstHost, port) # tcp.Connector calls socket.getservbyname() but .connect() doesn't : ( except TypeError: nstPort = socket.getservbyname(port, 'udp') # Avoid RuntimeError: already connected transport._connectedAddr = None transport.connect(nstHost, nstPort) raise StopIteration(transport) type.__call__(ctx, None, protocol).startListening() return transport
def startTls(transport): session = gnutls_session_t() gnutls_init(byref(session), GNUTLS_CLIENT) gnutls_priority_set_direct(session, 'PERFORMANCE:+ANON-DH', None) anoncred = gnutls_anon_client_credentials_t() gnutls_anon_allocate_client_credentials(byref(anoncred)) gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred) gnutls_transport_set_ptr(session, transport.socket.fileno()) def callback(): try: gnutls_handshake(session) except OperationWouldBlock: return del transport.doRead @untwisted.partial(setattr, transport.socket, 'recv') def _(size): data = create_string_buffer(size) size = gnutls_record_recv(session, data, size) return data[:size] transport.socket.send = lambda data: gnutls_record_send(session, str(data), len(data)) asdf(None) asdf = promise.promise() transport.doRead = callback callback() return asdf
def __call__(ctx): transport = promise.promise() @untwisted.call class protocol: datagramReceived = promise.sequence() # Avoid AttributeError: protocol instance has no attribute 'doStop' def doStop(ctx): pass makeConnection = transport try: type.__call__(ctx, port, protocol, interface).startListening() # tcp.Connector calls socket.getservbyname() but udp.Port doesn't : ( except TypeError: nstPort = socket.getservbyname(port, 'udp') type.__call__(ctx, nstPort, protocol, interface).startListening() return transport
def _(_): ctx.ctx.transport.write(content) return promise.promise()(ctx.ctx.reply())
class client: class __metaclass__(type): @promise.resume def __call__(ctx, transport): ctx = type.__call__(ctx, transport) # Greeting yield ctx.reply() try: yield ctx.ehlo() except reply as e: if int(e) not in (500, 502): raise yield ctx.helo() while True: try: yield ctx.mail() except StopIteration: break #return ... raise StopIteration(ctx.quit()) recv = '' def __init__(ctx, transport): ctx.transport = transport head = promise.promise()(None) def cascade(ctx, asdf): parent = ctx.head ctx.head = result = promise.promise() parent.then(result.then(promise.promise())) @result.then def _(clone): try: parent.traceback = clone.traceback except AttributeError: pass parent.args = clone.args parent.kwds = clone.kwds return asdf(clone) return result # Since some servers may generate other replies under special circumstances, # and to allow for future extension, SMTP clients SHOULD, when possible, # interpret only the first digit of the reply and MUST be prepared to deal # with unrecognized reply codes by interpreting the first digit only def reply(ctx, expect=range(200, 300)): def callback(clone): def callback(recv): try: replyLine = rfc5321.replyLine.match(recv, '( replyCode, textstring )') except ValueError: asdf.callback.insert(0, callback) return ctx.transport.protocol.dataReceived.shift().then(recv.__add__) ctx.recv = recv[len(replyLine):] @clone.then def _(_): result = reply(int(replyLine.replyCode), *map(str, replyLine.textstring)) if int(result) not in expect: raise result return result return clone asdf = promise.promise().then(callback) return asdf(ctx.recv) return ctx.cascade(callback) def ehlo(ctx): ctx.transport.write(str(command('EHLO', domain))) return ctx.reply() def helo(ctx): ctx.transport.write(str(command('HELO', domain))) return ctx.reply() class mail: class __metaclass__(type): __get__ = untwisted.ctxual @promise.resume def __call__(ctx): ctx = type.__call__(ctx) result = yield ctx.sender() if not isinstance(result, reply): yield ctx.mail(result) result = yield ctx.recipient() if not isinstance(result, reply): yield ctx.rcpt(result) while True: try: result = yield ctx.recipient() except StopIteration: break if not isinstance(result, reply): yield ctx.rcpt(result) result = yield ctx.content() if not isinstance(result, reply): #return ... raise StopIteration((yield ctx.data(result))) #return ... raise StopIteration(result) def mail(ctx, sender): #ctx.ctx.transport.write(str(command('MAIL FROM:<{}>'.format(sender)))) ctx.ctx.transport.write(str(command('MAIL FROM:<{0}>'.format(sender)))) return ctx.ctx.reply() def sender(ctx): raise NotImplementedError def rcpt(ctx, recipient): #ctx.ctx.transport.write(str(command('RCPT TO:<{}>'.format(recipient)))) ctx.ctx.transport.write(str(command('RCPT TO:<{0}>'.format(recipient)))) return ctx.ctx.reply() def recipient(ctx): raise NotImplementedError # Aesthetics : ( DATA involves two replies, and we may need to distinguish # because only if the second reply is an error is the transaction complete. # Also the first reply must be received before more commands can be issued, # but the second reply can start a pipeline command group. Don't want to # split .data() into two methods because they're *always* called together. # So far no need for first reply value (it should always be 354 unless it's # an error) - just whether it's an error, and when it's received. So # .data() returns a promise that's fulfilled when the first reply is # received. If the first reply isn't an error, then it's fulfilled with # another promise, which is fulfilled when the second reply is received def data(ctx, content): ctx.ctx.transport.write(str(command('DATA'))) # Since some servers may generate other replies under special # circumstances, and to allow for future extension, SMTP clients SHOULD, # when possible, interpret only the first digit of the reply and MUST be # prepared to deal with unrecognized reply codes by interpreting the # first digit only result = ctx.ctx.reply(range(300, 400)) # Before sending a line of mail text, the SMTP client checks the first # character of the line. If it is a period, one additional period is # inserted at the beginning of the line # Lookbehind requires fixed width pattern content = re.sub('(^|\r\n)\.', '\\1..', content) # An extra <CRLF> MUST NOT be added, as that would cause an empty line to # be added to the message. The only exception to this rule would arise # if the message body were passed to the originating SMTP-sender with a # final "line" that did not end in <CRLF>; in that case, the originating # SMTP system MUST either reject the message as invalid or add <CRLF> in # order to have the receiving SMTP server recognize the "end of data" # condition if '\r\n' != content[-2:]: content += '\r\n' content += '.\r\n' @result.then def _(_): ctx.ctx.transport.write(content) return promise.promise()(ctx.ctx.reply()) return result def content(ctx): raise NotImplementedError def rset(ctx): ctx.transport.write(str(command('RSET'))) return ctx.reply() def quit(ctx): ctx.transport.write(str(command('QUIT'))) return ctx.reply()
def timeout(secs, *args, **kwds): ctx = promise.promise() reactor.callLater(secs, untwisted.partial(ctx, *args or (None,), **kwds)) return ctx