hexlogger 2.0.1__tar.gz → 2.0.3__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.4
2
2
  Name: hexlogger
3
- Version: 2.0.1
3
+ Version: 2.0.3
4
4
  Summary: Premium console logging library with themes, gradients, panels, tables, progress bars, and spinners.
5
5
  Author: Itz Montage
6
6
  License: MIT
@@ -85,11 +85,11 @@ hexlogger.fatal("Token invalidated — shutting down")
85
85
  ---
86
86
 
87
87
 
88
- Nine display styles are available. All styles respond to the active theme for color. Switch styles with `hexlogger.set_style(name)`.
88
+ Nine display styles are available. All styles respond to the active theme for color. Switch styles with `hexlogger.setstyle(name)`.
89
89
 
90
90
 
91
91
  ```python
92
- hexlogger.set_style("default")
92
+ hexlogger.setstyle("default")
93
93
  ```
94
94
 
95
95
  ```
@@ -108,7 +108,7 @@ hexlogger.set_style("default")
108
108
 
109
109
 
110
110
  ```python
111
- hexlogger.set_style("box")
111
+ hexlogger.setstyle("box")
112
112
  ```
113
113
 
114
114
  ```
@@ -127,7 +127,7 @@ hexlogger.set_style("box")
127
127
 
128
128
 
129
129
  ```python
130
- hexlogger.set_style("modern")
130
+ hexlogger.setstyle("modern")
131
131
  ```
132
132
 
133
133
  ```
@@ -146,7 +146,7 @@ hexlogger.set_style("modern")
146
146
 
147
147
 
148
148
  ```python
149
- hexlogger.set_style("bracket")
149
+ hexlogger.setstyle("bracket")
150
150
  ```
151
151
 
152
152
  ```
@@ -165,7 +165,7 @@ hexlogger.set_style("bracket")
165
165
 
166
166
 
167
167
  ```python
168
- hexlogger.set_style("arrow")
168
+ hexlogger.setstyle("arrow")
169
169
  ```
170
170
 
171
171
  ```
@@ -184,7 +184,7 @@ hexlogger.set_style("arrow")
184
184
 
185
185
 
186
186
  ```python
187
- hexlogger.set_style("pipe")
187
+ hexlogger.setstyle("pipe")
188
188
  ```
189
189
 
190
190
  ```
@@ -203,7 +203,7 @@ hexlogger.set_style("pipe")
203
203
 
204
204
 
205
205
  ```python
206
- hexlogger.set_style("tag")
206
+ hexlogger.setstyle("tag")
207
207
  ```
208
208
 
209
209
  ```
@@ -224,7 +224,7 @@ hexlogger.set_style("tag")
224
224
 
225
225
 
226
226
  ```python
227
- hexlogger.set_style("dots")
227
+ hexlogger.setstyle("dots")
228
228
  ```
229
229
 
230
230
  ```
@@ -243,7 +243,7 @@ hexlogger.set_style("dots")
243
243
 
244
244
 
245
245
  ```python
246
- hexlogger.set_style("clean")
246
+ hexlogger.setstyle("clean")
247
247
  ```
248
248
 
249
249
  ```
@@ -266,12 +266,12 @@ hexlogger.set_style("clean")
266
266
  Six built-in themes control the colors applied to every style. Themes do not affect the structure of the output — only the palette.
267
267
 
268
268
  ```python
269
- hexlogger.set_theme("default") # Soft blue/green palette
270
- hexlogger.set_theme("neon") # Vivid cyan/magenta palette
271
- hexlogger.set_theme("minimal") # Muted grays, abbreviated labels
272
- hexlogger.set_theme("hacker") # Green-on-black matrix palette
273
- hexlogger.set_theme("sunset") # Warm orange/red palette
274
- hexlogger.set_theme("ocean") # Deep blue/teal palette
269
+ hexlogger.settheme("default") # Soft blue/green palette
270
+ hexlogger.settheme("neon") # Vivid cyan/magenta palette
271
+ hexlogger.settheme("minimal") # Muted grays, abbreviated labels
272
+ hexlogger.settheme("hacker") # Green-on-black matrix palette
273
+ hexlogger.settheme("sunset") # Warm orange/red palette
274
+ hexlogger.settheme("ocean") # Deep blue/teal palette
275
275
  ```
276
276
 
277
277
  The `minimal` theme also uses abbreviated level labels:
@@ -318,7 +318,7 @@ hexlogger._config.add_theme("mytheme", {
318
318
  "label_trace": "TRACE",
319
319
  })
320
320
 
321
- hexlogger.set_theme("mytheme")
321
+ hexlogger.settheme("mytheme")
322
322
  ```
323
323
 
324
324
  ---
@@ -347,13 +347,13 @@ hexlogger.blank(2)
347
347
 
348
348
 
349
349
  ```python
350
- hexlogger.banner("HexLogger\nv2.0.0")
350
+ hexlogger.banner("HexLogger\nv3.0.0")
351
351
  ```
352
352
 
353
353
  ```
354
354
  ╔═══════════════╗
355
355
  ║ HexLogger ║
356
- v2.0.0 ║
356
+ v3.0.0 ║
357
357
  ╚═══════════════╝
358
358
  ```
359
359
 
@@ -430,31 +430,31 @@ hexlogger.pair("Users", "94,210")
430
430
 
431
431
 
432
432
  ```python
433
- hexlogger.gradient_print("Hello World!", (255, 0, 100), (100, 0, 255))
434
- hexlogger.rainbow_print("Rainbow text!")
433
+ hexlogger.gprint("Hello World!", (255, 0, 100), (100, 0, 255))
434
+ hexlogger.rbprint("Rainbow text!")
435
435
 
436
- text = hexlogger.gradient_text("Custom gradient", (0, 255, 200), (255, 0, 100))
437
- multi = hexlogger.multi_gradient_text("Multi-stop", [(255,0,0), (0,255,0), (0,0,255)])
436
+ text = hexlogger.gtext("Custom gradient", (0, 255, 200), (255, 0, 100))
437
+ multi = hexlogger.mgtext("Multi-stop", [(255,0,0), (0,255,0), (0,0,255)])
438
438
  ```
439
439
 
440
440
 
441
441
  ```python
442
- from hexlogger import bold, italic, underline, colorize, Colors
442
+ from hexlogger import bold, italic, uline, clr, Colors
443
443
 
444
444
  print(bold("Bold text"))
445
445
  print(italic("Italic text"))
446
- print(underline("Underlined text"))
447
- print(colorize("Cyan text", Colors.CYAN))
446
+ print(uline("Underlined text"))
447
+ print(clr("Cyan text", Colors.CYAN))
448
448
  ```
449
449
 
450
450
 
451
451
  ```python
452
- from hexlogger import rgb, bg_rgb, hex_color, bg_hex
452
+ from hexlogger import rgb, bgrgb, hexclr, bghex
453
453
 
454
454
  color = rgb(255, 128, 0)
455
- bg = bg_rgb(30, 30, 30)
456
- from_hex = hex_color("#FF8800")
457
- bg_hex_ = bg_hex("#1E1E1E")
455
+ bg = bgrgb(30, 30, 30)
456
+ from_hex = hexclr("#FF8800")
457
+ bg_hex_ = bghex("#1E1E1E")
458
458
  ```
459
459
 
460
460
  ---
@@ -463,7 +463,7 @@ bg_hex_ = bg_hex("#1E1E1E")
463
463
  ```python
464
464
  import time
465
465
 
466
- bar = hexlogger.ProgressBar(total=100, label="Downloading", width=40)
466
+ bar = hexlogger.Progress(total=100, label="Downloading", width=40)
467
467
  for i in range(100):
468
468
  time.sleep(0.05)
469
469
  bar.update()
@@ -521,10 +521,10 @@ elapsed = timer.stop()
521
521
 
522
522
 
523
523
  ```python
524
- hexlogger.set_theme("neon")
525
- hexlogger.set_style("modern")
526
- hexlogger.set_log_file("app.log")
527
- hexlogger.set_min_level("warning")
524
+ hexlogger.settheme("neon")
525
+ hexlogger.setstyle("modern")
526
+ hexlogger.setlog("app.log")
527
+ hexlogger.setlevel("warning")
528
528
 
529
529
  hexlogger._config.time_format = "%Y-%m-%d %H:%M:%S"
530
530
  hexlogger._config.show_time = False
@@ -534,13 +534,13 @@ hexlogger._config.show_time = False
534
534
  Only messages at or above the configured level are printed.
535
535
 
536
536
  ```python
537
- hexlogger.set_min_level("trace")
538
- hexlogger.set_min_level("debug")
539
- hexlogger.set_min_level("info")
540
- hexlogger.set_min_level("warning")
541
- hexlogger.set_min_level("error")
542
- hexlogger.set_min_level("critical")
543
- hexlogger.set_min_level("fatal")
537
+ hexlogger.setlevel("trace")
538
+ hexlogger.setlevel("debug")
539
+ hexlogger.setlevel("info")
540
+ hexlogger.setlevel("warning")
541
+ hexlogger.setlevel("error")
542
+ hexlogger.setlevel("critical")
543
+ hexlogger.setlevel("fatal")
544
544
  ```
545
545
 
546
546
  ---
@@ -58,11 +58,11 @@ hexlogger.fatal("Token invalidated — shutting down")
58
58
  ---
59
59
 
60
60
 
61
- Nine display styles are available. All styles respond to the active theme for color. Switch styles with `hexlogger.set_style(name)`.
61
+ Nine display styles are available. All styles respond to the active theme for color. Switch styles with `hexlogger.setstyle(name)`.
62
62
 
63
63
 
64
64
  ```python
65
- hexlogger.set_style("default")
65
+ hexlogger.setstyle("default")
66
66
  ```
67
67
 
68
68
  ```
@@ -81,7 +81,7 @@ hexlogger.set_style("default")
81
81
 
82
82
 
83
83
  ```python
84
- hexlogger.set_style("box")
84
+ hexlogger.setstyle("box")
85
85
  ```
86
86
 
87
87
  ```
@@ -100,7 +100,7 @@ hexlogger.set_style("box")
100
100
 
101
101
 
102
102
  ```python
103
- hexlogger.set_style("modern")
103
+ hexlogger.setstyle("modern")
104
104
  ```
105
105
 
106
106
  ```
@@ -119,7 +119,7 @@ hexlogger.set_style("modern")
119
119
 
120
120
 
121
121
  ```python
122
- hexlogger.set_style("bracket")
122
+ hexlogger.setstyle("bracket")
123
123
  ```
124
124
 
125
125
  ```
@@ -138,7 +138,7 @@ hexlogger.set_style("bracket")
138
138
 
139
139
 
140
140
  ```python
141
- hexlogger.set_style("arrow")
141
+ hexlogger.setstyle("arrow")
142
142
  ```
143
143
 
144
144
  ```
@@ -157,7 +157,7 @@ hexlogger.set_style("arrow")
157
157
 
158
158
 
159
159
  ```python
160
- hexlogger.set_style("pipe")
160
+ hexlogger.setstyle("pipe")
161
161
  ```
162
162
 
163
163
  ```
@@ -176,7 +176,7 @@ hexlogger.set_style("pipe")
176
176
 
177
177
 
178
178
  ```python
179
- hexlogger.set_style("tag")
179
+ hexlogger.setstyle("tag")
180
180
  ```
181
181
 
182
182
  ```
@@ -197,7 +197,7 @@ hexlogger.set_style("tag")
197
197
 
198
198
 
199
199
  ```python
200
- hexlogger.set_style("dots")
200
+ hexlogger.setstyle("dots")
201
201
  ```
202
202
 
203
203
  ```
@@ -216,7 +216,7 @@ hexlogger.set_style("dots")
216
216
 
217
217
 
218
218
  ```python
219
- hexlogger.set_style("clean")
219
+ hexlogger.setstyle("clean")
220
220
  ```
221
221
 
222
222
  ```
@@ -239,12 +239,12 @@ hexlogger.set_style("clean")
239
239
  Six built-in themes control the colors applied to every style. Themes do not affect the structure of the output — only the palette.
240
240
 
241
241
  ```python
242
- hexlogger.set_theme("default") # Soft blue/green palette
243
- hexlogger.set_theme("neon") # Vivid cyan/magenta palette
244
- hexlogger.set_theme("minimal") # Muted grays, abbreviated labels
245
- hexlogger.set_theme("hacker") # Green-on-black matrix palette
246
- hexlogger.set_theme("sunset") # Warm orange/red palette
247
- hexlogger.set_theme("ocean") # Deep blue/teal palette
242
+ hexlogger.settheme("default") # Soft blue/green palette
243
+ hexlogger.settheme("neon") # Vivid cyan/magenta palette
244
+ hexlogger.settheme("minimal") # Muted grays, abbreviated labels
245
+ hexlogger.settheme("hacker") # Green-on-black matrix palette
246
+ hexlogger.settheme("sunset") # Warm orange/red palette
247
+ hexlogger.settheme("ocean") # Deep blue/teal palette
248
248
  ```
249
249
 
250
250
  The `minimal` theme also uses abbreviated level labels:
@@ -291,7 +291,7 @@ hexlogger._config.add_theme("mytheme", {
291
291
  "label_trace": "TRACE",
292
292
  })
293
293
 
294
- hexlogger.set_theme("mytheme")
294
+ hexlogger.settheme("mytheme")
295
295
  ```
296
296
 
297
297
  ---
@@ -320,13 +320,13 @@ hexlogger.blank(2)
320
320
 
321
321
 
322
322
  ```python
323
- hexlogger.banner("HexLogger\nv2.0.0")
323
+ hexlogger.banner("HexLogger\nv3.0.0")
324
324
  ```
325
325
 
326
326
  ```
327
327
  ╔═══════════════╗
328
328
  ║ HexLogger ║
329
- v2.0.0 ║
329
+ v3.0.0 ║
330
330
  ╚═══════════════╝
331
331
  ```
332
332
 
@@ -403,31 +403,31 @@ hexlogger.pair("Users", "94,210")
403
403
 
404
404
 
405
405
  ```python
406
- hexlogger.gradient_print("Hello World!", (255, 0, 100), (100, 0, 255))
407
- hexlogger.rainbow_print("Rainbow text!")
406
+ hexlogger.gprint("Hello World!", (255, 0, 100), (100, 0, 255))
407
+ hexlogger.rbprint("Rainbow text!")
408
408
 
409
- text = hexlogger.gradient_text("Custom gradient", (0, 255, 200), (255, 0, 100))
410
- multi = hexlogger.multi_gradient_text("Multi-stop", [(255,0,0), (0,255,0), (0,0,255)])
409
+ text = hexlogger.gtext("Custom gradient", (0, 255, 200), (255, 0, 100))
410
+ multi = hexlogger.mgtext("Multi-stop", [(255,0,0), (0,255,0), (0,0,255)])
411
411
  ```
412
412
 
413
413
 
414
414
  ```python
415
- from hexlogger import bold, italic, underline, colorize, Colors
415
+ from hexlogger import bold, italic, uline, clr, Colors
416
416
 
417
417
  print(bold("Bold text"))
418
418
  print(italic("Italic text"))
419
- print(underline("Underlined text"))
420
- print(colorize("Cyan text", Colors.CYAN))
419
+ print(uline("Underlined text"))
420
+ print(clr("Cyan text", Colors.CYAN))
421
421
  ```
422
422
 
423
423
 
424
424
  ```python
425
- from hexlogger import rgb, bg_rgb, hex_color, bg_hex
425
+ from hexlogger import rgb, bgrgb, hexclr, bghex
426
426
 
427
427
  color = rgb(255, 128, 0)
428
- bg = bg_rgb(30, 30, 30)
429
- from_hex = hex_color("#FF8800")
430
- bg_hex_ = bg_hex("#1E1E1E")
428
+ bg = bgrgb(30, 30, 30)
429
+ from_hex = hexclr("#FF8800")
430
+ bg_hex_ = bghex("#1E1E1E")
431
431
  ```
432
432
 
433
433
  ---
@@ -436,7 +436,7 @@ bg_hex_ = bg_hex("#1E1E1E")
436
436
  ```python
437
437
  import time
438
438
 
439
- bar = hexlogger.ProgressBar(total=100, label="Downloading", width=40)
439
+ bar = hexlogger.Progress(total=100, label="Downloading", width=40)
440
440
  for i in range(100):
441
441
  time.sleep(0.05)
442
442
  bar.update()
@@ -494,10 +494,10 @@ elapsed = timer.stop()
494
494
 
495
495
 
496
496
  ```python
497
- hexlogger.set_theme("neon")
498
- hexlogger.set_style("modern")
499
- hexlogger.set_log_file("app.log")
500
- hexlogger.set_min_level("warning")
497
+ hexlogger.settheme("neon")
498
+ hexlogger.setstyle("modern")
499
+ hexlogger.setlog("app.log")
500
+ hexlogger.setlevel("warning")
501
501
 
502
502
  hexlogger._config.time_format = "%Y-%m-%d %H:%M:%S"
503
503
  hexlogger._config.show_time = False
@@ -507,13 +507,13 @@ hexlogger._config.show_time = False
507
507
  Only messages at or above the configured level are printed.
508
508
 
509
509
  ```python
510
- hexlogger.set_min_level("trace")
511
- hexlogger.set_min_level("debug")
512
- hexlogger.set_min_level("info")
513
- hexlogger.set_min_level("warning")
514
- hexlogger.set_min_level("error")
515
- hexlogger.set_min_level("critical")
516
- hexlogger.set_min_level("fatal")
510
+ hexlogger.setlevel("trace")
511
+ hexlogger.setlevel("debug")
512
+ hexlogger.setlevel("info")
513
+ hexlogger.setlevel("warning")
514
+ hexlogger.setlevel("error")
515
+ hexlogger.setlevel("critical")
516
+ hexlogger.setlevel("fatal")
517
517
  ```
518
518
 
519
519
  ---
@@ -0,0 +1,25 @@
1
+ __version__ = "2.0.3"
2
+ __author__ = "Montage"
3
+
4
+ from .colors import Colors, rgb, bgrgb, hexclr, bghex
5
+ from .themes import Theme, THEMES, LEVEL_ICONS
6
+ from .config import LogLevel, LoggerConfig, settheme, setstyle, setlog, setlevel
7
+ from .core import debug, info, success, warn, warning, error, critical, fatal, trace
8
+ from .formatting import divider, section, blank, rule, banner, pair
9
+ from .gradient import gtext, gprint, mgtext, mgprint, rbtext, rbprint
10
+ from .widgets import panel, table, box
11
+ from .progress import Progress, Spinner, Timer
12
+ from .utils import clr, bold, italic, uline
13
+ from . import _compat
14
+
15
+ __all__ = [
16
+ "debug", "info", "success", "warn", "warning",
17
+ "error", "critical", "fatal", "trace",
18
+ "divider", "section", "blank", "rule", "banner", "pair",
19
+ "gtext", "gprint", "mgtext", "mgprint", "rbtext", "rbprint",
20
+ "panel", "table", "box",
21
+ "Progress", "Spinner", "Timer",
22
+ "clr", "bold", "italic", "uline",
23
+ "Colors", "rgb", "bgrgb", "hexclr", "bghex",
24
+ "Theme", "LogLevel", "settheme", "setstyle", "setlog", "setlevel",
25
+ ]
@@ -0,0 +1,9 @@
1
+ import os
2
+
3
+ if os.name == "nt":
4
+ try:
5
+ import ctypes
6
+ k32 = ctypes.windll.kernel32
7
+ k32.SetConsoleMode(k32.GetStdHandle(-11), 7)
8
+ except Exception:
9
+ pass
@@ -0,0 +1,66 @@
1
+ __all__ = ["Colors", "rgb", "bgrgb", "hexclr", "bghex"]
2
+
3
+
4
+ class Colors:
5
+ RESET = "\033[0m"
6
+ BOLD = "\033[1m"
7
+ DIM = "\033[2m"
8
+ ITALIC = "\033[3m"
9
+ UNDERLINE = "\033[4m"
10
+ BLINK = "\033[5m"
11
+ REVERSE = "\033[7m"
12
+ STRIKE = "\033[9m"
13
+ BLACK = "\033[30m"
14
+ RED = "\033[31m"
15
+ GREEN = "\033[32m"
16
+ YELLOW = "\033[33m"
17
+ BLUE = "\033[34m"
18
+ MAGENTA = "\033[35m"
19
+ CYAN = "\033[36m"
20
+ WHITE = "\033[37m"
21
+ GRAY = "\033[90m"
22
+ BRIGHT_RED = "\033[91m"
23
+ BRIGHT_GREEN = "\033[92m"
24
+ BRIGHT_YELLOW = "\033[93m"
25
+ BRIGHT_BLUE = "\033[94m"
26
+ BRIGHT_MAGENTA = "\033[95m"
27
+ BRIGHT_CYAN = "\033[96m"
28
+ BRIGHT_WHITE = "\033[97m"
29
+ BG_BLACK = "\033[40m"
30
+ BG_RED = "\033[41m"
31
+ BG_GREEN = "\033[42m"
32
+ BG_YELLOW = "\033[43m"
33
+ BG_BLUE = "\033[44m"
34
+ BG_MAGENTA = "\033[45m"
35
+ BG_CYAN = "\033[46m"
36
+ BG_WHITE = "\033[47m"
37
+
38
+
39
+ def _clamp(v):
40
+ return max(0, min(255, int(v)))
41
+
42
+ def rgb(r, g, b):
43
+ return f"\033[38;2;{_clamp(r)};{_clamp(g)};{_clamp(b)}m"
44
+
45
+ def bgrgb(r, g, b):
46
+ return f"\033[48;2;{_clamp(r)};{_clamp(g)};{_clamp(b)}m"
47
+
48
+ def hexclr(hex_code):
49
+ try:
50
+ hex_code = str(hex_code).lstrip("#")
51
+ if len(hex_code) < 6:
52
+ hex_code = hex_code.ljust(6, "0")
53
+ r, g, b = int(hex_code[0:2], 16), int(hex_code[2:4], 16), int(hex_code[4:6], 16)
54
+ return rgb(r, g, b)
55
+ except Exception:
56
+ return Colors.RESET
57
+
58
+ def bghex(hex_code):
59
+ try:
60
+ hex_code = str(hex_code).lstrip("#")
61
+ if len(hex_code) < 6:
62
+ hex_code = hex_code.ljust(6, "0")
63
+ r, g, b = int(hex_code[0:2], 16), int(hex_code[2:4], 16), int(hex_code[4:6], 16)
64
+ return bgrgb(r, g, b)
65
+ except Exception:
66
+ return Colors.RESET
@@ -0,0 +1,107 @@
1
+ import threading
2
+ from enum import Enum
3
+
4
+ from .themes import Theme, THEMES
5
+ from .styles import STYLES
6
+
7
+ __all__ = ["LogLevel", "LoggerConfig", "get_config", "settheme", "setstyle", "setlog", "setlevel"]
8
+
9
+
10
+ class LogLevel(Enum):
11
+ TRACE = 0
12
+ DEBUG = 1
13
+ INFO = 2
14
+ SUCCESS = 3
15
+ WARNING = 4
16
+ ERROR = 5
17
+ CRITICAL = 6
18
+ FATAL = 7
19
+
20
+
21
+ class LoggerConfig:
22
+ def __init__(self):
23
+ self.theme = THEMES.get("default", Theme("default", {}))
24
+ self.style = "default"
25
+ self.time_format = "%H:%M:%S"
26
+ self.show_time = True
27
+ self.log_file = None
28
+ self.min_level = LogLevel.TRACE
29
+ self._file_handle = None
30
+ self._lock = threading.Lock()
31
+
32
+ def set_theme(self, name):
33
+ if name in THEMES:
34
+ self.theme = THEMES[name]
35
+ else:
36
+ raise ValueError(f"Unknown theme: {name}. Available: {', '.join(THEMES.keys())}")
37
+
38
+ def set_style(self, name):
39
+ if name in STYLES:
40
+ self.style = name
41
+ else:
42
+ raise ValueError(f"Unknown style: {name}. Available: {', '.join(STYLES.keys())}")
43
+
44
+ def add_theme(self, name, colors):
45
+ try:
46
+ theme = Theme(str(name), colors if isinstance(colors, dict) else {})
47
+ THEMES[str(name)] = theme
48
+ return theme
49
+ except Exception:
50
+ raise ValueError(f"Failed to add theme: {name}")
51
+
52
+ def set_log_file(self, path):
53
+ try:
54
+ self.log_file = str(path)
55
+ if self._file_handle:
56
+ try:
57
+ self._file_handle.close()
58
+ except Exception:
59
+ pass
60
+ self._file_handle = open(self.log_file, "a", encoding="utf-8")
61
+ except Exception:
62
+ self._file_handle = None
63
+ raise
64
+
65
+ def close(self):
66
+ if self._file_handle:
67
+ try:
68
+ self._file_handle.close()
69
+ except Exception:
70
+ pass
71
+ self._file_handle = None
72
+
73
+ def __del__(self):
74
+ self.close()
75
+
76
+
77
+ _config = LoggerConfig()
78
+
79
+
80
+ def get_config():
81
+ return _config
82
+
83
+
84
+ def settheme(name):
85
+ _config.set_theme(str(name))
86
+
87
+
88
+ def setstyle(name):
89
+ _config.set_style(str(name))
90
+
91
+
92
+ def setlog(path):
93
+ _config.set_log_file(str(path))
94
+
95
+
96
+ def setlevel(level):
97
+ mapping = {
98
+ "trace": LogLevel.TRACE, "debug": LogLevel.DEBUG,
99
+ "info": LogLevel.INFO, "success": LogLevel.SUCCESS,
100
+ "warning": LogLevel.WARNING, "error": LogLevel.ERROR,
101
+ "critical": LogLevel.CRITICAL, "fatal": LogLevel.FATAL,
102
+ }
103
+ key = str(level).lower().strip()
104
+ if key in mapping:
105
+ _config.min_level = mapping[key]
106
+ else:
107
+ raise ValueError(f"Unknown level: {level}. Available: {', '.join(mapping.keys())}")
@@ -0,0 +1,49 @@
1
+ from datetime import datetime
2
+
3
+ from .config import get_config, LogLevel
4
+ from .styles import STYLES
5
+ from .utils import strip_ansi
6
+
7
+ __all__ = ["debug", "info", "success", "warn", "warning", "error", "critical", "fatal", "trace"]
8
+
9
+
10
+ def _get_time():
11
+ try:
12
+ return datetime.now().strftime(get_config().time_format)
13
+ except Exception:
14
+ return ""
15
+
16
+
17
+ def _log(level, message, level_enum):
18
+ try:
19
+ cfg = get_config()
20
+ if level_enum.value < cfg.min_level.value:
21
+ return
22
+ t = cfg.theme
23
+ now = _get_time()
24
+ style_fn = STYLES.get(cfg.style, STYLES["default"])
25
+ line = style_fn(now, level, t.get(level), t.get(f"label_{level}"), str(message), t, cfg.show_time)
26
+ with cfg._lock:
27
+ print(line)
28
+ if cfg._file_handle:
29
+ try:
30
+ cfg._file_handle.write(strip_ansi(line) + "\n")
31
+ cfg._file_handle.flush()
32
+ except Exception:
33
+ pass
34
+ except Exception:
35
+ try:
36
+ print(f"[{level.upper()}] {message}")
37
+ except Exception:
38
+ pass
39
+
40
+
41
+ def debug(msg): _log("debug", msg, LogLevel.DEBUG)
42
+ def info(msg): _log("info", msg, LogLevel.INFO)
43
+ def success(msg): _log("success", msg, LogLevel.SUCCESS)
44
+ def warn(msg): _log("warning", msg, LogLevel.WARNING)
45
+ def warning(msg): _log("warning", msg, LogLevel.WARNING)
46
+ def error(msg): _log("error", msg, LogLevel.ERROR)
47
+ def critical(msg): _log("critical", msg, LogLevel.CRITICAL)
48
+ def fatal(msg): _log("fatal", msg, LogLevel.FATAL)
49
+ def trace(msg): _log("trace", msg, LogLevel.TRACE)