webscout 8.2.8__py3-none-any.whl → 8.3__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 +34 -16
- webscout/AIbase.py +96 -37
- webscout/AIutel.py +491 -87
- webscout/Bard.py +441 -323
- webscout/Extra/GitToolkit/__init__.py +10 -10
- webscout/Extra/YTToolkit/ytapi/video.py +232 -232
- webscout/Litlogger/README.md +10 -0
- webscout/Litlogger/__init__.py +7 -59
- webscout/Litlogger/formats.py +4 -0
- webscout/Litlogger/handlers.py +103 -0
- webscout/Litlogger/levels.py +13 -0
- webscout/Litlogger/logger.py +92 -0
- webscout/Provider/AISEARCH/Perplexity.py +332 -358
- webscout/Provider/AISEARCH/felo_search.py +9 -35
- webscout/Provider/AISEARCH/genspark_search.py +30 -56
- webscout/Provider/AISEARCH/hika_search.py +4 -16
- webscout/Provider/AISEARCH/iask_search.py +410 -436
- webscout/Provider/AISEARCH/monica_search.py +4 -30
- webscout/Provider/AISEARCH/scira_search.py +6 -32
- webscout/Provider/AISEARCH/webpilotai_search.py +38 -64
- webscout/Provider/Blackboxai.py +155 -35
- webscout/Provider/ChatSandbox.py +2 -1
- webscout/Provider/Deepinfra.py +339 -339
- webscout/Provider/ExaChat.py +358 -358
- webscout/Provider/Gemini.py +169 -169
- webscout/Provider/GithubChat.py +1 -2
- webscout/Provider/Glider.py +3 -3
- webscout/Provider/HeckAI.py +172 -82
- webscout/Provider/LambdaChat.py +1 -0
- webscout/Provider/MCPCore.py +7 -3
- webscout/Provider/OPENAI/BLACKBOXAI.py +421 -139
- webscout/Provider/OPENAI/Cloudflare.py +38 -21
- webscout/Provider/OPENAI/FalconH1.py +457 -0
- webscout/Provider/OPENAI/FreeGemini.py +35 -18
- webscout/Provider/OPENAI/NEMOTRON.py +34 -34
- webscout/Provider/OPENAI/PI.py +427 -0
- webscout/Provider/OPENAI/Qwen3.py +304 -0
- webscout/Provider/OPENAI/README.md +952 -1253
- webscout/Provider/OPENAI/TwoAI.py +374 -0
- webscout/Provider/OPENAI/__init__.py +7 -1
- webscout/Provider/OPENAI/ai4chat.py +73 -63
- webscout/Provider/OPENAI/api.py +869 -644
- webscout/Provider/OPENAI/base.py +2 -0
- webscout/Provider/OPENAI/c4ai.py +34 -13
- webscout/Provider/OPENAI/chatgpt.py +575 -556
- webscout/Provider/OPENAI/chatgptclone.py +512 -487
- webscout/Provider/OPENAI/chatsandbox.py +11 -6
- webscout/Provider/OPENAI/copilot.py +258 -0
- webscout/Provider/OPENAI/deepinfra.py +327 -318
- webscout/Provider/OPENAI/e2b.py +140 -104
- webscout/Provider/OPENAI/exaai.py +420 -411
- webscout/Provider/OPENAI/exachat.py +448 -443
- webscout/Provider/OPENAI/flowith.py +7 -3
- webscout/Provider/OPENAI/freeaichat.py +12 -8
- webscout/Provider/OPENAI/glider.py +15 -8
- webscout/Provider/OPENAI/groq.py +5 -2
- webscout/Provider/OPENAI/heckai.py +311 -307
- webscout/Provider/OPENAI/llmchatco.py +9 -7
- webscout/Provider/OPENAI/mcpcore.py +18 -9
- webscout/Provider/OPENAI/multichat.py +7 -5
- webscout/Provider/OPENAI/netwrck.py +16 -11
- webscout/Provider/OPENAI/oivscode.py +290 -0
- webscout/Provider/OPENAI/opkfc.py +507 -496
- webscout/Provider/OPENAI/pydantic_imports.py +172 -0
- webscout/Provider/OPENAI/scirachat.py +29 -17
- webscout/Provider/OPENAI/sonus.py +308 -303
- webscout/Provider/OPENAI/standardinput.py +442 -433
- webscout/Provider/OPENAI/textpollinations.py +18 -11
- webscout/Provider/OPENAI/toolbaz.py +419 -413
- webscout/Provider/OPENAI/typefully.py +17 -10
- webscout/Provider/OPENAI/typegpt.py +21 -11
- webscout/Provider/OPENAI/uncovrAI.py +477 -462
- webscout/Provider/OPENAI/utils.py +90 -79
- webscout/Provider/OPENAI/venice.py +435 -425
- webscout/Provider/OPENAI/wisecat.py +387 -381
- webscout/Provider/OPENAI/writecream.py +166 -163
- webscout/Provider/OPENAI/x0gpt.py +26 -37
- webscout/Provider/OPENAI/yep.py +384 -356
- webscout/Provider/PI.py +2 -1
- webscout/Provider/TTI/README.md +55 -101
- webscout/Provider/TTI/__init__.py +4 -9
- webscout/Provider/TTI/aiarta.py +365 -0
- webscout/Provider/TTI/artbit.py +0 -0
- webscout/Provider/TTI/base.py +64 -0
- webscout/Provider/TTI/fastflux.py +200 -0
- webscout/Provider/TTI/magicstudio.py +201 -0
- webscout/Provider/TTI/piclumen.py +203 -0
- webscout/Provider/TTI/pixelmuse.py +225 -0
- webscout/Provider/TTI/pollinations.py +221 -0
- webscout/Provider/TTI/utils.py +11 -0
- webscout/Provider/TTS/__init__.py +2 -1
- webscout/Provider/TTS/base.py +159 -159
- webscout/Provider/TTS/openai_fm.py +129 -0
- webscout/Provider/TextPollinationsAI.py +308 -308
- webscout/Provider/TwoAI.py +239 -44
- webscout/Provider/UNFINISHED/Youchat.py +330 -330
- webscout/Provider/UNFINISHED/puterjs.py +635 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
- webscout/Provider/Writecream.py +246 -246
- webscout/Provider/__init__.py +2 -2
- webscout/Provider/ai4chat.py +33 -8
- webscout/Provider/granite.py +41 -6
- webscout/Provider/koala.py +169 -169
- webscout/Provider/oivscode.py +309 -0
- webscout/Provider/samurai.py +3 -2
- webscout/Provider/scnet.py +1 -0
- webscout/Provider/typegpt.py +3 -3
- webscout/Provider/uncovr.py +368 -368
- webscout/client.py +70 -0
- webscout/litprinter/__init__.py +58 -58
- webscout/optimizers.py +419 -419
- webscout/scout/README.md +3 -1
- webscout/scout/core/crawler.py +134 -64
- webscout/scout/core/scout.py +148 -109
- webscout/scout/element.py +106 -88
- webscout/swiftcli/Readme.md +323 -323
- webscout/swiftcli/plugins/manager.py +9 -2
- webscout/version.py +1 -1
- webscout/zeroart/__init__.py +134 -134
- webscout/zeroart/effects.py +100 -100
- webscout/zeroart/fonts.py +1238 -1238
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/METADATA +160 -35
- webscout-8.3.dist-info/RECORD +290 -0
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/WHEEL +1 -1
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/entry_points.txt +1 -0
- webscout/Litlogger/Readme.md +0 -175
- webscout/Litlogger/core/__init__.py +0 -6
- webscout/Litlogger/core/level.py +0 -23
- webscout/Litlogger/core/logger.py +0 -165
- webscout/Litlogger/handlers/__init__.py +0 -12
- webscout/Litlogger/handlers/console.py +0 -33
- webscout/Litlogger/handlers/file.py +0 -143
- webscout/Litlogger/handlers/network.py +0 -173
- webscout/Litlogger/styles/__init__.py +0 -7
- webscout/Litlogger/styles/colors.py +0 -249
- webscout/Litlogger/styles/formats.py +0 -458
- webscout/Litlogger/styles/text.py +0 -87
- webscout/Litlogger/utils/__init__.py +0 -6
- webscout/Litlogger/utils/detectors.py +0 -153
- webscout/Litlogger/utils/formatters.py +0 -200
- webscout/Provider/ChatGPTGratis.py +0 -194
- webscout/Provider/TTI/AiForce/README.md +0 -159
- webscout/Provider/TTI/AiForce/__init__.py +0 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
- webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
- webscout/Provider/TTI/FreeAIPlayground/README.md +0 -99
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
- webscout/Provider/TTI/ImgSys/README.md +0 -174
- webscout/Provider/TTI/ImgSys/__init__.py +0 -23
- webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
- webscout/Provider/TTI/MagicStudio/README.md +0 -101
- webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
- webscout/Provider/TTI/Nexra/README.md +0 -155
- webscout/Provider/TTI/Nexra/__init__.py +0 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
- webscout/Provider/TTI/PollinationsAI/README.md +0 -146
- webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
- webscout/Provider/TTI/aiarta/README.md +0 -134
- webscout/Provider/TTI/aiarta/__init__.py +0 -2
- webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
- webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
- webscout/Provider/TTI/artbit/README.md +0 -100
- webscout/Provider/TTI/artbit/__init__.py +0 -22
- webscout/Provider/TTI/artbit/async_artbit.py +0 -155
- webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
- webscout/Provider/TTI/fastflux/README.md +0 -129
- webscout/Provider/TTI/fastflux/__init__.py +0 -22
- webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
- webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
- webscout/Provider/TTI/huggingface/README.md +0 -114
- webscout/Provider/TTI/huggingface/__init__.py +0 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
- webscout/Provider/TTI/piclumen/README.md +0 -161
- webscout/Provider/TTI/piclumen/__init__.py +0 -23
- webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
- webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
- webscout/Provider/TTI/pixelmuse/README.md +0 -79
- webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
- webscout/Provider/TTI/talkai/README.md +0 -139
- webscout/Provider/TTI/talkai/__init__.py +0 -4
- webscout/Provider/TTI/talkai/async_talkai.py +0 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
- webscout/Provider/UNFINISHED/oivscode.py +0 -351
- webscout-8.2.8.dist-info/RECORD +0 -334
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/top_level.txt +0 -0
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import json
|
|
3
|
-
import socket
|
|
4
|
-
from typing import Optional, Dict, Any
|
|
5
|
-
import aiohttp
|
|
6
|
-
from ..core.level import LogLevel
|
|
7
|
-
|
|
8
|
-
class NetworkHandler:
|
|
9
|
-
"""Handler for sending log messages to a remote server."""
|
|
10
|
-
|
|
11
|
-
def __init__(
|
|
12
|
-
self,
|
|
13
|
-
host: str,
|
|
14
|
-
port: int,
|
|
15
|
-
protocol: str = "http",
|
|
16
|
-
endpoint: str = "/logs",
|
|
17
|
-
method: str = "POST",
|
|
18
|
-
headers: Optional[Dict[str, str]] = None,
|
|
19
|
-
timeout: float = 5.0,
|
|
20
|
-
level: LogLevel = LogLevel.DEBUG,
|
|
21
|
-
batch_size: int = 0,
|
|
22
|
-
retry_count: int = 3,
|
|
23
|
-
retry_delay: float = 1.0,
|
|
24
|
-
custom_fields: Optional[Dict[str, Any]] = None
|
|
25
|
-
):
|
|
26
|
-
"""
|
|
27
|
-
Initialize network handler.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
host: Remote server hostname/IP
|
|
31
|
-
port: Remote server port
|
|
32
|
-
protocol: 'http', 'https', or 'tcp'
|
|
33
|
-
endpoint: Server endpoint for HTTP/HTTPS
|
|
34
|
-
method: HTTP method to use
|
|
35
|
-
headers: Optional HTTP headers
|
|
36
|
-
timeout: Request timeout in seconds
|
|
37
|
-
level: Minimum log level to send
|
|
38
|
-
batch_size: Number of logs to batch (0 = no batching)
|
|
39
|
-
retry_count: Number of retries on failure
|
|
40
|
-
retry_delay: Delay between retries in seconds
|
|
41
|
-
custom_fields: Additional fields to include in log data
|
|
42
|
-
"""
|
|
43
|
-
self.host = host
|
|
44
|
-
self.port = port
|
|
45
|
-
self.protocol = protocol.lower()
|
|
46
|
-
self.endpoint = endpoint
|
|
47
|
-
self.method = method.upper()
|
|
48
|
-
self.headers = headers or {}
|
|
49
|
-
self.timeout = timeout
|
|
50
|
-
self.level = level
|
|
51
|
-
self.batch_size = batch_size
|
|
52
|
-
self.retry_count = retry_count
|
|
53
|
-
self.retry_delay = retry_delay
|
|
54
|
-
self.custom_fields = custom_fields or {}
|
|
55
|
-
|
|
56
|
-
if self.protocol not in ["http", "https", "tcp"]:
|
|
57
|
-
raise ValueError("Protocol must be 'http', 'https' or 'tcp'")
|
|
58
|
-
|
|
59
|
-
self._batch = []
|
|
60
|
-
self._tcp_socket = None
|
|
61
|
-
self._session = None
|
|
62
|
-
|
|
63
|
-
async def _init_session(self):
|
|
64
|
-
"""Initialize HTTP session if needed."""
|
|
65
|
-
if self.protocol in ["http", "https"] and not self._session:
|
|
66
|
-
self._session = aiohttp.ClientSession(
|
|
67
|
-
timeout=aiohttp.ClientTimeout(total=self.timeout)
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
async def _send_http(self, data: Dict[str, Any]) -> bool:
|
|
71
|
-
"""Send log data via HTTP/HTTPS."""
|
|
72
|
-
await self._init_session()
|
|
73
|
-
|
|
74
|
-
url = f"{self.protocol}://{self.host}:{self.port}{self.endpoint}"
|
|
75
|
-
|
|
76
|
-
for attempt in range(self.retry_count + 1):
|
|
77
|
-
try:
|
|
78
|
-
async with self._session.request(
|
|
79
|
-
method=self.method,
|
|
80
|
-
url=url,
|
|
81
|
-
json=data,
|
|
82
|
-
headers=self.headers
|
|
83
|
-
) as response:
|
|
84
|
-
return response.status < 400
|
|
85
|
-
|
|
86
|
-
except Exception:
|
|
87
|
-
if attempt == self.retry_count:
|
|
88
|
-
return False
|
|
89
|
-
await asyncio.sleep(self.retry_delay)
|
|
90
|
-
|
|
91
|
-
async def _send_tcp(self, data: Dict[str, Any]) -> bool:
|
|
92
|
-
"""Send log data via TCP."""
|
|
93
|
-
message = json.dumps(data).encode() + b"\n"
|
|
94
|
-
|
|
95
|
-
for attempt in range(self.retry_count + 1):
|
|
96
|
-
try:
|
|
97
|
-
if not self._tcp_socket:
|
|
98
|
-
self._tcp_socket = socket.socket(
|
|
99
|
-
socket.AF_INET, socket.SOCK_STREAM
|
|
100
|
-
)
|
|
101
|
-
self._tcp_socket.settimeout(self.timeout)
|
|
102
|
-
self._tcp_socket.connect((self.host, self.port))
|
|
103
|
-
|
|
104
|
-
self._tcp_socket.sendall(message)
|
|
105
|
-
return True
|
|
106
|
-
|
|
107
|
-
except Exception:
|
|
108
|
-
if self._tcp_socket:
|
|
109
|
-
self._tcp_socket.close()
|
|
110
|
-
self._tcp_socket = None
|
|
111
|
-
|
|
112
|
-
if attempt == self.retry_count:
|
|
113
|
-
return False
|
|
114
|
-
|
|
115
|
-
await asyncio.sleep(self.retry_delay)
|
|
116
|
-
|
|
117
|
-
def emit(self, message: str, level: LogLevel):
|
|
118
|
-
"""
|
|
119
|
-
Synchronously send log message.
|
|
120
|
-
Not recommended - use async_emit instead.
|
|
121
|
-
"""
|
|
122
|
-
if level.value >= self.level.value:
|
|
123
|
-
loop = asyncio.get_event_loop()
|
|
124
|
-
loop.run_until_complete(self.async_emit(message, level))
|
|
125
|
-
|
|
126
|
-
async def async_emit(self, message: str, level: LogLevel):
|
|
127
|
-
"""Asynchronously send log message to remote server."""
|
|
128
|
-
# Fix: Allow all messages if level is NOTSET
|
|
129
|
-
if self.level == LogLevel.NOTSET or level.value >= self.level.value:
|
|
130
|
-
log_data = {
|
|
131
|
-
"message": message,
|
|
132
|
-
"level": level.name,
|
|
133
|
-
**self.custom_fields
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if self.batch_size > 0:
|
|
137
|
-
self._batch.append(log_data)
|
|
138
|
-
if len(self._batch) >= self.batch_size:
|
|
139
|
-
await self._send_batch()
|
|
140
|
-
else:
|
|
141
|
-
if self.protocol in ["http", "https"]:
|
|
142
|
-
await self._send_http(log_data)
|
|
143
|
-
else:
|
|
144
|
-
await self._send_tcp(log_data)
|
|
145
|
-
|
|
146
|
-
async def _send_batch(self):
|
|
147
|
-
"""Send batched log messages."""
|
|
148
|
-
if not self._batch:
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
batch_data = {"logs": self._batch}
|
|
152
|
-
success = False
|
|
153
|
-
|
|
154
|
-
if self.protocol in ["http", "https"]:
|
|
155
|
-
success = await self._send_http(batch_data)
|
|
156
|
-
else:
|
|
157
|
-
success = await self._send_tcp(batch_data)
|
|
158
|
-
|
|
159
|
-
if success:
|
|
160
|
-
self._batch.clear()
|
|
161
|
-
|
|
162
|
-
async def close(self):
|
|
163
|
-
"""Close network connections."""
|
|
164
|
-
if self._batch:
|
|
165
|
-
await self._send_batch()
|
|
166
|
-
|
|
167
|
-
if self._tcp_socket:
|
|
168
|
-
self._tcp_socket.close()
|
|
169
|
-
self._tcp_socket = None
|
|
170
|
-
|
|
171
|
-
if self._session:
|
|
172
|
-
await self._session.close()
|
|
173
|
-
self._session = None
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
# Terminal Color Management System
|
|
2
|
-
# Provides extensive ANSI color support with themes, gradients, and animations
|
|
3
|
-
|
|
4
|
-
from typing import Optional
|
|
5
|
-
from ..core.level import LogLevel
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class LogColors:
|
|
9
|
-
"""
|
|
10
|
-
Comprehensive terminal color and styling system with support for:
|
|
11
|
-
- Basic and bright colors (foreground/background)
|
|
12
|
-
- RGB and 256-color modes
|
|
13
|
-
- Text styles (bold, italic, etc.)
|
|
14
|
-
- Gradients and animations
|
|
15
|
-
- Predefined themes
|
|
16
|
-
"""
|
|
17
|
-
# Reset
|
|
18
|
-
RESET = "\033[0m"
|
|
19
|
-
|
|
20
|
-
# Regular colors
|
|
21
|
-
BLACK = "\033[30m"
|
|
22
|
-
RED = "\033[31m"
|
|
23
|
-
GREEN = "\033[32m"
|
|
24
|
-
YELLOW = "\033[33m"
|
|
25
|
-
BLUE = "\033[34m"
|
|
26
|
-
MAGENTA = "\033[35m"
|
|
27
|
-
CYAN = "\033[36m"
|
|
28
|
-
WHITE = "\033[37m"
|
|
29
|
-
|
|
30
|
-
# Background colors
|
|
31
|
-
BG_BLACK = "\033[40m"
|
|
32
|
-
BG_RED = "\033[41m"
|
|
33
|
-
BG_GREEN = "\033[42m"
|
|
34
|
-
BG_YELLOW = "\033[43m"
|
|
35
|
-
BG_BLUE = "\033[44m"
|
|
36
|
-
BG_MAGENTA = "\033[45m"
|
|
37
|
-
BG_CYAN = "\033[46m"
|
|
38
|
-
BG_WHITE = "\033[47m"
|
|
39
|
-
|
|
40
|
-
# Bright colors
|
|
41
|
-
BRIGHT_BLACK = "\033[90m"
|
|
42
|
-
BRIGHT_RED = "\033[91m"
|
|
43
|
-
BRIGHT_GREEN = "\033[92m"
|
|
44
|
-
BRIGHT_YELLOW = "\033[93m"
|
|
45
|
-
BRIGHT_BLUE = "\033[94m"
|
|
46
|
-
BRIGHT_MAGENTA = "\033[95m"
|
|
47
|
-
BRIGHT_CYAN = "\033[96m"
|
|
48
|
-
BRIGHT_WHITE = "\033[97m"
|
|
49
|
-
|
|
50
|
-
# Bright background colors
|
|
51
|
-
BG_BRIGHT_BLACK = "\033[100m"
|
|
52
|
-
BG_BRIGHT_RED = "\033[101m"
|
|
53
|
-
BG_BRIGHT_GREEN = "\033[102m"
|
|
54
|
-
BG_BRIGHT_YELLOW = "\033[103m"
|
|
55
|
-
BG_BRIGHT_BLUE = "\033[104m"
|
|
56
|
-
BG_BRIGHT_MAGENTA = "\033[105m"
|
|
57
|
-
BG_BRIGHT_CYAN = "\033[106m"
|
|
58
|
-
BG_BRIGHT_WHITE = "\033[107m"
|
|
59
|
-
|
|
60
|
-
# Custom theme colors using RGB
|
|
61
|
-
FIRE = "\033[38;2;255;100;0m" # Orange-red
|
|
62
|
-
ICE = "\033[38;2;150;230;255m" # Light blue
|
|
63
|
-
GRASS = "\033[38;2;120;200;80m" # Light green
|
|
64
|
-
PURPLE = "\033[38;2;147;112;219m" # Medium purple
|
|
65
|
-
GOLD = "\033[38;2;255;215;0m" # Golden
|
|
66
|
-
|
|
67
|
-
# Gradient colors
|
|
68
|
-
SUNSET_START = "\033[38;2;255;128;0m" # Orange
|
|
69
|
-
SUNSET_END = "\033[38;2;255;51;153m" # Pink
|
|
70
|
-
|
|
71
|
-
OCEAN_START = "\033[38;2;0;204;255m" # Light blue
|
|
72
|
-
OCEAN_END = "\033[38;2;0;51;102m" # Dark blue
|
|
73
|
-
|
|
74
|
-
FOREST_START = "\033[38;2;34;139;34m" # Forest green
|
|
75
|
-
FOREST_END = "\033[38;2;0;100;0m" # Dark green
|
|
76
|
-
|
|
77
|
-
# Bold
|
|
78
|
-
BOLD = "\033[1m"
|
|
79
|
-
|
|
80
|
-
# Styles
|
|
81
|
-
DIM = "\033[2m"
|
|
82
|
-
ITALIC = "\033[3m"
|
|
83
|
-
UNDERLINE = "\033[4m"
|
|
84
|
-
|
|
85
|
-
# Level color mapping
|
|
86
|
-
LEVEL_COLORS = {
|
|
87
|
-
LogLevel.DEBUG: BRIGHT_BLACK,
|
|
88
|
-
LogLevel.INFO: BRIGHT_BLUE,
|
|
89
|
-
LogLevel.WARNING: BRIGHT_YELLOW,
|
|
90
|
-
LogLevel.ERROR: BRIGHT_RED,
|
|
91
|
-
LogLevel.CRITICAL: BRIGHT_RED + BOLD,
|
|
92
|
-
LogLevel.NOTSET: WHITE
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
# Add style combinations
|
|
96
|
-
STYLES = {
|
|
97
|
-
"bold": "\033[1m",
|
|
98
|
-
"dim": "\033[2m",
|
|
99
|
-
"italic": "\033[3m",
|
|
100
|
-
"underline": "\033[4m",
|
|
101
|
-
"blink": "\033[5m",
|
|
102
|
-
"reverse": "\033[7m",
|
|
103
|
-
"hidden": "\033[8m",
|
|
104
|
-
"strike": "\033[9m",
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@staticmethod
|
|
108
|
-
def rgb(r: int, g: int, b: int, background: bool = False) -> str:
|
|
109
|
-
"""Create RGB color code."""
|
|
110
|
-
if background:
|
|
111
|
-
return f"\033[48;2;{r};{g};{b}m"
|
|
112
|
-
return f"\033[38;2;{r};{g};{b}m"
|
|
113
|
-
|
|
114
|
-
@staticmethod
|
|
115
|
-
def color_256(code: int, background: bool = False) -> str:
|
|
116
|
-
"""Create 256-color code."""
|
|
117
|
-
if background:
|
|
118
|
-
return f"\033[48;5;{code}m"
|
|
119
|
-
return f"\033[38;5;{code}m"
|
|
120
|
-
|
|
121
|
-
@staticmethod
|
|
122
|
-
def combine(*colors):
|
|
123
|
-
return "".join(colors)
|
|
124
|
-
|
|
125
|
-
@staticmethod
|
|
126
|
-
def gradient(text: str, start_rgb: tuple, end_rgb: tuple) -> str:
|
|
127
|
-
"""Create a gradient effect across text."""
|
|
128
|
-
if len(text) < 2:
|
|
129
|
-
return LogColors.rgb(*start_rgb) + text
|
|
130
|
-
|
|
131
|
-
result = []
|
|
132
|
-
for i, char in enumerate(text):
|
|
133
|
-
r = int(start_rgb[0] + (end_rgb[0] - start_rgb[0]) * i / (len(text) - 1))
|
|
134
|
-
g = int(start_rgb[1] + (end_rgb[1] - start_rgb[1]) * i / (len(text) - 1))
|
|
135
|
-
b = int(start_rgb[2] + (end_rgb[2] - start_rgb[2]) * i / (len(text) - 1))
|
|
136
|
-
result.append(f"{LogColors.rgb(r, g, b)}{char}")
|
|
137
|
-
|
|
138
|
-
return "".join(result) + LogColors.RESET
|
|
139
|
-
|
|
140
|
-
@staticmethod
|
|
141
|
-
def rainbow(text: str) -> str:
|
|
142
|
-
"""Apply rainbow colors to text."""
|
|
143
|
-
colors = [
|
|
144
|
-
(255, 0, 0), # Red
|
|
145
|
-
(255, 127, 0), # Orange
|
|
146
|
-
(255, 255, 0), # Yellow
|
|
147
|
-
(0, 255, 0), # Green
|
|
148
|
-
(0, 0, 255), # Blue
|
|
149
|
-
(75, 0, 130), # Indigo
|
|
150
|
-
(148, 0, 211) # Violet
|
|
151
|
-
]
|
|
152
|
-
|
|
153
|
-
result = []
|
|
154
|
-
for i, char in enumerate(text):
|
|
155
|
-
color = colors[i % len(colors)]
|
|
156
|
-
result.append(f"{LogColors.rgb(*color)}{char}")
|
|
157
|
-
|
|
158
|
-
return "".join(result) + LogColors.RESET
|
|
159
|
-
|
|
160
|
-
@staticmethod
|
|
161
|
-
def animate(text: str, effect: str = "blink") -> str:
|
|
162
|
-
"""Apply animation effects to text."""
|
|
163
|
-
effects = {
|
|
164
|
-
"blink": LogColors.BLINK,
|
|
165
|
-
"reverse": LogColors.REVERSE,
|
|
166
|
-
"bold_blink": LogColors.combine(LogColors.BOLD, LogColors.BLINK),
|
|
167
|
-
"frame_blink": LogColors.combine(LogColors.FRAME, LogColors.BLINK),
|
|
168
|
-
"encircle_blink": LogColors.combine(LogColors.ENCIRCLE, LogColors.BLINK)
|
|
169
|
-
}
|
|
170
|
-
return effects.get(effect, LogColors.BLINK) + text + LogColors.RESET
|
|
171
|
-
|
|
172
|
-
@staticmethod
|
|
173
|
-
def style_text(text: str, *styles: str, color: Optional[str] = None) -> str:
|
|
174
|
-
"""Apply multiple styles and color to text."""
|
|
175
|
-
style_codes = "".join(LogColors.STYLES.get(style, "") for style in styles)
|
|
176
|
-
color_code = color if color else ""
|
|
177
|
-
return f"{style_codes}{color_code}{text}{LogColors.RESET}"
|
|
178
|
-
|
|
179
|
-
@staticmethod
|
|
180
|
-
def level_style(level: LogLevel, text: str) -> str:
|
|
181
|
-
"""Style text according to log level with enhanced formatting."""
|
|
182
|
-
color = LogColors.LEVEL_COLORS.get(level, LogColors.RESET)
|
|
183
|
-
|
|
184
|
-
# Apply appropriate styling based on level
|
|
185
|
-
if level == LogLevel.CRITICAL:
|
|
186
|
-
return f"{color}{LogColors.STYLES['bold']}{text}{LogColors.RESET}"
|
|
187
|
-
elif level == LogLevel.ERROR:
|
|
188
|
-
return f"{color}{text}{LogColors.RESET}"
|
|
189
|
-
elif level == LogLevel.WARNING:
|
|
190
|
-
return f"{color}{text}{LogColors.RESET}"
|
|
191
|
-
else:
|
|
192
|
-
return f"{color}{text}{LogColors.RESET}"
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
class LogTheme:
|
|
196
|
-
"""Pre-defined color themes and combinations."""
|
|
197
|
-
|
|
198
|
-
@staticmethod
|
|
199
|
-
def get_theme(name: str) -> str:
|
|
200
|
-
themes = {
|
|
201
|
-
# Status themes
|
|
202
|
-
"success": LogColors.combine(LogColors.BRIGHT_GREEN, LogColors.BOLD),
|
|
203
|
-
"error": LogColors.combine(LogColors.BRIGHT_RED, LogColors.BOLD),
|
|
204
|
-
"warning": LogColors.combine(LogColors.BRIGHT_YELLOW, LogColors.BOLD),
|
|
205
|
-
"info": LogColors.combine(LogColors.BRIGHT_BLUE, LogColors.BOLD),
|
|
206
|
-
"debug": LogColors.combine(LogColors.DIM, LogColors.WHITE),
|
|
207
|
-
"critical": LogColors.combine(LogColors.BG_RED, LogColors.WHITE, LogColors.BOLD),
|
|
208
|
-
|
|
209
|
-
# Special themes
|
|
210
|
-
"header": LogColors.combine(LogColors.BRIGHT_WHITE, LogColors.BOLD, LogColors.UNDERLINE),
|
|
211
|
-
"highlight": LogColors.combine(LogColors.BLACK, LogColors.BG_BRIGHT_YELLOW),
|
|
212
|
-
"important": LogColors.combine(LogColors.BRIGHT_RED, LogColors.BOLD, LogColors.UNDERLINE),
|
|
213
|
-
"subtle": LogColors.combine(LogColors.DIM, LogColors.BRIGHT_BLACK),
|
|
214
|
-
|
|
215
|
-
# UI themes
|
|
216
|
-
"title": LogColors.combine(LogColors.BRIGHT_WHITE, LogColors.BOLD, LogColors.UNDERLINE),
|
|
217
|
-
"subtitle": LogColors.combine(LogColors.BRIGHT_WHITE, LogColors.DIM),
|
|
218
|
-
"link": LogColors.combine(LogColors.BLUE, LogColors.UNDERLINE),
|
|
219
|
-
"code": LogColors.combine(LogColors.BRIGHT_BLACK, LogColors.BG_WHITE),
|
|
220
|
-
|
|
221
|
-
# Data themes
|
|
222
|
-
"number": LogColors.combine(LogColors.BRIGHT_CYAN, LogColors.BOLD),
|
|
223
|
-
"string": LogColors.combine(LogColors.BRIGHT_GREEN),
|
|
224
|
-
"boolean": LogColors.combine(LogColors.BRIGHT_YELLOW, LogColors.BOLD),
|
|
225
|
-
"null": LogColors.combine(LogColors.DIM, LogColors.ITALIC),
|
|
226
|
-
|
|
227
|
-
# Custom themes
|
|
228
|
-
"fire": LogColors.combine(LogColors.FIRE, LogColors.BOLD),
|
|
229
|
-
"ice": LogColors.combine(LogColors.ICE, LogColors.BOLD),
|
|
230
|
-
"nature": LogColors.combine(LogColors.GRASS, LogColors.BOLD),
|
|
231
|
-
"royal": LogColors.combine(LogColors.PURPLE, LogColors.BOLD),
|
|
232
|
-
"precious": LogColors.combine(LogColors.GOLD, LogColors.BOLD),
|
|
233
|
-
|
|
234
|
-
# Gradient themes
|
|
235
|
-
"sunset": LogColors.combine(LogColors.SUNSET_START, LogColors.SUNSET_END),
|
|
236
|
-
"ocean": LogColors.combine(LogColors.OCEAN_START, LogColors.OCEAN_END),
|
|
237
|
-
"forest": LogColors.combine(LogColors.FOREST_START, LogColors.FOREST_END),
|
|
238
|
-
}
|
|
239
|
-
return themes.get(name, LogColors.RESET)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
# Define level colors after both classes are defined
|
|
243
|
-
LogColors.LEVEL_COLORS = {
|
|
244
|
-
"DEBUG": LogTheme.get_theme("debug"),
|
|
245
|
-
"INFO": LogTheme.get_theme("info"),
|
|
246
|
-
"WARNING": LogTheme.get_theme("warning"),
|
|
247
|
-
"ERROR": LogTheme.get_theme("error"),
|
|
248
|
-
"CRITICAL": LogTheme.get_theme("critical")
|
|
249
|
-
}
|