PageRenderTime 13ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/examples/telnet.py

https://bitbucket.org/prologic/circuits/
Python | 172 lines | 88 code | 42 blank | 42 comment | 13 complexity | 5592be405552cbfe8565c79048a02640 MD5 | raw file
  1#!/usr/bin/env python
  2# -*- coding: utf-8 -*-
  3
  4
  5"""Telnet Example
  6
  7A basic telnet-like clone that connects to remote hosts
  8via tcp and allows the user to send data to the remote
  9server.
 10
 11This example demonstrates:
 12    * Basic Component creation.
 13    * Basic Event handling.
 14    * Basiv Networking
 15    * Basic Request/Response Networking
 16
 17This example makes use of:
 18    * Component
 19    * Event
 20    * net.sockets.TCPClient
 21"""
 22
 23
 24from __future__ import print_function
 25
 26import os
 27from optparse import OptionParser
 28
 29
 30import circuits
 31from circuits.io import stdin
 32from circuits.tools import graph
 33from circuits import handler, Component
 34from circuits.net.events import connect, write
 35from circuits.net.sockets import TCPClient, UNIXClient, UDPClient
 36
 37
 38USAGE = "%prog [options] host [port]"
 39VERSION = "%prog v" + circuits.__version__
 40
 41
 42def parse_options():
 43    parser = OptionParser(usage=USAGE, version=VERSION)
 44
 45    parser.add_option(
 46        "-u", "--udp",
 47        action="store_true", default=False, dest="udp",
 48        help="Use UDP transport",
 49    )
 50
 51    parser.add_option(
 52        "-v", "--verbose",
 53        action="store_true", default=False, dest="verbose",
 54        help="Enable verbose debugging",
 55    )
 56
 57    opts, args = parser.parse_args()
 58
 59    if len(args) < 1:
 60        parser.print_help()
 61        raise SystemExit(1)
 62
 63    return opts, args
 64
 65
 66class Telnet(Component):
 67
 68    # Define a separate channel for this component so we don't clash with
 69    # the ``read`` event of the ``stdin`` component.
 70    channel = "telnet"
 71
 72    def __init__(self, *args, **opts):
 73        super(Telnet, self).__init__()
 74
 75        self.args = args
 76        self.opts = opts
 77
 78        if len(args) == 1:
 79            if os.path.exists(args[0]):
 80                UNIXClient(channel=self.channel).register(self)
 81                host = dest = port = args[0]
 82                dest = (dest,)
 83            else:
 84                raise OSError("Path %s not found" % args[0])
 85        else:
 86            if not opts["udp"]:
 87                TCPClient(channel=self.channel).register(self)
 88            else:
 89                UDPClient(0, channel=self.channel).register(self)
 90
 91            host, port = args
 92            port = int(port)
 93            dest = host, port
 94
 95        self.host = host
 96        self.port = port
 97
 98        print("Trying %s ..." % host)
 99
100        if not opts["udp"]:
101            self.fire(connect(*dest))
102        else:
103            self.fire(write((host, port), b"\x00"))
104
105    def ready(self, *args):
106        graph(self.root)
107
108    def connected(self, host, port=None):
109        """connected Event Handler
110
111        This event is fired by the TCPClient Componentt to indicate a
112        successful connection.
113        """
114
115        print("connected to {0}".format(host))
116
117    def error(self, *args, **kwargs):
118        """error Event Handler
119
120        If any exception/error occurs in the system this event is triggered.
121        """
122
123        if len(args) == 3:
124            print("ERROR: {0}".format(args[1]))
125        else:
126            print("ERROR: {0}".format(args[0]))
127
128    def read(self, *args):
129        """read Event Handler
130
131        This event is fired by the underlying TCPClient Component when there
132        is data to be read from the connection.
133        """
134
135        if len(args) == 1:
136            data = args[0]
137        else:
138            peer, data = args
139
140        data = data.strip().decode("utf-8")
141
142        print(data)
143
144    # Setup an Event Handler for "read" events on the "stdin" channel.
145    @handler("read", channel="stdin")
146    def _on_stdin_read(self, data):
147        """read Event Handler for stdin
148
149        This event is triggered by the connected ``stdin`` component when
150        there is new data to be read in from standard input.
151        """
152
153        if not self.opts["udp"]:
154            self.fire(write(data))
155        else:
156            self.fire(write((self.host, self.port), data))
157
158
159def main():
160    opts, args = parse_options()
161
162    # Configure and "run" the System.
163    app = Telnet(*args, **opts.__dict__)
164    if opts.verbose:
165        from circuits import Debugger
166        Debugger().register(app)
167    stdin.register(app)
168    app.run()
169
170
171if __name__ == "__main__":
172    main()