webscout 3.9__py3-none-any.whl → 4.1__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/__init__.py CHANGED
@@ -7,12 +7,14 @@ from .voice import play_audio
7
7
  from .websx_search import WEBSX
8
8
 
9
9
  from .LLM import LLM
10
+ from .YTdownloader import *
10
11
  # from .Local import *
11
12
  import g4f
12
- # Import provider classes for direct access
13
+ from .YTdownloader import *
13
14
  from .Provider import *
14
15
  from .Extra import gguf
15
16
  from .Extra import autollama
17
+ from .Extra import weather_ascii, weather
16
18
  __repo__ = "https://github.com/OE-LUCIFER/Webscout"
17
19
 
18
20
  webai = [
webscout/cli.py CHANGED
@@ -12,6 +12,17 @@ from .webscout_search import WEBS
12
12
  from .utils import json_dumps, json_loads
13
13
  from .version import __version__
14
14
 
15
+ # Import rich for panel interface
16
+ from rich.panel import Panel
17
+ from rich.markdown import Markdown
18
+ from rich.console import Console
19
+ from rich.table import Table
20
+ from rich.style import Style
21
+ from rich.text import Text
22
+ from rich.align import Align
23
+ from rich.progress import track
24
+ from rich.prompt import Prompt, Confirm
25
+
15
26
  logger = logging.getLogger(__name__)
16
27
 
17
28
  COLORS = {
@@ -33,25 +44,16 @@ COLORS = {
33
44
  15: "bright_white",
34
45
  }
35
46
 
36
-
37
- def _save_json(jsonfile, data):
38
- with open(jsonfile, "w", encoding="utf-8") as file:
39
- file.write(json_dumps(data))
40
-
41
-
42
- def _save_csv(csvfile, data):
43
- with open(csvfile, "w", newline="", encoding="utf-8") as file:
44
- if data:
45
- headers = data[0].keys()
46
- writer = csv.DictWriter(file, fieldnames=headers, quoting=csv.QUOTE_MINIMAL)
47
- writer.writeheader()
48
- writer.writerows(data)
49
-
50
-
51
47
  def _print_data(data):
48
+ """Prints data using rich panels and markdown, asynchronously."""
49
+ console = Console()
52
50
  if data:
53
51
  for i, e in enumerate(data, start=1):
54
- click.secho(f"{i}.\t {'=' * 78}", bg="black", fg="white")
52
+ # Create a table for each result
53
+ table = Table(title=f"{i}.", show_lines=True)
54
+ table.add_column("Key", style="cyan", no_wrap=True)
55
+ table.add_column("Value", style="white")
56
+
55
57
  for j, (k, v) in enumerate(e.items(), start=1):
56
58
  if v:
57
59
  width = 300 if k in ("content", "href", "image", "source", "thumbnail", "url") else 78
@@ -61,14 +63,17 @@ def _print_data(data):
61
63
  )
62
64
  else:
63
65
  text = v
64
- click.secho(f"{k:<12}{text}", bg="black", fg=COLORS[j], overline=True)
65
- input()
66
+ table.add_row(k, text)
66
67
 
68
+ # Wrap the table in a panel with a title
69
+ console.print(Panel(Align(table, align="left"), title=f"Result {i}", expand=False))
70
+ console.print("\n")
67
71
 
68
72
  def _sanitize_keywords(keywords):
73
+ """Sanitizes keywords for file names and paths. Removes invalid characters like ':'. """
69
74
  keywords = (
70
75
  keywords.replace("filetype", "")
71
- .replace(":", "")
76
+ .replace(":", "") # Remove colons
72
77
  .replace('"', "'")
73
78
  .replace("site", "")
74
79
  .replace(" ", "_")
@@ -78,42 +83,9 @@ def _sanitize_keywords(keywords):
78
83
  )
79
84
  return keywords
80
85
 
81
-
82
- def _download_file(url, dir_path, filename, proxy):
83
- try:
84
- resp = pri.Client(proxy=proxy, impersonate="chrome_124", timeout=10, verify=False).get(url)
85
- if resp.status_code == 200:
86
- with open(os.path.join(dir_path, filename[:200]), "wb") as file:
87
- file.write(resp.content)
88
- except Exception as ex:
89
- logger.debug(f"download_file url={url} {type(ex).__name__} {ex}")
90
-
91
-
92
- def _download_results(keywords, results, images=False, proxy=None, threads=None):
93
- path_type = "images" if images else "text"
94
- path = f"{path_type}_{keywords}_{datetime.now():%Y%m%d_%H%M%S}"
95
- os.makedirs(path, exist_ok=True)
96
-
97
- threads = 10 if threads is None else threads
98
- with ThreadPoolExecutor(max_workers=threads) as executor:
99
- futures = []
100
- for i, res in enumerate(results, start=1):
101
- url = res["image"] if images else res["href"]
102
- filename = unquote(url.split("/")[-1].split("?")[0])
103
- f = executor.submit(_download_file, url, path, f"{i}_{filename}", proxy)
104
- futures.append(f)
105
-
106
- with click.progressbar(
107
- length=len(futures), label="Downloading", show_percent=True, show_pos=True, width=50
108
- ) as bar:
109
- for future in as_completed(futures):
110
- future.result()
111
- bar.update(1)
112
-
113
-
114
86
  @click.group(chain=True)
115
87
  def cli():
116
- """dukduckgo_search CLI tool"""
88
+ """webscout CLI tool - Search the web with a rich UI."""
117
89
  pass
118
90
 
119
91
 
@@ -126,32 +98,26 @@ def safe_entry_point():
126
98
 
127
99
  @cli.command()
128
100
  def version():
129
- print(__version__)
130
- return __version__
101
+ """Shows the current version of webscout."""
102
+ console = Console()
103
+ console.print(Panel(Text(f"webscout v{__version__}", style="cyan"), title="Version"))
131
104
 
132
105
 
133
106
  @cli.command()
134
- @click.option("-s", "--save", is_flag=True, default=False, help="save the conversation in the json file")
135
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
136
- def chat(save, proxy):
137
- """CLI function to perform an interactive AI chat using DuckDuckGo API."""
138
- cache_file = "WEBS_chat_conversation.json"
107
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
108
+ def chat(proxy):
109
+ """Interactive AI chat using DuckDuckGo's AI."""
139
110
  models = ["gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b"]
140
111
  client = WEBS(proxy=proxy)
141
112
 
142
- print("DuckDuckGo AI chat. Available models:")
113
+ console = Console()
114
+ console.print(Panel(Text("Available AI Models:", style="cyan"), title="DuckDuckGo AI Chat"))
143
115
  for idx, model in enumerate(models, start=1):
144
- print(f"{idx}. {model}")
145
- chosen_model_idx = input("Choose a model by entering its number[1]: ")
146
- chosen_model_idx = 0 if not chosen_model_idx.strip() else int(chosen_model_idx) - 1
116
+ console.print(f"{idx}. {model}")
117
+ chosen_model_idx = Prompt.ask("Choose a model by entering its number [1]", choices=[str(i) for i in range(1, len(models) + 1)], default="1")
118
+ chosen_model_idx = int(chosen_model_idx) - 1
147
119
  model = models[chosen_model_idx]
148
- print(f"Using model: {model}")
149
-
150
- if save and Path(cache_file).exists():
151
- with open(cache_file) as f:
152
- cache = json_loads(f.read())
153
- client._chat_vqd = cache.get("vqd", None)
154
- client._chat_messages = cache.get("messages", [])
120
+ console.print(f"Using model: {model}")
155
121
 
156
122
  while True:
157
123
  user_input = input(f"{'-'*78}\nYou: ")
@@ -160,28 +126,23 @@ def chat(save, proxy):
160
126
 
161
127
  resp_answer = client.chat(keywords=user_input, model=model)
162
128
  text = click.wrap_text(resp_answer, width=78, preserve_paragraphs=True)
163
- click.secho(f"AI: {text}", bg="black", fg="green", overline=True)
164
-
165
- cache = {"vqd": client._chat_vqd, "messages": client._chat_messages}
166
- _save_json(cache_file, cache)
129
+ console.print(Panel(Text(f"AI: {text}", style="green"), title="AI Response"))
167
130
 
168
131
  if "exit" in user_input.lower() or "quit" in user_input.lower():
132
+ console.print(Panel(Text("Exiting chat session.", style="cyan"), title="Goodbye"))
169
133
  break
170
134
 
171
135
 
172
136
  @cli.command()
173
- @click.option("-k", "--keywords", required=True, help="text search, keywords for query")
174
- @click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru, etc. -region https://duckduckgo.com/params")
175
- @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]))
176
- @click.option("-t", "--timelimit", default=None, type=click.Choice(["d", "w", "m", "y"]), help="day, week, month, year")
177
- @click.option("-m", "--max_results", default=20, help="maximum number of results, default=20")
178
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
179
- @click.option("-d", "--download", is_flag=True, default=False, help="download results to 'keywords' folder")
180
- @click.option("-b", "--backend", default="api", type=click.Choice(["api", "html", "lite"]), help="which backend to use")
181
- @click.option("-th", "--threads", default=10, help="download threads, default=10")
182
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
183
- def text(keywords, region, safesearch, timelimit, backend, output, download, threads, max_results, proxy):
184
- """CLI function to perform a text search using DuckDuckGo API."""
137
+ @click.option("-k", "--keywords", required=True, help="Keywords for text search.")
138
+ @click.option("-r", "--region", default="wt-wt", help="Region (e.g., wt-wt, us-en, ru-ru) - See https://duckduckgo.com/params for more options.")
139
+ @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]), help="Safe search level.")
140
+ @click.option("-t", "--timelimit", default=None, type=click.Choice(["d", "w", "m", "y"]), help="Time limit (d: day, w: week, m: month, y: year).")
141
+ @click.option("-m", "--max_results", default=20, help="Maximum number of results to retrieve (default: 20).")
142
+ @click.option("-b", "--backend", default="api", type=click.Choice(["api", "html", "lite"]), help="Backend to use (api, html, lite).")
143
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
144
+ def text(keywords, region, safesearch, timelimit, backend, max_results, proxy):
145
+ """Performs a text search using DuckDuckGo API with a rich UI."""
185
146
  data = WEBS(proxy=proxy).text(
186
147
  keywords=keywords,
187
148
  region=region,
@@ -190,40 +151,23 @@ def text(keywords, region, safesearch, timelimit, backend, output, download, thr
190
151
  backend=backend,
191
152
  max_results=max_results,
192
153
  )
193
- keywords = _sanitize_keywords(keywords)
194
- filename = f"text_{keywords}_{datetime.now():%Y%m%d_%H%M%S}"
195
- if output == "print" and not download:
196
- _print_data(data)
197
- elif output == "csv":
198
- _save_csv(f"{filename}.csv", data)
199
- elif output == "json":
200
- _save_json(f"{filename}.json", data)
201
- if download:
202
- _download_results(keywords, data, proxy=proxy, threads=threads)
203
-
154
+ _print_data(data)
204
155
 
205
156
  @cli.command()
206
- @click.option("-k", "--keywords", required=True, help="answers search, keywords for query")
207
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
208
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
209
- def answers(keywords, output, proxy):
210
- """CLI function to perform a answers search using DuckDuckGo API."""
157
+ @click.option("-k", "--keywords", required=True, help="Keywords for answers search.")
158
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
159
+ def answers(keywords, proxy):
160
+ """Performs an answers search using DuckDuckGo API with a rich UI."""
211
161
  data = WEBS(proxy=proxy).answers(keywords=keywords)
212
- filename = f"answers_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
213
- if output == "print":
214
- _print_data(data)
215
- elif output == "csv":
216
- _save_csv(f"{filename}.csv", data)
217
- elif output == "json":
218
- _save_json(f"{filename}.json", data)
162
+ _print_data(data)
219
163
 
220
164
 
221
165
  @cli.command()
222
- @click.option("-k", "--keywords", required=True, help="keywords for query")
223
- @click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru, etc. -region https://duckduckgo.com/params")
224
- @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]))
225
- @click.option("-t", "--timelimit", default=None, type=click.Choice(["Day", "Week", "Month", "Year"]))
226
- @click.option("-size", "--size", default=None, type=click.Choice(["Small", "Medium", "Large", "Wallpaper"]))
166
+ @click.option("-k", "--keywords", required=True, help="Keywords for images search.")
167
+ @click.option("-r", "--region", default="wt-wt", help="Region (e.g., wt-wt, us-en, ru-ru) - See https://duckduckgo.com/params for more options.")
168
+ @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]), help="Safe search level.")
169
+ @click.option("-t", "--timelimit", default=None, type=click.Choice(["Day", "Week", "Month", "Year"]), help="Time limit (Day, Week, Month, Year).")
170
+ @click.option("-size", "--size", default=None, type=click.Choice(["Small", "Medium", "Large", "Wallpaper"]), help="Image size (Small, Medium, Large, Wallpaper).")
227
171
  @click.option(
228
172
  "-c",
229
173
  "--color",
@@ -246,22 +190,21 @@ def answers(keywords, output, proxy):
246
190
  "White",
247
191
  ]
248
192
  ),
193
+ help="Image color (color, Monochrome, Red, Orange, Yellow, Green, Blue, Purple, Pink, Brown, Black, Gray, Teal, White).",
249
194
  )
250
195
  @click.option(
251
- "-type", "--type_image", default=None, type=click.Choice(["photo", "clipart", "gif", "transparent", "line"])
196
+ "-type", "--type_image", default=None, type=click.Choice(["photo", "clipart", "gif", "transparent", "line"]), help="Image type (photo, clipart, gif, transparent, line)."
252
197
  )
253
- @click.option("-l", "--layout", default=None, type=click.Choice(["Square", "Tall", "Wide"]))
198
+ @click.option("-l", "--layout", default=None, type=click.Choice(["Square", "Tall", "Wide"]), help="Image layout (Square, Tall, Wide).")
254
199
  @click.option(
255
200
  "-lic",
256
201
  "--license_image",
257
202
  default=None,
258
203
  type=click.Choice(["any", "Public", "Share", "Modify", "ModifyCommercially"]),
204
+ help="Image license (any, Public, Share, Modify, ModifyCommercially).",
259
205
  )
260
- @click.option("-m", "--max_results", default=90, help="maximum number of results, default=90")
261
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
262
- @click.option("-d", "--download", is_flag=True, default=False, help="download and save images to 'keywords' folder")
263
- @click.option("-th", "--threads", default=10, help="download threads, default=10")
264
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
206
+ @click.option("-m", "--max_results", default=90, help="Maximum number of results to retrieve (default: 90).")
207
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
265
208
  def images(
266
209
  keywords,
267
210
  region,
@@ -272,13 +215,10 @@ def images(
272
215
  type_image,
273
216
  layout,
274
217
  license_image,
275
- download,
276
- threads,
277
218
  max_results,
278
- output,
279
219
  proxy,
280
220
  ):
281
- """CLI function to perform a images search using DuckDuckGo API."""
221
+ """Performs an images search using DuckDuckGo API with a rich UI."""
282
222
  data = WEBS(proxy=proxy).images(
283
223
  keywords=keywords,
284
224
  region=region,
@@ -291,31 +231,21 @@ def images(
291
231
  license_image=license_image,
292
232
  max_results=max_results,
293
233
  )
294
- keywords = _sanitize_keywords(keywords)
295
- filename = f"images_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
296
- if output == "print" and not download:
297
- _print_data(data)
298
- elif output == "csv":
299
- _save_csv(f"{filename}.csv", data)
300
- elif output == "json":
301
- _save_json(f"{filename}.json", data)
302
- if download:
303
- _download_results(keywords, data, images=True, proxy=proxy, threads=threads)
234
+ _print_data(data)
304
235
 
305
236
 
306
237
  @cli.command()
307
- @click.option("-k", "--keywords", required=True, help="keywords for query")
308
- @click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru, etc. -region https://duckduckgo.com/params")
309
- @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]))
310
- @click.option("-t", "--timelimit", default=None, type=click.Choice(["d", "w", "m"]), help="day, week, month")
311
- @click.option("-res", "--resolution", default=None, type=click.Choice(["high", "standart"]))
312
- @click.option("-d", "--duration", default=None, type=click.Choice(["short", "medium", "long"]))
313
- @click.option("-lic", "--license_videos", default=None, type=click.Choice(["creativeCommon", "youtube"]))
314
- @click.option("-m", "--max_results", default=50, help="maximum number of results, default=50")
315
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
316
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
317
- def videos(keywords, region, safesearch, timelimit, resolution, duration, license_videos, max_results, output, proxy):
318
- """CLI function to perform a videos search using DuckDuckGo API."""
238
+ @click.option("-k", "--keywords", required=True, help="Keywords for videos search.")
239
+ @click.option("-r", "--region", default="wt-wt", help="Region (e.g., wt-wt, us-en, ru-ru) - See https://duckduckgo.com/params for more options.")
240
+ @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]), help="Safe search level.")
241
+ @click.option("-t", "--timelimit", default=None, type=click.Choice(["d", "w", "m"]), help="Time limit (d: day, w: week, m: month).")
242
+ @click.option("-res", "--resolution", default=None, type=click.Choice(["high", "standart"]), help="Video resolution (high, standart).")
243
+ @click.option("-d", "--duration", default=None, type=click.Choice(["short", "medium", "long"]), help="Video duration (short, medium, long).")
244
+ @click.option("-lic", "--license_videos", default=None, type=click.Choice(["creativeCommon", "youtube"]), help="Video license (creativeCommon, youtube).")
245
+ @click.option("-m", "--max_results", default=50, help="Maximum number of results to retrieve (default: 50).")
246
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
247
+ def videos(keywords, region, safesearch, timelimit, resolution, duration, license_videos, max_results, proxy):
248
+ """Performs a videos search using DuckDuckGo API with a rich UI."""
319
249
  data = WEBS(proxy=proxy).videos(
320
250
  keywords=keywords,
321
251
  region=region,
@@ -326,52 +256,38 @@ def videos(keywords, region, safesearch, timelimit, resolution, duration, licens
326
256
  license_videos=license_videos,
327
257
  max_results=max_results,
328
258
  )
329
- filename = f"videos_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
330
- if output == "print":
331
- _print_data(data)
332
- elif output == "csv":
333
- _save_csv(f"{filename}.csv", data)
334
- elif output == "json":
335
- _save_json(f"{filename}.json", data)
259
+ _print_data(data)
336
260
 
337
261
 
338
262
  @cli.command()
339
- @click.option("-k", "--keywords", required=True, help="keywords for query")
340
- @click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru, etc. -region https://duckduckgo.com/params")
341
- @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]))
342
- @click.option("-t", "--timelimit", default=None, type=click.Choice(["d", "w", "m", "y"]), help="day, week, month, year")
343
- @click.option("-m", "--max_results", default=25, help="maximum number of results, default=25")
344
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
345
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
346
- def news(keywords, region, safesearch, timelimit, max_results, output, proxy):
347
- """CLI function to perform a news search using DuckDuckGo API."""
263
+ @click.option("-k", "--keywords", required=True, help="Keywords for news search.")
264
+ @click.option("-r", "--region", default="wt-wt", help="Region (e.g., wt-wt, us-en, ru-ru) - See https://duckduckgo.com/params for more options.")
265
+ @click.option("-s", "--safesearch", default="moderate", type=click.Choice(["on", "moderate", "off"]), help="Safe search level.")
266
+ @click.option("-t", "--timelimit", default=None, type=click.Choice(["d", "w", "m", "y"]), help="Time limit (d: day, w: week, m: month, y: year).")
267
+ @click.option("-m", "--max_results", default=25, help="Maximum number of results to retrieve (default: 25).")
268
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
269
+ def news(keywords, region, safesearch, timelimit, max_results, proxy):
270
+ """Performs a news search using DuckDuckGo API with a rich UI."""
348
271
  data = WEBS(proxy=proxy).news(
349
272
  keywords=keywords, region=region, safesearch=safesearch, timelimit=timelimit, max_results=max_results
350
273
  )
351
- filename = f"news_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
352
- if output == "print":
353
- _print_data(data)
354
- elif output == "csv":
355
- _save_csv(f"{filename}.csv", data)
356
- elif output == "json":
357
- _save_json(f"{filename}.json", data)
274
+ _print_data(data)
358
275
 
359
276
 
360
277
  @cli.command()
361
- @click.option("-k", "--keywords", required=True, help="keywords for query")
362
- @click.option("-p", "--place", default=None, help="simplified search - if set, the other parameters are not used")
363
- @click.option("-s", "--street", default=None, help="house number/street")
364
- @click.option("-c", "--city", default=None, help="city of search")
365
- @click.option("-county", "--county", default=None, help="county of search")
366
- @click.option("-state", "--state", default=None, help="state of search")
367
- @click.option("-country", "--country", default=None, help="country of search")
368
- @click.option("-post", "--postalcode", default=None, help="postalcode of search")
369
- @click.option("-lat", "--latitude", default=None, help="""if lat and long are set, the other params are not used""")
370
- @click.option("-lon", "--longitude", default=None, help="""if lat and long are set, the other params are not used""")
371
- @click.option("-r", "--radius", default=0, help="expand the search square by the distance in kilometers")
372
- @click.option("-m", "--max_results", default=50, help="number of results, default=50")
373
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
374
- @click.option("-proxy", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
278
+ @click.option("-k", "--keywords", required=True, help="Keywords for maps search.")
279
+ @click.option("-p", "--place", default=None, help="Simplified search - if set, the other parameters are not used.")
280
+ @click.option("-s", "--street", default=None, help="House number/street.")
281
+ @click.option("-c", "--city", default=None, help="City of search.")
282
+ @click.option("-county", "--county", default=None, help="County of search.")
283
+ @click.option("-state", "--state", default=None, help="State of search.")
284
+ @click.option("-country", "--country", default=None, help="Country of search.")
285
+ @click.option("-post", "--postalcode", default=None, help="Postal code of search.")
286
+ @click.option("-lat", "--latitude", default=None, help="Geographic coordinate (north-south position).")
287
+ @click.option("-lon", "--longitude", default=None, help="Geographic coordinate (east-west position); if latitude and longitude are set, the other parameters are not used.")
288
+ @click.option("-r", "--radius", default=0, help="Expand the search square by the distance in kilometers.")
289
+ @click.option("-m", "--max_results", default=50, help="Number of results (default: 50).")
290
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
375
291
  def maps(
376
292
  keywords,
377
293
  place,
@@ -385,10 +301,9 @@ def maps(
385
301
  longitude,
386
302
  radius,
387
303
  max_results,
388
- output,
389
304
  proxy,
390
305
  ):
391
- """CLI function to perform a maps search using DuckDuckGo API."""
306
+ """Performs a maps search using DuckDuckGo API with a rich UI."""
392
307
  data = WEBS(proxy=proxy).maps(
393
308
  keywords=keywords,
394
309
  place=place,
@@ -403,48 +318,28 @@ def maps(
403
318
  radius=radius,
404
319
  max_results=max_results,
405
320
  )
406
- filename = f"maps_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
407
- if output == "print":
408
- _print_data(data)
409
- elif output == "csv":
410
- _save_csv(f"{filename}.csv", data)
411
- elif output == "json":
412
- _save_json(f"{filename}.json", data)
321
+ _print_data(data)
413
322
 
414
323
 
415
324
  @cli.command()
416
- @click.option("-k", "--keywords", required=True, help="text for translation")
417
- @click.option("-f", "--from_", help="What language to translate from (defaults automatically)")
418
- @click.option("-t", "--to", default="en", help="de, ru, fr, etc. What language to translate, defaults='en'")
419
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
420
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
421
- def translate(keywords, from_, to, output, proxy):
422
- """CLI function to perform translate using DuckDuckGo API."""
325
+ @click.option("-k", "--keywords", required=True, help="Text for translation.")
326
+ @click.option("-f", "--from_", help="Language to translate from (defaults automatically).")
327
+ @click.option("-t", "--to", default="en", help="Language to translate to (default: 'en').")
328
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
329
+ def translate(keywords, from_, to, proxy):
330
+ """Performs translation using DuckDuckGo API with a rich UI."""
423
331
  data = WEBS(proxy=proxy).translate(keywords=keywords, from_=from_, to=to)
424
- filename = f"translate_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
425
- if output == "print":
426
- _print_data(data)
427
- elif output == "csv":
428
- _save_csv(f"{filename}.csv", data)
429
- elif output == "json":
430
- _save_json(f"{filename}.json", data)
332
+ _print_data(data)
431
333
 
432
334
 
433
335
  @cli.command()
434
- @click.option("-k", "--keywords", required=True, help="keywords for query")
435
- @click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru, etc. -region https://duckduckgo.com/params")
436
- @click.option("-o", "--output", default="print", help="csv, json (save the results to a csv or json file)")
437
- @click.option("-p", "--proxy", default=None, help="the proxy to send requests, example: socks5://localhost:9150")
438
- def suggestions(keywords, region, output, proxy):
439
- """CLI function to perform a suggestions search using DuckDuckGo API."""
336
+ @click.option("-k", "--keywords", required=True, help="Keywords for query.")
337
+ @click.option("-r", "--region", default="wt-wt", help="Region (e.g., wt-wt, us-en, ru-ru) - See https://duckduckgo.com/params for more options.")
338
+ @click.option("-p", "--proxy", default=None, help="Proxy to send requests (e.g., socks5://localhost:9150)")
339
+ def suggestions(keywords, region, proxy):
340
+ """Performs a suggestions search using DuckDuckGo API with a rich UI."""
440
341
  data = WEBS(proxy=proxy).suggestions(keywords=keywords, region=region)
441
- filename = f"suggestions_{_sanitize_keywords(keywords)}_{datetime.now():%Y%m%d_%H%M%S}"
442
- if output == "print":
443
- _print_data(data)
444
- elif output == "csv":
445
- _save_csv(f"{filename}.csv", data)
446
- elif output == "json":
447
- _save_json(f"{filename}.json", data)
342
+ _print_data(data)
448
343
 
449
344
 
450
345
  if __name__ == "__main__":
webscout/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "3.9"
2
-
1
+ __version__ = "4.1"
2
+ __prog__ = "webscout"
webscout/webai.py CHANGED
@@ -695,8 +695,6 @@ class Main(cmd.Cmd):
695
695
  self.bot = GEMINIFLASH(
696
696
  is_conversation=disable_conversation,
697
697
  max_tokens=max_tokens,
698
- temperature=temperature,
699
- top_p=top_p,
700
698
  timeout=timeout,
701
699
  intro=intro,
702
700
  filepath=filepath,
@@ -711,8 +709,6 @@ class Main(cmd.Cmd):
711
709
  self.bot = GEMINIPRO(
712
710
  is_conversation=disable_conversation,
713
711
  max_tokens=max_tokens,
714
- temperature=temperature,
715
- top_p=top_p,
716
712
  timeout=timeout,
717
713
  intro=intro,
718
714
  filepath=filepath,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: webscout
3
- Version: 3.9
3
+ Version: 4.1
4
4
  Summary: Search for anything using Google, DuckDuckGo, brave, qwant, phind.com, Contains AI models, can transcribe yt videos, temporary email and phone number generation, has TTS support, webai (terminal gpt and open interpreter) and offline LLMs and more
5
5
  Author: OEvortex
6
6
  Author-email: helpingai5@gmail.com
@@ -92,7 +92,7 @@ Requires-Dist: huggingface-hub[cli] ; extra == 'local'
92
92
  <a href="#"><img alt="Python version" src="https://img.shields.io/pypi/pyversions/webscout"/></a>
93
93
  <a href="https://pepy.tech/project/webscout"><img alt="Downloads" src="https://static.pepy.tech/badge/webscout"></a>
94
94
 
95
- Search for anything using Google, DuckDuckGo, phind.com, Contains AI models, can transcribe yt videos, temporary email and phone number generation, has TTS support, webai (terminal gpt and open interpreter) and offline LLMs
95
+ Search for anything using Google, DuckDuckGo, phind.com, Contains AI models, can transcribe yt videos, temporary email and phone number generation, has TTS support, webai (terminal gpt and open interpreter) and offline LLMs and more
96
96
 
97
97
 
98
98
  ## Table of Contents
@@ -249,10 +249,49 @@ python -m webscout --help
249
249
  ve-es for Venezuela
250
250
  vn-vi for Vietnam
251
251
  wt-wt for No region
252
- ___
252
+
253
+
253
254
  </details>
254
255
 
256
+
255
257
  [Go To TOP](#TOP)
258
+ ## YTdownloader -webscout can now download yt videos
259
+
260
+ ```python
261
+ from os import rename, getcwd
262
+ from webscout import YTdownloader
263
+ def download_audio(video_id):
264
+ youtube_link = video_id
265
+ handler = YTdownloader.Handler(query=youtube_link)
266
+ for third_query_data in handler.run(format='mp3', quality='128kbps', limit=1):
267
+ audio_path = handler.save(third_query_data, dir=getcwd())
268
+ rename(audio_path, "audio.mp3")
269
+
270
+ def download_video(video_id):
271
+ youtube_link = video_id
272
+ handler = YTdownloader.Handler(query=youtube_link)
273
+ for third_query_data in handler.run(format='mp4', quality='auto', limit=1):
274
+ video_path = handler.save(third_query_data, dir=getcwd())
275
+ rename(video_path, "video.mp4")
276
+
277
+ if __name__ == "__main__":
278
+ # download_audio("https://www.youtube.com/watch?v=c0tMvzB0OKw")
279
+ download_video("https://www.youtube.com/watch?v=c0tMvzB0OKw")
280
+ ```
281
+
282
+ ## Weather - webscout can now forcast weather
283
+ 1. weather
284
+ ```python
285
+ from webscout import weather as w
286
+ weather = w.get("Qazigund")
287
+ w.print_weather(weather)
288
+ ```
289
+ 2. weather ascii
290
+ ```python
291
+ from webscout import weather_ascii as w
292
+ weather = w.get("Qazigund")
293
+ print(weather)
294
+ ```
256
295
 
257
296
  ## Tempmail and Temp number
258
297