.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.engines.radio_browser Namespace Reference

Functions

 init (_)
list[str] server_list ()
 request (query, params)
 response (resp)
 fetch_traits (EngineTraits engine_traits)

Variables

dict about
bool paging = True
list categories = ['music', 'radio']
int number_of_results = 10
list station_filters = []

Detailed Description

Search radio stations from RadioBrowser by `Advanced station search API`_.

.. _Advanced station search API:
   https://de1.api.radio-browser.info/#Advanced_station_search

Function Documentation

◆ fetch_traits()

searx.engines.radio_browser.fetch_traits ( EngineTraits engine_traits)
Fetch languages and countrycodes from RadioBrowser

- ``traits.languages``: `list of languages API`_
- ``traits.custom['countrycodes']``: `list of countries API`_

.. _list of countries API: https://de1.api.radio-browser.info/#List_of_countries
.. _list of languages API: https://de1.api.radio-browser.info/#List_of_languages

Definition at line 166 of file radio_browser.py.

166def fetch_traits(engine_traits: EngineTraits):
167 """Fetch languages and countrycodes from RadioBrowser
168
169 - ``traits.languages``: `list of languages API`_
170 - ``traits.custom['countrycodes']``: `list of countries API`_
171
172 .. _list of countries API: https://de1.api.radio-browser.info/#List_of_countries
173 .. _list of languages API: https://de1.api.radio-browser.info/#List_of_languages
174 """
175 # pylint: disable=import-outside-toplevel
176
177 init(None)
178 from babel.core import get_global
179
180 babel_reg_list = get_global("territory_languages").keys()
181
182 server = server_list()[0]
183 language_list = get(f'{server}/json/languages').json() # type: ignore
184 country_list = get(f'{server}/json/countries').json() # type: ignore
185
186 for lang in language_list:
187
188 babel_lang = lang.get('iso_639')
189 if not babel_lang:
190 # the language doesn't have any iso code, and hence can't be parsed
191 # print(f"ERROR: lang - no iso code in {lang}")
192 continue
193 try:
194 sxng_tag = language_tag(babel.Locale.parse(babel_lang, sep="-"))
195 except babel.UnknownLocaleError:
196 # print(f"ERROR: language tag {babel_lang} is unknown by babel")
197 continue
198
199 eng_tag = lang['name']
200 conflict = engine_traits.languages.get(sxng_tag)
201 if conflict:
202 if conflict != eng_tag:
203 print("CONFLICT: babel %s --> %s, %s" % (sxng_tag, conflict, eng_tag))
204 continue
205 engine_traits.languages[sxng_tag] = eng_tag
206
207 countrycodes = set()
208 for region in country_list:
209 # country_list contains duplicates that differ only in upper/lower case
210 _reg = region['iso_3166_1'].upper()
211 if _reg not in babel_reg_list:
212 print(f"ERROR: region tag {region['iso_3166_1']} is unknown by babel")
213 continue
214 countrycodes.add(_reg)
215
216 countrycodes = list(countrycodes)
217 countrycodes.sort()
218 engine_traits.custom['countrycodes'] = countrycodes

References init(), and server_list().

Here is the call graph for this function:

◆ init()

searx.engines.radio_browser.init ( _)

Definition at line 59 of file radio_browser.py.

59def init(_):
60 global CACHE # pylint: disable=global-statement
61 CACHE = EngineCache("radio_browser")
62 server_list()
63
64

References server_list().

Referenced by fetch_traits().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request()

searx.engines.radio_browser.request ( query,
params )

Definition at line 86 of file radio_browser.py.

86def request(query, params):
87
88 servers = server_list()
89 if not servers:
90 logger.error("Fetched server list is empty!")
91 params["url"] = None
92 return
93
94 server = random.choice(servers)
95
96 args = {
97 'name': query,
98 'order': 'votes',
99 'offset': (params['pageno'] - 1) * number_of_results,
100 'limit': number_of_results,
101 'hidebroken': 'true',
102 'reverse': 'true',
103 }
104
105 if 'language' in station_filters:
106 lang = traits.get_language(params['searxng_locale']) # type: ignore
107 if lang:
108 args['language'] = lang
109
110 if 'countrycode' in station_filters:
111 if len(params['searxng_locale'].split('-')) > 1:
112 countrycode = params['searxng_locale'].split('-')[-1].upper()
113 if countrycode in traits.custom['countrycodes']: # type: ignore
114 args['countrycode'] = countrycode
115
116 params['url'] = f"{server}/json/stations/search?{urlencode(args)}"
117
118

References server_list().

Here is the call graph for this function:

◆ response()

searx.engines.radio_browser.response ( resp)

Definition at line 119 of file radio_browser.py.

119def response(resp):
120 results = []
121
122 json_resp = resp.json()
123
124 for result in json_resp:
125 url = result['homepage']
126 if not url:
127 url = result['url_resolved']
128
129 content = []
130 tags = ', '.join(result.get('tags', '').split(','))
131 if tags:
132 content.append(tags)
133 for x in ['state', 'country']:
134 v = result.get(x)
135 if v:
136 v = str(v).strip()
137 content.append(v)
138
139 metadata = []
140 codec = result.get('codec')
141 if codec and codec.lower() != 'unknown':
142 metadata.append(f'{codec} ' + gettext('radio'))
143 for x, y in [
144 (gettext('bitrate'), 'bitrate'),
145 (gettext('votes'), 'votes'),
146 (gettext('clicks'), 'clickcount'),
147 ]:
148 v = result.get(y)
149 if v:
150 v = str(v).strip()
151 metadata.append(f"{x} {v}")
152 results.append(
153 {
154 'url': url,
155 'title': result['name'],
156 'thumbnail': result.get('favicon', '').replace("http://", "https://"),
157 'content': ' | '.join(content),
158 'metadata': ' | '.join(metadata),
159 'iframe_src': result['url_resolved'].replace("http://", "https://"),
160 }
161 )
162
163 return results
164
165

◆ server_list()

list[str] searx.engines.radio_browser.server_list ( )

Definition at line 65 of file radio_browser.py.

65def server_list() -> list[str]:
66
67 servers = CACHE.get("servers", [])
68 if servers:
69 return servers
70
71 # hint: can take up to 40sec!
72 ips = socket.getaddrinfo("all.api.radio-browser.info", 80, 0, 0, socket.IPPROTO_TCP)
73 for ip_tuple in ips:
74 _ip: str = ip_tuple[4][0] # type: ignore
75 url = socket.gethostbyaddr(_ip)[0]
76 srv = "https://" + url
77 if srv not in servers:
78 servers.append(srv)
79
80 # update server list once in 24h
81 CACHE.set(key="servers", value=servers, expire=60 * 60 * 24)
82
83 return servers
84
85

Referenced by fetch_traits(), init(), and request().

Here is the caller graph for this function:

Variable Documentation

◆ about

dict searx.engines.radio_browser.about
Initial value:
1= {
2 "website": 'https://www.radio-browser.info/',
3 "wikidata_id": 'Q111664849',
4 "official_api_documentation": 'https://de1.api.radio-browser.info/',
5 "use_official_api": True,
6 "require_api_key": False,
7 "results": 'JSON',
8}

Definition at line 20 of file radio_browser.py.

◆ categories

list searx.engines.radio_browser.categories = ['music', 'radio']

Definition at line 29 of file radio_browser.py.

◆ number_of_results

int searx.engines.radio_browser.number_of_results = 10

Definition at line 31 of file radio_browser.py.

◆ paging

bool searx.engines.radio_browser.paging = True

Definition at line 28 of file radio_browser.py.

◆ station_filters

list searx.engines.radio_browser.station_filters = []

Definition at line 33 of file radio_browser.py.