2025-02-25 23:09:16 -05:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
''' searx.py - SearX from the command line '''
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
import requests
|
|
|
|
|
|
|
|
|
|
# Constants
|
|
|
|
|
|
|
|
|
|
URL = 'https://searx.ndlug.org/search'
|
|
|
|
|
LIMIT = 5
|
|
|
|
|
ORDERBY = 'score'
|
|
|
|
|
|
|
|
|
|
# Functions
|
|
|
|
|
|
|
|
|
|
def usage(exit_status: int=0) -> None:
|
|
|
|
|
''' Print usage message and exit. '''
|
|
|
|
|
print(f'''Usage: searx.py [-u URL -n LIMIT -o ORDERBY] QUERY
|
|
|
|
|
|
|
|
|
|
Fetch SearX results for QUERY and print them out.
|
|
|
|
|
|
|
|
|
|
-u URL Use URL as the SearX instance (default is: {URL})
|
|
|
|
|
-n LIMIT Only display up to LIMIT results (default is: {LIMIT})
|
|
|
|
|
-o ORDERBY Sort the search results by ORDERBY (default is: {ORDERBY})
|
|
|
|
|
|
|
|
|
|
If ORDERBY is score, the results are shown in descending order. Otherwise,
|
|
|
|
|
results are shown in ascending order.''', file=sys.stderr)
|
|
|
|
|
sys.exit(exit_status)
|
|
|
|
|
|
|
|
|
|
def searx_query(query: str, url: str=URL) -> list[dict]:
|
|
|
|
|
''' Returns lists of results for query from SearX.
|
|
|
|
|
|
|
|
|
|
>>> searx_query('Python', 'https://yld.me/iB1T') # doctest: +ELLIPSIS
|
|
|
|
|
[{'url': 'https://www.python.org/', 'title': 'Welcome to Python.org', ...}]
|
|
|
|
|
'''
|
2025-03-01 16:37:35 -05:00
|
|
|
|
|
|
|
|
parameters = {'q': query, 'format': 'json'}
|
|
|
|
|
response = requests.get(url, params=parameters)
|
|
|
|
|
return response.json()['results']
|
2025-02-25 23:09:16 -05:00
|
|
|
|
|
|
|
|
def print_results(results: list[dict], limit: int=LIMIT, orderby: str=ORDERBY) -> None:
|
|
|
|
|
''' Print results of SearX query.
|
|
|
|
|
|
|
|
|
|
>>> print_results(searx_query('Python', 'https://yld.me/iB1T')) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
|
|
|
|
1. Welcome to Python.org [...]
|
|
|
|
|
https://www.python.org/
|
|
|
|
|
...
|
|
|
|
|
'''
|
2025-03-01 16:37:35 -05:00
|
|
|
|
|
|
|
|
sorted_results = sorted(results, key=lambda x: x[orderby], reverse=(orderby=='score'))
|
|
|
|
|
|
|
|
|
|
for index, result in enumerate(sorted_results[:limit], 1):
|
|
|
|
|
print(f"{index:>4}.\t{result['title']} [{result['score']:0.2f}]")
|
|
|
|
|
print(f"\t{result['url']}")
|
|
|
|
|
if index < len(sorted_results[:limit]): # only prints new line between items
|
|
|
|
|
print()
|
2025-02-25 23:09:16 -05:00
|
|
|
|
|
|
|
|
# Main Execution
|
|
|
|
|
|
|
|
|
|
def main(arguments=sys.argv[1:]) -> None:
|
|
|
|
|
''' Searches SearX and print results.
|
|
|
|
|
|
|
|
|
|
>>> main('-u https://yld.me/iB1T Python'.split()) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
|
|
|
|
1. Welcome to Python.org [...]
|
|
|
|
|
https://www.python.org/
|
|
|
|
|
...
|
|
|
|
|
'''
|
2025-03-01 16:37:35 -05:00
|
|
|
|
|
|
|
|
# Set variables equal to the constants (initially)
|
|
|
|
|
url = URL
|
|
|
|
|
limit = LIMIT
|
|
|
|
|
orderby = ORDERBY
|
|
|
|
|
|
|
|
|
|
search_terms = []
|
|
|
|
|
|
|
|
|
|
i = 0
|
|
|
|
|
while i < len(arguments):
|
|
|
|
|
arg = arguments[i]
|
|
|
|
|
|
|
|
|
|
if arg == '-u':
|
|
|
|
|
url = arguments[i+1]
|
|
|
|
|
i += 2
|
|
|
|
|
elif arg == '-n':
|
|
|
|
|
limit = int(arguments[i+1]) # convert the argument to int before setting limit
|
|
|
|
|
i += 2
|
|
|
|
|
elif arg == '-o':
|
|
|
|
|
orderby = arguments[i+1]
|
|
|
|
|
i += 2
|
|
|
|
|
elif arg == '-h':
|
|
|
|
|
usage(0)
|
|
|
|
|
elif arg.startswith('-'): # handles case where user enters an invalid command
|
|
|
|
|
usage(1)
|
|
|
|
|
else: # if it's not a command and it's not invalid, I can assume it's a search term
|
|
|
|
|
search_terms.append(arg)
|
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
|
|
# Display the usage message if the user didn't enter a search term
|
|
|
|
|
if not search_terms:
|
|
|
|
|
usage(1)
|
|
|
|
|
|
|
|
|
|
query = ' '.join(search_terms)
|
|
|
|
|
results = searx_query(query, url)
|
|
|
|
|
print_results(results, limit, orderby)
|
2025-02-25 23:09:16 -05:00
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|
|
|
|
|
|
2025-03-01 16:37:35 -05:00
|
|
|
# vim: set sts=4 sw=4 ts=8 expandtab ft=python:
|