client.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. """
  2. You don't really want to use this module. Try insults.py instead.
  3. """
  4. from __future__ import print_function
  5. from twisted.internet import protocol
  6. class InsultsClient(protocol.Protocol):
  7. escapeTimeout = 0.2
  8. def __init__(self):
  9. self.width = self.height = None
  10. self.xpos = self.ypos = 0
  11. self.commandQueue = []
  12. self.inEscape = ''
  13. def setSize(self, width, height):
  14. call = 0
  15. if self.width:
  16. call = 1
  17. self.width = width
  18. self.height = height
  19. if call:
  20. self.windowSizeChanged()
  21. def dataReceived(self, data):
  22. from twisted.internet import reactor
  23. for ch in data:
  24. if ch == '\x1b':
  25. if self.inEscape:
  26. self.keyReceived(ch)
  27. self.inEscape = ''
  28. else:
  29. self.inEscape = ch
  30. self.escapeCall = reactor.callLater(self.escapeTimeout,
  31. self.endEscape)
  32. elif ch in 'ABCD' and self.inEscape:
  33. self.inEscape = ''
  34. self.escapeCall.cancel()
  35. if ch == 'A':
  36. self.keyReceived('<Up>')
  37. elif ch == 'B':
  38. self.keyReceived('<Down>')
  39. elif ch == 'C':
  40. self.keyReceived('<Right>')
  41. elif ch == 'D':
  42. self.keyReceived('<Left>')
  43. elif self.inEscape:
  44. self.inEscape += ch
  45. else:
  46. self.keyReceived(ch)
  47. def endEscape(self):
  48. ch = self.inEscape
  49. self.inEscape = ''
  50. self.keyReceived(ch)
  51. def initScreen(self):
  52. self.transport.write('\x1b=\x1b[?1h')
  53. def gotoXY(self, x, y):
  54. """Go to a position on the screen.
  55. """
  56. self.xpos = x
  57. self.ypos = y
  58. self.commandQueue.append(('gotoxy', x, y))
  59. def writeCh(self, ch):
  60. """Write a character to the screen. If we're at the end of the row,
  61. ignore the write.
  62. """
  63. if self.xpos < self.width - 1:
  64. self.commandQueue.append(('write', ch))
  65. self.xpos += 1
  66. def writeStr(self, s):
  67. """Write a string to the screen. This does not wrap a the edge of the
  68. screen, and stops at \\r and \\n.
  69. """
  70. s = s[:self.width-self.xpos]
  71. if '\n' in s:
  72. s=s[:s.find('\n')]
  73. if '\r' in s:
  74. s=s[:s.find('\r')]
  75. self.commandQueue.append(('write', s))
  76. self.xpos += len(s)
  77. def eraseToLine(self):
  78. """Erase from the current position to the end of the line.
  79. """
  80. self.commandQueue.append(('eraseeol',))
  81. def eraseToScreen(self):
  82. """Erase from the current position to the end of the screen.
  83. """
  84. self.commandQueue.append(('eraseeos',))
  85. def clearScreen(self):
  86. """Clear the screen, and return the cursor to 0, 0.
  87. """
  88. self.commandQueue = [('cls',)]
  89. self.xpos = self.ypos = 0
  90. def setAttributes(self, *attrs):
  91. """Set the attributes for drawing on the screen.
  92. """
  93. self.commandQueue.append(('attributes', attrs))
  94. def refresh(self):
  95. """Redraw the screen.
  96. """
  97. redraw = ''
  98. for command in self.commandQueue:
  99. if command[0] == 'gotoxy':
  100. redraw += '\x1b[%i;%iH' % (command[2]+1, command[1]+1)
  101. elif command[0] == 'write':
  102. redraw += command[1]
  103. elif command[0] == 'eraseeol':
  104. redraw += '\x1b[0K'
  105. elif command[0] == 'eraseeos':
  106. redraw += '\x1b[OJ'
  107. elif command[0] == 'cls':
  108. redraw += '\x1b[H\x1b[J'
  109. elif command[0] == 'attributes':
  110. redraw += '\x1b[%sm' % ';'.join(map(str, command[1]))
  111. else:
  112. print(command)
  113. self.commandQueue = []
  114. self.transport.write(redraw)
  115. def windowSizeChanged(self):
  116. """Called when the size of the window changes.
  117. Might want to redraw the screen here, or something.
  118. """
  119. def keyReceived(self, key):
  120. """Called when the user hits a key.
  121. """