-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprogress.py
More file actions
98 lines (81 loc) · 4.13 KB
/
Copy pathprogress.py
File metadata and controls
98 lines (81 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from pathlib import Path
import sys
import inspect
import multiprocessing as mp
# TODO : Write down the entire execution process based on the code below
# TODO : Create a sync function for the settrace()
"""
First it gets the starting and ending positions and labels them globally.
Then it will label the total lines by subtracting the last line by the first.
Next it will run a function that hashes through the total lines, and will create a dictionary; the key will be the line number and the value will be the percentage of completion. We will calculate this percentage based on the current line / by the total lines and then multiply by 100 to get the percentage.
Then it runs a loop using settrace that will execute the dictionary percentage based on the current line.
"""
class ProgressBar:
def __init__(self, name=""):
self.process_name = name
self.start_line = 0
self.end_line = 0
self.current_line = 0
self.total_lines = 0
self.bar_size = 40
self.hash_result = {}
self.last_percentage = -1
self.current_path = Path(sys.argv[0]).resolve()
self._stop_event = mp.Event()
def start(self):
# Gets starting line
caller_frame = inspect.currentframe().f_back
self.start_line = caller_frame.f_lineno if caller_frame else 0
if caller_frame:
self.current_path = Path(caller_frame.f_code.co_filename).resolve()
if not self.__get_last():
raise RuntimeError("exit method was not detected in this instance. QUITTING...")
self.total_lines = self.end_line - self.start_line - 1
if self.total_lines <= 0:
raise RuntimeError("no work was found between start() and end().")
self.hash_result = self.__hash_lines()
sys.settrace(self.__get_tracer)
if caller_frame:
caller_frame.f_trace = self.__get_tracer
def end(self):
sys.settrace(None) #Deactivate tracer
self.__display_progress(100)
print("\033[K")
# Handler function for display progress.
def __get_tracer(self, frame, event, arg):
# Only process when a new line is executed
if event == "line":
# Verify the execution is happening in the current script file
if Path(frame.f_code.co_filename).resolve() == self.current_path:
self.current_line = frame.f_lineno
# Prevent crashing on the .end() line itself or trailing lines
if self.current_line in self.hash_result:
percentage = self.hash_result[self.current_line]
if percentage > self.last_percentage:
self.last_percentage = percentage
self.__display_progress(percentage)
return self.__get_tracer # Return itself to keep tracing active
def __get_last(self):
with open(self.current_path, 'r') as current_file:
stop_marker = ".end()"
for line_num, line in enumerate(current_file, start=1):
if line_num < self.start_line:
continue
if stop_marker in line:
# Assigns line number as value of end_line and returns a happy return code
self.end_line = line_num
return True
# If no end line
return False
def __display_progress(self, current_percentage):
current_amount = int(self.bar_size * current_percentage / 100)
whitespace = self.bar_size - current_amount
progress = "[" + "#" * current_amount + "-" * whitespace + "]"
print(f"\r\033[K{progress}: {self.process_name} - {current_percentage:.0f}%", end="", flush=True)
def __hash_lines(self):
# This function will hash through the total lines and create a dictionary with line number as key and percentage of completion as value
progress_dict = {}
for offset, line_num in enumerate(range(self.start_line + 1, self.end_line)):
percentage = offset / (self.total_lines - 1) * 100 if self.total_lines > 1 else 100
progress_dict[line_num] = percentage
return progress_dict