loader.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # load symbol from:
  2. # https://stackoverflow.com/questions/22029562/python-how-to-make-simple-animated-loading-while-process-is-running
  3. # imports
  4. from itertools import cycle
  5. from shutil import get_terminal_size
  6. from threading import Thread
  7. from time import sleep
  8. from termoutput import Printer
  9. class Loader:
  10. """Busy symbol.
  11. Can be called inside a context:
  12. with Loader("This take some Time..."):
  13. # do something
  14. pass
  15. """
  16. def __init__(self, chan, desc="Loading...", end='', timeout=0.1, mode='std1'):
  17. """
  18. A loader-like context manager
  19. Args:
  20. desc (str, optional): The loader's description. Defaults to "Loading...".
  21. end (str, optional): Final print. Defaults to "".
  22. timeout (float, optional): Sleep time between prints. Defaults to 0.1.
  23. """
  24. self.desc = desc
  25. self.end = end
  26. self.timeout = timeout
  27. self.channel = chan
  28. self._thread = Thread(target=self._animate, daemon=True)
  29. if mode == 'std1':
  30. self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
  31. elif mode == 'std2':
  32. self.steps = ["◜","◝","◞","◟"]
  33. elif mode == 'std3':
  34. self.steps = ["😐 ","😐 ","😮 ","😮 ","😦 ","😦 ","😧 ","😧 ","🤯 ","💥 ","✨ ","\u3000 ","\u3000 ","\u3000 "]
  35. elif mode == 'prog':
  36. self.steps = ["[∙∙∙]","[●∙∙]","[∙●∙]","[∙∙●]","[∙∙∙]"]
  37. self.done = False
  38. def start(self):
  39. self._thread.start()
  40. return self
  41. def _animate(self):
  42. for c in cycle(self.steps):
  43. if self.done:
  44. break
  45. Printer.print_loader(self.channel, f"\r\t{c} {self.desc} ")
  46. sleep(self.timeout)
  47. def __enter__(self):
  48. self.start()
  49. def stop(self):
  50. self.done = True
  51. cols = get_terminal_size((80, 20)).columns
  52. Printer.print_loader(self.channel, "\r" + " " * cols)
  53. if self.end != "":
  54. Printer.print_loader(self.channel, f"\r{self.end}")
  55. def __exit__(self, exc_type, exc_value, tb):
  56. # handle exceptions with those variables ^
  57. self.stop()