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