[feat] result types: add weather result answerer and template

This commit is contained in:
Bnyro 2025-04-24 17:28:16 +02:00 committed by Markus Heiser
parent 8ef5fbca4e
commit ef1a2c13c4
3 changed files with 123 additions and 3 deletions

View File

@ -13,14 +13,14 @@
from __future__ import annotations
__all__ = ["Result", "MainResult", "KeyValue", "EngineResults", "AnswerSet", "Answer", "Translations"]
__all__ = ["Result", "MainResult", "KeyValue", "EngineResults", "AnswerSet", "Answer", "Translations", "Weather"]
import abc
from searx import enginelib
from ._base import Result, MainResult, LegacyResult
from .answer import AnswerSet, Answer, Translations
from .answer import AnswerSet, Answer, Translations, Weather
from .keyvalue import KeyValue
@ -35,6 +35,7 @@ class ResultList(list, abc.ABC):
MainResult = MainResult
Result = Result
Translations = Translations
Weather = Weather
# for backward compatibility
LegacyResult = LegacyResult

View File

@ -18,6 +18,10 @@ template.
:members:
:show-inheritance:
.. autoclass:: Weather
:members:
:show-inheritance:
.. autoclass:: AnswerSet
:members:
:show-inheritance:
@ -26,7 +30,7 @@ template.
from __future__ import annotations
__all__ = ["AnswerSet", "Answer", "Translations"]
__all__ = ["AnswerSet", "Answer", "Translations", "Weather"]
import msgspec
@ -143,3 +147,51 @@ class Translations(BaseAnswer, kw_only=True):
synonyms: list[str] = []
"""List of synonyms for the requested translation."""
class Weather(BaseAnswer, kw_only=True):
"""Answer type for weather data."""
template: str = "answer/weather.html"
"""The template is located at :origin:`answer/weather.html
<searx/templates/simple/answer/weather.html>`"""
location: str
"""The geo-location the weather data is from (e.g. `Berlin, Germany`)."""
current: Weather.DataItem
"""Current weather at ``location``."""
forecasts: list[Weather.DataItem] = []
"""Weather forecasts for ``location``."""
def __post_init__(self):
if not self.location:
raise ValueError("Weather answer is missing a location")
class DataItem(msgspec.Struct, kw_only=True):
"""A container for weather data such as temperature, humidity, ..."""
time: str | None = None
"""Time of the forecast - not needed for the current weather."""
condition: str
"""Weather condition, e.g. `cloudy`, `rainy`, `sunny` ..."""
temperature: str
"""Temperature string, e.g. `17°C`"""
feelsLike: str | None = None
"""Felt temperature string, should be formatted like ``temperature``"""
humidity: str | None = None
"""Humidity percentage string, e.g. `60%`"""
pressure: str | None = None
"""Pressure string, e.g. `1030hPa`"""
wind: str | None = None
"""Information about the wind, e.g. `W, 231°, 10 m/s`"""
attributes: dict[str] = []
"""Key-Value dict of additional weather attributes that are not available above"""

View File

@ -0,0 +1,67 @@
{% macro show_weather_data(data) %}
<table>
<tbody>
{%- if data.condition -%}
<tr>
<td>{{ _("Condition") }}</td>
<td>{{ data.condition }}</td>
</tr>
{%- endif -%}
{%- if data.temperature -%}
<tr>
<td>{{ _("Temperature") }}</td>
<td>{{ data.temperature }}</td>
</tr>
{%- endif -%}
{%- if data.feelsLike -%}
<tr>
<td>{{ _("Feels Like") }}</td>
<td>{{ data.feelsLike }}</td>
</tr>
{%- endif -%}
{%- if data.wind -%}
<tr>
<td>{{ _("Wind") }}</td>
<td>{{ data.wind }}</td>
</tr>
{%- endif -%}
{%- if data.humidity -%}
<tr>
<td>{{ _("Humidity") }}</td>
<td>{{ data.humidity }}</td>
</tr>
{%- endif -%}
{%- if data.pressure -%}
<tr>
<td>{{ _("Pressure") }}</td>
<td>{{ data.pressure }}</td>
</tr>
{%- endif -%}
<tr>
{%- for name, value in data.attributes.items() -%}
<tr>
<td>{{ name }}</td>
<td>{{ value }}</td>
</tr>
{%- endfor -%}
</tbody>
</table>
{% endmacro %}
<details class="answer-weather">
<summary>It's currently {{ answer.current.condition }}, {{ answer.current.temperature }} in {{ answer.location }}</summary>
<div>
<h2 class="title">{{ answer.location }}</h2>
<h3>{{ _("Current condition") }}</h3>
{{ show_weather_data(answer.current) }}
{%- if answer.forecasts -%}
<div class="answer-weather-forecasts">
{%- for forecast in answer.forecasts -%}
<h3>{{ forecast.time }}</h3>
{{ show_weather_data(forecast) }}
{%- endfor -%}
</div>
{%- endif -%}
</div>
</details>