Implemented basic CLI based on python curses.

parent a4eaec32
import curses
class ChatWindow:
def __init__(self, main, top, left, height, width):
# Reference to the main window
self.main = main
# Command bar position
self.top = top
self.left = left
self.height = height
self.width = width
# Initialise window
self.window = curses.newwin(height, width, top, left)
# True, if help screen is currently displayed.
self.displayed_help = False
def handle_close(self):
# If the help screen is currently displayed, hide it.
if self.displayed_help:
self.displayed_help = False
self.window.clear()
self.window.refresh()
else:
# Stop user input handler (which will exit the application).
self.main.quit()
def display_help(self):
if self.displayed_help:
return
self.displayed_help = True
self.window.clear()
help_text = 'Help screen\n' \
+ '\n' \
+ 'All commands listed below should be preceded by a slash:\n' \
+ '\n' \
+ ' Command\tDescription\n' \
+ ' close\t\tClose visible chat window (or this help screen).\n' \
+ ' help\t\tThis help page.\n' \
+ ' quit\t\tQuit this chat application (shortcut: ^c).\n' \
for i, line in enumerate(help_text.split('\n')):
self.window.addstr(i, 0, line)
self.window.refresh()
import curses
import sys
from chat_window import ChatWindow
from info_bar import InfoBar
from command_bar import CommandBar
class CLI:
"""
Command line interface based on the Curses library used for the chat
application. This chat application is a practical assignment for the
University of Amsterdam's course Telematica 2011.
"""
def __init__(self):
# Initialse the curses library
self.stdscr = curses.initscr()
# start_color() initializes eight basic colors (black, red, green,
# yellow, blue, magenta, cyan, and white), and two global variables in
# the curses module, COLORS and COLOR_PAIRS, containing the maximum
# number of colors and color-pairs the terminal can support. It also
# restores the colors on the terminal to the values they had when the
# terminal was just turned on.
self.color_count = curses.start_color()
curses.use_default_colors()
# Usually curses applications turn off automatic echoing of keys to the
# screen, in order to be able to read keys and only display them under
# certain circumstances.
curses.noecho()
# Applications will also commonly need to react to keys instantly,
# without requiring the Enter key to be pressed; this is called cbreak
# mode, as opposed to the usual buffered input mode.
curses.cbreak()
# Terminals usually return special keys, such as the cursor keys or
# navigation keys such as Page Up and Home, as a multibyte escape
# sequence. While you could write your application to expect such
# sequences and process them accordingly, curses can do it for you,
# returning a special value such as curses.KEY_LEFT. To get curses to do
# the job, you'll have to enable keypad mode.
self.stdscr.keypad(1)
# After setting nodelay(1), getch() for the window becomes non-blocking
# and returns curses.ERR (a value of -1) when no input is ready.
self.stdscr.nodelay(1)
# Initialise color scheme.
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
# Window composition.
self.init_windows()
# Enter the user input handler loop.
self.init_input_handler()
def init_windows(self):
"""
Initialise the window of this command line interface. The user interface
of this chat application consists of a main chat window, an optional
user list window and a command bar. The chat window does also view the
help screen, when the help screen is requested by the user.
"""
self.max_y, self.max_x = self.stdscr.getmaxyx()
self.stdscr.refresh()
# Initalise chat window.
self.chat_window = ChatWindow(self, 0, 0, self.max_y - 2, self.max_x)
# Info bar between chat window and command bar
self.info_bar = InfoBar(self, self.max_y - 2, 0, 1, self.max_x)
# Command bar at the bottom of the screen.
self.command_bar = CommandBar(self, self.max_y - 1, 0, 1, self.max_x)
# set cursor position to bottom of screen.
self.stdscr.move(self.max_y - 1, 0)
self.stdscr.refresh()
def init_input_handler(self):
while True:
# KeyboardInterrupt is raised when an user presses ^C. This
# try/except block will catch the exception and shutdown the
# application gracefully.
try:
c = self.stdscr.getch()
except KeyboardInterrupt:
self.quit()
if c != curses.ERR and self.command_bar.handle_input(c):
break
def quit(self):
# Reverse the curses-friendly terminal settings.
curses.nocbreak();
self.stdscr.keypad(0);
curses.echo()
# Restore the terminal to its original operating mode.
curses.endwin()
sys.exit(0)
def __del__(self):
import curses
# Reverse the curses-friendly terminal settings.
curses.nocbreak();
self.stdscr.keypad(0);
curses.echo()
# Restore the terminal to its original operating mode.
curses.endwin()
import curses
from curses.textpad import Textbox
class CommandBar:
def __init__(self, main, top, left, height, width):
# Reference to the main window
self.main = main
# Command bar position
self.top = top
self.left = left
self.height = height
self.width = width
# Initialise window and textbox
self.window = curses.newwin(height, width, top, left)
self.textbox = Textbox(self.window)
def handle_input(self, c):
#if c == ord('Q'):
# return True
#if c == ord('q'):
# return self.handle_quit()
#if c == ord('h'):
# self.display_help()
#elif c == curses.KEY_HOME:
# self.x = self.y = 0
#if 32 <= c <= 127:
# self.append_command(c)
#elif c == 10: # Enter key
# return self.execute_command()
self.append_command(c)
def append_command(self, c):
if not self.textbox.do_command(c):
self.execute_command()
self.window.refresh()
def execute_command(self, command=''):
if not command:
# Clear command bar, reset cursor and redraw the command bar.
command = self.textbox.gather()
self.window.deleteln()
self.window.move(0, 0)
# Handle the given/typed command.
self.handle_command(command)
def handle_command(self, command):
if not command:
return
if command[0] == '/':
cmd = command.split(' ', 1)[0][1:]
if cmd == 'help':
self.main.chat_window.display_help()
elif cmd == 'quit':
self.main.quit()
elif cmd == 'close':
self.main.chat_window.handle_close()
else:
pass
import curses
class InfoBar:
def __init__(self, main, top, left, height, width):
# Reference to the main window
self.main = main
# Command bar position
self.top = top
self.left = left
self.height = height
self.width = width
# Initialise window
self.window = curses.newwin(height, width, top, left)
# Display start message
start_message = 'Type "/connect HOST" to connect to a chat server' \
+ ' or "/help" for help.'
self.display(start_message)
def display(self, msg):
color_pair = curses.color_pair(1)
try:
self.window.addstr(0, 0, msg.ljust(self.width), color_pair)
except curses.error:
pass
self.window.refresh()
#!/usr/bin/env python
from cli import CLI
try:
cli = CLI()
except Exception, e:
curses.nocbreak();
curses.echo()
curses.endwin()
print 'Error:', e
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment