예제 #1
0
      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)
예제 #2
0
    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)
예제 #3
0
파일: tcp.py 프로젝트: jablko/untwisted
      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
예제 #4
0
            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
예제 #5
0
파일: __init__.py 프로젝트: jablko/mail
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__()
예제 #6
0
  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
예제 #7
0
파일: tcp.py 프로젝트: jablko/untwisted
      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)
예제 #8
0
            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)
예제 #9
0
파일: __init__.py 프로젝트: jablko/cookie
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()
예제 #10
0
  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)
예제 #11
0
          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())
예제 #12
0
      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
예제 #13
0
파일: tls.py 프로젝트: jablko/mail
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
예제 #14
0
      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
예제 #15
0
      def _(_):
        ctx.ctx.transport.write(content)

        return promise.promise()(ctx.ctx.reply())
예제 #16
0
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()
예제 #17
0
파일: __init__.py 프로젝트: jablko/cookie
def timeout(secs, *args, **kwds):
  ctx = promise.promise()

  reactor.callLater(secs, untwisted.partial(ctx, *args or (None,), **kwds))

  return ctx