diff --git a/searx/result_types/_base.py b/searx/result_types/_base.py index 6d9a49943..66e31c7f2 100644 --- a/searx/result_types/_base.py +++ b/searx/result_types/_base.py @@ -110,6 +110,9 @@ class Result(msgspec.Struct, kw_only=True): return iter(self.__struct_fields__) + def as_dict(self): + return {f: getattr(self, f) for f in self.__struct_fields__} + class LegacyResult(dict): """A wrapper around a legacy result item. The SearXNG core uses this class @@ -130,10 +133,12 @@ class LegacyResult(dict): UNSET = object() WHITESPACE_REGEX = re.compile('( |\t|\n)+', re.M | re.U) + def as_dict(self): + return self + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.__dict__ = self # Init fields with defaults / compare with defaults of the fields in class Result self.engine = self.get("engine", "") diff --git a/searx/webutils.py b/searx/webutils.py index c58b981f6..6e49e3830 100644 --- a/searx/webutils.py +++ b/searx/webutils.py @@ -123,17 +123,18 @@ def write_csv_response(csv: CSVWriter, rc: ResultContainer) -> None: # pylint: """ - results = rc.get_ordered_results() keys = ('title', 'url', 'content', 'host', 'engine', 'score', 'type') csv.writerow(keys) - for row in results: + for res in rc.get_ordered_results(): + row = res.as_dict() row['host'] = row['parsed_url'].netloc row['type'] = 'result' csv.writerow([row.get(key, '') for key in keys]) for a in rc.answers: - row = {'title': a, 'type': 'answer'} + row = a.as_dict() + row['host'] = row['parsed_url'].netloc csv.writerow([row.get(key, '') for key in keys]) for a in rc.suggestions: @@ -158,18 +159,17 @@ class JSONEncoder(json.JSONEncoder): # pylint: disable=missing-class-docstring def get_json_response(sq: SearchQuery, rc: ResultContainer) -> str: """Returns the JSON string of the results to a query (``application/json``)""" - results = rc.number_of_results - x = { + data = { 'query': sq.query, - 'number_of_results': results, - 'results': rc.get_ordered_results(), - 'answers': list(rc.answers), + 'number_of_results': rc.number_of_results, + 'results': [_.as_dict() for _ in rc.get_ordered_results()], + 'answers': [_.as_dict() for _ in rc.answers], 'corrections': list(rc.corrections), 'infoboxes': rc.infoboxes, 'suggestions': list(rc.suggestions), 'unresponsive_engines': get_translated_errors(rc.unresponsive_engines), } - response = json.dumps(x, cls=JSONEncoder) + response = json.dumps(data, cls=JSONEncoder) return response