1#!/usr/bin/env python
2"""
3A simple chat application over telnet.
4Everyone that connects is asked for his name, and then people can chat with
5each other.
6"""
7from __future__ import unicode_literals
8
9import logging
10import random
11
12from prompt_toolkit.contrib.telnet.server import TelnetServer
13from prompt_toolkit.eventloop import From, get_event_loop
14from prompt_toolkit.formatted_text import HTML
15from prompt_toolkit.shortcuts import clear, prompt
16
17# Set up logging
18logging.basicConfig()
19logging.getLogger().setLevel(logging.INFO)
20
21# List of connections.
22_connections = []
23_connection_to_color = {}
24
25
26COLORS = [
27    'ansired', 'ansigreen', 'ansiyellow', 'ansiblue', 'ansifuchsia',
28    'ansiturquoise', 'ansilightgray', 'ansidarkgray', 'ansidarkred',
29    'ansidarkgreen', 'ansibrown', 'ansidarkblue', 'ansipurple', 'ansiteal']
30
31
32def interact(connection):
33    write = connection.send
34
35    # When a client is connected, erase the screen from the client and say
36    # Hello.
37    clear()
38    write('Welcome to our chat application!\n')
39    write('All connected clients will receive what you say.\n')
40
41    name = yield From(prompt(message='Type your name: ', async_=True))
42
43    # Random color.
44    color = random.choice(COLORS)
45    _connection_to_color[connection] = color
46
47    # Send 'connected' message.
48    _send_to_everyone(connection, name, '(connected)', color)
49
50    # Prompt.
51    prompt_msg = HTML('<reverse fg="{}">[{}]</reverse> &gt; ').format(color, name)
52
53    _connections.append(connection)
54    try:
55        # Set Application.
56        while True:
57            try:
58                result = yield From(prompt(message=prompt_msg, async_=True))
59                _send_to_everyone(connection, name, result, color)
60            except KeyboardInterrupt:
61                pass
62    except EOFError:
63        _send_to_everyone(connection, name, '(leaving)', color)
64    finally:
65        _connections.remove(connection)
66
67
68def _send_to_everyone(sender_connection, name, message, color):
69    """
70    Send a message to all the clients.
71    """
72    for c in _connections:
73        if c != sender_connection:
74            c.send_above_prompt([
75                ('fg:' + color, '[%s]' % name),
76                ('', ' '),
77                ('fg:' + color, '%s\n' % message),
78            ])
79
80
81def main():
82    server = TelnetServer(interact=interact, port=2323)
83    server.start()
84    get_event_loop().run_forever()
85
86
87if __name__ == '__main__':
88    main()
89