webscout 6.4__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.
- webscout/AIutel.py +7 -54
- webscout/DWEBS.py +48 -26
- webscout/{YTdownloader.py → Extra/YTToolkit/YTdownloader.py} +990 -1103
- webscout/Extra/YTToolkit/__init__.py +3 -0
- webscout/{transcriber.py → Extra/YTToolkit/transcriber.py} +1 -1
- webscout/Extra/YTToolkit/ytapi/__init__.py +6 -0
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -0
- webscout/Extra/YTToolkit/ytapi/errors.py +13 -0
- webscout/Extra/YTToolkit/ytapi/extras.py +45 -0
- webscout/Extra/YTToolkit/ytapi/https.py +88 -0
- webscout/Extra/YTToolkit/ytapi/patterns.py +61 -0
- webscout/Extra/YTToolkit/ytapi/playlist.py +59 -0
- webscout/Extra/YTToolkit/ytapi/pool.py +8 -0
- webscout/Extra/YTToolkit/ytapi/query.py +37 -0
- webscout/Extra/YTToolkit/ytapi/stream.py +60 -0
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -0
- webscout/Extra/YTToolkit/ytapi/video.py +102 -0
- webscout/Extra/__init__.py +2 -1
- webscout/Extra/autocoder/rawdog.py +679 -680
- webscout/Extra/gguf.py +441 -441
- webscout/Extra/markdownlite/__init__.py +862 -0
- webscout/Extra/weather_ascii.py +2 -2
- webscout/Provider/PI.py +292 -221
- webscout/Provider/Perplexity.py +6 -14
- webscout/Provider/Reka.py +0 -1
- webscout/Provider/TTS/__init__.py +5 -1
- webscout/Provider/TTS/deepgram.py +183 -0
- webscout/Provider/TTS/elevenlabs.py +137 -0
- webscout/Provider/TTS/gesserit.py +151 -0
- webscout/Provider/TTS/murfai.py +139 -0
- webscout/Provider/TTS/parler.py +134 -107
- webscout/Provider/TTS/streamElements.py +360 -275
- webscout/Provider/TTS/utils.py +280 -0
- webscout/Provider/TTS/voicepod.py +116 -116
- webscout/Provider/__init__.py +146 -146
- webscout/Provider/meta.py +794 -779
- webscout/Provider/typegpt.py +1 -2
- webscout/__init__.py +24 -28
- webscout/litprinter/__init__.py +831 -830
- webscout/optimizers.py +269 -269
- webscout/prompt_manager.py +279 -279
- webscout/scout/__init__.py +11 -0
- webscout/scout/core.py +884 -0
- webscout/scout/element.py +459 -0
- webscout/scout/parsers/__init__.py +69 -0
- webscout/scout/parsers/html5lib_parser.py +172 -0
- webscout/scout/parsers/html_parser.py +236 -0
- webscout/scout/parsers/lxml_parser.py +178 -0
- webscout/scout/utils.py +38 -0
- webscout/update_checker.py +125 -125
- webscout/version.py +1 -1
- webscout/zeroart/__init__.py +55 -0
- webscout/zeroart/base.py +61 -0
- webscout/zeroart/effects.py +99 -0
- webscout/zeroart/fonts.py +816 -0
- webscout/zerodir/__init__.py +225 -0
- {webscout-6.4.dist-info → webscout-6.5.dist-info}/METADATA +12 -68
- {webscout-6.4.dist-info → webscout-6.5.dist-info}/RECORD +62 -37
- webscout/Agents/Onlinesearcher.py +0 -182
- webscout/Agents/__init__.py +0 -2
- webscout/Agents/functioncall.py +0 -248
- webscout/Bing_search.py +0 -251
- webscout/gpt4free.py +0 -666
- webscout/requestsHTMLfix.py +0 -775
- webscout/webai.py +0 -2590
- {webscout-6.4.dist-info → webscout-6.5.dist-info}/LICENSE.md +0 -0
- {webscout-6.4.dist-info → webscout-6.5.dist-info}/WHEEL +0 -0
- {webscout-6.4.dist-info → webscout-6.5.dist-info}/entry_points.txt +0 -0
- {webscout-6.4.dist-info → webscout-6.5.dist-info}/top_level.txt +0 -0
webscout/update_checker.py
CHANGED
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Webscout Update Checker
|
|
3
|
-
A utility to check and compare Webscout versions
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import requests
|
|
7
|
-
import re
|
|
8
|
-
import subprocess
|
|
9
|
-
import sys
|
|
10
|
-
import os
|
|
11
|
-
from packaging import version
|
|
12
|
-
from typing import Optional
|
|
13
|
-
|
|
14
|
-
from webscout
|
|
15
|
-
|
|
16
|
-
# Initialize logger with custom format
|
|
17
|
-
CUSTOM_FORMAT = """{message}"""
|
|
18
|
-
|
|
19
|
-
logger = LitLogger(
|
|
20
|
-
name="WebscoutUpdate",
|
|
21
|
-
format=CUSTOM_FORMAT,
|
|
22
|
-
color_scheme=ColorScheme.OCEAN,
|
|
23
|
-
level_styles={
|
|
24
|
-
"TRACE": "DIM",
|
|
25
|
-
"DEBUG": "NORMAL",
|
|
26
|
-
"INFO": "BOLD",
|
|
27
|
-
"SUCCESS": "BOLD",
|
|
28
|
-
"WARNING": "BOLD",
|
|
29
|
-
"ERROR": "BOLD",
|
|
30
|
-
"CRITICAL": "BOLD"
|
|
31
|
-
}
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
def get_installed_version() -> Optional[str]:
|
|
35
|
-
"""Get the installed version of webscout"""
|
|
36
|
-
try:
|
|
37
|
-
import importlib.metadata
|
|
38
|
-
return importlib.metadata.version('webscout')
|
|
39
|
-
except ImportError:
|
|
40
|
-
try:
|
|
41
|
-
import pkg_resources
|
|
42
|
-
return pkg_resources.get_distribution('webscout').version
|
|
43
|
-
except Exception:
|
|
44
|
-
logger.error("Could not determine installed version using pkg_resources")
|
|
45
|
-
return None
|
|
46
|
-
except Exception:
|
|
47
|
-
logger.error("Could not determine installed version using importlib.metadata")
|
|
48
|
-
return None
|
|
49
|
-
|
|
50
|
-
def get_webscout_version() -> Optional[str]:
|
|
51
|
-
"""Get the current webscout version from CLI"""
|
|
52
|
-
try:
|
|
53
|
-
result = subprocess.run(['webscout', '--version'],
|
|
54
|
-
capture_output=True,
|
|
55
|
-
text=True,
|
|
56
|
-
timeout=5)
|
|
57
|
-
if result.returncode == 0:
|
|
58
|
-
version_match = re.search(r'\d+\.\d+\.\d+', result.stdout)
|
|
59
|
-
if version_match:
|
|
60
|
-
return version_match.group(0)
|
|
61
|
-
except (subprocess.TimeoutExpired, subprocess.SubprocessError, FileNotFoundError) as e:
|
|
62
|
-
logger.error(f"Failed to get version from CLI: {str(e)}")
|
|
63
|
-
return None
|
|
64
|
-
|
|
65
|
-
def get_pypi_version() -> Optional[str]:
|
|
66
|
-
"""Get the latest version from PyPI"""
|
|
67
|
-
try:
|
|
68
|
-
response = requests.get(
|
|
69
|
-
"https://pypi.org/pypi/webscout/json",
|
|
70
|
-
timeout=10
|
|
71
|
-
)
|
|
72
|
-
response.raise_for_status()
|
|
73
|
-
return response.json()['info']['version']
|
|
74
|
-
except requests.RequestException as e:
|
|
75
|
-
logger.error(f"Failed to fetch PyPI version: {str(e)}")
|
|
76
|
-
except (KeyError, ValueError) as e:
|
|
77
|
-
logger.error(f"Failed to parse PyPI response: {str(e)}")
|
|
78
|
-
return None
|
|
79
|
-
|
|
80
|
-
def version_compare(v1: str, v2: str) -> int:
|
|
81
|
-
"""Compare two version strings"""
|
|
82
|
-
try:
|
|
83
|
-
return -1 if version.parse(v1) < version.parse(v2) else 1
|
|
84
|
-
except version.InvalidVersion:
|
|
85
|
-
return 0
|
|
86
|
-
|
|
87
|
-
def display_version_info(installed: Optional[str], current: Optional[str], latest: Optional[str]) -> None:
|
|
88
|
-
"""Display version information"""
|
|
89
|
-
if installed:
|
|
90
|
-
logger.info(f"Currently using Webscout version {installed}")
|
|
91
|
-
|
|
92
|
-
if latest and installed:
|
|
93
|
-
if version_compare(installed, latest) < 0:
|
|
94
|
-
logger.warning(
|
|
95
|
-
f"A new version of Webscout is available: {latest}\n"
|
|
96
|
-
f"To update, run: pip install --upgrade webscout"
|
|
97
|
-
)
|
|
98
|
-
else:
|
|
99
|
-
logger.success("You're running the latest version!")
|
|
100
|
-
|
|
101
|
-
def check_for_updates() -> None:
|
|
102
|
-
"""Check for Webscout updates"""
|
|
103
|
-
logger.info("Checking for Webscout updates...")
|
|
104
|
-
|
|
105
|
-
installed_version = get_installed_version()
|
|
106
|
-
current_version = get_webscout_version()
|
|
107
|
-
latest_version = get_pypi_version()
|
|
108
|
-
|
|
109
|
-
if not installed_version:
|
|
110
|
-
logger.error("Could not determine installed Webscout version")
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
if not latest_version:
|
|
114
|
-
logger.error("Could not determine latest Webscout version from PyPI")
|
|
115
|
-
return
|
|
116
|
-
|
|
117
|
-
display_version_info(installed_version, current_version, latest_version)
|
|
118
|
-
|
|
119
|
-
if __name__ == "__main__":
|
|
120
|
-
try:
|
|
121
|
-
check_for_updates()
|
|
122
|
-
except KeyboardInterrupt:
|
|
123
|
-
logger.warning("Update check cancelled by user")
|
|
124
|
-
except Exception as e:
|
|
125
|
-
logger.error(f"An unexpected error occurred: {str(e)}")
|
|
1
|
+
"""
|
|
2
|
+
Webscout Update Checker
|
|
3
|
+
A utility to check and compare Webscout versions
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
import re
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import os
|
|
11
|
+
from packaging import version
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
from webscout import LitLogger, LogFormat, ColorScheme
|
|
15
|
+
|
|
16
|
+
# Initialize logger with custom format
|
|
17
|
+
CUSTOM_FORMAT = """{message}"""
|
|
18
|
+
|
|
19
|
+
logger = LitLogger(
|
|
20
|
+
name="WebscoutUpdate",
|
|
21
|
+
format=CUSTOM_FORMAT,
|
|
22
|
+
color_scheme=ColorScheme.OCEAN,
|
|
23
|
+
level_styles={
|
|
24
|
+
"TRACE": "DIM",
|
|
25
|
+
"DEBUG": "NORMAL",
|
|
26
|
+
"INFO": "BOLD",
|
|
27
|
+
"SUCCESS": "BOLD",
|
|
28
|
+
"WARNING": "BOLD",
|
|
29
|
+
"ERROR": "BOLD",
|
|
30
|
+
"CRITICAL": "BOLD"
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def get_installed_version() -> Optional[str]:
|
|
35
|
+
"""Get the installed version of webscout"""
|
|
36
|
+
try:
|
|
37
|
+
import importlib.metadata
|
|
38
|
+
return importlib.metadata.version('webscout')
|
|
39
|
+
except ImportError:
|
|
40
|
+
try:
|
|
41
|
+
import pkg_resources
|
|
42
|
+
return pkg_resources.get_distribution('webscout').version
|
|
43
|
+
except Exception:
|
|
44
|
+
logger.error("Could not determine installed version using pkg_resources")
|
|
45
|
+
return None
|
|
46
|
+
except Exception:
|
|
47
|
+
logger.error("Could not determine installed version using importlib.metadata")
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
def get_webscout_version() -> Optional[str]:
|
|
51
|
+
"""Get the current webscout version from CLI"""
|
|
52
|
+
try:
|
|
53
|
+
result = subprocess.run(['webscout', '--version'],
|
|
54
|
+
capture_output=True,
|
|
55
|
+
text=True,
|
|
56
|
+
timeout=5)
|
|
57
|
+
if result.returncode == 0:
|
|
58
|
+
version_match = re.search(r'\d+\.\d+\.\d+', result.stdout)
|
|
59
|
+
if version_match:
|
|
60
|
+
return version_match.group(0)
|
|
61
|
+
except (subprocess.TimeoutExpired, subprocess.SubprocessError, FileNotFoundError) as e:
|
|
62
|
+
logger.error(f"Failed to get version from CLI: {str(e)}")
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
def get_pypi_version() -> Optional[str]:
|
|
66
|
+
"""Get the latest version from PyPI"""
|
|
67
|
+
try:
|
|
68
|
+
response = requests.get(
|
|
69
|
+
"https://pypi.org/pypi/webscout/json",
|
|
70
|
+
timeout=10
|
|
71
|
+
)
|
|
72
|
+
response.raise_for_status()
|
|
73
|
+
return response.json()['info']['version']
|
|
74
|
+
except requests.RequestException as e:
|
|
75
|
+
logger.error(f"Failed to fetch PyPI version: {str(e)}")
|
|
76
|
+
except (KeyError, ValueError) as e:
|
|
77
|
+
logger.error(f"Failed to parse PyPI response: {str(e)}")
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
def version_compare(v1: str, v2: str) -> int:
|
|
81
|
+
"""Compare two version strings"""
|
|
82
|
+
try:
|
|
83
|
+
return -1 if version.parse(v1) < version.parse(v2) else 1
|
|
84
|
+
except version.InvalidVersion:
|
|
85
|
+
return 0
|
|
86
|
+
|
|
87
|
+
def display_version_info(installed: Optional[str], current: Optional[str], latest: Optional[str]) -> None:
|
|
88
|
+
"""Display version information"""
|
|
89
|
+
if installed:
|
|
90
|
+
logger.info(f"Currently using Webscout version {installed}")
|
|
91
|
+
|
|
92
|
+
if latest and installed:
|
|
93
|
+
if version_compare(installed, latest) < 0:
|
|
94
|
+
logger.warning(
|
|
95
|
+
f"A new version of Webscout is available: {latest}\n"
|
|
96
|
+
f"To update, run: pip install --upgrade webscout"
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
logger.success("You're running the latest version!")
|
|
100
|
+
|
|
101
|
+
def check_for_updates() -> None:
|
|
102
|
+
"""Check for Webscout updates"""
|
|
103
|
+
logger.info("Checking for Webscout updates...")
|
|
104
|
+
|
|
105
|
+
installed_version = get_installed_version()
|
|
106
|
+
current_version = get_webscout_version()
|
|
107
|
+
latest_version = get_pypi_version()
|
|
108
|
+
|
|
109
|
+
if not installed_version:
|
|
110
|
+
logger.error("Could not determine installed Webscout version")
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
if not latest_version:
|
|
114
|
+
logger.error("Could not determine latest Webscout version from PyPI")
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
display_version_info(installed_version, current_version, latest_version)
|
|
118
|
+
|
|
119
|
+
if __name__ == "__main__":
|
|
120
|
+
try:
|
|
121
|
+
check_for_updates()
|
|
122
|
+
except KeyboardInterrupt:
|
|
123
|
+
logger.warning("Update check cancelled by user")
|
|
124
|
+
except Exception as e:
|
|
125
|
+
logger.error(f"An unexpected error occurred: {str(e)}")
|
webscout/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "6.
|
|
1
|
+
__version__ = "6.5"
|
|
2
2
|
__prog__ = "webscout"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroArt: A zero-dependency ASCII art text generator
|
|
3
|
+
|
|
4
|
+
Create awesome ASCII art text without external dependencies!
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .base import ZeroArtFont
|
|
8
|
+
from .fonts import BlockFont, SlantFont, NeonFont, CyberFont
|
|
9
|
+
from .effects import AsciiArtEffects
|
|
10
|
+
|
|
11
|
+
def figlet_format(text, font='block'):
|
|
12
|
+
"""
|
|
13
|
+
Generate ASCII art text
|
|
14
|
+
|
|
15
|
+
:param text: Text to convert
|
|
16
|
+
:param font: Font style (default: 'block')
|
|
17
|
+
:return: ASCII art representation of text
|
|
18
|
+
"""
|
|
19
|
+
font_map = {
|
|
20
|
+
'block': BlockFont(),
|
|
21
|
+
'slant': SlantFont(),
|
|
22
|
+
'neon': NeonFont(),
|
|
23
|
+
'cyber': CyberFont()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
selected_font = font_map.get(font.lower(), BlockFont())
|
|
27
|
+
return selected_font.render(text)
|
|
28
|
+
|
|
29
|
+
def print_figlet(text, font='block'):
|
|
30
|
+
"""
|
|
31
|
+
Print ASCII art text directly
|
|
32
|
+
|
|
33
|
+
:param text: Text to convert and print
|
|
34
|
+
:param font: Font style (default: 'block')
|
|
35
|
+
"""
|
|
36
|
+
print(figlet_format(text, font))
|
|
37
|
+
|
|
38
|
+
# Expose additional effects
|
|
39
|
+
rainbow = AsciiArtEffects.rainbow_effect
|
|
40
|
+
glitch = AsciiArtEffects.glitch_effect
|
|
41
|
+
wrap_text = AsciiArtEffects.wrap_text
|
|
42
|
+
outline = AsciiArtEffects.outline_effect
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
'figlet_format',
|
|
46
|
+
'print_figlet',
|
|
47
|
+
'rainbow',
|
|
48
|
+
'glitch',
|
|
49
|
+
'wrap_text',
|
|
50
|
+
'outline',
|
|
51
|
+
'BlockFont',
|
|
52
|
+
'SlantFont',
|
|
53
|
+
'NeonFont',
|
|
54
|
+
'CyberFont'
|
|
55
|
+
]
|
webscout/zeroart/base.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroArt Base: Core classes and utilities for ASCII art generation
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
class ZeroArtFont:
|
|
6
|
+
"""Base class for ASCII art fonts"""
|
|
7
|
+
def __init__(self, name):
|
|
8
|
+
self.name = name
|
|
9
|
+
self.letters = {}
|
|
10
|
+
self.special_chars = {}
|
|
11
|
+
|
|
12
|
+
def add_letter(self, char, art_lines):
|
|
13
|
+
"""
|
|
14
|
+
Add a custom letter to the font
|
|
15
|
+
|
|
16
|
+
:param char: Character to add
|
|
17
|
+
:param art_lines: List of art lines representing the character
|
|
18
|
+
"""
|
|
19
|
+
self.letters[char.upper()] = art_lines
|
|
20
|
+
|
|
21
|
+
def add_special_char(self, name, art_lines):
|
|
22
|
+
"""
|
|
23
|
+
Add a special ASCII art character or design
|
|
24
|
+
|
|
25
|
+
:param name: Name of the special character
|
|
26
|
+
:param art_lines: List of art lines representing the character
|
|
27
|
+
"""
|
|
28
|
+
self.special_chars[name] = art_lines
|
|
29
|
+
|
|
30
|
+
def get_letter(self, char):
|
|
31
|
+
"""
|
|
32
|
+
Get ASCII art for a specific character
|
|
33
|
+
|
|
34
|
+
:param char: Character to retrieve
|
|
35
|
+
:return: List of art lines or default space
|
|
36
|
+
"""
|
|
37
|
+
return self.letters.get(char.upper(), self.letters.get(' ', [' ']))
|
|
38
|
+
|
|
39
|
+
def render(self, text):
|
|
40
|
+
"""
|
|
41
|
+
Render text as ASCII art
|
|
42
|
+
|
|
43
|
+
:param text: Text to convert
|
|
44
|
+
:return: Rendered ASCII art as a string
|
|
45
|
+
"""
|
|
46
|
+
# Ensure text is uppercase
|
|
47
|
+
text = text.upper()
|
|
48
|
+
|
|
49
|
+
# Initialize lines for rendering
|
|
50
|
+
art_lines = [''] * 5 # Assuming 5-line height
|
|
51
|
+
|
|
52
|
+
for char in text:
|
|
53
|
+
# Get character's art or use space if not found
|
|
54
|
+
char_art = self.get_letter(char)
|
|
55
|
+
|
|
56
|
+
# Combine lines
|
|
57
|
+
for i in range(len(char_art)):
|
|
58
|
+
art_lines[i] += char_art[i] + " "
|
|
59
|
+
|
|
60
|
+
# Join lines and remove trailing space
|
|
61
|
+
return "\n".join(art_lines)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroArt Effects: ASCII art text effects and transformations
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import random
|
|
6
|
+
import textwrap
|
|
7
|
+
|
|
8
|
+
class AsciiArtEffects:
|
|
9
|
+
"""Collection of ASCII art text effects"""
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def rainbow_effect(text, font):
|
|
13
|
+
"""
|
|
14
|
+
Apply a rainbow-like color effect to ASCII art
|
|
15
|
+
|
|
16
|
+
:param text: Text to render
|
|
17
|
+
:param font: Font to use
|
|
18
|
+
:return: Rainbow-styled ASCII art
|
|
19
|
+
"""
|
|
20
|
+
colors = [
|
|
21
|
+
'\033[91m', # Red
|
|
22
|
+
'\033[93m', # Yellow
|
|
23
|
+
'\033[92m', # Green
|
|
24
|
+
'\033[94m', # Blue
|
|
25
|
+
'\033[95m', # Magenta
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
art = font.render(text)
|
|
29
|
+
art_lines = art.split('\n')
|
|
30
|
+
|
|
31
|
+
colored_lines = []
|
|
32
|
+
for line in art_lines:
|
|
33
|
+
colored_line = ''
|
|
34
|
+
for char in line:
|
|
35
|
+
color = random.choice(colors)
|
|
36
|
+
colored_line += color + char
|
|
37
|
+
colored_lines.append(colored_line + '\033[0m') # Reset color
|
|
38
|
+
|
|
39
|
+
return '\n'.join(colored_lines)
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def glitch_effect(text, font, glitch_intensity=0.1):
|
|
43
|
+
"""
|
|
44
|
+
Apply a glitch-like distortion to ASCII art
|
|
45
|
+
|
|
46
|
+
:param text: Text to render
|
|
47
|
+
:param font: Font to use
|
|
48
|
+
:param glitch_intensity: Probability of character distortion
|
|
49
|
+
:return: Glitched ASCII art
|
|
50
|
+
"""
|
|
51
|
+
art = font.render(text)
|
|
52
|
+
art_lines = art.split('\n')
|
|
53
|
+
|
|
54
|
+
glitched_lines = []
|
|
55
|
+
glitch_chars = ['~', '^', '`', '¯', '±']
|
|
56
|
+
|
|
57
|
+
for line in art_lines:
|
|
58
|
+
glitched_line = ''
|
|
59
|
+
for char in line:
|
|
60
|
+
if random.random() < glitch_intensity:
|
|
61
|
+
glitched_line += random.choice(glitch_chars)
|
|
62
|
+
else:
|
|
63
|
+
glitched_line += char
|
|
64
|
+
glitched_lines.append(glitched_line)
|
|
65
|
+
|
|
66
|
+
return '\n'.join(glitched_lines)
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def wrap_text(text, width=20):
|
|
70
|
+
"""
|
|
71
|
+
Wrap ASCII art text to a specific width
|
|
72
|
+
|
|
73
|
+
:param text: Text to wrap
|
|
74
|
+
:param width: Maximum line width
|
|
75
|
+
:return: Wrapped text
|
|
76
|
+
"""
|
|
77
|
+
return textwrap.fill(text, width=width)
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def outline_effect(text, font, outline_char='*'):
|
|
81
|
+
"""
|
|
82
|
+
Add an outline effect to ASCII art
|
|
83
|
+
|
|
84
|
+
:param text: Text to render
|
|
85
|
+
:param font: Font to use
|
|
86
|
+
:param outline_char: Character to use for outline
|
|
87
|
+
:return: ASCII art with outline
|
|
88
|
+
"""
|
|
89
|
+
art = font.render(text)
|
|
90
|
+
art_lines = art.split('\n')
|
|
91
|
+
|
|
92
|
+
outlined_lines = []
|
|
93
|
+
for line in art_lines:
|
|
94
|
+
outlined_line = outline_char + line + outline_char
|
|
95
|
+
outlined_lines.append(outlined_line)
|
|
96
|
+
|
|
97
|
+
top_bottom_line = outline_char * (len(outlined_lines[0]))
|
|
98
|
+
|
|
99
|
+
return '\n'.join([top_bottom_line] + outlined_lines + [top_bottom_line])
|