webscout 7.1__py3-none-any.whl → 7.2__py3-none-any.whl
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.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/AIauto.py +191 -191
- webscout/AIbase.py +122 -122
- webscout/AIutel.py +440 -440
- webscout/Bard.py +343 -161
- webscout/DWEBS.py +489 -492
- webscout/Extra/YTToolkit/YTdownloader.py +995 -995
- webscout/Extra/YTToolkit/__init__.py +2 -2
- webscout/Extra/YTToolkit/transcriber.py +476 -479
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -307
- webscout/Extra/YTToolkit/ytapi/playlist.py +58 -58
- webscout/Extra/YTToolkit/ytapi/pool.py +7 -7
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -62
- webscout/Extra/YTToolkit/ytapi/video.py +103 -103
- webscout/Extra/autocoder/__init__.py +9 -9
- webscout/Extra/autocoder/autocoder_utiles.py +199 -199
- webscout/Extra/autocoder/rawdog.py +5 -7
- webscout/Extra/autollama.py +230 -230
- webscout/Extra/gguf.py +3 -3
- webscout/Extra/weather.py +171 -171
- webscout/LLM.py +442 -442
- webscout/Litlogger/__init__.py +67 -681
- webscout/Litlogger/core/__init__.py +6 -0
- webscout/Litlogger/core/level.py +20 -0
- webscout/Litlogger/core/logger.py +123 -0
- webscout/Litlogger/handlers/__init__.py +12 -0
- webscout/Litlogger/handlers/console.py +50 -0
- webscout/Litlogger/handlers/file.py +143 -0
- webscout/Litlogger/handlers/network.py +174 -0
- webscout/Litlogger/styles/__init__.py +7 -0
- webscout/Litlogger/styles/colors.py +231 -0
- webscout/Litlogger/styles/formats.py +377 -0
- webscout/Litlogger/styles/text.py +87 -0
- webscout/Litlogger/utils/__init__.py +6 -0
- webscout/Litlogger/utils/detectors.py +154 -0
- webscout/Litlogger/utils/formatters.py +200 -0
- webscout/Provider/AISEARCH/DeepFind.py +250 -250
- webscout/Provider/Blackboxai.py +3 -3
- webscout/Provider/ChatGPTGratis.py +226 -0
- webscout/Provider/Cloudflare.py +3 -4
- webscout/Provider/DeepSeek.py +218 -0
- webscout/Provider/Deepinfra.py +3 -3
- webscout/Provider/Free2GPT.py +131 -124
- webscout/Provider/Gemini.py +100 -115
- webscout/Provider/Glider.py +3 -3
- webscout/Provider/Groq.py +5 -1
- webscout/Provider/Jadve.py +3 -3
- webscout/Provider/Marcus.py +191 -192
- webscout/Provider/Netwrck.py +3 -3
- webscout/Provider/PI.py +2 -2
- webscout/Provider/PizzaGPT.py +2 -3
- webscout/Provider/QwenLM.py +311 -0
- webscout/Provider/TTI/AiForce/__init__.py +22 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +257 -257
- webscout/Provider/TTI/AiForce/sync_aiforce.py +242 -242
- webscout/Provider/TTI/Nexra/__init__.py +22 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +286 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +258 -258
- webscout/Provider/TTI/PollinationsAI/__init__.py +23 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +330 -330
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +285 -285
- webscout/Provider/TTI/artbit/__init__.py +22 -22
- webscout/Provider/TTI/artbit/async_artbit.py +184 -184
- webscout/Provider/TTI/artbit/sync_artbit.py +176 -176
- webscout/Provider/TTI/blackbox/__init__.py +4 -4
- webscout/Provider/TTI/blackbox/async_blackbox.py +212 -212
- webscout/Provider/TTI/blackbox/sync_blackbox.py +199 -199
- webscout/Provider/TTI/deepinfra/__init__.py +4 -4
- webscout/Provider/TTI/deepinfra/async_deepinfra.py +227 -227
- webscout/Provider/TTI/deepinfra/sync_deepinfra.py +199 -199
- webscout/Provider/TTI/huggingface/__init__.py +22 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +199 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -195
- webscout/Provider/TTI/imgninza/__init__.py +4 -4
- webscout/Provider/TTI/imgninza/async_ninza.py +214 -214
- webscout/Provider/TTI/imgninza/sync_ninza.py +209 -209
- webscout/Provider/TTI/talkai/__init__.py +4 -4
- webscout/Provider/TTI/talkai/async_talkai.py +229 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +207 -207
- webscout/Provider/TTS/deepgram.py +182 -182
- webscout/Provider/TTS/elevenlabs.py +136 -136
- webscout/Provider/TTS/gesserit.py +150 -150
- webscout/Provider/TTS/murfai.py +138 -138
- webscout/Provider/TTS/parler.py +133 -134
- webscout/Provider/TTS/streamElements.py +360 -360
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TTS/voicepod.py +116 -116
- webscout/Provider/TextPollinationsAI.py +2 -3
- webscout/Provider/WiseCat.py +193 -0
- webscout/Provider/__init__.py +144 -134
- webscout/Provider/cerebras.py +242 -227
- webscout/Provider/chatglm.py +204 -204
- webscout/Provider/dgaf.py +2 -3
- webscout/Provider/gaurish.py +2 -3
- webscout/Provider/geminiapi.py +208 -208
- webscout/Provider/granite.py +223 -0
- webscout/Provider/hermes.py +218 -218
- webscout/Provider/llama3mitril.py +179 -179
- webscout/Provider/llamatutor.py +3 -3
- webscout/Provider/llmchat.py +2 -3
- webscout/Provider/meta.py +794 -794
- webscout/Provider/multichat.py +331 -331
- webscout/Provider/typegpt.py +359 -359
- webscout/Provider/yep.py +2 -2
- webscout/__main__.py +5 -5
- webscout/cli.py +319 -319
- webscout/conversation.py +241 -242
- webscout/exceptions.py +328 -328
- webscout/litagent/__init__.py +28 -28
- webscout/litagent/agent.py +2 -3
- webscout/litprinter/__init__.py +0 -58
- webscout/scout/__init__.py +8 -8
- webscout/scout/core.py +884 -884
- webscout/scout/element.py +459 -459
- webscout/scout/parsers/__init__.py +69 -69
- webscout/scout/parsers/html5lib_parser.py +172 -172
- webscout/scout/parsers/html_parser.py +236 -236
- webscout/scout/parsers/lxml_parser.py +178 -178
- webscout/scout/utils.py +38 -38
- webscout/swiftcli/__init__.py +811 -811
- webscout/update_checker.py +2 -12
- webscout/version.py +1 -1
- webscout/webscout_search.py +5 -4
- webscout/zeroart/__init__.py +54 -54
- webscout/zeroart/base.py +60 -60
- webscout/zeroart/effects.py +99 -99
- webscout/zeroart/fonts.py +816 -816
- {webscout-7.1.dist-info → webscout-7.2.dist-info}/METADATA +4 -3
- webscout-7.2.dist-info/RECORD +217 -0
- webstoken/__init__.py +30 -30
- webstoken/classifier.py +189 -189
- webstoken/keywords.py +216 -216
- webstoken/language.py +128 -128
- webstoken/ner.py +164 -164
- webstoken/normalizer.py +35 -35
- webstoken/processor.py +77 -77
- webstoken/sentiment.py +206 -206
- webstoken/stemmer.py +73 -73
- webstoken/tagger.py +60 -60
- webstoken/tokenizer.py +158 -158
- webscout-7.1.dist-info/RECORD +0 -198
- {webscout-7.1.dist-info → webscout-7.2.dist-info}/LICENSE.md +0 -0
- {webscout-7.1.dist-info → webscout-7.2.dist-info}/WHEEL +0 -0
- {webscout-7.1.dist-info → webscout-7.2.dist-info}/entry_points.txt +0 -0
- {webscout-7.1.dist-info → webscout-7.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Terminal Color Management System
|
|
2
|
+
# Provides extensive ANSI color support with themes, gradients, and animations
|
|
3
|
+
|
|
4
|
+
class LogColors:
|
|
5
|
+
"""
|
|
6
|
+
Comprehensive terminal color and styling system with support for:
|
|
7
|
+
- Basic and bright colors (foreground/background)
|
|
8
|
+
- RGB and 256-color modes
|
|
9
|
+
- Text styles (bold, italic, etc.)
|
|
10
|
+
- Gradients and animations
|
|
11
|
+
- Predefined themes
|
|
12
|
+
"""
|
|
13
|
+
# Basic foreground colors
|
|
14
|
+
BLACK = "\033[30m"
|
|
15
|
+
RED = "\033[31m"
|
|
16
|
+
GREEN = "\033[32m"
|
|
17
|
+
YELLOW = "\033[33m"
|
|
18
|
+
BLUE = "\033[34m"
|
|
19
|
+
MAGENTA = "\033[35m"
|
|
20
|
+
CYAN = "\033[36m"
|
|
21
|
+
WHITE = "\033[37m"
|
|
22
|
+
RESET = "\033[0m"
|
|
23
|
+
|
|
24
|
+
# Basic background colors
|
|
25
|
+
BG_BLACK = "\033[40m"
|
|
26
|
+
BG_RED = "\033[41m"
|
|
27
|
+
BG_GREEN = "\033[42m"
|
|
28
|
+
BG_YELLOW = "\033[43m"
|
|
29
|
+
BG_BLUE = "\033[44m"
|
|
30
|
+
BG_MAGENTA = "\033[45m"
|
|
31
|
+
BG_CYAN = "\033[46m"
|
|
32
|
+
BG_WHITE = "\033[47m"
|
|
33
|
+
|
|
34
|
+
# Bright foreground colors
|
|
35
|
+
BRIGHT_BLACK = "\033[90m"
|
|
36
|
+
BRIGHT_RED = "\033[91m"
|
|
37
|
+
BRIGHT_GREEN = "\033[92m"
|
|
38
|
+
BRIGHT_YELLOW = "\033[93m"
|
|
39
|
+
BRIGHT_BLUE = "\033[94m"
|
|
40
|
+
BRIGHT_MAGENTA = "\033[95m"
|
|
41
|
+
BRIGHT_CYAN = "\033[96m"
|
|
42
|
+
BRIGHT_WHITE = "\033[97m"
|
|
43
|
+
|
|
44
|
+
# Bright background colors
|
|
45
|
+
BG_BRIGHT_BLACK = "\033[100m"
|
|
46
|
+
BG_BRIGHT_RED = "\033[101m"
|
|
47
|
+
BG_BRIGHT_GREEN = "\033[102m"
|
|
48
|
+
BG_BRIGHT_YELLOW = "\033[103m"
|
|
49
|
+
BG_BRIGHT_BLUE = "\033[104m"
|
|
50
|
+
BG_BRIGHT_MAGENTA = "\033[105m"
|
|
51
|
+
BG_BRIGHT_CYAN = "\033[106m"
|
|
52
|
+
BG_BRIGHT_WHITE = "\033[107m"
|
|
53
|
+
|
|
54
|
+
# Text styles
|
|
55
|
+
BOLD = "\033[1m"
|
|
56
|
+
DIM = "\033[2m"
|
|
57
|
+
ITALIC = "\033[3m"
|
|
58
|
+
UNDERLINE = "\033[4m"
|
|
59
|
+
BLINK = "\033[5m"
|
|
60
|
+
REVERSE = "\033[7m"
|
|
61
|
+
HIDDEN = "\033[8m"
|
|
62
|
+
STRIKE = "\033[9m"
|
|
63
|
+
DOUBLE_UNDERLINE = "\033[21m"
|
|
64
|
+
|
|
65
|
+
# Special effects
|
|
66
|
+
FRAME = "\033[51m"
|
|
67
|
+
ENCIRCLE = "\033[52m"
|
|
68
|
+
OVERLINE = "\033[53m"
|
|
69
|
+
|
|
70
|
+
# Extended color combinations
|
|
71
|
+
FIRE = "\033[38;2;255;100;0m"
|
|
72
|
+
ICE = "\033[38;2;150;230;255m"
|
|
73
|
+
GRASS = "\033[38;2;0;200;0m"
|
|
74
|
+
PURPLE = "\033[38;2;160;32;240m"
|
|
75
|
+
GOLD = "\033[38;2;255;215;0m"
|
|
76
|
+
SILVER = "\033[38;2;192;192;192m"
|
|
77
|
+
BRONZE = "\033[38;2;205;127;50m"
|
|
78
|
+
PINK = "\033[38;2;255;192;203m"
|
|
79
|
+
TEAL = "\033[38;2;0;128;128m"
|
|
80
|
+
ORANGE = "\033[38;2;255;165;0m"
|
|
81
|
+
BROWN = "\033[38;2;165;42;42m"
|
|
82
|
+
MAROON = "\033[38;2;128;0;0m"
|
|
83
|
+
NAVY = "\033[38;2;0;0;128m"
|
|
84
|
+
OLIVE = "\033[38;2;128;128;0m"
|
|
85
|
+
|
|
86
|
+
# Gradient colors
|
|
87
|
+
SUNSET_START = "\033[38;2;255;128;0m"
|
|
88
|
+
SUNSET_END = "\033[38;2;255;0;128m"
|
|
89
|
+
OCEAN_START = "\033[38;2;0;255;255m"
|
|
90
|
+
OCEAN_END = "\033[38;2;0;0;255m"
|
|
91
|
+
FOREST_START = "\033[38;2;34;139;34m"
|
|
92
|
+
FOREST_END = "\033[38;2;0;100;0m"
|
|
93
|
+
|
|
94
|
+
# Special background combinations
|
|
95
|
+
BG_FIRE = "\033[48;2;255;100;0m"
|
|
96
|
+
BG_ICE = "\033[48;2;150;230;255m"
|
|
97
|
+
BG_GRASS = "\033[48;2;0;200;0m"
|
|
98
|
+
BG_PURPLE = "\033[48;2;160;32;240m"
|
|
99
|
+
BG_GOLD = "\033[48;2;255;215;0m"
|
|
100
|
+
BG_SILVER = "\033[48;2;192;192;192m"
|
|
101
|
+
BG_BRONZE = "\033[48;2;205;127;50m"
|
|
102
|
+
BG_PINK = "\033[48;2;255;192;203m"
|
|
103
|
+
BG_TEAL = "\033[48;2;0;128;128m"
|
|
104
|
+
BG_ORANGE = "\033[48;2;255;165;0m"
|
|
105
|
+
BG_BROWN = "\033[48;2;165;42;42m"
|
|
106
|
+
BG_MAROON = "\033[48;2;128;0;0m"
|
|
107
|
+
BG_NAVY = "\033[48;2;0;0;128m"
|
|
108
|
+
BG_OLIVE = "\033[48;2;128;128;0m"
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def rgb(r: int, g: int, b: int, background: bool = False) -> str:
|
|
112
|
+
"""Create RGB color code."""
|
|
113
|
+
if background:
|
|
114
|
+
return f"\033[48;2;{r};{g};{b}m"
|
|
115
|
+
return f"\033[38;2;{r};{g};{b}m"
|
|
116
|
+
|
|
117
|
+
@staticmethod
|
|
118
|
+
def color_256(code: int, background: bool = False) -> str:
|
|
119
|
+
"""Create 256-color code."""
|
|
120
|
+
if background:
|
|
121
|
+
return f"\033[48;5;{code}m"
|
|
122
|
+
return f"\033[38;5;{code}m"
|
|
123
|
+
|
|
124
|
+
@staticmethod
|
|
125
|
+
def combine(*styles: str) -> str:
|
|
126
|
+
"""Combine multiple color and style codes."""
|
|
127
|
+
return "".join(styles)
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def gradient(text: str, start_rgb: tuple, end_rgb: tuple) -> str:
|
|
131
|
+
"""Create a gradient effect across text."""
|
|
132
|
+
if len(text) < 2:
|
|
133
|
+
return LogColors.rgb(*start_rgb) + text
|
|
134
|
+
|
|
135
|
+
result = []
|
|
136
|
+
for i, char in enumerate(text):
|
|
137
|
+
r = int(start_rgb[0] + (end_rgb[0] - start_rgb[0]) * i / (len(text) - 1))
|
|
138
|
+
g = int(start_rgb[1] + (end_rgb[1] - start_rgb[1]) * i / (len(text) - 1))
|
|
139
|
+
b = int(start_rgb[2] + (end_rgb[2] - start_rgb[2]) * i / (len(text) - 1))
|
|
140
|
+
result.append(f"{LogColors.rgb(r, g, b)}{char}")
|
|
141
|
+
|
|
142
|
+
return "".join(result) + LogColors.RESET
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def rainbow(text: str) -> str:
|
|
146
|
+
"""Apply rainbow colors to text."""
|
|
147
|
+
colors = [
|
|
148
|
+
(255, 0, 0), # Red
|
|
149
|
+
(255, 127, 0), # Orange
|
|
150
|
+
(255, 255, 0), # Yellow
|
|
151
|
+
(0, 255, 0), # Green
|
|
152
|
+
(0, 0, 255), # Blue
|
|
153
|
+
(75, 0, 130), # Indigo
|
|
154
|
+
(148, 0, 211) # Violet
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
result = []
|
|
158
|
+
for i, char in enumerate(text):
|
|
159
|
+
color = colors[i % len(colors)]
|
|
160
|
+
result.append(f"{LogColors.rgb(*color)}{char}")
|
|
161
|
+
|
|
162
|
+
return "".join(result) + LogColors.RESET
|
|
163
|
+
|
|
164
|
+
@staticmethod
|
|
165
|
+
def animate(text: str, effect: str = "blink") -> str:
|
|
166
|
+
"""Apply animation effects to text."""
|
|
167
|
+
effects = {
|
|
168
|
+
"blink": LogColors.BLINK,
|
|
169
|
+
"reverse": LogColors.REVERSE,
|
|
170
|
+
"bold_blink": LogColors.combine(LogColors.BOLD, LogColors.BLINK),
|
|
171
|
+
"frame_blink": LogColors.combine(LogColors.FRAME, LogColors.BLINK),
|
|
172
|
+
"encircle_blink": LogColors.combine(LogColors.ENCIRCLE, LogColors.BLINK)
|
|
173
|
+
}
|
|
174
|
+
return effects.get(effect, LogColors.BLINK) + text + LogColors.RESET
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class LogTheme:
|
|
178
|
+
"""Pre-defined color themes and combinations."""
|
|
179
|
+
|
|
180
|
+
@staticmethod
|
|
181
|
+
def get_theme(name: str) -> str:
|
|
182
|
+
themes = {
|
|
183
|
+
# Status themes
|
|
184
|
+
"success": LogColors.combine(LogColors.BRIGHT_GREEN, LogColors.BOLD),
|
|
185
|
+
"error": LogColors.combine(LogColors.BRIGHT_RED, LogColors.BOLD),
|
|
186
|
+
"warning": LogColors.combine(LogColors.BRIGHT_YELLOW, LogColors.BOLD),
|
|
187
|
+
"info": LogColors.combine(LogColors.BRIGHT_BLUE, LogColors.BOLD),
|
|
188
|
+
"debug": LogColors.combine(LogColors.DIM, LogColors.WHITE),
|
|
189
|
+
"critical": LogColors.combine(LogColors.BG_RED, LogColors.WHITE, LogColors.BOLD),
|
|
190
|
+
|
|
191
|
+
# Special themes
|
|
192
|
+
"header": LogColors.combine(LogColors.BRIGHT_WHITE, LogColors.BOLD, LogColors.UNDERLINE),
|
|
193
|
+
"highlight": LogColors.combine(LogColors.BLACK, LogColors.BG_BRIGHT_YELLOW),
|
|
194
|
+
"important": LogColors.combine(LogColors.BRIGHT_RED, LogColors.BOLD, LogColors.UNDERLINE),
|
|
195
|
+
"subtle": LogColors.combine(LogColors.DIM, LogColors.BRIGHT_BLACK),
|
|
196
|
+
|
|
197
|
+
# UI themes
|
|
198
|
+
"title": LogColors.combine(LogColors.BRIGHT_WHITE, LogColors.BOLD, LogColors.UNDERLINE),
|
|
199
|
+
"subtitle": LogColors.combine(LogColors.BRIGHT_WHITE, LogColors.DIM),
|
|
200
|
+
"link": LogColors.combine(LogColors.BLUE, LogColors.UNDERLINE),
|
|
201
|
+
"code": LogColors.combine(LogColors.BRIGHT_BLACK, LogColors.BG_WHITE),
|
|
202
|
+
|
|
203
|
+
# Data themes
|
|
204
|
+
"number": LogColors.combine(LogColors.BRIGHT_CYAN, LogColors.BOLD),
|
|
205
|
+
"string": LogColors.combine(LogColors.BRIGHT_GREEN),
|
|
206
|
+
"boolean": LogColors.combine(LogColors.BRIGHT_YELLOW, LogColors.BOLD),
|
|
207
|
+
"null": LogColors.combine(LogColors.DIM, LogColors.ITALIC),
|
|
208
|
+
|
|
209
|
+
# Custom themes
|
|
210
|
+
"fire": LogColors.combine(LogColors.FIRE, LogColors.BOLD),
|
|
211
|
+
"ice": LogColors.combine(LogColors.ICE, LogColors.BOLD),
|
|
212
|
+
"nature": LogColors.combine(LogColors.GRASS, LogColors.BOLD),
|
|
213
|
+
"royal": LogColors.combine(LogColors.PURPLE, LogColors.BOLD),
|
|
214
|
+
"precious": LogColors.combine(LogColors.GOLD, LogColors.BOLD),
|
|
215
|
+
|
|
216
|
+
# Gradient themes
|
|
217
|
+
"sunset": LogColors.combine(LogColors.SUNSET_START, LogColors.SUNSET_END),
|
|
218
|
+
"ocean": LogColors.combine(LogColors.OCEAN_START, LogColors.OCEAN_END),
|
|
219
|
+
"forest": LogColors.combine(LogColors.FOREST_START, LogColors.FOREST_END),
|
|
220
|
+
}
|
|
221
|
+
return themes.get(name, LogColors.RESET)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
# Define level colors after both classes are defined
|
|
225
|
+
LogColors.LEVEL_COLORS = {
|
|
226
|
+
"DEBUG": LogTheme.get_theme("debug"),
|
|
227
|
+
"INFO": LogTheme.get_theme("info"),
|
|
228
|
+
"WARNING": LogTheme.get_theme("warning"),
|
|
229
|
+
"ERROR": LogTheme.get_theme("error"),
|
|
230
|
+
"CRITICAL": LogTheme.get_theme("critical")
|
|
231
|
+
}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Dict
|
|
3
|
+
|
|
4
|
+
class LogFormat:
|
|
5
|
+
# Basic formats
|
|
6
|
+
MINIMAL = "[{time}] {level} {message}"
|
|
7
|
+
STANDARD = "[{time}] {level} {name}: {message}"
|
|
8
|
+
DETAILED = "[{time}] {level} {name} [{file}:{line}] >>> {message}"
|
|
9
|
+
SIMPLE = "{message}"
|
|
10
|
+
COMPACT = "{time} {level}: {message}"
|
|
11
|
+
|
|
12
|
+
# Modern Styles
|
|
13
|
+
MODERN = " {time} | {level} | {name} | {message}"
|
|
14
|
+
MODERN_EMOJI = "{emoji} [{time}] {level} {message}"
|
|
15
|
+
MODERN_CLEAN = "{time} {level} {message}"
|
|
16
|
+
MODERN_BRACKET = "【{time}】「{level}」{message}"
|
|
17
|
+
MODERN_PLUS = "⊕ {time} ⊕ {level} ⊕ {message}"
|
|
18
|
+
MODERN_DOT = "• {time} • {level} • {message}"
|
|
19
|
+
MODERN_ARROW = "→ {time} → {level} → {message}"
|
|
20
|
+
|
|
21
|
+
# Boxed Styles
|
|
22
|
+
BOXED = """
|
|
23
|
+
╭─────────────────────╮
|
|
24
|
+
│ [{time}]
|
|
25
|
+
│ {level} - {name}
|
|
26
|
+
│ {message}
|
|
27
|
+
╰─────────────────────╯"""
|
|
28
|
+
|
|
29
|
+
DOUBLE_BOX = """
|
|
30
|
+
╔══════════════════════╗
|
|
31
|
+
║ {level} @ {time}
|
|
32
|
+
║ {name}
|
|
33
|
+
║ {message}
|
|
34
|
+
╚══════════════════════╝"""
|
|
35
|
+
|
|
36
|
+
ROUNDED_BOX = """
|
|
37
|
+
╭──────────────────────╮
|
|
38
|
+
│ {time} • {level}
|
|
39
|
+
├──────────────────────┤
|
|
40
|
+
│ {message}
|
|
41
|
+
╰──────────────────────╯"""
|
|
42
|
+
|
|
43
|
+
RAINBOW_BOX = """
|
|
44
|
+
{level} - {time}
|
|
45
|
+
{name}: {message}
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
HEAVY_BOX = """
|
|
49
|
+
┏━━━━━━━━━━━━━━━━━━━━┓
|
|
50
|
+
┃ {time}
|
|
51
|
+
┃ {level} | {name}
|
|
52
|
+
┃ {message}
|
|
53
|
+
┗━━━━━━━━━━━━━━━━━━━━┛"""
|
|
54
|
+
|
|
55
|
+
DOTTED_BOX = """
|
|
56
|
+
╭┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈╮
|
|
57
|
+
┊ {time} | {level}
|
|
58
|
+
┊ {message}
|
|
59
|
+
╰┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈╯"""
|
|
60
|
+
|
|
61
|
+
# Debug & Development
|
|
62
|
+
DEBUG = "[{time}] {level} {name} ({file}:{line}) {message}"
|
|
63
|
+
DEBUG_FULL = """
|
|
64
|
+
┌─ Debug Info ─┐
|
|
65
|
+
│ Time: {time}
|
|
66
|
+
│ Level: {level}
|
|
67
|
+
│ Name: {name}
|
|
68
|
+
│ File: {file}:{line}
|
|
69
|
+
│ Message: {message}
|
|
70
|
+
└──────────────┘"""
|
|
71
|
+
|
|
72
|
+
TRACE = """
|
|
73
|
+
Trace Details:
|
|
74
|
+
Time: {time}
|
|
75
|
+
Level: {level}
|
|
76
|
+
Location: {file}:{line}
|
|
77
|
+
Message: {message}"""
|
|
78
|
+
|
|
79
|
+
DEBUG_COMPACT = "[DBG][{time}] {message} @{file}:{line}"
|
|
80
|
+
DEBUG_EXTENDED = """
|
|
81
|
+
🔍 Debug Information 🔍
|
|
82
|
+
⏰ Time: {time}
|
|
83
|
+
📊 Level: {level}
|
|
84
|
+
📂 File: {file}
|
|
85
|
+
📍 Line: {line}
|
|
86
|
+
💬 Message: {message}
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
# Error Formats
|
|
90
|
+
ERROR = "!!! {level} !!! [{time}] {name} - {message}"
|
|
91
|
+
ERROR_DETAILED = """
|
|
92
|
+
{level} ALERT
|
|
93
|
+
Time: {time}
|
|
94
|
+
Component: {name}
|
|
95
|
+
Location: {file}:{line}
|
|
96
|
+
Message: {message}"""
|
|
97
|
+
|
|
98
|
+
ERROR_COMPACT = " [{time}] {level}: {message}"
|
|
99
|
+
ERROR_EMOJI = "❌ {time} | {level} | {message}"
|
|
100
|
+
ERROR_BLOCK = """
|
|
101
|
+
█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
|
|
102
|
+
█ ERROR @ {time}
|
|
103
|
+
█ {message}
|
|
104
|
+
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█"""
|
|
105
|
+
|
|
106
|
+
# Status & Progress
|
|
107
|
+
STATUS = """
|
|
108
|
+
Status Update:
|
|
109
|
+
Time: {time}
|
|
110
|
+
Level: {level}
|
|
111
|
+
Component: {name}
|
|
112
|
+
Message: {message}"""
|
|
113
|
+
|
|
114
|
+
PROGRESS = """
|
|
115
|
+
[{time}] Progress Report
|
|
116
|
+
├─ Level: {level}
|
|
117
|
+
├─ Component: {name}
|
|
118
|
+
└─ Status: {message}"""
|
|
119
|
+
|
|
120
|
+
PROGRESS_SIMPLE = "► {time} | {level} | {message}"
|
|
121
|
+
PROGRESS_BAR = "[{progress_bar}] {percentage}% - {message}"
|
|
122
|
+
|
|
123
|
+
# Network & API
|
|
124
|
+
HTTP = """
|
|
125
|
+
API {level} [{time}]
|
|
126
|
+
Endpoint: {name}
|
|
127
|
+
Response: {message}"""
|
|
128
|
+
|
|
129
|
+
REQUEST = """
|
|
130
|
+
→ Incoming Request
|
|
131
|
+
Time: {time}
|
|
132
|
+
Level: {level}
|
|
133
|
+
API: {name}
|
|
134
|
+
Details: {message}"""
|
|
135
|
+
|
|
136
|
+
RESPONSE = """
|
|
137
|
+
← Outgoing Response
|
|
138
|
+
Time: {time}
|
|
139
|
+
Level: {level}
|
|
140
|
+
API: {name}
|
|
141
|
+
Details: {message}"""
|
|
142
|
+
|
|
143
|
+
API_COMPACT = "{method} {url} - {status_code} ({time})"
|
|
144
|
+
API_DETAILED = """
|
|
145
|
+
┌── API Call ──────────
|
|
146
|
+
│ Time: {time}
|
|
147
|
+
│ Method: {method}
|
|
148
|
+
│ URL: {url}
|
|
149
|
+
│ Status: {status_code}
|
|
150
|
+
│ Response: {message}
|
|
151
|
+
└────────────────────"""
|
|
152
|
+
|
|
153
|
+
# System & Metrics
|
|
154
|
+
SYSTEM = """
|
|
155
|
+
System Event
|
|
156
|
+
{time}
|
|
157
|
+
{level}
|
|
158
|
+
{name}
|
|
159
|
+
{message}"""
|
|
160
|
+
|
|
161
|
+
METRIC = """
|
|
162
|
+
Metric Report [{time}]
|
|
163
|
+
Level: {level}
|
|
164
|
+
Source: {name}
|
|
165
|
+
Value: {message}"""
|
|
166
|
+
|
|
167
|
+
METRIC_COMPACT = "[METRIC] {name}={value} {units}"
|
|
168
|
+
METRIC_JSON = '{{"metric":"{name}","value":{value},"time":"{time}"}}'
|
|
169
|
+
|
|
170
|
+
# Security & Audit
|
|
171
|
+
SECURITY = """
|
|
172
|
+
Security Event
|
|
173
|
+
Time: {time}
|
|
174
|
+
Level: {level}
|
|
175
|
+
Source: {name}
|
|
176
|
+
Event: {message}"""
|
|
177
|
+
|
|
178
|
+
AUDIT = """
|
|
179
|
+
Audit Log Entry
|
|
180
|
+
Time: {time}
|
|
181
|
+
Level: {level}
|
|
182
|
+
Component: {name}
|
|
183
|
+
Action: {message}"""
|
|
184
|
+
|
|
185
|
+
SECURITY_ALERT = """
|
|
186
|
+
🚨 SECURITY ALERT 🚨
|
|
187
|
+
Time: {time}
|
|
188
|
+
Level: {level}
|
|
189
|
+
Details: {message}
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
# Special Formats
|
|
193
|
+
RAINBOW = " {time} {level} {message}"
|
|
194
|
+
MINIMAL_EMOJI = "{emoji} {message}"
|
|
195
|
+
TIMESTAMP = "{time} {message}"
|
|
196
|
+
COMPONENT = "[{name}] {message}"
|
|
197
|
+
HASH = "#{hash} | {time} | {message}"
|
|
198
|
+
TAG = "@{tag} | {time} | {message}"
|
|
199
|
+
|
|
200
|
+
# Data Formats
|
|
201
|
+
JSON = '{{"time":"{time}","level":"{level}","name":"{name}","message":"{message}"}}'
|
|
202
|
+
JSON_PRETTY = """{
|
|
203
|
+
"time": "{time}",
|
|
204
|
+
"level": "{level}",
|
|
205
|
+
"name": "{name}",
|
|
206
|
+
"message": "{message}"
|
|
207
|
+
}"""
|
|
208
|
+
|
|
209
|
+
XML = """<log>
|
|
210
|
+
<time>{time}</time>
|
|
211
|
+
<level>{level}</level>
|
|
212
|
+
<name>{name}</name>
|
|
213
|
+
<message>{message}</message>
|
|
214
|
+
</log>"""
|
|
215
|
+
|
|
216
|
+
YAML = """---
|
|
217
|
+
time: {time}
|
|
218
|
+
level: {level}
|
|
219
|
+
name: {name}
|
|
220
|
+
message: {message}
|
|
221
|
+
"""
|
|
222
|
+
|
|
223
|
+
# Documentation Formats
|
|
224
|
+
MARKDOWN = """
|
|
225
|
+
## Log Entry
|
|
226
|
+
- **Time:** {time}
|
|
227
|
+
- **Level:** {level}
|
|
228
|
+
- **Component:** {name}
|
|
229
|
+
- **Message:** {message}
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
RST = """
|
|
233
|
+
Log Entry
|
|
234
|
+
=========
|
|
235
|
+
:Time: {time}
|
|
236
|
+
:Level: {level}
|
|
237
|
+
:Component: {name}
|
|
238
|
+
:Message: {message}
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
HTML = """<div class="log-entry">
|
|
242
|
+
<span class="time">{time}</span>
|
|
243
|
+
<span class="level">{level}</span>
|
|
244
|
+
<span class="name">{name}</span>
|
|
245
|
+
<span class="message">{message}</span>
|
|
246
|
+
</div>"""
|
|
247
|
+
|
|
248
|
+
# Template registry
|
|
249
|
+
TEMPLATES = {
|
|
250
|
+
# Basic formats
|
|
251
|
+
"minimal": MINIMAL,
|
|
252
|
+
"standard": STANDARD,
|
|
253
|
+
"detailed": DETAILED,
|
|
254
|
+
"simple": SIMPLE,
|
|
255
|
+
"compact": COMPACT,
|
|
256
|
+
|
|
257
|
+
# Modern styles
|
|
258
|
+
"modern": MODERN,
|
|
259
|
+
"modern_emoji": MODERN_EMOJI,
|
|
260
|
+
"modern_clean": MODERN_CLEAN,
|
|
261
|
+
"modern_bracket": MODERN_BRACKET,
|
|
262
|
+
"modern_plus": MODERN_PLUS,
|
|
263
|
+
"modern_dot": MODERN_DOT,
|
|
264
|
+
"modern_arrow": MODERN_ARROW,
|
|
265
|
+
|
|
266
|
+
# Boxed styles
|
|
267
|
+
"boxed": BOXED,
|
|
268
|
+
"double_box": DOUBLE_BOX,
|
|
269
|
+
"rounded_box": ROUNDED_BOX,
|
|
270
|
+
"rainbow_box": RAINBOW_BOX,
|
|
271
|
+
"heavy_box": HEAVY_BOX,
|
|
272
|
+
"dotted_box": DOTTED_BOX,
|
|
273
|
+
|
|
274
|
+
# Debug formats
|
|
275
|
+
"debug": DEBUG,
|
|
276
|
+
"debug_full": DEBUG_FULL,
|
|
277
|
+
"trace": TRACE,
|
|
278
|
+
"debug_compact": DEBUG_COMPACT,
|
|
279
|
+
"debug_extended": DEBUG_EXTENDED,
|
|
280
|
+
|
|
281
|
+
# Error formats
|
|
282
|
+
"error": ERROR,
|
|
283
|
+
"error_detailed": ERROR_DETAILED,
|
|
284
|
+
"error_compact": ERROR_COMPACT,
|
|
285
|
+
"error_emoji": ERROR_EMOJI,
|
|
286
|
+
"error_block": ERROR_BLOCK,
|
|
287
|
+
|
|
288
|
+
# Status formats
|
|
289
|
+
"status": STATUS,
|
|
290
|
+
"progress": PROGRESS,
|
|
291
|
+
"progress_simple": PROGRESS_SIMPLE,
|
|
292
|
+
"progress_bar": PROGRESS_BAR,
|
|
293
|
+
|
|
294
|
+
# Network formats
|
|
295
|
+
"http": HTTP,
|
|
296
|
+
"request": REQUEST,
|
|
297
|
+
"response": RESPONSE,
|
|
298
|
+
"api_compact": API_COMPACT,
|
|
299
|
+
"api_detailed": API_DETAILED,
|
|
300
|
+
|
|
301
|
+
# System formats
|
|
302
|
+
"system": SYSTEM,
|
|
303
|
+
"metric": METRIC,
|
|
304
|
+
"metric_compact": METRIC_COMPACT,
|
|
305
|
+
"metric_json": METRIC_JSON,
|
|
306
|
+
|
|
307
|
+
# Security formats
|
|
308
|
+
"security": SECURITY,
|
|
309
|
+
"audit": AUDIT,
|
|
310
|
+
"security_alert": SECURITY_ALERT,
|
|
311
|
+
|
|
312
|
+
# Special formats
|
|
313
|
+
"rainbow": RAINBOW,
|
|
314
|
+
"minimal_emoji": MINIMAL_EMOJI,
|
|
315
|
+
"timestamp": TIMESTAMP,
|
|
316
|
+
"component": COMPONENT,
|
|
317
|
+
"hash": HASH,
|
|
318
|
+
"tag": TAG,
|
|
319
|
+
|
|
320
|
+
# Data formats
|
|
321
|
+
"json": JSON,
|
|
322
|
+
"json_pretty": JSON_PRETTY,
|
|
323
|
+
"xml": XML,
|
|
324
|
+
"yaml": YAML,
|
|
325
|
+
|
|
326
|
+
# Documentation formats
|
|
327
|
+
"markdown": MARKDOWN,
|
|
328
|
+
"rst": RST,
|
|
329
|
+
"html": HTML,
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@staticmethod
|
|
333
|
+
def create_custom(template: str) -> str:
|
|
334
|
+
"""Create a custom log format template."""
|
|
335
|
+
try:
|
|
336
|
+
# Test if the template is valid by formatting with dummy data
|
|
337
|
+
dummy_data = {
|
|
338
|
+
"time": "2024-01-01 00:00:00",
|
|
339
|
+
"level": "INFO",
|
|
340
|
+
"name": "test",
|
|
341
|
+
"message": "test message",
|
|
342
|
+
"file": "test.py",
|
|
343
|
+
"line": 1,
|
|
344
|
+
"emoji": "✨",
|
|
345
|
+
"progress_bar": "==========",
|
|
346
|
+
"percentage": 100,
|
|
347
|
+
"method": "GET",
|
|
348
|
+
"url": "/test",
|
|
349
|
+
"status_code": 200,
|
|
350
|
+
"value": 42,
|
|
351
|
+
"units": "ms",
|
|
352
|
+
"hash": "abc123",
|
|
353
|
+
"tag": "test"
|
|
354
|
+
}
|
|
355
|
+
template.format(**dummy_data)
|
|
356
|
+
return template
|
|
357
|
+
except KeyError as e:
|
|
358
|
+
raise ValueError(f"Invalid format template. Missing key: {e}")
|
|
359
|
+
except Exception as e:
|
|
360
|
+
raise ValueError(f"Invalid format template: {e}")
|
|
361
|
+
|
|
362
|
+
@staticmethod
|
|
363
|
+
def get_format(format_name: str) -> str:
|
|
364
|
+
"""Get a predefined format template by name."""
|
|
365
|
+
if format_name in LogFormat.TEMPLATES:
|
|
366
|
+
return LogFormat.TEMPLATES[format_name]
|
|
367
|
+
raise ValueError(f"Unknown format: {format_name}")
|
|
368
|
+
|
|
369
|
+
@staticmethod
|
|
370
|
+
def register_template(name: str, template: str):
|
|
371
|
+
"""Register a new format template."""
|
|
372
|
+
if name in LogFormat.TEMPLATES:
|
|
373
|
+
raise ValueError(f"Format template '{name}' already exists")
|
|
374
|
+
|
|
375
|
+
# Validate template before registering
|
|
376
|
+
LogFormat.create_custom(template)
|
|
377
|
+
LogFormat.TEMPLATES[name] = template
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import textwrap
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
class TextStyle:
|
|
5
|
+
@staticmethod
|
|
6
|
+
def wrap(text: str, width: int = 80, indent: str = "") -> str:
|
|
7
|
+
"""Wrap text to specified width with optional indentation."""
|
|
8
|
+
return textwrap.fill(text, width=width, initial_indent=indent,
|
|
9
|
+
subsequent_indent=indent)
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def truncate(text: str, max_length: int, suffix: str = "...") -> str:
|
|
13
|
+
"""Truncate text to maximum length with suffix."""
|
|
14
|
+
if len(text) <= max_length:
|
|
15
|
+
return text
|
|
16
|
+
return text[:max_length - len(suffix)] + suffix
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def pad(text: str, width: int, align: str = "left",
|
|
20
|
+
fill_char: str = " ") -> str:
|
|
21
|
+
"""Pad text to specified width with alignment."""
|
|
22
|
+
if align == "left":
|
|
23
|
+
return text.ljust(width, fill_char)
|
|
24
|
+
elif align == "right":
|
|
25
|
+
return text.rjust(width, fill_char)
|
|
26
|
+
elif align == "center":
|
|
27
|
+
return text.center(width, fill_char)
|
|
28
|
+
raise ValueError(f"Invalid alignment: {align}")
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def indent(text: str, prefix: str = " ", predicate: Optional[callable] = None) -> str:
|
|
32
|
+
"""Indent text lines with prefix based on optional predicate."""
|
|
33
|
+
lines = text.splitlines(True)
|
|
34
|
+
if predicate is None:
|
|
35
|
+
predicate = bool
|
|
36
|
+
|
|
37
|
+
def should_indent(line):
|
|
38
|
+
return predicate(line)
|
|
39
|
+
|
|
40
|
+
return "".join(prefix + line if should_indent(line) else line
|
|
41
|
+
for line in lines)
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def highlight(text: str, substring: str, color: str) -> str:
|
|
45
|
+
"""Highlight substring within text using ANSI color codes."""
|
|
46
|
+
from ..styles.colors import LogColors
|
|
47
|
+
if not substring:
|
|
48
|
+
return text
|
|
49
|
+
|
|
50
|
+
parts = text.split(substring)
|
|
51
|
+
highlighted = f"{color}{substring}{LogColors.RESET}"
|
|
52
|
+
return highlighted.join(parts)
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def table(headers: list, rows: list, padding: int = 1) -> str:
|
|
56
|
+
"""Create a formatted table with headers and rows."""
|
|
57
|
+
if not rows:
|
|
58
|
+
return ""
|
|
59
|
+
|
|
60
|
+
# Calculate column widths
|
|
61
|
+
widths = [max(len(str(row[i])) for row in [headers] + rows)
|
|
62
|
+
for i in range(len(headers))]
|
|
63
|
+
|
|
64
|
+
# Create separator line
|
|
65
|
+
separator = "+" + "+".join("-" * (w + 2 * padding) for w in widths) + "+"
|
|
66
|
+
|
|
67
|
+
# Format header
|
|
68
|
+
header = "|" + "|".join(
|
|
69
|
+
str(h).center(w + 2 * padding) for h, w in zip(headers, widths)
|
|
70
|
+
) + "|"
|
|
71
|
+
|
|
72
|
+
# Format rows
|
|
73
|
+
formatted_rows = []
|
|
74
|
+
for row in rows:
|
|
75
|
+
formatted_row = "|" + "|".join(
|
|
76
|
+
str(cell).ljust(w + 2 * padding) for cell, w in zip(row, widths)
|
|
77
|
+
) + "|"
|
|
78
|
+
formatted_rows.append(formatted_row)
|
|
79
|
+
|
|
80
|
+
# Combine all parts
|
|
81
|
+
return "\n".join([
|
|
82
|
+
separator,
|
|
83
|
+
header,
|
|
84
|
+
separator,
|
|
85
|
+
*formatted_rows,
|
|
86
|
+
separator
|
|
87
|
+
])
|