nercone-modern 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ Metadata-Version: 2.3
2
+ Name: nercone-modern
3
+ Version: 1.0.0
4
+ Summary: Nercone Modern is a simple package for logging and progress bar and More!
5
+ Author: Nercone
6
+ Author-email: Nercone <nercone@diamondgotcat.net>
7
+ License: MIT
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.6
12
+ Project-URL: Homepage, https://github.com/DiamondGotCat/nercone-modern
13
+ Description-Content-Type: text/markdown
14
+
15
+ # nercone-modern
16
+ Modern Logging and Progress Bar Library
@@ -0,0 +1,2 @@
1
+ # nercone-modern
2
+ Modern Logging and Progress Bar Library
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.9.5,<0.10.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "nercone-modern"
7
+ version = "1.0.0"
8
+ description = "Nercone Modern is a simple package for logging and progress bar and More!"
9
+ readme = { file = "README.md", content-type = "text/markdown" }
10
+ authors = [
11
+ { name = "Nercone", email = "nercone@diamondgotcat.net" }
12
+ ]
13
+ license = { text = "MIT" }
14
+ requires-python = ">=3.6"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent"
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/DiamondGotCat/nercone-modern"
23
+
24
+ [tool.setuptools.packages.find]
25
+ where = ["."]
@@ -0,0 +1,30 @@
1
+ import sys
2
+
3
+ ModernLoggingLevels = ["DEBUG", "INFO", "WARN", "ERROR", "CRITICAL"]
4
+ MAX_LOG_LEVEL_WIDTH = max(len(level) for level in ModernLoggingLevels)
5
+
6
+ class ModernLogging:
7
+ def __init__(self, process_name):
8
+ self.process_name = process_name
9
+
10
+ def log(self, message, level="INFO"):
11
+ level_text = level.strip().upper()
12
+ if level_text in ["D", "DEBUG"]:
13
+ print(self._make(message, level="DEBUG", color=35))
14
+ elif level_text in ["I", "INFO", "INFORMATION"]:
15
+ print(self._make(message, level="INFO", color=34))
16
+ elif level_text in ["W", "WARN", "WARNING"]:
17
+ print(self._make(message, level="WARN", color=33))
18
+ elif level_text in ["E", "ERROR"]:
19
+ print(self._make(message, level="ERROR", color=31))
20
+ elif level_text in ["C", "CRITICAL"]:
21
+ print(self._make(message, level="CRITICAL", color=31))
22
+ else:
23
+ print(self._make(message, level=level, color=34))
24
+
25
+ def _make(self, message, level="INFO", color=34):
26
+ padded_level = level.ljust(max(MAX_LOG_LEVEL_WIDTH, len(level)))
27
+ return f"{self.process_name} {self._color(color)}{padded_level} | {self._color(0)}{message}"
28
+
29
+ def _color(self, color_code):
30
+ return f"\033[{color_code}m"
@@ -0,0 +1,209 @@
1
+ import sys
2
+ import threading
3
+ import time
4
+
5
+ class ModernProgressBar:
6
+ _active_bars = []
7
+ _last_rendered = False
8
+ _lock = threading.RLock()
9
+
10
+ def __init__(self, total, process_name, process_color, spinner_mode=True):
11
+ self.total = total
12
+ self.spinner_mode = spinner_mode
13
+ self.current = 0
14
+ self.process_name = process_name.strip()
15
+ self.process_color = process_color
16
+ self.index = len(ModernProgressBar._active_bars)
17
+ ModernProgressBar._active_bars.append(self)
18
+ self.log_lines = 0
19
+ self.step = 0
20
+ self.spinner_step = 0
21
+ self.message = "No Message"
22
+ self._spinner_thread = None
23
+ self._spinner_stop_event = threading.Event()
24
+ self._spinner_ready = False
25
+ self._initial_render()
26
+
27
+ def _initial_render(self):
28
+ print()
29
+
30
+ def spinner(self, enabled: bool = True):
31
+ if self.spinner_mode == enabled:
32
+ return
33
+ self.spinner_mode = enabled
34
+ if not self._spinner_ready:
35
+ self._render(advance_spinner=False)
36
+ return
37
+ if enabled:
38
+ self._start_spinner_thread_if_needed()
39
+ else:
40
+ self._stop_spinner_thread()
41
+ self._render(advance_spinner=False)
42
+
43
+ def spin_start(self):
44
+ if self._spinner_ready and self.spinner_mode:
45
+ return
46
+ self._spinner_ready = True
47
+ self.spinner_mode = True
48
+ self.spinner_step = 0
49
+ self._start_spinner_thread_if_needed()
50
+ self._render(advance_spinner=False)
51
+
52
+ def setMessage(self, message):
53
+ self.message = message
54
+
55
+ def start(self):
56
+ self._render(advance_spinner=False)
57
+ self._start_spinner_thread_if_needed()
58
+
59
+ def update(self, amount=1):
60
+ if self._should_spin():
61
+ self._render(advance_spinner=False)
62
+ return
63
+ self.current += amount
64
+ if self.current > self.total:
65
+ self.current = self.total
66
+ self._render(advance_spinner=False)
67
+
68
+ def finish(self):
69
+ self.current = self.total
70
+ self.spinner_mode = False
71
+ self._spinner_ready = False
72
+ self._stop_spinner_thread()
73
+ self._render(final=True, advance_spinner=False)
74
+
75
+ def makeModernLogging(self, process_name):
76
+ from .ModernLogging import ModernLogging
77
+ return ModernLogging(process_name)
78
+
79
+ def logging(self, message, level="INFO", modernLogging=None):
80
+ with ModernProgressBar._lock:
81
+ self.log_lines = 0
82
+ if modernLogging is None:
83
+ modernLogging = self.makeModernLogging(self.process_name)
84
+ result = modernLogging._make(message, level, self.process_color)
85
+ if self.log_lines > 0:
86
+ move_up = self.log_lines
87
+ else:
88
+ move_up = len(ModernProgressBar._active_bars) - self.index
89
+ sys.stdout.write(f"\033[{move_up}A")
90
+ sys.stdout.write("\033[K")
91
+ print(result)
92
+ self.log_lines += 1
93
+ self._render(advance_spinner=False)
94
+
95
+ def _start_spinner_thread_if_needed(self):
96
+ if not self._should_spin():
97
+ return
98
+ if self._spinner_thread and self._spinner_thread.is_alive():
99
+ return
100
+ self._spinner_stop_event = threading.Event()
101
+ self._spinner_thread = threading.Thread(target=self._spinner_worker, daemon=True)
102
+ self._spinner_thread.start()
103
+
104
+ def _stop_spinner_thread(self):
105
+ if self._spinner_thread and self._spinner_thread.is_alive():
106
+ self._spinner_stop_event.set()
107
+ self._spinner_thread.join()
108
+ self._spinner_thread = None
109
+
110
+ def _spinner_worker(self):
111
+ while not self._spinner_stop_event.wait(0.05):
112
+ if not self._should_spin():
113
+ continue
114
+ self._render()
115
+
116
+ def _render(self, final=False, advance_spinner=True):
117
+ with ModernProgressBar._lock:
118
+ progress = self.current / self.total if self.total else 0
119
+ bar = self._progress_bar(progress, advance_spinner=advance_spinner and self._should_spin())
120
+ percentage_value = int(round(min(max(progress, 0), 1) * 100))
121
+ percentage = f"{percentage_value:3d}%"
122
+ total_width = max(len(str(self.total)), 1)
123
+ if final:
124
+ status = "(DONE)"
125
+ elif self.spinner_mode and self._spinner_ready:
126
+ status = "(RUNN)"
127
+ else:
128
+ status = f"({self.current:>{total_width}}/{self.total})"
129
+ line = f"({self._color(self.process_color)}{bar}{self._color('reset')}) {self.process_name} - {'....' if self.spinner_mode else percentage} {status} | {self.message}"
130
+ total_move_up = self.log_lines + (len(ModernProgressBar._active_bars) - self.index)
131
+ if total_move_up > 0:
132
+ sys.stdout.write(f"\033[{total_move_up}A")
133
+ sys.stdout.write("\r")
134
+ sys.stdout.write("\033[K")
135
+ sys.stdout.write(line)
136
+ sys.stdout.write("\n")
137
+ down_lines = max(total_move_up - 1, 0)
138
+ if down_lines > 0:
139
+ sys.stdout.write(f"\033[{down_lines}B")
140
+ sys.stdout.flush()
141
+
142
+ def _progress_bar(self, progress, advance_spinner=True):
143
+ bar_length = 20
144
+ if not self._should_spin():
145
+ empty_bar = "-"
146
+ if self.current == self.total:
147
+ center_bar = ""
148
+ else:
149
+ center_bar = "-"
150
+ filled_bar = "-"
151
+ if self.current <= 0 and not self._spinner_ready:
152
+ return f"{self._color('gray')}{empty_bar * (bar_length + 1)}"
153
+ if self.current == self.total:
154
+ filled_length = int(progress * bar_length) + 1
155
+ else:
156
+ filled_length = int(progress * bar_length)
157
+ return f"{self._color('blue')}{filled_bar * filled_length}{self._color('cyan')}{center_bar}{self._color('black')}{empty_bar * (bar_length - filled_length)}"
158
+ else:
159
+ if self.current <= 0 and not self._spinner_ready:
160
+ return f"{self._color('gray')}{'-' * (bar_length + 1)}"
161
+ spinner_symbol_length = 1
162
+ spinner_end_bar_length = bar_length - self.spinner_step
163
+ spinner_start_bar_length = bar_length - spinner_end_bar_length
164
+ if advance_spinner:
165
+ self.spinner_step = (self.spinner_step + 1) % (bar_length + 1)
166
+ return f"{self._color('black')}{'-' * spinner_start_bar_length}{self._color('blue')}{'-' * spinner_symbol_length}{self._color('black')}{'-' * spinner_end_bar_length}"
167
+
168
+ def _should_spin(self):
169
+ return self.spinner_mode and self._spinner_ready
170
+
171
+ def _color(self, color_name):
172
+ if color_name == "cyan":
173
+ return self._color_by_code(36)
174
+ elif color_name == "magenta":
175
+ return self._color_by_code(35)
176
+ elif color_name == "yellow":
177
+ return self._color_by_code(33)
178
+ elif color_name == "green":
179
+ return self._color_by_code(32)
180
+ elif color_name == "red":
181
+ return self._color_by_code(31)
182
+ elif color_name == "blue":
183
+ return self._color_by_code(34)
184
+ elif color_name == "white":
185
+ return self._color_by_code(37)
186
+ elif color_name == "black":
187
+ return self._color_by_code(30)
188
+ elif color_name in ("gray", "grey"):
189
+ return self._color_by_code(90)
190
+ elif color_name == "reset":
191
+ return self._color_by_code(0)
192
+ else:
193
+ return ""
194
+
195
+ def _color_by_code(self, color_code):
196
+ return f"\033[{color_code}m"
197
+
198
+ if __name__ == "__main__":
199
+ progress_bar = ModernProgressBar(1000, "Example Task", 31)
200
+ progress_bar.start()
201
+ progress_bar.busy()
202
+ for i in range(100):
203
+ progress_bar.update()
204
+ time.sleep(0.1)
205
+ progress_bar.notbusy()
206
+ for i in range(1000):
207
+ progress_bar.update()
208
+ time.sleep(0.1)
209
+ progress_bar.finish()
@@ -0,0 +1,17 @@
1
+ import sys
2
+
3
+ class NerconeModern:
4
+ def __init__(self):
5
+ pass
6
+
7
+ def color(self, color_code):
8
+ return f"\033[{color_code}m"
9
+
10
+ def modernLogging(self, process_name):
11
+ from .ModernLogging import ModernLogging
12
+ return ModernLogging(process_name)
13
+
14
+ def modernProgressBar(self, total: int, process_name: str, process_color: int = 32, spinner_mode: bool = False):
15
+ from .ModernProgressBar import ModernProgressBar
16
+ return ModernProgressBar(total, process_name, process_color, spinner_mode)
17
+
@@ -0,0 +1,34 @@
1
+ from nercone_modern import NerconeModern
2
+
3
+ if __name__ == "__main__":
4
+ import time
5
+
6
+ logger = NerconeModern().modernLogging("Main")
7
+ logger.log("This is a debug message", "DEBUG")
8
+ logger.log("This is a test message", "INFO")
9
+ logger.log("This is a warning message", "WARNING")
10
+ logger.log("This is an error message", "ERROR")
11
+ logger.log("This is an error message", "CRITICAL")
12
+
13
+ progress_bar1 = NerconeModern().modernProgressBar(total=100, process_name="Task 1", process_color=32, spinner_mode=False)
14
+ progress_bar1.setMessage("WAITING")
15
+ progress_bar2 = NerconeModern().modernProgressBar(total=200, process_name="Task 2", process_color=34, spinner_mode=True)
16
+ progress_bar2.setMessage("WAITING")
17
+
18
+ progress_bar1.start()
19
+ progress_bar2.start()
20
+
21
+ progress_bar1.setMessage("RUNNING")
22
+ for i in range(100):
23
+ time.sleep(0.05)
24
+ progress_bar1.update()
25
+ progress_bar1.setMessage("DONE")
26
+ progress_bar1.finish()
27
+
28
+ progress_bar2.spin_start()
29
+ progress_bar2.setMessage("RUNNING (BACKGROUND)")
30
+ for i in range(100):
31
+ time.sleep(0.05)
32
+ progress_bar2.update(2)
33
+ progress_bar2.setMessage("DONE")
34
+ progress_bar2.finish()