webscout 8.3.7__py3-none-any.whl → 2025.10.13__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 +250 -250
- webscout/AIbase.py +379 -379
- webscout/AIutel.py +60 -60
- webscout/Bard.py +1012 -1012
- webscout/Bing_search.py +417 -417
- webscout/DWEBS.py +529 -529
- webscout/Extra/Act.md +309 -309
- webscout/Extra/GitToolkit/__init__.py +10 -10
- webscout/Extra/GitToolkit/gitapi/README.md +110 -110
- webscout/Extra/GitToolkit/gitapi/__init__.py +11 -11
- webscout/Extra/GitToolkit/gitapi/repository.py +195 -195
- webscout/Extra/GitToolkit/gitapi/user.py +96 -96
- webscout/Extra/GitToolkit/gitapi/utils.py +61 -61
- webscout/Extra/YTToolkit/README.md +375 -375
- webscout/Extra/YTToolkit/YTdownloader.py +956 -956
- webscout/Extra/YTToolkit/__init__.py +2 -2
- webscout/Extra/YTToolkit/transcriber.py +475 -475
- webscout/Extra/YTToolkit/ytapi/README.md +44 -44
- webscout/Extra/YTToolkit/ytapi/__init__.py +6 -6
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -307
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -13
- webscout/Extra/YTToolkit/ytapi/extras.py +118 -118
- webscout/Extra/YTToolkit/ytapi/https.py +88 -88
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -61
- webscout/Extra/YTToolkit/ytapi/playlist.py +58 -58
- webscout/Extra/YTToolkit/ytapi/pool.py +7 -7
- webscout/Extra/YTToolkit/ytapi/query.py +39 -39
- webscout/Extra/YTToolkit/ytapi/stream.py +62 -62
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -62
- webscout/Extra/YTToolkit/ytapi/video.py +232 -232
- webscout/Extra/autocoder/__init__.py +9 -9
- webscout/Extra/autocoder/autocoder.py +1105 -1105
- webscout/Extra/autocoder/autocoder_utiles.py +332 -332
- webscout/Extra/gguf.md +429 -429
- webscout/Extra/gguf.py +1213 -1213
- webscout/Extra/tempmail/README.md +487 -487
- webscout/Extra/tempmail/__init__.py +27 -27
- webscout/Extra/tempmail/async_utils.py +140 -140
- webscout/Extra/tempmail/base.py +160 -160
- webscout/Extra/tempmail/cli.py +186 -186
- webscout/Extra/tempmail/emailnator.py +84 -84
- webscout/Extra/tempmail/mail_tm.py +360 -360
- webscout/Extra/tempmail/temp_mail_io.py +291 -291
- webscout/Extra/weather.md +281 -281
- webscout/Extra/weather.py +193 -193
- webscout/Litlogger/README.md +10 -10
- webscout/Litlogger/__init__.py +15 -15
- webscout/Litlogger/formats.py +13 -13
- webscout/Litlogger/handlers.py +121 -121
- webscout/Litlogger/levels.py +13 -13
- webscout/Litlogger/logger.py +134 -134
- webscout/Provider/AISEARCH/Perplexity.py +332 -332
- webscout/Provider/AISEARCH/README.md +279 -279
- webscout/Provider/AISEARCH/__init__.py +16 -1
- webscout/Provider/AISEARCH/felo_search.py +206 -206
- webscout/Provider/AISEARCH/genspark_search.py +323 -323
- webscout/Provider/AISEARCH/hika_search.py +185 -185
- webscout/Provider/AISEARCH/iask_search.py +410 -410
- webscout/Provider/AISEARCH/monica_search.py +219 -219
- webscout/Provider/AISEARCH/scira_search.py +316 -316
- webscout/Provider/AISEARCH/stellar_search.py +177 -177
- webscout/Provider/AISEARCH/webpilotai_search.py +255 -255
- webscout/Provider/Aitopia.py +314 -314
- webscout/Provider/Andi.py +1 -1
- webscout/Provider/Apriel.py +306 -0
- webscout/Provider/ChatGPTClone.py +237 -236
- webscout/Provider/ChatSandbox.py +343 -343
- webscout/Provider/Cloudflare.py +324 -324
- webscout/Provider/Cohere.py +208 -208
- webscout/Provider/Deepinfra.py +370 -366
- webscout/Provider/ExaAI.py +260 -260
- webscout/Provider/ExaChat.py +308 -308
- webscout/Provider/Flowith.py +221 -221
- webscout/Provider/GMI.py +293 -0
- webscout/Provider/Gemini.py +164 -164
- webscout/Provider/GeminiProxy.py +167 -167
- webscout/Provider/GithubChat.py +371 -372
- webscout/Provider/Groq.py +800 -800
- webscout/Provider/HeckAI.py +383 -383
- webscout/Provider/Jadve.py +282 -282
- webscout/Provider/K2Think.py +307 -307
- webscout/Provider/Koboldai.py +205 -205
- webscout/Provider/LambdaChat.py +423 -423
- webscout/Provider/Nemotron.py +244 -244
- webscout/Provider/Netwrck.py +248 -248
- webscout/Provider/OLLAMA.py +395 -395
- webscout/Provider/OPENAI/Cloudflare.py +393 -393
- webscout/Provider/OPENAI/FalconH1.py +451 -451
- webscout/Provider/OPENAI/FreeGemini.py +296 -296
- webscout/Provider/OPENAI/K2Think.py +431 -431
- webscout/Provider/OPENAI/NEMOTRON.py +240 -240
- webscout/Provider/OPENAI/PI.py +427 -427
- webscout/Provider/OPENAI/README.md +959 -959
- webscout/Provider/OPENAI/TogetherAI.py +345 -345
- webscout/Provider/OPENAI/TwoAI.py +465 -465
- webscout/Provider/OPENAI/__init__.py +33 -18
- webscout/Provider/OPENAI/base.py +248 -248
- webscout/Provider/OPENAI/chatglm.py +528 -0
- webscout/Provider/OPENAI/chatgpt.py +592 -592
- webscout/Provider/OPENAI/chatgptclone.py +521 -521
- webscout/Provider/OPENAI/chatsandbox.py +202 -202
- webscout/Provider/OPENAI/deepinfra.py +318 -314
- webscout/Provider/OPENAI/e2b.py +1665 -1665
- webscout/Provider/OPENAI/exaai.py +420 -420
- webscout/Provider/OPENAI/exachat.py +452 -452
- webscout/Provider/OPENAI/friendli.py +232 -232
- webscout/Provider/OPENAI/{refact.py → gmi.py} +324 -274
- webscout/Provider/OPENAI/groq.py +364 -364
- webscout/Provider/OPENAI/heckai.py +314 -314
- webscout/Provider/OPENAI/llmchatco.py +337 -337
- webscout/Provider/OPENAI/netwrck.py +355 -355
- webscout/Provider/OPENAI/oivscode.py +290 -290
- webscout/Provider/OPENAI/opkfc.py +518 -518
- webscout/Provider/OPENAI/pydantic_imports.py +1 -1
- webscout/Provider/OPENAI/scirachat.py +535 -535
- webscout/Provider/OPENAI/sonus.py +308 -308
- webscout/Provider/OPENAI/standardinput.py +442 -442
- webscout/Provider/OPENAI/textpollinations.py +340 -340
- webscout/Provider/OPENAI/toolbaz.py +419 -416
- webscout/Provider/OPENAI/typefully.py +362 -362
- webscout/Provider/OPENAI/utils.py +295 -295
- webscout/Provider/OPENAI/venice.py +436 -436
- webscout/Provider/OPENAI/wisecat.py +387 -387
- webscout/Provider/OPENAI/writecream.py +166 -166
- webscout/Provider/OPENAI/x0gpt.py +378 -378
- webscout/Provider/OPENAI/yep.py +389 -389
- webscout/Provider/OpenGPT.py +230 -230
- webscout/Provider/Openai.py +243 -243
- webscout/Provider/PI.py +405 -405
- webscout/Provider/Perplexitylabs.py +430 -430
- webscout/Provider/QwenLM.py +272 -272
- webscout/Provider/STT/__init__.py +16 -1
- webscout/Provider/Sambanova.py +257 -257
- webscout/Provider/StandardInput.py +309 -309
- webscout/Provider/TTI/README.md +82 -82
- webscout/Provider/TTI/__init__.py +33 -18
- webscout/Provider/TTI/aiarta.py +413 -413
- webscout/Provider/TTI/base.py +136 -136
- webscout/Provider/TTI/bing.py +243 -243
- webscout/Provider/TTI/gpt1image.py +149 -149
- webscout/Provider/TTI/imagen.py +196 -196
- webscout/Provider/TTI/infip.py +211 -211
- webscout/Provider/TTI/magicstudio.py +232 -232
- webscout/Provider/TTI/monochat.py +219 -219
- webscout/Provider/TTI/piclumen.py +214 -214
- webscout/Provider/TTI/pixelmuse.py +232 -232
- webscout/Provider/TTI/pollinations.py +232 -232
- webscout/Provider/TTI/together.py +288 -288
- webscout/Provider/TTI/utils.py +12 -12
- webscout/Provider/TTI/venice.py +367 -367
- webscout/Provider/TTS/README.md +192 -192
- webscout/Provider/TTS/__init__.py +33 -18
- webscout/Provider/TTS/parler.py +110 -110
- webscout/Provider/TTS/streamElements.py +333 -333
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TeachAnything.py +237 -237
- webscout/Provider/TextPollinationsAI.py +310 -310
- webscout/Provider/TogetherAI.py +356 -356
- webscout/Provider/TwoAI.py +312 -312
- webscout/Provider/TypliAI.py +311 -311
- webscout/Provider/UNFINISHED/ChatHub.py +208 -208
- webscout/Provider/UNFINISHED/ChutesAI.py +313 -313
- webscout/Provider/UNFINISHED/GizAI.py +294 -294
- webscout/Provider/UNFINISHED/Marcus.py +198 -198
- webscout/Provider/UNFINISHED/Qodo.py +477 -477
- webscout/Provider/UNFINISHED/VercelAIGateway.py +338 -338
- webscout/Provider/UNFINISHED/XenAI.py +324 -324
- webscout/Provider/UNFINISHED/Youchat.py +330 -330
- webscout/Provider/UNFINISHED/liner.py +334 -0
- webscout/Provider/UNFINISHED/liner_api_request.py +262 -262
- webscout/Provider/UNFINISHED/puterjs.py +634 -634
- webscout/Provider/UNFINISHED/samurai.py +223 -223
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
- webscout/Provider/Venice.py +250 -250
- webscout/Provider/VercelAI.py +256 -256
- webscout/Provider/WiseCat.py +231 -231
- webscout/Provider/WrDoChat.py +366 -366
- webscout/Provider/__init__.py +33 -18
- webscout/Provider/ai4chat.py +174 -174
- webscout/Provider/akashgpt.py +331 -331
- webscout/Provider/cerebras.py +446 -446
- webscout/Provider/chatglm.py +394 -301
- webscout/Provider/cleeai.py +211 -211
- webscout/Provider/elmo.py +282 -282
- webscout/Provider/geminiapi.py +208 -208
- webscout/Provider/granite.py +261 -261
- webscout/Provider/hermes.py +263 -263
- webscout/Provider/julius.py +223 -223
- webscout/Provider/learnfastai.py +309 -309
- webscout/Provider/llama3mitril.py +214 -214
- webscout/Provider/llmchat.py +243 -243
- webscout/Provider/llmchatco.py +290 -290
- webscout/Provider/meta.py +801 -801
- webscout/Provider/oivscode.py +309 -309
- webscout/Provider/scira_chat.py +383 -383
- webscout/Provider/searchchat.py +292 -292
- webscout/Provider/sonus.py +258 -258
- webscout/Provider/toolbaz.py +370 -367
- webscout/Provider/turboseek.py +273 -273
- webscout/Provider/typefully.py +207 -207
- webscout/Provider/yep.py +372 -372
- webscout/__init__.py +27 -31
- webscout/__main__.py +5 -5
- webscout/auth/api_key_manager.py +189 -189
- webscout/auth/config.py +175 -175
- webscout/auth/models.py +185 -185
- webscout/auth/routes.py +663 -664
- webscout/auth/simple_logger.py +236 -236
- webscout/cli.py +523 -523
- webscout/conversation.py +438 -438
- webscout/exceptions.py +361 -361
- webscout/litagent/Readme.md +298 -298
- webscout/litagent/__init__.py +28 -28
- webscout/litagent/agent.py +581 -581
- webscout/litagent/constants.py +59 -59
- webscout/litprinter/__init__.py +58 -58
- webscout/models.py +181 -181
- webscout/optimizers.py +419 -419
- webscout/prompt_manager.py +288 -288
- webscout/sanitize.py +1078 -1078
- webscout/scout/README.md +401 -401
- webscout/scout/__init__.py +8 -8
- webscout/scout/core/__init__.py +6 -6
- webscout/scout/core/crawler.py +297 -297
- webscout/scout/core/scout.py +706 -706
- webscout/scout/core/search_result.py +95 -95
- webscout/scout/core/text_analyzer.py +62 -62
- webscout/scout/core/text_utils.py +277 -277
- webscout/scout/core/web_analyzer.py +51 -51
- webscout/scout/element.py +599 -599
- 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 +37 -37
- webscout/search/__init__.py +51 -0
- webscout/search/base.py +195 -0
- webscout/search/duckduckgo_main.py +54 -0
- webscout/search/engines/__init__.py +48 -0
- webscout/search/engines/bing.py +84 -0
- webscout/search/engines/bing_news.py +52 -0
- webscout/search/engines/brave.py +43 -0
- webscout/search/engines/duckduckgo/__init__.py +25 -0
- webscout/search/engines/duckduckgo/answers.py +78 -0
- webscout/search/engines/duckduckgo/base.py +187 -0
- webscout/search/engines/duckduckgo/images.py +97 -0
- webscout/search/engines/duckduckgo/maps.py +168 -0
- webscout/search/engines/duckduckgo/news.py +68 -0
- webscout/search/engines/duckduckgo/suggestions.py +21 -0
- webscout/search/engines/duckduckgo/text.py +211 -0
- webscout/search/engines/duckduckgo/translate.py +47 -0
- webscout/search/engines/duckduckgo/videos.py +63 -0
- webscout/search/engines/duckduckgo/weather.py +74 -0
- webscout/search/engines/mojeek.py +37 -0
- webscout/search/engines/wikipedia.py +56 -0
- webscout/search/engines/yahoo.py +65 -0
- webscout/search/engines/yahoo_news.py +64 -0
- webscout/search/engines/yandex.py +43 -0
- webscout/search/engines/yep/__init__.py +13 -0
- webscout/search/engines/yep/base.py +32 -0
- webscout/search/engines/yep/images.py +99 -0
- webscout/search/engines/yep/suggestions.py +35 -0
- webscout/search/engines/yep/text.py +114 -0
- webscout/search/http_client.py +156 -0
- webscout/search/results.py +137 -0
- webscout/search/yep_main.py +44 -0
- webscout/swiftcli/Readme.md +323 -323
- webscout/swiftcli/__init__.py +95 -95
- webscout/swiftcli/core/__init__.py +7 -7
- webscout/swiftcli/core/cli.py +308 -308
- webscout/swiftcli/core/context.py +104 -104
- webscout/swiftcli/core/group.py +241 -241
- webscout/swiftcli/decorators/__init__.py +28 -28
- webscout/swiftcli/decorators/command.py +221 -221
- webscout/swiftcli/decorators/options.py +220 -220
- webscout/swiftcli/decorators/output.py +302 -302
- webscout/swiftcli/exceptions.py +21 -21
- webscout/swiftcli/plugins/__init__.py +9 -9
- webscout/swiftcli/plugins/base.py +135 -135
- webscout/swiftcli/plugins/manager.py +269 -269
- webscout/swiftcli/utils/__init__.py +59 -59
- webscout/swiftcli/utils/formatting.py +252 -252
- webscout/swiftcli/utils/parsing.py +267 -267
- webscout/update_checker.py +117 -117
- webscout/version.py +1 -1
- webscout/version.py.bak +2 -0
- webscout/zeroart/README.md +89 -89
- webscout/zeroart/__init__.py +134 -134
- webscout/zeroart/base.py +66 -66
- webscout/zeroart/effects.py +100 -100
- webscout/zeroart/fonts.py +1238 -1238
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/METADATA +936 -937
- webscout-2025.10.13.dist-info/RECORD +329 -0
- webscout/Provider/AISEARCH/DeepFind.py +0 -254
- webscout/Provider/OPENAI/Qwen3.py +0 -303
- webscout/Provider/OPENAI/qodo.py +0 -630
- webscout/Provider/OPENAI/xenai.py +0 -514
- webscout/tempid.py +0 -134
- webscout/webscout_search.py +0 -1183
- webscout/webscout_search_async.py +0 -649
- webscout/yep_search.py +0 -346
- webscout-8.3.7.dist-info/RECORD +0 -301
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/WHEEL +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/entry_points.txt +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.13.dist-info}/top_level.txt +0 -0
|
@@ -1,252 +1,252 @@
|
|
|
1
|
-
"""Utility functions for text formatting and styling."""
|
|
2
|
-
|
|
3
|
-
import re
|
|
4
|
-
from typing import Any, Dict, List, Optional, Union
|
|
5
|
-
|
|
6
|
-
from rich.console import Console
|
|
7
|
-
from rich.style import Style
|
|
8
|
-
from rich.text import Text
|
|
9
|
-
from rich.table import Table
|
|
10
|
-
from rich.padding import Padding
|
|
11
|
-
|
|
12
|
-
console = Console()
|
|
13
|
-
|
|
14
|
-
def style_text(
|
|
15
|
-
text: str,
|
|
16
|
-
color: Optional[str] = None,
|
|
17
|
-
bold: bool = False,
|
|
18
|
-
italic: bool = False,
|
|
19
|
-
underline: bool = False
|
|
20
|
-
) -> Text:
|
|
21
|
-
"""
|
|
22
|
-
Apply styling to text.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
text: Text to style
|
|
26
|
-
color: Text color
|
|
27
|
-
bold: Bold text
|
|
28
|
-
italic: Italic text
|
|
29
|
-
underline: Underline text
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
Rich Text object with applied styling
|
|
33
|
-
"""
|
|
34
|
-
style = []
|
|
35
|
-
if color:
|
|
36
|
-
style.append(color)
|
|
37
|
-
if bold:
|
|
38
|
-
style.append("bold")
|
|
39
|
-
if italic:
|
|
40
|
-
style.append("italic")
|
|
41
|
-
if underline:
|
|
42
|
-
style.append("underline")
|
|
43
|
-
|
|
44
|
-
return Text(text, style=" ".join(style))
|
|
45
|
-
|
|
46
|
-
def format_error(message: str, title: str = "Error") -> None:
|
|
47
|
-
"""
|
|
48
|
-
Format and display error message.
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
message: Error message
|
|
52
|
-
title: Error title
|
|
53
|
-
"""
|
|
54
|
-
console.print(f"[bold red]{title}:[/] {message}")
|
|
55
|
-
|
|
56
|
-
def format_warning(message: str, title: str = "Warning") -> None:
|
|
57
|
-
"""
|
|
58
|
-
Format and display warning message.
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
message: Warning message
|
|
62
|
-
title: Warning title
|
|
63
|
-
"""
|
|
64
|
-
console.print(f"[bold yellow]{title}:[/] {message}")
|
|
65
|
-
|
|
66
|
-
def format_success(message: str, title: str = "Success") -> None:
|
|
67
|
-
"""
|
|
68
|
-
Format and display success message.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
message: Success message
|
|
72
|
-
title: Success title
|
|
73
|
-
"""
|
|
74
|
-
console.print(f"[bold green]{title}:[/] {message}")
|
|
75
|
-
|
|
76
|
-
def format_info(message: str, title: str = "Info") -> None:
|
|
77
|
-
"""
|
|
78
|
-
Format and display info message.
|
|
79
|
-
|
|
80
|
-
Args:
|
|
81
|
-
message: Info message
|
|
82
|
-
title: Info title
|
|
83
|
-
"""
|
|
84
|
-
console.print(f"[bold blue]{title}:[/] {message}")
|
|
85
|
-
|
|
86
|
-
def create_table(
|
|
87
|
-
headers: List[str],
|
|
88
|
-
rows: List[List[Any]],
|
|
89
|
-
title: Optional[str] = None,
|
|
90
|
-
style: str = "default",
|
|
91
|
-
show_lines: bool = False
|
|
92
|
-
) -> Table:
|
|
93
|
-
"""
|
|
94
|
-
Create a formatted table.
|
|
95
|
-
|
|
96
|
-
Args:
|
|
97
|
-
headers: Column headers
|
|
98
|
-
rows: Table rows
|
|
99
|
-
title: Table title
|
|
100
|
-
style: Table style
|
|
101
|
-
show_lines: Show row/column lines
|
|
102
|
-
|
|
103
|
-
Returns:
|
|
104
|
-
Rich Table object
|
|
105
|
-
"""
|
|
106
|
-
table = Table(
|
|
107
|
-
title=title,
|
|
108
|
-
show_header=True,
|
|
109
|
-
header_style="bold blue",
|
|
110
|
-
show_lines=show_lines
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
# Add columns
|
|
114
|
-
for header in headers:
|
|
115
|
-
table.add_column(header)
|
|
116
|
-
|
|
117
|
-
# Add rows
|
|
118
|
-
for row in rows:
|
|
119
|
-
table.add_row(*[str(cell) for cell in row])
|
|
120
|
-
|
|
121
|
-
return table
|
|
122
|
-
|
|
123
|
-
def truncate_text(
|
|
124
|
-
text: str,
|
|
125
|
-
max_length: int,
|
|
126
|
-
suffix: str = "..."
|
|
127
|
-
) -> str:
|
|
128
|
-
"""
|
|
129
|
-
Truncate text to specified length.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
text: Text to truncate
|
|
133
|
-
max_length: Maximum length
|
|
134
|
-
suffix: Truncation suffix
|
|
135
|
-
|
|
136
|
-
Returns:
|
|
137
|
-
Truncated text
|
|
138
|
-
"""
|
|
139
|
-
if len(text) <= max_length:
|
|
140
|
-
return text
|
|
141
|
-
return text[:max_length - len(suffix)] + suffix
|
|
142
|
-
|
|
143
|
-
def wrap_text(
|
|
144
|
-
text: str,
|
|
145
|
-
width: int,
|
|
146
|
-
indent: str = "",
|
|
147
|
-
initial_indent: str = ""
|
|
148
|
-
) -> str:
|
|
149
|
-
"""
|
|
150
|
-
Wrap text to specified width.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
text: Text to wrap
|
|
154
|
-
width: Maximum line width
|
|
155
|
-
indent: Indentation for wrapped lines
|
|
156
|
-
initial_indent: Indentation for first line
|
|
157
|
-
|
|
158
|
-
Returns:
|
|
159
|
-
Wrapped text
|
|
160
|
-
"""
|
|
161
|
-
import textwrap
|
|
162
|
-
return textwrap.fill(
|
|
163
|
-
text,
|
|
164
|
-
width=width,
|
|
165
|
-
initial_indent=initial_indent,
|
|
166
|
-
subsequent_indent=indent
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
def format_dict(
|
|
170
|
-
data: Dict[str, Any],
|
|
171
|
-
indent: int = 2,
|
|
172
|
-
sort_keys: bool = True
|
|
173
|
-
) -> str:
|
|
174
|
-
"""
|
|
175
|
-
Format dictionary for display.
|
|
176
|
-
|
|
177
|
-
Args:
|
|
178
|
-
data: Dictionary to format
|
|
179
|
-
indent: Indentation level
|
|
180
|
-
sort_keys: Sort dictionary keys
|
|
181
|
-
|
|
182
|
-
Returns:
|
|
183
|
-
Formatted string
|
|
184
|
-
"""
|
|
185
|
-
import json
|
|
186
|
-
return json.dumps(
|
|
187
|
-
data,
|
|
188
|
-
indent=indent,
|
|
189
|
-
sort_keys=sort_keys,
|
|
190
|
-
default=str
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
def format_list(
|
|
194
|
-
items: List[Any],
|
|
195
|
-
bullet: str = "•",
|
|
196
|
-
indent: int = 2
|
|
197
|
-
) -> str:
|
|
198
|
-
"""
|
|
199
|
-
Format list for display.
|
|
200
|
-
|
|
201
|
-
Args:
|
|
202
|
-
items: List to format
|
|
203
|
-
bullet: Bullet point character
|
|
204
|
-
indent: Indentation level
|
|
205
|
-
|
|
206
|
-
Returns:
|
|
207
|
-
Formatted string
|
|
208
|
-
"""
|
|
209
|
-
indent_str = " " * indent
|
|
210
|
-
return "\n".join(f"{indent_str}{bullet} {item}" for item in items)
|
|
211
|
-
|
|
212
|
-
def strip_ansi(text: str) -> str:
|
|
213
|
-
"""
|
|
214
|
-
Remove ANSI escape sequences from text.
|
|
215
|
-
|
|
216
|
-
Args:
|
|
217
|
-
text: Text containing ANSI sequences
|
|
218
|
-
|
|
219
|
-
Returns:
|
|
220
|
-
Clean text
|
|
221
|
-
"""
|
|
222
|
-
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
|
223
|
-
return ansi_escape.sub('', text)
|
|
224
|
-
|
|
225
|
-
def get_terminal_size() -> tuple:
|
|
226
|
-
"""
|
|
227
|
-
Get terminal size.
|
|
228
|
-
|
|
229
|
-
Returns:
|
|
230
|
-
Tuple of (width, height)
|
|
231
|
-
"""
|
|
232
|
-
return console.size
|
|
233
|
-
|
|
234
|
-
def clear_screen() -> None:
|
|
235
|
-
"""Clear the terminal screen."""
|
|
236
|
-
console.clear()
|
|
237
|
-
|
|
238
|
-
def create_padding(
|
|
239
|
-
renderable: Any,
|
|
240
|
-
pad: Union[int, tuple] = 1
|
|
241
|
-
) -> Padding:
|
|
242
|
-
"""
|
|
243
|
-
Add padding around content.
|
|
244
|
-
|
|
245
|
-
Args:
|
|
246
|
-
renderable: Content to pad
|
|
247
|
-
pad: Padding amount
|
|
248
|
-
|
|
249
|
-
Returns:
|
|
250
|
-
Padded content
|
|
251
|
-
"""
|
|
252
|
-
return Padding(renderable, pad)
|
|
1
|
+
"""Utility functions for text formatting and styling."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from typing import Any, Dict, List, Optional, Union
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.style import Style
|
|
8
|
+
from rich.text import Text
|
|
9
|
+
from rich.table import Table
|
|
10
|
+
from rich.padding import Padding
|
|
11
|
+
|
|
12
|
+
console = Console()
|
|
13
|
+
|
|
14
|
+
def style_text(
|
|
15
|
+
text: str,
|
|
16
|
+
color: Optional[str] = None,
|
|
17
|
+
bold: bool = False,
|
|
18
|
+
italic: bool = False,
|
|
19
|
+
underline: bool = False
|
|
20
|
+
) -> Text:
|
|
21
|
+
"""
|
|
22
|
+
Apply styling to text.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
text: Text to style
|
|
26
|
+
color: Text color
|
|
27
|
+
bold: Bold text
|
|
28
|
+
italic: Italic text
|
|
29
|
+
underline: Underline text
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Rich Text object with applied styling
|
|
33
|
+
"""
|
|
34
|
+
style = []
|
|
35
|
+
if color:
|
|
36
|
+
style.append(color)
|
|
37
|
+
if bold:
|
|
38
|
+
style.append("bold")
|
|
39
|
+
if italic:
|
|
40
|
+
style.append("italic")
|
|
41
|
+
if underline:
|
|
42
|
+
style.append("underline")
|
|
43
|
+
|
|
44
|
+
return Text(text, style=" ".join(style))
|
|
45
|
+
|
|
46
|
+
def format_error(message: str, title: str = "Error") -> None:
|
|
47
|
+
"""
|
|
48
|
+
Format and display error message.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
message: Error message
|
|
52
|
+
title: Error title
|
|
53
|
+
"""
|
|
54
|
+
console.print(f"[bold red]{title}:[/] {message}")
|
|
55
|
+
|
|
56
|
+
def format_warning(message: str, title: str = "Warning") -> None:
|
|
57
|
+
"""
|
|
58
|
+
Format and display warning message.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
message: Warning message
|
|
62
|
+
title: Warning title
|
|
63
|
+
"""
|
|
64
|
+
console.print(f"[bold yellow]{title}:[/] {message}")
|
|
65
|
+
|
|
66
|
+
def format_success(message: str, title: str = "Success") -> None:
|
|
67
|
+
"""
|
|
68
|
+
Format and display success message.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
message: Success message
|
|
72
|
+
title: Success title
|
|
73
|
+
"""
|
|
74
|
+
console.print(f"[bold green]{title}:[/] {message}")
|
|
75
|
+
|
|
76
|
+
def format_info(message: str, title: str = "Info") -> None:
|
|
77
|
+
"""
|
|
78
|
+
Format and display info message.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
message: Info message
|
|
82
|
+
title: Info title
|
|
83
|
+
"""
|
|
84
|
+
console.print(f"[bold blue]{title}:[/] {message}")
|
|
85
|
+
|
|
86
|
+
def create_table(
|
|
87
|
+
headers: List[str],
|
|
88
|
+
rows: List[List[Any]],
|
|
89
|
+
title: Optional[str] = None,
|
|
90
|
+
style: str = "default",
|
|
91
|
+
show_lines: bool = False
|
|
92
|
+
) -> Table:
|
|
93
|
+
"""
|
|
94
|
+
Create a formatted table.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
headers: Column headers
|
|
98
|
+
rows: Table rows
|
|
99
|
+
title: Table title
|
|
100
|
+
style: Table style
|
|
101
|
+
show_lines: Show row/column lines
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Rich Table object
|
|
105
|
+
"""
|
|
106
|
+
table = Table(
|
|
107
|
+
title=title,
|
|
108
|
+
show_header=True,
|
|
109
|
+
header_style="bold blue",
|
|
110
|
+
show_lines=show_lines
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Add columns
|
|
114
|
+
for header in headers:
|
|
115
|
+
table.add_column(header)
|
|
116
|
+
|
|
117
|
+
# Add rows
|
|
118
|
+
for row in rows:
|
|
119
|
+
table.add_row(*[str(cell) for cell in row])
|
|
120
|
+
|
|
121
|
+
return table
|
|
122
|
+
|
|
123
|
+
def truncate_text(
|
|
124
|
+
text: str,
|
|
125
|
+
max_length: int,
|
|
126
|
+
suffix: str = "..."
|
|
127
|
+
) -> str:
|
|
128
|
+
"""
|
|
129
|
+
Truncate text to specified length.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
text: Text to truncate
|
|
133
|
+
max_length: Maximum length
|
|
134
|
+
suffix: Truncation suffix
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Truncated text
|
|
138
|
+
"""
|
|
139
|
+
if len(text) <= max_length:
|
|
140
|
+
return text
|
|
141
|
+
return text[:max_length - len(suffix)] + suffix
|
|
142
|
+
|
|
143
|
+
def wrap_text(
|
|
144
|
+
text: str,
|
|
145
|
+
width: int,
|
|
146
|
+
indent: str = "",
|
|
147
|
+
initial_indent: str = ""
|
|
148
|
+
) -> str:
|
|
149
|
+
"""
|
|
150
|
+
Wrap text to specified width.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
text: Text to wrap
|
|
154
|
+
width: Maximum line width
|
|
155
|
+
indent: Indentation for wrapped lines
|
|
156
|
+
initial_indent: Indentation for first line
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Wrapped text
|
|
160
|
+
"""
|
|
161
|
+
import textwrap
|
|
162
|
+
return textwrap.fill(
|
|
163
|
+
text,
|
|
164
|
+
width=width,
|
|
165
|
+
initial_indent=initial_indent,
|
|
166
|
+
subsequent_indent=indent
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def format_dict(
|
|
170
|
+
data: Dict[str, Any],
|
|
171
|
+
indent: int = 2,
|
|
172
|
+
sort_keys: bool = True
|
|
173
|
+
) -> str:
|
|
174
|
+
"""
|
|
175
|
+
Format dictionary for display.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
data: Dictionary to format
|
|
179
|
+
indent: Indentation level
|
|
180
|
+
sort_keys: Sort dictionary keys
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Formatted string
|
|
184
|
+
"""
|
|
185
|
+
import json
|
|
186
|
+
return json.dumps(
|
|
187
|
+
data,
|
|
188
|
+
indent=indent,
|
|
189
|
+
sort_keys=sort_keys,
|
|
190
|
+
default=str
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
def format_list(
|
|
194
|
+
items: List[Any],
|
|
195
|
+
bullet: str = "•",
|
|
196
|
+
indent: int = 2
|
|
197
|
+
) -> str:
|
|
198
|
+
"""
|
|
199
|
+
Format list for display.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
items: List to format
|
|
203
|
+
bullet: Bullet point character
|
|
204
|
+
indent: Indentation level
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Formatted string
|
|
208
|
+
"""
|
|
209
|
+
indent_str = " " * indent
|
|
210
|
+
return "\n".join(f"{indent_str}{bullet} {item}" for item in items)
|
|
211
|
+
|
|
212
|
+
def strip_ansi(text: str) -> str:
|
|
213
|
+
"""
|
|
214
|
+
Remove ANSI escape sequences from text.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
text: Text containing ANSI sequences
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
Clean text
|
|
221
|
+
"""
|
|
222
|
+
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
|
223
|
+
return ansi_escape.sub('', text)
|
|
224
|
+
|
|
225
|
+
def get_terminal_size() -> tuple:
|
|
226
|
+
"""
|
|
227
|
+
Get terminal size.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
Tuple of (width, height)
|
|
231
|
+
"""
|
|
232
|
+
return console.size
|
|
233
|
+
|
|
234
|
+
def clear_screen() -> None:
|
|
235
|
+
"""Clear the terminal screen."""
|
|
236
|
+
console.clear()
|
|
237
|
+
|
|
238
|
+
def create_padding(
|
|
239
|
+
renderable: Any,
|
|
240
|
+
pad: Union[int, tuple] = 1
|
|
241
|
+
) -> Padding:
|
|
242
|
+
"""
|
|
243
|
+
Add padding around content.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
renderable: Content to pad
|
|
247
|
+
pad: Padding amount
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
Padded content
|
|
251
|
+
"""
|
|
252
|
+
return Padding(renderable, pad)
|