webscout 8.3.7__py3-none-any.whl → 2025.10.11__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/Apriel.py +306 -0
- webscout/Provider/ChatGPTClone.py +236 -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 +30 -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 +664 -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/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/webscout_search.py +1183 -1183
- webscout/webscout_search_async.py +649 -649
- webscout/yep_search.py +346 -346
- 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.11.dist-info}/METADATA +937 -937
- webscout-2025.10.11.dist-info/RECORD +300 -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-8.3.7.dist-info/RECORD +0 -301
- {webscout-8.3.7.dist-info → webscout-2025.10.11.dist-info}/WHEEL +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.11.dist-info}/entry_points.txt +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.11.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.3.7.dist-info → webscout-2025.10.11.dist-info}/top_level.txt +0 -0
webscout/update_checker.py
CHANGED
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
import importlib.metadata
|
|
2
|
-
from typing import Optional, Dict, Any, Literal
|
|
3
|
-
import requests
|
|
4
|
-
from packaging import version
|
|
5
|
-
|
|
6
|
-
# Constants
|
|
7
|
-
PYPI_URL = "https://pypi.org/pypi/webscout/json"
|
|
8
|
-
YOUTUBE_URL = "https://youtube.com/@OEvortex"
|
|
9
|
-
|
|
10
|
-
# Create a session for HTTP requests
|
|
11
|
-
session = requests.Session()
|
|
12
|
-
|
|
13
|
-
# Version comparison result type
|
|
14
|
-
VersionCompareResult = Literal[-1, 0, 1]
|
|
15
|
-
|
|
16
|
-
def get_package_version(package_name: str) -> Optional[str]:
|
|
17
|
-
"""Get the installed version of a package by name."""
|
|
18
|
-
try:
|
|
19
|
-
return importlib.metadata.version(package_name)
|
|
20
|
-
except importlib.metadata.PackageNotFoundError:
|
|
21
|
-
return None
|
|
22
|
-
|
|
23
|
-
def get_installed_version() -> Optional[str]:
|
|
24
|
-
"""Get the currently installed version of webscout.
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
Optional[str]: The installed version string or None if not found
|
|
28
|
-
|
|
29
|
-
Examples:
|
|
30
|
-
>>> version = get_installed_version()
|
|
31
|
-
>>> print(version)
|
|
32
|
-
'1.2.3'
|
|
33
|
-
"""
|
|
34
|
-
return get_package_version('webscout')
|
|
35
|
-
|
|
36
|
-
def get_pypi_version() -> Optional[str]:
|
|
37
|
-
"""Get the latest version available on PyPI.
|
|
38
|
-
|
|
39
|
-
Returns:
|
|
40
|
-
Optional[str]: The latest version string or None if retrieval failed
|
|
41
|
-
|
|
42
|
-
Examples:
|
|
43
|
-
>>> latest = get_pypi_version()
|
|
44
|
-
>>> print(latest)
|
|
45
|
-
'2.0.0'
|
|
46
|
-
"""
|
|
47
|
-
try:
|
|
48
|
-
response = session.get(PYPI_URL, timeout=10)
|
|
49
|
-
response.raise_for_status()
|
|
50
|
-
data: Dict[str, Any] = response.json()
|
|
51
|
-
return data.get('info', {}).get('version')
|
|
52
|
-
except (requests.RequestException, KeyError, ValueError):
|
|
53
|
-
return None
|
|
54
|
-
|
|
55
|
-
def version_compare(v1: str, v2: str) -> VersionCompareResult:
|
|
56
|
-
"""Compare two version strings.
|
|
57
|
-
|
|
58
|
-
Returns:
|
|
59
|
-
-1 if v1 < v2, 1 if v1 > v2, 0 if equal or invalid
|
|
60
|
-
|
|
61
|
-
Examples:
|
|
62
|
-
>>> version_compare('1.0.0', '2.0.0')
|
|
63
|
-
-1
|
|
64
|
-
"""
|
|
65
|
-
try:
|
|
66
|
-
version1 = version.parse(v1)
|
|
67
|
-
version2 = version.parse(v2)
|
|
68
|
-
if version1 < version2:
|
|
69
|
-
return -1
|
|
70
|
-
if version1 > version2:
|
|
71
|
-
return 1
|
|
72
|
-
return 0
|
|
73
|
-
except Exception:
|
|
74
|
-
return 0
|
|
75
|
-
|
|
76
|
-
def get_update_message(installed: str, latest: str) -> str:
|
|
77
|
-
"""Generate appropriate update message based on version comparison."""
|
|
78
|
-
comparison_result = version_compare(installed, latest)
|
|
79
|
-
youtube_msg = f'\033[1;32mSubscribe to my YouTube Channel: {YOUTUBE_URL}\033[0m'
|
|
80
|
-
if comparison_result < 0:
|
|
81
|
-
# Bold red for update available
|
|
82
|
-
return (
|
|
83
|
-
f"\033[1;31mNew Webscout version available: {latest} "
|
|
84
|
-
f"- Update with: pip install --upgrade webscout\033[0m\n{youtube_msg}"
|
|
85
|
-
)
|
|
86
|
-
elif comparison_result > 0:
|
|
87
|
-
# Bold yellow for dev version
|
|
88
|
-
return (
|
|
89
|
-
f"\033[1;33mYou're running a development version ({installed}) "
|
|
90
|
-
f"ahead of latest release ({latest})\033[0m\n{youtube_msg}"
|
|
91
|
-
)
|
|
92
|
-
# Bold green for up-to-date
|
|
93
|
-
|
|
94
|
-
def check_for_updates() -> Optional[str]:
|
|
95
|
-
"""Check if a newer version of Webscout is available.
|
|
96
|
-
|
|
97
|
-
Returns:
|
|
98
|
-
Optional[str]: Update message if newer version exists, None otherwise
|
|
99
|
-
"""
|
|
100
|
-
installed_version = get_installed_version()
|
|
101
|
-
if not installed_version:
|
|
102
|
-
return "\033[1;31mWebscout is not installed.\033[0m"
|
|
103
|
-
|
|
104
|
-
latest_version = get_pypi_version()
|
|
105
|
-
if not latest_version:
|
|
106
|
-
return "\033[1;31mCould not retrieve latest version from PyPI.\033[0m"
|
|
107
|
-
|
|
108
|
-
return get_update_message(installed_version, latest_version)
|
|
109
|
-
|
|
110
|
-
if __name__ == "__main__":
|
|
111
|
-
try:
|
|
112
|
-
update_message = check_for_updates()
|
|
113
|
-
if update_message:
|
|
114
|
-
print(update_message)
|
|
115
|
-
except KeyboardInterrupt:
|
|
116
|
-
print("\nUpdate check canceled by user.")
|
|
117
|
-
except Exception as e:
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
from typing import Optional, Dict, Any, Literal
|
|
3
|
+
import requests
|
|
4
|
+
from packaging import version
|
|
5
|
+
|
|
6
|
+
# Constants
|
|
7
|
+
PYPI_URL = "https://pypi.org/pypi/webscout/json"
|
|
8
|
+
YOUTUBE_URL = "https://youtube.com/@OEvortex"
|
|
9
|
+
|
|
10
|
+
# Create a session for HTTP requests
|
|
11
|
+
session = requests.Session()
|
|
12
|
+
|
|
13
|
+
# Version comparison result type
|
|
14
|
+
VersionCompareResult = Literal[-1, 0, 1]
|
|
15
|
+
|
|
16
|
+
def get_package_version(package_name: str) -> Optional[str]:
|
|
17
|
+
"""Get the installed version of a package by name."""
|
|
18
|
+
try:
|
|
19
|
+
return importlib.metadata.version(package_name)
|
|
20
|
+
except importlib.metadata.PackageNotFoundError:
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
def get_installed_version() -> Optional[str]:
|
|
24
|
+
"""Get the currently installed version of webscout.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Optional[str]: The installed version string or None if not found
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
>>> version = get_installed_version()
|
|
31
|
+
>>> print(version)
|
|
32
|
+
'1.2.3'
|
|
33
|
+
"""
|
|
34
|
+
return get_package_version('webscout')
|
|
35
|
+
|
|
36
|
+
def get_pypi_version() -> Optional[str]:
|
|
37
|
+
"""Get the latest version available on PyPI.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Optional[str]: The latest version string or None if retrieval failed
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
>>> latest = get_pypi_version()
|
|
44
|
+
>>> print(latest)
|
|
45
|
+
'2.0.0'
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
response = session.get(PYPI_URL, timeout=10)
|
|
49
|
+
response.raise_for_status()
|
|
50
|
+
data: Dict[str, Any] = response.json()
|
|
51
|
+
return data.get('info', {}).get('version')
|
|
52
|
+
except (requests.RequestException, KeyError, ValueError):
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
def version_compare(v1: str, v2: str) -> VersionCompareResult:
|
|
56
|
+
"""Compare two version strings.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
-1 if v1 < v2, 1 if v1 > v2, 0 if equal or invalid
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
>>> version_compare('1.0.0', '2.0.0')
|
|
63
|
+
-1
|
|
64
|
+
"""
|
|
65
|
+
try:
|
|
66
|
+
version1 = version.parse(v1)
|
|
67
|
+
version2 = version.parse(v2)
|
|
68
|
+
if version1 < version2:
|
|
69
|
+
return -1
|
|
70
|
+
if version1 > version2:
|
|
71
|
+
return 1
|
|
72
|
+
return 0
|
|
73
|
+
except Exception:
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
def get_update_message(installed: str, latest: str) -> str:
|
|
77
|
+
"""Generate appropriate update message based on version comparison."""
|
|
78
|
+
comparison_result = version_compare(installed, latest)
|
|
79
|
+
youtube_msg = f'\033[1;32mSubscribe to my YouTube Channel: {YOUTUBE_URL}\033[0m'
|
|
80
|
+
if comparison_result < 0:
|
|
81
|
+
# Bold red for update available
|
|
82
|
+
return (
|
|
83
|
+
f"\033[1;31mNew Webscout version available: {latest} "
|
|
84
|
+
f"- Update with: pip install --upgrade webscout\033[0m\n{youtube_msg}"
|
|
85
|
+
)
|
|
86
|
+
elif comparison_result > 0:
|
|
87
|
+
# Bold yellow for dev version
|
|
88
|
+
return (
|
|
89
|
+
f"\033[1;33mYou're running a development version ({installed}) "
|
|
90
|
+
f"ahead of latest release ({latest})\033[0m\n{youtube_msg}"
|
|
91
|
+
)
|
|
92
|
+
# Bold green for up-to-date
|
|
93
|
+
|
|
94
|
+
def check_for_updates() -> Optional[str]:
|
|
95
|
+
"""Check if a newer version of Webscout is available.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Optional[str]: Update message if newer version exists, None otherwise
|
|
99
|
+
"""
|
|
100
|
+
installed_version = get_installed_version()
|
|
101
|
+
if not installed_version:
|
|
102
|
+
return "\033[1;31mWebscout is not installed.\033[0m"
|
|
103
|
+
|
|
104
|
+
latest_version = get_pypi_version()
|
|
105
|
+
if not latest_version:
|
|
106
|
+
return "\033[1;31mCould not retrieve latest version from PyPI.\033[0m"
|
|
107
|
+
|
|
108
|
+
return get_update_message(installed_version, latest_version)
|
|
109
|
+
|
|
110
|
+
if __name__ == "__main__":
|
|
111
|
+
try:
|
|
112
|
+
update_message = check_for_updates()
|
|
113
|
+
if update_message:
|
|
114
|
+
print(update_message)
|
|
115
|
+
except KeyboardInterrupt:
|
|
116
|
+
print("\nUpdate check canceled by user.")
|
|
117
|
+
except Exception as e:
|
|
118
118
|
print(f"\033[1;31mUpdate check failed: {str(e)}\033[0m")
|
webscout/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "
|
|
1
|
+
__version__ = "2025.10.11"
|
|
2
2
|
__prog__ = "webscout"
|