summary refs log tree commit diff
path: root/example/cursesio.py
diff options
context:
space:
mode:
authormatrix.org <matrix@matrix.org>2014-08-12 15:10:52 +0100
committermatrix.org <matrix@matrix.org>2014-08-12 15:10:52 +0100
commit4f475c7697722e946e39e42f38f3dd03a95d8765 (patch)
tree076d96d3809fb836c7245fd9f7960e7b75888a77 /example/cursesio.py
downloadsynapse-4f475c7697722e946e39e42f38f3dd03a95d8765.tar.xz
Reference Matrix Home Server
Diffstat (limited to 'example/cursesio.py')
-rw-r--r--example/cursesio.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/example/cursesio.py b/example/cursesio.py
new file mode 100644
index 0000000000..83b4a9f186
--- /dev/null
+++ b/example/cursesio.py
@@ -0,0 +1,154 @@
+import curses
+import curses.wrapper
+from curses.ascii import isprint
+
+from twisted.internet import reactor
+
+
+class CursesStdIO():
+    def __init__(self, stdscr, callback=None):
+        self.statusText = "Synapse test app -"
+        self.searchText = ''
+        self.stdscr = stdscr
+
+        self.logLine = ''
+
+        self.callback = callback
+
+        self._setup()
+
+    def _setup(self):
+        self.stdscr.nodelay(1)  # Make non blocking
+
+        self.rows, self.cols = self.stdscr.getmaxyx()
+        self.lines = []
+
+        curses.use_default_colors()
+
+        self.paintStatus(self.statusText)
+        self.stdscr.refresh()
+
+    def set_callback(self, callback):
+        self.callback = callback
+
+    def fileno(self):
+        """ We want to select on FD 0 """
+        return 0
+
+    def connectionLost(self, reason):
+        self.close()
+
+    def print_line(self, text):
+        """ add a line to the internal list of lines"""
+
+        self.lines.append(text)
+        self.redraw()
+
+    def print_log(self, text):
+        self.logLine = text
+        self.redraw()
+
+    def redraw(self):
+        """ method for redisplaying lines
+            based on internal list of lines """
+
+        self.stdscr.clear()
+        self.paintStatus(self.statusText)
+        i = 0
+        index = len(self.lines) - 1
+        while i < (self.rows - 3) and index >= 0:
+            self.stdscr.addstr(self.rows - 3 - i, 0, self.lines[index],
+                               curses.A_NORMAL)
+            i = i + 1
+            index = index - 1
+
+        self.printLogLine(self.logLine)
+
+        self.stdscr.refresh()
+
+    def paintStatus(self, text):
+        if len(text) > self.cols:
+            raise RuntimeError("TextTooLongError")
+
+        self.stdscr.addstr(
+            self.rows - 2, 0,
+            text + ' ' * (self.cols - len(text)),
+            curses.A_STANDOUT)
+
+    def printLogLine(self, text):
+        self.stdscr.addstr(
+            0, 0,
+            text + ' ' * (self.cols - len(text)),
+            curses.A_STANDOUT)
+
+    def doRead(self):
+        """ Input is ready! """
+        curses.noecho()
+        c = self.stdscr.getch()  # read a character
+
+        if c == curses.KEY_BACKSPACE:
+            self.searchText = self.searchText[:-1]
+
+        elif c == curses.KEY_ENTER or c == 10:
+            text = self.searchText
+            self.searchText = ''
+
+            self.print_line(">> %s" % text)
+
+            try:
+                if self.callback:
+                    self.callback.on_line(text)
+            except Exception as e:
+                self.print_line(str(e))
+
+            self.stdscr.refresh()
+
+        elif isprint(c):
+            if len(self.searchText) == self.cols - 2:
+                return
+            self.searchText = self.searchText + chr(c)
+
+        self.stdscr.addstr(self.rows - 1, 0,
+                           self.searchText + (' ' * (
+                           self.cols - len(self.searchText) - 2)))
+
+        self.paintStatus(self.statusText + ' %d' % len(self.searchText))
+        self.stdscr.move(self.rows - 1, len(self.searchText))
+        self.stdscr.refresh()
+
+    def logPrefix(self):
+        return "CursesStdIO"
+
+    def close(self):
+        """ clean up """
+
+        curses.nocbreak()
+        self.stdscr.keypad(0)
+        curses.echo()
+        curses.endwin()
+
+
+class Callback(object):
+
+    def __init__(self, stdio):
+        self.stdio = stdio
+
+    def on_line(self, text):
+        self.stdio.print_line(text)
+
+
+def main(stdscr):
+    screen = CursesStdIO(stdscr)   # create Screen object
+
+    callback = Callback(screen)
+
+    screen.set_callback(callback)
+
+    stdscr.refresh()
+    reactor.addReader(screen)
+    reactor.run()
+    screen.close()
+
+
+if __name__ == '__main__':
+    curses.wrapper(main)