Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.80 KB | None | 0 0
  1. import os
  2. import platform
  3. import shlex
  4. import struct
  5. import subprocess
  6. from threading import Lock
  7.  
  8. def get_terminal_size():
  9. current_os = platform.system()
  10. tuple_xy = None
  11. if current_os == 'Windows':
  12. tuple_xy = _get_terminal_size_windows()
  13. if tuple_xy is None:
  14. tuple_xy = _get_terminal_size_tput()
  15. # needed for window's python in cygwin's xterm!
  16. if current_os in ['Linux', 'Darwin'] or current_os.startswith('CYGWIN'):
  17. tuple_xy = _get_terminal_size_linux()
  18. if tuple_xy is None:
  19. "default"
  20. tuple_xy = (80, 25) # default value
  21. return tuple_xy
  22.  
  23.  
  24. def _get_terminal_size_windows():
  25. try:
  26. from ctypes import windll, create_string_buffer
  27. # stdin handle is -10
  28. # stdout handle is -11
  29. # stderr handle is -12
  30. h = windll.kernel32.GetStdHandle(-12)
  31. csbi = create_string_buffer(22)
  32. res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
  33. if res:
  34. (bufx, bufy, curx, cury, wattr,
  35. left, top, right, bottom,
  36. maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
  37. sizex = right - left + 1
  38. sizey = bottom - top + 1
  39. return sizex, sizey
  40. except:
  41. pass
  42.  
  43.  
  44. def _get_terminal_size_tput():
  45. try:
  46. cols = int(subprocess.check_call(shlex.split('tput cols')))
  47. rows = int(subprocess.check_call(shlex.split('tput lines')))
  48. return cols, rows
  49. except:
  50. pass
  51.  
  52.  
  53. def _get_terminal_size_linux():
  54. def ioctl_GWINSZ(fd):
  55. try:
  56. import fcntl
  57. import termios
  58. cr = struct.unpack('hh',
  59. fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
  60. return cr
  61. except:
  62. pass
  63.  
  64. cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
  65. if not cr:
  66. try:
  67. fd = os.open(os.ctermid(), os.O_RDONLY)
  68. cr = ioctl_GWINSZ(fd)
  69. os.close(fd)
  70. except:
  71. pass
  72. if not cr:
  73. try:
  74. cr = (os.environ['LINES'], os.environ['COLUMNS'])
  75. except:
  76. return None
  77. return int(cr[1]), int(cr[0])
  78.  
  79.  
  80. class Progressbar:
  81. WIDTH = 50
  82. TEMPLATE = "{bar} | {pos}/{max} - {msg}"
  83. CHARS = ("[", "▏▎▍▌▋▊▉█", " ", "]")
  84.  
  85. def __init__(self, max):
  86. self.lock = Lock()
  87. self.max = max
  88. self.current = 0
  89. self.twidth = get_terminal_size()[0] - 1
  90. self.prev_msg = ""
  91.  
  92. def log(self, msg):
  93. """ Safely print full-length message """
  94. with self.lock:
  95. if len(msg) < self.twidth:
  96. msg += " " * (self.twidth - len(msg))
  97. print(msg)
  98. self.dump(self.prev_msg)
  99.  
  100. def inc(self, n=1, msg=""):
  101. with self.lock:
  102. self.current += n
  103. self.dump(msg or self.prev_msg)
  104. if msg:
  105. self.prev_msg = msg
  106.  
  107. def reset(self, max=0):
  108. with self.lock:
  109. self.current = 0
  110. self.max = max
  111.  
  112. def dump(self, msg=""):
  113. cnt = 0 if self.max == 0 else round(self.current / self.max * (self.WIDTH * len(self.CHARS[1])))
  114. r = cnt % len(self.CHARS[1])
  115. cnt //= len(self.CHARS[1])
  116. bar = self.CHARS[0] + self.CHARS[1][-1] * (cnt - 1) + self.CHARS[1][r]\
  117. + self.CHARS[2] * (self.WIDTH - cnt) + self.CHARS[3]
  118. if msg:
  119. self.prev_msg = msg
  120. else:
  121. msg = self.prev_msg
  122. t = self.TEMPLATE.format(bar=bar, pos=self.current, max=self.max,
  123. percent=self.current / self.max * 100,
  124. msg=msg)
  125. if len(t) >= self.twidth:
  126. t = t[:self.twidth][:-3] + "..."
  127. elif len(t) < self.twidth:
  128. t += " " * (self.twidth - len(t))
  129. print(t, end="\r")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement