webscout 3.8__py3-none-any.whl → 4.0__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 +5 -1
- webscout/Extra/__init__.py +3 -1
- webscout/Extra/weather.py +49 -0
- webscout/Extra/weather_ascii.py +18 -0
- webscout/Local/_version.py +1 -1
- webscout/Provider/Geminiflash.py +152 -0
- webscout/Provider/Geminipro.py +152 -0
- webscout/Provider/Youchat.py +5 -1
- webscout/Provider/__init__.py +6 -0
- webscout/YTdownloader.py +1105 -0
- webscout/__init__.py +6 -1
- webscout/cli.py +116 -221
- webscout/version.py +2 -2
- webscout/webai.py +44 -0
- {webscout-3.8.dist-info → webscout-4.0.dist-info}/METADATA +46 -332
- {webscout-3.8.dist-info → webscout-4.0.dist-info}/RECORD +20 -15
- {webscout-3.8.dist-info → webscout-4.0.dist-info}/LICENSE.md +0 -0
- {webscout-3.8.dist-info → webscout-4.0.dist-info}/WHEEL +0 -0
- {webscout-3.8.dist-info → webscout-4.0.dist-info}/entry_points.txt +0 -0
- {webscout-3.8.dist-info → webscout-4.0.dist-info}/top_level.txt +0 -0
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
|
-
|
|
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 = [
|
|
@@ -39,6 +41,9 @@ webai = [
|
|
|
39
41
|
"basedgpt",
|
|
40
42
|
"deepseek",
|
|
41
43
|
"deepinfra",
|
|
44
|
+
"vtlchat",
|
|
45
|
+
"geminiflash",
|
|
46
|
+
"geminipro",
|
|
42
47
|
]
|
|
43
48
|
|
|
44
49
|
gpt4free_providers = [
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"""
|
|
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
|
-
|
|
130
|
-
|
|
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("-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
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 =
|
|
146
|
-
chosen_model_idx =
|
|
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
|
-
|
|
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
|
|
174
|
-
@click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru
|
|
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="
|
|
178
|
-
@click.option("-
|
|
179
|
-
@click.option("-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
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
|
|
207
|
-
@click.option("-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
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="
|
|
223
|
-
@click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru
|
|
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="
|
|
261
|
-
@click.option("-
|
|
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
|
-
"""
|
|
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
|
-
|
|
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="
|
|
308
|
-
@click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru
|
|
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="
|
|
315
|
-
@click.option("-
|
|
316
|
-
|
|
317
|
-
|
|
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
|
-
|
|
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="
|
|
340
|
-
@click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru
|
|
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="
|
|
344
|
-
@click.option("-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
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="
|
|
362
|
-
@click.option("-p", "--place", default=None, help="
|
|
363
|
-
@click.option("-s", "--street", default=None, help="
|
|
364
|
-
@click.option("-c", "--city", default=None, help="
|
|
365
|
-
@click.option("-county", "--county", default=None, help="
|
|
366
|
-
@click.option("-state", "--state", default=None, help="
|
|
367
|
-
@click.option("-country", "--country", default=None, help="
|
|
368
|
-
@click.option("-post", "--postalcode", default=None, help="
|
|
369
|
-
@click.option("-lat", "--latitude", default=None, help="
|
|
370
|
-
@click.option("-lon", "--longitude", default=None, help="
|
|
371
|
-
@click.option("-r", "--radius", default=0, help="
|
|
372
|
-
@click.option("-m", "--max_results", default=50, help="
|
|
373
|
-
@click.option("-
|
|
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
|
-
"""
|
|
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
|
-
|
|
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="
|
|
417
|
-
@click.option("-f", "--from_", help="
|
|
418
|
-
@click.option("-t", "--to", default="en", help="
|
|
419
|
-
@click.option("-
|
|
420
|
-
|
|
421
|
-
|
|
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
|
-
|
|
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="
|
|
435
|
-
@click.option("-r", "--region", default="wt-wt", help="wt-wt, us-en, ru-ru
|
|
436
|
-
@click.option("-
|
|
437
|
-
|
|
438
|
-
|
|
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
|
-
|
|
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__ = "
|
|
2
|
-
|
|
1
|
+
__version__ = "4.0"
|
|
2
|
+
__prog__ = "webscout"
|
webscout/webai.py
CHANGED
|
@@ -689,7 +689,51 @@ class Main(cmd.Cmd):
|
|
|
689
689
|
history_offset=history_offset,
|
|
690
690
|
act=awesome_prompt,
|
|
691
691
|
)
|
|
692
|
+
elif provider == "geminiflash":
|
|
693
|
+
from webscout import GEMINIFLASH
|
|
692
694
|
|
|
695
|
+
self.bot = GEMINIFLASH(
|
|
696
|
+
is_conversation=disable_conversation,
|
|
697
|
+
max_tokens=max_tokens,
|
|
698
|
+
timeout=timeout,
|
|
699
|
+
intro=intro,
|
|
700
|
+
filepath=filepath,
|
|
701
|
+
update_file=update_file,
|
|
702
|
+
proxies=proxies,
|
|
703
|
+
history_offset=history_offset,
|
|
704
|
+
act=awesome_prompt,
|
|
705
|
+
)
|
|
706
|
+
elif provider == "geminipro":
|
|
707
|
+
from webscout import GEMINIPRO
|
|
708
|
+
|
|
709
|
+
self.bot = GEMINIPRO(
|
|
710
|
+
is_conversation=disable_conversation,
|
|
711
|
+
max_tokens=max_tokens,
|
|
712
|
+
timeout=timeout,
|
|
713
|
+
intro=intro,
|
|
714
|
+
filepath=filepath,
|
|
715
|
+
update_file=update_file,
|
|
716
|
+
proxies=proxies,
|
|
717
|
+
history_offset=history_offset,
|
|
718
|
+
act=awesome_prompt,
|
|
719
|
+
)
|
|
720
|
+
|
|
721
|
+
elif provider == "vtlchat":
|
|
722
|
+
from webscout import VTLchat
|
|
723
|
+
|
|
724
|
+
self.bot = VTLchat(
|
|
725
|
+
is_conversation=disable_conversation,
|
|
726
|
+
max_tokens=max_tokens,
|
|
727
|
+
temperature=temperature,
|
|
728
|
+
top_p=top_p,
|
|
729
|
+
timeout=timeout,
|
|
730
|
+
intro=intro,
|
|
731
|
+
filepath=filepath,
|
|
732
|
+
update_file=update_file,
|
|
733
|
+
proxies=proxies,
|
|
734
|
+
history_offset=history_offset,
|
|
735
|
+
act=awesome_prompt,
|
|
736
|
+
)
|
|
693
737
|
elif provider == "gemini":
|
|
694
738
|
from webscout import GEMINI
|
|
695
739
|
|