[enh] data: traits population

Job failing since October 2025.

enh: always raise and reuse data
fix: brave unknown locale
fix: startpage add "brazilian"
This commit is contained in:
Ivan Gabaldon
2026-03-01 11:33:06 +01:00
committed by Markus Heiser
parent a9f3baefe6
commit 2b03a61832
16 changed files with 946 additions and 864 deletions
+62 -45
View File
@@ -5,28 +5,28 @@
https://de1.api.radio-browser.info/#Advanced_station_search
"""
import random
import socket
from urllib.parse import urlencode
import babel
from flask_babel import gettext
from searx.network import get
from searx.enginelib import EngineCache
from searx.enginelib.traits import EngineTraits
from searx.locales import language_tag
about = {
"website": 'https://www.radio-browser.info/',
"wikidata_id": 'Q111664849',
"official_api_documentation": 'https://de1.api.radio-browser.info/',
"website": "https://www.radio-browser.info/",
"wikidata_id": "Q111664849",
"official_api_documentation": "https://de1.api.radio-browser.info/",
"use_official_api": True,
"require_api_key": False,
"results": 'JSON',
"results": "JSON",
}
paging = True
categories = ['music', 'radio']
categories = ["music", "radio"]
number_of_results = 10
@@ -98,26 +98,26 @@ def request(query, params):
server = random.choice(servers)
args = {
'name': query,
'order': 'votes',
'offset': (params['pageno'] - 1) * number_of_results,
'limit': number_of_results,
'hidebroken': 'true',
'reverse': 'true',
"name": query,
"order": "votes",
"offset": (params["pageno"] - 1) * number_of_results,
"limit": number_of_results,
"hidebroken": "true",
"reverse": "true",
}
if 'language' in station_filters:
lang = traits.get_language(params['searxng_locale']) # type: ignore
if "language" in station_filters:
lang = traits.get_language(params["searxng_locale"]) # type: ignore
if lang:
args['language'] = lang
args["language"] = lang
if 'countrycode' in station_filters:
if len(params['searxng_locale'].split('-')) > 1:
countrycode = params['searxng_locale'].split('-')[-1].upper()
if countrycode in traits.custom['countrycodes']: # type: ignore
args['countrycode'] = countrycode
if "countrycode" in station_filters:
if len(params["searxng_locale"].split("-")) > 1:
countrycode = params["searxng_locale"].split("-")[-1].upper()
if countrycode in traits.custom["countrycodes"]: # type: ignore
args["countrycode"] = countrycode
params['url'] = f"{server}/json/stations/search?{urlencode(args)}"
params["url"] = f"{server}/json/stations/search?{urlencode(args)}"
def response(resp):
@@ -126,28 +126,28 @@ def response(resp):
json_resp = resp.json()
for result in json_resp:
url = result['homepage']
url = result["homepage"]
if not url:
url = result['url_resolved']
url = result["url_resolved"]
content = []
tags = ', '.join(result.get('tags', '').split(','))
tags = ", ".join(result.get("tags", "").split(","))
if tags:
content.append(tags)
for x in ['state', 'country']:
for x in ["state", "country"]:
v = result.get(x)
if v:
v = str(v).strip()
content.append(v)
metadata = []
codec = result.get('codec')
if codec and codec.lower() != 'unknown':
metadata.append(f'{codec} ' + gettext('radio'))
codec = result.get("codec")
if codec and codec.lower() != "unknown":
metadata.append(f"{codec} " + gettext("radio"))
for x, y in [
(gettext('bitrate'), 'bitrate'),
(gettext('votes'), 'votes'),
(gettext('clicks'), 'clickcount'),
(gettext("bitrate"), "bitrate"),
(gettext("votes"), "votes"),
(gettext("clicks"), "clickcount"),
]:
v = result.get(y)
if v:
@@ -155,12 +155,12 @@ def response(resp):
metadata.append(f"{x} {v}")
results.append(
{
'url': url,
'title': result['name'],
'thumbnail': result.get('favicon', '').replace("http://", "https://"),
'content': ' | '.join(content),
'metadata': ' | '.join(metadata),
'iframe_src': result['url_resolved'].replace("http://", "https://"),
"url": url,
"title": result["name"],
"thumbnail": result.get("favicon", "").replace("http://", "https://"),
"content": " | ".join(content),
"metadata": " | ".join(metadata),
"iframe_src": result["url_resolved"].replace("http://", "https://"),
}
)
@@ -181,15 +181,32 @@ def fetch_traits(engine_traits: EngineTraits):
init(None)
from babel.core import get_global
from searx.network import get # see https://github.com/searxng/searxng/issues/762
babel_reg_list = get_global("territory_languages").keys()
server = server_list()[0]
language_list = get(f'{server}/json/languages').json() # type: ignore
country_list = get(f'{server}/json/countries').json() # type: ignore
resp = get(
f"{server}/json/languages",
timeout=5,
)
if not resp.ok:
raise RuntimeError("Response from radio-browser languages is not OK.")
language_list = resp.json()
resp = get(
f"{server}/json/countries",
timeout=5,
)
if not resp.ok:
raise RuntimeError("Response from radio-browser countries is not OK.")
country_list = resp.json()
for lang in language_list:
babel_lang = lang.get('iso_639')
babel_lang = lang.get("iso_639")
if not babel_lang:
# the language doesn't have any iso code, and hence can't be parsed
# print(f"ERROR: lang - no iso code in {lang}")
@@ -200,7 +217,7 @@ def fetch_traits(engine_traits: EngineTraits):
# print(f"ERROR: language tag {babel_lang} is unknown by babel")
continue
eng_tag = lang['name']
eng_tag = lang["name"]
conflict = engine_traits.languages.get(sxng_tag)
if conflict:
if conflict != eng_tag:
@@ -211,7 +228,7 @@ def fetch_traits(engine_traits: EngineTraits):
countrycodes = set()
for region in country_list:
# country_list contains duplicates that differ only in upper/lower case
_reg = region['iso_3166_1'].upper()
_reg = region["iso_3166_1"].upper()
if _reg not in babel_reg_list:
print(f"ERROR: region tag {region['iso_3166_1']} is unknown by babel")
continue
@@ -219,4 +236,4 @@ def fetch_traits(engine_traits: EngineTraits):
countrycodes = list(countrycodes)
countrycodes.sort()
engine_traits.custom['countrycodes'] = countrycodes
engine_traits.custom["countrycodes"] = countrycodes