You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.9 KiB

4 years ago
  1. # Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. from __future__ import print_function
  15. HIDE_CURSOR = '\x1b[?25l'
  16. SHOW_CURSOR = '\x1b[?25h'
  17. class WriteMixin(object):
  18. hide_cursor = False
  19. def __init__(self, message=None, **kwargs):
  20. super(WriteMixin, self).__init__(**kwargs)
  21. self._width = 0
  22. if message:
  23. self.message = message
  24. if self.file and self.file.isatty():
  25. if self.hide_cursor:
  26. print(HIDE_CURSOR, end='', file=self.file)
  27. print(self.message, end='', file=self.file)
  28. self.file.flush()
  29. def write(self, s):
  30. if self.file and self.file.isatty():
  31. b = '\b' * self._width
  32. c = s.ljust(self._width)
  33. print(b + c, end='', file=self.file)
  34. self._width = max(self._width, len(s))
  35. self.file.flush()
  36. def finish(self):
  37. if self.file and self.file.isatty() and self.hide_cursor:
  38. print(SHOW_CURSOR, end='', file=self.file)
  39. class WritelnMixin(object):
  40. hide_cursor = False
  41. def __init__(self, message=None, **kwargs):
  42. super(WritelnMixin, self).__init__(**kwargs)
  43. if message:
  44. self.message = message
  45. if self.file and self.file.isatty() and self.hide_cursor:
  46. print(HIDE_CURSOR, end='', file=self.file)
  47. def clearln(self):
  48. if self.file and self.file.isatty():
  49. print('\r\x1b[K', end='', file=self.file)
  50. def writeln(self, line):
  51. if self.file and self.file.isatty():
  52. self.clearln()
  53. print(line, end='', file=self.file)
  54. self.file.flush()
  55. def finish(self):
  56. if self.file and self.file.isatty():
  57. print(file=self.file)
  58. if self.hide_cursor:
  59. print(SHOW_CURSOR, end='', file=self.file)
  60. from signal import signal, SIGINT
  61. from sys import exit
  62. class SigIntMixin(object):
  63. """Registers a signal handler that calls finish on SIGINT"""
  64. def __init__(self, *args, **kwargs):
  65. super(SigIntMixin, self).__init__(*args, **kwargs)
  66. signal(SIGINT, self._sigint_handler)
  67. def _sigint_handler(self, signum, frame):
  68. self.finish()
  69. exit(0)