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.

Files changed (144) hide show
  1. webscout/AIauto.py +191 -191
  2. webscout/AIbase.py +122 -122
  3. webscout/AIutel.py +440 -440
  4. webscout/Bard.py +343 -161
  5. webscout/DWEBS.py +489 -492
  6. webscout/Extra/YTToolkit/YTdownloader.py +995 -995
  7. webscout/Extra/YTToolkit/__init__.py +2 -2
  8. webscout/Extra/YTToolkit/transcriber.py +476 -479
  9. webscout/Extra/YTToolkit/ytapi/channel.py +307 -307
  10. webscout/Extra/YTToolkit/ytapi/playlist.py +58 -58
  11. webscout/Extra/YTToolkit/ytapi/pool.py +7 -7
  12. webscout/Extra/YTToolkit/ytapi/utils.py +62 -62
  13. webscout/Extra/YTToolkit/ytapi/video.py +103 -103
  14. webscout/Extra/autocoder/__init__.py +9 -9
  15. webscout/Extra/autocoder/autocoder_utiles.py +199 -199
  16. webscout/Extra/autocoder/rawdog.py +5 -7
  17. webscout/Extra/autollama.py +230 -230
  18. webscout/Extra/gguf.py +3 -3
  19. webscout/Extra/weather.py +171 -171
  20. webscout/LLM.py +442 -442
  21. webscout/Litlogger/__init__.py +67 -681
  22. webscout/Litlogger/core/__init__.py +6 -0
  23. webscout/Litlogger/core/level.py +20 -0
  24. webscout/Litlogger/core/logger.py +123 -0
  25. webscout/Litlogger/handlers/__init__.py +12 -0
  26. webscout/Litlogger/handlers/console.py +50 -0
  27. webscout/Litlogger/handlers/file.py +143 -0
  28. webscout/Litlogger/handlers/network.py +174 -0
  29. webscout/Litlogger/styles/__init__.py +7 -0
  30. webscout/Litlogger/styles/colors.py +231 -0
  31. webscout/Litlogger/styles/formats.py +377 -0
  32. webscout/Litlogger/styles/text.py +87 -0
  33. webscout/Litlogger/utils/__init__.py +6 -0
  34. webscout/Litlogger/utils/detectors.py +154 -0
  35. webscout/Litlogger/utils/formatters.py +200 -0
  36. webscout/Provider/AISEARCH/DeepFind.py +250 -250
  37. webscout/Provider/Blackboxai.py +3 -3
  38. webscout/Provider/ChatGPTGratis.py +226 -0
  39. webscout/Provider/Cloudflare.py +3 -4
  40. webscout/Provider/DeepSeek.py +218 -0
  41. webscout/Provider/Deepinfra.py +3 -3
  42. webscout/Provider/Free2GPT.py +131 -124
  43. webscout/Provider/Gemini.py +100 -115
  44. webscout/Provider/Glider.py +3 -3
  45. webscout/Provider/Groq.py +5 -1
  46. webscout/Provider/Jadve.py +3 -3
  47. webscout/Provider/Marcus.py +191 -192
  48. webscout/Provider/Netwrck.py +3 -3
  49. webscout/Provider/PI.py +2 -2
  50. webscout/Provider/PizzaGPT.py +2 -3
  51. webscout/Provider/QwenLM.py +311 -0
  52. webscout/Provider/TTI/AiForce/__init__.py +22 -22
  53. webscout/Provider/TTI/AiForce/async_aiforce.py +257 -257
  54. webscout/Provider/TTI/AiForce/sync_aiforce.py +242 -242
  55. webscout/Provider/TTI/Nexra/__init__.py +22 -22
  56. webscout/Provider/TTI/Nexra/async_nexra.py +286 -286
  57. webscout/Provider/TTI/Nexra/sync_nexra.py +258 -258
  58. webscout/Provider/TTI/PollinationsAI/__init__.py +23 -23
  59. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +330 -330
  60. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +285 -285
  61. webscout/Provider/TTI/artbit/__init__.py +22 -22
  62. webscout/Provider/TTI/artbit/async_artbit.py +184 -184
  63. webscout/Provider/TTI/artbit/sync_artbit.py +176 -176
  64. webscout/Provider/TTI/blackbox/__init__.py +4 -4
  65. webscout/Provider/TTI/blackbox/async_blackbox.py +212 -212
  66. webscout/Provider/TTI/blackbox/sync_blackbox.py +199 -199
  67. webscout/Provider/TTI/deepinfra/__init__.py +4 -4
  68. webscout/Provider/TTI/deepinfra/async_deepinfra.py +227 -227
  69. webscout/Provider/TTI/deepinfra/sync_deepinfra.py +199 -199
  70. webscout/Provider/TTI/huggingface/__init__.py +22 -22
  71. webscout/Provider/TTI/huggingface/async_huggingface.py +199 -199
  72. webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -195
  73. webscout/Provider/TTI/imgninza/__init__.py +4 -4
  74. webscout/Provider/TTI/imgninza/async_ninza.py +214 -214
  75. webscout/Provider/TTI/imgninza/sync_ninza.py +209 -209
  76. webscout/Provider/TTI/talkai/__init__.py +4 -4
  77. webscout/Provider/TTI/talkai/async_talkai.py +229 -229
  78. webscout/Provider/TTI/talkai/sync_talkai.py +207 -207
  79. webscout/Provider/TTS/deepgram.py +182 -182
  80. webscout/Provider/TTS/elevenlabs.py +136 -136
  81. webscout/Provider/TTS/gesserit.py +150 -150
  82. webscout/Provider/TTS/murfai.py +138 -138
  83. webscout/Provider/TTS/parler.py +133 -134
  84. webscout/Provider/TTS/streamElements.py +360 -360
  85. webscout/Provider/TTS/utils.py +280 -280
  86. webscout/Provider/TTS/voicepod.py +116 -116
  87. webscout/Provider/TextPollinationsAI.py +2 -3
  88. webscout/Provider/WiseCat.py +193 -0
  89. webscout/Provider/__init__.py +144 -134
  90. webscout/Provider/cerebras.py +242 -227
  91. webscout/Provider/chatglm.py +204 -204
  92. webscout/Provider/dgaf.py +2 -3
  93. webscout/Provider/gaurish.py +2 -3
  94. webscout/Provider/geminiapi.py +208 -208
  95. webscout/Provider/granite.py +223 -0
  96. webscout/Provider/hermes.py +218 -218
  97. webscout/Provider/llama3mitril.py +179 -179
  98. webscout/Provider/llamatutor.py +3 -3
  99. webscout/Provider/llmchat.py +2 -3
  100. webscout/Provider/meta.py +794 -794
  101. webscout/Provider/multichat.py +331 -331
  102. webscout/Provider/typegpt.py +359 -359
  103. webscout/Provider/yep.py +2 -2
  104. webscout/__main__.py +5 -5
  105. webscout/cli.py +319 -319
  106. webscout/conversation.py +241 -242
  107. webscout/exceptions.py +328 -328
  108. webscout/litagent/__init__.py +28 -28
  109. webscout/litagent/agent.py +2 -3
  110. webscout/litprinter/__init__.py +0 -58
  111. webscout/scout/__init__.py +8 -8
  112. webscout/scout/core.py +884 -884
  113. webscout/scout/element.py +459 -459
  114. webscout/scout/parsers/__init__.py +69 -69
  115. webscout/scout/parsers/html5lib_parser.py +172 -172
  116. webscout/scout/parsers/html_parser.py +236 -236
  117. webscout/scout/parsers/lxml_parser.py +178 -178
  118. webscout/scout/utils.py +38 -38
  119. webscout/swiftcli/__init__.py +811 -811
  120. webscout/update_checker.py +2 -12
  121. webscout/version.py +1 -1
  122. webscout/webscout_search.py +5 -4
  123. webscout/zeroart/__init__.py +54 -54
  124. webscout/zeroart/base.py +60 -60
  125. webscout/zeroart/effects.py +99 -99
  126. webscout/zeroart/fonts.py +816 -816
  127. {webscout-7.1.dist-info → webscout-7.2.dist-info}/METADATA +4 -3
  128. webscout-7.2.dist-info/RECORD +217 -0
  129. webstoken/__init__.py +30 -30
  130. webstoken/classifier.py +189 -189
  131. webstoken/keywords.py +216 -216
  132. webstoken/language.py +128 -128
  133. webstoken/ner.py +164 -164
  134. webstoken/normalizer.py +35 -35
  135. webstoken/processor.py +77 -77
  136. webstoken/sentiment.py +206 -206
  137. webstoken/stemmer.py +73 -73
  138. webstoken/tagger.py +60 -60
  139. webstoken/tokenizer.py +158 -158
  140. webscout-7.1.dist-info/RECORD +0 -198
  141. {webscout-7.1.dist-info → webscout-7.2.dist-info}/LICENSE.md +0 -0
  142. {webscout-7.1.dist-info → webscout-7.2.dist-info}/WHEEL +0 -0
  143. {webscout-7.1.dist-info → webscout-7.2.dist-info}/entry_points.txt +0 -0
  144. {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
+ ])
@@ -0,0 +1,6 @@
1
+ """Utility functions for log level detection and message formatting."""
2
+
3
+ from .detectors import LevelDetector
4
+ from .formatters import MessageFormatter
5
+
6
+ __all__ = ["LevelDetector", "MessageFormatter"]