__main__.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. # lint: pylint
  3. # pylint: disable=missing-module-docstring
  4. import sys
  5. import io
  6. import os
  7. import argparse
  8. import logging
  9. import searx.search
  10. import searx.search.checker
  11. from searx.search import PROCESSORS
  12. from searx.engines import engine_shortcuts
  13. # configure logging
  14. root = logging.getLogger()
  15. handler = logging.StreamHandler(sys.stdout)
  16. for h in root.handlers:
  17. root.removeHandler(h)
  18. root.addHandler(handler)
  19. # color only for a valid terminal
  20. if sys.stdout.isatty() and os.environ.get('TERM') not in ['dumb', 'unknown']:
  21. RESET_SEQ = "\033[0m"
  22. COLOR_SEQ = "\033[1;%dm"
  23. BOLD_SEQ = "\033[1m"
  24. BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = map(lambda i: COLOR_SEQ % (30 + i), range(8))
  25. else:
  26. RESET_SEQ = ""
  27. COLOR_SEQ = ""
  28. BOLD_SEQ = ""
  29. BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = "", "", "", "", "", "", "", ""
  30. # equivalent of 'python -u' (unbuffered stdout, stderr)
  31. stdout = io.TextIOWrapper(
  32. # pylint: disable=consider-using-with
  33. open(sys.stdout.fileno(), 'wb', 0),
  34. write_through=True,
  35. )
  36. stderr = io.TextIOWrapper(
  37. # pylint: disable=consider-using-with
  38. open(sys.stderr.fileno(), 'wb', 0),
  39. write_through=True,
  40. )
  41. # iterator of processors
  42. def iter_processor(engine_name_list):
  43. if len(engine_name_list) > 0:
  44. for name in engine_name_list:
  45. name = engine_shortcuts.get(name, name)
  46. processor = PROCESSORS.get(name)
  47. if processor is not None:
  48. yield name, processor
  49. else:
  50. stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}{RED}Engine does not exist{RESET_SEQ}')
  51. else:
  52. for name, processor in searx.search.PROCESSORS.items():
  53. yield name, processor
  54. # actual check & display
  55. def run(engine_name_list, verbose):
  56. searx.search.initialize()
  57. for name, processor in iter_processor(engine_name_list):
  58. stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}Checking\n')
  59. if not sys.stdout.isatty():
  60. stderr.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}Checking\n')
  61. checker = searx.search.checker.Checker(processor)
  62. checker.run()
  63. if checker.test_results.successful:
  64. stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}{GREEN}OK{RESET_SEQ}\n')
  65. if verbose:
  66. stdout.write(f' {"found languages":15}: {" ".join(sorted(list(checker.test_results.languages)))}\n')
  67. else:
  68. stdout.write(f'{BOLD_SEQ}Engine {name:30}{RESET_SEQ}{RESET_SEQ}{RED}Error{RESET_SEQ}')
  69. if not verbose:
  70. errors = [test_name + ': ' + error for test_name, error in checker.test_results]
  71. stdout.write(f'{RED}Error {str(errors)}{RESET_SEQ}\n')
  72. else:
  73. stdout.write('\n')
  74. stdout.write(f' {"found languages":15}: {" ".join(sorted(list(checker.test_results.languages)))}\n')
  75. for test_name, logs in checker.test_results.logs.items():
  76. for log in logs:
  77. log = map(lambda l: l if isinstance(l, str) else repr(l), log)
  78. stdout.write(f' {test_name:15}: {RED}{" ".join(log)}{RESET_SEQ}\n')
  79. # call by setup.py
  80. def main():
  81. parser = argparse.ArgumentParser(description='Check searx engines.')
  82. parser.add_argument(
  83. 'engine_name_list',
  84. metavar='engine name',
  85. type=str,
  86. nargs='*',
  87. help='engines name or shortcut list. Empty for all engines.',
  88. )
  89. parser.add_argument(
  90. '--verbose',
  91. '-v',
  92. action='store_true',
  93. dest='verbose',
  94. help='Display details about the test results',
  95. default=False,
  96. )
  97. args = parser.parse_args()
  98. run(args.engine_name_list, args.verbose)
  99. if __name__ == '__main__':
  100. main()