| 
							
							# SPDX-License-Identifier: AGPL-3.0-or-later
 | 
						
						
						
						
							 | 
							
							# lint: pylint
 | 
						
						
						
						
							 | 
							
							# pylint: disable=missing-module-docstring
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							import sys
 | 
						
						
						
						
							 | 
							
							import io
 | 
						
						
						
						
							 | 
							
							import os
 | 
						
						
						
						
							 | 
							
							import argparse
 | 
						
						
						
						
							 | 
							
							import logging
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							import searx.search
 | 
						
						
						
						
							 | 
							
							import searx.search.checker
 | 
						
						
						
						
							 | 
							
							from searx.search import PROCESSORS
 | 
						
						
						
						
							 | 
							
							from searx.engines import engine_shortcuts
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# configure logging
 | 
						
						
						
						
							 | 
							
							root = logging.getLogger()
 | 
						
						
						
						
							 | 
							
							handler = logging.StreamHandler(sys.stdout)
 | 
						
						
						
						
							 | 
							
							for h in root.handlers:
 | 
						
						
						
						
							 | 
							
							    root.removeHandler(h)
 | 
						
						
						
						
							 | 
							
							root.addHandler(handler)
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# color only for a valid terminal
 | 
						
						
						
						
							 | 
							
							if sys.stdout.isatty() and os.environ.get('TERM') not in ['dumb', 'unknown']:
 | 
						
						
						
						
							 | 
							
							    RESET_SEQ = "\033[0m"
 | 
						
						
						
						
							 | 
							
							    COLOR_SEQ = "\033[1;%dm"
 | 
						
						
						
						
							 | 
							
							    BOLD_SEQ = "\033[1m"
 | 
						
						
						
						
							 | 
							
							    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = map(lambda i: COLOR_SEQ % (30 + i), range(8))
 | 
						
						
						
						
							 | 
							
							else:
 | 
						
						
						
						
							 | 
							
							    RESET_SEQ = ""
 | 
						
						
						
						
							 | 
							
							    COLOR_SEQ = ""
 | 
						
						
						
						
							 | 
							
							    BOLD_SEQ = ""
 | 
						
						
						
						
							 | 
							
							    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = "", "", "", "", "", "", "", ""
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# equivalent of 'python -u' (unbuffered stdout, stderr)
 | 
						
						
						
						
							 | 
							
							stdout = io.TextIOWrapper(
 | 
						
						
						
						
							 | 
							
							    # pylint: disable=consider-using-with
 | 
						
						
						
						
							 | 
							
							    open(sys.stdout.fileno(), 'wb', 0),
 | 
						
						
						
						
							 | 
							
							    write_through=True,
 | 
						
						
						
						
							 | 
							
							)
 | 
						
						
						
						
							 | 
							
							stderr = io.TextIOWrapper(
 | 
						
						
						
						
							 | 
							
							    # pylint: disable=consider-using-with
 | 
						
						
						
						
							 | 
							
							    open(sys.stderr.fileno(), 'wb', 0),
 | 
						
						
						
						
							 | 
							
							    write_through=True,
 | 
						
						
						
						
							 | 
							
							)
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# iterator of processors
 | 
						
						
						
						
							 | 
							
							def iter_processor(engine_name_list):
 | 
						
						
						
						
							 | 
							
							    if len(engine_name_list) > 0:
 | 
						
						
						
						
							 | 
							
							        for name in engine_name_list:
 | 
						
						
						
						
							 | 
							
							            name = engine_shortcuts.get(name, name)
 | 
						
						
						
						
							 | 
							
							            processor = PROCESSORS.get(name)
 | 
						
						
						
						
							 | 
							
							            if processor is not None:
 | 
						
						
						
						
							 | 
							
							                yield name, processor
 | 
						
						
						
						
							 | 
							
							            else:
 | 
						
						
						
						
							 | 
							
							                stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}{RED}Engine does not exist{RESET_SEQ}')
 | 
						
						
						
						
							 | 
							
							    else:
 | 
						
						
						
						
							 | 
							
							        for name, processor in searx.search.PROCESSORS.items():
 | 
						
						
						
						
							 | 
							
							            yield name, processor
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# actual check & display
 | 
						
						
						
						
							 | 
							
							def run(engine_name_list, verbose):
 | 
						
						
						
						
							 | 
							
							    searx.search.initialize()
 | 
						
						
						
						
							 | 
							
							    for name, processor in iter_processor(engine_name_list):
 | 
						
						
						
						
							 | 
							
							        stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}Checking\n')
 | 
						
						
						
						
							 | 
							
							        if not sys.stdout.isatty():
 | 
						
						
						
						
							 | 
							
							            stderr.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}Checking\n')
 | 
						
						
						
						
							 | 
							
							        checker = searx.search.checker.Checker(processor)
 | 
						
						
						
						
							 | 
							
							        checker.run()
 | 
						
						
						
						
							 | 
							
							        if checker.test_results.successful:
 | 
						
						
						
						
							 | 
							
							            stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}{GREEN}OK{RESET_SEQ}\n')
 | 
						
						
						
						
							 | 
							
							            if verbose:
 | 
						
						
						
						
							 | 
							
							                stdout.write(f'    {"found languages":15}: {" ".join(sorted(list(checker.test_results.languages)))}\n')
 | 
						
						
						
						
							 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
							            stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}{RESET_SEQ}{RED}Error{RESET_SEQ}')
 | 
						
						
						
						
							 | 
							
							            if not verbose:
 | 
						
						
						
						
							 | 
							
							                errors = [test_name + ': ' + error for test_name, error in checker.test_results]
 | 
						
						
						
						
							 | 
							
							                stdout.write(f'{RED}Error {str(errors)}{RESET_SEQ}\n')
 | 
						
						
						
						
							 | 
							
							            else:
 | 
						
						
						
						
							 | 
							
							                stdout.write('\n')
 | 
						
						
						
						
							 | 
							
							                stdout.write(f'    {"found languages":15}: {" ".join(sorted(list(checker.test_results.languages)))}\n')
 | 
						
						
						
						
							 | 
							
							                for test_name, logs in checker.test_results.logs.items():
 | 
						
						
						
						
							 | 
							
							                    for log in logs:
 | 
						
						
						
						
							 | 
							
							                        log = map(lambda l: l if isinstance(l, str) else repr(l), log)
 | 
						
						
						
						
							 | 
							
							                        stdout.write(f'    {test_name:15}: {RED}{" ".join(log)}{RESET_SEQ}\n')
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# call by setup.py
 | 
						
						
						
						
							 | 
							
							def main():
 | 
						
						
						
						
							 | 
							
							    parser = argparse.ArgumentParser(description='Check searx engines.')
 | 
						
						
						
						
							 | 
							
							    parser.add_argument(
 | 
						
						
						
						
							 | 
							
							        'engine_name_list',
 | 
						
						
						
						
							 | 
							
							        metavar='engine name',
 | 
						
						
						
						
							 | 
							
							        type=str,
 | 
						
						
						
						
							 | 
							
							        nargs='*',
 | 
						
						
						
						
							 | 
							
							        help='engines name or shortcut list. Empty for all engines.',
 | 
						
						
						
						
							 | 
							
							    )
 | 
						
						
						
						
							 | 
							
							    parser.add_argument(
 | 
						
						
						
						
							 | 
							
							        '--verbose',
 | 
						
						
						
						
							 | 
							
							        '-v',
 | 
						
						
						
						
							 | 
							
							        action='store_true',
 | 
						
						
						
						
							 | 
							
							        dest='verbose',
 | 
						
						
						
						
							 | 
							
							        help='Display details about the test results',
 | 
						
						
						
						
							 | 
							
							        default=False,
 | 
						
						
						
						
							 | 
							
							    )
 | 
						
						
						
						
							 | 
							
							    args = parser.parse_args()
 | 
						
						
						
						
							 | 
							
							    run(args.engine_name_list, args.verbose)
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							if __name__ == '__main__':
 | 
						
						
						
						
							 | 
							
							    main()
 |