webscout 7.5__py3-none-any.whl → 7.6__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 (118) hide show
  1. webscout/AIauto.py +5 -53
  2. webscout/AIutel.py +8 -318
  3. webscout/DWEBS.py +460 -489
  4. webscout/Extra/YTToolkit/YTdownloader.py +14 -53
  5. webscout/Extra/YTToolkit/transcriber.py +12 -13
  6. webscout/Extra/YTToolkit/ytapi/video.py +0 -1
  7. webscout/Extra/__init__.py +0 -1
  8. webscout/Extra/autocoder/autocoder_utiles.py +0 -4
  9. webscout/Extra/autocoder/rawdog.py +13 -41
  10. webscout/Extra/gguf.py +652 -428
  11. webscout/Extra/weather.py +178 -156
  12. webscout/Extra/weather_ascii.py +70 -17
  13. webscout/Litlogger/core/logger.py +1 -2
  14. webscout/Litlogger/handlers/file.py +1 -1
  15. webscout/Litlogger/styles/formats.py +0 -2
  16. webscout/Litlogger/utils/detectors.py +0 -1
  17. webscout/Provider/AISEARCH/DeepFind.py +0 -1
  18. webscout/Provider/AISEARCH/ISou.py +1 -1
  19. webscout/Provider/AISEARCH/felo_search.py +0 -1
  20. webscout/Provider/AllenAI.py +24 -9
  21. webscout/Provider/C4ai.py +29 -11
  22. webscout/Provider/ChatGPTGratis.py +24 -56
  23. webscout/Provider/DeepSeek.py +25 -17
  24. webscout/Provider/Deepinfra.py +115 -48
  25. webscout/Provider/Gemini.py +1 -1
  26. webscout/Provider/Glider.py +25 -8
  27. webscout/Provider/HF_space/qwen_qwen2.py +2 -2
  28. webscout/Provider/HeckAI.py +23 -7
  29. webscout/Provider/Jadve.py +20 -5
  30. webscout/Provider/Netwrck.py +42 -19
  31. webscout/Provider/PI.py +4 -2
  32. webscout/Provider/Perplexitylabs.py +26 -6
  33. webscout/Provider/PizzaGPT.py +10 -51
  34. webscout/Provider/TTI/AiForce/async_aiforce.py +4 -37
  35. webscout/Provider/TTI/AiForce/sync_aiforce.py +41 -38
  36. webscout/Provider/TTI/FreeAIPlayground/__init__.py +9 -9
  37. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +206 -206
  38. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +192 -192
  39. webscout/Provider/TTI/MagicStudio/__init__.py +2 -0
  40. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +111 -0
  41. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +109 -0
  42. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +5 -24
  43. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +2 -22
  44. webscout/Provider/TTI/__init__.py +2 -3
  45. webscout/Provider/TTI/aiarta/async_aiarta.py +14 -14
  46. webscout/Provider/TTI/aiarta/sync_aiarta.py +52 -21
  47. webscout/Provider/TTI/fastflux/__init__.py +22 -0
  48. webscout/Provider/TTI/fastflux/async_fastflux.py +257 -0
  49. webscout/Provider/TTI/fastflux/sync_fastflux.py +247 -0
  50. webscout/Provider/TTS/__init__.py +2 -2
  51. webscout/Provider/TTS/deepgram.py +12 -39
  52. webscout/Provider/TTS/elevenlabs.py +14 -40
  53. webscout/Provider/TTS/gesserit.py +11 -35
  54. webscout/Provider/TTS/murfai.py +13 -39
  55. webscout/Provider/TTS/parler.py +17 -40
  56. webscout/Provider/TTS/speechma.py +180 -0
  57. webscout/Provider/TTS/streamElements.py +17 -44
  58. webscout/Provider/TextPollinationsAI.py +39 -59
  59. webscout/Provider/Venice.py +25 -8
  60. webscout/Provider/WiseCat.py +27 -5
  61. webscout/Provider/Youchat.py +64 -37
  62. webscout/Provider/__init__.py +0 -6
  63. webscout/Provider/akashgpt.py +20 -5
  64. webscout/Provider/flowith.py +20 -5
  65. webscout/Provider/freeaichat.py +32 -45
  66. webscout/Provider/koala.py +20 -5
  67. webscout/Provider/llamatutor.py +1 -1
  68. webscout/Provider/llmchat.py +30 -8
  69. webscout/Provider/multichat.py +65 -9
  70. webscout/Provider/talkai.py +1 -0
  71. webscout/Provider/turboseek.py +3 -0
  72. webscout/Provider/tutorai.py +2 -0
  73. webscout/Provider/typegpt.py +154 -64
  74. webscout/Provider/x0gpt.py +3 -1
  75. webscout/Provider/yep.py +102 -20
  76. webscout/__init__.py +3 -0
  77. webscout/cli.py +4 -40
  78. webscout/conversation.py +1 -10
  79. webscout/litagent/__init__.py +2 -2
  80. webscout/litagent/agent.py +351 -20
  81. webscout/litagent/constants.py +34 -5
  82. webscout/litprinter/__init__.py +0 -3
  83. webscout/models.py +181 -0
  84. webscout/optimizers.py +1 -1
  85. webscout/prompt_manager.py +2 -8
  86. webscout/scout/core/scout.py +1 -4
  87. webscout/scout/core/search_result.py +1 -1
  88. webscout/scout/core/text_utils.py +1 -1
  89. webscout/scout/core.py +2 -5
  90. webscout/scout/element.py +1 -1
  91. webscout/scout/parsers/html_parser.py +1 -1
  92. webscout/scout/utils.py +0 -1
  93. webscout/swiftcli/__init__.py +1 -3
  94. webscout/tempid.py +1 -1
  95. webscout/update_checker.py +1 -3
  96. webscout/version.py +1 -1
  97. webscout/webscout_search_async.py +1 -2
  98. webscout/yep_search.py +297 -297
  99. {webscout-7.5.dist-info → webscout-7.6.dist-info}/LICENSE.md +4 -4
  100. {webscout-7.5.dist-info → webscout-7.6.dist-info}/METADATA +101 -390
  101. {webscout-7.5.dist-info → webscout-7.6.dist-info}/RECORD +104 -110
  102. webscout/Extra/autollama.py +0 -231
  103. webscout/Provider/Amigo.py +0 -274
  104. webscout/Provider/Bing.py +0 -243
  105. webscout/Provider/DiscordRocks.py +0 -253
  106. webscout/Provider/TTI/blackbox/__init__.py +0 -4
  107. webscout/Provider/TTI/blackbox/async_blackbox.py +0 -212
  108. webscout/Provider/TTI/blackbox/sync_blackbox.py +0 -199
  109. webscout/Provider/TTI/deepinfra/__init__.py +0 -4
  110. webscout/Provider/TTI/deepinfra/async_deepinfra.py +0 -227
  111. webscout/Provider/TTI/deepinfra/sync_deepinfra.py +0 -199
  112. webscout/Provider/TTI/imgninza/__init__.py +0 -4
  113. webscout/Provider/TTI/imgninza/async_ninza.py +0 -214
  114. webscout/Provider/TTI/imgninza/sync_ninza.py +0 -209
  115. webscout/Provider/TTS/voicepod.py +0 -117
  116. {webscout-7.5.dist-info → webscout-7.6.dist-info}/WHEEL +0 -0
  117. {webscout-7.5.dist-info → webscout-7.6.dist-info}/entry_points.txt +0 -0
  118. {webscout-7.5.dist-info → webscout-7.6.dist-info}/top_level.txt +0 -0
webscout/conversation.py CHANGED
@@ -1,13 +1,6 @@
1
1
  import os
2
- import logging
3
2
  from typing import Optional
4
- from .Litlogger import Logger, LogFormat
5
3
 
6
- # Create a logger instance for this module
7
- logger = Logger(
8
- name="Conversation",
9
- format=LogFormat.MODERN_EMOJI,
10
- )
11
4
 
12
5
  class Conversation:
13
6
  """Handles prompt generation based on history and maintains chat context.
@@ -79,11 +72,9 @@ class Conversation:
79
72
  ), f"File '{filepath}' does not exist"
80
73
 
81
74
  if not os.path.isfile(filepath):
82
- logging.debug(f"Creating new chat-history file - '{filepath}'")
83
75
  with open(filepath, "w", encoding="utf-8") as fh:
84
76
  fh.write(self.intro)
85
77
  else:
86
- logging.debug(f"Loading conversation from '{filepath}'")
87
78
  with open(filepath, encoding="utf-8") as fh:
88
79
  file_contents = fh.readlines()
89
80
  if file_contents:
@@ -221,7 +212,7 @@ class Conversation:
221
212
  if role in role_formats:
222
213
  self.chat_history += f"\n{role_formats[role]} : {content}"
223
214
  else:
224
- logger.warning(f"Unknown role '{role}' for message: {content}")
215
+ raise ValueError(f"Invalid role: {role}. Must be one of {list(role_formats.keys())}")
225
216
 
226
217
  # # Enhanced logging for message addition
227
218
  # logger.info(f"Added message from {role}: {content}")
@@ -22,8 +22,8 @@ Examples:
22
22
  """
23
23
 
24
24
  from .agent import LitAgent
25
- from .constants import BROWSERS, OS_VERSIONS, DEVICES
25
+ from .constants import BROWSERS, OS_VERSIONS, DEVICES, FINGERPRINTS
26
26
 
27
27
  agent = LitAgent()
28
28
 
29
- __all__ = ['LitAgent', 'agent', 'BROWSERS', 'OS_VERSIONS', 'DEVICES']
29
+ __all__ = ['LitAgent', 'agent', 'BROWSERS', 'OS_VERSIONS', 'DEVICES', 'FINGERPRINTS']
@@ -1,21 +1,31 @@
1
1
  """Main LitAgent implementation."""
2
2
 
3
3
  import random
4
- from typing import List
5
- from webscout.Litlogger import Logger, LogFormat
6
- from webscout.litagent.constants import BROWSERS, OS_VERSIONS, DEVICES
4
+ import threading
5
+ from typing import List, Dict, Any, Optional
6
+
7
+ from webscout.litagent.constants import BROWSERS, OS_VERSIONS, DEVICES, FINGERPRINTS
7
8
 
8
- logger = Logger(
9
- name="LitAgent",
10
- format=LogFormat.MODERN_EMOJI,
11
- )
12
9
 
13
10
  class LitAgent:
14
11
  """A lit user agent generator that keeps it fresh! 🌟"""
15
12
 
16
- def __init__(self):
17
- """Initialize LitAgent with style! 💫"""
13
+ def __init__(self, thread_safe: bool = False):
14
+ """Initialize LitAgent with style! 💫
15
+
16
+ Args:
17
+ thread_safe (bool): Enable thread-safety for multi-threaded applications
18
+ """
18
19
  self.agents = self._generate_agents(100) # Keep 100 agents in memory
20
+ self.thread_safe = thread_safe
21
+ self.lock = threading.RLock() if thread_safe else None
22
+ self._refresh_timer = None
23
+ self._stats = {
24
+ "total_generated": 100,
25
+ "requests_served": 0,
26
+ "browser_usage": {browser: 0 for browser in BROWSERS.keys()},
27
+ "device_usage": {device: 0 for device in DEVICES.keys()}
28
+ }
19
29
 
20
30
  def _generate_agents(self, count: int) -> List[str]:
21
31
  """Generate some lit user agents! 🛠️"""
@@ -24,7 +34,7 @@ class LitAgent:
24
34
  browser = random.choice(list(BROWSERS.keys()))
25
35
  version = random.randint(*BROWSERS[browser])
26
36
 
27
- if browser in ['chrome', 'firefox', 'edge', 'opera']:
37
+ if browser in ['chrome', 'firefox', 'edge', 'opera', 'brave', 'vivaldi']:
28
38
  os_type = random.choice(['windows', 'mac', 'linux'])
29
39
  os_ver = random.choice(OS_VERSIONS[os_type])
30
40
 
@@ -44,6 +54,10 @@ class LitAgent:
44
54
  agent += f"Edge/{version}.0.0.0"
45
55
  elif browser == 'opera':
46
56
  agent += f"OPR/{version}.0.0.0"
57
+ elif browser == 'brave':
58
+ agent += f"Chrome/{version}.0.0.0 Safari/537.36 Brave/{version}.0.0.0"
59
+ elif browser == 'vivaldi':
60
+ agent += f"Chrome/{version}.0.0.0 Safari/537.36 Vivaldi/{version}.0.{random.randint(1000, 9999)}"
47
61
 
48
62
  elif browser == 'safari':
49
63
  device = random.choice(['mac', 'ios'])
@@ -60,29 +74,127 @@ class LitAgent:
60
74
 
61
75
  return list(set(agents)) # Remove any duplicates
62
76
 
77
+ def _update_stats(self, browser_type=None, device_type=None):
78
+ """Update usage statistics."""
79
+ if self.thread_safe and self.lock:
80
+ with self.lock:
81
+ self._stats["requests_served"] += 1
82
+ if browser_type:
83
+ self._stats["browser_usage"][browser_type] = self._stats["browser_usage"].get(browser_type, 0) + 1
84
+ if device_type:
85
+ self._stats["device_usage"][device_type] = self._stats["device_usage"].get(device_type, 0) + 1
86
+ else:
87
+ self._stats["requests_served"] += 1
88
+ if browser_type:
89
+ self._stats["browser_usage"][browser_type] = self._stats["browser_usage"].get(browser_type, 0) + 1
90
+ if device_type:
91
+ self._stats["device_usage"][device_type] = self._stats["device_usage"].get(device_type, 0) + 1
92
+
63
93
  def random(self) -> str:
64
94
  """Get a random user agent! 🎲"""
65
- return random.choice(self.agents)
95
+ if self.thread_safe and self.lock:
96
+ with self.lock:
97
+ agent = random.choice(self.agents)
98
+ self._update_stats()
99
+ return agent
100
+ else:
101
+ agent = random.choice(self.agents)
102
+ self._update_stats()
103
+ return agent
66
104
 
67
105
  def browser(self, name: str) -> str:
68
106
  """Get a browser-specific agent! 🌐"""
69
107
  name = name.lower()
70
108
  if name not in BROWSERS:
71
- logger.warning(f"Unknown browser: {name} - Using random browser")
72
109
  return self.random()
73
110
 
74
- agents = [a for a in self.agents if name in a.lower()]
75
- return random.choice(agents) if agents else self.random()
111
+ if self.thread_safe and self.lock:
112
+ with self.lock:
113
+ agents = [a for a in self.agents if name in a.lower()]
114
+ agent = random.choice(agents) if agents else self.random()
115
+ self._update_stats(browser_type=name)
116
+ return agent
117
+ else:
118
+ agents = [a for a in self.agents if name in a.lower()]
119
+ agent = random.choice(agents) if agents else self.random()
120
+ self._update_stats(browser_type=name)
121
+ return agent
76
122
 
77
123
  def mobile(self) -> str:
78
124
  """Get a mobile device agent! 📱"""
79
- agents = [a for a in self.agents if any(d in a for d in DEVICES['mobile'])]
80
- return random.choice(agents) if agents else self.random()
125
+ if self.thread_safe and self.lock:
126
+ with self.lock:
127
+ agents = [a for a in self.agents if any(d in a for d in DEVICES['mobile'])]
128
+ agent = random.choice(agents) if agents else self.random()
129
+ self._update_stats(device_type="mobile")
130
+ return agent
131
+ else:
132
+ agents = [a for a in self.agents if any(d in a for d in DEVICES['mobile'])]
133
+ agent = random.choice(agents) if agents else self.random()
134
+ self._update_stats(device_type="mobile")
135
+ return agent
81
136
 
82
137
  def desktop(self) -> str:
83
138
  """Get a desktop agent! 💻"""
84
- agents = [a for a in self.agents if 'Windows' in a or 'Macintosh' in a or 'Linux' in a]
85
- return random.choice(agents) if agents else self.random()
139
+ if self.thread_safe and self.lock:
140
+ with self.lock:
141
+ agents = [a for a in self.agents if 'Windows' in a or 'Macintosh' in a or 'Linux' in a]
142
+ agent = random.choice(agents) if agents else self.random()
143
+ self._update_stats(device_type="desktop")
144
+ return agent
145
+ else:
146
+ agents = [a for a in self.agents if 'Windows' in a or 'Macintosh' in a or 'Linux' in a]
147
+ agent = random.choice(agents) if agents else self.random()
148
+ self._update_stats(device_type="desktop")
149
+ return agent
150
+
151
+ def tablet(self) -> str:
152
+ """Get a tablet agent! 📱"""
153
+ if self.thread_safe and self.lock:
154
+ with self.lock:
155
+ # Focus on iPad and Android tablets
156
+ agents = [a for a in self.agents if 'iPad' in a or 'Android' in a and not 'Mobile' in a]
157
+ agent = random.choice(agents) if agents else self.random()
158
+ self._update_stats(device_type="tablet")
159
+ return agent
160
+ else:
161
+ agents = [a for a in self.agents if 'iPad' in a or 'Android' in a and not 'Mobile' in a]
162
+ agent = random.choice(agents) if agents else self.random()
163
+ self._update_stats(device_type="tablet")
164
+ return agent
165
+
166
+ def smart_tv(self) -> str:
167
+ """Get a Smart TV agent! 📺"""
168
+ # Create a TV-specific agent since they may not be in our standard pool
169
+ tv_type = random.choice(DEVICES['tv'])
170
+ if 'Samsung' in tv_type:
171
+ agent = f"Mozilla/5.0 (SMART-TV; SAMSUNG; {tv_type}; Tizen 5.5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.38 Safari/537.36"
172
+ elif 'LG' in tv_type:
173
+ agent = f"Mozilla/5.0 (Web0S; {tv_type}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"
174
+ elif 'Android' in tv_type:
175
+ agent = f"Mozilla/5.0 (Linux; Android 9; {tv_type}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"
176
+ elif 'Apple' in tv_type:
177
+ agent = f"Mozilla/5.0 (AppleTV; CPU like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
178
+ else:
179
+ agent = f"Mozilla/5.0 (Linux; {tv_type}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36"
180
+
181
+ self._update_stats(device_type="tv")
182
+ return agent
183
+
184
+ def gaming(self) -> str:
185
+ """Get a gaming console agent! 🎮"""
186
+ console_type = random.choice(DEVICES['console'])
187
+ if 'PlayStation' in console_type:
188
+ agent = f"Mozilla/5.0 ({console_type}/5.0) AppleWebKit/601.2 (KHTML, like Gecko)"
189
+ elif 'Xbox' in console_type:
190
+ agent = f"Mozilla/5.0 ({console_type}; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19041"
191
+ elif 'Nintendo' in console_type:
192
+ agent = f"Mozilla/5.0 (Nintendo Switch; {console_type}) AppleWebKit/601.6 (KHTML, like Gecko) NintendoBrowser/5.1.0.13343"
193
+ else:
194
+ agent = self.random()
195
+
196
+ self._update_stats(device_type="console")
197
+ return agent
86
198
 
87
199
  def chrome(self) -> str:
88
200
  """Get a Chrome agent! 🌐"""
@@ -103,10 +215,220 @@ class LitAgent:
103
215
  def opera(self) -> str:
104
216
  """Get an Opera agent! 🎭"""
105
217
  return self.browser('opera')
218
+
219
+ def brave(self) -> str:
220
+ """Get a Brave agent! 🦁"""
221
+ return self.browser('brave')
222
+
223
+ def vivaldi(self) -> str:
224
+ """Get a Vivaldi agent! 🎨"""
225
+ return self.browser('vivaldi')
226
+
227
+ # OS-specific agents
228
+ def windows(self) -> str:
229
+ """Get a Windows agent! 🪟"""
230
+ agents = [a for a in self.agents if 'Windows' in a]
231
+ agent = random.choice(agents) if agents else self.random()
232
+ self._update_stats()
233
+ return agent
234
+
235
+ def macos(self) -> str:
236
+ """Get a macOS agent! 🍎"""
237
+ agents = [a for a in self.agents if 'Macintosh' in a]
238
+ agent = random.choice(agents) if agents else self.random()
239
+ self._update_stats()
240
+ return agent
241
+
242
+ def linux(self) -> str:
243
+ """Get a Linux agent! 🐧"""
244
+ agents = [a for a in self.agents if 'Linux' in a and 'Android' not in a]
245
+ agent = random.choice(agents) if agents else self.random()
246
+ self._update_stats()
247
+ return agent
248
+
249
+ def android(self) -> str:
250
+ """Get an Android agent! 🤖"""
251
+ agents = [a for a in self.agents if 'Android' in a]
252
+ agent = random.choice(agents) if agents else self.random()
253
+ self._update_stats()
254
+ return agent
255
+
256
+ def ios(self) -> str:
257
+ """Get an iOS agent! 📱"""
258
+ agents = [a for a in self.agents if 'iPhone' in a or 'iPad' in a]
259
+ agent = random.choice(agents) if agents else self.random()
260
+ self._update_stats()
261
+ return agent
262
+
263
+ def custom(self, browser: str, version: Optional[str] = None,
264
+ os: Optional[str] = None, os_version: Optional[str] = None,
265
+ device_type: Optional[str] = None) -> str:
266
+ """Generate a custom user agent with specified parameters! 🛠️
267
+
268
+ Args:
269
+ browser: Browser name (chrome, firefox, safari, edge, opera)
270
+ version: Browser version (optional)
271
+ os: Operating system (windows, mac, linux, android, ios)
272
+ os_version: OS version (optional)
273
+ device_type: Device type (desktop, mobile, tablet)
274
+
275
+ Returns:
276
+ Customized user agent string
277
+ """
278
+ browser = browser.lower() if browser else 'chrome'
279
+ if browser not in BROWSERS:
280
+ browser = 'chrome'
281
+
282
+ if version:
283
+ try:
284
+ version_num = int(version.split('.')[0])
285
+ except (ValueError, IndexError):
286
+ version_num = random.randint(*BROWSERS[browser])
287
+ else:
288
+ version_num = random.randint(*BROWSERS[browser])
289
+
290
+ os = os.lower() if os else random.choice(['windows', 'mac', 'linux'])
291
+ if os not in OS_VERSIONS:
292
+ os = 'windows'
293
+
294
+ os_ver = os_version or random.choice(OS_VERSIONS[os])
295
+
296
+ device_type = device_type.lower() if device_type else 'desktop'
297
+
298
+ # Build the user agent
299
+ if os == 'windows':
300
+ platform = f"Windows NT {os_ver}"
301
+ elif os == 'mac':
302
+ platform = f"Macintosh; Intel Mac OS X {os_ver}"
303
+ elif os == 'linux':
304
+ platform = f"X11; Linux {OS_VERSIONS['linux'][0]}"
305
+ elif os == 'android':
306
+ platform = f"Linux; Android {os_ver}; {random.choice(DEVICES['mobile'])}"
307
+ elif os == 'ios':
308
+ device = 'iPhone' if device_type == 'mobile' else 'iPad'
309
+ platform = f"{device}; CPU OS {os_ver} like Mac OS X"
310
+ else:
311
+ platform = f"Windows NT 10.0" # Default fallback
312
+
313
+ agent = f"Mozilla/5.0 ({platform}) AppleWebKit/537.36 (KHTML, like Gecko) "
314
+
315
+ if browser == 'chrome':
316
+ agent += f"Chrome/{version_num}.0.0.0 Safari/537.36"
317
+ elif browser == 'firefox':
318
+ agent += f"Firefox/{version_num}.0"
319
+ elif browser == 'safari':
320
+ safari_ver = random.randint(*BROWSERS['safari'])
321
+ agent += f"Version/{version_num}.0 Safari/{safari_ver}.0"
322
+ elif browser == 'edge':
323
+ agent += f"Chrome/{version_num}.0.0.0 Safari/537.36 Edg/{version_num}.0.0.0"
324
+ elif browser == 'opera':
325
+ agent += f"Chrome/{version_num}.0.0.0 Safari/537.36 OPR/{version_num}.0.0.0"
326
+ elif browser == 'brave':
327
+ agent += f"Chrome/{version_num}.0.0.0 Safari/537.36 Brave/{version_num}.1.0"
328
+
329
+ self._update_stats(browser_type=browser, device_type=device_type)
330
+ return agent
331
+
332
+ def generate_fingerprint(self, browser: Optional[str] = None) -> Dict[str, str]:
333
+ """Generate a consistent browser fingerprint! 👆
334
+
335
+ This creates a coherent set of headers for anti-fingerprinting.
336
+
337
+ Args:
338
+ browser: Specific browser to generate fingerprint for
339
+
340
+ Returns:
341
+ Dictionary with fingerprinting headers
342
+ """
343
+ browser = browser.lower() if browser else random.choice(list(BROWSERS.keys()))
344
+ if browser not in BROWSERS:
345
+ browser = 'chrome'
346
+
347
+ version = random.randint(*BROWSERS[browser])
348
+ user_agent = self.custom(browser=browser, version=str(version))
349
+
350
+ accept_language = random.choice(FINGERPRINTS["accept_language"])
351
+ accept = random.choice(FINGERPRINTS["accept"])
352
+ platform = random.choice(FINGERPRINTS["platforms"])
353
+
354
+ # Generate sec-ch-ua
355
+ sec_ch_ua = ""
356
+ if browser in FINGERPRINTS["sec_ch_ua"]:
357
+ sec_ch_ua = FINGERPRINTS["sec_ch_ua"][browser].format(version, version)
358
+
359
+ fingerprint = {
360
+ "user_agent": user_agent,
361
+ "accept_language": accept_language,
362
+ "accept": accept,
363
+ "sec_ch_ua": sec_ch_ua,
364
+ "platform": platform
365
+ }
366
+
367
+ self._update_stats(browser_type=browser)
368
+ return fingerprint
106
369
 
107
370
  def refresh(self) -> None:
108
371
  """Refresh the agents with new ones! 🔄"""
109
- self.agents = self._generate_agents(100)
372
+ if self.thread_safe and self.lock:
373
+ with self.lock:
374
+ self.agents = self._generate_agents(100)
375
+ self._stats["total_generated"] += 100
376
+ else:
377
+ self.agents = self._generate_agents(100)
378
+ self._stats["total_generated"] += 100
379
+
380
+
381
+ def auto_refresh(self, interval_minutes: int = 30) -> None:
382
+ """Set up automatic refreshing of agents pool! ⏱️
383
+
384
+ Args:
385
+ interval_minutes: Minutes between refreshes
386
+ """
387
+ if self._refresh_timer:
388
+ self._refresh_timer.cancel()
389
+
390
+ def _refresh_task():
391
+ self.refresh()
392
+ self._refresh_timer = threading.Timer(interval_minutes * 60, _refresh_task)
393
+ self._refresh_timer.daemon = True
394
+ self._refresh_timer.start()
395
+
396
+ self._refresh_timer = threading.Timer(interval_minutes * 60, _refresh_task)
397
+ self._refresh_timer.daemon = True
398
+ self._refresh_timer.start()
399
+
400
+ def get_stats(self) -> Dict[str, Any]:
401
+ """Get statistics about agent usage! 📊
402
+
403
+ Returns:
404
+ Dictionary with usage statistics
405
+ """
406
+ stats_copy = self._stats.copy()
407
+ # Calculate top browser
408
+ top_browser = max(stats_copy["browser_usage"].items(), key=lambda x: x[1])[0] if stats_copy["browser_usage"] else None
409
+ stats_copy["top_browser"] = top_browser
410
+
411
+ # Calculate fake detection avoidance rate (just for fun)
412
+ stats_copy["avoidance_rate"] = min(99.9, 90 + (stats_copy["total_generated"] / 1000))
413
+
414
+ return stats_copy
415
+
416
+ def export_stats(self, filename: str) -> bool:
417
+ """Export usage statistics to a file! 💾
418
+
419
+ Args:
420
+ filename: Path to export the stats
421
+
422
+ Returns:
423
+ True if export was successful, False otherwise
424
+ """
425
+ try:
426
+ import json
427
+ with open(filename, 'w') as f:
428
+ json.dump(self.get_stats(), f, indent=2)
429
+ return True
430
+ except Exception as e:
431
+ return False
110
432
 
111
433
  if __name__ == "__main__":
112
434
  # Test it out! 🧪
@@ -116,4 +438,13 @@ if __name__ == "__main__":
116
438
  print("Firefox:", agent.firefox())
117
439
  print("Safari:", agent.safari())
118
440
  print("Mobile:", agent.mobile())
119
- print("Desktop:", agent.desktop())
441
+ print("Desktop:", agent.desktop())
442
+ print("Tablet:", agent.tablet())
443
+ print("Smart TV:", agent.smart_tv())
444
+ print("Gaming:", agent.gaming())
445
+
446
+ # Test custom agent
447
+ print("Custom:", agent.custom(browser="chrome", os="windows", os_version="10.0"))
448
+
449
+ # Test fingerprinting
450
+ print("Fingerprint:", agent.generate_fingerprint("chrome"))
@@ -6,7 +6,9 @@ BROWSERS = {
6
6
  "firefox": (48, 121),
7
7
  "safari": (605, 617),
8
8
  "edge": (79, 120),
9
- "opera": (48, 104)
9
+ "opera": (48, 104),
10
+ "brave": (100, 120),
11
+ "vivaldi": (5, 6)
10
12
  }
11
13
 
12
14
  # OS versions
@@ -15,7 +17,8 @@ OS_VERSIONS = {
15
17
  "mac": ["10_15_7", "11_0", "12_0", "13_0", "14_0"],
16
18
  "linux": ["x86_64", "i686"],
17
19
  "android": ["10", "11", "12", "13", "14"],
18
- "ios": ["14_0", "15_0", "16_0", "17_0"]
20
+ "ios": ["14_0", "15_0", "16_0", "17_0"],
21
+ "chrome_os": ["13.0", "14.0", "15.0"]
19
22
  }
20
23
 
21
24
  # Device types
@@ -25,7 +28,33 @@ DEVICES = {
25
28
  "OnePlus", "Xiaomi", "Huawei", "OPPO", "Vivo"
26
29
  ],
27
30
  "desktop": ["Windows PC", "MacBook", "iMac", "Linux Desktop"],
28
- "tablet": ["iPad", "Samsung Galaxy Tab", "Microsoft Surface"],
29
- "console": ["PlayStation 5", "Xbox Series X", "Nintendo Switch"],
30
- "tv": ["Samsung Smart TV", "LG WebOS", "Android TV", "Apple TV"]
31
+ "tablet": ["iPad", "Samsung Galaxy Tab", "Microsoft Surface", "Huawei MatePad", "Lenovo Tab"],
32
+ "console": ["PlayStation 5", "Xbox Series X", "Nintendo Switch", "PlayStation 4", "Xbox One"],
33
+ "tv": ["Samsung Smart TV", "LG WebOS", "Android TV", "Apple TV", "Sony Bravia"],
34
+ "wearable": ["Apple Watch", "Samsung Galaxy Watch", "Fitbit", "Garmin"]
35
+ }
36
+
37
+ # Browser fingerprinting components
38
+ FINGERPRINTS = {
39
+ "accept_language": [
40
+ "en-US,en;q=0.9",
41
+ "en-GB,en;q=0.8,en-US;q=0.6",
42
+ "es-ES,es;q=0.9,en;q=0.8",
43
+ "fr-FR,fr;q=0.9,en;q=0.8",
44
+ "de-DE,de;q=0.9,en;q=0.8"
45
+ ],
46
+ "accept": [
47
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
48
+ "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
49
+ "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
50
+ ],
51
+ "sec_ch_ua": {
52
+ "chrome": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"{}\", \"Google Chrome\";v=\"{}\"",
53
+ "edge": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"{}\", \"Microsoft Edge\";v=\"{}\"",
54
+ "firefox": "\"Firefox\";v=\"{}\", \"Not;A=Brand\";v=\"8\"",
55
+ "safari": "\"Safari\";v=\"{}\", \"Not;A=Brand\";v=\"99\""
56
+ },
57
+ "platforms": [
58
+ "Windows", "macOS", "Linux", "Android", "iOS"
59
+ ]
31
60
  }
@@ -5,11 +5,8 @@ import time
5
5
  import threading
6
6
  import re
7
7
  from typing import Any, Optional, TextIO, Union, Sequence, Dict, List
8
- from datetime import datetime
9
8
  import textwrap
10
- from collections import defaultdict
11
9
  import shutil
12
- import inspect
13
10
  from .colors import Colors
14
11
  import ctypes
15
12