webscout 6.3__py3-none-any.whl → 6.5__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 (131) hide show
  1. webscout/AIauto.py +191 -176
  2. webscout/AIbase.py +0 -197
  3. webscout/AIutel.py +441 -1130
  4. webscout/DWEBS.py +189 -35
  5. webscout/{YTdownloader.py → Extra/YTToolkit/YTdownloader.py} +990 -1103
  6. webscout/Extra/YTToolkit/__init__.py +3 -0
  7. webscout/{transcriber.py → Extra/YTToolkit/transcriber.py} +479 -551
  8. webscout/Extra/YTToolkit/ytapi/__init__.py +6 -0
  9. webscout/Extra/YTToolkit/ytapi/channel.py +307 -0
  10. webscout/Extra/YTToolkit/ytapi/errors.py +13 -0
  11. webscout/Extra/YTToolkit/ytapi/extras.py +45 -0
  12. webscout/Extra/YTToolkit/ytapi/https.py +88 -0
  13. webscout/Extra/YTToolkit/ytapi/patterns.py +61 -0
  14. webscout/Extra/YTToolkit/ytapi/playlist.py +59 -0
  15. webscout/Extra/YTToolkit/ytapi/pool.py +8 -0
  16. webscout/Extra/YTToolkit/ytapi/query.py +37 -0
  17. webscout/Extra/YTToolkit/ytapi/stream.py +60 -0
  18. webscout/Extra/YTToolkit/ytapi/utils.py +62 -0
  19. webscout/Extra/YTToolkit/ytapi/video.py +102 -0
  20. webscout/Extra/__init__.py +3 -1
  21. webscout/Extra/autocoder/__init__.py +9 -0
  22. webscout/Extra/autocoder/autocoder_utiles.py +121 -0
  23. webscout/Extra/autocoder/rawdog.py +680 -0
  24. webscout/Extra/autollama.py +246 -195
  25. webscout/Extra/gguf.py +81 -56
  26. webscout/Extra/markdownlite/__init__.py +862 -0
  27. webscout/Extra/weather_ascii.py +2 -2
  28. webscout/LLM.py +206 -43
  29. webscout/Litlogger/__init__.py +681 -0
  30. webscout/Provider/DARKAI.py +1 -1
  31. webscout/Provider/EDITEE.py +1 -1
  32. webscout/Provider/NinjaChat.py +1 -1
  33. webscout/Provider/PI.py +120 -35
  34. webscout/Provider/Perplexity.py +590 -598
  35. webscout/Provider/Reka.py +0 -1
  36. webscout/Provider/RoboCoders.py +206 -0
  37. webscout/Provider/TTI/AiForce/__init__.py +22 -0
  38. webscout/Provider/TTI/AiForce/async_aiforce.py +257 -0
  39. webscout/Provider/TTI/AiForce/sync_aiforce.py +242 -0
  40. webscout/Provider/TTI/Nexra/__init__.py +22 -0
  41. webscout/Provider/TTI/Nexra/async_nexra.py +286 -0
  42. webscout/Provider/TTI/Nexra/sync_nexra.py +258 -0
  43. webscout/Provider/TTI/PollinationsAI/__init__.py +23 -0
  44. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +330 -0
  45. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +285 -0
  46. webscout/Provider/TTI/__init__.py +2 -4
  47. webscout/Provider/TTI/artbit/__init__.py +22 -0
  48. webscout/Provider/TTI/artbit/async_artbit.py +184 -0
  49. webscout/Provider/TTI/artbit/sync_artbit.py +176 -0
  50. webscout/Provider/TTI/blackbox/__init__.py +4 -0
  51. webscout/Provider/TTI/blackbox/async_blackbox.py +212 -0
  52. webscout/Provider/TTI/{blackboximage.py → blackbox/sync_blackbox.py} +199 -153
  53. webscout/Provider/TTI/deepinfra/__init__.py +4 -0
  54. webscout/Provider/TTI/deepinfra/async_deepinfra.py +227 -0
  55. webscout/Provider/TTI/deepinfra/sync_deepinfra.py +199 -0
  56. webscout/Provider/TTI/huggingface/__init__.py +22 -0
  57. webscout/Provider/TTI/huggingface/async_huggingface.py +199 -0
  58. webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -0
  59. webscout/Provider/TTI/imgninza/__init__.py +4 -0
  60. webscout/Provider/TTI/imgninza/async_ninza.py +214 -0
  61. webscout/Provider/TTI/{imgninza.py → imgninza/sync_ninza.py} +209 -136
  62. webscout/Provider/TTI/talkai/__init__.py +4 -0
  63. webscout/Provider/TTI/talkai/async_talkai.py +229 -0
  64. webscout/Provider/TTI/talkai/sync_talkai.py +207 -0
  65. webscout/Provider/TTS/__init__.py +5 -1
  66. webscout/Provider/TTS/deepgram.py +183 -0
  67. webscout/Provider/TTS/elevenlabs.py +137 -0
  68. webscout/Provider/TTS/gesserit.py +151 -0
  69. webscout/Provider/TTS/murfai.py +139 -0
  70. webscout/Provider/TTS/parler.py +134 -107
  71. webscout/Provider/TTS/streamElements.py +360 -275
  72. webscout/Provider/TTS/utils.py +280 -0
  73. webscout/Provider/TTS/voicepod.py +116 -116
  74. webscout/Provider/__init__.py +8 -1
  75. webscout/Provider/askmyai.py +2 -2
  76. webscout/Provider/cerebras.py +227 -219
  77. webscout/Provider/llama3mitril.py +0 -1
  78. webscout/Provider/meta.py +794 -779
  79. webscout/Provider/mhystical.py +176 -0
  80. webscout/Provider/perplexitylabs.py +265 -0
  81. webscout/Provider/twitterclone.py +251 -245
  82. webscout/Provider/typegpt.py +358 -0
  83. webscout/__init__.py +9 -8
  84. webscout/__main__.py +5 -5
  85. webscout/cli.py +252 -280
  86. webscout/conversation.py +227 -0
  87. webscout/exceptions.py +161 -29
  88. webscout/litagent/__init__.py +172 -0
  89. webscout/litprinter/__init__.py +832 -0
  90. webscout/optimizers.py +270 -0
  91. webscout/prompt_manager.py +279 -0
  92. webscout/scout/__init__.py +11 -0
  93. webscout/scout/core.py +884 -0
  94. webscout/scout/element.py +459 -0
  95. webscout/scout/parsers/__init__.py +69 -0
  96. webscout/scout/parsers/html5lib_parser.py +172 -0
  97. webscout/scout/parsers/html_parser.py +236 -0
  98. webscout/scout/parsers/lxml_parser.py +178 -0
  99. webscout/scout/utils.py +38 -0
  100. webscout/swiftcli/__init__.py +810 -0
  101. webscout/update_checker.py +125 -0
  102. webscout/version.py +1 -1
  103. webscout/zeroart/__init__.py +55 -0
  104. webscout/zeroart/base.py +61 -0
  105. webscout/zeroart/effects.py +99 -0
  106. webscout/zeroart/fonts.py +816 -0
  107. webscout/zerodir/__init__.py +225 -0
  108. {webscout-6.3.dist-info → webscout-6.5.dist-info}/METADATA +37 -112
  109. webscout-6.5.dist-info/RECORD +179 -0
  110. webscout/Agents/Onlinesearcher.py +0 -182
  111. webscout/Agents/__init__.py +0 -2
  112. webscout/Agents/functioncall.py +0 -248
  113. webscout/Bing_search.py +0 -154
  114. webscout/Provider/TTI/AIuncensoredimage.py +0 -103
  115. webscout/Provider/TTI/Nexra.py +0 -120
  116. webscout/Provider/TTI/PollinationsAI.py +0 -138
  117. webscout/Provider/TTI/WebSimAI.py +0 -142
  118. webscout/Provider/TTI/aiforce.py +0 -160
  119. webscout/Provider/TTI/artbit.py +0 -141
  120. webscout/Provider/TTI/deepinfra.py +0 -148
  121. webscout/Provider/TTI/huggingface.py +0 -155
  122. webscout/Provider/TTI/talkai.py +0 -116
  123. webscout/g4f.py +0 -666
  124. webscout/models.py +0 -23
  125. webscout/requestsHTMLfix.py +0 -775
  126. webscout/webai.py +0 -2590
  127. webscout-6.3.dist-info/RECORD +0 -124
  128. {webscout-6.3.dist-info → webscout-6.5.dist-info}/LICENSE.md +0 -0
  129. {webscout-6.3.dist-info → webscout-6.5.dist-info}/WHEEL +0 -0
  130. {webscout-6.3.dist-info → webscout-6.5.dist-info}/entry_points.txt +0 -0
  131. {webscout-6.3.dist-info → webscout-6.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,832 @@
1
+ """
2
+ Welcome to WebScout's Advanced Console Printer!
3
+
4
+ About This Printer:
5
+ - A powerful, feature-rich console output manager
6
+ - Created by Abhay Koul as part of the WebScout project
7
+ - Designed for beautiful, informative, and interactive terminal output
8
+
9
+ Core Features:
10
+ >>> printer.success("Operation completed successfully! ")
11
+ >>> printer.warning("Important notice! ")
12
+ >>> printer.info("Here's something interesting ")
13
+ >>> printer.error("Houston, we have a problem! ")
14
+
15
+ Special Features:
16
+ - Rich ANSI color support
17
+ - Data visualization tools
18
+ - Progress bars and spinners
19
+ - Code syntax highlighting
20
+ - Markdown rendering
21
+ - JSON pretty printing
22
+
23
+ For the best experience, use a terminal that supports UTF-8 and ANSI colors.
24
+
25
+ >>> # Basic Printing with Style
26
+ >>> printer.print("Hello World!", color="blue", bold=True)
27
+ >>> printer.print("Important Notice", bg_color="yellow", italic=True)
28
+
29
+ >>> # Layout and Formatting
30
+ >>> printer.print("Centered Text", center=True, width=50)
31
+ >>> printer.print("Indented Text", indent=4, prefix="→ ")
32
+
33
+ >>> # Borders and Decorations
34
+ >>> printer.print("Special Message", border=True, rounded_corners=True)
35
+ >>> printer.print("Alert", border=True, border_color="red", double_border=True)
36
+
37
+ >>> # Animations
38
+ >>> printer.print("Loading...", animate=True, animation_type="typing")
39
+ >>> printer.print("Processing", animate=True, animation_speed=0.1)
40
+
41
+ >>> # Data Visualization
42
+ >>> data = {"status": "active", "users": 100}
43
+ >>> printer.print(data, as_json=True) # Pretty JSON
44
+ >>> printer.print(data, as_tree=True) # Tree View
45
+
46
+ >>> # Code Highlighting
47
+ >>> code = '''def greet(): print("Hello!")'''
48
+ >>> printer.print(code, as_code=True, language="python")
49
+
50
+ >>> # Tables
51
+ >>> headers = ["Name", "Status"]
52
+ >>> rows = [["Server", "Online"]]
53
+ >>> printer.print([headers, rows], as_table=True)
54
+
55
+ >>> # Markdown Support
56
+ >>> printer.print("# Title\n- List item", markdown=True)
57
+ """
58
+
59
+ import sys
60
+ import os
61
+ import json
62
+ import time
63
+ import threading
64
+ import re
65
+ from typing import Any, Optional, TextIO, Union, Sequence, Dict, List
66
+ from datetime import datetime
67
+ import textwrap
68
+ from collections import defaultdict
69
+ import shutil
70
+ import inspect
71
+ try:
72
+ from pygments import highlight
73
+ from pygments.lexers import get_lexer_by_name
74
+ from pygments.formatters import Terminal256Formatter
75
+ PYGMENTS_AVAILABLE = True
76
+ except ImportError:
77
+ PYGMENTS_AVAILABLE = False
78
+
79
+ # Enable UTF-8 output on Windows
80
+ if sys.platform == 'win32':
81
+ import ctypes
82
+ kernel32 = ctypes.windll.kernel32
83
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
84
+ sys.stdout.reconfigure(encoding='utf-8')
85
+
86
+ # Enable ANSI escape sequences for Windows
87
+ if os.name == 'nt':
88
+ import ctypes
89
+ kernel32 = ctypes.windll.kernel32
90
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
91
+
92
+ # ANSI Color Codes
93
+ class Colors:
94
+ """ANSI color codes for terminal output."""
95
+ # Base colors
96
+ BLACK = '\033[30m'
97
+ RED = '\033[31m'
98
+ GREEN = '\033[32m'
99
+ YELLOW = '\033[33m'
100
+ BLUE = '\033[34m'
101
+ MAGENTA = '\033[35m'
102
+ CYAN = '\033[36m'
103
+ WHITE = '\033[37m'
104
+ GRAY = '\033[90m'
105
+
106
+ # Bright colors
107
+ BRIGHT_BLACK = '\033[90m'
108
+ BRIGHT_RED = '\033[91m'
109
+ BRIGHT_GREEN = '\033[92m'
110
+ BRIGHT_YELLOW = '\033[93m'
111
+ BRIGHT_BLUE = '\033[94m'
112
+ BRIGHT_MAGENTA = '\033[95m'
113
+ BRIGHT_CYAN = '\033[96m'
114
+ BRIGHT_WHITE = '\033[97m'
115
+
116
+ # Background colors
117
+ BG_BLACK = '\033[40m'
118
+ BG_RED = '\033[41m'
119
+ BG_GREEN = '\033[42m'
120
+ BG_YELLOW = '\033[43m'
121
+ BG_BLUE = '\033[44m'
122
+ BG_MAGENTA = '\033[45m'
123
+ BG_CYAN = '\033[46m'
124
+ BG_WHITE = '\033[47m'
125
+
126
+ # Styles
127
+ BOLD = '\033[1m'
128
+ DIM = '\033[2m'
129
+ ITALIC = '\033[3m'
130
+ UNDERLINE = '\033[4m'
131
+ BLINK = '\033[5m'
132
+ REVERSE = '\033[7m'
133
+ STRIKE = '\033[9m'
134
+ HIDDEN = '\033[8m'
135
+
136
+ # Special
137
+ RESET = '\033[0m'
138
+ CLEAR_SCREEN = '\033[2J'
139
+ CLEAR_LINE = '\033[2K'
140
+
141
+ # Cursor movement
142
+ UP = '\033[1A'
143
+ DOWN = '\033[1B'
144
+ RIGHT = '\033[1C'
145
+ LEFT = '\033[1D'
146
+
147
+ class SyntaxTheme:
148
+ """Syntax highlighting theme."""
149
+ KEYWORD = Colors.MAGENTA + Colors.BOLD
150
+ STRING = Colors.GREEN
151
+ NUMBER = Colors.CYAN
152
+ COMMENT = Colors.BRIGHT_BLACK + Colors.ITALIC
153
+ FUNCTION = Colors.BRIGHT_BLUE
154
+ CLASS = Colors.BRIGHT_YELLOW + Colors.BOLD
155
+ OPERATOR = Colors.WHITE
156
+ BRACKET = Colors.WHITE
157
+ VARIABLE = Colors.BRIGHT_WHITE
158
+
159
+ class MarkdownTheme:
160
+ """Theme for markdown elements."""
161
+ H1 = Colors.BOLD + Colors.BLUE
162
+ H2 = Colors.BOLD + Colors.CYAN
163
+ H3 = Colors.BOLD + Colors.GREEN
164
+ BOLD = Colors.BOLD
165
+ ITALIC = Colors.ITALIC
166
+ CODE = Colors.YELLOW
167
+ LINK = Colors.BLUE + Colors.UNDERLINE
168
+ LIST_BULLET = Colors.CYAN + "•" + Colors.RESET
169
+ QUOTE = Colors.GRAY
170
+ STRIKE = Colors.STRIKE
171
+ TABLE = Colors.GREEN
172
+ TASK = Colors.YELLOW
173
+ DETAILS = Colors.MAGENTA
174
+
175
+ class ThemeStyles:
176
+ SUCCESS = f"{Colors.GREEN}{Colors.BOLD}"
177
+ ERROR = f"{Colors.RED}{Colors.BOLD}"
178
+ WARNING = f"{Colors.YELLOW}{Colors.BOLD}"
179
+ INFO = f"{Colors.BLUE}{Colors.BOLD}"
180
+ DEBUG = f"{Colors.MAGENTA}"
181
+ CODE = f"{Colors.CYAN}"
182
+
183
+ class HoverInfo:
184
+ """Hover information for different elements."""
185
+ BANNER = "A fancy banner to make your output pop!"
186
+ SUCCESS = "Something went right! "
187
+ ERROR = "Oops! Something went wrong "
188
+ WARNING = "Heads up! Something needs attention "
189
+ INFO = "Just some helpful info "
190
+ TABLE = "Data organized in rows and columns "
191
+ TREE = "Hierarchical data visualization "
192
+ JSON = "Pretty-printed JSON data "
193
+ CODE = "Syntax-highlighted code block "
194
+
195
+ class ProgressBar:
196
+ def __init__(self, total: int, width: int = 40, prefix: str = '', suffix: str = ''):
197
+ self.total = total
198
+ self.width = width
199
+ self.prefix = prefix
200
+ self.suffix = suffix
201
+ self.current = 0
202
+
203
+ def update(self, current: int):
204
+ self.current = current
205
+ filled = int(self.width * current / self.total)
206
+ bar = f"{Colors.GREEN}{'█' * filled}{Colors.RESET}{'░' * (self.width - filled)}"
207
+ percent = f"{Colors.CYAN}{int(100 * current / self.total)}%{Colors.RESET}"
208
+ print(f'\r{self.prefix} |{bar}| {percent} {self.suffix}', end='', flush=True)
209
+ if current >= self.total:
210
+ print()
211
+
212
+ class Spinner:
213
+ def __init__(self, message: str = ''):
214
+ self.message = message
215
+ self.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
216
+ self.running = False
217
+ self.thread = None
218
+
219
+ def spin(self):
220
+ while self.running:
221
+ for frame in self.frames:
222
+ if not self.running:
223
+ break
224
+ print(f'\r{Colors.CYAN}{frame}{Colors.RESET} {self.message}', end='', flush=True)
225
+ time.sleep(0.1)
226
+
227
+ def __enter__(self):
228
+ self.start()
229
+ return self
230
+
231
+ def __exit__(self, exc_type, exc_val, exc_tb):
232
+ self.stop()
233
+
234
+ def start(self):
235
+ self.running = True
236
+ self.thread = threading.Thread(target=self.spin)
237
+ self.thread.start()
238
+
239
+ def stop(self):
240
+ self.running = False
241
+ if self.thread:
242
+ self.thread.join()
243
+ print('\r' + ' ' * (len(self.message) + 2), end='', flush=True)
244
+ print('\r', end='')
245
+
246
+ class LitPrinter:
247
+ def __init__(self,
248
+ file: TextIO = sys.stdout,
249
+ theme: Optional[dict] = None,
250
+ indent_size: int = 4,
251
+ buffer_size: int = 1024,
252
+ syntax_theme: Optional[Dict[str, str]] = None,
253
+ markdown_theme: Optional[Dict[str, str]] = None):
254
+ self.file = file
255
+ self.indent_size = indent_size
256
+ self.buffer_size = buffer_size
257
+ self._terminal_width = shutil.get_terminal_size().columns
258
+ self._last_line = ""
259
+ self._spinner_active = False
260
+ self._progress_active = False
261
+
262
+ # Default theme
263
+ self.theme = theme or {
264
+ "str": Colors.WHITE,
265
+ "int": Colors.CYAN,
266
+ "float": Colors.CYAN,
267
+ "bool": Colors.YELLOW,
268
+ "list": Colors.MAGENTA,
269
+ "dict": Colors.BLUE,
270
+ "none": Colors.RED,
271
+ "timestamp": Colors.GREEN,
272
+ "key": Colors.YELLOW,
273
+ "bracket": Colors.BLUE,
274
+ "comma": Colors.WHITE,
275
+ "colon": Colors.WHITE,
276
+ "url": f"{Colors.BLUE}{Colors.UNDERLINE}",
277
+ "number": Colors.CYAN,
278
+ "special": Colors.MAGENTA + Colors.BOLD,
279
+ "error": Colors.RED + Colors.BOLD,
280
+ "warning": Colors.YELLOW + Colors.BOLD,
281
+ "success": Colors.GREEN + Colors.BOLD,
282
+ "info": Colors.BLUE + Colors.BOLD,
283
+ }
284
+
285
+ self.syntax_theme = syntax_theme or vars(SyntaxTheme)
286
+ self.markdown_theme = markdown_theme or vars(MarkdownTheme)
287
+
288
+ def _get_terminal_width(self) -> int:
289
+ """Get the terminal width or default to 80."""
290
+ try:
291
+ width = shutil.get_terminal_size().columns
292
+ return width if width > 0 else 80
293
+ except:
294
+ return 80
295
+
296
+ def _format_dict(self, d: dict, indent_level: int = 0) -> str:
297
+ """Format dictionary with proper indentation and colors."""
298
+ if not d:
299
+ return f"{self.theme['bracket']}{{}}{Colors.RESET}"
300
+
301
+ indent = " " * (self.indent_size * indent_level)
302
+ next_indent = " " * (self.indent_size * (indent_level + 1))
303
+
304
+ lines = [f"{self.theme['bracket']}{{{Colors.RESET}"]
305
+
306
+ for i, (key, value) in enumerate(d.items()):
307
+ # Format key with quotes if it's a string
308
+ if isinstance(key, str):
309
+ formatted_key = f"{self.theme['key']}'{key}'{Colors.RESET}"
310
+ else:
311
+ formatted_key = f"{self.theme['key']}{key}{Colors.RESET}"
312
+
313
+ # Format value based on type
314
+ if isinstance(value, dict):
315
+ formatted_value = self._format_dict(value, indent_level + 1)
316
+ elif isinstance(value, str):
317
+ # Special handling for URLs
318
+ if any(url_prefix in value.lower() for url_prefix in ['http://', 'https://', 'www.']):
319
+ formatted_value = f"{self.theme['url']}{value}{Colors.RESET}"
320
+ else:
321
+ # Word wrap long strings
322
+ if len(value) > 80:
323
+ wrapped = textwrap.fill(value, width=80, subsequent_indent=next_indent + " ")
324
+ formatted_value = f"{self.theme['str']}'{wrapped}'{Colors.RESET}"
325
+ else:
326
+ formatted_value = f"{self.theme['str']}'{value}'{Colors.RESET}"
327
+ elif isinstance(value, (int, float)):
328
+ formatted_value = f"{self.theme['number']}{value}{Colors.RESET}"
329
+ elif isinstance(value, bool):
330
+ formatted_value = f"{self.theme['bool']}{value}{Colors.RESET}"
331
+ elif value is None:
332
+ formatted_value = f"{self.theme['none']}None{Colors.RESET}"
333
+ else:
334
+ formatted_value = self._format_value(value)
335
+
336
+ # Add comma if not last item
337
+ comma = f"{self.theme['comma']},{Colors.RESET}" if i < len(d) - 1 else ""
338
+
339
+ lines.append(f"{next_indent}{formatted_key}{self.theme['colon']}: {Colors.RESET}{formatted_value}{comma}")
340
+
341
+ lines.append(f"{indent}{self.theme['bracket']}}}{Colors.RESET}")
342
+ return '\n'.join(lines)
343
+
344
+ def _format_sequence(self, seq: Sequence, indent_level: int = 0) -> str:
345
+ """Format sequences (lists, tuples, sets) with proper indentation."""
346
+ if not seq:
347
+ return f"{self.theme['bracket']}[]{Colors.RESET}"
348
+
349
+ indent = " " * (self.indent_size * indent_level)
350
+ next_indent = " " * (self.indent_size * (indent_level + 1))
351
+
352
+ lines = [f"{self.theme['bracket']}[{Colors.RESET}"]
353
+
354
+ for i, item in enumerate(seq):
355
+ formatted_item = self._format_value(item, indent_level + 1)
356
+ comma = f"{self.theme['comma']},{Colors.RESET}" if i < len(seq) - 1 else ""
357
+ lines.append(f"{next_indent}{formatted_item}{comma}")
358
+
359
+ lines.append(f"{indent}{self.theme['bracket']}]{Colors.RESET}")
360
+ return '\n'.join(lines)
361
+
362
+ def _format_value(self, value: Any, indent_level: int = 0) -> str:
363
+ """Enhanced format for any value with proper indentation and styling."""
364
+ if value is None:
365
+ return f"{self.theme['none']}None{Colors.RESET}"
366
+
367
+ if isinstance(value, dict):
368
+ return self._format_dict(value, indent_level)
369
+
370
+ if isinstance(value, (list, tuple, set)):
371
+ return self._format_sequence(value, indent_level)
372
+
373
+ if isinstance(value, str):
374
+ return str(value)
375
+
376
+ if isinstance(value, bool):
377
+ return f"{self.theme['bool']}{str(value)}{Colors.RESET}"
378
+
379
+ if isinstance(value, (int, float)):
380
+ return f"{self.theme['number']}{str(value)}{Colors.RESET}"
381
+
382
+ if hasattr(value, '__dict__'):
383
+ return self._format_dict(value.__dict__, indent_level)
384
+
385
+ return str(value)
386
+
387
+ def _highlight_code(self, code: str, language: str = "python") -> str:
388
+ """Print code with that extra drip """
389
+ if PYGMENTS_AVAILABLE:
390
+ try:
391
+ lexer = get_lexer_by_name(language)
392
+ formatter = Terminal256Formatter(style='monokai')
393
+ return highlight(code, lexer, formatter)
394
+ except:
395
+ pass
396
+
397
+ if language != 'python':
398
+ return code
399
+
400
+ lines = []
401
+ for line in code.split('\n'):
402
+ if '#' in line:
403
+ code_part, comment_part = line.split('#', 1)
404
+ line = code_part + f"{self.syntax_theme['COMMENT']}#{comment_part}{Colors.RESET}"
405
+
406
+ line = re.sub(r'(".*?"|\'.*?\')',
407
+ f"{self.syntax_theme['STRING']}\\1{Colors.RESET}", line)
408
+
409
+ line = re.sub(r'\b(\d+)\b',
410
+ f"{self.syntax_theme['NUMBER']}\\1{Colors.RESET}", line)
411
+
412
+ keywords = ['def', 'class', 'if', 'else', 'elif', 'for', 'while', 'try',
413
+ 'except', 'finally', 'with', 'as', 'import', 'from', 'return']
414
+
415
+ for keyword in keywords:
416
+ line = re.sub(f'\\b{keyword}\\b',
417
+ f"{self.syntax_theme['KEYWORD']}{keyword}{Colors.RESET}", line)
418
+
419
+ lines.append(line)
420
+
421
+ return '\n'.join(lines)
422
+
423
+ def _format_markdown_stream(self, text: str) -> str:
424
+ """Enhanced markdown formatting for streaming mode."""
425
+ # Headers with emoji flair
426
+ text = re.sub(r'^# (.+)$', f"{self.markdown_theme['H1']}🔥 \\1{Colors.RESET}", text, flags=re.M)
427
+ text = re.sub(r'^## (.+)$', f"{self.markdown_theme['H2']}✨ \\1{Colors.RESET}", text, flags=re.M)
428
+ text = re.sub(r'^### (.+)$', f"{self.markdown_theme['H3']}💫 \\1{Colors.RESET}", text, flags=re.M)
429
+
430
+ # Bold, italic, and combined with multiple styles
431
+ text = re.sub(r'\*\*\*(.+?)\*\*\*', f"{Colors.BOLD}{Colors.ITALIC}\\1{Colors.RESET}", text)
432
+ text = re.sub(r'\*\*(.+?)\*\*', f"{Colors.BOLD}\\1{Colors.RESET}", text)
433
+ text = re.sub(r'\*(.+?)\*', f"{Colors.ITALIC}\\1{Colors.RESET}", text)
434
+ text = re.sub(r'__(.+?)__', f"{Colors.BOLD}\\1{Colors.RESET}", text)
435
+ text = re.sub(r'_(.+?)_', f"{Colors.ITALIC}\\1{Colors.RESET}", text)
436
+
437
+ # Code blocks and inline code
438
+ text = re.sub(r'```(\w+)?\n(.*?)\n```', lambda m: self._highlight_code(m.group(2), m.group(1) or 'text'), text, flags=re.S)
439
+ text = re.sub(r'`(.+?)`', f"{Colors.CYAN}\\1{Colors.RESET}", text)
440
+
441
+ # Lists with proper indentation and bullets
442
+ lines = text.split('\n')
443
+ formatted_lines = []
444
+ for i, line in enumerate(lines):
445
+ # Match different bullet point styles
446
+ bullet_match = re.match(r'^(\s*)([-•*]|\d+\.) (.+)$', line)
447
+ if bullet_match:
448
+ indent, bullet, content = bullet_match.groups()
449
+ indent_level = len(indent) // 2
450
+
451
+ # Choose bullet style based on nesting level
452
+ if indent_level == 0:
453
+ bullet_style = "•"
454
+ elif indent_level == 1:
455
+ bullet_style = "◦"
456
+ else:
457
+ bullet_style = "▪"
458
+
459
+ # Format the line with proper indentation and bullet
460
+ formatted_line = f"{' ' * (indent_level * 2)}{Colors.CYAN}{bullet_style}{Colors.RESET} {content}"
461
+ formatted_lines.append(formatted_line)
462
+ else:
463
+ formatted_lines.append(line)
464
+ text = '\n'.join(formatted_lines)
465
+
466
+ # Links with underline
467
+ text = re.sub(r'\[(.+?)\]\((.+?)\)', f"{Colors.BLUE}{Colors.UNDERLINE}\\1{Colors.RESET}", text)
468
+
469
+ # Blockquotes with style
470
+ text = re.sub(r'^> (.+)$', f"{self.markdown_theme['QUOTE']}│ \\1{Colors.RESET}", text, flags=re.M)
471
+
472
+ # Strikethrough
473
+ text = re.sub(r'~~(.+?)~~', f"{Colors.STRIKE}\\1{Colors.RESET}", text)
474
+
475
+ # Task lists with fancy checkboxes
476
+ text = re.sub(r'- \[ \] (.+)$', f"{self.markdown_theme['TASK']}☐ \\1{Colors.RESET}", text, flags=re.M)
477
+ text = re.sub(r'- \[x\] (.+)$', f"{self.markdown_theme['TASK']}☑ \\1{Colors.RESET}", text, flags=re.M)
478
+
479
+ # Tables with borders
480
+ table_pattern = r'\|(.+?)\|[\r\n]+\|[-:| ]+\|[\r\n]+((?:\|.+?\|[\r\n]+)+)'
481
+ text = re.sub(table_pattern, self._format_table_markdown, text, flags=re.M)
482
+
483
+ return text
484
+
485
+ def _format_table_markdown(self, match) -> str:
486
+ """Format markdown tables with style."""
487
+ header = [cell.strip() for cell in match.group(1).split('|') if cell.strip()]
488
+ rows = []
489
+ for row in match.group(2).strip().split('\n'):
490
+ cells = [cell.strip() for cell in row.split('|')[1:-1]]
491
+ if cells:
492
+ rows.append(cells)
493
+
494
+ # Get column widths
495
+ widths = [max(len(str(row[i])) for row in [header] + rows) for i in range(len(header))]
496
+
497
+ # Build table
498
+ result = []
499
+ # Header
500
+ result.append('┌' + '┬'.join('─' * (w + 2) for w in widths) + '┐')
501
+ result.append('│ ' + ' │ '.join(f"{h:<{w}}" for h, w in zip(header, widths)) + ' │')
502
+ result.append('├' + '┼'.join('─' * (w + 2) for w in widths) + '┤')
503
+ # Rows
504
+ for row in rows:
505
+ result.append('│ ' + ' │ '.join(f"{str(c):<{w}}" for c, w in zip(row, widths)) + ' │')
506
+ result.append('└' + '┴'.join('─' * (w + 2) for w in widths) + '┘')
507
+
508
+ return '\n'.join(result)
509
+
510
+ def print(self, *args,
511
+ # Builtin print compatibility
512
+ sep: str = " ",
513
+ end: str = "\n",
514
+ file: Optional[TextIO] = None,
515
+ flush: bool = True,
516
+
517
+ # Styling options
518
+ style: Optional[str] = None,
519
+ color: Optional[str] = None,
520
+ bg_color: Optional[str] = None,
521
+ bold: bool = False,
522
+ italic: bool = False,
523
+ underline: bool = False,
524
+ blink: bool = False,
525
+ strike: bool = False,
526
+ dim: bool = False,
527
+ reverse: bool = False,
528
+
529
+ # Layout options
530
+ markdown: Optional[bool] = None,
531
+ highlight: bool = False,
532
+ center: bool = False,
533
+ indent: int = 0,
534
+ prefix: Optional[str] = None,
535
+ suffix: Optional[str] = None,
536
+ width: Optional[int] = None,
537
+ padding: int = 0,
538
+ margin: int = 0,
539
+ align: str = "left",
540
+
541
+ # Border options
542
+ border: bool = False,
543
+ border_style: Optional[str] = None,
544
+ border_char: str = "─",
545
+ border_color: Optional[str] = None,
546
+ rounded_corners: bool = False,
547
+ double_border: bool = False,
548
+
549
+ # Animation options
550
+ animate: bool = False,
551
+ animation_speed: float = 0.05,
552
+ animation_type: str = "typing",
553
+
554
+ # Special features
555
+ as_table: bool = False,
556
+ as_tree: bool = False,
557
+ as_json: bool = False,
558
+ as_code: bool = False,
559
+ language: str = "python",
560
+
561
+ # Advanced features
562
+ raw: bool = False) -> None:
563
+ """
564
+ Enhanced print with all builtin features plus rich formatting.
565
+
566
+ Supports all builtin print parameters plus rich formatting features.
567
+ Automatically detects and formats markdown content unless explicitly disabled.
568
+ """
569
+ # Handle raw output mode
570
+ if raw:
571
+ print(*args, sep=sep, end=end, file=file or self.file, flush=flush)
572
+ return
573
+
574
+ # Join args with separator
575
+ output = sep.join(str(arg) for arg in args)
576
+
577
+ # Auto-detect markdown if not explicitly set
578
+ if markdown is None:
579
+ markdown = any(marker in output for marker in [
580
+ '#', '*', '_', '`', '>', '-', '•', '|',
581
+ # '✨', '🔥', '💫', '☐', '☑',
582
+ 'http://', 'https://',
583
+ '```', '~~~',
584
+ '<details>', '<summary>',
585
+ ])
586
+
587
+ # Apply markdown formatting if enabled
588
+ if markdown:
589
+ output = self._format_markdown_stream(output)
590
+
591
+ # Build style string
592
+ style_str = style or ""
593
+ if color:
594
+ style_str += getattr(Colors, color.upper(), "")
595
+ if bg_color:
596
+ style_str += getattr(Colors, f"BG_{bg_color.upper()}", "")
597
+ if bold:
598
+ style_str += Colors.BOLD
599
+ if italic:
600
+ style_str += Colors.ITALIC
601
+ if underline:
602
+ style_str += Colors.UNDERLINE
603
+ if blink:
604
+ style_str += Colors.BLINK
605
+ if strike:
606
+ style_str += Colors.STRIKE
607
+ if dim:
608
+ style_str += Colors.DIM
609
+ if reverse:
610
+ style_str += Colors.REVERSE
611
+
612
+ # Apply style if any
613
+ if style_str:
614
+ output = f"{style_str}{output}{Colors.RESET}"
615
+
616
+ # Handle special formatting
617
+ if as_json:
618
+ output = self._format_json(output)
619
+ elif as_code:
620
+ output = self._highlight_code(output, language)
621
+ elif as_table:
622
+ if isinstance(output, (list, tuple)):
623
+ self.table(*output)
624
+ return
625
+ elif as_tree:
626
+ if isinstance(output, (dict, list)):
627
+ self.tree(output)
628
+ return
629
+
630
+ # Apply layout options
631
+ if center:
632
+ term_width = self._get_terminal_width()
633
+ output = output.center(term_width)
634
+ if indent > 0:
635
+ output = " " * (indent * 4) + output
636
+ if prefix:
637
+ output = prefix + output
638
+ if suffix:
639
+ output = output + suffix
640
+ if width:
641
+ output = textwrap.fill(output, width=width)
642
+
643
+ # Add borders
644
+ if border:
645
+ width = max(len(line) for line in output.split('\n'))
646
+ border_top = '┌' + border_char * width + '┐'
647
+ border_bottom = '└' + border_char * width + '┘'
648
+ output = f"{border_top}\n{output}\n{border_bottom}"
649
+
650
+ # Handle animation
651
+ if animate:
652
+ for char in output:
653
+ print(char, end="", flush=True)
654
+ time.sleep(animation_speed)
655
+ print(end=end, flush=flush)
656
+ return
657
+
658
+ # Final output
659
+ print(output, end=end, file=file or self.file, flush=flush)
660
+
661
+ def status(self, text: str, style: Optional[str] = None):
662
+ """Print a status message that can be overwritten."""
663
+ style = style or self.theme['info']
664
+ self._clear_line()
665
+ self._last_line = f"{style}{text}{Colors.RESET}"
666
+ print(self._last_line, end='\r', file=self.file, flush=True)
667
+
668
+ def banner(self, text: str, style: Optional[str] = None):
669
+ """Print a fancy banner with hover info."""
670
+ print(f"\033]1337;Custom=id=banner:{HoverInfo.BANNER}\a", end='')
671
+ style = style or self.theme['special']
672
+ width = self._get_terminal_width() - 4
673
+
674
+ lines = textwrap.wrap(text, width=width, break_long_words=False)
675
+
676
+ print('╔' + '═' * width + '╗')
677
+ for line in lines:
678
+ padding = width - len(line)
679
+ print('║ ' + line + ' ' * padding + ' ║')
680
+ print('╚' + '═' * width + '╝')
681
+ print("\033]1337;Custom=id=banner:end\a", end='')
682
+
683
+ def success(self, text: str):
684
+ """Print a success message with hover info."""
685
+ print(f"\033]1337;Custom=id=success:{HoverInfo.SUCCESS}\a", end='')
686
+ self.print(f"✓ {text}", style=self.theme['success'])
687
+ print("\033]1337;Custom=id=success:end\a", end='')
688
+
689
+ def error(self, text: str):
690
+ """Print an error message with hover info."""
691
+ print(f"\033]1337;Custom=id=error:{HoverInfo.ERROR}\a", end='')
692
+ self.print(f"✗ {text}", style=self.theme['error'])
693
+ print("\033]1337;Custom=id=error:end\a", end='')
694
+
695
+ def warning(self, text: str):
696
+ """Print a warning message with hover info."""
697
+ print(f"\033]1337;Custom=id=warning:{HoverInfo.WARNING}\a", end='')
698
+ self.print(f"⚠ {text}", style=self.theme['warning'])
699
+ print("\033]1337;Custom=id=warning:end\a", end='')
700
+
701
+ def info(self, text: str):
702
+ """Print an info message with hover info."""
703
+ print(f"\033]1337;Custom=id=info:{HoverInfo.INFO}\a", end='')
704
+ self.print(f"ℹ {text}", style=self.theme['info'])
705
+ print("\033]1337;Custom=id=info:end\a", end='')
706
+
707
+ def table(self, headers: List[str], rows: List[List[Any]], style: Optional[str] = None):
708
+ """Print a formatted table."""
709
+ style = style or self.theme['special']
710
+
711
+ col_widths = [len(h) for h in headers]
712
+ for row in rows:
713
+ for i, cell in enumerate(row):
714
+ col_widths[i] = max(col_widths[i], len(str(cell)))
715
+
716
+ header_line = '| ' + ' | '.join(f"{h:<{w}}" for h, w in zip(headers, col_widths)) + ' |'
717
+ print(header_line)
718
+
719
+ separator = '+' + '+'.join('-' * (w + 2) for w in col_widths) + '+'
720
+ print(separator)
721
+
722
+ for row in rows:
723
+ row_line = '| ' + ' | '.join(f"{str(cell):<{w}}" for cell, w in zip(row, col_widths)) + ' |'
724
+ print(row_line)
725
+
726
+ def tree(self, data: Union[Dict, List], indent: int = 0):
727
+ """Print a tree structure of nested data."""
728
+ if isinstance(data, dict):
729
+ for key, value in data.items():
730
+ self.print(" " * indent + "├─ " + str(key) + ":", style=self.theme['key'])
731
+ if isinstance(value, (dict, list)):
732
+ self.tree(value, indent + 1)
733
+ else:
734
+ self.print(" " * (indent + 1) + "└─ " + str(value))
735
+ elif isinstance(data, list):
736
+ for item in data:
737
+ if isinstance(item, (dict, list)):
738
+ self.tree(item, indent + 1)
739
+ else:
740
+ self.print(" " * indent + "├─ " + str(item))
741
+
742
+ def json(self, data: Any, indent: int = 4):
743
+ """Print formatted JSON data."""
744
+ formatted = json.dumps(data, indent=indent)
745
+ self.print(formatted, highlight=True)
746
+
747
+ def code_block(self, code: str, language: str = "python"):
748
+ """Print code in a fancy box with syntax highlighting."""
749
+ highlighted = self._highlight_code(code, language)
750
+ lines = highlighted.split('\n')
751
+
752
+ width = max(len(line) for line in lines)
753
+ width = min(width, self._get_terminal_width() - 4) # Account for borders
754
+
755
+ print('┌' + '─' * width + '┐')
756
+
757
+ for line in lines:
758
+ if len(line) > width:
759
+ line = line[:width-3] + '...'
760
+ else:
761
+ line = line + ' ' * (width - len(line))
762
+ print('│ ' + line + ' │')
763
+
764
+ print('└' + '─' * width + '┘')
765
+
766
+ def _clear_line(self):
767
+ """Clear the current line."""
768
+ print('\r' + ' ' * self._get_terminal_width(), end='\r', file=self.file, flush=True)
769
+
770
+ print = LitPrinter().print
771
+ if __name__ == "__main__":
772
+ printer = LitPrinter()
773
+
774
+ printer.banner("Welcome to the LitPrinter Demo! ")
775
+
776
+ printer.status("Loading that heat... ")
777
+ time.sleep(1)
778
+ printer.status("Almost ready to drop... ")
779
+ time.sleep(1)
780
+ printer.status("")
781
+
782
+ printer.success("Ayy, we made it! ")
783
+ printer.error("Houston, we got a problem! ")
784
+ printer.warning("Hold up, something sus... ")
785
+ printer.info("Just so you know fam... ")
786
+
787
+ headers = ["Name", "Vibe", "Energy"]
788
+ rows = [
789
+ ["Python", "Immaculate", "100%"],
790
+ ["Java", "Decent", "75%"],
791
+ ["C++", "Complex", "85%"]
792
+ ]
793
+ printer.table(headers, rows)
794
+
795
+ data = {
796
+ "squad": {
797
+ "python": {"vibe": "lit", "power": "over 9000"},
798
+ "javascript": {"vibe": "cool", "power": "8000"}
799
+ },
800
+ "config": {
801
+ "mode": "beast",
802
+ "activated": True
803
+ }
804
+ }
805
+ printer.tree(data)
806
+
807
+ printer.json(data)
808
+
809
+ code = '''def print_drip():
810
+ # This function brings the heat
811
+ print("Straight bussin!")
812
+ return True # No cap'''
813
+ printer.code_block(code)
814
+
815
+ printer.print("Basic text but make it fancy ")
816
+ printer.print("Colors go hard", style=Colors.GREEN)
817
+ printer.print("Bold & Blue = Different breed", style=Colors.BLUE + Colors.BOLD)
818
+
819
+ markdown_text = """# Main Title (Straight Fire)
820
+ ## Subtitle (Also Heat)
821
+ - First thing's first
822
+ - Second thing's second
823
+ **Bold moves** and *smooth style*
824
+ """
825
+ printer.print(markdown_text, markdown=True)
826
+
827
+ test_dict = {
828
+ "name": "LitPrinter",
829
+ "vibes": ["immaculate", "unmatched", "different"],
830
+ "config": {"mode": "beast", "level": "over 9000"}
831
+ }
832
+ printer.print(test_dict)