Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

155 Zeilen
3.7 KiB

  1. import curses
  2. import curses.wrapper
  3. from curses.ascii import isprint
  4. from twisted.internet import reactor
  5. class CursesStdIO():
  6. def __init__(self, stdscr, callback=None):
  7. self.statusText = "Synapse test app -"
  8. self.searchText = ''
  9. self.stdscr = stdscr
  10. self.logLine = ''
  11. self.callback = callback
  12. self._setup()
  13. def _setup(self):
  14. self.stdscr.nodelay(1) # Make non blocking
  15. self.rows, self.cols = self.stdscr.getmaxyx()
  16. self.lines = []
  17. curses.use_default_colors()
  18. self.paintStatus(self.statusText)
  19. self.stdscr.refresh()
  20. def set_callback(self, callback):
  21. self.callback = callback
  22. def fileno(self):
  23. """ We want to select on FD 0 """
  24. return 0
  25. def connectionLost(self, reason):
  26. self.close()
  27. def print_line(self, text):
  28. """ add a line to the internal list of lines"""
  29. self.lines.append(text)
  30. self.redraw()
  31. def print_log(self, text):
  32. self.logLine = text
  33. self.redraw()
  34. def redraw(self):
  35. """ method for redisplaying lines
  36. based on internal list of lines """
  37. self.stdscr.clear()
  38. self.paintStatus(self.statusText)
  39. i = 0
  40. index = len(self.lines) - 1
  41. while i < (self.rows - 3) and index >= 0:
  42. self.stdscr.addstr(self.rows - 3 - i, 0, self.lines[index],
  43. curses.A_NORMAL)
  44. i = i + 1
  45. index = index - 1
  46. self.printLogLine(self.logLine)
  47. self.stdscr.refresh()
  48. def paintStatus(self, text):
  49. if len(text) > self.cols:
  50. raise RuntimeError("TextTooLongError")
  51. self.stdscr.addstr(
  52. self.rows - 2, 0,
  53. text + ' ' * (self.cols - len(text)),
  54. curses.A_STANDOUT)
  55. def printLogLine(self, text):
  56. self.stdscr.addstr(
  57. 0, 0,
  58. text + ' ' * (self.cols - len(text)),
  59. curses.A_STANDOUT)
  60. def doRead(self):
  61. """ Input is ready! """
  62. curses.noecho()
  63. c = self.stdscr.getch() # read a character
  64. if c == curses.KEY_BACKSPACE:
  65. self.searchText = self.searchText[:-1]
  66. elif c == curses.KEY_ENTER or c == 10:
  67. text = self.searchText
  68. self.searchText = ''
  69. self.print_line(">> %s" % text)
  70. try:
  71. if self.callback:
  72. self.callback.on_line(text)
  73. except Exception as e:
  74. self.print_line(str(e))
  75. self.stdscr.refresh()
  76. elif isprint(c):
  77. if len(self.searchText) == self.cols - 2:
  78. return
  79. self.searchText = self.searchText + chr(c)
  80. self.stdscr.addstr(self.rows - 1, 0,
  81. self.searchText + (' ' * (
  82. self.cols - len(self.searchText) - 2)))
  83. self.paintStatus(self.statusText + ' %d' % len(self.searchText))
  84. self.stdscr.move(self.rows - 1, len(self.searchText))
  85. self.stdscr.refresh()
  86. def logPrefix(self):
  87. return "CursesStdIO"
  88. def close(self):
  89. """ clean up """
  90. curses.nocbreak()
  91. self.stdscr.keypad(0)
  92. curses.echo()
  93. curses.endwin()
  94. class Callback(object):
  95. def __init__(self, stdio):
  96. self.stdio = stdio
  97. def on_line(self, text):
  98. self.stdio.print_line(text)
  99. def main(stdscr):
  100. screen = CursesStdIO(stdscr) # create Screen object
  101. callback = Callback(screen)
  102. screen.set_callback(callback)
  103. stdscr.refresh()
  104. reactor.addReader(screen)
  105. reactor.run()
  106. screen.close()
  107. if __name__ == '__main__':
  108. curses.wrapper(main)