nercone-modern 1.1.1__tar.gz → 1.2.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nercone-modern
3
- Version: 1.1.1
3
+ Version: 1.2.2
4
4
  Summary: Modern Logging and Progress Bar Library
5
5
  Author: Nercone
6
6
  Author-email: Nercone <nercone@diamondgotcat.net>
@@ -13,7 +13,7 @@ Project-URL: Homepage, https://github.com/DiamondGotCat/nercone-modern
13
13
  Description-Content-Type: text/markdown
14
14
 
15
15
 
16
- <img width="1920" alt="Nercone Modern" src="https://github.com/user-attachments/assets/803bbff3-44fd-4347-b2cd-08d8f0122ae8" />
16
+ <img width="1920" alt="Nercone Modern" src="https://github.com/user-attachments/assets/c92b0407-916f-46ec-9116-c3388b38c88c" />
17
17
 
18
18
  # nercone-modern
19
19
  Modern Logging and Progress Bar Library
@@ -39,20 +39,21 @@ pip3 install nercone-modern
39
39
  ## Usage
40
40
 
41
41
  ```python
42
- from nercone_modern import NerconeModern
42
+ from nercone_modern.logging import ModernLogging
43
+ from nercone_modern.progressbar import ModernProgressBar
43
44
  ```
44
45
 
45
46
  ### Logging
46
47
 
47
48
  ```python
48
- logger = NerconeModern().modernLogging(process_name="Main")
49
+ logger = ModernLogging("Main", display_level="DEBUG")
49
50
  logger.log("This is a test message", level="INFO")
50
51
  ```
51
52
 
52
53
  ### Progress Bar
53
54
 
54
55
  ```python
55
- progress_bar = NerconeModern().modernProgressBar(total=100, process_name="Task 1", process_color=32, spinner_mode=True)
56
+ progress_bar = ModernProgressBar(total=100, process_name="Task 1", spinner_mode=True)
56
57
  progress_bar.start()
57
58
 
58
59
  time.sleep(5)
@@ -1,5 +1,5 @@
1
1
 
2
- <img width="1920" alt="Nercone Modern" src="https://github.com/user-attachments/assets/803bbff3-44fd-4347-b2cd-08d8f0122ae8" />
2
+ <img width="1920" alt="Nercone Modern" src="https://github.com/user-attachments/assets/c92b0407-916f-46ec-9116-c3388b38c88c" />
3
3
 
4
4
  # nercone-modern
5
5
  Modern Logging and Progress Bar Library
@@ -25,20 +25,21 @@ pip3 install nercone-modern
25
25
  ## Usage
26
26
 
27
27
  ```python
28
- from nercone_modern import NerconeModern
28
+ from nercone_modern.logging import ModernLogging
29
+ from nercone_modern.progressbar import ModernProgressBar
29
30
  ```
30
31
 
31
32
  ### Logging
32
33
 
33
34
  ```python
34
- logger = NerconeModern().modernLogging(process_name="Main")
35
+ logger = ModernLogging("Main", display_level="DEBUG")
35
36
  logger.log("This is a test message", level="INFO")
36
37
  ```
37
38
 
38
39
  ### Progress Bar
39
40
 
40
41
  ```python
41
- progress_bar = NerconeModern().modernProgressBar(total=100, process_name="Task 1", process_color=32, spinner_mode=True)
42
+ progress_bar = ModernProgressBar(total=100, process_name="Task 1", spinner_mode=True)
42
43
  progress_bar.start()
43
44
 
44
45
  time.sleep(5)
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "nercone-modern"
7
- version = "1.1.1"
7
+ version = "1.2.2"
8
8
  description = "Modern Logging and Progress Bar Library"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  authors = [
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env python3
2
+
3
+ # -- nercone-modern --------------------------------------------- #
4
+ # __init__.py on nercone-modern #
5
+ # Made by DiamondGotCat, Licensed under MIT License #
6
+ # Copyright (c) 2025 DiamondGotCat #
7
+ # ---------------------------------------------- DiamondGotCat -- #
8
+
9
+ from .logging import ModernLogging
10
+ from .progressbar import ModernProgressBar
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env python3
2
+
3
+ # -- nercone-modern --------------------------------------------- #
4
+ # __main__.py on nercone-modern #
5
+ # Made by DiamondGotCat, Licensed under MIT License #
6
+ # Copyright (c) 2025 DiamondGotCat #
7
+ # ---------------------------------------------- DiamondGotCat -- #
8
+
9
+ import time
10
+ from nercone_modern.logging import ModernLogging
11
+ from nercone_modern.progressbar import ModernProgressBar
12
+
13
+ logger1 = ModernLogging("Main", display_level="DEBUG")
14
+ logger2 = ModernLogging("Sub", display_level="DEBUG")
15
+
16
+ try:
17
+ logger1.log("This is a debug message", "DEBUG")
18
+ logger1.log("This is a info message", "INFO")
19
+ logger1.log("This is a info message", "INFO")
20
+ logger1.log("This is a info message", "INFO")
21
+ logger2.log("This is an error message", "INFO")
22
+ logger1.log("This is a warning message", "WARNING")
23
+ logger1.log("This is an error message", "ERROR")
24
+ logger1.log("This is an critical error message", "CRITICAL")
25
+ prompt_result = logger1.prompt("This is an Prompt. Let's try it: ")
26
+ logger1.log(f"Answer is: {prompt_result}", "INFO")
27
+
28
+ progress_bar1 = ModernProgressBar(total=100, process_name="Task 1", spinner_mode=False)
29
+ progress_bar1.setMessage("WAITING")
30
+ progress_bar2 = ModernProgressBar(total=200, process_name="Task 2", spinner_mode=True)
31
+ progress_bar2.setMessage("WAITING")
32
+
33
+ progress_bar1.start()
34
+ progress_bar2.start()
35
+
36
+ progress_bar1.setMessage("RUNNING")
37
+ for i in range(100):
38
+ time.sleep(0.05)
39
+ progress_bar1.update()
40
+ progress_bar1.setMessage("DONE")
41
+ progress_bar1.finish()
42
+
43
+ progress_bar2.spin_start()
44
+ progress_bar2.setMessage("RUNNING (BACKGROUND)")
45
+ for i in range(100):
46
+ time.sleep(0.05)
47
+ progress_bar2.update(2)
48
+ progress_bar2.setMessage("DONE")
49
+ progress_bar2.finish()
50
+ except KeyboardInterrupt:
51
+ print()
52
+ logger1.log("Aborted.", "INFO")
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env python3
2
+
3
+ # -- nercone-modern --------------------------------------------- #
4
+ # logging.py on nercone-modern #
5
+ # Made by DiamondGotCat, Licensed under MIT License #
6
+ # Copyright (c) 2025 DiamondGotCat #
7
+ # ---------------------------------------------- DiamondGotCat -- #
8
+
9
+ ModernLoggingLevels = ["DEBUG", "INFO", "WARN", "ERROR", "CRITICAL"]
10
+ MAX_LOG_LEVEL_WIDTH = max(len(level) for level in ModernLoggingLevels)
11
+ LEVEL_ALIASES = {
12
+ "D": "DEBUG",
13
+ "DEBUG": "DEBUG",
14
+ "I": "INFO",
15
+ "INFO": "INFO",
16
+ "INFORMATION": "INFO",
17
+ "W": "WARN",
18
+ "WARN": "WARN",
19
+ "WARNING": "WARN",
20
+ "E": "ERROR",
21
+ "ERROR": "ERROR",
22
+ "C": "CRITICAL",
23
+ "CRITICAL": "CRITICAL"
24
+ }
25
+
26
+ _last_process = None
27
+ _last_level = None
28
+ _max_proc_width = 0
29
+
30
+ def normalize_level(level: str) -> str:
31
+ level = level.strip().upper()
32
+ return LEVEL_ALIASES.get(level, level)
33
+
34
+ def is_higher_priority(level_a: str, level_b: str) -> bool:
35
+ a = normalize_level(level_a)
36
+ b = normalize_level(level_b)
37
+ try:
38
+ return ModernLoggingLevels.index(a) >= ModernLoggingLevels.index(b)
39
+ except ValueError:
40
+ raise ValueError(f"Unknown log level: {level_a} or {level_b}")
41
+
42
+ class ModernLogging:
43
+ def __init__(self, process_name: str, display_level: str = "INFO"):
44
+ self.process_name = process_name
45
+ self.display_level = display_level
46
+
47
+ global _max_proc_width
48
+ _max_proc_width = max(_max_proc_width, len(process_name))
49
+
50
+ def log(self, message="", level="INFO"):
51
+ if not is_higher_priority(level, self.display_level):
52
+ return
53
+
54
+ global _last_process, _last_level
55
+ level_text = normalize_level(level.strip().upper())
56
+ show_proc = (self.process_name != _last_process)
57
+ show_level = show_proc or (level_text != _last_level)
58
+
59
+ if level_text == "DEBUG":
60
+ color = 'gray'
61
+ elif level_text == "INFO":
62
+ color = 'blue'
63
+ elif level_text == "WARN":
64
+ color = 'yellow'
65
+ elif level_text == "ERROR":
66
+ color = 'red'
67
+ elif level_text == "CRITICAL":
68
+ color = 'red'
69
+ else:
70
+ color = 'blue'
71
+
72
+ print(self._make(message, level_text, color, show_proc, show_level))
73
+
74
+ _last_process = self.process_name
75
+ _last_level = level_text
76
+
77
+ def prompt(self, message="", level="INFO") -> str:
78
+ if not is_higher_priority(level, self.display_level):
79
+ return
80
+
81
+ global _last_process, _last_level
82
+ level_text = normalize_level(level.strip().upper())
83
+ show_proc = (self.process_name != _last_process)
84
+ show_level = show_proc or (level_text != _last_level)
85
+
86
+ if level_text == "DEBUG":
87
+ color = 'gray'
88
+ elif level_text == "INFO":
89
+ color = 'blue'
90
+ elif level_text == "WARN":
91
+ color = 'yellow'
92
+ elif level_text == "ERROR":
93
+ color = 'red'
94
+ elif level_text == "CRITICAL":
95
+ color = 'red'
96
+ else:
97
+ color = 'blue'
98
+
99
+ print(self._make(message, level_text, color, show_proc, show_level), end="")
100
+
101
+ _last_process = self.process_name
102
+ _last_level = level_text
103
+ return input()
104
+
105
+ def _make(self, message, level_text, color, show_proc, show_level):
106
+ global _max_proc_width
107
+ level_width = max(MAX_LOG_LEVEL_WIDTH, len(level_text))
108
+
109
+ proc_part = self.process_name if show_proc else ""
110
+ proc_part = proc_part.ljust(_max_proc_width) if proc_part else " " * _max_proc_width
111
+
112
+ if show_level:
113
+ level_part = f"{self._color(color)}{level_text.ljust(level_width)} |{self._color('reset')}"
114
+ else:
115
+ level_part = (" " * level_width) + f"{self._color(color)} |{self._color('reset')}"
116
+
117
+ return f"{proc_part} {level_part} {str(message)}"
118
+
119
+ def _color(self, color_name):
120
+ if color_name == "cyan":
121
+ return self._color_by_code(36)
122
+ elif color_name == "magenta":
123
+ return self._color_by_code(35)
124
+ elif color_name == "yellow":
125
+ return self._color_by_code(33)
126
+ elif color_name == "green":
127
+ return self._color_by_code(32)
128
+ elif color_name == "red":
129
+ return self._color_by_code(31)
130
+ elif color_name == "blue":
131
+ return self._color_by_code(34)
132
+ elif color_name == "white":
133
+ return self._color_by_code(37)
134
+ elif color_name == "black":
135
+ return self._color_by_code(30)
136
+ elif color_name in ("gray", "grey"):
137
+ return self._color_by_code(90)
138
+ elif color_name == "reset":
139
+ return self._color_by_code(0)
140
+ else:
141
+ return ""
142
+
143
+ def _color_by_code(self, color_code):
144
+ return f"\033[{color_code}m"
@@ -1,18 +1,24 @@
1
+ #!/usr/bin/env python3
2
+
3
+ # -- nercone-modern --------------------------------------------- #
4
+ # progressbar.py on nercone-modern #
5
+ # Made by DiamondGotCat, Licensed under MIT License #
6
+ # Copyright (c) 2025 DiamondGotCat #
7
+ # ---------------------------------------------- DiamondGotCat -- #
8
+
1
9
  import sys
2
10
  import threading
3
- import time
4
11
 
5
12
  class ModernProgressBar:
6
13
  _active_bars = []
7
14
  _last_rendered = False
8
15
  _lock = threading.RLock()
9
16
 
10
- def __init__(self, total, process_name, process_color, spinner_mode=True):
17
+ def __init__(self, total: int, process_name: str, spinner_mode=True):
11
18
  self.total = total
12
19
  self.spinner_mode = spinner_mode
13
20
  self.current = 0
14
21
  self.process_name = process_name.strip()
15
- self.process_color = process_color
16
22
  self.index = len(ModernProgressBar._active_bars)
17
23
  ModernProgressBar._active_bars.append(self)
18
24
  self.log_lines = 0
@@ -81,7 +87,7 @@ class ModernProgressBar:
81
87
  self.log_lines = 0
82
88
  if modernLogging is None:
83
89
  modernLogging = self.makeModernLogging(self.process_name)
84
- result = modernLogging._make(message, level, self.process_color)
90
+ result = modernLogging._make(message, level)
85
91
  if self.log_lines > 0:
86
92
  move_up = self.log_lines
87
93
  else:
@@ -126,7 +132,7 @@ class ModernProgressBar:
126
132
  status = "(RUNN)"
127
133
  else:
128
134
  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}"
135
+ line = f"({self._color('gray')}{bar}{self._color('reset')}) {self.process_name} - {'....' if self.spinner_mode else percentage} {status} | {self.message}"
130
136
  total_move_up = self.log_lines + (len(ModernProgressBar._active_bars) - self.index)
131
137
  if total_move_up > 0:
132
138
  sys.stdout.write(f"\033[{total_move_up}A")
@@ -154,7 +160,7 @@ class ModernProgressBar:
154
160
  filled_length = int(progress * bar_length) + 1
155
161
  else:
156
162
  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)}"
163
+ return f"{self._color('blue')}{filled_bar * filled_length}{self._color('cyan')}{center_bar}{self._color('gray')}{empty_bar * (bar_length - filled_length)}"
158
164
  else:
159
165
  if self.current <= 0 and not self._spinner_ready:
160
166
  return f"{self._color('gray')}{'-' * (bar_length + 1)}"
@@ -163,7 +169,7 @@ class ModernProgressBar:
163
169
  spinner_start_bar_length = bar_length - spinner_end_bar_length
164
170
  if advance_spinner:
165
171
  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}"
172
+ return f"{self._color('gray')}{'-' * spinner_start_bar_length}{self._color('blue')}{'-' * spinner_symbol_length}{self._color('gray')}{'-' * spinner_end_bar_length}"
167
173
 
168
174
  def _should_spin(self):
169
175
  return self.spinner_mode and self._spinner_ready
@@ -1,17 +0,0 @@
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 .logging 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 .progressbar import ModernProgressBar
16
- return ModernProgressBar(total, process_name, process_color, spinner_mode)
17
-
@@ -1,34 +0,0 @@
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()
@@ -1,30 +0,0 @@
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"