webscout 7.1__py3-none-any.whl → 7.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webscout might be problematic. Click here for more details.

Files changed (144) hide show
  1. webscout/AIauto.py +191 -191
  2. webscout/AIbase.py +122 -122
  3. webscout/AIutel.py +440 -440
  4. webscout/Bard.py +343 -161
  5. webscout/DWEBS.py +489 -492
  6. webscout/Extra/YTToolkit/YTdownloader.py +995 -995
  7. webscout/Extra/YTToolkit/__init__.py +2 -2
  8. webscout/Extra/YTToolkit/transcriber.py +476 -479
  9. webscout/Extra/YTToolkit/ytapi/channel.py +307 -307
  10. webscout/Extra/YTToolkit/ytapi/playlist.py +58 -58
  11. webscout/Extra/YTToolkit/ytapi/pool.py +7 -7
  12. webscout/Extra/YTToolkit/ytapi/utils.py +62 -62
  13. webscout/Extra/YTToolkit/ytapi/video.py +103 -103
  14. webscout/Extra/autocoder/__init__.py +9 -9
  15. webscout/Extra/autocoder/autocoder_utiles.py +199 -199
  16. webscout/Extra/autocoder/rawdog.py +5 -7
  17. webscout/Extra/autollama.py +230 -230
  18. webscout/Extra/gguf.py +3 -3
  19. webscout/Extra/weather.py +171 -171
  20. webscout/LLM.py +442 -442
  21. webscout/Litlogger/__init__.py +67 -681
  22. webscout/Litlogger/core/__init__.py +6 -0
  23. webscout/Litlogger/core/level.py +20 -0
  24. webscout/Litlogger/core/logger.py +123 -0
  25. webscout/Litlogger/handlers/__init__.py +12 -0
  26. webscout/Litlogger/handlers/console.py +50 -0
  27. webscout/Litlogger/handlers/file.py +143 -0
  28. webscout/Litlogger/handlers/network.py +174 -0
  29. webscout/Litlogger/styles/__init__.py +7 -0
  30. webscout/Litlogger/styles/colors.py +231 -0
  31. webscout/Litlogger/styles/formats.py +377 -0
  32. webscout/Litlogger/styles/text.py +87 -0
  33. webscout/Litlogger/utils/__init__.py +6 -0
  34. webscout/Litlogger/utils/detectors.py +154 -0
  35. webscout/Litlogger/utils/formatters.py +200 -0
  36. webscout/Provider/AISEARCH/DeepFind.py +250 -250
  37. webscout/Provider/Blackboxai.py +3 -3
  38. webscout/Provider/ChatGPTGratis.py +226 -0
  39. webscout/Provider/Cloudflare.py +3 -4
  40. webscout/Provider/DeepSeek.py +218 -0
  41. webscout/Provider/Deepinfra.py +3 -3
  42. webscout/Provider/Free2GPT.py +131 -124
  43. webscout/Provider/Gemini.py +100 -115
  44. webscout/Provider/Glider.py +3 -3
  45. webscout/Provider/Groq.py +5 -1
  46. webscout/Provider/Jadve.py +3 -3
  47. webscout/Provider/Marcus.py +191 -192
  48. webscout/Provider/Netwrck.py +3 -3
  49. webscout/Provider/PI.py +2 -2
  50. webscout/Provider/PizzaGPT.py +2 -3
  51. webscout/Provider/QwenLM.py +311 -0
  52. webscout/Provider/TTI/AiForce/__init__.py +22 -22
  53. webscout/Provider/TTI/AiForce/async_aiforce.py +257 -257
  54. webscout/Provider/TTI/AiForce/sync_aiforce.py +242 -242
  55. webscout/Provider/TTI/Nexra/__init__.py +22 -22
  56. webscout/Provider/TTI/Nexra/async_nexra.py +286 -286
  57. webscout/Provider/TTI/Nexra/sync_nexra.py +258 -258
  58. webscout/Provider/TTI/PollinationsAI/__init__.py +23 -23
  59. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +330 -330
  60. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +285 -285
  61. webscout/Provider/TTI/artbit/__init__.py +22 -22
  62. webscout/Provider/TTI/artbit/async_artbit.py +184 -184
  63. webscout/Provider/TTI/artbit/sync_artbit.py +176 -176
  64. webscout/Provider/TTI/blackbox/__init__.py +4 -4
  65. webscout/Provider/TTI/blackbox/async_blackbox.py +212 -212
  66. webscout/Provider/TTI/blackbox/sync_blackbox.py +199 -199
  67. webscout/Provider/TTI/deepinfra/__init__.py +4 -4
  68. webscout/Provider/TTI/deepinfra/async_deepinfra.py +227 -227
  69. webscout/Provider/TTI/deepinfra/sync_deepinfra.py +199 -199
  70. webscout/Provider/TTI/huggingface/__init__.py +22 -22
  71. webscout/Provider/TTI/huggingface/async_huggingface.py +199 -199
  72. webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -195
  73. webscout/Provider/TTI/imgninza/__init__.py +4 -4
  74. webscout/Provider/TTI/imgninza/async_ninza.py +214 -214
  75. webscout/Provider/TTI/imgninza/sync_ninza.py +209 -209
  76. webscout/Provider/TTI/talkai/__init__.py +4 -4
  77. webscout/Provider/TTI/talkai/async_talkai.py +229 -229
  78. webscout/Provider/TTI/talkai/sync_talkai.py +207 -207
  79. webscout/Provider/TTS/deepgram.py +182 -182
  80. webscout/Provider/TTS/elevenlabs.py +136 -136
  81. webscout/Provider/TTS/gesserit.py +150 -150
  82. webscout/Provider/TTS/murfai.py +138 -138
  83. webscout/Provider/TTS/parler.py +133 -134
  84. webscout/Provider/TTS/streamElements.py +360 -360
  85. webscout/Provider/TTS/utils.py +280 -280
  86. webscout/Provider/TTS/voicepod.py +116 -116
  87. webscout/Provider/TextPollinationsAI.py +2 -3
  88. webscout/Provider/WiseCat.py +193 -0
  89. webscout/Provider/__init__.py +144 -134
  90. webscout/Provider/cerebras.py +242 -227
  91. webscout/Provider/chatglm.py +204 -204
  92. webscout/Provider/dgaf.py +2 -3
  93. webscout/Provider/gaurish.py +2 -3
  94. webscout/Provider/geminiapi.py +208 -208
  95. webscout/Provider/granite.py +223 -0
  96. webscout/Provider/hermes.py +218 -218
  97. webscout/Provider/llama3mitril.py +179 -179
  98. webscout/Provider/llamatutor.py +3 -3
  99. webscout/Provider/llmchat.py +2 -3
  100. webscout/Provider/meta.py +794 -794
  101. webscout/Provider/multichat.py +331 -331
  102. webscout/Provider/typegpt.py +359 -359
  103. webscout/Provider/yep.py +2 -2
  104. webscout/__main__.py +5 -5
  105. webscout/cli.py +319 -319
  106. webscout/conversation.py +241 -242
  107. webscout/exceptions.py +328 -328
  108. webscout/litagent/__init__.py +28 -28
  109. webscout/litagent/agent.py +2 -3
  110. webscout/litprinter/__init__.py +0 -58
  111. webscout/scout/__init__.py +8 -8
  112. webscout/scout/core.py +884 -884
  113. webscout/scout/element.py +459 -459
  114. webscout/scout/parsers/__init__.py +69 -69
  115. webscout/scout/parsers/html5lib_parser.py +172 -172
  116. webscout/scout/parsers/html_parser.py +236 -236
  117. webscout/scout/parsers/lxml_parser.py +178 -178
  118. webscout/scout/utils.py +38 -38
  119. webscout/swiftcli/__init__.py +811 -811
  120. webscout/update_checker.py +2 -12
  121. webscout/version.py +1 -1
  122. webscout/webscout_search.py +5 -4
  123. webscout/zeroart/__init__.py +54 -54
  124. webscout/zeroart/base.py +60 -60
  125. webscout/zeroart/effects.py +99 -99
  126. webscout/zeroart/fonts.py +816 -816
  127. {webscout-7.1.dist-info → webscout-7.2.dist-info}/METADATA +4 -3
  128. webscout-7.2.dist-info/RECORD +217 -0
  129. webstoken/__init__.py +30 -30
  130. webstoken/classifier.py +189 -189
  131. webstoken/keywords.py +216 -216
  132. webstoken/language.py +128 -128
  133. webstoken/ner.py +164 -164
  134. webstoken/normalizer.py +35 -35
  135. webstoken/processor.py +77 -77
  136. webstoken/sentiment.py +206 -206
  137. webstoken/stemmer.py +73 -73
  138. webstoken/tagger.py +60 -60
  139. webstoken/tokenizer.py +158 -158
  140. webscout-7.1.dist-info/RECORD +0 -198
  141. {webscout-7.1.dist-info → webscout-7.2.dist-info}/LICENSE.md +0 -0
  142. {webscout-7.1.dist-info → webscout-7.2.dist-info}/WHEEL +0 -0
  143. {webscout-7.1.dist-info → webscout-7.2.dist-info}/entry_points.txt +0 -0
  144. {webscout-7.1.dist-info → webscout-7.2.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@ import requests
15
15
  from packaging import version
16
16
  import re
17
17
 
18
- from webscout import LitLogger, ColorScheme
18
+ from webscout.Litlogger import Logger
19
19
  from importlib.metadata import version as get_package_version
20
20
  from importlib.metadata import PackageNotFoundError
21
21
  from importlib.metadata import metadata as get_package_metadata
@@ -23,19 +23,9 @@ from importlib.metadata import metadata as get_package_metadata
23
23
  # Setting up that clean logger format, no cap! 💯
24
24
  CUSTOM_FORMAT = """{message}"""
25
25
 
26
- logger = LitLogger(
26
+ logger = Logger(
27
27
  name="WebscoutUpdate",
28
28
  format=CUSTOM_FORMAT,
29
- color_scheme=ColorScheme.OCEAN,
30
- level_styles={
31
- "TRACE": "DIM",
32
- "DEBUG": "NORMAL",
33
- "INFO": "BOLD",
34
- "SUCCESS": "BOLD",
35
- "WARNING": "BOLD",
36
- "ERROR": "BOLD",
37
- "CRITICAL": "BOLD"
38
- }
39
29
  )
40
30
 
41
31
  def get_installed_version() -> Optional[str]:
webscout/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "7.1"
1
+ __version__ = "7.2"
2
2
  __prog__ = "webscout"
@@ -178,7 +178,8 @@ class WEBS:
178
178
  """
179
179
  models_deprecated = {
180
180
  "gpt-3.5": "gpt-4o-mini",
181
- "llama-3-70b": "llama-3.1-70b"
181
+ "llama-3.1-70b": "llama-3.3-70b",
182
+ "mixtral-8x7b": "mistral-24B"
182
183
  }
183
184
  if model in models_deprecated:
184
185
  # logger.info(f"{model=} is deprecated, using {models_deprecated[model]}")
@@ -186,9 +187,9 @@ class WEBS:
186
187
  models = {
187
188
  "claude-3-haiku": "claude-3-haiku-20240307",
188
189
  "gpt-4o-mini": "gpt-4o-mini",
189
- "llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
190
- "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1",
191
- "o3-mini":"o3-mini"
190
+ "llama-3.3-70b": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
191
+ "o3-mini":"o3-mini",
192
+ "mistral-24B": "mistralai/Mistral-Small-24B-Instruct-2501"
192
193
  }
193
194
  # vqd
194
195
  if not self._chat_vqd:
@@ -1,55 +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'
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
55
  ]
webscout/zeroart/base.py CHANGED
@@ -1,60 +1,60 @@
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
- if not text:
41
- return ""
42
-
43
- # Get the maximum height of any character in the font
44
- max_height = max(len(self.get_letter(c)) for c in text)
45
-
46
- # Initialize art_lines with empty strings
47
- art_lines = ["" for _ in range(max_height)]
48
-
49
- # Process each character
50
- for char in text:
51
- char_art = self.get_letter(char)
52
- # Pad shorter characters with empty lines to match max_height
53
- while len(char_art) < max_height:
54
- char_art.append(" " * len(char_art[0]))
55
-
56
- # Add character art to each line
57
- for i in range(max_height):
58
- art_lines[i] += char_art[i] + " "
59
-
60
- return "\n".join(art_lines)
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
+ if not text:
41
+ return ""
42
+
43
+ # Get the maximum height of any character in the font
44
+ max_height = max(len(self.get_letter(c)) for c in text)
45
+
46
+ # Initialize art_lines with empty strings
47
+ art_lines = ["" for _ in range(max_height)]
48
+
49
+ # Process each character
50
+ for char in text:
51
+ char_art = self.get_letter(char)
52
+ # Pad shorter characters with empty lines to match max_height
53
+ while len(char_art) < max_height:
54
+ char_art.append(" " * len(char_art[0]))
55
+
56
+ # Add character art to each line
57
+ for i in range(max_height):
58
+ art_lines[i] += char_art[i] + " "
59
+
60
+ return "\n".join(art_lines)
@@ -1,99 +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])
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])